/* assets/css/main.css */
/* Jazz pod Kozákovem — design system entry point (no build step, native @import) */

/* tokens */
/* assets/css/tokens/fonts.css */
/* Brand typefaces (supplied by the festival):
   Youth Bold           -> display/headline face (the only weight supplied: bold)
   Jannon 10 Pro Italic -> accent/editorial italic face (the only style supplied: italic)
   Space Grotesk        -> body/UI workhorse (self-hosted variable font, 400-700) */

/* Youth Bold a Jannon 10 Pro Italic se servírují jako subsetované woff2
   (latin + latin-ext, tedy včetně české diakritiky) — 316 kB OTF → 69 kB.
   Původní OTF zůstává jako druhý zdroj: prohlížeč si bere první formát,
   kterému rozumí, takže woff2 vyhraje všude, kde je podporovaný (od IE11
   dál to je každý prohlížeč), a OTF je jen záchranná síť.
   Subset se generuje z OTF příkazem:
     pyftsubset FONT.otf --output-file=FONT.woff2 --flavor=woff2 \
       --unicodes="<latin>,<latin-ext>" --layout-features+=tnum,lnum,pnum,onum \
       --desubroutinize
   Displejové písmo se navíc preloaduje v hlavičce (site/snippets/meta.php). */

@font-face {
  font-family: "Youth Bold";
  src:
    url("/assets/fonts/Youth-Bold.woff2?v=1785106422") format("woff2"),
    url("/assets/fonts/Youth-Bold.otf?v=1785106422") format("opentype");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Jannon 10 Pro";
  src:
    url("/assets/fonts/Jannon10Pro-Italic.woff2?v=1785106422") format("woff2"),
    url("/assets/fonts/Jannon10Pro-Italic.otf?v=1785106422") format("opentype");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

/* latin */
@font-face {
  font-family: "Space Grotesk";
  src: url("/assets/fonts/SpaceGrotesk-latin.woff2?v=1785106422") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

/* latin-ext (czech diacritics) */
@font-face {
  font-family: "Space Grotesk";
  src: url("/assets/fonts/SpaceGrotesk-latin-ext.woff2?v=1785106422") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}


/* assets/css/tokens/colors.css */
:root {
  /* ---- Base palette (from brand color sheet) ---- */
  --green: #0af00f;   /* neon jazz-lettering green */
  --orange: #f0571d;  /* sunburst / stamp orange — plochy, rámečky, akcenty */
  /* Tmavší odstín téže oranžové, výhradně pro TEXT. Jasná --orange má na cream
     jen 2,40:1, tenhle projde AA na obou světlých podkladech (cream 5,17:1,
     bílá 7,44:1). Na plochy se nepoužívá — tam barva není nositelem informace. */
  --orange-text: #9c2f07;
  --blue: #2cadda;    /* poster-shape blue */
  --yellow: #ffed00;  /* highlight yellow */
  --cream: #d7d8cd;   /* warm off-white, paper/print stock */
  --ink: #1c1d1b;     /* near-black, sampled from printed lettering */
  --white: #ffffff;

  /* tints for hover/press/subtle fills */
  --green-dark: #08c00c;
  --orange-dark: #cf3f0f;
  --blue-dark: #1f8fb3;
  --yellow-dark: #e0d100;
  --ink-soft: #4a4b48;

  /* ---- Semantic aliases ---- */
  --surface-page: var(--cream);
  --surface-card: var(--white);
  --surface-inverse: var(--ink);

  --text-primary: var(--ink);
  --text-secondary: var(--ink-soft);
  --text-inverse: var(--white);
  --text-on-brand: var(--ink);

  --brand-primary: var(--green);
  --brand-primary-hover: var(--green-dark);
  --brand-secondary: var(--orange);
  --brand-secondary-hover: var(--orange-dark);
  --brand-secondary-text: var(--orange-text);
  --accent-blue: var(--blue);
  --accent-yellow: var(--yellow);

  --border-default: var(--ink);
  --border-subtle: color-mix(in oklch, var(--ink) 25%, transparent);

  /* Focus ring je dvoubarevný, aby nezávisel na podkladu: tmavý obrys (--ink)
     obalený tenkým světlým prstencem (--white). Na světlých plochách nese
     kontrast obrys (blue 6,52:1, orange 4,90:1, green 10,87:1, cream 11,76:1,
     bílá 16,92:1), na ink podkladu prstenec (16,92:1). Samotná --blue měla
     na modré patičce 1,00:1. */
  --focus-ring: var(--ink);
  --focus-ring-contrast: var(--white);
  /* 7px = 2px mezera + 3px obrys + 2px vnější prstenec; obrys se kreslí přes
     prostředek prstence, takže zbydou 2px světla z každé strany. Komponenty,
     které mají vlastní box-shadow (button, icon-button, interpret__link),
     si tenhle stín přiskládají, aby o prstenec nepřišly. */
  --focus-ring-halo: 0 0 0 7px var(--focus-ring-contrast);
}


/* assets/css/tokens/typography.css */
/* Fluid type scale (utopia.fyi) — viewport range 320px -> 1240px,
   min/max anchored to the design's px values. */

:root {
  --font-display: "Youth Bold", "Space Grotesk", sans-serif; /* bold only */
  --font-accent: "Jannon 10 Pro", Georgia, serif;            /* italic only */
  --font-body: "Space Grotesk", "Helvetica Neue", Arial, sans-serif;
  --font-mono: "Space Grotesk", monospace; /* no monospace face supplied; reuses body */

  /* fluid sizes: 48->96, 36->64, 28->40, 20->22 */
  --size-display-xl: clamp(3rem, 1.9565rem + 5.2174vw, 6rem);
  --size-display-l: clamp(2.25rem, 1.6413rem + 3.0435vw, 4rem);
  --size-display-m: clamp(1.75rem, 1.4891rem + 1.3043vw, 2.5rem);
  --size-display-s: clamp(1.25rem, 1.2065rem + 0.2174vw, 1.375rem);

  /* fluid sizes: 24->28, 18->20 */
  --size-accent-l: clamp(1.5rem, 1.413rem + 0.4348vw, 1.75rem);
  --size-accent-m: clamp(1.125rem, 1.0815rem + 0.2174vw, 1.25rem);

  /* 17->19, 16, 14, 13 */
  --size-body-l: clamp(1.0625rem, 1.019rem + 0.2174vw, 1.1875rem);
  --size-body-m: 1rem;
  --size-body-s: 0.875rem;
  --size-label: 0.8125rem;

  /* font shorthand tokens: usage `font: var(--text-display-xl)` */
  --text-display-xl: 700 var(--size-display-xl)/0.95 var(--font-display);
  --text-display-l: 700 var(--size-display-l)/1 var(--font-display);
  --text-display-m: 700 var(--size-display-m)/1.05 var(--font-display);
  --text-display-s: 700 var(--size-display-s)/1.1 var(--font-display);

  --text-accent-l: italic 400 var(--size-accent-l)/1.3 var(--font-accent);
  --text-accent-m: italic 400 var(--size-accent-m)/1.4 var(--font-accent);

  --text-body-l: 400 var(--size-body-l)/1.6 var(--font-body);
  --text-body-m: 400 var(--size-body-m)/1.6 var(--font-body);
  --text-body-s: 400 var(--size-body-s)/1.5 var(--font-body);
  --text-label: 600 var(--size-label)/1.2 var(--font-body);
  --text-eyebrow: 700 var(--size-label)/1.2 var(--font-body);

  --tracking-wide: 0.08em;
  --tracking-eyebrow: 0.14em;
}


/* assets/css/tokens/spacing.css */
/* Fluid space scale (utopia.fyi) — viewport range 320px -> 1240px.
   Max values = the design's 4px-based scale (4/8/12/16/24/32/48/64/96/128),
   min values ~15-25% smaller on mobile. */

:root {
  --space-3xs: 0.25rem; /* 4px fixed */
  --space-2xs: clamp(0.375rem, 0.3315rem + 0.2174vw, 0.5rem);   /* 6->8 */
  --space-xs: clamp(0.625rem, 0.5815rem + 0.2174vw, 0.75rem);   /* 10->12 */
  --space-s: clamp(0.875rem, 0.8315rem + 0.2174vw, 1rem);       /* 14->16 */
  --space-m: clamp(1.25rem, 1.163rem + 0.4348vw, 1.5rem);       /* 20->24 */
  --space-l: clamp(1.625rem, 1.4946rem + 0.6522vw, 2rem);       /* 26->32 */
  --space-xl: clamp(2.25rem, 1.9891rem + 1.3043vw, 3rem);       /* 36->48 */
  --space-2xl: clamp(3rem, 2.6522rem + 1.7391vw, 4rem);         /* 48->64 */
  --space-3xl: clamp(4.5rem, 3.9783rem + 2.6087vw, 6rem);       /* 72->96 */
  --space-4xl: clamp(6rem, 5.3043rem + 3.4783vw, 8rem);         /* 96->128 */

  /* one-step fluid pairs for section rhythm */
  --space-s-m: clamp(0.875rem, 0.6576rem + 1.087vw, 1.5rem);    /* 14->24 */
  --space-m-l: clamp(1.25rem, 0.9891rem + 1.3043vw, 2rem);      /* 20->32 */
  --space-l-xl: clamp(1.625rem, 1.1467rem + 2.3913vw, 3rem);    /* 26->48 */
  --space-xl-2xl: clamp(2.25rem, 1.6413rem + 3.0435vw, 4rem);   /* 36->64 */

  --radius-s: 4px;
  --radius-m: 8px;
  --radius-l: 16px;
  --radius-pill: 999px;

  --border-w: 2px;
  --border-w-thick: 3px;

  /* hard, unblurred "print/stamp" offset shadow — no soft/blurred shadows in this brand */
  --shadow-stamp-s: 3px 3px 0 var(--ink);
  --shadow-stamp-m: 5px 5px 0 var(--ink);
  --shadow-stamp-l: 8px 8px 0 var(--ink);

  /* ---- pohyb ----
     Snap (mírně přestřelí) = reakce prvku na dotyk. Out = náběh plochy,
     která přijíždí. In = odchod; konec má být rychlý, ať se nečeká na
     doznění. --ease-out sdílí i motion.js u odometru. */
  --ease-snap: cubic-bezier(0.2, 0.9, 0.2, 1.2);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in: cubic-bezier(0.4, 0, 1, 1);

  --duration-fast: 120ms; /* press, stav malého ovládacího prvku */
  --duration-base: 180ms; /* náběh menu, změny stavu komponent */
  --duration-slow: 260ms; /* plochy, které se zvedají nebo mění výšku */

  /* Zdvih karty pod kurzorem — trojice odpovídá razítkovým stínům výše:
     karta se --shadow-stamp-m se zvedne o --lift-m a stín povyroste na -l. */
  --lift-s: 4px;
  --lift-m: 6px;
  --lift-l: 8px;

  /* Stisk = posun o offset razítkového stínu, stín zmizí. */
  --press-offset: 3px;

  /* page measure */
  --measure: 65ch;
  --content-max: 88rem; /* 1248px */
}



/* base */
/* assets/css/base/reset.css */
/* Minimal modern reset */

*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
}

html {
  -webkit-text-size-adjust: none;
  text-size-adjust: none;
}

body {
  min-height: 100vh;
}

img,
picture,
video,
canvas,
svg {
  display: block;
  max-width: 100%;
}

input,
button,
textarea,
select {
  font: inherit;
  color: inherit;
}

p,
h1,
h2,
h3,
h4,
h5,
h6 {
  overflow-wrap: break-word;
}

/* Strip list defaults from any list that opts in with a class. Wrapped in
   :where() so it carries zero specificity — a component/layout class (e.g.
   .c-…__grid or .l-stack) always wins without needing an `ul.c-…` hack. */
:where(ul[class], ol[class]) {
  list-style: none;
  padding: 0;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}


/* assets/css/base/global.css */
body {
  background: var(--surface-page);
  color: var(--text-primary);
  font: var(--text-body-m);
}

/* Youth Bold is the only display weight — big, sparing, lowercase (brand rule) */
h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  font-weight: 700;
}

h1 {
  font: var(--text-display-xl);
}

h2 {
  font: var(--text-display-l);
}

h3 {
  font: var(--text-display-m);
}

h4 {
  font: var(--text-display-s);
}

a {
  color: inherit;
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}

/* Dvoubarevný focus ring — tmavý obrys + světlý prstenec, viz --focus-ring
   v tokens/colors.css. Vidět je na všech šesti podkladech webu. */
:focus-visible {
  outline: var(--border-w-thick) solid var(--focus-ring);
  outline-offset: 2px;
  box-shadow: var(--focus-ring-halo);
}

::selection {
  background: var(--accent-yellow);
  color: var(--ink);
}

/* text helpers tied to brand voice */
.u-eyebrow {
  font: var(--text-eyebrow);
  letter-spacing: var(--tracking-eyebrow);
}

.u-accent {
  font: var(--text-accent-m);
}

.u-accent-l {
  font: var(--text-accent-l);
}

/* Rozmazaný náhled fotky (LQIP z helperu lqip()) leží jako pozadí přímo pod
   <img>. Než fotka dorazí, drží místo barevný otisk; jakmile se načte,
   překryje ho — nic se nemusí přepínat JS-em. */
.u-lqip {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.u-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Fokusovatelná varianta — skip-link je skrytý, dokud na něj uživatel
   netabuje; pak vyskočí nad obsah jako razítkový štítek. Na neinteraktivních
   prvcích (popisky pro čtečky) se nikdy neuplatní, protože nejdou zaostřit. */
.u-visually-hidden:focus,
.u-visually-hidden:focus-visible {
  position: fixed;
  inset-block-start: var(--space-xs);
  inset-inline-start: var(--space-xs);
  width: auto;
  height: auto;
  margin: 0;
  padding: var(--space-2xs) var(--space-s);
  overflow: visible;
  clip-path: none;
  z-index: 200;
  background: var(--surface-inverse);
  color: var(--text-inverse);
  font: var(--text-label);
  letter-spacing: var(--tracking-wide);
  text-decoration: none;
  border: var(--border-w) solid var(--border-default);
  border-radius: var(--radius-m);
  box-shadow: var(--focus-ring-halo);
}



/* Every Layout primitives */
/* assets/css/layouts/stack.css */
/* Every Layout: The Stack — vertical rhythm via owl selector */

.l-stack {
  --gap: var(--space-m);
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
}

.l-stack > * {
  margin-block: 0;
}

.l-stack > * + * {
  margin-block-start: var(--gap);
}

.l-stack--xl {
  --gap: var(--space-xl-2xl);
}


/* assets/css/layouts/cluster.css */
/* Every Layout: The Cluster — wrapping row of items */

.l-cluster {
  --gap: var(--space-s);
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap);
  align-items: center;
}


/* assets/css/layouts/center.css */
/* Every Layout: The Center — horizontally centered column with gutters */

.l-center {
  --measure-max: var(--content-max);
  box-sizing: content-box;
  max-inline-size: var(--measure-max);
  margin-inline: auto;
  padding-inline: var(--space-m);
}


