/* ============================================================
   Foundation — design tokens, type scale, spacing rhythm, base
   Edit the :root tokens to restyle the whole site. Sections only
   consume these tokens; they never hard-code colors or sizes.
   ============================================================ */
:root {
  /* Palette (light). Override --accent/--accent-contrast from the brand. */
  --bg: #faf9f7;
  --surface: #ffffff;
  --surface-2: #f1efeb;
  --text: #191817;
  --muted: #5f5b55;
  --accent: #19407a;
  --accent-contrast: #ffffff;
  --border: #e2dfd9;

  /* Typography: exactly two families site-wide. */
  --font-display: Georgia, 'Times New Roman', serif;
  --font-body: system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* Fluid type scale (minor-third at mobile widening toward desktop). */
  --step--1: clamp(0.83rem, 0.8rem + 0.16vw, 0.94rem);
  --step-0: clamp(1rem, 0.96rem + 0.22vw, 1.13rem);
  --step-1: clamp(1.25rem, 1.17rem + 0.42vw, 1.5rem);
  --step-2: clamp(1.56rem, 1.41rem + 0.78vw, 2.05rem);
  --step-3: clamp(1.95rem, 1.63rem + 1.62vw, 2.95rem);
  --step-4: clamp(2.44rem, 1.86rem + 2.9vw, 4.2rem);
  --step-5: clamp(3.05rem, 2.1rem + 4.7vw, 5.9rem);

  /* Spacing rhythm. Sections use --space-section for vertical rhythm. */
  --space-2xs: 0.25rem;
  --space-xs: 0.5rem;
  --space-sm: 0.75rem;
  --space-md: 1rem;
  --space-lg: 1.5rem;
  --space-xl: 2.5rem;
  --space-2xl: 4rem;
  --space-section: clamp(4rem, 3rem + 5vw, 7rem);

  /* One radius + shadow language for the whole site. */
  --radius-sm: 6px;
  --radius: 12px;
  --radius-lg: 20px;
  --shadow-1: 0 1px 2px rgb(0 0 0 / 0.06), 0 4px 12px rgb(0 0 0 / 0.06);
  --shadow-2: 0 2px 4px rgb(0 0 0 / 0.08), 0 12px 32px rgb(0 0 0 / 0.12);

  --container: 72rem;
  --gutter: clamp(1.25rem, 4vw, 2.5rem);

  /* Tickivo web components inherit the same system. */
  --tickivo-font: var(--font-body);
  --tickivo-text: var(--text);
  --tickivo-accent: var(--accent);
  --tickivo-accent-contrast: var(--accent-contrast);
  --tickivo-surface: var(--surface);
  --tickivo-radius: var(--radius);
  --tickivo-gap: var(--space-lg);
  --tickivo-border: var(--border);
  --tickivo-error: #b3261e;
  --tickivo-hero-overlay: linear-gradient(180deg, rgb(0 0 0 / 0.15), rgb(0 0 0 / 0.65));
  --tickivo-hero-text: #ffffff;

  color-scheme: light;
}

/* Dark preset — set data-theme="dark" on <html>. Same tokens, re-tuned. */
:root[data-theme="dark"] {
  --bg: #121110;
  --surface: #1c1b19;
  --surface-2: #262421;
  --text: #f2f0ec;
  --muted: #a5a099;
  --border: #35322e;
  --shadow-1: 0 1px 2px rgb(0 0 0 / 0.4), 0 4px 12px rgb(0 0 0 / 0.4);
  --shadow-2: 0 2px 4px rgb(0 0 0 / 0.5), 0 12px 32px rgb(0 0 0 / 0.55);
  --tickivo-error: #ff7a6e;
  color-scheme: dark;
}

* { box-sizing: border-box; }

/* The shape layer's .bleed uses 100vw, which INCLUDES the scrollbar on
   desktops that show one — without this every bleed section overflows by
   the scrollbar's width and the page scrolls sideways. 'clip', not 'hidden':
   'hidden' makes <html> a scroll container and breaks position: sticky for
   every header in the library. Lives here, not in foundation/shape.ts, so
   no template can opt into bleed without it. */
