/* Faluf studio site (faluf.com). The page is the farm at night from STILHED's trailer, and the visitor carries the
   light. Motion speaks the trailers' HyperFrames language (a torch beam on the wall, words that come into focus, a line
   drawn out from the centre, text that decodes, a band of light across a title), driven by the pointer and by scrolling
   instead of a timeline (motion.js, hero.js). One typeface, Archivo: the wordmark narrow and heavy, STILHED wide and
   light as in its trailer, statements light, text plain. */

@font-face {
  font-family: "Archivo";
  src: url("fonts/archivo-var-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
}

:root {
  --night: #06080b;
  --ink: #ece4d6;
  --quiet: #a39e95;
  --dim: #75736e;
  --torch: #ffd9a6;
  --ember: #e8a65a;
  --line: rgb(236 228 214 / 14%);
  --gutter: clamp(1.25rem, 5vw, 4rem);
  --out: cubic-bezier(0.16, 1, 0.3, 1);
  color-scheme: dark;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  background: var(--night);
  color: var(--ink);
  font-family: "Archivo", system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  overflow-x: clip;
}

a {
  color: inherit;
}

:focus-visible {
  outline: 2px solid var(--torch);
  outline-offset: 4px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------- what motion.js brings in (and a fallback if scripts never run) ---------- */

[data-split],
[data-reveal],
[data-intro],
.masthead {
  animation: fallback-show 0s 2.5s both;
}

.motion [data-split],
.motion [data-reveal],
.motion [data-intro],
.motion .masthead {
  animation: none;
}

@keyframes fallback-show {
  from {
    opacity: 0;
  }
}

.w,
.ch {
  display: inline-block;
}

/* Words come into focus one after another, as in the trailers' title cards. */
.motion [data-split="words"]:not(.stilhed-tagline) .w {
  opacity: 0;
  filter: blur(10px);
  transform: translateY(0.18em);
  transition: opacity 0.8s var(--out), filter 0.8s var(--out), transform 1s var(--out);
  transition-delay: calc(var(--i, 0) * 90ms);
}

.motion [data-split="words"].is-in .w {
  opacity: 1;
  filter: none;
  transform: none;
}

.motion [data-reveal],
.motion .motto,
.motion .scroll-cue,
.motion .masthead {
  opacity: 0;
  filter: blur(8px);
  transform: translateY(0.75rem);
  transition: opacity 1s var(--out), filter 1s var(--out), transform 1.2s var(--out);
}

.motion [data-reveal].is-in,
.motion .motto.is-in,
.motion .scroll-cue.is-in,
.motion .masthead.is-in {
  opacity: 1;
  filter: none;
  transform: none;
}

/* ---------- masthead ---------- */

.masthead {
  position: fixed;
  inset: 0 0 auto;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: clamp(1rem, 2.4vw, 1.6rem) var(--gutter) 2.5rem;
  pointer-events: none;
}

.masthead::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to bottom, rgb(6 8 11 / 92%), rgb(6 8 11 / 0%));
  opacity: 0;
  transition: opacity 0.5s ease;
}

.masthead.is-scrolled::before {
  opacity: 1;
}

.masthead > * {
  pointer-events: auto;
}

.wordmark {
  font-size: 1.5rem;
  font-weight: 800;
  font-stretch: 62%;
  letter-spacing: 0.04em;
  text-decoration: none;
}

.nav {
  display: flex;
  gap: clamp(1.1rem, 2.6vw, 2.4rem);
  font-size: 0.9375rem;
}

.nav a {
  color: var(--quiet);
  text-decoration: none;
  transition: color 0.25s ease;
}

.nav a:hover {
  color: var(--ink);
}

/* ---------- the hero: the wall, and the visitor's torch ---------- */

.hero {
  position: relative;
  height: 100svh;
  min-height: 34rem;
  overflow: hidden;
  background: var(--night);
}

.hero-wall {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  touch-action: pan-y;
}