/* assets/css/layouts/sidebar.css */
/* Every Layout: The Sidebar — sidebar + fluid main, wraps when too narrow */

.l-sidebar {
  --gap: var(--space-l);
  --side-width: 18rem;
  --content-min: 55%;
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap);
}

.l-sidebar > :first-child {
  flex-basis: var(--side-width);
  flex-grow: 1;
}

.l-sidebar > :last-child {
  flex-basis: 0;
  flex-grow: 999;
  min-inline-size: var(--content-min);
}

/* sidebar on the right instead */
.l-sidebar--right > :first-child {
  flex-basis: 0;
  flex-grow: 999;
  min-inline-size: var(--content-min);
}

.l-sidebar--right > :last-child {
  flex-basis: var(--side-width);
  flex-grow: 1;
  min-inline-size: unset;
}


/* assets/css/layouts/switcher.css */
/* Every Layout: The Switcher — row that switches to a column below a threshold */

.l-switcher {
  --gap: var(--space-m);
  --threshold: 40rem;
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap);
}

.l-switcher > * {
  flex-grow: 1;
  flex-basis: calc((var(--threshold) - 100%) * 999);
}


/* assets/css/layouts/grid.css */
/* Every Layout: The Grid — responsive grid without media queries */

.l-grid {
  --gap: var(--space-m);
  --min-item: 16rem;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(var(--min-item), 100%), 1fr));
  gap: var(--gap);
}

.l-grid--s {
  --min-item: 11rem;
}


/* assets/css/layouts/box.css */
/* Every Layout: The Box — padded, bordered container (brand: ink keyline) */

.l-box {
  --pad: var(--space-m);
  padding: var(--pad);
  border: var(--border-w) solid var(--border-default);
}

.l-box--inverse {
  background: var(--surface-inverse);
  color: var(--text-inverse);
}


/* assets/css/layouts/reel.css */
/* Every Layout: The Reel — horizontal scroll strip */

.l-reel {
  --gap: var(--space-m);
  --item-width: auto;
  display: flex;
  gap: var(--gap);
  block-size: auto;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-color: var(--ink) var(--cream);
}

.l-reel > * {
  flex: 0 0 var(--item-width);
}

.l-reel::-webkit-scrollbar {
  block-size: 0.75rem;
}

.l-reel::-webkit-scrollbar-track {
  background-color: var(--cream);
}

.l-reel::-webkit-scrollbar-thumb {
  background-color: var(--ink);
  border-radius: var(--radius-pill);
}



/* components */
/* assets/css/components/header.css */
/* Site header — white bar with ink rule, wordmark left, lowercase nav + CTA right.
   Mobile-first: nav collapses behind a stamp-style hamburger below 48rem. */

.c-header {
  border-block-end: var(--border-w) solid var(--border-default);
}

/* homepage: the bar sits on the blue hero and blends into it */
.c-header--home {
  background: var(--blue);
  border-block-end-color: transparent;
}

.c-header__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-m);
  /* jen vodorovně: mobilní navigace je v toku i zavřená (viz níže) a svislý
     row-gap by pod značkou držel prázdný pruh vysoký --space-m */
  row-gap: 0;
  padding-block: var(--space-m);
}

.c-header__brand {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  font: var(--text-display-s);
  text-decoration: none;
}

/* Značková hvězda z hera vedle názvu, se stejně pomalou otáčkou jako
   sluneční hroty v heru — lišta tak nese kousek jeho pohybu. Maskou je
   star-header.svg: stejný chaotický sluneční výbuch jako star.svg,
   jen s 24 hroty místo 80 — jemnější kresba originálu se v malé
   velikosti slévala. */
.c-header__star {
  flex-shrink: 0;
  inline-size: 2.3em;
  block-size: 2.3em;
  background: var(--orange);
  -webkit-mask: url("/assets/img/star-header.svg?v=1785106422") center / contain no-repeat;
  mask: url("/assets/img/star-header.svg?v=1785106422") center / contain no-repeat;
  animation: header-star-spin 24s linear infinite;
}

@keyframes header-star-spin {
  to {
    rotate: 1turn;
  }
}

/* Zavřené menu dřív skákalo přes display: none → flex a obsah pod ním
   poskočil naráz. Teď je navigace v toku pořád: grid s jediným řádkem,
   jehož výška jede 0fr → 1fr, takže menu obsah stránky plynule odsune.
   Výška se tím animuje nativně, bez měření v JS.

   Svislý odstup od horní lišty nedělá row-gap (viz .c-header__inner), ale
   marginy dětí uvnitř .c-header__nav-inner — ty se oříznou a najíždí
   s obsahem.

   ui.js přepíná .is-open; sbaleno = mobilní výchozí stav */
.c-header__nav {
  display: grid;
  grid-template-rows: 0fr;
  flex-basis: 100%;
  visibility: hidden;
  transition:
    grid-template-rows var(--duration-base) var(--ease-in),
    visibility 0s linear var(--duration-base);
}

.c-header__nav.is-open {
  grid-template-rows: 1fr;
  visibility: visible;
  transition:
    grid-template-rows var(--duration-slow) var(--ease-out),
    visibility 0s;
}

/* min-block-size: 0 pouští buňku pod min-content (jinak by 0fr nebyla nula),
   overflow: hidden ořezává obsah po dobu najíždění. Obsah k tomu prolíná
   a dojíždí zpod lišty — stejný rukopis jako dřív, odchod je kratší,
   zavírání nemá zdržovat. */
.c-header__nav-inner {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-s);
  min-block-size: 0;
  overflow: hidden;
  opacity: 0;
  translate: 0 -8px;
  transition:
    opacity var(--duration-fast) var(--ease-in),
    translate var(--duration-fast) var(--ease-in);
}

.c-header__nav.is-open .c-header__nav-inner {
  opacity: 1;
  translate: 0 0;
  transition:
    opacity var(--duration-base) var(--ease-out),
    translate var(--duration-base) var(--ease-out);
}

/* Svislé odstupy rozbaleného menu dělají marginy dětí, ne padding obalu:
   padding je součást boxu grid položky, takže by ho řádek 0fr nestlačil
   (min-block-size pouští pod minimum jen obsah) a sbalená navigace by
   v liště nechávala prázdný pruh vysoký ~34 px. */
.c-header__nav-inner > :first-child {
  margin-block-start: var(--space-m);
}

.c-header__nav-inner > :last-child {
  margin-block-end: var(--space-s);
}

.c-header__menu {
  display: flex;
  flex-direction: column;
  list-style: none;
  margin: 0;
  padding: 0;
  font: var(--text-body-l);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
}

.c-header__menu a {
  display: block;
  padding-block: var(--space-s);
  border-block-end: var(--border-w) solid var(--border-subtle);
  text-decoration: none;
}

.c-header__menu a:hover {
  text-decoration: underline;
}

.c-header__menu a[aria-current="page"] {
  text-decoration: underline;
  text-decoration-thickness: var(--border-w);
  text-decoration-color: var(--brand-primary);
}

/* Stisk odkazu se dotvrdí posunem, stejně jako u tlačítek — jen menším,
   protože pod odkazem není razítkový stín, který by měl kam zapadnout. */
.c-header__menu a:active,
.c-header__brand:active {
  translate: 1px 1px;
}

.c-header__nav .c-button {
  align-self: flex-start;
  /* match the nav links' size so the CTA reads as part of the menu */
  font-size: var(--size-body-l);
  animation: header-cta-breathe 5s ease-in-out infinite;
}

/* Jemné, stálé „nadechnutí" CTA: jednou za cyklus se tlačítko krátce
   nadzvedne o kousek razítkového zdvihu (stín povyroste z -s na -m,
   pravý dolní roh stínu zůstává na místě) a zase dosedne. Většinu cyklu
   je v klidu, aby pohyb ke koupi lákal, ale nerušil od čtení. */
@keyframes header-cta-breathe {
  0%,
  82%,
  100% {
    transform: none;
    box-shadow: var(--shadow-stamp-s);
  }
  88% {
    transform: translate(-2px, -2px);
    box-shadow: var(--shadow-stamp-m);
  }
  94% {
    transform: none;
    box-shadow: var(--shadow-stamp-s);
  }
}

/* Jakmile uživatel s tlačítkem pracuje, smyčka končí — běžící animace by
   svým transform/box-shadow přebila hover, press i focus ring z button.css. */
.c-header__nav .c-button:hover,
.c-header__nav .c-button:focus-visible,
.c-header__nav .c-button:active {
  animation: none;
}

@media (prefers-reduced-motion: reduce) {
  .c-header__nav .c-button,
  .c-header__star {
    animation: none;
  }
}

/* hamburger reuses .c-icon-button in markup; here only the icon swap.
   Obě ikony leží na sobě v jedné buňce gridu (rozměry drží icon-button.css)
   a prolínají se s půlotáčkou místo tvrdého přepnutí display. */
.c-header__toggle .c-icon-button__icon {
  display: grid;
}

.c-header__toggle .c-icon-button__icon > svg {
  grid-area: 1 / 1;
  transition:
    opacity var(--duration-fast) linear,
    rotate var(--duration-base) var(--ease-snap);
}

.c-header__toggle .c-header__icon-close {
  opacity: 0;
  rotate: -90deg;
}

.c-header__toggle[aria-expanded="true"] .c-header__icon-menu {
  opacity: 0;
  rotate: 90deg;
}

.c-header__toggle[aria-expanded="true"] .c-header__icon-close {
  opacity: 1;
  rotate: 0deg;
}

@media (min-width: 48rem) {
  /* beats .c-icon-button's display:inline-flex, which is imported later */
  .c-header .c-header__toggle {
    display: none;
  }

  .c-header__nav,
  .c-header__nav.is-open {
    display: flex;
    flex-basis: auto;
    flex-direction: row;
    align-items: center;
    gap: var(--space-m);
    visibility: visible;
    /* mobilní přechod visibility má zpoždění — při překlopení přes breakpoint
       (otočení displeje) by navigaci na ten okamžik podrželo schovanou */
    transition: none;
  }

  /* obal je jen kvůli mobilní animaci výšky; tady se z layoutu ztratí
     a řádkem menu je zase samotný <nav> (opacity/translate bez boxu neplatí) */
  .c-header__nav-inner {
    display: contents;
  }

  /* mobilní svislé odstupy menu — v řádku lišty nemají co dělat */
  .c-header__nav-inner > :first-child,
  .c-header__nav-inner > :last-child {
    margin-block: 0;
  }

  .c-header__menu {
    flex-direction: row;
    align-items: center;
    gap: var(--space-m);
  }

  .c-header__menu a {
    padding-block: 0;
    border-block-end: 0;
    position: relative;
  }

  /* Podtržení jako tah štětcem. text-decoration se animovat nedá, proto
     vlastní inkoustový pruh: vyjede zleva a při odchodu se stáhne doprava,
     tedy tam, kam odešel kurzor. Jen nad 48rem — na mobilu sedí pod odkazem
     dělicí linka, se kterou by se pruh sečetl na dvojitou.

     Aktivní stránka je převedená na stejný pruh, ať se dvě podtržení nebijí;
     význam pořád nese aria-current, pruh je dekorace. */
  .c-header__menu a:hover,
  .c-header__menu a[aria-current="page"] {
    text-decoration: none;
  }

  .c-header__menu a::after {
    content: "";
    position: absolute;
    inset-inline: 0;
    inset-block-end: -2px;
    block-size: var(--border-w);
    background: currentColor;
    scale: 0 1;
    transform-origin: right; /* uplatní se při zmenšování = odchod */
    transition: scale var(--duration-fast) var(--ease-out);
  }

  .c-header__menu a:hover::after,
  .c-header__menu a:focus-visible::after {
    scale: 1 1;
    transform-origin: left; /* uplatní se při zvětšování = příchod */
  }

  .c-header__menu a[aria-current="page"]::after {
    scale: 1 1;
    background: var(--brand-primary);
  }
}

/* Najetím na menu ostatní položky ustoupí do pozadí — oko jde tam, kam míří
   kurzor. Jen myš a jen na širokém displeji; dotyk hover nemá. */
@media (hover: hover) and (pointer: fine) and (min-width: 48rem) {
  .c-header__menu a {
    transition: opacity var(--duration-fast) var(--ease-out);
  }

  .c-header__menu:has(a:hover) a:not(:hover) {
    opacity: 0.5;
  }
}


/* assets/css/components/footer.css */
/* Footer — the site's closing poster on brand blue (bookending the blue
   hero): a marquee strip runs along the top, the hero logo returns with
   its slowly spinning sunburst, subpages get big display-type links in
   columns, and the ticket CTA closes the show. */

.c-footer {
  background: var(--blue);
  color: var(--text-primary);
}

/* Časté dotazy — accordion úplně nahoře v patičce, nad pruhem interpretů.
   Karty accordionu jsou bílé na modré ploše a barvu textu si nesou samy,
   takže tu zbývá jen odsazení a rozumná šířka řádku. Oddělovací linku dělá
   horní rámeček pruhu pod tím — vlastní by se s ním sečetla na dvojitou. */
.c-footer__faq {
  padding-block: var(--space-xl);
}

/* Poznámka pod accordionem si nechává rozumnou míru řádku, samotný
   accordion teď jede na celou šířku sloupce. */
.c-footer__faq-note {
  max-inline-size: 62ch;
}

.c-footer__faq-title {
  font: var(--text-display-s);
}

.c-footer__faq-note {
  font: var(--text-body-s);
}

.c-footer__faq .c-accordion {
  inline-size: 100%;
}

.c-footer__faq .c-accordion__title {
  font: var(--text-accent-m);
}

.c-footer__faq .c-accordion__content {
  font: var(--text-body-l);
}

/* ticker between the page and the footer body */
.c-footer__marquee {
  overflow: hidden;
  white-space: nowrap;
  padding-block: var(--space-s);
  border-block: var(--border-w) solid var(--border-default);
}

/* Bez JS jede pruh čistě na CSS animaci. Jakmile ho převezme motion.js
   (motion.js přidá .is-interactive), animaci vypneme — posun i tažení
   prstem řídí JS, jinak by se oba praly o transform. */
.c-footer__marquee.is-interactive {
  touch-action: pan-y; /* svislý scroll stránky zůstává prstu k dispozici */
  user-select: none;
  -webkit-user-select: none;
  cursor: grab;
}

.c-footer__marquee.is-interactive .c-footer__marquee-photo {
  -webkit-user-drag: none;
}

.c-footer__marquee.is-dragging {
  cursor: grabbing;
}

.c-footer__marquee-track {
  display: inline-block;
}

/* Animace posouvá pás o polovinu jeho šířky, takže dává smysl teprve tehdy,
   když jsou v něm dvě identické poloviny. PHP renderuje jednu (viz footer.php)
   a druhou klonuje JS — do té doby drží třída is-single pás v klidu.
   :not(.is-interactive) tu musí být explicitně: pravidlo níž má nižší
   specificitu, takže by ho tenhle selektor jinak přebil a pás by se hýbal
   dvakrát — CSS animací i transformem z motion.js. */
.c-footer__marquee:not(.is-single):not(.is-interactive) .c-footer__marquee-track {
  animation: footer-marquee 40s linear infinite;
}

