/* Tetra Launcher site.
   One dark surface throughout — no alternating light/dark bands, no seams
   between sections. Structure comes from elevated panels (cards, entries)
   sitting on the dark ground, the same way the app's own UI works.
   Palette sampled from the hero photo (an overgrown, abandoned industrial
   ruin — assets/hero-bg.jpg): deep shadow, moss overgrowth, oxidised steel.
   Signal-blue (#38bdf8) is the app's own brand colour and is reserved for
   it: the TETRA wordmark, links, underlines, and primary buttons — nothing
   else competes with it. */

:root {
  --night: #0b0e09;
  --night-2: #161a11;
  --night-3: #1f2417;
  --bone: #ece7d8;
  --bone-dim: #a9a496;
  --moss: #576245;
  --moss-light: #7c8968;
  --signal: #38bdf8;
  --signal-bright: #7dd3fc;

  --font-display: "Oswald", "Arial Narrow", sans-serif;
  --font-body: "IBM Plex Sans", -apple-system, "Segoe UI", sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Consolas, monospace;
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--night);
  color: var(--bone);
  font-family: var(--font-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

a {
  color: inherit;
  text-decoration: none;
}

.container {
  max-width: 1080px;
  margin: 0 auto;
  padding: 0 28px;
}

img {
  max-width: 100%;
}

::selection {
  background: var(--signal);
  color: #061019;
}

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

/* ── Nav ── */

header.site-nav {
  position: sticky;
  top: 0;
  z-index: 40;
  background: rgba(11, 14, 9, 0.85);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--night-3);
}

.site-nav .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 68px;
  flex-wrap: wrap;
  gap: 8px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--bone);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 17px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.brand img {
  width: 26px;
  height: 26px;
}

.brand .tetra {
  color: var(--signal);
}

nav.links {
  display: flex;
  gap: 30px;
}

nav.links a {
  position: relative;
  color: var(--bone-dim);
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  padding-bottom: 4px;
}

nav.links a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 100%;
  bottom: 0;
  height: 1px;
  background: var(--signal);
  transition: right 0.25s ease;
}

nav.links a:hover,
nav.links a.active {
  color: var(--bone);
}

nav.links a:hover::after,
nav.links a.active::after {
  right: 0;
}

section {
  padding: 88px 0;
  position: relative;
}

/* ── Type ── */

h1,
h2,
h3 {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-weight: 600;
  margin: 0 0 18px;
  letter-spacing: 0.01em;
}

h1 {
  font-size: clamp(38px, 6vw, 62px);
  line-height: 1.05;
}

h2 {
  font-size: clamp(26px, 3.4vw, 34px);
  line-height: 1.1;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  margin: 0 0 18px;
  color: var(--signal);
}

.eyebrow::before {
  content: "";
  width: 22px;
  height: 1px;
  background: currentColor;
}

p.lede {
  font-size: 18px;
  max-width: 560px;
  margin: 0 0 36px;
  color: var(--bone-dim);
}

/* ── Buttons ── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 15px 28px;
  border-radius: 3px;
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color 0.15s, color 0.15s, border-color 0.15s, transform 0.15s;
}

.btn:active {
  transform: translateY(1px);
}

/* The one and only primary action colour — matches the app's own accent. */
.btn-signal {
  background: var(--signal);
  color: #061019;
  border-color: var(--signal);
}

.btn-signal:hover {
  background: var(--signal-bright);
  border-color: var(--signal-bright);
}

.btn-outline {
  background: transparent;
  border-color: var(--moss-light);
  color: var(--bone);
}

.btn-outline:hover {
  border-color: var(--signal);
  color: var(--signal);
}

.btn[disabled] {
  opacity: 0.4;
  pointer-events: none;
}

/* ── Hero: the photo ── */

.hero {
  position: relative;
  overflow: hidden;
  padding-top: 130px;
  padding-bottom: 150px;
  /* A near-opaque, uniform wash over the whole photo — not a side-fading
     gradient. Text needs to stay readable wherever it lands, and the photo
     only needs to read as texture/mood behind it, not as a bright image
     competing with the headline. */
  background-image: linear-gradient(rgba(8, 10, 6, 0.88), rgba(8, 10, 6, 0.88)),
    url("assets/hero-bg.jpg");
  background-size: cover;
  background-position: center 38%;
}

.hero-content {
  position: relative;
  z-index: 1;
}

.hero h1,
.hero p.lede {
  text-shadow: 0 2px 16px rgba(0, 0, 0, 0.5);
}

.hero .coord {
  font-family: var(--font-mono);
  color: var(--bone-dim);
}

/* Small "live" pulse — used inline next to a fact that's true right now
   (server count, a fetched release). Not decorative: it always sits next
   to a number that could change. */
.pulse-dot {
  position: relative;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--signal);
  flex-shrink: 0;
  display: inline-block;
}

.pulse-dot::before {
  content: "";
  position: absolute;
  inset: -5px;
  border-radius: 50%;
  border: 1px solid var(--signal);
  animation: pulse-ring 2s ease-out infinite;
}

@keyframes pulse-ring {
  0% {
    transform: scale(1);
    opacity: 0.9;
  }
  100% {
    transform: scale(2.6);
    opacity: 0;
  }
}

/* Staggered load-in for the hero headline. */
.load-in > * {
  opacity: 0;
  transform: translateY(14px);
  animation: load-in 0.7s ease forwards;
}

