/* ============================================================================
   Feral Ente — landing page
   Dark instrument-panel aesthetic. No webfonts, no external requests: the CSP
   in nginx.conf is 'self' only, so everything here has to be local or inline
   as a data: URI (images only).
   Voice/tone notes live in docs/landing-page.md.
   ========================================================================= */

/* ── tokens ───────────────────────────────────────────────────────────── */
:root {
  --bg:        #05060a;
  --bg-lift:   #0a0d14;
  --panel:     #090c12;
  --panel-hi:  #0e131c;
  --line:      rgba(140, 165, 190, 0.14);
  --line-hi:   rgba(140, 165, 190, 0.26);

  --ink:       #d3dbe7;
  --ink-dim:   #8b98ab;
  --ink-faint: #5c6879;

  /* The accent is swapped wholesale when the interlock is disengaged, so
     everything tinted must reference --accent rather than a literal. */
  --phos:      #46f2a4;
  --amber:     #ffb020;
  --alert:     #ff4d5e;
  --accent:    var(--phos);
  --accent-dim: color-mix(in srgb, var(--accent) 55%, transparent);
  --accent-ghost: color-mix(in srgb, var(--accent) 12%, transparent);

  --mono: ui-monospace, "SFMono-Regular", "SF Mono", "Cascadia Mono", "Segoe UI Mono",
          "Roboto Mono", Menlo, Consolas, monospace;
  --sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;

  --pad:  clamp(1.15rem, 4vw, 2.75rem);
  --maxw: 1180px;
  --r:    2px;   /* instruments have corners, not curves */
}

html[data-interlock="disengaged"] {
  --accent: var(--amber);
}

/* ── reset-ish ────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { margin: 0; font-weight: 620; letter-spacing: -0.022em; line-height: 1.06; }
p  { margin: 0; }
a  { color: inherit; text-decoration: none; }
dl, dd, dt { margin: 0; }

::selection { background: var(--accent); color: #04060a; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* ── full-screen texture ──────────────────────────────────────────────── */
/* Grain keeps the flat blacks from banding on big monitors. */
.fx-grain, .fx-scan {
  position: fixed; inset: 0; pointer-events: none; z-index: 900;
}
.fx-grain {
  opacity: 0.35;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.42'/%3E%3C/svg%3E");
}
.fx-scan {
  opacity: 0.5;
  background: repeating-linear-gradient(
    to bottom,
    rgba(255,255,255,0.018) 0 1px,
    transparent 1px 3px
  );
}

/* ── top instrument strip ─────────────────────────────────────────────── */
.strip {
  position: relative; z-index: 3;
  border-bottom: 1px solid var(--line);
  background: #04050a;
  overflow: hidden;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  color: var(--ink-faint);
  height: 30px;
}
.strip__rail {
  display: flex; align-items: center; height: 100%;
  width: max-content;
  animation: rail 44s linear infinite;
}
.strip__set { padding-right: 2.5rem; white-space: nowrap; }
.strip b { color: var(--accent-dim); font-weight: 500; transition: color .5s ease; }
.strip i { color: var(--ink-faint); font-style: normal; padding: 0 .85rem; opacity: .5; }
@keyframes rail { to { transform: translateX(-50%); } }

/* ── nav ──────────────────────────────────────────────────────────────── */
.nav {
  position: sticky; top: 0; z-index: 500;
  display: flex; align-items: center; gap: 1.5rem;
  padding: 0.85rem var(--pad);
  border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(14px) saturate(1.2);
}
.mark { display: flex; align-items: center; gap: .6rem; }
.mark__glyph { color: var(--accent); display: flex; transition: color .5s ease; }
.mark__glyph svg { animation: spin 24s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.mark__word {
  font-family: var(--mono); font-size: 13px; font-weight: 600;
  letter-spacing: 0.2em; color: var(--ink);
}
.mark__word i { font-style: normal; color: var(--accent); transition: color .5s ease; }

.nav__links { display: flex; gap: 1.75rem; margin-left: auto; }
.nav__links a {
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .1em;
  color: var(--ink-dim); text-transform: uppercase; transition: color .18s;
}
.nav__links a:hover { color: var(--accent); }
.nav__cta { margin-left: 0; }

/* ── buttons ──────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .12em;
  text-transform: uppercase; white-space: nowrap;
  padding: .72rem 1.15rem; border-radius: var(--r);
  border: 1px solid var(--line-hi); color: var(--ink);
  transition: background .18s, border-color .18s, color .18s, box-shadow .18s;
  cursor: pointer;
}
.btn--ghost:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-ghost); }
.btn--solid {
  background: var(--accent); border-color: var(--accent); color: #04060a; font-weight: 600;
}
.btn--solid:hover { box-shadow: 0 0 26px -4px var(--accent); }

/* ── hero ─────────────────────────────────────────────────────────────── */
.hero { position: relative; overflow: hidden; border-bottom: 1px solid var(--line); }
.hero__field { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; }
.hero__glow {
  position: absolute; z-index: 1; inset: -30% -10% auto -10%; height: 130%;
  background: radial-gradient(60% 50% at 50% 42%,
      color-mix(in srgb, var(--accent) 13%, transparent) 0%, transparent 70%);
  transition: background .6s ease;
  pointer-events: none;
}
.hero__inner {
  position: relative; z-index: 2;
  max-width: var(--maxw); margin: 0 auto;
  padding: clamp(3.5rem, 9vw, 7rem) var(--pad) clamp(3.5rem, 8vw, 6rem);
  display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, .95fr);
  gap: clamp(2rem, 5vw, 4rem); align-items: start;
}

