:root { --vj-css-build: 68; }
/* ============================================
   Vincent Johnson · Portfolio
   Plain CSS — Kirby CMS · STRATO
   ============================================ */

@font-face {
  font-family: 'Moret';
  src: url('../fonts/Moret-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: block;
}

@font-face {
  font-family: 'Moret';
  src: url('../fonts/Moret-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: block;
}

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

:root {
  --bg: #000;
  --fg: #fff;
  --fg-dim: rgba(255,255,255,0.5);
  --hover: #ff1f1f;
  --about-bg: #fff;
  --about-fg: #000;
  --sans: "Helvetica Neue", Helvetica, Arial, sans-serif;
  --serif: "Moret", "Times New Roman", Georgia, serif;
  --nav-h: 96px;
  --content-max: 965px;
  --grid-pad: 48px;
  /* C41 colour-negative look (used by darkroom photos on desktop + mobile) */
  --neg-filter: invert(1) sepia(0.92) saturate(2.1) hue-rotate(-35deg) brightness(0.9) contrast(1.12);
}

html { background: var(--bg); color: var(--fg); -webkit-text-size-adjust: 100%; }

/* White-bg pages: keep the whole document white (no black reveal on overscroll) */
html.is-about, html.page-about, html.template-about,
html.is-darkroom, html.page-darkroom, html.template-darkroom {
  background: #fff;
}

body {
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 400;
  letter-spacing: 0.01em;
  overflow-x: hidden;
  cursor: none;
}

@media (hover: none), (pointer: coarse) {
  body { cursor: auto; }
  .cursor { display: none !important; }
}

a { color: inherit; text-decoration: none; }
img, video { max-width: 100%; display: block; }

/* ════════════════════════════════════════════
   HEADER — aligned with project list lines
   ════════════════════════════════════════════ */
.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 50;
  height: var(--nav-h);
  padding: 0;
  color: #fff;
  pointer-events: auto;
}

.site-header-inner {
  max-width: var(--content-max);
  margin: 0 auto;
  padding: 0 var(--grid-pad);
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.site-header .logo {
  font-family: var(--serif);
  font-size: clamp(28px, 3.4vw, 46px);
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0;
  color: #fff;
  transition: color 0.2s;
}

/* Logo turns black on white pages */
body.is-about .site-header .logo,
body.page-about .site-header .logo,
body.template-about .site-header .logo {
  color: #000;
}

/* ── Darkroom cursor = loupe ring (the negative overlay is masked beneath it) ── */
body.is-darkroom .cursor,
body.page-darkroom .cursor,
body.template-darkroom .cursor,
body.home-darkroom-active .cursor {
  width: 150px !important;
  height: 150px !important;
  margin: -75px 0 0 -75px !important;
  background: transparent !important;
  mix-blend-mode: normal !important;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border: 1.5px solid rgba(0,0,0,0.30);
  box-shadow: 0 0 0 1px rgba(255,255,255,0.25);
}
body.home-darkroom-active .cursor .cursor-preview,
body.home-darkroom-active .cursor .cursor-circle-frame,
body.home-darkroom-active .cursor .cursor-random-icon,
body.home-darkroom-active .cursor .cursor-project-number {
  display: none !important;
  opacity: 0 !important;
}

.site-header nav ul {
  display: flex;
  gap: 36px;
  list-style: none;
  align-items: center;
}

.site-header nav a {
  font-family: var(--sans);
  font-size: clamp(16px, 1.5vw, 22px);
  font-weight: 400;
  color: inherit;
  transition: color 0.2s;
}

.site-header nav a:hover,
.site-header nav a.is-active { color: var(--hover); }

/* Hamburger button — hidden on desktop, shown on mobile */
.nav-toggle {
  display: none;
  background: none;
  border: 0;
  padding: 8px;
  cursor: pointer;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  width: 44px;
  height: 44px;
  color: #fff; /* default: dark pages → white bars */
}
.nav-toggle span {
  display: block;
  width: 30px;
  height: 2.5px;
  background: #fff;
  transition: transform 0.3s, opacity 0.3s, background 0.3s;
}

/* White-bg pages → black hamburger bars */
body.is-about .nav-toggle span,
body.page-about .nav-toggle span,
body.template-about .nav-toggle span,
body.lt-ready .nav-toggle span {
  background: #000;
}
/* but when the menu overlay (black) is open, bars are white */
.site-header.nav-open .nav-toggle span { background: #fff !important; }

/* White-bg pages: black header (about always; darkroom animates) */
body.is-about,
body.page-about,
body.template-about {
  background: var(--about-bg) !important;
  color: var(--about-fg);
}

body.is-about .site-header,
body.page-about .site-header,
body.template-about .site-header {
  color: #000 !important;
}

/* ── DARKROOM ENTRY ANIMATION (black→white, text inverts) ── */
body.is-darkroom,
body.page-darkroom,
body.template-darkroom {
  background: #160202;
}
body.lt-ready {
  background: #fff;
}

/* logo + nav start WHITE on black, animate to BLACK on white */
body.is-darkroom .site-header .logo,
body.is-darkroom .site-header nav a,
body.page-darkroom .site-header .logo,
body.page-darkroom .site-header nav a,
body.template-darkroom .site-header .logo,
body.template-darkroom .site-header nav a {
  color: #fff;
  transition: color 1.2s ease;
}

body.lt-ready .site-header .logo,
body.lt-ready .site-header nav a {
  color: #000 !important;
}

/* active/hover stays red even during/after animation */
body.is-darkroom .site-header nav a:hover,
body.is-darkroom .site-header nav a.is-active,
body.lt-ready .site-header nav a:hover,
body.lt-ready .site-header nav a.is-active { color: var(--hover) !important; }

/* ════════════════════════════════════════════
   CUSTOM CURSOR
   ════════════════════════════════════════════ */
.cursor {
  position: fixed;
  top: 0; left: 0;
  width: 150px; height: 150px;
  margin: -75px 0 0 -75px;
  border-radius: 50%;
  background: #fff;
  pointer-events: none;
  z-index: 9999;
  mix-blend-mode: difference;
  transition: width 0.6s cubic-bezier(0.16,1,0.3,1),
              height 0.6s cubic-bezier(0.16,1,0.3,1),
              margin 0.6s cubic-bezier(0.16,1,0.3,1),
              background 0.5s;
  will-change: transform;
}

.cursor.is-small {
  width: 30px; height: 30px;
  margin: -15px 0 0 -15px;
}

.cursor.is-large {
  width: 200px; height: 200px;
  margin: -100px 0 0 -100px;
  mix-blend-mode: normal;
  background: transparent;
  overflow: visible;
}

.cursor .cursor-preview {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.3s;
  border-radius: 50%;
}

.cursor.is-large .cursor-preview { opacity: 1; }

.cursor .cursor-circle-frame,
.cursor .cursor-random-icon,
.cursor .cursor-project-number {
  position: absolute;
  display: block;
  height: auto !important;
  max-width: none;
  pointer-events: none;
  user-select: none;
  background: transparent;
  opacity: 0;
  transition: opacity 0.28s ease;
}

.cursor .cursor-circle-frame {
  left: 50%;
  top: 50%;
  z-index: 4;
  width: 128%;
  mix-blend-mode: screen;
  transform: translate(-50%, -50%) rotate(var(--cursor-circle-rot, 0deg)) scale(var(--cursor-circle-scale, 1));
}

.cursor .cursor-random-icon {
  left: var(--cursor-icon-left, 82%);
  top: var(--cursor-icon-top, -8%);
  z-index: 5;
  width: var(--cursor-icon-w, 82px);
  mix-blend-mode: screen;
  filter: none;
  transform: translate(-50%, -50%) rotate(var(--cursor-icon-rot, 0deg));
}

.cursor .cursor-project-number {
  left: 109%;
  top: 19%;
  z-index: 6;
  width: var(--cursor-number-w, 42px);
  mix-blend-mode: difference;
  filter: invert(1) grayscale(1) brightness(2);
  transform: translate(-50%, -50%) rotate(var(--cursor-number-rot, -4deg));
}

.cursor.has-scribbles .cursor-circle-frame,
.cursor.has-scribbles .cursor-project-number { opacity: 0.96; }
.cursor.has-scribbles .cursor-random-icon { opacity: 0; }

.cursor.is-small .cursor-circle-frame,
.cursor.is-small .cursor-random-icon,
.cursor.is-small .cursor-project-number { opacity: 0 !important; }

/* ════════════════════════════════════════════
   HOME · HERO VIDEO + SCROLL TRIANGLE
   ════════════════════════════════════════════ */
.hero {
  position: fixed;
  top: 0; left: 0;
  width: 100vw;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  z-index: 0;
  pointer-events: none;
}

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

.hero-scroll {
  position: fixed;
  bottom: 48px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 30;
  width: 88px; height: 72px;
  background: none; border: 0; padding: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: auto;
  animation: floatBob 2.2s ease-in-out infinite;
  transition: opacity 0.3s;
  mix-blend-mode: difference;
  isolation: auto;
}

.hero-scroll svg { display: block; width: 56px; height: 44px; }
.hero-scroll .hero-scroll-mark {
  display: block;
  width: 59px;
  max-height: 59px;
  object-fit: contain;
  background: transparent;
  filter: none;
  mix-blend-mode: normal;
  pointer-events: none;
  user-select: none;
}

@keyframes floatBob {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50%      { transform: translateX(-50%) translateY(-10px); }
}

.hero-spacer {
  height: 100vh;
  height: 100svh;
  position: relative;
  z-index: 1;
  pointer-events: none;
}

/* ════════════════════════════════════════════
   PROJECT LINE-LIST (reusable everywhere)
   ════════════════════════════════════════════ */
.project-list {
  position: relative;
  z-index: 2;
  background: transparent;
  max-width: 965px;
  margin: 0 auto;
  padding: 0 var(--grid-pad);
}

.project-list--bottom {
  padding-top: 80px;
  padding-bottom: 160px;
}

/* home menu: extra room below so the LAST project can scroll up to the centre (sharp) */
#projects .project-list--bottom {
  padding-bottom: 48vh;
}

.project-list-inner {
  /* no border-top — first row has no line above */
  perspective: 1200px;
  transform-style: preserve-3d;
}

.project-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  height: 35px;            /* 35px between divider lines (matches old site) */
  padding: 0;
  border-bottom: 1px solid #fff;
  color: #fff;
  font-family: var(--sans);
  font-weight: 400;
  text-transform: uppercase;
  font-size: clamp(18px, 1.8vw, 24px);
  letter-spacing: 0.01em;
  line-height: 1;
  transition: color 0.2s;
  transform-style: preserve-3d;
  backface-visibility: hidden;
  will-change: transform, filter, opacity;
}

.project-row:hover,
.project-row:hover .p-category {
  color: var(--hover);
}

/* ── Focus-plane effect, CSS scroll-driven (runs on the compositor → smooth on
   iOS where JS/rAF freeze during momentum scrolling). JS only adds the click. ── */
@keyframes focusPlane {
  0%   { filter: blur(6px); opacity: 0.5; }
  42%  { filter: blur(0px); opacity: 1; }
  58%  { filter: blur(0px); opacity: 1; }
  100% { filter: blur(6px); opacity: 0.5; }
}
@supports (animation-timeline: view()) {
  #projects .project-row {
    animation: focusPlane linear both;
    animation-timeline: view();
    will-change: filter, opacity;
  }
}

.project-row .p-title {
  display: flex;
  align-items: center;
  gap: 14px;
  flex: 1;
  min-width: 0;
}

.project-row .p-lock {
  font-size: 0.85em;
  opacity: 0.9;
}

.project-row .p-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.project-row .p-category {
  font-size: inherit;
  letter-spacing: 0.01em;
  white-space: nowrap;
  flex-shrink: 0;
  color: inherit;
  transition: color 0.2s;
}

/* Project list on white pages: black instead of white
   (NOTE: project detail pages stay dark, so .is-project NOT included) */
body.is-about .project-list-inner,
body.is-darkroom .project-list-inner,
body.page-about .project-list-inner,
body.page-darkroom .project-list-inner,
body.template-about .project-list-inner,
body.template-darkroom .project-list-inner {
  border-top-color: #000;
}

body.is-about .project-row,
body.is-darkroom .project-row,
body.page-about .project-row,
body.page-darkroom .project-row,
body.template-about .project-row,
body.template-darkroom .project-row {
  color: #000;
  border-bottom-color: #000;
}

/* ════════════════════════════════════════════
   ABOUT PAGE — large text, classic blue links
   ════════════════════════════════════════════ */
.about {
  max-width: var(--content-max);
  margin: 0 auto;
  padding: calc(var(--nav-h) + 80px) var(--grid-pad) 0;
  color: #000;
}

.about-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 80px;
  align-items: start;
}

.about-col {
  font-family: var(--sans);
  font-size: clamp(16px, 1.5vw, 21px);
  line-height: 1.35;
  color: #000;
  font-weight: 400;
}

.about-col p {
  margin-bottom: 1.1em;
}