.is-interactive .c-footer__marquee-track {
  animation: none;
  will-change: transform;
}

.c-footer__marquee-run {
  display: inline-flex;
  align-items: center;
  font: var(--text-label);
}

/* jeden interpret v pruhu — klikatelný odkaz: malá čtvercová fotka + jméno */
.c-footer__marquee-act {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding-inline: var(--space-m);
  text-decoration: none;
  color: var(--text-primary);
}

.c-footer__marquee-act:hover .c-footer__marquee-name {
  text-decoration: underline;
  text-decoration-thickness: var(--border-w-thick);
}

.c-footer__marquee-photo {
  inline-size: 64px;
  block-size: 64px;
  object-fit: cover;
  border-radius: var(--radius-pill);
  flex-shrink: 0;
}

.c-footer__marquee-name {
  white-space: nowrap;
}

@keyframes footer-marquee {
  to {
    transform: translateX(-50%);
  }
}

.c-footer__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xl);
  padding-block: var(--space-2xl);
}

.c-footer__logo {
  flex: 1 1 14rem;
  max-inline-size: 18rem;
}

.c-footer__logo-svg {
  display: block;
  aspect-ratio: 2407 / 2313;
}

/* same slow-record spin as the hero's sunburst */
.c-footer__spikes {
  transform-box: fill-box;
  transform-origin: center;
  animation: footer-spin 150s linear infinite;
}

@keyframes footer-spin {
  to {
    transform: rotate(1turn);
  }
}

.c-footer__main {
  flex: 999 1 24rem;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-xl);
}

.c-footer__main nav {
  align-self: stretch; /* let the menu grid use the full column width */
}

/* subpages as a wrapping cluster of big links */
.c-footer__menu {
  --gap: var(--space-xs) var(--space-l);
  margin: 0;
}

.c-footer__menu a {
  font: var(--text-display-m);
  text-decoration: none;
  color: var(--text-primary);
}

.c-footer__menu a:hover {
  text-decoration: underline;
  text-decoration-thickness: var(--border-w-thick);
}

.c-footer__meta {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-m);
  padding-block: var(--space-m);
  border-block-start: var(--border-w) solid var(--border-subtle);
  font: var(--text-body-s);
}

@media (prefers-reduced-motion: reduce) {
  .c-footer__marquee-track,
  .c-footer__spikes {
    animation: none;
  }
}


/* assets/css/components/hero.css */
/* Hero — full-viewport poster: the logo is the headline.
   Sits on brand blue; below it a fringe strip of wide blue drops (the
   bottom half of the spikes.svg shape, generated and animated by JS)
   hangs over the next section's green as an organic transition.
   The orange sunburst group inside the inline SVG rotates slowly (ambient),
   the lettering mark stays put. On load the whole logo "stamps" onto the
   paper, then eyebrow / tagline / actions rise in with a stagger. */

.c-hero {
  display: grid;
  /* short of the full viewport so the fringe transition below stays
     visible above the fold (header ~5rem + fringe up to 6rem) */
  min-block-size: calc(85svh - 5rem);
  background: var(--blue);
  overflow: hidden; /* rotating spikes may not force a scrollbar */
}

/* transition strip: blue drops hanging from the hero over the green of
   the section below; JS generates and gently animates them */
.c-hero__fringe {
  background: var(--green);
  block-size: clamp(3rem, 8svh, 6rem);
}

.c-hero__fringe-svg {
  display: block;
  inline-size: 100%;
  block-size: 100%;
}

.c-hero__fringe path {
  fill: var(--blue);
  transform-box: fill-box;
  transform-origin: top;
  transform: scaleY(0.875); /* rest length; JS pulses around this value */
}

.c-hero__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-m-l);
  padding-block: var(--space-l);
  text-align: center;
  min-width: 30%; /* for the tagline's max-inline-size to work in Firefox */
}

/* real heading for the document outline; the visible "title" is the logo */
.c-hero__title {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.c-hero__eyebrow {
  font: var(--text-eyebrow);
  letter-spacing: var(--tracking-eyebrow);
  animation: hero-rise 500ms var(--ease-snap) 350ms backwards;
}

.c-hero__logo {
  inline-size: min(100%, 72svh, 46rem);
  animation: hero-stamp 450ms var(--ease-snap) backwards;
}

.c-hero__logo-svg {
  display: block;
  aspect-ratio: 2407 / 2313;
}

/* the signature: sunburst spikes turn like a slow record */
.c-hero__spikes {
  transform-box: fill-box;
  transform-origin: center;
  animation: hero-spin 24s linear infinite;
}

.c-hero__tagline {
  font: var(--text-accent-l);
  color: var(--text-primary); /* soft gray lacks contrast on the neon green */
  max-inline-size: 28ch;
  animation: hero-rise 500ms var(--ease-snap) 450ms backwards;
}

.c-hero__actions {
  justify-content: center;
  animation: hero-rise 500ms var(--ease-snap) 550ms backwards;
}

@keyframes hero-spin {
  to {
    transform: rotate(1turn);
  }
}

@keyframes hero-stamp {
  from {
    opacity: 0;
    transform: scale(1.12);
  }
}

@keyframes hero-rise {
  from {
    opacity: 0;
    transform: translateY(0.75rem);
  }
}

@media (prefers-reduced-motion: reduce) {
  .c-hero__spikes,
  .c-hero__logo,
  .c-hero__eyebrow,
  .c-hero__tagline,
  .c-hero__actions {
    animation: none;
  }
}


/* assets/css/components/intro.css */
/* Intro — festival history block that continues the hero's green field
   seamlessly. Left-aligned editorial voice as a counterpoint to the
   centred hero poster, an archival photo pinned to the right; the
   "0 vynechaných ročníků" stamp is the punchline of the fact row. */

.c-intro {
  background: var(--green);
  color: var(--text-primary);
}

.c-intro__inner {
  display: grid;
  gap: var(--space-l-xl);
  padding-block: var(--space-xl-2xl);
}

.c-intro__columns {
  --side-width: 20rem;
  align-items: start;
}

.c-intro__eyebrow {
  font: var(--text-eyebrow);
  letter-spacing: var(--tracking-eyebrow);
}

.c-intro__heading {
  font: var(--text-display-m);
  max-inline-size: 22ch;
}

.c-intro__lead {
  font: var(--text-accent-l);
  max-inline-size: 34ch;
}

.c-intro__text {
  font: var(--text-body-l);
  max-inline-size: var(--measure);
}

/* archival print: ink frame and the brand's hard stamp shadow */
.c-intro__figure {
  margin: 0;
}

.c-intro__figure img {
  display: block;
  inline-size: 100%;
  /* atribut height jinak drží výšku thumbnailu i po zúžení na šířku
     sloupce a fotka se svisle roztáhne */
  block-size: auto;
  border: var(--border-w) solid var(--border-default);
  box-shadow: var(--shadow-stamp-m);
}

.c-intro__caption {
  font: var(--text-accent-m);
  padding-block-start: var(--space-s);
}

/* Osa festivalu místo tří hranatých karet: letopočty jako zarážky na
   koncích, mezi nimi perforovaná čára (stejné tečkování jako útržek
   permanentky) a uprostřed kulaté oranžové razítko se součtem
   vystoupení — jediný ne-hranatý tvar značky vedle hvězdy. */
.c-intro__era {
  display: flex;
  align-items: center;
  gap: var(--space-m-l);
}

.c-intro__era-point {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.c-intro__era-point--latest {
  text-align: end;
}

.c-intro__era-year {
  font: var(--text-display-l);
  line-height: 0.9;
}

.c-intro__era-caption {
  font: var(--text-label);
  letter-spacing: var(--tracking-wide);
}

.c-intro__era-line {
  flex: 1;
  border-block-start: var(--border-w-thick) dashed var(--border-default);
}

/* razítko + odkaz na historii pod ním */
.c-intro__era-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-s);
  flex-shrink: 0;
}

.c-intro__era-link {
  font: var(--text-body-s);
  font-weight: 600;
  color: var(--text-primary);
}

/* kulaté razítko: tvrdý stín bez rozostření drží rukopis značky */
.c-intro__era-badge {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-3xs);
  flex-shrink: 0;
  inline-size: 9.5rem;
  aspect-ratio: 1;
  border-radius: var(--radius-pill);
  background: var(--orange);
  border: var(--border-w-thick) solid var(--border-default);
  box-shadow: var(--shadow-stamp-m);
  rotate: -4deg;
  text-align: center;
}

.c-intro__era-count {
  font: var(--text-display-m);
}

/* úzké displeje: osa se postaví na výšku, perforace svisle */
@media (max-width: 40em) {
  .c-intro__era {
    flex-direction: column;
    gap: var(--space-s);
  }

  .c-intro__era-point,
  .c-intro__era-point--latest {
    align-items: center;
    text-align: center;
  }

  .c-intro__era-line {
    flex: none;
    block-size: 2.75rem;
    border-block-start: 0;
    border-inline-start: var(--border-w-thick) dashed var(--border-default);
  }
}

.c-intro__names {
  font: var(--text-accent-m);
  max-inline-size: var(--measure);
}


/* assets/css/components/collage.css */
/* Collage — full-bleed night-stage band: polaroid prints scattered and
   tilted, with colored stamp shadows instead of the default ink ones
   (they'd vanish on the ink background). Deliberately uncontained —
   the prints run to the viewport edges. */

.c-collage {
  position: relative;
  overflow: hidden;
  background: var(--surface-inverse);
  color: var(--text-inverse);
  padding-block: var(--space-3xl);
}

/* heading for the document outline only; the prints speak for themselves */
.c-collage__title {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.c-collage__grid {
  position: relative;
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  align-items: center;
  gap: var(--space-m);
  list-style: none;
  margin: 0;
  /* roomy sides — the tilted prints lean past their grid tracks and
     would otherwise poke off-screen; the overhang grows with the
     viewport, so the padding does too */
  padding-inline: clamp(2rem, 3rem + 4vw, 8rem);
}

.c-collage__item {
  margin: 0;
}

/* polaroid print: cream card, photo, handwritten-style caption */
.c-collage__polaroid {
  margin: 0;
  padding: var(--space-2xs);
  background: var(--cream);
  color: var(--text-primary);
}

.c-collage__polaroid img {
  display: block;
  inline-size: 100%;
  /* atribut height jinak přebije aspect-ratio položek (ratio se uplatní
     jen při výšce auto) a tisky se svisle roztáhnou */
  block-size: auto;
  object-fit: cover;
}

.c-collage__caption {
  font: var(--text-accent-m);
  font-size: var(--size-body-s);
  padding: var(--space-xs) var(--space-2xs) var(--space-2xs);
}

/* scatter: each print gets its own spot, tilt, and shadow color */
.c-collage__item--1 {
  grid-column: 1 / 4;
  transform: rotate(-4deg);
}
.c-collage__item--1 .c-collage__polaroid {
  box-shadow: 8px 8px 0 var(--orange);
}
.c-collage__item--1 img { aspect-ratio: 3 / 4; }

.c-collage__item--2 {
  grid-column: 4 / 7;
  transform: rotate(2.5deg) translateY(2.5rem);
}
.c-collage__item--2 .c-collage__polaroid {
  box-shadow: 8px 8px 0 var(--blue);
}
.c-collage__item--2 img { aspect-ratio: 4 / 5; }

.c-collage__item--3 {
  grid-column: 7 / 10;
  transform: rotate(-2deg) translateY(-1.5rem);
}
.c-collage__item--3 .c-collage__polaroid {
  box-shadow: 8px 8px 0 var(--yellow);
}
.c-collage__item--3 img { aspect-ratio: 3 / 4; }

.c-collage__item--4 {
  grid-column: 10 / 13;
  transform: rotate(3.5deg) translateY(1rem);
}
.c-collage__item--4 .c-collage__polaroid {
  box-shadow: 8px 8px 0 var(--green);
}
.c-collage__item--4 img { aspect-ratio: 4 / 5; }

.c-collage__item--5 {
  grid-column: 2 / 7;
  transform: rotate(1.5deg) translateY(1.5rem);
}
.c-collage__item--5 .c-collage__polaroid {
  box-shadow: 8px 8px 0 var(--yellow);
}
.c-collage__item--5 img { aspect-ratio: 16 / 10; }

.c-collage__item--6 {
  grid-column: 7 / 12;
  transform: rotate(-3deg) translateY(3rem);
}
.c-collage__item--6 .c-collage__polaroid {
  box-shadow: 8px 8px 0 var(--orange);
}
.c-collage__item--6 img { aspect-ratio: 16 / 10; }

.c-collage__more {
  display: flex;
  justify-content: center;
  padding-block-start: var(--space-4xl);
}

/* mobile: a tighter two-column scrapbook, smaller tilts */
@media (max-width: 47.9375rem) {
  .c-collage__grid {
    grid-template-columns: repeat(2, 1fr);
    padding-inline: var(--space-l);
  }

  .c-collage__item,
  .c-collage__item--1,
  .c-collage__item--2,
  .c-collage__item--3,
  .c-collage__item--4 {
    grid-column: auto / span 1;
    transform: rotate(-1.5deg);
  }

  .c-collage__item--2,
  .c-collage__item--4 {
    transform: rotate(1.5deg) translateY(1rem);
  }

  .c-collage__item--5,
  .c-collage__item--6 {
    grid-column: auto / span 2;
    transform: rotate(-1deg);
  }
}

/* ---- Hover: „zvednout tisk ze stolu" ----
   Koláž se dřív skládala animací spuštěnou scrollem — polaroidy přiletěly
   a „vyvolaly se" z přepalu do barvy. Teď leží na stole hotové a reagují
   až na kurzor: náklon se narovná a tisk se nadzvedne, jako by ho člověk
   vzal do ruky. Stín zůstává — každý tisk ho má ve vlastní barvě a měnit
   ho tady by znamenalo opakovat všech šest hodnot.

   Náklon drží .c-collage__item--N (rotate), takže transform přepisujeme
   na položce, ne na polaroidu — jinak by se obojí pralo. */
.c-collage__item {
  transition: transform var(--duration-slow) var(--ease-snap);
}

@media (hover: hover) and (pointer: fine) {
  .c-collage__item:hover {
    transform: rotate(0deg) translateY(calc(-1 * var(--lift-l)));
    z-index: 3; /* zvednutý tisk patří nad sousedy */
  }
}

@media (prefers-reduced-motion: reduce) {
  .c-collage__item {
    transition: none;
  }
  .c-collage__item:hover {
    transform: none;
  }
}


/* assets/css/components/pass.css */
/* Pass — season-ticket push under the intro. An orange stamp band carrying
   one oversized festival ticket: cream body with perks + price on the left,
   a perforated ink stub with the display word on the right. The notches at
   the seam are filled with the band colour so the stub looks torn off; the
   green CTA on orange is the logo's core pairing. */

.c-pass {
  --pass-band: var(--orange);
  --pass-notch: 1.25rem; /* diameter of the punched perforation holes */

  background: var(--pass-band);
  color: var(--text-primary);
}

.c-pass__inner {
  padding-block: var(--space-3xl);
}

/* the ticket: one hard-stamped card, tilted a hair off true like a print.
   Kept narrow and centred so the orange band breathes around it. */
.c-pass__ticket {
  display: grid;
  grid-template-columns: 1fr minmax(7rem, 11rem);
  margin-inline: auto;
  background: var(--cream);
  border: var(--border-w) solid var(--border-default);
  box-shadow: var(--shadow-stamp-m);
  transform: rotate(-0.75deg);
}

.c-pass__body {
  --gap: var(--space-l);
  padding: var(--space-xl);
}

.c-pass__eyebrow {
  font: var(--text-eyebrow);
  letter-spacing: var(--tracking-eyebrow);
  color: var(--brand-secondary-text); /* text na cream útržku — --orange-dark měl 3,34:1 */
}

.c-pass__heading {
  font: var(--text-display-m);
  max-inline-size: 18ch;
}

.c-pass__lead {
  font: var(--text-accent-m);
  max-inline-size: 42ch;
}

/* perks: two-up checklist, each ticked with an orange stamp diamond */
.c-pass__perks {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: var(--space-s) var(--space-l);
  padding: 0;
  list-style: none;
}

.c-pass__perk {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: var(--space-xs);
  font: var(--text-body-m);
}

.c-pass__perk::before {
  content: "";
  inline-size: 0.85em;
  block-size: 0.85em;
  margin-block-start: 0.35em;
  background: var(--orange);
  border: var(--border-w) solid var(--ink);
  transform: rotate(45deg);
}

.c-pass__cta {
  align-items: center;
  gap: var(--space-m);
  padding-block-start: var(--space-2xs);
}

.c-pass__cta .c-button {
  font-size: var(--size-body-l);
}

.c-pass__price {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
  margin: 0;
}

.c-pass__price-value {
  font: var(--text-display-m);
}

.c-pass__price-note {
  font: var(--text-body-s);
  color: var(--text-secondary);
  max-inline-size: 26ch;
}

/* stub: the tear-off. Ink field, dashed seam, display word set vertically */
.c-pass__stub {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-s);
  padding: var(--space-m);
  background: var(--surface-inverse);
  color: var(--text-inverse);
  border-inline-start: var(--border-w-thick) dashed var(--cream);
}

