// welcome.jsx — Fire Lingo Face-to-Face welcome screen
// iPad landscape, 1194x834

const LANGUAGES = [
{ code: 'es', flag: 'mx', native: 'Español', english: 'Spanish', greeting: 'Bienvenido/a', prompt: 'Toca tu idioma', listening: 'Toca el botón, mantenlo presionado y habla', script: 'latin' },
{ code: 'zh', flag: 'cn', native: '中文', english: 'Chinese', greeting: '欢迎', prompt: '请选择您的语言', listening: '按住按钮，开始说话', script: 'cjk' },
{ code: 'vi', flag: 'vn', native: 'Tiếng Việt', english: 'Vietnamese', greeting: 'Chào mừng', prompt: 'Chọn ngôn ngữ của bạn', listening: 'Nhấn giữ nút và bắt đầu nói', script: 'latin' },
{ code: 'ko', flag: 'kr', native: '한국어', english: 'Korean', greeting: '환영합니다', prompt: '언어를 선택하세요', listening: '버튼을 길게 눌러 말씀하세요', script: 'cjk' },
{ code: 'ht', flag: 'ht', native: 'Kreyòl ayisyen', english: 'Haitian Creole', greeting: 'Byenveni', prompt: 'Chwazi lang ou', listening: 'Peze bouton an, kenbe l, epi pale', script: 'latin' },
{ code: 'ar', flag: 'sa', native: 'العربية', english: 'Arabic', greeting: 'أهلاً وسهلاً', prompt: 'اختر لغتك', listening: 'اضغط الزر مع الاستمرار وتحدث', script: 'rtl' },
{ code: 'fr', flag: 'fr', native: 'Français', english: 'French', greeting: 'Bienvenue', prompt: 'Choisissez votre langue', listening: 'Appuyez et maintenez le bouton pour parler', script: 'latin' },
{ code: 'pt', flag: 'br', native: 'Português', english: 'Portuguese', greeting: 'Bem-vindo/a', prompt: 'Escolha o seu idioma', listening: 'Toque e segure o botão, depois fale', script: 'latin' },
{ code: 'ru', flag: 'ru', native: 'Русский', english: 'Russian', greeting: 'Добро пожаловать', prompt: 'Выберите ваш язык', listening: 'Нажмите и удерживайте кнопку, затем говорите', script: 'latin' },
{ code: 'hi', flag: 'in', native: 'हिन्दी', english: 'Hindi', greeting: 'स्वागत है', prompt: 'अपनी भाषा चुनें', listening: 'बटन दबाकर रखें और बोलें', script: 'devanagari' },
{ code: 'tl', flag: 'ph', native: 'Filipino', english: 'Tagalog', greeting: 'Maligayang pagdating', prompt: 'Piliin ang iyong wika', listening: 'Pindutin at hawakan ang pindutan, tapos magsalita', script: 'latin' },
{ code: 'sw', flag: 'ke', native: 'Kiswahili', english: 'Swahili', greeting: 'Karibu', prompt: 'Chagua lugha yako', listening: 'Bonyeza na ushikilie kitufe, kisha sema', script: 'latin' }];


// A rotating greeting ticker — shows native greetings cycling
function GreetingTicker({ languages, paused }) {
  const [idx, setIdx] = React.useState(0);
  React.useEffect(() => {
    if (paused) return;
    const t = setInterval(() => setIdx((i) => (i + 1) % languages.length), 1800);
    return () => clearInterval(t);
  }, [paused, languages.length]);
  const current = languages[idx];
  return (
    <div style={{
      height: 56, width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'flex-start',
      position: 'relative', overflow: 'hidden'
    }}>
      {languages.map((l, i) =>
      <div key={l.code} style={{
        position: 'absolute', inset: 0,
        display: 'flex', alignItems: 'center', justifyContent: 'flex-start', gap: 18,
        opacity: i === idx ? 1 : 0,
        transform: i === idx ? 'translateY(0)' : i === (idx - 1 + languages.length) % languages.length ? 'translateY(-16px)' : 'translateY(16px)',
        transition: 'opacity 500ms var(--ease-out), transform 500ms var(--ease-out)',
        fontFamily: 'var(--font-display)', fontSize: 40, fontWeight: 800,
        color: '#fff', letterSpacing: '-0.01em',
        direction: l.script === 'rtl' ? 'rtl' : 'ltr'
      }}>
          <span style={{
          fontSize: 13, fontWeight: 600, textTransform: 'uppercase',
          letterSpacing: '0.14em', color: 'rgba(255,255,255,0.55)',
          fontFamily: 'var(--font-sans)'
        }}>Welcome</span>
          <span style={{
          fontFamily: l.script === 'cjk' ? '"Noto Sans SC", "Noto Sans KR", system-ui' :
          l.script === 'devanagari' ? '"Noto Sans Devanagari", var(--font-display)' :
          l.script === 'rtl' ? '"Noto Naskh Arabic", var(--font-display)' :
          'var(--font-display)'
        }}>{l.greeting}</span>
        </div>
      )}
    </div>);

}

