/* ============================================================
   KAUR VIRSA — design tokens
   Single source of truth. Mirrored in ../theme.json for the
   future WordPress block theme — change both together.
   ============================================================ */
:root{
  color-scheme: light;

  /* ── colour ────────────────────────────────────────────── */
  --kv-white:      #FFFFFF;   /* light surface                 */
  --kv-off:        #F4F4F2;   /* inset panels, image backdrop  */
  --kv-ink:        #101010;   /* dark surface + text on light  */
  --kv-ink-soft:   #6B655F;   /* secondary text on light       */
  --kv-line:       #E2E0DC;   /* hairline on light             */

  --kv-on-dark:      #FFFFFF; /* text on dark surface          */
  --kv-on-dark-soft: #ABA49C; /* secondary text on dark        */
  --kv-line-dark:    rgba(255,255,255,.16);

  --kv-accent:     #F7A115;   /* accent on DARK (9.3:1) + fills */

  --kv-wa-green:    #25D366;  /* WhatsApp brand green — CTA only     */
  --kv-wa-green-dk: #128C7E;  /* its hover/pressed state             */

  /* how much of the hero background film shows through, 0–1.
     One value, one place — this is the dial to turn. */
  --kv-hero-video: .22;

  /* Note: #F7A115 is 9.1:1 on the dark surface but only 2.1:1 on white.
     Client direction is to use it on both, so highlights on the light
     section fall below WCAG AA — accepted, the brand accent takes priority. */

  /* ── type ──────────────────────────────────────────────── */
  --kv-display: "Bricolage Grotesque", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --kv-body:    "Instrument Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  --kv-fs-hero:   clamp(3.25rem, 11vw, 11.5rem);
  /* capped by height as well as width so the section always holds one fold */
  --kv-fs-cascade:clamp(3rem, min(13vw, 18.5vh), 12rem);
  --kv-fs-h2:     clamp(2.25rem, 7.4vw, 7rem);
  --kv-fs-lead:   clamp(1rem, 1.9vw, 1.25rem);
  --kv-fs-body:   1rem;
  --kv-fs-sm:     .8125rem;
  --kv-fs-label:  .6875rem;

  --kv-lh-tight:  .92;
  --kv-track-tight: -.035em;
  --kv-track-label: .16em;

  /* ── layout ────────────────────────────────────────────── */
  --kv-pad:       clamp(1.25rem, 4vw, 3.25rem);
  --kv-content:   1120px;
  --kv-gap:       clamp(1.5rem, 4vw, 3rem);
  --kv-section-y: clamp(5rem, 13vh, 9rem);
  --kv-radius:    2px;
}

/* ============================================================
   BASE
   ============================================================ */
*{ box-sizing: border-box; }
html{ scroll-behavior: smooth; }

