/* Arjan Huizer — implementation of "Arjan Huizer.dc.html" design */

:root {
  --sand:      #f4efe3;
  --sand-warm: #efe8d6;
  --ink:       #2a2331;
  --ink-soft:  #4a4152;
  --purple:    #93758f;
  --terra:     #c2857a;
  --gold:      #e3d5a3;
  --green:     #7d976a;
  --line:      #d9d0bc;
  --gutter:    42px;
  --maxw:      1200px;

  /* Body copy. The design file set it at 17px light; older readers asked
     for more, so paragraphs run 19px regular. Change it here, not per block. */
  --fs-body:   19px;
  --fw-body:   400;
  --lh-body:   1.75;
}

/* ---------- reset / base ---------- */

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

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--sand);
  color: var(--ink);
  font-family: 'Karla', sans-serif;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--purple); text-decoration: none; }
a:hover { color: var(--terra); }

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

::selection { background: var(--terra); color: var(--sand); }

:focus-visible { outline: 2px solid var(--terra); outline-offset: 3px; }

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

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--gold);
  color: var(--ink);
  padding: 12px 20px;
  border-radius: 0 0 6px 0;
  font-weight: 600;
}
.skip-link:focus { left: 0; color: var(--ink); }

/* Back to top. The link is plain HTML with href="#top", which every browser
   treats as "scroll to the top of the document" even where no element
   carries that id, so it works with JavaScript switched off. Script then
   adds .to-top--auto, which keeps it out of sight until the reader is well
   past the first screen. visibility, not opacity alone: a hidden link must
   drop out of the tab order too. */
.to-top {
  position: fixed;
  right: calc(18px + env(safe-area-inset-right, 0px));
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  z-index: 40;
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(42, 35, 49, 0.82);
  border: 1px solid rgba(244, 239, 227, 0.38);
  color: var(--sand);
  backdrop-filter: blur(6px);
  box-shadow: 0 6px 20px rgba(42, 35, 49, 0.3);
  transition: opacity 0.35s ease, visibility 0.35s ease, transform 0.35s ease, background 0.2s ease, border-color 0.2s ease;
}
.to-top svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.to-top:hover,
.to-top:focus-visible {
  background: var(--purple);
  border-color: var(--gold);
  color: var(--sand);
}
.to-top--auto {
  opacity: 0;
  visibility: hidden;
  transform: translateY(12px);
}
.to-top--auto.is-on {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

/* ---------- keyframes ---------- */

/* 1.03 instead of 1.08: the drift still reads, but the photo is scaled up
   far less, which keeps it crisp on high-density screens. */
@keyframes kenburns   { 0% { transform: scale(1) translateY(0); }  100% { transform: scale(1.03) translateY(-1.2%); } }
@keyframes drift      { 0% { transform: translateX(0); }           100% { transform: translateX(-50%); } }
@keyframes eq         { 0%, 100% { transform: scaleY(0.25); }       50% { transform: scaleY(1); } }
@keyframes floatY     { 0%, 100% { transform: translateY(0); }      50% { transform: translateY(-14px); } }
@keyframes fadeDown   { from { opacity: 0; transform: translateY(-16px); } to { opacity: 1; transform: translateY(0); } }
@keyframes riseIn     { from { opacity: 0; transform: translateY(34px); }  to { opacity: 1; transform: translateY(0); } }
@keyframes scrollHint { 0%, 100% { transform: translateY(0); opacity: 1; } 70% { transform: translateY(10px); opacity: 0.2; } }

/* ---------- shared pieces ---------- */

.eyebrow {
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  margin-bottom: 18px;
}
.eyebrow--purple { color: var(--purple); }
.eyebrow--sand   { color: var(--gold); }
.eyebrow--light  { color: rgba(244, 239, 227, 0.85); }

.section-title {
  margin: 0;
  font-family: 'Cormorant Garamond', serif;
  font-weight: 500;
  font-size: clamp(38px, 4.5vw, 58px);
  line-height: 1.05;
}
.section-title--xl { font-size: clamp(40px, 5vw, 64px); }
.section-title--sm { font-size: clamp(34px, 4vw, 52px); line-height: 1.1; margin-bottom: 20px; }

.btn {
  display: inline-block;
  padding: 15px 30px;
  border-radius: 999px;
  font-size: 16px;
  letter-spacing: 0.06em;
  border: 1px solid transparent;
  transition: background 0.3s ease, color 0.3s ease, border-color 0.3s ease;
}
.btn--solid          { background: var(--terra); color: var(--sand); font-weight: 600; }
.btn--solid:hover    { background: var(--purple); color: var(--sand); }
.btn--ghost          { border-color: rgba(244, 239, 227, 0.6); color: var(--sand); font-weight: 500; }
.btn--ghost:hover    { border-color: var(--gold); color: var(--gold); }
.btn--dark           { background: var(--ink); color: var(--sand); font-weight: 600; }
.btn--dark:hover     { background: var(--sand); color: var(--ink); }
.btn--outline-light       { border-color: rgba(244, 239, 227, 0.7); color: var(--sand); font-weight: 500; }
.btn--outline-light:hover { background: rgba(244, 239, 227, 0.15); color: var(--sand); }

.link-underline {
  color: var(--gold);
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  border-bottom: 1px solid rgba(227, 213, 163, 0.4);
  padding-bottom: 6px;
  transition: color 0.3s ease;
}
.link-underline:hover { color: var(--sand); }
.link-underline--terra { color: var(--terra); border-bottom-color: var(--terra); }
.link-underline--terra:hover { color: var(--purple); }

/* ---------- nav ---------- */

.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px var(--gutter);
  background: linear-gradient(rgba(42, 35, 49, 0.55), rgba(42, 35, 49, 0));
  backdrop-filter: blur(2px);
  animation: fadeDown 0.9s ease both;
}

