/* ---------------- INTRO LOADER (v2, 2026-10-25) --------------------------------
   Black screen with the logo and a thin red line, then the three hero panels
   fly in from three directions (left, top, right; on phones left, right,
   bottom), then one word per panel flies in letter by letter (small, tilted),
   then the words leave, the panel labels fly in and header + chat fade in.

   Stages are <html> classes set by js/intro-loader.js on a FIXED timeline
   (nothing waits on the videos any more; a video simply fades in when it can
   play). The head of index.html adds html.lx-intro before first paint, so there
   is no flash of the finished hero. Without that class (reduced motion, second
   page view in the same session, JS off) none of these rules apply and the
   page renders normally: the overlay elements are display:none by default.

     lx-intro  waiting (black, logo, line)      t = 0
     lx-go     overlay fades, panels fly in     t = T0 (max 1.6 s)
     lx-text   words fly in                     T0 + 0.8 s
     lx-out    words leave, labels + header in  T0 + 3.1 s
     lx-done   classes removed, overlay removed T0 + 3.8 s
   Hard stops: js at 7 s, inline head guard at 9 s, both always remove it. */

:root { --lx-ease-settle: cubic-bezier(.22, 1, .36, 1); --lx-ease-panel: cubic-bezier(.77, 0, .175, 1); }

