/* Godfrey Engineering — holding page.
   Zero JS: every motion here is a CSS keyframe, which is what lets the CSP
   below stay at `script-src 'none'`. Timings are deliberately long — the
   house style is slow and cinematic, never busy. */

@font-face {
  font-family: 'Inter';
  src: url('/fonts/inter-latin-wght-normal.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-display: swap;
  font-style: normal;
}

@font-face {
  font-family: 'JetBrains Mono';
  src: url('/fonts/jetbrains-mono-latin-wght-normal.woff2') format('woff2-variations');
  font-weight: 100 800;
  font-display: swap;
  font-style: normal;
}

:root {
  /* #FF5E1A — sampled from the logomark itself, not eyeballed. */
  --brand: oklch(66% 0.204 42);
  --brand-hot: oklch(76% 0.17 52);
  --brand-deep: oklch(52% 0.18 38);

  --bg: oklch(13% 0.008 42);
  --fg: oklch(94% 0.008 60);
  --fg-muted: oklch(66% 0.014 50);
  /* 63%, not the 48% this started at: measured against the composited
     backdrop, 48% gave the footer only 3.09:1 and WCAG AA wants 4.5:1. */
  --fg-faint: oklch(63% 0.014 50);

  --mark-w: clamp(9rem, 26vw, 15rem);
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
}

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

html {
  height: 100%;
}

body {
  /* min-height, not height, and never `overflow: hidden`: on a landscape phone
     the content is taller than the viewport, and hiding the overflow put the
     statutory company details permanently out of reach. It scrolls instead. */
  min-height: 100%;
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  display: grid;
  grid-template-rows: 1fr auto;
  /* computes overflow-y to auto, so tall content stays reachable */
  overflow-x: hidden;
}

@supports (min-height: 100dvh) {
  body {
    min-height: 100dvh;
  }
}

/* ── Backdrop ─────────────────────────────────────────────────────────── */

/* Blueprint grid. Oversized and drifting so the loop never shows an edge. */
.grid {
  position: fixed;
  inset: -50%;
  background-image:
    linear-gradient(to right, oklch(70% 0.03 45 / 0.05) 1px, transparent 1px),
    linear-gradient(to bottom, oklch(70% 0.03 45 / 0.05) 1px, transparent 1px);
  background-size: 64px 64px;
  animation: drift 90s linear infinite;
  will-change: transform;
}

@keyframes drift {
  from {
    transform: translate3d(0, 0, 0);
  }
  to {
    transform: translate3d(64px, 64px, 0);
  }
}

/* Warms the centre and lets the grid fall away at the edges. */
.vignette {
  position: fixed;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 90% 70% at 50% 42%, oklch(30% 0.06 42 / 0.5), transparent 70%),
    radial-gradient(ellipse 120% 100% at 50% 50%, transparent 30%, var(--bg) 78%);
}

/* ── Stage ────────────────────────────────────────────────────────────── */

.stage {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0;
  padding: 2rem 1.5rem;
  text-align: center;
}

