/* ============================================================================
   Michael Huber — VFX Portfolio
   main.css

   Contents:
     00  Webfonts
     01  Tokens
     02  Reset & base
     03  Typography
     04  Layout primitives
     05  Header / nav
     06  Footer
     07  Buttons & links
     08  Home hero
     09  Work — filters, grid
     10  Project detail
     11  Legal pages
     12  Contact page
     13  News — banner + timeline
     14  Filmography & awards
     15  Lightbox
     16  Before/after compare
     17  Motion & reveal
     18  Responsive
   ========================================================================== */


/* == 00  Webfonts =========================================================
   Self-hosted so nothing is requested from Google — no third party, no
   privacy question, and they work offline.

   The four files go in assets/fonts/. If they're missing the site still
   works: it falls back to the system fonts named in --font-sans/--font-mono
   below. See README §6 for where to download them.

   font-display: swap  →  text shows immediately in the fallback and swaps
   when the webfont arrives, instead of flashing invisible.               */

@font-face {
  font-family: "Inter";
  src: url("../fonts/Inter-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("../fonts/Inter-Medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("../fonts/Inter-SemiBold.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("../fonts/JetBrainsMono-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("../fonts/JetBrainsMono-Medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}


/* == 01  Tokens =========================================================== */

:root {
  --bg:         #0A0A0B;
  --surface:    #141416;
  --surface-hi: #1E1E21;
  --text:       #EDEDEF;
  --text-dim:   #9A9AA3;   /* AA-checked against --bg (6.9:1) */
  --text-faint: #6E6E77;   /* decorative only — never body copy */
  --rule:       #2A2A2E;
  /* ACCENT — links, active states, highlights, focus rings.
     Cool icy silver with a hint of blue. Change --accent and it updates
     everywhere on the site; --accent-dim is the quieter version used for
     hover borders and list markers, --accent-ink is the dark text that sits
     on top of an accent-filled button. */
  --accent:     #C3D4E3;
  --accent-dim: #6E8398;
  --accent-ink: #0B1119;

  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI",
               Helvetica, Arial, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo,
               Consolas, monospace;

  /* PAGE WIDTH — the max width of content on every page.
     Make this bigger for a wider site, smaller for a narrower one.
     Body text stays readable regardless: paragraphs are capped separately
     by `.prose` further down (search for "max-width: 68ch"). */
  --max:    1520px;

  --gutter: clamp(1.25rem, 5vw, 4rem);

  /* PROJECT GRID — how many project cards sit in one row on a wide screen.
     Change this number and the grid follows. Narrower screens step down
     automatically (see section 18, Responsive). */
  --grid-cols: 4;

  /* THUMBNAIL SHAPE — the proportions of every project card image.
     Written as width / height. 280 / 415 is a portrait, movie-poster shape.
     Use 16 / 9 for landscape, 1 / 1 for square.
     This is a RATIO, not a fixed size: cards keep this shape while scaling
     to fit the screen, so they stay sharp on large and small displays. */
  --thumb-ratio: 280 / 415;

  --t-fast: 180ms cubic-bezier(0.4, 0, 0.2, 1);
  --t-mid:  300ms cubic-bezier(0.4, 0, 0.2, 1);
  --t-slow: 600ms cubic-bezier(0.16, 1, 0.3, 1);

  --nav-h: 72px;
}


/* == 02  Reset & base ===================================================== */

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 1rem);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 17px;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

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

/* Animated particle background (assets/js/background.js).
   Fixed behind everything. Anything opaque drawn on top — the hero video, a
   project's video frame, a poster — hides it, so it shows through only where
   there is no video. It never intercepts clicks. */
#bg-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}

/* Lift the real content above the canvas. */
body > main,
body > .site-footer { position: relative; z-index: 1; }

::selection { background: var(--accent); color: var(--accent-ink); }

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

.skip-link {
  position: absolute;
  top: -100px; left: 1rem;
  z-index: 200;
  padding: 0.75rem 1.25rem;
  background: var(--accent);
  color: var(--accent-ink);
  font-family: var(--font-mono);
  font-size: 0.8rem;
  text-decoration: none;
  transition: top var(--t-fast);
}
.skip-link:focus { top: 1rem; }

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


/* == 03  Typography ======================================================= */

h1, h2, h3, h4 {
  margin: 0 0 0.5em;
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.02em;
}

/* PAGE HEADLINE SIZE — PORTFOLIO / VFX BREAKDOWNS / ABOUT / project titles / 404.
   Change the middle value to resize them all at once; the first is the floor
   on phones, the last the ceiling on very wide screens.
   Was: clamp(1.8rem, 4.8vw, 3.2rem) — this is another 20% smaller. */
h1 { font-size: clamp(1.44rem, 3.84vw, 2.56rem); }
h2 { font-size: clamp(1.4rem, 3.2vw, 2.2rem); }
h3 { font-size: clamp(1.15rem, 2vw, 1.4rem); letter-spacing: -0.01em; }

p { margin: 0 0 1.25em; }

.prose { max-width: 68ch; }
.prose p:last-child { margin-bottom: 0; }

/* PAGE HEADLINES — all caps.
   Covers the big heading at the top of Portfolio / VFX Breakdowns / About /
   404, the project title on a case-study page, and "Contact" in the footer.
   Delete a line from this list to return that heading to normal case. */
.page-head h1,
.project-title,
.site-footer h2 {
  text-transform: uppercase;
  letter-spacing: 0.005em;   /* capitals don't want the tight tracking */
}

/* PAGE TAGLINES — the short line under a page headline, also all caps.
   A tagline is a few words; the error pages carry a full sentence instead and
   opt out with class="lead lead--sentence". */
.page-head .lead:not(.lead--sentence) {
  text-transform: uppercase;
  letter-spacing: 0.1em;     /* caps at this size need room to breathe */
  font-size: clamp(0.8rem, 1.4vw, 0.95rem);
  font-family: var(--font-mono);
}

/* Monospace meta — the technical accent used for labels, years, tool lists */
.mono {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.lead {
  font-size: clamp(1.05rem, 2vw, 1.3rem);
  color: var(--text-dim);
  max-width: 60ch;
}

/* Numbered section header:  01 —— SELECTED WORK  */
.section-head {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 2.5rem;
}
.section-head__num {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  color: var(--accent);
  flex: none;
}
.section-head__title {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text);
  flex: none;
  margin: 0;
  font-weight: 500;
}
.section-head::after {
  content: "";
  height: 1px;
  background: var(--rule);
  flex: 1 1 auto;
}


/* == 04  Layout primitives ================================================ */

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

.section { padding-block: clamp(4rem, 10vw, 7.5rem); }
.section--tight { padding-block: clamp(2.5rem, 6vw, 4rem); }

.page-head {
  padding-top: calc(var(--nav-h) + clamp(3rem, 8vw, 6rem));
  padding-bottom: clamp(2rem, 5vw, 3.5rem);
}
.page-head h1 { margin-bottom: 0.75rem; }

.rule { height: 1px; background: var(--rule); border: 0; margin: 0; }


/* == 05  Header / nav ===================================================== */

.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  transition: background var(--t-mid), border-color var(--t-mid),
              backdrop-filter var(--t-mid);
  /* The rule under the nav. It's on every page including the home page, where
     it sits over the hero video before you've scrolled. */
  border-bottom: 1px solid var(--rule);
}

/* While the mobile menu is open the header must NOT have a backdrop-filter:
   a filter on an ancestor becomes the containing block for position:fixed
   descendants, which traps the full-screen menu inside the 72px header and
   pushes its first items off the top of the screen.

   All three selectors are spelled out because the two rules that set the
   header background above are more specific than a bare .is-menu-open. */
.site-header.is-menu-open,
body:not(.home) .site-header.is-menu-open,
body.home .site-header.is-menu-open:not(.is-scrolled) {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  background: transparent;
}

/* HOME PAGE, BEFORE YOU SCROLL — the band of video from the top of the screen
   down to the rule under the nav is blurred and darkened, so the logo and menu
   stay readable over any footage. Two knobs: blur() is the softness,
   brightness() the darkening (1 = untouched, lower = darker). */
body.home .site-header:not(.is-scrolled) {
  backdrop-filter: blur(12px) brightness(0.6);
  -webkit-backdrop-filter: blur(12px) brightness(0.6);
}
.site-header.is-scrolled,
body:not(.home) .site-header {
  background: rgba(10, 10, 11, 0.82);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom-color: var(--rule);
}

.site-header__inner {
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
}

/* HOME — the button at the top-left. Set in the same monospace caps as the
   nav items on the right so the header reads as one row of controls. */
.brand {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-dim);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  /* A comfortable thumb target on phones without moving the label. */
  min-height: 44px;
  padding-right: 0.75rem;
  position: relative;
  transition: color var(--t-fast);
}
.brand::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: calc(100% - 0.75rem);   /* discount the padding on the right */
  height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-mid);
}
.brand:hover::after,
.brand[aria-current="page"]::after { transform: scaleX(1); }
.brand:hover,
.brand[aria-current="page"] { color: var(--text); }

