/* ============================================================
   NxtAtlas — design system
   Modern, calm, premium. Typography follows the logo: geometric
   sans, no serif. Motion is deliberately minimal. No frames,
   no grain, no rotating decoration.
   Every page loads this first, then its own stylesheet.
   ============================================================ */

@import url("https://fonts.googleapis.com/css2?family=Sora:wght@300;400;500;600&family=Manrope:wght@300;400;500;600&display=swap");

:root{
  /* ---- surface ---- */
  --ink:        #0a0b0d;
  --ink-raise:  #0f1114;
  --ink-card:   #12141a;

  /* ---- text ---- */
  --paper:       #ece8e1;
  --paper-soft:  rgba(236,232,225,.68);
  --paper-dim:   rgba(236,232,225,.48);
  --paper-faint: rgba(236,232,225,.16);

  /* ---- brass: the single accent ---- */
  --brass:       #d1a05a;
  --brass-lit:   #e0b473;
  --brass-soft:  rgba(209,160,90,.34);
  --brass-faint: rgba(209,160,90,.12);

  --line:        rgba(236,232,225,.10);
  --line-strong: rgba(236,232,225,.18);

  /* ---- type: geometric display + clean body ---- */
  --display: "Sora", system-ui, sans-serif;
  --body:    "Manrope", system-ui, sans-serif;
  /* compatibility aliases: stylesheets written against the old serif/mono
     pairing now resolve to the current type system instead of browser defaults */
  --serif: "Sora", system-ui, sans-serif;
  --mono:  "Manrope", system-ui, sans-serif;

  /* ---- rhythm ---- */
  --edge:    clamp(18px, 4vw, 48px);
  --max:     1200px;
  --section: clamp(80px, 12vh, 140px);

  --ease: cubic-bezier(.22, 1, .36, 1);
  --fast: .24s;
}

*,*::before,*::after{ box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; scroll-behavior:smooth; }

body{
  margin:0;
  background:var(--ink);
  color:var(--paper);
  font-family:var(--body);
  font-weight:400;
  font-size:16px;
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
  min-height:100svh;
  position:relative;
}

/* ---- atmosphere: one soft warm halo. no grain, no noise ---- */
body::before{
  content:""; position:fixed; inset:0; z-index:0; pointer-events:none;
  background:
    radial-gradient(85% 65% at 70% 0%, rgba(209,160,90,.085), transparent 62%),
    linear-gradient(180deg, var(--ink-raise), var(--ink) 45%);
}
/* ---- and one warm light that never quite settles ----
   The apps carry an ambient brass glow that drifts behind everything; this is
   the same idea on the web, and it is the same colour, so the two feel like one
   product. Transform and opacity only — a moving blur or a shifting gradient
   stop would repaint the whole viewport every frame, which is exactly what the
   hero bloom was rewritten to stop doing.

   Fixed, so it drifts under the page rather than with it, and behind the content
   layer below. */
body::after{
  content:""; position:fixed; z-index:0; pointer-events:none;
  top:-30vh; left:-25vw; width:80vw; height:80vw; max-width:1100px; max-height:1100px;
  background:radial-gradient(circle,
    rgba(209,160,90,.13) 0%, rgba(209,160,90,.06) 38%, transparent 68%);
  will-change:transform, opacity;
  animation:atlas-drift 34s ease-in-out infinite alternate;
}
@keyframes atlas-drift{
  from{ transform:translate3d(0, 0, 0) scale(1); opacity:.75; }
  to  { transform:translate3d(46vw, 34vh, 0) scale(1.22); opacity:1; }
}
@media (prefers-reduced-motion: reduce){
  body::after{ animation:none; opacity:.6; }
}

main,header,footer,nav{ position:relative; z-index:2; }

/* the decorative plate frame is retired — hide it wherever it still exists */
.plate{ display:none !important; }

/* ---- layout ---- */
.shell{ width:100%; max-width:var(--max); margin-inline:auto;
        padding-inline:clamp(20px, 5vw, 40px); }
section{ padding-block:var(--section); }

/* ---- type scale ---- */
h1,h2,h3{ font-family:var(--display); font-weight:500; margin:0;
          letter-spacing:-.03em; line-height:1.08; }
h1{ font-size:clamp(2.4rem, 6vw, 4.4rem); letter-spacing:-.04em; }
h2{ font-size:clamp(1.8rem, 4vw, 2.9rem); }
h3{ font-size:clamp(1.15rem, 2.2vw, 1.4rem); letter-spacing:-.02em; }
p{ margin:0; }
a{ color:inherit; }

/* small caps label */
.lbl{ font-family:var(--body); font-size:11px; font-weight:500; letter-spacing:.16em;
      text-transform:uppercase; color:var(--paper-dim); }
.lbl-brass{ color:var(--brass); }

