/* ==========================================================================
   The redesign layer

   Loaded last, so it leans on the tokens the rest of the stylesheets already
   define rather than replacing them. The identity stays: the warm terracotta,
   Inter, the rounded cards. What changes is depth -- a backdrop with something
   behind it, surfaces that catch a little light, and one accent gradient used
   consistently instead of a flat fill.

   The backdrop is a Haikei-style layered mesh, written as radial gradients
   rather than exported as an SVG. Same look, and better here: no file to
   fetch, it re-reads the theme tokens so it follows light and dark on its own,
   and it costs nothing at runtime because a gradient is painted once. That
   last part is deliberate. A full-bleed blurred element animating behind every
   page is exactly the kind of thing that made this app crawl on desktop
   before, so the background does not move and does not use filter: blur().
   ========================================================================== */

:root {
  /* One accent gradient, used everywhere something is the primary action. */
  --accent-a: #e0785d;
  --accent-b: #eb9375;
  --accent-grad: linear-gradient(135deg, var(--accent-a) 0%, var(--accent-b) 100%);

  /* The mesh pools. Warm, low opacity, and far apart so they read as light
     rather than as three coloured circles. */
  --mesh-1: rgba(224, 120, 93, 0.16);
  --mesh-2: rgba(235, 147, 117, 0.12);
  --mesh-3: rgba(120, 107, 98, 0.10);

  --ring: rgba(224, 120, 93, 0.35);
  --hairline: rgba(255, 255, 255, 0.55);
  --elev: 0 1px 2px rgba(76, 52, 42, 0.04), 0 8px 24px rgba(76, 52, 42, 0.07);
  --elev-lift: 0 2px 6px rgba(76, 52, 42, 0.06), 0 18px 44px rgba(76, 52, 42, 0.12);
}

:root[data-theme="dark"],
:root:not([data-theme="light"]) {
  --accent-a: #ef8a6b;
  --accent-b: #f0a184;
  --mesh-1: rgba(239, 138, 107, 0.16);
  --mesh-2: rgba(240, 161, 132, 0.10);
  --mesh-3: rgba(90, 120, 140, 0.10);
  --ring: rgba(239, 138, 107, 0.38);
  --hairline: rgba(255, 255, 255, 0.07);
  --elev: 0 1px 2px rgba(0, 0, 0, 0.4), 0 10px 30px rgba(0, 0, 0, 0.45);
  --elev-lift: 0 2px 8px rgba(0, 0, 0, 0.45), 0 22px 60px rgba(0, 0, 0, 0.55);
}

/* --- the backdrop ------------------------------------------------------ */

body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background:
    radial-gradient(58% 44% at 12% 6%, var(--mesh-1) 0%, transparent 68%),
    radial-gradient(50% 40% at 88% 14%, var(--mesh-2) 0%, transparent 66%),
    radial-gradient(64% 50% at 72% 92%, var(--mesh-3) 0%, transparent 70%),
    var(--bg);
}

/* Grain. A 120-byte SVG, tiled -- it takes the flatness off the gradients
   without a texture file or a blur filter. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.5;
  mix-blend-mode: soft-light;
  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='3'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='0.35'/%3E%3C/svg%3E");
}

/* --- surfaces ---------------------------------------------------------- */

.card,
.auth-card,
.stat-card,
.qa-card,
.lp-feature {
  border-radius: var(--radius-lg);
  box-shadow: var(--elev);
  /* A single hairline along the top edge, the way light actually falls on a
     raised surface. Cheaper and quieter than a full border gradient. */
  background-image: linear-gradient(var(--hairline), transparent 1px);
  background-repeat: no-repeat;
  background-size: 100% 1px;
  transition: box-shadow .28s var(--ease-out), translate .28s var(--ease-out);
}

.card-hover:hover,
.qa-card:hover,
.lp-feature:hover {
  box-shadow: var(--elev-lift);
  /* translate, not transform: the tilt below writes transform, and a hover
     rule that overwrote it would cancel the tilt mid-gesture. */
  translate: 0 -3px;
}

/* --- the one accent ---------------------------------------------------- */

.btn-primary,
.lp-btn-primary {
  background: var(--accent-grad);
  border: 0;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .12), 0 8px 22px var(--ring);
}

/* The sheen is motion-primitives' border-trail idea, reduced to one element:
   a highlight that crosses the button once on hover instead of a light
   orbiting it forever. Transform-only, and it never runs at rest. */
.btn-primary::after,
.lp-btn-primary::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(100deg, transparent 35%,
    rgba(255, 255, 255, .38) 50%, transparent 65%);
  translate: -120% 0;
  opacity: 0;
}