html { overflow-x: clip; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  /* Baseline for ordinary prose: break a word only when it would otherwise
     overflow its box. Safe everywhere, and it catches the plain blocks the
     narrower rules below do not reach - a footer wordmark is a <p>, and a
     credo pull-quote is one oversized sentence. */
  overflow-wrap: break-word;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  line-height: 1.1;
  margin: 0 0 var(--space-md);
  letter-spacing: -0.01em;
  text-wrap: balance;
  /* A concept name is very often ONE long compound word — Swedish builds them
     by default ("Kulturforeningssammanslutningen") — and a display face renders
     it at 50-130px, so it can set a min-content width wider than the phone and
     scroll the whole page sideways. 'anywhere' fixes that by shrinking the
     intrinsic size, and it USED to be the rule here at every width.

     The cost was worse than the bug. 'anywhere' does not wait for a word to
     overflow; it lets the layout shrink the box first and then breaks the word
     to fit whatever is left. So a heading in a narrow grid column broke mid
     syllable on a 1440px desktop with room to spare — press rendered its about
     heading as "OM NOBELBE / RGET", which is the single most amateur thing a
     page can do to a customer's name.

     'break-word' breaks only a word that genuinely cannot fit its line, and it
     is paired below with 'min-width: 0' on the layout children that were the
     real cause of the sideways scroll: a flex/grid item defaults to
     'min-width: auto', which refuses to go below its content's min-content
     size. Fixing THAT is what makes the eager break unnecessary. Verified at
     390px across all eight templates: no page scrolls sideways. */
  overflow-wrap: break-word;
}
h1 { font-size: var(--step-4); }
h2 { font-size: var(--step-3); }
h3 { font-size: var(--step-1); }
p { margin: 0 0 var(--space-md); }
/* The chrome, whole. The header wordmark is the element that actually widens
   the top bar, and it is a link in one template and a paragraph in another, so
   targeting a tag name misses half of them. Everything in the header and
   footer is a short label or a name, where breaking beats a page that scrolls
   sideways - and scoping to the stamped chrome keeps 'anywhere' out of body
   copy, which keeps its gentler break-word baseline above. */
[data-tickivo-section="header-nav"] *,
[data-tickivo-section="footer"] * { overflow-wrap: anywhere; }

/* The other half of the wrap fix above. A flex or grid item is 'min-width:
   auto' by default, so it refuses to shrink below its content's min-content
   width — one long word in a heading then pushes its whole track wider than
   the viewport, and the page scrolls sideways no matter what the heading's
   overflow-wrap says. Zeroing it on the layout boxes is the actual repair;
   the heading rule above can then break words only when they truly do not
   fit, which is what keeps a venue's name whole on a desktop. */
.container > *,
.section > *,
.section-head { min-width: 0; }
img { max-width: 100%; display: block; }
a { color: inherit; }

.container {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--space-section); }
.section-head { max-width: 44rem; margin-bottom: var(--space-xl); }
.section-head p { color: var(--muted); font-size: var(--step-1); margin: 0; }

.eyebrow {
  display: block;
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--space-sm);
}
:root[data-theme="dark"] .eyebrow { filter: brightness(1.35) saturate(0.85); }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  padding: 0.85em 1.7em;
  border-radius: var(--radius);
  border: 1px solid transparent;
  font: 600 var(--step-0)/1.2 var(--font-body);
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
}
.btn:hover { transform: translateY(-1px); box-shadow: var(--shadow-1); }
.btn-primary { background: var(--accent); color: var(--accent-contrast); }
.btn-ghost { background: transparent; color: inherit; border-color: currentColor; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* layer: motion */
/* ============================================================
   Motion — scroll-driven plumbing. No keyframes live here: the
   template names them in --reveal-name / --parallax-name, and an
   element only moves once it carries data-reveal or data-parallax.
   Everything is inside @supports + prefers-reduced-motion, so an
   unsupported browser or a reduced-motion visitor sees the page
   still, with nothing hidden.
   ============================================================ */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    [data-reveal] {
      animation: var(--reveal-name, none) var(--reveal-easing, linear) both;
      animation-timeline: view();
      animation-range: var(--reveal-range, entry 10% cover 30%);
    }
    [data-parallax] {
      animation: var(--parallax-name, none) linear both;
      animation-timeline: view();
      animation-range: var(--parallax-range, cover 0% cover 100%);
    }
  }
}

