/* One stylesheet for the whole site. Dark, quiet, and the same haze the app puts
   behind a portal: soft radial light, nothing with a hard edge. */

:root {
  color-scheme: dark;
  --ink: #f4f2ef;
  --dim: rgba(244, 242, 239, .62);
  --faint: rgba(244, 242, 239, .38);
  --ground: #0b0b0e;
  --accent: #7fb3ff;
  --edge: rgba(255, 255, 255, .14);
  --serif: "New York", "Iowan Old Style", Palatino, Georgia, serif;
  --sans: -apple-system, "SF Pro Text", system-ui, "Segoe UI", sans-serif;
}

* { box-sizing: border-box }

body {
  margin: 0;
  min-height: 100vh;
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
  background: var(--ground);
  color: var(--ink);
  font: 17px/1.55 var(--sans);
  -webkit-font-smoothing: antialiased;
  display: flex;
  flex-direction: column;
}

/* The haze: two slow washes of colour, well behind everything. */
body::before {
  content: "";
  position: fixed;
  inset: -20vmax;
  z-index: -1;
  background:
    radial-gradient(38vmax 38vmax at 20% 12%, rgba(104, 142, 235, .46), transparent 68%),
    radial-gradient(46vmax 46vmax at 86% 64%, rgba(203, 122, 196, .34), transparent 70%),
    radial-gradient(64vmax 42vmax at 46% 106%, rgba(118, 202, 194, .26), transparent 72%);
  filter: blur(34px);
  animation: drift 46s ease-in-out infinite alternate;
}

@keyframes drift {
  to { transform: translate3d(2vmax, -2vmax, 0) scale(1.06) }
}

@media (prefers-reduced-motion: reduce) {
  body::before { animation: none }
}

main {
  flex: 1;
  width: 100%;
  max-width: 40rem;
  margin: 0 auto;
  padding: 12vh 1.75rem 4rem;
}

.mark {
  display: flex;
  align-items: center;
  gap: .6rem;
  font: 600 .95rem/1 var(--sans);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--faint);
}

.mark img { width: 22px; height: 22px; opacity: .75 }

h1 {
  font: 400 clamp(2.6rem, 9vw, 4.1rem)/1.03 var(--serif);
  letter-spacing: -.015em;
  margin: 1.5rem 0 0;
}

.lede {
  font: 400 clamp(1.15rem, 3.6vw, 1.4rem)/1.4 var(--serif);
  color: var(--dim);
  margin: .9rem 0 0;
  max-width: 30ch;
}

p { margin: 1.15rem 0 0; color: var(--dim) }
p.tight { margin-top: .5rem }
p.small { font-size: .9rem; color: var(--faint); max-width: 42ch }
strong { color: var(--ink); font-weight: 600 }

.rule { height: 1px; background: var(--edge); border: 0; margin: 3rem 0 0 }

h2 {
  font: 600 .8rem/1 var(--sans);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--faint);
  margin: 2.6rem 0 0;
}

ol.steps { list-style: none; counter-reset: step; margin: 1rem 0 0; padding: 0 }

ol.steps li {
  counter-increment: step;
  position: relative;
  padding: 0 0 0 2.4rem;
  margin: 1.1rem 0 0;
  color: var(--dim);
}

ol.steps li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: -.05rem;
  width: 1.65rem;
  height: 1.65rem;
  border: 1px solid var(--edge);
  border-radius: 999px;
  display: grid;
  place-items: center;
  font: 600 .8rem/1 var(--sans);
  color: var(--faint);
}

ol.steps b { color: var(--ink); font-weight: 600 }

.actions { display: flex; flex-wrap: wrap; gap: .7rem; margin: 2rem 0 0 }

a.btn {
  display: inline-block;
  padding: .85rem 1.5rem;
  border-radius: 999px;
  font: 600 1rem/1.2 var(--sans);
  text-decoration: none;
  color: var(--ground);
  background: var(--ink);
  transition: transform .15s ease, opacity .15s ease;
}

a.btn:hover { transform: translateY(-1px) }
a.btn.ghost { color: var(--ink); background: transparent; border: 1px solid var(--edge) }

.note {
  margin: 1.6rem 0 0;
  padding: .95rem 1.1rem;
  border: 1px solid var(--edge);
  border-radius: 14px;
  background: rgba(255, 255, 255, .04);
  color: var(--dim);
  font-size: .95rem;
}

footer {
  width: 100%;
  max-width: 40rem;
  margin: 0 auto;
  padding: 2rem 1.75rem 3rem;
  color: var(--faint);
  font-size: .85rem;
  display: flex;
  flex-wrap: wrap;
  gap: 1.1rem;
}