/* Without WebGL: a plain warm beam that still follows the pointer. */
.hero.no-webgl {
  background:
    radial-gradient(circle 24rem at var(--bx, 30%) var(--by, 45%), rgb(255 217 166 / 16%), transparent 70%),
    linear-gradient(#0b0f14, var(--night));
}

.hero-text {
  position: absolute;
  bottom: clamp(7rem, 17vh, 10rem);
  left: var(--gutter);
  z-index: 2;
  max-width: min(48rem, calc(100vw - 2 * var(--gutter)));
  pointer-events: none;
}

/* A soft darkness behind the words keeps them readable when the beam passes behind them. */
.hero-text::before {
  content: "";
  position: absolute;
  inset: -35% -25% -35% -40%;
  z-index: -1;
  background: radial-gradient(closest-side, rgb(3 4 6 / 72%), transparent);
}

.statement {
  margin: 0;
  font-size: clamp(2.5rem, 6.4vw, 6.25rem);
  font-weight: 300;
  line-height: 1.03;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

.motto {
  margin: 1.5rem 0 0;
  color: var(--quiet);
  font-size: clamp(1.05rem, 1.5vw, 1.3rem);
}

.scroll-cue {
  position: absolute;
  bottom: 1.25rem;
  left: 50%;
  z-index: 2;
  display: grid;
  place-items: start center;
  width: 2.75rem;
  height: 3.75rem;
  margin-left: -1.375rem;
}

.scroll-cue span {
  width: 1px;
  height: 3rem;
  background: linear-gradient(var(--ink), transparent);
  transform-origin: top;
  animation: cue 2.6s var(--out) infinite;
}

@keyframes cue {
  0% {
    opacity: 0.7;
    transform: scaleY(0);
  }

  60% {
    opacity: 0.7;
    transform: scaleY(1);
  }

  100% {
    opacity: 0;
    transform: scaleY(1);
  }
}

/* ---------- STILHED: its trailer's end card, played by scrolling ---------- */

.stilhed-scene {
  position: relative;
  height: 230vh;
}

.stilhed-stage {
  position: sticky;
  top: 0;
  display: grid;
  place-items: center;
  height: 100svh;
  overflow: hidden;
}

/* The farm sits a little low, so the title has the night sky above the roofs to itself. */
.stilhed-art {
  position: absolute;
  inset: 11% 0 0;
  width: 100%;
  height: 89%;
  object-fit: cover;
  object-position: 50% 62%;
  transform-origin: 50% 70%;
  will-change: transform, opacity;
}

.stilhed-stage::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to bottom, var(--night) 8%, rgb(6 8 11 / 35%) 26%, rgb(6 8 11 / 0%) 44%, rgb(6 8 11 / 0%) 56%, rgb(6 8 11 / 80%) 80%, var(--night) 100%);
  pointer-events: none;
}

.stilhed-card {
  position: relative;
  z-index: 1;
  text-align: center;
  transform: translateY(-26svh);
}

.stilhed-title {
  margin: 0 -0.32em 0 0;
  font-size: clamp(2.4rem, 8.4vw, 8rem);
  font-weight: 250;
  font-stretch: 125%;
  line-height: 1.1;
  letter-spacing: 0.32em;
}

.stilhed-title .ch {
  color: color-mix(in srgb, var(--ink), var(--torch) calc(var(--g, 0) * 70%));
  text-shadow: 0 0 calc(var(--g, 0) * 2.5rem) rgb(255 217 166 / calc(var(--g, 0) * 85%));
  opacity: var(--o, 0);
}

.stilhed-tagline {
  margin: 1.5rem -0.42em 0 0;
  font-size: clamp(0.8rem, 1.45vw, 1.3rem);
  font-weight: 400;
  font-stretch: 112%;
  letter-spacing: 0.42em;
  text-transform: uppercase;
}

.stilhed-tagline .w {
  filter: blur(calc((1 - var(--o, 0)) * 8px));
  opacity: var(--o, 0);
}

.stilhed-rule {
  display: block;
  width: min(22rem, 46vw);
  height: 1px;
  margin: 2.25rem auto 0;
  background: rgb(236 228 214 / 40%);
  transform: scaleX(var(--r, 0));
}

.stilhed-status {
  min-height: 1.5em;
  margin: 1.5rem -0.62em 0 0;
  color: rgb(236 228 214 / 72%);
  font-size: clamp(0.68rem, 0.95vw, 0.875rem);
  font-weight: 500;
  font-stretch: 125%;
  letter-spacing: 0.62em;
  text-transform: uppercase;
  white-space: pre;
}

.stilhed-more {
  position: relative;
  z-index: 1;
  max-width: 46rem;
  margin: -24vh auto 0;
  padding: 0 var(--gutter) clamp(6rem, 13vw, 10rem);
  text-align: center;
}

.stilhed-pitch {
  margin: 0;
  font-size: clamp(1.15rem, 1.8vw, 1.45rem);
  line-height: 1.6;
}

.stilhed-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 1.25rem 2rem;
  margin-top: 2.5rem;
}

.stilhed-steam {
  margin: 1.75rem 0 0;
  color: var(--quiet);
}

