/* Forest-charcoal background shared with Sebastian's portfolio. */
:root {
  --bg: #0e1210;
  --surface: #0e1013;
  --surface-2: #191c21;
  --line: #2c313a;
  --line-strong: #454c58;
  --text: #f2f4f7;
  --muted: #9aa3ae;
  --accent: #6ee7b7;
  --danger: #fb7185;
  --detect: #7dd3fc;
  --warn: #e8c37e;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  color-scheme: dark;
}
* {
  box-sizing: border-box;
}
body {
  margin: 0;
  padding: 2rem 1.25rem 4rem;
  background: var(--bg);
  color: var(--text);
  font-family:
    system-ui,
    -apple-system,
    'Segoe UI',
    Roboto,
    sans-serif;
  line-height: 1.55;
}
main {
  max-width: 34rem;
  margin: 0 auto;
  text-align: center;
}
/* Decorative: the word underneath says the same thing, so a screen reader
   gains nothing by hearing it twice (hence the empty alt). Sized in the markup
   as well as here so it holds its space before it loads and the page does not
   jump. */
.logo {
  width: 6rem;
  height: 6rem;
  border-radius: 1.35rem;
  margin-bottom: 0.75rem;
}
h1 {
  font-size: 2.75rem;
  margin: 0;
  letter-spacing: -0.03em;
}
h2 {
  font-size: 1rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  margin-top: 2.5rem;
}
.tagline {
  color: var(--accent);
  margin: 0.25rem 0 1.5rem;
  font-size: 1.1rem;
}
.lede {
  font-size: 1.05rem;
}
.small {
  color: var(--muted);
  font-size: 0.85rem;
}
.code {
  font-family: ui-monospace, 'SF Mono', monospace;
  font-size: 2.75rem;
  letter-spacing: 0.25em;
  color: var(--accent);
  margin: 0.25rem 0 1.5rem;
}
/* A pill rather than a rounded rectangle: the radius is half the height, so
   the ends are true semicircles at whatever size the text makes it. */
.download {
  display: inline-block;
  margin: 1.5rem 0 1.25rem;
  padding: 0.7rem 1.5rem;
  font-weight: 650;
  font-size: 1rem;
  text-decoration: none;
  color: #04121f;
  background: var(--accent);
  border-radius: 999px;
}
a {
  color: var(--accent);
}
ul,
ol {
  padding-left: 1.2rem;
}
li {
  margin-bottom: 0.6rem;
}
footer {
  margin-top: 3rem;
  border-top: 1px solid var(--line);
  padding-top: 1rem;
}

/* --- brought in line with the app -------------------------------------- */

h1 {
  letter-spacing: -0.035em;
}
h2 {
  color: var(--text);
  opacity: 0.72;
}

a,
button,
.button,
input,
select {
  transition:
    background-color 440ms var(--ease),
    border-color 440ms var(--ease),
    color 440ms var(--ease),
    transform 440ms var(--ease);
}
button:active:not(:disabled),
.button:active {
  transform: scale(0.98);
}

/* Borders do the separating, exactly as in the app: two near-black surfaces
   are the same surface at arm's length. */
.card,
.panel,
.box,
section > div {
  border-color: var(--line);
}

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

/* Anything sitting on the accent has to be legible on bright green. */
.cta,
.primary,
button.go {
  background: var(--accent) !important;
  border-color: var(--accent) !important;
  color: #04231a !important;
  font-weight: 650;
}

code,
.code,
.mono {
  font-family: ui-monospace, 'SF Mono', monospace;
  font-variant-numeric: tabular-nums;
}

/* --- how it works ------------------------------------------------------- */

#how-to-play {
  scroll-margin-top: 1.5rem;
}

h3 {
  font-size: 1rem;
  margin: 0.9rem 0 0.35rem;
  letter-spacing: -0.01em;
}
.cards {
  display: grid;
  gap: 0.75rem;
  margin: 1.25rem 0 2.5rem;
}
@media (min-width: 34rem) {
  .cards {
    grid-template-columns: 1fr 1fr;
  }
}
.card {
  padding: 1.25rem 1rem;
  border: 1px solid var(--line);
  border-radius: 0.9rem;
  background: var(--surface);
}
.card p {
  margin: 0;
  color: var(--muted);
  font-size: 0.9rem;
}
/* The app's own colour language, so the page teaches the thing the game will
   then rely on: green is you, rose is the hunt. */
.card svg {
  width: 2rem;
  height: 2rem;
  stroke: currentColor;
  stroke-width: 1.6;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.card svg .fill {
  fill: currentColor;
  stroke: none;
}
.card[data-tone='runner'] {
  color: var(--accent);
}
.card[data-tone='hunter'] {
  color: var(--danger);
}
.card[data-tone='warn'] {
  color: var(--warn);
}
.card[data-tone='detect'] {
  color: var(--detect);
}
.card h3,
.card p {
  color: var(--text);
}
.card p {
  color: var(--muted);
}

/* --- the footer is background noise -------------------------------------- */

/* Present, reachable, and never competing with the button above them. These
   are the two links nobody comes here to press. */
footer a {
  color: var(--muted);
  text-decoration: none;
}
footer a:hover,
footer a:focus-visible {
  color: var(--text);
  text-decoration: underline;
}

/* --- arriving ------------------------------------------------------------ */

/* Only applied once the observer is running, so a page whose script never
   loads shows everything rather than nothing.

   Slow on purpose. At half a second the page reads as things snapping into
   place; stretched out, the same movement reads as the page settling, and the
   eye follows it instead of catching up with it. */
.reveals .reveal {
  opacity: 0;
  transform: translateY(0.75rem);
  transition:
    opacity 1600ms var(--ease),
    transform 1600ms var(--ease);
}
.reveals .reveal.shown {
  opacity: 1;
  transform: none;
}
/* The download button both arrives and gets pressed, and the rule above
   animates `transform`, which is what a press uses. It has to sit here rather
   than with the other button styles: at equal specificity the later rule wins,
   and that is this one. A squash that takes a second and a half to appear does
   not read as a press. */
.reveals .reveal:active {
  transition-duration: 120ms;
}
/* Cards arrive in sequence rather than as a block, which is the difference
   between a page that moves and a page that flinches. The gaps grow with the
   duration, or the sequence collapses back into one block. */
.reveals .cards .reveal:nth-child(2) {
  transition-delay: 260ms;
}
.reveals .cards .reveal:nth-child(3) {
  transition-delay: 520ms;
}
.reveals .cards .reveal:nth-child(4) {
  transition-delay: 780ms;
}
@media (prefers-reduced-motion: reduce) {
  .reveals .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}