// The brand mark, reused. Accepts a breathing-pulse state for listening.
function BrandMark({ size = 84, pulse = false, tone = 'light' }) {
  const src = tone === 'light' ? 'assets/traduality-icon.png' : 'assets/traduality-icon-white.png';
  return (
    <div style={{
      width: size, height: size, position: 'relative', display: 'inline-block'
    }}>
      {pulse &&
      <>
          <div className="fl-pulse fl-pulse-1" />
          <div className="fl-pulse fl-pulse-2" />
        </>
      }
      <img src={src} alt="Traduality" style={{
        width: '100%', height: '100%', position: 'relative', zIndex: 2,
        filter: pulse ? 'drop-shadow(0 4px 18px rgba(70,137,200,0.45))' : 'drop-shadow(0 2px 10px rgba(15,56,92,0.18))'
      }} />
    </div>);

}

// Language card
function LanguageCard({ lang, selected, onSelect, variant, broadcast }) {
  const rtl = lang.script === 'rtl';
  const [hover, setHover] = React.useState(false);

  // Font sizing per script: CJK and Devanagari render smaller at the same px
  const scriptFs =
  lang.script === 'cjk' ? 28 :
  lang.script === 'devanagari' ? 26 :
  lang.script === 'rtl' ? 30 :
  lang.native.length > 13 ? 21 :
  lang.native.length > 9 ? 24 : 28;

  // In broadcast mode the card swaps its accent to orange (the announcement tone),
  // so it's clear a tap publishes rather than starts a customer flow.
  const accent = broadcast ? 'var(--td-orange)' : 'var(--td-blue)';
  const accentTintBg = broadcast ? '#FFF3EB' : 'var(--td-blue-50)';
  const accentRing = broadcast ? 'rgba(207,99,40,0.18)' : 'rgba(70,137,200,0.15)';

  return (
    <button
      onClick={() => onSelect(lang)}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      className="fl-card"
      style={{
        position: 'relative',
        background: selected ? accentTintBg : (broadcast && hover ? accentTintBg : '#fff'),
        border: `1.5px solid ${selected ? accent : hover ? (broadcast ? accent : 'var(--border-strong)') : 'var(--border)'}`,
        borderRadius: 'var(--radius-lg)',
        padding: '18px 20px',
        display: 'flex', flexDirection: 'column', alignItems: 'flex-start',
        gap: 4, cursor: 'pointer',
        textAlign: rtl ? 'right' : 'left',
        direction: rtl ? 'rtl' : 'ltr',
        boxShadow: selected ? `var(--shadow-md), 0 0 0 3px ${accentRing}` :
        hover ? 'var(--shadow-sm)' : 'var(--shadow-xs)',
        transform: selected ? 'translateY(-1px)' : 'translateY(0)',
        transition: 'all 180ms var(--ease-out)',
        fontFamily: 'var(--font-display)',
        outline: 'none',
        minHeight: 112
      }}>
      
      {/* Flag — flat SVG per design system (never emoji flags) */}
      <div style={{
        position: 'absolute', top: 16, [rtl ? 'left' : 'right']: 16
      }}>
        <Flag code={lang.flag} size={32} />
      </div>

      {/* Native name — the star of the card */}
      <div style={{
        fontSize: scriptFs,
        fontWeight: 800, color: 'var(--td-navy)', lineHeight: 1.1,
        letterSpacing: lang.script === 'cjk' ? 0 : '-0.015em',
        paddingRight: rtl ? 0 : 54,
        paddingLeft: rtl ? 54 : 0,
        whiteSpace: 'nowrap',
        fontFamily: lang.script === 'cjk' ? '"Noto Sans SC", "Noto Sans KR", system-ui, sans-serif' :
        lang.script === 'devanagari' ? '"Noto Sans Devanagari", var(--font-display)' :
        lang.script === 'rtl' ? '"Noto Naskh Arabic", var(--font-display)' :
        'var(--font-display)'
      }}>
        {lang.native}
      </div>

      {/* English subtitle — between brackets, lower weight */}
      <div style={{
        fontSize: 15, fontWeight: 500, color: 'var(--fg3)',
        fontFamily: 'var(--font-sans)', letterSpacing: 0,
        direction: 'ltr', textAlign: rtl ? 'right' : 'left'
      }}>
        ({lang.english})
      </div>

      {/* Selected indicator */}
      {selected &&
      <div style={{
        position: 'absolute', bottom: 14, [rtl ? 'left' : 'right']: 14,
        width: 24, height: 24, borderRadius: 999,
        background: accent, color: '#fff',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        fontSize: 14, fontWeight: 700
      }}>✓</div>
      }
    </button>);

}