/* layer: shape */
/* ============================================================
   Shape — bleed, arch, diagonal, overlap, tilt. Utilities a
   template's markup opts into by class. The overflow-x guard they
   rely on is in the foundation base, on <html>.
   ============================================================ */
.bleed {
  width: 100vw;
  margin-inline: calc(50% - 50vw);
}
.bleed-inset {
  width: calc(100vw - var(--gutter) * 2);
  margin-inline: calc(50% - 50vw + var(--gutter));
  border-radius: var(--radius-lg);
}
/* Percentages, not viewport units: a radius relative to the element's own
   box is the same arch at every container width. */
.shape-arch {
  border-radius: 50% 50% var(--radius-lg) var(--radius-lg) / 28% 28% var(--radius-lg) var(--radius-lg);
}
.shape-diagonal {
  clip-path: polygon(0 var(--slant, 4vw), 100% 0, 100% 100%, 0 100%);
}
.shape-diagonal-bottom {
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - var(--slant, 4vw)), 0 100%);
}
.overlap-up {
  margin-block-start: calc(var(--space-2xl) * -1);
  position: relative;
  z-index: 1;
}
.tilt-a { rotate: -2.5deg; }
.tilt-b { rotate: 1.8deg; }

/* layer: media */
/* ============================================================
   Media — image treatment, keyed on data-treatment on <html>.
   Wrap an authored image in .media and it takes the site's
   treatment; the gallery takes it through ::part(image). Every
   treatment is a filter chain on the image — no overlays, so a
   caption beside the image is never touched. The filters live in
   the <svg class="media-filters"> at the top of <body>.
   ============================================================ */
:root {
  --media-contrast: 1.6;
}