.button {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  padding: 1rem 1.8rem 1rem 1.4rem;
  border: 1px solid var(--ember);
  border-radius: 3rem;
  background: rgb(232 166 90 / 8%);
  color: var(--ink);
  font: inherit;
  font-size: 1.0625rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.3s ease, color 0.3s ease, transform 0.5s var(--out);
}

.button:hover {
  background: var(--ember);
  color: var(--night);
}

.button-icon {
  width: 1.25rem;
  height: 1.25rem;
  fill: currentColor;
}

.text-link {
  display: inline-block;
  color: var(--quiet);
  text-underline-offset: 0.3em;
  transition: color 0.25s ease, transform 0.5s var(--out);
}

.text-link:hover {
  color: var(--ink);
}

/* ---------- concepts ---------- */

.concepts,
.studio,
.contact {
  padding: clamp(6rem, 12vw, 10rem) var(--gutter);
}

.section-head {
  max-width: 42rem;
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
}

.section-title {
  margin: 0;
  font-size: clamp(2.2rem, 5vw, 4.25rem);
  font-weight: 300;
  line-height: 1.05;
  letter-spacing: -0.01em;
}

.section-note {
  margin: 1.1rem 0 0;
  color: var(--quiet);
  font-size: 1.125rem;
  line-height: 1.6;
}

.concept-list {
  display: flex;
  gap: clamp(0.75rem, 1.4vw, 1.25rem);
  height: clamp(26rem, 64vh, 40rem);
  margin: 0;
  padding: 0;
  list-style: none;
}

.concept {
  flex: 1 1 0;
  min-width: 0;
  transition: flex-grow 0.8s var(--out);
}

.concept-card {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  height: 100%;
  container-type: inline-size;
  padding: clamp(1.25rem, 2.2vw, 2rem);
  overflow: hidden;
  border-radius: 0.375rem;
  color: var(--ink);
  text-decoration: none;
  transform: perspective(1100px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform 0.7s var(--out);
  isolation: isolate;
}

.concept-card.is-tilting {
  transition: transform 0.12s linear;
}

/* Keyboard focus takes the concept's own colour. */
.concept-card:focus-visible {
  outline-color: var(--c);
}

.concept-media,
.concept-media img,
.concept-media video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.concept-media {
  z-index: -1;
  background: var(--c-bg);
}

.concept-media img,
.concept-media video {
  object-fit: cover;
  transition: transform 1.2s var(--out), opacity 0.6s ease;
}

.concept-media video {
  opacity: 0;
}

.concept.is-playing .concept-media video {
  opacity: 1;
}

.concept-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgb(0 0 0 / 85%), rgb(0 0 0 / 20%) 50%, rgb(0 0 0 / 0%) 75%);
}

/* The glint: light on the card follows the pointer. */
.concept-glint {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: radial-gradient(circle 20rem at var(--gx, 50%) var(--gy, 40%), rgb(255 240 220 / 18%), transparent 65%);
  opacity: 0;
  transition: opacity 0.5s ease;
}

/* Names size with their card (cqi), so a narrow card never clips its name. */
.concept-name {
  display: inline-block;
  align-self: flex-start;
  font-size: clamp(1.4rem, 10cqi, 2.6rem);
  line-height: 1;
}

.concept-line {
  max-width: 26rem;
  margin-top: 0.75rem;
  color: rgb(236 228 214 / 82%);
  font-size: 1rem;
  line-height: 1.5;
}

/* Each concept keeps the cut of Archivo its own page uses (services/concepts). */
.wordmark-deepwater {
  font-size: clamp(1.3rem, 8.4cqi, 2.4rem);
  font-weight: 500;
  font-stretch: 112%;
  letter-spacing: 0.16em;
}

.wordmark-outclimb {
  font-size: clamp(1.8rem, 13cqi, 3.3rem);
  font-weight: 900;
  font-stretch: 62%;
  letter-spacing: -0.01em;
}

.wordmark-sendline {
  font-weight: 800;
  font-stretch: 125%;
  letter-spacing: 0.02em;
  transform: skewX(-9deg);
  transform-origin: left bottom;
}

@media (hover: hover) and (pointer: fine) {
  .concept:hover,
  .concept:focus-within {
    flex-grow: 1.9;
  }

  .concept-card:hover .concept-glint {
    opacity: 1;
  }

  .concept-card:hover .concept-media img,
  .concept-card:hover .concept-media video {
    transform: scale(1.04);
  }
}

/* ---------- the studio: how we make games ---------- */

