/*
  Hide & Shriek — landing page.

  The palette is lifted straight from the game's title screen
  (src/HideAndShriek.Game/Screens/TitleScreen.cs): Night, Bone, Blood,
  ShadowInk, Ash. Keep them in sync — the site should look like the first
  frame of the game, not like a page about it.
*/

:root {
  --night: #060508;
  --crypt: #0c0a0f;
  --slab: #131017;
  --bone: #e2e2e8;
  --blood: #b03636;
  --blood-bright: #d8452f;
  --shadow-ink: #22080a;
  --ash: #966060;
  --smoke: #8b8792;

  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  --wrap: 68rem;
  --edge: clamp(1.25rem, 4vw, 3rem);
}

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

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--night);
  color: var(--bone);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

a {
  color: var(--blood-bright);
  text-decoration-color: rgba(216, 69, 47, 0.4);
  text-underline-offset: 0.25em;
}

a:hover {
  color: var(--bone);
}

code {
  font-family: var(--mono);
  font-size: 0.86em;
  background: rgba(226, 226, 232, 0.07);
  border: 1px solid rgba(226, 226, 232, 0.09);
  padding: 0.1em 0.4em;
  color: #cfc7cf;
  white-space: nowrap;
}

.wrap {
  width: min(var(--wrap), 100%);
  margin-inline: auto;
  padding-inline: var(--edge);
}

/* ------------------------------------------------------------ atmosphere */

/* Film grain over everything, so flat colour never reads as clean. */
.grain {
  position: fixed;
  inset: -50%;
  pointer-events: none;
  z-index: 9;
  opacity: 0.055;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/></filter><rect width='160' height='160' filter='url(%23n)'/></svg>");
  animation: grain-shift 700ms steps(3) infinite;
}

@keyframes grain-shift {
  0% { transform: translate(0, 0); }
  33% { transform: translate(-2%, 1%); }
  66% { transform: translate(1%, -2%); }
  100% { transform: translate(0, 0); }
}

