/* ── BLACK SYNTAX — base ─────────────────────────────────────────── */

:root {
  --void: #000000;
  --grey: #6e6e6e;      /* resting glyph grey */
  --grey-dim: #3a3a3a;  /* low point of the pulse */
  --grey-lit: #a8a8a8;  /* hover / focus */
  --orb-glow: #e9e9e9;  /* almost white */
  --mono: "Cascadia Mono", "JetBrains Mono", Consolas, "SF Mono", Menlo, monospace;
  --orb-rest: 30vh;     /* where the orb settles */
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html, body {
  height: 100%;
  background: var(--void);
  overflow: hidden;
}

body {
  font-family: var(--mono);
  color: var(--grey);
  -webkit-font-smoothing: antialiased;
  cursor: default;
}

.scene {
  position: fixed;
  inset: 0;
}

/* present for machines and screen readers, invisible to the eye */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ── Scene 0 — The Threshold ─────────────────────────────────────── */

/*
 * The sigil sits on the lower-third line: its baseline rides at 2/3
 * viewport height, pinned toward the right edge.
 */
.sigil {
  position: absolute;
  top: 66.666vh;
  right: clamp(1.5rem, 8vw, 7rem);
  transform: translateY(-50%);

  display: inline-flex;
  align-items: baseline;
  gap: 1.1em;

  background: none;
  border: 0;
  font: inherit;
  color: var(--grey);
  font-size: clamp(0.85rem, 1.6vw, 1.25rem);
  letter-spacing: 0.32em;
  white-space: nowrap;
  cursor: pointer;

  animation: breathe 5.2s ease-in-out infinite;
  transition: color 1.2s ease;
}

.sigil__key {
  font-size: 0.82em;
  opacity: 0.85;
}

/* the slow flash — a breath, not a blink */
@keyframes breathe {
  0%, 100% { opacity: 0.25; }
  50%      { opacity: 1; }
}

.sigil:hover,
.sigil:focus-visible {
  color: var(--grey-lit);
  animation-play-state: paused;
  opacity: 1;
  outline: none;
}

/* each glyph is its own body once gravity takes it */
.sigil__char {
  display: inline-block;
}

/* ── The crossing — the ground gives way ─────────────────────────── */

.scene--threshold.is-crossing .sigil {
  animation: none;
  opacity: 1;
  cursor: default;
  pointer-events: none;
}

.scene--threshold.is-crossing .sigil__char {
  animation: drop 1.35s cubic-bezier(0.5, 0.05, 0.9, 0.5) forwards;
  animation-delay: var(--d, 0s);
}

@keyframes drop {
  0%   { transform: translate(0, 0) rotate(0deg); opacity: 1; }
  8%   { transform: translate(0, -0.08em) rotate(0deg); }      /* a last breath before the fall */
  100% { transform: translate(var(--x, 0), 110vh) rotate(var(--r, 0deg)); opacity: 0.85; }
}

.scene--threshold.is-fallen .sigil {
  display: none;
}

/* ── Scene 1 — The Orb ───────────────────────────────────────────── */

.orb-wrap {
  position: absolute;
  left: 50%;
  top: -14vh;
  width: 56px;
  height: 56px;
  transform: translateX(-50%);
  transition: top 2.6s cubic-bezier(0.2, 0.7, 0.3, 1);
  /* after the descent, js/main.js takes over this element's
     position with inline styles — the orb becomes a free body */
}

.orb-wrap.is-arrived {
  top: var(--orb-rest);
}

.orb {
  position: relative;
  width: 56px;   /* generous hit area — the visible orb is the core */
  height: 56px;
  background: none;
  border: 0;
  cursor: pointer;
  animation: hover-drift 6.4s ease-in-out infinite;
}

.orb__core {
  position: absolute;
  inset: 50%;
  width: clamp(13px, 1.6vw, 18px);
  height: clamp(13px, 1.6vw, 18px);
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle at 36% 32%,
              #ffffff 0%, var(--orb-glow) 42%, rgba(233, 233, 233, 0) 74%);
  box-shadow:
    0 0 10px 2px  rgba(238, 238, 238, 0.65),
    0 0 34px 9px  rgba(228, 228, 228, 0.22),
    0 0 90px 26px rgba(220, 220, 220, 0.07);
  transition: box-shadow 1s ease;
}

/* the floatiness — a slow bob with a hint of sway */
@keyframes hover-drift {
  0%, 100% { transform: translate(0, 0); }
  30%      { transform: translate(2px, -7px); }
  55%      { transform: translate(-2px, 3px); }
  80%      { transform: translate(1px, -4px); }
}

.orb:hover .orb__core,
.orb:focus-visible .orb__core {
  box-shadow:
    0 0 14px 3px  rgba(244, 244, 244, 0.85),
    0 0 44px 12px rgba(232, 232, 232, 0.3),
    0 0 110px 34px rgba(224, 224, 224, 0.1);
}

.orb:focus-visible { outline: none; }

/* ── The menu — unfolds downward from the orb ────────────────────── */

.menu {
  position: absolute;
  top: calc(100% + 2.2rem);
  left: 50%;
  transform: translateX(-50%);
  visibility: hidden;
  /* wait for the links' fade-out before vanishing */
  transition: visibility 0s linear 0.4s;
}

.menu__list {
  list-style: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.55rem;
}

.menu__link {
  display: inline-block;
  color: var(--grey);
  text-decoration: none;
  font-size: clamp(0.8rem, 1.3vw, 1rem);
  letter-spacing: 0.38em;
  white-space: nowrap;

  opacity: 0;
  transform: translateY(-14px);
  transition:
    opacity 0.7s ease var(--md, 0s),
    transform 0.7s cubic-bezier(0.2, 0.7, 0.3, 1) var(--md, 0s),
    color 0.4s ease, text-shadow 0.4s ease;
}

.menu__item:nth-child(1) .menu__link { --md: 0.05s; }
.menu__item:nth-child(2) .menu__link { --md: 0.17s; }
.menu__item:nth-child(3) .menu__link { --md: 0.29s; }
.menu__item:nth-child(4) .menu__link { --md: 0.41s; }
.menu__item:nth-child(5) .menu__link { --md: 0.53s; }
.menu__item:nth-child(6) .menu__link { --md: 0.65s; }
.menu__item:nth-child(8) .menu__link { --md: 0.82s; }
.menu__item:nth-child(9) .menu__link { --md: 0.94s; }

/* the line between what we made and what is yours */
.menu__divider {
  --md: 0.74s;
  width: 5.5rem;
  height: 1px;
  background: #2a2a2a;
  opacity: 0;
  transition: opacity 0.7s ease var(--md);
}

.orb-wrap.is-open .menu__divider {
  opacity: 1;
}

.orb-wrap:not(.is-open) .menu__divider {
  --md: 0s;
  transition-duration: 0.35s;
}

.orb-wrap.is-open .menu {
  visibility: visible;
  transition-delay: 0s;
}

.orb-wrap.is-open .menu__link {
  opacity: 1;
  transform: translateY(0);
}

/* closing: collapse back up, no stagger */
.orb-wrap:not(.is-open) .menu__link {
  --md: 0s;
  transition-duration: 0.35s;
}

.menu__link:hover,
.menu__link:focus-visible {
  color: var(--orb-glow);
  text-shadow: 0 0 18px rgba(233, 233, 233, 0.45);
  outline: none;
}

/* ── Scene 2 — Manifestation ─────────────────────────────────────
   The threshold falls apart; a product assembles. Its glyphs
   drift in from scattered positions and lock into place. */

.product {
  position: fixed;
  inset: 0;
  z-index: 5;
  display: grid;
  place-items: center;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.8s ease, visibility 0s linear 0.8s;
}

.product.is-in {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}

.product__body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.6rem;
  text-align: center;
  padding: 0 1.5rem;
}

