/* WYLD demo — header, mega menu, footer, transitions, cursor */

/* ---------- header ---------- */
/* Transparent over the hero, then a solid ground once scrolled: the nav sits on
   photography at the top of a page and on flat colour everywhere after, so the
   type is legible on both without a scrim over the opening image. */
.hdr {
  position: fixed; inset: 0 0 auto 0; z-index: 500;
  height: var(--header-h);
  display: flex; align-items: center;
  color: var(--bone);
  background: transparent;
  transition: color .4s ease, background-color .4s ease;
}
.hdr.is-stuck { background: var(--ink); }
.hdr.is-stuck.is-light { background: var(--bone); }
.hdr::after {
  content: ''; position: absolute; inset: auto 0 0 0; height: 1px;
  background: var(--line-d); transition: background-color .4s ease;
  opacity: 0; transition: opacity .4s ease, background-color .4s ease;
}
.hdr.is-stuck::after { opacity: 1; }
.hdr.is-light { color: var(--ink); }
.hdr.is-light::after { background: var(--line); }

.hdr__in { display: flex; align-items: center; justify-content: space-between; gap: clamp(14px, 2.4vw, 40px); }

/* The supplied mark is dark ink on transparent, so it inverts to bone on the
   dark ground and sits as-is on the light one. */
.mark { display: block; flex: 0 0 auto; }
.mark__img { width: clamp(96px, 9vw, 132px); height: auto; filter: invert(1); transition: filter .4s ease; }
.hdr.is-light .mark__img { filter: none; }
/* The header suppresses its own transition for the opening state, and the mark
   has to follow suit or it inverts a beat behind the type. */
.hdr.is-init, .hdr.is-init .mark__img, .hdr.is-init::after { transition: none; }

.nav { display: flex; align-items: center; gap: clamp(14px, 2vw, 34px); }
.nav__i { position: relative; padding-block: 6px; white-space: nowrap; }
.nav__i::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: currentColor; transform: scaleX(0); transform-origin: left;
  transition: transform .45s var(--ease);
}
.nav__i:hover::after { transform: scaleX(1); }

/* Items are framed rather than underlined: the same four focus brackets the
   cursor uses, so "where you are" and "what you are pointing at" speak one
   language. Every item carries the brackets so hovering cannot shift the row;
   only their opacity changes. Static, not hunting — a header is no place for a
   permanent animation. */
.nav__i { padding-inline: 5px; }
.nav__i::after { display: none; }
.nav__b {
  position: absolute; width: 6px; height: 6px;
  border: 0 solid currentColor; pointer-events: none;
  opacity: 0; transform: scale(.7);
  transition: opacity .26s var(--ease), transform .3s var(--ease);
}
/* The brackets hunt inward before they settle, the way a lens racks to focus:
   they arrive from slightly outside the box and land on it. */
.nav__i:hover .nav__b, .nav__i:focus-visible .nav__b { opacity: .75; transform: scale(1); }
.nav__i.is-here .nav__b { opacity: 1; transform: scale(1); }
.nav__b--tl { --hx: -3px; --hy: -3px; }
.nav__b--tr { --hx:  3px; --hy: -3px; }
.nav__b--bl { --hx: -3px; --hy:  3px; }
.nav__b--br { --hx:  3px; --hy:  3px; }
.nav__b { transform: translate(var(--hx), var(--hy)) scale(.7); }
.nav__i:hover .nav__b, .nav__i:focus-visible .nav__b, .nav__i.is-here .nav__b { transform: translate(0, 0) scale(1); }

/* The cursor's cage, scaled onto the label and dropped in strength: two
   verticals and two horizontals on the thirds, 1.5px, spanning the full box.
   Real elements rather than a background layer — a negative z-index put it
   behind the header's own ground and made it invisible. */
.nav__gr { position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity .3s var(--ease); }
.nav__i:hover .nav__gr, .nav__i:focus-visible .nav__gr { opacity: .16; }
.nav__i.is-here .nav__gr { opacity: .2; }
.nav__gr i { position: absolute; background: currentColor; }
.nav__gr i:nth-child(1) { left: 33.333%; top: 0; bottom: 0; width: 1.5px; }
.nav__gr i:nth-child(2) { left: 66.666%; top: 0; bottom: 0; width: 1.5px; }
.nav__gr i:nth-child(3) { top: 33.333%; left: 0; right: 0; height: 1.5px; }
.nav__gr i:nth-child(4) { top: 66.666%; left: 0; right: 0; height: 1.5px; }
/* one rack cycle when the frame first arrives, then it holds */
.nav__i.is-focusing .nav__b { animation: navRack .52s var(--ease); }
@keyframes navRack {
  0%   { transform: translate(calc(var(--hx) * 2.2), calc(var(--hy) * 2.2)) scale(.7); }
  58%  { transform: translate(calc(var(--hx) * -.45), calc(var(--hy) * -.45)) scale(1.04); }
  100% { transform: translate(0, 0) scale(1); }
}

