/* Pocket Mammoth
   Material: raw denim, contrast stitching, a mammoth in the pocket.
   Type: Anybody only. Display lines share one setting (condensed, medium, tight); body stays at normal width. */

@font-face {
  font-family: "Anybody";
  src: url("../fonts/anybody.woff2") format("woff2");
  font-weight: 100 900;
  font-stretch: 50% 150%;
  font-display: swap;
}

:root {
  --indigo: #1c2a45;   /* raw denim */
  --cotton: #efe9dc;   /* undyed thread, main text */
  --wash: #9badc9;     /* faded denim, secondary text */
  --thread: #e3a53e;   /* contrast stitching */
  --fur: #c4612a;      /* mammoth */
  --copper: #b8733a;   /* rivets */
  --stitch: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='6'%3E%3Cpath d='M3 3.8Q9 5.4 15 3.8M21 2.2Q27 .6 33 2.2' fill='none' stroke='%23e3a53e' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E");

  --font: "Anybody", ui-sans-serif, system-ui, "Segoe UI", sans-serif;
  --pad: clamp(1.25rem, 4vw, 3rem);
  --max: 1360px;
  --ease: cubic-bezier(0.2, 0.8, 0.2, 1);
}

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font);
  font-size: 1.125rem;
  line-height: 1.5;
  color: var(--cotton);
  background-color: var(--indigo);
  /* Twill: the diagonal weave of denim. */
  background-image: repeating-linear-gradient(118deg, rgba(255, 255, 255, 0.03) 0 1px, transparent 1px 4px);
  -webkit-font-smoothing: antialiased;
}
/* Slub: uneven yarn. */
body::before {
  content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 100; opacity: 0.6; mix-blend-mode: soft-light;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 .14 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
h1, h2, p { margin: 0; font-weight: inherit; }
::selection { background: var(--fur); color: var(--cotton); }
:focus-visible { outline: 2px solid var(--thread); outline-offset: 6px; border-radius: 2px; }

/* Seams: SVG double stitch along an uneven curve, drawn by script at the real width so the
   stitches stay the same length everywhere. Sewn in left to right when they come into view. */
.seam { display: block; width: 100%; height: 46px; overflow: visible; }
.seam--yoke { height: clamp(84px, 10vw, 140px); }
.seam path {
  fill: none; stroke: var(--thread); stroke-width: 1.6; stroke-linecap: round;
  stroke-dasharray: 9 6.5; opacity: 0.85;
}
.seam path + path { stroke-dashoffset: 7; }
.rivet circle { fill: var(--copper); }
.rivet circle + circle { fill: #e2a46a; opacity: 0.55; }
/* (A mask, not clip-path: a fully clipped element never counts as visible to IntersectionObserver.) */
.js .seam:not(.done) {
  -webkit-mask: linear-gradient(90deg, #000 50%, transparent 54%) 100% 0 / 230% 100% no-repeat;
  mask: linear-gradient(90deg, #000 50%, transparent 54%) 100% 0 / 230% 100% no-repeat;
}
.js .seam.sewn:not(.done) {
  -webkit-mask-position: 0 0; mask-position: 0 0;
  transition: -webkit-mask-position 1.4s cubic-bezier(0.55, 0, 0.25, 1), mask-position 1.4s cubic-bezier(0.55, 0, 0.25, 1);
}

/* Links get a running stitch instead of an underline. */
.stitch { position: relative; padding-bottom: 6px; }
.stitch::after {
  content: ""; position: absolute; left: 0; bottom: 0; height: 6px; width: 0;
  background: var(--stitch) 0 0 / 36px 6px repeat-x;
  transition: width 0.45s var(--ease);
}
.stitch:hover::after, .stitch:focus-visible::after { width: 100%; }

/* Bar */
.bar {
  display: flex; align-items: center; justify-content: space-between;
  max-width: var(--max); margin-inline: auto;
  padding: 1.1rem var(--pad);
}
.bar__brand img { height: 48px; width: auto; }
.bar__link { font-weight: 600; font-stretch: 100%; }

/* Hero */
.hero {
  display: grid;
  grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr);
  grid-template-areas: "title art" "lede art";
  align-content: center; column-gap: 2rem;
  min-height: min(calc(100svh - 160px), 860px);
  max-width: var(--max); margin-inline: auto;
  padding: 2rem var(--pad) 2.5rem;
}
/* One display style everywhere: Anybody, condensed, medium weight, tight. Calm, like a stamped label. */
.hero__title, .project__name, .mail {
  font-weight: 580; font-stretch: 80%;
  letter-spacing: -0.03em; line-height: 0.92;
}
.hero__title { grid-area: title; align-self: end; font-size: clamp(2.8rem, 8.2vw, 8.4rem); }
.hero__title span { display: block; white-space: nowrap; }
.hero__lede {
  grid-area: lede;
  margin-top: 2rem;
  font-size: clamp(1.1rem, 1.5vw, 1.35rem);
  color: var(--wash);
  max-width: 34ch;
}
.hero__art { grid-area: art; display: grid; place-items: center; perspective: 900px; }
.mascot {
  width: min(100%, 430px);
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform 0.5s var(--ease);
  filter: drop-shadow(0 28px 36px rgba(5, 10, 25, 0.45));
}

/* The one moment: the line sets, then the mammoth looks up out of the pocket. */
@media (prefers-reduced-motion: no-preference) {
  .hero__title span { animation: appear 0.6s var(--ease) both; }
  .hero__title span + span { animation-delay: 0.15s; }
  .mascot { animation: peek 0.8s 0.55s var(--ease) both, breathe 5.5s 1.4s ease-in-out infinite; }
  .mascot.wiggle { animation: peek 0.8s 0.55s var(--ease) both, breathe 5.5s 1.4s ease-in-out infinite, wiggle 0.7s var(--ease); }
  .js .project, .js .contact { opacity: 0; translate: 0 18px; transition: opacity 0.8s var(--ease), translate 0.8s var(--ease); }
  .js .project.in, .js .contact.in { opacity: 1; translate: none; }
}
.mascot { cursor: grab; -webkit-tap-highlight-color: transparent; transform-origin: 50% 80%; }
@keyframes appear { from { opacity: 0; translate: 0 0.12em; } }
@keyframes peek { from { opacity: 0; translate: 0 24px; } }
@keyframes breathe { 50% { translate: 0 -5px; scale: 1.012; } }
@keyframes wiggle { 20% { rotate: -5deg; } 45% { rotate: 4deg; } 70% { rotate: -2deg; } 100% { rotate: 0deg; } }

/* Projects: rows on a seam, not cards. */
.projects, .contact { max-width: var(--max); margin-inline: auto; padding-inline: var(--pad); }
.project {
  display: grid;
  grid-template-columns: 8rem minmax(0, 1.2fr) minmax(0, 1fr);
  grid-template-areas: "mark name text" "seam seam seam";
  align-items: center; column-gap: 2rem;
}
.project > .seam { grid-area: seam; }
.project__mark { grid-area: mark; width: 100%; height: auto; overflow: visible; margin-block: clamp(2.5rem, 5vw, 4rem); }
.project__name { grid-area: name; font-size: clamp(2.4rem, 5vw, 4.8rem); }
.project__text { grid-area: text; max-width: 36ch; }
.project__text > p:first-of-type { font-size: 1.2rem; }
/* A few seconds of the real game under the Ruined God row, blended into the denim like a print:
   its blacks take on the indigo, so only the lit parts of the scene show through. */
.project:has(.project__glimpse) { grid-template-areas: "mark name text" ". media media" "seam seam seam"; }
.project:has(.project__glimpse) .project__mark { margin-bottom: 1.5rem; }
.project__glimpse {
  grid-area: media;
  display: block; width: 100%; height: auto;
  margin: -1rem 0 clamp(1.5rem, 3vw, 2.5rem);
  mix-blend-mode: lighten;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent), linear-gradient(transparent, #000 20%, #000 80%, transparent);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent), linear-gradient(transparent, #000 20%, #000 80%, transparent);
  mask-composite: intersect;
}
.project__status { margin-top: 0.6rem; color: var(--wash); }
/* An always-visible stitch that runs when the row is pointed at. */
.go {
  display: inline-block; white-space: nowrap;
  color: var(--cotton); font-weight: 600;
  background: var(--stitch) 0 100% / 36px 6px repeat-x;
  padding-bottom: 7px;
  transition: color 0.3s var(--ease);
}
a.project:hover .go, a.project:focus-visible .go { color: var(--thread); animation: run 0.9s linear infinite; }
@keyframes run { to { background-position: 36px 100%; } }

/* Ruined God mark: a broken halo that turns when you point at it. */
.halo path { fill: none; stroke: var(--thread); stroke-width: 2.4; stroke-linecap: round; }
.halo__ring { transform-origin: 70px 40px; transition: transform 0.9s var(--ease); }
.halo__shard { transform: translate(-5px, -6px); transition: transform 0.9s var(--ease); }
.project:hover .halo__ring, .project:focus-visible .halo__ring { transform: rotate(28deg); }
.project:hover .halo__shard, .project:focus-visible .halo__shard { transform: translate(-12px, -15px) rotate(-6deg); }

/* Particular mark: a heap of grains that slumps. */
.pile circle { fill: var(--cotton); transition: transform 0.55s var(--ease); transition-delay: var(--t); }
.project:hover .pile circle { transform: translate(var(--dx), var(--dy)); }

/* Contact */
.contact { margin-top: clamp(5rem, 12vw, 9rem); }
.contact__label { color: var(--wash); margin-bottom: 0.9rem; }
.mail {
  display: inline-block;
  font-size: clamp(1.7rem, 5vw, 4.4rem);
  line-height: 1.05;
  overflow-wrap: anywhere;
  padding-bottom: 14px;
}
.mail.stitch::after { height: 9px; background-size: 54px 9px; }

.foot {
  max-width: var(--max); margin: clamp(4rem, 9vw, 7rem) auto 0;
  padding: 1.5rem var(--pad) 1.75rem;
  font-size: 0.9rem; color: var(--wash);
}
/* Selvedge: the clean, self-finished edge of the cloth, with its coloured ID thread. */
.selvedge {
  height: 10px;
  background:
    linear-gradient(var(--fur), var(--fur)) 0 4px / 100% 2px no-repeat,
    repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.07) 0 1px, transparent 1px 3px),
    var(--cotton);
  opacity: 0.9;
}

@media (max-width: 820px) {
  .hero {
    grid-template-columns: 1fr;
    grid-template-areas: "art" "title" "lede";
    min-height: auto; padding-top: 0.25rem; padding-bottom: 1.5rem;
  }
  .hero__art { margin-bottom: 1.75rem; }
  .mascot { width: min(64vw, 300px); }
  .hero__title { font-size: clamp(2.6rem, 14.5vw, 5.4rem); }
  .hero__lede { margin-top: 1.25rem; }
  .seam--yoke { height: 72px; }
  .project {
    grid-template-columns: 3.75rem minmax(0, 1fr);
    grid-template-areas: "mark name" "text text" "seam seam";
    column-gap: 1rem;
  }
  .project:has(.project__glimpse) { grid-template-areas: "mark name" "text text" "media media" "seam seam"; }
  /* The fighters stand at the clip's far edges: let it run edge to edge and fade only a little. */
  .project__glimpse {
    width: calc(100% + 2 * var(--pad)); max-width: none; margin: 0.25rem calc(-1 * var(--pad)) 0.5rem;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent), linear-gradient(transparent, #000 15%, #000 85%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent), linear-gradient(transparent, #000 15%, #000 85%, transparent);
  }
  .project__mark { margin-block: 1.75rem 1rem; }
  .project:has(.project__glimpse) .project__mark { margin-bottom: 1rem; }
  .project__name { font-size: clamp(2.2rem, 10vw, 3.4rem); }
  .project__text { padding-bottom: 1.5rem; }
  .project__text > p:first-of-type { font-size: 1.15rem; }
  .contact { margin-top: 4rem; }
  .bar__brand img { height: 36px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  html { scroll-behavior: auto; }
}
