/* ==========================================================================
   Team #RIProken — karting landing page

   Every value below is taken from riproken.be's own Elementor stylesheet, not
   estimated. The four brand tokens are its global colour roles; the type scale,
   button spec and 4px mint frames are lifted from the live rules.

     --e-global-color-primary   #142837   navy   (page + button text)
     --e-global-color-secondary #6EE6DC   mint   (frames, links, accents)
     --e-global-color-accent    #FAFF14   yellow (buttons, highlights)
     --e-global-color-text      #FFFFFF   white  (body copy)

   #FFBC7D exists on their site but only as a page-transition colour, so it is
   deliberately not used as a UI colour here.

   Type: proxima-nova at 900 / 600 / 400 (Adobe kit ort8pew, domain-locked to
   riproken.be — see README). Figtree is the closest freely-licensed stand-in:
   geometric sans, tall x-height, real 900 weight.

   Corners are square. riproken.be sets border-radius 0 everywhere; the only
   radius is Elementor's 3px default on buttons, kept here.
   ========================================================================== */

:root {
  --navy:      #142837;
  --mint:      #6EE6DC;   /* riproken.be's token: frames, links, hero accents */
  --mint-2:    #80E9E4;   /* BBDO's PSD, measured: band fills and on-navy accents */
  --yellow:    #FAFF14;
  --white:     #ffffff;

  /* Tints derived from the tokens — used for panels and hairlines only. */
  --navy-2:    #0f1f2b;
  --navy-3:    #1b3446;
  --ink-soft:  rgba(255,255,255,.78);
  --ink-faint: rgba(255,255,255,.55);

  /* The content width of .wrap, restated so elements that must scale with the
     container (the kart) can compute against it. Keep in step with .wrap. */
  --cw:        calc(min(1130px, 100vw) - 2 * clamp(20px, 8.8vw, 88px));

  --frame:     4px;            /* mint image frame, per their image rules */
  --wrap:      1130px;         /* their --container-max-width */
  --font:      'Proxima Nova', 'proxima-nova', Figtree, system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* ONE type scale for the whole page.
     Anke's feedback of 07/09/2026: the sizes were switching everywhere and the
     form and the popup were too small to read. Every piece of type below now
     comes from one of these six values and nothing renders under 16px.
     Do not introduce a seventh: if something needs a new size, the scale is
     wrong, not the element. */
  --fs-marker:  clamp(1.9rem, 5vw, 3.1rem);      /* the yellow marker headings, PSD 50px */
  --fs-display: clamp(1.75rem, 4vw, 2.5rem);     /* h1 and section titles, PSD 40px */
  --fs-h2:      clamp(1.5rem, 3.2vw, 2rem);      /* mint band, popup title, PSD 35px */
  --fs-h3:      clamp(1.15rem, 2.4vw, 1.375rem); /* step headings, creator names */
  --fs-lead:    clamp(1.15rem, 2.1vw, 1.375rem); /* intro paragraphs and bullet lists */
  --fs-body:    1.1875rem;                       /* 19px, the default */
  --fs-small:   1rem;                            /* 16px, the floor */
}

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background-color: var(--navy);
  /* Their dot pattern, same asset, anchored top-right like the original. */
  background-image: url('../img/dots-bg.png');
  background-repeat: no-repeat;
  background-position: right -120px top -80px;
  background-attachment: scroll;
  color: var(--white);
  font-family: var(--font);
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; display: block; }

/* Any author rule that sets display beats the UA's [hidden] { display: none },
   so .btn[hidden] and figure[hidden] would both stay on screen. This is what
   makes the hidden attribute mean what it says. */
[hidden] { display: none !important; }

a { color: var(--mint); text-decoration: underline; text-underline-offset: 3px; }
a:hover { color: var(--mint); text-decoration-thickness: 2px; }

/* PSD: 850 content in a 1004 viewport, so ~77px of side padding, not 24.
   Everything downstream was scaling ~12% larger than the design because of it. */
