/* =========================================================================
   Lari Lähde — portfolio styles
   Dark, moody theme. Mobile-first. Vanilla CSS, no build step.
   ========================================================================= */

/* ---- Design tokens ------------------------------------------------------ */
:root {
  --bg:            #0a0a0b;   /* near-black page background */
  --bg-elev:       #131316;   /* elevated surfaces (cards, header) */
  --bg-elev-2:     #1c1c21;   /* inputs, hovered cards */
  --line:          #2a2a30;   /* hairline borders */
  --text:          #f4f4f5;   /* primary text */
  --text-dim:      #a1a1aa;   /* secondary text */
  --text-faint:    #6b6b74;   /* tertiary / captions */
  --accent:        #e5e5e5;   /* subtle accent (keep it monochrome/moody) */
  --accent-strong: #ffffff;
  --danger:        #f87171;
  --success:       #4ade80;

  --maxw:   1200px;
  --gap:    clamp(1rem, 3vw, 2rem);
  --radius: 10px;

  --header-h: 68px;

  --ff-sans: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --ff-display: "Tanker", "Anton", "Impact", sans-serif; /* titles/logo only — heavy display face, single weight */
  --ff-label: "Clash Grotesk", var(--ff-sans); /* eyebrow/kicker labels — pairs with Tanker, has real lowercase */

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

/* ---- Reset / base ------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--ff-sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* clip (not hidden): hides any horizontal overflow WITHOUT forcing
     overflow-y to `auto`, which would turn <body> into a broken scroll
     container and freeze vertical scrolling on mobile. */
  overflow-x: clip;
}

img, picture, video { max-width: 100%; display: block; }

a { color: inherit; text-decoration: none; }

h1, h2, h3 { line-height: 1.1; letter-spacing: -0.02em; margin: 0; font-weight: 600; }

/* Reduced motion respect */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

/* ---- Shared bits -------------------------------------------------------- */
.section-kicker {
  font-family: var(--ff-label);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  font-size: 0.72rem;
  color: var(--text-faint);
  margin: 0 0 0.75rem;
}

.section-title, .page-title { font-size: clamp(1.8rem, 5vw, 3rem); }
.page-title {
  font-family: var(--ff-display);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.01em;
}

/* Buttons */
.btn {
  --btn-pad-y: 0.8rem;
  --btn-pad-x: 1.5rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: var(--btn-pad-y) var(--btn-pad-x);
  border-radius: 999px;
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.01em;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform 0.2s var(--ease), background 0.2s var(--ease), border-color 0.2s var(--ease), color 0.2s var(--ease);
  white-space: nowrap;
}
.btn:active { transform: translateY(1px); }

