/* Klipzy.lv — Academy: vertical story-style lessons (TikTok/Reels ratio).
   Each category is a "story" that plays its short clips one after another,
   auto-advancing and sliding to the next category — like an IG story series. */
const ACADEMY_STORIES = [
  {
    cat: 'Kas ir klipošana?', catEn: 'What is clipping?', icon: 'play', grad: ['#0EA5E9', '#38BDF8'],
    clips: [
      { t: ['Kas ir klipošana?', 'What is clipping?'], b: ['', ''], thumb: ['assets/academy/thumbs/what-lv.png', 'assets/academy/thumbs/what-en.png'], video: ['https://firebasestorage.googleapis.com/v0/b/klipzy-225a7.firebasestorage.app/o/academy%2FV1%20-%20Kas%20Ir%20Klipos%CC%8Cana%20LV.mp4?alt=media&token=51c09456-8a5e-45b6-af0b-c5b5f7f1ac9b', 'https://firebasestorage.googleapis.com/v0/b/klipzy-225a7.firebasestorage.app/o/academy%2FV1%20-%20What%20Is%20Clipping%20ENG.mp4?alt=media&token=94962e26-a562-4770-9284-b79b553ec4c1'] },
    ],
  },
  {
    cat: 'Kādi rīki ir vajadzīgi?', catEn: 'What tools you need?', icon: 'star', grad: ['#0F766E', '#10B981'],
    clips: [
      { t: ['Kādi rīki ir vajadzīgi?', 'What tools you need?'], b: ['', ''], thumb: ['assets/academy/thumbs/tools-lv.png', 'assets/academy/thumbs/tools-en.png'], video: ['https://firebasestorage.googleapis.com/v0/b/klipzy-225a7.firebasestorage.app/o/academy%2FV2%20-%20Ka%CC%84di%20Ri%CC%84ki%20Ir%20Vajadzi%CC%84gi%20LV.mp4?alt=media&token=be724351-fbd8-4f51-93d0-1bfa91667611', 'https://firebasestorage.googleapis.com/v0/b/klipzy-225a7.firebasestorage.app/o/academy%2FV2%20-%20What%20Tools%20You%20Need%20ENG.mp4?alt=media&token=4ba15aa6-41a3-436f-a30a-941a0e2f5aca'] },
    ],
  },
  {
    cat: 'Kā izveidot labu klipu?', catEn: 'How to make a good clip?', icon: 'film', grad: ['#7C3AED', '#A855F7'],
    clips: [
      { t: ['Kā izveidot labu klipu?', 'How to make a good clip?'], b: ['', ''], thumb: ['assets/academy/thumbs/howto-lv.png', 'assets/academy/thumbs/howto-en.png'], video: ['https://firebasestorage.googleapis.com/v0/b/klipzy-225a7.firebasestorage.app/o/academy%2FV3%20-%20Ka%CC%84%20Izveidot%20Labu%20Klipu%20LV.mp4?alt=media&token=433f07eb-3b1a-43d8-9209-e1e3d1d3e1f7', 'https://firebasestorage.googleapis.com/v0/b/klipzy-225a7.firebasestorage.app/o/academy%2FV3%20-%20How%20To%20Make%20A%20Good%20Clip%20ENG.mp4?alt=media&token=7541fcb0-687d-4841-95e7-90cbd8fa8084'] },
    ],
  },
  {
    cat: 'Kļūdas, no kurām izvairīties', catEn: 'Mistakes to avoid', icon: 'alert', grad: ['#64748B', '#94A3B8'],
    clips: [
      { t: ['Kļūdas, no kurām izvairīties', 'Mistakes to avoid'], b: ['', ''], thumb: ['assets/academy/thumbs/mistakes-lv.png', 'assets/academy/thumbs/mistakes-en.png'], video: ['assets/academy/V4-mistakes-lv.mp4', 'assets/academy/V4-mistakes-en.mp4'] },
    ],
  },
  {
    cat: 'Viens klips, visas platformas', catEn: 'One clip, all platforms', icon: 'grid', grad: ['#DB2777', '#F472B6'],
    clips: [
      { t: ['Viens klips, visas platformas', 'One clip, all platforms'], b: ['', ''], thumb: ['assets/academy/thumbs/oneclip-lv.png', 'assets/academy/thumbs/oneclip-en.png'], video: ['https://firebasestorage.googleapis.com/v0/b/klipzy-225a7.firebasestorage.app/o/academy%2FV5%20-%20Viens%20Klips%2C%20Visas%20Platformas%20LV.mp4?alt=media&token=148f5efd-41c4-4e57-a585-9ee0aca9c3ad', 'https://firebasestorage.googleapis.com/v0/b/klipzy-225a7.firebasestorage.app/o/academy%2FV5%20-%20One%20Clip%2C%20Every%20Platform%20ENG.mp4?alt=media&token=9ebfce89-3daa-4b0c-a520-15070637e621'] },
    ],
  },
  {
    cat: 'Mākslīgais intelekts klipošanā', catEn: 'AI in clipping', icon: 'spark', grad: ['#2563EB', '#3B82F6'],
    clips: [
      { t: ['Mākslīgais intelekts (AI) klipošanā', 'Artificial intelligence (AI) in clipping'], b: ['', ''], thumb: ['assets/academy/thumbs/ai-lv.png', 'assets/academy/thumbs/ai-en.png'], video: ['https://firebasestorage.googleapis.com/v0/b/klipzy-225a7.firebasestorage.app/o/academy%2FV6%20-%20Ma%CC%84ksli%CC%84gais%20Intelekts%20Klipos%CC%8Cana%CC%84%20LV.mp4?alt=media&token=824edb0c-0c6e-4cca-818e-d6139f003abf', 'https://firebasestorage.googleapis.com/v0/b/klipzy-225a7.firebasestorage.app/o/academy%2FV6%20-%20Using%20AI%20When%20Clipping%20ENG.mp4?alt=media&token=7ceae277-c193-4b53-956b-e114b7c42ca5'] },
    ],
  },
  {
    cat: 'Subtitri klipošanā', catEn: 'Captions in clipping', icon: 'book', grad: ['#D97706', '#FBBF24'],
    clips: [
      { t: ['Subtitri klipošanā', 'Captions in clipping'], b: ['', ''], thumb: ['assets/academy/thumbs/subs-lv.png', 'assets/academy/thumbs/subs-en.png'], video: ['https://firebasestorage.googleapis.com/v0/b/klipzy-225a7.firebasestorage.app/o/academy%2FV7%20-%20Subtitri%20Klipos%CC%8Cana%CC%84%20LV.mp4?alt=media&token=db784964-6113-4f48-b091-3ca38265b1a7', 'https://firebasestorage.googleapis.com/v0/b/klipzy-225a7.firebasestorage.app/o/academy%2FV7%20-%20Subtitles%20For%20Clipping%20ENG.mp4?alt=media&token=92354774-9742-47bb-af95-a9e981907b67'] },
    ],
  },
];

