/* ==========================================================================
   No Work All Play — Hugo van Noorden portfolio
   Design tokens + base styles
   ========================================================================== */

/* Self-hosted (not Google Fonts @import) — @import adds a network round-trip
   AFTER this stylesheet itself loads before the font request even starts, and
   Google's default font-display:swap means the page can visibly reflow once the
   font arrives. That reflow, if it happens to land while someone is mid-scroll on
   their very first visit (before the font is cached), was throwing the sticky
   footer-reveal panel's position out of sync with the page until the next scroll
   — the "cream sliver at the bottom, only on a fresh load" bug. Self-hosting with
   font-display:optional removes the network dependency and guarantees there is
   never a footer-desyncing swap: the font is either ready in time for first
   paint, or the page just keeps the fallback font for that visit. */
@font-face {
  font-family: 'Albert Sans';
  font-style: normal;
  font-weight: 300;
  font-display: optional;
  src: url('../fonts/AlbertSans-Light.ttf') format('truetype');
}
@font-face {
  font-family: 'Albert Sans';
  font-style: normal;
  font-weight: 400;
  font-display: optional;
  src: url('../fonts/AlbertSans-Regular.ttf') format('truetype');
}
@font-face {
  font-family: 'Albert Sans';
  font-style: normal;
  font-weight: 500;
  font-display: optional;
  src: url('../fonts/AlbertSans-Medium.ttf') format('truetype');
}
@font-face {
  font-family: 'Albert Sans';
  font-style: normal;
  font-weight: 600;
  font-display: optional;
  src: url('../fonts/AlbertSans-SemiBold.ttf') format('truetype');
}
@font-face {
  font-family: 'Albert Sans';
  font-style: normal;
  font-weight: 700;
  font-display: optional;
  src: url('../fonts/AlbertSans-Bold.ttf') format('truetype');
}
@font-face {
  font-family: 'Albert Sans';
  font-style: normal;
  font-weight: 800;
  font-display: optional;
  src: url('../fonts/AlbertSans-ExtraBold.ttf') format('truetype');
}
@font-face {
  font-family: 'Albert Sans';
  font-style: italic;
  font-weight: 400;
  font-display: optional;
  src: url('../fonts/AlbertSans-Italic.ttf') format('truetype');
}

:root {
  --bg-cream: #FAF6EF;
  --text-color: #3F3F3F;
  --void-black: #101010;
  --accent-dark-pink: #3C0A1A;
  --accent-light-pink: #FBC7DE;
  --white: #FFFFFF;

  --font: 'Albert Sans', ui-sans-serif, system-ui, -apple-system, sans-serif;

  --page-pad: clamp(1.25rem, 4vw, 5.33rem);
  --gap-sm: 1.5rem;
  --gap-md: 2rem;
  --gap-lg: 4rem;
  --gap-xl: 7.5rem;

  /* smooth + slightly funky ease: a soft overshoot, not a hard bounce */
  --ease-funky: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
}

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

html { scroll-behavior: smooth; }

body {
  margin: 0;
  /* black, not cream — matches the footer reveal-panel. navbar, .mobile-menu and
     main all paint their own explicit cream background over their full extent, so
     this is only ever visible in the gap between main and .reveal-panel at the
     very bottom of a page. Whatever tiny/timing-dependent cause opens that gap
     (sub-pixel rounding, a font-swap reflow, sticky/GPU compositing lag...), it
     now reads as black-on-black instead of a cream sliver against the footer —
     fixes the *symptom* regardless of which of those causes is behind it. */
  background: var(--void-black);
  color: var(--text-color);
  font-family: var(--font);
  font-weight: 400;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

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

a { color: inherit; text-decoration: none; }

.container {
  width: 100%;
  max-width: 73.125rem; /* 1170px */
  margin-inline: auto;
}

.container--wide {
  width: 100%;
  padding-inline: var(--page-pad);
}

/* ==========================================================================
   Reveal-on-load / reveal-on-scroll animation system
   ========================================================================== */

[data-reveal] {
  opacity: 0;
  transform: translateY(28px) scale(0.985);
  transition: opacity 0.9s var(--ease-funky), transform 0.9s var(--ease-funky);
  will-change: opacity, transform;
}

[data-reveal].is-visible {
  opacity: 1;
  transform: translateY(0) scale(1);
}

/* staggered children within a reveal group */
[data-reveal-group] > * {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out);
}
[data-reveal-group].is-visible > * { opacity: 1; transform: translateY(0); }
[data-reveal-group].is-visible > *:nth-child(1) { transition-delay: 0.05s; }
[data-reveal-group].is-visible > *:nth-child(2) { transition-delay: 0.12s; }
[data-reveal-group].is-visible > *:nth-child(3) { transition-delay: 0.19s; }
[data-reveal-group].is-visible > *:nth-child(4) { transition-delay: 0.26s; }
[data-reveal-group].is-visible > *:nth-child(5) { transition-delay: 0.33s; }
[data-reveal-group].is-visible > *:nth-child(6) { transition-delay: 0.40s; }

