:root {
  --graphite-950: #08090c;
  --graphite-900: #12141a;
  --graphite-800: #1a1d26;
  --graphite-700: #262a36;
  --graphite-600: #383e4d;

  --cyan-400: #22d3ee;
  --cyan-600: #0e7490;
  --cyan-glow: #7dfdff;

  --purple-400: #c084fc;
  --purple-500: #a855f7;

  --cream-100: #f6efdf;
  --cream-200: #efe6d1;

  --font-display: "Cormorant Garamond", "Times New Roman", serif;
  --font-mono: "Martian Mono", ui-monospace, monospace;
  --font-body: "Manrope", system-ui, sans-serif;

  --container-max: 1400px;
}

* {
  box-sizing: border-box;
}

html {
  background: var(--graphite-950);
  scroll-behavior: auto;
}

/* No background-color here on purpose: when both html and body declare an
   opaque background, which one actually supplies the page's root canvas
   vs. paints as body's own box is a genuine cross-browser inconsistency —
   and body's own box background can end up compositing in front of the
   fixed z-index:-1 .galaxy-bg canvas instead of behind it. html's
   background above is the only one needed as the fallback/base color. */
body {
  margin: 0;
  color: var(--cream-200);
  font-family: var(--font-body);
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Subtle film-grain overlay across the whole page — the cheapest signal
   that a surface was authored, not assembled from flat default fills. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 50;
  pointer-events: none;
  opacity: 0.05;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

img,
video {
  max-width: 100%;
  display: block;
}

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

::selection {
  background: var(--purple-500);
  color: var(--graphite-950);
}

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

.container {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 24px;
}

/* ---------- Loader ---------- */

.loader {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 20px;
  background: var(--graphite-950);
  transition: opacity 0.5s ease;
}

.loader-brand {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.6rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--cream-100);
}

.loader-brand .accent {
  color: var(--purple-500);
}

.loader-bar {
  width: 160px;
  height: 2px;
  background: rgba(14, 116, 144, 0.25);
  overflow: hidden;
}

.loader-bar span {
  display: block;
  width: 40%;
  height: 100%;
  background: var(--purple-500);
  animation: loader-sweep 1.1s ease-in-out infinite;
}

@keyframes loader-sweep {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(350%);
  }
}

.loader-done {
  opacity: 0;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .loader-bar span {
    animation: none;
  }
}

/* ---------- Nav ---------- */

/* Floats over the hero instead of pushing it down: position:absolute (not
   fixed) so it's pinned to the top of the document, not the viewport — it
   scrolls away normally once the page moves past the hero, rather than
   staying pinned for the whole site. */
.nav {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 20;
  background: linear-gradient(180deg, rgba(8, 9, 12, 0.7) 0%, rgba(8, 9, 12, 0.45) 100%);
}

.nav .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 20px;
  padding-bottom: 20px;
}

.wordmark {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.wordmark .accent {
  color: var(--purple-500);
}

.nav-links {
  display: none;
  gap: 2rem;
  font-family: var(--font-body);
  font-size: 0.875rem;
  font-weight: 500;
}

.nav-links a {
  color: rgba(239, 230, 209, 0.7);
  transition: color 0.2s ease;
}

.nav-links a:hover {
  color: var(--cyan-400);
}

@media (min-width: 640px) {
  .nav-links {
    display: flex;
  }
}

.nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: 1px solid rgba(14, 116, 144, 0.3);
  background: transparent;
  color: var(--cyan-400);
  font-size: 1.1rem;
  cursor: pointer;
}

@media (min-width: 640px) {
  .nav-toggle {
    display: none;
  }
}

.nav-mobile {
  display: flex;
  flex-direction: column;
  border-top: 1px solid rgba(14, 116, 144, 0.2);
}

.nav-mobile[hidden] {
  display: none;
}

.nav-mobile a {
  padding: 16px 24px;
  border-bottom: 1px solid rgba(14, 116, 144, 0.15);
  color: rgba(239, 230, 209, 0.8);
  font-family: var(--font-mono);
  font-size: 0.875rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

.nav-mobile a:hover {
  color: var(--cyan-400);
}

@media (min-width: 640px) {
  .nav-mobile {
    display: none !important;
  }
}

/* ---------- Telemetry strip ---------- */

/* Floats directly beneath .nav, same reasoning: position:absolute so both
   overlay the hero and scroll away together with the page afterward. */
.telemetry {
  position: absolute;
  top: 69px;
  left: 0;
  right: 0;
  z-index: 19;
  background: linear-gradient(180deg, rgba(18, 20, 26, 0.55) 0%, rgba(18, 20, 26, 0.2) 70%, transparent 100%);
}

#main {
  position: relative;
  z-index: 1;
}