.product__title {
  font-size: clamp(1.8rem, 6.5vw, 4.2rem);
  font-weight: normal;
  color: var(--grey-lit);
  letter-spacing: 0.28em;
  text-shadow: 0 0 40px rgba(233, 233, 233, 0.12);
  white-space: nowrap;
}

/* quieter scale — for titles that are a doorway, not a monument */
.product__title--small {
  font-size: clamp(1.05rem, 3.2vw, 2rem);
  letter-spacing: 0.34em;
}

.product__glyph {
  display: inline-block;
  opacity: 0;
  transform: translate(var(--gx, 0), var(--gy, 0)) rotate(var(--gr, 0deg));
  transition:
    transform 1.15s cubic-bezier(0.2, 0.7, 0.2, 1) var(--gd, 0s),
    opacity 0.9s ease var(--gd, 0s);
}

.product.is-in .product__glyph {
  opacity: 1;
  transform: none;
}

.product__line {
  font-size: clamp(0.7rem, 1.2vw, 0.85rem);
  letter-spacing: 0.4em;
  color: var(--grey);
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 1s ease 1.1s, transform 1s ease 1.1s;
}

.product.is-in .product__line {
  opacity: 1;
  transform: none;
}

.product__enter {
  font-size: 0.8rem;
  letter-spacing: 0.38em;
  color: var(--grey);
  text-decoration: none;
  opacity: 0;
  transition: opacity 1s ease 1.5s, color 0.4s ease, text-shadow 0.4s ease;
}