.nav { display: flex; align-items: center; gap: clamp(1.25rem, 3vw, 2.25rem); }

.nav a {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-dim);
  text-decoration: none;
  position: relative;
  padding-block: 0.35rem;
  transition: color var(--t-fast);
}
.nav a::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-mid);
}
.nav a:hover { color: var(--text); }
.nav a:hover::after,
.nav a[aria-current="page"]::after { transform: scaleX(1); }
.nav a[aria-current="page"] { color: var(--text); }

/* Mobile menu toggle */
.nav-toggle {
  display: none;
  width: 40px; height: 40px;
  background: none; border: 0;
  padding: 0; cursor: pointer;
  color: var(--text);
}
.nav-toggle span {
  display: block;
  width: 22px; height: 1.5px;
  margin: 5px auto;
  background: currentColor;
  transition: transform var(--t-mid), opacity var(--t-fast);
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }


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

.site-footer {
  border-top: 1px solid var(--rule);
  padding-block: clamp(3rem, 7vw, 5rem);
  margin-top: auto;
}
.site-footer__grid {
  display: flex;
  flex-wrap: wrap;
  gap: 2.5rem 4rem;
  justify-content: space-between;
  align-items: flex-start;
}
/* "GET IN TOUCH" in the footer. Was: clamp(1.2rem, 3.2vw, 1.8rem) — another
   20% smaller, in step with the page headlines above. */
