/* ==========================================================================
   CoVince new home - cinema.css  (owner: agent 3, media curator + cinematic look)
   Reusable cinematic utilities. Every class is opt-in; nothing here styles an
   element by tag. Performance: the heavy grade is baked into the derived stills
   and loops in media/ (ffmpeg), so .nh-grade is a LIGHT touch meant for raw
   originals only - never put a CSS filter on a large layer that moves.

   Classes  (.nh-award = award laurel, never inverted)
     .nh-grade          light film grade for an ungraded <img>/<video> (static layers)
     .nh-grade--none    turn the grade off (derived media in media/ is pre-graded)
     .nh-grain          animated film grain overlay (::after), reduced-motion = still
     .nh-vignette       soft edge darkening (::before)
     .nh-letterbox      2.39:1 bars that close in while .is-letterboxed is set
     .nh-kenburns       slow push-in on the child media (transform only)
     .nh-reveal         clip-path reveal when .is-in is added (ctx.onVisible)
     .nh-reveal--up / --left / --circle   reveal variants
     .nh-media          positioned media frame: child img/video covers, uses --focal
     .nh-ring-mask      circular mask for concentric ring tiles
     .nh-logo           monochrome client / award logo, dark + light theme
     .nh-duotone        duotone wash for a still (teal shadows, warm highlights)
   ========================================================================== */

:root {
  /* grade - kept subtle; the derived files already carry the main grade */
  --nh-grade-filter: contrast(1.06) saturate(0.92) brightness(0.98);
  --nh-grain-opacity: 0.07;
  --nh-vignette-strength: 0.55;
  --nh-letterbox-bar: 12.5%;          /* 16:9 -> ~2.39:1 */
  --nh-kenburns-duration: 18s;
  --nh-kenburns-scale: 1.08;
  --nh-reveal-duration: 1.1s;
  --nh-ease-film: cubic-bezier(0.22, 0.61, 0.21, 1);
  --nh-duo-dark: #0b2a33;             /* teal shadow */
  --nh-duo-light: #f1d9b8;            /* warm highlight */
  --nh-logo-dark: rgba(255, 255, 255, 0.78);  /* logo on dark */
  --nh-logo-light: rgba(15, 20, 25, 0.72);    /* logo on light */
}

/* ---------- grade ---------- */
.nh-grade { filter: var(--nh-grade-filter); }
.nh-grade--none, .nh-grade.nh-grade--none { filter: none; }

/* ---------- positioned media frame (focal point aware) ---------- */
.nh-media { position: relative; overflow: hidden; background: #0a0d10; isolation: isolate; }
.nh-media > img,
.nh-media > video,
.nh-media > picture > img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: var(--focal, 50% 50%);
  display: block;
}

/* ---------- vignette ---------- */
.nh-vignette { position: relative; isolation: isolate; }
.nh-vignette::before {
  content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: radial-gradient(ellipse 75% 70% at 50% 50%,
              transparent 55%, rgba(0, 0, 0, var(--nh-vignette-strength)) 100%);
}

/* ---------- film grain (one small tile, stepped transform, no repaint of the media) ---------- */
.nh-grain { position: relative; isolation: isolate; }
.nh-grain::after {
  content: ""; position: absolute; inset: -10%; z-index: 3;  /* small overscan: 1.44x area, not 4x */ pointer-events: none;
  opacity: var(--nh-grain-opacity);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.5 0 0 0 0 0.5 0 0 0 0 0.5 0 0 0 1.6 -0.35'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 160px 160px;
  mix-blend-mode: overlay;
  animation: nh-grain 0.9s steps(6) infinite;
  will-change: transform;
}
@keyframes nh-grain {
  0%   { transform: translate(0, 0); }
  17%  { transform: translate(-5%, 3%); }
  33%  { transform: translate(4%, -6%); }
  50%  { transform: translate(-2%, 6%); }
  67%  { transform: translate(6%, 2%); }
  83%  { transform: translate(-6%, -3%); }
  100% { transform: translate(0, 0); }
}
/* still grain for the many small tiles; animate only the big hero-size layer.
   A section can also switch it off: [data-motion="off"] .nh-grain::after */
.nh-grain--still::after, [data-motion="off"] .nh-grain::after { animation: none; }

