/* STRATEGIC opening sheet: "the mark is drawn".
   A sheet of butter paper lies over the page on the first visit of a session.
   The S is traced in ink over a pencil guide and inked in, the floor is set
   down square by square (e3, d4 f4, c5 g5), STRATEGIC closes in from the
   centre, then "1. e4" is written once the page is ready. The sheet lifts
   away with a sheen and the S settles into the nav logo.

   Markup: src/partials/loader.js (hidden by default). Decision: js/boot.js
   sets html.ld-on before first paint. The build below is pure CSS, so it
   starts on the first painted frame and keeps time while the page below
   starts up; js/loader.js tracks readiness and runs the exit.

   Every curve is a single cubic, so each is exactly its cubic-bezier():
     ink   CustomEase "M0,0 C0.42,0.02 0.18,1 1,1"
     place CustomEase "M0,0 C0.12,0.72 0.26,1 1,1"
     silk  CustomEase "M0,0 C0.22,1 0.36,1 1,1" (the site's --ease)

   States on <html>: ld-on (sheet down), ld-still (reduced motion), ld-go (the
   build may start: the page's scripts have run), ld-run (loader.js took over),
   ld-played (the page is ready: 1. e4), ld-built (the build is done: the
   official path takes over), ld-lift (the exit).

   The ink is drawn on the main thread (stroke-dashoffset, fill-opacity), so the
   build waits for ld-go: until the page's scripts have been parsed and run, the
   paper and the board are laid (compositor-only) and the pen is still. The
   pages' own heavy setup waits until the S is inked (StrategicLoader.afterInk). */

