/* MothMute site styles.
 *
 * Palette and type live in tokens.css, which is canonical. Nothing here may
 * redeclare a token: a second :root wins by load order and silently reverts
 * the design, which is exactly what happened once already.
 *
 * Colour use is constrained by measured contrast (see tokens.css):
 *   --purple-mid  is large text only
 *   --purple-dark and --deep-3 are never text
 */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--ink);
  color: var(--text);
  font: 16px/1.65 var(--font-body);
  text-rendering: optimizeLegibility;
}

/* Keyboard users get the same reach as pointer users. */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--purple);
  color: var(--ink);
  padding: 0.7rem 1.1rem;
  font: 700 0.85rem var(--font-mono);
  z-index: 10;
}
.skip:focus { left: 0; }

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

a { color: var(--purple); text-decoration-thickness: 1px; text-underline-offset: 0.2em; }
a:hover { color: var(--light); }

img, svg { max-width: 100%; height: auto; }

.wrap { width: min(68rem, 100% - 3rem); margin-inline: auto; }

/* --- Header --------------------------------------------------------------- */

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
  width: min(68rem, 100% - 3rem);
  margin: 0 auto;
  padding: 1.4rem 0;
  border-bottom: 1px solid var(--deep-3);
}

.brand {
  display: inline-flex;
  align-items: baseline;
  gap: 0.55rem;
  color: var(--light);
  font: 700 1.05rem var(--font-mono);
  text-decoration: none;
  letter-spacing: -0.01em;
}
.brand-prompt { color: var(--purple); }
.brand:hover .brand-name { color: var(--purple); }

.site-nav { display: flex; gap: 1.6rem; }
.site-nav a {
  color: var(--text-muted);
  font: 400 0.78rem var(--font-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
}
.site-nav a:hover { color: var(--light); }

/* Current-page marking without a template engine: each page sets a body
   class and the shared partial stays a single static file. */
.page-projects .nav-projects,
.page-about    .nav-about,
.page-contact  .nav-contact { color: var(--purple); }

/* --- Hero ----------------------------------------------------------------- */

.hero {
  position: relative;
  overflow: hidden;
  border-bottom: 1px solid var(--deep-3);
}
.hero-media {
  position: absolute;
  inset: 0;
  background: url("/assets/hero.57126b6b.png") center 45%/cover no-repeat;
  opacity: 0.9;
}
/* Keeps headline contrast at AAA over the artwork rather than hoping. */
.hero-scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to right, var(--ink) 0%, rgba(10,8,18,0.86) 34%, rgba(10,8,18,0.12) 100%),
    linear-gradient(to top, var(--ink) 0%, rgba(10,8,18,0) 32%);
}
.hero-inner { position: relative; padding: 5.5rem 0 4.5rem; }