function Academy({ go }) {
  const lang = useLang();
  const L = (lv, en) => (lang === 'en' ? en : lv);
  const K = window.KLIPZY;
  const [player, setPlayer] = useState(null); // starting category index, or null

  return (
    <div className="app-scroll fade-in" style={{ height: '100%' }}>
      <PublicNav go={go} route="academy" lang={lang} />

      {/* hero */}
      <section style={{ background: 'linear-gradient(180deg,#F4F8FF,#fff)', borderBottom: '1px solid var(--border)' }}>
        <div className="container" style={{ padding: '52px 28px 40px', textAlign: 'center' }}>
          <span className="eyebrow">{L('Klipzy Mācības', 'Klipzy Learning')}</span>
          <h1 style={{ fontSize: 44, letterSpacing: '-0.035em', marginTop: 12, lineHeight: 1.05 }}>{L('Iemācies klipot', 'Learn to clip')}</h1>
          <p style={{ fontSize: 17, color: 'var(--text-2)', marginTop: 14, maxWidth: 520, margin: '14px auto 0', lineHeight: 1.5 }}>{L('Izvēlies tēmu un skaties īsus video ar noderīgiem padomiem.', 'Choose a topic and watch short clips with useful tips.')}</p>
          {/* story bubbles */}
          <div className="academy-bubbles" style={{ display: 'flex', gap: 22, justifyContent: 'center', flexWrap: 'wrap', marginTop: 32 }}>
            {ACADEMY_STORIES.map((s, i) => {
              return (
              <button key={s.cat} onClick={() => setPlayer(i)} style={{ background: 'none', border: 'none', cursor: 'pointer', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 9, width: 92 }}>
                <span style={{ width: 72, height: 72, borderRadius: 999, padding: 3, background: `linear-gradient(135deg, ${s.grad[0]}, ${s.grad[1]})`, display: 'grid', placeItems: 'center' }}>
                  <span style={{ width: '100%', height: '100%', borderRadius: 999, background: '#fff', display: 'grid', placeItems: 'center' }}>
                    <span style={{ width: 58, height: 58, borderRadius: 999, background: `linear-gradient(135deg, ${s.grad[0]}, ${s.grad[1]})`, color: '#fff', display: 'grid', placeItems: 'center' }}><Icon d={I[s.icon]} size={26} sw={1.7} stroke="#fff" style={{ display: 'block' }} /></span>
                  </span>
                </span>
                <span style={{ fontSize: 12.5, fontWeight: 540, color: 'var(--text-2)', lineHeight: 1.2, textAlign: 'center' }}>{L(s.cat, s.catEn)}</span>
              </button>
              );
            })}
          </div>
        </div>
      </section>

      <div className="container" style={{ padding: '40px 28px 70px' }}>
        {/* vertical story cards (9:16) */}
        <h2 style={{ fontSize: 22, marginBottom: 20 }}>{L('Video sērijas', 'Video series')}</h2>
        <div className="academy-grid" style={{ display: 'grid', gridTemplateColumns: 'repeat(4,1fr)', gap: 18 }}>
          {ACADEMY_STORIES.map((s, i) => {
            const c0 = s.clips[0];
            const thumbImg = c0 && c0.thumb ? c0.thumb[lang === 'en' ? 1 : 0] : null;
            return (
            <button key={s.cat} onClick={() => setPlayer(i)} className="academy-card" style={{ padding: 0, border: 'none', background: 'none', cursor: 'pointer', textAlign: 'left' }}>
              <GradTile grad={s.grad} radius={16} style={{ aspectRatio: '9/16', position: 'relative', overflow: 'hidden', display: 'flex', flexDirection: 'column', justifyContent: 'space-between', padding: 16 }}>
                {thumbImg && <img src={thumbImg} alt="" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', zIndex: 0 }} />}
                {thumbImg && <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg, rgba(0,0,0,.05), rgba(0,0,0,.4))', zIndex: 0 }} />}
                <div className="spread" style={{ position: 'relative', zIndex: 1 }}>
                  <span style={{ width: 38, height: 38, borderRadius: 11, background: 'rgba(255,255,255,.2)', backdropFilter: 'blur(4px)', color: '#fff', display: 'grid', placeItems: 'center' }}><Icon d={I[s.icon]} size={19} stroke="#fff" /></span>
                  {s.soon ? <span style={{ background: 'rgba(0,0,0,.25)', color: '#fff', fontSize: 11, fontWeight: 600, borderRadius: 999, padding: '3px 9px' }}>{L('Drīzumā', 'Soon')}</span> : null}
                </div>
                <div style={{ position: 'relative', zIndex: 1 }}>
                  <div style={{ color: '#fff', fontSize: 17, fontWeight: 600, letterSpacing: '-0.01em', lineHeight: 1.2, textShadow: '0 1px 8px rgba(0,0,0,.35)' }}>{L(s.cat, s.catEn)}</div>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 6, color: 'rgba(255,255,255,.9)', fontSize: 12.5, marginTop: 8 }}><Icon d={I.play} size={13} fill="#fff" stroke="none" /> {L('Skatīties', 'Watch')}</div>
                </div>
              </GradTile>
            </button>
            );
          })}
        </div>

        {/* written guides */}
        <h2 style={{ fontSize: 22, margin: '46px 0 20px' }}>{L('Uzzini vairāk', 'Find out more')}</h2>
        <div className="r-grid3" style={{ display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: 20 }}>
          {K.articles.slice(0, 1).map((a) => <ArticleCard key={a.id} a={a} go={go} />)}
        </div>
      </div>

      {player !== null && <StoryPlayer stories={ACADEMY_STORIES} start={player} lang={lang} onClose={() => setPlayer(null)} />}
      <Footer go={go} lang={lang} />
    </div>
  );
}

/* Full-screen vertical story player. Auto-advances each clip, slides to the
   next category when a series ends, tap left/right to navigate, hold to pause. */