.eyebrow {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .22em;
  color: var(--accent-dim); margin-bottom: 1.4rem; transition: color .5s ease;
}
/* Sized to the COPY, not to taste: the headline is three full statements
   ("Seven known network attacks." is 28 characters), so the scale is set so
   each one holds its own line down to 360px. Shorten the copy and this can
   grow again — lengthen it and re-measure before shipping, because a
   statement that wraps reads as two statements. */
.hero__title {
  font-size: clamp(1.55rem, 4.5vw, 2.95rem);
  letter-spacing: -0.03em;
  margin-bottom: 1.5rem;
  /* No `text-wrap: balance` here: the statements are separated by explicit
     <br>, and balance re-breaks a line that already fits to even out the
     block — measured splitting the middle statement at 1440px. */
}
.hero__title-accent { color: var(--accent); transition: color .5s ease; }
.hero__lede {
  max-width: 46ch; color: var(--ink-dim);
  font-size: clamp(1rem, 1.5vw, 1.14rem); line-height: 1.62;
}
.hero__actions { display: flex; flex-wrap: wrap; gap: .8rem; margin: 2.1rem 0 1.1rem; }
.hero__note {
  font-family: var(--mono); font-size: 11px; color: var(--ink-faint); letter-spacing: .05em;
}

/* ── panels ───────────────────────────────────────────────────────────── */
/* Corner ticks: the cheapest way to make a <div> read as an instrument. */
.panel {
  position: relative;
  background: linear-gradient(180deg, var(--panel-hi), var(--panel));
  border: 1px solid var(--line);
  border-radius: var(--r);
}
.panel::before, .panel::after {
  content: ""; position: absolute; width: 7px; height: 7px;
  border: 1px solid var(--accent); opacity: .55; transition: border-color .5s ease;
}
.panel::before { top: -1px; left: -1px; border-right: 0; border-bottom: 0; }
.panel::after  { bottom: -1px; right: -1px; border-left: 0; border-top: 0; }

.panel__head {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: .7rem .95rem; border-bottom: 1px solid var(--line);
}
.panel__title, .panel__meta {
  font-family: var(--mono); font-size: 10px; letter-spacing: .18em; color: var(--ink-faint);
}
.panel__meta { color: var(--accent-dim); transition: color .5s ease; }

.dot {
  /* flex:none because the lamp is a flex item in .panel__head, and a default
     flex-shrink lets a tight header squeeze it to 0px — measured. It is also
     the R1 control, so a narrow viewport would make that round unsolvable. */
  flex: none;
  width: 7px; height: 7px; border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 10px var(--accent); animation: pulse 2.4s ease-in-out infinite;
}
@keyframes pulse { 50% { opacity: .25; } }

/* ── hero readout ─────────────────────────────────────────────────────── */
.readout { padding-bottom: .95rem; }
.readout__rows { padding: .3rem 0; }
.readout__row {
  display: flex; justify-content: space-between; align-items: baseline; gap: 1rem;
  padding: .48rem .95rem;
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .06em;
}
.readout__row dt { color: var(--ink-faint); }
.readout__row dd { color: var(--ink); font-variant-numeric: tabular-nums; }
.readout__row + .readout__row { border-top: 1px dashed rgba(140,165,190,.09); }