.site-footer h2 {
  font-size: clamp(0.96rem, 2.56vw, 1.44rem);
  margin-bottom: 0.35rem;
}
.footer-links {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.footer-links a {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  color: var(--text-dim);
  text-decoration: none;
  transition: color var(--t-fast);
  width: fit-content;
}
.footer-links a:hover { color: var(--accent); }
.footer-links a::before {
  content: attr(data-label);
  display: inline-block;
  width: 5.5rem;
  color: var(--text-faint);
}
.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2rem;
  justify-content: space-between;
  margin-top: 3rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
}
/* On the Contact page the contact block above is dropped, so the bottom bar
   is the whole footer and doesn't need a rule or a gap above it. */
.footer-bottom--only { margin-top: 0; padding-top: 0; border-top: 0; }
.availability {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--accent);
}
.availability::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--accent);
  animation: pulse 2.4s ease-in-out infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }


/* == 07  Buttons & links ================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.85rem 1.6rem;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  border: 1px solid var(--rule);
  background: transparent;
  color: var(--text);
  cursor: pointer;
  transition: border-color var(--t-fast), background var(--t-fast), color var(--t-fast);
}
.btn:hover { border-color: var(--accent); color: var(--accent); }

.btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
}
.btn--primary:hover {
  background: transparent;
  color: var(--accent);
}

.btn-row { display: flex; flex-wrap: wrap; gap: 1rem; }

.link-arrow {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  text-decoration: none;
  display: inline-flex;
  gap: 0.5rem;
  align-items: center;
}
.link-arrow span { transition: transform var(--t-fast); }
.link-arrow:hover span { transform: translateX(4px); }

a { color: var(--accent); }


/* == 08  Home hero ======================================================== */

.hero {
  position: relative;
  height: 100svh;
  min-height: 560px;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
}

.hero__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: #000 center/cover no-repeat;
}
/* Vimeo/self-hosted video scaled to cover the viewport regardless of ratio */
.hero__media iframe,
.hero__media video {
  position: absolute;
  top: 50%; left: 50%;
  width: 100vw;
  height: 56.25vw;            /* 16:9 */
  min-height: 100svh;
  min-width: 177.78svh;
  transform: translate(-50%, -50%);
  border: 0;
  pointer-events: none;
  object-fit: cover;
}
.hero__poster {
  position: absolute;
  inset: 0;
  background: center/cover no-repeat;
  animation: kenburns 24s ease-in-out infinite alternate;
}
@keyframes kenburns {
  from { transform: scale(1); }
  to   { transform: scale(1.09); }
}
.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(to top, rgba(10,10,11,0.95) 0%, rgba(10,10,11,0.35) 45%, rgba(10,10,11,0.55) 100%);
}
.hero__inner {
  position: relative;
  z-index: 2;
  width: 100%;
  padding-bottom: clamp(4rem, 12vh, 8rem);
}
/* YOUR NAME ON THE LANDING PAGE.
   Change the middle number in clamp() to resize it — that's the one that
   applies at normal window sizes. The first is the floor on small phones,
   the last is the ceiling on very wide screens.
   Was: clamp(2.75rem, 9vw, 6.5rem) — this is roughly a third of that. */