/* punched holes riding the seam, filled with the band colour = "torn off" */
.c-pass__stub::before,
.c-pass__stub::after {
  content: "";
  position: absolute;
  inline-size: var(--pass-notch);
  block-size: var(--pass-notch);
  inset-inline-start: 0;
  background: var(--pass-band);
  border: var(--border-w) solid var(--ink);
  border-radius: var(--radius-pill);
  transform: translate(-50%, -50%);
}

.c-pass__stub::before { inset-block-start: 0; }
.c-pass__stub::after  { inset-block-start: 100%; }

.c-pass__stub-label {
  font: var(--text-display-s);
  line-height: 1;
  text-transform: lowercase;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
}

.c-pass__stub-sub {
  font: var(--text-display-s);
  letter-spacing: var(--tracking-wide);
  color: var(--accent-yellow);
}

/* mobile: stub drops under the body, seam turns horizontal, notches ride it */
@media (max-width: 47.9375rem) {
  .c-pass__ticket {
    grid-template-columns: 1fr;
    transform: rotate(-0.5deg);
  }

  .c-pass__stub {
    flex-direction: row;
    gap: var(--space-m);
    border-inline-start: 0;
    border-block-start: var(--border-w-thick) dashed var(--cream);
    padding-block: var(--space-l);
  }

  .c-pass__stub::before,
  .c-pass__stub::after {
    inset-block-start: 0;
    inset-inline-start: auto;
    transform: translate(-50%, -50%);
  }

  .c-pass__stub::before { inset-inline-start: 0; }
  .c-pass__stub::after  { inset-inline-start: 100%; }

  .c-pass__stub-label {
    writing-mode: horizontal-tb;
    transform: none;
  }

  /* stack price over a full-width buy button */
  .c-pass__cta {
    flex-direction: column;
    align-items: stretch;
  }

  .c-pass__cta .c-button {
    inline-size: 100%;
  }
}

/* the tilt is decorative; respect users who ask for no motion/flourish */
@media (prefers-reduced-motion: reduce) {
  .c-pass__ticket { transform: none; }
}

/* ---- Hover: permanentka ----
   Vstupenka se dřív skládala animací spuštěnou scrollem (přiletěla zdola,
   utržený díl a výhody po ní). Teď leží na stránce hotová a pod kurzorem se
   narovná a nadzvedne — razítkový stín povyroste, jako by se zvedla ze stolu. */
.c-pass__ticket {
  transition:
    transform var(--duration-slow) var(--ease-snap),
    box-shadow var(--duration-slow) var(--ease-snap);
}

@media (hover: hover) and (pointer: fine) {
  .c-pass__ticket:hover {
    transform: rotate(0deg) translateY(calc(-1 * var(--lift-m)));
    box-shadow: var(--shadow-stamp-l);
  }
}

@media (prefers-reduced-motion: reduce) {
  .c-pass__ticket {
    transition: none;
  }
  .c-pass__ticket:hover {
    transform: rotate(-0.75deg);
    box-shadow: var(--shadow-stamp-m);
  }
}


/* assets/css/components/button.css */
.c-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  padding: 12px 20px;
  font: var(--text-label);
  letter-spacing: var(--tracking-wide);
  text-decoration: none;
  border: var(--border-w) solid var(--border-default);
  border-radius: var(--radius-m);
  background: var(--brand-primary);
  color: var(--text-on-brand);
  box-shadow: var(--shadow-stamp-s);
  cursor: pointer;
  transition:
    transform var(--duration-fast) var(--ease-snap),
    box-shadow var(--duration-fast),
    background var(--duration-fast);
}

.c-button:hover {
  background: var(--brand-primary-hover);
}

/* press = "stamp": nudge by the shadow offset, shadow disappears */
.c-button:active {
  transform: translate(var(--press-offset), var(--press-offset));
  box-shadow: none;
}

/* razítkový stín + světlý prstenec focus ringu (jinak by ho vlastní
   box-shadow komponenty přebil — viz --focus-ring-halo) */
.c-button:focus-visible {
  box-shadow: var(--shadow-stamp-s), var(--focus-ring-halo);
}

/* darker orange + white text: the base orange fails AA under white text */
.c-button--secondary {
  background: var(--brand-secondary-hover);
  color: var(--text-inverse);
}

.c-button--secondary:hover {
  background: color-mix(in oklch, var(--brand-secondary-hover) 80%, var(--ink));
}

.c-button--ghost {
  background: var(--surface-card);
  color: var(--text-primary);
}

.c-button--ghost:hover {
  background: var(--cream);
}

.c-button--s {
  padding: 8px 14px;
}

.c-button--l {
  padding: 16px 28px;
  font: var(--text-display-s);
  letter-spacing: var(--tracking-wide);
}

.c-button:disabled,
.c-button--disabled {
  box-shadow: none;
  cursor: not-allowed;
  opacity: 0.45;
}

.c-button:disabled:active,
.c-button--disabled:active {
  transform: none;
}

.c-button:disabled:hover {
  background: var(--brand-primary);
}

.c-button--secondary:disabled:hover {
  background: var(--brand-secondary-hover);
}

.c-button--ghost:disabled:hover {
  background: var(--surface-card);
}


/* assets/css/components/icon-button.css */
.c-icon-button {
  --size: 40px;
  inline-size: var(--size);
  block-size: var(--size);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: var(--border-w) solid var(--border-default);
  border-radius: var(--radius-m);
  background: var(--surface-card);
  color: var(--text-primary);
  box-shadow: var(--shadow-stamp-s);
  cursor: pointer;
  transition:
    transform var(--duration-fast) var(--ease-snap),
    box-shadow var(--duration-fast),
    background var(--duration-fast);
}

.c-icon-button:hover {
  background: var(--cream);
}

.c-icon-button:active {
  transform: translate(var(--press-offset), var(--press-offset));
  box-shadow: none;
}

/* razítkový stín + světlý prstenec focus ringu (jinak by ho vlastní
   box-shadow komponenty přebil — viz --focus-ring-halo) */
.c-icon-button:focus-visible {
  box-shadow: var(--shadow-stamp-s), var(--focus-ring-halo);
}

.c-icon-button--primary {
  background: var(--brand-primary);
  color: var(--text-on-brand);
}

.c-icon-button--primary:hover {
  background: var(--brand-primary-hover);
}

.c-icon-button--s {
  --size: 32px;
}

.c-icon-button--l {
  --size: 52px;
}

.c-icon-button__icon {
  inline-size: 50%;
  block-size: 50%;
}

.c-icon-button__icon svg {
  inline-size: 100%;
  block-size: 100%;
}


/* assets/css/components/badge.css */
.c-badge {
  display: inline-flex;
  align-items: center;
  padding: 4px 12px;
  border: var(--border-w) solid var(--border-default);
  border-radius: var(--radius-pill);
  background: var(--brand-primary);
  color: var(--text-on-brand);
  font: var(--text-label);
}

.c-badge--secondary {
  background: var(--brand-secondary);
}

.c-badge--blue {
  background: var(--accent-blue);
}

.c-badge--yellow {
  background: var(--accent-yellow);
}

.c-badge--ink {
  background: var(--ink);
  color: var(--text-inverse);
}


/* assets/css/components/tag.css */
.c-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  border: var(--border-w) solid var(--border-default);
  border-radius: var(--radius-pill);
  background: var(--surface-card);
  color: var(--text-primary);
  font: var(--text-body-s);
  user-select: none;
}

/* interactive tag (filter chip) */
button.c-tag,
a.c-tag {
  cursor: pointer;
  text-decoration: none;
  transition: background var(--duration-fast);
}

button.c-tag:hover,
a.c-tag:hover {
  background: var(--cream);
}

.c-tag--selected {
  background: var(--ink);
  color: var(--text-inverse);
}

button.c-tag--selected:hover,
a.c-tag--selected:hover {
  background: var(--ink-soft);
}

/* Stejně jako u toastu: znak „×" má ~14 px, cílová plocha se dotahuje
   na 24×24 px (minimum WCAG 2.5.8). Záporné okraje drží tag v původní výšce. */
.c-tag__remove {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 24px;
  block-size: 24px;
  margin-block: -5px;
  margin-inline-end: -4px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-s);
  background: none;
  color: inherit;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
}


/* assets/css/components/card.css */
.c-card {
  background: var(--surface-card);
  border: var(--border-w) solid var(--border-default);
  border-radius: var(--radius-m);
  box-shadow: var(--shadow-stamp-m);
  padding: var(--space-l);
}

.c-card--pad-s {
  padding: var(--space-s);
}

.c-card--pad-m {
  padding: var(--space-m);
}


/* assets/css/components/partners.css */
/* Partners — same light page header as the rest of the site. Partner logos
   are dark PNGs on transparent background and sit freely on the page,
   without any chip, border or background. */

.c-partners {
  padding-block: var(--space-xl-2xl);
}

.c-partners__heading {
  font: var(--text-display-s);
}

/* set directly rather than via the inherited --gap custom property: this section
   is itself an .l-stack, so the generic .l-stack rule would reset --gap back to
   --space-m on this element before the group-to-group margin is resolved */
.c-partners__group {
  margin-block-start: var(--space-2xl);
}

.c-partners__grid {
  list-style: none;
  margin: 0;
  padding: 0;
}

.c-partners__item {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  transition: transform var(--duration-base) var(--ease-snap);
}

/* Logo se pod kurzorem přiblíží místo dřívějšího ztlumení na opacity 0.7 —
   u partnerů působilo zesvětlení spíš jako by odkaz nefungoval. */
@media (hover: hover) and (pointer: fine) {
  a.c-partners__item:hover {
    transform: scale(1.06);
  }
}

a.c-partners__item:focus-visible {
  transform: scale(1.06);
}

@media (prefers-reduced-motion: reduce) {
  .c-partners__item {
    transition: none;
  }
  a.c-partners__item:hover,
  a.c-partners__item:focus-visible {
    transform: none;
  }
}

.c-partners__item img {
  max-inline-size: 100%;
  max-block-size: 11rem;
  inline-size: auto;
}

.c-partners__patronage {
  font: var(--text-body-s);
  color: var(--text-secondary);
  max-inline-size: var(--measure);
}


/* assets/css/components/program.css */
/* Program — timeline lineup, same page header as the other content pages.
   Each event sets `--accent` (brand color) used for the timeline dot. */

.c-program {
  padding-block: var(--space-xl-2xl);
}

/* set directly rather than via the inherited --gap custom property: .c-program__body
   is itself an .l-stack, so the generic .l-stack rule would reset --gap back to
   --space-m on this element before the header-to-body margin is resolved */
.c-program__body {
  margin-block-start: var(--space-xl-2xl);
}

/* ---- timeline ---- */

.c-program__event {
  display: flex;
  gap: var(--space-l-xl);
  padding-block-end: var(--space-4xl);
}

/* fluid width keeps every event's spine aligned to the same x-position while
   giving the content column more room on narrower (tablet) viewports */
.c-program__date {
  inline-size: clamp(6.5rem, 9vw, 8rem);
  flex-shrink: 0;
  text-align: end;
}

.c-program__day {
  font: var(--text-display-l);
  line-height: 0.85;
  color: var(--text-primary);
}

.c-program__monthweek {
  margin-block-start: var(--space-xs);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: flex-end;
  gap: var(--space-2xs);
}

.c-program__month,
.c-program__weekday {
  font: var(--text-display-s);
  color: var(--text-primary);
}

/* dot separator between month and weekday — jen na mobilu, kde datum
   a název měsíce/dne stojí v jednom hutném řádku vedle sebe */
@media (max-width: 37.5em) {
  .c-program__weekday::before {
    content: "·";
    margin-inline-end: var(--space-2xs);
    color: var(--text-secondary);
  }
}

.c-program__spine {
  position: relative;
  flex: 1;
  min-inline-size: 0;
  padding-inline-start: var(--space-l-xl);
  border-inline-start: var(--border-w-thick) solid var(--border-default);
}

/* one dot on the timeline per performer (act), sitting on the vertical spine
   next to the act's name. Real element (ne ::before), aby ho JS mohl svisle
   zarovnat na jméno a na mobilu zmenšovat u sticky linky — viz motion.js.
   inset-block-start je jen hrubý fallback pro stav bez JS; přesnou polohu
   dopočítá JS vůči jménu. */
.c-program__dot {
  position: absolute;
  inset-inline-start: calc(-1 * var(--space-l-xl) - 11px);
  inset-block-start: var(--space-s);
  inline-size: 18px;
  block-size: 18px;
  border-radius: var(--radius-pill);
  border: var(--border-w-thick) solid var(--border-default);
  background: var(--accent, var(--orange));
  transform-origin: center;
}

.c-program__series {
  margin-block-end: var(--space-m);
  padding: 6px 16px;
  font: 600 var(--size-body-m)/1.2 var(--font-body);
}

.c-program__block {
  position: relative;
  display: flex;
  gap: var(--space-xl-2xl);
  padding-block-start: var(--space-m);
}

