/**
 * Landing hero — the one-screen prompt box.
 *
 * Loaded AFTER landing.css so these overrides win on specificity ties without
 * !important. landing.css stays the single source of design tokens and is still
 * what /pricing, /why-tyga and /compare render from; nothing in here is needed
 * by those pages.
 *
 * The move this file implements: the template screenshots stop being the hero's
 * right-hand column and become its wallpaper. Dimmed, blurred and slow, they
 * say "this is what comes out" without asking to be read, which leaves the
 * prompt box as the only thing on the screen with anything to do.
 */

/* ---------------------------------------------------------------------------
   One screen
   --------------------------------------------------------------------------- */

/* .hero in landing.css is a two-column flex row at 85vh. Here it is a single
   centred stack that owns the viewport, with the backdrop positioned against
   it. 100svh, not 100vh: on mobile Safari 100vh is the *largest* viewport, so
   the URL bar would push the chips under the fold on the one screen that is
   supposed to fit. */
.hero-single {
  position: relative;
  /* Undoes `display: flex` from landing.css's .hero. It has to go: on a phone
     the legal line drops out of absolute positioning and back into flow, and
     as a flex item it became a second column of one-word lines beside the
     stage instead of a row under it. */
  display: block;
  min-height: 100svh;
  overflow: hidden;
  padding-top: calc(var(--nav-height) + 40px);
  padding-bottom: 48px;
  text-align: center;
}

.hero-stage {
  position: relative;
  z-index: 1;
  max-width: 760px;
  /* With .hero no longer centring its children, the stage centres itself
     against the viewport the section claims. */
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: calc(100svh - var(--nav-height) - 88px);
}

.hero-single h1 {
  font-size: clamp(2.25rem, 5.5vw, 3.75rem);
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1.05;
  margin: 0 0 1.75rem;
}

/* ---------------------------------------------------------------------------
   Backdrop: the reel, demoted
   --------------------------------------------------------------------------- */

.hero-backdrop {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  /* The viewing frustum for the tilted grid below. On the parent, not on the
     grid itself: `perspective` on the transformed element would make every
     column share one vanishing point at its own centre, which reads as a fisheye
     rather than a receding wall. `filter` here would flatten a preserve-3d on
     *this* element, but it does not stop perspective reaching children, which is
     why the blur can stay on the same box. */
  perspective: 1600px;
  perspective-origin: 50% 45%;
  /* Soft, not illegible. The first pass blurred these to 14px and the strips
     stopped being screenshots of websites and became grey slabs — which defeats
     the point, since the only job the wallpaper has is to show what comes out.
     Enough blur to stop the tiles competing with the box for focus, not enough
     to stop them reading as work. */
  filter: blur(3px) saturate(0.95);
  /* Light mode is the harder of the two: dark type on mid-tone screenshots,
     where dark mode gets light type on tiles already dimmed by the page. */
  opacity: 0.45;
  /* Hollow the middle out: the prompt box sits there and needs clean page
     behind it, so the mask is transparent at the centre and opaque at the
     edges. Reaching full opacity at 70% rather than 100% is what makes the
     tiles visible at all — fading right to the frame edge left a ring so thin
     that only the four corners carried any image. */
  mask-image: radial-gradient(ellipse 95% 85% at 50% 45%, transparent 32%, black 82%);
  -webkit-mask-image: radial-gradient(ellipse 95% 85% at 50% 45%, transparent 32%, black 82%);
}

[data-theme="dark"] .hero-backdrop {
  opacity: 0.3;
}

/* Overrides the 2-column, 520px-tall, masked showcase from landing.css: as a
   backdrop it has to fill the section and read as many small tiles rather than
   a few large ones.
 *
 * The tilt is the ../tyga.ventures treatment (views/landing.html `.skew`):
 * rotateX/Y/Z together instead of a flat rotate(), so the columns recede into
 * the page rather than sitting on it. Ours differs in two ways on purpose —
 * six columns rather than two, and the whole viewport rather than one half —
 * so the angles are pulled well in from their 22/-12/34, and scale3d is >1
 * because a full-bleed backdrop has no neighbouring column to hide behind. */