.media {
  display: block;
  overflow: hidden;
}
.media > img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* --- duotone: shadows to --duo-dark, highlights to --duo-light --- */
[data-treatment="duotone"] .media > img,
[data-treatment="duotone"] tickivo-gallery::part(image) {
  filter: grayscale(1) contrast(var(--media-contrast)) url(#duotone);
}

/* --- grain: colour kept, film grain inside the frame --------- */
[data-treatment="grain"] .media > img,
[data-treatment="grain"] tickivo-gallery::part(image) {
  filter: contrast(1.06) saturate(0.94) url(#grain);
}

/* --- halftone: dithered, then two-colour ---------------------- */
[data-treatment="halftone"] .media > img,
[data-treatment="halftone"] tickivo-gallery::part(image) {
  filter: grayscale(1) contrast(var(--media-contrast)) url(#halftone) url(#duotone);
}

/* layer: decor */
/* ============================================================
   Decor — sizing for the authored SVG motifs. They draw in
   currentColor, so colour is whatever the parent's is; set it
   with color: var(--accent) on the motif or its container.
   ============================================================ */
.decor {
  display: inline-block;
  width: 1.5em;
  height: auto;
  vertical-align: middle;
  flex: none;
}
.decor-lg { width: 4rem; }
.decor-xl { width: 7rem; }
.decor-rule { display: block; width: 100%; max-width: 12rem; height: auto; color: var(--muted); }
.decor-behind { position: absolute; inset: -0.35em -0.6em; width: auto; height: auto; z-index: -1; }

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Template: neon */
:root, :root[data-theme="dark"] {
  --bg: #0a1620;
  --surface: #101f2b;
  --surface-2: #16303f;
  --text: #eef8fb;
  --muted: #9ab9c4;
  --accent: #7fe0f5;
  --accent-contrast: #071820;
  --border: #234152;
  --font-display: Anton, Impact, 'Haettenschweiler', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-body: 'DM Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --radius-sm: 8px;
  --radius: 16px;
  --radius-lg: 28px;
  --duo-dark: var(--bg);
  --duo-light: var(--accent);
  color-scheme: dark;
}

/* neon motif */
/* RHYTHM, ON SECTION ROLES RATHER THAN ON CLASS NAMES.
   Cadence is a property of the PAGE, so it belongs in one place. Roles rather
   than this template's own section classes: motifCss is emitted BEFORE the
   section stylesheets, so a section-class rule here loses at equal specificity,
   and the seed's cascade guard requires the choreography to precede every
   section rule. */
/* Four boundaries measured 224-253px, all the same, and all four section heads
   were the identical 47.2px - one interior size and no rhythm. The marquee now
   runs into the calendar, the gallery gets the air (its content can carry it),
   and the heads step so the calendar reads as the main event. */
[data-tickivo-section="events"] { padding-block: var(--space-lg) clamp(2rem, 4vw, 3.25rem); }
[data-tickivo-section="tickets"], [data-tickivo-section="faq"] { padding-block: clamp(2rem, 3.5vw, 3rem); }
[data-tickivo-section="events"] .section-head h2 { font-size: clamp(2.5rem, 6vw, 5rem); }
[data-tickivo-section="faq"] h2 { font-size: var(--step-2); }
h1, h2, h3 { text-transform: uppercase; letter-spacing: 0.01em; line-height: 0.95; }
.eyebrow { letter-spacing: 0.2em; }
.btn { border-radius: 999px; text-transform: uppercase; letter-spacing: 0.06em; }

/* neon choreography: reveal */
/* Generic entrance for every data-reveal section (marquee, events, FAQ, and
   any future one): a soft rise-and-fade as it crosses into view. Defining
   --reveal-name/--reveal-easing here is what turns on the foundation's own
   [data-reveal] rule above, which otherwise defaults to no animation at all.
   Gated exactly like the heading flicker below: unsupported browsers and
   reduced-motion visitors keep the static, fully-visible page. */
@supports (animation-timeline: view()) {
@media (prefers-reduced-motion: no-preference) {
  :root {
    --reveal-name: s-neon-reveal;
    --reveal-easing: cubic-bezier(0.2, 0.7, 0.2, 1);
  }
  @keyframes s-neon-reveal {
    from { opacity: 0; transform: translateY(2rem); }
    to { opacity: 1; transform: translateY(0); }
  }
}
}

/* neon choreography: flicker */
@supports (animation-timeline: view()) {
@media (prefers-reduced-motion: no-preference) {
@keyframes neon-flicker {
  0% { opacity: 0.15; }
  30% { opacity: 1; }
  45% { opacity: 0.35; }
  60% { opacity: 1; }
  100% { opacity: 1; }
}
[data-reveal] :is(h1, h2, h3) {
  animation: neon-flicker steps(2, jump-none) both;
  animation-timeline: view();
  animation-range: entry 5% entry 25%;
}
}
}

.s-neon-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: rgb(15 10 26 / 0.92);
  border-bottom: 1px solid var(--border);
}
.s-neon-header-inner { display: flex; align-items: center; gap: var(--space-lg); padding-block: var(--space-sm); }
.s-neon-wordmark {
  font-family: var(--font-display);
  font-size: var(--step-1);
  text-transform: uppercase;
  text-decoration: none;
  margin-right: auto;
}
.s-neon-wordmark img { height: 1.8rem; width: auto; max-width: none; }
.s-neon-nav { display: none; gap: var(--space-lg); }
.s-neon-nav a {
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--muted);
}
.s-neon-nav a:hover { color: var(--text); }
.s-neon-account {
  display: inline-flex;
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.s-neon-account:hover { color: var(--text); }
.s-neon-header-cta { padding: 0.6em 1.4em; font-size: var(--step--1); }
@media (min-width: 860px) { .s-neon-nav { display: flex; } }

.s-neon-hero--image { padding: 0; position: relative; }
.s-neon-hero-media {
  display: grid;
  height: clamp(22rem, 62vw, 46rem);
}
/* Mini-gallery: four brand photos cross-fade in an endless loop. Every slide
   is stacked in the SAME grid cell (grid-area: 1 / 1), not positioned with
   absolute/inset — that stacking survives regardless of what a parent's own
   layout rules do, which is the fix for the images rendering as a plain
   vertical list on the published site. Delays are plain, literal values on
   nth-child, not custom-property arithmetic, for the same reason: the most
   compatible path across every browser that publishes this page. Reduced
   motion holds the first photo still. */
.s-neon-hero-media img {
  grid-area: 1 / 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.s-neon-hero-slide { opacity: 0; }
.s-neon-hero-slide:first-child { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  .s-neon-hero-slide {
    animation: s-neon-hero-crossfade 24s linear infinite both;
  }
  .s-neon-hero-slide:nth-child(1) { animation-delay: -24s; }
  .s-neon-hero-slide:nth-child(2) { animation-delay: -18s; }
  .s-neon-hero-slide:nth-child(3) { animation-delay: -12s; }
  .s-neon-hero-slide:nth-child(4) { animation-delay: -6s; }
}
@keyframes s-neon-hero-crossfade {
  0%, 20% { opacity: 1; }
  25%, 95% { opacity: 0; }
  100% { opacity: 1; }
}


.s-neon-events tickivo-events::part(list) { display: block; }
.s-neon-events tickivo-events::part(card) {
  display: flex;
  align-items: center;
  gap: var(--space-lg);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-md);
  margin-bottom: var(--space-sm);
  transition: background-color 0.15s ease, border-color 0.15s ease;
}
.s-neon-events tickivo-events::part(card):hover { background: var(--surface-2); border-color: var(--accent); }
.s-neon-events tickivo-events::part(image) {
  width: 5rem;
  height: 5rem;
  flex: none;
  border-radius: var(--radius);
  aspect-ratio: 1;
}
.s-neon-events tickivo-events::part(body) { padding: 0; }
.s-neon-events tickivo-events::part(title) {
  font-family: var(--font-display);
  font-size: var(--step-2);
  text-transform: uppercase;
  margin: 0 0 var(--space-2xs);
}
.s-neon-events tickivo-events::part(meta) {
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  opacity: 1;
}

/* The FAQ is the last data-reveal section before the static footer, so it
   has the least scroll room left to complete its entry-to-cover range on a
   short page. A tighter, earlier range means it finishes fading in almost as
   soon as it starts entering, instead of risking staying part-way faded on
   pages that run out of scroll distance before the default range resolves. */
[data-tickivo-section="faq"] { --reveal-range: entry 0% cover 12%; }

.s-neon-faq tickivo-faq::part(item) {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: var(--space-xs);
  padding-inline: var(--space-md);
}
.s-neon-faq tickivo-faq::part(question) { font-weight: 700; }
.s-neon-faq tickivo-faq::part(answer) { color: var(--muted); }

.s-neon-footer { padding-block: var(--space-2xl) var(--space-lg); border-top: 1px solid var(--border); }
.s-neon-footer-wordmark {
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 12vw, 8rem);
  line-height: 0.85;
  text-transform: uppercase;
  /* --surface-2 on --bg is 1.16:1: not a watermark, an invisible one. The
     section reads as a name bled off the edge, so it has to be legible as a
     name. color-mix lifts it clear of the ground while keeping it well under
     the display type above, so it still recedes. */
  color: color-mix(in srgb, var(--muted) 55%, var(--bg));
  margin: 0 0 var(--space-lg);
  overflow-wrap: break-word;
}
.s-neon-footer-band {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md) var(--space-lg);
  justify-content: space-between;
  align-items: center;
  border-top: 1px solid var(--border);
  padding-top: var(--space-md);
}
.s-footer-links { display: flex; flex-wrap: wrap; gap: var(--space-lg); }
.s-footer-links a,
.s-neon-footer-legal {
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
  margin: 0;
}
.s-footer-links a:hover { color: var(--accent); }

.s-event-page-bar { padding-block: var(--space-md); border-bottom: 1px solid var(--border); }
.s-event-page-bar-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-md); }
.s-event-page-back { font-size: var(--step--1); font-weight: 600; text-decoration: none; color: var(--muted); }
.s-event-page-back:hover { color: var(--text); }
.s-event-page-account { display: inline-flex; font-size: var(--step--1); font-weight: 600; color: var(--muted); }
.s-event-page-account:hover { color: var(--text); }
.s-event-page-body {
  display: grid;
  gap: var(--space-xl);
  padding-block: var(--space-xl) var(--space-section);
  align-items: start;
}
.s-event-page-info { display: grid; gap: var(--space-lg); }
.s-event-page-footer { text-align: center; padding-block: var(--space-xl); color: var(--muted); font-size: var(--step--1); }
@media (min-width: 900px) {
  .s-event-page-body { grid-template-columns: 1.1fr 0.9fr; gap: var(--space-2xl); }
  .s-event-page-checkout { position: sticky; top: var(--space-lg); }
}
