// HIWCinematic: full-viewport scroll-jacked cinematic for How It Works.
//
// Layout: 3 devices (phone + laptop + desktop + tablet) orbit a central
// "sync core" made from the Synchronize logo's double-bubble motif.
// Scroll advances through 6 chapters; each chapter drives a scene state
// that the devices and core react to.

const { useState: useStC, useEffect: useEffC, useRef: useRefC, useMemo: useMemoC } = React;

// ---------- Scene script ----------
// Each scene is a snapshot of the world: which device is active, what
// messages are visible on each device, what the sync core is doing, and
// a caption.
// Sample thread: an engaging, fictional conversation that unfolds across all three platforms.
const THREAD_Q = "When a critical software vendor goes down, what does your team communicate before you have a confirmed recovery time?";

const REPLIES = [
  { who: 'Mei L.', role: 'CTO', via: 'circle', color: '#21C089',
    text: "We send three things: what is affected, what people should do now, and when the next update will arrive. Facts first; no guessed ETA.",
    reacts: ['💡', '✅', '👏'] },
  { who: 'David O.', role: 'Head of Customer Experience', via: 'email', color: '#B24848',
    text: "Naming one communications owner made the biggest difference for us. Support, sales, and engineering all work from the same update.",
    reacts: ['🙌', '💯'] },
  { who: 'Nora B.', role: 'COO', via: 'email', color: '#2F7CFF',
    text: "We also state what is still working. It lowers the temperature and gives teams a useful next step while engineering investigates.",
    reacts: ['✅', '👏'] },
];

const SCENES = [
  {
    id: 'meet',
    caption: { eyebrow: 'Your community, three platforms', title: 'Members show up where they already live.', body: 'Some are in Slack all day. Some only check email. Some live inside your community platform. Meeting them everywhere used to mean running three separate communities.' },
    core: { state: 'idle' },
    slack:  { mode: 'intro', who: 'Alyssa G.', sub: 'VP Operations · checks Slack throughout the day' },
    circle: { mode: 'intro', who: 'Mei L.', sub: 'CTO · participates in the community platform' },
    gmail:  { mode: 'intro', who: 'David O.', sub: 'Customer leader · prefers email' },
  },
  {
    id: 'ask',
    caption: { eyebrow: 'Step 01 · Slack', title: 'A member asks for practical advice in Slack.', body: 'Alyssa shares a timely operating question in the channel she already uses with her team.' },
    core: { state: 'listening' },
    slack:  { mode: 'composing', text: THREAD_Q },
    circle: { mode: 'idle' },
    gmail:  { mode: 'idle' },
  },
  {
    id: 'sync',
    caption: { eyebrow: 'Step 02 · Synchronize', title: 'Synchronize carries the conversation everywhere.', body: 'The post keeps its author, context, and timestamp as it is prepared for email and your online community.' },
    core: { state: 'active', direction: 'in' },
    slack:  { mode: 'posted', text: THREAD_Q },
    circle: { mode: 'idle' },
    gmail:  { mode: 'idle' },
  },
  {
    id: 'fanout',
    caption: { eyebrow: 'Step 03 · Everywhere', title: 'Every member sees it in a familiar format.', body: 'The community displays a native post while email delivers a clean, reply-ready message. No links to chase and nothing to repost.' },
    core: { state: 'active', direction: 'out' },
    slack:  { mode: 'posted', text: THREAD_Q },
    circle: { mode: 'posted', text: THREAD_Q },
    gmail:  { mode: 'posted', text: THREAD_Q },
  },
  {
    id: 'replies',
    caption: { eyebrow: 'Step 04 · The response', title: 'Expert answers return from every surface.', body: 'Mei replies in the community. David responds from Gmail. Both answers join the same thread in Slack with clear attribution.' },
    core: { state: 'active', direction: 'through' },
    slack:  { mode: 'thread', text: THREAD_Q, replies: REPLIES },
    circle: { mode: 'thread', text: THREAD_Q, replies: REPLIES.slice(0, 2) },
    gmail:  { mode: 'thread', text: THREAD_Q, replying: REPLIES[1] },
  },
  {
    id: 'unified',
    caption: { eyebrow: 'The result', title: 'One useful conversation, open to everyone.', body: 'Members contribute from the tools they prefer while Synchronize preserves one complete thread, its participants, and every interaction.' },
    core: { state: 'halo' },
    slack:  { mode: 'thread', text: THREAD_Q, replies: REPLIES, tag: 'LIVE' },
    circle: { mode: 'thread', text: THREAD_Q, replies: REPLIES, tag: 'LIVE' },
    gmail:  { mode: 'thread', text: THREAD_Q, replies: REPLIES, tag: 'LIVE' },
  },
];