.nav__logo {
  font-family: 'Cormorant Garamond', serif;
  font-size: 22px;
  letter-spacing: 0.14em;
  color: var(--sand);
  text-transform: uppercase;
}
.nav__logo:hover { color: var(--gold); }

.nav__menu {
  display: flex;
  gap: 30px;
  align-items: center;
  font-size: 15px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.nav__menu a { color: var(--sand); transition: color 0.25s ease, background 0.25s ease; }
.nav__menu a:hover { color: var(--gold); }

.nav__cta {
  color: var(--ink) !important;
  background: var(--gold);
  padding: 9px 20px;
  border-radius: 999px;
  font-weight: 600;
}
.nav__cta:hover { background: var(--sand); color: var(--ink) !important; }

.nav__toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 42px;
  height: 42px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.nav__toggle span {
  display: block;
  height: 2px;
  width: 22px;
  margin: 0 auto;
  background: var(--sand);
  transition: transform 0.3s ease, opacity 0.3s ease;
}
.nav__toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav__toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ---------- hero ---------- */

.hero-bg {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  background: var(--sand) linear-gradient(160deg, #93758f 0%, #c2857a 55%, #e3d5a3 120%);
}
.hero-bg__photo {
  position: absolute;
  inset: -20px;
  /* max-width: none overrides the base img rule. Without it the element is
     clamped back to the container's width, so with left: -20px the right
     edge falls 20px short and the background shows through. The Ken Burns
     zoom closes that gap at the end of its cycle and opens it again at the
     start, which reads as a flickering edge. */
  max-width: none;
  width: calc(100% + 40px);
  height: calc(100% + 40px);
  object-fit: cover;
  /* Arjan stands just left of centre in the photo. Framing a little to the
     left of the middle keeps him clear of the headline. */
  object-position: 45% 50%;
  animation: kenburns 22s ease-in-out infinite alternate;
  will-change: filter;
}
.hero-bg__tint {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(42, 35, 49, 0.22) 0%, rgba(42, 35, 49, 0) 32%, rgba(42, 35, 49, 0.72) 100%);
  will-change: opacity;
}
.hero-bg__veil {
  position: absolute;
  inset: 0;
  background: var(--sand);
  opacity: 0;
  will-change: opacity;
}

.hero {
  position: relative;
  /* svh keeps the hero from jumping when iOS hides its address bar. */
  height: 100vh;
  height: 100svh;
  min-height: 640px;
  display: flex;
  align-items: flex-end;
}
.hero__inner {
  position: relative;
  width: 100%;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 var(--gutter) 9vh;
}
.hero__eyebrow {
  display: flex;
  align-items: center;
  gap: 14px;
  animation: riseIn 1s 0.2s ease both;
}
.hero__kicker {
  color: var(--gold);
  font-size: 15px;
  letter-spacing: 0.3em;
  text-transform: uppercase;
}
.hero__title {
  margin: 10px 0 0;
  font-family: 'Cormorant Garamond', serif;
  font-weight: 500;
  font-size: clamp(64px, 11vw, 148px);
  line-height: 0.95;
  color: var(--sand);
  letter-spacing: 0.01em;
  animation: riseIn 1.1s 0.35s ease both;
}
.hero__lead {
  max-width: 500px;
  margin: 22px 0 30px;
  color: rgba(244, 239, 227, 0.9);
  font-size: var(--fs-body);
  line-height: 1.65;
  font-weight: var(--fw-body);
  animation: riseIn 1.1s 0.5s ease both;
}
.hero__actions {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  animation: riseIn 1.1s 0.65s ease both;
}
.hero__scroll-hint {
  position: absolute;
  bottom: 26px;
  left: 50%;
  width: 1px;
  height: 44px;
  background: linear-gradient(var(--sand), transparent);
  animation: scrollHint 2.2s ease-in-out infinite;
}

.wave {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 22px;
}
.wave span {
  width: 3px;
  height: 22px;
  background: var(--gold);
  transform-origin: bottom;
  animation: eq var(--eq-dur) ease-in-out var(--eq-delay) infinite;
}

/* ---------- over ---------- */

.about {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 110px var(--gutter) 90px;
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: 70px;
  align-items: start;
}
.about__body {
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: var(--fw-body);
  color: var(--ink-soft);
}
.about__body p { margin: 0 0 18px; }
.about__body p:last-child { margin: 0; }

/* ---------- muziek ---------- */

.music {
  /* The band at the top where the film shows through, clear of any text.
     Behind the Sevenfy player it has to be tinted so heavily that it barely
     registers, so the film gets its own strip, like the hero above. */
  --music-band: clamp(240px, 42vh, 440px);
  position: relative;
  overflow: hidden;
  background: rgba(42, 35, 49, 0.93);
  color: var(--sand);
  padding: var(--music-band) 0 120px;
}
/* The blurred film (scripts/build-video.sh). The tint runs darker towards
   the bottom: the heading only needs to hold its own against the brightest
   pixels of the sun, the Sevenfy player below is transparent and carries
   small, partly dimmed text, so it gets the most. Measured, not guessed:
   see "The music film" in README.md. */
/* The film covers the band plus a run-out below it, not the whole section.
   Scaled to the full section height it only ever showed the pale sky above
   the sun; this way the band holds the sun, the horizon and the heather,
   and the run-out ends in the section's own colour behind the player. */
.music__film {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: calc(var(--music-band) + 260px);
  overflow: hidden;
  /* The section's own background is slightly see-through, so no fixed tint
     matches it exactly. Fading the film itself out avoids a visible edge
     across the player. */
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 220px), transparent);
  mask-image: linear-gradient(to bottom, #000 calc(100% - 220px), transparent);
}
.music__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 70%;
}
.music__film::after {
  content: '';
  position: absolute;
  inset: 0;
  /* Light in the band, so the film reads; then a quick ramp that is fully
     dark just before the heading's small gold label, which needs the most
     help against the sun. The stops follow --music-band, so the ramp always
     ends where the text begins. */
  background: linear-gradient(180deg,
    rgba(42, 35, 49, 0.22) 0,
    rgba(42, 35, 49, 0.30) calc(var(--music-band) - 240px),
    rgba(42, 35, 49, 0.84) calc(var(--music-band) - 16px),
    rgba(42, 35, 49, 0.93) 100%);
}
.music__head { text-shadow: 0 1px 2px rgba(42, 35, 49, 0.55), 0 0 16px rgba(42, 35, 49, 0.45); }