.btn-primary,
.lp-btn-primary { position: relative; overflow: hidden; }

.btn-primary:hover::after,
.lp-btn-primary:hover::after {
  opacity: 1;
  translate: 120% 0;
  transition: translate .7s var(--ease-out), opacity .2s linear;
}

/* --- the AI prompt, which is the product ------------------------------- */

.ai-input-row {
  position: relative;
  border-radius: var(--radius-pill);
}

/* border-trail, ported: a conic highlight rotating just inside the border.
   Runs only while the box has focus, so nothing animates on an idle page. */
.ai-input-row::before {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 1px;
  background: conic-gradient(from var(--trail-angle, 0deg),
    transparent 0turn, var(--accent-a) .12turn, transparent .28turn, transparent 1turn);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask-composite: exclude;
  opacity: 0;
  transition: opacity .3s ease;
}

.ai-input-row:focus-within::before { opacity: 1; }

@property --trail-angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

@keyframes trailSpin { to { --trail-angle: 1turn; } }

.ai-input-row:focus-within::before {
  animation: trailSpin 4s linear infinite;
}

/* --- chips and pills --------------------------------------------------- */

.ai-example-chip,
.lp-eyebrow,
.lp-trust {
  border-radius: var(--radius-pill);
  transition: translate .2s var(--ease-out), border-color .2s ease;
}

.ai-example-chip:hover { translate: 0 -2px; border-color: var(--accent-a); }

/* --- landing rhythm ---------------------------------------------------- */

.lp-title {
  letter-spacing: -0.035em;
  line-height: 1.04;
}

/* The accent half of the headline gets the gradient rather than a flat
   colour, so the hero and the primary button are visibly the same family. */
.lp-title span {
  background: var(--accent-grad);
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* A Haikei stacked-wave divider, drawn as a mask on the section edge instead
   of an exported SVG so it follows the background token. */
.lp-section + .lp-section { position: relative; }
.lp-section + .lp-section::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: -1px;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--border-strong), transparent);
}

/* --- motion base states ------------------------------------------------
   The script sets .is-in when an element has been seen once. Everything here
   is transform and opacity only, and the transition is removed afterwards so
   a settled page has no pending animation state on it. */

[data-reveal] {
  opacity: 0;
  translate: 0 14px;
}

[data-reveal].is-in {
  opacity: 1;
  translate: none;
  transition: opacity .5s var(--ease-out), translate .5s var(--ease-out);
}

/* Words of the hero headline, split by the script. */
.word {
  display: inline-block;
  opacity: 0;
  translate: 0 0.35em;
}

/* --- spotlight: motion-primitives' cursor-follow highlight -------------- */

.spot { position: relative; }
.spot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  transition: opacity .25s ease;
  background: radial-gradient(220px circle at var(--mx, 50%) var(--my, 50%),
    rgba(255, 255, 255, .10), transparent 60%);
}
.spot:hover::after { opacity: 1; }

/* --- reduced motion ---------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  [data-reveal],
  [data-reveal].is-in,
  .word { opacity: 1; translate: none; transition: none; }
  .ai-input-row:focus-within::before { animation: none; }
  .btn-primary:hover::after,
  .lp-btn-primary:hover::after { transition: none; opacity: 0; }
  body::after { display: none; }
}

/* Touch devices get none of the pointer effects -- there is no cursor to
   follow, and a :hover that sticks after a tap is worse than no effect. */
@media (pointer: coarse) {
  .spot::after { display: none; }
}

/* ==========================================================================
   The chrome: sidebar and top bar

   These were left alone in the first pass, which showed -- the page behind
   them had depth and they still read as two flat panels bolted to the edges.

   What is deliberately NOT changed is the top bar's opacity. glass.css argues
   the case already and it is right: the page scrolls underneath that strip,
   and at a faint alpha a heading passing beneath stays legible through it, so
   two lines of text end up occupying the same band of screen. Blur does not
   fix that, it smears it. So the bar keeps its solid backing and what changes
   is how it is framed.
   ========================================================================== */

/* --- sidebar ----------------------------------------------------------- */

.sidebar {
  /* A hairline that fades out as it descends rather than a full-height rule.
     The border was the only thing separating the rail from the page, and a
     hard line the height of the window is the heaviest possible way to say
     something so quiet. */
  border-right: 0;
  background-image:
    linear-gradient(var(--hairline), transparent 1px),
    linear-gradient(to bottom, var(--border-strong) 0%, transparent 85%);
  background-repeat: no-repeat, no-repeat;
  background-size: 100% 1px, 1px 100%;
  background-position: 0 0, 100% 0;
}

