/* Velum Studio coming-soon pages (velumstudio.app, velumstudio.dev).
   One stylesheet, no frameworks: the silk ground drifts, light moves across
   its folds, the wordmark rises in and a gold sheen passes over it. Everything
   holds still for people who ask for reduced motion. */

:root {
  --ink: #070506;
  --cream: #f4e9d8;
  --gold: #d4af37;
  --ease: cubic-bezier(.2, .7, .1, 1);
}

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

html, body { height: 100%; }

body {
  background: var(--ink);
  color: var(--cream);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, sans-serif;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
}

/* ---- the silk ground ---------------------------------------------------- */

.ground, .ground::before, .ground::after, .sheen, .vignette, .motes {
  position: fixed;
  inset: 0;
  pointer-events: none;
}

.ground {
  overflow: hidden;
  opacity: 0;
  animation: fade-in 2.4s var(--ease) .1s forwards;
}

/* Two copies of the same silk: the base drifts slowly; the second, brighter
   and softer, drifts the other way so the folds seem to breathe. */
.ground::before, .ground::after {
  content: "";
  inset: -6%;
  background-image: url(img/ground-2560.webp);
  background-image: image-set(url(img/ground-2560.avif) type("image/avif"), url(img/ground-2560.webp) type("image/webp"));
  background-size: cover;
  background-position: center 62%;
  will-change: transform;
}

.ground::before {
  animation: drift-a 42s ease-in-out infinite alternate;
}

.ground::after {
  mix-blend-mode: screen;
  opacity: .32;
  filter: blur(3px) brightness(1.35) saturate(1.15);
  animation: drift-b 33s ease-in-out infinite alternate;
}

@media (max-width: 1500px) {
  .ground::before, .ground::after {
    background-image: url(img/ground-1440.webp);
    background-image: image-set(url(img/ground-1440.avif) type("image/avif"), url(img/ground-1440.webp) type("image/webp"));
  }
}

/* Light travelling across the folds. */
.sheen {
  background:
    radial-gradient(38% 30% at var(--x, 20%) var(--y, 70%), rgba(255, 214, 160, .20), transparent 70%),
    radial-gradient(30% 24% at calc(100% - var(--x, 20%)) calc(var(--y, 70%) - 8%), rgba(214, 150, 190, .12), transparent 70%);
  mix-blend-mode: screen;
  animation: light 26s ease-in-out infinite alternate;
}

@property --x { syntax: "<percentage>"; inherits: false; initial-value: 20%; }
@property --y { syntax: "<percentage>"; inherits: false; initial-value: 70%; }

.vignette {
  background:
    radial-gradient(70% 60% at 50% 42%, transparent 35%, rgba(7, 5, 6, .55) 80%, rgba(7, 5, 6, .9) 100%),
    linear-gradient(to bottom, rgba(7, 5, 6, .55), transparent 22%, transparent 70%, rgba(7, 5, 6, .8));
}

/* A few motes of gold dust, rising very slowly. */
.motes span {
  position: absolute;
  bottom: -2vh;
  left: var(--l);
  width: var(--s);
  height: var(--s);
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 228, 170, .95), rgba(255, 200, 120, 0) 70%);
  opacity: 0;
  animation: rise var(--d) linear var(--w) infinite;
}

/* ---- the stage ----------------------------------------------------------- */

main {
  position: relative;
  z-index: 1;
  height: 100%;
  display: grid;
  grid-template-rows: 1fr auto;
  justify-items: center;
  padding: 0 16px;
}

.stage {
  align-self: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(18px, 3.2vh, 34px);
  width: 100%;
  margin-top: -4vh;
}

h1 { width: min(80vw, 1080px); line-height: 0; }

.wordmark {
  position: relative;
  display: block;
  opacity: 0;
  animation: rise-in 2.2s var(--ease) .5s forwards;
}

.wordmark img { width: 100%; height: auto; display: block; }

/* The sheen: a band of light clipped to the letters themselves. */
.wordmark::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 38%, rgba(255, 249, 230, .85) 48%, rgba(255, 236, 196, .4) 52%, transparent 62%);
  background-size: 260% 100%;
  background-position: 130% 0;
  -webkit-mask: url(img/wordmark.webp) center / 100% 100% no-repeat;
  mask: url(img/wordmark.webp) center / 100% 100% no-repeat;
  mix-blend-mode: soft-light;
  animation: gleam 7.5s ease-in-out 2.6s infinite;
}

.line {
  display: block;
  height: auto;
  opacity: 0;
  animation: rise-in 1.8s var(--ease) forwards;
}

.tagline { width: min(64vw, 760px); animation-delay: 1.3s; }