footer a { color: var(--faint); text-decoration: none; border-bottom: 1px solid var(--edge) }
footer a:hover { color: var(--ink) }

/* An inline script sets data-ios on <html> before paint; the page reads the same
   without it, so a browser with no JavaScript gets the non-iOS wording. */
.ios-only { display: none }
[data-ios] .ios-only { display: revert }
[data-ios] .not-ios { display: none }

/* ---- the peep box: an arch cut in the page, with somewhere else behind it ----
   Each layer inside carries --d, how far it travels at the edges of the screen;
   near things move most, which is the whole trick. website/peep.js sets --px / --py. */

.hero { display: grid; gap: .2rem }
.say .after { margin-top: 1.15rem }
.peep { margin: 2.2rem 0 0 }

.arch {
  position: relative;
  width: min(100%, 23rem);
  aspect-ratio: 5 / 6;
  overflow: hidden;
  border-radius: 46% 46% 12px 12px / 34% 34% 10px 10px;
  background: #0c1030;
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, .16),
    0 2px 0 0 rgba(255, 255, 255, .07) inset,
    0 30px 70px -30px rgba(120, 150, 255, .5),
    0 0 90px -20px rgba(210, 150, 120, .28);
}

.scene { position: absolute; inset: 0; width: 100%; height: 100% }

.scene .lyr {
  transform: translate3d(calc(var(--px, 0) * var(--d) * -1px), calc(var(--py, 0) * var(--d) * -.42px), 0);
  will-change: transform;
}

/* The jamb: the page has thickness, and the light spills over the sill. */
.glass {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(180deg, rgba(6, 6, 14, .55), transparent 22%),
    radial-gradient(120% 88% at 50% 46%, transparent 52%, rgba(6, 6, 14, .5)),
    linear-gradient(104deg, rgba(255, 255, 255, .1) 4%, transparent 26%);
}

.hint { margin: .9rem 0 0; font-size: .84rem; color: var(--faint); letter-spacing: .01em }
.hint .coarse { display: none }
@media (pointer: coarse) {
  .hint .fine { display: none }
  .hint .coarse { display: inline }
}

/* The same arch with the curtain still drawn: a world nobody has opened yet. */
.arch.shut {
  width: min(100%, 17.5rem);
  background: radial-gradient(130% 100% at 50% 62%, #35315f, #100e24 74%);
}

.arch.shut .veil {
  position: absolute;
  inset: -34%;
  background:
    radial-gradient(28% 24% at 30% 30%, rgba(140, 174, 255, .8), transparent 70%),
    radial-gradient(32% 28% at 72% 58%, rgba(226, 140, 214, .66), transparent 72%),
    radial-gradient(38% 24% at 46% 96%, rgba(126, 226, 214, .5), transparent 74%),
    radial-gradient(22% 20% at 84% 20%, rgba(255, 206, 150, .38), transparent 72%);
  filter: blur(20px);
  animation: breathe 16s ease-in-out infinite alternate;
}

/* A few motes, so the thing is clearly holding something back. */
.arch.shut .veil::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(1.5px 1.5px at 22% 38%, rgba(255, 255, 255, .85), transparent),
    radial-gradient(1.5px 1.5px at 58% 22%, rgba(255, 255, 255, .6), transparent),
    radial-gradient(2px 2px at 74% 66%, rgba(255, 255, 255, .7), transparent),
    radial-gradient(1.5px 1.5px at 38% 78%, rgba(255, 255, 255, .5), transparent),
    radial-gradient(1.5px 1.5px at 84% 44%, rgba(255, 255, 255, .45), transparent);
  animation: motes 22s ease-in-out infinite alternate;
}

@keyframes breathe { to { transform: translate3d(4%, -3%, 0) scale(1.14) } }
@keyframes motes { to { transform: translate3d(-3%, -6%, 0) } }

@media (prefers-reduced-motion: reduce) {
  .arch.shut .veil, .arch.shut .veil::after { animation: none }
}

/* Wide enough for the box to sit beside what it is explaining. */
@media (min-width: 62rem) {
  main { max-width: 58rem }
  main > :not(.hero) { max-width: 34rem }
  footer { max-width: 58rem }
  .hero {
    grid-template-columns: minmax(0, 1fr) 21rem;
    gap: 4rem;
    align-items: center;
    margin-bottom: 1rem;
  }
  .say { max-width: 34rem }
  .peep { margin: 0 }
  .arch { width: 21rem }
  .hero .hint { text-align: center }   /* under the box, which is its own column here */
}