.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 clamp(20px, 8.8vw, 88px); }

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

.skip { position: absolute; left: -9999px; background: var(--yellow); color: var(--navy); padding: 10px 16px; z-index: 99; }
.skip:focus { left: 12px; top: 12px; }

/* ---------- type ----------
   Display 64px/61px uppercase 900; section heads 42px with +1.6px tracking;
   sub-heads 27–30px. Their tracking is POSITIVE on headings, not tight. */

/* PSD: 80px at 2x = 40px, sentence case, tracking 0. The uppercase and the
   +1.6px tracking on riproken.be's own section heads are not used here. */
.section-title {
  font-weight: 900; text-transform: none;
  font-size: var(--fs-display);
  line-height: 1.05; letter-spacing: 0; margin: 0 0 18px;
}
/* PSD: body copy is #FFFFFF, 40px at 2x = 20px. */
.section-lede, .lede { font-size: var(--fs-lead); color: var(--white); max-width: 72ch; }
/* The small print. It is small in rank, not unreadable: 16px, and on the softer
   white rather than the faint one, which measured under 4.5:1 on the navy. */
.micro { font-size: var(--fs-small); color: var(--ink-soft); }

/* Bold carries emphasis in body copy — 900 matches their heading weight. */
strong, b { font-weight: 900; color: var(--white); }

/* ---------- buttons ----------
   Their exact spec: yellow fill, navy text, 1px yellow border, 19px/23px,
   weight 900, uppercase. Hover inverts to a transparent ghost with yellow
   text and the same yellow border. */
.btn {
  display: inline-block; cursor: pointer;
  background-color: var(--yellow);
  color: var(--navy);
  border: 1px solid var(--yellow);
  border-radius: 3px;
  font-family: var(--font);
  font-size: 19px; line-height: 23px; font-weight: 900;
  text-transform: uppercase; text-decoration: none;
  padding: 12px 24px;
  transition: background-color .3s, color .3s;
}
.btn:hover, .btn:focus-visible {
  background-color: transparent;
  color: var(--yellow);
  border-color: var(--yellow);
}
.btn:focus-visible { outline: 2px solid var(--mint); outline-offset: 3px; }
.btn--sm { font-size: var(--fs-small); line-height: 19px; padding: 9px 18px; }
.btn--lg { font-size: 20px; line-height: 25px; padding: 15px 30px; }
.btn--xl {
  /* Was 52px on a 476 x 144 box. The client found that far too big in the
     08/09/2026 meeting, so it comes back to the PSD's own 35px and the box
     shrinks with it. Still the largest button on the page, which is the point:
     it is what opens the form. */
  font-size: clamp(1.375rem, 3.4vw, 2.1875rem); line-height: 1.15;
  padding: clamp(14px, 2.6vw, 22px) clamp(26px, 4.4vw, 44px);
  min-width: min(340px, 100%);
  border-radius: 22px;
  text-transform: none;             /* the PSD sets it in sentence case */
  letter-spacing: 0;
}
.btn--submit { width: 100%; max-width: 340px; margin-top: 10px; }
.btn[disabled] { opacity: .55; cursor: progress; }

/* ---------- topbar ----------
   Mint bar with navy logo and navy nav, exactly as on riproken.be. */
.topbar {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 14px 24px;
  background: var(--mint);
  color: var(--navy);
}
.topbar__logo { display: block; color: var(--navy); }
.topbar__logo img { width: 184px; height: auto; }
.topbar__nav { display: flex; flex-wrap: wrap; gap: 20px; font-size: var(--fs-small); font-weight: 900; }
.topbar__nav a { color: var(--navy); text-decoration: none; }
.topbar__nav a:hover, .topbar__nav a.is-current { color: var(--navy); text-decoration: underline; text-decoration-thickness: 3px; text-underline-offset: 4px; }

/* ---------- hero ----------
   Key visual left, copy right, exactly as in BBDO's design. The "Doe mee"
   button sits under the first paragraph (Anke's feedback) and jumps straight to
   the form at the bottom of the page. */