.c-program__block + .c-program__block {
  margin-block-start: var(--space-2xl);
}

/* first block sits right under the timeline dot — no divider needed */
.c-program__spine > .c-program__block:first-child {
  padding-block-start: 0;
  border-block-start: 0;
}

.c-program__block-main {
  flex: 1;
  min-inline-size: 0;
}

/* portrait in the same stamp frame as the interpreti grid; the event
   accent shows through as the placeholder background */
.c-program__block-media {
  position: relative;
  inline-size: 19rem;
  flex-shrink: 0;
  align-self: flex-start;
  margin-block-start: var(--space-2xs);
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--accent, var(--orange));
  border: var(--border-w-thick) solid var(--border-default);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-stamp-m);
}

.c-program__block-media img {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

/* photoless blocks get the brand star on the accent block */
.c-program__media-placeholder {
  position: absolute;
  inset: 18%;
  background: var(--ink);
  -webkit-mask: url("/assets/img/star.svg?v=1785106422") center / contain no-repeat;
  mask: url("/assets/img/star.svg?v=1785106422") center / contain no-repeat;
}

.c-program__act {
  position: relative; /* kotva pro tečku na časové ose vedle jména */
  padding-block: var(--space-xs);
}

.c-program__act-name {
  font: var(--text-display-m);
  text-transform: uppercase;
  color: var(--text-primary);
}

.c-program__act-name--link {
  display: inline-block;
  text-decoration: none;
}

.c-program__act-name--link:hover {
  text-decoration: underline;
}

/* Malá šipka na místě exponentu prozrazuje, že jméno vede na profil
   interpreta — jména bez odkazu ji nemají. Hranaté SVG (rovné tahy se
   čtvercovými konci jako ikony v hlavičce) místo textového „↗": glyf by
   se napříč systémy kreslil pokaždé jinak. Maska + currentColor, ať šipka
   přebírá barvu; prázdný content ji drží mimo čtečky a inline-block brání
   tomu, aby hover podtržení jména podtrhlo i šipku. */
.c-program__act-name--link::after {
  content: "";
  display: inline-block;
  inline-size: 0.45em;
  block-size: 0.45em;
  margin-inline-start: var(--space-3xs);
  /* horní hrana šipky lícuje s horní hranou verzálek (kapitálka Youth
     je ~0.73 em nad účařím), aby šipka nevyčnívala nad text */
  vertical-align: 0.28em;
  background: currentColor;
  -webkit-mask: url("/assets/img/arrow-ne.svg?v=1785106422") center / contain no-repeat;
  mask: url("/assets/img/arrow-ne.svg?v=1785106422") center / contain no-repeat;
  color: var(--text-secondary);
}

.c-program__act-name--link:hover::after {
  color: var(--text-primary);
}

.c-program__act-genre {
  margin-block-start: var(--space-3xs);
  font: var(--text-accent-m);
  color: var(--text-secondary);
}

/* ---- facts row (time / venue / price) ---- */

/* 2×2 grid: začátek + místo on top, vstupné + button below */
.c-program__facts {
  position: relative;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-l) var(--space-xl);
  margin-block-start: var(--space-l);
  padding-block-start: var(--space-m);
  border-block-start: var(--border-w-thick) solid var(--border-default);
}

/* extend the facts line left so it meets the vertical timeline */
.c-program__facts::before {
  content: "";
  position: absolute;
  inset-block-start: calc(-1 * var(--border-w-thick));
  inset-inline-start: calc(-1 * var(--space-l-xl));
  inline-size: var(--space-l-xl);
  block-size: var(--border-w-thick);
  background: var(--border-default);
}

.c-program__facts-action {
  align-self: end;
}

.c-program__fact-label {
  font: var(--text-eyebrow);
  letter-spacing: var(--tracking-eyebrow);
  color: var(--text-primary);
}

.c-program__fact-time,
.c-program__fact-value {
  margin-block-start: var(--space-3xs);
  font: var(--text-display-s);
  font-size: clamp(1.375rem, 1.2717rem + 0.4348vw, 1.625rem);
  color: var(--text-primary);
}

.c-program__note {
  margin-block-start: var(--space-m);
  font: var(--text-accent-m);
  color: var(--orange-text); /* text na cream — --orange-dark měl 3,34:1 */
}

/* ---- small screens: date sits above the spine ---- */

@media (max-width: 37.5em) {
  .c-program__event {
    flex-direction: column;
    gap: var(--space-xs);
  }

  .c-program__date {
    inline-size: auto;
    display: flex;
    align-items: baseline;
    gap: var(--space-xs);
    text-align: start;
  }

  .c-program__monthweek {
    margin-block-start: 0;
    justify-content: flex-start;
  }

  .c-program__block {
    flex-direction: column;
    gap: var(--space-s);
  }

  .c-program__block-media {
    order: -1;
    inline-size: min(100%, 18rem);
    margin-inline: auto;
  }

  .c-program__facts {
    grid-template-columns: 1fr;
  }

  .c-program__facts-action {
    align-self: start;
  }
}

/* odkaz na export do kalendáře pod úvodním textem */
.c-program__ical {
  font: var(--text-body-s);
}

.c-program__ical a {
  color: var(--text-secondary);
}

/* název večera nad koncerty toho dne */
.c-program__series-name {
  margin-block-end: var(--space-m);
  font: var(--text-eyebrow);
  letter-spacing: var(--tracking-eyebrow);
  color: var(--orange-text);
}

/* ---- Hover: odkaz na interpreta ----
   Tečka na ose povyroste jen při najetí na jméno interpreta (pokud vede na
   jeho profil) — ne při najetí na celý koncertní blok. */
.c-program__dot {
  transition: scale 200ms var(--ease-snap);
}

@media (hover: hover) and (pointer: fine) {
  .c-program__act:has(.c-program__act-name--link:hover) .c-program__dot {
    scale: 1.35;
  }
}

@media (prefers-reduced-motion: reduce) {
  .c-program__dot {
    transition: none;
  }
  .c-program__act:has(.c-program__act-name--link:hover) .c-program__dot {
    scale: 1;
  }
}


/* assets/css/components/interpret.css */
/* Interpret — detail page for one artist. Cream page with a stamp-framed
   portrait; sections stay on cream with white cards. The only color blocks
   are the ink bio and the green CTA strip. */

/* ---- breadcrumb ---- */

.c-interpret__crumbs {
  padding-block-start: var(--space-m);
  font: var(--text-body-s);
  color: var(--text-secondary);
}

.c-interpret__crumbs a {
  color: var(--text-secondary);
}

.c-interpret__crumbs span[aria-hidden] {
  margin-inline: var(--space-2xs);
}

.c-interpret__crumbs-current {
  color: var(--text-primary);
}

/* ---- hero ---- */

.c-interpret__hero {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-l-xl);
  padding-block: var(--space-l-xl) var(--space-xl-2xl);
}

.c-interpret__portrait {
  flex: 0 1 23.75rem; /* 380px */
  min-inline-size: 16rem;
}

.c-interpret__portrait img,
.c-interpret__portrait-placeholder {
  inline-size: 100%;
  block-size: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border: var(--border-w-thick) solid var(--border-default);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-stamp-l);
}

.c-interpret__portrait-placeholder {
  display: flex;
  align-items: flex-end;
  background: var(--surface-card);
}

.c-interpret__portrait-note {
  margin: var(--space-s);
  padding: 4px 10px;
  font: var(--text-label);
  background: var(--ink);
  color: var(--text-inverse);
  border-radius: var(--radius-pill);
}

.c-interpret__intro {
  flex: 1 1 26rem;
  min-inline-size: 0;
}

/* kdy a kde interpret hraje — dopočítáno z programu (viz interpretSlot) */
.c-interpret__eyebrow {
  margin-block-end: var(--space-2xs);
  font: var(--text-eyebrow);
  letter-spacing: var(--tracking-eyebrow);
  color: var(--ink-soft);
}

.c-interpret__title {
  font: var(--text-display-xl);
  letter-spacing: -0.01em;
}

.c-interpret__quote {
  margin-block-start: var(--space-s);
  max-inline-size: 30ch;
  font: var(--text-accent-l);
  color: var(--ink-soft);
}

.c-interpret__pills {
  margin-block-start: var(--space-m);
  list-style: none;
  padding: 0;
}

.c-interpret__pill {
  padding: 3px 11px;
  font: var(--text-body-s);
  background: var(--surface-card);
  border: var(--border-w) solid var(--border-default);
  border-radius: var(--radius-pill);
}

/* ---- shared section chrome ---- */

.c-interpret__section {
  padding-block: var(--space-xl-2xl);
  border-block-start: var(--border-w-thick) solid var(--border-default);
}

.c-interpret__section-eyebrow {
  margin-block-end: var(--space-xs);
  font: var(--text-eyebrow);
  letter-spacing: var(--tracking-eyebrow);
  color: var(--brand-secondary-text); /* text na cream — jasná oranžová má 2,40:1 */
}

.c-interpret__section-title {
  margin-block-end: var(--space-l);
  font: var(--text-display-m);
}

/* ---- bio (ink) ---- */

.c-interpret__section--bio {
  background: var(--surface-inverse);
  color: var(--cream);
}

.c-interpret__section--bio .c-interpret__section-eyebrow {
  color: var(--brand-primary);
}

.c-interpret__section--bio .c-interpret__section-title {
  color: var(--text-inverse);
}

.c-interpret__bio {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xl-2xl);
}

.c-interpret__bio-main {
  flex: 1 1 32.5rem;
  min-inline-size: min(100%, 18rem);
}

.c-interpret__bio-text {
  font: var(--text-body-l);
}

.c-interpret__bio-text > * + * {
  margin-block-start: var(--space-m);
}

.c-interpret__bio-text strong {
  color: var(--white);
}

.c-interpret__bio-quote {
  margin-block-start: var(--space-m);
  font: var(--text-accent-m);
  color: var(--cream);
  opacity: 0.85;
}

.c-interpret__lineup {
  flex: 0 1 18.75rem;
  min-inline-size: min(100%, 16rem);
}

.c-interpret__members {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  list-style: none;
  padding: 0;
}

.c-interpret__member {
  display: flex;
  justify-content: space-between;
  gap: var(--space-xs);
  padding: var(--space-xs) var(--space-s);
  background: color-mix(in oklch, var(--white) 8%, transparent);
  border: var(--border-w) solid color-mix(in oklch, var(--white) 22%, transparent);
  border-radius: var(--radius-m);
}

.c-interpret__member-name {
  font: var(--text-label);
  color: var(--text-inverse);
}

.c-interpret__member-role {
  font: var(--text-body-s);
  text-align: end;
  color: var(--cream);
}

/* ---- tracks ---- */

.c-interpret__tracks {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 18.75rem), 1fr));
  gap: var(--space-m);
}

.c-interpret__track {
  display: block;
  overflow: hidden;
  background: var(--surface-card);
  color: var(--text-primary);
  text-decoration: none;
  border: var(--border-w-thick) solid var(--border-default);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-stamp-m);
  transition: translate var(--duration-base) var(--ease-snap);
}

.c-interpret__track:hover {
  translate: -2px -2px;
}

/* stisk = otisk razítka, stejně jako u tlačítek */
.c-interpret__track:active {
  translate: var(--press-offset) var(--press-offset);
  box-shadow: none;
}

.c-interpret__track-media {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 16 / 9;
  background: var(--ink);
}

.c-interpret__track-media img {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

.c-interpret__track-play {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  inline-size: 64px;
  block-size: 64px;
  background: var(--white);
  border: var(--border-w-thick) solid var(--border-default);
  border-radius: var(--radius-pill);
}

.c-interpret__track-play::before {
  content: "";
  margin-inline-start: 5px;
  border-block: 13px solid transparent;
  border-inline-start: 20px solid var(--ink);
}

.c-interpret__track-duration {
  position: absolute;
  inset-block-end: var(--space-xs);
  inset-inline-end: var(--space-xs);
  padding: 2px 8px;
  font: var(--text-body-s);
  color: var(--white);
  background: color-mix(in oklch, var(--ink) 70%, transparent);
  border-radius: var(--radius-s);
}

.c-interpret__track-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xs);
  padding: var(--space-s) var(--space-s-m);
}

.c-interpret__track-title {
  font: var(--text-display-s);
}

.c-interpret__track-kind {
  font: var(--text-body-s);
  color: var(--text-secondary);
}

/* ---- gallery (cream) ---- */

.c-interpret__gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 13.75rem), 1fr));
  gap: var(--space-m);
}

.c-interpret__gallery img {
  inline-size: 100%;
  /* atribut height jinak přebije aspect-ratio (uplatní se jen při výšce
     auto) a fotky se svisle roztáhnou */
  block-size: auto;
  aspect-ratio: 1;
  object-fit: cover;
  border: var(--border-w-thick) solid var(--border-default);
  border-radius: var(--radius-m);
  box-shadow: var(--shadow-stamp-s);
}

/* ---- links ---- */

.c-interpret__links {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
  gap: var(--space-s-m);
}

.c-interpret__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xs);
  padding: var(--space-m) var(--space-m);
  color: var(--text-primary);
  text-decoration: none;
  background: var(--surface-card);
  border: var(--border-w-thick) solid var(--border-default);
  border-radius: var(--radius-m);
  box-shadow: var(--shadow-stamp-s);
  transition: translate var(--duration-base) var(--ease-snap);
}

.c-interpret__link:hover {
  translate: -2px -2px;
}

/* stisk = otisk razítka; stojí před :focus-visible, aby prstenec fokusu
   zůstal vidět i během stisku (stejné pořadí jako v button.css) */
.c-interpret__link:active {
  translate: var(--press-offset) var(--press-offset);
  box-shadow: none;
}

/* razítkový stín + světlý prstenec focus ringu (viz --focus-ring-halo) */
.c-interpret__link:focus-visible {
  box-shadow: var(--shadow-stamp-s), var(--focus-ring-halo);
}

.c-interpret__link-label {
  display: block;
  font: var(--text-display-s);
}

.c-interpret__link-sub {
  display: block;
  font: var(--text-body-s);
  color: var(--ink);
  opacity: 0.75;
}

/* Hranatá SVG šipka (stejná maska jako u odkazů v programu) místo dřívějšího
   textového „↗" — glyf se napříč systémy kreslil pokaždé jinak. */
.c-interpret__link-arrow {
  inline-size: 1.25rem;
  block-size: 1.25rem;
  flex-shrink: 0;
  background: var(--ink);
  -webkit-mask: url("/assets/img/arrow-ne.svg?v=1785106422") center / contain no-repeat;
  mask: url("/assets/img/arrow-ne.svg?v=1785106422") center / contain no-repeat;
}

/* ---- CTA strip (green) ---- */

.c-interpret__section--cta {
  background: var(--green);
  border-block-end: var(--border-w-thick) solid var(--border-default);
}

.c-interpret__cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-l);
}

.c-interpret__cta-title {
  margin-block-end: var(--space-2xs);
  font: var(--text-display-m);
  color: var(--ink);
}

.c-interpret__cta-text {
  font: var(--text-body-l);
  color: var(--ink);
}