.hero-backdrop .hero-showcase {
  position: absolute;
  /* Overscan, and mostly vertical. Rotating the 1440x900 viewport back by 24deg
     needs roughly 1680x1410 of source to cover it, and the perspective divide
     shrinks the receding edge further, so the element runs about 2070x1710.
     The horizontal figure matters twice over, because it also sets how wide
     each of the six tiles ends up — overscanning sideways to be safe is what
     made the first pass render four enormous slabs. */
  inset: -45% -22%;
  height: auto;
  /* Must match COLUMNS in landing-catalogue.js: the script emits that many
     reels, and a grid with fewer tracks would wrap the extras into a second
     row that the scroll animation knows nothing about. */
  grid-template-columns: repeat(6, 1fr);
  gap: 14px;
  border-radius: 0;
  mask-image: none;
  -webkit-mask-image: none;
  transform-style: preserve-3d;
  /* Pulled well in from tyga.ventures' 22/-12/34. Those angles are for one
     half-width column that recedes off the side of the page; at full bleed the
     Y rotation is what hurts, because it drives the far half of the grid so far
     back that it shrinks into the middle of the frame and leaves the right of
     the screen empty. Z carries the diagonal, X and Y only hint at depth.
     scale3d is a safety margin on the overscan above, not a zoom — push it past
     ~1.1 and the tiles start reading as slabs again. */
  transform: rotateX(8deg) rotateY(-4deg) rotateZ(24deg) scale3d(1.05, 1.05, 1);
  /* The reels animate transform; without this the compositor re-rasterises the
     tilted, blurred layer every frame. */
  will-change: transform;
  backface-visibility: hidden;
}

.hero-backdrop .hero-reel {
  gap: 14px;
}

.hero-backdrop .hero-reel img {
  box-shadow: none;
}

/* Even columns run the other way, so the wallpaper never reads as one sliding
   sheet. The durations are deliberately coprime-ish: round numbers would let
   the columns re-synchronise into a visible beat every few minutes. */
.hero-backdrop .hero-reel:nth-child(1) { animation: heroScrollUp 96s linear infinite; }
.hero-backdrop .hero-reel:nth-child(2) { animation: heroScrollDown 112s linear infinite; }
.hero-backdrop .hero-reel:nth-child(3) { animation: heroScrollUp 128s linear infinite; }
.hero-backdrop .hero-reel:nth-child(4) { animation: heroScrollDown 104s linear infinite; }
.hero-backdrop .hero-reel:nth-child(5) { animation: heroScrollUp 118s linear infinite; }
.hero-backdrop .hero-reel:nth-child(6) { animation: heroScrollDown 90s linear infinite; }

/* landing.css pauses the reel on hover — right for a gallery you are looking
   at, wrong for wallpaper, and the backdrop is pointer-events:none anyway. */
.hero-backdrop .hero-showcase:hover .hero-reel {
  animation-play-state: running;
}

@media (prefers-reduced-motion: reduce) {
  .hero-backdrop .hero-reel { animation: none !important; }
}

/* ---------------------------------------------------------------------------
   The prompt box
   --------------------------------------------------------------------------- */

/* The textarea's label. A placeholder is not a label — it disappears on the
   first keystroke and screen readers are not obliged to announce it — but the
   whole point of this screen is that it carries one visible question. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.vibe-prompt {
  position: relative;
  display: flex;
  align-items: flex-end;
  gap: 10px;
  padding: 14px 14px 14px 20px;
  background: var(--bg-primary);
  border: 1px solid var(--border);
  border-radius: 20px;
  box-shadow: var(--shadow-lg, 0 18px 50px rgba(0, 0, 0, 0.14));
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}

.vibe-prompt:focus-within {
  border-color: #10b981;
  box-shadow: 0 0 0 4px rgba(16, 185, 129, 0.12), var(--shadow-lg, 0 18px 50px rgba(0, 0, 0, 0.14));
}

.vibe-prompt textarea {
  flex: 1;
  /* The box grows with the brief: rows=2 is the floor, and the submit handler
     nudges the height on input. No scrollbar until it stops growing. */
  min-height: 56px;
  max-height: 200px;
  padding: 6px 0;
  border: 0;
  outline: 0;
  resize: none;
  background: transparent;
  color: var(--text-primary);
  font-family: inherit;
  font-size: 1.05rem;
  line-height: 1.5;
  text-align: left;
}