// ---------- Sync core (conversation bubbles from logo motif) ----------
function SyncCore({ state = 'idle', direction, progress = 0 }) {
  // Two bubbles in S-shape with 3 dots each (from logo). They pulse & rotate.
  const active = state !== 'idle';
  return (
    <div style={{ width: '100%', height: '100%', position: 'relative', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
      {/* halo rings when in halo state */}
      {state === 'halo' && [0, 1, 2].map(i => (
        <div key={i} style={{
          position: 'absolute', width: `${110 + i * 25}%`, height: `${110 + i * 25}%`,
          borderRadius: '50%', border: '1.5px solid #4242F0',
          opacity: 0.22 - i * 0.06,
          animation: `hiw-halo 2.4s ${i * 0.3}s infinite ease-out`,
        }}/>
      ))}
      {/* soft glow */}
      <div style={{
        position: 'absolute', width: '145%', height: '145%', borderRadius: '50%',
        background: 'radial-gradient(circle, rgba(66,66,240,0.28) 0%, rgba(66,66,240,0) 65%)',
        opacity: active ? 1 : 0.4,
        transition: 'opacity .5s',
        filter: active ? 'blur(0px)' : 'blur(2px)',
      }}/>

      {/* The exact Synchronize logo mark (two rounded speech bubbles) */}
      <svg viewBox="0 0 48 48" style={{ width: '83%', height: '83%', position: 'relative', zIndex: 2, overflow: 'visible' }}>
        <defs>
          <linearGradient id="bubble-grad" x1="0" y1="0" x2="1" y2="1">
            <stop offset="0%" stopColor="#4242F0"/>
            <stop offset="100%" stopColor="#6868FF"/>
          </linearGradient>
        </defs>

        {/* Solid bubble silhouette. The logo asset normally punches static dot
            holes through this path; keeping the silhouette solid ensures the
            animated typing dots are the only visible dots. */}
        <g style={{ transformOrigin: '24px 12px', animation: active ? 'hiw-breathe 2.8s infinite ease-in-out' : 'none' }}>
          <path fillRule="nonzero" fill="url(#bubble-grad)" opacity={active ? 1 : 0.9}
            d="M36.2739 0.960205H18.5257C15.3593 0.960205 12.4889 2.26389 10.4228 4.35476C8.35679 6.44564 7.0686 9.3506 7.0686 12.5551C7.0686 18.4226 11.4018 23.2802 17.0212 24.0232C17.2755 24.0578 17.3798 23.7026 17.1483 23.5932C15.6837 22.9 14.6991 21.8901 14.7162 20.2255C14.737 18.102 16.4862 16.4104 18.5845 16.4104H36.2739C40.4894 16.4104 43.9062 12.9525 43.9062 8.68629C43.9062 4.42005 40.4894 0.960205 36.2739 0.960205Z"/>
          {/* Three-dot iOS-style typing pulse. */}
          {[21.0072, 28.6396, 36.272].map((cx, i) => (
            <circle key={i} cx={cx} cy="8.684" r="2.545" fill="#fff"
              style={{ transformBox: 'fill-box', transformOrigin: 'center',
                animation: active ? `hiw-type 1.3s ${i * 0.18}s infinite ease-in-out` : 'none' }}/>
          ))}
        </g>

        {/* Bottom solid bubble silhouette, with dots supplied only below. */}
        <g style={{ transformOrigin: '24px 36px', animation: active ? 'hiw-breathe 2.8s 0.2s infinite ease-in-out' : 'none' }}>
          <path fillRule="nonzero" fill="url(#bubble-grad)" opacity={active ? 1 : 0.9}
            d="M27.8147 23.5951C27.5605 23.5606 27.4562 23.9158 27.6876 24.0252C29.1523 24.7183 30.1369 25.7283 30.1198 27.3929C30.099 29.5164 28.3498 31.2079 26.2515 31.2079H8.56402C4.34847 31.2079 0.931641 34.6659 0.931641 38.9321C0.931641 43.1983 4.34847 46.6562 8.56402 46.6562H26.3103C29.4767 46.6562 32.3471 45.3526 34.4132 43.2617C36.4792 41.1708 37.7674 38.2659 37.7674 35.0614C37.7674 29.1939 33.4342 24.3362 27.8147 23.5932V23.5951Z"/>
          {/* Three-dot iOS-style typing pulse, offset from the top row. */}
          {[8.564, 16.1964, 23.8288].map((cx, i) => (
            <circle key={i} cx={cx} cy="38.932" r="2.545" fill="#fff"
              style={{ transformBox: 'fill-box', transformOrigin: 'center',
                animation: active ? `hiw-type 1.3s ${0.5 + i * 0.18}s infinite ease-in-out` : 'none' }}/>
          ))}
        </g>
      </svg>

      {/* direction arrows for in/out/through */}
      {active && (
        <svg viewBox="0 0 400 400" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', pointerEvents: 'none' }}>
          {[0, 72, 144, 216, 288].map((deg, i) => (
            <g key={i} transform={`translate(200,200) rotate(${deg})`}>
              <circle r="3" fill="#4242F0">
                <animate attributeName="opacity" values="0;1;0" dur="1.4s" begin={`${i*0.28}s`} repeatCount="indefinite"/>
                <animate attributeName="cx"
                  values={direction === 'out' ? '60;180' : direction === 'in' ? '180;60' : '60;180;60'}
                  dur="1.4s" begin={`${i*0.28}s`} repeatCount="indefinite"/>
              </circle>
            </g>
          ))}
        </svg>
      )}
    </div>
  );
}

// ---------- Device frames ----------

function PhoneFrame({ children, active, label, tilt = -4 }) {
  return (
    <div style={{
      position: 'relative',
      width: 240, height: 490,
      transform: `rotate(${tilt}deg) translateY(${active ? -8 : 0}px)`,
      transition: 'transform .5s cubic-bezier(.2,.8,.2,1), filter .5s',
      filter: active ? 'drop-shadow(0 20px 40px rgba(66,66,240,0.25))' : 'drop-shadow(0 8px 20px rgba(0,0,0,0.08))',
    }}>
      <div style={{
        position: 'absolute', inset: 0,
        background: '#1A1B3A', borderRadius: 40,
        padding: 10,
      }}>
        <div style={{
          position: 'absolute', top: 14, left: '50%', transform: 'translateX(-50%)',
          width: 80, height: 22, background: '#0A0B20', borderRadius: 20, zIndex: 3,
        }}/>
        <div style={{
          width: '100%', height: '100%', background: '#fff', borderRadius: 30,
          overflow: 'hidden', position: 'relative',
        }}>
          {children}
        </div>
      </div>
      {label && <DeviceLabel text={label} color="#611F69" active={active}/>}
    </div>
  );
}

function LaptopFrame({ children, active, label, tilt = 0 }) {
  return (
    <div style={{
      position: 'relative',
      width: 480,
      transform: `rotate(${tilt}deg) translateY(${active ? -6 : 0}px)`,
      transition: 'transform .5s cubic-bezier(.2,.8,.2,1), filter .5s',
      filter: active ? 'drop-shadow(0 24px 48px rgba(66,66,240,0.22))' : 'drop-shadow(0 8px 20px rgba(0,0,0,0.08))',
    }}>
      {/* screen */}
      <div style={{
        background: '#1A1B3A', borderRadius: '14px 14px 4px 4px',
        padding: 12, paddingBottom: 14,
      }}>
        <div style={{
          width: '100%', height: 320, background: '#fff', borderRadius: 6,
          overflow: 'hidden', position: 'relative',
        }}>
          {children}
        </div>
      </div>
      {/* base */}
      <div style={{
        width: '110%', marginLeft: '-5%',
        height: 14,
        background: 'linear-gradient(180deg, #2A2B4A 0%, #1A1B3A 100%)',
        borderRadius: '0 0 14px 14px',
        position: 'relative',
      }}>
        <div style={{
          position: 'absolute', left: '50%', top: 0, transform: 'translateX(-50%)',
          width: 60, height: 4, background: '#0A0B20', borderRadius: '0 0 6px 6px',
        }}/>
      </div>
      {label && <DeviceLabel text={label} color="#2F7CFF" active={active}/>}
    </div>
  );
}

function DesktopFrame({ children, active, label, tilt = 2 }) {
  return (
    <div style={{
      position: 'relative',
      width: 420,
      transform: `rotate(${tilt}deg) translateY(${active ? -6 : 0}px)`,
      transition: 'transform .5s cubic-bezier(.2,.8,.2,1), filter .5s',
      filter: active ? 'drop-shadow(0 24px 48px rgba(217,48,37,0.25))' : 'drop-shadow(0 8px 20px rgba(0,0,0,0.08))',
    }}>
      <div style={{
        background: '#1A1B3A', borderRadius: '10px 10px 4px 4px',
        padding: 10, paddingBottom: 12,
      }}>
        <div style={{
          width: '100%', height: 280, background: '#fff', borderRadius: 4,
          overflow: 'hidden', position: 'relative',
        }}>
          {children}
        </div>
      </div>
      {/* stand */}
      <div style={{
        width: 80, height: 24, background: '#1A1B3A', margin: '0 auto',
        borderRadius: '0 0 6px 6px',
      }}/>
      <div style={{
        width: 160, height: 6, background: '#1A1B3A', margin: '0 auto',
        borderRadius: 3,
      }}/>
      {label && <DeviceLabel text={label} color="#315EFB" active={active}/>} 
    </div>
  );
}

function TabletFrame({ children, active, label, tilt = 6 }) {
  return (
    <div style={{
      position: 'relative',
      width: 280, height: 380,
      transform: `rotate(${tilt}deg) translateY(${active ? -6 : 0}px)`,
      transition: 'transform .5s cubic-bezier(.2,.8,.2,1), filter .5s',
      filter: active ? 'drop-shadow(0 20px 40px rgba(33,192,137,0.25))' : 'drop-shadow(0 8px 20px rgba(0,0,0,0.08))',
    }}>
      <div style={{
        position: 'absolute', inset: 0,
        background: '#1A1B3A', borderRadius: 24,
        padding: 12,
      }}>
        <div style={{
          width: '100%', height: '100%', background: '#fff', borderRadius: 16,
          overflow: 'hidden', position: 'relative',
        }}>
          {children}
        </div>
      </div>
      {label && <DeviceLabel text={label} color="#21C089" active={active}/>}
    </div>
  );
}

function DeviceLabel({ text, color, active }) {
  return (
    <div style={{
      position: 'absolute', bottom: -28, left: '50%', transform: 'translateX(-50%)',
      fontSize: 10, fontWeight: 700, letterSpacing: '.08em', textTransform: 'uppercase',
      color: active ? color : 'var(--site-ink-soft)',
      whiteSpace: 'nowrap', transition: 'color .3s',
    }}>
      {text}
    </div>
  );
}

// ---------- Screen contents per device ----------

// Big platform panel that replaces the device frames. Shows the platform name,
// a chrome stripe, and the actual UI screen beneath. Much more legible than
// shrunken device frames.
function PlatformPanel({ id, platform, sub, brandColor, active, compact = false, children }) {
  return (
    <div data-platform={id} style={{
      position: 'relative',
      display: 'flex', flexDirection: 'column',
      borderRadius: 3,
      border: `1px solid ${active ? brandColor + '55' : 'var(--site-line)'}`,
      background: '#fff',
      boxShadow: active ? `0 8px 0 ${brandColor}10` : 'none',
      transition: 'box-shadow .4s, border-color .4s, transform .4s cubic-bezier(.2,.8,.2,1)',
      transform: active ? 'translateY(-6px)' : 'translateY(0)',
      overflow: 'hidden',
      minHeight: compact ? 0 : 380,
      height: compact ? '100%' : 'auto',
    }}>
      {/* header strip */}
      <div style={{
        padding: '10px 14px',
        borderBottom: '1px solid var(--site-line)',
        display: 'flex', alignItems: 'center', gap: 10,
        background: active ? brandColor + '08' : '#FBFAF6',
      }}>
        <PlatformIcon kind={id === 'gmail' ? 'email' : id} size={24}/>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--site-ink)', letterSpacing: '-0.01em' }}>{platform}</div>
          <div style={{ fontSize: 10, color: 'var(--site-ink-soft)', marginTop: 1 }}>{sub}</div>
        </div>
        {active && (
          <span style={{
            fontSize: 9, fontWeight: 700, letterSpacing: '.08em', textTransform: 'uppercase',
            padding: '3px 7px', borderRadius: 2,
            background: brandColor + '14', color: brandColor,
            animation: 'hiw-in .4s both',
          }}>Active</span>
        )}
      </div>
      {/* screen */}
      <div style={{ flex: 1, position: 'relative', overflow: 'hidden', minHeight: compact ? 0 : 340 }}>
        {children}
      </div>
    </div>
  );
}

function SlackScreen({ data }) {
  return (
    <div style={{ width: '100%', height: '100%', display: 'grid', gridTemplateColumns: '60px 1fr', fontSize: 12 }}>
      {/* sidebar */}
      <div style={{ background: '#3F0E40', padding: '12px 6px', color: '#fff' }}>
        <div style={{ width: 36, height: 36, borderRadius: 8, background: '#4A1D4B', display: 'flex', alignItems: 'center', justifyContent: 'center', fontWeight: 700, fontSize: 13 }}>LE</div>
        <div style={{ marginTop: 14, fontSize: 10, opacity: 0.78, padding: '0 4px', fontWeight: 600 }}>#incident-response</div>
        <div style={{ marginTop: 4, fontSize: 10, opacity: 0.45, padding: '0 4px' }}>#member-asks</div>
        <div style={{ marginTop: 4, fontSize: 10, opacity: 0.45, padding: '0 4px' }}>#introductions</div>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column' }}>
        {/* header */}
        <div style={{ padding: '10px 14px', borderBottom: '1px solid #EEE', fontWeight: 700, fontSize: 13 }}>
          #incident-response <span style={{ color: '#8B8695', fontWeight: 400, marginLeft: 6, fontSize: 11 }}>238 members</span>
        </div>
        <div style={{ padding: 14, flex: 1, display: 'flex', flexDirection: 'column', gap: 12, overflow: 'hidden' }}>
          {data.mode === 'intro' && (
            <PersonIntro who={data.who} sub={data.sub} color="#611F69"/>
          )}
          {(data.mode === 'composing' || data.mode === 'posted' || data.mode === 'thread') && (
            <SlackPost text={data.text} composing={data.mode === 'composing'}/>
          )}
          {data.mode === 'thread' && data.replies && (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 10, marginTop: 2 }}>
              {data.replies.slice(0, 3).map((r, i) => (
                <SlackReply key={i} r={r} delay={i * 0.2}/>
              ))}
            </div>
          )}
        </div>
        {data.tag && <LiveTag/>}
      </div>
    </div>
  );
}