.eyebrow{ display:flex; align-items:center; gap:12px; }
/* width lives in a custom property so GSAP can draw the line in */
.eyebrow::before{ content:""; height:1px; width:var(--ew, 24px); background:var(--brass-soft); flex:none; }

.lede{ color:var(--paper-soft); font-size:clamp(15px,1.3vw,17px);
       line-height:1.7; max-width:58ch; }

/* ============================================================
   THE WORDMARK — NXTΛTLAS
   First A is the crossbar-less Λ, exactly as in the logo; the
   second A stays a normal A. Always ship the aria-label.
   Markup:  <span class="wm" aria-label="NxtAtlas">NXT<i>Λ</i>TLAS</span>
   ============================================================ */
.wm{ font-family:var(--display); font-weight:600; letter-spacing:.14em; }
.wm i{ font-style:normal; }
.wm-mono{ letter-spacing:.2em; text-transform:uppercase; }
.wm-brass i{ color:var(--brass); }

/* ---- buttons ---- */
.btn{ display:inline-flex; align-items:center; justify-content:center; gap:9px;
      font-family:var(--body); font-size:14.5px; font-weight:500;
      text-decoration:none; cursor:pointer; white-space:nowrap;
      padding:13px 24px; border-radius:10px;
      border:1px solid var(--line-strong); background:transparent; color:var(--paper);
      transition:background var(--fast) ease, border-color var(--fast) ease, color var(--fast) ease; }
