/* ================================================================
   COMPONENT: PRELOADER
   Full-screen intro splash — four sketch strokes draw a flat
   parallelogram on the dark field, the paper card rises out of
   the drawing, folds once TOWARD THE VIEWER over its crease into
   the "K" mark, lands with weight, holds, then pushes toward the
   viewer and cross-fades into the hero. Pure CSS + SVG.
   No rotateZ anywhere — the sheet stays upright.

   Timeline (percentages of --pl-dur = 2.4s):
     0–8      blank beat
     8–36     four sketch strokes at an ACCELERATING tempo (10/9/8/7)
              — both horizontals first (left→right), then both
              diagonals (top→bottom); each stroke extends past the
              corners so they cross; the hand commits as it goes
     36–42    breath — the finished drawing registers before it
              becomes paper
     42–58    pop — the card materializes and springs up out of
              the drawing (unhurried reveal)
     58–64    presentation beat — the flat card sits over the
              sketch as the ink fades beneath it
     64–86    THE fold — ONE cinematic ease-in-out curve: slow
              peel off the table, fast through the air, cushioned
              landing (no terminal strobe). The moving leaf's
              brightness arcs with it (catches light mid-flight,
              shadows on touchdown) and the center slide + shadow
              pulse ride the same curve — one coupled object
     86–91    settle — a whisper of squash into the landing
     91–100   rest on the K (breathing room before the exit)
   ================================================================ */

/* Skip the intro splash on internal case → home navigation (the head
   script sets .skip-preloader before first paint, so the splash never
   paints and is never captured in the paper-fold view transition).
   preloader.js then releases the hero on boot. */
html.skip-preloader #preloader {
  display: none !important;
}

.preloader {
  /* Local tokens — paper duotone + intro/exit timing */
  --pl-dur:        2.4s;      /* full intro: beat → sketch → pop → fold; freezes on the final "K" */
  --pl-zoom:       0.8s;      /* exit: push the K toward the viewer */
  --pl-fade:       0.5s;      /* exit: cross-fade into the homepage */
  --pl-fade-delay: 0.35s;     /* fade waits — so we zoom FIRST, then dissolve */
  --pl-ease:       cubic-bezier(0.0, 0.85, 0.15, 1);     /* dramatic ease-out: fast start → slow finish */
  /* NOTE: per-segment eases (draw / pop spring / lift / slam / zoom)
     are written as LITERAL cubic-bezier() inside the keyframes below —
     var() does not resolve for animation-timing-function within
     @keyframes (Chrome silently falls back to the base ease, which is
     what made the fold read laggy). Do not "clean them up" into vars. */
  /* Material — ONE ink, TWO values, FLAT (the simplicity constraint).
     Both leaves are the footer wordmark's teal family — a pale wash for
     the lit face, a deeper wash for the reverse. No gradients anywhere:
     the fold reads through value, the crease, and motion. Everything
     derives from system tokens (no invented hex). */
  --pl-leaf-lit:   color-mix(in srgb, var(--accent) 30%, var(--paper));       /* lit face — pale ink wash */
  --pl-leaf-deep:  color-mix(in srgb, var(--accent) 62%, var(--paper-alt));   /* reverse — the ink itself */
  --pl-shade:      color-mix(in srgb, var(--accent-dk) 60%, var(--gray-900)); /* A's shadow crossing the deep leaf */
  --pl-sketch:     color-mix(in srgb, var(--accent-dk) 50%, transparent);     /* teal pencil on warm paper */

  position: fixed;
  inset: 0;
  z-index: 9999;           /* above navbar (90) and cursor (999) */
  display: flex;
  align-items: center;
  justify-content: center;
  /* Warm paper stock — same surface as the footer panel, under a warm
     light veil arcing from above the crown (the nipponcolors gloss:
     strongest at the top edge, dissolving by mid-page). Radial and
     GENEROUS on purpose — a whisper-thin or linear veil quantizes into
     a visible seam across the flat field; a full warm arc dissolves
     smoothly. The mark and the pigment speckle (below) then read as
     one dyed sheet. */
  background:
    radial-gradient(140% 85% at 50% -8%, color-mix(in srgb, var(--crease-highlight) 65%, transparent), transparent 70%),
    var(--paper-alt);
}