.telemetry .container {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  overflow-x: auto;
  padding-top: 8px;
  padding-bottom: 8px;
  font-family: var(--font-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  color: var(--purple-500);
  white-space: nowrap;
}

.telemetry .sep {
  color: rgba(14, 116, 144, 0.4);
}

.telemetry .glow {
  color: var(--cyan-glow);
  animation: pulse 2.2s ease-in-out infinite;
}

@keyframes pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.45;
  }
}

/* ---------- Buttons ---------- */

.btn-primary {
  display: inline-block;
  border: 1px solid var(--purple-500);
  color: var(--cyan-400);
  background: transparent;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  padding: 16px 32px;
  box-shadow: 0 0 24px rgba(34, 211, 238, 0.18);
  transition:
    background 0.2s ease,
    color 0.2s ease;
  cursor: pointer;
}

.btn-primary:hover,
.btn-primary:focus-visible {
  background: var(--purple-500);
  color: var(--graphite-950);
}

/* ---------- Sections (shared) ---------- */

.section {
  padding: 6rem 0;
  border-bottom: 1px solid rgba(14, 116, 144, 0.15);
}

.section-alt {
  background: var(--graphite-900);
}

.section-title {
  margin: 0 0 24px;
  font-family: var(--font-display);
  font-weight: 300;
  line-height: 1.08;
  letter-spacing: 0.005em;
  font-size: clamp(2.1rem, 5.2vw, 3.4rem);
  color: var(--cream-100);
}

.section-title .accent {
  color: var(--purple-500);
}

/* Closes #work right after the vault sequence with the "this is the
   general idea, not just these four materials" beat — paired with a
   small ambient gallery so the section's large remaining scroll space
   reads as composed, not one lonely line of text on an empty background. */
.work-payoff-row {
  display: grid;
  grid-template-columns: 1fr;
  align-items: center;
  gap: 48px;
  /* Longhand on purpose: this class shares an element with .container,
     which sets padding: 0 24px for the side margins. A padding shorthand
     here has equal specificity and comes later in the file, so it was
     winning outright and zeroing out those side margins — that's what
     was reading as the text sitting flush against the left edge. */
  padding-top: 120px;
  padding-bottom: 120px;
}

.work-payoff-col {
  position: relative;
}

.work-payoff {
  position: relative;
  max-width: 40ch;
  margin: 0;
  font-family: var(--font-display);
  font-weight: 300;
  font-style: italic;
  line-height: 1.3;
  font-size: clamp(1.9rem, 4.2vw, 3.1rem);
  color: var(--cream-100);
}

.work-payoff .accent {
  color: var(--purple-500);
}

.work-payoff br + .accent {
  display: block;
  width: 100%;
  text-align: center;
  margin-top: 48px;
}

.work-payoff-gallery {
  position: relative;
  aspect-ratio: 1 / 1;
  width: 100%;
  max-width: 480px;
  margin: 0 auto;
}