.soon {
  width: min(34vw, 300px);
  margin-top: clamp(8px, 2vh, 20px);
  animation:
    rise-in 1.8s var(--ease) 1.9s forwards,
    breathe 5.5s ease-in-out 3.7s infinite;
}

/* ---- footer -------------------------------------------------------------- */

footer {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 14px 22px;
  padding: 0 0 clamp(22px, 4.5vh, 44px);
  opacity: 0;
  animation: fade-in 2s var(--ease) 2.6s forwards;
}

footer a {
  display: block;
  opacity: .5;
  transition: opacity .35s ease;
}

footer a:hover, footer a:focus-visible { opacity: 1; }

footer img { display: block; width: auto; }

footer .lmi, footer .cl { height: 20px; }
footer .velora { height: 24px; }

footer .bar {
  width: 1px;
  height: 22px;
  background: rgba(244, 233, 216, .35);
}

.legal {
  position: fixed;
  right: 18px;
  bottom: 14px;
  z-index: 2;
  font-size: 12px;
  letter-spacing: .02em;
  color: rgba(244, 233, 216, .38);
  text-decoration: none;
  opacity: 0;
  animation: fade-in 2s var(--ease) 3s forwards;
}

.legal a { color: inherit; text-decoration: none; }
.legal a:hover { color: rgba(244, 233, 216, .8); }

/* ---- motion -------------------------------------------------------------- */

@keyframes fade-in { to { opacity: 1; } }

@keyframes rise-in {
  from { opacity: 0; transform: translateY(18px); filter: blur(12px); }
  to { opacity: 1; transform: none; filter: blur(0); }
}

@keyframes drift-a {
  from { transform: scale(1.04) translate3d(-1.2%, 0.6%, 0) rotate(-.4deg); }
  to { transform: scale(1.12) translate3d(1.4%, -1.2%, 0) rotate(.5deg); }
}

@keyframes drift-b {
  from { transform: scale(1.14) translate3d(1.6%, -0.4%, 0) rotate(.6deg); }
  to { transform: scale(1.06) translate3d(-1.8%, 1.4%, 0) rotate(-.5deg); }
}

@keyframes light {
  0% { --x: 14%; --y: 78%; }
  50% { --x: 46%; --y: 64%; }
  100% { --x: 82%; --y: 74%; }
}

@keyframes gleam {
  0% { background-position: 130% 0; }
  45%, 100% { background-position: -30% 0; }
}

@keyframes breathe {
  0%, 100% { filter: drop-shadow(0 0 0 rgba(255, 214, 150, 0)); }
  50% { filter: drop-shadow(0 0 14px rgba(255, 214, 150, .35)); }
}

@keyframes rise {
  0% { opacity: 0; transform: translate3d(0, 0, 0); }
  12% { opacity: var(--o); }
  85% { opacity: var(--o); }
  100% { opacity: 0; transform: translate3d(var(--dx), -104vh, 0); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }
  .ground, .wordmark, .line, footer, .legal, .dev .grid { opacity: 1; }
  .ground::before, .ground::after { transform: scale(1.06); }
  .motes { display: none; }
}

/* ---- small screens --------------------------------------------------------- */

@media (max-width: 640px) {
  h1 { width: 90vw; }
  .tagline { width: 86vw; }
  .soon { width: 52vw; }
  footer { gap: 12px 16px; }
  footer .bar { display: none; }
  footer .lmi, footer .cl { height: 15px; }
  footer .velora { height: 18px; }
  .legal { position: static; display: block; text-align: center; padding-bottom: 14px; }
}

/* The developer site: the same silk, cooler and a touch more technical. */
.dev .ground::before { filter: hue-rotate(-18deg) saturate(.85); }
.dev .ground::after { filter: blur(3px) brightness(1.3) saturate(.9) hue-rotate(-24deg); }
.dev .sheen {
  background:
    radial-gradient(38% 30% at var(--x, 20%) var(--y, 70%), rgba(190, 210, 255, .14), transparent 70%),
    radial-gradient(30% 24% at calc(100% - var(--x, 20%)) calc(var(--y, 70%) - 8%), rgba(255, 214, 160, .14), transparent 70%);
}
.dev .grid {
  position: fixed;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(rgba(244, 233, 216, .045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(244, 233, 216, .045) 1px, transparent 1px);
  background-size: 64px 64px;
  -webkit-mask: radial-gradient(60% 55% at 50% 45%, #000, transparent 75%);
  mask: radial-gradient(60% 55% at 50% 45%, #000, transparent 75%);
  opacity: 0;
  animation: fade-in 3s var(--ease) 1s forwards, grid-pan 60s linear infinite;
}
@keyframes grid-pan { to { background-position: 64px 64px, 64px 64px; } }
.dev .subline { width: min(70vw, 820px); animation-delay: 1.3s; }
@media (max-width: 640px) { .dev .subline { width: 88vw; } }