/* Pause control for the film (WCAG 2.2.2: anything that moves on its own
   for more than five seconds must be stoppable). Hidden until the film
   actually runs. */
.music__pause {
  position: absolute;
  top: 24px;
  right: var(--gutter);
  z-index: 3;
  width: 40px;
  height: 40px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid rgba(244, 239, 227, 0.38);
  background: rgba(42, 35, 49, 0.6);
  color: var(--sand);
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease;
}
.music__pause[hidden] { display: none; }
.music__pause:hover,
.music__pause:focus-visible { background: var(--purple); border-color: var(--gold); }
.music__pause-icon {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.music__pause-icon--play { fill: currentColor; stroke-width: 1.5; display: none; }
.music__pause.is-paused .music__pause-icon--pause { display: none; }
.music__pause.is-paused .music__pause-icon--play { display: block; }

.music__orb {
  position: absolute;
  z-index: 1;
  border-radius: 50%;
  pointer-events: none;
}
.music__orb--one {
  top: -120px; right: -80px;
  width: 420px; height: 420px;
  background: radial-gradient(circle, rgba(194, 133, 122, 0.25), transparent 70%);
  animation: floatY 9s ease-in-out infinite;
}
.music__orb--two {
  bottom: -140px; left: -60px;
  width: 380px; height: 380px;
  background: radial-gradient(circle, rgba(125, 151, 106, 0.22), transparent 70%);
  animation: floatY 11s 1.5s ease-in-out infinite;
}
.music__inner {
  position: relative;
  z-index: 2;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 var(--gutter);
}
.music__head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 30px;
  flex-wrap: wrap;
  margin-bottom: 56px;
}
/* ---------- video ---------- */

.video {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 110px var(--gutter) 100px;
  display: grid;
  grid-template-columns: 1fr 1.35fr;
  gap: 64px;
  align-items: center;
}
.video__body {
  margin: 18px 0 28px;
  max-width: 46ch;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: var(--fw-body);
  color: var(--ink-soft);
}

/* Click-to-play poster. Nothing from YouTube loads until the visitor asks
   for it: no cookies, no third-party script, and the page stays fast. */
.yt {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  padding: 0;
  border: 0;
  border-radius: 8px;
  overflow: hidden;
  background: var(--ink);
  color: var(--sand);
  cursor: pointer;
  box-shadow: 0 34px 60px -34px rgba(42, 35, 49, 0.6);
}
.yt__poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.7s ease;
}
.yt::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(42, 35, 49, 0) 55%, rgba(42, 35, 49, 0.6) 100%);
  pointer-events: none;
}
.yt:hover .yt__poster,
.yt:focus-visible .yt__poster { transform: scale(1.03); }
.yt__play {
  position: absolute;
  left: 50%; top: 50%;
  width: 84px; height: 84px;
  margin: -42px 0 0 -42px;
  border-radius: 50%;
  background: rgba(244, 239, 227, 0.94);
  color: var(--ink);
  display: grid;
  place-items: center;
  z-index: 1;
  transition: transform 0.3s ease, background 0.3s ease;
}
.yt__play svg { width: 30px; height: 30px; fill: currentColor; margin-left: 5px; }
.yt:hover .yt__play,
.yt:focus-visible .yt__play { transform: scale(1.08); background: var(--gold); }
.yt__meta {
  position: absolute;
  left: 20px; bottom: 18px;
  z-index: 1;
  font-size: 13px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(244, 239, 227, 0.92);
}
.yt:focus-visible { outline: 3px solid var(--terra); outline-offset: 4px; }
.yt--playing { cursor: default; }
.yt--playing::after { display: none; }
.yt--playing iframe {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  border: 0;
}

/* ---------- reacties ---------- */

.quotes {
  padding: 100px 0;
  overflow: hidden;
  background: rgba(239, 232, 214, 0.78);
}
.quotes__label {
  text-align: center;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--purple);
  margin-bottom: 46px;
}
/* Standaard is de rail een gewone horizontale scroller. Dat is wat een
   crawler, een bezoeker zonder JavaScript en elk aanraakscherm krijgt: te
   vegen, te stoppen, en met precies vier citaten in de broncode. */