.work-payoff-gallery video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* screen blend only fully hides a PURE black background — this footage's
     background is a dark charcoal gray, not true black, so blend alone
     left a visible rectangular panel. brightness/contrast push that gray
     down toward black before blending (the bright chrome highlights stay
     well above the threshold), and the radial mask feathers the video's
     hard rectangular edge into nothing so what's left reads as a soft
     glow sitting in the starfield rather than a panel with corners. */
  filter: brightness(0.72) contrast(1.35);
  mix-blend-mode: screen;
  -webkit-mask-image: radial-gradient(closest-side, #000 62%, transparent 100%);
  mask-image: radial-gradient(closest-side, #000 62%, transparent 100%);
}

@media (min-width: 900px) {
  .work-payoff-row {
    grid-template-columns: 1.15fr 0.85fr;
    gap: 64px;
  }
}

/* Full-width closer for #work: the same "one object, infinite materials"
   idea, scaled up to an entire room, right below the payoff line. */
.room-transform {
  max-width: var(--container-max);
  margin: 0 auto 120px;
  padding: 0 24px;
}

.room-transform-video {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: var(--graphite-950);
  border: 1px solid rgba(14, 116, 144, 0.35);
  box-shadow: 0 24px 60px rgba(8, 9, 12, 0.45);
}

.section-lead {
  max-width: 60ch;
  margin: 0 0 48px;
  font-size: 1.05rem;
  line-height: 1.6;
  color: rgba(239, 230, 209, 0.8);
}

/* ---------- Lively text ---------- */
/* Two reveal tiers, populated by js/main.js's splitChars()/splitWords();
   degrades to plain unsplit text with no JS or under
   prefers-reduced-motion.

   Tier 1 — decode: headlines, numbers, short labels. Each character
   cycles through glyph noise before locking to the real character, the
   same "resolving from generative noise" idea as the hero video, applied
   to type.

   Tier 2 — resolve: paragraphs. Each word rises out of a blur with a
   slight 3D tilt, cheaper to read at paragraph length than a full
   per-character decode. */

.char,
.word {
  display: inline-block;
  will-change: transform, opacity, filter;
}

/* Groups one word's .char spans so they can't be split across a line
   break — see the comment on splitChars() in js/main.js. */
.char-word {
  display: inline-block;
  white-space: nowrap;
}

.char-scramble {
  color: var(--cyan-400);
  text-shadow: 0 0 6px var(--cyan-glow);
}

.char-lock {
  animation: char-lock-flash 0.42s ease-out;
}

@keyframes char-lock-flash {
  0% {
    text-shadow:
      0 0 3px var(--cyan-glow),
      0 0 16px var(--cyan-glow);
  }
  100% {
    text-shadow: none;
  }
}

/* ---------- Galaxy background (fixed, parallax-scrolled) ---------- */
/* A position:fixed canvas sitting behind the whole page. Deliberately a
   non-negative z-index: negative z-index on a fixed child of an
   unpositioned <body> depends on which of html/body supplies the root
   "canvas background" per spec, which is inconsistent enough across
   engines that it was compositing behind opaque content unpredictably.
   Positive z-index is unambiguous instead — everything meant to sit in
   front (.nav, .telemetry, #main, .site-footer) is given an explicit
   z-index: 1+ of its own so ordinary stacking-order comparison settles it.
   Any section left without its own opaque fill (#work, #process,
   #contact) shows this through, which is what visually threads the hero
   scroll, the vault scroll and the process section into one continuous
   space instead of a series of flat-panel cuts. */

.galaxy-bg {
  position: fixed;
  inset: 0;
  z-index: 0;
  display: block;
  background:
    radial-gradient(ellipse 65% 50% at 18% 22%, rgba(168, 85, 247, 0.28), transparent 62%),
    radial-gradient(ellipse 60% 45% at 82% 68%, rgba(34, 211, 238, 0.24), transparent 62%),
    radial-gradient(ellipse 45% 35% at 50% 92%, rgba(168, 85, 247, 0.16), transparent 68%);
}

/* ---------- Process: floating windows over the galaxy background ---------- */

.process-section {
  position: relative;
  padding-top: 96px;
  padding-bottom: 96px;
}

.process-windows {
  position: relative;
  max-width: var(--container-max);
  margin: 56px auto 0;
  padding: 0 24px;
  display: grid;
  grid-template-columns: 1fr;
  gap: 32px;
}

.process-window {
  position: relative;
  display: flex;
  flex-direction: column;
  /* A flat, more opaque fill instead of backdrop-filter: blur — three
     always-visible glass cards re-blurring an animated canvas behind them
     every frame is one of the more expensive things a browser can be
     asked to composite, and it's what was reading as page-wide jank. */
  background: rgba(8, 9, 12, 0.82);
  border: 1px solid rgba(14, 116, 144, 0.35);
  box-shadow: 0 24px 60px rgba(8, 9, 12, 0.45);
}

.process-window-media {
  position: relative;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  border-bottom: 1px solid rgba(14, 116, 144, 0.35);
}

.process-window-media img,
.process-window-media video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.process-window-copy {
  padding: 24px;
}

.process-index {
  display: block;
  margin-bottom: 10px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  color: var(--purple-500);
}

.process-window-copy h3 {
  margin: 0 0 8px;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.6rem;
  color: var(--cream-100);
}

.process-window-copy p {
  margin: 0;
  color: rgba(239, 230, 209, 0.75);
  line-height: 1.55;
  font-size: 0.95rem;
}

@media (min-width: 900px) {
  .process-windows {
    grid-template-columns: repeat(3, 1fr);
    align-items: start;
  }

  /* A slight vertical stagger so the three windows read as one composed
     view rather than a rigid grid — still "en el mismo golpe de vista". */
  .process-window:nth-child(2) {
    margin-top: 40px;
  }

  .process-window:nth-child(3) {
    margin-top: -20px;
  }
}

/* ---------- Upscale before/after slider ---------- */

.upscale-slider {
  position: relative;
  width: 100%;
  height: 100%;
  --pos: 50%;
  cursor: ew-resize;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}

.upscale-sharp,
.upscale-blur {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}

.upscale-blur {
  clip-path: inset(0 calc(100% - var(--pos)) 0 0);
}

.upscale-handle {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--pos);
  width: 2px;
  background: var(--cyan-400);
  box-shadow: 0 0 10px var(--cyan-glow);
  transform: translateX(-50%);
  pointer-events: none;
}