.hero__name {
  font-size: clamp(1rem, 3vw, 2.15rem);
  line-height: 1.2;
  text-transform: uppercase;
  letter-spacing: 0.14em;   /* capitals need more air than lowercase */
  font-weight: 600;
  margin-bottom: 0.9rem;
}
.hero__role {
  font-family: var(--font-mono);
  font-size: clamp(0.72rem, 1.6vw, 0.9rem);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 1.5rem;
}
.hero__tagline {
  max-width: 46ch;
  color: var(--text);
  opacity: 0.85;
  margin-bottom: 2.25rem;
}
.scroll-cue {
  position: absolute;
  left: 50%; bottom: 1.75rem;
  z-index: 2;
  transform: translateX(-50%);
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.24em;
  color: var(--text-dim);
  text-transform: uppercase;
  text-decoration: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
}
.scroll-cue::after {
  content: "";
  width: 1px; height: 34px;
  background: linear-gradient(to bottom, var(--accent), transparent);
  animation: cue 2.2s ease-in-out infinite;
}
@keyframes cue {
  0%, 100% { transform: scaleY(0.35); transform-origin: top; opacity: 0.4; }
  50%      { transform: scaleY(1);    transform-origin: top; opacity: 1; }
}


/* == 09  Work — filters, grid ============================================= */

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 2.75rem;
}
.filter {
  appearance: none;
  background: none;
  border: 1px solid var(--rule);
  border-radius: 100px;
  padding: 0.4rem 1rem;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-dim);
  cursor: pointer;
  transition: all var(--t-fast);
}
.filter:hover { color: var(--text); border-color: var(--text-faint); }
.filter[aria-pressed="true"] {
  color: var(--accent-ink);
  background: var(--accent);
  border-color: var(--accent);
  font-weight: 600;
}

.grid {
  display: grid;
  grid-template-columns: repeat(var(--grid-cols), 1fr);
  gap: clamp(1.5rem, 3vw, 2.5rem);
}

.card {
  display: block;
  text-decoration: none;
  color: inherit;
  position: relative;
}
.card__media {
  position: relative;
  aspect-ratio: var(--thumb-ratio);
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--rule);
  transition: border-color var(--t-mid);
}
.card__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform var(--t-slow), opacity var(--t-mid);
}
.card:hover .card__media { border-color: var(--accent-dim); }
.card:hover .card__media img { transform: scale(1.04); }

.card__overlay {
  position: absolute;
  inset: auto 0 0 0;
  padding: 1rem;
  background: linear-gradient(to top, rgba(10,10,11,0.92), transparent);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity var(--t-mid), transform var(--t-mid);
}
.card:hover .card__overlay,
.card:focus-visible .card__overlay { opacity: 1; transform: translateY(0); }

.card__play {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  opacity: 0;
  transition: opacity var(--t-mid);
}
.card:hover .card__play { opacity: 1; }
.card__play svg {
  width: 54px; height: 54px;
  filter: drop-shadow(0 2px 12px rgba(0,0,0,0.6));
}

.card__body { padding-top: 0.9rem; }
.card__title {
  font-size: 1.05rem;
  font-weight: 600;
  margin: 0 0 0.35rem;
  letter-spacing: -0.01em;
  transition: color var(--t-fast);
}
.card:hover .card__title { color: var(--accent); }
.card__meta {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.empty-state {
  grid-column: 1 / -1;
  padding: 4rem 0;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-faint);
}


/* == 10  Project detail =================================================== */

.project-hero {
  padding-top: var(--nav-h);
  background: #000;
}
.video-frame {
  position: relative;
  aspect-ratio: 16 / 9;
  background: var(--surface);
  overflow: hidden;
  border: 1px solid var(--rule);
}
.video-frame iframe { width: 100%; height: 100%; border: 0; }