html.ld-on .ld[hidden] { display: block; }
.ld {
  --ldp: #f4f4f1;
  --ldi: #0e0e0e;
  --ld-sq: rgba(14, 14, 14, .045);
  --ld-grain: .05;
  --ld-rank: rgba(14, 14, 14, .2);
  --ld-sh: rgba(255, 255, 255, .62);
  --ld-sh-2: rgba(255, 255, 255, .34);
  --ld-sh-3: rgba(255, 255, 255, .12);
  --ld-shadow: rgba(17, 17, 17, .16);
  --ld-shadow-2: rgba(17, 17, 17, .06);
  --ld-ghost: .075;
  --ld-ink: cubic-bezier(.42, .02, .18, 1);
  --ld-place: cubic-bezier(.12, .72, .26, 1);
  --ld-silk: cubic-bezier(.22, 1, .36, 1);
  /* the lockup: the stacked logo, 942.47 x 596.55 */
  --ld-w: clamp(14rem, 58vw, 22.5rem);
  --ld-b: min(78vmin, 46rem);
  position: fixed; inset: 0; z-index: 2147483000;
  pointer-events: auto; contain: strict;
  perspective: 1800px; perspective-origin: 50% 110%;
  color: var(--ldi);
}
html[data-theme="dark"] .ld {
  --ldp: #1c1c1c;
  --ldi: #ecebe7;
  --ld-sq: rgba(236, 235, 231, .035);
  --ld-grain: .07;
  --ld-rank: rgba(236, 235, 231, .22);
  --ld-sh: rgba(255, 255, 255, .085);
  --ld-sh-2: rgba(255, 255, 255, .045);
  --ld-sh-3: rgba(255, 255, 255, .015);
  --ld-shadow: rgba(0, 0, 0, .55);
  --ld-shadow-2: rgba(0, 0, 0, .3);
  --ld-ghost: .1;
}
/* the same paper under the sheet, so nothing white can show before it paints */
html.ld-on:not(.ld-lift) { background: #f4f4f1; }
html[data-theme="dark"].ld-on:not(.ld-lift) { background: #1c1c1c; }
html.ld-lift .ld { pointer-events: none; }

/* The nav logo waits under the sheet for the S to be set down on it */
html.ld-on:not(.ld-still) .nav-logo { opacity: 0; }
/* a keyboard visitor's first stop, the skip link, is never under the sheet as it goes */
html.ld-on .skip:focus { z-index: 2147483001; }

/* ---------- The sheet ---------- */
/* oversized, so the turn of the lift never uncovers a corner */
.ld-sheet { position: absolute; left: -8vw; right: -8vw; top: -8vh; bottom: -8vh; transform-origin: 0% 100%; will-change: transform; }
.ld-paper { position: absolute; inset: 0; overflow: hidden; background: var(--ldp); }
/* paper grain, the site's own noise tile */
.ld-paper::after { content: ""; position: absolute; inset: 0; background-image: var(--noise); background-size: 160px 160px; opacity: var(--ld-grain); }
html[data-theme="dark"] .ld-paper::after { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 1 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>"); }
/* the soft light that falls across the site's paper */
.ld-paper::before { content: ""; position: absolute; inset: 0; background: radial-gradient(90% 70% at 18% 0%, var(--ld-sh-3), transparent 60%); }

/* the shadow the lifted edge casts on the page, and the edge catching the light */
.ld-cast { position: absolute; left: 0; right: 0; top: 100%; height: 22vh; opacity: 0;
  background: linear-gradient(180deg, var(--ld-shadow) 0%, var(--ld-shadow-2) 22%, transparent 100%); }
.ld-lip { position: absolute; left: 0; right: 0; bottom: 0; height: 26vh; opacity: 0;
  background: linear-gradient(0deg, var(--ld-sh-2) 0%, var(--ld-sh-3) 30%, transparent 100%); }

/* the reflection: a wide feathered highlight drifting across the paper */
.ld-sheen { position: absolute; top: -10%; left: 0; width: 70vw; height: 120%;
  background: radial-gradient(ellipse 50% 50% at 50% 50%, var(--ld-sh) 0%, var(--ld-sh-2) 26%, var(--ld-sh-3) 52%, transparent 76%);
  transform: translate3d(-34vw, 0, 0) rotate(14deg);
  animation: ld-drift 2.6s cubic-bezier(.45, 0, .55, 1) infinite alternate; will-change: transform; }
@keyframes ld-drift { to { transform: translate3d(22vw, 0, 0) rotate(14deg); } }

/* a faint board under the mark, as under every sheet on the site */
.ld-board { position: absolute; left: 50%; top: 50%; width: var(--ld-b); aspect-ratio: 1;
  background: repeating-conic-gradient(var(--ld-sq) 0 25%, transparent 0 50%) 0 0 / 25% 25%;
  -webkit-mask-image: radial-gradient(closest-side, #000 20%, transparent 100%);
  mask-image: radial-gradient(closest-side, #000 20%, transparent 100%);
  transform: translate(-50%, -50%);
  animation: ld-board 1.2s var(--ld-silk) backwards; }
@keyframes ld-board { from { opacity: 0; transform: translate(-50%, -50%) scale(1.06); } }

/* Readiness, rank by rank: a hairline beside the board's middle six files. Each
   rank inks as the page gets ready (DOM, Michroma, Hanken, images, fonts, load). */
.ld-ranks { position: absolute; top: 50%; left: calc(50% - var(--ld-b) * .375 - 14px); height: calc(var(--ld-b) * .75);
  width: 1.5px; transform: translateY(-50%); display: flex; flex-direction: column-reverse; gap: 3px;
  opacity: 0; animation: ld-fade .6s ease-out .2s forwards; }
.ld-ranks i { flex: 1; background: var(--ld-rank); transform: scaleY(0); transform-origin: 50% 100%; transition: transform .38s var(--ld-silk); }
.ld-ranks i.on { transform: scaleY(1); }
@keyframes ld-fade { to { opacity: 1; } }

/* ---------- The lockup ---------- */
.ld-art { position: absolute; left: 50%; top: 50%; width: var(--ld-w); aspect-ratio: 942.47 / 596.55; transform: translate(-50%, -54%); }
.ld-fly { z-index: 1; }
.ld-art svg { position: absolute; display: block; height: auto; overflow: visible; fill: currentColor; }
/* the mark flies in an HTML box, so its flight runs on the compositor */
.ld-mk { position: absolute; display: block; left: 21.865%; top: 0; width: 56.271%; transform-origin: 0 0; }
.ld-art .ld-mk .ld-mark { position: relative; width: 100%; }
.ld-word { left: 0; top: 79.884%; width: 100%; }

/* the pencil guide: the whole mark, faint, which the ink traces over */
.ld-ghost { opacity: 0; animation: ld-ghost 1.15s linear .04s both; }
@keyframes ld-ghost { 0% { opacity: 0; } 30%, 68% { opacity: var(--ld-ghost); } 100% { opacity: 0; } }

/* the S: traced in a hairline of ink, then inked in solid while the line is still wet */
.ld-blade { fill-opacity: 0; stroke: currentColor; stroke-width: 4.4; stroke-linejoin: round; stroke-linecap: round;
  stroke-dasharray: 1 1; stroke-dashoffset: 1;
  animation: ld-trace .5s var(--ld-ink) var(--d) both, ld-ink .16s ease-out calc(var(--d) + .4s) both, ld-dry .22s ease-in calc(var(--d) + .56s) both; }
@keyframes ld-trace { to { stroke-dashoffset: 0; } }
@keyframes ld-ink { to { fill-opacity: 1; } }
@keyframes ld-dry { to { stroke-opacity: 0; } }

/* the floor: each square set down like a tile on the board */
.ld-tile { opacity: 0; animation: ld-place .44s var(--ld-place) var(--d) both; }
@keyframes ld-place { from { opacity: 0; transform: translateY(-26px); } to { opacity: 1; transform: none; } }

/* STRATEGIC closes in from the centre; BHM follows */
.ld-l { opacity: 0; animation: ld-letter .5s var(--ld-silk) var(--d) both; }
@keyframes ld-letter { from { opacity: 0; transform: translateX(var(--dx)); } to { opacity: 1; transform: none; } }

/* 1. e4: the first move, written when the page is ready */
.ld-note { position: absolute; left: 50%; top: calc(100% + 1.4rem); transform: translateX(-50%); white-space: nowrap;
  font-family: var(--display); font-size: .75rem; line-height: 1; letter-spacing: .14em; font-synthesis: none;
  color: var(--ldi); opacity: 0; transition: opacity .5s var(--ld-silk), transform .5s var(--ld-silk); }
html.ld-played .ld-note { opacity: .5; transform: translateX(-50%) translateY(-2px); }

/* the pen waits for the page's scripts (ld-go), so no long task can stop it mid-stroke */
html.ld-on:not(.ld-go) .ld-art svg * { animation-play-state: paused; }

/* the build is done: the official single path takes over (no seam can remain) */
.ld .ld-final { visibility: hidden; }
html.ld-built .ld-final { visibility: visible; }
html.ld-built .ld-parts, html.ld-built .ld-ghost { visibility: hidden; }

/* ---------- Without loader.js: the build still ends, and the sheet fades by itself ----------
   Timed from the sheet's first frame: gone by 2.4s. boot.js removes it when the fade ends. */
html.ld-on:not(.ld-run) .ld-note { animation: ld-note .5s var(--ld-silk) 1s both; }
@keyframes ld-note { to { opacity: .5; } }
html.ld-on:not(.ld-run) .ld { animation: ld-gone .5s ease 1.9s forwards; }
html.ld-on:not(.ld-run) .nav-logo { animation: ld-back .5s ease 1.9s forwards; }
@keyframes ld-gone { to { opacity: 0; visibility: hidden; } }
@keyframes ld-back { to { opacity: 1; } }

/* ---------- Reduced motion: the finished lockup, still; a brief crossfade (loader.js) ---------- */
html.ld-still .ld *, html.ld-still .ld *::before, html.ld-still .ld *::after { animation: none !important; transition: none !important; }
html.ld-still .ld-final, html.ld-still .ld-ranks, html.ld-still .ld-note { visibility: visible; opacity: 1; }
html.ld-still .ld-parts, html.ld-still .ld-ghost { visibility: hidden; }
html.ld-still .ld-l { opacity: 1; }
html.ld-still .ld-note { opacity: .5; }
@media (prefers-reduced-motion: reduce) { .ld *, .ld *::before, .ld *::after { animation: none !important; } }

/* Print and forced colours: never cover the page */
@media print { .ld { display: none !important; } html.ld-on .nav-logo { opacity: 1 !important; } }
@media (forced-colors: active) { .ld { forced-color-adjust: none; } }