/* ---- pager (prev/next interpret, loops) ---- */

.c-interpret__section--pager {
  background: var(--yellow);
  border-block-start: none;
  border-block-end: var(--border-w-thick) solid var(--border-default);
}

.c-interpret__pager {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
}

.c-interpret__pager-link {
  flex: 1 1 12rem;
  display: flex;
  align-items: center;
  gap: var(--space-s);
  padding: var(--space-s) var(--space-m);
  background: var(--yellow);
  border: var(--border-w-thick) solid var(--border-default);
  color: var(--ink);
  text-decoration: none;
  transition: transform 120ms ease, background-color 120ms ease;
}

.c-interpret__pager-link--next {
  justify-content: flex-end;
  text-align: end;
}

.c-interpret__pager-link:hover,
.c-interpret__pager-link:focus-visible {
  background: var(--yellow-dark);
}

.c-interpret__pager-thumb {
  flex: none;
  inline-size: 3rem;
  block-size: 3rem;
  overflow: hidden;
  border: var(--border-w-thin, 1px) solid var(--border-default);
}

.c-interpret__pager-thumb img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  display: block;
}

.c-interpret__pager-link--prev:hover,
.c-interpret__pager-link--prev:focus-visible {
  transform: translateX(calc(-1 * var(--space-3xs)));
}

.c-interpret__pager-link--next:hover,
.c-interpret__pager-link--next:focus-visible {
  transform: translateX(var(--space-3xs));
}

.c-interpret__pager-arrow {
  font: var(--text-display-s);
  line-height: 1;
}

.c-interpret__pager-text {
  display: flex;
  flex-direction: column;
}

.c-interpret__pager-label {
  font: var(--text-body-s);
  color: var(--ink);
  opacity: 0.7;
}

.c-interpret__pager-name {
  font: var(--text-display-s);
  color: var(--ink);
}

/* ---- Hover: fotky ze živých show ----
   Sekce se dřív odhalovaly scrollem jedna po druhé (ukázky, fotky, odkazy).
   Teď jsou vidět hned a pohyb si vyžádá kurzor — stejným posunem, jaký už
   používají ukázky a odkazy výš. */
.c-interpret__gallery img {
  transition: transform var(--duration-slow) var(--ease-snap);
}

@media (hover: hover) and (pointer: fine) {
  .c-interpret__gallery img:hover {
    transform: translateY(calc(-1 * var(--lift-s))) scale(1.02);
  }
}

@media (prefers-reduced-motion: reduce) {
  .c-interpret__gallery img {
    transition: none;
  }
  .c-interpret__gallery img:hover {
    transform: none;
  }
}


/* assets/css/components/interpreti.css */
/* Interpreti — grid overview of the year's lineup. Portraits sit in
   stamp-framed cards (thick ink border + hard offset shadow, same frame
   as the detail-page hero); cards without a photo show the brand star
   on a solid color block instead. */

.c-interpreti {
  padding-block: var(--space-xl-2xl);
}

.c-interpreti__eyebrow {
  font: var(--text-eyebrow);
  letter-spacing: var(--tracking-eyebrow);
  color: var(--brand-secondary-text);
  /* text na cream — jasná oranžová má 2,40:1 */
}

.c-interpreti__grid {
  list-style: none;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(20rem, 100%), 1fr));
  gap: var(--space-xl) var(--space-l);
}

.c-interpreti__card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-s);
  text-decoration: none;
  color: var(--text-primary);
}

.c-interpreti__media {
  position: relative;
  inline-size: 100%;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--orange);
  border: var(--border-w-thick) solid var(--border-default);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-stamp-m);
  transition:
    transform var(--duration-base) var(--ease-snap),
    box-shadow var(--duration-base) var(--ease-snap);
}

.c-interpreti__media img {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  /* fotky přicházejí z různých zdrojů (tiskové materiály, AI generovaný
     obrázek…) a barevně si vůbec neodpovídají — odbarvení + zvýšený
     kontrast je sjednotí a zároveň připraví pro tečkovaný přeliv níž */
  filter: grayscale(35%) contrast(1.15);
}

/* halftone — puntíkovaný přeliv jako u starého novinového tisku, ladí
   s razítkovým stylem karet (tlustý rámeček, tvrdý stín). Čistě CSS
   vzorek (stejná velikost puntíku všude), ne skutečný halftone podle
   jasu fotky — na to by bylo potřeba SVG filtr. */
.c-interpreti__media:has(img)::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: radial-gradient(var(--ink) 71%, transparent 82%);
  background-size: 1.5px 1.5px;
  mix-blend-mode: overlay;
  opacity: 0.2;
}

/* photoless cards get the brand star on the color block */
.c-interpreti__placeholder {
  position: absolute;
  inset: 18%;
  background: var(--ink);
  -webkit-mask: url("/assets/img/star.svg?v=1785106422") center / contain no-repeat;
  mask: url("/assets/img/star.svg?v=1785106422") center / contain no-repeat;
}

/* placeholder color cycle through the row */
.c-interpreti__grid li:nth-child(3n + 2) .c-interpreti__media {
  background: var(--blue);
}

.c-interpreti__grid li:nth-child(3n) .c-interpreti__media {
  background: var(--green);
}

.c-interpreti__grid .c-interpreti__card:hover .c-interpreti__media,
.c-interpreti__grid .c-interpreti__card:focus-visible .c-interpreti__media {
  transform: translateY(calc(-1 * var(--lift-m)));
  box-shadow: var(--shadow-stamp-l);
}

/* Stisk kartu zase položí a otiskne: posun o offset stínu, stín zmizí —
   stejné gesto jako u tlačítek. */
.c-interpreti__grid .c-interpreti__card:active .c-interpreti__media {
  transform: translate(var(--press-offset), var(--press-offset));
  box-shadow: none;
}

.c-interpreti__name {
  font: var(--text-display-s);
  text-align: center;
}

/* ročníky u archivních interpretů — v letošním výpisu se nevypisují */
.c-interpreti__years {
  display: block;
  margin-block-start: var(--space-3xs);
  font: var(--text-body-s);
  text-align: center;
  color: var(--text-secondary);
}


/* assets/css/components/gallery.css */
/* Galerie — alba fotek. Masonry přes CSS columns, aby se fotky zobrazily
   celé (bez ořezu) a přitom se sloupce dobře vyskládaly. Lightbox: GLightbox
   (assets/vendor/glightbox). */

.c-gallery {
  padding-block: var(--space-xl-2xl);
}

.c-gallery__heading {
  font: var(--text-display-s);
}

.c-gallery__grid {
  columns: 3;
  column-gap: var(--space-m);
}

@media (max-width: 64em) {
  .c-gallery__grid {
    columns: 2;
  }
}

@media (max-width: 40em) {
  .c-gallery__grid {
    columns: 1;
  }
}

.c-gallery__item {
  display: block;
  margin-block-end: var(--space-m);
  break-inside: avoid;
  border-radius: var(--radius-m);
  overflow: hidden;
  transition: transform var(--duration-base) var(--ease-snap);
}

.c-gallery__item img {
  display: block;
  inline-size: 100%;
  block-size: auto;
  transition: transform 320ms var(--ease-snap);
}

/* Fotka se pod kurzorem nadzvedne a lehce přisune — dlaždice mřížky ořezává
   (overflow: hidden), takže zvětšení uvnitř nikam nepřeteče. Dřív se místo
   toho jen ztlumila na opacity 0.85, což vypadalo spíš jako chyba načítání. */
@media (hover: hover) and (pointer: fine) {
  .c-gallery__item:hover img,
  .c-gallery__item:focus-visible img {
    transform: scale(1.06);
  }
}

.c-gallery__item:focus-visible {
  transform: translateY(calc(-1 * var(--lift-s)));
}

@media (prefers-reduced-motion: reduce) {
  .c-gallery__item,
  .c-gallery__item img {
    transition: none;
  }
  .c-gallery__item:hover img,
  .c-gallery__item:focus-visible img {
    transform: none;
  }
}


/* assets/css/components/history.css */
/* Historie festivalu — svislá „nepřerušená" osa na stránce galerie.
   Čte se shora dolů = přítomnost → minulost: nahoře letošní ročník
   (zelený stamp blok s odkazem na program), pod ním nejnovější ročníky
   a tlačítko, které rozbalí celý archiv. Dvousloupcová
   mřížka drží všechny lineupy zarovnané na jedné ose x.
   Data: jazzpodkozakovem.cz/historie-festivalu. */

.c-history {
  /* na .c-history, ne jen na osu: --reveal (tlačítko) je jejich sourozenec
     a potřebuje stejné --rail/--marker-w, aby s nimi zůstal zarovnaný */
  --spine: 7px;
  --rail: var(--space-xl);
  --marker-w: clamp(4rem, 5vw + 2rem, 6.5rem);
  background: var(--surface-card);
  border-block: var(--border-w) solid var(--border-default);
  padding-block: var(--space-xl-2xl);
}

.c-history__intro {
  display: grid;
  gap: var(--space-s);
  margin-block-end: var(--space-xl);
}

.c-history__eyebrow {
  font: var(--text-eyebrow);
  letter-spacing: var(--tracking-eyebrow);
  color: var(--brand-secondary-text); /* text na bílé — jasná oranžová má 3,45:1 */
}

.c-history__heading {
  font: var(--text-display-m);
  max-inline-size: 20ch;
}

.c-history__lead {
  font: var(--text-accent-l);
  max-inline-size: 52ch;
}

/* ---- festival v číslech: tři „stamp" dlaždice nad osou ---- */

.c-history__stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(9rem, 100%), 1fr));
  gap: var(--space-m);
  margin: 0 0 var(--space-xl);
}

.c-history__stat {
  display: grid;
  gap: var(--space-3xs);
  padding: var(--space-m);
  background: var(--surface-page);
  border: var(--border-w) solid var(--border-default);
  border-block-start: 6px solid var(--ink);
  box-shadow: var(--shadow-stamp-s);
}

.c-history__stat:nth-child(1) { border-block-start-color: var(--green); }
.c-history__stat:nth-child(2) { border-block-start-color: var(--orange); }
.c-history__stat:nth-child(3) { border-block-start-color: var(--blue); }
.c-history__stat:nth-child(4) { border-block-start-color: var(--ink); }

/* Značka je <dt> (popisek) a číslo <dd>, jak velí sémantika definičního
   seznamu — vizuálně ale patří číslo nahoru, proto se v gridu přeřadí. */
.c-history__stat-num {
  order: -1;
  font: var(--text-display-l);
  line-height: 0.85;
  font-variant-numeric: tabular-nums;
}

.c-history__stat-label {
  margin: 0;
  font: var(--text-label);
  letter-spacing: var(--tracking-wide);
  color: var(--text-secondary);
}

/* ---- osa: společné proměnné ---- */

.c-history__timeline,
.c-history__archive {
  position: relative;
  display: grid;
  gap: var(--space-l);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* páteř = světlá „kolej" přes celou osu (statický základ / stav bez JS) */
.c-history__timeline::before,
.c-history__archive::before {
  content: "";
  position: absolute;
  inset-block: 0.55rem 0;
  inset-inline-start: var(--spine);
  inline-size: var(--border-w-thick);
  background: var(--border-subtle);
}

/* zelená výplň páteře. Dřív ji podle scrollu „dokresloval" GSAP (scaleY 0 → 1),
   což znamenalo přepočet při každém snímku scrollu. Osa je teď vykreslená celá
   od začátku — pohyb na ose patří ročníku pod kurzorem, ne pozici stránky. */
.c-history__progress {
  position: absolute;
  inset-block: 0.55rem 0;
  inset-inline-start: var(--spine);
  inline-size: var(--border-w-thick);
  background: var(--green);
  z-index: 0;
}

/* ---- jeden ročník ---- */

.c-history__entry {
  position: relative;
  padding-inline-start: var(--rail);
  display: grid;
  grid-template-columns: var(--marker-w) 1fr;
  column-gap: var(--space-m);
  row-gap: var(--space-2xs);
  align-items: start;
}

/* uzel na páteři */
.c-history__node {
  position: absolute;
  inset-block-start: 0.28em;
  inset-inline-start: 1px;
  inline-size: 15px;
  block-size: 15px;
  z-index: 1;
  background: var(--blue);
  border: var(--border-w) solid var(--ink);
  border-radius: var(--radius-pill);
}

.c-history__entry:nth-child(4n + 1) .c-history__node { background: var(--green); }
.c-history__entry:nth-child(4n + 2) .c-history__node { background: var(--orange); }
.c-history__entry:nth-child(4n + 3) .c-history__node { background: var(--blue); }
.c-history__entry:nth-child(4n)     .c-history__node { background: var(--yellow); }

/* marker: rok nad označením ročníku */
.c-history__marker {
  grid-column: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
}

.c-history__year {
  font: var(--text-display-m);
  line-height: 0.9;
}

.c-history__label {
  font: var(--text-label);
  letter-spacing: var(--tracking-wide);
  color: var(--text-secondary);
  white-space: nowrap;
}

.c-history__body {
  grid-column: 2;
  min-inline-size: 0;
}

/* soupiska interpretů — zarovnaná v pravém sloupci */
.c-history__lineup {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-xs);
  margin: 0;
  padding: 0;
  list-style: none;
}

.c-history__lineup > li {
  display: inline-flex;
}

.c-history__lineup .c-tag {
  background: var(--surface-page);
}

.c-history__note {
  margin: 0;
  font: var(--text-accent-m);
  color: var(--text-secondary);
  max-inline-size: 60ch;
}

/* ---- letošní ročník: zelený stamp blok s odkazem na program ---- */

/* letošní ročník stojí sám — rok + „letos" v řádku, pod tím zelený blok */
.c-history__entry--upcoming {
  grid-template-columns: 1fr;
  row-gap: var(--space-s);
}

.c-history__entry--upcoming .c-history__marker {
  grid-column: 1;
  flex-direction: row;
  align-items: baseline;
  gap: var(--space-s);
}

.c-history__entry--upcoming .c-history__body {
  grid-column: 1;
}

.c-history__entry--upcoming .c-history__node {
  inline-size: 22px;
  block-size: 22px;
  inset-inline-start: -2px;
  inset-block-start: 0.18em;
  background: var(--green);
}

.c-history__entry--upcoming .c-history__year {
  font: var(--text-display-l);
}

.c-history__panel {
  display: grid;
  gap: var(--space-m);
  justify-items: start;
  max-inline-size: 32rem;
  padding: var(--space-m);
  background: var(--green);
  border: var(--border-w) solid var(--border-default);
  box-shadow: var(--shadow-stamp-m);
}

.c-history__panel-text {
  font: var(--text-accent-l);
  max-inline-size: 26ch;
}

/* ---- původ: založení klubu ---- */

.c-history__entry--origin .c-history__node {
  inline-size: 18px;
  block-size: 18px;
  inset-inline-start: -1px;
  background: var(--green);
}

.c-history__entry--origin .c-history__note {
  font: var(--text-accent-l);
  color: var(--text-primary);
}

/* ---- tlačítko „celá historie" na páteři ---- */