.quotes__track {
  display: flex;
  gap: 28px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  padding: 4px var(--gutter) 16px;
  scrollbar-width: none;
}
.quotes__track::-webkit-scrollbar { display: none; }

/* main.js zet deze klasse erop zodra het de citaten heeft gedupliceerd, en
   alleen op een apparaat met hover dat beweging toestaat. Pas dan wordt het
   de doorlopende band. */
.quotes__track--marquee {
  width: max-content;
  overflow-x: visible;
  scroll-snap-type: none;
  padding: 0 0 0 28px;
  animation: drift 42s linear infinite;
}
.quotes:hover .quotes__track--marquee { animation-play-state: paused; }

.quote {
  margin: 0;
  width: 380px;
  flex-shrink: 0;
  scroll-snap-align: center;
  background: var(--sand);
  border: 1px solid var(--line);
  padding: 30px 32px;
}
.quote blockquote {
  margin: 0;
  font-family: 'Cormorant Garamond', serif;
  font-size: 25px;
  font-style: italic;
  line-height: 1.35;
  color: var(--ink);
}
.quote figcaption {
  margin-top: 16px;
  font-size: 14px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--terra);
}

/* ---------- reis + concerten: one photo behind two blocks ---------- */

/* The concert photo sits behind both the trip announcement and the concerts
   block, so the two share one scene. clip-path clips the fixed photo layer to
   this wrapper, which gives the same "content slides over a still photo" feel
   as the hero. The gradient stays as the fallback while the photo loads.
   main.js blurs the photo and raises the veil while the wrapper scrolls out
   ([data-scrollfade]). */