.product.is-in .product__enter {
  opacity: 1;
}

.product__enter:hover,
.product__enter:focus-visible {
  color: var(--orb-glow);
  text-shadow: 0 0 18px rgba(233, 233, 233, 0.45);
  outline: none;
}

/* ── Scene 3 — Speak ─────────────────────────────────────────────
   The form condenses out of the dark: it starts unfocused and
   dim, then resolves — like something surfacing, not appearing. */

.orb-wrap { z-index: 10; } /* the orb rides above the contact veil */

.contact {
  position: fixed;
  inset: 0;
  z-index: 5;
  display: grid;
  place-items: center;
  opacity: 0;
  filter: blur(14px);
  transition: opacity 1.3s ease, filter 1.3s ease, visibility 0s linear 1.3s;
  visibility: hidden;
}

.contact.is-in {
  opacity: 1;
  filter: none;
  visibility: visible;
  transition-delay: 0s;
}

.contact__form {
  display: flex;
  flex-direction: column;
  gap: 1.7rem;
  width: min(400px, 86vw);
}

.contact__title {
  font-size: clamp(0.85rem, 1.4vw, 1.1rem);
  font-weight: normal;
  color: var(--grey);
  letter-spacing: 0.55em;
  margin-bottom: 0.4rem;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}

.field__name {
  font-size: 0.62rem;
  letter-spacing: 0.45em;
  color: var(--grey-dim);
  transition: color 0.5s ease;
}

.field:focus-within .field__name {
  color: var(--grey);
}

.field__input {
  background: transparent;
  border: 0;
  border-bottom: 1px solid #242424;
  border-radius: 0;
  color: var(--grey-lit);
  caret-color: var(--orb-glow);
  font: inherit;
  font-size: 0.95rem;
  letter-spacing: 0.08em;
  padding: 0.45em 0;
  outline: none;
  transition: border-color 0.5s ease;
}

.field__input:focus {
  border-color: var(--grey-lit);
}

.field__input--area {
  resize: vertical;
  min-height: 5.5em;
  line-height: 1.7;
}

.contact__send {
  align-self: flex-start;
  margin-top: 0.4rem;
  background: none;
  border: 0;
  font: inherit;
  font-size: 0.85rem;
  letter-spacing: 0.38em;
  color: var(--grey);
  cursor: pointer;
  transition: color 0.4s ease, text-shadow 0.4s ease;
}

.contact__send:hover,
.contact__send:focus-visible {
  color: var(--orb-glow);
  text-shadow: 0 0 18px rgba(233, 233, 233, 0.45);
  outline: none;
}

.contact__status {
  min-height: 1.2em;
  font-size: 0.62rem;
  letter-spacing: 0.35em;
  color: var(--grey-dim);
}

/* ── Context awareness ───────────────────────────────────────────── */

/* motion-sensitive visitors: no fall, no drift — quiet dissolves */
@media (prefers-reduced-motion: reduce) {
  .sigil { animation: none; opacity: 0.8; }
  .scene--threshold.is-crossing .sigil__char {
    animation: none;
    transition: opacity 0.8s ease;
    opacity: 0;
  }
  .orb-wrap { transition: opacity 0.8s ease; opacity: 0; }
  .orb-wrap.is-arrived { top: var(--orb-rest); opacity: 1; }
  .orb { animation: none; }
  .contact { filter: none; transition: opacity 0.8s ease, visibility 0s linear 0.8s; }
  .product__glyph { transform: none; transition: opacity 0.9s ease var(--gd, 0s); }
  .product__line { transform: none; }
}

/* portrait / narrow framing keeps the lines readable */
@media (max-width: 480px) {
  .sigil { letter-spacing: 0.22em; gap: 0.8em; }
  .menu__link { letter-spacing: 0.28em; }
}
