/* ===== Hyola landing page =====
   Single locked viewport, no scroll, no nav. Structure and treatment follow a
   Figma reference ("RenoMono"): blurred glow-blob background (the reference's
   actual exported Ellipses/Noise assets, recolored), a huge serif headline
   with a vertical white-to-transparent gradient fill, and a small caption
   flanked by hairlines. Headline font is Boska (Fontshare, free for personal
   and commercial use under the ITF Free Font License) standing in for the
   paid, ligature-heavy "Cigra" the user referenced. Self-hosted like every
   other font here — the license permits @font-face embedding on your own
   site, it only forbids redistributing the raw files to other people.
   Caption font substitutes the paid Muller with Plus Jakarta Sans. */

@font-face {
  font-family: "Plus Jakarta Sans";
  src: url("../fonts/PlusJakartaSans-Variable.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Boska";
  src: url("../fonts/boska-300.woff2") format("woff2");
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Boska";
  src: url("../fonts/boska-300i.woff2") format("woff2");
  font-weight: 300;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "Playfair Display";
  src: url("../fonts/playfair.woff2") format("woff2");
  font-weight: 700;
  font-style: italic;
  font-display: swap;
}

:root {
  --bg: #03060f;
  --ink: #04173d;
  --text-primary: #eaf4ff;
  --text-secondary: #a9b8dd;
  --text-tertiary: #6b7aa3;
  --accent: #3fe0f5;
  --border: rgba(234, 244, 255, 0.14);
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
  overflow: hidden;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text-primary);
  font-family: "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  -webkit-font-smoothing: antialiased;
}

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

/* the Figma reference's actual exported "Ellipses" asset (frame 1:3), recolored
   from green/indigo/purple to Hyola cyan/blue — same shapes, blurs and drop
   shadow baked into the SVG, only the fill/gradient stop hex values changed. */
.wave {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: url("../assets/ellipses.svg");
  background-size: cover;
  background-position: 50% 46%;
  background-repeat: no-repeat;
  animation: drift 46s ease-in-out infinite;
}

/* scale stays above 1 at every step so the oversized background always
   covers the fixed viewport-sized box - drifting it without that would
   expose bare background color at the edges as it moves off-center. */
@keyframes drift {
  0% {
    transform: translate(0%, 0%) scale(1.06);
  }
  25% {
    transform: translate(-2.5%, 1.5%) scale(1.09);
  }
  50% {
    transform: translate(1.5%, -2%) scale(1.05);
  }
  75% {
    transform: translate(-1%, 2.5%) scale(1.1);
  }
  100% {
    transform: translate(0%, 0%) scale(1.06);
  }
}

/* a soft diffused line of light running along each of the four edges, brand
   blue/cyan, fading out quickly toward the center rather than blooming from
   the corners. */
.edge-glow {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    linear-gradient(to bottom, rgba(46, 111, 224, 0.03), transparent 5%),
    linear-gradient(to top, rgba(63, 224, 245, 0.025), transparent 5%),
    linear-gradient(to right, rgba(63, 224, 245, 0.02), transparent 5%),
    linear-gradient(to left, rgba(46, 111, 224, 0.025), transparent 5%);
}

/* Procedural grain via an SVG feTurbulence filter, not a sampled bitmap. A
   fixed-resolution PNG/WebP tile only has as many pixels as it was exported
   with — zoom in and the browser just blows those same pixels up into visible
   blocks. feTurbulence regenerates the noise at whatever resolution it's
   actually painted at, so it stays fine grain at any zoom, matching how
   Figma's own noise effect behaves (it's procedural there too, not a raster
   layer — that's why it never degrades when you zoom into it). */
.grain {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.55;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 120px 120px;
  background-repeat: repeat;
}

.screen {
  position: relative;
  z-index: 2;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 6vh 24px;
  gap: clamp(16px, 3vh, 28px);
}

.mark-icon {
  position: fixed;
  z-index: 2;
  left: max(24px, env(safe-area-inset-left));
  top: max(24px, env(safe-area-inset-top));
  display: flex;
}