.hero { position: relative; padding: clamp(44px, 6vw, 80px) 0 clamp(52px, 7vw, 92px); }
.hero__inner {
  position: relative;
  /* PSD: the visual is 311 wide and the copy 470 in an 850 container, so 40/60
     of the space either side of a 69px gap. */
  display: grid; grid-template-columns: 310fr 449fr; gap: clamp(28px, 6.8vw, 69px);
  /* PSD: the copy block is vertically centred against the image, not top-aligned. */
  align-items: center;
}
.hero__visual { margin: 0; }
.hero__title {
  font-weight: 900;
  font-size: var(--fs-display);
  line-height: 1.05; letter-spacing: 0; margin: 0 0 20px;
}
.hero__title em { font-style: normal; color: var(--mint); }  /* they colour, not italicise */
.hero__copy .btn { margin: 30px 0 0; }
.lede--mint { color: var(--mint); font-weight: 600; }

/* No frame here: measured off the PSD, the key visual sits straight on the
   navy. 896x1593 is the delivered asset, so the ratio is its own. */
.hero__visual img {
  width: 100%; aspect-ratio: 896 / 1593;
  /* PSD height. Past the design width the box gets wider rather than taller and
     the crop takes it off the top and bottom, which keeps the proportion the
     mockup has instead of a very tall portrait on a big screen. */
  max-height: 552px;
  object-fit: cover; object-position: center 42%;
  background: var(--navy-3);
}

/* ---------- marker heading ----------
   /* Measured off the PSD's own pixels rather than its layer boxes, because those
   marker layers are masked.

   Each LINE gets its own bar, and the two are different widths because each one
   hugs its own text: 294 for "Wat kan", 370 for "je winnen?". The second is
   staggered 42px further left, which is what makes them read as two overlapping
   strokes rather than one slab. Each bar is 80 tall for a 50px line, so the line
   box IS the bar height with no vertical padding.

   They are skewed, not rotated: measured, the horizontal edges slant 9.9 degrees
   while the vertical edges stay exactly vertical. Skewing also leaves the type's
   vertical strokes upright, which is why it reads as a marker stroke. */
.marker {
  margin: 0 0 30px;
  font-weight: 900; text-transform: none; letter-spacing: 0;
  font-size: var(--fs-marker);
  line-height: 1.6;
}
.marker span {
  display: table; text-align: center;
  background: var(--yellow); color: var(--navy);
  padding: 0 .56em;
  /* PSD: 294 wide at a 50px type size, with the line centred in it. */
  min-width: min(5.88em, 88vw);
  transform: skewY(-10deg);
  position: relative; z-index: 1;
}
/* PSD: the second bar is wider, 370, and sits 42px left of the first. */
.marker span + span { min-width: min(7.4em, 88vw); margin-left: -.84em; }

/* PSD: the first bar starts 10px left of the container edge. */
.marker--bleed { margin-left: -.21em; }

/* The single-line marker is centred. Its bottom margin has to clear the skew as
   well as the gap: a skewed box overflows its own height by width*tan(10)/2,
   which is what was letting it sit on the text below. */
.marker--wide { margin: 0 auto 86px; text-align: center; }
.marker--wide span { margin: 0 auto; min-width: min(11.47em, 100%); line-height: 1.8; }  /* PSD: 573.5 x 90 */

/* ---------- prizes (arena backdrop) ---------- */
/* The band is clipped nowhere: in the PSD the kart hangs past its left edge and
   about 110px below it. overflow stays visible so that can happen. */
/* The mint fill from the PSD is gone: the client's mail of 09/09/2026 delivered
   'landingspagina backdrop.png', the blurred Rocket League arena, as the
   background for this block, with a mock-up showing the kart and the bullets
   sitting on it. The image is 1920x1434 and this band is far wider than tall,
   so cover crops it top and bottom. The vertical anchor is 72%, not centre:
   measured in the browser, centre lands on the blurred stand and only 72%
   brings the floor logo up behind the kart, which is what the mock-up shows. The navy under it is what a
   viewport wider than the asset gets, and what shows while it loads.
   The gradient on top is not decoration: the bullets are white type over a
   photograph, and without it they land on the bright pink and yellow signage.
   It darkens towards the right, where the copy column is. */
