/*
 * InfiniStack - custom.css
 * Entry stylesheet — imports component modules + hero styles.
 */

@import url('components/header.css');
@import url('components/navigation.css');
@import url('components/page-skeleton.css');
@import url('components/footer.css');
@import url('components/insights-scroll.css');
@import url('components/product-story.css');
@import url('components/platform-bento.css');
@import url('components/connectors-strip.css');
@import url('components/why-infinistack.css');
@import url('components/final-cta.css');
@import url('components/scroll-reveal.css');

:root {
  /* Ignite brand palette (see infinistack_etl_frontend/src/styles/_theme.scss) */
  --brand-600: #ff5a1f;
  --infinistack-ink: #17161b;
  --infinistack-ash: #6b6a66;
  --infinistack-apricot: #ffe7d9;
  --infinistack-sky: #dee4ff;
  --infinistack-rust: #7a2e0a;
  --infinistack-fog: #faf9f6;
  --infinistack-accent: #ff5a1f;
  --infinistack-accent-hover: #e84e15;
  --infinistack-accent-foreground: #ffffff;
  --infinistack-accent-2: #3d5bff;
  --infinistack-card-shadow:
    0 20px 25px -5px rgba(0, 0, 0, 0.1),
    0 8px 10px -6px rgba(0, 0, 0, 0.05);
}

html {
  /* No `scroll-behavior: smooth` here — it fights GSAP ScrollTrigger's pinned
     sections (the hero, the insights timeline), which set scroll position
     directly and end up jittering or sticking on it. Anchor links still glide:
     assets/js/modules/smooth-scroll.js does it per-click with scrollIntoView. */
  scroll-padding-top: 5rem;
}

a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--brand-600);
  outline-offset: 2px;
}

body {
  /* Must stay `clip`, not `hidden`: `overflow-x: hidden` computes overflow-y to
     `auto`, which makes <body> its own scroll container. GSAP ScrollTrigger
     then tracks the window scroller and reads 0 forever, so the pinned hero and
     the insights timeline never animate. `clip` leaves overflow-y `visible`. */
  overflow-x: clip;
}

/* ---- InfiniStack hero ---- */

.infinistack-hero h1 em {
  font-style: italic;
}

.infinistack-hero-noise {
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.91' numOctaves='2' seed='10' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='discrete' tableValues='0 1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
  background-size: 180px 180px;
  mix-blend-mode: overlay;
  opacity: 0.18;
}

.infinistack-hero-glow {
  background: radial-gradient(
    ellipse at center,
    rgba(255, 231, 217, 0.85) 0%,
    rgba(255, 231, 217, 0.35) 45%,
    transparent 70%
  );
}

/* Ignite hero backdrop — two brand-color glows on the warm neutral
   base, replacing the legacy InfiniStack photography entirely so the hero
   reads as InfiniStack rather than a re-colored template asset. */
.infinistack-hero-wash {
  background:
    radial-gradient(48% 45% at 14% 20%, rgba(61, 91, 255, 0.24) 0%, transparent 72%),
    radial-gradient(55% 50% at 84% 12%, rgba(255, 90, 31, 0.30) 0%, transparent 70%),
    linear-gradient(180deg, var(--infinistack-fog) 0%, #ffffff 100%);
}

.infinistack-btn-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 2.75rem;
  padding: 0 1.25rem;
  border-radius: 9999px;
  background: var(--infinistack-accent);
  color: var(--infinistack-accent-foreground);
  font-size: 1.125rem;
  line-height: 1;
  transition: background-color 0.2s;
}

.infinistack-btn-primary:hover {
  background: var(--infinistack-accent-hover);
}

.infinistack-btn-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 2.75rem;
  padding: 0 1.25rem;
  border-radius: 9999px;
  color: var(--infinistack-ink);
  font-size: 1.125rem;
  line-height: 1;
  transition: background-color 0.2s;
}

.infinistack-btn-secondary:hover {
  background: rgba(23, 22, 27, 0.05);
}

/* Reserve the pinned hero's full-viewport height before hero-scroll.js (which
   waits on CDN GSAP) sets the same value inline. Without this the pin has no
   in-flow content, collapses to 0, and the section below flashes into view. */
.infinistack-hero-pin {
  height: 100vh;
  height: 100svh;
}

.infinistack-hero-stage-wrap {
  will-change: transform;
}

/* The screenshot of the app's content, laid into the empty content area of the
   dashboard shell (hero-desktop-clean.webp). Measured from that raster: its
   sidebar divider is at x 212 and its top-bar divider at y 52 of 1731x908,
   which `object-cover` scales by 880/908 into the 1200x880 box -> the content
   area is 214..1200 x 50..880. The 920x481 overlay is centred in it, so
   left = 214 + (986-920)/2 = 247 and its settled top is 224. `top` here is
   that 224 minus the 84px the timeline leaves on `y` (posOverlayTo), so the
   overlay still drifts up as it fades in. */
#infinistackHeroContent {
  top: 140px;
  left: 247px;
}

/* The chat card's visible box is `.ai-button-container`, which fills this
   wrapper so the hero timeline can size it — it starts large and shrinks into
   the dashboard's search bar. This width is only the fallback for when the
   timeline never runs (prefers-reduced-motion), and matches the search bar. */
#infinistackHeroAi {
  width: 493px;
}

/* Fallback size for when the timeline never runs (prefers-reduced-motion) —
   matches the image's native dimensions, since the img is now `object-fill`
   and needs the wrapper's box to size itself instead of sizing to content. */
#infinistackHeroBlue {
  width: 600px;
  height: 311px;
}

#infinistackHeroCarousel {
  bottom: 0;
  left: -5%;
}

.infinistack-block-wrap {
  --block-shadow: var(--infinistack-card-shadow);
  --shadow-opacity: 1;
}

.infinistack-block-wrap::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: var(--block-shadow);
  opacity: var(--shadow-opacity);
  pointer-events: none;
}

.infinistack-logo-marquee {
  mask-image: linear-gradient(to right, transparent, #000 20%, #000 80%, transparent);
}

.infinistack-logo-fade {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 20%;
  z-index: 10;
  pointer-events: none;
}

.infinistack-logo-fade-left {
  left: 0;
  background: linear-gradient(to right, #fff, transparent);
}

.infinistack-logo-fade-right {
  right: 0;
  background: linear-gradient(to left, #fff, transparent);
}

.infinistack-logo-track {
  /* `max-content`, not `fit-content`: the logos are `w-auto`, so the track's
     min-content collapses and `fit-content` clamps to the 1200px container
     while the copies overflow to 3266px. translateX(-50%) would then resolve
     against the clamped box and shift a fraction of one copy, so the strip
     snapped back mid-loop instead of cycling. */
  width: max-content;
  animation: infinistack-carousel 35s linear infinite;
}

@keyframes infinistack-carousel {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-50%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .infinistack-logo-track {
    animation: none;
  }

  .infinistack-hero-stage-wrap.invisible {
    visibility: visible !important;
  }
}