.brand-block {
  padding-bottom: 26px;
}

/* The wordmark picks up the same gradient as the hero and the primary
   button, so the three places the brand appears agree with each other. */
.brand-name span {
  background: var(--accent-grad);
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

.nav-link {
  border-radius: 12px;
  transition: background .2s var(--ease-out), color .2s var(--ease-out),
              translate .2s var(--ease-out);
}

/* Nudged rather than filled on hover: the active item is the one wearing the
   gradient, and a hover that also fills competes with it. */
.nav-link:hover { translate: 2px 0; }

.nav-link.active {
  background: var(--accent-grad);
  box-shadow: 0 6px 18px var(--ring);
}

/* The sliding indicator -- motion-primitives calls this animated-background --
   already exists here. It only needed to agree with the new radius. */
.sidebar .nav-pill {
  border-radius: 12px;
}

.sidebar-quote {
  border-top: 1px solid var(--border);
  padding-top: 14px;
}

/* --- top bar ----------------------------------------------------------- */

.topbar {
  /* Same hairline along the top edge as every raised surface in the app, and
     a bottom edge that fades at both ends instead of stopping dead. */
  border-bottom: 0;
  background-image:
    linear-gradient(var(--hairline), transparent 1px),
    linear-gradient(90deg, transparent, var(--border-strong) 18%,
                    var(--border-strong) 82%, transparent);
  background-repeat: no-repeat, no-repeat;
  background-size: 100% 1px, 100% 1px;
  background-position: 0 0, 0 100%;
}

/* --- the controls in it ------------------------------------------------- */

.icon-btn,
.user-chip {
  border-radius: var(--radius-pill);
  transition: translate .2s var(--ease-out), box-shadow .2s var(--ease-out),
              border-color .2s var(--ease-out);
}

.icon-btn:hover,
.user-chip:hover {
  translate: 0 -1px;
  border-color: var(--accent-a);
  box-shadow: 0 4px 14px var(--ring);
}

.user-avatar {
  background: var(--accent-grad);
  color: #fff;
}

/* The personal / work switch reads as one control with a selected half,
   rather than two buttons that happen to sit together. */
.mode-switch {
  border-radius: var(--radius-pill);
  padding: 3px;
  background: var(--bg-tint);
  border: 1px solid var(--border);
}

.mode-opt {
  border-radius: var(--radius-pill);
  transition: background .2s var(--ease-out), color .2s var(--ease-out);
}

.mode-opt.is-on {
  background: var(--accent-grad);
  color: #fff;
  box-shadow: 0 2px 10px var(--ring);
}

/* On a phone the rail slides in over the page, so it needs a real edge --
   the fading hairline above has nothing to sit against once it is floating. */
@media (max-width: 768px) {
  .sidebar {
    background-image: linear-gradient(var(--hairline), transparent 1px);
    background-size: 100% 1px;
    box-shadow: 0 18px 50px rgba(0, 0, 0, .28);
  }
}

/* ==========================================================================
   The flow field

   The reference design's ground: copper filaments moving through near-black.
   The mesh gradient above stays as the base colour; this layers light over it.

   The rules are the same ones the rest of this file lives by, and here they
   matter most, because unlike a hover effect this runs on every page for as
   long as the page is open:

     - transform only. No blur filter, no animated opacity, no moving
       gradients. Three groups drift; the compositor handles all three and the
       main thread does nothing per frame.
     - slow. Ninety seconds a loop. Slow motion at low contrast reads as
       depth; fast motion at low contrast reads as a rendering fault.
     - it stops when nobody is looking. A hidden tab pauses it, so a
       background tab is not spending a phone's battery on scenery.
     - reduced motion gets the filaments, still. They are part of the design,
       not an effect on top of it -- what goes is the movement.
   ========================================================================== */

:root {
  --ff-warm: #e0785d;
  --ff-hot: #f6b79a;
  --ff-cool: #7c8fa8;
  --ff-opacity: .30;
}

:root[data-theme="dark"],
:root:not([data-theme="light"]) {
  --ff-warm: #ef8a6b;
  --ff-hot: #ffd2bd;
  --ff-cool: #6f86a4;
  --ff-opacity: .55;
}

.flowfield {
  position: fixed;
  inset: -10%;                 /* overscan, so a drifting edge never enters */
  z-index: -1;
  pointer-events: none;
  opacity: var(--ff-opacity);
  /* Its own compositing island: nothing inside can trigger layout or paint
     anywhere else on the page, whatever it does. */
  contain: layout paint;
}

.flowfield svg {
  width: 100%;
  height: 100%;
  display: block;
}

.flowfield path {
  fill: none;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

.ff-drift {
  will-change: transform;      /* three layers, held on purpose */
  transform-box: fill-box;
  transform-origin: center;
}

/* Three different paths through the same small box. Nothing travels far --
   the movement should be noticed only if you look for it. */
@keyframes ffDriftA {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  50%  { transform: translate3d(-2.2%, 1.4%, 0) scale(1.035); }
  100% { transform: translate3d(0, 0, 0) scale(1); }
}
@keyframes ffDriftB {
  0%   { transform: translate3d(0, 0, 0) scale(1.02); }
  50%  { transform: translate3d(2.6%, -1.1%, 0) scale(1); }
  100% { transform: translate3d(0, 0, 0) scale(1.02); }
}
@keyframes ffDriftC {
  0%   { transform: translate3d(0, 0, 0); }
  50%  { transform: translate3d(1.4%, 2%, 0); }
  100% { transform: translate3d(0, 0, 0); }
}

.ff-1 { animation: ffDriftA 90s ease-in-out infinite; }
.ff-2 { animation: ffDriftB 112s ease-in-out infinite; }
.ff-3 { animation: ffDriftC 74s  ease-in-out infinite; }

/* Where the ground is painted.

   style.css puts the page colour on <body>, and that is the reason the
   backdrop and the flow field were both invisible. A background on <body>
   is painted in the block-background step, which the spec runs *after*
   every negative z-index child of the stacking context -- so an opaque
   body background sits on top of anything placed behind the content, no
   matter how negative its z-index is. Moving the colour to the root gives
   the scenery somewhere to live: the canvas underneath, then the mesh at
   -2, then the filaments at -1, then the page. */
html { background: var(--bg); }
body { background: transparent; }

/* Clearing a path down to it.

   A negative z-index puts an element behind the page content, but "behind
   the content" still means in front of nothing at all if an ordinary block
   in the flow paints an opaque background over the whole viewport -- block
   backgrounds are painted after negative z-index children, so .landing at
   2891px tall and solid --bg was burying the whole backdrop. These are the
   full-bleed wrappers, and each of them is handing its colour back to the
   root so there is something to see through them. Nothing here changes what
   the page looks like on its own; it changes what is underneath it. */
.landing,
.content,
.app-shell .content {
  background: transparent;
}

/* The alternating band stays a band -- it is just mixed into what is behind
   it now instead of replacing it. The values land within a shade of the
   --bg-tint they replace in both themes. */
:root { --band: rgba(0, 0, 0, 0.045); }
:root[data-theme="dark"],
:root:not([data-theme="light"]) { --band: rgba(255, 255, 255, 0.035); }
.lp-section-alt { background: var(--band); }

/* The sign-in glow keeps its two blooms and drops the flat colour beneath
   them, so the filaments run under the auth card as well. */
.auth-wrap,
:root[data-theme="dark"] .auth-wrap,
:root:not([data-theme="light"]) .auth-wrap {
  background-color: transparent;
}

/* The grain sits above the filaments now, so the light picks it up. */
body::after { z-index: 0; }
.flowfield  { z-index: -1; }
body::before { z-index: -2; }

/* --- display type ------------------------------------------------------- */

/* The reference leads with a serif, and that is most of what makes it read as
   considered rather than as another SaaS page. Applied to display headings
   only: body copy and the interface stay on Inter, where a serif at 14px
   would cost legibility for nothing. */
.lp-title,
.lp-h2,
.auth-panel h1,
.section-title h2 {
  font-family: "Instrument Serif", "Iowan Old Style", Georgia, serif;
  font-weight: 400;
  letter-spacing: -0.015em;
}

.lp-title { line-height: 1.06; }

/* --- section flow ------------------------------------------------------- */

/* Native smooth scrolling, not a hijacked wheel.

   The reference reads as smooth because its sections are tall and its
   transitions are unhurried, not because it intercepts scrolling. Taking the
   wheel away costs a frame of latency on every gesture, breaks the scrollbar
   drag and the keyboard, and is the exact shape of the thing that made this
   application crawl on a wide screen. This gets the feel and leaves the
   scroll alone. */
html { scroll-behavior: smooth; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .ff-drift { animation: none; }
}

/* Paused rather than left running behind a tab nobody is looking at. */
.is-away .ff-drift { animation-play-state: paused; }