.switch {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  margin: .55rem .95rem 0; padding-top: .85rem; border-top: 1px solid var(--line);
}
.switch__label { font-family: var(--mono); font-size: 10.5px; letter-spacing: .14em; color: var(--ink-dim); }
.switch__body {
  display: flex; align-items: center; gap: .6rem;
  background: none; border: 0; padding: 0; cursor: pointer;
}
.switch__track {
  width: 40px; height: 21px; border-radius: 11px; padding: 2px;
  background: #131922; border: 1px solid var(--line-hi);
  display: flex; justify-content: flex-end; transition: background .22s, border-color .22s;
}
.switch__knob {
  width: 15px; height: 15px; border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 10px var(--accent); transition: transform .22s ease;
}
[aria-checked="false"] .switch__track { justify-content: flex-start; background: #1a1108; border-color: var(--amber); }
.switch__state {
  font-family: var(--mono); font-size: 10px; letter-spacing: .1em; color: var(--accent);
  min-width: 8ch; text-align: left; transition: color .5s ease;
}
.switch__fine {
  margin: .7rem .95rem 0; font-family: var(--mono); font-size: 10px; line-height: 1.5;
  color: var(--ink-faint);
}

/* ── research access code ─────────────────────────────────────────────── */
/* Spans both hero columns on its own row at the bottom of the section. */
.keypad {
  grid-column: 1 / -1;
  margin-top: clamp(1.75rem, 4vw, 2.75rem);
  transition: border-color .3s ease;
}
.keypad[data-state="denied"] { border-color: color-mix(in srgb, var(--alert) 42%, transparent); }
.keypad[data-state="denied"]::before,
.keypad[data-state="denied"]::after { border-color: var(--alert); opacity: 1; }

.keypad__body {
  display: flex; align-items: center; flex-wrap: wrap; gap: .85rem 1.1rem;
  padding: 1.1rem .95rem;
}
.keypad__digits { display: flex; gap: .45rem; }
.keypad__digit {
  width: 46px; height: 54px; padding: 0; text-align: center;
  background: #05070c; border: 1px solid var(--line-hi); border-radius: var(--r);
  color: var(--accent); caret-color: var(--accent);
  font-family: var(--mono); font-size: 21px; font-weight: 600;
  transition: border-color .15s, box-shadow .15s, color .5s ease;
}
.keypad__digit:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-ghost);
}
.keypad__hint {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .14em;
  color: var(--ink-faint); max-width: 22ch; line-height: 1.5;
}
.keypad__go { margin-left: auto; }
.keypad__go[disabled] { opacity: .45; cursor: progress; }

.keypad__log {
  display: block; padding: .85rem .95rem; border-top: 1px solid var(--line);
  font-family: var(--mono); font-size: 11.5px; line-height: 1.8; color: var(--ink-dim);
}
.keypad__log:empty { display: none; }
.keypad__line { white-space: pre-wrap; }
.keypad__line.is-denied { color: var(--alert); font-weight: 700; letter-spacing: .1em; }
.keypad__line.is-reason { color: var(--ink-faint); }

/* terminal cursor while the sequence is running */
.keypad[data-state="busy"] .keypad__log::after {
  content: "▋"; color: var(--accent); animation: blink 1s steps(1) infinite;
}
@keyframes blink { 50% { opacity: 0; } }

.keypad[data-state="denied"] .keypad__digits {
  animation: shake .34s cubic-bezier(.36, .07, .19, .97);
}
@keyframes shake {
  10%, 90% { transform: translateX(-1px); }
  20%, 80% { transform: translateX(2px); }
  30%, 50%, 70% { transform: translateX(-4px); }
  40%, 60% { transform: translateX(4px); }
}

.panel__meta[data-tone="alert"] { color: var(--alert); }

/* ── section scaffolding ──────────────────────────────────────────────── */
.section {
  position: relative; max-width: var(--maxw); margin: 0 auto;
  padding: clamp(3.5rem, 8vw, 6.5rem) var(--pad);
}
.section--rule { border-top: 1px solid var(--line); }
.section__head { margin-bottom: 2.6rem; }
.section__idx {
  display: block; font-family: var(--mono); font-size: 10.5px; letter-spacing: .22em;
  color: var(--accent-dim); margin-bottom: .8rem; transition: color .5s ease;
}
.section__title { font-size: clamp(1.8rem, 3.6vw, 2.6rem); margin-bottom: .6rem; }
.section__sub { color: var(--ink-dim); font-size: .98rem; }