.btn:hover{ background:rgba(236,232,225,.06); border-color:var(--paper-faint); }
.btn::after{ content:none !important; }          /* retire the old sweep effect */
.btn-brass{ background:var(--brass); border-color:var(--brass); color:#14100a; font-weight:600; }
.btn-brass:hover{ background:var(--brass-lit); border-color:var(--brass-lit); color:#14100a; }
.btn-ghost{ border-color:transparent; padding-inline:4px; color:var(--paper-soft); }
.btn-ghost:hover{ background:transparent; color:var(--brass); border-color:transparent; }

/* ---- text link ---- */
.ul{ text-decoration:none; color:inherit; transition:color var(--fast) ease; }
.ul::after{ content:none !important; }            /* retire the sweeping underline */
.ul:hover{ color:var(--brass); }

/* ---- status chip: static, no pulsing ---- */
.chip{ display:inline-flex; align-items:center; gap:7px; font-family:var(--body);
       font-size:11.5px; font-weight:500; letter-spacing:.1em; text-transform:uppercase;
       color:var(--paper-dim); white-space:nowrap; }
.chip::before{ content:""; width:6px; height:6px; border-radius:50%;
               background:var(--paper-faint); box-shadow:none !important; animation:none !important; }
.chip-live{ color:var(--brass); }
.chip-live::before{ background:var(--brass); }

/* present to screen readers, absent to the eye */
.sr-only{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0;
}

.rule{ display:flex; align-items:center; gap:14px; }
.rule span{ flex:1; height:1px; background:var(--line); transform-origin:0 50%; }

/* ============================================================
   MOTION
   GSAP + ScrollTrigger drive everything; Lenis drives the scroll.
   CSS's only job here is the pre-animation state (so nothing
   flashes before JS runs) and the machinery GSAP animates into.

   Content is visible by default. It is hidden ONLY once JS has
   confirmed it can animate — html.js without .no-motion — so a
   failed script or reduced-motion never leaves a blank page.
   ============================================================ */
html.js:not(.no-motion) .reveal,
html.js:not(.no-motion) .card{ opacity:0; }

/* The home page opens with the avatar alone: until it has landed there is
   no header, no copy, no buttons on screen. Scoped to .home so the product
   and auth pages — which reuse some of these class names — are unaffected. */
html.js:not(.no-motion) .home .hero-logo,
html.js:not(.no-motion) .home .hero-bloom,
html.js:not(.no-motion) .home .site-head,
html.js:not(.no-motion) .home .hero-tagline,
html.js:not(.no-motion) .home .hero-cta > *,
html.js:not(.no-motion) .home .hero-stats,
html.js:not(.no-motion) .home .hero-chips > *,
html.js:not(.no-motion) .home .marquee{ opacity:0; }

/* legacy stagger classes are no-ops now — GSAP staggers by group */
.r-1,.r-2,.r-3,.r-4,.r-5,.r-6,.r-7,.r-8{ transition-delay:0s; }
.rise{ opacity:1; }
.d-1,.d-2,.d-3,.d-4,.d-5,.d-6{ animation-delay:0s; }

/* words ride up out of their own line */
.w-outer{ display:inline-block; overflow:hidden; vertical-align:top; padding-bottom:.06em; }
.w-inner{ display:inline-block; will-change:transform; }

/* smooth scroll: Lenis owns the scroll position, so the native
   smooth behaviour must stand down or the two fight each other */
html.lenis, html.lenis body{ height:auto; }
html.js{ scroll-behavior:auto; }
.lenis.lenis-smooth{ scroll-behavior:auto !important; }
.lenis.lenis-stopped{ overflow:hidden; }

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{ animation:none !important; transition:none !important; }
  html{ scroll-behavior:auto; }
  .reveal,.rise,.card,.hero-logo,.hero-bloom,.site-head,.hero-tagline,
  .hero-cta > *,.hero-stats,.hero-chips > *,.marquee{ opacity:1 !important; transform:none !important; }
}

:focus-visible{ outline:2px solid var(--brass); outline-offset:2px; }
::selection{ background:var(--brass); color:#14100a; }

/* ============================================================
   MOTION FURNITURE — elements the motion system creates or uses
   ============================================================ */

/* page-load curtain: an ink panel that lifts to reveal the page */
.curtain{
  position:fixed; inset:0; z-index:100; background:var(--ink);
  display:flex; align-items:center; justify-content:center; pointer-events:none;
}
.curtain-mark{ width:64px; height:64px; opacity:.9; }

/* soft warm light trailing the pointer */
.cursor-glow{
  position:fixed; top:0; left:0; width:460px; height:460px; z-index:1; pointer-events:none;
  background:radial-gradient(circle, rgba(209,160,90,.10), transparent 62%);
  will-change:transform; opacity:0;
}

/* .rise is the entrance hook on the auth and product pages. It is declared
   here — after the legacy `.rise{opacity:1}` compatibility rule — so the
   pre-animation hidden state actually wins. */
html.js:not(.no-motion) .rise{ opacity:0; }
@media (prefers-reduced-motion: reduce){ .rise{ opacity:1 !important; } }

/* back to top */
.to-top{
  pointer-events:none;
  position:fixed; right:clamp(16px,3vw,28px); bottom:clamp(16px,3vw,28px); z-index:40;
  width:44px; height:44px; border-radius:50%; cursor:pointer;
  display:grid; place-items:center;
  background:rgba(10,11,13,.72); color:var(--paper);
  border:1px solid var(--line-strong);
  backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
  opacity:0; transform:translateY(12px) scale(.9);
  transition:background var(--fast) ease, border-color var(--fast) ease, color var(--fast) ease;
}
.to-top:hover{ background:var(--brass); border-color:var(--brass); color:#14100a; }

@media (prefers-reduced-motion: reduce){
  .curtain{ display:none; }
  .cursor-glow{ display:none; }
  .to-top{ opacity:1; transform:none; }
}

/* the scroll-progress hairline is retired */
.scroll-progress{ display:none !important; }

/* ============================================================
   HEADER ACCOUNT CHIP
   Replaces the "Sign in" button once you are signed in. Built by
   auth.js, which also swaps the .btn classes off the element.
   ============================================================ */
.head-account{
  display:inline-flex; align-items:center; gap:10px;
  padding:6px 14px 6px 6px; border-radius:999px;
  border:1px solid var(--line-strong); background:rgba(236,232,225,.03);
  text-decoration:none; color:var(--paper); max-width:230px;
  transition:border-color var(--fast) ease, background var(--fast) ease;
}
.head-account:hover{ border-color:var(--brass-soft); background:var(--brass-faint); }

.ha-avatar{
  flex:none; width:28px; height:28px; border-radius:50%; overflow:hidden;
  display:grid; place-items:center;
  background:var(--brass); color:#14100a;
  font-family:var(--display); font-weight:600; font-size:13px; line-height:1;
}
.ha-avatar img{ width:100%; height:100%; object-fit:cover; display:block; }

/* the two lines sit tight so the chip stays header-height */
.ha-text{ display:flex; flex-direction:column; min-width:0; line-height:1.15; }
.ha-name{
  font-size:13px; font-weight:500; letter-spacing:-.01em;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.ha-email{
  font-size:10.5px; letter-spacing:.02em; color:var(--paper-dim);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}

@media (max-width:560px){
  .head-account{ padding:5px; max-width:none; }
  .ha-text{ display:none; }   /* on a phone the avatar alone is the account */
}

/* ------------------------------------------------------------------
   The language switch.

   It sits in whatever row a page already has — inside the nav where
   there is one, beside the meta label where there is not — so spacing
   and alignment come from that row rather than from here. What it adds
   is only what a bare <a> never gets: the size and tracking of a label
   rather than a link, and a colour that stays quiet until pointed at.

   Where it lands inside a nav it also carries that nav's own link
   class, and those rules win. This is the floor, not the design.
   ------------------------------------------------------------------ */
.lang-switch{
  font-size: .72rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  opacity: .58;
  transition: opacity .18s ease, color .18s ease;
}
.lang-switch:hover,
.lang-switch:focus-visible{ opacity: 1; }