function StoryPlayer({ stories, start, lang, onClose }) {
  const L = (lv, en) => (lang === 'en' ? en : lv);
  const CLIP_MS = 6000;
  const [ci, setCi] = useState(start);     // category index
  const [ki, setKi] = useState(0);         // clip index
  const [prog, setProg] = useState(0);     // 0..100 for current clip
  const [paused, setPaused] = useState(false);
  const videoRef = useRef(null);
  const cat = stories[ci];
  const clip = cat.clips[ki];
  const videoSrc = clip.video ? (clip.video[lang === 'en' ? 1 : 0] || clip.video[0] || null) : null;

  const next = () => {
    if (ki < cat.clips.length - 1) { setKi(ki + 1); setProg(0); }
    else if (ci < stories.length - 1) { setCi(ci + 1); setKi(0); setProg(0); }
    else onClose();
  };
  const prev = () => {
    if (ki > 0) { setKi(ki - 1); setProg(0); }
    else if (ci > 0) { const p = ci - 1; setCi(p); setKi(stories[p].clips.length - 1); setProg(0); }
    else setProg(0);
  };

  // progress timer — driven by the video's own playback when a clip has one,
  // otherwise a fixed-duration timer (text-only story cards).
  useEffect(() => {
    if (videoSrc) return; // video's timeupdate handler drives progress instead
    if (paused) return;
    const step = 100 / (CLIP_MS / 50);
    const id = setInterval(() => {
      setProg((p) => {
        if (p + step >= 100) { clearInterval(id); next(); return 100; }
        return p + step;
      });
    }, 50);
    return () => clearInterval(id);
  }, [ci, ki, paused]);

  // keyboard nav
  useEffect(() => {
    const onKey = (e) => {
      if (e.key === 'Escape') onClose();
      else if (e.key === 'ArrowRight') next();
      else if (e.key === 'ArrowLeft') prev();
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [ci, ki]);

  // lock background scroll while the player is open (body + app scroll container)
  useEffect(() => {
    const prevBody = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    const scrollers = document.querySelectorAll('.app-scroll');
    const saved = [];
    scrollers.forEach((el) => { saved.push([el, el.style.overflow]); el.style.overflow = 'hidden'; });
    return () => {
      document.body.style.overflow = prevBody;
      saved.forEach(([el, v]) => { el.style.overflow = v; });
    };
  }, []);

  // pause/resume the actual <video> element to match the tap-hold pause state
  useEffect(() => {
    const v = videoRef.current;
    if (!v) return;
    if (paused) v.pause(); else v.play().catch(() => {});
  }, [paused, videoSrc]);

  const atStart = ci === 0 && ki === 0;
  const arrowStyle = (side) => ({ position: 'absolute', [side]: 'max(12px, calc(50vw - 300px))', top: '50%', transform: 'translateY(-50%)', width: 46, height: 46, borderRadius: 999, background: 'rgba(255,255,255,.16)', color: '#fff', border: '1px solid rgba(255,255,255,.28)', cursor: 'pointer', display: 'grid', placeItems: 'center', zIndex: 4 });

  // Portal to <body> so position:fixed always anchors to the viewport (an
  // ancestor with a transform — e.g. the page fade-in — would otherwise make
  // the overlay land at the top of the page instead of the current screen).
  return ReactDOM.createPortal((
    <div style={{ position: 'fixed', inset: 0, zIndex: 200, background: 'rgba(30,32,38,.92)', backdropFilter: 'blur(6px)', display: 'grid', placeItems: 'center', padding: 16 }} onClick={onClose}>
      <button onClick={onClose} style={{ position: 'absolute', top: 18, right: 20, width: 40, height: 40, borderRadius: 999, background: 'rgba(255,255,255,.14)', color: '#fff', border: 'none', cursor: 'pointer', display: 'grid', placeItems: 'center', zIndex: 3 }}><Icon d={I.x} size={20} /></button>

      {/* left / right nav arrows */}
      {!atStart && <button aria-label="previous" onClick={(e) => { e.stopPropagation(); prev(); }} style={arrowStyle('left')} className="story-arrow"><Icon d={I.chevronR} size={22} style={{ transform: 'rotate(180deg)' }} /></button>}
      <button aria-label="next" onClick={(e) => { e.stopPropagation(); next(); }} style={arrowStyle('right')} className="story-arrow"><Icon d={I.chevronR} size={22} /></button>
      <div className="story-frame" style={{ position: 'relative', width: 'min(420px, 92vw)', aspectRatio: '9/16', maxHeight: '92vh', borderRadius: 20, overflow: 'hidden', boxShadow: '0 30px 80px rgba(0,0,0,.5)' }} onClick={(e) => e.stopPropagation()}>
        <div key={ci + '-' + ki} className="story-clip fade-in" style={{ position: 'absolute', inset: 0, background: `linear-gradient(160deg, ${cat.grad[0]}, ${cat.grad[1]})`, display: 'flex', flexDirection: 'column' }}>
          {videoSrc && (
            <video ref={videoRef} key={videoSrc} src={videoSrc} autoPlay playsInline poster={clip.thumb ? clip.thumb[lang === 'en' ? 1 : 0] : undefined}
              style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', zIndex: 0 }}
              onTimeUpdate={(e) => { if (!paused && e.target.duration) setProg((e.target.currentTime / e.target.duration) * 100); }}
              onEnded={next} />
          )}
          {/* progress bars (current clip is draggable to seek) */}
          <div style={{ display: 'flex', gap: 5, padding: '12px 14px 0', position: 'relative', zIndex: 5 }}>
            {cat.clips.map((_, i) => {
              const seekTo = (clientX, el) => {
                const v = videoRef.current; if (!v || !v.duration) return;
                const r = el.getBoundingClientRect();
                const pct = Math.min(1, Math.max(0, (clientX - r.left) / r.width));
                let t = pct * v.duration;
                // Clamp to what's actually seekable (guards files without a range index).
                try { if (v.seekable && v.seekable.length) t = Math.min(t, v.seekable.end(v.seekable.length - 1) - 0.05); } catch (_) {}
                try { v.currentTime = t; } catch (_) {}
                setProg((t / v.duration) * 100);
              };
              const canSeek = i === ki && !!videoSrc;
              return (
                <div key={i}
                  onPointerDown={canSeek ? (e) => { e.stopPropagation(); setPaused(true); const el = e.currentTarget; el.setPointerCapture(e.pointerId); seekTo(e.clientX, el); } : undefined}
                  onPointerMove={canSeek ? (e) => { if (e.buttons) seekTo(e.clientX, e.currentTarget); } : undefined}
                  onPointerUp={canSeek ? (e) => { e.stopPropagation(); setPaused(false); } : undefined}
                  style={{ flex: 1, height: canSeek ? 10 : 3, display: 'flex', alignItems: 'center', cursor: canSeek ? 'pointer' : 'default', touchAction: 'none' }}>
                  <div style={{ width: '100%', height: 3, borderRadius: 3, background: 'rgba(255,255,255,.3)', overflow: 'hidden' }}>
                    <div style={{ height: '100%', width: (i < ki ? 100 : i === ki ? prog : 0) + '%', background: '#fff', transition: i === ki ? 'width .05s linear' : 'none' }} />
                  </div>
                </div>
              );
            })}
          </div>
          {/* header */}
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '14px 16px', position: 'relative', zIndex: 2 }}>
            <span style={{ width: 34, height: 34, borderRadius: 10, background: 'rgba(255,255,255,.2)', color: '#fff', display: 'grid', placeItems: 'center' }}><Icon d={I[cat.icon]} size={18} stroke="#fff" /></span>
            <div style={{ color: '#fff', fontSize: 13.5, fontWeight: 600 }}>{L(cat.cat, cat.catEn)}</div>
          </div>

          {/* watermark icon */}
          {!videoSrc && <div aria-hidden="true" style={{ position: 'absolute', right: -30, top: '30%', color: 'rgba(255,255,255,.10)' }}><Icon d={I[cat.icon]} size={220} stroke="#fff" /></div>}

          {/* content */}
          {!videoSrc && (
          <div style={{ flex: 1, display: 'flex', flexDirection: 'column', justifyContent: 'flex-end', padding: '0 26px 40px', position: 'relative', zIndex: 2 }}>
            <div style={{ color: 'rgba(255,255,255,.85)', fontSize: 13, fontWeight: 600, letterSpacing: '.06em', textTransform: 'uppercase', marginBottom: 12 }}>{ki + 1} / {cat.clips.length}</div>
            <h2 style={{ color: '#fff', fontSize: 30, lineHeight: 1.12, letterSpacing: '-0.02em', textShadow: '0 2px 14px rgba(0,0,0,.25)' }}>{L(clip.t[0], clip.t[1])}</h2>
            <p style={{ color: 'rgba(255,255,255,.92)', fontSize: 16, lineHeight: 1.55, marginTop: 14, textShadow: '0 1px 10px rgba(0,0,0,.2)' }}>{L(clip.b[0], clip.b[1])}</p>
          </div>
          )}

          {/* paused overlay — 50% dark gradient + blur */}
          {videoSrc && paused && (
            <div style={{ position: 'absolute', inset: 0, zIndex: 3, background: 'linear-gradient(180deg, rgba(0,0,0,.5), rgba(0,0,0,.5))', backdropFilter: 'blur(8px)', WebkitBackdropFilter: 'blur(8px)', display: 'grid', placeItems: 'center', pointerEvents: 'none' }}>
              <span style={{ width: 66, height: 66, borderRadius: 999, background: 'rgba(255,255,255,.16)', border: '2px solid rgba(255,255,255,.7)', display: 'grid', placeItems: 'center' }}>
                <Icon d="M8 5v14l11-7z" size={30} stroke="none" fill="#fff" />
              </span>
            </div>
          )}

          {/* tap zones */}
          {videoSrc ? (
            <button aria-label="pause" onClick={() => setPaused((p) => !p)} style={{ position: 'absolute', left: 0, right: 0, top: 60, bottom: 0, background: 'none', border: 'none', cursor: 'pointer', zIndex: 2 }} />
          ) : (
            <>
              <button aria-label="prev" onClick={prev} style={{ position: 'absolute', left: 0, top: 60, bottom: 0, width: '35%', background: 'none', border: 'none', cursor: 'pointer', zIndex: 1 }}
                onPointerDown={() => setPaused(true)} onPointerUp={() => setPaused(false)} onPointerLeave={() => setPaused(false)} />
              <button aria-label="next" onClick={next} style={{ position: 'absolute', right: 0, top: 60, bottom: 0, width: '65%', background: 'none', border: 'none', cursor: 'pointer', zIndex: 1 }}
                onPointerDown={() => setPaused(true)} onPointerUp={() => setPaused(false)} onPointerLeave={() => setPaused(false)} />
            </>
          )}
        </div>
      </div>
    </div>
  ), document.body);
}

function ArticleCard({ a, go }) {
  const lang = useLang();
  return (
    <div className="card" style={{ overflow: 'hidden', cursor: 'pointer', display: 'flex', flexDirection: 'column', transition: 'box-shadow .16s, transform .16s' }}
      onClick={() => go('article', { id: a.id })}
      onMouseEnter={(e) => { e.currentTarget.style.boxShadow = 'var(--sh-md)'; e.currentTarget.style.transform = 'translateY(-2px)'; }}
      onMouseLeave={(e) => { e.currentTarget.style.boxShadow = 'var(--sh-sm)'; e.currentTarget.style.transform = 'none'; }}>
      <GradTile grad={a.grad} radius={0} style={{ aspectRatio: '16/9' }} />
      <div style={{ padding: 18, flex: 1, display: 'flex', flexDirection: 'column' }}>
        <span className="pill pill-niche" style={{ alignSelf: 'flex-start' }}>{lang === 'en' ? (a.catEn || a.cat) : a.cat}</span>
        <h3 style={{ fontSize: 16.5, marginTop: 11, lineHeight: 1.25 }}>{lang === 'en' ? (a.titleEn || a.title) : a.title}</h3>
        <p className="muted" style={{ fontSize: 13.5, marginTop: 8, lineHeight: 1.5, flex: 1 }}>{lang === 'en' ? (a.excerptEn || a.excerpt) : a.excerpt}</p>
        <div className="muted" style={{ fontSize: 12.5, marginTop: 14, display: 'flex', alignItems: 'center', gap: 6 }}><Icon d={I.clock} size={13} /> {a.read} {lang === 'en' ? 'read' : 'lasīšana'}</div>
      </div>
    </div>
  );
}