/* Click-to-load facade — the iframe only loads when you press play */
.video-facade {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  border: 0;
  padding: 0;
  background: var(--surface) center/cover no-repeat;
  cursor: pointer;
  display: grid;
  place-items: center;
}
.video-facade::before {
  content: "";
  position: absolute; inset: 0;
  background: rgba(10,10,11,0.35);
  transition: background var(--t-mid);
}
.video-facade:hover::before { background: rgba(10,10,11,0.15); }
.play-btn {
  position: relative;
  width: 72px; height: 72px;
  border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(10,10,11,0.55);
  border: 1px solid rgba(237,237,239,0.35);
  backdrop-filter: blur(6px);
  transition: transform var(--t-mid), background var(--t-mid), border-color var(--t-mid);
}
.video-facade:hover .play-btn {
  transform: scale(1.08);
  background: var(--accent);
  border-color: var(--accent);
}
.play-btn svg { width: 22px; height: 22px; margin-left: 3px; fill: var(--text); }
.video-facade:hover .play-btn svg { fill: var(--accent-ink); }

.project-title { margin-bottom: 1.5rem; }

/* Role · Director · Studio · Shots, spanning the full width. The first two
   read from the left, the last two are anchored to the right edge — the same
   two-sided reading as a filmography row. */
.fact-table {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1.75rem 2rem;
  padding: 2rem 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  margin-bottom: 3.5rem;
}
.fact__label {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 0.4rem;
}
.fact__value { font-size: 0.95rem; line-height: 1.45; }

.fact--end { text-align: right; }

.tag-list { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.tag {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  padding: 0.28rem 0.65rem;
  border: 1px solid var(--rule);
  border-radius: 3px;
  color: var(--text-dim);
  background: var(--surface);
}

.gallery {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.5rem;
}
.gallery__item { margin: 0; }
.gallery__item--wide { grid-column: 1 / -1; }
.gallery__item button {
  display: block; width: 100%;
  padding: 0; border: 1px solid var(--rule);
  background: var(--surface);
  cursor: pointer;
  overflow: hidden;
}
.gallery__item img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  transition: transform var(--t-slow);
}
.gallery__item button:hover img { transform: scale(1.03); }
.gallery__item figcaption {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-dim);
  padding-top: 0.65rem;
}

.credits-list { list-style: none; padding: 0; margin: 0; }
.credits-list li {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--text-dim);
  padding: 0.4rem 0;
}

.prev-next {
  display: flex;
  justify-content: space-between;
  gap: 2rem;
  border-top: 1px solid var(--rule);
  padding-top: 2rem;
  margin-top: 4rem;
}
.prev-next a { text-decoration: none; color: var(--text-dim); }
.prev-next a:hover { color: var(--accent); }
.prev-next .mono { display: block; margin-bottom: 0.3rem; }
.prev-next strong { color: var(--text); font-weight: 500; font-size: 1rem; }
.prev-next .pn-next { text-align: right; margin-left: auto; }


/* Impressum / Datenschutz links in the bottom bar. German law wants these
   reachable from every page, so they live in the footer, not the nav. */
.footer-legal { display: flex; gap: 1.5rem; }
.footer-legal a {
  color: var(--text-faint);
  text-decoration: none;
  transition: color var(--t-fast);
}
.footer-legal a:hover { color: var(--accent); }


.project-imdb { margin: -0.25rem 0 1.25rem; }


/* == 11  Legal pages ====================================================== */

.legal-body { max-width: 70ch; }
.legal-section { margin-bottom: clamp(2rem, 5vw, 3rem); }
.legal-section h2 {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 1rem;
  font-weight: 500;
}
.legal-section p {
  color: var(--text-dim);
  margin-bottom: 0.6rem;
}
.legal-updated { margin-top: 3rem; color: var(--text-faint); }


/* == 12  Contact page ===================================================== */

.contact-intro {
  max-width: 60ch;
  color: var(--text-dim);
  font-size: clamp(1rem, 1.6vw, 1.1rem);
  margin-bottom: clamp(2.5rem, 6vw, 3.5rem);
}

/* COLUMN WIDTH for the Contact page. The link boxes and the form share it, so
   their left and right edges line up. Change it in one place and both follow. */
.contact-links,
.contact-form { max-width: 860px; }

/* Email / IMDb / LinkedIn */
.contact-links {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;                        /* the gap IS the rule between them */
  background: var(--rule);
  border: 1px solid var(--rule);
  margin-bottom: clamp(3rem, 7vw, 4.5rem);
}
.contact-link {
  background: var(--surface);
  padding: 1.5rem;
  text-decoration: none;
  display: block;
  transition: background var(--t-fast);
}
.contact-link:hover { background: var(--surface-hi); }
.contact-link__label {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 0.5rem;
}
.contact-link__value {
  display: block;
  color: var(--text);
  font-size: 0.95rem;
  word-break: break-word;
}