/* ── capability cards ─────────────────────────────────────────────────── */
.cards {
  display: grid; gap: 1px;
  grid-template-columns: repeat(auto-fit, minmax(248px, 1fr));
}
.card { padding: 1.5rem 1.4rem 1.7rem; transition: border-color .2s, transform .2s; }
.card:hover { border-color: var(--line-hi); transform: translateY(-2px); }
.card__idx {
  font-family: var(--mono); font-size: 10px; letter-spacing: .2em; color: var(--accent-dim);
  transition: color .5s ease;
}
.card__title { font-size: 1.12rem; margin: .85rem 0 .6rem; }
.card p { color: var(--ink-dim); font-size: .93rem; line-height: 1.6; }

/* ── telemetry ────────────────────────────────────────────────────────── */
.tiles {
  display: grid; gap: 1px; margin-bottom: 1.4rem;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}
.tile { padding: 1.25rem 1.3rem; display: flex; flex-direction: column; gap: .4rem; }
.tile__label { font-family: var(--mono); font-size: 9.5px; letter-spacing: .2em; color: var(--ink-faint); }
.tile__value {
  font-family: var(--mono); font-size: clamp(1.5rem, 3vw, 2rem); font-weight: 600;
  color: var(--accent); font-variant-numeric: tabular-nums; letter-spacing: -.02em;
  transition: color .5s ease;
}
.tile__value small { font-size: .5em; opacity: .7; }
.tile__unit { font-family: var(--mono); font-size: 10.5px; color: var(--ink-faint); letter-spacing: .06em; }
.tile__unit .up { color: var(--accent); transition: color .5s ease; }

.graph__canvas { display: block; width: 100%; height: 190px; }
.graph__caption {
  padding: .85rem .95rem; border-top: 1px solid var(--line);
  font-family: var(--mono); font-size: 10.5px; line-height: 1.55; color: var(--ink-faint);
}

/* ── spec table ───────────────────────────────────────────────────────── */
.spec { padding: .35rem .35rem 0; overflow-x: auto; }
.spec__table { width: 100%; border-collapse: collapse; font-family: var(--mono); font-size: 12.5px; }
.spec__table th, .spec__table td { text-align: left; padding: .78rem .95rem; }
.spec__table thead th {
  font-size: 9.5px; letter-spacing: .2em; text-transform: uppercase;
  color: var(--ink-faint); font-weight: 500; border-bottom: 1px solid var(--line);
}
.spec__table tbody tr { border-bottom: 1px dashed rgba(140,165,190,.09); }
.spec__table tbody tr:hover { background: rgba(140,165,190,.03); }
.spec__table tbody th { font-weight: 400; color: var(--ink-dim); }
.spec__table td:nth-child(2) { color: var(--accent); font-variant-numeric: tabular-nums; transition: color .5s ease; }
.spec__table td:last-child { color: var(--ink-faint); }
.spec__foot {
  padding: 1rem .95rem 1.15rem; font-family: var(--mono); font-size: 10.5px;
  line-height: 1.6; color: var(--ink-faint); max-width: 78ch;
}

/* Three columns cannot hold their text on a phone: they squeeze to ~100px and
   every cell wraps one word per line. `overflow-x: auto` on .spec does not
   save it — a `width: 100%` table shrinks to its container rather than
   overflowing, so the scroll container never has anything to scroll.
   Stack each row into a labelled block instead, which beats a horizontally
   scrolling table for eight short rows. */
@media (max-width: 640px) {
  .spec { overflow-x: visible; }
  .spec__table thead { display: none; }
  .spec__table tbody tr {
    display: block;
    padding: .72rem .95rem;
  }
  .spec__table tbody th,
  .spec__table tbody td { display: inline; padding: 0; }
  .spec__table tbody th {
    display: block; color: var(--ink-dim); margin-bottom: .15rem;
    font-size: 12px; letter-spacing: .02em;
  }
  /* value and notes share one line: "2,000,000 tok · plus retained material" */
  .spec__table tbody td:last-child::before {
    content: " · "; color: var(--ink-faint);
  }
}

/* ── containment prose + badges ───────────────────────────────────────── */
.prose { max-width: 62ch; display: grid; gap: 1.15rem; }
.prose p { color: var(--ink-dim); font-size: 1.02rem; line-height: 1.68; }
.prose p:first-child { color: var(--ink); }

.badges { display: flex; flex-wrap: wrap; gap: .55rem; margin-top: 2.4rem; }
.badge {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .16em;
  padding: .5rem .8rem; border: 1px solid var(--line); border-radius: var(--r);
  color: var(--ink-faint); background: var(--panel);
}