.stage {
  position: relative;
  overflow: hidden;
  clip-path: inset(0);
  background: linear-gradient(160deg, rgba(147, 117, 143, 0.92) 0%, rgba(194, 133, 122, 0.92) 55%, rgba(227, 213, 163, 0.92) 130%);
  color: var(--sand);
  /* A soft dark halo around the letters keeps them readable where the photo
     is bright behind them (the sheet music, the shirt collar). */
  text-shadow: 0 1px 2px rgba(42, 35, 49, 0.55), 0 0 16px rgba(42, 35, 49, 0.45);
}
.stage .btn,
.stage .newsletter__input { text-shadow: none; }
.stage__bg {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
.stage__photo {
  position: absolute;
  inset: -20px;
  max-width: none; /* see .hero-bg__photo */
  width: calc(100% + 40px);
  height: calc(100% + 40px);
  object-fit: cover;
  /* Arjan sits left of centre at the grand piano; keep him in frame. */
  object-position: 45% 40%;
  will-change: filter;
}
/* Dark enough that sand text over it stays readable, whatever the photo
   shows behind a given line. */
.stage__tint {
  position: absolute;
  inset: 0;
  background: linear-gradient(160deg, rgba(147, 117, 143, 0.56) 0%, rgba(42, 35, 49, 0.5) 50%, rgba(42, 35, 49, 0.68) 100%);
}
.stage__veil {
  position: absolute;
  inset: 0;
  background: var(--sand);
  opacity: 0;
  will-change: opacity;
}

/* Trip announcement (temporary). main.js removes it after data-expires. */
.promo {
  position: relative;
  z-index: 1;
  padding: 100px var(--gutter) 90px;
}
.promo__inner {
  max-width: var(--maxw);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1.25fr 1fr;
  gap: 60px;
  align-items: center;
}
.promo__body {
  margin: 18px 0 0;
  max-width: 52ch;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: var(--fw-body);
  color: rgba(244, 239, 227, 0.92);
}
.promo__facts {
  margin: 0 0 28px;
  padding: 0;
  list-style: none;
  border-top: 1px solid rgba(244, 239, 227, 0.3);
}
.promo__facts li {
  padding: 12px 0;
  border-bottom: 1px solid rgba(244, 239, 227, 0.3);
  font-size: 17px;
  font-weight: 500;
}
/* A hairline keeps the two blocks apart on the shared photo. */
.promo + .concerts::before {
  content: '';
  position: absolute;
  top: 0;
  left: var(--gutter);
  right: var(--gutter);
  max-width: var(--maxw);
  margin: 0 auto;
  border-top: 1px solid rgba(244, 239, 227, 0.24);
}

.concerts {
  position: relative;
  z-index: 1;
  padding: 120px var(--gutter);
}
.concerts__inner {
  max-width: 760px;
  margin: 0 auto;
  text-align: center;
}
.concerts__lead {
  margin: 24px auto 36px;
  max-width: 560px;
  font-size: var(--fs-body);
  line-height: 1.7;
  font-weight: var(--fw-body);
  color: rgba(244, 239, 227, 0.9);
}
/* ---------- footer ---------- */

.footer {
  background: rgba(42, 35, 49, 0.95);
  color: var(--sand);
  padding: 90px var(--gutter) 40px;
}
.footer__inner { max-width: var(--maxw); margin: 0 auto; }
.footer__top {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 60px;
  align-items: start;
  padding-bottom: 60px;
  border-bottom: 1px solid rgba(244, 239, 227, 0.15);
}
.footer__top .section-title { margin-bottom: 16px; }
.footer__lead {
  margin: 0 0 26px;
  font-size: 18px;
  font-weight: var(--fw-body);
  color: rgba(244, 239, 227, 0.8);
  max-width: 460px;
  line-height: 1.7;
}
.footer__mail {
  font-family: 'Cormorant Garamond', serif;
  font-size: clamp(22px, 3vw, 34px);
  font-style: italic;
  color: var(--gold);
  border-bottom: 1px solid rgba(227, 213, 163, 0.4);
  padding-bottom: 4px;
}
.footer__mail:hover { color: var(--terra); }
.footer__social {
  display: flex;
  flex-direction: column;
  gap: 14px;
  font-size: 16px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.footer__social a { color: rgba(244, 239, 227, 0.8); }
.footer__social a:hover { color: var(--gold); }
.footer__bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
  padding-top: 28px;
  font-size: 14px;
  color: rgba(244, 239, 227, 0.6);
}
.footer__bottom a { color: rgba(244, 239, 227, 0.5); }
.footer__bottom a:hover { color: var(--gold); }

/* ---------- reveal on scroll ---------- */

[data-reveal].is-hidden {
  opacity: 0;
  transform: translateY(30px);
  transition: opacity 0.9s ease, transform 0.9s cubic-bezier(0.22, 1, 0.36, 1);
}
[data-reveal].is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* ---------- responsive ---------- */

@media (max-width: 860px) {
  :root { --gutter: 24px; }

  .nav__toggle { display: flex; }
  .nav__menu {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    padding: 18px var(--gutter) 26px;
    background: rgba(42, 35, 49, 0.96);
    backdrop-filter: blur(6px);
    display: none;
  }
  .nav__menu.is-open { display: flex; }
  .nav__menu a { padding: 10px 0; }
  .nav__cta { margin-top: 8px; }

  .about { grid-template-columns: 1fr; gap: 34px; }
  .promo { padding: 80px var(--gutter) 70px; }
  .promo__inner { grid-template-columns: 1fr; gap: 30px; }
  .promo .btn { display: block; text-align: center; }
  .video { grid-template-columns: 1fr; gap: 34px; padding: 80px var(--gutter) 70px; }
  .yt__play { width: 66px; height: 66px; margin: -33px 0 0 -33px; }
  .yt__play svg { width: 24px; height: 24px; }
  .stage__photo { object-position: 38% 45%; }
  /* The narrow crop puts the bright sheet music right behind the text, so
     the tint runs heavier on phones. */
  .stage__tint { background: linear-gradient(160deg, rgba(147, 117, 143, 0.62) 0%, rgba(42, 35, 49, 0.64) 50%, rgba(42, 35, 49, 0.74) 100%); }
  .newsletter .btn { width: 100%; }
  .about { padding-top: 90px; }
  .footer__top { grid-template-columns: 1fr; gap: 40px; }
  .footer__social { flex-direction: row; flex-wrap: wrap; gap: 20px; }
  .music__head { align-items: flex-start; }
  /* The phone shows a narrow slice of the film; 40% keeps the sun and the
     hand in the heather in it instead of the dark back of the jacket. */
  .music__video { object-position: 40% 70%; }
  .concerts { padding: 90px var(--gutter); }
  .quote { width: min(82vw, 340px); }

  /* One role per line. Set across the width of a phone the three ran over
     Arjan's collar, whatever the tracking; stacked at the left edge they
     stay in the empty heather beside him. The separators belong to the one
     wide line, so they go. The hero is anchored to its bottom, so the
     taller block grows upwards and the title, the lead and the buttons keep
     their place. */
  /* The equaliser moves above the stack instead of beside it. Next to the
     words it pushed them 41px to the right, which put the tail of the
     longest one back onto Arjan's jacket on a 360 and a 375 wide screen. */
  .hero__eyebrow {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }
  .hero__kicker {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    font-size: 14px;
    letter-spacing: 0.14em;
    line-height: 1.3;
  }
  .hero__kicker-sep { display: none; }
}

/* A phone held in portrait on a short screen. Stacking the three roles cost
   the hero about 40px of height, and on a 568px screen that was enough to
   push the top of the block up behind the navigation. Everything here buys
   vertical room without touching the size of the body copy. */
@media (max-width: 860px) and (max-height: 700px) {
  /* No room for the equaliser on a screen this short. It is decoration and
     carries aria-hidden, so nothing is lost. */
  .hero__eyebrow .wave { display: none; }
  .hero__eyebrow { gap: 0; }
  .hero__inner { padding-bottom: 5vh; }
  .hero__kicker { gap: 0; line-height: 1.25; }
  .hero__title { margin-top: 6px; font-size: clamp(52px, 13vw, 84px); }
  .hero__lead { margin: 14px 0 20px; }
  .hero__actions { gap: 10px; }
}

@media (max-width: 560px) {
  .hero { min-height: 560px; }
  .hero__actions .btn { flex: 1 1 auto; text-align: center; }
}

/* ---------- motion preference ---------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .quotes__track--marquee { animation: none; }
  [data-reveal].is-hidden { opacity: 1; transform: none; }
}

/* ================================================================== *
 * Language switch in the nav
 * ================================================================== */

.nav__lang {
  font-size: 13px;
  letter-spacing: 0.16em;
  opacity: 0.75;
  border: 1px solid rgba(244, 239, 227, 0.35);
  border-radius: 999px;
  padding: 5px 10px;
}
.nav__lang:hover { opacity: 1; border-color: var(--gold); }

/* ================================================================== *
 * Music player
 * ================================================================== */

/* The embed is the last thing in the music section, so the section padding
   supplies the space below it. */
.player {
  margin-bottom: 0;
}

/* ================================================================== *
 * Newsletter
 * ================================================================== */

.newsletter {
  max-width: 560px;
  margin: 46px auto 0;
  text-align: left;
  /* The gradient behind this section runs light at the bottom, so the
     newsletter carries its own dark panel to keep the text readable. */
  background: rgba(42, 35, 49, 0.32);
  backdrop-filter: blur(6px);
  border: 1px solid rgba(244, 239, 227, 0.18);
  border-radius: 8px;
  padding: 26px 28px 24px;
}
.newsletter__label {
  display: block;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(244, 239, 227, 0.9);
  margin-bottom: 12px;
}
.newsletter__grid {
  display: grid;
  grid-template-columns: 1fr 1.25fr auto;
  gap: 10px;
}
/* Onder elkaar op smalle schermen. Deze media query hoort hier en niet bij de
   andere bovenin het bestand: daar stond hij vóór de regel hierboven, en bij
   gelijke specificiteit wint de laatste. Het formulier kreeg zo drie kolommen
   van 48, 59 en 157 pixels op een telefoon. */
@media (max-width: 860px) {
  .newsletter__grid { grid-template-columns: minmax(0, 1fr); }
}
/* Honeypot for bots. Off-screen, never in the tab order. */
.newsletter__trap {
  position: absolute;
  left: -9999px; top: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}
.newsletter__hint {
  margin: 12px 2px 8px;
  font-size: 15px;
  line-height: 1.55;
  font-weight: var(--fw-body);
  color: rgba(244, 239, 227, 0.85);
}
.newsletter__input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 15px 20px;
  border-radius: 999px;
  border: 1px solid rgba(244, 239, 227, 0.6);
  background: rgba(42, 35, 49, 0.35);
  color: var(--sand);
  font: inherit;
  font-size: 17px;
}
.newsletter__input::placeholder { color: rgba(244, 239, 227, 0.65); }
.newsletter__input:focus {
  outline: none;
  border-color: var(--gold);
  background: rgba(42, 35, 49, 0.5);
}
.newsletter__input:disabled,
.newsletter .btn:disabled { opacity: 0.6; cursor: wait; }