/* The form */
.contact-form {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.5rem clamp(1.25rem, 3vw, 2rem);
}
.field--full { grid-column: 1 / -1; }
/* The spam trap. Kept out of sight without display:none, which some bots
   check for. */
.field--trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.field label {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 0.5rem;
}
.field input,
.field textarea {
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--rule);
  color: var(--text);
  font-family: inherit;
  font-size: 0.95rem;
  padding: 0.8rem 0.9rem;
  border-radius: 2px;
  transition: border-color var(--t-fast), background var(--t-fast);
}
.field textarea { resize: vertical; min-height: 8rem; line-height: 1.6; }
.field input:hover,
.field textarea:hover { border-color: var(--accent-dim); }
.field input:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--surface-hi);
}
.field.has-error input,
.field.has-error textarea { border-color: #E3766F; }
.field-error {
  margin: 0.4rem 0 0;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  color: #E3766F;
}

.form-status {
  margin: 1rem 0 0;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  color: var(--text-dim);
  min-height: 1.2em;             /* reserve the line so nothing jumps */
}
.form-status.is-ok    { color: var(--accent); }
.form-status.is-error { color: #E3766F; }

.contact-byline {
  margin: clamp(2rem, 5vw, 3rem) 0 0;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-faint);
}


/* == 13  News — "currently" banner + timeline ============================= */

/* The banner. Deliberately at the same type scale as the rest of the site —
   it earns its emphasis from the border, the tint and the live dot, not from
   size. */
.now {
  border: 1px solid var(--rule);
  border-left: 2px solid var(--accent);
  /* 50% transparent, so the drifting particles show through. The first line
     is a fallback for browsers without color-mix(); both are --surface at
     half strength. Change the 50% to make it more or less see-through. */
  background: rgba(20, 20, 22, 0.5);
  background: color-mix(in srgb, var(--surface) 50%, transparent);
  padding: clamp(1.5rem, 4vw, 2.25rem);
}
.now__label {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 1rem;
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
/* The live dot — same idea as the footer availability line. */
.now__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  flex: none;
  animation: now-pulse 2.4s ease-in-out infinite;
}
@keyframes now-pulse {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: 0.4; transform: scale(0.82); }
}
.now__title {
  font-size: clamp(1.15rem, 2vw, 1.4rem);   /* matches h3 elsewhere */
  margin: 0 0 0.5rem;
}
.now__facts {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin: 0 0 0.75rem;
}
.now__sep { color: var(--text-faint); }
/* Same monospace as the facts line above — it carries a "Starring:" label,
   so it reads as metadata rather than prose. */
.now__status {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text);
}
.now__link { margin: 1.25rem 0 0; }

/* The timeline. The spine is a border on the feed itself, so it grows with
   the content and never needs a fixed height. */
.timeline-feed {
  position: relative;
  border-left: 1px solid var(--rule);
  margin-left: 0.5rem;
  padding-left: clamp(1.25rem, 4vw, 2.5rem);
}
.timeline-year {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  color: var(--accent);
  margin: 2.5rem 0 1.5rem;
  position: relative;
}
.timeline-feed > .timeline-year:first-child { margin-top: 0; }

.news {
  display: grid;
  grid-template-columns: 110px 1fr;
  gap: clamp(1rem, 3vw, 2rem);
  padding: 0 0 2.75rem;
  position: relative;
}
/* The node on the spine, lined up with the entry's first line. */
.news::before {
  content: "";
  position: absolute;
  left: calc(clamp(1.25rem, 4vw, 2.5rem) * -1 - 4px);
  top: 0.45rem;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--bg);
  border: 1px solid var(--accent-dim);
  transition: background var(--t-fast), border-color var(--t-fast);
}
.news:hover::before { background: var(--accent); border-color: var(--accent); }

.news__date {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  color: var(--text-dim);
  padding-top: 0.15rem;
}
/* The entry fills its column — headline, media and links all use the full
   width. Only the running text is capped, and generously: long measures are
   hard to read, but 68ch left a third of a wide screen empty. */
.news__body { max-width: none; }
.news__tag {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin: 0 0 0.4rem;
}
.news__title { font-size: 1.05rem; margin: 0 0 0.75rem; letter-spacing: -0.01em; }

.news__media {
  margin: 0 0 1rem;
  max-width: 860px;
  border: 1px solid var(--rule);
  background: var(--surface);
}
.news__media img { width: 100%; }