.lockup {
  position: relative;
  width: var(--mark-w);
  /* Matches the trimmed logomark's own 462×242 bbox. */
  aspect-ratio: 462 / 242;
  margin-bottom: 2.75rem;
  animation: rise 1.6s var(--ease-out) both;
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Soft amber bloom behind the mark — breathes slowly, 10s. */
.halo {
  position: absolute;
  inset: -60% -35%;
  background: radial-gradient(ellipse at center, oklch(60% 0.19 42 / 0.4), transparent 65%);
  filter: blur(18px);
  animation: breathe 10s ease-in-out infinite;
  will-change: opacity, transform;
}

@keyframes breathe {
  0%,
  100% {
    opacity: 0.55;
    transform: scale(0.97);
  }
  50% {
    opacity: 0.9;
    transform: scale(1.03);
  }
}

/* The mark: the PNG is used purely as a mask, so the fill is live colour
   and the shine can be clipped to the glyph. */
.mark {
  position: absolute;
  inset: 0;
  background: linear-gradient(155deg, var(--brand-hot) 0%, var(--brand) 52%, var(--brand-deep) 100%);
  -webkit-mask: url('/logomark.png') center / contain no-repeat;
  mask: url('/logomark.png') center / contain no-repeat;
  overflow: hidden;
  filter: drop-shadow(0 0 22px oklch(60% 0.2 42 / 0.35));
}

/* Specular sweep. Long dwell, quick pass — 9s round trip.
   Width is pinned to the mark on purpose: translateX resolves against this
   element's OWN width, so a wider box silently throws the highlight off the
   glyph entirely. At 100% width, ±120% is exactly "just off each edge". */
.mark::after {
  content: '';
  position: absolute;
  top: -25%;
  height: 150%;
  left: 0;
  width: 100%;
  background: linear-gradient(
    105deg,
    transparent 35%,
    oklch(100% 0 0 / 0.55) 50%,
    transparent 65%
  );
  transform: translateX(-120%);
  animation: shine 9s cubic-bezier(0.45, 0, 0.55, 1) infinite;
  will-change: transform;
}

@keyframes shine {
  0%,
  62% {
    transform: translateX(-120%);
  }
  86%,
  100% {
    transform: translateX(120%);
  }
}

/* ── Speed lines ──────────────────────────────────────────────────────── */

/* Pinned to the measured bar centres so they read as the logo's own bars
   smearing forward, not as decoration laid on top. */
.streaks {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.streak {
  position: absolute;
  height: 6.5%;
  width: 34%;
  margin-top: -3.25%; /* centre the streak on its bar's measured midpoint */
  border-radius: 999px;
  /* Tapered at both ends so it reads as a trail of motion, not a rod. */
  background: linear-gradient(
    to right,
    transparent 0%,
    oklch(66% 0.204 42 / 0.55) 30%,
    oklch(72% 0.19 46 / 0.32) 60%,
    transparent 100%
  );
  transform-origin: left center;
  opacity: 0;
  animation: streak 4.6s cubic-bezier(0.25, 0.7, 0.25, 1) infinite;
  will-change: transform, opacity;
}

/* `left` is each bar's own measured right tip — the streaks are shed by the
   bars themselves rather than floating at a shared arbitrary x. */
.streak--1 {
  top: 12.2%;
  left: 96.5%;
  animation-delay: 0s;
}
.streak--2 {
  top: 49.8%;
  left: 89.5%;
  animation-delay: 0.28s;
}
.streak--3 {
  top: 87.6%;
  left: 89.5%;
  animation-delay: 0.56s;
}

/* Fires, then rests — a pulse of speed every ~4.6s rather than a strobe. */
@keyframes streak {
  0% {
    opacity: 0;
    transform: translateX(-10%) scaleX(0.2);
  }
  14% {
    opacity: 0.9;
  }
  38% {
    opacity: 0.55;
  }
  52%,
  100% {
    opacity: 0;
    transform: translateX(48%) scaleX(1);
  }
}

/* ── Type ─────────────────────────────────────────────────────────────── */

.wordmark {
  margin: 0 0 1.25rem;
  font-size: clamp(0.66rem, 1.5vw, 0.78rem);
  font-weight: 500;
  letter-spacing: 0.42em;
  text-indent: 0.42em; /* balance the trailing tracking */
  text-transform: uppercase;
  color: var(--fg-muted);
  animation: fade-in 1.4s var(--ease-out) 0.5s both;
}

.headline {
  margin: 0 0 2rem;
  font-size: clamp(2.1rem, 7vw, 3.6rem);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.05;
  color: var(--fg);
  animation: fade-in 1.4s var(--ease-out) 0.75s both;
}

.contact {
  margin: 0;
  animation: fade-in 1.4s var(--ease-out) 1s both;
}

.email {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: clamp(0.8rem, 2.2vw, 0.95rem);
  color: var(--brand);
  text-decoration: none;
  padding: 0.6rem 1.1rem;
  border: 1px solid oklch(66% 0.204 42 / 0.28);
  border-radius: 999px;
  display: inline-block;
  transition:
    border-color 0.5s var(--ease-out),
    background-color 0.5s var(--ease-out),
    color 0.5s var(--ease-out);
}

.email:hover,
.email:focus-visible {
  color: oklch(88% 0.11 55);
  border-color: oklch(66% 0.204 42 / 0.7);
  background: oklch(66% 0.204 42 / 0.09);
}

.email:focus-visible {
  outline: 2px solid var(--brand-hot);
  outline-offset: 3px;
}

@keyframes fade-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.footer {
  position: relative;
  padding: 1.5rem;
  text-align: center;
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  color: var(--fg-faint);
  animation: fade-in 1.4s var(--ease-out) 1.3s both;
}

.footer p {
  margin: 0;
}

/* Landscape phones: pull the lockup and rhythm in so the whole composition
   still lands within a ~360px-tall viewport without needing to scroll. */
@media (max-height: 480px) {
  :root {
    --mark-w: clamp(6rem, 16vw, 8.5rem);
  }

  .lockup {
    margin-bottom: 1.5rem;
  }

  .wordmark {
    margin-bottom: 0.75rem;
  }

  .headline {
    margin-bottom: 1.25rem;
  }

  .stage {
    padding: 1.25rem 1.5rem;
  }

  .footer {
    padding: 0.75rem 1.5rem;
  }
}

/* ── Reduced motion ───────────────────────────────────────────────────── */

/* Everything resolves to the composed still frame — nothing merely slows down. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }

  .streak {
    opacity: 0.5;
    transform: translateX(40%) scaleX(0.7);
  }

  .mark::after {
    display: none;
  }

  .halo {
    opacity: 0.7;
  }
}