/* Light variant for sand backgrounds (streaming page) */
.newsletter--light {
  max-width: none;
  margin: 0;
  background: rgba(255, 255, 255, 0.55);
  backdrop-filter: none;
  border-color: var(--line);
}
.newsletter--light .newsletter__label { color: var(--ink); }
.newsletter--light .newsletter__input {
  border-color: var(--line);
  background: #fff;
  color: var(--ink);
}
.newsletter--light .newsletter__input::placeholder { color: rgba(42, 35, 49, 0.45); }
.newsletter--light .newsletter__input:focus { border-color: var(--purple); background: #fff; }
.newsletter--light .newsletter__hint { color: var(--ink-soft); }

.newsletter-band {
  background: var(--sand-warm);
  padding: 100px var(--gutter);
}
.newsletter-band__inner {
  max-width: var(--maxw);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr 1.15fr;
  gap: 64px;
  align-items: center;
}
/* Dark variant: the QR pages open with the signup, so it also carries the
   fixed nav, the way the page header does elsewhere. The form inside is the
   dark one from the concerts block. */
.newsletter-band--dark {
  background: rgba(42, 35, 49, 0.95);
  color: var(--sand);
}
.newsletter-band--dark .newsletter-band__text { color: rgba(244, 239, 227, 0.84); }
.newsletter-band--dark .newsletter {
  max-width: none;
  margin: 0;
  background: rgba(244, 239, 227, 0.06);
  backdrop-filter: none;
}
.newsletter-band--dark .form__message--ok { color: var(--sand); }
.newsletter-band--dark .form__message--error { color: #ffd9d4; }
.newsletter-band--top { padding-top: 150px; }

/* ---------- alle platforms (QR pages) ---------- */

.socials {
  background: var(--sand-warm);
  padding: 100px var(--gutter);
}
.socials__inner { max-width: var(--maxw); margin: 0 auto; }
.socials__text {
  margin: 18px 0 0;
  max-width: 52ch;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: var(--fw-body);
  color: var(--ink-soft);
}
.socials__grid {
  display: grid;
  /* minmax(0, 1fr): a long word in a tile must not widen its column past
     the container, which it would with a plain 1fr. */
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
  margin-top: 44px;
}
.social {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 18px 20px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--sand);
  color: var(--ink);
  transition: border-color 0.25s ease, transform 0.25s ease, background 0.25s ease;
}
.social:hover {
  border-color: var(--brand, var(--terra));
  background: #fff;
  color: var(--ink);
  transform: translateY(-3px);
}
.social .platform__logo { flex: 0 0 auto; width: 52px; height: 52px; border-radius: 15px; }
.social .platform__logo svg { width: 25px; height: 25px; }
.social.platform--whillo .platform__logo svg { width: 31px; height: 31px; }
.social__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.social__name { font-size: 18px; font-weight: 600; }
.social__note { font-size: 15px; line-height: 1.4; color: var(--ink-soft); overflow-wrap: anywhere; }
.newsletter-band__text {
  margin: 18px 0 0;
  max-width: 44ch;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: var(--fw-body);
  color: var(--ink-soft);
}

/* ================================================================== *
 * Booking form
 * ================================================================== */

/* The same heather at dusk sits behind this block, blurred far enough that it
   reads as atmosphere rather than a second hero. Like the hero, the layer is
   fixed and clipped to the section, so the text slides over a still photo.
   main.js fades the whole layer in and out with the scroll. */
.booking {
  position: relative;
  overflow: hidden;
  clip-path: inset(0);
  background: var(--sand-warm);
  padding: 110px var(--gutter) 120px;
}
.booking__bg {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
.booking__photo {
  position: absolute;
  inset: -60px;
  max-width: none; /* see .hero-bg__photo */
  width: calc(100% + 120px);
  height: calc(100% + 120px);
  object-fit: cover;
  object-position: 50% 58%;
  filter: blur(26px) saturate(0.88);
}
/* A flat sand wash over the photo: it keeps the dark text readable and leaves
   the section edges crisp, the way the other blocks meet each other. */
.booking__blend {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: rgba(239, 232, 214, 0.62);
}
/* Same reason as the newsletter grid above: these have to come after the
   rules they override, not with the other media queries near the top. */
@media (max-width: 860px) {
  .booking__photo { filter: blur(20px) saturate(0.88); }
  .booking__blend { background: rgba(239, 232, 214, 0.66); }
}
.booking__inner {
  position: relative;
  z-index: 2;
  max-width: 760px;
  margin: 0 auto;
}
.booking__text {
  margin: 20px 0 0;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: var(--fw-body);
  color: var(--ink-soft);
}

.booking__mail {
  display: inline-block;
  margin-top: 30px;
  font-family: 'Cormorant Garamond', serif;
  font-size: clamp(24px, 3.4vw, 38px);
  font-style: italic;
  /* Zelfde kleur als de alinea erboven, op Arjans verzoek. De onderstreping
     blijft, anders leest het niet meer als een link. */
  color: var(--ink-soft);
  border-bottom: 1px solid rgba(74, 65, 82, 0.4);
  padding-bottom: 4px;
}
.booking__mail:hover { color: var(--terra); border-bottom-color: var(--terra); }
.booking__list {
  margin: 24px 0 0;
  padding: 0;
  list-style: none;
  font-size: 18px;
  font-weight: var(--fw-body);
  color: var(--ink-soft);
}
.booking__list li {
  position: relative;
  padding: 7px 0 7px 22px;
}
.booking__list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 16px;
  width: 8px;
  height: 2px;
  background: var(--terra);
}

.form__message {
  margin: 0;
  font-size: 16px;
  font-weight: 400;
  min-height: 1.2em;
}
.form__message--ok { color: var(--green); }
.form__message--error { color: #a8443a; }
.concerts .form__message--ok { color: var(--sand); }
.concerts .form__message--error { color: #ffd9d4; }

/* ================================================================== *
 * Responsive additions
 * ================================================================== */

@media (max-width: 860px) {
  .booking { padding: 80px var(--gutter); }
  .newsletter__input { width: 100%; }
  .newsletter .btn { width: 100%; }

  /* Narrow viewports crop the photo hard; hold Arjan inside the frame. */
  .hero-bg__photo { object-position: 38% 50%; }
}

/* A phone held upright loads background-portrait, an upright slice of the
   master (x 640 to 1640, see scripts/build-images.py). 39% across that slice
   puts Arjan where 38% across the full photo did, to within a pixel. The
   media query must stay identical to the one on the <source> elements. */
@media (max-aspect-ratio: 3/5) {
  .hero-bg__photo { object-position: 39% 50%; }
}

/* ================================================================== *
 * Subpage header
 * ================================================================== */

.page-head {
  padding: 150px var(--gutter) 70px;
  background: rgba(42, 35, 49, 0.95);
  color: var(--sand);
}
.page-head__inner { max-width: var(--maxw); margin: 0 auto; }
.page-head h1 {
  margin: 0;
  font-family: 'Cormorant Garamond', serif;
  font-weight: 500;
  font-size: clamp(40px, 5vw, 64px);
  line-height: 1.05;
}
.page-head__lead {
  margin: 22px 0 0;
  max-width: 640px;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: var(--fw-body);
  color: rgba(244, 239, 227, 0.84);
}

/* ================================================================== *
 * Long-form text page (privacy policy)
 * ================================================================== */

.prose {
  max-width: 760px;
  margin: 0 auto;
  padding: 80px var(--gutter) 110px;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: var(--fw-body);
  color: var(--ink-soft);
}
.prose h2 {
  margin: 48px 0 12px;
  font-family: 'Cormorant Garamond', serif;
  font-weight: 500;
  font-size: clamp(30px, 3.4vw, 40px);
  line-height: 1.15;
  color: var(--ink);
}
.prose h2:first-child { margin-top: 0; }
.prose h3 {
  margin: 30px 0 6px;
  font-size: 20px;
  font-weight: 600;
  color: var(--ink);
}
.prose p { margin: 0 0 18px; }
.prose a { border-bottom: 1px solid rgba(147, 117, 143, 0.4); }
.prose__note {
  padding-top: 22px;
  border-top: 1px solid var(--line);
  font-size: 16px;
}
.prose__contact { font-size: 16px; }
.prose__links {
  margin: 0 0 28px;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--line);
}
.prose__links li { border-bottom: 1px solid var(--line); }
.prose__links a {
  display: block;
  padding: 15px 0;
  border-bottom: 0;
  font-size: 18px;
}

/* ================================================================== *
 * Streaming platforms
 * ================================================================== */

.platforms {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 80px var(--gutter) 40px;
}

.platform {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 28px;
  padding: 26px 30px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--sand);
  color: var(--ink);
  margin-bottom: 14px;
  transition: border-color 0.25s ease, transform 0.25s ease, background 0.25s ease;
}
.platform:hover {
  border-color: var(--brand, var(--terra));
  background: var(--sand-warm);
  color: var(--ink);
  transform: translateY(-3px);
}

/* Each platform carries its brand colour in --brand. The mark sits on a soft
   tinted disc; the disc and the hover border both take that colour, so the
   row reads as the platform without shouting. */
.platform--sevenfy    { --brand: #ff0066; }
.platform--spotify    { --brand: #1db954; }
.platform--applemusic { --brand: #fa243c; }
.platform--youtube    { --brand: #ff0000; }
.platform--whillo     { --brand: #663399; }
.platform--itunes     { --brand: #ea4cc0; }
.platform--instagram  { --brand: #e4405f; }
.platform--facebook   { --brand: #0866ff; }

.platform__logo {
  width: 58px;
  height: 58px;
  border-radius: 17px;
  display: grid;
  place-items: center;
  color: var(--brand, var(--ink));
  background: rgba(42, 35, 49, 0.07);
  background: color-mix(in srgb, var(--brand, var(--ink)) 11%, transparent);
  transition: transform 0.25s ease, background 0.25s ease;
}
.platform__logo svg {
  display: block;
  width: 28px;
  height: 28px;
  fill: currentColor;
}
.platform--whillo .platform__logo svg { width: 34px; height: 34px; }
.platform:hover .platform__logo,
.social:hover .platform__logo {
  transform: scale(1.06);
  background: color-mix(in srgb, var(--brand, var(--ink)) 16%, transparent);
}
.platform__name {
  font-size: 20px;
  font-weight: 600;
  letter-spacing: 0.01em;
}
.platform__text {
  margin: 5px 0 0;
  font-size: 17px;
  line-height: 1.6;
  font-weight: var(--fw-body);
  color: var(--ink-soft);
}
.platform__go {
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--purple);
  white-space: nowrap;
}
.platform:hover .platform__go { color: var(--terra); }

/* Sevenfy is Arjan's own platform, so it leads and it looks like it. */
.platform--lead {
  background: rgba(42, 35, 49, 0.95);
  border-color: rgba(42, 35, 49, 0.95);
  color: var(--sand);
  padding: 32px 30px;
  margin-bottom: 26px;
}
.platform--lead:hover {
  background: var(--ink);
  border-color: var(--gold);
  color: var(--sand);
}
.platform--lead .platform__logo {
  width: 68px;
  height: 68px;
  border-radius: 20px;
  background: rgba(244, 239, 227, 0.08);
}
.platform--lead .platform__logo svg { width: 36px; height: 36px; }
.platform--lead:hover .platform__logo { background: rgba(244, 239, 227, 0.13); }
.platform--lead .platform__name { font-size: 22px; }
.platform--lead .platform__text { color: rgba(244, 239, 227, 0.72); }
.platform--lead .platform__go { color: var(--gold); }

.platform__badge {
  display: inline-block;
  margin-left: 10px;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--gold);
  color: var(--ink);
  font-family: 'Karla', sans-serif;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  vertical-align: 3px;
}

/* Sevenfy hands out two players: a dark-text one for light backgrounds
   (used here) and a light-text one for dark backgrounds (homepage). Both
   are transparent, so the surface behind them sets the look. */
.listen {
  padding: 30px var(--gutter) 100px;
  color: var(--ink);
}
.listen__inner { max-width: var(--maxw); margin: 0 auto; }
.listen__lead {
  margin: 14px 0 34px;
  max-width: 560px;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: var(--fw-body);
  color: var(--ink-soft);
}
.player--light {
  padding: 8px;
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.45);
  border: 1px solid var(--line);
}
.player--light iframe { display: block; }
.listen__more { margin: 28px 0 0; }

@media (max-width: 860px) {
  .page-head { padding: 120px var(--gutter) 50px; }
  .newsletter-band--top { padding-top: 120px; }
  .socials { padding: 70px var(--gutter); }
  .socials__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-top: 32px; }
  .social { padding: 14px 14px; gap: 12px; }
  .social .platform__logo { width: 44px; height: 44px; border-radius: 12px; }
  .social .platform__logo svg { width: 22px; height: 22px; }
  .social__name { font-size: 16px; }
  .social__note { font-size: 14px; }
  .prose { padding: 60px var(--gutter) 80px; }
  .platforms { padding: 60px var(--gutter) 30px; }
  .platform {
    grid-template-columns: auto 1fr;
    align-items: start;
    gap: 18px;
    row-gap: 12px;
    padding: 22px 22px;
  }
  .platform__logo { width: 50px; height: 50px; border-radius: 14px; }
  .platform__logo svg { width: 24px; height: 24px; }
  .platform--whillo .platform__logo svg { width: 30px; height: 30px; }
  .platform--lead .platform__logo { width: 56px; height: 56px; border-radius: 16px; }
  .platform--lead .platform__logo svg { width: 30px; height: 30px; }
  .platform__go { grid-column: 2; justify-self: start; }
  .listen { padding: 20px var(--gutter) 70px; }
  .player--light { padding: 6px; border-radius: 14px; }
  .newsletter-band { padding: 70px var(--gutter); }
  .newsletter-band__inner { grid-template-columns: 1fr; gap: 34px; }
}

@media (max-width: 560px) {
  /* One tile per row on phones: two columns broke words in half. This sits
     after the 860px block on purpose, so it wins at equal specificity. */
  .socials__grid { grid-template-columns: minmax(0, 1fr); }
}