.nav__b--tl { top: -2px; left: -4px;  border-top-width: 1.5px; border-left-width: 1.5px; }
.nav__b--tr { top: -2px; right: -4px; border-top-width: 1.5px; border-right-width: 1.5px; }
.nav__b--bl { bottom: -2px; left: -4px;  border-bottom-width: 1.5px; border-left-width: 1.5px; }
.nav__b--br { bottom: -2px; right: -4px; border-bottom-width: 1.5px; border-right-width: 1.5px; }
.hdr__end { display: flex; align-items: center; gap: clamp(12px, 1.6vw, 22px); }
.hdr__cta { border: 1px solid currentColor; padding: 9px 15px; transition: opacity .3s ease; }
.hdr__cta:hover { opacity: .66; }

.burger { display: none; width: 30px; height: 30px; position: relative; flex: 0 0 auto; }
.burger i { position: absolute; left: 4px; right: 4px; height: 1px; background: currentColor; transition: transform .4s var(--ease); }
.burger i:first-child { top: 13px; }
.burger i:last-child { top: 19px; }
.burger[aria-expanded="true"] i:first-child { transform: translateY(3px) rotate(45deg); }
.burger[aria-expanded="true"] i:last-child { transform: translateY(-3px) rotate(-45deg); }

@media (max-width: 940px) {
  .nav, .hdr__cta { display: none; }
  .burger { display: block; }
}

/* ---------- mobile drawer ---------- */
.drawer {
  position: fixed; inset: 0; z-index: 470;
  background: var(--ink-2); color: var(--bone);
  padding: calc(var(--header-h) + 14px) var(--gutter) clamp(24px, 5vh, 48px);
  display: grid; align-content: space-between; gap: 30px;
  clip-path: inset(0 0 100% 0); visibility: hidden;
  transition: clip-path .55s var(--ease);
  overflow-y: auto;
}
.drawer.is-open { clip-path: inset(0 0 0 0); visibility: visible; }
.drawer__nav { display: grid; gap: 0; }
.drawer__i {
  font-family: var(--f-display); font-size: clamp(1.5rem, 6.4vw, 2.3rem);
  line-height: 1.12; letter-spacing: -.025em; font-weight: 300;
  padding-block: 13px; border-bottom: 1px solid var(--line-d);
  display: flex; align-items: baseline; gap: 14px;
}
.drawer__i > span { font-family: var(--f-mono); font-size: 10px; letter-spacing: .16em; color: var(--stone); }
.js .drawer__i, .js .drawer__foot { opacity: 0; transform: translateY(14px); transition: opacity .5s var(--ease), transform .5s var(--ease); transition-delay: calc(var(--i,0) * 55ms + 120ms); }
.drawer.is-open .drawer__i, .drawer.is-open .drawer__foot { opacity: 1; transform: none; }
.drawer__foot { display: grid; gap: 18px; }
@media (min-width: 941px) { .drawer { display: none; } }
@media (prefers-reduced-motion: reduce) { .drawer { transition: none; } }

/* ---------- social row ---------- */
.soc { display: flex; align-items: center; gap: 9px; }
.soc a {
  width: 38px; height: 38px; display: grid; place-items: center;
  border: 1px solid currentColor; opacity: .6;
  transition: opacity .3s ease;
}
.soc a:hover { opacity: 1; }
.soc svg { width: 15px; height: 15px; fill: currentColor; display: block; }

