:root {
  --ink: #0e0b0c;
  --ink-soft: #191315;
  --paper: #f2ede8;
  --paper-worn: #e3dcd3;
  --paper-aged: #d7bb98;
  --paper-aged-deep: #c4a074;
  --graphite: #514640;
  --smoke: #8a7d74;
  --fire: #ff6a2b;
  --ember: #e23b2e;
  --ember-deep: #b32b1f;
  --gold: #e8a020;
  --moss: #3ec97a;
  --project-accent: #ff6a2b;
  --project-rgb: 255, 106, 43;
  --stroke: 3px;
  --stroke-hero: 4px;
  --radius-object: 14px 20px 16px 22px;
  --radius-button: 10px 14px 11px 15px;
  --lift-1: 3px 3px 0 var(--ink);
  --lift-2: 5px 6px 0 var(--ink), 0 10px 22px rgb(0 0 0 / 0.32);
  --lift-3: 8px 10px 0 var(--ink), 0 24px 50px rgb(0 0 0 / 0.5);
  --spring: cubic-bezier(0.16, 1, 0.3, 1);
}

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

html {
  scroll-behavior: smooth;
  scrollbar-color: var(--fire) var(--ink);
}

body {
  min-width: 320px;
  margin: 0;
  overflow-x: hidden;
  color: var(--paper);
  background: var(--ink);
  font-family: "Outfit", Arial, sans-serif;
  transition: --project-accent 0.35s ease;
}

body::selection {
  color: var(--ink);
  background: var(--fire);
}

button,
input,
select {
  font: inherit;
}

button,
a,
input,
select {
  -webkit-tap-highlight-color: transparent;
}

a {
  color: inherit;
}

button {
  color: inherit;
}

.skip-link {
  position: fixed;
  top: 0.75rem;
  left: 0.75rem;
  z-index: 10000;
  padding: 0.8rem 1rem;
  color: var(--ink);
  background: var(--paper);
  border: var(--stroke) solid var(--ink);
  box-shadow: var(--lift-1);
  transform: translateY(-180%);
}

.skip-link:focus {
  transform: translateY(0);
}

:focus-visible {
  outline: 3px dashed var(--fire);
  outline-offset: 4px;
}

.lab-atmosphere {
  position: fixed;
  inset: 0;
  z-index: -2;
  overflow: hidden;
  background: #0e0b0c;
  pointer-events: none;
}

.lab-atmosphere__light {
  position: absolute;
  inset: -30%;
  background: radial-gradient(circle at 76% 20%, rgba(var(--project-rgb), 0.2), transparent 36%);
  transition: background 0.5s ease;
}

.lab-atmosphere__grid {
  position: absolute;
  inset: 0;
  opacity: 0.16;
  background-image: repeating-linear-gradient(
    90deg,
    transparent 0,
    transparent calc(8.333vw - 1px),
    rgba(242, 237, 232, 0.11) calc(8.333vw - 1px),
    rgba(242, 237, 232, 0.11) 8.333vw
  );
  mask-image: linear-gradient(to bottom, black, transparent 75%);
}

.lab-beacon {
  position: absolute;
  top: 12vh;
  right: 8vw;
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  background: var(--fire);
  box-shadow: 0 0 0 0 rgba(255, 106, 43, 0.58);
  animation: beacon-breathe 2.8s ease-out infinite;
}

.site-header,
.hero,
.experiments,
.why,
.signup,
.site-footer {
  width: min(100% - 3rem, 1440px);
  margin-inline: auto;
}

.site-header {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  min-height: 5.5rem;
  border-bottom: 1px solid rgba(242, 237, 232, 0.17);
}

.brand,
.back-link {
  display: inline-flex;
  align-items: center;
  gap: 0.72rem;
  width: max-content;
  color: var(--paper);
  font-family: "DM Mono", monospace;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-decoration: none;
  text-transform: uppercase;
}

.brand__mark {
  display: grid;
  width: 2rem;
  height: 2rem;
  place-items: center;
  color: var(--ink);
  background: var(--paper);
  border: 2px solid var(--paper);
  border-radius: 6px 9px 7px 5px;
  font-weight: 500;
  transform: rotate(-2deg);
}

.back-link {
  justify-self: end;
  transition: color 0.18s ease, transform 0.18s var(--spring);
}

.back-link:hover,
.back-link:focus-visible {
  color: var(--fire);
  transform: translateX(-3px);
}

.lab-status {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  color: var(--paper-worn);
  font-family: "DM Mono", monospace;
  font-size: 0.66rem;
  letter-spacing: 0.14em;
}

.lab-status img {
  width: 1.35rem;
  height: 1.35rem;
  image-rendering: pixelated;
}

.lab-status b {
  padding: 0.28rem 0.42rem;
  color: var(--ink);
  background: var(--moss);
  border: 2px solid var(--ink);
  border-radius: 4px 6px 5px 3px;
  box-shadow: 2px 2px 0 var(--paper);
  font-weight: 500;
}

.hero {
  /* How much page sits between the top of the screen and the top of the hero:
     the render reaches back over it when it goes full screen. */
  --hero-top-gap: 5.5rem;
  display: grid;
  grid-template-columns: minmax(0, 0.92fr) minmax(24rem, 0.78fr);
  gap: clamp(3rem, 8vw, 9rem);
  align-items: end;
  min-height: calc(100vh - 5.5rem);
  min-height: calc(100svh - 5.5rem);
  padding-block: clamp(4rem, 10vh, 8rem);
  position: relative;
}