.load-in > *:nth-child(1) {
  animation-delay: 0.05s;
}
.load-in > *:nth-child(2) {
  animation-delay: 0.2s;
}
.load-in > *:nth-child(3) {
  animation-delay: 0.35s;
}
.load-in > *:nth-child(4) {
  animation-delay: 0.5s;
}

@keyframes load-in {
  to {
    opacity: 1;
    transform: none;
  }
}

/* ── Scroll reveal ── */

.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

.reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* ── Field manual entries (features) ── */

.entries {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1px;
  background: var(--night-3);
  border: 1px solid var(--night-3);
  margin-top: 8px;
}

.entry {
  background: var(--night-2);
  padding: 30px 26px;
}

.entry .tag {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--bone);
  background: var(--moss);
  padding: 3px 8px;
  margin-bottom: 14px;
}

.entry h3 {
  font-size: 18px;
  margin-bottom: 10px;
}

.entry p {
  color: var(--bone-dim);
  margin: 0;
  font-size: 15px;
}

/* ── Screenshot carousel ── */

.carousel {
  background: var(--night-2);
  border: 1px solid var(--night-3);
  padding: 14px 14px 18px;
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.3);
}

.carousel-track {
  display: grid;
  border: 1px solid var(--night-3);
  position: relative;
  overflow: hidden;
}

/* Crossfade with a slow settle-zoom, not a flat opacity swap — the
   incoming slide eases down from a slight zoom while it fades in, the
   outgoing one holds still and just fades. `visibility` is delayed on the
   way out (so the fade can finish) but instant on the way in. */
.carousel-slide {
  grid-area: 1 / 1;
  opacity: 0;
  visibility: hidden;
  transform: scale(1.04);
  transition: opacity 0.8s ease, transform 1.1s ease, visibility 0s linear 0.8s;
}

.carousel-slide.is-active {
  opacity: 1;
  visibility: visible;
  transform: scale(1);
  transition: opacity 0.8s ease, transform 1.1s ease, visibility 0s linear 0s;
}

.carousel-slide img {
  display: block;
  width: 100%;
}

.carousel-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--night-3);
  background: rgba(11, 14, 9, 0.65);
  color: var(--bone);
  font-size: 22px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  backdrop-filter: blur(4px);
  transition: background-color 0.15s, border-color 0.15s, color 0.15s;
}

.carousel-arrow:hover {
  border-color: var(--signal);
  color: var(--signal);
}

.carousel-arrow-prev {
  left: 14px;
}

.carousel-arrow-next {
  right: 14px;
}

@media (max-width: 640px) {
  .carousel-arrow {
    width: 34px;
    height: 34px;
    font-size: 18px;
  }
}

.carousel-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 14px;
}

.carousel-caption {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--bone-dim);
  min-height: 1.4em;
}

.carousel-dots {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}

.carousel-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: 1px solid var(--moss-light);
  background: transparent;
  padding: 0;
  cursor: pointer;
}

.carousel-dot.is-active {
  background: var(--signal);
  border-color: var(--signal);
}

/* ── Panels (download groups, join panel) ── */

.panel {
  background: var(--night-2);
  border: 1px solid var(--night-3);
  padding: 26px;
}

/* ── Download builds, grouped by platform, stacked within the group ── */

.build-group h3 {
  font-size: 16px;
  margin-bottom: 4px;
}

.build-group .build-group-sub {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--bone-dim);
  margin-bottom: 20px;
}

.build-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 14px 0;
  border-top: 1px solid var(--night-3);
}

.build-row:first-of-type {
  border-top: none;
}

.build-row .build-label {
  font-family: var(--font-mono);
  font-size: 13px;
}

.build-row .build-size {
  color: var(--bone-dim);
}

/* ── Coordinate readout (join page) ── */

.readout {
  font-family: var(--font-mono);
  font-size: 15px;
  letter-spacing: 0.03em;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  background: var(--night-2);
  color: var(--bone);
  border: 1px solid var(--night-3);
  margin-bottom: 22px;
}

/* ── Footer ── */

footer {
  border-top: 1px solid var(--night-3);
  padding: 36px 0;
  color: var(--bone-dim);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.02em;
}

footer a {
  color: var(--bone-dim);
  text-decoration: underline;
  text-decoration-color: var(--moss-light);
  text-underline-offset: 3px;
}

footer a:hover {
  color: var(--signal);
  text-decoration-color: var(--signal);
}

code {
  background: var(--night-2);
  border: 1px solid var(--night-3);
  padding: 2px 6px;
  font-size: 0.9em;
  font-family: var(--font-mono);
}

/* ── Motion & accessibility ── */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  .pulse-dot::before {
    animation: none;
    opacity: 0.4;
  }
  .load-in > * {
    animation: none;
    opacity: 1;
    transform: none;
  }
  .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .carousel-slide {
    transition: opacity 0.2s linear, visibility 0s linear 0.2s;
    transform: none;
  }
  .carousel-slide.is-active {
    transition: opacity 0.2s linear, visibility 0s linear 0s;
    transform: none;
  }
}

@media (max-width: 640px) {
  section {
    padding: 56px 0;
  }
  .hero {
    padding-top: 76px;
    padding-bottom: 84px;
    background-position: 70% 38%;
  }
}