.c-history__reveal {
  position: relative;
  /* zarovnat text tlačítka se sloupcem let (roky u ročníků nad ním) */
  padding-inline-start: var(--rail);
  padding-block: var(--space-l);
}

/* přerušovaná páteř naznačuje, že dole pokračuje archiv */
.c-history__reveal::before {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline-start: 7px;
  inline-size: var(--border-w-thick);
  background: repeating-linear-gradient(
    var(--ink) 0 7px,
    transparent 7px 14px
  );
}

.c-history__reveal-btn {
  gap: var(--space-xs);
}

.c-history__reveal-arrow {
  transition: transform var(--duration-base) var(--ease-snap);
}

.c-history__reveal-btn:hover .c-history__reveal-arrow {
  transform: translateY(3px);
}

/* archiv skrytý atributem hidden (progresivní vylepšení přes JS) */
.c-history__archive[hidden] {
  display: none;
}

/* odsazení shora: po kliknutí zmizí .c-history__reveal (i s jeho vlastním
   padding-block), takže archiv potřebuje vlastní mezeru od osy nad ním */
.c-history__archive {
  margin-block-start: var(--space-l);
}

/* ---- mobil: marker se skládá do řádku, tělo pod něj ---- */

@media (max-width: 40em) {
  .c-history__heading {
    font: var(--text-display-s);
  }

  .c-history__entry {
    grid-template-columns: 1fr;
    row-gap: var(--space-xs);
  }

  .c-history__marker {
    grid-column: 1;
    flex-direction: row;
    align-items: baseline;
    gap: var(--space-xs);
  }

  .c-history__body {
    grid-column: 1;
  }

  .c-history__year {
    font: var(--text-display-s);
  }

  .c-history__entry--upcoming .c-history__year {
    font: var(--text-display-m);
  }

  .c-history__stats {
    gap: var(--space-s);
  }

  .c-history__stat {
    padding: var(--space-s);
  }

  .c-history__stat-num {
    font: var(--text-display-m);
    line-height: 0.9;
  }
}

/* ---- bez animací: osu rovnou „dokresli" a nic neschovávej ---- */

@media (prefers-reduced-motion: reduce) {
  .c-history__progress {
    transform: scaleY(1) !important;
  }
}

/* ---- Hover: ročník pod kurzorem ----
   Řádky se dřív odhalovaly scrollem jeden po druhém a páteř se plnila podle
   pozice stránky. Osa je teď celá vidět a zvýrazní se ten ročník, na kterém
   kurzor stojí — uzel povyroste, text se posune za ním. */
.c-history__node {
  transition: scale 220ms var(--ease-snap);
}

.c-history__entry {
  transition: transform 220ms var(--ease-snap);
}

@media (hover: hover) and (pointer: fine) {

  .c-history__entry:hover .c-history__node {
    scale: 1.5;
  }
}

@media (prefers-reduced-motion: reduce) {
  .c-history__node,
  .c-history__entry {
    transition: none;
  }
  .c-history__entry:hover {
    transform: none;
  }
  .c-history__entry:hover .c-history__node {
    scale: 1;
  }
}


/* assets/css/components/tickets.css */
/* Vstupenky — seznam koncertů generovaný z programu, karty ve stejném
   razítkovém stylu jako kontaktní karty (viz card.css). Každá položka
   nese `--accent` (barva večera z programu, u permanentek volba v panelu)
   jako barvu značek u data/času/místa. Permanentka apod. se navíc dá
   zapnutím „Zvýraznit" vybarvit celá — viz `--highlight`. */

.c-tickets {
  padding-block: var(--space-xl-2xl);
}

.c-tickets__list {
  /* list-style/margin/padding už nuluje reset; vlastní margin: 0 zde jen
     přebíjel odsazení z rodičovského .l-stack (stejná specificita, pozdější pořadí) */
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
}

.c-tickets__item {
  --accent: var(--green);
  display: flex;
  align-items: center;
  padding: 0;
  overflow: hidden;
  transition:
    transform var(--duration-slow) var(--ease-snap),
    box-shadow var(--duration-slow) var(--ease-snap);
}

/* Karta se pod kurzorem nadzvedne stejně jako permanentka — je to list papíru
   na stole, ne tlačítko: klikatelné je jen CTA uvnitř, proto žádný press.
   :focus-within dá stejnou odezvu klávesnici, až se fokus dostane na
   „koupit vstupenky". Fotku ořízne overflow: hidden výše. */
@media (hover: hover) and (pointer: fine) {
  .c-tickets__item:hover {
    transform: translateY(calc(-1 * var(--lift-m)));
    box-shadow: var(--shadow-stamp-l);
  }

  .c-tickets__media img {
    transition: scale var(--duration-slow) var(--ease-out);
  }

  .c-tickets__item:hover .c-tickets__media img {
    scale: 1.04;
  }
}

.c-tickets__item:focus-within {
  transform: translateY(calc(-1 * var(--lift-m)));
  box-shadow: var(--shadow-stamp-l);
}

/* Permanentky a jiné zvláštní vstupenky nemají řádek s datem, kde by se
   akcent projevil — barvu tedy nesou jako podtržení názvu. */
.c-tickets__item--extra .c-tickets__name {
  padding-block-end: var(--space-3xs);
  border-block-end: var(--border-w-thick) solid var(--accent);
}

/* Zvýrazněná vstupenka: celá karta v akcentní barvě, silnější rámeček
   a hlubší razítkový stín — vystoupí ze seznamu. Text zůstává inkoustový,
   všechny čtyři akcenty jsou světlé. */
.c-tickets__item--highlight {
  background: var(--accent);
  border-width: var(--border-w-thick);
  box-shadow: var(--shadow-stamp-l);
}

.c-tickets__item--highlight .c-tickets__name {
  border-block-end-color: var(--ink);
}

.c-tickets__media {
  inline-size: 16rem;
  aspect-ratio: 1;
  flex-shrink: 0;
}

.c-tickets__media img {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

/* položka bez fotky — akcentní plocha s hvězdou, stejný vzorec jako v programu
   (dřív tu byla náhodná fotka z picsum.photos, viz audit 5.2) */
.c-tickets__media--placeholder {
  position: relative;
  background: var(--accent, var(--orange));
}

.c-tickets__media-placeholder {
  position: absolute;
  inset: 18%;
  background: var(--ink);
  -webkit-mask: url("/assets/img/star.svg?v=1785106422") center / contain no-repeat;
  mask: url("/assets/img/star.svg?v=1785106422") center / contain no-repeat;
}

.c-tickets__content {
  flex: 1;
  min-inline-size: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s) var(--space-l);
  padding: var(--space-l);
}

.c-tickets__main {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  flex: 1 1 24rem;
}

.c-tickets__name {
  font: var(--text-display-m);
  text-transform: uppercase;
  align-self: flex-start;
}

.c-tickets__acts {
  font: var(--text-body-l);
}

/* Datum · čas · místo — plakátový akcent: datum jako barevné „razítko"
   večera, čas a místo tučnými verzálkami s akcentní značkou. */
.c-tickets__meta {
  margin-block-end: var(--space-2xs);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2xs) var(--space-m);
}

.c-tickets__date,
.c-tickets__when,
.c-tickets__where {
  font: var(--text-eyebrow);
  font-size: var(--size-body-s);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--text-primary);
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
}

.c-tickets__date::before,
.c-tickets__when::before,
.c-tickets__where::before {
  content: "";
  inline-size: 0.55em;
  block-size: 0.55em;
  background: var(--accent);
  rotate: 45deg;
  flex-shrink: 0;
}

.c-tickets__buy {
  display: flex;
  align-items: center;
  gap: var(--space-m);
  margin-inline-start: auto;
}

.c-tickets__price {
  display: flex;
  flex-direction: column;
  align-items: end;
  font: var(--text-display-s);
  white-space: nowrap;
}

.c-tickets__price-door {
  font: var(--text-body-s);
  color: var(--text-secondary);
}

.c-tickets__notes {
  font: var(--text-body-s);
  color: var(--text-secondary);
}

/* Zdvih má jiný koncový stav než klid, takže globální kill-switch v reset.css
   nestačí — hover a fokus musí kartu nechat na místě. Stín se vrací na -m;
   zvýrazněná permanentka si svůj -l ponechá vlastním pravidlem výše. */
@media (prefers-reduced-motion: reduce) {
  .c-tickets__item {
    transition: none;
  }

  .c-tickets__item:hover,
  .c-tickets__item:focus-within {
    transform: none;
    box-shadow: var(--shadow-stamp-m);
  }

  .c-tickets__item--highlight:hover,
  .c-tickets__item--highlight:focus-within {
    box-shadow: var(--shadow-stamp-l);
  }

  .c-tickets__item:hover .c-tickets__media img {
    scale: 1;
  }
}

@media (max-width: 37.5em) {
  .c-tickets__item {
    flex-direction: column;
    align-items: stretch;
  }

  .c-tickets__media {
    inline-size: 100%;
    block-size: 12rem;
  }
}


/* assets/css/components/contact.css */
/* Kontakt — trojice razítkových karet (napište / pořadatel / sledujte);
   každý nadpis je podtržený jinou brandovou barvou, ozvěna sekce partnerů */

.c-contact {
  padding-block: var(--space-xl-2xl);
}

.c-contact__card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-m);
}

.c-contact__heading {
  font: var(--text-display-s);
  align-self: stretch;
  border-block-end: var(--border-w) solid var(--accent-yellow);
  padding-block-end: var(--space-2xs);
}

.c-contact__card:nth-child(2) .c-contact__heading { border-color: var(--brand-secondary); }
.c-contact__card:nth-child(3) .c-contact__heading { border-color: var(--accent-blue); }

.c-contact__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}

.c-contact__label {
  display: block;
  font: var(--text-eyebrow);
  letter-spacing: var(--tracking-eyebrow);
  color: var(--text-secondary);
  margin-block-end: var(--space-3xs);
}

.c-contact__link {
  font: var(--text-display-s);
  overflow-wrap: anywhere;
  text-decoration-thickness: var(--border-w);
  text-underline-offset: 4px;
}

.c-contact__link:hover {
  text-decoration-color: var(--brand-secondary);
}

.c-contact__address {
  font-style: normal;
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.c-contact__org {
  font: var(--text-display-s);
}

.c-contact__legal {
  font: var(--text-body-s);
  color: var(--text-secondary);
}

/* odkaz na mapu drží u spodní hrany karty */
.c-contact__maplink {
  margin-block-start: auto;
  font: var(--text-label);
  text-decoration-thickness: var(--border-w);
  text-underline-offset: 4px;
}

.c-contact__maplink:hover {
  text-decoration-color: var(--brand-secondary);
}

/* ---- mapa festivalových míst (Leaflet + OSM) ---- */

/* mapová sekce je sama .l-stack, takže by generické pravidlo .l-stack resetovalo
   --gap zpět na --space-m dřív, než se vyřeší její odsazení od karet nad ní */
.c-contact__map-section {
  margin-block-start: var(--space-xl);
}

.c-contact__heading--map {
  border-color: var(--brand-primary);
  margin-block-end: var(--space-m);
}

.c-contact__map {
  inline-size: 100%;
  block-size: clamp(20rem, 55vh, 28rem);
  border: var(--border-w) solid var(--border-default);
  border-radius: var(--radius-m);
  box-shadow: var(--shadow-stamp-m);
  background: var(--surface-card);
  isolation: isolate; /* drží leafletí z-indexy uvnitř mapy */
}

/* dlaždice v černobílé — mapa pak sedí k tiskové estetice brandu
   a barevné hvězdy markerů vyniknou */
.c-contact__map .leaflet-tile-pane {
  filter: grayscale(1);
}

.c-contact__map .leaflet-container,
.c-contact__map.leaflet-container {
  font: var(--text-body-s);
  border-radius: calc(var(--radius-m) - var(--border-w));
}

/* markery — stejná hvězda jako u interpretů */
.c-map-marker {
  background: var(--orange);
  -webkit-mask: url("/assets/img/star.svg?v=1785106422") center / contain no-repeat;
  mask: url("/assets/img/star.svg?v=1785106422") center / contain no-repeat;
  transition: transform var(--duration-base) var(--ease-snap);
}

.c-map-marker--blue { background: var(--blue); }
.c-map-marker--green { background: var(--green); }

.c-map-marker:hover,
.c-map-marker:focus-visible {
  transform: rotate(8deg) scale(1.15);
}

/* stálé jmenovky u markerů — malé razítkové štítky, bez nutnosti klikat */
.c-contact__map .c-map-label {
  font: var(--text-label);
  color: var(--text-primary);
  background: var(--surface-card);
  border: var(--border-w) solid var(--border-default);
  border-radius: var(--radius-s);
  box-shadow: var(--shadow-stamp-s);
  padding: var(--space-3xs) var(--space-2xs);
  opacity: 1;
}

/* bez šipky — štítek sedí volně pod hvězdou */
.c-contact__map .c-map-label::before {
  display: none;
}

/* popupy a ovládání v duchu razítkových karet */
.c-contact__map .leaflet-popup-content-wrapper {
  background: var(--surface-card);
  color: var(--text-primary);
  border: var(--border-w) solid var(--border-default);
  border-radius: var(--radius-m);
  box-shadow: var(--shadow-stamp-s);
}

.c-contact__map .leaflet-popup-content {
  font: var(--text-body-s);
  margin: var(--space-s) var(--space-m);
}

.c-contact__map .leaflet-popup-content strong {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--size-body-l);
}

.c-contact__map .leaflet-popup-tip {
  background: var(--surface-card);
  border: var(--border-w) solid var(--border-default);
  box-shadow: none;
}

.c-contact__map .leaflet-bar {
  border: var(--border-w) solid var(--border-default);
  border-radius: var(--radius-s);
  box-shadow: var(--shadow-stamp-s);
}

.c-contact__map .leaflet-bar a {
  color: var(--ink);
}


/* assets/css/components/field.css */
/* shared block for text inputs and selects */

.c-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font: var(--text-body-s);
}

.c-field__label {
  font: var(--text-label);
  color: var(--text-primary);
}

.c-field__input {
  font: var(--text-body-m);
  padding: 10px 12px;
  border: var(--border-w) solid var(--border-default);
  border-radius: var(--radius-s);
  background: var(--surface-card);
  color: var(--text-primary);
}

/* stejný dvoubarevný ring jako globálně, jen bez odsazení od rámečku */
.c-field__input:focus-visible {
  outline: var(--border-w-thick) solid var(--focus-ring);
  outline-offset: 2px;
  box-shadow: var(--focus-ring-halo);
}

.c-field__input::placeholder {
  color: var(--text-secondary);
}

/* native select styled to match, with an ink chevron */
select.c-field__input {
  appearance: none;
  padding-inline-end: var(--space-xl);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%231c1d1b' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
}

.c-field--error .c-field__input {
  border-color: var(--brand-secondary);
}

/* text chyby na bílém podkladu — jasná oranžová má jen 3,45:1 */
.c-field__error {
  color: var(--brand-secondary-text);
}


/* assets/css/components/checkbox.css */
/* styled native checkbox — the input itself is the 20px box */