/* ---------- footer ---------- */
.ftr { background: var(--ink); color: var(--bone); padding-top: clamp(64px, 10vh, 132px); overflow: hidden; }
.ftr__grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: var(--colgap); padding-bottom: clamp(48px, 7vh, 96px); }
.ftr__mark { width: clamp(110px, 11vw, 150px); height: auto; filter: invert(1); margin-bottom: 22px; }
.ftr__col > .m { color: var(--stone); margin-bottom: 18px; }
.ftr__list { display: grid; gap: 9px; }
.ftr__list a { color: rgba(241,237,228,.74); transition: color .3s ease; font-size: .9375rem; }
.ftr__list a:hover { color: var(--bone); }
.news { display: flex; border-bottom: 1px solid var(--line-d); max-width: 400px; }
.news input {
  flex: 1; background: none; border: 0; color: var(--bone);
  font-family: var(--f-mono); font-size: 12px; letter-spacing: .1em; padding: 12px 0;
}
.news input::placeholder { color: var(--stone); text-transform: uppercase; letter-spacing: .14em; font-size: 11px; }
.news button { padding: 12px 0 12px 16px; }
.wordmark {
  font-family: var(--f-display); font-weight: 300;
  font-size: 25.5vw; line-height: .74; letter-spacing: -.045em;
  display: block; margin-bottom: -.14em; user-select: none;
}
.ftr__base { display: flex; flex-wrap: wrap; gap: 10px 28px; justify-content: space-between; padding-block: 18px; border-top: 1px solid var(--line-d); }
@media (max-width: 900px) { .ftr__grid { grid-template-columns: 1fr 1fr; row-gap: 42px; } }
@media (max-width: 560px) { .ftr__grid { grid-template-columns: 1fr; row-gap: 34px; } .wordmark { font-size: 31vw; } }

/* ---------- page transition panel ---------- */
.trans {
  position: fixed; inset: 0; z-index: 800; background: var(--bone);
  transform: translateY(-100%); pointer-events: none;
  display: grid; place-items: center;
}
.trans__mark { width: clamp(120px, 15vw, 210px); height: auto; }
.trans.is-in { transform: translateY(0); transition: transform .34s cubic-bezier(.7,0,.84,0); }
.trans.is-out { transform: translateY(-100%); transition: transform .38s var(--ease); }

/* ---------- load sequence ---------- */
.pre { position: fixed; inset: 0; z-index: 850; background: var(--ink); }
.pre__panel {
  position: absolute; inset: 0; background: var(--bone); transform: translateY(0);
  display: grid; align-content: center; justify-items: center; gap: 18px;
}
/* The mark is wiped in rather than faded: a hard edge travelling across the
   letterforms reads as a shutter opening, and costs one clip-path. */
.pre__mark {
  width: clamp(150px, 21vw, 290px); height: auto; opacity: .92;
  clip-path: inset(0 100% 0 0);
  animation: markIn .86s var(--ease) .06s forwards;
}
@keyframes markIn { to { clip-path: inset(0 0 0 0); } }

.pre__line {
  width: clamp(150px, 21vw, 290px); height: 1px; background: var(--ink);
  opacity: .22; transform: scaleX(0); transform-origin: left;
  animation: lineIn .8s var(--ease) .1s forwards;
}
@keyframes lineIn { to { transform: scaleX(1); } }
.pre.is-done .pre__panel { transform: translateY(-100%); transition: transform .82s var(--ease); }
.pre.is-done .pre__mark, .pre.is-done /* The loader is a viewfinder firing the shutter. Frames from the site flash
   through it, each tracking as if panning on a moving animal, with a curtain
   sweeping between them. Built from real photographs and CSS rectangles — an
   illustrated animal would read as clip art and undercut the photography. */
.pre__stage {
  position: relative; width: clamp(190px, 26vw, 330px); aspect-ratio: 3/2;
  overflow: hidden; background: rgba(var(--ink-rgb), .06);
  outline: 1px solid rgba(var(--ink-rgb), .2);
}
.pre__f {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transform: scale(1.12);
}

/* A running big cat, told by what it leaves behind. Anatomy drawn by hand in
   SVG reads as clip art; a pugmark is five ellipses, which SVG renders cleanly.
   The prints land in a bounding-gait rhythm — two, pause, two — so the trail
   has the cadence of an animal at speed rather than a walk. */
.pre__trail { position: absolute; inset: 0; width: 100%; height: 100%; }
.pre__pug {
  opacity: 0;
  transform-box: fill-box; transform-origin: center;
  animation: pugIn .42s var(--ease) forwards;
  animation-delay: var(--d, 0ms);
}
@keyframes pugIn {
  0%   { opacity: 0; transform: translateY(4px) scale(.72); }
  55%  { opacity: .95; transform: translateY(0) scale(1.06); }
  100% { opacity: .78; transform: translateY(0) scale(1); }
}
.pre__trail.is-out { opacity: 0; transition: opacity .3s ease; }
.pre__f.is-on { opacity: 1; animation: track 1.15s var(--ease) forwards; }
@keyframes track {
  from { transform: scale(1.12) translateX(2.5%); }
  to   { transform: scale(1) translateX(0); }
}
/* focal-plane curtain: one blade crossing the frame */
.pre__curtain { position: absolute; inset: 0; background: var(--bone); transform: translateY(-101%); }
.pre__curtain.is-fire { animation: curtain .34s ease-in forwards; }
@keyframes curtain {
  0%   { transform: translateY(-101%); }
  46%  { transform: translateY(0); }
  100% { transform: translateY(101%); }
}
.pre__ro { color: var(--stone); }