function CircleScreen({ data }) {
  return (
    <div style={{ width: '100%', height: '100%', display: 'grid', gridTemplateColumns: '100px 1fr', fontSize: 12, background: '#FAF8F3' }}>
      <div style={{ background: '#fff', borderRight: '1px solid #EEE', padding: '14px 10px' }}>
        <div style={{ width: 28, height: 28, borderRadius: '50%', border: '2.5px solid #2F7CFF', margin: '0 auto 10px', position: 'relative' }}>
          <div style={{ width: 10, height: 10, borderRadius: '50%', background: '#2F7CFF', margin: '6px auto' }}/>
        </div>
        <div style={{ fontSize: 10, fontWeight: 700, color: '#1A1B3A', textAlign: 'center' }}>Leadership Exchange</div>
        <div style={{ fontSize: 9, color: '#8B8695', textAlign: 'center', marginTop: 1 }}>238 members</div>
        <div style={{ marginTop: 14, display: 'flex', flexDirection: 'column', gap: 5 }}>
          {['Home','#incident-response','Events','Directory','Resources'].map((s, i) => (
            <div key={s} style={{ fontSize: 11, padding: '5px 8px', borderRadius: 5,
              background: i === 1 ? '#EFEFFE' : 'transparent', color: i === 1 ? '#4242F0' : '#2B2C54',
              fontWeight: i === 1 ? 700 : 500 }}>{s}</div>
          ))}
        </div>
      </div>
      <div style={{ padding: 16, display: 'flex', flexDirection: 'column', gap: 10, overflow: 'hidden' }}>
        <div style={{ fontSize: 13, fontWeight: 700, color: '#1A1B3A' }}>#incident-response</div>
        {data.mode === 'intro' && (
          <PersonIntro who={data.who} sub={data.sub} color="#2F7CFF"/>
        )}
        {(data.mode === 'posted' || data.mode === 'thread') && (
          <div style={{ border: '1px solid #E8E3D6', borderRadius: 8, padding: 12, background: '#fff' }}>
            <div style={{ display: 'flex', gap: 8, alignItems: 'center', marginBottom: 6 }}>
              <PortraitAvatar name="Alyssa Grant" color="#4242F0" size={22}/>
              <div style={{ fontSize: 11, fontWeight: 700 }}>Alyssa G.</div>
              <div style={{ fontSize: 10, color: '#8B8695' }}>· now · via Slack</div>
            </div>
            <div style={{ fontSize: 11, color: '#2B2C54', lineHeight: 1.5 }}>{data.text}</div>
          </div>
        )}
        {data.mode === 'thread' && data.replies && (
          <div style={{ paddingLeft: 10, borderLeft: '3px solid #EFEFFE', display: 'flex', flexDirection: 'column', gap: 10, marginTop: 2 }}>
            {data.replies.map((r, i) => (
              <CircleReply key={i} who={r.who} color={r.color} text={r.text} tag={r.via === 'email' ? 'VIA EMAIL' : 'IN-PLATFORM'} delay={i * 0.2}/>
            ))}
          </div>
        )}
        {data.tag && <LiveTag/>}
      </div>
    </div>
  );
}