.upscale-handle-grip {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  background: var(--graphite-950);
  border: 1px solid var(--cyan-400);
  color: var(--cyan-400);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.05em;
}

/* ---------- About: "qué es FutureFormStudios" ---------- */

.about-section {
  position: relative;
  overflow: hidden;
  padding-top: 120px;
  padding-bottom: 120px;
}

.about-bg {
  position: absolute;
  left: 0;
  right: 0;
  top: -12%;
  height: 124%;
  background-position: center 30%;
  background-size: cover;
  background-repeat: no-repeat;
  opacity: 0.34;
  will-change: transform;
}

.about-scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, var(--graphite-950) 0%, rgba(8, 9, 12, 0.55) 22%, rgba(8, 9, 12, 0.72) 78%, var(--graphite-950) 100%),
    radial-gradient(ellipse 60% 55% at 50% 40%, rgba(8, 9, 12, 0.35), transparent 70%);
}

.about-panel {
  position: relative;
  z-index: 1;
  max-width: 760px;
}

.about-eyebrow {
  display: block;
  margin-bottom: 14px;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--purple-500);
}

.about-brand-title {
  margin-bottom: 28px;
}

/* Shared "material" text treatment: an animated gradient sweeping through
   grass/amethyst/diamond/stone tones, clipped to the text itself. Reused
   on any accent word that should read as "made of shifting materials" —
   the about section's brand word, and .title-material-accent below for
   the same effect on section-title accent spans elsewhere on the page. */
.about-brand-word,
.title-material-accent {
  display: inline-block;
  background-image: linear-gradient(
    90deg,
    #6b9b37, #a8d570, #d9f2b0,
    #a855f7, #c084fc, #e9d5ff,
    #ffffff, #bff4ff, #7dfdff,
    #8a8a8a, #cfcfcf, #6b6b6b,
    #6b9b37
  );
  background-size: 420% 100%;
  background-clip: text;
  -webkit-background-clip: text;
  /* !important: .title-material-accent is applied alongside .accent on
     section-title/hero-headline spans, and the scoped ".x .accent { color:
     var(--purple-500) }" rules those live under — one of them (hero.css)
     in a stylesheet that loads after this one — otherwise win the color
     on specificity/order and paint over the gradient with flat purple. */
  color: transparent !important;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 0 22px rgba(125, 253, 255, 0.25));
  animation: about-material-flow 16s linear infinite;
}

.about-brand-word {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(2.4rem, 7vw, 5rem);
  line-height: 1.05;
}

.title-material-accent {
  filter: drop-shadow(0 0 14px rgba(125, 253, 255, 0.2));
}

@keyframes about-material-flow {
  from { background-position: 0% 0%; }
  to { background-position: -420% 0%; }
}

@media (prefers-reduced-motion: reduce) {
  .about-brand-word,
  .title-material-accent {
    animation: none;
    background-position: -180% 0%;
  }
}

.about-quote {
  margin: 22px 0 0;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.2rem, 2.2vw, 1.5rem);
  color: var(--purple-400);
  text-shadow: 0 0 24px rgba(168, 85, 247, 0.25);
}

.about-quote::before {
  content: '— ';
  color: rgba(192, 132, 252, 0.5);
}

.about-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  margin: 36px 0 28px;
  padding-top: 28px;
  border-top: 1px solid rgba(14, 116, 144, 0.25);
}