.pre__line { opacity: 0; transition: opacity .34s ease; }
.pre--brief.is-done .pre__panel { transition: transform .62s var(--ease); }
.pre.is-done { pointer-events: none; }
.pre.is-gone { display: none; }
.pre__count { position: absolute; left: var(--gutter); bottom: clamp(24px, 5vh, 48px); color: var(--ink); }
.pre--brief .pre__count { display: none; }
.pre.is-done .pre__count { opacity: 0; transition: opacity .3s ease; }

/* ---------- cursor: a viewfinder ----------
   Corner brackets alone read as a crop tool, so the frame also carries a
   rule-of-thirds live-view grid and a centre reticle. Idle, it hunts focus the
   way a lens does in low light and the grid fades up. Moving, the frame snaps
   tight, the grid drops away and a second frame lags behind it — the lag is the
   motion blur. Hairlines and mono type only; nothing is drawn. */
.vf, .vf-ghost {
  position: fixed; top: 0; left: 0; z-index: 700; pointer-events: none;
  width: 0; height: 0;
  mix-blend-mode: difference; color: var(--bone);
}
.vf { opacity: 0; transition: opacity .25s ease; }
.vf.is-shown { opacity: 1; }
.vf.is-off { opacity: 0; }
.vf-ghost { opacity: 0; }

.vf__cage { position: absolute; inset: 0; transform: scale(1); transition: transform .4s var(--ease); }
.vf:not(.is-moving) .vf__cage { animation: hunt 2.8s ease-in-out infinite; }
.vf.is-moving .vf__cage { transform: scale(.86); }
.vf.is-drag .vf__cage { transform: scale(1.9); animation: none; }
.vf.is-link .vf__cage { transform: scale(1.32); animation: none; }
@keyframes hunt {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.14); }
}

/* focus brackets */
.vf__b { position: absolute; width: 9px; height: 9px; border: 0 solid currentColor; }
.vf__b--tl { border-top-width: 2px; border-left-width: 2px;  transform: translate(-20px, -20px); }
.vf__b--tr { border-top-width: 2px; border-right-width: 2px; transform: translate(12px, -20px); }
.vf__b--bl { border-bottom-width: 2px; border-left-width: 2px;  transform: translate(-20px, 12px); }
.vf__b--br { border-bottom-width: 2px; border-right-width: 2px; transform: translate(12px, 12px); }

/* rule-of-thirds grid — the live-view tell */
.vf__g { position: absolute; background: currentColor; opacity: .58; transition: opacity .3s ease; }
.vf__g--v { width: 1.5px; height: 40px; }
.vf__g--h { width: 40px; height: 1.5px; }
.vf__g--v1 { transform: translate(-7px, -20px); }
.vf__g--v2 { transform: translate(6px, -20px); }
.vf__g--h1 { transform: translate(-20px, -7px); }
.vf__g--h2 { transform: translate(-20px, 6px); }
.vf.is-moving .vf__g, .vf.is-link .vf__g { opacity: 0; }

/* centre reticle */
.vf__x { position: absolute; background: currentColor; }
.vf__x--v { width: 2px; height: 8px; transform: translate(-.5px, -4px); }
.vf__x--h { width: 8px; height: 2px; transform: translate(-4px, -.5px); }

.vf__r {
  position: absolute; left: 30px; top: -6px; white-space: nowrap;
  font-family: var(--f-mono); font-size: 9px; font-weight: 400;
  letter-spacing: .16em; text-transform: uppercase;
  font-variant-numeric: tabular-nums; opacity: 1; font-weight: 500;
  transition: opacity .25s ease;
}
.vf.is-link .vf__r { opacity: 0; }

@media (pointer: coarse) { .vf, .vf-ghost { display: none; } }

@media (prefers-reduced-motion: reduce) {
  .vf, .vf-ghost, .pre { display: none !important; }
}