.mark-icon img {
  display: block;
  border-radius: 8px;
}

.mark {
  position: fixed;
  z-index: 2;
  left: 0;
  right: 0;
  top: max(28px, env(safe-area-inset-top));
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1px;
}

.mark span:first-child {
  font-weight: 700;
  font-size: 1.05rem;
  letter-spacing: -0.01em;
  text-shadow: 0 2px 12px rgba(3, 6, 15, 0.6);
}

.mark-dot {
  font-weight: 700;
  font-size: 1.05rem;
  color: #34d399;
}

h1 {
  margin: 0;
  font-family: "Boska", "Playfair Display", Georgia, serif;
  font-weight: 300;
  font-style: italic;
  letter-spacing: -0.01em;
  line-height: 1.15;
  font-size: clamp(2rem, 1.2rem + 4vw, 3.6rem);
  max-width: 21ch;
  background: linear-gradient(180deg, #ffffff 0%, #ffffff 70%, rgba(234, 244, 255, 0.55) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

/* "call" now reads as plain text on the first line - this box is what's
   left of its old badge, kept empty on the line below intentionally. */
.cycle-word {
  position: relative;
  display: inline-block;
  vertical-align: top;
  width: min(320px, 72vw);
  height: 56px;
}

.cycle-word::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 18px;
  background: linear-gradient(135deg, rgba(63, 224, 245, 0.07), rgba(46, 111, 224, 0.05));
  mix-blend-mode: overlay;
  border: 1px solid rgba(234, 244, 255, 0.16);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.16), 0 8px 24px -10px rgba(63, 224, 245, 0.4);
}

.screen p {
  margin: 0;
  color: var(--text-secondary);
  font-weight: 350;
  font-size: clamp(0.95rem, 0.85rem + 0.5vw, 1.1rem);
  letter-spacing: 0.005em;
  max-width: 40ch;
  line-height: 1.6;
  text-shadow: 0 2px 18px rgba(3, 6, 15, 0.65), 0 1px 4px rgba(3, 6, 15, 0.6);
}

.tag {
  display: inline-flex;
  align-items: center;
}

.tag-label {
  font-family: "Plus Jakarta Sans", sans-serif;
  font-weight: 800;
  font-size: 0.8rem;
  letter-spacing: 0.03em;
  color: var(--text-primary);
  white-space: nowrap;
  text-shadow: 0 2px 14px rgba(3, 6, 15, 0.5);
}

.signature {
  position: fixed;
  z-index: 2;
  left: 0;
  right: 0;
  bottom: max(18px, env(safe-area-inset-bottom));
  margin: 0;
  text-align: center;
  font-size: 0.78rem;
  color: var(--text-primary);
  opacity: 0.75;
  text-shadow: 0 2px 14px rgba(3, 6, 15, 0.7);
}

/* entrance: no scroll to trigger reveal on, so a single fade-in on load */
.mark-icon,
.mark,
h1,
.screen p,
.tag {
  opacity: 0;
  animation: rise 0.8s var(--ease) forwards;
}

.mark-icon,
.mark {
  animation-delay: 0s;
}
h1 {
  animation-delay: 0.08s;
}
.screen p {
  animation-delay: 0.16s;
}
.tag {
  animation-delay: 0.24s;
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .wave {
    animation: none;
  }
  .mark-icon,
  .mark,
  h1,
  .screen p,
  .tag {
    animation: none;
    opacity: 1;
    transform: none;
  }
}

@media (max-height: 480px) {
  .screen {
    gap: 14px;
    padding: 3vh 24px;
  }
  h1 {
    font-size: clamp(1.25rem, 1rem + 2vw, 1.9rem);
  }
}

@media (max-width: 600px) {
  h1 {
    font-size: clamp(1.5rem, 1.15rem + 3.4vw, 2.1rem);
  }
  .cycle-word {
    width: min(180px, 58vw);
    height: 42px;
  }
}