/* Role switcher inside the "How Klipzy works" article — distinct step-by-step
   guidance for clippers vs brands, with a stepped visual layout. */
function ArticleRoleGuide({ lang, go }) {
  const [role, setRole] = React.useState('clipper');
  const en = lang === 'en';
  const CLIPPER = [
    { t: en ? 'Create your clipper account' : 'Izveido klipotāja kontu',
      d: en ? 'Start registration by clicking *Register* and choose Clipper role. Confirm the code sent to your email. Then verify your TikTok and Instagram accounts in *Settings*. Without verification, you can only submit YouTube clips.'
            : 'Sāc reģistrāciju spiežot uz *Reģistrēties* un izvēlies Klipotājs. Apstiprini kodu, kas nosūtīts uz e-pastu. Iestatījumos verificē savus TikTok un Instagram kontus — bez tā vari iesniegt tikai YouTube klipus.' },
    { t: en ? 'Find a campaign' : 'Atrodi kampaņu',
      d: en ? 'Open *Campaigns* and find one that fits your content. Check the price per 1,000 views, remaining budget, supported platforms and campaign guidelines. When you\u2019re ready, click *Join a campaign* or *Submit a clip*.'
            : 'Atver *Kampaņas*, filtrē pēc nišas un platformas un atver kādu. Apskati cenu par 1 000 skatījumiem, atlikušo budžetu, atļautās platformas un vadlīnijas. Nospied *Pievienoties kampaņai*.' },
    { t: en ? 'Create and post your clip' : 'Izveido un publicē klipu',
      d: en ? 'Create a short clip that follows the brand\u2019s guidelines and post it publicly on TikTok, Instagram or YouTube.'
            : 'Izveido īsu klipu, kas atbilst zīmola vadlīnijām, un publicē to TikTok, Instagram vai YouTube.' },
    { t: en ? 'Submit your clip within 60 minutes' : 'Iesniedz saiti 60 minūšu laikā',
      d: en ? 'Go to *Submit a clip* in your dashboard, choose the campaign and paste your link. Make sure to submit it within 60 minutes of publishing or it won\u2019t be accepted.'
            : 'Panelī atver *Iesniegt klipu*, izvēlies kampaņu un ielīmē saiti. Tā jāiesniedz 60 minūšu laikā pēc publicēšanas, citādi netiks pieņemta.' },
    { t: en ? 'Get paid per 1,000 views' : 'Saņem samaksu par katriem 1 000 skatījumiem',
      d: en ? 'Once the brand approves your clip, we’ll track the views automatically. You earn for every full 1,000 views. Follow your progress under *My clips* and cash out from *Earnings* once you reach the minimum payout amount.'
            : 'Kad zīmols apstiprina klipu, skatījumi tiek izsekoti automātiski. Tu pelni par katriem pilniem 1 000 skatījumiem. Seko līdzi sadaļā *Mani klipi* un izmaksā no *Ieņēmumi*, kad sasniedz minimumu.' },
  ];
  const BRAND = [
    { t: en ? 'Create your brand account' : 'Izveido zīmola kontu',
      d: en ? 'Start registration by pressing *Register* and choose *Brand / Company* role. Confirm the email code and add your company name and logo in *Settings*.'
            : 'Sāc reģistrāciju spiežot uz *Reģistrēties* un izvēlies Zīmols / Uzņēmums. Apstiprini uz e-pastu nosūtīto kodu un iestatījumos pievieno uzņēmuma nosaukumu un logo.' },
    { t: en ? 'Add funds' : 'Pievieno līdzekļus',
      d: en ? 'Go to *Payments* → *Add funds* and top up your balance. Campaign budgets are reserved from this balance, so you always pay only for what campaigns actually spend.'
            : 'Atver *Maksājumi* → *Pievienot līdzekļus* un papildini konta atlikumu. Kampaņas budžets tiek rezervēts no šī atlikuma, bet maksā tikai par skatījumiem, ko kampaņa reāli saņem.' },
    { t: en ? 'Create a campaign' : 'Izveido kampaņu',
      d: en ? 'Click *Create a campaign* in *My campaigns* section. Set the price per 1,000 views, total budget, maximum views per clip, allowed platforms, start/end dates and clear do/don\u2019t guidelines. Publish — clippers see it instantly.'
            : '*Manas kampaņas* sadaļā nospied *Izveidot kampaņu* un norādi cenu par 1 000 skatījumiem, kopējo budžetu, maksimālo summu par vienu klipu, platformas, termiņu un vadlīnijas. Publicē kampaņu, un tā uzreiz būs pieejama klipotājiem.' },
    { t: en ? 'Verify submitted clips' : 'Pārbaudi iesniegtos klipus',
      d: en ? 'When a clip is submitted it appears in *Submitted clips*. Confirm it meets your guidelines (*Verify clip*) or reject it. This is a one-time quality check, not a views check.'
            : 'Iesniegtos klipus atradīsi sadaļā *Iesniegtie klipi*. Pārbaudi, vai klips atbilst kampaņas vadlīnijām, un apstirptini to (Verificēt klipu) vai noraidi. Šeit tu pārbaudi pašu klipu - skatījumi tiek pārbaudīti automātiski.' },
    { t: en ? 'Views are validated and paid' : 'Skatījumi tiek validēti un izmaksāti',
      d: en ? 'Views are validated automatically every 24 hours and paid from your reserved budget for every 1,000 views. Follow each campaign\u2019s spend, views and clippers under *My campaigns*.'
            : 'Skatījumi tiek automātiski pārbaudīti ik pēc 24 stundām. Par katriem 1 000 skatījumiem attiecīgā summa tiek atskaitīta no kampaņai rezervētā budžeta. Kampaņas izdevumiem, skatījumiem un klipotājiem vari sekot sadaļā *Manas kampaņas*.' },
  ];
  const steps = role === 'clipper' ? CLIPPER : BRAND;
  const accent = role === 'clipper' ? '#2563EB' : '#BE123C';
  return (
    <div style={{ marginTop: 24 }}>
      <p style={{ fontSize: 18, color: 'var(--text)', fontWeight: 450, lineHeight: 1.6 }}>
        {en ? 'Klipzy connects brands that want more views with clippers who create short-form content. Choose your role to see how it works.'
            : 'Klipzy savieno zīmolus, kas vēlas vairāk skatījumu, ar klipotājiem, kas veido īsus klipus. Izvēlies savu lomu un uzzini, kā tas darbojas.'}
      </p>
      {/* role toggle */}
      <div style={{ display: 'inline-flex', gap: 4, padding: 4, background: '#F1F5F9', border: '1px solid var(--border)', borderRadius: 999, margin: '18px 0 8px' }}>
        {[['clipper', en ? 'For clippers' : 'Klipotājiem'], ['brand', en ? 'For brands' : 'Zīmoliem']].map(([k, label]) => (
          <button key={k} onClick={() => setRole(k)} style={{
            height: 36, padding: '0 20px', borderRadius: 999, border: 'none', cursor: 'pointer', fontSize: 14, fontWeight: 560,
            background: role === k ? '#fff' : 'transparent', color: role === k ? (k === 'brand' ? '#BE123C' : 'var(--accent-700)') : 'var(--text-2)',
            boxShadow: role === k ? 'var(--sh-sm)' : 'none',
          }}>{label}</button>
        ))}
      </div>
      {/* stepped list */}
      <div style={{ display: 'flex', flexDirection: 'column', gap: 0, marginTop: 18 }}>
        {steps.map((s, i) => (
          <div key={i} style={{ display: 'flex', gap: 16, position: 'relative', paddingBottom: i < steps.length - 1 ? 22 : 0 }}>
            <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', flex: 'none' }}>
              <span style={{ width: 34, height: 34, borderRadius: 999, background: accent, color: '#fff', display: 'grid', placeItems: 'center', fontSize: 15, fontWeight: 700, flex: 'none' }}>{i + 1}</span>
              {i < steps.length - 1 && <span style={{ width: 2, flex: 1, background: 'var(--border)', marginTop: 4 }} />}
            </div>
            <div style={{ paddingTop: 3 }}>
              <div style={{ fontSize: 16.5, fontWeight: 600, color: 'var(--text)', marginBottom: 5 }}>{s.t}</div>
              <p style={{ fontSize: 15, color: 'var(--text-2)', lineHeight: 1.6, margin: 0 }}>{typeof s.d === 'string' ? s.d.split(/\*([^*]+)\*/).map((seg, j) => j % 2 ? <strong key={j} style={{ color: 'var(--text)', fontWeight: 600 }}>{seg}</strong> : seg) : s.d}</p>
            </div>
          </div>
        ))}
      </div>
      <div style={{ marginTop: 26, display: 'flex', gap: 10, flexWrap: 'wrap' }}>
        {role === 'clipper'
          ? <button className="btn btn-primary" onClick={() => go('marketplace')}>{en ? 'Browse campaigns' : 'Pārlūkot kampaņas'}</button>
          : <button className="btn btn-primary" style={{ background: '#BE123C', borderColor: '#BE123C' }} onClick={() => go('auth', { role: 'brand' })}>{en ? 'Register a brand' : 'Reģistrēt zīmolu'}</button>}
      </div>
    </div>
  );
}