.vibe-prompt textarea::placeholder {
  color: var(--text-muted);
}

.vibe-submit {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 44px;
  padding: 0 1.1rem;
  border: 0;
  border-radius: 14px;
  background: var(--accent);
  color: var(--bg-primary);
  font-family: inherit;
  font-size: 0.9rem;
  font-weight: 700;
  cursor: pointer;
  transition: transform 0.15s ease, opacity 0.15s ease;
}

.vibe-submit:hover { transform: translateY(-1px); }
.vibe-submit:disabled { opacity: 0.45; cursor: not-allowed; transform: none; }
.vibe-submit svg { width: 16px; height: 16px; fill: currentColor; }

/* ---------------------------------------------------------------------------
   The transcript, above the box
   --------------------------------------------------------------------------- */

/* The hero answers questions in place, which means this page now has something
   on it that grows without bound — and the one promise the page makes is that
   it is one screen (tests/e2e/33-landing-funnel.spec.js asserts
   scrollHeight <= viewport). So the transcript is capped and scrolls inside
   itself, and the box stays where it was.
 *
 * `display: none` until a turn exists, not `height: 0`: an empty flex column
 * with a gap and a margin still occupies space, and the first paint has to be
 * the hero exactly as it was before this file grew this block. The class is
 * added by public/js/landing-prompt.js on the first message. */
.hero-transcript {
  display: none;
}

.hero-transcript.has-turns {
  display: flex;
  flex-direction: column;
  gap: 10px;
  /* The cap. 38vh leaves the h1, the box, the chips and the trial line on the
     screen at 700px of viewport height, which is the shortest laptop worth
     designing for; the px ceiling stops a tall desktop monitor turning the
     transcript into the page's main event. */
  max-height: min(38vh, 320px);
  overflow-y: auto;
  margin-bottom: 14px;
  padding-right: 4px;
  /* The bubbles are left-aligned prose inside a centred hero. */
  text-align: left;
  scrollbar-width: thin;
}

/* tai-widget.css styles the bubbles for a fixed panel on its own white card and
   switches to dark on prefers-color-scheme. Neither is right here: this page
   has an explicit [data-theme] the visitor chose with the toggle in the nav, so
   a light page on a dark-OS browser would otherwise render dark-grey bubbles
   over light wallpaper. Re-stated against the landing tokens, and by descendant
   selector so the load order of the two stylesheets does not matter. */
.hero-transcript .tai-msg {
  max-width: 88%;
  font-size: 0.92rem;
}

.hero-transcript .tai-msg.assistant {
  background: var(--bg-secondary);
  color: var(--text-primary);
}

.hero-transcript .tai-msg.assistant strong {
  color: var(--text-primary);
}

.hero-transcript .tai-msg.user {
  background: var(--accent);
  color: var(--bg-primary);
}

.hero-transcript .tai-msg.system {
  color: var(--text-muted);
}

.hero-transcript .tai-escalation,
.hero-transcript .tai-quick-replies {
  align-self: flex-start;
}

/* The typing dots sit between the transcript and the box, outside the scroller,
   so waiting for an answer never moves the box. tai-widget.css already gives
   .tai-typing its panel styling and the .show toggle; only the placement and
   the token colours differ. */
.hero-stage .tai-typing {
  align-self: center;
  margin-bottom: 14px;
  background: var(--bg-secondary);
}

.hero-stage .tai-typing span {
  background: var(--text-muted);
}

/* ---------------------------------------------------------------------------
   Chips and the trial line
   --------------------------------------------------------------------------- */