body{
  margin: 0;
  background: var(--kv-white);
  color: var(--kv-ink);
  font-family: var(--kv-body);
  font-size: var(--kv-fs-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;              /* clip, NOT hidden — hidden makes body a
                                    scroll container and breaks position:sticky */
}

img{ max-width: 100%; display: block; }
:focus-visible{ outline: 2px solid var(--kv-accent); outline-offset: 3px; }

/* ============================================================
   SURFACES — the site alternates dark / light for contrast
   ============================================================ */
[data-surface="dark"]{ background: var(--kv-ink); color: var(--kv-on-dark); }
[data-surface="light"]{ background: var(--kv-white); color: var(--kv-ink); }

/* ============================================================
   TYPE PRIMITIVES
   ============================================================ */
.kv-display{
  font-family: var(--kv-display);
  font-weight: 800;
  font-variation-settings: "wdth" 92, "opsz" 96;
  line-height: var(--kv-lh-tight);
  letter-spacing: var(--kv-track-tight);
  text-wrap: balance;
  margin: 0;
}

/* highlight = colour only, no background block.
   #F7A115 on every surface, per client direction. On white this is 2.1:1,
   below the WCAG AA floor — kept because the brand accent takes priority. */
.kv-hl{ color: var(--kv-accent); }

/* struck-through phrase, line draws in on reveal */
.kv-struck{ position: relative; white-space: nowrap; }
.kv-struck::after{
  content: ""; position: absolute; left: -.03em; right: -.03em; top: 52%;
  height: .07em; background: var(--kv-accent); border-radius: 1px;
  transform: scaleX(var(--sx, 0)); transform-origin: left;
  transition: transform .75s cubic-bezier(.22,.9,.3,1);
}

.kv-label{
  display: inline-flex; align-items: center; gap: .5rem;
  font-size: var(--kv-fs-label); font-weight: 600;
  letter-spacing: var(--kv-track-label); text-transform: uppercase;
  color: var(--kv-ink); margin: 0;
}
[data-surface="dark"] .kv-label{ color: var(--kv-on-dark); }
.kv-label::before{
  content: ""; width: .5em; height: .5em;
  background: var(--kv-accent); flex: none;
}

.kv-lead{
  font-size: var(--kv-fs-lead); line-height: 1.55;
  color: var(--kv-ink-soft); margin: 0; max-width: 48ch; text-wrap: balance;
}
[data-surface="dark"] .kv-lead{ color: var(--kv-on-dark-soft); }
/* the hero's lead is the exception — full white, so it holds its own
   against the headline and the film behind it */
.kv-hero .kv-lead{ color: var(--kv-on-dark); }

/* ============================================================
   BUTTONS
   ============================================================ */
.kv-btn{
  display: inline-flex; align-items: center; gap: .75rem;
  padding: 1rem 1.625rem;
  font-family: var(--kv-body);
  font-size: var(--kv-fs-sm); font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  text-decoration: none; border: 0; border-radius: 999px; cursor: pointer;
  transition: background .2s ease, color .2s ease, gap .25s ease;
}
.kv-btn svg{ flex: none; }
.kv-btn--accent{ background: var(--kv-accent); color: var(--kv-ink); }
.kv-btn--accent:hover, .kv-btn--accent:focus-visible{ background: var(--kv-ink); color: var(--kv-white); gap: 1.25rem; }
[data-surface="dark"] .kv-btn--accent:hover,
[data-surface="dark"] .kv-btn--accent:focus-visible{ background: var(--kv-white); color: var(--kv-ink); }

.kv-btn--ink{ background: var(--kv-ink); color: var(--kv-white); }
.kv-btn--ink:hover, .kv-btn--ink:focus-visible{ background: var(--kv-accent); color: var(--kv-ink); }

/* ============================================================
   HEADER — wordmark left, menu right; flips over dark sections
   ============================================================ */
.kv-hdr{
  position: fixed; inset: 0 0 auto 0; z-index: 60;
  display: flex; align-items: flex-start; justify-content: space-between;
  padding: clamp(1.125rem,2.6vw,1.75rem) var(--kv-pad);
  pointer-events: none;
}
.kv-hdr > *{ pointer-events: auto; }

/* The lockup is one inline SVG filled with currentColor, so the whole mark
   — icon, wordmark and tagline — flips with the header in one declaration. */
.kv-brand{
  display: flex; align-items: center; text-decoration: none;
  color: var(--kv-ink); transition: color .3s ease;
}
.kv-brand__logo{
  display: block; height: clamp(30px, 3.4vw, 40px); width: auto;
}
/* the name still reaches screen readers and search, just not the eye */
.kv-brand__sr{
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

.kv-hdr[data-on-dark="true"] .kv-brand{ color: var(--kv-on-dark); }
.kv-hdr[data-on-dark="true"] .kv-btn--ink{ background: var(--kv-white); color: var(--kv-ink); }
.kv-hdr[data-on-dark="true"] .kv-btn--ink:hover,
.kv-hdr[data-on-dark="true"] .kv-btn--ink:focus-visible{ background: var(--kv-accent); color: var(--kv-ink); }

/* ============================================================
   NAV OVERLAY
   ============================================================ */
.kv-nav{
  position: fixed; inset: 0; z-index: 70;
  background: var(--kv-ink);
  display: flex; flex-direction: column; justify-content: center;
  padding: var(--kv-pad);
  opacity: 0; visibility: hidden;
  transition: opacity .35s ease, visibility .35s;
}
.kv-nav[data-open="true"]{ opacity: 1; visibility: visible; }
.kv-nav__close{
  position: absolute; top: clamp(1.125rem,2.6vw,1.75rem); right: var(--kv-pad);
  background: var(--kv-accent); color: var(--kv-ink);
}
.kv-nav ol{ list-style: none; margin: 0; padding: 0; }
.kv-nav li{ border-top: 1px solid var(--kv-line-dark); }
.kv-nav li:last-child{ border-bottom: 1px solid var(--kv-line-dark); }
.kv-nav a{
  display: flex; align-items: baseline; gap: clamp(1rem,4vw,2.5rem);
  text-decoration: none; color: var(--kv-on-dark);
  padding: clamp(.6875rem,1.8vw,1rem) 0;
  font-family: var(--kv-display); font-weight: 800;
  font-variation-settings: "wdth" 92, "opsz" 96;
  font-size: clamp(1.75rem,6.6vw,3.75rem); line-height: 1.04;
  letter-spacing: var(--kv-track-tight);
  transition: color .2s ease, padding-left .3s cubic-bezier(.22,.9,.3,1);
}
.kv-nav a:hover, .kv-nav a:focus-visible{ color: var(--kv-accent); padding-left: clamp(.75rem,2vw,1.5rem); }
.kv-nav__n{
  font-family: var(--kv-body); font-size: var(--kv-fs-label); font-weight: 600;
  letter-spacing: .18em; color: var(--kv-accent); flex: none;
  font-variant-numeric: tabular-nums;
}

/* ============================================================
   FLOATING WHATSAPP CTA — WhatsApp green, reads on both surfaces
   Ink text rather than white: white on #25D366 is only 2.2:1,
   #101010 on it is 11.4:1 and still unmistakably WhatsApp.
   ============================================================ */
.kv-wa{
  position: fixed; z-index: 65;
  right: var(--kv-pad); bottom: clamp(1.125rem,2.6vw,1.75rem);
  background: var(--kv-wa-green); color: var(--kv-ink);
  box-shadow: 0 8px 26px rgba(0,0,0,.24);
  animation: kv-wa-breathe 4.2s ease-in-out infinite;
  transition: background .2s ease, color .2s ease, gap .25s ease, transform .25s cubic-bezier(.22,.9,.3,1);
}
.kv-wa:hover, .kv-wa:focus-visible{
  background: var(--kv-wa-green-dk); color: var(--kv-white);
  gap: 1.25rem; transform: translateY(-2px); animation-play-state: paused;
}
.kv-wa__txt{ white-space: nowrap; }

/* the icon gives a small "new message" nudge on its own cycle */
.kv-wa__ico{ animation: kv-wa-nudge 4.2s ease-in-out infinite; transform-origin: 50% 65%; }
.kv-wa:hover .kv-wa__ico{ animation-duration: 1.1s; }

/* a halo that pushes out of the pill and fades — the pulse you see on
   messaging widgets, kept to one ring so it stays quiet */
.kv-wa__ring{
  position: absolute; inset: 0; border-radius: inherit;
  border: 2px solid var(--kv-wa-green);
  animation: kv-wa-ring 2.6s cubic-bezier(.22,.9,.3,1) infinite;
  pointer-events: none;
}
@keyframes kv-wa-breathe{
  0%,100%{ box-shadow: 0 8px 26px rgba(0,0,0,.24), 0 0 0 0 rgba(37,211,102,.0); }
  50%    { box-shadow: 0 10px 30px rgba(0,0,0,.30), 0 0 0 6px rgba(37,211,102,.16); }
}
@keyframes kv-wa-ring{
  0%     { opacity: .65; transform: scale(1); }
  70%,100%{ opacity: 0;  transform: scale(1.22); }
}
@keyframes kv-wa-nudge{
  0%,72%,100%{ transform: rotate(0) scale(1); }
  78%{ transform: rotate(-13deg) scale(1.12); }
  84%{ transform: rotate(11deg)  scale(1.12); }
  90%{ transform: rotate(-6deg)  scale(1.05); }
}
@media (max-width: 560px){
  .kv-wa{ padding: .875rem 1.125rem; gap: .5rem; font-size: .625rem; }
}

/* ============================================================
   01 · HERO — dark, with a muted background film
   ============================================================ */
.kv-hero{
  position: relative;
  min-height: 100svh;
  display: flex;
  overflow: hidden;
}

.kv-hero__bg{
  position: absolute; inset: 0; z-index: 0;
  overflow: hidden; pointer-events: none;
}

/* A native <video> covers the fold with object-fit, so no aspect-ratio maths
   is needed and the film is never letterboxed whatever the window shape. */
.kv-hero__video{
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  display: block; border: 0;
  opacity: var(--kv-hero-video);
}

/* Only the top and bottom are darkened — enough to hold the header and the
   WhatsApp pill — so the middle of the film stays as clear as the opacity
   token allows. */
.kv-hero__scrim{
  position: absolute; inset: 0;
  background: linear-gradient(
    to bottom,
    rgba(16,16,16,.72) 0%,
    rgba(16,16,16,.18) 26%,
    rgba(16,16,16,.18) 68%,
    rgba(16,16,16,.78) 100%);
}

/* ── the four pinned photos ────────────────────────────────
   Three transforms, one job each, so they never fight:
     .kv-float      — scroll parallax + fade, driven by site.js (--kv-y)
     .kv-float img  — the resting tilt, via transform: rotate()
     kv-drift       — the endless up/down, via the independent translate:
   Sitting at z-index 1 alongside the type but with the headline
   painted over them — pointer-events off, they are decoration. */
.kv-hero__floats{
  position: absolute; inset: 0; z-index: 1;
  pointer-events: none;
}
.kv-float{
  position: absolute;
  width: var(--w);
  --bw: clamp(2px, .28vw, 4px);        /* frame weight — see .kv-float img */
  margin: 0;
  /* --kv-y / --kv-fade are written by site.js on scroll */
  transform: translate3d(0, var(--kv-y, 0px), 0);
  opacity: var(--kv-fade, 1);
  will-change: transform;
}
.kv-float img{
  display: block; width: 100%; height: auto;
  aspect-ratio: 3 / 4; object-fit: cover;
  background: #1C1C1C;
  /* the frame is a box-shadow ring, not a border: half the old weight, and
     drawn OUTSIDE the box so it never eats into the photo itself */
  box-shadow: 0 0 0 var(--bw) var(--kv-white), 0 18px 44px rgba(0,0,0,.55);
  transform: rotate(var(--rot));
  animation: kv-drift var(--dur) ease-in-out var(--delay, 0s) infinite;
}

/* Each keeps its own amplitude and rhythm — matched periods would read
   as one block moving, which is the opposite of the point. */
@keyframes kv-drift{
  0%,100%{ translate: 0 calc(var(--amp) * -1); }
  50%    { translate: 0 var(--amp); }
}

/* Positions mirror the pinned-photo layout: two high on the shoulders of
   the headline, two low. Widths are vw-fluid with a hard cap. */
.kv-float--a{ --w: clamp(96px, 10vw, 190px); --rot: -8deg;  --amp: 11px; --dur: 7.5s;  --delay: -1.2s;
              left: 1.2%;  top: 26%; }
.kv-float--b{ --w: clamp(92px, 9.4vw, 178px); --rot: 7deg;  --amp: 9px;  --dur: 9.2s;  --delay: -3.4s;
              right: .9%;  top: 28%; }
.kv-float--c{ --w: clamp(90px, 9.2vw, 174px); --rot: -6deg; --amp: 13px; --dur: 8.3s;  --delay: -5.1s;
              left: 15.5%; top: 68%; }
.kv-float--d{ --w: clamp(94px, 9.6vw, 182px); --rot: 8deg;  --amp: 10px; --dur: 10.4s; --delay: -2.3s;
              right: 6.5%; top: 54%; }

/* Tablets: same arrangement, pulled tight to the edges so the four still
   frame the headline on a narrower fold. */
@media (max-width: 760px){
  .kv-float img{ box-shadow: 0 0 0 var(--bw) var(--kv-white), 0 10px 26px rgba(0,0,0,.5); }
  .kv-float--a{ --w: clamp(84px, 13vw, 120px); left: .5%;  top: 24%; }
  .kv-float--b{ --w: clamp(80px, 12.4vw, 114px); right: .5%; top: 27%; }
  .kv-float--c{ --w: clamp(78px, 12vw, 110px); left: 8%;   top: 72%; }
  .kv-float--d{ --w: clamp(82px, 12.6vw, 116px); right: 4%; top: 60%; }
}

/* Phones: the headline runs the full width of the fold, so all four drop
   into the empty band below it rather than sitting behind the type. They
   bleed off the side edges — enough to feel alive, never in the way. */
@media (max-width: 560px){
  .kv-float--a{ --w: 23vw; left: -4%;  top: 60%; }
  .kv-float--b{ --w: 22vw; right: -5%; top: 55%; }
  .kv-float--c{ --w: 21vw; left: 9%;   top: 76%; }
  .kv-float--d{ --w: 22vw; right: 8%;  top: 72%; }
}

.kv-hero__content{
  position: relative; z-index: 2;
  flex: 1;
  display: flex; flex-direction: column; justify-content: center; align-items: center;
  text-align: center;
  padding: clamp(7rem,16vh,10rem) var(--kv-pad) clamp(3.5rem,9vh,6rem);
  gap: clamp(1.5rem,3.5vw,2.5rem);
}
.kv-hero__title{ font-size: var(--kv-fs-hero); max-width: 14ch; }

.kv-cue{
  display: flex; flex-direction: column; align-items: center; gap: .5rem;
  font-size: .625rem; font-weight: 600; letter-spacing: .22em;
  text-transform: uppercase; color: var(--kv-on-dark-soft);
  margin-top: clamp(.5rem,2vw,1.25rem);
}
.kv-cue__bar{
  width: 2px; height: 40px; background: var(--kv-accent);
  transform-origin: top; animation: kv-cue 2.2s ease-in-out infinite;
}
@keyframes kv-cue{ 0%,100%{ transform: scaleY(.35); opacity:.5 } 50%{ transform: scaleY(1); opacity:1 } }

/* ============================================================
   02 · COLLECTION — light, scroll-driven fan
   ============================================================ */
.kv-fan{ position: relative; height: 260vh; }
.kv-fan__sticky{
  position: sticky; top: 0; height: 100svh;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: clamp(1.25rem,3.5vh,2.5rem);
  overflow: hidden;
  padding: clamp(5rem,12vh,7rem) var(--kv-pad) clamp(2.5rem,7vh,4.5rem);
}
.kv-fan__head{ display: flex; flex-direction: column; align-items: center; gap: .875rem; text-align: center; }
.kv-fan__title{ font-size: var(--kv-fs-h2); }

.kv-stage{
  position: relative; width: 100%; flex: 1; min-height: 0;
  display: flex; align-items: center; justify-content: center;
}
.kv-card{
  position: absolute;
  width: clamp(150px, 21vw, 290px);
  aspect-ratio: 3 / 4;
  margin: 0; overflow: hidden;
  border-radius: var(--kv-radius);
  background: var(--kv-off);
  box-shadow: 0 16px 40px rgba(16,16,16,.2);
  will-change: transform;
}
.kv-card img{ width: 100%; height: 100%; object-fit: cover; }
.kv-card figcaption{
  position: absolute; inset: auto 0 0 0;
  padding: 2.5rem .875rem .8125rem;
  background: linear-gradient(transparent, rgba(16,16,16,.85));
  color: var(--kv-white);
  display: flex; flex-direction: column; gap: .1875rem;
}
.kv-card__cat{
  font-size: .5rem; font-weight: 600; letter-spacing: .18em;
  text-transform: uppercase; color: var(--kv-accent);
}
.kv-card__name{
  font-family: var(--kv-display); font-weight: 700;
  font-variation-settings: "wdth" 92, "opsz" 24;
  font-size: .9375rem; line-height: 1.15;
}

/* under 760px the fan becomes a swipe rail */
@media (max-width: 760px){
  .kv-fan{ height: auto; }
  .kv-fan__sticky{ position: static; height: auto; overflow: visible; padding-block: clamp(4rem,11vh,6rem); }
  .kv-stage{
    position: static; flex: none;
    /* flex-start, not the inherited center — centring an overflowing flex row
       pushes the leading items to negative offsets that scrolling can't reach */
    justify-content: flex-start;
    gap: .75rem; width: 100vw;
    margin-inline: calc(var(--kv-pad) * -1);
    padding-inline: var(--kv-pad);
    overflow-x: auto; scroll-snap-type: x mandatory;
    scroll-padding-inline-start: var(--kv-pad);
    scrollbar-width: none;
  }
  .kv-stage::-webkit-scrollbar{ display: none; }
  .kv-card{
    position: static; flex: 0 0 68vw; width: 68vw;
    /* start, not center — a centred first card has no reachable snap point at
       scrollLeft 0, so mandatory snapping jumps the rail off the first item */
    transform: none !important; scroll-snap-align: start;
    box-shadow: 0 8px 22px rgba(16,16,16,.14);
  }
}

/* ============================================================
   03 · STORY — dark
   ============================================================ */
.kv-say{
  padding: var(--kv-section-y) var(--kv-pad) calc(var(--kv-section-y) + 2rem);
  display: flex; flex-direction: column; align-items: center;
  gap: clamp(2.5rem,7vh,4.5rem);
}
.kv-say__big{ font-size: var(--kv-fs-h2); max-width: 16ch; text-align: center; }

.kv-say__grid{
  display: grid; grid-template-columns: minmax(0,1fr); gap: var(--kv-gap);
  width: 100%; max-width: var(--kv-content);
  padding-top: clamp(2rem,5vh,3rem);
  border-top: 1px solid var(--kv-line-dark);
}
@media (min-width: 860px){
  .kv-say__grid{ grid-template-columns: .8fr 1.2fr; align-items: start; gap: clamp(2rem,6vw,4.5rem); }
}
.kv-say__l{ display: flex; flex-direction: column; gap: 1rem; }
.kv-say__r{ display: flex; flex-direction: column; gap: 1.5rem; align-items: flex-start; }
.kv-say__r p{
  font-size: var(--kv-fs-lead); line-height: 1.62;
  color: var(--kv-on-dark-soft); margin: 0; max-width: 52ch;
}
.kv-say__r p b{ color: var(--kv-on-dark); font-weight: 600; }

/* ============================================================
   SWIPE / SCROLL INDICATOR
   Shared by the fan (phones only, where it becomes a rail) and by
   the slider (every width). Only `display` is breakpoint-bound —
   the visuals sit outside the media query so both can reach them,
   and so [data-surface="dark"] can still override them further down.
   ============================================================ */
.kv-rail{
  display: none; align-items: center; gap: .875rem;
  width: 100%; max-width: 20rem;
  margin: 1.5rem auto 0;
}
@media (max-width: 760px){ .kv-rail{ display: flex; } }

.kv-rail__label{
  font-size: var(--kv-fs-label); font-weight: 600;
  letter-spacing: var(--kv-track-label); text-transform: uppercase;
  color: var(--kv-ink-soft); white-space: nowrap;
  display: inline-flex; align-items: center; gap: .375rem;
  transition: opacity .3s ease;
}
.kv-rail[data-touched="true"] .kv-rail__label{ opacity: 0; }
.kv-rail__arrow{ animation: kv-nudge 1.6s ease-in-out infinite; }
.kv-rail__track{
  position: relative; flex: 1; height: 3px;
  background: var(--kv-line); border-radius: 999px; overflow: hidden;
}
.kv-rail__thumb{
  position: absolute; top: 0; bottom: 0; left: 0; width: 20%;
  background: var(--kv-accent); border-radius: 999px;
  transition: left .12s linear;
}
.kv-rail__count{
  font-size: var(--kv-fs-label); font-weight: 600; letter-spacing: .1em;
  color: var(--kv-ink-soft); font-variant-numeric: tabular-nums; white-space: nowrap;
}
@keyframes kv-nudge{ 0%,100%{ transform: translateX(0) } 50%{ transform: translateX(4px) } }

/* ============================================================
   ZOOM BUTTON — covers an image, opens the lightbox
   ============================================================ */
.kv-zoom{
  position: absolute; inset: 0; z-index: 2;
  display: flex; align-items: flex-start; justify-content: flex-end;
  padding: .75rem;
  background: transparent; border: 0; cursor: zoom-in;
  -webkit-appearance: none; appearance: none;
}
.kv-zoom:focus-visible{ outline: 3px solid var(--kv-accent); outline-offset: -3px; }
.kv-zoom__icon{
  display: grid; place-items: center;
  width: 30px; height: 30px; border-radius: 999px;
  background: var(--kv-accent); color: var(--kv-ink);
  font-family: var(--kv-body); font-size: 1.125rem; font-weight: 600; line-height: 1;
  opacity: 0; transform: scale(.7);
  transition: opacity .22s ease, transform .22s cubic-bezier(.34,1.4,.5,1);
}
.kv-zoom:hover .kv-zoom__icon,
.kv-zoom:focus-visible .kv-zoom__icon{ opacity: 1; transform: scale(1); }

/* ============================================================
   LIGHTBOX
   ============================================================ */
.kv-lb{
  position: fixed; inset: 0; z-index: 90;
  display: grid; place-items: center;
  padding: clamp(3.25rem,8vh,5rem) clamp(1rem,4vw,5rem);
  background: rgba(10,10,10,.96);
  opacity: 0; visibility: hidden;
  transition: opacity .28s ease, visibility .28s;
}
.kv-lb[data-open="true"]{ opacity: 1; visibility: visible; }

.kv-lb__fig{
  margin: 0; display: flex; flex-direction: column; align-items: center;
  gap: 1rem; max-height: 100%; min-height: 0;
}
.kv-lb__img{
  max-height: min(76vh, 900px); width: auto; max-width: 100%;
  height: auto; object-fit: contain;
  border-radius: var(--kv-radius);
  background: var(--kv-ink);
  transform: scale(.97); opacity: 0;
  transition: transform .3s cubic-bezier(.22,.9,.3,1), opacity .3s ease;
}
.kv-lb[data-open="true"] .kv-lb__img{ transform: none; opacity: 1; }

.kv-lb__cap{ display: flex; flex-direction: column; align-items: center; gap: .25rem; text-align: center; }
.kv-lb__cat{
  font-size: var(--kv-fs-label); font-weight: 600;
  letter-spacing: var(--kv-track-label); text-transform: uppercase;
  color: var(--kv-accent);
}
.kv-lb__name{
  font-family: var(--kv-display); font-weight: 700;
  font-variation-settings: "wdth" 92, "opsz" 24;
  font-size: 1.25rem; line-height: 1.2; color: var(--kv-on-dark);
}

.kv-lb__close, .kv-lb__nav{
  position: absolute; z-index: 2;
  display: grid; place-items: center;
  width: 46px; height: 46px; padding: 0;
  border: 1px solid var(--kv-line-dark); border-radius: 999px;
  background: rgba(255,255,255,.06); color: var(--kv-on-dark);
  cursor: pointer;
  transition: background .2s ease, color .2s ease, border-color .2s ease;
}
.kv-lb__close:hover, .kv-lb__nav:hover,
.kv-lb__close:focus-visible, .kv-lb__nav:focus-visible{
  background: var(--kv-accent); color: var(--kv-ink); border-color: var(--kv-accent);
}
.kv-lb__close{ top: clamp(1rem,2.4vw,1.75rem); right: clamp(1rem,4vw,2rem); }
.kv-lb__nav{ top: 50%; transform: translateY(-50%); }
.kv-lb__nav--prev{ left: clamp(.625rem,2.5vw,2rem); }
.kv-lb__nav--next{ right: clamp(.625rem,2.5vw,2rem); }

.kv-lb__count{
  position: absolute; left: 50%; transform: translateX(-50%);
  bottom: clamp(1rem,2.4vw,1.75rem); margin: 0;
  font-size: var(--kv-fs-label); font-weight: 600; letter-spacing: .16em;
  color: var(--kv-on-dark-soft); font-variant-numeric: tabular-nums;
}

@media (max-width: 560px){
  .kv-lb__nav{ top: auto; bottom: clamp(1rem,2.4vw,1.75rem); transform: none; width: 42px; height: 42px; }
  .kv-lb__nav--prev{ left: clamp(1rem,6vw,2rem); }
  .kv-lb__nav--next{ right: clamp(1rem,6vw,2rem); }
  .kv-lb__img{ max-height: 62vh; }
}

/* ============================================================
   MOBILE TYPE SCALE
   The desktop scale is vw-driven, which shrinks everything on a
   narrow screen. On phones the floors are raised and the hero's
   vertical padding is cut so the type fills the screen instead of
   floating in the middle of it.
   ============================================================ */
@media (max-width: 600px){
  :root{
    --kv-fs-hero:    clamp(3.75rem, 16.5vw, 5rem);
    --kv-fs-h2:      clamp(2.625rem, 12vw, 3.75rem);
    --kv-fs-cascade: clamp(2.5rem, min(14.5vw, 9vh), 4.5rem);
    --kv-fs-lead:    1.0625rem;
  }
  .kv-hero__content{
    /* anchor to the top and push the cue to the bottom — centring on a tall
       phone screen leaves a big empty band above and below the type */
    justify-content: flex-start;
    padding-top: 7.25rem;
    padding-bottom: 5.5rem;   /* clears the fixed WhatsApp pill */
    gap: 1.25rem;
  }
  .kv-cue{ margin-top: auto; }
  .kv-hero__title{ max-width: none; }
  .kv-say__big{ max-width: none; }
}

/* ============================================================
   The fan on a dark surface (05 · Latkan) — the rest of .kv-fan
   is shared with the light Collection section above.
   ============================================================ */
[data-surface="dark"] .kv-card{ background: #1C1C1C; box-shadow: 0 16px 44px rgba(0,0,0,.55); }
[data-surface="dark"] .kv-rail__track{ background: var(--kv-line-dark); }
[data-surface="dark"] .kv-rail__label,
[data-surface="dark"] .kv-rail__count{ color: var(--kv-on-dark-soft); }

@media (max-width: 760px){
  [data-surface="dark"] .kv-card{ box-shadow: 0 8px 24px rgba(0,0,0,.45); }
}

/* ============================================================
   04 · THE MAKING
   Three columns: a staggered image collage, the three words, and
   the numerals pinned to the far right edge. Words and numerals
   share grid rows, so 001/002/003 line up with CLOTH/RIBBON/MIRROR
   however long the words are.
   ============================================================ */
.kv-make{
  min-height: 100svh;
  display: flex;
  padding: clamp(5rem,10vh,7rem) var(--kv-pad) clamp(2rem,5vh,3.25rem);
}
.kv-make__inner{
  flex: 1; width: 100%; max-width: 1500px; margin-inline: auto;
  display: grid;
  /* the media column is capped by height too, so a short window shrinks the
     collage instead of pushing the section past the fold */
  grid-template-columns: clamp(230px, min(38%, 54vh), 560px) minmax(0, 1fr) auto;
  grid-template-rows: auto auto auto auto minmax(0, 1fr);
  column-gap: clamp(1.5rem, 4vw, 4rem);
}

.kv-make__label{ grid-column: 1 / -1; grid-row: 1; margin-bottom: clamp(.75rem,2.2vh,1.75rem); }

/* ── left: staggered collage ── */
.kv-make__media{
  grid-column: 1; grid-row: 2 / 6;
  display: grid;
  grid-template-columns: 1.55fr 1fr;
  grid-template-rows: auto auto;
  gap: clamp(.75rem, 1.6vw, 1.5rem);
  align-content: start;
}
.kv-make__fig{ position: relative; margin: 0; overflow: hidden; }
.kv-make__fig img{
  width: 100%; height: auto; display: block;
  border: 0; border-radius: 0;
}
.kv-make__fig--1{ grid-column: 1; grid-row: 1; }
.kv-make__fig--2{ grid-column: 2; grid-row: 1; align-self: end; }   /* bottom-aligned with fig 1 */
.kv-make__fig--3{ grid-column: 1; grid-row: 2; width: 62%; }

/* ── middle: the three words ── */
.kv-make__title{ display: contents; }
.kv-make__word{
  grid-column: 2; justify-self: start;
  font-size: var(--kv-fs-cascade);
  line-height: .86;
  letter-spacing: -.045em;
  text-transform: uppercase;
  white-space: nowrap;
}
.kv-make__word--1{ grid-row: 2; }
.kv-make__word--2{ grid-row: 3; }
.kv-make__word--3{ grid-row: 4; }

/* ── right: the numerals, flush to the edge ── */
.kv-make__n{
  grid-column: 3; justify-self: end; align-self: start;
  font-family: var(--kv-body);
  font-size: clamp(.75rem, 1.05vw, 1.0625rem);
  font-weight: 600; letter-spacing: .12em; line-height: 1;
  color: var(--kv-accent);
  font-variant-numeric: tabular-nums;
  padding-top: .35em;
}
.kv-make__n--1{ grid-row: 2; }
.kv-make__n--2{ grid-row: 3; }
.kv-make__n--3{ grid-row: 4; }

/* ── the note, under the words ── */
.kv-make__copy{
  grid-column: 2 / -1; grid-row: 5;
  align-self: start;
  margin: 0; max-width: 60ch;
  padding-top: clamp(1.5rem, 4vh, 3.25rem);
  font-size: clamp(.875rem, 1.05vw, 1rem);
  line-height: 1.6; color: var(--kv-ink-soft);
  text-align: left;
}

/* Phones: all three images the same width, stacked at their natural heights,
   then the words, numerals and note beneath them. */
@media (max-width: 760px){
  .kv-make{ min-height: 0; padding: clamp(4rem,9vh,5.5rem) var(--kv-pad) clamp(4.5rem,8vh,6rem); }
  .kv-make__inner{
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-rows: auto auto auto auto auto auto;
    row-gap: 0;
  }
  .kv-make__label{ grid-column: 1 / -1; grid-row: 1; }
  .kv-make__media{
    grid-column: 1 / -1; grid-row: 2;
    display: flex; flex-direction: column;
    gap: clamp(.625rem, 2vw, 1rem);
    margin-bottom: clamp(1.25rem, 3.5vh, 2rem);
  }
  .kv-make__fig--3{ width: 100%; }
  .kv-make__word{ grid-column: 1; }
  /* must be column 2, not the desktop's 3 — asking for a column the mobile
     grid doesn't define creates an implicit one, and `1 / -1` then stops
     short of it, pinching the images narrower than the container */
  .kv-make__n{ grid-column: 2; }
  .kv-make__word--1{ grid-row: 3; }
  .kv-make__word--2{ grid-row: 4; }
  .kv-make__word--3{ grid-row: 5; }
  .kv-make__n--1{ grid-row: 3; }
  .kv-make__n--2{ grid-row: 4; }
  .kv-make__n--3{ grid-row: 5; }
  .kv-make__copy{ grid-column: 1 / -1; grid-row: 6; max-width: none; font-size: .9375rem; line-height: 1.55; }
}

/* ============================================================
   THE SLIDER — a shared component, not one section
   One horizontal scroller that takes either kind of card:
   .kv-card (a 3:4 photo) or .kv-reel (a 9:16 video). Arrows above
   760px, swipe below, the shared .kv-rail underneath at every
   width.

   Unlike .kv-fan this has no card ceiling. The fan computes its
   spread from the card count and falls apart past about eight —
   at twenty each card shows a 68px sliver and the row runs wider
   than the window. Any gallery that keeps growing belongs here.
   ============================================================ */
.kv-slider{
  padding: var(--kv-section-y) 0;
  display: flex; flex-direction: column; align-items: center;
  gap: clamp(2rem,5vh,3.25rem);
  overflow: hidden;                      /* the track bleeds wider than the page */
}
.kv-slider__head{
  display: flex; flex-direction: column; align-items: center; gap: .875rem;
  text-align: center; padding-inline: var(--kv-pad);
}
.kv-slider__title{ font-size: var(--kv-fs-h2); }
.kv-slider__head .kv-lead{ max-width: 52ch; }

.kv-slider__viewport{
  position: relative; width: 100%;
  max-width: calc(var(--kv-content) + var(--kv-pad) * 2);
}
.kv-slider__track{
  display: flex; gap: clamp(.625rem,1.4vw,1rem);
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-inline-start: var(--kv-pad);
  padding: .25rem var(--kv-pad);
  scrollbar-width: none;
}
.kv-slider__track::-webkit-scrollbar{ display: none; }

/* ── photo card ───────────────────────────────────────────
   The fan's .kv-card with the fan taken out of it: no absolute
   positioning, no JS transform, a real flex width. Everything
   else — the caption, the zoom button, the dark-surface
   treatment — is inherited unchanged.                        */
.kv-slider .kv-card{
  position: static;
  flex: 0 0 clamp(200px, 24vw, 300px);
  width: auto;
  transform: none !important;
  scroll-snap-align: start;              /* start, not center — see the fan rail */
}

/* ── video card ───────────────────────────────────────────
   Unused by any section right now; kept so a reels strip is
   markup-only if it comes back. site.js wires the player only
   for cards that actually contain a <video>.                 */
.kv-reel{
  position: relative; margin: 0;
  flex: 0 0 clamp(190px, 23vw, 268px);
  aspect-ratio: 9 / 16;
  scroll-snap-align: start;
  overflow: hidden;
  border-radius: var(--kv-radius);
  background: var(--kv-off);
  box-shadow: 0 16px 40px rgba(16,16,16,.2);
  cursor: pointer;
}
.kv-reel__v{
  width: 100%; height: 100%; display: block;
  object-fit: cover; background: var(--kv-off);
}
.kv-reel__cap{
  position: absolute; inset: auto 0 0 0; z-index: 2;
  padding: 3rem .875rem .8125rem;
  background: linear-gradient(transparent, rgba(16,16,16,.85));
  color: var(--kv-white);
  display: flex; flex-direction: column; gap: .1875rem;
  pointer-events: none;
}
.kv-reel__cat{
  font-size: .5rem; font-weight: 600; letter-spacing: .18em;
  text-transform: uppercase; color: var(--kv-accent);
}
.kv-reel__name{
  font-family: var(--kv-display); font-weight: 700;
  font-variation-settings: "wdth" 92, "opsz" 24;
  font-size: .9375rem; line-height: 1.15;
}
.kv-reel__play{
  position: absolute; inset: 0; z-index: 3;
  display: grid; place-items: center;
  background: transparent; border: 0; padding: 0;
  cursor: pointer; -webkit-appearance: none; appearance: none;
}
.kv-reel__play:focus-visible{ outline: 3px solid var(--kv-accent); outline-offset: -3px; }
.kv-reel__play span{
  display: grid; place-items: center;
  width: clamp(44px,4.4vw,54px); aspect-ratio: 1; border-radius: 999px;
  background: var(--kv-accent); color: var(--kv-ink);
  box-shadow: 0 6px 18px rgba(16,16,16,.35);
  transition: opacity .25s ease, transform .25s cubic-bezier(.34,1.4,.5,1);
}
.kv-reel__play svg{ display: block; margin-left: 2px; }   /* optical centre of a triangle */
.kv-reel__ico--pause{ display: none; margin-left: 0; }
.kv-reel[data-playing="true"] .kv-reel__play span{
  opacity: 0; transform: scale(.82);
  background: rgba(255,255,255,.92);
}
.kv-reel[data-playing="true"]:hover .kv-reel__play span,
.kv-reel[data-playing="true"] .kv-reel__play:focus-visible span{ opacity: 1; transform: none; }
.kv-reel[data-playing="true"] .kv-reel__ico--play{ display: none; }
.kv-reel[data-playing="true"] .kv-reel__ico--pause{ display: block; }
.kv-reel[data-state="poster"]{ cursor: default; }
.kv-reel[data-state="poster"] .kv-reel__play,
.kv-reel[data-state="poster"] .kv-reel__sound{ display: none; }
.kv-reel__sound{
  position: absolute; top: .625rem; right: .625rem; z-index: 4;
  display: grid; place-items: center;
  width: 30px; height: 30px; border-radius: 999px;
  background: rgba(16,16,16,.55); color: var(--kv-white);
  border: 0; padding: 0; cursor: pointer;
  -webkit-appearance: none; appearance: none;
  backdrop-filter: blur(6px);
  transition: background .2s ease;
}
.kv-reel__sound:hover{ background: rgba(16,16,16,.8); }
.kv-reel__sound:focus-visible{ outline: 2px solid var(--kv-accent); outline-offset: 2px; }
.kv-reel__ico--on{ display: none; }
.kv-reel[data-muted="false"] .kv-reel__sound{ background: var(--kv-accent); color: var(--kv-ink); }
.kv-reel[data-muted="false"] .kv-reel__ico--on{ display: block; }
.kv-reel[data-muted="false"] .kv-reel__ico--off{ display: none; }

/* ── arrows — desktop only, the swipe rail covers phones ── */
.kv-slider__arrow{
  position: absolute; top: 50%; z-index: 5;
  transform: translateY(-50%);
  display: none; place-items: center;
  width: 46px; height: 46px; border-radius: 999px;
  background: var(--kv-ink); color: var(--kv-on-dark);
  border: 0; padding: 0; cursor: pointer;
  -webkit-appearance: none; appearance: none;
  box-shadow: 0 8px 24px rgba(16,16,16,.28);
  transition: background .2s ease, opacity .2s ease, transform .2s cubic-bezier(.22,.9,.3,1);
}
.kv-slider__arrow:hover{ background: var(--kv-accent); color: var(--kv-ink); }
.kv-slider__arrow:focus-visible{ outline: 2px solid var(--kv-accent); outline-offset: 3px; }
.kv-slider__arrow[disabled]{ opacity: 0; pointer-events: none; }
.kv-slider__arrow--prev{ left: calc(var(--kv-pad) * .35); }
.kv-slider__arrow--next{ right: calc(var(--kv-pad) * .35); }
@media (min-width: 761px){ .kv-slider__arrow{ display: grid; } }

/* the rail runs at every width here — the "Swipe" hint only means
   anything on touch, where there are no arrows */
.kv-slider .kv-rail{ display: flex; }
@media (min-width: 761px){
  .kv-slider .kv-rail{ max-width: 22rem; margin-top: 0; }
  .kv-slider .kv-rail__label{ display: none; }
}

@media (max-width: 760px){
  .kv-slider .kv-card{ flex: 0 0 68vw; }
  .kv-reel{ flex: 0 0 68vw; box-shadow: 0 8px 22px rgba(16,16,16,.14); }
  .kv-slider .kv-rail{ margin-top: 0; }
}

/* dark-surface variants */
[data-surface="dark"] .kv-reel{ background: #1C1C1C; box-shadow: 0 16px 44px rgba(0,0,0,.55); }
[data-surface="dark"] .kv-slider__arrow{ background: var(--kv-white); color: var(--kv-ink); }

/* ============================================================
   08 · MADE TO ORDER — light, closes the page
   The galleries above are a sample, not a catalogue. This is the
   section that says so: send a photo, agree the details, it gets
   made. Typographic on purpose — every section above it carries
   photographs, so the page ends on words and one green button.
   ============================================================ */
.kv-ask{
  padding: var(--kv-section-y) var(--kv-pad) calc(var(--kv-section-y) + 2rem);
  display: flex; justify-content: center;
}
.kv-ask__inner{
  width: 100%; max-width: var(--kv-content);
  display: flex; flex-direction: column;
  gap: clamp(2.5rem,7vh,4.5rem);
}
.kv-ask__head{
  display: flex; flex-direction: column; align-items: center;
  gap: 1.125rem; text-align: center;
}
.kv-ask__title{ font-size: var(--kv-fs-h2); max-width: 18ch; }
.kv-ask__head .kv-lead{ max-width: 56ch; }

/* ── the three steps ──────────────────────────────────── */
.kv-ask__steps{
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: minmax(0,1fr);
  gap: clamp(1.75rem,4vw,3rem);
}
@media (min-width: 860px){
  .kv-ask__steps{ grid-template-columns: repeat(3, minmax(0,1fr)); gap: clamp(2rem,4vw,3.5rem); }
}
.kv-ask__step{
  display: flex; flex-direction: column; gap: .625rem;
  padding-top: 1.125rem;
  border-top: 1px solid var(--kv-line);
}
.kv-ask__n{
  font-size: var(--kv-fs-label); font-weight: 600;
  letter-spacing: .18em; color: var(--kv-accent);
  font-variant-numeric: tabular-nums;
}
.kv-ask__st{
  font-family: var(--kv-display); font-weight: 800;
  font-variation-settings: "wdth" 92, "opsz" 24;
  font-size: clamp(1.125rem,2.2vw,1.4375rem); line-height: 1.1;
  letter-spacing: var(--kv-track-tight);
  margin: 0;
}
.kv-ask__step p{
  margin: 0; font-size: .9375rem; line-height: 1.6;
  color: var(--kv-ink-soft); max-width: 38ch;
}

/* ── the close ────────────────────────────────────────── */
.kv-ask__cta{
  display: flex; flex-direction: column; align-items: center;
  gap: 1.125rem; text-align: center;
  padding-top: clamp(1.5rem,4vh,2.5rem);
  border-top: 1px solid var(--kv-line);
}
.kv-ask__note{
  margin: 0; font-size: var(--kv-fs-sm); line-height: 1.6;
  color: var(--kv-ink-soft); max-width: 44ch;
}

/* WhatsApp green on a button that is not the floating pill. Same green,
   same job — ordering — so the rule holds: green means WhatsApp, nothing
   else. Ink text again, because white on #25D366 is only 2.2:1.
   None of the pill's idle animations come along; this one sits still. */
.kv-btn--wa{ background: var(--kv-wa-green); color: var(--kv-ink); }
.kv-btn--wa:hover, .kv-btn--wa:focus-visible{
  background: var(--kv-wa-green-dk); color: var(--kv-white); gap: 1.25rem;
}
[data-surface="dark"] .kv-ask__step,
[data-surface="dark"] .kv-ask__cta{ border-top-color: var(--kv-line-dark); }
[data-surface="dark"] .kv-ask__step p,
[data-surface="dark"] .kv-ask__note{ color: var(--kv-on-dark-soft); }

/* ============================================================
   REVEAL
   ============================================================ */
.kv-rv{
  opacity: 0; transform: translateY(24px);
  transition: opacity .75s ease, transform .75s cubic-bezier(.22,.9,.3,1);
}
.kv-rv.is-in{ opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior: auto; }
  .kv-rv{ opacity: 1; transform: none; transition: none; }
  .kv-cue__bar{ animation: none; }
  /* the pinned photos hold still — no drift, no parallax, no pulse */
  .kv-float img{ animation: none; }
  .kv-float{ transform: none; opacity: 1; }
  .kv-wa, .kv-wa__ico{ animation: none; }
  .kv-wa__ring{ display: none; }
  .kv-struck::after{ transition: none; }
  .kv-btn{ transition: none; }
  .kv-lb, .kv-lb__img, .kv-zoom__icon{ transition: none; }
  /* reels never autoplay here — site.js leaves every card on its poster
     until the play button is pressed */
  .kv-reel__play span, .kv-reel__sound, .kv-slider__arrow{ transition: none; }
  .kv-lb__img{ transform: none; }
}