/* ===== ARTICLE DETAIL ===== */
function ArticleClip({ clip, lang }) {
  const ref = useRef(null);
  const [playing, setPlaying] = useState(false);
  const [started, setStarted] = useState(false);
  const [prog, setProg] = useState(0);
  const barRef = useRef(null);
  const src = clip.video ? clip.video[lang === 'en' ? 1 : 0] : null;
  const poster = clip.thumb ? clip.thumb[lang === 'en' ? 1 : 0] : null;
  const title = clip.t[lang === 'en' ? 1 : 0];
  const toggle = () => { const v = ref.current; if (!v) return; if (v.paused) { v.play(); setStarted(true); setPlaying(true); } else { v.pause(); setPlaying(false); } };
  const seek = (clientX) => { const v = ref.current, bar = barRef.current; if (!v || !bar || !v.duration) return; const r = bar.getBoundingClientRect(); const p = Math.min(1, Math.max(0, (clientX - r.left) / r.width)); v.currentTime = p * v.duration; setProg(p * 100); };
  return (
    <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
      <div className="eyebrow" style={{ padding: '14px 16px 10px' }}>{lang === 'en' ? 'Watch the lesson' : 'Noskaties nodarbību'}</div>
      <div style={{ position: 'relative', aspectRatio: '9/16', background: '#0F172A', cursor: src ? 'pointer' : 'default' }} onClick={src ? toggle : undefined}>
        {src
          ? <video ref={ref} src={src} playsInline poster={poster || undefined} style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' }}
              onTimeUpdate={(e) => { if (e.target.duration) setProg((e.target.currentTime / e.target.duration) * 100); }}
              onEnded={() => setPlaying(false)} onPlay={() => setPlaying(true)} onPause={() => setPlaying(false)} />
          : <img src={poster} alt="" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' }} />}
        {src && poster && !started && <img src={poster} alt="" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', zIndex: 1 }} />}
        {src && started && (
          <div ref={barRef} onClick={(e) => { e.stopPropagation(); seek(e.clientX); }}
            onPointerDown={(e) => { e.stopPropagation(); const mv = (ev) => seek(ev.clientX); seek(e.clientX); const up = () => { window.removeEventListener('pointermove', mv); window.removeEventListener('pointerup', up); }; window.addEventListener('pointermove', mv); window.addEventListener('pointerup', up); }}
            style={{ position: 'absolute', top: 8, left: 10, right: 10, height: 14, display: 'flex', alignItems: 'center', zIndex: 4, cursor: 'pointer' }}>
            <div style={{ width: '100%', height: 3, borderRadius: 999, background: 'rgba(255,255,255,.35)' }}>
              <div style={{ width: prog + '%', height: '100%', borderRadius: 999, background: '#fff' }} />
            </div>
          </div>
        )}
        {src && !playing && (
          <div style={{ position: 'absolute', inset: 0, background: 'rgba(0,0,0,.5)', backdropFilter: started ? 'blur(6px)' : 'none', WebkitBackdropFilter: started ? 'blur(6px)' : 'none', display: 'grid', placeItems: 'center', pointerEvents: 'none' }}>
            <span style={{ width: 58, height: 58, borderRadius: 999, background: 'rgba(255,255,255,.16)', border: '2px solid rgba(255,255,255,.7)', display: 'grid', placeItems: 'center' }}><Icon d="M8 5v14l11-7z" size={26} stroke="none" fill="#fff" /></span>
          </div>
        )}
        {!src && (
          <div style={{ position: 'absolute', inset: 0, background: 'rgba(0,0,0,.35)', display: 'grid', placeItems: 'center' }}>
            <span style={{ background: 'rgba(255,255,255,.9)', color: 'var(--text)', fontSize: 12, fontWeight: 600, borderRadius: 999, padding: '5px 12px' }}>{lang === 'en' ? 'Coming soon' : 'Drīzumā'}</span>
          </div>
        )}
      </div>
      <div style={{ padding: '11px 16px', fontSize: 13.5, fontWeight: 540 }}>{title}</div>
    </div>
  );
}

function ArticleDetail({ go, params }) {
  const K = window.KLIPZY;
  const lang = useLang();
  const a = K.articles.find((x) => x.id === params.id) || K.articles[0];
  const related = K.articles.filter((x) => x.id !== a.id).slice(0, 4);
  const backTo = params.from === 'blog' ? 'blog' : 'academy';
  const backLabel = params.from === 'blog' ? (lang === 'en' ? 'Blog' : 'Blogs') : (lang === 'en' ? 'Learning' : 'Mācības');
  const ART_CLIP = { a2: 0 };
  const clip = ART_CLIP[a.id] != null ? ACADEMY_STORIES[ART_CLIP[a.id]].clips[0] : null;

  return (
    <div className="app-scroll fade-in" style={{ height: '100%' }}>
      <PublicNav go={go} route="academy" lang={lang} />
      <GradTile grad={a.grad} radius={0} style={{ height: 220 }} />
      <div className="container" style={{ padding: '32px 28px 70px', marginTop: 0 }}>
        <div className="r-rail" style={{ display: 'grid', gridTemplateColumns: '1fr 280px', gap: 40, alignItems: 'start' }}>
          {/* article */}
          <article className="card" style={{ padding: '28px 44px 36px', marginTop: 0 }}>
            <button className="btn btn-secondary btn-sm" style={{ gap: 6, marginBottom: 18 }} onClick={() => go(backTo)}><Icon d={I.arrowL} size={16} /> {backLabel}</button>
            <h1 style={{ fontSize: 34, letterSpacing: '-0.03em', marginTop: 0, lineHeight: 1.1 }}>{lang === 'en' ? (a.titleEn || a.title) : a.title}</h1>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginTop: 16, paddingBottom: 24, borderBottom: '1px solid var(--border)' }}>
              <img src="assets/favicon.png" alt="Klipzy" style={{ width: 36, height: 36, borderRadius: 9, objectFit: 'cover', flex: 'none' }} />
              <div>
                <div style={{ fontSize: 13.5, fontWeight: 540 }}>{lang === 'en' ? 'Klipzy Academy' : 'Klipzy Akadēmija'}</div>
                <div className="muted" style={{ fontSize: 12.5 }}>{a.read} {lang === 'en' ? 'read · Updated May 28' : 'lasīšana · Atjaunots 28. maijā'}</div>
              </div>
            </div>

            <ArticleRoleGuide lang={lang} go={go} />
          </article>

          {/* sidebar */}
          <aside style={{ position: 'sticky', top: 84, marginTop: 0, display: 'flex', flexDirection: 'column', gap: 18 }}>
            {clip && <ArticleClip clip={clip} lang={lang} />}
            {related.length > 0 && (
            <div className="card" style={{ padding: 20 }}>
              <div className="eyebrow" style={{ marginBottom: 14 }}>{lang === 'en' ? 'Related lessons' : 'Saistītās nodarbības'}</div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
                {related.map((r, i) => (
                  <div key={r.id} onClick={() => go('article', { id: r.id, from: params.from })} style={{ display: 'flex', gap: 11, padding: '11px 0', borderTop: i ? '1px solid var(--border)' : 'none', cursor: 'pointer' }}>
                    <GradTile grad={r.grad} radius={8} style={{ width: 48, height: 40, flex: 'none' }} />
                    <div style={{ minWidth: 0 }}>
                      <div style={{ fontSize: 13.5, fontWeight: 540, lineHeight: 1.3 }}>{lang === 'en' ? (r.titleEn || r.title) : r.title}</div>
                      <div className="muted" style={{ fontSize: 12, marginTop: 3 }}>{r.read}</div>
                    </div>
                  </div>
                ))}
              </div>
            </div>
            )}
            <div className="card" style={{ padding: 22, background: 'linear-gradient(160deg,#1E3A8A,#2563EB)', color: '#fff' }}>
              <h4 style={{ fontSize: 16 }}>{lang === 'en' ? 'Ready to apply it?' : 'Gatavs pielietot?'}</h4>
              <p style={{ fontSize: 13.5, opacity: .85, marginTop: 8, lineHeight: 1.5 }}>{lang === 'en' ? 'Find a campaign and turn this knowledge into money.' : 'Atrodi kampaņu un pārvērt šīs zināšanas naudā.'}</p>
              <button className="btn btn-block" style={{ marginTop: 14, background: '#fff', color: 'var(--accent-700)' }} onClick={() => go('marketplace')}>{lang === 'en' ? 'View campaigns' : 'Skatīt kampaņas'}</button>
            </div>
          </aside>
        </div>
      </div>
      <Footer go={go} lang={lang} />
    </div>
  );
}
function ArticleH({ children }) { return <h2 style={{ fontSize: 22, color: 'var(--text)', marginTop: 30, marginBottom: 12, letterSpacing: '-0.02em' }}>{children}</h2>; }
function Callout({ children }) {
  return (
    <div style={{ background: 'var(--accent-tint)', borderLeft: '3px solid var(--accent)', borderRadius: '0 10px 10px 0', padding: '14px 18px', margin: '20px 0', fontSize: 15, color: 'var(--accent-700)', lineHeight: 1.55 }}>{children}</div>
  );
}