.prizes {
  color: var(--white);
  background:
    linear-gradient(100deg, rgba(20,40,55,.30) 0%, rgba(20,40,55,.62) 46%, rgba(20,40,55,.78) 100%),
    url('../img/prizes-backdrop.webp') center 72% / cover no-repeat,
    var(--navy);
  padding: clamp(28px, 5.2vw, 52px) 0 clamp(70px, 16.8vw, 169px);
  /* The heading bleeds off the left edge and the kart hangs below the band, so
     x is clipped to keep the page from scrolling sideways while y stays free.
     clip, not hidden: hidden on one axis forces a scroll container on both. */
  overflow-x: clip; overflow-y: visible;
}
.prizes__inner {
  display: grid; grid-template-columns: 334fr 464fr; gap: clamp(20px, 3vw, 30px);
  align-items: center;
}
.prizes__left { min-width: 0; }
.prizes__copy { padding-bottom: 6px; }

/* The kart. In the PSD the whole 1298px asset is placed 649 wide spanning -130
   to 519, but its left third is a speckled tyre-mark trail that reads as dirt on
   the mint. The asset is cropped to drop it, so what is placed here is the kart
   and its smoke only: 479 wide with its left edge at 40, which is exactly where
   the kart itself sits in the design.
   It rises into the bottom of the second marker bar and hangs 110px below
   the band, in front of both. Everything is a share of --cw, the container
   width: the column is far narrower, and the viewport keeps growing after the
   container has stopped. */
.prizes__visual {
  margin: 0; position: relative; z-index: 2;
  margin-top: calc(-.054 * var(--cw));
  margin-bottom: calc(-.302 * var(--cw));
}
.prizes__visual img {
  max-width: none;                  /* the global img cap would clamp it to the column */
  width: calc(.5785 * var(--cw));   /* the design's 479, at our slightly narrower container */
  margin-left: calc(-.058 * var(--cw));
}

.icon-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 16px; }
.icon-list li {
  display: grid; grid-template-columns: 1.7em 1fr; gap: 12px;
  font-size: var(--fs-lead); line-height: 1.45; font-weight: 600;
}
.icon-list span { font-size: 1.25em; line-height: 1.1; }
/* Centred variant: the emoji sits inline before the text, as in the design. */
.icon-list--center { text-align: center; }
.icon-list--center li { display: block; }
.icon-list--center li span { margin-right: 6px; }