.about-col a {
  color: #1010ff;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}

.about-col a:hover {
  color: var(--hover);
}

/* Kabupaten-game — tiny, unobtrusive link tucked at the very bottom */
.about-game-tiny {
  max-width: var(--content-max);
  margin: 0 auto;
  padding: 8px var(--grid-pad) 36px;
  text-align: right;
}
.about-game-tiny a {
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #9a9a9a;
  text-decoration: none;
  transition: color 0.2s;
}
.about-game-tiny a:hover { color: var(--hover); }

.about-col h3 {
  font-family: var(--sans);
  font-size: inherit;
  font-weight: 700;
  margin: 1.5em 0 0.4em;
  letter-spacing: 0;
  text-transform: none;
  line-height: 1.2;
}

.about-col h3.uppercase {
  text-transform: uppercase;
}

.about-col .field-list {
  list-style: none;
  font-size: inherit;
  line-height: 1.3;
  margin-bottom: 1em;
}

.about-col .field-list li {
  margin-bottom: 0;
}

.about-portrait {
  margin-top: 1.5em;
  max-width: 60%;
}
.about-portrait img {
  width: 100%;
  height: auto;
  display: block;
}

.about-seen {
  margin-top: 64px;
  padding-top: 28px;
  border-top: 1px solid rgba(0,0,0,0.14);
  font-family: var(--sans);
  font-size: clamp(13px, 1.1vw, 16px);
  color: #000;
}
.about-seen h3 {
  font-family: var(--sans);
  font-weight: 700;
  font-size: inherit;
  margin: 0 0 16px;
  letter-spacing: 0;
}
.about-seen .seen-list {
  display: flex;
  flex-wrap: wrap;
  gap: 18px 48px;
}
.about-seen .seen-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.about-seen .seen-item strong {
  font-weight: 700;
}
.about-seen .seen-item a {
  color: #1010ff;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  font-size: 0.9em;
  word-break: break-word;
}
.about-seen .seen-item a:hover { color: var(--hover); }

@media (max-width: 640px) {
  .about-seen .seen-list { gap: 16px 28px; }
}

/* Impressum & Datenschutz */
#impressum {
  max-width: var(--content-max);
  margin: 80px auto 0;
  padding: 60px var(--grid-pad) 100px;
  border-top: 1px solid #000;
}
#impressum h2 {
  font-family: var(--sans);
  font-size: 20px; font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 24px;
}
#impressum h4,
#impressum h3 {
  font-family: var(--sans);
  font-size: 14px; font-weight: 700;
  margin: 22px 0 6px;
  letter-spacing: 0.02em;
}
#impressum .impressum-body { max-width: 720px; }
#impressum p {
  font-size: 14px; line-height: 1.6;
  color: #333; margin-bottom: 10px;
}
#impressum a { color: #1010ff; text-decoration: underline; }
#impressum ul {
  margin: 8px 0 16px 1.2em;
  padding: 0;
}
#impressum li {
  font-size: 14px;
  line-height: 1.6;
  color: #333;
  margin-bottom: 4px;
}
#impressum strong { font-weight: 700; }
#impressum .legal-updated {
  margin-top: 28px;
  font-size: 13px;
  color: #666;
}

/* ════════════════════════════════════════════
   DARKROOM PAGE — LIGHT TABLE
   ════════════════════════════════════════════ */
.lighttable-viewport {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  overflow: hidden;
  background-color: #160202;
  /* No background-image gradient swap here: iOS/Safari does not interpolate gradient
     background-images, so the red→white change snapped ("plötzlich weiß"). The red glow
     lives entirely on ::before/::after (which fade smoothly via opacity); the dark→light
     base is now a single smooth background-color transition. */
  cursor: none;
  transition: background-color 2.2s cubic-bezier(0.33, 0, 0.2, 1);
}

/* red safelight wash on entry: like switching from darkroom red light to ceiling light */
.lighttable-viewport::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 46;
  pointer-events: none;
  background:
    radial-gradient(circle at 52% 42%, rgba(255, 78, 38, 0.50) 0%, rgba(176, 13, 9, 0.60) 48%, rgba(36, 0, 0, 0.90) 100%),
    linear-gradient(180deg, rgba(255, 35, 20, 0.24), rgba(70, 0, 0, 0.56));
  mix-blend-mode: screen;
  opacity: 1;
  transition: opacity 2.2s cubic-bezier(0.33, 0, 0.2, 1);
}

.lighttable-viewport::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 47;
  pointer-events: none;
  background: radial-gradient(ellipse 70% 70% at 50% 45%, transparent 42%, rgba(26, 0, 0, 0.5) 100%);
  opacity: 1;
  transition: opacity 2.2s cubic-bezier(0.33, 0, 0.2, 1);
}

/* white glowing light table (ceiling light on) */
body.lt-ready .lighttable-viewport {
  background-color: #fff;
}
body.lt-ready .lighttable-viewport::before,
body.lt-ready .lighttable-viewport::after {
  opacity: 0;
}

.lighttable-surface {
  position: absolute;
  top: 0; left: 0;
  transform-origin: 0 0;
  will-change: transform, filter;
  opacity: 1;
  filter: brightness(0.62) contrast(1.08) saturate(0.82) sepia(0.36) hue-rotate(-18deg);
  transition:
    opacity 1.6s ease,
    filter 2.2s cubic-bezier(0.33, 0, 0.2, 1);
}
body.lt-ready .lighttable-surface {
  opacity: 1;
  filter: none;
  will-change: transform;
}

/* ── LENS DISTORTION + CHROMATIC ABERRATION (edges) ── */
.lens-fx {
  position: absolute;
  inset: 0;
  z-index: 52;
  pointer-events: none;
  /* heavy edge softening = lens distortion blur toward the rim */
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  /* only the edges are affected; center stays sharp */
  -webkit-mask: radial-gradient(ellipse 64% 64% at 50% 50%, transparent 48%, #000 94%);
  mask: radial-gradient(ellipse 64% 64% at 50% 50%, transparent 48%, #000 94%);
  opacity: 0;
  transition: opacity 1.6s ease;
}
body.lt-ready .lens-fx { opacity: 1; }

/* chromatic aberration: red + cyan fringing at the very edge */
.lens-fx::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 73% 73% at 50% 50%, transparent 62%, rgba(255,30,30,0.20) 90%, rgba(255,0,40,0.34) 100%),
    radial-gradient(ellipse 79% 79% at 50% 50%, transparent 66%, rgba(0,170,255,0.18) 92%, rgba(0,90,255,0.32) 100%);
  mix-blend-mode: screen;
}

/* lens vignette: light falloff at the edges */
.lens-fx::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 70% 70% at 50% 50%, transparent 55%, rgba(0,0,0,0.30) 90%, rgba(0,0,0,0.55) 100%);
}

/* animatable radius for the develop-from-point reveal */
@property --dev-r {
  syntax: "<length>";
  inherits: false;
  initial-value: 0px;
}

.lt-photo {
  position: absolute;
  display: block;
  cursor: none;
  touch-action: none;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
  /* overlapping photos blend like stacked negatives/prints on the light table */
  mix-blend-mode: multiply;
  transform: translate(var(--drag-x, 0px), calc(var(--drag-y, 0px) + var(--entry-y, 0px))) rotate(var(--rot, 0deg)) scale(var(--hover-scale, 1)) scaleX(var(--flipx, 1));
  transform-origin: center center;
  opacity: var(--entry-opacity, 1);
  transition:
    transform 0.28s cubic-bezier(0.16, 1, 0.3, 1),
    opacity 0.55s ease,
    box-shadow 0.28s cubic-bezier(0.16, 1, 0.3, 1),
    filter 0.28s cubic-bezier(0.16, 1, 0.3, 1);
  /* NOTE: no permanent will-change — promoting every photo to its own GPU layer
     made panning jank. Photos are static while panning (only the surface moves),
     so they only need promotion during hover / drag / the entry slide-in. */
}
.lt-photo:hover,
.lt-photo.lt-photo-dragging,
body:not(.lt-photos-arranged) .lt-photo {
  will-change: transform;
}

.lt-photo img {
  display: block;
  width: 280px;
  height: auto;
}

/* the positive base image (revealed under the loupe / after developing) */
.lt-photo .lt-base { position: relative; z-index: 1; }

/* the negative layer: same photo with a real C41 colour-negative look,
   stacked exactly on top; the cursor masks a hole → positive shows through */
.lt-photo .lt-neg {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  z-index: 2;
  /* realistic colour negative: inverted + orange film-base mask (orange, not yellow, no blue) */
  filter: var(--neg-filter);
  opacity: 1;
  transition: opacity 0.6s ease;
  /* default: full negative, no mask → cheap. The loupe hole is only computed for
     the photo(s) actually under the cursor (class .lt-loupe, added by JS). */
  -webkit-mask-image: none;
          mask-image: none;
}
/* only the photo currently beneath the loupe pays for the radial-gradient mask */
.lt-photo.lt-loupe .lt-neg {
  -webkit-mask-image: radial-gradient(circle at
      calc((var(--lcx, -99999) - var(--ox, 0)) * 1px) calc((var(--lcy, -99999) - var(--oy, 0)) * 1px),
      transparent 0, transparent calc(var(--lr1, 0) * 1px), #000 calc(var(--lr2, 0) * 1px));
          mask-image: radial-gradient(circle at
      calc((var(--lcx, -99999) - var(--ox, 0)) * 1px) calc((var(--lcy, -99999) - var(--oy, 0)) * 1px),
      transparent 0, transparent calc(var(--lr1, 0) * 1px), #000 calc(var(--lr2, 0) * 1px));
}

/* Per-photo logical darkroom scribbles
   The PNGs have pure white backgrounds and are multiplied into the image,
   so white disappears and only pencil/marker strokes remain visible. */
.lt-scribble-layer,
.lt-floating-scribble-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: visible;
  mix-blend-mode: multiply;
  opacity: 0;
  transition: opacity 1.6s ease;
}
.lt-scribble-layer { z-index: 4; }
.lt-floating-scribble-layer { z-index: 3; }
/* Scribbles are visible immediately. The PNGs are cleaned, so no delayed fade is needed. */
body.lt-ready .lt-scribble-layer,
body.lt-scribbles-ready .lt-scribble-layer { opacity: 1; }
body.lt-ready .lt-floating-scribble-layer,
body.lt-scribbles-ready .lt-floating-scribble-layer { opacity: 0.78; }

.lt-scribble {
  position: absolute;
  display: block;
  height: auto !important;
  max-width: none;
  object-fit: contain;
  pointer-events: none;
  user-select: none;
  mix-blend-mode: multiply;
  transform-origin: center center;
}
.lt-scribble--number { z-index: 7; }
.lt-scribble--crop { z-index: 6; opacity: 0.86; }
.lt-scribble--focus { z-index: 5; }
.lt-scribble--detail { z-index: 8; }
.lt-scribble--star { z-index: 9; }
/* Keep extreme long/thin scribble PNGs from becoming huge black strokes. */
.lt-floating-scribble-layer .lt-scribble--crop,
.lt-floating-scribble-layer .lt-scribble--detail,
.lt-floating-scribble-layer .lt-scribble--star {
  max-width: 72px !important;
  max-height: 58px !important;
}
.lt-scribble-layer .lt-scribble--crop,
.lt-scribble-layer .lt-scribble--detail,
.lt-scribble-layer .lt-scribble--star {
  max-height: 28% !important;
}
.lt-scribble--rect {
  max-width: 92% !important;
  max-height: 72% !important;
}
body.lt-grid .lt-scribble-layer,
body.lt-grid .lt-floating-scribble-layer { display: none !important; }

/* "develop": reveal the positive outward from the exact click/tap point.
   --devx/--devy = point (set in JS); --dev-r animates 0 → full via @property. */
.lt-photo.lt-developing .lt-neg {
  -webkit-mask-image: radial-gradient(circle at var(--devx, 50%) var(--devy, 50%),
      transparent 0, transparent calc(var(--dev-r) - 150px), #000 var(--dev-r));
          mask-image: radial-gradient(circle at var(--devx, 50%) var(--devy, 50%),
      transparent 0, transparent calc(var(--dev-r) - 150px), #000 var(--dev-r));
  animation: lt-develop 0.95s cubic-bezier(0.33, 0, 0.2, 1) forwards;
}
@keyframes lt-develop {
  from { --dev-r: 0px; }
  to   { --dev-r: 960px; }   /* large enough to clear any photo from any point */
}

/* once a photo has been developed, it stays positive on the light table */
.lt-photo.lt-developed .lt-neg {
  opacity: 0;
  pointer-events: none;
  -webkit-mask-image: none !important;
          mask-image: none !important;
  animation: none !important;
}

/* RASTER (grid) view shows only the finished positive image */
body.lt-grid .lt-photo .lt-neg { display: none; }
body.lt-grid .lt-photo img { width: 100% !important; }

/* ── MOBILE / TOUCH ──
   No loupe is used on touch, so drop the continuous mask (the negative fully
   covers); tap-to-develop still reveals from the point via the rule above. */
@media (hover: none), (pointer: coarse) {
  .lt-photo .lt-neg { -webkit-mask-image: none; mask-image: none; }
}


.lt-photo:hover {
  z-index: 999 !important;
}

/* Zoom slider UI */
.lt-zoom {
  position: fixed;
  right: 24px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 60;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  color: #fff;
  mix-blend-mode: difference;
  opacity: 0;
  transition: opacity 1s ease 0.6s;
}
body.lt-ready .lt-zoom { opacity: 1; }

.lt-zoom-label {
  font-size: 16px;
  color: currentColor;
  user-select: none;
}

#lt-zoom-slider {
  -webkit-appearance: none;
  appearance: none;
  writing-mode: vertical-lr;
  direction: rtl;
  width: 4px;
  height: 160px;
  background: rgba(255,255,255,0.35);
  border-radius: 4px;
  outline: none;
  cursor: pointer;
}
#lt-zoom-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 16px; height: 16px;
  border-radius: 50%;
  background: #fff;
  cursor: pointer;
}
#lt-zoom-slider::-moz-range-thumb {
  width: 16px; height: 16px;
  border: 0;
  border-radius: 50%;
  background: #fff;
  cursor: pointer;
}