.c-checkbox {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font: var(--text-body-m);
  color: var(--text-primary);
}

.c-checkbox__input {
  appearance: none;
  inline-size: 20px;
  block-size: 20px;
  flex-shrink: 0;
  margin: 0;
  border: var(--border-w) solid var(--border-default);
  border-radius: var(--radius-s);
  background: var(--surface-card);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background var(--duration-fast);
}

.c-checkbox__input:checked {
  background-color: var(--brand-primary);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%231c1d1b' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
}


/* assets/css/components/radio.css */
/* styled native radio — round box, ink dot when checked */

.c-radio {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font: var(--text-body-m);
  color: var(--text-primary);
}

.c-radio__input {
  appearance: none;
  inline-size: 20px;
  block-size: 20px;
  flex-shrink: 0;
  margin: 0;
  border: var(--border-w) solid var(--border-default);
  border-radius: 50%;
  background: var(--surface-card);
  display: inline-grid;
  place-content: center;
  cursor: pointer;
  transition: background var(--duration-fast);
}

.c-radio__input::before {
  content: "";
  inline-size: 8px;
  block-size: 8px;
  border-radius: 50%;
  background: var(--ink);
  transform: scale(0);
  transition: transform var(--duration-fast) var(--ease-snap);
}

.c-radio__input:checked {
  background: var(--brand-primary);
}

.c-radio__input:checked::before {
  transform: scale(1);
}


/* assets/css/components/switch.css */
/* styled native checkbox as an on/off switch */

.c-switch {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  font: var(--text-body-m);
  color: var(--text-primary);
}

.c-switch__input {
  appearance: none;
  inline-size: 44px;
  block-size: 24px;
  flex-shrink: 0;
  margin: 0;
  position: relative;
  border: var(--border-w) solid var(--border-default);
  border-radius: var(--radius-pill);
  background: var(--surface-card);
  cursor: pointer;
  transition: background var(--duration-base);
}

.c-switch__input::before {
  content: "";
  position: absolute;
  inset-block-start: 1px;
  inset-inline-start: 1px;
  inline-size: 18px;
  block-size: 18px;
  border-radius: 50%;
  background: var(--ink);
  transition: inset-inline-start var(--duration-base) var(--ease-snap);
}

.c-switch__input:checked {
  background: var(--brand-primary);
}

.c-switch__input:checked::before {
  inset-inline-start: 21px;
}


/* assets/css/components/tabs.css */
.c-tabs__list {
  display: flex;
  gap: 4px;
  border-block-end: var(--border-w) solid var(--border-default);
}

.c-tabs__tab {
  padding: 10px 18px;
  border: 0;
  background: transparent;
  color: var(--text-primary);
  font: var(--text-label);
  border-radius: var(--radius-s) var(--radius-s) 0 0;
  cursor: pointer;
  transition: background var(--duration-fast);
}

.c-tabs__tab:hover {
  background: color-mix(in oklch, var(--ink) 10%, transparent);
}

.c-tabs__tab[aria-selected="true"] {
  background: var(--ink);
  color: var(--text-inverse);
}

.c-tabs__panel {
  padding-block: var(--space-s);
  font: var(--text-body-m);
}

.c-tabs__panel[hidden] {
  display: none;
}


/* assets/css/components/accordion.css */
/* native <details>/<summary>, no JS */

.c-accordion {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.c-accordion__item {
  border: var(--border-w) solid var(--border-default);
  border-radius: var(--radius-m);
  background: var(--surface-card);
}

.c-accordion__title {
  --marker-size: 14px;
  --marker-w: 3px;
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-m);
  padding: 14px 18px;
  cursor: pointer;
  font: var(--text-label);
  list-style: none;
  transition:
    transform var(--duration-fast) var(--ease-snap),
    background var(--duration-fast);
}

.c-accordion__title::-webkit-details-marker {
  display: none;
}

.c-accordion__title:hover {
  background: color-mix(in oklch, var(--ink) 6%, transparent);
}

/* summary je klikatelné, takže dostane razítkový press jako tlačítka */
.c-accordion__title:active {
  transform: translate(var(--press-offset), var(--press-offset));
}

/* Značka „+" / „−" ze dvou inkoustových proužků místo záměny znaku — stejný
   jazyk jako 2–3px hrany webu, a hlavně se dá animovat. Vodorovný proužek
   (::after) je flex položka, takže drží původní rozvržení; svislý (::before)
   leží přes něj absolutně a při otevření se sklopí.

   Znak zmizel z content, ale čtečce nic nechybí — stav rozbalení nese
   sémantika <details>/<summary> sama. */
.c-accordion__title::after {
  content: "";
  flex: none;
  inline-size: var(--marker-size);
  block-size: var(--marker-w);
  background: currentColor;
}

.c-accordion__title::before {
  content: "";
  position: absolute;
  inset-inline-end: calc(18px + (var(--marker-size) - var(--marker-w)) / 2);
  inset-block-start: 50%;
  inline-size: var(--marker-w);
  block-size: var(--marker-size);
  background: currentColor;
  translate: 0 -50%;
  transition: scale var(--duration-base) var(--ease-snap);
}

.c-accordion__item[open] > .c-accordion__title::before {
  scale: 1 0;
}

/* Nativní <details> se dá rozbalit až přes ::details-content. Výšku umí
   interpolovat jen s interpolate-size (zapnuto vědomě na komponentě, ne na
   :root — globální přepnutí by měnilo chování všem budoucím přechodům),
   content-visibility se musí přepnout diskrétně, jinak obsah zmizí dřív,
   než dojede.

   Plynulou výšku zatím umí jen Chromium; jinde se položka rozbalí skokem
   jako dřív, plně čitelně. Morf značky výše funguje všude. */
.c-accordion {
  interpolate-size: allow-keywords;
}

.c-accordion__item::details-content {
  block-size: 0;
  overflow: hidden;
  opacity: 0;
  transition:
    block-size var(--duration-slow) var(--ease-out),
    opacity var(--duration-fast) linear,
    content-visibility var(--duration-slow) allow-discrete;
}

.c-accordion__item[open]::details-content {
  block-size: auto;
  opacity: 1;
}

.c-accordion__content {
  padding: 4px 18px 16px;
  font: var(--text-body-m);
  color: var(--text-secondary);
}


/* assets/css/components/dialog.css */
/* native <dialog>, opened via [data-dialog-open] triggers (ui.js) */

.c-dialog {
  background: var(--surface-card);
  color: var(--text-primary);
  border: var(--border-w-thick) solid var(--border-default);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-stamp-l);
  padding: var(--space-l);
  max-inline-size: min(440px, 90%);
}

.c-dialog::backdrop {
  background: rgba(28, 29, 27, 0.5);
}

.c-dialog__title {
  font: var(--text-display-s);
  margin-block-end: var(--space-xs);
}

.c-dialog__body {
  font: var(--text-body-m);
}

.c-dialog__footer {
  margin-block-start: var(--space-m);
  display: flex;
  justify-content: flex-end;
  gap: var(--space-s);
}


/* assets/css/components/toast.css */
.c-toast-region {
  position: fixed;
  inset-block-end: var(--space-m);
  inset-inline-end: var(--space-m);
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  z-index: 100;
}

.c-toast {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  background: var(--brand-primary);
  color: var(--text-on-brand);
  border: var(--border-w) solid var(--border-default);
  border-radius: var(--radius-m);
  box-shadow: var(--shadow-stamp-s);
  font: var(--text-body-m);
  max-inline-size: 360px;
  animation: c-toast-in var(--duration-base) var(--ease-snap);
}

.c-toast--secondary {
  background: var(--brand-secondary);
}

.c-toast--ink {
  background: var(--ink);
  color: var(--text-inverse);
}

.c-toast__message {
  flex: 1;
}

/* Zavírací „×" má sám o sobě jen ~14 px. Cílová plocha se proto roztahuje
   na 24×24 px (minimum WCAG 2.5.8), aniž by se znak opticky zvětšil. */
.c-toast__close {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 24px;
  block-size: 24px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-s);
  background: none;
  color: inherit;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
}

@keyframes c-toast-in {
  from {
    translate: 0 var(--space-s);
    opacity: 0;
  }
  to {
    translate: 0 0;
    opacity: 1;
  }
}


/* assets/css/components/tooltip.css */
/* Tooltip: <span class="c-tooltip"><trigger><span class="c-tooltip__bubble">…</span></span>

   Bublina je skutečný element, ne ::after z data-tooltip. Dřív byl text v HTML
   dvakrát — jednou v atributu pro CSS a jednou ve skrytém elementu, protože
   atribut čtečka nepřečte a trigger na něj musí ukazovat přes aria-describedby.
   Takhle stačí jednou. */

.c-tooltip {
  position: relative;
  display: inline-block;
}

.c-tooltip__bubble {
  position: absolute;
  inset-block-end: calc(100% + 8px);
  inset-inline-start: 50%;
  transform: translateX(-50%);
  background: var(--ink);
  color: var(--text-inverse);
  font: var(--text-body-s);
  padding: 6px 10px;
  border-radius: var(--radius-s);
  white-space: nowrap;
  z-index: 10;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--duration-fast);
}

.c-tooltip:hover .c-tooltip__bubble,
.c-tooltip:focus-within .c-tooltip__bubble {
  opacity: 1;
  visibility: visible;
}

/* Stavy, které přepíná ui.js:
   • .is-tooltip-open drží bublinu ještě chvíli po odjezdu kurzoru, aby šlo
     přejet přes mezeru mezi triggerem a bublinou a číst ji v klidu,
   • .is-tooltip-dismissed = zavřeno klávesou Esc; musí přebít i :hover,
     jinak by se bublina okamžitě vrátila. */
.c-tooltip.is-tooltip-open .c-tooltip__bubble {
  opacity: 1;
  visibility: visible;
}

.c-tooltip.is-tooltip-dismissed .c-tooltip__bubble {
  opacity: 0 !important;
  visibility: hidden !important;
}


/* assets/css/components/motion.css */
/* Motion — doprovodné styly k assets/js/motion.js
   ------------------------------------------------
   Web se řídí zásadou „obsah je vidět hned". Nic se tu proto předem neskrývá.
   Vstupní náběh hera dělá CSS v hero.css, zbytek pohybu je odpověď na akci
   uživatele — najetí myší, tažení, kliknutí.

   Dřív tady byl velký blok, který před příchodem GSAPu schoval opacity: 0
   všechno, co se mělo odhalovat scrollem. Ten je pryč i s třídou .js-anim,
   watchdogem v hlavičce a nouzovým odhalováním v JS. */

/* ---- Hero: třásně pod herem ----
   Délku kapek dřív přepisoval JS inline stylem na ~60 <path> v 60 fps (a
   transform na <path> není kompozitorová operace, takže to bylo drahé hned
   pod heroem). Teď se hýbe CSS animací: hlavní vlákno má klid, každá kapka má
   vlastní délku cyklu a fázi — obojí nastaví ui.js jednorázově při stavbě, aby
   pás nepulzoval jako jeden celek. Vodorovné měřítko (--fringe-sx) i kotvení
   k horní hraně řeší hero.css. */
@keyframes hero-fringe-sway {
  0%,
  100% {
    transform: scale(var(--fringe-sx, 1.2), 0.875);
  }
  22% {
    transform: scale(var(--fringe-sx, 1.2), 0.95);
  }
  48% {
    transform: scale(var(--fringe-sx, 1.2), 0.805);
  }
  74% {
    transform: scale(var(--fringe-sx, 1.2), 0.925);
  }
}

.c-hero__fringe path {
  animation: hero-fringe-sway var(--fringe-dur, 12s) ease-in-out
    var(--fringe-delay, 0s) infinite;
}

/* Mimo obrazovku ať se nic nepřekresluje (třídu přepíná ui.js). */
.c-hero__fringe.is-paused path {
  animation-play-state: paused;
}

@media (prefers-reduced-motion: reduce) {
  .c-hero__fringe path {
    animation: none;
  }
}

/* ---- Odometer čísla (intro fakta, statistika historie) ----
   Každá číslice je svislý pásek 0–9 v okénku vysokém 1 em; JS ho posune tak,
   aby v okénku zůstala cílová číslice. Číslo je správně od začátku — přetočí
   se, až o to uživatel stojí (najetí myší, fokus, klepnutí). Trvání a časování
   nastavuje JS inline, protože se u každé číslice liší.

   will-change tu nedržíme natrvalo: přetočení je krátké a vrstva navíc by
   zbytečně žrala paměť. Zapíná ho JS jen po dobu animace. */
.u-odo {
  display: inline-flex;
}
.u-odo__col {
  display: inline-block;
  block-size: 1em;
  overflow: hidden;
  line-height: 1;
}
.u-odo__reel {
  display: flex;
  flex-direction: column;
}
.u-odo__d {
  display: block;
  block-size: 1em;
  line-height: 1;
  text-align: center;
}

@media (prefers-reduced-motion: reduce) {
  .u-odo__reel {
    transition: none !important;
  }
}

/* ---- Koláž: reflektor sledující kurzor (tmavé pozadí, jen myš) ----
   Polohu píše motion.js do --mx/--my; tady se z toho skládá světelný kužel.
   Zapíná se najetím myši, takže bez ní se nic nepřekresluje. */
.c-collage {
  --mx: 50;
  --my: 50;
}

.c-collage::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.5s ease;
  background: radial-gradient(
    circle at calc(var(--mx) * 1px) calc(var(--my) * 1px),
    rgba(0, 0, 0, 0) 90px,
    rgba(0, 0, 0, 0.55) 360px
  );
}

.c-collage.is-lit::after {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce), (hover: none) {
  .c-collage::after {
    display: none;
  }
}

/* ---- Program: přišpendlené datum dne ----
   Tablet a výš: datum je svislý sloupec vlevo, drží se u horního okraje,
   zatímco kolem projíždějí koncerty toho dne. */
@media (min-width: 37.5em) {
  .c-program__date {
    position: sticky;
    top: var(--space-l);
    align-self: flex-start;
  }
}

/* Mobil: datum je vodorovný pruh nad koncerty — přilepí se k hornímu okraji
   a koncerty pod ním rolují. Potřebuje neprůhledné pozadí (barva stránky).
   Spodní hrana je tlustá černá linka, která se v levém rohu napojí na svislou
   páteř koncertů → z časové osy vznikne souvislý „roh". */
@media (max-width: 37.5em) {
  /* datum sedí těsně na páteři, ať se linky v rohu opravdu potkají */
  .c-program__event {
    gap: 0;
  }
  .c-program__date {
    position: sticky;
    top: 0;
    z-index: 3;
    background: var(--surface-page);
    padding-block: var(--space-xs);
    /* pruh i linka až k pravému okraji displeje, ať překryjí přesah stínu fotky
       (l-center má po stranách gutter var(--space-m)) */
    margin-inline-end: calc(-1 * var(--space-m));
    padding-inline-end: var(--space-m);
    border-block-end: var(--border-w-thick) solid var(--border-default);
  }
  /* vzduch pod vodorovnou linkou; svislá páteř přitom začíná hned u rohu */
  .c-program__spine {
    padding-block-start: var(--space-m);
  }
}