.eyebrow {
  margin: 0 0 1.1rem;
  color: var(--purple);
  font: 400 0.75rem var(--font-mono);
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

h1 {
  margin: 0 0 1.1rem;
  max-width: 18ch;
  font: 700 clamp(2.4rem, 6vw, 3.9rem)/1.05 var(--font-display);
  letter-spacing: -0.03em;
  color: var(--light);
}

.lede {
  margin: 0 0 2rem;
  max-width: 46ch;
  font-size: 1.075rem;
  color: var(--text-muted);
}

.actions { display: flex; gap: 0.85rem; flex-wrap: wrap; }

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.72rem 1.3rem;
  border: 1px solid transparent;
  border-radius: 4px;
  font: 500 0.9rem var(--font-body);
  text-decoration: none;
  transition: background-color 0.15s, border-color 0.15s, color 0.15s;
}
.btn-primary { background: var(--purple-dark); color: #fff; }
.btn-primary:hover { background: var(--purple-mid); color: #fff; }
.btn-secondary { border-color: var(--deep-3); color: var(--light); }
.btn-secondary:hover { border-color: var(--purple); color: var(--purple); }

/* --- Sections ------------------------------------------------------------- */

main { display: block; flex: 1 0 auto; }
section { padding: 4rem 0; }
section + section { border-top: 1px solid var(--deep-3); }

.section-label {
  margin: 0 0 1.75rem;
  color: var(--text-muted);
  font: 400 0.72rem var(--font-mono);
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

h2 {
  margin: 0 0 0.9rem;
  font: 700 clamp(1.5rem, 3vw, 2rem)/1.15 var(--font-display);
  letter-spacing: -0.02em;
  color: var(--light);
}
h3 {
  margin: 0 0 0.5rem;
  font: 600 1.1rem var(--font-display);
  color: var(--light);
}
p { margin: 0 0 1rem; }
p:last-child { margin-bottom: 0; }

.prose { max-width: 62ch; }
.prose ul { padding-left: 1.15rem; margin: 0 0 1rem; }
.prose li { margin-bottom: 0.55rem; }
.prose li::marker { color: var(--purple-dark); }

/* --- Cards ---------------------------------------------------------------- */

.grid {
  display: grid;
  gap: 1.1rem;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
}

.card {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  padding: 1.5rem;
  background: var(--deep-1);
  border: 1px solid var(--deep-3);
  border-radius: 6px;
  transition: border-color 0.15s, background-color 0.15s;
}
a.card { text-decoration: none; color: inherit; }
a.card:hover { border-color: var(--purple); background: var(--deep-2); }

.card .icon { width: 26px; height: 26px; color: var(--purple); }
.card p { color: var(--text-muted); font-size: 0.95rem; }

.tag {
  align-self: flex-start;
  padding: 0.18rem 0.5rem;
  border: 1px solid var(--deep-3);
  border-radius: 3px;
  color: var(--text-muted);
  font: 400 0.68rem var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.tag-live    { color: var(--purple); border-color: var(--purple-dark); }
.tag-soon    { color: var(--text-muted); }

.meta {
  display: flex;
  gap: 1.2rem;
  flex-wrap: wrap;
  margin: 0 0 2rem;
  padding: 0;
  list-style: none;
  font: 400 0.78rem var(--font-mono);
  color: var(--text-muted);
}
.meta strong { color: var(--light); font-weight: 400; }

/* --- Footer --------------------------------------------------------------- */

.site-footer {
  width: min(68rem, 100% - 3rem);
  margin: 0 auto;
  padding: 2rem 0 3rem;
  border-top: 1px solid var(--deep-3);
}

.statusbar {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding: 0.75rem 1rem;
  margin-bottom: 1.5rem;
  background: var(--deep-1);
  border: 1px solid var(--deep-3);
  border-radius: 4px;
  font: 400 0.72rem var(--font-mono);
  letter-spacing: 0.12em;
  color: var(--text-muted);
}
.status { display: inline-flex; align-items: center; gap: 0.5rem; color: var(--light); }
.dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--purple);
  box-shadow: 0 0 0 3px rgba(166,107,255,0.18);
}

.foot-nav { display: flex; gap: 1.4rem; flex-wrap: wrap; }
.foot-nav a {
  color: var(--text-muted);
  font: 400 0.78rem var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
}
.foot-nav a:hover { color: var(--purple); }

/* --- Motion --------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* --- Home ----------------------------------------------------------------- */
/*
 * The scene is the page and its moth is the only control. That constrains the
 * layout: the hotspot is positioned in percentages of the image box, so the
 * image must never be cropped or the coordinates drift. `cover` would crop,
 * so the image keeps its natural 724x454 ratio and simply scales.
 *
 * Moth position measured from the pixels, not estimated: bright-pixel bounds
 * are x 478-665, y 154-263 (66.0% / 33.9%, 25.8% x 24.0%). The target is
 * padded slightly past that, because the dark outer wings fall below the
 * brightness threshold that found it - but only slightly, or a click on empty
 * sky navigates. Verified against a rendered outline, not assumed.
 */

.landing {
  position: relative;
  width: 100%;
  overflow: hidden;
  display: grid;
  place-items: center;
  min-height: min(68vh, 34rem);
}

/* The frame keeps the artwork's ratio while growing to cover the container in
   both axes - "cover" behaviour, but applied to a real box. The hotspot is
   positioned against this frame, so it rides along with the image instead of
   drifting when the container crops it. That is why cover cannot be used on
   the image itself. */
.landing-frame {
  position: relative;
  min-width: 100%;
  min-height: 100%;
  aspect-ratio: 724 / 454;
}

.landing-scene {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: fill;
}

/* Fades the artwork's hard bottom edge into the page. */
.landing::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 22%;
  background: linear-gradient(to top, var(--ink) 0%, rgba(10,8,18,0) 100%);
  pointer-events: none;
}

.moth-hotspot {
  position: absolute;
  left: 65%;
  top: 30%;
  width: 29%;
  height: 31%;
  border-radius: 50%;
  z-index: 1;
  transition: box-shadow 0.25s, background-color 0.25s;
}

/* Narrow viewports crop the frame horizontally. Centring it pushes the moth -
   the page's only control - off the right edge, so anchor to the right
   instead: at 375px that lands the moth near the middle of the screen. The
   moon and left landscape crop instead, which costs nothing functional. */
@media (max-width: 767px) {
  .landing { place-items: center end; }
}

.moth-hotspot:hover,
.moth-hotspot:focus-visible {
  background: radial-gradient(closest-side,
              rgba(166,107,255,0.20) 0%, rgba(166,107,255,0) 72%);
  box-shadow: 0 0 40px 10px rgba(166,107,255,0.10);
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Toggle in devtools to check the target still covers the moth after any
   change to the artwork. */
.debug-hotspot .moth-hotspot { outline: 2px dashed var(--purple); }