function GmailScreen({ data }) {
  return (
    <div style={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', fontSize: 12, background: '#fff' }}>
      <div style={{ padding: '9px 12px', borderBottom: '1px solid #E7E8EB', display: 'flex', alignItems: 'center', gap: 9, background: '#F8FAFD' }}>
        <span style={{ fontSize: 16, color: '#5F6368', lineHeight: 1 }}>☰</span>
        <PlatformIcon kind="email" size={24}/>
        <span style={{ fontWeight: 700, fontSize: 13 }}>Inbox</span>
        <div style={{ marginLeft: 'auto', width: '36%', height: 24, borderRadius: 12, background: '#EEF2F7', color: '#7A808A', display: 'flex', alignItems: 'center', padding: '0 9px', fontSize: 9 }}>Search mail</div>
        <PortraitAvatar name="David Ortiz" color="#315EFB" size={24}/>
      </div>
      <div style={{ padding: 10, flex: 1, display: 'flex', flexDirection: 'column', gap: 6, overflow: 'hidden' }}>
        {data.mode === 'intro' && (
          <PersonIntro who={data.who} sub={data.sub} color="#315EFB"/>
        )}
        {(data.mode === 'posted' || data.mode === 'thread') && (
          <div style={{
            padding: '10px 12px', border: '1px solid #B8C7FF', borderRadius: 3, background: '#F7F9FF',
            display: 'flex', gap: 10, alignItems: 'center',
          }}>
            <span style={{ color: '#A8ADB7', fontSize: 13 }}>☆</span>
            <PortraitAvatar name="Alyssa Grant" color="#4242F0" size={24}/>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 11, fontWeight: 700, color: '#1A1B3A' }}>Alyssa G. via Leadership Exchange</div>
              <div style={{ fontSize: 11, color: '#2B2C54', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                {data.text}
              </div>
            </div>
            <span style={{ fontSize: 10, color: '#8B8695', flexShrink: 0 }}>now</span>
          </div>
        )}
        {/* faux inbox filler */}
        {['Weekly digest: 14 new posts','Event: Leadership roundtable','Introductions to review (3)'].map((s, i) => (
          <div key={s} style={{ padding: '7px 10px', display: 'flex', gap: 10, alignItems: 'center', opacity: 0.55 }}>
            <span style={{ color: '#A8ADB7', fontSize: 13 }}>☆</span>
            <PortraitAvatar name={['Mei Lin','Nora Bennett','David Ortiz'][i]} color="#7A75E8" size={20}/>
            <span style={{ fontSize: 11, fontWeight: 700, width: 96, flexShrink: 0 }}>Leadership Exchange</span>
            <span style={{ fontSize: 11, color: '#5F6368', flex: 1, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{s}</span>
            <span style={{ fontSize: 10, color: '#8B8695' }}>{i+1}h</span>
          </div>
        ))}
        {data.mode === 'thread' && data.replying && (
          <div style={{ marginTop: 8, padding: 10, background: '#F8F7F2', borderRadius: 6, border: '1px solid #E8E3D6', display: 'flex', gap: 8, alignItems: 'flex-start' }}>
            <PortraitAvatar name="David Ortiz" color="#315EFB" size={24}/>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 10, color: '#8B8695', marginBottom: 4 }}>David O. replying to Alyssa G.</div>
              <div style={{ fontSize: 11, color: '#2B2C54', lineHeight: 1.5 }}>
                {data.replying.text}<span style={{ display: 'inline-block', width: 2, height: 12, background: '#315EFB', marginLeft: 2, verticalAlign: 'middle', animation: 'hiw-blink 1s infinite' }}/>
              </div>
              <div style={{ marginTop: 8, display: 'flex', alignItems: 'center', gap: 8 }}>
                <div style={{ fontSize: 10, fontWeight: 700, padding: '4px 10px', background: '#1A73E8', color: '#fff', borderRadius: 3 }}>Send</div>
                <span style={{ fontSize: 9, color: '#8B8695' }}>↻ Auto-syncs to Slack + community</span>
              </div>
            </div>
          </div>
        )}
        {data.tag && <LiveTag/>}
      </div>
    </div>
  );
}

function TabletScreen({ data }) {
  return (
    <div style={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', fontSize: 11, background: '#FAF8F3' }}>
      <div style={{ padding: '8px 12px', borderBottom: '1px solid #EEE', display: 'flex', alignItems: 'center', gap: 6, background: '#fff' }}>
        <div style={{ width: 16, height: 12, background: '#D93025', borderRadius: 2 }}/>
        <span style={{ fontWeight: 700, fontSize: 10 }}>Mail</span>
        <span style={{ marginLeft: 'auto', fontSize: 8, color: '#8B8695' }}>noor@founder.io</span>
      </div>
      <div style={{ padding: 10, flex: 1, display: 'flex', flexDirection: 'column', gap: 6, overflow: 'hidden' }}>
        {data.mode === 'intro' && (
          <PersonIntro who={data.who} sub={data.sub} color="#21C089"/>
        )}
        {(data.mode === 'posted' || data.mode === 'thread' || data.mode === 'reacting') && (
          <>
            <div style={{
              padding: 8, border: '1px solid #E8E3D6', borderRadius: 6, background: '#fff',
              display: 'flex', flexDirection: 'column', gap: 4,
            }}>
              <div style={{ fontSize: 8, color: '#8B8695', display: 'flex', gap: 6 }}>
                <span style={{ fontWeight: 700, color: '#1A1B3A' }}>Alyssa G.</span>
                <span>· Leadership Exchange · now</span>
              </div>
              <div style={{ fontSize: 10, color: '#2B2C54' }}>
                {data.text || 'How do you structure communications during a vendor outage?'}
              </div>
            </div>
            {data.mode === 'reacting' && (
              <div style={{ display: 'flex', gap: 6, alignItems: 'center', marginLeft: 8, animation: 'hiw-in .4s .2s both' }}>
                <span style={{ fontSize: 10 }}>You reacted:</span>
                <span style={{ fontSize: 14, padding: '2px 8px', background: '#EFEFFE', borderRadius: 999, border: '1px solid #4242F055' }}>🙏</span>
                <span style={{ fontSize: 14, padding: '2px 8px', background: '#FDF5E1', borderRadius: 999, border: '1px solid #F5B82055' }}>⭐</span>
              </div>
            )}
            {data.mode === 'thread' && (
              <div style={{ display: 'flex', flexDirection: 'column', gap: 4, paddingLeft: 12, borderLeft: '2px solid #EFEFFE' }}>
                <div style={{ fontSize: 9, color: '#2B2C54' }}>
                  <b>Nora:</b> We always name the next update time, even when the ETA is unknown.
                </div>
                <div style={{ fontSize: 8, color: '#8B8695' }}>+ 2 reactions · syncs back everywhere</div>
              </div>
            )}
          </>
        )}
        {data.tag && <LiveTag/>}
      </div>
    </div>
  );
}

// ---------- Screen sub-components ----------

function PersonIntro({ who, sub, color }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 6, flex: 1, padding: 10, textAlign: 'center' }}>
      {window.PortraitAvatar
        ? <window.PortraitAvatar name={who} color={color} size={48}/>
        : <div style={{ width: 48, height: 48, borderRadius: '50%', background: color, color: '#fff', fontWeight: 700, fontSize: 18, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>{(who||'?')[0]}</div>}
      <div style={{ fontSize: 11, fontWeight: 700, color: '#1A1B3A' }}>{who}</div>
      <div style={{ fontSize: 9, color: '#8B8695', maxWidth: 140 }}>{sub}</div>
    </div>
  );
}

function SlackPost({ text, composing }) {
  if (composing) {
    return (
      <div style={{ marginTop: 'auto', border: '2px solid #4242F0', borderRadius: 8, padding: '10px 12px', background: '#F4F4FF' }}>
        <div style={{ fontSize: 12, color: '#2B2C54', lineHeight: 1.5 }}>
          {text}<span style={{ display: 'inline-block', width: 2, height: 14, background: '#4242F0', marginLeft: 2, verticalAlign: 'middle', animation: 'hiw-blink 1s infinite' }}/>
        </div>
        <div style={{ marginTop: 6, fontSize: 10, fontWeight: 700, color: '#4242F0' }}>⏎ Enter to send</div>
      </div>
    );
  }
  return (
    <div style={{ display: 'flex', gap: 10, alignItems: 'flex-start' }}>
      <PortraitAvatar name="Alyssa Grant" color="#4242F0" size={32} radius={5}/>
      <div style={{ minWidth: 0, flex: 1 }}>
        <div style={{ fontSize: 12, fontWeight: 700 }}>Alyssa G. <span style={{ fontWeight: 400, color: '#8B8695', marginLeft: 4, fontSize: 10 }}>9:12 AM</span></div>
        <div style={{ fontSize: 12, color: '#2B2C54', lineHeight: 1.5, marginTop: 2 }}>{text}</div>
      </div>
    </div>
  );
}

function SlackReply({ r, delay }) {
  return (
    <div style={{ display: 'flex', gap: 8, alignItems: 'flex-start', marginLeft: 8, animation: `hiw-in .4s ${delay}s both` }}>
      <PortraitAvatar name={r.who} color={r.color} size={26} radius={5}/>
      <div style={{ minWidth: 0, flex: 1 }}>
        <div style={{ fontSize: 11, fontWeight: 700, display: 'flex', alignItems: 'center', gap: 6 }}>
          {r.who}
          <span style={{ fontSize: 8.5, fontWeight: 700, padding: '2px 5px', background: r.via === 'email' ? '#315EFB' : '#2F7CFF', color: '#fff', borderRadius: 3, letterSpacing: '.05em' }}>
            {r.via === 'email' ? 'VIA EMAIL' : 'VIA COMMUNITY'}
          </span>
        </div>
        <div style={{ fontSize: 11, color: '#2B2C54', lineHeight: 1.5, marginTop: 1 }}>{r.text}</div>
        {r.reacts && <div style={{ display: 'flex', gap: 4, marginTop: 4 }}>{r.reacts.map((x, i) => (
          <span key={i} style={{ fontSize: 10, padding: '2px 6px', background: '#EFEFFE', borderRadius: 10, border: '1px solid #4242F022' }}>{x} 1</span>
        ))}</div>}
      </div>
    </div>
  );
}

function CircleReply({ who, color, text, tag }) {
  return (
    <div style={{ display: 'flex', gap: 4, alignItems: 'flex-start' }}>
      <PortraitAvatar name={who} color={color} size={16}/>
      <div style={{ minWidth: 0, flex: 1 }}>
        <div style={{ fontSize: 8, fontWeight: 700, display: 'flex', alignItems: 'center', gap: 4 }}>
          {who}
          {tag && <span style={{ fontSize: 6.5, fontWeight: 700, padding: '1px 3px', background: color + '22', color: color, borderRadius: 2, letterSpacing: '.04em' }}>{tag}</span>}
        </div>
        <div style={{ fontSize: 9, color: '#2B2C54', lineHeight: 1.4 }}>{text}</div>
      </div>
    </div>
  );
}

function LiveTag() {
  return (
    <div style={{
      position: 'absolute', top: 6, right: 6,
      fontSize: 8, fontWeight: 700, padding: '2px 6px',
      background: '#21C089', color: '#fff', borderRadius: 3,
      display: 'flex', alignItems: 'center', gap: 3,
      animation: 'hiw-in .4s both',
    }}>
      <span style={{ width: 4, height: 4, borderRadius: '50%', background: '#fff', animation: 'hiw-pulse 1.4s infinite' }}/>
      LIVE
    </div>
  );
}

// ---------- Connectors (SVG paths from sync core to each platform panel) ----------
// Measures real positions of [data-platform] elements inside the stage and
// draws curved paths from the core to each platform, with flowing dots when
// active.
function Connectors({ scene, sceneIdx }) {
  const [paths, setPaths] = useStC([]);
  const [size, setSize] = useStC({ w: 0, h: 0 });

  useEffC(() => {
    const recalc = () => {
      const stage = document.querySelector('.hiw-stage');
      if (!stage) return;
      const r0 = stage.getBoundingClientRect();
      const core = stage.querySelector('[data-platform="core"]');
      if (!core) return;
      const cr = core.getBoundingClientRect();
      const cx = cr.left + cr.width / 2 - r0.left;
      const cy = cr.top + cr.height / 2 - r0.top;
      const coreRadius = Math.min(cr.width, cr.height) / 2 * 0.6;

      const targets = ['slack', 'circle', 'gmail'];
      const next = [];
      targets.forEach(id => {
        const el = stage.querySelector(`[data-platform="${id}"]`);
        if (!el) return;
        const er = el.getBoundingClientRect();
        const tx = er.left + er.width / 2 - r0.left;
        const ty = er.top - r0.top + 16; // just below the panel's top edge
        // start anchor: a point on the core edge in direction of target
        const dx = tx - cx, dy = ty - cy;
        const dist = Math.hypot(dx, dy) || 1;
        const sx = cx + (dx / dist) * coreRadius;
        const sy = cy + (dy / dist) * coreRadius;
        // control point: midpoint pulled outward for a gentle curve
        const mx = (sx + tx) / 2;
        const my = (sy + ty) / 2;
        // perpendicular offset for curve
        const nx = -dy / dist, ny = dx / dist;
        const bow = id === 'circle' ? 0 : (id === 'slack' ? -40 : 40);
        const qx = mx + nx * bow;
        const qy = my + ny * bow;
        const d = `M ${sx} ${sy} Q ${qx} ${qy} ${tx} ${ty}`;
        next.push({ id, d, color: id === 'slack' ? '#611F69' : id === 'circle' ? '#2F7CFF' : '#315EFB' });
      });
      setPaths(next);
      setSize({ w: r0.width, h: r0.height });
    };
    recalc();
    window.addEventListener('resize', recalc);
    const t = setInterval(recalc, 500); // catch late layouts
    setTimeout(() => clearInterval(t), 3000);
    return () => { window.removeEventListener('resize', recalc); clearInterval(t); };
  }, [sceneIdx]);

  // direction of flow per scene
  const flowDir = scene.core.direction; // 'in' | 'out' | 'through' | undefined
  const activeMap = {
    slack:  ['composing','posted','thread'].includes(scene.slack?.mode),
    circle: ['posted','thread'].includes(scene.circle?.mode),
    gmail:  ['posted','thread'].includes(scene.gmail?.mode),
  };

  return (
    <svg style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', pointerEvents: 'none', zIndex: 1 }}
         viewBox={`0 0 ${size.w || 1000} ${size.h || 600}`}
         preserveAspectRatio="xMidYMid meet">
      <defs>
        {paths.map(p => (
          <linearGradient key={p.id} id={`conn-${p.id}`} gradientUnits="userSpaceOnUse">
            <stop offset="0%" stopColor={p.color} stopOpacity="0.15"/>
            <stop offset="100%" stopColor={p.color} stopOpacity="0.65"/>
          </linearGradient>
        ))}
      </defs>
      {paths.map(p => {
        const active = activeMap[p.id];
        return (
          <g key={p.id}>
            <path d={p.d}
              fill="none"
              stroke={active ? p.color : '#CDC7B6'}
              strokeWidth={active ? 2 : 1.25}
              strokeOpacity={active ? 0.55 : 0.4}
              strokeDasharray={active ? '0' : '5 7'}
              style={{ transition: 'stroke .35s, stroke-width .35s, stroke-opacity .35s' }}/>
            {active && [0, 1, 2].map(i => (
              <circle key={i} r="4.5" fill={p.color} opacity="0.9">
                <animateMotion
                  dur="2s"
                  begin={`${i * 0.6}s`}
                  repeatCount="indefinite"
                  path={p.d}
                  keyPoints={flowDir === 'in' ? '1;0' : flowDir === 'through' ? '0;1;0' : '0;1'}
                  keyTimes={flowDir === 'through' ? '0;0.5;1' : '0;1'}
                />
                <animate attributeName="opacity" values="0;1;1;0" keyTimes="0;0.1;0.85;1" dur="2s" begin={`${i * 0.6}s`} repeatCount="indefinite"/>
              </circle>
            ))}
          </g>
        );
      })}
    </svg>
  );
}

// ---------- Main cinematic ----------
function HIWCinematic() {
  const [sceneIdx, setSceneIdx] = useStC(0);
  const wrapRef = useRefC(null);

  // Scroll-driven: the wrapper is sceneCount * 100vh tall. The sticky stage
  // fills the viewport; we compute current scene from how far we've scrolled
  // through the wrapper.
  useEffC(() => {
    const onScroll = () => {
      if (!wrapRef.current) return;
      const rect = wrapRef.current.getBoundingClientRect();
      const total = rect.height - window.innerHeight;
      if (total <= 0) return;
      const scrolled = Math.min(Math.max(-rect.top, 0), total);
      const p = scrolled / total; // 0..1 through the whole sequence
      const idx = Math.min(SCENES.length - 1, Math.max(0, Math.floor(p * SCENES.length)));
      setSceneIdx(idx);
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  const [isMobile, setIsMobile] = useStC(typeof window !== 'undefined' && window.innerWidth <= 760);
  useEffC(() => {
    const on = () => setIsMobile(window.innerWidth <= 760);
    window.addEventListener('resize', on);
    return () => window.removeEventListener('resize', on);
  }, []);

  const scene = SCENES[sceneIdx] || SCENES[0];

  // Which single panel to feature on mobile per scene
  const MOBILE_PANEL = ['slack', 'slack', 'slack', 'gmail', 'circle', 'slack'];
  const primaryId = MOBILE_PANEL[sceneIdx] || 'slack';
  const panelProps = {
    slack:  { id: 'slack',  platform: 'Slack', sub: 'Where busy members already chat', brandColor: '#611F69', screen: <SlackScreen data={scene.slack}/> },
    circle: { id: 'circle', platform: 'Community platform', sub: 'Your web-based home for members', brandColor: '#2F7CFF', screen: <CircleScreen data={scene.circle}/> },
    gmail:  { id: 'gmail',  platform: 'Email', sub: 'For the email-first crowd', brandColor: '#315EFB', screen: <GmailScreen data={scene.gmail}/> },
  };

  return (
    <div ref={wrapRef} style={{ position: 'relative', height: `${SCENES.length * 100}vh` }}>
      {/* Sticky stage */}
      <div style={{
        position: 'sticky', top: 0, height: '100vh', width: '100%',
        background: 'linear-gradient(180deg, #FAF8F3 0%, #F4F1E9 100%)',
        overflow: 'hidden',
      }}>
        {!isMobile && <Connectors scene={scene} sceneIdx={sceneIdx}/>}

        {/* Platform layout with three big panels side by side and the sync core above. */}
        {!isMobile ? (
        <div className="hiw-stage" style={{ position: 'absolute', inset: 0 }}>
          {/* Central sync core in the upper portion. */}
          <div data-platform="core" style={{
            position: 'absolute', left: '50%', top: '22%',
            transform: 'translate(-50%, -50%)',
            width: 240, height: 240, zIndex: 3,
          }}>
            <SyncCore state={scene.core.state} direction={scene.core.direction}/>
          </div>

          {/* Three platform panels in a row beneath the core. */}
          <div style={{
            position: 'absolute', left: '4%', right: '4%', bottom: '10%',
            display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: '2.5%',
            zIndex: 2,
          }}>
            <PlatformPanel
              id="slack"
              platform="Slack"
              sub="Where busy members already chat"
              brandColor="#611F69"
              active={sceneIdx === 1 || sceneIdx === 2 || sceneIdx >= 4}
            >
              <SlackScreen data={scene.slack}/>
            </PlatformPanel>
            <PlatformPanel
              id="circle"
              platform="Community platform"
              sub="Your web-based home for members"
              brandColor="#2F7CFF"
              active={sceneIdx === 3 || sceneIdx >= 4}
            >
              <CircleScreen data={scene.circle}/>
            </PlatformPanel>
            <PlatformPanel
              id="gmail"
              platform="Email"
              sub="For the email-first crowd"
              brandColor="#315EFB"
              active={sceneIdx === 3 || sceneIdx >= 4}
            >
              <GmailScreen data={scene.gmail}/>
            </PlatformPanel>
          </div>
        </div>
        ) : (
        /* Mobile layout with core, platform chips, and one featured panel. */
        <div className="hiw-stage" style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', alignItems: 'center', padding: '82px 12px 12px' }}>
          <div data-platform="core" style={{ width: 84, height: 84, flexShrink: 0 }}>
            <SyncCore state={scene.core.state} direction={scene.core.direction}/>
          </div>
          {/* platform chips */}
          <div style={{ display: 'flex', gap: 5, marginTop: 2, marginBottom: 9 }}>
            {['slack','circle','gmail'].map(pid => {
              const pp = panelProps[pid];
              const on = pid === primaryId;
              return (
                <span key={pid} style={{
                  fontSize: 10, fontWeight: 700, padding: '4px 9px', borderRadius: 999,
                  background: on ? pp.brandColor : '#fff',
                  color: on ? '#fff' : 'var(--site-ink-soft)',
                  border: '1px solid ' + (on ? pp.brandColor : 'var(--site-line)'),
                  transition: 'all .3s',
                }}>{pid === 'gmail' ? 'Email' : pid === 'circle' ? 'Community' : 'Slack'}</span>
              );
            })}
          </div>
          {/* featured panel */}
          <div key={primaryId + sceneIdx} style={{ width: '100%', maxWidth: 420, flex: '1 1 0', minHeight: 240, maxHeight: 380, animation: 'hiw-in .4s both' }}>
            <PlatformPanel {...panelProps[primaryId]} active compact>
              {panelProps[primaryId].screen}
            </PlatformPanel>
          </div>
          <div key={'mobile-caption-' + sceneIdx} style={{ width: '100%', maxWidth: 420, marginTop: 9, flexShrink: 0, textAlign: 'center', animation: 'hiw-mobile-caption .45s cubic-bezier(.2,.8,.2,1) both' }}>
            <div style={{ padding: '11px 14px 12px', background: 'rgba(255,255,255,0.94)', border: '1px solid var(--site-line)', borderRadius: 14, boxShadow: '0 10px 28px rgba(26,27,58,0.07)' }}>
              <div style={{ fontSize: 9, fontWeight: 700, letterSpacing: '.1em', color: 'var(--brand)', textTransform: 'uppercase', marginBottom: 5 }}>{scene.caption.eyebrow}</div>
              <div style={{ fontFamily: 'var(--font-display)', fontSize: 17, lineHeight: 1.15, color: 'var(--site-ink)', marginBottom: 5, letterSpacing: '-0.01em' }}>{scene.caption.title}</div>
              <div style={{ fontSize: 11, color: 'var(--site-ink-soft)', lineHeight: 1.4 }}>{scene.caption.body}</div>
            </div>
          </div>
        </div>
        )}

        {/* Caption overlay at the bottom center. */}
        {!isMobile && <div key={sceneIdx} style={{
          position: 'absolute',
          left: '50%', bottom: '6%',
          transform: 'translateX(-50%)',
          width: isMobile ? 'calc(100% - 32px)' : 'min(640px, 80%)',
          textAlign: 'center',
          animation: 'hiw-caption .5s cubic-bezier(.2,.8,.2,1) both',
          zIndex: 10,
          pointerEvents: 'none',
        }}>
          <div style={{
            display: 'inline-block',
            padding: isMobile ? '14px 18px' : '24px 32px',
            background: 'rgba(255,255,255,0.9)',
            backdropFilter: 'blur(12px)',
            WebkitBackdropFilter: 'blur(12px)',
            border: '1px solid var(--site-line)',
            borderRadius: 18,
            boxShadow: '0 18px 40px rgba(26,27,58,0.08)',
          }}>
            <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: '.1em', color: 'var(--brand)', textTransform: 'uppercase', marginBottom: 8 }}>
              {scene.caption.eyebrow}
            </div>
            <div style={{ fontFamily: 'var(--font-display)', fontSize: isMobile ? 20 : 26, lineHeight: 1.15, color: 'var(--site-ink)', marginBottom: 8, letterSpacing: '-0.01em' }}>
              {scene.caption.title}
            </div>
            <div style={{ fontSize: isMobile ? 12.5 : 14, color: 'var(--site-ink-soft)', lineHeight: 1.5, display: isMobile ? '-webkit-box' : 'block', WebkitLineClamp: isMobile ? 3 : 'none', WebkitBoxOrient: 'vertical', overflow: isMobile ? 'hidden' : 'visible' }}>
              {scene.caption.body}
            </div>
          </div>
        </div>}

        {/* Scene dots (progress) */}
        <div style={{
          position: 'absolute', top: isMobile ? 14 : '50%', right: isMobile ? 'auto' : 24, left: isMobile ? '50%' : 'auto', transform: isMobile ? 'translateX(-50%)' : 'translateY(-50%)',
          display: 'flex', flexDirection: isMobile ? 'row' : 'column', gap: isMobile ? 6 : 10, zIndex: 10,
        }}>
          {SCENES.map((_, i) => (
            <div key={i} style={{
              width: isMobile ? (i === sceneIdx ? 22 : 6) : 6, height: isMobile ? 6 : (i === sceneIdx ? 22 : 6),
              borderRadius: 3,
              background: i === sceneIdx ? 'var(--brand)' : '#D8D3C4',
              transition: 'all .4s',
            }}/>
          ))}
        </div>

        {/* Scroll cue on first scene */}
        {sceneIdx === 0 && !isMobile && (
          <div style={{
            position: 'absolute', top: 24, left: '50%', transform: 'translateX(-50%)',
            fontSize: 11, fontWeight: 700, letterSpacing: '.1em', color: 'var(--site-ink-soft)',
            textTransform: 'uppercase', display: 'flex', alignItems: 'center', gap: 8, zIndex: 10,
          }}>
            <span>Scroll to watch</span>
            <span style={{ display: 'inline-block', animation: 'hiw-bounce 1.4s infinite' }}>↓</span>
          </div>
        )}
      </div>

      {/* Scene trigger stack is no longer needed; wrapper height does the work */}

      <style>{`
        @keyframes hiw-caption {
          from { opacity: 0; transform: translate(-50%, 12px); }
          to   { opacity: 1; transform: translate(-50%, 0); }
        }
        @keyframes hiw-mobile-caption {
          from { opacity: 0; transform: translateY(8px); }
          to   { opacity: 1; transform: translateY(0); }
        }
        @keyframes hiw-breathe {
          0%,100% { transform: scale(1); }
          50%     { transform: scale(1.03); }
        }
        @keyframes hiw-halo {
          0%   { opacity: 0.3; transform: scale(0.8); }
          80%  { opacity: 0;   transform: scale(1.15); }
          100% { opacity: 0;   transform: scale(1.2); }
        }
        @keyframes hiw-dot {
          0%,100% { transform: scale(1); opacity: 1; }
          50%     { transform: scale(1.3); opacity: 0.7; }
        }
        @keyframes hiw-type {
          0%, 60%, 100% { transform: translateY(1.1px) scale(0.82); opacity: 0.55; }
          30%           { transform: translateY(-1.1px) scale(1); opacity: 1; }
        }
        @keyframes hiw-in {
          from { opacity: 0; transform: translateY(6px); }
          to   { opacity: 1; transform: none; }
        }
        @keyframes hiw-pulse {
          0%,100% { opacity: 1; transform: scale(1); }
          50%     { opacity: 0.5; transform: scale(1.2); }
        }
        @keyframes hiw-blink {
          0%,100% { opacity: 1; }
          50%     { opacity: 0; }
        }
        @keyframes hiw-bounce {
          0%,100% { transform: translateY(0); }
          50%     { transform: translateY(4px); }
        }
      `}</style>
    </div>
  );
}

Object.assign(window, { HIWCinematic });