.btn-primary { background: var(--accent-strong); color: #0a0a0b; }
.btn-primary:hover { background: #d4d4d8; }

.btn-ghost { background: transparent; color: var(--text); border-color: var(--line); }
.btn-ghost:hover { border-color: var(--text-dim); background: rgba(255,255,255,0.04); }

.btn-lg { --btn-pad-y: 1rem; --btn-pad-x: 2rem; font-size: 1rem; }
.btn-block { width: 100%; }

/* =========================================================================
   HEADER / NAV
   ========================================================================= */
.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  height: var(--header-h);
  display: flex;
  align-items: center;
  transition: background 0.3s var(--ease), border-color 0.3s var(--ease);
  border-bottom: 1px solid transparent;
}
/* Transparent over hero, solid once scrolled (JS toggles .is-scrolled) */
.site-header.is-scrolled,
.site-header.is-solid {
  background: rgba(10,10,11,0.85);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom-color: var(--line);
}
/* Solid-header pages need top padding so content isn't hidden under the bar */
.is-solid ~ main,
.portfolio-page, .contact-page { padding-top: var(--header-h); }

.nav-inner {
  width: 100%;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 var(--gap);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.brand {
  font-family: var(--ff-display);
  font-weight: 400;
  letter-spacing: 0.06em;
  font-size: 1.05rem;
}

.primary-nav { display: flex; align-items: center; gap: 2rem; }
.primary-nav ul {
  list-style: none;
  display: flex;
  gap: 1.75rem;
  margin: 0; padding: 0;
}
.primary-nav a {
  font-size: 0.9rem;
  color: var(--text-dim);
  position: relative;
  padding: 0.25rem 0;
  transition: color 0.2s var(--ease);
}
.primary-nav a:hover { color: var(--text); }
.primary-nav a.is-active { color: var(--text); }
.primary-nav a.is-active::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -2px;
  height: 1px;
  background: var(--text);
}

.nav-social { display: flex; align-items: center; gap: 0.75rem; color: var(--text-dim); }
.nav-social a { display: inline-flex; transition: color 0.2s var(--ease); }
.nav-social a:hover { color: var(--text); }

/* Hamburger */
.nav-toggle {
  display: none;
  position: relative; /* z-index below is a no-op without this */
  flex-direction: column;
  gap: 5px;
  width: 40px; height: 40px;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 0;
  z-index: 110;
  /* iOS Safari: suppress the gray tap-flash and make sure a tap is treated
     as a click rather than possibly waiting on a double-tap-to-zoom gesture. */
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
.nav-toggle span {
  display: block;
  width: 24px; height: 2px;
  background: var(--text);
  /* Taps always resolve to the <button> itself, never a child span —
     defensive against WebKit hit-testing quirks on nested elements. */
  pointer-events: none;
  transition: transform 0.3s var(--ease), opacity 0.2s var(--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 {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  overflow: hidden;
  background: #000;
}
.hero-video {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  z-index: 0;
}
/* Poster shows through until/if video loads; also covers when video absent */
.hero-overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    radial-gradient(120% 80% at 50% 0%, rgba(0,0,0,0.35), transparent 60%),
    linear-gradient(180deg, rgba(10,10,11,0.55) 0%, rgba(10,10,11,0.35) 40%, rgba(10,10,11,0.9) 100%);
}
.hero-content {
  position: relative;
  z-index: 2;
  max-width: 820px;
  padding: 0 var(--gap);
}
.hero-eyebrow {
  font-family: var(--ff-label);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  font-size: 0.78rem;
  color: var(--text-dim);
  margin: 0 0 1.25rem;
}
.hero-title {
  font-family: var(--ff-display);
  font-size: clamp(2.6rem, 8.5vw, 5.5rem);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  margin-bottom: 1.25rem;
}
.hero-sub {
  font-size: clamp(1rem, 2.5vw, 1.25rem);
  color: var(--text-dim);
  max-width: 560px;
  margin: 0 auto 2rem;
}
.hero-actions { display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; }

.hero-scroll {
  position: absolute;
  bottom: 1.75rem; left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  width: 26px; height: 42px;
  border: 1px solid var(--text-faint);
  border-radius: 999px;
  display: flex;
  justify-content: center;
  padding-top: 8px;
}
.hero-scroll span {
  width: 3px; height: 8px;
  background: var(--text-dim);
  border-radius: 3px;
  animation: scrolldot 1.8s var(--ease) infinite;
}
@keyframes scrolldot {
  0% { opacity: 0; transform: translateY(-4px); }
  40% { opacity: 1; }
  100% { opacity: 0; transform: translateY(10px); }
}

.hero-sound-toggle {
  position: absolute;
  bottom: 1.75rem; right: var(--gap);
  z-index: 2;
  width: 42px; height: 42px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(10, 10, 11, 0.55);
  backdrop-filter: blur(6px);
  color: var(--text-dim);
  cursor: pointer;
  transition: color 0.2s var(--ease), border-color 0.2s var(--ease), background 0.2s var(--ease);
}
.hero-sound-toggle:hover,
.hero-sound-toggle:focus-visible {
  color: var(--text);
  border-color: var(--text-faint);
}
.hero-sound-toggle svg { width: 20px; height: 20px; }
.hero-sound-toggle .icon-sound-on { display: none; }
.hero-sound-toggle[aria-pressed="true"] .icon-sound-off { display: none; }
.hero-sound-toggle[aria-pressed="true"] .icon-sound-on { display: block; }
.hero-sound-toggle[aria-pressed="true"] { color: var(--accent-strong); border-color: var(--text-faint); }

/* =========================================================================
   SECTION LAYOUT HELPERS
   ========================================================================= */
.intro, .featured, .cta { padding: clamp(3rem, 8vw, 6rem) var(--gap); }
.intro, .featured, .cta { max-width: var(--maxw); margin: 0 auto; }
/* First section after the hero — extra top space so it doesn't feel glued
   to the hero's bottom edge when the scroll-gate lands here. */
.intro { padding-top: clamp(4.5rem, 11vw, 7.5rem); }

/* =========================================================================
   WORKED WITH — JR-style "next station" display
   Ported from a React/Tailwind component (StationDisplay.tsx) to plain CSS.
   Fixed dark/blue palette by design (mimics a real train departure screen) —
   intentionally not using the site's --bg/--text tokens here.
   ========================================================================= */
.font-jr {
  font-family: "Zen Kaku Gothic New", ui-sans-serif, system-ui, sans-serif;
  font-feature-settings: "palt" 1;
}
/* Sits in the intro grid's right column, so its width no longer tracks the
   viewport — size the insides against the panel itself (container queries). */
.station-display { width: 100%; max-width: 1080px; margin: 0 auto; container-type: inline-size; }
.station-bezel {
  border-radius: 26px;
  background: linear-gradient(180deg, #2b2f34, #0f1113);
  padding: 0.625rem;
  box-shadow: 0 30px 80px -30px rgba(0, 0, 0, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 0 0 1px rgba(0, 0, 0, 0.6);
}
.station-screen {
  overflow: hidden;
  border-radius: 18px;
  background: #0a1320;
}

/* -- Header bar: bound-for / current stop / clock -- */
.station-header {
  display: flex;
  align-items: stretch;
  gap: 0.75rem;
  background: linear-gradient(90deg, #12315c, #0e2547 55%, #081527);
  padding: 0.75rem 1rem;
  color: #fff;
}
.station-boundfor {
  display: flex;
  flex-direction: column;
  justify-content: center;
  border-left: 4px solid #4b8bff;
  padding-left: 0.75rem;
  line-height: 1.2;
}
.station-label {
  font-size: 9px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  color: rgba(255, 255, 255, 0.6);
}
.station-boundfor-name { white-space: nowrap; font-size: 0.75rem; font-weight: 700; }

.station-current {
  display: flex;
  min-width: 0;
  flex: 1;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.station-workedwith {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.24em;
  color: #7fb0ff;
}
.station-dot {
  width: 0.5rem; height: 0.5rem;
  border-radius: 50%;
  background: #ff3b3b;
  animation: station-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.station-current-name {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: clamp(1.75rem, 6vw, 3.6rem);
  font-weight: 900;
  line-height: 1;
  animation: station-fade-up 0.5s ease;
}

.station-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  gap: 0.25rem;
}
.station-clock {
  font-variant-numeric: tabular-nums;
  font-size: 1.125rem;
  font-weight: 700;
  line-height: 1;
}
.station-cam {
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.12);
  padding: 0.125rem 0.5rem;
  text-align: center;
  font-size: 9px;
  font-weight: 500;
  line-height: 1.2;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.2);
}
.station-cam b { font-weight: 700; color: #7fb0ff; }

/* -- Screen: bezier ribbon + stops + legend -- */
.station-viz {
  position: relative;
  width: 100%;
  aspect-ratio: 960 / 430;
  background: linear-gradient(180deg, #0c1a2e, #0a1320);
}
.station-svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.station-stop-marker { transition: transform 900ms cubic-bezier(0.22, 1, 0.36, 1), opacity 900ms ease; }

.station-legend {
  position: absolute;
  left: 4%; bottom: 10%;
  z-index: 1;
  color: #c6d6ef;
}
.station-legend-title {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: #5b9bff;
}
.station-legend-rows {
  margin-top: 0.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  font-size: 10px;
  font-weight: 500;
}
.station-legend-rows span { display: flex; align-items: center; gap: 0.375rem; }
.station-legend-dot { width: 0.625rem; height: 0.625rem; border-radius: 50%; }
.station-legend-dot.is-now { background: #ff3b3b; }
.station-legend-dot.is-upcoming { border: 2px solid #4b8bff; background: #0b1727; }

/* Narrow panels: the three header columns fight over ~100px and the station
   name truncates to "Events…". Give it its own full-width row instead.
   Viewport-based fallback first, then the container-query version which is
   what actually matters now that the panel is a narrow grid column. */
@media (max-width: 639px) {
  .station-header { flex-wrap: wrap; row-gap: 0.5rem; }
  .station-boundfor { order: 1; }
  .station-meta { order: 2; margin-left: auto; }
  .station-current { order: 3; flex-basis: 100%; }
}

@media (min-width: 640px) {
  .station-header { gap: 1rem; padding: 0.75rem 1.25rem; }
  .station-label { font-size: 11px; }
  .station-boundfor-name { font-size: 1rem; }
  .station-workedwith { font-size: 11px; }
  .station-legend-title, .station-legend-rows { font-size: 0.75rem; }
}

@container (max-width: 560px) {
  .station-header { flex-wrap: wrap; row-gap: 0.4rem; gap: 0.6rem; padding: 0.6rem 0.85rem; }
  .station-boundfor { order: 1; padding-left: 0.6rem; border-left-width: 3px; }
  .station-meta { order: 2; margin-left: auto; flex-direction: row; align-items: center; gap: 0.5rem; }
  .station-current { order: 3; flex-basis: 100%; }
  .station-label, .station-workedwith { font-size: 9px; letter-spacing: 0.16em; }
  .station-boundfor-name { font-size: 0.8rem; }
  .station-legend-title, .station-legend-rows { font-size: 9px; }
}

/* Panel-relative sizing for the one element that must not overflow. */
.station-current-name { font-size: clamp(1.4rem, 2.4vw, 2rem); }
@supports (container-type: inline-size) {
  .station-current-name { font-size: clamp(1.05rem, 7.5cqw, 2.2rem); }
  .station-clock { font-size: clamp(0.95rem, 4cqw, 1.4rem); }
}

@keyframes station-fade-up {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes station-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}
@media (prefers-reduced-motion: reduce) {
  .station-dot { animation: none; }
  .station-current-name { animation: none; }
  .station-stop-marker { transition: none; }
}

/* Intro / bio + the partner display sharing one row */
.intro {
  max-width: var(--maxw);
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(300px, 0.85fr);
  gap: clamp(1.75rem, 4vw, 3rem);
  align-items: center;
}
.intro-about {
  display: grid;
  grid-template-columns: minmax(150px, 210px) minmax(0, 1fr);
  gap: clamp(1.25rem, 3vw, 2rem);
  align-items: center;
}
.intro-photo img {
  width: 100%;
  height: auto;
  border-radius: var(--radius);
  filter: brightness(0.95);
}
.intro-title { font-size: clamp(1.5rem, 2.6vw, 2.1rem); margin-bottom: 1rem; }
.intro-body { color: var(--text-dim); margin: 0 0 0.9rem; font-size: 0.98rem; }

/* Stack the partner display under the bio before the columns get too tight */
@media (max-width: 1080px) {
  .intro { grid-template-columns: 1fr; }
  .intro-partners { max-width: 620px; margin: 0 auto; width: 100%; }
}
@media (max-width: 700px) {
  .intro-about { grid-template-columns: 1fr; text-align: center; }
  .intro-photo { max-width: 260px; margin: 0 auto; }
}

/* Featured */
.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  margin-bottom: 2rem;
}
.section-head .section-kicker { margin: 0; flex-basis: 100%; }
.section-link { color: var(--text-dim); font-size: 0.9rem; transition: color 0.2s var(--ease); }
.section-link:hover { color: var(--text); }

.featured-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: clamp(0.75rem, 2vw, 1.25rem);
}
.feat-card {
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  aspect-ratio: 4 / 5;
  background: var(--bg-elev);
  isolation: isolate;
}
/* <picture> is just a wrapper with no height of its own — without this the
   img's height:100% has nothing to resolve against and falls back to its
   intrinsic ratio, leaving dead space below the photo inside the card. */
.feat-card picture {
  display: block;
  width: 100%;
  height: 100%;
}
.feat-card img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 0.5s var(--ease), filter 0.4s var(--ease);
  filter: brightness(0.9);
}
.feat-card:hover img { transform: scale(1.05); filter: brightness(1); }
.feat-meta {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  background: linear-gradient(0deg, rgba(0,0,0,0.85), transparent);
  z-index: 1;
}
.feat-tag {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--text-dim);
}
.feat-name { font-weight: 600; font-size: 1rem; }

/* --- Homepage entry cards -------------------------------------------------
   Three doors into the portfolio (Full Portfolio / Photos / Videos) rather
   than a spread of individual events. Bigger, squarer and set in the display
   face so they read as navigation, not as photo captions. */
.featured-grid--entry { grid-template-columns: repeat(4, 1fr); }
.feat-card--entry { aspect-ratio: 3 / 4; }
.feat-card--entry img { filter: brightness(0.62); }
.feat-card--entry:hover img { filter: brightness(0.78); }
/* Deeper scrim than the event cards: the title sits larger here and has to
   stay readable over a busy festival frame. */
.feat-card--entry .feat-meta {
  padding: 1.25rem;
  background: linear-gradient(0deg, rgba(0,0,0,0.9) 10%, rgba(0,0,0,0.45) 55%, transparent);
}
.feat-card--entry .feat-name {
  font-family: var(--ff-display);
  font-weight: 400;
  font-size: clamp(1.5rem, 2.6vw, 2.1rem);
  line-height: 1.05;
  letter-spacing: 0.01em;
  text-transform: uppercase;
}

/* CTA */
.cta { text-align: center; }
.cta-inner {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(2.5rem, 6vw, 4.5rem) var(--gap);
  background:
    radial-gradient(120% 140% at 50% 0%, rgba(255,255,255,0.05), transparent 60%),
    var(--bg-elev);
}
.cta-title { font-size: clamp(1.6rem, 4.5vw, 2.6rem); margin-bottom: 0.75rem; }
.cta-sub { color: var(--text-dim); margin: 0 auto 2rem; max-width: 480px; }

/* =========================================================================
   FOOTER
   ========================================================================= */
.site-footer {
  border-top: 1px solid var(--line);
  padding: 3rem var(--gap) 2.5rem;
}
.footer-inner {
  max-width: var(--maxw);
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 2rem;
}
.footer-brand { font-weight: 700; letter-spacing: 0.12em; }
.footer-nav { display: flex; gap: 1.5rem; }
.footer-nav a, .footer-social a { color: var(--text-dim); font-size: 0.9rem; transition: color 0.2s var(--ease); }
.footer-nav a:hover, .footer-social a:hover { color: var(--text); }
.footer-social { margin-left: auto; }
.footer-social a { display: inline-flex; align-items: center; }
.footer-social svg { display: block; width: 20px; height: 20px; }
.footer-tagline { flex-basis: 100%; color: var(--text-dim); font-size: 0.85rem; margin: 0.75rem 0 0; max-width: 640px; }
.footer-copy { flex-basis: 100%; color: var(--text-faint); font-size: 0.8rem; margin: 0.4rem 0 0; }

/* =========================================================================
   PORTFOLIO PAGE
   ========================================================================= */
.page-head {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: clamp(2.5rem, 6vw, 4rem) var(--gap) 1.5rem;
  text-align: center;
}
.page-lead { color: var(--text-dim); max-width: 560px; margin: 1rem auto 0; }

.filter-bar {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 var(--gap) 2rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  justify-content: center;
}
.filter-btn {
  background: transparent;
  border: 1px solid var(--line);
  color: var(--text-dim);
  padding: 0.55rem 1.1rem;
  border-radius: 999px;
  font-size: 0.85rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s var(--ease);
}
.filter-btn:hover { border-color: var(--text-dim); color: var(--text); }
.filter-btn.is-active { background: var(--accent-strong); color: #0a0a0b; border-color: var(--accent-strong); }

/* Secondary tier — filters within the Video tab only, visually smaller/
   quieter than the main filter row above it. */
.subfilter-bar {
  max-width: var(--maxw);
  margin: -0.75rem auto 1.5rem;
  padding: 0 var(--gap);
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  justify-content: center;
}
.subfilter-bar[hidden] { display: none; }
.subfilter-btn {
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-faint);
  padding: 0.35rem 0.85rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s var(--ease);
}
.subfilter-btn:hover { color: var(--text-dim); }
.subfilter-btn.is-active { background: var(--bg-elev-2); color: var(--text); border-color: var(--line); }

/* Masonry-style grid via CSS columns */
.portfolio-grid {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 var(--gap) 4rem;
  column-count: 3;
  column-gap: clamp(0.75rem, 2vw, 1.25rem);
}
.grid-item {
  position: relative;
  margin: 0 0 clamp(0.75rem, 2vw, 1.25rem);
  break-inside: avoid;
  border-radius: var(--radius);
  overflow: hidden;
  cursor: pointer;
  background: var(--bg-elev);
  display: block;
}
.grid-item img {
  width: 100%;
  height: auto;
  transition: transform 0.5s var(--ease), filter 0.4s var(--ease);
  filter: brightness(0.9);
}
.grid-item:hover img { transform: scale(1.04); filter: brightness(1); }

.grid-cap {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 0.9rem 1rem;
  font-size: 0.9rem;
  font-weight: 600;
  background: linear-gradient(0deg, rgba(0,0,0,0.85), transparent);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
}
.grid-item:hover .grid-cap { opacity: 1; transform: translateY(0); }
.cap-tag {
  display: inline-block;
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: var(--text-dim);
  margin-right: 0.5rem;
}

/* Play badge for video items */
.play-badge {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 60px; height: 60px;
  border-radius: 50%;
  background: rgba(0,0,0,0.55);
  border: 1px solid rgba(255,255,255,0.6);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.2rem;
  padding-left: 4px;
  backdrop-filter: blur(2px);
  transition: transform 0.25s var(--ease), background 0.25s var(--ease);
  z-index: 1;
}
.grid-item:hover .play-badge { transform: translate(-50%, -50%) scale(1.1); background: rgba(0,0,0,0.75); }

/* Video grid tiles: the thumbnail IS the (muted, looping) video — no static
   poster shown, no play button, nothing to click "to start" — it's already
   playing. A small expand cue on hover is the only affordance; clicking
   anywhere opens the lightbox with sound, continuing from the same frame. */
.grid-video {
  display: block;
  width: 100%;
  height: auto;
  transition: transform 0.5s var(--ease), filter 0.4s var(--ease);
  filter: brightness(0.9);
}
.grid-item:hover .grid-video { transform: scale(1.04); filter: brightness(1); }
.grid-expand {
  position: absolute;
  top: 0.75rem; right: 0.75rem;
  width: 34px; height: 34px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: rgba(10, 10, 11, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.25);
  color: #fff;
  opacity: 0;
  transform: scale(0.85);
  transition: opacity 0.25s var(--ease), transform 0.25s var(--ease);
  z-index: 1;
}
.grid-expand svg { width: 15px; height: 15px; }
.grid-item:hover .grid-expand { opacity: 1; transform: scale(1); }

/* Hidden by filter */
.grid-item.is-hidden { display: none; }

/* Scroll-reveal: fade + rise as grid photos enter the viewport. JS adds
   .reveal-pending only when motion is allowed and IntersectionObserver
   exists — no JS / reduced motion just means everything renders visible,
   never permanently hidden. Main portfolio grid only (not the album popup). */
@media (prefers-reduced-motion: no-preference) {
  #portfolioGrid .grid-item {
    transition: opacity 0.5s var(--ease), transform 0.5s var(--ease);
  }
  #portfolioGrid .grid-item.reveal-pending {
    opacity: 0;
    transform: translateY(14px);
  }
}

.grid-empty {
  text-align: center;
  color: var(--text-faint);
  padding: 3rem var(--gap) 5rem;
}

/* =========================================================================
   LIGHTBOX
   ========================================================================= */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(5,5,6,0.94);
  backdrop-filter: blur(6px);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  padding: clamp(1rem, 4vw, 3rem);
  opacity: 0;
  transition: opacity 0.25s var(--ease);
}
.lightbox:not([hidden]) { opacity: 1; }
.lightbox[hidden] { display: none; }

.lightbox-stage {
  max-width: min(1100px, 92vw);
  max-height: 82vh;
  display: flex;
  align-items: center;
  justify-content: center;
}
.lightbox-stage img,
.lightbox-stage video {
  max-width: 100%;
  max-height: 82vh;
  width: auto; height: auto;
  border-radius: 6px;
  object-fit: contain;
}
.lightbox-stage iframe {
  width: min(1100px, 92vw);
  aspect-ratio: 16 / 9;
  max-height: 82vh;
  border: 0;
  border-radius: 6px;
}
.lightbox-caption {
  color: var(--text-dim);
  font-size: 0.9rem;
  margin: 1rem 0 0;
  text-align: center;
}

.lightbox-close, .lightbox-nav {
  position: absolute;
  background: rgba(255,255,255,0.08);
  border: 1px solid var(--line);
  color: var(--text);
  cursor: pointer;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.2s var(--ease), transform 0.2s var(--ease);
}
.lightbox-close:hover, .lightbox-nav:hover { background: rgba(255,255,255,0.18); }

.lightbox-close {
  top: clamp(1rem, 3vw, 2rem);
  right: clamp(1rem, 3vw, 2rem);
  width: 44px; height: 44px;
  font-size: 1.1rem;
}
.lightbox-nav {
  top: 50%;
  transform: translateY(-50%);
  width: 48px; height: 48px;
  font-size: 1.8rem;
  line-height: 1;
}
.lightbox-prev { left: clamp(0.5rem, 2vw, 1.5rem); }
.lightbox-next { right: clamp(0.5rem, 2vw, 1.5rem); }
.lightbox-nav:hover { transform: translateY(-50%) scale(1.08); }

/* =========================================================================
   EVENT ALBUM POPUP
   A floating, centered window showing one event's photos — not a full-screen
   takeover. Sits BELOW the fixed header (z 90 < 100) so the nav stays usable;
   the fullscreen photo viewer (z 200) still opens on top when a photo is tapped.
   ========================================================================= */
.album-modal {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: calc(var(--header-h) + 1.25rem) var(--gap) 1.5rem;
  /* light scrim — dims just enough to focus, without blacking out the site */
  background: rgba(4,4,6,0.55);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  animation: albumFade 0.2s var(--ease);
}
.album-modal[hidden] { display: none; }
@keyframes albumFade { from { opacity: 0; } to { opacity: 1; } }

/* The floating window */
.album-card {
  position: relative;
  width: min(1080px, 100%);
  max-height: 100%;
  display: flex;
  flex-direction: column;
  background: linear-gradient(180deg, #17171b, #101013);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: 0 40px 120px rgba(0,0,0,0.65);
  overflow: hidden;
  animation: albumPop 0.3s var(--ease);
}
@keyframes albumPop {
  from { opacity: 0; transform: translateY(18px) scale(0.98); }
  to   { opacity: 1; transform: none; }
}

.album-head {
  flex-shrink: 0;
  padding: 1.4rem 1.75rem 1.15rem;
  border-bottom: 1px solid var(--line);
  background: rgba(255,255,255,0.015);
}
.album-tag {
  text-transform: uppercase;
  letter-spacing: 0.2em;
  font-size: 0.66rem;
  color: var(--text-faint);
  margin: 0 0 0.4rem;
}
.album-title { font-size: clamp(1.3rem, 3vw, 1.9rem); margin: 0 0 0.25rem; }
.album-count { color: var(--text-dim); font-size: 0.85rem; margin: 0; }

/* Photo grid scrolls INSIDE the card */
.album-grid {
  overflow-y: auto;
  padding: 1.25rem 1.75rem 1.75rem;
  column-count: 3;
  column-gap: 0.85rem;
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}
.album-grid::-webkit-scrollbar { width: 10px; }
.album-grid::-webkit-scrollbar-thumb { background: var(--line); border-radius: 10px; border: 3px solid transparent; background-clip: padding-box; }

.album-cell {
  margin: 0 0 0.85rem;
  break-inside: avoid;
  border-radius: 10px;
  overflow: hidden;
  cursor: pointer;
  background: var(--bg-elev-2);
}
.album-cell img {
  width: 100%; height: auto; display: block;
  transition: transform 0.5s var(--ease), filter 0.4s var(--ease);
  filter: brightness(0.94);
}
.album-cell:hover img { transform: scale(1.05); filter: brightness(1.05); }

.album-close {
  position: absolute;
  top: 0.85rem; right: 0.85rem;
  z-index: 3;
  width: 38px; height: 38px;
  border-radius: 999px;
  background: rgba(0,0,0,0.4);
  border: 1px solid var(--line);
  color: var(--text);
  font-size: 1rem;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.2s var(--ease), transform 0.2s var(--ease);
}
.album-close:hover { background: rgba(0,0,0,0.7); transform: scale(1.08); }

/* Keep the nav bar solid + readable + clickable above the open popup */
body.album-open .site-header {
  background: rgba(10,10,11,0.9);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom-color: var(--line);
}

@media (max-width: 900px) { .album-grid { column-count: 2; } }
@media (max-width: 560px) {
  .album-modal { padding: calc(var(--header-h) + 0.5rem) 0.6rem 0.6rem; }
  .album-card { border-radius: 12px; }
  .album-grid { padding: 1rem; column-gap: 0.6rem; }
  .album-cell { margin-bottom: 0.6rem; }
}

/* =========================================================================
   CONTACT PAGE
   ========================================================================= */
.contact-wrap {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: clamp(2.5rem, 6vw, 4.5rem) var(--gap) 5rem;
  display: grid;
  grid-template-columns: 1fr 1.1fr;
  gap: clamp(2rem, 6vw, 4.5rem);
  align-items: start;
}
.contact-points {
  list-style: none;
  padding: 0;
  margin: 2rem 0 0;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.contact-points li {
  color: var(--text-dim);
  padding-left: 1.5rem;
  position: relative;
}
.contact-points li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.65em;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--text);
}

/* Form */
.contact-form {
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(1.5rem, 4vw, 2.5rem);
}
.field { margin-bottom: 1.25rem; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }

.field label {
  display: block;
  font-size: 0.85rem;
  font-weight: 500;
  margin-bottom: 0.5rem;
  color: var(--text-dim);
}
.req { color: var(--danger); }
.optional { color: var(--text-faint); font-weight: 400; }

.field input,
.field select,
.field textarea {
  width: 100%;
  background: var(--bg-elev-2);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.75rem 0.85rem;
  color: var(--text);
  font-family: inherit;
  font-size: 0.95rem;
  transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.field textarea { resize: vertical; min-height: 120px; }
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--text-dim);
  box-shadow: 0 0 0 3px rgba(255,255,255,0.06);
}
.field input::placeholder,
.field textarea::placeholder { color: var(--text-faint); }

/* select arrow colour on dark */
.field select { appearance: none; background-image:
  linear-gradient(45deg, transparent 50%, var(--text-dim) 50%),
  linear-gradient(135deg, var(--text-dim) 50%, transparent 50%);
  background-position: calc(100% - 20px) 55%, calc(100% - 15px) 55%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 2.5rem;
}
/* date input calendar icon on dark */
.field input[type="date"]::-webkit-calendar-picker-indicator { filter: invert(0.7); cursor: pointer; }

/* Invalid state */
.field.has-error input,
.field.has-error select,
.field.has-error textarea { border-color: var(--danger); }
.field-error {
  display: block;
  color: var(--danger);
  font-size: 0.78rem;
  margin-top: 0.4rem;
  min-height: 0;
}

/* Honeypot — visually hidden but present in the DOM for bots */
.hp-field {
  position: absolute !important;
  left: -9999px !important;
  width: 1px; height: 1px;
  overflow: hidden;
}

/* Form status message */
.form-status {
  margin: 1.25rem 0 0;
  padding: 0.85rem 1rem;
  border-radius: 8px;
  font-size: 0.9rem;
  border: 1px solid var(--line);
}
.form-status[hidden] { display: none; }
.form-status.is-success { color: var(--success); border-color: rgba(74,222,128,0.4); background: rgba(74,222,128,0.08); }
.form-status.is-error { color: var(--danger); border-color: rgba(248,113,113,0.4); background: rgba(248,113,113,0.08); }

.submit-loading { opacity: 0.7; pointer-events: none; }

/* =========================================================================
   RESPONSIVE — TABLET
   ========================================================================= */
@media (max-width: 900px) {
  .portfolio-grid { column-count: 2; }
  .contact-wrap { grid-template-columns: 1fr; }
}

/* =========================================================================
   RESPONSIVE — MOBILE (nav collapses to hamburger)
   ========================================================================= */
@media (max-width: 720px) {
  .nav-toggle { display: flex; }

  .primary-nav {
    position: fixed;
    inset: 0 0 0 auto;
    width: min(320px, 82vw);
    height: 100dvh;
    background: var(--bg-elev);
    border-left: 1px solid var(--line);
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    padding: calc(var(--header-h) + 1.5rem) 2rem 2rem;
    gap: 2rem;
    transform: translateX(100%);
    transition: transform 0.3s var(--ease);
    z-index: 105;
  }
  .primary-nav.is-open { transform: translateX(0); }
  .primary-nav ul { flex-direction: column; gap: 1.25rem; width: 100%; }
  .primary-nav a { font-size: 1.15rem; }

  /* Dim backdrop when menu open */
  body.nav-open::after {
    content: "";
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.5);
    z-index: 104;
  }

  /* The backdrop above lives in the ROOT stacking context, but the nav panel
     and the toggle button are both nested inside .site-header — so at the
     header's normal z-index: 100 the backdrop painted over the entire header
     and swallowed every tap, including the one that closes the menu. Lifting
     the header above the backdrop while the menu is open keeps the panel and
     the X button tappable; page content underneath stays dimmed and inert. */
  body.nav-open .site-header { z-index: 106; }

  .featured-grid { grid-template-columns: 1fr 1fr; }
  .featured-grid--entry { grid-template-columns: 1fr 1fr; }
  /* Stacked on phones — full width gives each cover real presence, and avoids
     an orphaned card whenever the count is not a multiple of the column count. */
  .featured-grid--entry { grid-template-columns: 1fr; }
  .feat-card--entry { aspect-ratio: 16 / 10; }
  .section-head { flex-direction: column; }

  /* Footer: stack into one centred column. The desktop row layout left the
     Instagram link stranded against the right edge on its own line, because
     margin-left:auto still applied after the items wrapped. */
  .footer-inner {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 1.25rem;
  }
  .footer-social { margin-left: 0; }
  .footer-nav { gap: 1.75rem; }
  /* flex-basis is the MAIN axis once the container is a column — leaving these
     at 100% would size them against the footer's height, not its width. */
  .footer-tagline,
  .footer-copy { flex-basis: auto; margin: 0; max-width: 40ch; }
}

@media (max-width: 480px) {
  .portfolio-grid { column-count: 1; }
  .field-row { grid-template-columns: 1fr; }
  .featured-grid { grid-template-columns: 1fr; }
  .hero-actions { flex-direction: column; }
  .hero-actions .btn { width: 100%; }
}