/* ===== AUTH / ROLE SELECT ===== */
function Auth({ go, params }) {
  const [mode, setMode] = useState(params.mode === 'login' ? 'login' : 'register');
  const [role, setRole] = useState(params.role || null);
  const [step, setStep] = useState(role ? 'form' : 'role');
  const [lang, setLang] = useState(() => { try { return localStorage.getItem('klipzy_lang') || 'lv'; } catch (_) { return 'lv'; } });
  useEffect(() => {
    const on = (e) => setLang(e.detail || (localStorage.getItem('klipzy_lang') || 'lv'));
    window.addEventListener('klipzy-lang', on);
    return () => window.removeEventListener('klipzy-lang', on);
  }, []);

  // form state
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [busy, setBusy] = useState(false);
  const [resetOpen, setResetOpen] = useState(false);
  const [error, setError] = useState('');
  // Google sign-up profile-completion step (new Google users must set a name).
  const [gProfile, setGProfile] = useState(null); // { uid, role } | null
  const [gName, setGName] = useState('');
  const [remember, setRemember] = useState(true);

  const switchTo = (m) => { setMode(m); setStep(role ? 'form' : 'role'); setError(''); };

  const fb = () => window.KlipzyFirebase;
  const showErr = (e) => { console.error('[Klipzy auth]', e && e.code, e && e.message, e); const m = fb() ? fb().friendlyError(e) : { lv: 'Kļūda.', en: 'Error.', ru: 'Ошибка.' }; setError(m[lang] || m.lv); };
  const routeFor = (profile) => homeForRole(profile && profile.role);

  const doLogin = async () => {
    if (!fb()) return;
    setBusy(true); setError('');
    console.time('[perf] TOTAL login -> navigation');
    try {
      const { profile } = await fb().signInEmail({ email, password, remember });
      console.log('[perf] signInEmail resolved, navigating to', routeFor(profile));
      console.timeEnd('[perf] TOTAL login -> navigation');
      go(routeFor(profile), { tab: 'panel' });
    } catch (e) { console.timeEnd('[perf] TOTAL login -> navigation'); showErr(e); } finally { setBusy(false); }
  };

  const doRegister = async () => {
    if (!fb()) return;
    if (!name.trim()) { setError(tr('Lūdzu, ievadi vārdu.', lang)); return; }
    setBusy(true); setError('');
    try {
      const { profile } = await fb().registerEmail({ email, password, displayName: name, role: role || 'clipper' });
      go(routeFor(profile) || role, { tab: 'panel' });
    } catch (e) { showErr(e); } finally { setBusy(false); }
  };

  const doGoogle = async () => {
    if (!fb()) return;
    setBusy(true); setError('');
    try {
      const { user, profile, needsProfile } = await fb().signInGoogle(mode === 'register' ? (role || 'clipper') : undefined);
      if (needsProfile) { setGProfile({ uid: user.uid, role: profile.role || role || 'clipper' }); setGName(''); setBusy(false); return; }
      go(routeFor(profile), { tab: 'panel' });
    } catch (e) { showErr(e); } finally { setBusy(false); }
  };

  const doCompleteGoogle = async () => {
    if (!fb() || !gProfile) return;
    if (!gName.trim()) { setError(tr('Lūdzu, ievadi vārdu.', lang)); return; }
    setBusy(true); setError('');
    try {
      const profile = await fb().completeGoogleProfile(gProfile.uid, { displayName: gName.trim(), role: gProfile.role });
      go(routeFor(profile) || gProfile.role, { tab: 'panel' });
    } catch (e) { showErr(e); } finally { setBusy(false); }
  };

  const ErrorMsg = () => error ? (
    <div style={{ background: '#FEF2F2', border: '1px solid #FECACA', color: '#B91C1C', borderRadius: 'var(--r)', padding: '10px 13px', fontSize: 13.5, lineHeight: 1.4 }}>{error}</div>
  ) : null;

  return (
    <div className="app-scroll fade-in" style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
      <div style={{ padding: '22px 28px', display: 'flex', alignItems: 'center', gap: 14 }}>
        <button className="btn btn-secondary btn-sm" style={{ gap: 6 }} onClick={() => go(params.from && params.from !== 'auth' ? params.from : 'landing')}><Icon d={I.arrowL} size={16} /> {tr('Atpakaļ', lang)}</button>
        <Logo size={21} onClick={() => go('landing')} />
      </div>
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 22, padding: '20px 28px 60px' }}>

        {gProfile ? (
          <div style={{ width: '100%', maxWidth: 420 }}>
            <div className="card fade-in" style={{ padding: 32 }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 11, marginBottom: 18 }}>
                <span style={{ width: 40, height: 40, borderRadius: 11, background: 'var(--accent-tint)', color: 'var(--accent-700)', display: 'grid', placeItems: 'center' }}><Icon d={I[gProfile.role === 'brand' ? 'megaphone' : 'film']} size={20} /></span>
                <div>
                  <h1 style={{ fontSize: 21, letterSpacing: '-0.02em' }}>{tr('Tikai viens solis', lang)}</h1>
                  <p className="muted" style={{ fontSize: 13.5, marginTop: 2 }}>{gProfile.role === 'brand' ? tr('Ievadi sava zīmola nosaukumu.', lang) : tr('Ievadi savu vārdu.', lang)}</p>
                </div>
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
                <ErrorMsg />
                <div className="field">
                  <label htmlFor="gname">{gProfile.role === 'brand' ? tr('Zīmola nosaukums', lang) : tr('Vārds, uzvārds', lang)}</label>
                  <input className="input" id="gname" name="name" autoComplete={gProfile.role === 'brand' ? 'organization' : 'name'} value={gName} onChange={(e) => setGName(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && doCompleteGoogle()} placeholder={gProfile.role === 'brand' ? tr('piem. Rīga Energy', lang) : tr('piem. Jānis Bērziņš', lang)} autoFocus />
                </div>
                <button className="btn btn-primary btn-lg btn-block" disabled={busy || !gName.trim()} onClick={doCompleteGoogle}>{busy ? tr('Notiek...', lang) : tr('Turpināt', lang)} <Icon d={I.arrowR} size={17} /></button>
              </div>
            </div>
          </div>
        ) : mode === 'login' ? (
          <div style={{ width: '100%', maxWidth: 420 }}>
            <div className="card fade-in" style={{ padding: 32 }}>
              <div style={{ textAlign: 'center', marginBottom: 24 }}>
                <h1 style={{ fontSize: 26, letterSpacing: '-0.03em' }}>{tr('Pieslēgties', lang)}</h1>
                <p className="muted" style={{ fontSize: 14.5, marginTop: 8 }}>{tr('Laipni lūdzam atpakaļ Klipzy.', lang)}</p>
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
                <GoogleButton onClick={doGoogle} disabled={busy} lang={lang} />
                <OrDivider lang={lang} />
                <ErrorMsg />
                <div className="field"><label htmlFor="login-email">{tr('E-pasts', lang)}</label><input className="input" id="login-email" name="email" required type="email" autoComplete="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="tu@example.lv" /></div>
                <PasswordField label={tr('Parole', lang)} required autoComplete="current-password" id="login-password" value={password} onChange={(e) => setPassword(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && doLogin()} placeholder="••••••••" />
                <div className="spread" style={{ fontSize: 13 }}>
                  <label style={{ display: 'flex', alignItems: 'center', gap: 7, color: 'var(--text-2)', cursor: 'pointer' }}><input type="checkbox" checked={remember} onChange={(e) => setRemember(e.target.checked)} /> {tr('Atcerēties mani', lang)}</label>
                  <a onClick={() => setResetOpen(true)} style={{ color: 'var(--accent-700)', cursor: 'pointer' }}>{tr('Aizmirsi paroli?', lang)}</a>
                </div>
                <button className="btn btn-primary btn-lg btn-block" disabled={busy} onClick={doLogin}>{busy ? tr('Notiek...', lang) : tr('Pieslēgties', lang)}</button>
              </div>
              <p className="muted" style={{ fontSize: 13.5, textAlign: 'center', marginTop: 22 }}>
                {tr('Nav konta?', lang)} <a onClick={() => switchTo('register')} style={{ color: 'var(--accent-700)', fontWeight: 560, cursor: 'pointer' }}>{tr('Reģistrējies', lang)}</a>
              </p>
              {resetOpen && <PasswordResetModal lang={lang} initialEmail={email} onClose={() => setResetOpen(false)} />}
            </div>
          </div>
        ) : (
          <div style={{ width: '100%', maxWidth: step === 'role' ? 720 : 460 }}>
            {step === 'role' ? (
              <div className="fade-in">
                <div style={{ textAlign: 'center', marginBottom: 32 }}>
                  <h1 style={{ fontSize: 32, letterSpacing: '-0.03em' }}>{tr('Pievienojies Klipzy', lang)}</h1>
                  <p className="muted" style={{ fontSize: 16, marginTop: 10 }}>{tr('Izvēlies, kā vēlies izmantot Klipzy.', lang)}</p>
                </div>
                <div className="r-grid2" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 18 }}>
                  <RoleCard
                    active={role === 'clipper'} onClick={() => setRole('clipper')}
                    icon="film" title={tr('Klipotājs', lang)} grad={['#2563EB', '#3B82F6']}
                    desc={tr('Veido klipus zīmoliem un pelni pēc skatījumiem.', lang)}
                    bullets={[tr('Pārlūko kampaņas', lang), tr('Veido un iesniedz klipus', lang), tr('Saņem samaksu', lang)]} />
                  <RoleCard
                    active={role === 'brand'} onClick={() => setRole('brand')}
                    icon="megaphone" title={tr('Zīmols / Uzņēmums', lang)} grad={['#F43F5E', '#FB7185']}
                    desc={tr('Veido kampaņas un maksā par rezultātu.', lang)}
                    bullets={[tr('Izveido kampaņas', lang), tr('Saņem saturu no veidotājiem', lang), tr('Maksā par skatījumiem', lang)]} />
                </div>
                <button className="btn btn-primary btn-lg btn-block" style={{ marginTop: 24 }} disabled={!role} onClick={() => setStep('form')}>{tr('Turpināt', lang)} <Icon d={I.arrowR} size={17} /></button>
                <p className="muted" style={{ fontSize: 13.5, textAlign: 'center', marginTop: 18 }}>
                  {tr('Jau ir konts?', lang)} <a onClick={() => switchTo('login')} style={{ color: 'var(--accent-700)', fontWeight: 560, cursor: 'pointer' }}>{tr('Pieslēdzies', lang)}</a>
                </p>
              </div>
            ) : (
              <div className="card fade-in" style={{ padding: 32 }}>
                <button className="btn btn-ghost btn-sm" style={{ paddingLeft: 6, color: 'var(--muted)', marginBottom: 8 }} onClick={() => setStep('role')}><Icon d={I.arrowL} size={16} /> {tr('Pārslēgt lomu', lang)}</button>
                <div style={{ display: 'flex', alignItems: 'center', gap: 11, marginBottom: 6 }}>
                  <span style={{ width: 40, height: 40, borderRadius: 11, background: 'var(--accent-tint)', color: 'var(--accent-700)', display: 'grid', placeItems: 'center' }}><Icon d={I[role === 'brand' ? 'megaphone' : 'film']} size={20} /></span>
                  <div>
                    <h2 style={{ fontSize: 20 }}>{role === 'brand' ? tr('Reģistrē savu zīmolu', lang) : tr('Izveido klipotāja kontu', lang)}</h2>
                    <p className="muted" style={{ fontSize: 13.5 }}>{tr('Vēl tikai daži soļi.', lang)}</p>
                  </div>
                </div>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 16, marginTop: 18 }}>
                  <GoogleButton onClick={doGoogle} disabled={busy} lang={lang} />
                  <OrDivider lang={lang} />
                  <ErrorMsg />
                  <div className="field required"><label htmlFor="reg-name">{role === 'brand' ? tr('Uzņēmuma nosaukums', lang) : tr('Vārds, uzvārds', lang)}</label><input className="input" id="reg-name" name="name" required autoComplete={role === 'brand' ? 'organization' : 'name'} value={name} onChange={(e) => setName(e.target.value)} placeholder={role === 'brand' ? tr('piem. Rīga Energy', lang) : tr('piem. Jānis Bērziņš', lang)} /></div>
                  <div className="field"><label htmlFor="reg-email">{tr('E-pasts', lang)}</label><input className="input" id="reg-email" name="email" required type="email" autoComplete="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="tu@example.lv" /></div>
                  <PasswordField label={tr('Parole', lang)} required autoComplete="new-password" id="reg-password" value={password} onChange={(e) => setPassword(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && doRegister()} placeholder="••••••••" />
                  <button className="btn btn-primary btn-lg btn-block" disabled={busy} onClick={doRegister}>
                    {busy ? tr('Notiek...', lang) : (role === 'brand' ? tr('Izveidot zīmola kontu', lang) : tr('Izveidot klipotāja kontu', lang))}
                  </button>
                  <p className="muted" style={{ fontSize: 12.5, textAlign: 'center', lineHeight: 1.5 }}>{lang === 'en'
                    ? <>By signing up, you agree to Klipzy's <a href="#/noteikumi" target="_blank" rel="noopener noreferrer" style={{ color: 'var(--accent-700)' }}>Terms and Conditions</a> and <a href="#/privatums" target="_blank" rel="noopener noreferrer" style={{ color: 'var(--accent-700)' }}>Privacy Policy</a>.</>
                    : <>Reģistrējoties, tu piekrīti Klipzy <a href="#/noteikumi" target="_blank" rel="noopener noreferrer" style={{ color: 'var(--accent-700)' }}>noteikumiem</a> un <a href="#/privatums" target="_blank" rel="noopener noreferrer" style={{ color: 'var(--accent-700)' }}>privātuma politikai</a>.</>}</p>
                </div>
                <p className="muted" style={{ fontSize: 13.5, textAlign: 'center', marginTop: 16, paddingTop: 16, borderTop: '1px solid var(--border)' }}>
                  {tr('Jau ir konts?', lang)} <a onClick={() => switchTo('login')} style={{ color: 'var(--accent-700)', fontWeight: 560, cursor: 'pointer' }}>{tr('Pieslēdzies', lang)}</a>
                </p>
              </div>
            )}
          </div>
        )}

        <LangSwitch lang={lang} setLang={setLang} langs={['lv', 'en']} />

      </div>
    </div>
  );
}