.news__text {
  color: var(--text-dim);
  /* Effectively no cap at normal window sizes — it only starts to bind past
     ~1600px, where unbroken lines would get genuinely hard to follow. */
  max-width: 110ch;
}
.news__text p:last-child { margin-bottom: 0; }
/* Collapsed state: show the opening lines and fade the cut edge. Line-clamp
   is used rather than a fixed height so it adapts to any font size. */
.news__text.is-clamped {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, #000 55%, transparent 100%);
          mask-image: linear-gradient(to bottom, #000 55%, transparent 100%);
}
.news__more {
  appearance: none;
  background: none;
  border: 0;
  padding: 0.5rem 0 0;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  cursor: pointer;
}
.news__more:hover { color: var(--text); }
.news__links {
  margin: 1rem 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
}


/* == 14  Filmography & awards ============================================= */

.film-year {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  color: var(--accent);
  padding: 1.75rem 0 0.75rem;
  border-bottom: 1px solid var(--rule);
  margin-bottom: 0;
}
.film-row {
  display: grid;
  /* title · role · director · studio */
  grid-template-columns: 1.5fr 1.2fr 1fr 1fr;
  gap: 1.5rem;
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--rule);
  align-items: baseline;
}
.film-row__title { font-weight: 500; }

/* The IMDb link on a credit row.
   Touch devices have no hover to reveal anything, so they get a small arrow
   that's always visible. Pointer devices get the full "IMDb ↗", faded in when
   the row is hovered or the link is focused — so a list of 35 credits reads as
   titles, not as the word IMDb repeated 35 times. */
.film-row__title .film-row__imdb {
  margin-left: 0.45rem;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  color: var(--accent-dim);
  border-bottom: 0;          /* not the underlined title link */
  white-space: nowrap;
}
.film-row__title .film-row__imdb:hover { color: var(--accent); }
.film-row__imdb-label { display: none; }

@media (hover: hover) and (pointer: fine) {
  .film-row__title .film-row__imdb {
    opacity: 0;
    transition: opacity var(--t-fast), color var(--t-fast);
  }
  .film-row:hover .film-row__imdb,
  .film-row__imdb:focus-visible { opacity: 1; }
  .film-row__imdb-label { display: inline; margin-right: 0.25rem; }
}
.film-row__title a { text-decoration: none; color: var(--text); border-bottom: 1px solid var(--accent-dim); }
.film-row__title a:hover { color: var(--accent); }
.film-row__role,
.film-row__director,
.film-row__studio {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  color: var(--text-dim);
}
/* Role stays left, next to the title; director and studio hang off the right
   edge so the list reads as two anchored sides. */
.film-row__director,
.film-row__studio { text-align: right; }

/* Awards */
.award-row {
  display: grid;
  grid-template-columns: 90px 1fr auto;
  gap: 1.5rem;
  padding: 1.1rem 0;
  border-bottom: 1px solid var(--rule);
  align-items: baseline;
}
.award-row__year {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--text-dim);
}
.award-row__name { font-weight: 500; margin-bottom: 0.15rem; }
.award-row__cat {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--text-dim);
  letter-spacing: 0.04em;
}
.award-row__link { margin: 0.6rem 0 0; }
.award-row__cat a { color: var(--text-dim); }
.award-row__cat a:hover { color: var(--accent); }
.result {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 0.25rem 0.6rem;
  border: 1px solid var(--rule);
  border-radius: 3px;
  color: var(--text-faint);
  white-space: nowrap;
}
.result--won {
  color: var(--accent-ink);
  background: var(--accent);
  border-color: var(--accent);
  font-weight: 600;
}

/* == 15  Lightbox ========================================================= */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: grid;
  place-items: center;
  padding: clamp(1rem, 5vw, 3rem);
  background: rgba(5, 5, 6, 0.94);
  backdrop-filter: blur(8px);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--t-mid), visibility var(--t-mid);
}
.lightbox.is-open { opacity: 1; visibility: visible; }
.lightbox__inner {
  width: min(1400px, 100%);
  max-height: 100%;
  transform: scale(0.98);
  transition: transform var(--t-mid);
}
.lightbox.is-open .lightbox__inner { transform: scale(1); }
.lightbox__inner img {
  width: 100%;
  max-height: 85svh;
  object-fit: contain;
  margin-inline: auto;
}
.lightbox__inner .video-frame { border-color: transparent; }
.lightbox__close {
  position: fixed;
  top: 1.25rem; right: 1.25rem;
  width: 46px; height: 46px;
  display: grid; place-items: center;
  background: transparent;
  border: 1px solid var(--rule);
  color: var(--text);
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  transition: all var(--t-fast);
}
.lightbox__close:hover { border-color: var(--accent); color: var(--accent); }
.lightbox__caption {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-dim);
  text-align: center;
  padding-top: 1rem;
}
body.no-scroll { overflow: hidden; }