/* Pigment speckle across the whole splash — the nipponcolors washi
   recipe: an ultra-fine black speckle (128px tile, peak ~5% darkening),
   NOT the footer's blotchier fractal clouds. feColorMatrix keeps only a
   thin alpha slice of the noise so the grain reads as ground pigment
   sitting in the paper's tooth. Covers field AND mark (z 8) so both
   read as one dyed sheet. */
.preloader__grain {
  position: absolute;
  inset: 0;
  z-index: 8;
  pointer-events: none;
  opacity: 0.09;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='128' height='128'%3E%3Cfilter id='pg'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.1' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0.55 0'/%3E%3C/filter%3E%3Crect width='128' height='128' filter='url(%23pg)'/%3E%3C/svg%3E");
  background-repeat: repeat;
}

/* -- Exit: anticipation dip, push toward the viewer, cross-fade -- */
.preloader.is-hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity    var(--pl-fade) var(--ease-out) var(--pl-fade-delay),
    visibility 0s linear calc(var(--pl-fade-delay) + var(--pl-fade));
}

/* The K breathes back for a beat, then launches through the viewer */
.preloader.is-hidden .preloader__stage {
  animation: pl-exit var(--pl-zoom) linear 1 forwards;
}

@keyframes pl-exit {
  0%   { transform: scale(1);    animation-timing-function: cubic-bezier(0.3, 0, 0.6, 1); }
  18%  { transform: scale(0.92); animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); } /* easeInCubic launch */
  100% { transform: scale(6.5); }
}

/* Note: we deliberately do NOT lock scroll with overflow:hidden during
   the splash — that removes the scrollbar and shifts the centered splash
   sideways when it returns on dismiss. The page is always tall enough to
   keep a scrollbar, so leaving scroll alone keeps the width constant.
   preloader.js resets scroll to the top on dismiss so the hero entrance
   always starts from the top. */

/* -- The folding stage ------------------------------------------ */
.preloader__stage {
  position: relative;
  width: min(300px, 58vw);
  aspect-ratio: 15 / 8;
  perspective: 1000px;     /* tight enough that the forward fold bulges */
}

/* Centering wrapper — slides horizontally only (never rotates).
   Base transform = final state, so reduced-motion (animation: none)
   shows the resolved K. */
.preloader__center {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  transform: translateX(-12.5%);
  will-change: transform;
  animation: pl-keep-centered var(--pl-dur) var(--pl-ease) 1 forwards;
}

.preloader__piece {
  position: absolute;
  inset: 0;
  transform-origin: 50% 50%;
  transform-style: preserve-3d;
  backface-visibility: visible;
  will-change: transform, opacity;
}