function RoleCard({ active, onClick, icon, title, desc, bullets, grad }) {
  return (
    <button onClick={onClick} className="card" style={{ padding: 26, textAlign: 'left', cursor: 'pointer', border: active ? '2px solid var(--accent)' : '1px solid var(--border)', background: active ? 'var(--accent-tint)' : '#fff', transition: 'all .16s', position: 'relative' }}>
      {active && <span style={{ position: 'absolute', top: 18, right: 18, width: 22, height: 22, borderRadius: 999, background: 'var(--accent)', color: '#fff', display: 'grid', placeItems: 'center' }}><Icon d={I.check} size={14} stroke="#fff" sw={2.6} /></span>}
      <GradTile grad={grad} radius={13} style={{ width: 52, height: 52, display: 'grid', placeItems: 'center', color: '#fff', marginBottom: 16 }}><Icon d={I[icon]} size={26} stroke="#fff" /></GradTile>
      <h3 style={{ fontSize: 18 }}>{title}</h3>
      <p className="muted" style={{ fontSize: 14, marginTop: 7, lineHeight: 1.5 }}>{desc}</p>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8, marginTop: 16 }}>
        {bullets.map((b) => <div key={b} style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13.5, color: 'var(--text-2)' }}><Icon d={I.check} size={15} stroke="var(--accent)" sw={2.4} /> {b}</div>)}
      </div>
    </button>
  );
}

