/* NavOverlay site styles
   Motion curve, reveal choreography, island nav, tagline reveal.
   Everything that Tailwind utilities cannot express lives here. */

:root {
  --fluid: cubic-bezier(0.32, 0.72, 0, 1);
  --ink: #0b1130;
  --muted: #59627d;
  --brand: #7d37e8;
  --brand-dark: #6a22d6;
  --brand-line: #e9e3f5;
}

html {
  scroll-behavior: smooth;
  scroll-padding-top: 96px;
}

body {
  text-wrap: pretty;
}

/* The hidden attribute must beat responsive display utilities. */
[hidden] {
  display: none !important;
}

h1, h2, h3 {
  text-wrap: balance;
}

/* ---------------------------------------------------------------- focus */

:focus-visible {
  outline: 3px solid var(--brand);
  outline-offset: 3px;
  border-radius: 2px;
}

.skip-link {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 90;
  transform: translateY(-200%);
  transition: transform 400ms var(--fluid);
}

.skip-link:focus-visible {
  transform: translateY(0);
}

/* ------------------------------------------------------------- ambience
   Section backdrops: a lavender wash falling from behind the nav, glows
   pooled behind focal elements, and contour arcs sweeping the lower
   half. Pure decoration, so none of it may catch the pointer. */

.ambient {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.ambient__wash {
  position: absolute;
  inset: 0 0 auto 0;
  height: 60%;
  background: linear-gradient(180deg, #f7f4fe 0%, rgba(247, 244, 254, 0) 100%);
}

.ambient__arc {
  position: absolute;
  bottom: -32px;
  left: 50%;
  width: 160%;
  min-width: 1600px;
  transform: translateX(-50%);
  color: #e9e3f5;
}

.ambient__glow {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 70%;
  min-width: 480px;
  aspect-ratio: 2 / 1;
  transform: translate(-50%, -50%);
  border-radius: 9999px;
  background: radial-gradient(closest-side, rgba(125, 55, 232, 0.08), transparent);
}

/* On the lavender band the lavender arcs vanish; white reads instead. */
.ambient--cta .ambient__arc {
  color: #ffffff;
}

/* Invisible buttons laid over the pill painted into the hero render.
   They light up faintly on hover and focus so the live areas read as
   pressable, and shrink slightly on press like the app's buttons. */
.phone-hotspot {
  position: absolute;
  width: 10%;
  aspect-ratio: 1 / 1;
  border-radius: 25%;
  transform: translate(-50%, -50%) rotate(-12deg);
  pointer-events: auto;
  transition:
    background-color 300ms var(--fluid),
    box-shadow 300ms var(--fluid);
}

.phone-hotspot:hover,
.phone-hotspot:focus-visible {
  background-color: rgba(125, 55, 232, 0.12);
  box-shadow: 0 0 0 2px rgba(125, 55, 232, 0.35);
}

.phone-hotspot:active {
  transform: translate(-50%, -50%) rotate(-12deg) scale(0.94);
}

.phone-glow {
  background: radial-gradient(
    circle closest-side at 50% 45%,
    rgba(125, 55, 232, 0.14) 0%,
    rgba(242, 233, 254, 0.7) 55%,
    rgba(242, 233, 254, 0) 100%
  );
}

/* ------------------------------------------------------------ hero type */

.hero-gradient {
  background-image: linear-gradient(90deg, #000000 0%, #666666 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* --------------------------------------------------------- scroll reveal
   Elements start low, blurred and transparent, then settle. Only applied
   once JS has confirmed it is running, so a failed script never hides
   content. */

.js .reveal {
  opacity: 0;
  transform: translateY(64px);
  filter: blur(12px);
  transition:
    opacity 900ms var(--fluid),
    transform 900ms var(--fluid),
    filter 900ms var(--fluid);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: transform, opacity;
}

.js .reveal.is-in {
  opacity: 1;
  transform: translateY(0);
  filter: blur(0);
}

/* -------------------------------------------------------- tagline reveal
   Each word crosses a trigger band on its own and lifts from muted to
   full ink in reading order. */

.tagline-word {
  color: rgba(11, 17, 48, 0.3);
  transition: color 700ms var(--fluid);
  transition-delay: var(--word-delay, 0ms);
}

.tagline-word.is-lit {
  color: var(--ink);
}

/* ------------------------------------------------------------ island nav */

.island {
  transition:
    box-shadow 700ms var(--fluid),
    background-color 700ms var(--fluid),
    border-color 700ms var(--fluid);
}

.burger-line {
  position: absolute;
  left: 50%;
  width: 16px;
  height: 2px;
  margin-left: -8px;
  border-radius: 2px;
  background: var(--ink);
  transition: transform 700ms var(--fluid);
}

.burger-line--top { transform: translateY(-4px); }
.burger-line--bottom { transform: translateY(4px); }

[aria-expanded="true"] .burger-line--top { transform: translateY(0) rotate(45deg); }
[aria-expanded="true"] .burger-line--bottom { transform: translateY(0) rotate(-45deg); }

.menu-sheet {
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 700ms var(--fluid),
    visibility 0s linear 700ms;
}

.menu-sheet.is-open {
  opacity: 1;
  visibility: visible;
  transition:
    opacity 700ms var(--fluid),
    visibility 0s;
}

.menu-item {
  opacity: 0;
  transform: translateY(48px);
  transition:
    opacity 700ms var(--fluid),
    transform 700ms var(--fluid);
}

.menu-sheet.is-open .menu-item {
  opacity: 1;
  transform: translateY(0);
}

/* ----------------------------------------------------------------- grain
   A fixed noise wash over every surface, faint enough to read as paper
   rather than pattern. Sits above everything, so it must never catch
   the pointer. */

body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 100;
  pointer-events: none;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* -------------------------------------------------------- overlay demo
   The live pill sits above the page the way the app sits above other
   apps. It rests at reduced opacity, exactly like the 50% default in the
   Android build, and comes to full strength on hover or focus. */

.demo-pill {
  opacity: 0.55;
  transition:
    opacity 700ms var(--fluid),
    transform 700ms var(--fluid);
}

.demo-pill:hover,
.demo-pill:focus-within {
  opacity: 1;
}

.demo-dock {
  transition:
    opacity 700ms var(--fluid),
    transform 700ms var(--fluid),
    visibility 0s;
}

/* Hidden means gone: opacity alone would leave the five buttons in the
   tab order, so a keyboard user would land on controls nobody can see. */
.demo-dock[data-hidden="true"] {
  opacity: 0;
  transform: translateY(48px);
  pointer-events: none;
  visibility: hidden;
  transition:
    opacity 700ms var(--fluid),
    transform 700ms var(--fluid),
    visibility 0s linear 700ms;
}

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

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  .js .reveal {
    opacity: 1;
    transform: none;
    filter: none;
    transition: none;
  }

  .tagline-word {
    color: var(--ink);
    transition: none;
  }

  .menu-item { opacity: 1; transform: none; }

  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