.preloader__piece svg {
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* Back leaf (Piece B, teal/lower) — never moves: it lies flat as the
   lower half of the card and simply IS the lower leg of the final K.
   Base transform = final state; only its opacity animates (the pop). */
.preloader__piece--b {
  transform: translateZ(-2px) rotateY(0deg);
  animation: pl-fade-b var(--pl-dur) var(--pl-ease) 1 forwards;
}
.preloader__piece--b path { fill: var(--pl-leaf-deep); }

/* Front leaf (Piece A, white/upper) — base = correct K (folded, on top) */
.preloader__piece--a {
  transform: translateZ(2px) rotateY(-180deg);
  animation: pl-fold-a var(--pl-dur) var(--pl-ease) 1 forwards;
}
.preloader__piece--a path { fill: var(--pl-leaf-lit); }

/* Fold shadow — the back leaf's silhouette in shadow tone, between
   the leaves (z −1). Pulses while the white leaf passes overhead,
   vanishing at the instant of impact. */
.preloader__shade {
  position: absolute;
  inset: 0;
  transform: translateZ(-1px);
  opacity: 0;
  will-change: opacity;
  animation: pl-shade var(--pl-dur) linear 1 forwards;
}

.preloader__shade svg {
  width: 100%;
  height: 100%;
  overflow: visible;
}

.preloader__shade path { fill: var(--pl-shade); }

@keyframes pl-shade {
  0%, 64%   { opacity: 0; animation-timing-function: cubic-bezier(0.76, 0, 0.24, 1); } /* builds on the fold curve */
  78%       { opacity: 0.22; }
  87%, 100% { opacity: 0; }
}

/* -- Blueprint: the four sketch strokes --------------------------
   Sits BEHIND the leaves (translateZ -3) so the popped card rises
   out of the drawing and occludes it — only the crossed stroke ends
   peek past the paper's edges while the ink fades beneath. */
.preloader__blueprint {
  position: absolute;
  inset: 0;
  transform: translateZ(-3px);
  will-change: opacity;
  animation: pl-blueprint var(--pl-dur) var(--pl-ease) 1 forwards;
}

.preloader__blueprint svg {
  width: 100%;
  height: 100%;
  overflow: visible;
}

.preloader__line {
  fill: none;
  stroke: var(--pl-sketch);
  stroke-opacity: 0.85;
  stroke-width: 3;             /* ~1.5px rendered at the 300px stage */
  stroke-dasharray: 1;         /* paths carry pathLength="1" */
  stroke-dashoffset: 1;        /* hidden until drawn */
}

/* Sketch rhythm: horizontals first, then diagonals, each stroke
   starting just before the previous one lands — a sketching hand,
   not a plotter. (line--1/2 are the horizontals, 3/4 the diagonals.) */
.preloader__line--1 { animation: pl-draw-1 var(--pl-dur) linear 1 forwards; }
.preloader__line--2 { animation: pl-draw-2 var(--pl-dur) linear 1 forwards; }
.preloader__line--3 { animation: pl-draw-3 var(--pl-dur) linear 1 forwards; }
.preloader__line--4 { animation: pl-draw-4 var(--pl-dur) linear 1 forwards; }

/* Accelerating tempo — 10/9/8/7 (% of the timeline per stroke): the
   hand speeds up as it commits, and the sketch ends at 36 so the
   finished drawing gets a breath (36–42) before it becomes paper. */
@keyframes pl-draw-1 {
  0%, 8%    { stroke-dashoffset: 1; animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); }
  18%, 100% { stroke-dashoffset: 0; }
}
@keyframes pl-draw-2 {
  0%, 16%   { stroke-dashoffset: 1; animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); }
  25%, 100% { stroke-dashoffset: 0; }
}
@keyframes pl-draw-3 {
  0%, 23%   { stroke-dashoffset: 1; animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); }
  31%, 100% { stroke-dashoffset: 0; }
}
@keyframes pl-draw-4 {
  0%, 29%   { stroke-dashoffset: 1; animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); }
  36%, 100% { stroke-dashoffset: 0; }
}

/* The drawing holds under the popped card through the presentation
   beat, then the ink fades away beneath it */
@keyframes pl-blueprint {
  0%, 56%   { opacity: 1; animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); }
  68%, 100% { opacity: 0; }
}

/* -- Pop + fold keyframes ---------------------------------------------
   The two leaves open FLAT (A at rotateY 0, B at its resting pose) —
   together they are the parallelogram card the sketch just drew. The
   pop fades them in while the center springs up (scale + lift, soft
   spring overshoot) — the card is "designed out of the drawing".

   Then ONE fold with weight: A rotates +180° about the SVG's 50%
   origin, which IS the crease at x=300 — folding TOWARD the viewer,
   so its plane never crosses B's (rotating −180° sweeps the back
   half-space and slices through B — the source of the old clipping
   glitch). The whole fold is a single cinematic ease-in-out curve —
   slow peel, fast flight, cushioned landing — with a synced
   brightness arc on the moving leaf and a whisper of settle at
   touchdown. That single fold resolves the correct K.

   The center slides left during the fold (translateX only, no
   rotation) so the visual mass stays centered as the card halves. */