// ────────────────────────────────────────────────────────────
// WELCOME SCREEN
// ────────────────────────────────────────────────────────────
function WelcomeScreen({ onSelect, tweaks, brand }) {
  const [selectedCode, setSelectedCode] = React.useState(null);
  // Announcement overlay state — staff broadcasts a translated phrase without
  // entering the conversation flow.
  // mode: null | 'pickLang' | 'recording' | 'translating' | 'playing'
  const [announceMode, setAnnounceMode] = React.useState(null);
  const [announceLang, setAnnounceLang] = React.useState(null);

  const startAnnouncement = () => setAnnounceMode('pickLang');
  const cancelAnnouncement = () => { setAnnounceMode(null); setAnnounceLang(null); };
  const pickAnnouncementLang = (lang) => { setAnnounceLang(lang); setAnnounceMode('recording'); };

  const handleSelect = (lang) => {
    // While in announcement mode, taps target the broadcast — not the customer flow
    if (announceMode === 'pickLang') {
      pickAnnouncementLang(lang);
      return;
    }
    if (selectedCode || announceMode) return;
    setSelectedCode(lang.code);
    setTimeout(() => onSelect(lang), 550);
  };

  const heroTone = tweaks.heroTone; // 'navy' | 'light'
  const columns = tweaks.columns; // 3 or 4
  const showHero = tweaks.showHero;

  return (
    <div style={{
      width: '100%', height: '100%', display: 'flex', flexDirection: 'column',
      background: heroTone === 'navy' ?
      'linear-gradient(180deg, #ffffff 0%, #ffffff 52%, var(--td-slate-50) 100%)' :
      'var(--td-slate-50)',
      position: 'relative', overflow: 'hidden'
    }}>
      {/* Hero band */}
      {showHero &&
      <div style={{
        position: 'relative',
        background: heroTone === 'navy' ?
        'linear-gradient(15deg, var(--td-navy) 0%, var(--td-blue-600) 60%, var(--td-blue) 100%)' :
        '#fff',
        borderBottom: heroTone === 'navy' ? 'none' : '1px solid var(--border)',
        padding: '28px 48px 36px',
        color: heroTone === 'navy' ? '#fff' : 'var(--td-navy)',
        flexShrink: 0
      }}>
          {/* subtle grid of dots behind */}
          {heroTone === 'navy' &&
        <div style={{
          position: 'absolute', inset: 0, opacity: 0.08,
          backgroundImage: 'radial-gradient(circle, #fff 1px, transparent 1px)',
          backgroundSize: '28px 28px',
          maskImage: 'linear-gradient(180deg, #000 0%, transparent 100%)',
          WebkitMaskImage: 'linear-gradient(180deg, #000 0%, transparent 100%)'
        }} />
        }

          <div style={{
          display: 'flex', alignItems: 'center', gap: 24,
          position: 'relative', zIndex: 1
        }}>
            {/* Logo lockup — Traduality (default) renders mark + wordmark.
                White-labeled customers render their logo only. */}
            {brand && brand.useDefaultMark === false ? (
              <div style={{ display: 'flex', flexDirection: 'column', gap: 10, maxWidth: 460 }}>
                <img src={brand.logoWhite} alt={brand.name} style={{
                  height: 64, width: 'auto', objectFit: 'contain',
                  filter: heroTone === 'navy' ? 'none' : 'invert(1)',
                  display: 'block',
                }} />
                {brand.tagline && (
                  <div style={{
                    fontFamily: 'var(--font-sans)', fontSize: 11, fontWeight: 600,
                    textTransform: 'uppercase', letterSpacing: '0.14em',
                    color: heroTone === 'navy' ? 'rgba(255,255,255,0.75)' : 'var(--td-blue)',
                  }}>{brand.tagline}</div>
                )}
              </div>
            ) : (
              <>
                <BrandMark size={72} tone={heroTone === 'navy' ? 'dark' : 'light'} />
                <div>
                  <div style={{
                    fontFamily: 'var(--font-display)', fontSize: 44, fontWeight: 900,
                    color: heroTone === 'navy' ? '#fff' : 'var(--td-navy)',
                    letterSpacing: '-0.02em', lineHeight: 1
                  }}>{brand ? brand.name : 'Traduality'}</div>
                  {(!brand || brand.tagline) && (
                    <div style={{
                      fontFamily: 'var(--font-sans)', fontSize: 11, fontWeight: 600,
                      textTransform: 'uppercase', letterSpacing: '0.14em',
                      color: heroTone === 'navy' ? 'rgba(255,255,255,0.75)' : 'var(--td-blue)',
                      marginTop: 6
                    }}>{(brand && brand.tagline) || 'Get closer to your people'}</div>
                  )}
                </div>
              </>
            )}

            {/* Powered by / Fire Lingo badge */}
            <div style={{ marginLeft: 'auto', display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 8 }}>
              <div style={{
              fontFamily: 'var(--font-sans)', fontSize: 10, fontWeight: 600,
              textTransform: 'uppercase', letterSpacing: '0.18em',
              color: heroTone === 'navy' ? 'rgba(255,255,255,0.55)' : 'var(--fg3)'
            }}>Fire Lingo · Face-to-Face</div>
              {brand && brand.showPoweredBy && (
                <div style={{
                  fontFamily: 'var(--font-sans)', fontSize: 10, fontWeight: 500,
                  letterSpacing: '0.04em',
                  color: heroTone === 'navy' ? 'rgba(255,255,255,0.55)' : 'var(--fg3)',
                  marginTop: -4,
                }}>{brand.partnerType === 'credit-union' ? 'Powered by Traduality CUSO' : 'Powered by Traduality'}</div>
              )}
              <div style={{
              display: 'flex', alignItems: 'center', gap: 8,
              background: heroTone === 'navy' ? 'rgba(255,255,255,0.1)' : 'var(--td-blue-50)',
              border: `1px solid ${heroTone === 'navy' ? 'rgba(255,255,255,0.16)' : 'var(--border)'}`,
              padding: '6px 12px', borderRadius: 'var(--radius-pill)',
              fontSize: 12, fontWeight: 600,
              color: heroTone === 'navy' ? '#fff' : 'var(--td-navy)',
              fontFamily: 'var(--font-sans)'
            }}>
                <span style={{
                width: 8, height: 8, borderRadius: 999, background: '#5fd089',
                boxShadow: '0 0 0 3px rgba(95,208,137,0.2)'
              }} />
                Ready to translate
              </div>
            </div>
          </div>

          {/* Greeting ticker + prompt */}
          <div style={{
          marginTop: 20, display: 'flex', alignItems: 'center', gap: 32,
          position: 'relative', zIndex: 1
        }}>
            {heroTone === 'navy' ?
          <GreetingTicker languages={LANGUAGES} paused={!!selectedCode} /> :

          <div style={{
            fontFamily: 'var(--font-display)', fontSize: 40, fontWeight: 800,
            color: 'var(--td-navy)', letterSpacing: '-0.015em'
          }}>
                Welcome. <span style={{ color: 'var(--td-blue)' }}>Please choose your language.</span>
              </div>
          }
          </div>
        </div>
      }

      {/* Instructions row — transforms into announcement bar in announce mode */}
      {!announceMode ? (
        <div style={{
          padding: '20px 48px 8px',
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          flexShrink: 0
        }}>
          <div>
            <div className="eyebrow" style={{
              fontSize: 11, fontWeight: 700, textTransform: 'uppercase',
              letterSpacing: '0.14em', color: 'var(--td-blue)',
              fontFamily: 'var(--font-sans)'
            }}>
              Select your language · Seleccione su idioma · 选择语言
            </div>
            <div style={{
              marginTop: 6, fontFamily: 'var(--font-display)',
              fontSize: 22, fontWeight: 700, color: 'var(--td-navy)',
              letterSpacing: '-0.01em'
            }}>
              Tap the language you speak most comfortably.
            </div>
          </div>

          {/* Make announcement — staff broadcasts a translated phrase, in place */}
          <button
            onClick={startAnnouncement}
            style={{
              display: 'flex', alignItems: 'center', gap: 10,
              padding: '10px 16px',
              background: 'linear-gradient(180deg, var(--td-blue) 0%, var(--td-blue-600) 100%)',
              color: '#fff',
              border: 'none', borderRadius: 'var(--radius-pill)',
              boxShadow: '0 6px 16px rgba(37,100,152,0.32)',
              fontFamily: 'var(--font-sans)', fontSize: 13, fontWeight: 700,
              letterSpacing: '0.02em',
              cursor: 'pointer',
              WebkitTapHighlightColor: 'transparent',
            }}>
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round">
              <path d="M3 11v3a4 4 0 0 0 4 4h.5"/>
              <path d="M7 18l-1 4 4-2"/>
              <path d="M3 11l18-7v16L3 14"/>
            </svg>
            Make announcement
          </button>
        </div>
      ) : (
        <AnnouncementBar
          mode={announceMode}
          setMode={setAnnounceMode}
          lang={announceLang}
          onCancel={cancelAnnouncement}
        />
      )}

      {/* Language grid — dimmed slightly while a broadcast is being recorded/played */}
      <div style={{
        flex: 1, padding: '12px 48px 32px',
        overflow: 'hidden',
        opacity: (announceMode && announceMode !== 'pickLang') ? 0.45 : 1,
        transition: 'opacity 220ms var(--ease-out)',
        pointerEvents: (announceMode && announceMode !== 'pickLang') ? 'none' : 'auto',
      }}>
        <div style={{
          display: 'grid',
          gridTemplateColumns: `repeat(${columns}, 1fr)`,
          gap: 14,
          height: '100%'
        }}>
          {LANGUAGES.map((l) =>
          <LanguageCard
            key={l.code} lang={l}
            selected={selectedCode === l.code}
            onSelect={handleSelect}
            broadcast={announceMode === 'pickLang'}
            variant={tweaks.cardVariant} />

          )}
        </div>
      </div>

      {/* Footer — employee controls */}
      <div style={{
        padding: '14px 48px', borderTop: '1px solid var(--border)',
        background: '#fff',
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        flexShrink: 0, fontFamily: 'var(--font-sans)', fontSize: 13
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 18, color: 'var(--fg3)' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round">
              <rect x="3" y="4" width="18" height="16" rx="2" />
              <path d="M7 2v4M17 2v4M3 10h18" />
            </svg>
            Sat, April 18 · 2:45 PM
          </div>
          <div style={{ width: 1, height: 14, background: 'var(--border)' }} />
          <div>Branch: <strong style={{ color: 'var(--fg2)' }}>{(brand && brand.branchName) || 'Eastpoint'} </strong></div>
          <div style={{ width: 1, height: 14, background: 'var(--border)' }} />
          <div>Tablet ID <span className="mono" style={{
              fontFamily: 'var(--font-mono)', fontSize: 12,
              background: 'var(--td-slate-100)', padding: '2px 6px', borderRadius: 4
            }}>#TRAD-IP02</span></div>
        </div>

        <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
          <button className="fl-ghost-btn">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round">
              <path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/>
              <path d="M12 9v4M12 17h.01"/>
            </svg>
            Report an issue with this device
          </button>
        </div>
      </div>

      {/* ambient selection flash */}
      {selectedCode &&
      <div style={{
        position: 'absolute', inset: 0, pointerEvents: 'none',
        background: 'radial-gradient(circle at center, rgba(70,137,200,0.15) 0%, transparent 60%)',
        animation: 'fl-flash 550ms var(--ease-out) forwards',
        zIndex: 5
      }} />
      }
    </div>);

}

// ────────────────────────────────────────────────────────────
// ANNOUNCEMENT OVERLAY
// Employee taps "Make announcement", picks a target language,
// holds the mic to speak in English, then releases — the system
// translates and (mock-)plays the audio in the chosen language.
// ────────────────────────────────────────────────────────────

const ANNOUNCE_PHRASE = {
  // English source (employee speaks)
  source: 'Hi there — I can help you over here at this window.',
  // Mock translations per language
  translated: {
    es: 'Hola, puedo atenderle aquí en esta ventanilla.',
    zh: '您好,我可以在这个窗口为您服务。',
    vi: 'Xin chào, tôi có thể phục vụ quý vị ở quầy này.',
    ko: '안녕하세요, 이쪽 창구에서 도와드릴 수 있습니다.',
    ht: 'Bonjou — mwen ka ede w bò isit la nan fenèt sa a.',
    ar: 'مرحباً — يمكنني مساعدتك هنا عند هذا الشباك.',
    fr: 'Bonjour — je peux vous aider ici à ce guichet.',
    pt: 'Olá — posso atendê-lo aqui neste guichê.',
    ru: 'Здравствуйте — я могу помочь вам здесь, у этого окошка.',
    hi: 'नमस्ते — मैं आपकी इस खिड़की पर सहायता कर सकता हूँ।',
    tl: 'Kumusta — matutulungan ko po kayo dito sa bintanang ito.',
    sw: 'Habari — naweza kukusaidia hapa kwenye dirisha hili.',
  },
};

function AnnouncementBar({ mode, setMode, lang, onCancel }) {
  // ──────────────────────────────────────────────
  // Inline announcement strip — replaces the instruction row.
  // pickLang ➜ recording ➜ translating ➜ playing ➜ auto-close
  // ──────────────────────────────────────────────

  // Audio level for the mic-button glow
  const [level, setLevel] = React.useState(0);
  const [duration, setDuration] = React.useState(0);

  // Drive the level meter while recording
  React.useEffect(() => {
    if (mode !== 'recording') { setLevel(0); setDuration(0); return; }
    const start = performance.now();
    let raf, last = start;
    const tick = (now) => {
      const dt = now - last; last = now;
      setDuration((now - start) / 1000);
      setLevel(l => {
        const target = 0.55 + 0.35 * Math.sin(now / 230) + (Math.random() - 0.5) * 0.4;
        return Math.max(0.18, Math.min(1, l + (target - l) * (dt / 90)));
      });
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [mode]);

  // Auto-advance translating ➜ playing ➜ done
  React.useEffect(() => {
    if (mode === 'translating') {
      const t = setTimeout(() => setMode('playing'), 1200);
      return () => clearTimeout(t);
    }
    if (mode === 'playing') {
      const t = setTimeout(() => onCancel(), 4500);
      return () => clearTimeout(t);
    }
  }, [mode]);

  const recording = mode === 'recording';
  const translating = mode === 'translating';
  const playing = mode === 'playing';
  const pickLang = mode === 'pickLang';

  const translated = lang ? ANNOUNCE_PHRASE.translated[lang.code] : '';
  const nativeFont = !lang ? 'var(--font-display)' :
    lang.script === 'cjk' ? '"Noto Sans SC", "Noto Sans KR", system-ui' :
    lang.script === 'devanagari' ? '"Noto Sans Devanagari", var(--font-display)' :
    lang.script === 'rtl' ? '"Noto Naskh Arabic", var(--font-display)' :
    'var(--font-display)';

  // Mic press handlers — only fire while in recording
  const endRecord = (e) => { if (e) e.preventDefault(); if (recording) setMode('translating'); };

  return (
    <div style={{
      margin: '16px 36px 8px',
      padding: '14px 20px 14px 18px',
      background: pickLang
        ? 'linear-gradient(180deg, #FFF6EE 0%, #FFEFE0 100%)'
        : 'linear-gradient(180deg, var(--td-navy) 0%, var(--td-blue-600) 100%)',
      border: pickLang ? '1.5px solid #F0C4A0' : '1px solid rgba(255,255,255,0.08)',
      borderRadius: 'var(--radius-lg)',
      boxShadow: pickLang
        ? '0 6px 16px rgba(207,99,40,0.10)'
        : '0 12px 28px rgba(11,42,70,0.18)',
      display: 'flex', alignItems: 'center', gap: 18,
      flexShrink: 0, position: 'relative', overflow: 'hidden',
      animation: 'fl-fade-in 220ms var(--ease-out) both',
      minHeight: pickLang ? 64 : 88,
    }}>
      {/* Megaphone badge */}
      <div style={{
        width: 44, height: 44, borderRadius: 12, flexShrink: 0,
        background: pickLang ? 'rgba(207,99,40,0.14)' : 'rgba(255,255,255,0.10)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        color: pickLang ? 'var(--td-orange)' : '#fff',
      }}>
        <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round">
          <path d="M3 11v3a4 4 0 0 0 4 4h.5"/>
          <path d="M7 18l-1 4 4-2"/>
          <path d="M3 11l18-7v16L3 14"/>
        </svg>
      </div>

      {/* Center stack — varies by mode */}
      <div style={{ flex: 1, minWidth: 0 }}>
        {pickLang && (
          <>
            <div style={{
              fontFamily: 'var(--font-sans)', fontSize: 11, fontWeight: 700,
              textTransform: 'uppercase', letterSpacing: '0.14em',
              color: 'var(--td-orange)',
            }}>Make announcement</div>
            <div style={{
              marginTop: 4, fontFamily: 'var(--font-display)',
              fontSize: 20, fontWeight: 700, color: 'var(--td-navy)',
              letterSpacing: '-0.01em', lineHeight: 1.15,
            }}>Tap a language card to broadcast in.</div>
          </>
        )}

        {recording && (
          <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
            {/* lang chip */}
            <div style={{
              display: 'flex', alignItems: 'center', gap: 8,
              padding: '4px 10px 4px 6px',
              background: 'rgba(255,255,255,0.10)',
              border: '1px solid rgba(255,255,255,0.18)',
              borderRadius: 'var(--radius-pill)',
              flexShrink: 0,
            }}>
              <Flag code={lang?.flag} size={18} />
              <div style={{
                fontFamily: 'var(--font-sans)', fontSize: 11, fontWeight: 700,
                color: '#fff', letterSpacing: '0.06em', textTransform: 'uppercase',
              }}>{lang?.english}</div>
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{
                fontFamily: 'var(--font-display)', fontSize: 17, fontWeight: 700,
                color: '#FFD4B7', letterSpacing: '-0.005em', lineHeight: 1.1,
              }}>Listening · {duration.toFixed(1)}s</div>
              <div style={{
                marginTop: 3, fontFamily: 'var(--font-sans)', fontSize: 12,
                color: 'rgba(255,255,255,0.62)',
              }}>Hold the mic and speak. Release to translate.</div>
              {/* live waveform */}
              <div style={{
                marginTop: 6, display: 'flex', gap: 3, alignItems: 'center', height: 16,
              }}>
                {Array.from({ length: 28 }).map((_, i) => {
                  const phase = (i + duration * 8) % 28;
                  const h = 4 + 12 * Math.abs(Math.sin(phase * 0.45)) * level;
                  return (
                    <div key={i} style={{
                      width: 3, height: h, borderRadius: 2,
                      background: 'var(--td-orange)', opacity: 0.85,
                      transition: 'height 80ms linear',
                    }} />
                  );
                })}
              </div>
            </div>
          </div>
        )}

        {translating && (
          <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
            <div style={{
              display: 'flex', alignItems: 'center', gap: 8,
              padding: '4px 10px 4px 6px',
              background: 'rgba(255,255,255,0.10)',
              border: '1px solid rgba(255,255,255,0.18)',
              borderRadius: 'var(--radius-pill)',
              flexShrink: 0,
            }}>
              <Flag code={lang?.flag} size={18} />
              <div style={{
                fontFamily: 'var(--font-sans)', fontSize: 11, fontWeight: 700,
                color: '#fff', letterSpacing: '0.06em', textTransform: 'uppercase',
              }}>{lang?.english}</div>
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{
                fontFamily: 'var(--font-display)', fontSize: 17, fontWeight: 700,
                color: '#fff', lineHeight: 1.1,
              }}>Translating into {lang?.english}…</div>
              <div style={{
                marginTop: 3, fontFamily: 'var(--font-sans)', fontSize: 12,
                color: 'rgba(255,255,255,0.55)', fontStyle: 'italic',
                whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
              }}>"{ANNOUNCE_PHRASE.source}"</div>
            </div>
          </div>
        )}

        {playing && (
          <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
            <div style={{
              display: 'flex', alignItems: 'center', gap: 8,
              padding: '4px 10px 4px 6px',
              background: 'rgba(120,168,214,0.18)',
              border: '1px solid rgba(120,168,214,0.40)',
              borderRadius: 'var(--radius-pill)',
              flexShrink: 0,
            }}>
              <Flag code={lang?.flag} size={18} />
              <div style={{
                fontFamily: 'var(--font-sans)', fontSize: 11, fontWeight: 700,
                color: '#fff', letterSpacing: '0.06em', textTransform: 'uppercase',
              }}>Playing · {lang?.english}</div>
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{
                fontFamily: nativeFont, fontSize: 18, fontWeight: 700,
                color: '#fff', lineHeight: 1.25,
                direction: lang?.script === 'rtl' ? 'rtl' : 'ltr',
                whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
              }}>{translated}</div>
              <div style={{
                marginTop: 3, fontFamily: 'var(--font-sans)', fontSize: 12,
                color: 'rgba(255,255,255,0.55)', fontStyle: 'italic',
                whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
              }}>"{ANNOUNCE_PHRASE.source}"</div>
            </div>
          </div>
        )}
      </div>

      {/* Mic / playing button on the right (hidden in pickLang) */}
      {!pickLang && (
        <div style={{ position: 'relative', width: 60, height: 60, flexShrink: 0 }}>
          {recording && (
            <div style={{
              position: 'absolute', inset: -8, borderRadius: 9999,
              background: 'radial-gradient(circle, rgba(207,99,40,0.45) 35%, rgba(207,99,40,0) 65%)',
              transform: `scale(${1 + level * 0.18})`,
              transition: 'transform 120ms var(--ease-out)',
              pointerEvents: 'none',
            }} />
          )}
          {playing && (
            <div style={{
              position: 'absolute', inset: -6, borderRadius: 9999,
              border: '2px solid rgba(120,168,214,0.55)',
              animation: 'fl-breathe 1.6s var(--ease-in-out) infinite',
              pointerEvents: 'none',
            }} />
          )}
          <button
            onPointerUp={endRecord}
            onPointerLeave={endRecord}
            onPointerCancel={endRecord}
            disabled={!recording}
            aria-label={recording ? 'Release to translate' : translating ? 'Translating' : 'Playing'}
            style={{
              position: 'absolute', inset: 0, borderRadius: 9999,
              border: 'none',
              cursor: recording ? 'pointer' : 'default',
              background: recording
                ? 'radial-gradient(circle at 32% 28%, #e27a3f 0%, var(--td-orange) 60%, #a64d1e 100%)'
                : playing
                ? 'radial-gradient(circle at 32% 28%, #6a9d70 0%, #4d7d52 60%, #335538 100%)'
                : 'radial-gradient(circle at 32% 28%, var(--td-blue-300) 0%, var(--td-blue) 55%, var(--td-blue-600) 100%)',
              color: '#fff',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              boxShadow: recording
                ? '0 8px 18px rgba(207,99,40,0.45), inset 0 -3px 8px rgba(0,0,0,0.18)'
                : '0 6px 14px rgba(37,100,152,0.32), inset 0 -3px 8px rgba(0,0,0,0.18)',
              transition: 'background 200ms var(--ease-out), box-shadow 200ms var(--ease-out)',
              WebkitTapHighlightColor: 'transparent', touchAction: 'none', outline: 'none',
            }}>
            {playing ? (
              <svg width="22" height="22" viewBox="0 0 24 24" fill="#fff" stroke="none">
                <path d="M9 7v10a1 1 0 0 0 1.5.85l8-5a1 1 0 0 0 0-1.7l-8-5A1 1 0 0 0 9 7z"/>
              </svg>
            ) : translating ? (
              <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"
                style={{ animation: 'fl-spin 1.4s linear infinite' }}>
                <path d="M21 12a9 9 0 1 1-6.22-8.56"/>
              </svg>
            ) : (
              <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
                <rect x="9" y="2" width="6" height="12" rx="3" fill="rgba(255,255,255,0.22)"/>
                <path d="M5 11a7 7 0 0 0 14 0"/>
                <path d="M12 18v3M9 21h6"/>
              </svg>
            )}
          </button>
        </div>
      )}

      {/* Cancel — always present */}
      <button
        onClick={onCancel}
        style={{
          padding: '8px 14px',
          background: pickLang ? '#fff' : 'rgba(255,255,255,0.10)',
          color: pickLang ? 'var(--td-navy)' : '#fff',
          border: `1px solid ${pickLang ? '#E8C9A8' : 'rgba(255,255,255,0.20)'}`,
          borderRadius: 'var(--radius-pill)',
          fontFamily: 'var(--font-sans)', fontSize: 11, fontWeight: 700,
          letterSpacing: '0.08em', textTransform: 'uppercase',
          cursor: 'pointer', flexShrink: 0,
          WebkitTapHighlightColor: 'transparent',
        }}>
        Cancel ✕
      </button>
    </div>
  );
}


Object.assign(window, { WelcomeScreen, BrandMark, LANGUAGES });