/* ---------- letterbox (bars slide in when .is-letterboxed) ---------- */
.nh-letterbox { position: relative; isolation: isolate; --_bar: 0%; }
.nh-letterbox.is-letterboxed { --_bar: var(--nh-letterbox-bar); }
.nh-letterbox::after {
  content: ""; position: absolute; inset: 0; z-index: 4; pointer-events: none;
  background:
    linear-gradient(#000, #000) top / 100% var(--_bar) no-repeat,
    linear-gradient(#000, #000) bottom / 100% var(--_bar) no-repeat;
  transition: background-size 1.2s var(--nh-ease-film);
}
/* registered property lets the bars animate; browsers without @property just snap */
@property --_bar { syntax: "<percentage>"; inherits: true; initial-value: 0%; }
.nh-letterbox { transition: --_bar 1.2s var(--nh-ease-film); }

/* ---------- Ken Burns (transform only; set .is-playing, or it runs by default) ---------- */
.nh-kenburns { overflow: hidden; }
.nh-kenburns > img,
.nh-kenburns > video,
.nh-kenburns > picture > img {
  transform-origin: var(--focal, 50% 50%);
  animation: nh-kenburns var(--nh-kenburns-duration) var(--nh-ease-film) infinite alternate both;
  will-change: transform;
}
.nh-kenburns.is-paused > img,
.nh-kenburns.is-paused > video,
.nh-kenburns.is-paused > picture > img { animation-play-state: paused; }
@keyframes nh-kenburns {
  from { transform: scale(1); }
  to   { transform: scale(var(--nh-kenburns-scale)) translate3d(-1%, -1%, 0); }
}

/* ---------- reveal on enter (add .is-in via ctx.onVisible) ---------- */
.nh-reveal {
  clip-path: inset(12% 8% 12% 8% round 24px);
  opacity: 0.001;
  transform: scale(1.04);
  transition: clip-path var(--nh-reveal-duration) var(--nh-ease-film),
              opacity calc(var(--nh-reveal-duration) * 0.6) ease-out,
              transform var(--nh-reveal-duration) var(--nh-ease-film);
}
.nh-reveal--up     { clip-path: inset(100% 0 0 0); transform: translateY(24px); }
.nh-reveal--left   { clip-path: inset(0 100% 0 0); transform: none; }
.nh-reveal--circle { clip-path: circle(0% at var(--focal, 50% 50%)); transform: none; }
.nh-reveal.is-in {
  clip-path: inset(0 0 0 0 round 0);
  opacity: 1; transform: none;
}
.nh-reveal--circle.is-in { clip-path: circle(75% at var(--focal, 50% 50%)); }
/* no-JS: never leave content hidden */
html:not(.js) .nh-reveal { clip-path: none; opacity: 1; transform: none; }

/* ---------- concentric ring tile mask ---------- */
.nh-ring-mask { border-radius: 50%; overflow: hidden; -webkit-mask-image: radial-gradient(circle, #000 68%, transparent 71%); mask-image: radial-gradient(circle, #000 68%, transparent 71%); }

/* ---------- duotone wash (static stills only) ---------- */
.nh-duotone { position: relative; isolation: isolate; background: var(--nh-duo-dark); }
.nh-duotone > img { filter: grayscale(1) contrast(1.1); mix-blend-mode: luminosity; }
.nh-duotone::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(135deg, var(--nh-duo-dark), var(--nh-duo-light));
  mix-blend-mode: color; opacity: 0.55;
}

/* ---------- monochrome logo (client + award) ----------
   .nh-logo turns ANY logo into one flat colour: white on dark, ink on light. It works on the
   pre-flattened media/logos/*.png (white on transparent, interior detail kept as holes - prefer
   these, see manifest sets.proofClients) AND on a raw /www/english/images original (black or white
   on transparent) - the raw one just loses interior detail (the KNVB lion) to a silhouette.
   Award laurels (AwardCoVince*.png, or class .nh-award) are grey with white lettering: never
   flattened, only darkened a little on the light theme so the lettering stays readable. */
.nh-logo {
  display: block; max-width: 100%; height: auto; object-fit: contain;
  filter: brightness(0) invert(1);
  opacity: 0.8;
  transition: opacity 0.3s ease;
}
.nh-logo:hover, a:focus-visible > .nh-logo { opacity: 1; }
.nh-logo--raw { filter: brightness(0) invert(1); }  /* kept for callers; same as .nh-logo now */
.nh-award, .nh-logo.nh-award, .nh-logo[src*="AwardCoVince"] { filter: none; opacity: 0.9; }
.nh-award { display: block; max-width: 100%; height: auto; object-fit: contain; }

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .nh-logo { filter: brightness(0); opacity: 0.75; }
  :root:not([data-theme="dark"]) .nh-award,
  :root:not([data-theme="dark"]) .nh-logo.nh-award,
  :root:not([data-theme="dark"]) .nh-logo[src*="AwardCoVince"] { filter: brightness(0.62) contrast(1.15); opacity: 1; }
  :root:not([data-theme="dark"]) { --nh-grain-opacity: 0.04; --nh-vignette-strength: 0.3; }
}
:root[data-theme="light"] .nh-logo { filter: brightness(0); opacity: 0.75; }
:root[data-theme="light"] .nh-award,
:root[data-theme="light"] .nh-logo.nh-award,
:root[data-theme="light"] .nh-logo[src*="AwardCoVince"] { filter: brightness(0.62) contrast(1.15); opacity: 1; }
:root[data-theme="light"] { --nh-grain-opacity: 0.04; --nh-vignette-strength: 0.3; }

/* ---------- reduced motion: motion becomes stillness / fades ---------- */
@media (prefers-reduced-motion: reduce) {
  .nh-grain::after { animation: none; }
  .nh-kenburns > img, .nh-kenburns > video, .nh-kenburns > picture > img { animation: none; transform: none; }
  .nh-reveal, .nh-reveal--up, .nh-reveal--left, .nh-reveal--circle {
    clip-path: none; transform: none;
    transition: opacity 0.6s ease-out;
  }
  .nh-letterbox, .nh-letterbox::after { transition: none; }
}
