/* wulfhaven.com — the temporary landing page and the 404 page. Preset H: Archivo and Newsreader. */

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

@font-face {
  font-family: "Newsreader";
  src: url("/assets/fonts/Newsreader-Variable.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}

:root {
  color-scheme: dark;
  --bg: #0e0d0b;
  --ink: #ece5d6;
  --ink-2: #bcb3a2;
  --ink-3: #958c7c;
  --brass: #c9a55a;
  --brass-2: #e2c68c;
  --ember: 226 132 60;
  --sans: "Archivo", ui-sans-serif, system-ui, "Segoe UI", sans-serif;
  --serif: "Newsreader", Georgia, "Times New Roman", serif;
  --rise: cubic-bezier(0.2, 0.7, 0.2, 1);
  font-family: var(--sans);
  font-synthesis: none;
  background: var(--bg);
  color: var(--ink);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

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

html {
  min-height: 100%;
  background: var(--bg);
}

body {
  display: grid;
  grid-template-rows: 1fr auto;
  min-height: 100svh;
  margin: 0;
  overflow-x: hidden;
}

/* The room: a vignette at the edges, and a soft mottled texture over everything behind the page's
   content, the lockup's light included. */
body::before,
body::after {
  position: fixed;
  z-index: -1;
  inset: 0;
  content: "";
  pointer-events: none;
}

body::before {
  background: radial-gradient(ellipse 120% 90% at 50% 40%, transparent 55%, rgb(0 0 0 / 0.55));
}

/* The texture is a seamless mid-grey tile, overlaid: it lightens and darkens in equal measure, so
   the background keeps its colour, and it shows most where the light falls. */
body::after {
  background: url("/assets/texture.webp") 0 0 / 1024px 1024px;
  mix-blend-mode: overlay;
  opacity: 0.2;
}

p {
  margin: 0;
}

a {
  color: var(--brass-2);
  text-decoration-line: underline;
  text-decoration-color: rgb(201 165 90 / 0.45);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.32em;
  transition: color 160ms ease, text-decoration-color 160ms ease;
}

a:hover {
  color: var(--ink);
  text-decoration-color: var(--brass);
}

a:focus-visible {
  border-radius: 2px;
  outline: 2px solid var(--brass);
  outline-offset: 0.3rem;
}

/* The home page. Its lockup ends two gaps above where a 22svh lockup centred on the screen would
   end, and reaches up five-eighths of the way from that lockup's top to the top of the screen;
   everything else sits below it, the status line and all that follows where they would be under
   the centred lockup.
   Under the lockup, one gap to the headline; twice the gap under the headline, under the statement
   and on both sides of the button; and whatever height is left, split evenly round the socials row.
   The
   gaps scale with the screen's height, and the text is trimmed to its cap height and baseline, so
   each gap measures what the eye sees. A short screen caps the lockup so the page still fits, and a
   phone caps it by width; where the space below is still too short, the lockup rises only as far as
   it must. */
.home {
  --logo-h-centred: calc(min(66vw, 22rem, 22svh) * 981 / 960);
  --logo-h: max(var(--logo-h-centred), min(31.25svh + var(--logo-h-centred) * 11 / 16, 100svh - 30rem - var(--gap-wide), 72vw * 981 / 960));
  --logo-w: calc(var(--logo-h) * 960 / 981);
  --gap: clamp(1rem, 1.8svh, 2.6rem);
  --gap-wide: calc(2 * var(--gap));
}

/* The lockup's light is wider than a phone; clipping it here keeps it from widening the page. */
.stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow-x: clip;
  padding: clamp(2.5rem, 7svh, 5rem) 1.5rem 1.5rem;
  text-align: center;
}

.home .stage {
  padding-block: 0;
}

/* The space above the lockup: at most what puts its bottom edge two gaps above the centred lockup's,
   and it gives way first. */
.home .stage::before {
  flex: 1 1 0;
  min-height: clamp(1.5rem, 4svh, 3rem);
  max-height: calc(50svh + var(--logo-h-centred) / 2 - var(--logo-h) - var(--gap-wide));
  content: "";
}

.home .mark {
  width: var(--logo-w);
}

/* The lockup, exactly as designed, with the forge's light behind it, centred on the emblem. The
   trademark notice is in the footer. */
.mark {
  position: relative;
  width: min(66vw, 24rem, 28svh);
  margin: 0;
  line-height: 0;
}

.mark::before {
  position: absolute;
  z-index: -1;
  top: 42%;
  left: 50%;
  width: 260%;
  aspect-ratio: 4 / 3;
  background: radial-gradient(closest-side, rgb(var(--ember) / 0.2), rgb(var(--ember) / 0.07) 50%, transparent);
  content: "";
  pointer-events: none;
  transform: translate(-50%, -50%);
}

.mark__logo {
  display: block;
  width: 100%;
  height: auto;
}

.line {
  max-width: 22ch;
  margin-top: var(--gap);
  color: var(--ink);
  font-family: var(--serif);
  font-size: clamp(1.625rem, 1.2rem + 1.5vw, 2.5rem);
  font-optical-sizing: auto;
  font-weight: 400;
  letter-spacing: -0.012em;
  line-height: 1.15;
  text-box: trim-both cap alphabetic;
  text-wrap: balance;
}

.about {
  max-width: 28rem;
  margin-top: 0.75rem;
  color: var(--ink-2);
  font-size: clamp(0.9375rem, 0.88rem + 0.22vw, 1.0625rem);
  font-weight: 400;
  line-height: 1.5;
  text-wrap: balance;
}

/* The home page states what the studio stands for, at a size meant to be read: a measure wide enough
   to set the statement in two balanced lines on a computer, open leading, and a touch of tracking for
   Archivo at this size. It keeps the secondary ivory, so the headline above it leads. Its closing
   sentence starts a line of its own, so it is never split. */
.home .about {
  max-width: 42rem;
  margin-top: var(--gap-wide);
  font-size: clamp(1.0625rem, 0.95rem + 0.5vw, 1.3125rem);
  letter-spacing: 0.01em;
  line-height: 1.5;
  text-box: trim-both cap alphabetic;
}

.about__coda {
  display: block;
}

.status {
  margin-top: var(--gap-wide);
  color: var(--ink-3);
  font-size: 0.9375rem;
  letter-spacing: 0.02em;
  text-box: trim-both cap alphabetic;
}

.contact {
  margin-top: clamp(1.75rem, 4svh, 2.5rem);
  font-size: 0.9375rem;
  font-weight: 500;
  letter-spacing: 0.02em;
}

/* Next steps: the email button alone on its row, as the one dominant action. */
.actions {
  display: flex;
  justify-content: center;
  margin-top: var(--gap-wide);
}

.button {
  display: inline-flex;
  align-items: center;
  min-height: 3rem;
  padding: 0.75rem 1.5rem;
  border-radius: 0.5rem;
  background: var(--brass);
  color: #14110c;
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-decoration: none;
  transition: background-color 160ms ease;
}

.button:hover {
  background: var(--brass-2);
  color: #14110c;
}

.button:focus-visible {
  border-radius: 0.5rem;
  outline: 2px solid var(--brass-2);
  outline-offset: 3px;
}

/* The socials rail: a quieter row of its own under the button, labelled, wrapping as networks are
   added. Every network's official white mark, unaltered and unframed, so the gold button stays the
   only colour. A new network is a new <li>, using its own white mark, self-hosted.
   The spacing keeps each network's clear space: Bluesky's, the butterfly's own size on every side,
   is the largest, and the label's distance from the row and the 1rem gap both hold it.
   The row takes the button's wide gap on both sides plus half the height left over each, measured
   from the label's cap height above and from the marks, not their 44 px targets, below. */
.follow {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.875rem;
  margin-block: auto;
  padding-block: var(--gap-wide) calc(var(--gap-wide) - (2.75rem - 1.5rem) / 2);
}

.follow__label {
  color: var(--ink-3);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-box: trim-start cap alphabetic;
  text-transform: uppercase;
}

.socials {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1rem;
  max-width: 28rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* A 44 px target round a 24 px mark: WCAG 2.2's enhanced target size, with room for clear space. */
.social {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 0.5rem;
  transition: background-color 160ms ease;
}

.social:hover {
  background: rgb(236 229 214 / 0.06);
}

.social:focus-visible {
  border-radius: 0.5rem;
  outline-offset: 2px;
}

.social img {
  display: block;
  width: auto;
  height: 1.5rem;
}

/* LinkedIn's file carries its ® beside the square, so the image centre sits right of the square's.
   Shift the image, never the artwork, to centre the square itself: its centre is at 46.37% of the
   file's width. */
.social--linkedin img {
  transform: translateX(3.63%);
}

/* YouTube's file pads the icon with transparent space: the icon is 827 × 579 in the middle of a
   1255 × 1075 canvas. Draw the file larger, so the icon is as tall as the other marks, and give the
   padding back, so the icon is what the layout centres. */
.social--youtube img {
  height: calc(1.5rem * 1075 / 579);
  margin: calc(1.5rem * -248 / 579) calc(1.5rem * -214 / 579);
}

/* Reddit offers no white mark, so its one-colour silhouette is turned white here by a filter and the
   file stays Reddit's own. The file pads the Snoo, which is 204.9 × 179.22 inside a 256 square:
   draw the file larger, so the Snoo is as tall as the other marks, and give the padding back. */
.social--reddit img {
  height: calc(1.5rem * 256 / 179.22);
  margin: calc(1.5rem * -38.4 / 179.22) calc(1.5rem * -25.55 / 179.22);
  filter: brightness(0) invert(1);
}

.colophon {
  padding: 1.5rem 1.5rem max(1.5rem, env(safe-area-inset-bottom));
  color: var(--ink-3);
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  text-align: center;
}

.colophon p + p {
  margin-top: 0.375rem;
}

.home .colophon {
  padding-top: 0;
  text-box: trim-start cap alphabetic;
}

/* Phones up to 400 px wide get 1rem gutters. Below 452 px the seven marks no longer fit on one line,
   so the row sets as four over three, keeping the 1rem gap and every network's clear space. */
@media (max-width: 25em) {
  .stage,
  .colophon {
    padding-inline: 1rem;
  }
}

@media (max-width: 28.2em) {
  .socials {
    max-width: calc(4 * 2.75rem + 3 * 1rem);
  }
}

/* The 404 page: the same light and type, the lockup smaller and linked home. */
.missing .mark {
  width: min(48vw, 13rem, 34svh);
}

.missing .title {
  margin: clamp(1.5rem, 4svh, 2.25rem) 0 0;
  color: var(--ink);
  font-family: var(--serif);
  font-size: clamp(1.625rem, 1.2rem + 1.5vw, 2.5rem);
  font-optical-sizing: auto;
  font-weight: 400;
  letter-spacing: -0.012em;
  line-height: 1.15;
}

.missing .home-link {
  display: inline-block;
  line-height: 0;
  text-decoration: none;
}

/* Arrival: the lockup and each line rise into place once; the light breathes slowly. The lockup's
   image rises rather than the lockup itself, so the lockup never becomes a stacking context and its
   light stays under the texture. */
@media (prefers-reduced-motion: no-preference) {
  .mark::before {
    animation: breathe 9s ease-in-out infinite alternate;
  }

  .mark__logo,
  .line,
  .about,
  .status,
  .contact,
  .actions,
  .follow,
  .missing .title {
    animation: rise 1.1s var(--rise) both;
  }

  .line,
  .missing .title {
    animation-delay: 0.3s;
  }

  .about {
    animation-delay: 0.45s;
  }

  .status {
    animation-delay: 0.55s;
  }

  .contact,
  .actions {
    animation-delay: 0.65s;
  }

  .follow {
    animation-delay: 0.75s;
  }
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(0.6rem);
  }
}

@keyframes breathe {
  from {
    opacity: 0.78;
  }

  to {
    opacity: 1;
  }
}