/* The torch you don't have. Breathes at roughly a resting heart rate. */
.vignette {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 8;
  background: radial-gradient(120% 90% at 50% 35%, transparent 30%, rgba(3, 2, 4, 0.55) 72%, #030204 100%);
  animation: heartbeat 4.6s ease-in-out infinite;
}

@keyframes heartbeat {
  0%, 100% { opacity: 0.9; }
  50% { opacity: 1; }
}

/* ------------------------------------------------------------------ hero */

.hero {
  position: relative;
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding: 6rem var(--edge) 5rem;
  overflow: hidden;
  isolation: isolate;
}

.hero__glow {
  position: absolute;
  inset: -20% -10% auto -10%;
  height: 90%;
  z-index: -1;
  background:
    radial-gradient(45% 40% at 50% 42%, rgba(176, 54, 54, 0.30), transparent 68%),
    radial-gradient(70% 55% at 50% 55%, rgba(34, 8, 10, 0.85), transparent 75%);
  animation: gutter 5.3s ease-in-out infinite;
}

/* A light that is losing the argument with the dark. */
@keyframes gutter {
  0%, 100% { opacity: 0.85; transform: scale(1); }
  17% { opacity: 0.62; }
  23% { opacity: 0.95; }
  55% { opacity: 0.7; transform: scale(1.04); }
  61% { opacity: 0.5; }
}

.dust {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

.dust span {
  position: absolute;
  bottom: -8px;
  width: 2px;
  height: 2px;
  background: rgba(226, 226, 232, 0.5);
  border-radius: 50%;
  animation: drift linear infinite;
}

.dust span:nth-child(1)  { left: 6%;  animation-duration: 21s; animation-delay: -3s;  opacity: 0.35; }
.dust span:nth-child(2)  { left: 13%; animation-duration: 27s; animation-delay: -11s; opacity: 0.2; }
.dust span:nth-child(3)  { left: 21%; animation-duration: 18s; animation-delay: -7s;  opacity: 0.45; }
.dust span:nth-child(4)  { left: 28%; animation-duration: 30s; animation-delay: -19s; opacity: 0.25; }
.dust span:nth-child(5)  { left: 35%; animation-duration: 24s; animation-delay: -2s;  opacity: 0.3; }
.dust span:nth-child(6)  { left: 42%; animation-duration: 19s; animation-delay: -14s; opacity: 0.5; }
.dust span:nth-child(7)  { left: 49%; animation-duration: 33s; animation-delay: -6s;  opacity: 0.18; }
.dust span:nth-child(8)  { left: 56%; animation-duration: 22s; animation-delay: -23s; opacity: 0.38; }
.dust span:nth-child(9)  { left: 63%; animation-duration: 26s; animation-delay: -9s;  opacity: 0.28; }
.dust span:nth-child(10) { left: 70%; animation-duration: 17s; animation-delay: -16s; opacity: 0.42; }
.dust span:nth-child(11) { left: 77%; animation-duration: 29s; animation-delay: -4s;  opacity: 0.22; }
.dust span:nth-child(12) { left: 84%; animation-duration: 23s; animation-delay: -21s; opacity: 0.33; }
.dust span:nth-child(13) { left: 90%; animation-duration: 20s; animation-delay: -12s; opacity: 0.46; }
.dust span:nth-child(14) { left: 95%; animation-duration: 31s; animation-delay: -8s;  opacity: 0.2; }
.dust span:nth-child(15) { left: 47%; animation-duration: 35s; animation-delay: -27s; opacity: 0.15; }

@keyframes drift {
  0% { transform: translateY(0) translateX(0); }
  50% { transform: translateY(-55vh) translateX(14px); }
  100% { transform: translateY(-110vh) translateX(-6px); }
}

/*
  What is lying either side of the wordmark. Same argument the game's title
  screen makes with TitleGore: whichever side you pick, the floor already shows
  how it ends. Kept behind the text and off the middle of the page, because the
  words are the one thing here that has to stay legible.
*/
.hero__gore {
  position: absolute;
  inset: 0;
  z-index: -1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  pointer-events: none;
  animation: gutter 5.3s ease-in-out infinite;
}

/*
  Each body sits just under halfway across its own box with the spray thrown at
  the near edge, so pinning the boxes to the edges of the page is what keeps the
  bodies out from under the words — the same job MenuHalfWidth does in the game.
*/
.gore {
  width: clamp(10rem, 30vw, 24rem);
  height: auto;
  opacity: 0.85;
}

/*
  Narrow enough and there is no "either side" left — the text takes the whole
  width, so the bodies drop to the floor of the hero, below the buttons.

  The box goes deliberately taller than it is wide here. With `slice` on the
  SVGs, the scene scales to cover the box and crops, so a portrait box zooms in
  on the body and throws away the far spatter — which is the opposite of what
  scaling the whole scene down does, and the only way a body still reads as one
  at phone width.
*/
@media (max-width: 46rem) {
  .hero__gore {
    align-items: flex-end;
    padding-bottom: 2rem;
  }

  /*
    Capped, because the crop scales with the box: uncapped, the wide end of this
    range zooms a body up over the buttons. The caps hold the zoom at roughly
    two thirds across the whole range, so a body is the same size on a phone as
    on a small tablet.
  */
  .gore {
    width: min(50vw, 15rem);
    height: min(72vw, 17rem);
    opacity: 0.75;
  }
}

.hero__inner {
  text-align: center;
  max-width: 46rem;
}

.title {
  font-family: var(--mono);
  font-weight: 700;
  font-size: clamp(2.6rem, 11vw, 7rem);
  line-height: 0.95;
  letter-spacing: 0.02em;
  margin: 0;
  color: var(--bone);
  text-shadow:
    0 0 1px var(--shadow-ink),
    0 4px 0 var(--shadow-ink),
    0 0 42px rgba(176, 54, 54, 0.35);
  animation: breathe 2.2s ease-in-out infinite;
}

.title__word + .title__amp,
.title__amp + .title__word {
  margin-left: 0.12em;
}

.title__amp {
  color: var(--blood);
  text-shadow: 0 0 24px rgba(176, 54, 54, 0.9), 0 4px 0 var(--shadow-ink);
  animation: amp-flicker 4.1s steps(1) infinite;
}

/* The title drifts a few pixels, exactly like TitleScreen's BreathPixels. */
@keyframes breathe {
  0%, 100% { transform: translateY(-2px); }
  50% { transform: translateY(2px); }
}

@keyframes amp-flicker {
  0%, 42%, 46%, 71%, 74%, 100% { opacity: 1; }
  44%, 72.5% { opacity: 0.35; }
}

.subtitle {
  font-family: var(--mono);
  font-size: clamp(0.78rem, 2.4vw, 1.05rem);
  letter-spacing: 0.55em;
  text-indent: 0.55em;
  color: var(--ash);
  margin: 1.6rem 0 0;
}

.pitch {
  margin: 2.2rem auto 0;
  max-width: 34rem;
  color: var(--smoke);
  font-size: 1.05rem;
}

.hero__actions {
  margin-top: 2.6rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem;
  justify-content: center;
}

.hero__scroll {
  position: absolute;
  bottom: 1.6rem;
  left: 50%;
  transform: translateX(-50%);
  color: var(--ash);
  font-family: var(--mono);
  animation: nudge 2.8s ease-in-out infinite;
}

@keyframes nudge {
  0%, 100% { transform: translate(-50%, 0); opacity: 0.5; }
  50% { transform: translate(-50%, 7px); opacity: 1; }
}

/* --------------------------------------------------------------- buttons */

.btn {
  --btn-face: transparent;
  --btn-edge: rgba(226, 226, 232, 0.22);
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 0.15rem;
  padding: 0.85rem 1.7rem;
  font-family: var(--mono);
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-decoration: none;
  color: var(--bone);
  background: var(--btn-face);
  border: 1px solid var(--btn-edge);
  transition: transform 120ms ease, background-color 160ms ease, border-color 160ms ease, box-shadow 160ms ease;
}

.btn:hover,
.btn:focus-visible {
  color: var(--bone);
  transform: translateY(-2px);
  box-shadow: 0 0 0 1px rgba(176, 54, 54, 0.4), 0 12px 30px -12px rgba(176, 54, 54, 0.8);
}

.btn:active {
  transform: translateY(0);
}

.btn--primary {
  --btn-face: var(--blood);
  --btn-edge: rgba(216, 69, 47, 0.9);
  color: #f6efef;
  box-shadow: 0 0 26px -6px rgba(176, 54, 54, 0.65);
}

.btn--primary:hover,
.btn--primary:focus-visible {
  --btn-face: var(--blood-bright);
}

.btn--ghost {
  --btn-face: rgba(226, 226, 232, 0.03);
}

.btn--block {
  display: flex;
  width: 100%;
  margin-top: auto;
}

/* Nothing to download yet. Reads as a button, refuses to behave like one. */
.btn--dead {
  --btn-face: rgba(176, 54, 54, 0.14);
  --btn-edge: rgba(176, 54, 54, 0.4);
  color: var(--ash);
  box-shadow: none;
  cursor: default;
}

.btn--dead:hover,
.btn--dead:focus-visible {
  color: var(--ash);
  transform: none;
  box-shadow: none;
}

.btn__meta {
  font-size: 0.66rem;
  font-weight: 400;
  letter-spacing: 0.08em;
  opacity: 0.8;
  text-transform: none;
}

:focus-visible {
  outline: 2px solid var(--blood-bright);
  outline-offset: 3px;
}

/* -------------------------------------------------------------- sections */

.section {
  position: relative;
  padding: clamp(4rem, 9vw, 7rem) 0;
  border-top: 1px solid rgba(226, 226, 232, 0.06);
}

.section--alt {
  background: linear-gradient(180deg, var(--crypt), var(--night));
}

.section--quiet {
  background: #08070a;
}

.section__title {
  font-family: var(--mono);
  font-size: clamp(1.15rem, 3.4vw, 1.6rem);
  font-weight: 700;
  letter-spacing: 0.3em;
  margin: 0 0 0.4rem;
  color: var(--bone);
}

.section__title::after {
  content: "";
  display: block;
  width: 3.5rem;
  height: 2px;
  margin-top: 1rem;
  background: var(--blood);
  box-shadow: 0 0 14px rgba(176, 54, 54, 0.8);
}

.section__lede {
  color: var(--smoke);
  margin: 1.4rem 0 0;
}

.prose {
  margin-top: 1.8rem;
  max-width: 44rem;
  color: var(--smoke);
}

.prose em {
  color: var(--bone);
  font-style: italic;
}

/* ----------------------------------------------------------------- cards */

.cards {
  list-style: none;
  margin: 2.6rem 0 0;
  padding: 0;
  display: grid;
  gap: 1px;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  background: rgba(226, 226, 232, 0.07);
  border: 1px solid rgba(226, 226, 232, 0.07);
}

.card {
  background: var(--slab);
  padding: 1.6rem 1.5rem;
  transition: background-color 200ms ease;
}

.card:hover {
  background: #191320;
}

/* Closes the last row off however many columns the grid ended up with. */
.card--wide {
  grid-column: 1 / -1;
}

.card__title {
  font-family: var(--mono);
  font-size: 0.95rem;
  letter-spacing: 0.06em;
  margin: 0 0 0.6rem;
  color: var(--bone);
}

.card p {
  margin: 0;
  color: var(--smoke);
  font-size: 0.95rem;
}

/* ----------------------------------------------------------------- items */

.items {
  list-style: none;
  margin: 2.6rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.75rem;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}

.item {
  padding: 1.1rem 1.2rem;
  background: var(--slab);
  border: 1px solid rgba(226, 226, 232, 0.08);
  border-left: 2px solid var(--edge-mark, var(--ash));
}

/* Polarity is the only thing worth colour-coding: what it costs you, or them. */
.item--curse {
  --edge-mark: var(--blood);
}

.item--blessing {
  --edge-mark: #4e7f6a;
}

.item--sabotage {
  --edge-mark: var(--blood-bright);
}

.item__name {
  font-family: var(--mono);
  font-size: 0.9rem;
  margin: 0;
  color: var(--bone);
}

.item__kind {
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  margin: 0.35rem 0 0.6rem;
  color: var(--edge-mark, var(--ash));
}

.item__effect {
  margin: 0;
  font-size: 0.88rem;
  color: var(--smoke);
}

.items__note {
  margin: 1.8rem 0 0;
  font-size: 0.88rem;
  color: var(--ash);
}

/* ------------------------------------------------------------- downloads */

.platforms {
  list-style: none;
  margin: 2.8rem 0 0;
  padding: 0;
  display: grid;
  gap: 1.25rem;
  grid-template-columns: repeat(auto-fit, minmax(16.5rem, 1fr));
}

.platform {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  padding: 1.8rem 1.6rem;
  background: linear-gradient(180deg, var(--slab), #0b090e);
  border: 1px solid rgba(226, 226, 232, 0.09);
  position: relative;
}

/* Whichever OS you're on gets pulled out of the dark. */
.platform[data-detected="true"] {
  border-color: rgba(176, 54, 54, 0.55);
  box-shadow: 0 0 40px -18px rgba(176, 54, 54, 0.9);
}

.platform[data-detected="true"]::before {
  content: "YOUR SYSTEM";
  position: absolute;
  top: -0.62rem;
  left: 1.4rem;
  padding: 0 0.5rem;
  background: var(--night);
  color: var(--blood-bright);
  font-family: var(--mono);
  font-size: 0.6rem;
  letter-spacing: 0.22em;
}

.platform__icon {
  width: 2rem;
  height: 2rem;
  color: var(--ash);
}

.platform__icon svg {
  width: 100%;
  height: 100%;
  fill: currentColor;
}

.platform__name {
  font-family: var(--mono);
  font-size: 1.05rem;
  letter-spacing: 0.05em;
  margin: 0;
}

.platform__meta {
  margin: 0 0 0.6rem;
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  color: var(--ash);
  text-transform: uppercase;
}

.platform__hint {
  margin: 0.9rem 0 0;
  font-size: 0.82rem;
  color: var(--smoke);
  line-height: 1.55;
}

.downloads__all {
  margin-top: 2rem;
  font-size: 0.9rem;
  color: var(--smoke);
}

/* ----------------------------------------------------------------- steps */

.steps {
  margin: 2.2rem 0 0;
  padding: 0;
  list-style: none;
  counter-reset: step;
  display: grid;
  gap: 1rem;
  max-width: 46rem;
}

.steps li {
  counter-increment: step;
  position: relative;
  padding-left: 3rem;
  color: var(--smoke);
}

.steps li::before {
  content: counter(step, decimal-leading-zero);
  position: absolute;
  left: 0;
  top: 0.1rem;
  font-family: var(--mono);
  font-size: 0.85rem;
  color: var(--blood);
  border: 1px solid rgba(176, 54, 54, 0.4);
  padding: 0.05rem 0.45rem;
}

/* ---------------------------------------------------------------- footer */

.footer {
  border-top: 1px solid rgba(226, 226, 232, 0.06);
  padding: 3rem 0 4rem;
  background: #040305;
}

.footer__inner {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem 2rem;
  align-items: baseline;
  justify-content: space-between;
}

.footer__mark {
  font-family: var(--mono);
  font-weight: 700;
  letter-spacing: 0.24em;
  margin: 0;
  color: var(--ash);
}

.footer__mark span {
  color: var(--blood);
}

.footer__note {
  margin: 0;
  font-size: 0.88rem;
  color: var(--smoke);
}

/* --------------------------------------------------------- accessibility */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  .grain,
  .vignette,
  .hero__glow,
  .hero__gore,
  .title,
  .title__amp,
  .hero__scroll,
  .dust span {
    animation: none;
  }

  .dust {
    display: none;
  }
}