.about-stat dt {
  font-family: var(--font-mono);
  font-size: clamp(1.6rem, 3.4vw, 2.25rem);
  color: var(--cyan-400);
  text-shadow: 0 0 18px var(--cyan-glow);
}

.about-stat dd {
  margin: 6px 0 0;
  font-family: var(--font-body);
  font-size: 0.8rem;
  color: rgba(239, 230, 209, 0.65);
}

.about-collab {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  letter-spacing: 0.03em;
  color: rgba(239, 230, 209, 0.7);
}

.about-collab-logo {
  display: inline-block;
  height: 34px;
  width: auto;
  margin-left: 6px;
  vertical-align: -11px;
  filter: brightness(0) invert(1);
  opacity: 0.95;
}

@media (max-width: 640px) {
  .about-stats {
    grid-template-columns: 1fr 1fr;
  }
}

/* ---------- Course ---------- */

.course-trailer {
  margin: 40px 0 48px;
  background: rgba(8, 9, 12, 0.82);
  border: 1px solid rgba(14, 116, 144, 0.35);
  box-shadow: 0 24px 60px rgba(8, 9, 12, 0.45);
}

.course-trailer-video {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: var(--graphite-950);
}

.course-trailer-caption {
  margin: 0;
  padding: 14px 20px;
  border-top: 1px solid rgba(14, 116, 144, 0.35);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  color: rgba(239, 230, 209, 0.7);
  text-transform: uppercase;
}

.course-trailer-caption span {
  color: var(--purple-500);
  margin-right: 8px;
}

.course-modules {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  list-style: none;
  margin: 0 0 48px;
  padding: 0;
  border-top: 1px solid rgba(14, 116, 144, 0.2);
}

.course-modules li {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px 0;
  border-bottom: 1px solid rgba(14, 116, 144, 0.2);
  font-family: var(--font-body);
  color: rgba(239, 230, 209, 0.85);
}

.course-modules li > span:first-child {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--purple-500);
  min-width: 2.5ch;
}

.course-module-label {
  display: inline-block;
}

@media (min-width: 768px) {
  .course-modules {
    grid-template-columns: 1fr 1fr;
    column-gap: 40px;
  }
}

.course-cta {
  display: flex;
  align-items: center;
  gap: 24px;
  flex-wrap: wrap;
}

.course-price {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 2rem;
  color: var(--cyan-400);
}

.course-price span {
  font-size: 0.75rem;
  color: rgba(239, 230, 209, 0.55);
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

/* ---------- Contact form ---------- */

.contact-form {
  max-width: 640px;
  display: grid;
  gap: 20px;
}

.form-row {
  display: grid;
  gap: 8px;
}

/* Honeypot: kept in normal layout flow (not display:none) since some bots
   skip hidden fields, just moved off-screen so no human ever sees or
   tabs into it. */
.form-honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-row-half {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
}

@media (min-width: 480px) {
  .form-row-half {
    grid-template-columns: 1fr 1fr;
  }
}

.form-row-half > div {
  display: grid;
  gap: 8px;
}

label {
  font-family: var(--font-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: rgba(239, 230, 209, 0.7);
}

input,
select,
textarea {
  background: var(--graphite-900);
  border: 1px solid rgba(14, 116, 144, 0.3);
  color: var(--cream-100);
  font-family: var(--font-body);
  font-size: 1rem;
  padding: 12px 14px;
  border-radius: 0;
}

input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  border-color: var(--purple-500);
}

.form-error {
  min-height: 1em;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--cyan-glow);
}

.form-row.has-error input,
.form-row.has-error textarea {
  border-color: var(--cyan-glow);
}

.form-confirmation {
  margin: 0;
  padding: 14px 16px;
  border: 1px solid rgba(14, 116, 144, 0.4);
  background: rgba(168, 85, 247, 0.08);
  color: var(--cyan-400);
  font-size: 0.9rem;
}

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

.site-footer {
  position: relative;
  z-index: 1;
  padding: 32px 0;
}

.site-footer p {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: rgba(239, 230, 209, 0.5);
}

.site-footer .legal-footer-links {
  margin-top: 8px;
}

.legal-footer-links a {
  color: rgba(239, 230, 209, 0.6);
}

.legal-footer-links a:hover {
  color: var(--cyan-400);
}

/* ---------- Utility ---------- */

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
