/* Minimal: page gutter, dark palette, plus what the hero animation needs. The JS
   emits .nt spans (state classes .d/.r/.hl) and .aa spans into #hero-seq; the
   character grid they wrap onto is set up in the hero block below. */

@font-face {
  font-family: "Fira Code";
  src: url("../assets/fonts/fira-code-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}

@font-face {
  font-family: "Fira Code";
  src: url("../assets/fonts/fira-code-latin-700-normal.woff2") format("woff2");
  font-weight: 700;
  font-display: swap;
}

/* Nerd Font symbols, subset to the icons used below. Fira Code has no glyph at
   these codepoints, so the browser falls through to this family per character. */
@font-face {
  font-family: "Symbols Nerd Font";
  src: url("../assets/fonts/symbols-nerd-font-subset.woff2") format("woff2");
  font-display: swap;
}

:root {
  --bg: #111;
  /* Terminal-green sequence: the gene is background texture, so every nucleotide
     and every residue outside a word stays well under the motif's brightness. */
  --base: #1f6b31; /* nucleotides, template strand and mRNA alike */
  --base-read: #39c84a; /* whatever the polymerase or ribosome is on right now */
  --residue: #123d1e; /* finished chain outside the motif: the dimmest thing shown */
  --motif: #39ff6e; /* DECODE and AGING, brightest thing in the strand */
  color-scheme: dark; /* dark scrollbars and form controls; no light variant */
}

html {
  overflow-x: clip; /* the hero line hangs into the margins; never scroll to reach it */
}

body {
  background: var(--bg);
  color: #eee;
  max-width: 60rem;
  margin: 0 auto; /* max-width leaves slack for auto to split evenly */
  padding: 0 2rem 2rem;
  font-family: "Fira Code", "Symbols Nerd Font", monospace;
}

a {
  color: inherit; /* default link blue is unreadable on dark */
}

.skip-link:not(:focus) {
  position: absolute;
  left: -100vw; /* offscreen until tabbed to, then it drops into flow */
}

main:focus {
  outline: none; /* tabindex="-1" target, focused by the skip link only */
}

.hero {
  min-height: 100svh; /* fills the first screen */
  display: flex;
  flex-direction: column;
  justify-content: center;
  container-type: inline-size; /* cqi below measures this box, not the viewport */
  /* The hanging line has to be clipped here as well as on html: a phone widens its
     layout viewport to fit overflow even when the root clips it, which would move
     the clip off the window edge and leave part of the line reachable by scrolling. */
  margin-inline: calc(50% - 50vw);
  padding-inline: calc(50vw - 50%);
  overflow-x: clip;
}

/* The sequence is one unbroken run of letters wrapped onto a fixed character grid.

   The font sizes the character cell, and only the cell: 16 of them span the content
   box. Fira Code advances 0.6em per character, so 16 need 9.6em, and dividing by 9.7
   instead leaves 1% of slack against sub-pixel rounding. cqi rather than vw because
   vw includes the scrollbar. Changing this divisor moves DECODE and AGING, because it
   changes how wide a column is.

   The line itself is wider than the content box — 36 columns, of which 10 hang past
   each side into the page margins, pulled out by the negative margins. Width in ch
   rather than em: ch is the font's own advance, so the line is exactly 36 characters
   whatever Fira Code's metrics turn out to be. The middle 16 columns still sit over
   the content box, which is what keeps the words where they were before the line
   grew; hero.js offsets their columns by the same overhang.

   The box is six lines tall and clips the rest, so the strand reads as an excerpt.
   During transcription it runs about twenty lines; translation collapses three
   characters per codon into one, pulling the tail up to seven.

   These measurements live on the block rather than the title so the sequence and the
   countdown share them: both resolve 1ch and 1em against this font-size, which is
   what keeps the countdown on the same cells as the letters running behind it. */
.hero__block {
  --cols: 36;
  --over: 10;
  --lines: 6;
  --lh: 1.05;
  position: relative; /* the countdown is placed against this box */
  margin-inline: calc(var(--over) * -1ch); /* hang into both margins */
  width: calc(var(--cols) * 1ch);
  font-size: calc(100cqi / 9.7);
  line-height: var(--lh);
}

.hero__title {
  margin: 0;
  font-size: inherit;
  height: calc(var(--lines) * var(--lh) * 1em);
  overflow: hidden;
  word-break: break-all; /* an unbroken run of letters has no break opportunities */
}

/* The countdown holds the fifth line and never animates. It is laid over the sequence
   rather than spliced into it: splicing would tie it to a position in the strand, and
   that position slides up the grid as three characters per codon collapse into one.
   Opaque, so the characters it covers stay covered while they keep changing. Bold to
   match the residues around it — the h1 gives those weight, and this sits outside it. */
.hero__when {
  position: absolute;
  top: calc(4 * var(--lh) * 1em); /* clear of four line boxes */
  left: calc(var(--over) * 1ch); /* first column of the content box */
  margin: 0;
  font-size: inherit;
  font-weight: bold;
  color: var(--motif); /* matches DECODE and AGING */
  background: var(--bg);
  white-space: nowrap;
}

.nt {
  color: var(--base);
}

.nt.hl {
  color: var(--base-read); /* the active head, still dimmer than any residue */
}

.aa {
  /* Flanking residues sit below even the nucleotides: once a stretch is translated
     it has done its job, so it recedes and leaves the words alone in the foreground. */
  color: var(--residue);
}

.aa--motif {
  color: var(--motif); /* DECODE and AGING only */
}

.hero__facts {
  margin: 2.5rem 0 0;
  padding: 0;
  list-style: none;
}

.hero__logos {
  margin: 2.5rem 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 2rem;
}

.hero__logo {
  height: 4rem;
  width: auto;
}

/* The Anthropic wordmark's letterforms fill far more of its own viewBox than the
   other two marks fill theirs, so matching height alone reads as oversized. */
.hero__logo--anthropic {
  height: 1.7rem;
}

footer {
  margin-top: 4rem;
  text-align: center;
}