@media (prefers-reduced-motion: reduce) {
  [data-reveal], [data-reveal-group] > * {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

/* ==========================================================================
   Navbar
   ========================================================================== */

.navbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.5rem var(--page-pad);
  background: var(--bg-cream);
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 10;
  transition: transform 0.35s var(--ease-out);
}

/* toggled by the scroll-direction listener in main.js — hides on scroll down,
   slides back in on scroll up */
.navbar--hidden {
  transform: translateY(-100%);
}

.navbar__logo {
  display: inline-flex;
  align-items: center;
  gap: 0.5em; /* 12px next to 25px in the design */
  font-size: 1.125rem;
  font-weight: 400;
  color: var(--text-color);
}

/* No Work All Play icon in front of the name: every few seconds it does a little
   dance (hop, wiggle, land with a squash), and in between it blinks; hovering the
   name makes it dance right away */
.logo-icon {
  flex: none;
  width: 1.05em;
  height: 1.05em;
  fill: currentColor;
  overflow: visible;
}
.logo-icon__body {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: logo-dance 9s cubic-bezier(0.45, 0, 0.55, 1) 2.5s infinite;
}
.logo-icon__eyes {
  transform-box: fill-box;
  transform-origin: 50% 50%;
  animation: logo-blink 5.3s ease-in-out 1.2s infinite;
}
.logo-icon__mouth {
  transform-box: fill-box;
  transform-origin: 50% 50%;
  animation: logo-grin 9s ease-in-out 2.5s infinite;
}
.navbar__logo:hover .logo-icon__body { animation: logo-dance-now 0.9s cubic-bezier(0.45, 0, 0.55, 1); }
.navbar__logo:hover .logo-icon__mouth { animation: logo-grin-now 0.9s ease-in-out; }

/* the dance takes the first ~10% of the 9s loop, then it stands still */
@keyframes logo-dance {
  0%    { transform: none; }
  1.5%  { transform: translateY(0) scale(1.08, 0.88); }
  3.5%  { transform: translateY(-38%) rotate(-12deg) scale(0.94, 1.08); }
  5.5%  { transform: translateY(-20%) rotate(10deg); }
  7.5%  { transform: translateY(0) rotate(-4deg) scale(1.1, 0.86); }
  9%    { transform: translateY(0) rotate(2deg) scale(0.97, 1.03); }
  10.5%, 100% { transform: none; }
}
@keyframes logo-dance-now {
  0%   { transform: none; }
  14%  { transform: translateY(0) scale(1.08, 0.88); }
  33%  { transform: translateY(-38%) rotate(-12deg) scale(0.94, 1.08); }
  52%  { transform: translateY(-20%) rotate(10deg); }
  71%  { transform: translateY(0) rotate(-4deg) scale(1.1, 0.86); }
  86%  { transform: translateY(0) rotate(2deg) scale(0.97, 1.03); }
  100% { transform: none; }
}
@keyframes logo-blink {
  0%, 94%, 100% { transform: none; }
  96%           { transform: scaleY(0.15); }
}
/* the mouth widens into a grin while it's in the air */
@keyframes logo-grin {
  0%, 2.5%, 9%, 100% { transform: none; }
  4.5%, 6.5%         { transform: scaleX(1.12) translateY(8%); }
}
@keyframes logo-grin-now {
  0%, 25%, 86%, 100% { transform: none; }
  43%, 62%           { transform: scaleX(1.12) translateY(8%); }
}

@media (prefers-reduced-motion: reduce) {
  .logo-icon__body,
  .logo-icon__eyes,
  .logo-icon__mouth { animation: none !important; }
}

.navbar__right {
  display: flex;
  align-items: center;
  gap: 2.5rem;
}

.navbar__links {
  display: flex;
  align-items: center;
  gap: 2rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.navbar__links a {
  font-size: 0.9375rem;
  font-weight: 600;
  transition: opacity 0.25s var(--ease-out);
}
.navbar__links a:hover { opacity: 0.6; }

.navbar__lang {
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}
.navbar__lang span { opacity: 0.4; font-weight: 400; }

/* Hamburger toggle — hidden on desktop */
.hamburger {
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 0.375rem;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  background: none;
  border: none;
  cursor: pointer;
  position: relative;
  z-index: 30;
}

.hamburger__bar {
  display: block;
  width: 1.5rem;
  height: 2px;
  background: var(--text-color);
  transition: transform 0.4s var(--ease-funky), opacity 0.2s var(--ease-out), width 0.3s var(--ease-out);
}

.hamburger:hover .hamburger__bar { width: 1.75rem; }

.hamburger[aria-expanded="true"] .hamburger__bar:nth-child(1) {
  transform: translateY(0.375rem) rotate(45deg);
}
.hamburger[aria-expanded="true"] .hamburger__bar:nth-child(2) {
  transform: translateY(-0.375rem) rotate(-45deg);
}

/* Full-screen mobile menu panel */
.mobile-menu {
  position: fixed;
  inset: 0;
  background: var(--bg-cream);
  z-index: 20;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--page-pad);
  clip-path: circle(2.5% at calc(100% - 2.75rem) 2.75rem);
  transition: clip-path 0.6s var(--ease-funky);
  visibility: hidden;
}

.mobile-menu__logo {
  position: fixed;
  top: 1.5rem;
  left: var(--page-pad);
  z-index: 21;
  /* matches the navbar row: the logo there sits centered (align-items:center)
     against the hamburger button's height (2.25rem), not flush with padding-top —
     replicate that exact centering instead of guessing a pixel offset. */
  height: 2.25rem;
  display: flex;
  align-items: center;
}

.mobile-menu__close {
  position: fixed;
  top: 1.5rem;
  right: var(--page-pad);
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  background: none;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.3s var(--ease-out);
  transition-delay: 0.2s;
}
.mobile-menu.is-open .mobile-menu__close { opacity: 1; }

.mobile-menu__close .hamburger__bar {
  position: absolute;
  transition: width 0.2s var(--ease-out);
}
.mobile-menu__close .hamburger__bar:nth-child(1) { transform: rotate(45deg); }
.mobile-menu__close .hamburger__bar:nth-child(2) { transform: rotate(-45deg); }
.mobile-menu__close:hover .hamburger__bar { width: 1.75rem; }

.mobile-menu.is-open {
  clip-path: circle(150% at calc(100% - 2.75rem) 2.75rem);
  visibility: visible;
}

.mobile-menu__links {
  list-style: none;
  margin: 0 0 3rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.mobile-menu__links li {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.5s var(--ease-out), transform 0.5s var(--ease-out);
}

.mobile-menu.is-open .mobile-menu__links li {
  opacity: 1;
  transform: translateY(0);
}
.mobile-menu.is-open .mobile-menu__links li:nth-child(1) { transition-delay: 0.15s; }
.mobile-menu.is-open .mobile-menu__links li:nth-child(2) { transition-delay: 0.22s; }
.mobile-menu.is-open .mobile-menu__links li:nth-child(3) { transition-delay: 0.29s; }
.mobile-menu.is-open .mobile-menu__links li:nth-child(4) { transition-delay: 0.36s; }
.mobile-menu.is-open .mobile-menu__links li:nth-child(5) { transition-delay: 0.43s; }

.mobile-menu__links a {
  font-size: clamp(2rem, 1.3rem + 3vw, 3.5rem);
  font-weight: 800;
  letter-spacing: -0.01em;
  display: inline-block;
}

.mobile-menu__lang {
  font-size: 0.9375rem;
  font-weight: 600;
  opacity: 0;
  transition: opacity 0.5s var(--ease-out);
  transition-delay: 0.5s;
}
.mobile-menu.is-open .mobile-menu__lang { opacity: 1; }
.mobile-menu__lang span { opacity: 0.4; font-weight: 400; }

body.menu-open { overflow: hidden; }

@media (max-width: 56rem) {
  .navbar__right { display: none; }
  .hamburger { display: flex; }
}

@media (min-width: 56.0625rem) {
  .mobile-menu { display: none; }
}

/* ==========================================================================
   Hero
   ========================================================================== */

.hero {
  padding: 2.25rem var(--page-pad) 6.7rem;
}

.hero__text {
  font-size: clamp(1.5rem, 1rem + 2.4vw, 2.75rem);
  font-weight: 500;
  line-height: 1.28;
  letter-spacing: -0.01em;
  max-width: 71rem;
}

.hero__text strong { font-weight: 800; }

/* ==========================================================================
   Showreel
   ========================================================================== */

.showreel {
  padding-inline: var(--page-pad);
  background: var(--bg-cream);
}

.showreel__frame {
  width: 100%;
  aspect-ratio: 16 / 9;
  position: relative;
  overflow: hidden;
}

.showreel__frame video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.placeholder {
  width: 100%;
  height: 100%;
  border: 1.5px dashed rgba(63, 63, 63, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-color);
}

.placeholder--clickable {
  cursor: pointer;
  transition: opacity 0.25s var(--ease-out), border-color 0.25s var(--ease-out);
}
.placeholder--clickable:hover {
  opacity: 0.8;
  border-color: var(--text-color);
}

.showreel__frame--youtube iframe {
  width: 100%;
  height: 100%;
  border: 0;
}

.showreel__mute {
  position: absolute;
  right: 1.5rem;
  bottom: 1.5rem;
  width: 3rem;
  height: 3rem;
  padding: 0;
  border: 1.5px solid rgba(255, 255, 255, 0.6);
  border-radius: 9999px;
  background: rgba(16, 16, 16, 0.35);
  backdrop-filter: blur(6px);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.25s var(--ease-out), border-color 0.25s var(--ease-out), background 0.25s var(--ease-out);
}
.showreel__mute:hover { border-color: rgba(255, 255, 255, 0.9); background: rgba(16, 16, 16, 0.5); }

.showreel__mute-icon {
  position: relative;
  width: 1.125rem;
  height: 1.125rem;
}
.showreel__mute-icon::before,
.showreel__mute-icon::after {
  content: '';
  position: absolute;
}
/* speaker body */
.showreel__mute-icon::before {
  left: 0;
  top: 0.3rem;
  width: 0.5rem;
  height: 0.55rem;
  background: var(--white);
  clip-path: polygon(0 25%, 40% 25%, 100% 0, 100% 100%, 40% 75%, 0 75%);
}
/* mute slash — hidden by default (unmuted state) */
.showreel__mute-icon::after {
  right: -0.1rem;
  top: -0.05rem;
  width: 1px;
  height: 1.3rem;
  background: var(--white);
  transform: rotate(45deg);
  transform-origin: center;
  opacity: 0;
  transition: opacity 0.2s var(--ease-out);
}
.showreel__mute[aria-pressed="false"] .showreel__mute-icon::after { opacity: 1; }

.placeholder__label {
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0.5;
}

.placeholder__play {
  width: 0;
  height: 0;
  border-top: 1.3rem solid transparent;
  border-bottom: 1.3rem solid transparent;
  border-left: 2rem solid var(--text-color);
  opacity: 0.85;
}

/* ==========================================================================
   Intro (photo + typography block)
   ========================================================================== */

.intro {
  padding: var(--gap-xl) var(--page-pad);
}

.intro__inner {
  max-width: 73.125rem; /* 1170px, same as .diensten__inner */
  margin-inline: auto;
}

.intro__row {
  display: flex;
  gap: 4rem;
  align-items: flex-start;
}

.intro__label {
  flex: 0 0 15.625rem; /* 250px — matches .diensten__label */
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0.55;
  padding-top: 0.25rem; /* matches .diensten__label */
}

.intro__content {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 2rem;
}

.intro__heading {
  font-size: clamp(1.75rem, 1.1rem + 2.6vw, 3.25rem);
  font-weight: 800;
  letter-spacing: -0.01em;
  line-height: 1.12;
  margin: 0;
}

.intro__lead {
  font-size: 1.375rem;
  font-weight: 500;
  line-height: 1.4;
  margin: 0;
}

.intro__body {
  font-size: 1.125rem;
  line-height: 1.6;
  margin: 0;
}
.intro__body strong { font-weight: 700; }

.intro__quote {
  display: flex;
  gap: 1.25rem;
  border-left: 3px solid var(--text-color);
  padding-left: 1.25rem;
}
.intro__quote p {
  font-style: italic;
  font-weight: 500;
  font-size: 1.5rem;
  line-height: 1.4;
  margin: 0;
}

.intro__link {
  font-weight: 600;
  font-size: 1rem;
  text-decoration: underline;
  align-self: flex-start;
}

.intro__meta {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.intro__meta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 2.5rem;
}

.intro__meta-row .cv-entry {
  flex: 1 1 12rem;
  min-width: 10rem;
}

@media (max-width: 56rem) {
  .intro__row { flex-direction: column; }
  .intro__label { display: none; }
}

/* ==========================================================================
   Profile page (CV, Over mij) — photo + text column, sticky page heading
   ========================================================================== */

.profile {
  position: relative;
  padding: var(--gap-lg) 0 var(--gap-xl); /* top/bottom match the project-detail page's spacing */
}

.profile__inner {
  padding: 0 var(--page-pad); /* full-width, matches navbar/hero — not the centered 1170px container */
}

.profile__row {
  display: flex;
  gap: 4rem;
  align-items: flex-start;
}

.profile__photo {
  width: 28.125rem; /* 450px */
  flex: 0 0 auto;
  aspect-ratio: 1 / 1;
}

.profile__content {
  flex: 0 1 53.5rem; /* 856px — matches .intro__content's width (1170px container − 250px label − 64px gap); shrinks on narrow viewports, never grows past it */
  display: flex;
  flex-direction: column;
  gap: 2rem;
  min-width: 0;
}

.profile__divider {
  height: 1px;
  background: rgba(63, 63, 63, 0.2);
  margin: 0.5rem 0;
}

.profile__section-label {
  display: block;
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0.55;
  margin-bottom: -0.75rem; /* pulls the first entry closer, gap on .profile__content handles the rest */
}

.cv-entry {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.cv-entry__period {
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  opacity: 0.5;
}

.cv-subhead {
  display: block;
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  opacity: 0.5;
  margin-bottom: -0.75rem; /* pulls the item right below it closer, matching .profile__section-label */
}

.cv-entry__role {
  font-size: 1.375rem;
  font-weight: 700;
  margin: 0;
}

.cv-entry__org {
  font-size: 1rem;
  color: var(--text-color);
  margin: 0;
}

.cv-entry__desc {
  font-size: 1rem;
  line-height: 1.6;
  margin: 0;
}

.cv-skills {
  font-size: 1.125rem;
  font-weight: 500;
  line-height: 1.6;
  margin: 0;
}

.contact-details-block {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}
.contact-details-block a { text-decoration: none; }
.contact-details-block a:hover { opacity: 0.7; }

/* ==========================================================================
   Project detail — sticky left info column + right photo stack
   ========================================================================== */

.project {
  padding: var(--gap-lg) var(--page-pad) var(--gap-xl);
}

.project__row {
  display: flex;
  align-items: flex-start;
  gap: 4rem;
}

.project__info {
  flex: 0 0 38.125rem; /* 610px */
  position: sticky;
  top: 2rem;
  min-height: calc(100vh - 4rem);
}

.project__kicker {
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  opacity: 0.55;
}

.project__title {
  font-size: 2.5rem;
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.01em;
  margin: 0.75rem 0 0;
}

.project__meta {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 8rem; /* pinned distance from the bottom of the first view — the block grows upward as content is added, matching CV's sticky-heading offset */
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.project__photos {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1.875rem; /* 30px */
}

.project-photo-row--full .project-photo {
  width: 100%;
  aspect-ratio: 16 / 10;
}

.project-photo-row--pair {
  display: flex;
  gap: 1.875rem; /* 30px */
}

.project-photo-row--pair .project-photo {
  flex: 1 1 0;
  aspect-ratio: 4 / 5;
}

.project-photo {
  overflow: hidden;
}

.project-photo img,
.project-photo video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (max-width: 64rem) {
  .project__row { flex-direction: column; }
  .project__info { position: static; flex-basis: auto; min-height: 0; }
  .project__meta { position: static; margin-top: 3rem; }
  .project__photos { width: 100%; }
}

@media (max-width: 40rem) {
  .project-photo-row--pair { flex-direction: column; }
  .project-photo-row--pair .project-photo { flex: none; width: 100%; }
}

.project-photo-row--triple {
  display: flex;
  gap: 1.875rem; /* 30px */
}

.project-photo-row--triple .project-photo {
  flex: 1 1 0;
  aspect-ratio: 3 / 4;
}

@media (max-width: 48rem) {
  .project-photo-row--triple { flex-direction: column; }
  .project-photo-row--triple .project-photo { flex: none; width: 100%; }
}

/* ==========================================================================
   Project detail — alternate, single-column layout
   ========================================================================== */

.project-alt-top {
  padding: var(--gap-lg) var(--page-pad) 0;
}

.project-alt-top__inner {
  max-width: 112.5rem; /* 1800px — full-width, but capped so images don't need to keep
    growing indefinitely on ultra-wide monitors */
  margin-inline: auto;
}

.project-alt-top__header {
  margin-bottom: 2.5rem;
}

.project-alt-top__kicker {
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  opacity: 0.55;
}

.project-alt-top__title {
  font-size: clamp(2rem, 1.3rem + 3.5vw, 4.5rem);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.01em;
  margin: 0.75rem 0 0;
}

.project-alt-sections {
  padding: 4rem var(--page-pad) var(--gap-xl);
}

.project-alt-sections__inner {
  max-width: 112.5rem; /* 1800px — same cap as .project-alt-top__inner */
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: 1.875rem; /* 30px, matches the gap between rows in the other project layout */
}

/* "Video met bediening" beeldsectie — smaller, centered, real player controls.
   60% of the 1800px section cap = ~1080px on a large screen; percentage-based
   so it keeps scaling proportionally at narrower viewports instead of a fixed px. */
.project-video-controlled {
  position: relative;
  width: 60%;
  margin-inline: auto;
}

.project-video-controlled video {
  width: 100%;
  display: block;
  /* no aspect-ratio/object-fit crop here on purpose — unlike the autoplay
     background videos elsewhere, this one has real player controls and should
     show its full, uncropped frame */
}

@media (max-width: 48rem) {
  .project-video-controlled { width: 100%; }
}

.video-replay-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(16, 16, 16, 0.55);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.25s var(--ease-out), visibility 0.25s var(--ease-out);
}

.video-replay-overlay.is-visible {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

.video-replay-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  padding: 0;
  border: none;
  background: none;
  color: var(--white);
  font-family: var(--font);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
}

.video-replay-btn__icon {
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 9999px;
  border: 1.5px solid rgba(255, 255, 255, 0.7);
  background: rgba(16, 16, 16, 0.35);
  backdrop-filter: blur(6px);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: border-color 0.25s var(--ease-out), background 0.25s var(--ease-out);
}
.video-replay-btn:hover .video-replay-btn__icon {
  border-color: rgba(255, 255, 255, 0.95);
  background: rgba(16, 16, 16, 0.5);
}

/* replay icon — small right-pointing triangle, reuses the same CSS-triangle
   technique as .placeholder__play */
.video-replay-btn__icon::before {
  content: '';
  width: 0;
  height: 0;
  border-top: 0.55rem solid transparent;
  border-bottom: 0.55rem solid transparent;
  border-left: 0.85rem solid var(--white);
  margin-left: 0.2rem; /* optical centering */
}


/* the sticky page heading — bottom-left, per DESIGN.md "Sticky page heading" pattern */
.profile__sticky-heading {
  position: sticky;
  bottom: 4rem; /* ~64px */
  left: var(--page-pad);
  z-index: 2;
  margin: 5rem 0 0 var(--page-pad);
  font-size: clamp(2.5rem, 1.5rem + 5.5vw, 8.75rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--text-color);
  pointer-events: none;
}

@media (max-width: 56rem) {
  .profile__row { flex-direction: column; }
  .profile__photo { width: 100%; }
  /* .profile__content's flex-basis (53.5rem) is meant as a WIDTH constraint for the
     desktop row layout; once .profile__row stacks into a column, that same value gets
     read as a HEIGHT basis instead, stretching short content (e.g. Contact) with empty
     space. Let it size to its actual content on mobile. */
  .profile__content { flex: 1 1 auto; }

  /* on shorter pages (e.g. Contact) the reveal-panel's own content can be shorter than
     the viewport, leaving a strip of the page background visible below it once fully
     scrolled/bounced — force it to always fill at least a full screen once pinned.
     The wrapper itself has no background (only its .contact/.footer children do), so
     it needs one too, otherwise the extra height it now gains just shows the page's
     own cream background instead of black. */
  .reveal-panel { min-height: 100vh; background: var(--void-black); }

  /* below 56rem the sticky bottom-left heading doesn't work (photo stacks full width) —
     show it as a regular top-of-page heading instead, left-aligned like .page-heading */
  .profile { display: flex; flex-direction: column; }
  .profile__sticky-heading {
    display: block;
    position: static;
    order: -1;
    margin: 0 0 2rem var(--page-pad);
    pointer-events: auto;
  }
}

/* ==========================================================================
   Diensten (dark pink accent section)
   ========================================================================== */

.diensten {
  background: var(--accent-dark-pink);
  color: var(--white);
  padding: var(--gap-xl) var(--page-pad);
}

.diensten__inner {
  max-width: 73.125rem;
  margin-inline: auto;
}

.diensten__block {
  display: flex;
  gap: 4rem;
  align-items: flex-start;
}

.diensten__label {
  flex: 0 0 15.625rem;
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent-light-pink);
  padding-top: 0.25rem;
}

.diensten__content {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.diensten__heading {
  font-size: clamp(1.75rem, 1.1rem + 2.6vw, 3.25rem);
  font-weight: 800;
  letter-spacing: -0.01em;
  line-height: 1.12;
  margin: 0;
}

.diensten__intro {
  font-size: 1.0625rem;
  line-height: 1.55;
  margin: 0;
}

.diensten__button {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  border: 1px solid var(--white);
  padding: 0.9rem 1.5rem;
  font-size: 0.9375rem;
  font-weight: 500;
  align-self: flex-start;
  transition: background 0.3s var(--ease-out), color 0.3s var(--ease-out);
}
.diensten__button:hover { background: var(--white); color: var(--accent-dark-pink); }

.diensten__block + .diensten__block { margin-top: 3rem; }

.accordion {
  list-style: none;
  margin: 0;
  padding: 0;
  flex: 1 1 auto; /* stretch to fill the row, same as .diensten__content */
  min-width: 0;
}

.accordion__item {
  border-top: 1px solid rgba(255,255,255,0.25);
}
.accordion__item:last-child { border-bottom: 1px solid rgba(255,255,255,0.25); }

.accordion__trigger {
  width: 100%;
  background: none;
  border: none;
  color: inherit;
  font-family: inherit;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.75rem 0;
  font-size: 1.375rem;
  font-weight: 600;
  cursor: pointer;
  text-align: left;
  transition: opacity 0.25s var(--ease-out);
}
.accordion__trigger:hover { opacity: 0.75; }

.accordion__icon {
  font-size: 1.5rem;
  font-weight: 300;
  flex: 0 0 auto;
  transition: transform 0.4s var(--ease-funky);
}
.accordion__item.is-open .accordion__icon { transform: rotate(45deg); }

.accordion__panel {
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-height 0.5s var(--ease-funky), opacity 0.4s var(--ease-out);
}
.accordion__item.is-open .accordion__panel { opacity: 1; }
.accordion__panel p { margin: 0 0 1.5rem; font-size: 1rem; opacity: 0.85; }

@media (max-width: 56rem) {
  .diensten__block { flex-direction: column; gap: 1.5rem; }
  .diensten__label { flex: none; }
}

/* ==========================================================================
   Klanten
   ========================================================================== */

.klanten {
  padding: var(--gap-lg) var(--page-pad);
  background: var(--bg-cream);
}

.klanten__label {
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin: 0 0 2rem;
}

.klanten__ticker {
  overflow: hidden;
  width: 100%;
  /* soft fade at both edges so the ticker doesn't cut off abruptly */
  mask-image: linear-gradient(to right, transparent, black 6%, black 94%, transparent);
  -webkit-mask-image: linear-gradient(to right, transparent, black 6%, black 94%, transparent);
}

.klanten__ticker-track {
  display: flex;
  align-items: baseline;
  width: max-content;
  white-space: nowrap;
  animation: klanten-scroll 42s linear infinite;
}

.klanten__ticker:hover .klanten__ticker-track {
  animation-play-state: paused;
}

.klanten__name {
  font-size: clamp(1.125rem, 0.9rem + 1vw, 1.75rem);
  font-weight: 800;
  line-height: 1.5;
}

.klanten__ticker-track .sep {
  display: inline-block;
  opacity: 0.4;
  margin: 0 0.5em;
  vertical-align: 0.22em; /* the middle-dot glyph sits low by default in most fonts */
  font-size: clamp(1.125rem, 0.9rem + 1vw, 1.75rem);
}

@keyframes klanten-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .klanten__ticker-track { animation: none; }
}

/* ==========================================================================
   Footer reveal — main content scrolls over the sticky Contact + Footer panel
   ========================================================================== */

main {
  position: relative;
  z-index: 1;
  background: var(--bg-cream);
  /* compensates for .navbar now being position:fixed (no longer in normal
     flow) — measured navbar height is ~74–75px across breakpoints, so one
     shared value covers both without a visible gap */
  padding-top: 4.6875rem; /* 75px */
  /* forces its own GPU compositing layer so Safari properly invalidates it
     on a fresh page load, instead of occasionally reusing/"ghosting" a stale
     layer from the previous page (a known iOS Safari position:sticky quirk) */
  transform: translateZ(0);
}

/* main's own box can end up a sub-pixel taller than its visible content (rounding
   in nested rem/vw layout), and since main sits above .reveal-panel in z-index,
   that invisible overshoot can paint cream over the very top of the black panel.
   A small solid-black bar, deliberately oversized relative to that sub-pixel
   overshoot (observed ~0.1–2px) and pinned to main's own bottom edge, guarantees
   the seam is always covered in black regardless of which side the rounding
   error falls on — more robust than trying to fade/align it exactly. */
main::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -3px;
  height: 6px;
  background: var(--void-black);
}

.reveal-panel {
  position: sticky;
  bottom: 0;
  z-index: 0;
  /* NOT translateZ(0) here — unlike main (static, never repositions), this element
     actively repositions during scroll (position:sticky). Promoting it to its own
     GPU layer let that layer lag a frame or two behind main's during active/momentum
     scrolling, which is what actually caused the cream sliver Hugo kept seeing: it
     only ever appeared while scrolling and was gone on a fresh reload at the same
     scroll position (i.e. it was never really a static layout gap). */
}

/* ==========================================================================
   Contact
   ========================================================================== */

.contact {
  background: var(--void-black);
  color: var(--white);
  padding: var(--gap-xl) var(--page-pad);
}

.contact__heading {
  font-size: clamp(2.5rem, 1.5rem + 5.5vw, 8.75rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  margin: 0 0 2rem;
}

.contact__details {
  display: flex;
  flex-wrap: wrap;
  gap: 3rem;
}

.contact__item { display: flex; flex-direction: column; gap: 0.35rem; }

.contact__item span {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0.5;
}

.contact__item a, .contact__item p {
  font-size: 1.125rem;
  font-weight: 600;
  margin: 0;
}

/* ==========================================================================
   Footer
   ========================================================================== */

.footer {
  background: var(--void-black);
  color: var(--white);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.75rem var(--page-pad);
  border-top: 1px solid var(--void-black);
}

.footer__socials {
  display: flex;
  gap: 1.5rem;
  list-style: none;
  margin: 0;
  padding: 0;
}
.footer__socials a {
  display: inline-block;
  /* bigger tap area on phones without moving anything: padding cancelled out by margin */
  padding: 0.75rem 0.375rem;
  margin: -0.75rem -0.375rem;
  font-size: 0.875rem;
  font-weight: 600;
  transition: opacity 0.25s var(--ease-out);
}
.footer__socials a:hover { opacity: 0.6; }

.footer__meta {
  font-size: 0.875rem;
  opacity: 0.6;
}

@media (max-width: 40rem) {
  .footer { flex-direction: column; gap: 0.75rem; align-items: flex-start; }
}

/* ==========================================================================
   Page heading — big, left-aligned, non-sticky page title (Geselecteerd werk, etc.)
   ========================================================================== */

.page-heading-section {
  padding: var(--gap-lg) var(--page-pad) 0; /* matches the project-detail page's top spacing */
}

.page-heading {
  font-size: clamp(2.5rem, 1.5rem + 5.5vw, 8.75rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--text-color);
  margin: 0;
}

/* ==========================================================================
   Geselecteerd werk — case card grid
   ========================================================================== */

.werk-grid-section {
  padding: var(--gap-lg) var(--page-pad) var(--gap-xl);
}

.werk-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.875rem; /* 30px */
}

.werk-card {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

a.werk-card {
  cursor: pointer;
  transition: opacity 0.25s var(--ease-out);
}
a.werk-card:hover { opacity: 0.75; }
a.werk-card:hover .werk-card__image img,
a.werk-card:hover .werk-card__image video { transform: scale(1.03); }

.werk-card__image img,
.werk-card__image video { transition: transform 0.5s var(--ease-funky); }

.werk-card__image {
  width: 100%;
  aspect-ratio: 4 / 5;
  overflow: hidden;
}

.werk-card__image img,
.werk-card__image video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.werk-card__text {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.werk-card__caption {
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  opacity: 0.55;
}

.werk-card__category {
  font-size: 1.0625rem;
  margin: 0;
}

/* only Panel users see this marker — a reminder which cards need a toegangslink */
.werk-card__locked { opacity: 0.7; }

/* ==========================================================================
   Afgeschermd — stand-in for pages that need a personal toegangslink
   ========================================================================== */

.locked {
  padding: var(--gap-md) var(--page-pad) var(--gap-xl);
}

.locked__text {
  max-width: 40rem;
  margin: 0;
  font-size: clamp(1.25rem, 1rem + 1vw, 1.75rem);
  font-weight: 500;
  line-height: 1.3;
}

.locked__text a {
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 0.15em;
  transition: opacity 0.25s var(--ease-out);
}
.locked__text a:hover { opacity: 0.6; }

.locked__form {
  max-width: 40rem;
  margin-top: var(--gap-lg);
}

.locked__label {
  display: block;
  margin-bottom: 0.75rem;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  opacity: 0.55;
}

.locked__row {
  display: flex;
  gap: 1rem;
  align-items: flex-end;
}

.locked__input {
  flex: 1;
  min-width: 0;
  padding: 0.5rem 0;
  border: 0;
  border-bottom: 1.5px solid currentColor;
  border-radius: 0;
  background: none;
  color: inherit;
  font: inherit;
  font-size: 1.25rem;
}
.locked__input:focus { outline: none; border-bottom-width: 2.5px; }

.locked__button {
  padding: 0.75rem 1.5rem;
  border: 1.5px solid currentColor;
  border-radius: 999px;
  background: none;
  color: inherit;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.25s var(--ease-out), color 0.25s var(--ease-out);
}
.locked__button:hover,
.locked__button:focus-visible { background: var(--text-color); color: var(--bg-cream); }

@media (max-width: 56rem) {
  .werk-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 40rem) {
  .werk-grid { grid-template-columns: 1fr; }
}

/* ==========================================================================
   Mobile tuning — tighter vertical rhythm, bigger hero text
   ========================================================================== */

@media (max-width: 40rem) {
  .navbar {
    padding-bottom: 0.875rem; /* ~14px, tighter navbar-to-hero gap on mobile */
  }

  .hero {
    padding-top: 0.875rem; /* ~14px, tighter navbar-to-text gap on mobile */
    padding-bottom: 2.25rem; /* ~36px, tighter text-to-video gap on mobile */
  }

  .hero__text {
    font-size: clamp(1.625rem, 1.1rem + 4vw, 2.5rem); /* slightly smaller again on mobile */
  }

  .intro {
    padding-top: 3.75rem; /* ~60px, was 7.5rem */
  }

  /* same tighter navbar-to-first-section gap as the homepage hero, on every other page */
  .profile,
  .page-heading-section,
  .project,
  .project-alt-top {
    padding-top: 0.875rem;
  }
}

/* visually hidden, still read by search engines and screen readers */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