/* Mode toggle button (light table on/off) */
.lt-mode-toggle {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 62;
  background: rgba(255,255,255,0.85);
  border: 1px solid rgba(0,0,0,0.2);
  border-radius: 100px;
  padding: 9px 18px;
  font-family: var(--sans);
  font-size: 14px;
  letter-spacing: 0.02em;
  color: #000;
  cursor: pointer;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  opacity: 0;
  transition: opacity 1s ease 0.6s, background 0.2s;
}
body.lt-ready .lt-mode-toggle { opacity: 1; }
.lt-mode-toggle:hover { background: #fff; }

/* ── GRID MODE (light table "off") — simple scrollable grid ── */
body.lt-grid .lighttable-viewport {
  position: static;
  height: auto;
  min-height: 100vh;
  overflow: visible;
  padding: calc(var(--nav-h) + 16px) 12px 90px;
  cursor: auto;
}
body.lt-grid.lt-ready .lighttable-viewport {
  background-image: none;
  background-color: #fff;
}
body.lt-grid .lighttable-surface {
  position: static !important;
  width: auto !important;
  height: auto !important;
  transform: none !important;
  opacity: 1 !important;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 12px;
  max-width: 1500px;
  margin: 0 auto;
}
body.lt-grid .lt-photo {
  position: static !important;
  transform: none !important;
  width: 100% !important;
  height: auto !important;
  mix-blend-mode: normal;
  box-shadow: 0 2px 12px rgba(0,0,0,0.12);
  cursor: pointer;
}
body.lt-grid .lt-photo img { width: 100% !important; height: auto !important; cursor: pointer; }
body.lt-grid .lt-zoom,
body.lt-grid .lens-fx { display: none !important; }
body.lt-grid .cursor { display: none !important; }
body.lt-grid .lt-hint { display: none !important; }

/* Gesture hint */
.lt-hint {
  position: fixed;
  left: 50%;
  bottom: max(56px, calc(env(safe-area-inset-bottom, 0px) + 56px));
  transform: translateX(-50%) translateY(0);
  z-index: 61;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  color: #fff;                    /* white + difference = always opposite of bg */
  mix-blend-mode: difference;
  font-family: var(--sans);
  font-size: 14px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  pointer-events: none;
  opacity: 0;
  will-change: opacity, transform;
  transition: opacity 1.15s ease, transform 1.15s ease;
}
body.lt-ready .lt-hint {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
.lt-hint svg { display: block; }
.lt-hint > span { display: block; }
.lt-hint-row {
  display: flex;
  align-items: flex-start;
  gap: 28px;
}
.lt-hint-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.lt-hint-item span {
  white-space: nowrap;
}
.lt-hint-item--drag svg {
  animation: lt-hint-drag-icon 2.2s ease-in-out infinite;
}
.lt-hint:not(.lt-hint--open) > svg {
  animation: lt-hint-drag-icon 2.2s ease-in-out infinite;
}
.lt-hint-item--zoom svg {
  animation: lt-hint-zoom-icon 1.7s ease-in-out infinite;
}
.lt-hint-item--reorder svg {
  animation: lt-hint-drag-icon 2.2s ease-in-out infinite;
}
.lt-hint--hide { opacity: 0 !important; transform: translateX(-50%) translateY(12px) !important; animation: none; }
.lt-hint--open {
  animation: none;
}
.lt-hint--open .lt-hint-row {
  gap: 30px;
}
.lt-hint--open svg {
  width: 64px;
  height: 54px;
}
.lt-hint--open .lt-hint-item--click svg,
.lt-hint--open > svg {
  animation: lt-hint-tap-icon 1.8s ease-in-out infinite;
}
.lt-hint--reorder .lt-hint-row {
  justify-content: center;
}
.lt-hint--reorder svg {
  width: 72px;
  height: 56px;
}
@keyframes lt-hint-tap-icon {
  0%, 100% { transform: translateY(0) scale(1); }
  25%      { transform: translateY(-4px) scale(1.01); }
  50%      { transform: translateY(2px) scale(0.98); }
  75%      { transform: translateY(7px) scale(0.96); }
}


@keyframes lt-hint-drag-icon {
  0%, 100% { transform: translateX(-6px); }
  50%      { transform: translateX(6px); }
}
@keyframes lt-hint-zoom-icon {
  0%, 100% { transform: scale(1) translateY(0); }
  45%      { transform: scale(1.08) translateY(-1px); }
  60%      { transform: scale(0.97) translateY(1px); }
}

@media (max-width: 900px) {
  .lt-hint {
    bottom: calc(env(safe-area-inset-bottom, 0px) + clamp(96px, 14svh, 148px));
    gap: 8px;
    font-size: 13px;
  }
  .lt-hint > span {
    max-width: min(78vw, 270px);
    text-align: center;
    line-height: 1.2;
  }
  .lt-hint-row {
    gap: 18px;
  }
  .lt-hint--open svg {
    width: 74px;
    height: 58px;
  }
  .lt-hint-item--zoom span {
    max-width: 108px;
    text-align: center;
    white-space: normal;
    line-height: 1.15;
  }
}

/* Lightbox */
.lightbox {
  position: fixed; inset: 0;
  z-index: 9000;
  background: rgba(0,0,0,0.96);
  display: none;
  align-items: center; justify-content: center;
  padding: 40px;
}
.lightbox.is-open { display: flex; }
.lightbox img { max-width: 90vw; max-height: 90vh; object-fit: contain; }
.lightbox-close {
  position: fixed; top: 24px; right: 28px;
  font-size: 12px; letter-spacing: 0.15em;
  text-transform: uppercase; color: #fff;
}

/* ════════════════════════════════════════════
   PROJECT DETAIL PAGE — centered Moret title
   ════════════════════════════════════════════ */
.project-detail {
  padding: calc(var(--nav-h) + 100px) var(--grid-pad) 60px;
  max-width: var(--content-max);
  margin: 0 auto;
  text-align: center;
}

.project-detail .meta {
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-dim);
  margin-bottom: 24px;
}

.project-detail h1 {
  font-family: var(--serif);
  font-size: clamp(48px, 7vw, 96px);
  font-weight: 400;
  text-align: center;
  letter-spacing: 0;
  line-height: 1.05;
  margin-bottom: 60px;
  text-transform: none;
}

.project-detail .video-heading {
  font-family: var(--sans);
  font-size: clamp(18px, 1.8vw, 24px);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: #fff;
  text-align: center;
  margin: 48px 0 18px;
}

.project-detail .video-wrap {
  position: relative;
  width: 100%;
  aspect-ratio: 16/9;
  background: #111;
  margin: 0 auto 32px;
}

.project-detail .video-wrap iframe,
.project-detail .video-wrap > div,
.project-detail .video-wrap > div iframe {
  position: absolute; inset: 0;
  width: 100% !important;
  height: 100% !important;
  border: 0;
}

.project-detail .cover { margin-bottom: 32px; }
.project-detail .cover img { width: 100%; height: auto; }

.project-detail .description {
  max-width: 900px;
  margin: 0 auto 48px;
  font-family: var(--sans);
  font-size: clamp(18px, 1.8vw, 24px);
  line-height: 1.4;
  color: #fff;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  text-align: center;
}
.project-detail .description p { margin-bottom: 0.8em; }

.project-detail .info-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
  border-top: 1px solid rgba(255,255,255,0.15);
  padding-top: 20px;
  margin-bottom: 60px;
  font-size: 13px;
  text-align: left;
}

.project-detail .info-row .label {
  display: block;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--fg-dim);
  margin-bottom: 6px;
}

.project-detail .gallery {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  margin-bottom: 60px;
}
.project-detail .gallery img { width: 100%; height: auto; }

.back-link {
  display: inline-block;
  margin-top: 20px;
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  border-bottom: 1px solid currentColor;
  padding-bottom: 2px;
}

/* ════════════════════════════════════════════
   CONTENT BLOCKS (free-form per project)
   ════════════════════════════════════════════ */
.blocks {
  max-width: var(--content-max);
  margin: 40px auto 0;
  text-align: left;
}

.block-heading {
  font-family: var(--sans);
  font-size: clamp(18px, 1.8vw, 24px);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: #fff;
  text-align: center;
  margin: 48px 0 18px;
}

.block-text {
  max-width: 700px;
  margin: 0 auto 32px;
  font-size: 15px;
  line-height: 1.7;
  color: var(--fg-dim);
}
.block-text p { margin-bottom: 1em; }

/* alignment options */
.block-text.align-left   { text-align: left; }
.block-text.align-center { text-align: center; }
.block-text.align-right  { text-align: right; }