/* ---------- dates ---------- */
.events {
  padding: clamp(52px, 7vw, 92px) 0 clamp(24px, 4.8vw, 48px);
  /* The tile row bleeds past the container, and on a narrow viewport that bleed
     was widening the document and giving the page a horizontal scrollbar.
     clip, not hidden: hidden here would make the section a scroll container. */
  overflow-x: clip;
}
.events .section-title { margin-bottom: 30px; }
.slider { position: relative; }
.events__track {
  /* PSD: the row runs from 57 to 940 in a 1004 viewport, so it bleeds past the
     container on both sides. */
  list-style: none; margin: 0 max(-2.7vw, -27px); padding: 0 0 6px;
  display: grid; gap: 18px;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

.event { display: flex; }
.event__card {
  /* No gap: the names sit in a box that continues the image's frame, so the two
     read as one card. Client, 08/09/2026: the names "zweefden" under the
     visuals. */
  display: flex; flex-direction: column; gap: 0; width: 100%;
  padding: 0; margin: 0; text-align: left;
  background: transparent; border: 0; color: inherit;
  /* font shorthand resets family, size, weight and line-height in one go.
     text-transform and letter-spacing are NOT part of it, and riproken.be's
     kit sets text-transform: uppercase on every button, which inherits into
     the creator names once this page is embedded in their theme. Caught by
     tools/embed_harness.py. */
  font: inherit; text-transform: none; letter-spacing: normal;
}
/* The tiles no longer lead anywhere. Anke, 07/09/2026: clicking a race day
   jumped you into the entry form, which she asked us to switch off. They are
   plain figures now, and the creator names below them are the point of the
   section. */
.event__img { position: relative; display: block; }
.event__img img {
  width: 100%; aspect-ratio: 1 / 1; object-fit: cover;
  /* Measured off the PSD: 4px at 2x, so half the 4px frame used elsewhere. */
  border: 2px solid var(--mint);
  background: var(--navy-3);
  transition: border-color .3s;
}

/* The yellow date badge from the design, bottom-left over the image. */
.event__date {
  position: absolute; left: 10px; bottom: 10px;
  background: var(--yellow); color: var(--navy);
  font-weight: 900; font-size: var(--fs-small); line-height: 1.1;
  padding: 6px 10px; transform: rotate(-3deg);
}
/* BBDO's visuals have the date burned in, so ours is for screen readers only.
   Not display:none, which would take it out of the accessibility tree too. */
.event__date--in-image {
  position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; transform: none;
}

.event__badge {
  position: absolute; right: 10px; top: 10px;
  background: var(--white); color: var(--navy);
  font-size: var(--fs-small); font-weight: 900; letter-spacing: 1.2px; text-transform: uppercase;
  padding: 4px 9px;
}

/* The creator line-up, per race day. This used to live only in the image's alt
   text and in whatever BBDO had burned into the visual, which is what Anke
   meant by "die staan heel klein". One name per line, at heading size. */
/* Weight is 600, not 900: the client asked for "iets minder vet" on 09/09/2026.
   The kit carries 900 / 600 / 400 only, so 600 is the next real face down and
   700 would have the browser synthesise one. */
.event__creators {
  list-style: none; margin: 0; padding: 12px 14px 14px;
  /* Continues the image's own 2px mint frame downward: same colour, same width,
     no top edge, so the tile and its line-up are a single box. */
  border: 2px solid var(--mint); border-top: 0;
  background: var(--navy-3);
  display: grid; gap: 4px;
  flex: 1;                          /* equal-height boxes across the row */
}
.event__creators li {
  font-size: var(--fs-h3); font-weight: 600; line-height: 1.25;
  color: var(--mint-2);
}

/* A race whose entry period has passed: visibly done.
   Driven by closesAt in data/events.json, one week before the race. */
/* A closed day's frame goes quiet with the image it belongs to. */
.event--closed .event__creators, .event--tbc .event__creators { border-color: var(--ink-faint); }
.event--closed .event__img img { filter: grayscale(1); opacity: .4; }
.event--closed .event__date { background: var(--white); }
.event--tbc .event__img img { filter: grayscale(1); opacity: .45; }
.event--closed .event__creators li, .event--tbc .event__creators li { color: var(--ink-faint); }

.slider__nav { display: none; }
/* Set here, not only inside the mobile block: a <button> with no font-size
   falls back to the UA's 13px, which is one more size on the page. */
.slider__btn { font-size: var(--fs-body); }

/* ---------- steps ---------- */
.brief { padding: clamp(24px, 4.8vw, 48px) 0 clamp(20px, 3vw, 34px); }
.steps { counter-reset: step; list-style: none; margin: 34px 0 0; padding: 0; display: grid; gap: 26px; }
.steps li { counter-increment: step; display: grid; grid-template-columns: 62px 1fr; gap: 18px; }
.steps li::before {
  content: counter(step);
  display: flex; align-items: center; justify-content: center;
  /* PSD: 96x110 at 2x, skewed like the markers. */
  width: 48px; height: 55px;
  transform: skewY(-10deg);
  background: var(--yellow); color: var(--navy);
  font-weight: 900; font-size: 1.6rem;
}
/* PSD: the heading sits beside the number, the description below it at the
   container's left edge rather than indented under the heading. */
.steps li { grid-template-areas: "num head" "body body"; }
.steps li::before { grid-area: num; }
.steps h3 { grid-area: head; }
.steps h3 {
  margin: 6px 0 8px; color: var(--mint-2); font-weight: 900;
  font-size: var(--fs-h3); line-height: 1.15;
}
/* Full container width and 19px, which is what the PSD measures and what puts
   the first step's sentence on a single line as the design has it. */
.steps p {
  grid-area: body; margin: 4px 0 0; color: var(--white);
  max-width: none; font-size: var(--fs-body);
}

/* ---------- good to know ---------- */
.know { padding: clamp(40px, 6vw, 74px) 0; }
.know__inner { text-align: center; }
.know__grid { display: grid; grid-template-columns: 1.15fr .85fr; gap: clamp(24px, 4vw, 48px); align-items: center; }
/* With the visual slot still hidden, the bullets take the full width, which is
   how the PSD has it. Remove [hidden] from the figure and this stops applying. */
.know__grid:has(.know__visual[hidden]) { grid-template-columns: 1fr; }
/* Same size as the other bullet list. The PSD ran these larger; two lists at two
   sizes is exactly the switching Anke flagged, so they match. */
.know .icon-list li { color: var(--mint-2); font-size: var(--fs-lead); line-height: 1.35; font-weight: 400; }
.know__visual { margin: 0; }
.know__visual img { width: 100%; border: var(--frame) solid var(--mint); aspect-ratio: 1 / 1; object-fit: cover; background: var(--navy-3); }
.know .micro { margin-top: 26px; }

/* Placeholder slot: BBDO is still adding a visual here. */
.know__visual.is-placeholder img { opacity: .55; }

/* ---------- repeat entries (mint band) ---------- */
.repeat { background: var(--mint-2); color: var(--navy); padding: clamp(30px, 4.5vw, 46px) 0; text-align: center; }
/* PSD 70px at 2x = 35px for both the heading and the two lines under it. */
.repeat h2 {
  margin: 0 0 8px; font-weight: 900; letter-spacing: 0;
  font-size: var(--fs-h2); line-height: 1.15;
}
/* Both lines are one size in the PSD, and they stay one size here. */
.repeat p { margin: 0; font-size: var(--fs-h2); line-height: 1.25; }

/* ---------- form ---------- */
.signup { padding: clamp(52px, 7vw, 92px) 0 clamp(60px, 8vw, 105px); background: var(--navy-2); }

/* The form unfurls from the big button. Collapsed state is applied by JS, so the
   form is plain visible when JavaScript does not run. visibility keeps the
   fields out of the tab order while it is shut. */
/* The form unfurls from the big button. The height is animated from 0 to the
   measured content height in JS and then released to auto, rather than the
   0fr/1fr grid trick: an fr track in an auto-height container resolves to the
   free space, which is zero here, so it never opened.

   visibility is deliberately NOT transitioned. It would stay "visible" for the
   duration of the initial collapse, leaving the fields tabbable. */
.formwrap {
  height: 0; overflow: hidden; visibility: hidden;
  transition: height .45s ease;
}
.formwrap.is-open { visibility: visible; }
.formwrap .form { margin-top: 0; }
.signup__toggle { margin-bottom: 8px; }
.signup { text-align: center; }
.signup .form { text-align: left; }
.form { max-width: 680px; margin: 34px auto 0; }
.btn--submit { display: block; margin-left: auto; margin-right: auto; }
.form > .micro { text-align: center; margin-top: 34px; }
.form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.field { margin-bottom: 22px; }
/* Anke, 07/09/2026: no capitals as titles, and the labels were too small to
   read. They are body size, bold, sentence case. */
.field label, .checks legend {
  display: block; font-weight: 900; font-size: var(--fs-body);
  text-transform: none; letter-spacing: 0; line-height: 1.3; margin-bottom: 10px;
}
.req { color: var(--yellow); }

input[type="text"], input[type="email"], input[type="tel"], select {
  width: 100%; padding: 13px 14px;
  background: var(--navy); color: var(--white);
  border: 1px solid var(--mint); border-radius: 0;
  font-family: var(--font); font-size: var(--fs-body);
}
select:disabled { opacity: .45; }
input:focus, select:focus { outline: 0; border-color: var(--yellow); }
.hint { margin: 7px 0 0; font-size: var(--fs-small); color: var(--ink-soft); }

.upload { position: relative; }
/* Visually hidden but still focusable and still in the accessibility tree.
   display is forced: something in riproken.be's stylesheets computes this input
   to display:none once the page is embedded there, which silently killed the
   picker. The label above is a real <label for>, so the control works either
   way; this keeps keyboard focus working too. */
.upload input[type="file"] {
  display: block !important;
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0; cursor: pointer;
}
.upload:focus-within .upload__label { border-color: var(--yellow); color: var(--white); }

/* riproken.be's theme JS (main.*.js) hunts down every input[type=file] on the
   page, sets style="display:none" on it inline, and injects its own widget next
   to it: a <label class="custom-file-upload"> and a <span id="file-selected">.
   That is why the input is forced back above, and why anything else their script
   drops into our dropzone is hidden here. Matching on "not ours" rather than on
   their class names, so a rename on their side cannot bring it back. */
.upload > *:not(input[type="file"]):not(.upload__label) { display: none !important; }
.upload__label {
  display: block; padding: 26px 16px; text-align: center; cursor: pointer;
  font-weight: 400; text-transform: none; letter-spacing: normal;
  border: 2px dashed var(--mint); background: var(--navy);
  color: var(--ink-soft); font-size: var(--fs-body);
}
.upload--over .upload__label, .upload input:focus + .upload__label { border-color: var(--yellow); color: var(--white); }
.upload--filled .upload__label { border-style: solid; border-color: var(--mint); color: var(--white); }

/* Upload progress. Only appears for a file large enough to be sent in parts,
   which is the only case where a person is left waiting long enough to wonder
   whether anything is happening. */
.uploadbar { margin: 12px 0 0; }
.uploadbar__track { height: 10px; background: var(--navy-3); border: 1px solid var(--mint); }
.uploadbar__fill {
  height: 100%; width: 0; background: var(--yellow);
  transition: width .2s linear;
}
.uploadbar__label { margin: 8px 0 0; font-size: var(--fs-small); color: var(--ink-soft); }

.checks { border: 0; margin: 10px 0 26px; padding: 0; }
.checks legend { margin-bottom: 14px; }
.check {
  display: grid; grid-template-columns: 22px 1fr; gap: 12px; align-items: start;
  margin-bottom: 15px; font-size: var(--fs-body); font-weight: 400;
  text-transform: none; letter-spacing: 0; line-height: 1.5;
  color: var(--ink-soft); cursor: pointer;
}
.check input { width: 20px; height: 20px; margin: 2px 0 0; accent-color: var(--mint); }

.err { margin: 7px 0 0; font-size: var(--fs-small); color: var(--yellow); font-weight: 600; }
.err:empty { display: none; }
.err--form { margin-bottom: 14px; font-weight: 900; }
.field--invalid input, .field--invalid select { border-color: var(--yellow); border-width: 2px; }

/* ---------- footer ---------- */
.footer { padding: 44px 0; background: var(--navy); }
.footer__inner { display: grid; gap: 18px; justify-items: start; }
.footer__links { display: flex; flex-wrap: wrap; gap: 20px; font-size: var(--fs-small); font-weight: 600; }

/* ---------- modal ---------- */
.modal { border: 0; padding: 0; background: transparent; max-width: 470px; width: calc(100% - 32px); }
.modal::backdrop { background: rgba(15,31,43,.82); }
.modal__inner {
  background: var(--navy-3); color: var(--white);
  padding: 34px 30px; text-align: center;
  border: 4px solid var(--mint);
}
.modal__flag {
  width: 64px; height: 44px; margin: 0 auto 20px;
  background: repeating-conic-gradient(var(--white) 0% 25%, var(--navy) 0% 50%) 0 0 / 16px 16px;
}
/* The closing popup carried three different sizes and the smallest was
   unreadable (Anke, 07/09/2026). Title, body and small print now come from the
   same scale as the page, and the title is sentence case like every other one. */
.modal__inner h2 {
  margin: 0 0 14px; text-transform: none; font-weight: 900;
  font-size: var(--fs-h2); letter-spacing: 0; line-height: 1.05;
}
.modal__inner p { color: var(--white); font-size: var(--fs-body); }
.modal__inner .micro { color: var(--ink-soft); }
.modal__inner .btn { margin-top: 20px; }

/* ==========================================================================
   Responsive. Their breakpoints: 1024 (tablet) and 767 (mobile), with the
   display size dropping 64px -> 55px. Event tiles become a snap slider on
   small screens, as agreed on the call.
   ========================================================================== */
/* The PSD is laid out at ~1004px wide and still has a two-column hero and a
   two-column mint band there, so those hold well below their breakpoint. */
@media (max-width: 860px) {
  .hero__inner { grid-template-columns: 1fr; }
  .hero__visual { display: flex; justify-content: center; }
  .hero__visual img { max-height: 70vh; width: auto; }
  .prizes__inner, .know__grid { grid-template-columns: 1fr; }
  /* Stacked, the band is taller than wide, so cover blows the arena up to a
     narrow slice and the diagonal scrim no longer lines up with a copy column
     that now runs full width. One flat, heavier scrim instead. */
  .prizes {
    background:
      linear-gradient(rgba(20,40,55,.66), rgba(20,40,55,.66)),
      url('../img/prizes-backdrop.webp') center 72% / cover no-repeat,
      var(--navy);
  }
  /* Stacked on mobile, so the bullets follow the kart in the flow. The desktop
     lift into the marker and the overhang below the band would drag them
     underneath it. */
  .prizes__visual { margin-top: 0; margin-bottom: 14px; }
  .prizes__visual img { width: min(112%, 460px); margin-left: max(-6%, -26px); }
  .know__visual { max-width: 380px; margin: 0 auto; }
  .topbar { flex-wrap: wrap; }
  body { background-position: right -180px top -120px; }
}

@media (max-width: 767px) {
  /* No body size override here: the scale already clamps, and dropping the base
     size on mobile was one more size switch. */
  .hero__title { font-size: clamp(1.9rem, 8vw, 2.6rem); }
  .steps li { grid-template-columns: 40px 1fr; gap: 14px; }
  .steps li::before { width: 36px; height: 36px; font-size: 1.2rem; }
  .form__row { grid-template-columns: 1fr; gap: 0; }

  .events__track {
    /* No bleed on mobile: the row already scrolls, and the negative margins
       only widened the page. */
    margin-inline: 0;
    display: flex; grid-template-columns: none;
    overflow-x: auto; scroll-snap-type: x mandatory;
    gap: 16px; padding-bottom: 14px;
    scrollbar-width: none; -ms-overflow-style: none;
  }
  .events__track::-webkit-scrollbar { display: none; }
  .event { flex: 0 0 72%; scroll-snap-align: center; }

  .slider__nav { display: flex; align-items: center; justify-content: center; gap: 14px; margin-top: 8px; }
  .slider__btn {
    border: 1px solid var(--mint); background: transparent; color: var(--mint);
    width: 42px; height: 42px; cursor: pointer; font-weight: 900;
    text-transform: none; letter-spacing: normal;   /* their kit styles all buttons */
  }
  .slider__btn[disabled] { opacity: .3; cursor: default; }
  .slider__dots { display: flex; gap: 8px; list-style: none; margin: 0; padding: 0; }
  .slider__dots li { width: 8px; height: 8px; background: rgba(255,255,255,.3); }
  .slider__dots li.is-active { background: var(--yellow); width: 22px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { transition: none !important; }
}