.principles {
  margin: clamp(2.5rem, 5vw, 4rem) 0 0;
  padding: 0;
  list-style: none;
}

/* One fixed size and cut; each line comes into focus once as it scrolls into view (data-reveal), like the rest. */
.principles li {
  color: var(--ink);
  font-size: clamp(1.65rem, 4.4vw, 4.6rem);
  font-weight: 280;
  font-stretch: 120%;
  line-height: 1.12;
  letter-spacing: 0.005em;
  white-space: nowrap;
}

/* ---------- contact ---------- */

.contact {
  padding-bottom: clamp(5rem, 9vw, 7rem);
}

.contact-mail {
  display: inline-block;
  margin-top: 1.25rem;
  font-size: clamp(2.2rem, 7.4vw, 7.25rem);
  font-weight: 300;
  letter-spacing: -0.02em;
  text-decoration: none;
  transition: transform 0.5s var(--out);
}

/* On hover a band of torchlight runs through the address letter by letter, like the band that lights STILHED. */
.contact-mail:hover .ch,
.contact-mail:focus-visible .ch {
  animation: catch-light 1.4s ease-in-out calc(var(--i, 0) * 45ms) both;
}

@keyframes catch-light {
  30%,
  45% {
    color: var(--torch);
    text-shadow: 0 0 1.5rem rgb(255 217 166 / 55%);
  }
}

.footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.5rem 2rem;
  padding: 2rem var(--gutter) 2.5rem;
  border-top: 1px solid var(--line);
  color: var(--quiet);
  font-size: 0.9375rem;
}

.footer p {
  margin: 0;
}

/* ---------- the theatre: STILHED's trailer over the page, in the Faluf player ---------- */

.theatre {
  width: 100vw;
  max-width: none;
  height: 100dvh;
  max-height: none;
  margin: 0;
  padding: 0;
  overflow: hidden;
  border: 0;
  background: #000;
  color: var(--ink);
}

.theatre::backdrop {
  background: #000;
}

.theatre[open] {
  animation: theatre-in 0.7s var(--out);
}

@keyframes theatre-in {
  from {
    opacity: 0;
    filter: blur(14px);
    transform: scale(1.03);
  }
}

.theatre-stage {
  --player-accent: var(--ember);
  --player-ink: var(--ink);
  position: relative;
  width: 100%;
  height: 100%;
}

.theatre-video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #000;
}

.theatre-close {
  position: absolute;
  top: clamp(0.75rem, 2vw, 1.25rem);
  right: clamp(0.75rem, 2vw, 1.25rem);
  z-index: 5;
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border: 1px solid rgb(236 228 214 / 28%);
  border-radius: 50%;
  background: rgb(0 0 0 / 45%);
  color: var(--ink);
  cursor: pointer;
  transition: background-color 0.2s ease, opacity 0.6s ease;
}

.theatre-close:hover {
  background: rgb(255 255 255 / 14%);
}

.theatre-close svg {
  width: 1.25rem;
  height: 1.25rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
}

.theatre:has(.player.is-idle) .theatre-close {
  opacity: 0;
}

/* ---------- the visitor's light, and the sound of a click ---------- */

.lantern {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 30;
  width: 36rem;
  height: 36rem;
  margin: -18rem 0 0 -18rem;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgb(255 217 166 / 7%), rgb(255 217 166 / 2.5%) 55%, transparent);
  opacity: 0;
  pointer-events: none;
  mix-blend-mode: screen;
  transition: opacity 0.6s ease;
}

.lantern.is-on {
  opacity: 1;
}

.ripple {
  position: fixed;
  z-index: 40;
  width: 15rem;
  height: 15rem;
  margin: -7.5rem 0 0 -7.5rem;
  border: 1px solid rgb(255 217 166 / 60%);
  border-radius: 50%;
  pointer-events: none;
  animation: ripple 0.9s var(--out) forwards;
}

@keyframes ripple {
  from {
    opacity: 1;
    transform: scale(0.04);
  }

  to {
    opacity: 0;
    transform: scale(1);
  }
}

/* ---------- small screens ---------- */
/* No prefers-reduced-motion branch: the site animates whatever the visitor's system setting says (client,
   2026-10-31: "ignore user's windows animation settings, and animate so they can see it"). */

@media (max-width: 47.99rem) {
  .nav-wide {
    display: none;
  }

  .concept-list {
    flex-direction: column;
    height: auto;
  }

  .concept-card {
    height: max(19rem, 62vw);
  }

  .principles li {
    white-space: normal;
  }
}