.hero__code {
  position: absolute;
  top: 3rem;
  left: 0;
  display: flex;
  gap: 1rem;
  color: var(--smoke);
  font-family: "DM Mono", monospace;
  font-size: 0.64rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.hero__code span:first-child {
  color: var(--fire);
}

.system-label {
  margin: 0 0 1rem;
  color: var(--fire);
  font-family: "DM Mono", monospace;
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

.hero__title,
.hero__copy {
  position: relative;
  /* The copy takes the upper layer itself. Pushing the render down with
     z-index instead would make it a stacking context, and its screen blend
     would then have nothing but its own transparent box to blend against —
     which is what left a dark rectangle behind the text on small screens. */
  z-index: 1;
  animation: settle-in 0.7s var(--spring) both;
}

.hero__copy {
  animation-delay: 0.12s;
}

h1,
h2,
h3,
p {
  margin-top: 0;
}

h1,
h2,
h3 {
  text-wrap: balance;
}

h1 {
  margin-bottom: 0;
  color: var(--paper);
  font-family: "Archivo Black", Impact, sans-serif;
  font-size: clamp(5.25rem, 12vw, 11rem);
  font-weight: 400;
  letter-spacing: -0.075em;
  line-height: 0.76;
  text-transform: uppercase;
}

h1 em {
  position: relative;
  color: var(--fire);
  font-style: normal;
}

h1 em::after {
  content: "";
  position: absolute;
  right: -0.1em;
  bottom: 0.03em;
  width: 0.16em;
  height: 0.16em;
  background: var(--gold);
  border: 0.025em solid var(--ink);
  box-shadow: 0.025em 0.025em 0 var(--paper);
  transform: rotate(7deg);
}

/* The qualifier that closes the headline: same sentence, but it should read
   as a note under the shout rather than compete with it. */
.hero__aside {
  display: block;
  max-width: 30ch;
  margin-top: 0.7rem;
  color: var(--paper-worn);
  font-family: "Outfit", Arial, sans-serif;
  font-size: clamp(0.92rem, 1.2vw, 1.1rem);
  font-weight: 500;
  letter-spacing: 0;
  line-height: 1.3;
  text-transform: none;
}

.hero__copy h2 {
  max-width: 13ch;
  margin-bottom: 1.35rem;
  font-family: "Archivo Black", Impact, sans-serif;
  font-size: clamp(1.65rem, 3vw, 3.4rem);
  font-weight: 400;
  letter-spacing: -0.045em;
  line-height: 1;
  text-transform: uppercase;
}

.hero__copy > p:not(.hero__mantra) {
  max-width: 34rem;
  margin-bottom: 1.4rem;
  color: var(--paper-worn);
  font-size: clamp(1rem, 1.5vw, 1.18rem);
  line-height: 1.55;
}

.hero__mantra {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  margin-bottom: 2rem;
  color: var(--smoke);
  font-family: "DM Mono", monospace;
  font-size: 0.78rem;
  line-height: 1.55;
  text-transform: uppercase;
}

.hero__mantra strong {
  color: var(--paper);
  font-weight: 500;
}

.foxi-button {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: 3.25rem;
  padding: 0.82rem 1rem;
  border: var(--stroke) solid var(--ink);
  border-radius: var(--radius-button);
  box-shadow: var(--lift-1);
  font-family: "Archivo Black", Impact, sans-serif;
  font-size: 0.82rem;
  letter-spacing: -0.02em;
  line-height: 1;
  text-decoration: none;
  text-transform: uppercase;
  transition: filter 0.18s ease, transform 0.18s var(--spring), box-shadow 0.18s var(--spring);
}

.foxi-button--primary {
  color: var(--ink);
  background: var(--fire);
}

.foxi-button--secondary {
  color: var(--ink);
  background: var(--paper);
}

.foxi-button b {
  font-family: "DM Mono", monospace;
  font-size: 1rem;
}

@media (hover: hover) {
  .foxi-button:hover {
    box-shadow: var(--lift-2);
    filter: brightness(1.06);
    transform: translate(-2px, -2px);
  }
}

.foxi-button:active {
  box-shadow: none;
  transform: translate(3px, 3px);
  transition-duration: 0.06s;
}

.experiments {
  padding-block: clamp(5rem, 9vw, 9rem);
  scroll-margin-top: 1rem;
}

.section-heading {
  display: grid;
  grid-template-columns: 1fr minmax(20rem, 0.55fr);
  gap: 2rem;
  align-items: end;
  margin-bottom: 2rem;
}

.section-heading h2,
.why h2,
.signup h2 {
  margin-bottom: 0;
  font-family: "Archivo Black", Impact, sans-serif;
  font-size: clamp(2.4rem, 5.2vw, 5.5rem);
  font-weight: 400;
  letter-spacing: -0.065em;
  line-height: 0.92;
  text-transform: uppercase;
}

.section-heading > p {
  max-width: 35rem;
  margin-bottom: 0;
  color: var(--paper-worn);
  font-size: 1.05rem;
  line-height: 1.55;
}

.filter-rail {
  display: flex;
  gap: 0.65rem;
  overflow-x: auto;
  margin: 0 0 1.5rem;
  padding: 0.35rem 0.35rem 0.55rem;
  scrollbar-width: thin;
}

.filter {
  flex: 0 0 auto;
  min-height: 2.55rem;
  padding: 0.55rem 0.78rem;
  color: var(--paper);
  background: var(--ink-soft);
  border: 2px solid var(--paper-worn);
  border-radius: 7px 9px 8px 6px;
  box-shadow: 2px 2px 0 rgba(242, 237, 232, 0.32);
  cursor: pointer;
  font-family: "DM Mono", monospace;
  font-size: 0.67rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  transition: color 0.16s ease, background 0.16s ease, transform 0.16s var(--spring), box-shadow 0.16s var(--spring);
}

.filter.is-active {
  color: var(--ink);
  background: var(--fire);
  border-color: var(--ink);
  box-shadow: 3px 3px 0 var(--paper);
  transform: rotate(-1deg);
}

@media (hover: hover) {
  .filter:not(.is-active):hover {
    color: var(--fire);
    transform: translateY(-2px);
  }
}

.filter:active {
  box-shadow: none;
  transform: translate(2px, 2px);
}

.experiment-console {
  display: grid;
  grid-template-columns: minmax(21rem, 0.82fr) minmax(0, 1.18fr);
  gap: clamp(1.5rem, 3vw, 3rem);
  align-items: start;
}

.experiment-list-wrap {
  min-width: 0;
}

.list-header {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.7rem;
  color: var(--smoke);
  font-family: "DM Mono", monospace;
  font-size: 0.64rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.experiment-list {
  display: grid;
  gap: 0.72rem;
}

.experiment-option {
  --option-accent: var(--fire);
  display: grid;
  grid-template-columns: 2.2rem 4.2rem minmax(0, 1fr) auto;
  gap: 0.7rem;
  gap: 0.8rem;
  align-items: center;
  width: 100%;
  min-height: 5.35rem;
  padding: 0.9rem 0.95rem 0.9rem 0.65rem;
  color: var(--ink);
  text-align: left;
  background: var(--paper-worn);
  border: var(--stroke) solid var(--ink);
  border-left: 7px solid var(--option-accent);
  border-radius: var(--radius-object);
  box-shadow: var(--lift-1);
  cursor: pointer;
  transform: rotate(var(--option-rotation, 0deg));
  transition: opacity 0.22s ease, filter 0.18s ease, transform 0.2s var(--spring), box-shadow 0.2s var(--spring);
}

.experiment-option:nth-child(3n + 1) {
  --option-rotation: -0.25deg;
}

.experiment-option:nth-child(3n + 2) {
  --option-rotation: 0.18deg;
}

.experiment-option__number {
  color: var(--graphite);
  font-family: "DM Mono", monospace;
  font-size: 0.72rem;
  letter-spacing: 0.08em;
}

/* The face of the card. What exists shows itself; what does not shows a lock
   on a tile in its own colour, so the row still says which project it is. */
.experiment-option__thumb {
  display: grid;
  place-items: center;
  overflow: hidden;
  width: 4.2rem;
  aspect-ratio: 1;
  border: 2px solid var(--ink);
  border-radius: 12px 15px 13px 16px;
  background:
    linear-gradient(150deg, rgba(255, 255, 255, 0.55), transparent 62%),
    var(--option-accent);
  box-shadow: inset 0 0 0 2px var(--paper-worn);
}

.experiment-option__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.experiment-option__lock {
  width: 1.6rem;
  height: 1.6rem;
  fill: none;
  stroke: var(--ink);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.72;
}

.experiment-option__pitch {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  margin-top: 0.3rem;
  color: var(--graphite);
  font-size: 0.78rem;
  font-style: normal;
  line-height: 1.35;
}

/* Not ready yet: older paper, so the row reads as a different state before
   anyone gets to the label. Barely any greyscale — the point is that it looks
   aged, not broken. */
.experiment-option.is-pending {
  background: var(--paper-aged);
  filter: saturate(0.85);
  opacity: 0.92;
}

/* Hovering or picking one never turns it back into finished paper: it goes a
   shade deeper instead, so the state survives the interaction. */
.experiment-option.is-pending:hover,
.experiment-option.is-pending.is-previewed,
.experiment-option.is-pending.is-selected {
  background: var(--paper-aged-deep);
  filter: none;
  opacity: 1;
}

.experiment-option__copy {
  min-width: 0;
}

.experiment-option__copy strong {
  display: block;
  margin-bottom: 0.25rem;
  font-family: "Archivo Black", Impact, sans-serif;
  font-size: clamp(1rem, 1.5vw, 1.25rem);
  font-weight: 400;
  letter-spacing: -0.04em;
  /* Wraps rather than trailing off: with the thumbnail in the row there is not
     always a full line of space, and half a name reads worse than two lines. */
  line-height: 1.02;
  text-transform: uppercase;
  overflow-wrap: anywhere;
}

.experiment-option__copy small {
  display: block;
  overflow: hidden;
  color: var(--graphite);
  font-family: "DM Mono", monospace;
  font-size: 0.6rem;
  letter-spacing: 0.04em;
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
}

.experiment-option__status {
  max-width: 8rem;
  padding: 0.42rem 0.5rem;
  color: var(--ink);
  background: transparent;
  border: 2px solid var(--ink);
  border-radius: 6px 8px 7px 5px;
  font-family: "DM Mono", monospace;
  font-size: 0.56rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  line-height: 1.1;
  text-align: center;
  text-transform: uppercase;
  transform: rotate(1.5deg);
}

.experiment-option__arrow {
  display: none;
  font-family: "DM Mono", monospace;
  font-size: 1.1rem;
}

.experiment-option.is-previewed,
.experiment-option.is-selected {
  background: var(--paper);
}

.experiment-option.is-selected::after {
  content: "ABIERTO";
  position: absolute;
  right: 0.75rem;
  bottom: -0.6rem;
  padding: 0.28rem 0.42rem;
  color: var(--ember-deep);
  background: var(--paper);
  border: 2px solid var(--ember-deep);
  border-radius: 4px;
  font-family: "DM Mono", monospace;
  font-size: 0.52rem;
  font-weight: 500;
  letter-spacing: 0.09em;
  transform: rotate(-4deg);
}

.experiment-option.is-selected {
  position: relative;
}

.experiment-option.is-locked {
  filter: grayscale(0.7) saturate(0.35);
  opacity: 0.62;
}

.experiment-option.is-filtered-in {
  animation: filter-settle 0.34s var(--spring) both;
}

@media (hover: hover) {
  .experiment-option:hover {
    box-shadow: var(--lift-2);
    filter: brightness(1.06);
    transform: translate(-2px, -2px) rotate(var(--option-rotation));
  }

  .experiment-option:hover .experiment-option__copy {
    transform: translateX(5px);
  }
}

.experiment-option__copy {
  transition: transform 0.2s var(--spring);
}

.experiment-option:active {
  box-shadow: none;
  transform: translate(3px, 3px) rotate(var(--option-rotation));
  transition-duration: 0.06s;
}

.empty-filter {
  margin: 0;
  padding: 2rem;
  color: var(--ink);
  background: var(--paper-worn);
  border: var(--stroke) dashed var(--ink);
  border-radius: var(--radius-object);
  font-family: "DM Mono", monospace;
  font-size: 0.78rem;
  line-height: 1.6;
}

.experiment-preview {
  position: sticky;
  top: 1.25rem;
  min-height: 38rem;
  color: var(--ink);
  background: var(--paper);
  border: var(--stroke-hero) solid var(--ink);
  border-radius: 18px 26px 20px 30px;
  box-shadow: var(--lift-3);
  overflow: hidden;
  transition: background 0.3s ease, transform 0.3s var(--spring);
}

.experiment-preview::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 0.55rem;
  height: 100%;
  background: var(--project-accent);
}

.experiment-preview::after,
.dossier-sheet::after,
.paper-note::after {
  content: "";
  position: absolute;
  top: -4px;
  right: -4px;
  width: 2.25rem;
  height: 2.25rem;
  background: var(--paper-worn);
  border-bottom: var(--stroke) solid var(--ink);
  border-left: var(--stroke) solid var(--ink);
  transform: skew(-4deg, -4deg);
}

.experiment-preview.is-idle {
  display: grid;
  place-items: center;
  background: var(--paper-worn);
}

.preview-idle {
  width: min(100% - 3rem, 28rem);
  text-align: center;
}

.preview-idle__symbol {
  display: grid;
  width: 4.5rem;
  height: 4.5rem;
  place-items: center;
  margin: 0 auto 1.5rem;
  color: var(--fire);
  border: var(--stroke) dashed var(--ink);
  border-radius: 50%;
  font-family: "DM Mono", monospace;
  font-size: 2rem;
}

.preview-idle .system-label,
.preview-content .system-label {
  color: var(--graphite);
}

.preview-idle h3,
.preview-content h3 {
  font-family: "Archivo Black", Impact, sans-serif;
  font-size: clamp(2rem, 4vw, 4.3rem);
  font-weight: 400;
  letter-spacing: -0.06em;
  line-height: 0.95;
  text-transform: uppercase;
}

.preview-idle > p:not(.system-label) {
  color: var(--graphite);
  line-height: 1.55;
}

.control-line {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem 1rem;
  margin-top: 2rem;
  color: var(--graphite);
  font-family: "DM Mono", monospace;
  font-size: 0.6rem;
  text-transform: uppercase;
}

kbd {
  padding: 0.22rem 0.36rem;
  color: var(--paper);
  background: var(--ink);
  border-radius: 4px;
  box-shadow: 2px 2px 0 var(--smoke);
  font-family: inherit;
}

.preview-content {
  min-height: 38rem;
  padding: clamp(2rem, 4vw, 4rem);
  animation: preview-settle 0.34s var(--spring) both;
}

/* The panel opens with the thing itself. What has no artwork yet says so on a
   plate of its own colour, at the same height, so nothing jumps between one
   experiment and the next. */
.preview-art {
  overflow: hidden;
  margin-bottom: 2rem;
  border: 2px solid var(--ink);
  border-radius: 12px 16px 13px 17px;
  box-shadow: var(--lift-1);
}

.preview-art img {
  display: block;
  width: 100%;
  aspect-ratio: 5 / 1;
  max-height: 11rem;
  object-fit: cover;
  object-position: center 22%;
}

.preview-art--locked {
  display: grid;
  place-items: center;
  gap: 0.55rem;
  aspect-ratio: 5 / 1;
  max-height: 11rem;
  background:
    linear-gradient(150deg, rgba(255, 255, 255, 0.5), transparent 62%),
    var(--project-accent);
}

.preview-art--locked .experiment-option__lock {
  width: 2.2rem;
  height: 2.2rem;
}

.preview-art--locked span {
  color: var(--ink);
  font-family: "DM Mono", monospace;
  font-size: 0.6rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  opacity: 0.72;
}

.preview-topline {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.8rem;
  margin-bottom: 2.5rem;
  padding-right: 2rem;
}

.status-stamp,
.category-label {
  display: inline-flex;
  align-items: center;
  min-height: 2rem;
  padding: 0.35rem 0.55rem;
  color: var(--ink);
  border: 2px solid var(--ink);
  border-radius: 6px 8px 7px 5px;
  font-family: "DM Mono", monospace;
  font-size: 0.58rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.status-stamp {
  color: var(--ember-deep);
  border-color: var(--ember-deep);
  transform: rotate(-2deg);
}

.preview-content h3 {
  max-width: 11ch;
  margin-bottom: 1.4rem;
  color: var(--ink);
}

.preview-description {
  max-width: 39rem;
  margin-bottom: 2rem;
  color: var(--graphite);
  font-size: clamp(1rem, 1.4vw, 1.15rem);
  line-height: 1.55;
}

.preview-inside {
  margin-bottom: 2rem;
  padding: 1.2rem 1.25rem;
  background: var(--paper-worn);
  border-left: 7px solid var(--project-accent);
  border-radius: 7px 10px 8px 11px;
}

.preview-inside p {
  margin-bottom: 0.7rem;
  font-family: "DM Mono", monospace;
  font-size: 0.62rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.preview-inside ul {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.5rem 1.2rem;
  margin: 0;
  padding: 0;
  color: var(--graphite);
  list-style: none;
}

.preview-inside li::before {
  content: ">";
  margin-right: 0.45rem;
  color: var(--project-accent);
  font-family: "DM Mono", monospace;
  font-weight: 500;
}

.preview-action-row {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: center;
}

.preview-hint {
  margin: 0;
  color: var(--graphite);
  font-family: "DM Mono", monospace;
  font-size: 0.66rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.preview-content .foxi-button--primary {
  background: var(--project-accent);
}

.why {
  display: grid;
  grid-template-columns: minmax(0, 0.75fr) minmax(22rem, 1fr);
  gap: clamp(3rem, 9vw, 10rem);
  align-items: center;
  padding-block: clamp(6rem, 11vw, 11rem);
}

.paper-note {
  position: relative;
  padding: clamp(2.2rem, 5vw, 4.5rem);
  color: var(--ink);
  background: var(--paper);
  border: var(--stroke-hero) solid var(--ink);
  border-radius: 20px 28px 18px 26px;
  box-shadow: var(--lift-3);
  transform: rotate(0.6deg);
}

.paper-note__pin {
  position: absolute;
  top: 1.4rem;
  left: 50%;
  width: 1rem;
  height: 1rem;
  border: 2px solid var(--ink);
  border-radius: 50%;
  background: var(--ember);
  box-shadow: 2px 3px 0 rgba(14, 11, 12, 0.45);
}

.paper-note p {
  color: var(--graphite);
  font-size: clamp(1rem, 1.5vw, 1.2rem);
  line-height: 1.65;
}

.paper-note strong {
  color: var(--ink);
}

.paper-note small {
  display: block;
  margin-top: 2rem;
  color: var(--ember-deep);
  font-family: "DM Mono", monospace;
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-align: right;
}

.signup {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(23rem, 0.75fr);
  gap: clamp(3rem, 8vw, 9rem);
  align-items: start;
  padding-block: clamp(5rem, 9vw, 9rem);
  border-top: 1px solid rgba(242, 237, 232, 0.17);
}

.signup__copy > p:last-child {
  max-width: 34rem;
  margin-top: 1.5rem;
  color: var(--paper-worn);
  font-size: 1.06rem;
  line-height: 1.55;
}

.signup-form {
  display: grid;
  gap: 1rem;
  padding: clamp(1.3rem, 3vw, 2.2rem);
  color: var(--ink);
  background: var(--paper-worn);
  border: var(--stroke) solid var(--ink);
  border-radius: var(--radius-object);
  box-shadow: var(--lift-2);
  transform: rotate(-0.3deg);
}

.signup-form label {
  display: grid;
  gap: 0.45rem;
}

.signup-form label > span {
  font-family: "DM Mono", monospace;
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.signup-form input,
.signup-form select {
  width: 100%;
  min-height: 3.2rem;
  padding: 0.75rem 0.85rem;
  color: var(--ink);
  background: var(--paper);
  border: var(--stroke) solid var(--ink);
  border-radius: 8px 11px 9px 7px;
  box-shadow: 2px 2px 0 var(--ink);
}

.signup-form .foxi-button {
  width: 100%;
  margin-top: 0.25rem;
}

.form-status,
.dossier-status {
  min-height: 1.25rem;
  margin: 0;
  color: var(--ember-deep);
  font-family: "DM Mono", monospace;
  font-size: 0.68rem;
  line-height: 1.5;
}

.form-status.is-success,
.dossier-status.is-success {
  color: #17663a;
}

.site-footer {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 2rem;
  align-items: center;
  min-height: 8rem;
  color: var(--smoke);
  border-top: 1px solid rgba(242, 237, 232, 0.17);
  font-family: "DM Mono", monospace;
  font-size: 0.62rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.site-footer a {
  color: var(--paper);
  text-decoration: none;
}

.site-footer p {
  max-width: 44rem;
  margin: 0 auto;
  text-align: center;
  text-transform: none;
}

.dossier-dialog {
  width: 100%;
  max-width: none;
  height: 100%;
  max-height: none;
  margin: 0;
  padding: 0;
  overflow: hidden;
  background: transparent;
  border: 0;
}

.dossier-dialog::backdrop {
  background: rgba(6, 4, 5, 0.74);
  backdrop-filter: blur(2px);
}

.dossier-dialog[open] {
  display: flex;
  justify-content: flex-end;
}

.dossier-sheet {
  position: relative;
  width: min(100%, 38rem);
  height: 100%;
  overflow-y: auto;
  padding: clamp(1.5rem, 4vw, 3.5rem);
  color: var(--ink);
  background: var(--paper);
  border-left: var(--stroke-hero) solid var(--ink);
  box-shadow: var(--lift-3);
  animation: drawer-slide 0.42s var(--spring) both;
}

.dossier-header {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  align-items: flex-start;
  margin-bottom: 1.5rem;
  padding-bottom: 1.5rem;
  border-bottom: var(--stroke) solid var(--ink);
}

.dossier-header h2 {
  max-width: 9ch;
  margin: 0;
  font-family: "Archivo Black", Impact, sans-serif;
  font-size: clamp(2.4rem, 6vw, 4.6rem);
  font-weight: 400;
  letter-spacing: -0.065em;
  line-height: 0.9;
  text-transform: uppercase;
}

.dossier-close {
  flex: 0 0 auto;
  display: grid;
  width: 3rem;
  height: 3rem;
  place-items: center;
  color: var(--paper);
  background: var(--ink);
  border: var(--stroke) solid var(--ink);
  border-radius: var(--radius-button);
  box-shadow: 3px 3px 0 var(--fire);
  cursor: pointer;
  font-family: "DM Mono", monospace;
  font-size: 1.45rem;
}

.dossier-close:active {
  box-shadow: none;
  transform: translate(3px, 3px);
}

.dossier-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-bottom: 2rem;
}

/* ---- What the experiment actually looks like ---------------------------- */
/* Only the ones with something built carry this. The cover sets the scene and
   the clips are the app running, straight from the video CDN. */
.dossier-media {
  display: grid;
  gap: 1rem;
  margin-bottom: 2rem;
}

.dossier-media[hidden] {
  display: none;
}

.dossier-cover {
  margin: 0;
  border: var(--stroke) solid var(--ink);
  border-radius: var(--radius-object);
  overflow: hidden;
  background: var(--paper-worn);
  box-shadow: var(--lift-1);
}

.dossier-cover img {
  display: block;
  width: 100%;
  height: auto;
}

.dossier-clips {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.7rem;
}

.dossier-clip {
  margin: 0;
  display: grid;
  gap: 0.45rem;
}

.dossier-clip video {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  border: 2px solid var(--ink);
  border-radius: 10px 13px 11px 14px;
  background: var(--ink);
}

.dossier-clip figcaption {
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: 0.58rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--graphite);
}

@media (max-width: 520px) {
  .dossier-clips {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .dossier-clip:first-child {
    grid-column: 1 / -1;
  }

  .dossier-clip:first-child video {
    aspect-ratio: 4 / 3;
  }
}

.dossier-body {
  display: grid;
  gap: 1.65rem;
}

.dossier-section {
  position: relative;
  padding-left: 1.15rem;
  border-left: 5px solid var(--project-accent);
}

.dossier-section h3 {
  margin-bottom: 0.55rem;
  font-family: "Archivo Black", Impact, sans-serif;
  font-size: 0.95rem;
  font-weight: 400;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}

.dossier-section p {
  margin-bottom: 0.55rem;
  color: var(--graphite);
  line-height: 1.58;
}

.dossier-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2.2rem;
  padding-top: 1.5rem;
  border-top: var(--stroke) dashed var(--ink);
}

.dossier-actions .foxi-button {
  border-width: 2px;
  font-size: 0.72rem;
}

.dossier-actions .foxi-button:first-child {
  background: var(--project-accent);
}

.dossier-status {
  margin-top: 1.25rem;
}

.noscript-content {
  width: min(100% - 3rem, 70rem);
  margin: 3rem auto;
  padding: 2rem;
  color: var(--ink);
  background: var(--paper);
}

/* Holds both halves of the cursor in the top layer. Every declaration here is
   undoing a popover default: without them it would be a bordered white box
   parked in the middle of the screen. */
.game-cursor-layer {
  position: fixed;
  inset: 0;
  z-index: 10001;
  width: auto;
  height: auto;
  max-width: none;
  max-height: none;
  margin: 0;
  border: 0;
  padding: 0;
  overflow: visible;
  color: inherit;
  background: transparent;
  pointer-events: none;
}

.game-cursor,
.game-cursor-trail {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 10001;
  pointer-events: none;
  opacity: 0;
  will-change: transform, opacity;
}

.game-cursor {
  width: 2rem;
  height: 2rem;
  margin: -1rem 0 0 -1rem;
  background: url("../assets/img/flame-clean.webp") center / contain no-repeat;
  filter: drop-shadow(0 0 0.38rem rgba(255, 106, 43, 0.7));
  image-rendering: pixelated;
  transition: width 0.16s var(--spring), height 0.16s var(--spring), margin 0.16s var(--spring), opacity 0.15s ease;
}

.game-cursor-trail {
  width: 2.8rem;
  height: 2.8rem;
  margin: -1.4rem 0 0 -1.4rem;
  border: 2px solid rgba(255, 106, 43, 0.52);
  border-radius: 50%;
  box-shadow: inset 0 0 0 2px rgba(232, 160, 32, 0.12);
  transition: width 0.18s var(--spring), height 0.18s var(--spring), margin 0.18s var(--spring), opacity 0.15s ease;
}

.custom-cursor-ready,
.custom-cursor-ready a,
.custom-cursor-ready button,
.custom-cursor-ready input,
.custom-cursor-ready select,
.custom-cursor-ready label {
  cursor: none;
}

.cursor-visible .game-cursor,
.cursor-visible .game-cursor-trail {
  opacity: 1;
}

.cursor-hover .game-cursor {
  width: 2.35rem;
  height: 2.35rem;
  margin: -1.175rem 0 0 -1.175rem;
}

.cursor-hover .game-cursor-trail {
  width: 3.45rem;
  height: 3.45rem;
  margin: -1.725rem 0 0 -1.725rem;
  border-color: rgba(255, 106, 43, 0.9);
}

.cursor-down .game-cursor-trail {
  width: 2rem;
  height: 2rem;
  margin: -1rem 0 0 -1rem;
}

@keyframes beacon-breathe {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 106, 43, 0.5); }
  45% { box-shadow: 0 0 0 0.85rem rgba(255, 106, 43, 0); }
}

@keyframes settle-in {
  from { opacity: 0; transform: translateY(24px) rotate(0.2deg); }
  to { opacity: 1; transform: translateY(0) rotate(0); }
}

@keyframes filter-settle {
  from { opacity: 0; transform: translateY(8px) scale(0.985); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes preview-settle {
  from { opacity: 0; transform: translateX(10px) rotate(0.3deg); }
  to { opacity: 1; transform: translateX(0) rotate(0); }
}

@keyframes drawer-slide {
  from { transform: translateX(104%); }
  to { transform: translateX(0); }
}

@media (max-width: 1050px) {
  .hero {
    gap: 3rem;
  }

  .experiment-console {
    grid-template-columns: minmax(18.5rem, 0.86fr) minmax(0, 1.14fr);
  }

  .experiment-option__status {
    display: none;
  }

  .experiment-option {
    grid-template-columns: 2.2rem 4rem minmax(0, 1fr) auto;
  }

  .experiment-option__thumb {
    width: 4rem;
  }

  .experiment-option__arrow {
    display: block;
  }
}

@media (max-width: 767px) {
  html {
    scroll-behavior: auto;
  }

  .site-header,
  .hero,
  .experiments,
  .why,
  .signup,
  .site-footer {
    width: min(100% - 1.5rem, 46rem);
  }

  .site-header {
    grid-template-columns: 1fr auto;
    min-height: 4.75rem;
  }

  .brand {
    font-size: 0.68rem;
  }

  .brand__mark {
    width: 1.75rem;
    height: 1.75rem;
  }

  .lab-status {
    justify-self: end;
  }

  .lab-status > span,
  .back-link {
    display: none;
  }

  .hero {
    --hero-top-gap: 4.75rem;
    grid-template-columns: 1fr;
    gap: 2.5rem;
    align-content: center;
    min-height: calc(100svh - 4.75rem);
    padding-block: 4.5rem 3rem;
  }

  .hero__code {
    top: 1.25rem;
  }

  h1 {
    font-size: clamp(5.25rem, 28vw, 8rem);
  }

  .hero__copy h2 {
    max-width: 15ch;
    font-size: clamp(1.55rem, 8vw, 2.5rem);
  }

  .hero__aside {
    max-width: none;
    font-size: 0.95rem;
  }

  .hero__copy > p:not(.hero__mantra) {
    font-size: 1rem;
  }

  .experiments {
    padding-block: 5.5rem;
  }

  .section-heading,
  .why,
  .signup {
    grid-template-columns: 1fr;
  }

  .section-heading {
    gap: 1.2rem;
  }

  .section-heading h2,
  .why h2,
  .signup h2 {
    font-size: clamp(2.35rem, 12vw, 4rem);
  }

  .filter-rail {
    width: calc(100% + 0.75rem);
    margin-right: -0.75rem;
    padding-right: 1rem;
  }

  /* The panel used to sit above the list, so choosing meant scrolling down to
     the rows and then back up for the answer. Now it follows the row you
     touched: script drops it in right after it. */
  .experiment-console {
    grid-template-columns: 1fr;
    grid-template-areas:
      "list"
      "preview";
  }

  .experiment-list-wrap {
    grid-area: list;
  }

  .experiment-list > .experiment-preview,
  .experiment-preview {
    position: relative;
    top: 0;
    grid-area: preview;
    min-height: 20rem;
    border-radius: 14px 19px 15px 21px;
    box-shadow: 5px 6px 0 var(--ink), 0 16px 32px rgba(0, 0, 0, 0.4);
  }

  /* Inside the list it is one more row among the buttons, so it must drop the
     named area it uses when it is a column of the console. */
  .experiment-list > .experiment-preview {
    grid-area: auto;
    margin: 0.75rem 0 1.1rem;
  }

  .preview-content {
    min-height: 0;
    padding: 2rem 1.5rem 1.6rem;
  }

  .preview-idle {
    padding-block: 2.4rem;
  }

  .preview-idle__symbol,
  .control-line {
    display: none;
  }

  .preview-idle h3,
  .preview-content h3 {
    font-size: clamp(2rem, 11vw, 3.2rem);
  }

  .preview-topline {
    margin-bottom: 1.5rem;
  }

  .preview-inside {
    display: none;
  }

  .experiment-option {
    min-height: 5rem;
  }

  .why,
  .signup {
    gap: 2.5rem;
    padding-block: 6rem;
  }

  .paper-note {
    padding: 2.6rem 1.4rem 1.8rem;
    transform: none;
  }

  .signup-form {
    padding: 1.25rem;
    transform: none;
  }

  .site-footer {
    grid-template-columns: 1fr;
    gap: 1rem;
    padding-block: 2rem;
    text-align: center;
  }

  .site-footer a {
    justify-self: center;
  }

  .site-footer p {
    order: -1;
  }

  .dossier-dialog[open] {
    align-items: flex-end;
  }

  .dossier-sheet {
    width: 100%;
    height: min(92svh, 54rem);
    padding: 1.5rem 1.25rem calc(1.5rem + env(safe-area-inset-bottom));
    border-top: var(--stroke-hero) solid var(--ink);
    border-left: 0;
    border-radius: 20px 20px 0 0;
    animation-name: sheet-slide;
  }

  .dossier-sheet::before {
    content: "";
    display: block;
    width: 3.25rem;
    height: 0.32rem;
    margin: -0.65rem auto 1.15rem;
    background: var(--ink);
    border-radius: 999px;
  }

  .dossier-sheet::after {
    display: none;
  }

  .dossier-header h2 {
    font-size: clamp(2.35rem, 13vw, 4rem);
  }

  @keyframes sheet-slide {
    from { transform: translateY(104%); }
    to { transform: translateY(0); }
  }
}

@media (max-width: 410px) {
  .brand > span:last-child {
    display: none;
  }

  .hero {
    padding-top: 3.75rem;
  }

  .hero__title .system-label {
    margin-bottom: 0.7rem;
  }

  .hero__mantra {
    margin-bottom: 1.5rem;
  }

  .foxi-button {
    width: 100%;
  }

  .experiment-option__number {
    font-size: 0.65rem;
  }

  .experiment-option__copy strong {
    font-size: 0.95rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  .lab-beacon {
    box-shadow: none;
  }

  .game-cursor-trail {
    display: none;
  }
}

/* Door to the subscribers-only area, next to the signup. */
.signup-gate {
  margin: 0 0 1.25rem;
  color: rgba(255, 255, 255, 0.55);
  font-size: 0.9rem;
}

.signup-gate a {
  color: var(--accent, #ff5a35);
  text-decoration: none;
  border-bottom: 1px solid rgba(var(--accent-rgb, 255, 90, 53), 0.4);
}

.signup-gate a:hover,
.signup-gate a:focus-visible {
  border-bottom-color: currentColor;
}

/* The hidden attribute is only display:none from the browser stylesheet, so any
   author `display` rule silently defeats it. This puts it back. */
[hidden] {
  display: none !important;
}

/* Single opt-in: this notice is the consent record, so it must be readable
   and sit with the field, not buried in a footer. */
.signup-consent {
  margin: 0;
  color: rgba(255, 255, 255, 0.45);
  font-size: 0.78rem;
  line-height: 1.5;
}

.signup-consent a {
  color: inherit;
  text-decoration: underline;
}

.signup-consent a:hover {
  color: #fff;
}

/* ---- Foxi in the hero ------------------------------------------------- */
/* The character render is portrait 900x1600, so it gets its own hero column
   on wide screens and falls back to a faded backdrop when there is no room. */
.hero__foxi {
  --foxi-opacity: 1;
  position: relative;
  align-self: end;
  justify-self: center;
  width: 100%;
  max-height: calc(100svh - 12rem);
  aspect-ratio: 9 / 16;
  /* Opacity-only fade on purpose: a transform here would create a stacking
     context and stop the video blending with the page behind it. */
  opacity: var(--foxi-opacity);
  animation: foxi-fade-in 0.8s ease 0.24s both;
  pointer-events: none;
}

/* Ends at the declared strength, not at 1: an animation fills forwards and
   outranks a plain opacity declaration, so a hard 1 here quietly cancelled
   every opacity the responsive rules below set. */
@keyframes foxi-fade-in {
  from { opacity: 0; }
  to { opacity: var(--foxi-opacity, 1); }
}

/* This render sits on a smoky backdrop rather than pure black, so screening it
   is not enough on its own: the vignette dissolves what is left of the frame. */
.hero__foxi video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center bottom;
  mix-blend-mode: screen;
  mask-image: radial-gradient(ellipse 53% 62% at 50% 50%, #000 0 34%, transparent 100%);
}

/* A failed load must not leave a tall empty column behind. */
.hero__foxi[hidden] {
  display: none !important;
}

@media (min-width: 1200px) {
  .hero {
    grid-template-columns: minmax(0, 0.85fr) minmax(20rem, 0.7fr) minmax(13rem, 0.42fr);
    gap: clamp(2.5rem, 5vw, 6rem);
  }
}

/* Below the three-column layout Foxi drops behind the copy so the text keeps
   its full measure. */
@media (max-width: 1199px) {
  .hero {
    position: relative;
  }

  .hero__foxi {
    position: absolute;
    right: 0;
    bottom: 0;
    width: min(22rem, 42%);
    --foxi-opacity: 0.34;
  }
}

/* Portrait screens — every phone, and tablets held upright — give the render
   the whole viewport. Kept inside the page column it was a small figure with
   dead space either side of it, which no amount of opacity fixes. A portrait
   viewport is close enough to the 9:16 of the source that covering it crops
   very little; landscape is not, so it keeps the corner composition above. */
@media (max-width: 1199px) and (max-aspect-ratio: 4 / 5) {
  .hero__foxi {
    right: auto;
    left: calc(50% - 50vw);
    top: calc(-1 * var(--hero-top-gap));
    bottom: 0;
    width: 100vw;
    max-width: none;
    max-height: none;
    aspect-ratio: auto;
    /* Inherited from the wide layout, where this was a grid column. Left in
       place it would keep sizing the box to the video and park it at the
       bottom of the span instead of filling it. */
    align-self: stretch;
    justify-self: stretch;
    /* Full screen it carries far more of the frame than it did as a corner
       figure, so it steps back to keep the copy first. */
    --foxi-opacity: 0.15;
  }

  .hero__foxi video {
    height: 100%;
    object-fit: cover;
    object-position: center 20%;
    mask-image: linear-gradient(180deg, transparent 0%, #000 20%, #000 72%, transparent 100%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero__foxi {
    display: none;
  }
}

/* ---- Room for the route dock ------------------------------------------- */
/* The pill is fixed to the bottom of the screen, and the hero puts its call to
   action right there. Shortening the hero lifts the whole centred block clear
   of it instead of padding the button away from its own section. */
@media (max-width: 820px) {
  .hero {
    /* On a tall screen the shorter minimum lifts the centred block; on a short
       one the hero is taller than the viewport anyway, so the only thing that
       buys room for the button is tightening what sits above it. */
    min-height: calc(100svh - 4.75rem - 5.5rem);
    gap: 1.25rem;
    padding-block: 1.75rem 4rem;
  }

  .hero__copy h2 {
    margin-bottom: 0.9rem;
  }

  .hero__mantra {
    margin-bottom: 1rem;
  }

  .hero__copy > p:not(.hero__mantra) {
    margin-bottom: 1rem;
  }

  /* The tighter hero brings its first line up level with the floating code
     stamp, so the stamp moves out of its way. */
  .hero__code {
    top: 0.4rem;
  }
}

/* Short phones: two lines of a 28vw wordmark plus the new subtitle leave the
   button under the dock, so the wordmark gives up the difference. */
@media (max-width: 820px) and (max-height: 800px) {
  h1 {
    font-size: clamp(4.25rem, 23vw, 6.5rem);
  }
}