html.lx-intro, html.lx-intro body { background: #000 !important; overflow: hidden; }
html.lx-intro .hero-section { background: #000; }
html.lx-intro .header,
html.lx-intro .chat-search-container { opacity: 0; visibility: hidden; pointer-events: none; }
html.lx-intro.lx-out .header,
html.lx-intro.lx-out .chat-search-container { opacity: 1; visibility: visible; pointer-events: auto; transition: opacity .8s ease .15s; }

/* Overlay: hidden unless the intro really runs (fixes the stuck overlay under reduced motion) */
#lx-intro, #lx-words { display: none; }
html.lx-intro #lx-intro { position: fixed; inset: 0; z-index: 10000; background: #000; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 22px; transition: opacity .4s ease; }
#lx-intro img { width: 150px; height: auto; opacity: .92; }
#lx-intro .lx-line { width: 150px; height: 1px; background: rgba(255,255,255,.14); overflow: hidden; }
#lx-intro .lx-line i { display: block; height: 100%; background: #e2313b; transform-origin: left; transform: scaleX(0); transition: transform 1.4s cubic-bezier(.3, .6, .4, 1); box-shadow: 0 0 10px #e2313b; }
html.lx-intro.lx-go #lx-intro { opacity: 0; pointer-events: none; }

/* Panels: no old blur dissolve; a dark base so a panel is visible before its video can play */
html.lx-intro .page-index .hero-panel,
html.lx-done .page-index .hero-panel { animation: none !important; opacity: 1; filter: none; }
html.lx-intro .hero-panel { background: #1a1c22; box-shadow: inset 0 0 0 1px rgba(255,255,255,.06); }
html.lx-intro .hero-panel video { opacity: 0; transition: opacity .6s ease; }
html.lx-intro .hero-panel video.lx-vid { opacity: 1; }

/* Panels wait outside the viewport and fly in on lx-go */
html.lx-intro .hero-split .hero-panel:nth-child(1) { transform: translateX(-105%); }
html.lx-intro .hero-split .hero-panel:nth-child(2) { transform: translateY(-105%); }
html.lx-intro .hero-split .hero-panel:nth-child(3) { transform: translateX(105%); }
html.lx-intro.lx-go .hero-split .hero-panel:nth-child(n) { transform: none; transition: transform 1.1s var(--lx-ease-panel); }
html.lx-intro.lx-go .hero-split .hero-panel:nth-child(2) { transition-delay: .12s; }
html.lx-intro.lx-go .hero-split .hero-panel:nth-child(3) { transition-delay: .24s; }

/* Panel labels: hidden during the intro, fly in (offset + extra tilt, settle to the
   normal -90deg) on lx-out. Desktop labels are vertical, phone labels horizontal. */
html.lx-intro .panel-label-thin { opacity: 0; transform: translate(-50%, -50%) rotate(-90deg) translate(-28px, 34px) rotate(-10deg); }
html.lx-intro.lx-out .panel-label-thin { opacity: 1; transform: translate(-50%, -50%) rotate(-90deg); transition: opacity .55s ease-out, transform .9s var(--lx-ease-settle); transition-delay: .35s; }
html.lx-intro.lx-out .hero-panel:nth-child(2) .panel-label-thin { transition-delay: .45s; }
html.lx-intro.lx-out .hero-panel:nth-child(3) .panel-label-thin { transition-delay: .55s; }

@media screen and (max-width: 768px) {
  html.lx-intro .hero-split .hero-panel:nth-child(1) { transform: translateX(-105%); }
  html.lx-intro .hero-split .hero-panel:nth-child(2) { transform: translateX(105%); }
  html.lx-intro .hero-split .hero-panel:nth-child(3) { transform: translateY(105%); }
  html.lx-intro .panel-label-thin { transform: translate(-50%, -50%) translate(-28px, 34px) rotate(-10deg); }
  html.lx-intro.lx-out .panel-label-thin { transform: translate(-50%, -50%) rotate(0deg); }
}

/* Words (v3, 2026-10-29): one per panel, straight (no tilt). They glitch in: RGB-split
   slices of the word (red / blue copies, as in css/scroll-reveal.css) plus band cuts on
   the word itself, while js decodes the letters from random glyphs. On lx-out they
   glitch out the same way and vanish. Staggered per word (--w). */
html.lx-intro #lx-words { display: block; position: fixed; inset: 0; z-index: 9000; pointer-events: none; }
#lx-words .lx-w { position: absolute; top: 50%; left: var(--x); transform: translate(-50%, -50%); white-space: nowrap;
  font-family: var(--font-tech, inherit); font-weight: 300; font-size: clamp(24px, 2.6vw, 44px); letter-spacing: .06em; text-transform: uppercase;
  color: #fff; text-shadow: 0 3px 24px rgba(0,0,0,.7); opacity: 0; }
#lx-words .lx-w:nth-child(1) { --x: 19%; --w: 0ms; }
#lx-words .lx-w:nth-child(2) { --x: 50%; --w: 150ms; }
#lx-words .lx-w:nth-child(3) { --x: 81%; --w: 300ms; }
#lx-words .lx-w::before, #lx-words .lx-w::after { content: attr(data-text); position: absolute; inset: 0; opacity: 0; pointer-events: none; text-shadow: none; }
#lx-words .lx-w::before { color: #e2313b; }
#lx-words .lx-w::after  { color: #3b8dff; }
html.lx-text #lx-words .lx-w { opacity: 1; animation: lx-cut .5s steps(1, end) var(--w) both, lx-on .01s linear var(--w) both; }
html.lx-text #lx-words .lx-w::before { animation: lx-rgb-a .5s steps(1, end) var(--w) both; }
html.lx-text #lx-words .lx-w::after  { animation: lx-rgb-b .5s steps(1, end) var(--w) both; }
html.lx-out #lx-words .lx-w { animation: lx-cut .38s steps(1, end) calc(var(--w) * .5) both, lx-gone .38s steps(1, end) calc(var(--w) * .5) both; }
html.lx-out #lx-words .lx-w::before { animation: lx-rgb-a .38s steps(1, end) calc(var(--w) * .5) reverse both; }
html.lx-out #lx-words .lx-w::after  { animation: lx-rgb-b .38s steps(1, end) calc(var(--w) * .5) reverse both; }
@keyframes lx-on { from { opacity: 0; } to { opacity: 1; } }
@keyframes lx-gone { 0%, 70% { opacity: 1; transform: translate(-50%, -50%); } 70.1%, 85% { opacity: .6; transform: translate(calc(-50% + 6px), -50%); } 85.1%, 100% { opacity: 0; transform: translate(-50%, -50%); } }
@keyframes lx-cut {
  0%, 18%  { clip-path: inset(0 0 0 0); }
  18.1%, 26% { clip-path: inset(0 0 58% 0); }
  26.1%, 44% { clip-path: inset(0 0 0 0); }
  44.1%, 52% { clip-path: inset(38% 0 0 0); }
  52.1%, 66% { clip-path: inset(0 0 0 0); }
  66.1%, 72% { clip-path: inset(0 0 30% 0); }
  72.1%, 100% { clip-path: inset(0 0 0 0); }
}
@keyframes lx-rgb-a {
  0%   { opacity: .9; clip-path: inset(10% 0 55% 0); transform: translateX(-9px); }
  18%  { opacity: .9; clip-path: inset(42% 0 20% 0); transform: translateX(7px); }
  34%  { opacity: .9; clip-path: inset(0 0 66% 0);  transform: translateX(-5px); }
  52%  { opacity: .8; clip-path: inset(60% 0 8% 0);  transform: translateX(8px); }
  70%  { opacity: .7; clip-path: inset(22% 0 48% 0); transform: translateX(-3px); }
  84%  { opacity: .5; clip-path: inset(0 0 80% 0);  transform: translateX(2px); }
  100% { opacity: 0;  clip-path: inset(0 0 100% 0); transform: none; }
}
@keyframes lx-rgb-b {
  0%   { opacity: .9; clip-path: inset(50% 0 12% 0); transform: translateX(8px); }
  18%  { opacity: .9; clip-path: inset(0 0 70% 0);   transform: translateX(-6px); }
  34%  { opacity: .9; clip-path: inset(30% 0 36% 0); transform: translateX(6px); }
  52%  { opacity: .8; clip-path: inset(6% 0 62% 0);  transform: translateX(-8px); }
  70%  { opacity: .7; clip-path: inset(66% 0 4% 0);  transform: translateX(3px); }
  84%  { opacity: .5; clip-path: inset(84% 0 0 0);   transform: translateX(-2px); }
  100% { opacity: 0;  clip-path: inset(100% 0 0 0);  transform: none; }
}
@media screen and (max-width: 768px) {
  #lx-words .lx-w { font-size: clamp(22px, 6.5vw, 32px); left: 50%; }
  #lx-words .lx-w:nth-child(1) { top: 17%; }
  #lx-words .lx-w:nth-child(2) { top: 50%; }
  #lx-words .lx-w:nth-child(3) { top: 83%; }
}

/* Reduced motion never gets html.lx-intro (head script), but if a browser flips
   the preference mid-run: everything in place, plain fades only. */
@media (prefers-reduced-motion: reduce) {
  html.lx-intro .hero-split .hero-panel,
  html.lx-intro .panel-label-thin,
  html.lx-intro #lx-words .lx-w, html.lx-intro #lx-words .lx-w::before, html.lx-intro #lx-words .lx-w::after { animation: none !important; }
}