/* color options */
.block-text.color-blue  { color: #1010ff; }
.block-text.color-red   { color: #ff1f1f; }
.block-text.color-grey  { color: #888; }
.block-text.color-white { color: #fff; }
.block-text.color-black { color: #000; }

/* links are ALWAYS blue (content areas) */
.block-text a,
.block-heading a,
.project-detail a,
.darkroom-blocks .block-text a,
.kirbytext a {
  color: #1010ff !important;
  border-bottom: none;
  text-decoration: underline;
  text-underline-offset: 2px;
  /* break long URLs/words so they never overflow the viewport on mobile */
  overflow-wrap: anywhere;
  word-break: break-word;
}
/* same safety for the surrounding text containers */
.project-detail,
.project-detail .description,
.block-text,
.block-heading,
.kirbytext,
.ext-links,
.credits {
  overflow-wrap: anywhere;
  word-break: break-word;
}
.block-text a:hover,
.block-heading a:hover,
.project-detail a:hover,
.kirbytext a:hover { color: var(--hover) !important; }

.block-image {
  margin: 0 auto 32px;
}
.block-image img { width: 100%; height: auto; display: block; }
.block-image figcaption {
  font-size: 12px; color: var(--fg-dim);
  text-align: center; margin-top: 8px;
}

.block-video {
  position: relative;
  width: 100%;
  background: #111;
  margin: 0 auto 12px;
}
.block-embed {
  position: relative;
  width: 100%;
  margin: 0 auto 32px;
}

/* ── format options (16:9 default, 9:16 / 1:1 / 4:5 for vertical/square) ── */
.block-video.ratio-16-9, .block-embed.ratio-16-9 { aspect-ratio: 16 / 9; }
.block-video.ratio-9-16, .block-embed.ratio-9-16 { aspect-ratio: 9 / 16;  max-width: 360px; }
.block-video.ratio-1-1,  .block-embed.ratio-1-1  { aspect-ratio: 1 / 1;   max-width: 540px; }
.block-video.ratio-4-5,  .block-embed.ratio-4-5  { aspect-ratio: 4 / 5;   max-width: 460px; }

/* Instagram: 9:16 media PLUS Instagram's own header/footer bars (≈ fixed px),
   so use a padding box that adds room for the chrome → nothing gets cut off */
.block-video.ratio-ig {
  aspect-ratio: auto;
  max-width: 340px;
  width: 100%;
  height: 0;
  padding-bottom: calc(177.78% + 96px);
  background: #fff;
}

.block-video iframe {
  position: absolute; inset: 0;
  width: 100%; height: 100%; border: 0;
}
/* embeds with a fixed format fill the box */
.block-embed:not(.ratio-auto) iframe {
  position: absolute; inset: 0;
  width: 100% !important; height: 100% !important; border: 0;
}
/* "auto" lets the embed (e.g. the Instagram script) define its own height */
.block-embed.ratio-auto {
  aspect-ratio: auto;
  max-width: 400px;
  background: transparent;
}
.block-embed.ratio-auto iframe,
.block-embed.ratio-auto > * {
  position: static !important;
  width: 100% !important;
  height: auto !important;
  border: 0;
  margin: 0 auto;
}

.block-video-caption {
  font-size: 12px; color: var(--fg-dim);
  text-align: center; margin-bottom: 40px;
}

.block-line {
  border: 0;
  border-top: 1px solid rgba(255,255,255,0.2);
  margin: 48px 0;
}

/* ── Blocks on the white Darkroom page ── */
.darkroom-blocks {
  max-width: 1600px;
  margin: 0 auto 40px;
}
.darkroom-blocks .block-heading {
  color: #000;
  text-align: left;
  margin: 56px 0 20px;
}
.darkroom-blocks .block-text {
  color: #333;
  margin-left: 0;
}
.darkroom-blocks .block-text a { color: #000; border-bottom-color: rgba(0,0,0,0.4); }
.darkroom-blocks .block-line { border-top-color: rgba(0,0,0,0.15); }

/* Gallery block as masonry grid */
.block-gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  margin-bottom: 32px;
}
.block-gallery img { width: 100%; height: auto; display: block; }
.block-gallery-item { display: block; overflow: hidden; cursor: none; }
.block-gallery-item img {
  transition: transform 0.5s cubic-bezier(0.16,1,0.3,1), opacity 0.3s;
  opacity: 1;
}
.block-gallery-item:hover img { transform: scale(1.02); opacity: 1; }

@media (max-width: 900px) {
  .block-gallery { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 600px) {
  .block-gallery { grid-template-columns: 1fr; }
}

/* ════════════════════════════════════════════
   FOOTER
   ════════════════════════════════════════════ */
.site-footer {
  position: relative;
  z-index: 2;
  border-top: 1px solid rgba(255,255,255,0.1);
  padding: 28px 0;
  font-size: 11px;
  color: var(--fg-dim);
  letter-spacing: 0.04em;
}

.site-footer-inner {
  max-width: var(--content-max);
  margin: 0 auto;
  padding: 0 var(--grid-pad);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

body.is-about .site-footer,
body.page-about .site-footer,
body.template-about .site-footer {
  border-top-color: rgba(0,0,0,0.1);
  color: rgba(0,0,0,0.5);
}

/* Darkroom: hide footer (it would slip behind the fixed light table) */
body.is-darkroom .site-footer,
body.page-darkroom .site-footer,
body.template-darkroom .site-footer {
  display: none !important;
}

/* ════════════════════════════════════════════
   RESPONSIVE
   ════════════════════════════════════════════ */

/* ── TABLET ── */
@media (max-width: 1024px) {
  :root { --nav-h: 84px; --grid-pad: 32px; }
  .site-header nav ul { gap: 24px; }
}

@media (max-width: 900px) {
  :root { --nav-h: 80px; }
  .about-grid { grid-template-columns: 1fr; gap: 40px; }
  .about-portrait { max-width: 70%; }
  .project-detail .info-row { grid-template-columns: 1fr 1fr; }
  .project-detail .gallery { grid-template-columns: 1fr; }

  /* ── HAMBURGER MENU ── */
  .nav-toggle { display: flex; z-index: 120; }

  .site-header nav {
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0;
    background: #000;
    display: flex;
    align-items: center;
    justify-content: center;
    transform: translateY(-100%);
    opacity: 0;
    visibility: hidden;
    transition: transform 0.4s cubic-bezier(0.16,1,0.3,1), opacity 0.4s, visibility 0.4s;
    z-index: 110;
  }
  .site-header.nav-open nav {
    transform: translateY(0);
    opacity: 1;
    visibility: visible;
  }
  .site-header nav ul {
    flex-direction: column;
    gap: 28px;
    align-items: center;
  }
  .site-header nav a {
    font-size: clamp(34px, 9vw, 52px);
    font-weight: 400;
    color: #fff !important;
  }
  .site-header nav a.is-active { color: var(--hover) !important; }

  /* open menu = black overlay + white text on ALL pages (beats lt-ready/about color rules) */
  .site-header.nav-open nav { background: #000 !important; }
  .site-header.nav-open nav a,
  body.is-about .site-header.nav-open nav a,
  body.page-about .site-header.nav-open nav a,
  body.template-about .site-header.nav-open nav a,
  body.lt-ready .site-header.nav-open nav a {
    color: #fff !important;
  }
  .site-header.nav-open nav a.is-active,
  body.lt-ready .site-header.nav-open nav a.is-active {
    color: var(--hover) !important;
  }

  /* hamburger turns into an X when open */
  .site-header.nav-open .nav-toggle { color: #fff; }
  .site-header.nav-open .nav-toggle span:nth-child(1) { transform: translateY(8.5px) rotate(45deg); }
  .site-header.nav-open .nav-toggle span:nth-child(2) { opacity: 0; }
  .site-header.nav-open .nav-toggle span:nth-child(3) { transform: translateY(-8.5px) rotate(-45deg); }

  /* logo + toggle always visible above the overlay */
  .site-header .logo { z-index: 120; position: relative; }
  .site-header.nav-open .logo { color: #fff; }
}

/* ── DARKROOM on touch: interactive table works; tap photos to enlarge ── */
@media (hover: none), (pointer: coarse) {
  .lighttable-viewport { cursor: auto; }
  .lt-photo, .lt-photo img { cursor: pointer; }
  /* bigger zoom slider touch target */
  #lt-zoom-slider { width: 6px; height: 140px; }
  #lt-zoom-slider::-webkit-slider-thumb { width: 22px; height: 22px; }
  #lt-zoom-slider::-moz-range-thumb { width: 22px; height: 22px; }
}

/* grid mode on small screens → 2 columns */
@media (max-width: 768px) {
  body.lt-grid .lighttable-surface { grid-template-columns: 1fr 1fr; }
}

/* ── PHONE ── */
@media (max-width: 600px) {
  :root { --grid-pad: 18px; --nav-h: 68px; }

  /* Header */
  .site-header .logo { font-size: 26px; }

  /* Project line-list — large, wrapping titles, tight to the lines (like the old site) */
  .project-row {
    align-items: flex-start;
    height: auto;              /* override desktop fixed 35px so titles can wrap */
    padding: 11px 0 9px;
    font-size: clamp(28px, 7.6vw, 38px);
    line-height: 1.04;
    letter-spacing: 0;
  }
  .project-row .p-title { gap: 10px; }
  .project-row .p-name {
    white-space: normal;       /* allow wrapping instead of cutting off */
    overflow: visible;
    text-overflow: clip;
  }
  .project-row .p-category { display: none; } /* hide category for clean title lines */

  /* Project detail */
  .project-detail h1 { font-size: clamp(34px, 10vw, 52px); }
  .project-detail .info-row { grid-template-columns: 1fr; gap: 18px; }
  .project-detail .description { font-size: clamp(20px, 5.5vw, 26px); }

  /* About: bigger text, full-width portrait */
  .about-col { font-size: clamp(22px, 6vw, 30px); }
  .about-portrait { max-width: 100%; }

  /* Light table padding */
  .lighttable-viewport { padding-left: 10px; padding-right: 10px; }
}

/* Hide custom cursor entirely on touch devices */
@media (hover: none), (pointer: coarse) {
  .cursor { display: none !important; }
}

/* ════════════════════════════════════════════
   AUTO-CONTRAST — text colour follows a custom page background's luminance
   (bg-light → black ink, bg-dark → white ink). Added last so it wins.
   ════════════════════════════════════════════ */
.bg-custom.bg-light { --ink: #000; --ink-soft: rgba(0,0,0,0.55); }
.bg-custom.bg-dark  { --ink: #fff; --ink-soft: rgba(255,255,255,0.62); }

.bg-custom body { color: var(--ink); }

/* header logo + nav (nav links inherit colour from .site-header) */
.bg-custom .site-header { color: var(--ink); }
.bg-custom .site-header .logo { color: var(--ink); }
.bg-custom .site-header nav a:hover,
.bg-custom .site-header nav a.is-active { color: var(--hover); }

/* project line-list */
.bg-custom .project-row { color: var(--ink); border-bottom-color: var(--ink); }
.bg-custom .project-row .p-category { color: var(--ink); }
.bg-custom .project-row:hover,
.bg-custom .project-row:hover .p-category { color: var(--hover); }

/* project detail text */
.bg-custom .project-detail,
.bg-custom .project-detail h1,
.bg-custom .project-detail h2,
.bg-custom .project-detail .meta,
.bg-custom .project-detail .video-heading,
.bg-custom .project-detail .description,
.bg-custom .project-detail .info-row,
.bg-custom .project-detail .info-row .label,
.bg-custom .back-link { color: var(--ink); }

/* free text/heading blocks without an explicit colour choice */
.bg-custom .block-text:not(.color-white):not(.color-black),
.bg-custom .block-heading { color: var(--ink); }

/* about page */
.bg-custom .about-col,
.bg-custom .about-col h3,
.bg-custom .about-seen,
.bg-custom .about-seen h3,
.bg-custom .seen-item strong { color: var(--ink); }

/* footer */
.bg-custom .site-footer { color: var(--ink-soft); border-top-color: var(--ink-soft); }
.bg-custom .site-footer a { color: var(--ink-soft); }
.bg-custom .site-footer a:hover { color: var(--hover); }

/* on a DARK custom background the blue body links become unreadable → use ink */
.bg-custom.bg-dark a { color: var(--ink); }
.bg-custom.bg-dark a:hover { color: var(--hover); }


/* Mobile hamburger follows custom background contrast too */
.bg-custom .nav-toggle span { background: var(--ink); }
.bg-custom .site-header.nav-open .nav-toggle span { background: #fff !important; }


/* Project hover: keep only the red circle around the preview cursor.
   Random white scribble icons are intentionally hidden. */
.cursor .cursor-random-icon {
  display: none !important;
  opacity: 0 !important;
}
.cursor.has-scribbles .cursor-random-icon {
  opacity: 0 !important;
}


/* Project hover numbers: correct handwritten project index next to the preview. */
.cursor .cursor-project-number {
  display: block;
  background: transparent;
  pointer-events: none;
}
.cursor.has-scribbles .cursor-project-number {
  opacity: 0.96 !important;
}


/* Project hover simplified: no red circles and no handwritten numbers */
.cursor .cursor-circle-frame,
.cursor .cursor-project-number {
  display: none !important;
  opacity: 0 !important;
}


/* Progressive hero video: low-res first, high-res fades in smoothly */
.hero { background: #000; }
.hero .hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.hero .hero-video--low {
  z-index: 1;
}
.hero .hero-video--high {
  z-index: 2;
  opacity: 0;
  transition: opacity 1.8s cubic-bezier(0.16, 1, 0.3, 1);
  will-change: opacity;
}
.hero .hero-video--high.is-ready {
  opacity: 1;
}


/* Project hover simplified: only the round preview image, no red circles or numbers */
.cursor .cursor-circle-frame,
.cursor .cursor-project-number,
.cursor .cursor-random-icon {
  display: none !important;
  opacity: 0 !important;
}

.lt-photo:hover {
  --hover-scale: 1.045;
  box-shadow: 0 18px 42px rgba(0,0,0,0.18);
}
.lt-photo.lt-photo-dragging {
  --hover-scale: 1.055;
  transition: none !important;
  cursor: grabbing;
  box-shadow: 0 22px 54px rgba(0,0,0,0.22);
}
.lt-photo.lt-photo-dragging,
.lt-photo.lt-photo-dragging img {
  cursor: grabbing !important;
}
/* Mobile: lift the grabbed photo noticeably more so it clearly "picks up".
   (Position is driven by left/top while touch-dragging, so --drag-x/-y are 0 here;
   overriding the transform to add a real translateY lift is safe.) */
@media (pointer: coarse) {
  .lt-photo.lt-photo-dragging {
    --hover-scale: 1.12;
    transform: translateY(-12px) rotate(var(--rot, 0deg)) scale(var(--hover-scale, 1)) !important;
    box-shadow: 0 40px 90px rgba(0,0,0,0.42);
  }
}


/* Home: clean Dunkelkammer button below the project menu */
#projects .project-list--bottom {
  padding-bottom: 0;
}
#projects {
  padding-bottom: 0;
  transition: transform 0.85s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.65s ease, filter 0.75s ease;
  will-change: transform, opacity, filter;
}
.home-darkroom-link-wrap {
  width: 100%;
  padding: clamp(34px, 4.8vw, 58px) var(--grid-pad) clamp(48px, 6vw, 76px);
  display: flex;
  justify-content: center;
  align-items: center;
  background: transparent;
  position: relative;
  z-index: 2;
}
.home-darkroom-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 32px;
  padding: 6px 17px 8px;
  border: 1px solid #fff;
  border-radius: 0;
  color: #000;
  font-family: var(--serif);
  font-size: clamp(15px, 1.55vw, 22px);
  font-weight: 400;
  line-height: 0.95;
  letter-spacing: -0.025em;
  text-transform: none;
  text-decoration: none;
  background: #fff;
  transform: translateY(0) scale(1);
  box-shadow: 0 0 0 rgba(0,0,0,0);
  transition: transform 0.45s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.45s cubic-bezier(0.16, 1, 0.3, 1), background 0.25s ease, color 0.25s ease, border-color 0.25s ease;
  will-change: transform;
}
.home-darkroom-link:hover {
  color: #fff;
  background: #000;
  border-color: #000;
  transform: translateY(-7px) scale(1.025);
  box-shadow: 0 18px 34px rgba(0,0,0,0.22);
}
.bg-custom .home-darkroom-link { color: #000; background: #fff; border-color: #fff; }
.bg-custom .home-darkroom-link:hover { color: #fff; background: #000; border-color: #000; }

@media (max-width: 700px) {
  .home-darkroom-link-wrap {
    padding: 30px var(--grid-pad) 54px;
  }
  .home-darkroom-link {
    min-height: 31px;
    padding: 6px 16px 8px;
    font-size: clamp(17px, 5.8vw, 23px);
  }
  .home-darkroom-link:hover {
    transform: translateY(-5px) scale(1.018);
  }
}

body.home-to-darkroom #projects {
  /* Kamerafahrt ersetzt durch Iris: der Inhalt bleibt stehen und wird von
     der wachsenden Kreis-Blende des Leuchttischs überdeckt */
  transform: none;
  transform-origin: 50% 12%;
  opacity: 1;
  filter: none;
  pointer-events: none;
}
body.home-to-darkroom .hero-scroll {
  opacity: 0 !important;
  filter: blur(12px) !important;
  pointer-events: none !important;
}
.home-darkroom-transition-screen {
  position: fixed;
  inset: 0;
  z-index: 9000;
  pointer-events: none;
  /* stillgelegt: die Iris übernimmt die Dramaturgie — bleibt transitionsfähig,
     falls Code auf transitionend wartet */
  transform: none;
  opacity: 0;
  background:
    radial-gradient(circle at 50% 42%, rgba(255, 68, 34, 0.28) 0%, rgba(170, 8, 5, 0.62) 50%, rgba(10,0,0,0.96) 100%);
  transition: opacity 0.05s linear;
  filter: brightness(0.82);
}
.home-darkroom-transition-screen.is-active {
  transform: none;
  opacity: 0;
  animation: none;
}
@keyframes homeDarkroomFlicker {
  0%   { filter: brightness(0.70) saturate(1.08); }
  24%  { filter: brightness(0.96) saturate(1.15); }
  46%  { filter: brightness(0.82) saturate(1.10); }
  68%  { filter: brightness(1.04) saturate(1.18); }
  100% { filter: brightness(0.95) saturate(1.12); }
}

/* Dunkelkammer button hover: red cursor ring, but the button text stays readable */
.cursor.is-darkroom-button {
  width: 150px;
  height: 150px;
  margin: -75px 0 0 -75px;
  border-radius: 50%;
  box-sizing: border-box;
  background: rgba(255, 31, 31, 0.14) !important;
  background-image: none !important;
  border: 2px solid var(--hover);
  box-shadow: 0 0 0 1px rgba(255, 31, 31, 0.22);
  mix-blend-mode: normal !important;
}
.cursor.is-darkroom-button .cursor-preview,
.cursor.is-darkroom-button .cursor-circle-frame,
.cursor.is-darkroom-button .cursor-random-icon,
.cursor.is-darkroom-button .cursor-project-number {
  display: none !important;
  opacity: 0 !important;
}


/* Darkroom page enter from Home: light table slides in from below, then red safelight fades to white */
body.lt-from-home .lighttable-viewport {
  /* Iris-Blende statt Hochfahren — Ursprung ist die Knopfmitte der Home
     (reist per sessionStorage mit, Fallback: unten mittig) */
  transform: none;
  clip-path: circle(0px at var(--dkx, 50%) var(--dky, 92%));
  transition:
    clip-path 1.6s cubic-bezier(0.4, 0, 0.15, 1),
    background-color 2.4s ease,
    background-image 2.4s ease;
  will-change: clip-path;
}
body.lt-from-home.lt-entered .lighttable-viewport {
  transform: none;
  clip-path: circle(150% at var(--dkx, 50%) var(--dky, 92%));
}
body.lt-from-home.lt-entered .lighttable-viewport::before {
  animation: none;
}
body.lt-from-home:not(.lt-photos-arranged) .lt-photo {
  --entry-y: 88px;
  --entry-opacity: 0;
}
body.lt-from-home.lt-photos-arranged .lt-photo {
  --entry-y: 0px;
  --entry-opacity: 1;
}
@keyframes ltRedLightFlicker {
  /* sanftes Glimmen der Safelight — Deckkraft bleibt hoch (min .9), damit
     das Projektmenü hinter dem Overlay nie durchscheint */
  0%   { opacity: 1;   filter: brightness(0.72); }
  22%  { opacity: .94; filter: brightness(1.12); }
  44%  { opacity: 1;   filter: brightness(0.9); }
  66%  { opacity: .95; filter: brightness(1.06); }
  100% { opacity: 1;   filter: brightness(1); }
}


/* Darkroom → Projects: reverse transition when leaving the light table */
body.darkroom-to-projects {
  overflow: hidden;
  background: #fff !important;
}
body.darkroom-to-projects .site-header {
  opacity: 0;
  transform: translateY(-22px);
  transition: opacity 0.42s ease, transform 0.62s cubic-bezier(0.16, 1, 0.3, 1);
  pointer-events: none;
}
body.darkroom-to-projects .lighttable-viewport {
  transform: translateY(105vh) scale(0.985) !important;
  filter: none;
  opacity: 1;
  transition:
    transform 0.86s cubic-bezier(0.16, 1, 0.3, 1),
    filter 0.72s cubic-bezier(0.16, 1, 0.3, 1),
    opacity 0.72s ease !important;
  will-change: transform, filter, opacity;
}
body.darkroom-to-projects .lens-fx,
body.darkroom-to-projects .lt-hint,
body.darkroom-to-projects .lt-open-hint,
body.darkroom-to-projects .lt-mode-toggle,
body.darkroom-to-projects .lt-zoom {
  opacity: 0 !important;
  pointer-events: none !important;
}
.darkroom-projects-transition-screen {
  position: fixed;
  inset: 0;
  z-index: 9000;
  pointer-events: none;
  opacity: 0;
  background:
    radial-gradient(circle at 50% 42%, rgba(255, 68, 34, 0.30) 0%, rgba(170, 8, 5, 0.62) 50%, rgba(10, 0, 0, 0.96) 100%);
  filter: brightness(0.7);
  transition: opacity 0.24s ease;
}
.darkroom-projects-transition-screen.is-active {
  opacity: 1;
  filter: brightness(0.94);
  animation: none;
}

/* Home + inline Darkroom: real in-page transition, no page-load freeze */
.home-inline-darkroom {
  position: fixed;
  inset: 0;
  z-index: 40;
  pointer-events: none;
}
.home-inline-darkroom .lighttable-viewport {
  z-index: 40;
  /* Iris-Blende statt Hochfahren: Kreis-Maske startet in der Knopfmitte
     (--dkx/--dky setzt das JS beim Klick) */
  transform: none;
  clip-path: circle(0px at var(--dkx, 50%) var(--dky, 92%));
  transition:
    clip-path 1.6s cubic-bezier(0.4, 0, 0.15, 1),
    background-color 2.15s ease,
    background-image 2.15s ease,
    filter 0.72s cubic-bezier(0.16, 1, 0.3, 1),
    opacity 0.72s ease;
  will-change: clip-path, filter, opacity;
}
body.home-darkroom-active .home-inline-darkroom {
  pointer-events: auto;
}
body.is-home.home-darkroom-active.lt-entered .home-inline-darkroom .lighttable-viewport {
  transform: none;
  clip-path: circle(150% at var(--dkx, 50%) var(--dky, 92%));
}
body.is-home.home-darkroom-leaving .home-inline-darkroom .lighttable-viewport {
  transform: none;
  clip-path: circle(0px at var(--dkx, 50%) var(--dky, 92%));
  filter: none;
  opacity: 1;
}
body.is-home.home-darkroom-active.lt-entered .home-inline-darkroom .lighttable-viewport::before {
  animation: none;
}
body.is-home.home-darkroom-active:not(.lt-photos-arranged) .home-inline-darkroom .lt-photo {
  --entry-y: 88px;
  --entry-opacity: 0;
}
body.is-home.home-darkroom-active.lt-photos-arranged .home-inline-darkroom .lt-photo {
  --entry-y: 0px;
  --entry-opacity: 1;
}
body.is-home.home-darkroom-active .site-header {
  z-index: 80;
}
body.is-home.home-darkroom-active .site-footer {
  pointer-events: none;
}


/* Dunkelkammer button final: smaller, white, sharp edges */
.home-darkroom-link,
.bg-custom .home-darkroom-link {
  border-radius: 0 !important;
  background: #fff;
  color: #000;
  border-color: #fff;
}
.home-darkroom-link:hover,
.bg-custom .home-darkroom-link:hover {
  background: #000;
  color: #fff;
  border-color: #000;
}

/* Darkroom logo: difference blend, readable on red light, white table and imagery */
body.is-darkroom .site-header .logo,
body.page-darkroom .site-header .logo,
body.template-darkroom .site-header .logo,
body.is-home.home-darkroom-active .site-header .logo {
  color: #fff !important;
  mix-blend-mode: difference;
}


/* Final darkroom button cursor: solid red with difference blend, no outline */
.cursor.is-darkroom-button {
  width: 150px !important;
  height: 150px !important;
  margin: -75px 0 0 -75px !important;
  background: #ff1f1f !important;
  border: 0 !important;
  outline: 0 !important;
  box-shadow: none !important;
  mix-blend-mode: difference !important;
}
.cursor.is-darkroom-button::before,
.cursor.is-darkroom-button::after {
  display: none !important;
}

/* Stronger darkroom logo difference mode */
body.is-darkroom .site-header .logo,
body.page-darkroom .site-header .logo,
body.template-darkroom .site-header .logo,
body.home-darkroom-active .site-header .logo,
html.template-darkroom .site-header .logo,
html.page-darkroom .site-header .logo,
html.home-darkroom-active .site-header .logo {
  color: #fff !important;
  mix-blend-mode: difference !important;
  isolation: auto !important;
  text-shadow: none !important;
}
body.is-darkroom.lt-ready .site-header .logo,
body.page-darkroom.lt-ready .site-header .logo,
body.template-darkroom.lt-ready .site-header .logo {
  color: #fff !important;
}

/* Final fix: make Vincent Johnson logo truly blend on all Darkroom states.
   The earlier generic lt-ready rule can turn the logo black, which kills difference.
   This forces white source color + difference on the actual logo element and keeps
   parent header layers transparent/non-isolated so the logo blends with the page. */
body.is-darkroom .site-header,
body.page-darkroom .site-header,
body.template-darkroom .site-header,
body.is-dunkelkammer .site-header,
body.page-dunkelkammer .site-header,
body.home-darkroom-active .site-header,
body.lt-from-home .site-header {
  background: transparent !important;
  isolation: auto !important;
}

body.is-darkroom .site-header-inner,
body.page-darkroom .site-header-inner,
body.template-darkroom .site-header-inner,
body.is-dunkelkammer .site-header-inner,
body.page-dunkelkammer .site-header-inner,
body.home-darkroom-active .site-header-inner,
body.lt-from-home .site-header-inner {
  background: transparent !important;
  isolation: auto !important;
}

body.is-darkroom .site-header .logo,
body.page-darkroom .site-header .logo,
body.template-darkroom .site-header .logo,
body.is-dunkelkammer .site-header .logo,
body.page-dunkelkammer .site-header .logo,
body.home-darkroom-active .site-header .logo,
body.lt-from-home .site-header .logo,
body.is-darkroom.lt-ready .site-header .logo,
body.page-darkroom.lt-ready .site-header .logo,
body.template-darkroom.lt-ready .site-header .logo,
body.home-darkroom-active.lt-ready .site-header .logo,
body.lt-from-home.lt-ready .site-header .logo {
  display: inline-block !important;
  position: relative !important;
  z-index: 10000 !important;
  color: #fff !important;
  -webkit-text-fill-color: #fff !important;
  mix-blend-mode: difference !important;
  isolation: auto !important;
  opacity: 1 !important;
  text-shadow: none !important;
  filter: none !important;
}


/* Darkroom logo blend fallback: apply difference to the header layer itself.
   Some browsers keep a fixed child logo inside its own stacking context, so the
   logo element alone can remain white. Blending the transparent header group
   against the page makes the Vincent Johnson logo invert reliably. */
body.is-darkroom .site-header,
body.page-darkroom .site-header,
body.template-darkroom .site-header,
body.is-dunkelkammer .site-header,
body.page-dunkelkammer .site-header,
body.home-darkroom-active .site-header,
body.lt-from-home .site-header {
  mix-blend-mode: difference !important;
  background: transparent !important;
  color: #fff !important;
  isolation: auto !important;
}

body.is-darkroom .site-header .logo,
body.page-darkroom .site-header .logo,
body.template-darkroom .site-header .logo,
body.is-dunkelkammer .site-header .logo,
body.page-dunkelkammer .site-header .logo,
body.home-darkroom-active .site-header .logo,
body.lt-from-home .site-header .logo {
  color: #fff !important;
  -webkit-text-fill-color: #fff !important;
  mix-blend-mode: normal !important;
}

/* Darkroom header difference fix: keep the right navigation visible.
   The header blends as one group, so all text inside it must start as white. */
body.is-darkroom .site-header nav a,
body.page-darkroom .site-header nav a,
body.template-darkroom .site-header nav a,
body.is-dunkelkammer .site-header nav a,
body.page-dunkelkammer .site-header nav a,
body.home-darkroom-active .site-header nav a,
body.lt-from-home .site-header nav a,
body.is-darkroom .site-header .nav a,
body.home-darkroom-active .site-header .nav a {
  color: #fff !important;
  -webkit-text-fill-color: #fff !important;
  opacity: 1 !important;
  mix-blend-mode: normal !important;
  visibility: visible !important;
}

body.is-darkroom .nav-toggle span,
body.page-darkroom .nav-toggle span,
body.template-darkroom .nav-toggle span,
body.home-darkroom-active .nav-toggle span,
body.lt-from-home .nav-toggle span {
  background: #fff !important;
}


/* Direct load of /#dunkelkammer: show inline darkroom immediately, without the home-to-darkroom slide. */
body.home-darkroom-direct #projects,
body.home-darkroom-direct .hero-scroll,
body.home-darkroom-direct .home-inline-darkroom .lighttable-viewport,
body.home-darkroom-direct .home-inline-darkroom .lt-photo {
  transition: none !important;
  animation: none !important;
}
body.home-darkroom-direct .home-inline-darkroom .lighttable-viewport {
  transform: none !important;
  clip-path: circle(150% at 50% 50%) !important;
}
body.home-darkroom-direct .home-inline-darkroom .lt-photo {
  --entry-y: 0px !important;
  --entry-opacity: 1 !important;
}


/* Smoother inline Darkroom transitions */
body.is-home.home-to-darkroom #projects {
  transform-origin: 50% 12%;
  transition: none;
}
body.is-home.home-darkroom-leaving #projects {
  transform: translateY(0) !important;
  opacity: 1 !important;
  filter: none !important;
  pointer-events: auto !important;
}
body.is-home.home-darkroom-leaving .hero-scroll {
  opacity: 1 !important;
  filter: none !important;
  pointer-events: auto !important;
}
body.is-home.home-darkroom-leaving .home-inline-darkroom .lighttable-viewport,
body.darkroom-to-projects .lighttable-viewport {
  transform: translateY(105vh) !important;
  filter: none !important;
  opacity: 1 !important;
  transition: transform 0.95s cubic-bezier(0.16, 1, 0.3, 1) !important;
}
body.is-home.home-darkroom-leaving .home-inline-darkroom .lighttable-viewport::before,
body.darkroom-to-projects .lighttable-viewport::before,
body.darkroom-to-projects .darkroom-projects-transition-screen {
  animation: none !important;
}
body.darkroom-to-projects .darkroom-projects-transition-screen {
  display: none !important;
}


/* Iris-Ausgang: Liste bleibt unbewegt; Interaktion kehrt nach dem Ende zurück. */
body.is-home.home-darkroom-leaving #projects {
  animation: none !important;
  pointer-events: none !important;
}
body.is-home.home-darkroom-leaving .home-inline-darkroom .lighttable-viewport::before,
body.is-home.home-darkroom-leaving .home-inline-darkroom .lighttable-viewport::after {
  animation: none !important;
  opacity: 0 !important;
}


/* Inline Darkroom raster mode: allow the fixed inline panel to scroll on mobile */
body.lt-grid.home-darkroom-active .home-inline-darkroom {
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}
body.lt-grid.home-darkroom-active .home-inline-darkroom .lighttable-viewport {
  position: relative !important;
  top: auto !important;
  left: auto !important;
  right: auto !important;
  bottom: auto !important;
  height: auto !important;
  min-height: 100vh;
  overflow: visible !important;
  transform: none !important;
}


/* Mobile raster view: allow natural page/panel scrolling over the photos. */
body.lt-grid .lighttable-viewport,
body.lt-grid .lighttable-surface,
body.lt-grid .lt-photo,
body.lt-grid .lt-photo img {
  touch-action: auto !important;
}

/* Raster view: keep the custom round cursor visible on desktop.
   Previously body.lt-grid hid .cursor, which made it disappear after pressing Raster. */
@media (hover: hover) and (pointer: fine) {
  body.lt-grid .cursor {
    display: block !important;
  }
}

/* Raster mode fix: keep the real difference cursor and the Leuchttisch toggle visible */
@media (hover: hover) and (pointer: fine) {
  body.lt-grid .cursor,
  body.lt-grid.home-darkroom-active .cursor {
    display: block !important;
    opacity: 1 !important;
    width: 150px !important;
    height: 150px !important;
    margin: -75px 0 0 -75px !important;
    background: #fff !important;
    border: 0 !important;
    box-shadow: none !important;
    mix-blend-mode: difference !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }
}

body.lt-grid .lt-mode-toggle,
body.lt-grid.lt-ready .lt-mode-toggle,
body.lt-grid.home-darkroom-active .lt-mode-toggle,
body.lt-grid.home-darkroom-active.lt-ready .lt-mode-toggle {
  display: block !important;
  visibility: visible !important;
  opacity: 1 !important;
  pointer-events: auto !important;
  position: fixed !important;
  right: 24px !important;
  bottom: 24px !important;
  z-index: 9999 !important;
}


/* Keep the Raster/Leuchttisch toggle pinned to the visible screen when the
   inline darkroom grid scrolls. Also prevent the hidden toggle from catching
   clicks after leaving the darkroom. */
.lt-mode-toggle {
  pointer-events: none;
}
body.lt-ready .lt-mode-toggle,
body.lt-grid .lt-mode-toggle,
body.home-darkroom-active .lt-mode-toggle {
  pointer-events: auto;
}
body.lt-grid .lt-mode-toggle,
body.lt-grid.lt-ready .lt-mode-toggle,
body.lt-grid.home-darkroom-active .lt-mode-toggle,
body.lt-grid.home-darkroom-active.lt-ready .lt-mode-toggle {
  position: fixed !important;
  right: max(18px, env(safe-area-inset-right)) !important;
  bottom: max(18px, env(safe-area-inset-bottom)) !important;
  z-index: 2147483000 !important;
  transform: translateZ(0) !important;
}

/* Large screen project menu: keep enough real scroll room after the list/button
   so the last project row can always reach at least the vertical center. */
body.is-home #projects {
  padding-bottom: max(56vh, 520px) !important;
}
body.is-home #projects .project-list--bottom {
  padding-bottom: 0 !important;
}


/* Project menu end stop: JS calculates the exact bottom padding so the last
   project row can reach the viewport center, but the page cannot scroll much
   past that point on large screens. */
body.is-home #projects {
  padding-bottom: var(--projects-end-pad, 32vh) !important;
}
body.is-home #projects .project-list--bottom {
  padding-bottom: 0 !important;
}


/* Darkroom scribbles: no delayed fade-in */
.lt-scribble-layer,
.lt-floating-scribble-layer {
  transition: none !important;
}

/* Darkroom scribbles: cleaned PNGs, visible immediately during red-light start */
.lt-scribble-layer {
  opacity: 1 !important;
  transition: none !important;
}
.lt-floating-scribble-layer {
  opacity: 0.78 !important;
  transition: none !important;
}

/* Mobile Darkroom menu overlay fix:
   When the menu is open, it must not be part of the darkroom difference-blend layer.
   Otherwise the black fullscreen menu background gets visually cancelled on mobile. */
@media (max-width: 900px) {
  body.nav-menu-open .site-header,
  body.is-darkroom.nav-menu-open .site-header,
  body.page-darkroom.nav-menu-open .site-header,
  body.template-darkroom.nav-menu-open .site-header,
  body.is-dunkelkammer.nav-menu-open .site-header,
  body.page-dunkelkammer.nav-menu-open .site-header,
  body.home-darkroom-active.nav-menu-open .site-header,
  body.lt-from-home.nav-menu-open .site-header {
    z-index: 2147483000 !important;
    mix-blend-mode: normal !important;
    isolation: isolate !important;
    background: transparent !important;
    color: #fff !important;
  }

  body.nav-menu-open .site-header-inner,
  body.nav-menu-open .site-header .logo,
  body.nav-menu-open .site-header .nav-toggle,
  body.nav-menu-open .site-header nav,
  body.nav-menu-open .site-header nav ul,
  body.nav-menu-open .site-header nav a {
    mix-blend-mode: normal !important;
    isolation: isolate !important;
  }

  body.nav-menu-open .site-header nav {
    position: fixed !important;
    inset: 0 !important;
    width: 100vw !important;
    min-height: 100svh !important;
    min-height: 100vh !important;
    background: #000 !important;
    opacity: 1 !important;
    visibility: visible !important;
    transform: translateY(0) !important;
    z-index: 2147482900 !important;
    pointer-events: auto !important;
  }

  body.nav-menu-open .site-header .logo,
  body.nav-menu-open .site-header nav a,
  body.nav-menu-open .site-header .nav-toggle {
    color: #fff !important;
    -webkit-text-fill-color: #fff !important;
    filter: none !important;
    text-shadow: none !important;
  }

  body.nav-menu-open .site-header .nav-toggle span {
    background: #fff !important;
  }
}

/* Desktop-only darkroom reorder help: only appears after a photo was opened and closed. */
@media (hover: hover) and (pointer: fine) {
  .lt-hint-row--open .lt-hint-item--reorder span,
  .lt-hint .lt-hint-item--reorder span {
    max-width: 150px;
    text-align: center;
    white-space: normal;
    line-height: 1.15;
  }
}


/* Scribble darkroom button under the project list */
.home-darkroom-link-wrap {
  padding-top: clamp(16px, 2.8vw, 28px);
  animation: darkroomButtonFloat 4.8s ease-in-out infinite;
  will-change: transform;
}
.home-darkroom-link,
.bg-custom .home-darkroom-link {
  width: clamp(220px, 28vw, 440px);
  aspect-ratio: 760 / 178;
  min-height: 0;
  padding: 0;
  position: relative;
  display: block;
  overflow: visible;
  isolation: isolate;
  border: 0 !important;
  background: transparent url('/assets/img/dunkelkammer-button-new-v9-trans.webp') center center / contain no-repeat !important;
  color: transparent !important;
  font-size: 0;
  line-height: 0;
  box-shadow: none;
  cursor: pointer;
  filter: none;
  opacity: var(--darkroom-button-opacity, 0.985);
  --btn-mx: 50%;
  --btn-my: 50%;
  --btn-displace-x: 0px;
  --btn-displace-y: 0px;
  --btn-hover-strength: 0;
  transition: filter 0.28s ease, opacity 0.28s ease, transform 0.28s ease;
}
.home-darkroom-link::before,
.home-darkroom-link::after,
.bg-custom .home-darkroom-link::before,
.bg-custom .home-darkroom-link::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: transparent url('/assets/img/dunkelkammer-button-new-v9-trans.webp') center center / contain no-repeat;
  opacity: 0;
  will-change: transform, opacity, mask-position;
}
.home-darkroom-link::before,
.bg-custom .home-darkroom-link::before {
  opacity: calc(var(--btn-hover-strength) * 0.55);
  transform: translate3d(var(--btn-displace-x), var(--btn-displace-y), 0) scale(1.012);
  mix-blend-mode: screen;
  filter: none;
  -webkit-mask-image: radial-gradient(circle at var(--btn-mx) var(--btn-my), rgba(0,0,0,1) 0%, rgba(0,0,0,0.98) 16%, rgba(0,0,0,0.72) 31%, rgba(0,0,0,0) 55%);
  mask-image: radial-gradient(circle at var(--btn-mx) var(--btn-my), rgba(0,0,0,1) 0%, rgba(0,0,0,0.98) 16%, rgba(0,0,0,0.72) 31%, rgba(0,0,0,0) 55%);
}
.home-darkroom-link::after,
.bg-custom .home-darkroom-link::after {
  opacity: calc(var(--btn-hover-strength) * 0.32);
  transform: translate3d(calc(var(--btn-displace-x) * -0.5), calc(var(--btn-displace-y) * -0.5), 0) scale(1.005);
  mix-blend-mode: screen;
  filter: none;
  -webkit-mask-image: radial-gradient(circle at var(--btn-mx) var(--btn-my), rgba(0,0,0,0.95) 0%, rgba(0,0,0,0.68) 24%, rgba(0,0,0,0) 48%);
  mask-image: radial-gradient(circle at var(--btn-mx) var(--btn-my), rgba(0,0,0,0.95) 0%, rgba(0,0,0,0.68) 24%, rgba(0,0,0,0) 48%);
}
.home-darkroom-link:hover,
.bg-custom .home-darkroom-link:hover {
  background: transparent url('/assets/img/dunkelkammer-button-new-v9-trans.webp') center center / contain no-repeat !important;
  border: 0 !important;
  color: transparent !important;
  transform: scale(1.014);
  filter: none;
  box-shadow: none;
  opacity: var(--darkroom-button-opacity, 1);
}
@media (max-width: 700px) {
  .home-darkroom-link-wrap {
    padding-top: 10px;
    padding-bottom: 34px;
  }
  .home-darkroom-link,
  .bg-custom .home-darkroom-link {
    width: min(84vw, 340px);
  }
  .home-darkroom-link:hover,
  .bg-custom .home-darkroom-link:hover {
    transform: scale(1.01);
  }
}
@media (hover: none), (pointer: coarse) {
  .home-darkroom-link::before,
  .home-darkroom-link::after,
  .bg-custom .home-darkroom-link::before,
  .bg-custom .home-darkroom-link::after {
    display: none;
  }
}

@keyframes darkroomButtonFloat {
  0% { transform: translateY(-4px); }
  50% { transform: translateY(4px); }
  100% { transform: translateY(-4px); }
}

/* Final smoother Darkroom → Projects return:
   one continuous camera move upward, without a delayed second scroll. */
body.is-home.home-darkroom-leaving #projects {
  animation: none !important;
  transform: perspective(1000px) translateY(0) rotateX(0deg) rotateZ(0deg) translateX(0) !important;
  transform-origin: 50% 12%;
  opacity: 1 !important;
  filter: none !important;
  pointer-events: auto !important;
  transition:
    transform 1.18s cubic-bezier(0.16, 1, 0.3, 1),
    opacity 0.92s ease,
    filter 0.92s ease !important;
  will-change: transform, opacity, filter;
}
body.is-home.home-darkroom-leaving .home-inline-darkroom .lighttable-viewport {
  transform: translateY(112vh) scale(0.992) !important;
  opacity: 1 !important;
  filter: none !important;
  transition:
    transform 1.18s cubic-bezier(0.16, 1, 0.3, 1),
    opacity 0.92s ease !important;
  will-change: transform, opacity;
}
body.is-home.home-darkroom-leaving .hero-scroll {
  opacity: 0 !important;
  filter: blur(10px) !important;
  pointer-events: none !important;
}
body.is-home.home-darkroom-leaving .home-inline-darkroom {
  pointer-events: none !important;
}

/* Final pass: smoother Darkroom → Projects flow.
   The light table fades/feathers out while the project menu travels in from above,
   so the transition reads like one continuous upward camera move. */
@keyframes projectsCameraReturnFromTop {
  0% {
    transform: perspective(1000px) translateY(-48vh) rotateX(8deg) rotateZ(-1.2deg) translateX(-1.2vw);
    opacity: 0;
    filter: blur(12px);
  }
  18% {
    opacity: 0.18;
  }
  100% {
    transform: perspective(1000px) translateY(0) rotateX(0deg) rotateZ(0deg) translateX(0);
    opacity: 1;
    filter: none;
  }
}

body.is-home.home-darkroom-leaving #projects {
  animation: projectsCameraReturnFromTop 1.24s cubic-bezier(0.16, 1, 0.3, 1) forwards !important;
  transform-origin: 50% 0%;
  pointer-events: auto !important;
  will-change: transform, opacity, filter;
}

body.is-home.home-darkroom-leaving .home-inline-darkroom {
  opacity: 0;
  pointer-events: none !important;
  transition: opacity 1.24s cubic-bezier(0.16, 1, 0.3, 1) !important;
  -webkit-mask-image: linear-gradient(to bottom,
    transparent 0%,
    rgba(0,0,0,0.36) 7%,
    #000 22%,
    #000 76%,
    rgba(0,0,0,0.42) 90%,
    transparent 100%);
  mask-image: linear-gradient(to bottom,
    transparent 0%,
    rgba(0,0,0,0.36) 7%,
    #000 22%,
    #000 76%,
    rgba(0,0,0,0.42) 90%,
    transparent 100%);
}

body.is-home.home-darkroom-leaving .home-inline-darkroom .lighttable-viewport {
  transform: translateY(112vh) scale(0.996) !important;
  opacity: 0.72 !important;
  transition:
    transform 1.24s cubic-bezier(0.16, 1, 0.3, 1),
    opacity 1.12s ease !important;
  will-change: transform, opacity;
}

/* Inline Darkroom → Projects nav fix:
   First place Projects above the frame invisibly, then transition it in.
   This prevents the mobile nav path from revealing the list abruptly. */


/* ── Darkroom → Projects: projects slide down from the top (driven in JS) while the
   darkroom WHITE fades out slowly over the top of them. No viewport slide — the user
   wants the white to dissolve, not move. ── */
.cursor.is-darkroom-button {
  width: 150px !important;
  height: 150px !important;
  margin: -75px 0 0 -75px !important;
  border-radius: 50% !important;
  overflow: hidden !important;
  background: #ff1f1f !important;
  border: 0 !important;
  outline: 0 !important;
  box-shadow: none !important;
  mix-blend-mode: difference !important;
}
.cursor.is-darkroom-button .cursor-preview,
.cursor.is-darkroom-button .cursor-circle-frame,
.cursor.is-darkroom-button .cursor-random-icon,
.cursor.is-darkroom-button .cursor-project-number {
  display: none !important;
  opacity: 0 !important;
}


/* Home logo: chromatic colour with slowly wandering patchy blur */
body.is-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx,
body.page-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx,
body.template-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx {
  position: relative;
  display: inline-block;
  isolation: isolate;
  color: #f7edf2 !important;
  -webkit-text-fill-color: #f7edf2 !important;
  text-shadow:
    0 0 1px rgba(255,255,255,0.30),
    0 0 10px rgba(255, 176, 214, 0.18),
    0 0 14px rgba(162, 176, 255, 0.12);
}
body.is-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx::before,
body.is-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx::after,
body.page-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx::before,
body.page-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx::after,
body.template-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx::before,
body.template-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx::after {
  content: attr(data-logo-text);
  position: absolute;
  inset: 0;
  pointer-events: none;
  white-space: nowrap;
  font: inherit;
  letter-spacing: inherit;
  line-height: inherit;
}
body.is-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx::before,
body.page-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx::before,
body.template-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx::before {
  color: rgba(255, 184, 221, 0.92);
  mix-blend-mode: screen;
  opacity: 0.72;
  filter: blur(5.4px);
  transform: translate3d(-0.65px, 0.08px, 0);
  -webkit-mask-image:
    radial-gradient(24% 74% at 9% 48%, rgba(0,0,0,1) 0 44%, rgba(0,0,0,0.78) 58%, rgba(0,0,0,0) 76%),
    radial-gradient(24% 58% at 36% 62%, rgba(0,0,0,0.95) 0 42%, rgba(0,0,0,0) 69%),
    radial-gradient(18% 54% at 59% 40%, rgba(0,0,0,0.92) 0 42%, rgba(0,0,0,0) 68%),
    radial-gradient(22% 58% at 90% 52%, rgba(0,0,0,0.95) 0 44%, rgba(0,0,0,0) 70%);
  mask-image:
    radial-gradient(24% 74% at 9% 48%, rgba(0,0,0,1) 0 44%, rgba(0,0,0,0.78) 58%, rgba(0,0,0,0) 76%),
    radial-gradient(24% 58% at 36% 62%, rgba(0,0,0,0.95) 0 42%, rgba(0,0,0,0) 69%),
    radial-gradient(18% 54% at 59% 40%, rgba(0,0,0,0.92) 0 42%, rgba(0,0,0,0) 68%),
    radial-gradient(22% 58% at 90% 52%, rgba(0,0,0,0.95) 0 44%, rgba(0,0,0,0) 70%);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  animation: homeLogoBlurDriftA 16s ease-in-out infinite alternate;
}
body.is-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx::after,
body.page-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx::after,
body.template-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx::after {
  color: rgba(185, 192, 255, 0.90);
  mix-blend-mode: screen;
  opacity: 0.64;
  filter: blur(6.2px);
  transform: translate3d(0.78px, -0.02px, 0);
  -webkit-mask-image:
    radial-gradient(20% 56% at 16% 32%, rgba(0,0,0,0.92) 0 40%, rgba(0,0,0,0) 66%),
    radial-gradient(22% 52% at 46% 40%, rgba(0,0,0,0.90) 0 40%, rgba(0,0,0,0) 66%),
    radial-gradient(26% 62% at 76% 56%, rgba(0,0,0,0.98) 0 46%, rgba(0,0,0,0) 72%),
    radial-gradient(18% 54% at 96% 50%, rgba(0,0,0,0.98) 0 42%, rgba(0,0,0,0) 68%);
  mask-image:
    radial-gradient(20% 56% at 16% 32%, rgba(0,0,0,0.92) 0 40%, rgba(0,0,0,0) 66%),
    radial-gradient(22% 52% at 46% 40%, rgba(0,0,0,0.90) 0 40%, rgba(0,0,0,0) 66%),
    radial-gradient(26% 62% at 76% 56%, rgba(0,0,0,0.98) 0 46%, rgba(0,0,0,0) 72%),
    radial-gradient(18% 54% at 96% 50%, rgba(0,0,0,0.98) 0 42%, rgba(0,0,0,0) 68%);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  animation: homeLogoBlurDriftB 19s ease-in-out infinite alternate;
}
@keyframes homeLogoBlurDriftA {
  0% {
    transform: translate3d(-0.8px, 0.05px, 0);
    -webkit-mask-position: 0% 0%, 0% 0%, 0% 0%, 0% 0%;
    mask-position: 0% 0%, 0% 0%, 0% 0%, 0% 0%;
  }
  25% {
    transform: translate3d(-0.32px, -0.12px, 0);
    -webkit-mask-position: 2% -3%, 5% 2%, -2% 4%, 1% -1%;
    mask-position: 2% -3%, 5% 2%, -2% 4%, 1% -1%;
  }
  50% {
    transform: translate3d(0.12px, 0.14px, 0);
    -webkit-mask-position: 4% -2%, -2% 4%, 3% -2%, -2% 3%;
    mask-position: 4% -2%, -2% 4%, 3% -2%, -2% 3%;
  }
  75% {
    transform: translate3d(-0.08px, 0.26px, 0);
    -webkit-mask-position: -3% 3%, 2% -1%, -1% 3%, 4% -2%;
    mask-position: -3% 3%, 2% -1%, -1% 3%, 4% -2%;
  }
  100% {
    transform: translate3d(-0.62px, -0.06px, 0);
    -webkit-mask-position: 1% 4%, -4% 1%, 4% -3%, -2% 2%;
    mask-position: 1% 4%, -4% 1%, 4% -3%, -2% 2%;
  }
}
@keyframes homeLogoBlurDriftB {
  0% {
    transform: translate3d(0.78px, 0px, 0);
    -webkit-mask-position: 0% 0%, 0% 0%, 0% 0%, 0% 0%;
    mask-position: 0% 0%, 0% 0%, 0% 0%, 0% 0%;
  }
  22% {
    transform: translate3d(0.28px, -0.2px, 0);
    -webkit-mask-position: -2% 3%, 2% -2%, -1% 4%, 2% 0%;
    mask-position: -2% 3%, 2% -2%, -1% 4%, 2% 0%;
  }
  48% {
    transform: translate3d(-0.08px, 0.16px, 0);
    -webkit-mask-position: 2% 4%, -2% 1%, 4% -2%, -1% 2%;
    mask-position: 2% 4%, -2% 1%, 4% -2%, -1% 2%;
  }
  74% {
    transform: translate3d(0.22px, 0.06px, 0);
    -webkit-mask-position: 4% -2%, -3% 3%, 2% 2%, -3% 1%;
    mask-position: 4% -2%, -3% 3%, 2% 2%, -3% 1%;
  }
  100% {
    transform: translate3d(-0.3px, -0.1px, 0);
    -webkit-mask-position: -2% 3%, 3% -1%, -4% 2%, 2% -3%;
    mask-position: -2% 3%, 3% -1%, -4% 2%, 2% -3%;
  }
}


/* Home header logo: plain "Vincent Johnson" wordmark in Moret —
   no glow image, no chromatic noise effect. Darkroom button untouched. */
body.is-home:not(.home-darkroom-active) .site-header .logo,
body.page-home:not(.home-darkroom-active) .site-header .logo,
body.template-home:not(.home-darkroom-active) .site-header .logo,
body.is-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx,
body.page-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx,
body.template-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx {
  display: inline-block;
  width: auto;
  aspect-ratio: auto;
  background: none !important;
  color: #fff !important;
  -webkit-text-fill-color: #fff !important;
  text-indent: 0 !important;
  overflow: visible;
  white-space: nowrap;
  text-shadow: none !important;
}
/* kill the chromatic colour-fringe layers on home */
body.is-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx::before,
body.is-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx::after,
body.page-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx::before,
body.page-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx::after,
body.template-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx::before,
body.template-home:not(.home-darkroom-active) .site-header .logo.logo-noisefx::after {
  display: none !important;
  content: none !important;
}


/* ─────────────────────────────────────────────────────────────
   PASSWORD GATE (protected projects)
   Markup: main.project-password-gate > .project-password-box >
           .project-password-lock / h1 / p / form(input+button) / .project-password-error
   Previously unstyled (top-left, partly under the fixed header → not clickable).
   Now a centered card that sits above the page, below the header so the nav stays usable.
   ───────────────────────────────────────────────────────────── */
.project-password-gate {
  position: fixed;
  top: var(--nav-h);
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  overflow: auto;
  background: rgba(255, 255, 255, 0.9);
  -webkit-backdrop-filter: blur(10px) saturate(1.1);
  backdrop-filter: blur(10px) saturate(1.1);
  cursor: auto;
}
.project-password-box {
  width: min(440px, 100%);
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 14px;
  padding: 42px 36px 34px;
  background: #fff;
  border: 1px solid rgba(0, 0, 0, 0.1);
  border-radius: 18px;
  box-shadow: 0 30px 90px rgba(0, 0, 0, 0.2);
}
.project-password-lock {
  font-size: 34px;
  line-height: 1;
  margin-bottom: 2px;
}
.project-password-box h1 {
  font-family: var(--serif);
  font-size: clamp(28px, 5vw, 40px);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: 0;
  margin: 0;
  color: #111;
}
.project-password-box p {
  margin: 0;
  font-size: 15px;
  line-height: 1.45;
  color: #555;
}
.project-password-box form {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  width: 100%;
  margin-top: 12px;
}
.project-password-box input[type="password"] {
  flex: 1 1 160px;
  min-width: 0;
  padding: 14px 16px;
  font-size: 16px;            /* 16px avoids iOS zoom-on-focus */
  font-family: inherit;
  color: #111;
  background: #f4f4f2;
  border: 1px solid rgba(0, 0, 0, 0.14);
  border-radius: 11px;
  outline: none;
  cursor: text;
  transition: border-color 0.2s, background 0.2s;
}
.project-password-box input[type="password"]::placeholder { color: #9a9a96; }
.project-password-box input[type="password"]:focus {
  border-color: #111;
  background: #fff;
}
.project-password-box button[type="submit"] {
  flex: 0 0 auto;
  padding: 14px 24px;
  font-size: 15px;
  font-family: inherit;
  font-weight: 600;
  color: #fff;
  background: #111;
  border: 0;
  border-radius: 11px;
  cursor: pointer;
  transition: background 0.2s, transform 0.08s;
}
.project-password-box button[type="submit"]:hover { background: #333; }
.project-password-box button[type="submit"]:active { transform: scale(0.97); }
.project-password-error {
  margin: 2px 0 0 !important;
  color: #c0392b !important;
  font-size: 14px !important;
  font-weight: 500;
}

/* On a password page, swap the big difference-blend custom cursor for the native one
   so the field shows a normal text caret and is obviously clickable. */
body:has(.project-password-gate) { cursor: auto; }
body:has(.project-password-gate) .cursor { display: none !important; }

@media (max-width: 600px) {
  .project-password-box { padding: 34px 24px 28px; border-radius: 16px; }
}


/* Over a *playing* embedded video show the normal/native cursor (the custom cursor is
   hidden there in JS — it can't follow inside an <iframe>). Scoped to the real media
   element only; the click-to-play poster (a button) keeps the custom cursor. */
iframe,
video,
embed,
object {
  cursor: auto !important;
}


/* ───── Click-to-play video poster (facade) ─────
   Fills the video box; same document so the custom cursor shows over it. */
.vj-video-facade {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #111;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  cursor: none;               /* keep the custom cursor over the poster */
  overflow: hidden;
}
.vj-video-facade::after {     /* slight darken so the play button reads on any thumbnail */
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.18);
  transition: background 0.3s ease;
}
.vj-video-facade:hover::after { background: rgba(0, 0, 0, 0.04); }
.vj-video-play {
  position: relative;
  z-index: 1;
  display: block;
  transform: scale(1);
  transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
  filter: drop-shadow(0 6px 22px rgba(0, 0, 0, 0.45));
}
.vj-video-facade:hover .vj-video-play { transform: scale(1.09); }
@media (pointer: coarse) {
  .vj-video-facade { cursor: pointer; }     /* touch: normal tap affordance */
}


/* ───── "Labor" link → Darkroom Lab OS (only inside the active darkroom) ───── */
.lt-os-link {
  position: fixed;
  bottom: 24px;
  left: 24px;
  z-index: 62;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 18px 9px 14px;
  background: rgba(255, 255, 255, 0.85);
  border: 1px solid rgba(0, 0, 0, 0.2);
  border-radius: 100px;
  font-family: var(--sans);
  font-size: 14px;
  letter-spacing: 0.02em;
  color: #000;
  text-decoration: none;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 1s ease 0.6s, transform 0.2s ease, background 0.2s ease;
}
body.lt-ready .lt-os-link {
  opacity: 1;
  pointer-events: auto;
}
.lt-os-link:hover {
  background: rgba(255, 255, 255, 0.97);
  transform: translateY(-1px);
}
.lt-os-link svg { display: block; }
.lt-os-link span { line-height: 1; }
@media (max-width: 600px) {
  .lt-os-link { bottom: 18px; left: 16px; padding: 8px 15px 8px 12px; font-size: 13px; }
}


/* ───── Freie Text-Blöcke (frei-anordnen): Ausrichtung / Größe / Stärke ───── */
.text-block { line-height: 1.55; }
/* Absätze (Enter im Editor = neuer <p>) brauchen Abstand – der globale Reset nimmt ihn sonst */
.text-block p { margin: 0 0 1em; }
.text-block p:last-child { margin-bottom: 0; }
.text-block.ta-left   { text-align: left; }
.text-block.ta-center { text-align: center; }
.text-block.ta-right  { text-align: right; }
.text-block.fs-klein  { font-size: 0.85em; }
.text-block.fs-normal { font-size: 1em; }
.text-block.fs-gross  { font-size: 1.35em; }
.text-block.fs-xl     { font-size: 1.85em; line-height: 1.15; }
.text-block.fw-leicht { font-weight: 300; }
.text-block.fw-normal { font-weight: 400; }
.text-block.fw-fett   { font-weight: 700; }
/* Writer-Inhalt: Links klar als Links, Überschriften/Listen sauber */
.text-block a { text-decoration: underline; text-underline-offset: 2px; }
.text-block h2, .text-block h3 { line-height: 1.1; margin: 0.4em 0 0.2em; }
.text-block ul, .text-block ol { padding-left: 1.3em; }
.text-block blockquote { margin: 0.6em 0; padding-left: 0.9em; border-left: 2px solid currentColor; opacity: 0.85; }


/* ───── DARKROOM: Prints entwickeln sich beim ersten Sichtbarwerden ─────
   Reihenfolge wichtig: contrast() ZUERST (kollabiert zu Grau), dann brightness()
   hebt auf Fast-Weiß = unbelichtetes Papier. Durch mix-blend multiply ist das
   auf dem weißen Tisch nahezu unsichtbar → das Bild "taucht auf" wie im
   Entwicklerbad. Läuft pro Foto genau einmal. */
@keyframes lt-emerge {
  0%   { filter: contrast(0.05) brightness(1.95) sepia(0.3); }
  45%  { filter: contrast(0.42) brightness(1.38) sepia(0.35); }
  100% { filter: contrast(1) brightness(1) sepia(0); }
}
.lt-photo.lt-undeveloped {
  filter: contrast(0.05) brightness(1.95) sepia(0.3);
}
.lt-photo.lt-emerging {
  animation: lt-emerge 2.6s cubic-bezier(0.33, 0, 0.18, 1) both;
  animation-delay: var(--dev-delay, 0s);
}
@media (prefers-reduced-motion: reduce) {
  .lt-photo.lt-undeveloped { filter: none; }
  .lt-photo.lt-emerging { animation: none; filter: none; }
}


/* ───── VIEW TRANSITIONS: weiche Übergänge zwischen Seiten ─────
   Progressive enhancement: Chrome/Edge/Safari blenden Seiten weich ineinander.
   (Der frühere Titel-Morph auf Projektseiten wurde entfernt.)
   Browser ohne Support ignorieren das komplett. */
@view-transition { navigation: auto; }
::view-transition-old(root),
::view-transition-new(root) { animation-duration: 0.5s; }
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}


/* ───── FOTO-RÜCKSEITEN (Doppeltipp auf entwickelte Prints) ─────
   Der Flip läuft über --flipx im bestehenden .lt-photo-Transform und reitet
   auf dessen 0.28s-Transition. Beim Nulldurchgang (~0.14s) tauschen die
   Seiten. Die Rückseite ist scaleX(-1) vorgespiegelt, damit sie im
   gespiegelten Zustand richtig herum lesbar ist. */
.lt-photo .lt-back {
  position: absolute;
  inset: 0;
  z-index: 6;
  background: #f6f3ec;
  box-shadow: inset 0 0 48px rgba(0, 0, 0, 0.07);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 8%;
  text-align: center;
  opacity: 0;
  pointer-events: none;
  transform: scaleX(-1);
  transition: opacity 0s linear 0.14s;
}
.lt-photo.lt-flipped {
  --flipx: -1;
  mix-blend-mode: normal; /* multiply würde die weiße Rückseite auf dem weißen Tisch unsichtbar machen */
}
.lt-photo.lt-flipped .lt-back { opacity: 1; }
.lt-photo.lt-flipped .lt-base,
.lt-photo.lt-flipped .lt-neg,
.lt-photo.lt-flipped .lt-scribble-layer {
  opacity: 0;
  transition: opacity 0s linear 0.14s;
}
.lt-back-stamp {
  font-family: var(--sans);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(64, 54, 148, 0.62);
  border: 1.5px solid rgba(64, 54, 148, 0.5);
  border-radius: 3px;
  padding: 5px 10px;
  transform: rotate(-5deg);
  margin-bottom: 4px;
}
.lt-back-line {
  font-family: 'Courier New', ui-monospace, monospace;
  font-size: 11px;
  line-height: 1.35;
  color: #45413a;
}
.lt-back-line b {
  display: block;
  font-weight: 400;
  font-size: 8.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #9a938a;
}
.lt-back-note {
  font-family: var(--serif);
  font-style: italic;
  font-size: 12px;
  color: #6d675e;
  margin-top: 4px;
  transform: rotate(-1.5deg);
}
body.lt-grid .lt-photo .lt-back { display: none !important; }

/* ───── RE-SHUFFLE (Schütteln): Prints animiert neu über den Tisch werfen ───── */
body.lt-reshuffling .lt-photo {
  transition:
    left 0.9s cubic-bezier(0.22, 1, 0.36, 1),
    top 0.9s cubic-bezier(0.22, 1, 0.36, 1),
    transform 0.9s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.55s ease,
    box-shadow 0.28s cubic-bezier(0.16, 1, 0.3, 1),
    filter 0.28s cubic-bezier(0.16, 1, 0.3, 1);
}
@media (prefers-reduced-motion: reduce) {
  body.lt-reshuffling .lt-photo { transition: none; }
}


/* ───── TITEL-PHYSIK: Projekttitel zerfallen in Wörter mit echter Physik ─────
   Klick auf einen Projekttitel → die Wörter fallen, titschen an den Rändern,
   die Projektseite blendet ein und der Titel liegt bespielbar unten
   (Scrollen schubst ihn hoch). Zurück auf Home fliegen die Wörter an ihren
   Platz in der Liste. Logik: Block "TITEL-PHYSIK" in site.js. */
.vj-word {
  /* Jedes Wort ist ein eigenes fixes Element mit eigenem Difference-Blend:
     der Browser verrechnet nur wortgroße Rechtecke statt (wie vorher über
     eine viewportgroße Ebene) den kompletten Bildschirm pro Frame. */
  position: fixed;
  left: 0;
  top: 0;
  z-index: 45;               /* unter dem Header (50), über dem Inhalt */
  mix-blend-mode: difference;
  white-space: nowrap;
  font-family: var(--serif);
  font-weight: 400;
  line-height: 1;
  /* will-change setzt das JS nur, solange die Wörter fliegen — ruhende
     Wörter belegen so keine Compositing-Layer */
  pointer-events: auto;      /* anschubsbar */
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
}
/* echter Seitentitel bleibt für Screenreader & Google — aber ohne Platz zu
   beanspruchen (kein leerer Riesen-Block dort, wo der h1 stand; der Titel
   liegt ja als Haufen unten). position:absolute nimmt ihn aus dem Layout. */
.vj-title-hidden {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  overflow: hidden !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
  opacity: 0 !important;
}

/* ───── Footer als Filmrand-Beschriftung (Edge Print) ─────
   Impressum & Datenschutz dürfen rechtlich nicht versteckt werden
   (Impressumspflicht: leicht erkennbar, unmittelbar erreichbar, von jeder
   Seite). Also wird der Footer stattdessen Teil der Bildsprache: die kleine
   Randbeschriftung eines Filmstreifens — Versalien, gesperrt, leise,
   beim Hover voll da. Lesbar und klickbar bleibt alles. */
.site-footer {
  border-top: none;
  padding: 36px 0 26px;
  font-size: 10px;
  font-weight: 400;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.36);   /* wie Kantenschrift auf S/W-Negativ */
}
.site-footer span::before,
.site-footer a::after {
  content: '\25B8';                    /* ▸ Rahmen-Marke wie auf dem Filmrand */
  opacity: 0.55;
  font-size: 8px;
  vertical-align: 1px;
}
.site-footer span::before { margin-right: 10px; }
.site-footer a::after { margin-left: 10px; }
.site-footer a {
  color: inherit;
  text-decoration: none;
  transition: color 0.25s ease;
}
.site-footer a:hover,
.site-footer a:focus-visible {
  color: rgba(255, 255, 255, 0.92);
}
/* helle Projektseiten: gleiche Randnotiz, dunkel */
body.bg-custom .site-footer { color: rgba(0, 0, 0, 0.4); }
body.bg-custom .site-footer a:hover,
body.bg-custom .site-footer a:focus-visible { color: rgba(0, 0, 0, 0.85); }

/* Filmrand-Footer auf schmalen Screens: untereinander statt gequetscht */
@media (max-width: 640px) {
  .site-footer { padding: 30px 0 24px; letter-spacing: 0.18em; }
  .site-footer-inner {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }
}

/* ───── POSTER-LAYOUT ─────
   Plakat-Look: NUR auf Projekten mit aktiviertem Panel-Toggle (🟥) —
   die Klasse kommt über main[data-poster] aus dem Template. Farbige Seiten
   OHNE Toggle bleiben komplett unangetastet. Die Gründe schmiegen sich per
   box-decoration-break an jede Zeile (JS legt .pl-snug-Spans um die Texte). */

body.layout-poster .description {
  background: none;
  max-width: none;
  text-align: left;
  margin: 9vh 0 11vh 8vw;
}
body.layout-poster .description p,
body.layout-poster .blocks p {
  max-width: min(66ch, 80vw);
  font-size: clamp(14px, 1.25vw, 17px);
  line-height: 1.62;                 /* Luft, damit die Zeilen-Kästen sauber stehen */
  text-align: left;
  margin: 0 0 18px;
}
body.layout-poster .blocks { text-align: left; }

/* das eng anliegende Rechteck — Zeile für Zeile */
body.layout-poster .pl-snug {
  background: #eceae4;
  color: #111;
  padding: 0.13em 0.42em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
body.layout-poster .pl-snug a { color: inherit; }

body.layout-poster .video-heading {
  font-family: var(--sans);
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(20px, 3vw, 40px);
  line-height: 1.34;
  letter-spacing: 0.01em;
  max-width: min(24ch, 84vw);
  margin: 12vh 0 26px 5vw;
  text-align: left;
}

/* Projektmenü unten: Titel & Kategorie auf eigenen engen weißen Kästchen */
body.layout-poster .project-row .p-name,
body.layout-poster .project-row .p-category {
  background: #eceae4;
  color: #111;
  padding: 0.1em 0.42em;
}

/* Logo & Menü oben: Hover-Farbwechsel aus — auf der Farbfläche würden sie
   sonst verschwinden. Farbe bleibt einfach stehen. */
body.layout-poster .site-header .logo:hover,
body.layout-poster .site-header nav a:hover,
body.layout-poster .site-header nav a:focus-visible,
body.layout-poster .site-header nav a.is-active {
  color: inherit !important;
}

/* Physik-Wörter: schwarze Plakatschrift auf eigenem engen weißen Kästchen */
body.layout-poster .vj-word {
  mix-blend-mode: normal !important;
  color: #111 !important;
  background: #eceae4;
  padding: 0.08em 0.32em;
}

/* ───── DUNKELKAMMER-EINTRITT: Iris-Blende statt Hochfahren ─────
   Der Leuchttisch öffnet sich als Kreis-Maske aus der Mitte des geklickten
   Knopfs (Ursprung setzt das JS als --dkx/--dky). In der wachsenden Maske
   flackern die Bilder auf wie eine zündende Rotlicht-Röhre. Beim Verlassen
   schließt sich die Iris zurück in den Knopf — gleiche Mechanik, rückwärts. */

/* ───── COMPOSITING-FIX: Blend-Isolation während der Iris ─────
   Die Prints blenden per mix-blend-mode:multiply. Während der clip-path-
   Animation kann Chromes Compositor die Blend-Isolation frameweise verlieren —
   die Prints verrechnen sich dann kurz mit der SEITE dahinter statt mit dem
   Leuchttisch: sichtbar als Blitzen, in dem das Projektmenü durchscheint.
   isolation:isolate + eigene Kompositions-Ebene binden die Verrechnung fest
   an den Leuchttisch. Kein visueller Unterschied, nur stabil. */
.home-inline-darkroom {
  isolation: isolate;
}
.home-inline-darkroom .lighttable-viewport {
  isolation: isolate;
  transform: translateZ(0);
}
body.is-home.home-darkroom-active.lt-entered .home-inline-darkroom .lighttable-viewport {
  transform: translateZ(0);
}

/* ───── IRIS-FENSTER: Header-Difference pausiert während der Maske läuft ─────
   Der Header invertiert im Dunkelkammer-Zustand per mix-blend-mode:difference
   (erzwungen, s.o.). Über der ANIMIERTEN Kreismaske re-compositet das jeden
   Frame gegen die wandernde Kante → Stroboskop, in dem das Projektmenü
   aufblitzt. Während body.vj-iris-anim gesetzt ist (Öffnen/Schließen der
   Iris, ~1,7s), blendet der Header normal und das Logo steht ruhig dunkel;
   danach übernimmt wieder die Difference-Invertierung. */
body.vj-iris-anim.home-darkroom-active .site-header,
body.vj-iris-anim.lt-from-home .site-header,
body.vj-iris-anim.home-darkroom-active .site-header-inner,
body.vj-iris-anim.lt-from-home .site-header-inner {
  mix-blend-mode: normal !important;
  isolation: isolate !important;
}
body.vj-iris-anim.home-darkroom-active .site-header .logo,
body.vj-iris-anim.lt-from-home .site-header .logo {
  mix-blend-mode: normal !important;
  color: #111 !important;
  -webkit-text-fill-color: #111 !important;
}

/* Iris-Ausgang: während die Maske schließt, ist das Innere eingefroren —
   keine Zoom-/Pan-/Foto-Transition darf als Kamerabewegung durchscheinen */
body.home-darkroom-leaving .home-inline-darkroom .lighttable-surface,
body.home-darkroom-leaving .home-inline-darkroom .lt-photo {
  transition: none !important;
  animation: none !important;
}