/* ── access ───────────────────────────────────────────────────────────── */
.access { padding: clamp(2rem, 5vw, 3.2rem); text-align: center; }
.access .section__idx { margin-bottom: 1rem; }
.access__title { font-size: clamp(1.7rem, 3.4vw, 2.35rem); margin-bottom: .9rem; }
.access__lede { max-width: 48ch; margin: 0 auto 2rem; color: var(--ink-dim); }
.access__form {
  display: flex; flex-wrap: wrap; gap: .6rem; justify-content: center;
  max-width: 520px; margin: 0 auto;
}
.access__input {
  flex: 1 1 260px; min-width: 0;
  background: #05070c; border: 1px solid var(--line-hi); border-radius: var(--r);
  color: var(--ink); font-family: var(--mono); font-size: 12.5px;
  padding: .72rem .9rem; transition: border-color .18s;
}
.access__input::placeholder { color: var(--ink-faint); }
.access__input:focus { border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px var(--accent-ghost); }
.access__out {
  display: block; min-height: 1.4rem; margin-top: 1.15rem;
  font-family: var(--mono); font-size: 11px; letter-spacing: .06em; color: var(--accent);
}
.access__out[data-tone="warn"] { color: var(--amber); }
.access__fine {
  margin-top: 1.6rem; font-family: var(--mono); font-size: 10px;
  letter-spacing: .1em; color: var(--ink-faint);
}
/* The 404 CTA ("Return to the operations portal") is the one .btn that sits
   directly in an .access panel; the home page's sits inside .access__form, so
   the child combinator leaves it alone. At 290px it overran the panel below
   ~394px and pushed a 320px page 22px wide, which makes phones zoom the page
   out. Tighter tracking keeps it on one line down to 360px; narrower, it wraps. */
@media (max-width: 410px) {
  .access > .btn { padding-inline: .6rem; letter-spacing: .04em; white-space: normal; }
}

/* ── footer ───────────────────────────────────────────────────────────── */
.foot {
  border-top: 1px solid var(--line); background: #04050a;
  padding: 2.4rem var(--pad); max-width: var(--maxw); margin: 0 auto;
}
.foot__row { display: flex; flex-wrap: wrap; align-items: center; gap: .9rem; }
.foot__tag { font-family: var(--mono); font-size: 11px; color: var(--ink-faint); letter-spacing: .06em; }
.foot__row--fine {
  margin-top: 1.1rem; padding-top: 1.1rem; border-top: 1px solid var(--line);
  font-family: var(--mono); font-size: 10px; color: var(--ink-faint); letter-spacing: .06em;
}
/* The one way off the page that is not the game: /contact/. */
.foot__link {
  color: var(--ink-dim);
  text-decoration: underline; text-decoration-color: var(--line-hi); text-underline-offset: 3px;
  transition: color .18s;
}
.foot__link:hover { color: var(--accent); }

/* ── responsive ───────────────────────────────────────────────────────── */
@media (max-width: 900px) {
  .hero__inner { grid-template-columns: minmax(0, 1fr); }
  .nav__links { display: none; }
  .nav__cta { margin-left: auto; }
}
@media (max-width: 560px) {
  .foot__row--fine { display: grid; gap: .35rem; }
  .foot__row--fine span[aria-hidden] { display: none; }
  /* six boxes + gaps must clear a 320px viewport minus page padding */
  .keypad__digit { width: 40px; height: 48px; font-size: 18px; }
  .keypad__digits { gap: .35rem; }
  .keypad__go { margin-left: 0; width: 100%; }
  .keypad__hint { max-width: none; }
}
/* The 404 CTA ("Return to containment") is 32px longer than the home one and
   overran the nav below ~405px, which makes phones zoom the page out. Tighter
   tracking keeps it on one line down to 360px; narrower still, it wraps. */
@media (max-width: 410px) {
  .nav { gap: .5rem; }
  .nav__cta { padding-inline: .6rem; letter-spacing: .04em; white-space: normal; text-align: center; }
}

/* ── reduced motion ───────────────────────────────────────────────────── */
/* The canvases check this too (app.js) and render a single static frame. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .strip__rail, .mark__glyph svg, .dot { animation: none; }
  .keypad[data-state="denied"] .keypad__digits { animation: none; }
  .keypad[data-state="busy"] .keypad__log::after { animation: none; }
  *, *::before, *::after { transition-duration: .01ms !important; }
}