Object.assign(window, { Academy, ArticleDetail, Auth });

/* Password reset: request a code by email, then set a new password. */
function PasswordResetModal({ lang, initialEmail, onClose }) {
  const T = (s) => tr(s, lang);
  const [step, setStep] = useState('email');   // email → code → done
  const [email, setEmail] = useState(initialEmail || '');
  const [code, setCode] = useState('');
  const [pw, setPw] = useState('');
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState('');
  const [resent, setResent] = useState(false);
  const [cool, setCool] = useState(0);
  useEffect(() => {
    if (cool <= 0) return;
    const t = setTimeout(() => setCool((n) => n - 1), 1000);
    return () => clearTimeout(t);
  }, [cool]);

  const send = async (resend) => {
    if (!email.trim()) { setErr(T('Ievadi savu e-pastu.')); return; }
    setBusy(true); setErr(''); setResent(false);
    try {
      await window.KlipzyFirebase.sendPasswordResetCode(email.trim(), lang, !!resend);
      setStep('code');
      setCool(30);
      if (resend) { setResent(true); setTimeout(() => setResent(false), 6000); }
    } catch (e) {
      const msg = (e && e.message) || '';
      setErr(/not-found|No account/i.test(msg)
        ? T('Šis e-pasts nav reģistrēts.')
        : /resource-exhausted|Too many/i.test(msg)
        ? T('Pārāk daudz mēģinājumu. Mēģini vēlāk.')
        : msg || T('Neizdevās nosūtīt kodu. Mēģini vēlreiz.'));
    }
    setBusy(false);
  };
  const confirm = async () => {
    if (code.length !== 6) { setErr(T('Ievadi 6 ciparu kodu.')); return; }
    if (pw.length < 6) { setErr(T('Parolei jābūt vismaz 6 simbolus garai.')); return; }
    setBusy(true); setErr('');
    try {
      await window.KlipzyFirebase.confirmPasswordResetCode(email.trim(), code, pw);
      setStep('done');
    } catch (e) {
      const msg = (e && e.message) || '';
      // Surface the real reason instead of a bare "internal".
      setErr(/expired|deadline/i.test(msg) ? T('Kods ir beidzies. Pieprasi jaunu kodu.')
        : /already-exists|different from your current/i.test(msg) ? T('Jaunā parole nedrīkst būt tāda pati kā iepriekšējā.')
        : /Request a code first|failed-precondition/i.test(msg) ? T('Vispirms pieprasīi kodu.')
        : /Incorrect code|invalid-argument|permission-denied/i.test(msg) ? T('Nepareizs kods.')
        : /at least 6/i.test(msg) ? T('Parolei jābūt vismaz 6 simbolus garai.')
        : msg || T('Nepareizs kods.'));
    }
    setBusy(false);
  };

  return (
    <ModalShell onClose={onClose} width={400}>
        <div className="spread" style={{ marginBottom: 6 }}>
          <h3 style={{ fontSize: 19 }}>{T('Atjaunot paroli')}</h3>
          <button className="btn btn-ghost btn-sm" style={{ padding: 6 }} onClick={onClose}><Icon d={I.x} size={18} /></button>
        </div>

        {step === 'email' && (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
            <p className="muted" style={{ fontSize: 13.5, lineHeight: 1.5 }}>{T('Ievadi savu e-pastu, un mēs nosūtīsim 6 ciparu kodu paroles atjaunošanai.')}</p>
            <div className="field"><label>{T('E-pasts')}</label><input className="input" type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="tu@example.lv" autoFocus /></div>
            {err && <div style={{ background: '#FEF2F2', border: '1px solid #FECACA', color: '#B91C1C', borderRadius: 'var(--r)', padding: '10px 13px', fontSize: 13.5 }}>{err}</div>}
            <button className="btn btn-primary btn-lg btn-block" disabled={busy} onClick={send}>{busy ? T('Sūta…') : T('Nosūtīt kodu')}</button>
          </div>
        )}

        {step === 'code' && (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
            <p className="muted" style={{ fontSize: 13.5, lineHeight: 1.5 }}>{T('Ja konts eksistē, kods ir nosūtīts uz')} <strong style={{ color: 'var(--text)' }}>{email}</strong>. {T('Kods derīgs 30 minūtes.')}</p>
            <div className="field"><label>{T('Kods')}</label><input className="input tnum" style={{ letterSpacing: '0.3em', textAlign: 'center' }} inputMode="numeric" maxLength={6} placeholder="000000" value={code} onChange={(e) => setCode(e.target.value.replace(/\D/g, '').slice(0, 6))} autoFocus /></div>
            <PasswordField label={T('Jaunā parole')} value={pw} onChange={(e) => setPw(e.target.value)} placeholder="••••••••" />
            {resent && <div style={{ background: 'var(--green-tint)', border: '1px solid #BBF7D0', color: '#166534', borderRadius: 'var(--r)', padding: '10px 13px', fontSize: 13.5 }}>{T('Jauns kods nosūtīts. Pārbaudi savu e-pastu.')}</div>}
            {err && <div style={{ background: '#FEF2F2', border: '1px solid #FECACA', color: '#B91C1C', borderRadius: 'var(--r)', padding: '10px 13px', fontSize: 13.5 }}>{err}</div>}
            <button className="btn btn-primary btn-lg btn-block" disabled={busy} onClick={confirm}>{busy ? T('Saglabā…') : T('Nomainīt paroli')}</button>
            <button className="btn btn-secondary btn-sm" disabled={busy || cool > 0} onClick={() => send(true)}>{cool > 0 ? T('Nosūtīt kodu vēlreiz') + ` (${cool}s)` : T('Nosūtīt kodu vēlreiz')}</button>
          </div>
        )}

        {step === 'done' && (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 14, textAlign: 'center' }}>
            <div style={{ width: 52, height: 52, borderRadius: 999, background: 'var(--green-tint)', color: 'var(--green)', display: 'grid', placeItems: 'center', margin: '8px auto 0' }}><Icon d={I.check} size={26} sw={2.4} /></div>
            <div style={{ fontWeight: 600, fontSize: 16 }}>{T('Parole nomainīta!')}</div>
            <p className="muted" style={{ fontSize: 13.5 }}>{T('Tagad vari pieslēgties ar jauno paroli.')}</p>
            <button className="btn btn-primary btn-block" onClick={onClose}>{T('Pieslēgties')}</button>
          </div>
        )}
    </ModalShell>
  );
}

function GoogleButton({ onClick, disabled, lang }) {
  return (
    <button className="btn btn-secondary btn-lg btn-block" onClick={onClick} disabled={disabled} style={{ gap: 10 }}>
      <svg width="18" height="18" viewBox="0 0 18 18" aria-hidden="true">
        <path fill="#4285F4" d="M17.64 9.2c0-.64-.06-1.25-.16-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.72v2.26h2.92c1.7-1.57 2.68-3.88 2.68-6.62z" />
        <path fill="#34A853" d="M9 18c2.43 0 4.47-.8 5.96-2.18l-2.92-2.26c-.8.54-1.84.86-3.04.86-2.34 0-4.32-1.58-5.03-3.7H.96v2.33A9 9 0 0 0 9 18z" />
        <path fill="#FBBC05" d="M3.97 10.72a5.4 5.4 0 0 1 0-3.44V4.95H.96a9 9 0 0 0 0 8.1l3.01-2.33z" />
        <path fill="#EA4335" d="M9 3.58c1.32 0 2.5.45 3.44 1.35l2.58-2.58A9 9 0 0 0 .96 4.95l3.01 2.33C4.68 5.16 6.66 3.58 9 3.58z" />
      </svg>
      {tr('Turpināt ar Google', lang)}
    </button>
  );
}

function OrDivider({ lang }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 12, color: 'var(--muted)', fontSize: 12.5 }}>
      <span style={{ flex: 1, height: 1, background: 'var(--border)' }} />
      {tr('vai', lang)}
      <span style={{ flex: 1, height: 1, background: 'var(--border)' }} />
    </div>
  );
}