/* == 16  Before/after compare ============================================= */

.compare {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border: 1px solid var(--rule);
  background: var(--surface);
  touch-action: none;
  user-select: none;
  cursor: ew-resize;
}
.compare img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  pointer-events: none;
}
.compare__after { clip-path: inset(0 0 0 var(--pos, 50%)); }
.compare__handle {
  position: absolute;
  top: 0; bottom: 0;
  left: var(--pos, 50%);
  width: 2px;
  background: var(--accent);
  pointer-events: none;
}
.compare__handle::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 42px; height: 42px;
  transform: translate(-50%, -50%);
  border: 2px solid var(--accent);
  border-radius: 50%;
  background: rgba(10,10,11,0.6);
  backdrop-filter: blur(4px);
}
.compare__label {
  position: absolute;
  top: 0.9rem;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text);
  background: rgba(10,10,11,0.7);
  padding: 0.25rem 0.6rem;
  pointer-events: none;
}
.compare__label--before { left: 0.9rem; }
.compare__label--after  { right: 0.9rem; }
.compare__range {
  position: absolute;
  inset: 0;
  width: 100%;
  opacity: 0;
  cursor: ew-resize;
  margin: 0;
}
.compare__range:focus-visible + .compare__handle::after {
  box-shadow: 0 0 0 4px rgba(195, 212, 227, 0.35);
}


/* == 17  Motion & reveal ================================================== */

[data-reveal] {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity var(--t-slow), transform var(--t-slow);
}
[data-reveal].is-visible { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .now__dot { animation: none; }
  .film-row__imdb { transition: none; }
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  [data-reveal] { opacity: 1; transform: none; }
  .hero__poster { animation: none; }
}


/* == 18  Responsive ======================================================= */

/* The grid steps down as the screen narrows so cards never get too small.
   Each of these overrides --grid-cols for that width and below. */
@media (max-width: 1360px) {
  :root { --grid-cols: 3; }
}

@media (max-width: 1024px) {
  :root { --grid-cols: 2; }
}

@media (max-width: 768px) {
  body { font-size: 16px; }

  .nav-toggle { display: block; }

  .nav {
    position: fixed;
    inset: 0;
    flex-direction: column;
    justify-content: center;
    gap: 2rem;
    /* Scrollable and inside the safe area, so a long menu on a short phone
       stays reachable rather than being clipped. */
    overflow-y: auto;
    padding: max(5rem, env(safe-area-inset-top)) 1.5rem
             max(2rem, env(safe-area-inset-bottom));
    background: rgba(10, 10, 11, 0.97);
    backdrop-filter: blur(16px);
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--t-mid), visibility var(--t-mid);
  }
  .nav.is-open { opacity: 1; visibility: visible; }
  .nav a { font-size: 1rem; letter-spacing: 0.2em; }

  .site-header__inner { position: relative; z-index: 2; }
  .nav-toggle { position: relative; z-index: 3; }

  :root            { --grid-cols: 1; }
  .gallery         { grid-template-columns: 1fr; }

  .contact-links   { grid-template-columns: 1fr; }
  .contact-form    { grid-template-columns: 1fr; }

  .news            { grid-template-columns: 1fr; gap: 0.35rem; }
  .news__date      { padding-top: 0; }
  .timeline-feed   { padding-left: 1.25rem; }

  .film-row        { grid-template-columns: 1fr; gap: 0.25rem; padding: 1rem 0; }
  .film-row__director,
  .film-row__studio { text-align: left; }
  .award-row       { grid-template-columns: 1fr; gap: 0.5rem; }
  .award-row .result { justify-self: start; }

  /* Two columns on phones, in reading order — the pinned columns and the
     right alignment both belong to the wide layout. */
  .fact-table      { grid-template-columns: repeat(2, 1fr); gap: 1.5rem; }
  .fact            { grid-column: auto !important; }
  .fact--end       { text-align: left; }

  .prev-next       { flex-direction: column; gap: 1.5rem; }
  .prev-next .pn-next { text-align: left; margin-left: 0; }

  .scroll-cue      { display: none; }
  .footer-links a::before { width: 4.5rem; }
}