@keyframes pl-keep-centered {
  0%, 42% { transform: translateX(0) translateY(12px) scale(0.94, 0.94);
            animation-timing-function: cubic-bezier(0.34, 1.35, 0.64, 1); }  /* sketch phase: small, low → soft spring up */
  58%     { transform: translateX(0) translateY(0) scale(1, 1); } /* POP — the card rises, unhurried */
  64%     { transform: translateX(0) translateY(0) scale(1, 1);
            animation-timing-function: cubic-bezier(0.76, 0, 0.24, 1); } /* beat — then the slide rides the fold curve */
  86%     { transform: translateX(-12.5%) translateY(0) scale(1, 1);
            animation-timing-function: cubic-bezier(0.3, 0, 0.4, 1); }  /* recentred exactly at landing */
  91%     { transform: translateX(-12.5%) translateY(1px) scale(1.006, 0.985);
            animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1); } /* a whisper of settle */
  100%    { transform: translateX(-12.5%) translateY(0) scale(1, 1); } /* at rest — hold on the K */
}

/* Piece A: hidden flat (0–42), materializes gently (42–56), presented
   flat (→64), then ONE cinematic fold (64–86, ease-in-out-quart):
   slow peel off the table, fast through the air, cushioned landing —
   peak angular velocity stays low enough that no frame strobes. Its
   brightness arcs in sync: catches the light mid-flight, dips into
   shadow at touchdown, settles to true paper tone. Holds (→100). */
@keyframes pl-fold-a {
  0%, 42% { opacity: 0; filter: brightness(1); transform: translateZ(2px) rotateY(0deg);
            animation-timing-function: cubic-bezier(0.45, 0, 0.25, 1); } /* unhurried materialize */
  56%     { opacity: 1; }
  64%     { filter: brightness(1); transform: translateZ(2px) rotateY(0deg);
            animation-timing-function: cubic-bezier(0.76, 0, 0.24, 1); } /* one curve: peel → flight → cushion */
  75%     { filter: brightness(1.09);
            animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); }  /* face catches the light mid-flight */
  86%     { filter: brightness(0.97); transform: translateZ(2px) rotateY(180deg);
            animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1); } /* touchdown in its own shadow */
  93%     { filter: brightness(1); }                                     /* light returns as it settles */
  100%    { opacity: 1; filter: brightness(1); transform: translateZ(2px) rotateY(180deg); }
}

/* Piece B: static — only materializes with the card (42–56) */
@keyframes pl-fade-b {
  0%, 42%   { opacity: 0; animation-timing-function: cubic-bezier(0.45, 0, 0.25, 1); }
  56%, 100% { opacity: 1; }
}

/* ================================================================
   HERO ENTRANCE GATING
   Hold the hero's CSS entrance animations at frame 0 while the
   splash is up, so they play fresh once it fades — not behind it.
   ================================================================ */
body.is-preloading .hero-anim-nav,
body.is-preloading .hero__heading .word-inner,
body.is-preloading .hero-anim-sub,
body.is-preloading .hero-anim-tags,
body.is-preloading .hero-anim-tag {
  animation-play-state: paused;
}

/* -- Reduced motion: hold a static folded "K", no draw/fold ------ */
@media (prefers-reduced-motion: reduce) {
  .preloader__center,
  .preloader__piece--a,
  .preloader__piece--b,
  .preloader__shade,
  .preloader__line {
    animation: none;   /* hold the static correct "K" (base transforms) */
  }

  .preloader__blueprint {
    display: none;     /* no sketch lines */
  }

  /* Skip the push-in — cross-fade only */
  .preloader.is-hidden .preloader__stage {
    animation: none;
    transform: none;
    transition: none;
  }
}