/* Chips carry a one-word label and a full sentence in data-prompt. The label is
   for the eye; the sentence is what lands in the textarea. Both halves matter:
   a bare "Restaurant" is a single signal token, which BriefInferenceAgent reads
   as too vague and answers with a clarifying question instead of a build. */
.vibe-chips {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-top: 1.1rem;
}

.vibe-chip {
  padding: 6px 14px;
  border: 1px solid var(--border);
  border-radius: 50px;
  background: var(--bg-secondary);
  color: var(--text-secondary);
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 500;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}

.vibe-chip:hover {
  color: var(--text-primary);
  border-color: var(--text-muted);
  background: var(--bg-tertiary);
}

.vibe-trial {
  margin-top: 1.75rem;
  font-size: 0.82rem;
  color: var(--text-muted);
}

/* ---------------------------------------------------------------------------
   The legal line, inside the hero
   --------------------------------------------------------------------------- */

/* Not a page footer. A <footer> below the hero would add a second screen, and a
   page that scrolls to reveal a copyright notice is two screens — so this is
   pinned to the hero's own floor and sized to be read only if looked for.
   Absolute rather than margin-top:auto because .hero-single centres its stage;
   a flex footer would drag the h1 and the box off centre. */
.hero-footer {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 18px;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 4px 18px;
  padding: 0 20px;
  font-size: 0.75rem;
  color: var(--text-muted);
}

.hero-footer a {
  color: var(--text-muted);
  text-decoration: none;
  transition: color 0.15s ease;
}

.hero-footer a:hover {
  color: var(--text-primary);
}

@media (max-width: 768px) {
  /* A column, so the legal line is a row under the chips rather than a pinned
     overlay. Pinning is a desktop move: there the stage is centred in a fixed
     100svh and the floor is reliably empty, whereas a phone with the software
     keyboard up has no spare floor and an absolute footer would land on the
     chips. `align-items` has to be reset too — landing.css's .hero sets
     `center`, which in a column shrinks both children to their content width
     (that is what turned the legal line into a narrow right-hand column).

     And the hero stops claiming the viewport: 100svh is a promise on a phone,
     not a layout, since a long brief plus the software keyboard needs the room
     more than the fold does. The slack that leaves below the legal line is not
     worth closing with margin-top:auto — that pushes the line onto the floor,
     which on a first visit is under the cookie banner. */
  .hero-single {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    min-height: auto;
    padding-top: calc(var(--nav-height) + 24px);
  }
  .hero-footer {
    position: static;
    margin-top: 2.5rem;
  }
  /* The column above does the centring now, and a stage still claiming most of
     the viewport would push the footer off it. */
  .hero-stage {
    min-height: 0;
  }
  .hero-backdrop {
    /* The desktop mask is an ellipse wider than it is tall, cut out of a
       landscape frame. In a portrait one the same ellipse swallows almost the
       whole backdrop and the wallpaper disappears, so the hole shrinks and the
       tiles come up to meet the narrower frame. */
    mask-image: radial-gradient(ellipse 85% 55% at 50% 42%, transparent 20%, black 72%);
    -webkit-mask-image: radial-gradient(ellipse 85% 55% at 50% 42%, transparent 20%, black 72%);
    opacity: 0.55;
  }
  [data-theme="dark"] .hero-backdrop { opacity: 0.38; }
  .hero-backdrop .hero-showcase {
    grid-template-columns: repeat(3, 1fr);
    /* Three columns in a 390px-wide frustum: the desktop angles put the
       outer column edge-on and open a wedge of bare page in the top corner,
       so the tilt is halved and the overscan widened. */
    transform: rotateX(12deg) rotateY(-6deg) rotateZ(16deg) scale3d(1.3, 1.3, 1);
    inset: -45% -40%;
  }
  /* Three tracks, so the last three reels would wrap to a second row that the
     scroll animation does not drive. They are wallpaper; drop them. */
  .hero-backdrop .hero-reel:nth-child(n + 4) { display: none; }
  .vibe-prompt {
    flex-direction: column;
    align-items: stretch;
    padding: 14px;
    border-radius: 16px;
  }
  .vibe-submit { justify-content: center; }
}
