// Reel — Player screen + all overlay sheets
const TP = REEL_TOKENS;

const pIconBtn = { width:38,height:38,borderRadius:19,border:'none',background:'transparent',color:'#fff',display:'inline-flex',alignItems:'center',justifyContent:'center',cursor:'pointer',padding:0 };
const pCenterBtn = { width:54,height:54,borderRadius:27,border:'none',background:'rgba(0,0,0,0.45)',backdropFilter:'blur(6px)',color:'#fff',display:'flex',alignItems:'center',justifyContent:'center',cursor:'pointer' };
const iconBtn = { width:38,height:38,borderRadius:19,border:'none',background:'transparent',color:TP.text,display:'inline-flex',alignItems:'center',justifyContent:'center',cursor:'pointer',padding:0 };
const fileRow = { display:'flex',alignItems:'center',gap:12,padding:'10px 12px',border:'1px solid '+TP.border,borderRadius:12,background:'transparent',color:TP.text,fontFamily:'inherit',cursor:'pointer',width:'100%' };

// ── Player screen ──────────────────────────────────────────────────────
function PlayerScreen({ video, onBack, accent, chromeStyle='full', subtitleStyle='cinema', overlay, setOverlay, dualSubs, skipSeconds=10, onVideoUpdate }) {
  const videoRef  = React.useRef(null);
  const surfaceRef = React.useRef(null);
  const [playing, setPlaying]   = React.useState(false);
  const [pos, setPos]           = React.useState(video.resumePos || 0);
  const [duration, setDuration] = React.useState(video.duration || 0);
  const [locked, setLocked]     = React.useState(false);
  const [showGesture, setGesture] = React.useState(null);
  const [favScenes, setFavScenes] = React.useState([]);
  const [bookmarks, setBookmarks] = React.useState([]);
  const [toast, setToast]       = React.useState(null);
  const [brightness, setBrightness] = React.useState(70);
  const [volume, setVolume]     = React.useState(80);
  const [skipPulse, setSkipPulse] = React.useState(null);
  const [loaded, setLoaded]     = React.useState(false);
  // error kinds: null | 'no-file' | 'codec' | 'generic'
  const [errorKind, setErrorKind] = React.useState(null);
  const [errorMsg,  setErrorMsg]  = React.useState('');
  const [reselecting, setReselecting] = React.useState(false);
  const [retrying, setRetrying]       = React.useState(false);
  const [showControls, setShowControls] = React.useState(true);
  const [speed, setSpeed]       = React.useState(1);
  const hideTimer = React.useRef(null);
  const gestureTimer = React.useRef(null);
  const urlRef = React.useRef(null);
  const saveTimer = React.useRef(null);

  // videoSrc is a React state — <video src={videoSrc}> so React never clears it on re-render
  const [videoSrc, setVideoSrc] = React.useState(null);

  // Single effect handles everything: get URL, attach listeners, play when ready
  React.useEffect(() => {
    const vid = videoRef.current;
    if (!vid) return;

    // Reset state for the new video
    setLoaded(false);
    setErrorKind(null);
    setErrorMsg('');
    setPlaying(false);

    const startAt = video.resumePos || 0;
    const ext = (video.filename || video.title || '').split('.').pop().toLowerCase();

    // ── Native error listener (React onError prop is unreliable for <video>) ──
    const onErr = () => {
      const code = vid.error ? vid.error.code : 0;
      if (code === 3 || code === 4) {
        setErrorKind('codec');
        setErrorMsg(ext === 'mkv' ? 'MKV_CODEC' : 'FORMAT_ERROR');
      } else {
        setErrorKind('no-file');
        setErrorMsg('');
      }
    };

    // ── Native canplay listener — try to play as soon as browser has enough data ──
    const onCanPlay = () => {
      if (startAt > 2) { try { vid.currentTime = startAt; } catch(e){} }
      vid.playbackRate = speed;
      vid.play().catch(() => {
        // Autoplay blocked — that's OK, user can tap the play button
      });
    };

    vid.addEventListener('error',   onErr);
    vid.addEventListener('canplay', onCanPlay);

    // Safety net: if 15 s pass with no canplay/error, show no-file error
    const timer = setTimeout(() => {
      if (vid.readyState < 3 && !vid.error) setErrorKind('no-file');
    }, 15000);

    // ── Get the file URL and set it via React state ──
    REEL_SCANNER.getVideoUrl(video)
      .then(url => {
        if (!url) { clearTimeout(timer); setErrorKind('no-file'); return; }
        if (urlRef.current) { try { URL.revokeObjectURL(urlRef.current); } catch(e){} }
        urlRef.current = url;
        setVideoSrc(url); // React sets <video src={url}> on next render
      })
      .catch(() => { clearTimeout(timer); setErrorKind('no-file'); });

    return () => {
      clearTimeout(timer);
      vid.removeEventListener('error',   onErr);
      vid.removeEventListener('canplay', onCanPlay);
      try { vid.pause(); } catch(e) {}
      if (urlRef.current) { try { URL.revokeObjectURL(urlRef.current); } catch(e){} urlRef.current = null; }
      setVideoSrc(null);
    };
  }, [video.id]);

  // Re-select file when user taps the button in the error screen
  const handleReselect = async () => {
    setReselecting(true);
    try {
      const file = await REEL_SCANNER.reselectFile(video);
      if (!file) { setReselecting(false); return; }
      const url = URL.createObjectURL(file);
      if (urlRef.current) { try { URL.revokeObjectURL(urlRef.current); } catch(e){} }
      urlRef.current = url;
      setErrorKind(null); setErrorMsg(''); setLoaded(false);
      setVideoSrc(url);
    } catch(e) {}
    setReselecting(false);
  };

  // Load fav scenes + bookmarks from DB
  React.useEffect(() => {
    REEL_DB.getFavScenes(video.id).then(s => setFavScenes(s||[]));
    REEL_DB.getBookmarks(video.id).then(b => setBookmarks(b||[]));
    REEL_DB.logHistory(video.id, video.title, video.folder, video.hue, video.duration);
  }, [video.id]);

  // Auto-hide controls
  const resetHideTimer = () => {
    setShowControls(true);
    clearTimeout(hideTimer.current);
    hideTimer.current = setTimeout(() => setShowControls(false), 3500);
  };

  React.useEffect(() => { resetHideTimer(); return () => clearTimeout(hideTimer.current); }, []);

  // Save progress periodically
  React.useEffect(() => {
    saveTimer.current = setInterval(() => {
      const vid = videoRef.current;
      if (!vid || !duration) return;
      const p = vid.currentTime;
      REEL_DB.updateProgress(video.id, p, duration);
      if (onVideoUpdate) onVideoUpdate(video.id, p, duration);
    }, 5000);
    return () => clearInterval(saveTimer.current);
  }, [video.id, duration]);

  const onTimeUpdate = () => {
    const vid = videoRef.current;
    if (vid) setPos(vid.currentTime);
  };

  const onLoadedMetadata = () => {
    const vid = videoRef.current;
    if (!vid) return;
    setDuration(vid.duration);
    setLoaded(true);
    REEL_DB.setDuration(video.id, vid.duration);
    if (onVideoUpdate) onVideoUpdate(video.id, video.resumePos||0, vid.duration);
  };

  const onEnded = () => {
    setPlaying(false);
    REEL_DB.updateProgress(video.id, duration, duration);
    if (onVideoUpdate) onVideoUpdate(video.id, duration, duration);
  };

  const togglePlay = () => {
    const vid = videoRef.current;
    if (!vid) return;
    if (playing) { vid.pause(); setPlaying(false); }
    else { vid.play().then(() => setPlaying(true)).catch(() => {}); }
    resetHideTimer();
  };

  const seekTo = (t) => {
    const vid = videoRef.current;
    if (!vid) return;
    vid.currentTime = Math.max(0, Math.min(duration, t));
    setPos(vid.currentTime);
    resetHideTimer();
  };

  // Drag gestures on the video surface
  const onSurfacePointerDown = e => {
    if (e.target.closest('button')) return;
    if (locked) return;
    const surface = surfaceRef.current;
    if (!surface) return;
    const rect = surface.getBoundingClientRect();
    const startX = e.clientX, startY = e.clientY;
    const isRight = (startX - rect.left) > rect.width / 2;
    let mode = null, initialPos = pos, initialBright = brightness, initialVol = volume;
    const THRESH = 8;
    try { e.target.setPointerCapture && e.target.setPointerCapture(e.pointerId); } catch(ex) {}

    const move = ev => {
      const dx = ev.clientX - startX, dy = ev.clientY - startY;
      if (!mode) {
        if (Math.abs(dx) < THRESH && Math.abs(dy) < THRESH) return;
        mode = Math.abs(dx) > Math.abs(dy) ? 'h' : 'v';
      }
      clearTimeout(gestureTimer.current);
      if (mode === 'h') {
        const next = Math.max(0, Math.min(duration, initialPos + (dx / rect.width) * 90));
        setPos(next);
        setGesture({ type:'seek', from:initialPos, to:next, delta:next-initialPos });
      } else {
        const pct = -(dy / rect.height) * 100;
        if (isRight) {
          const v = Math.max(0, Math.min(100, initialVol + pct));
          setVolume(v);
          const vid = videoRef.current;
          if (vid) vid.volume = v / 100;
          setGesture({ type:'volume', value:Math.round(v) });
        } else {
          const v = Math.max(0, Math.min(100, initialBright + pct));
          setBrightness(v);
          setGesture({ type:'brightness', value:Math.round(v) });
        }
      }
    };
    const up = () => {
      window.removeEventListener('pointermove', move);
      window.removeEventListener('pointerup', up);
      window.removeEventListener('pointercancel', up);
      if (mode === 'h') {
        const vid = videoRef.current;
        if (vid) vid.currentTime = pos;
      }
      clearTimeout(gestureTimer.current);
      gestureTimer.current = setTimeout(() => setGesture(null), 700);
    };
    window.addEventListener('pointermove', move);
    window.addEventListener('pointerup', up);
    window.addEventListener('pointercancel', up);
  };

  // Double-tap to skip
  const lastTap = React.useRef({ side:null, time:0 });
  const onSurfaceTap = e => {
    if (e.target.closest('button')) return;
    if (locked) return;
    resetHideTimer();
    const surface = surfaceRef.current;
    if (!surface) return;
    const rect = surface.getBoundingClientRect();
    const side = (e.clientX - rect.left) > rect.width / 2 ? 'r' : 'l';
    const now = Date.now();
    if (lastTap.current.side === side && now - lastTap.current.time < 320) {
      const amount = skipSeconds;
      if (side === 'r') { seekTo(pos + amount); setSkipPulse({ side:'r', key:now }); }
      else              { seekTo(pos - amount); setSkipPulse({ side:'l', key:now }); }
      lastTap.current = { side:null, time:0 };
      setTimeout(() => setSkipPulse(null), 600);
    } else {
      lastTap.current = { side, time:now };
    }
  };

  const markFavScene = async () => {
    const t = Math.floor(pos);
    const exists = favScenes.find(f => Math.abs(f.t - t) < 2);
    if (exists) {
      await REEL_DB.delFavScene(exists.fid);
      setFavScenes(s => s.filter(f => f.fid !== exists.fid));
      setToast({ kind:'removed', t, key:Date.now() });
    } else {
      const newScene = { videoId:video.id, t, label:`Scene at ${fmt(t)}` };
      const fid = await REEL_DB.addFavScene(video.id, t, newScene.label);
      setFavScenes(s => [...s, { ...newScene, fid }]);
      setToast({ kind:'added', t, key:Date.now() });
    }
    resetHideTimer();
  };

  React.useEffect(() => {
    if (!toast) return;
    const id = setTimeout(() => setToast(null), 1500);
    return () => clearTimeout(id);
  }, [toast]);

  const isFav = favScenes.some(f => Math.abs(f.t - pos) < 2);
  const minimal = chromeStyle === 'minimal';
  const visible = showControls || !playing;

  return (
    <div style={{ position:'absolute',inset:0,background:'#000',color:'#fff',overflow:'hidden',display:'flex',flexDirection:'column' }}
      onClick={() => { if (!locked) { resetHideTimer(); if (!showControls) setShowControls(true); } }}>

      {/* src via React state — survives re-renders. autoPlay helps mobile browsers start immediately */}
      <video ref={videoRef}
        src={videoSrc || undefined}
        style={{ position:'absolute',inset:0,width:'100%',height:'100%',objectFit:'contain',background:'#000' }}
        playsInline autoPlay preload="auto"
        onTimeUpdate={onTimeUpdate} onLoadedMetadata={onLoadedMetadata} onEnded={onEnded}
        onPlay={() => setPlaying(true)} onPause={() => setPlaying(false)}
      />

      {/* Brightness overlay */}
      <div style={{ position:'absolute',inset:0,background:`rgba(0,0,0,${(100-brightness)/200})`,pointerEvents:'none',zIndex:1 }}/>

      {/* Gesture capture surface — disabled when error is showing so buttons are tappable */}
      {!errorKind && (
        <div ref={surfaceRef} onPointerDown={e => { onSurfaceTap(e); onSurfacePointerDown(e); }}
          style={{ position:'absolute',inset:0,touchAction:'none',zIndex:2,cursor:'pointer' }}/>
      )}

      {/* Loading spinner */}
      {!loaded && !errorKind && (
        <div style={{ position:'absolute',inset:0,display:'flex',alignItems:'center',justifyContent:'center',zIndex:3,pointerEvents:'none' }}>
          <style>{`@keyframes spin{to{transform:rotate(360deg)}}`}</style>
          <div style={{ width:48,height:48,border:'3px solid rgba(255,255,255,0.2)',borderTopColor:'#fff',borderRadius:'50%',animation:'spin 0.8s linear infinite' }}/>
        </div>
      )}

      {/* Error / no-file state — solid background covers the striped video element */}
      {errorKind && (() => {
        const ext = (video.filename || video.title || '').split('.').pop().toLowerCase();
        const isMkv = ext === 'mkv';
        const cs = window.REEL_CODEC_SUPPORT || {};
        // If browser doesn't report H.265 support AND this is an MKV codec error,
        // we know specifically it's an H.265/HEVC issue.
        const noH265 = !cs.h265 && !cs.mkvH265;
        const isMkvCodec = errorKind === 'codec' && isMkv;
        const isH265Issue = isMkvCodec && noH265;

        // Retry: clear source elements and try plain src without MIME hints
        const handleRetry = () => {
          const vid = videoRef.current;
          if (!vid || !urlRef.current) return;
          setRetrying(true);
          setErrorKind(null); setErrorMsg(''); setLoaded(false);
          while (vid.firstChild) vid.removeChild(vid.firstChild);
          vid.removeAttribute('src');
          vid.src = urlRef.current;
          vid.load();
          const startAt = video.resumePos || 0;
          const resume = () => {
            if (startAt > 2) try { vid.currentTime = startAt; } catch(e) {}
            vid.play().then(() => { setPlaying(true); setRetrying(false); }).catch(() => setRetrying(false));
            vid.removeEventListener('canplay', resume);
          };
          vid.addEventListener('canplay', resume);
        };

        return (
          <div style={{ position:'absolute',inset:0,background:'#0a0a0a',display:'flex',flexDirection:'column',alignItems:'center',justifyContent:'center',gap:18,zIndex:10,padding:'32px 24px',textAlign:'center',overflowY:'auto' }}>
            <button onClick={onBack} style={{ position:'absolute',top:14,left:12,...pIconBtn }}>
              <Icon name="back" size={22}/>
            </button>

            <div style={{ width:72,height:72,borderRadius:22,background:'rgba(255,255,255,0.05)',border:'1px solid rgba(255,255,255,0.08)',display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0 }}>
              <Icon name={errorKind==='no-file'?'file':'film'} size={34} color="rgba(255,255,255,0.35)"/>
            </div>

            <div style={{ maxWidth:320 }}>
              <div style={{ fontSize:18,fontWeight:700,color:'#fff',marginBottom:8 }}>
                {errorKind==='no-file'  ? 'File not accessible'
                  : isH265Issue         ? 'H.265 decoder missing'
                  : isMkvCodec          ? 'MKV codec not supported'
                  : errorKind==='codec' ? 'Format not supported'
                  : 'Playback error'}
              </div>
              <div style={{ fontSize:13,color:'rgba(255,255,255,0.45)',lineHeight:1.75 }}>
                {errorKind==='no-file'
                  ? 'This video is not available this session. Select it below to play.'
                  : isH265Issue
                  ? 'Your browser does not have an H.265 (HEVC) decoder. Install the free Windows extension to fix this.'
                  : isMkvCodec
                  ? 'MKV plays in Chrome with H.264 or VP9. H.265 needs a hardware decoder — tap Retry to try.'
                  : 'This format is not supported. Try a different file or convert to MP4 H.264.'}
              </div>
            </div>

            {/* ── No-file: pick the file ── */}
            {errorKind === 'no-file' && (
              <button onClick={handleReselect} disabled={reselecting}
                style={{ padding:'14px 32px',borderRadius:14,border:'none',background:accent,color:'#000',fontFamily:'inherit',fontSize:15,fontWeight:700,cursor:'pointer',display:'flex',alignItems:'center',gap:10,opacity:reselecting?0.6:1,minWidth:220,justifyContent:'center' }}>
                <Icon name="file" size={20} color="#000"/>
                {reselecting ? 'Opening picker…' : 'Select the video file'}
              </button>
            )}

            {/* ── H.265 missing: install guide ── */}
            {isH265Issue && (
              <div style={{ background:'rgba(239,68,68,0.08)',borderRadius:14,padding:'14px 18px',fontSize:12,color:'rgba(255,255,255,0.55)',textAlign:'left',width:'100%',maxWidth:320,border:'1px solid rgba(239,68,68,0.2)' }}>
                <div style={{ color:'#f87171',fontWeight:700,marginBottom:8,fontSize:13 }}>Fix in 30 seconds on Windows</div>
                <div style={{ marginBottom:4 }}>1. Open <b style={{color:'rgba(255,255,255,0.8)'}}>Microsoft Store</b> on your PC</div>
                <div style={{ marginBottom:4 }}>2. Search <b style={{color:'rgba(255,255,255,0.8)'}}>HEVC Video Extensions</b></div>
                <div style={{ marginBottom:4 }}>3. Install the free version (from Device Manufacturer)</div>
                <div style={{ marginBottom:10 }}>4. Restart Chrome and come back</div>
                <div style={{ color:'rgba(255,255,255,0.3)',fontSize:11 }}>Or convert your MKV to MP4 using VLC (free) — it plays everywhere without any extension.</div>
              </div>
            )}

            {/* ── MKV codec (H.264 or unknown): retry ── */}
            {isMkvCodec && !isH265Issue && (
              <button onClick={handleRetry} disabled={retrying}
                style={{ padding:'13px 28px',borderRadius:14,border:'none',background:accent,color:'#000',fontFamily:'inherit',fontSize:14,fontWeight:700,cursor:'pointer',display:'flex',alignItems:'center',gap:10,opacity:retrying?0.6:1,minWidth:200,justifyContent:'center' }}>
                <Icon name="play" size={18} color="#000"/>
                {retrying ? 'Trying…' : 'Retry playback'}
              </button>
            )}

            {/* ── Generic codec error info ── */}
            {errorKind === 'codec' && !isMkvCodec && (
              <div style={{ background:'rgba(255,255,255,0.04)',borderRadius:12,padding:'12px 16px',fontSize:12,color:'rgba(255,255,255,0.38)',textAlign:'left',width:'100%',maxWidth:320,border:'1px solid rgba(255,255,255,0.07)' }}>
                <div style={{ color:'rgba(255,255,255,0.6)',fontWeight:700,marginBottom:6 }}>Plays in Chrome</div>
                <div>✓ MP4 (H.264) &nbsp; ✓ WebM (VP8/VP9/AV1)</div>
                <div>✓ MKV (H.264 / VP9)</div>
                <div style={{ marginTop:6,color:'rgba(255,255,255,0.22)' }}>✗ AVI, WMV, FLV — convert to MP4</div>
              </div>
            )}

            {/* ── Pick different file (for all non-no-file errors) ── */}
            {errorKind !== 'no-file' && (
              <button onClick={handleReselect} disabled={reselecting}
                style={{ padding:'10px 22px',borderRadius:12,border:'1px solid rgba(255,255,255,0.1)',background:'rgba(255,255,255,0.04)',color:'rgba(255,255,255,0.6)',fontFamily:'inherit',fontSize:13,fontWeight:600,cursor:'pointer',display:'flex',alignItems:'center',gap:8,justifyContent:'center' }}>
                <Icon name="file" size={15} color="rgba(255,255,255,0.6)"/>
                {reselecting ? 'Opening picker…' : 'Pick a different file'}
              </button>
            )}

            {/* ── Drag hint for desktop ── */}
            <div style={{ fontSize:11,color:'rgba(255,255,255,0.18)',marginTop:4 }}>
              On PC you can also drag &amp; drop a video file onto the Reel window
            </div>
          </div>
        );
      })()}

      {/* Skip pulse */}
      {skipPulse && <SkipPulse side={skipPulse.side} amount={skipSeconds} accent={accent}/>}

      {/* Top controls — hidden when error is showing (error screen has its own back button) */}
      {!locked && visible && !errorKind && (
        <div style={{ position:'absolute',top:0,left:0,right:0,zIndex:4,padding:'14px 12px',background:minimal?'transparent':'linear-gradient(to bottom, rgba(0,0,0,0.75), transparent)',display:'flex',alignItems:'center',gap:6 }}>
          <button onClick={onBack} style={pIconBtn}><Icon name="back" size={22}/></button>
          <div style={{ flex:1,minWidth:0 }}>
            <div style={{ fontSize:14,fontWeight:600,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap' }}>{video.title}</div>
            <div style={{ fontSize:11,color:'rgba(255,255,255,0.6)',fontFamily:TP.mono,marginTop:1 }}>{video.res||''}{video.res&&' · '}{video.codec||''}</div>
          </div>
          {!minimal && <>
            <button style={pIconBtn} onClick={markFavScene}><Icon name={isFav?'heart-fill':'heart'} size={20} color={isFav?accent:'#fff'}/></button>
            <button style={pIconBtn} onClick={() => setOverlay('pip')}><Icon name="pip" size={20}/></button>
            <button style={pIconBtn} onClick={() => setOverlay('more')}><Icon name="more" size={20}/></button>
          </>}
          {minimal && <>
            <button style={pIconBtn} onClick={markFavScene}><Icon name={isFav?'heart-fill':'heart'} size={20} color={isFav?accent:'#fff'}/></button>
            <button style={pIconBtn} onClick={() => setOverlay('more')}><Icon name="more" size={20}/></button>
          </>}
        </div>
      )}

      {/* Lock overlay */}
      {locked && (
        <button onClick={() => setLocked(false)} style={{ position:'absolute',top:60,left:'50%',transform:'translateX(-50%)',width:56,height:56,borderRadius:28,border:'none',background:'rgba(0,0,0,0.5)',backdropFilter:'blur(8px)',color:'#fff',display:'flex',alignItems:'center',justifyContent:'center',cursor:'pointer',zIndex:5 }}>
          <Icon name="lock" size={24}/>
        </button>
      )}

      {/* Center play/pause + skip — hidden when error is showing */}
      {!locked && !minimal && visible && !errorKind && (
        <div style={{ position:'absolute',inset:0,display:'flex',alignItems:'center',justifyContent:'center',gap:40,zIndex:3,pointerEvents:'none' }}>
          <button style={{ ...pCenterBtn,pointerEvents:'auto' }} onClick={() => { seekTo(pos-skipSeconds); resetHideTimer(); }}>
            <Icon name="back10" size={26} text={skipSeconds}/>
          </button>
          <button style={{ ...pCenterBtn,width:72,height:72,background:accent,color:'#000',pointerEvents:'auto' }} onClick={togglePlay}>
            <Icon name={playing?'pause':'play'} size={32} color="#000"/>
          </button>
          <button style={{ ...pCenterBtn,pointerEvents:'auto' }} onClick={() => { seekTo(pos+skipSeconds); resetHideTimer(); }}>
            <Icon name="fwd10" size={26} text={skipSeconds}/>
          </button>
        </div>
      )}

      {/* Gesture indicator */}
      {!locked && showGesture && <GestureIndicator info={showGesture} accent={accent}/>}

      {/* Subtitle layer */}
      {!locked && <SubtitleLayer style={subtitleStyle} dual={dualSubs}/>}

      {/* Bottom controls */}
      {!locked && visible && (
        <div style={{ position:'absolute',bottom:0,left:0,right:0,zIndex:4,padding:minimal?'0 12px 14px':'60px 12px 14px',background:minimal?'transparent':'linear-gradient(to top, rgba(0,0,0,0.88), transparent)' }}>
          {!minimal && (
            <div style={{ display:'flex',alignItems:'center',justifyContent:'space-between',padding:'0 4px 8px' }}>
              <div style={{ fontFamily:TP.mono,fontSize:12,fontWeight:600 }}>
                {fmt(pos)} <span style={{ color:'rgba(255,255,255,0.5)' }}>/ {duration>0?fmt(duration):'--:--'}</span>
              </div>
              <button onClick={() => setOverlay('chapters')} style={{ background:'rgba(255,255,255,0.08)',border:'none',color:'#fff',fontFamily:'inherit',fontSize:11.5,fontWeight:600,padding:'4px 10px',borderRadius:10,cursor:'pointer',display:'flex',alignItems:'center',gap:4 }}>
                <Icon name="bookmark" size={12}/><span>Chapters</span><Icon name="chev-down" size={12}/>
              </button>
            </div>
          )}
          <SeekBar pos={pos} duration={duration} accent={accent} onChange={seekTo} favScenes={favScenes} bookmarks={bookmarks}/>
          {minimal && (
            <div style={{ display:'flex',alignItems:'center',justifyContent:'space-between',padding:'6px 4px 0' }}>
              <div style={{ fontFamily:TP.mono,fontSize:11,color:'rgba(255,255,255,0.7)' }}>{fmt(pos)} / {duration>0?fmt(duration):'--:--'}</div>
              <div style={{ display:'flex',gap:4 }}>
                <button style={pIconBtn} onClick={togglePlay}><Icon name={playing?'pause':'play'} size={22}/></button>
                <button style={pIconBtn} onClick={() => setOverlay('subtitle')}><Icon name="cc" size={20}/></button>
              </div>
            </div>
          )}
          {!minimal && (
            <div style={{ display:'flex',alignItems:'center',gap:2,marginTop:4 }}>
              <button style={pIconBtn} onClick={() => setLocked(true)}><Icon name="unlock" size={20}/></button>
              <button style={pIconBtn} onClick={() => setOverlay('subtitle')}><Icon name="cc" size={20}/></button>
              <button style={pIconBtn} onClick={() => setOverlay('audio')}><Icon name="audio" size={20}/></button>
              <button style={pIconBtn} onClick={() => setOverlay('rotation')}><Icon name="rotate" size={20}/></button>
              <div style={{ flex:1 }}/>
              <button onClick={() => setOverlay('speed')} style={{ background:'rgba(255,255,255,0.08)',border:'none',color:'#fff',fontFamily:TP.mono,fontSize:13,fontWeight:700,padding:'7px 12px',borderRadius:10,cursor:'pointer' }}>{speed}×</button>
              <button style={pIconBtn} onClick={() => setOverlay('settings')}><Icon name="gear" size={20}/></button>
            </div>
          )}
        </div>
      )}

      {/* Fav-scene toast */}
      {toast && <FavToast key={toast.key} info={toast} accent={accent}/>}
    </div>
  );
}

// ── Fav scene toast ────────────────────────────────────────────────────
function FavToast({ info, accent }) {
  const added = info.kind === 'added';
  return (
    <>
      <style>{`@keyframes fav-pill{0%{opacity:0;transform:translate(-50%,-6px)}15%,85%{opacity:1;transform:translate(-50%,0)}100%{opacity:0;transform:translate(-50%,-4px)}}`}</style>
      <div style={{ position:'absolute',top:60,left:'50%',zIndex:10,animation:'fav-pill 1500ms ease-out forwards',pointerEvents:'none',background:'rgba(0,0,0,0.7)',backdropFilter:'blur(10px)',border:'1px solid rgba(255,255,255,0.10)',borderRadius:20,padding:'7px 14px 7px 11px',display:'flex',alignItems:'center',gap:8 }}>
        <Icon name={added?'heart-fill':'heart'} size={14} color={added?accent:'#fff'}/>
        <div style={{ fontSize:12,fontWeight:600,color:'#fff' }}>
          {added?'Scene saved':'Scene removed'}
          <span style={{ fontFamily:TP.mono,color:'rgba(255,255,255,0.55)',marginLeft:8,fontWeight:500 }}>{fmt(info.t)}</span>
        </div>
      </div>
    </>
  );
}

// ── Gesture indicator ──────────────────────────────────────────────────
function GestureIndicator({ info, accent }) {
  if (info.type === 'brightness' || info.type === 'volume') {
    const isVol = info.type === 'volume';
    return (
      <div style={{ position:'absolute',[isVol?'right':'left']:22,top:'50%',transform:'translateY(-50%)',zIndex:5,background:'rgba(0,0,0,0.65)',backdropFilter:'blur(8px)',padding:'14px 12px',borderRadius:14,display:'flex',flexDirection:'column',alignItems:'center',gap:8,border:'1px solid rgba(255,255,255,0.08)',pointerEvents:'none' }}>
        <Icon name={isVol?(info.value<5?'volume-x':'volume'):'sun'} size={20} color="#fff"/>
        <div style={{ width:5,height:120,borderRadius:3,background:'rgba(255,255,255,0.2)',position:'relative',overflow:'hidden' }}>
          <div style={{ position:'absolute',bottom:0,left:0,right:0,height:`${info.value}%`,background:'#fff',transition:'height 60ms linear' }}/>
        </div>
        <div style={{ fontFamily:TP.mono,fontSize:12,fontWeight:700,color:'#fff' }}>{info.value}</div>
        <div style={{ fontSize:9,color:'rgba(255,255,255,0.55)',textTransform:'uppercase',letterSpacing:1,fontWeight:700 }}>{isVol?'Volume':'Brightness'}</div>
      </div>
    );
  }
  if (info.type === 'seek') {
    const sign = info.delta >= 0 ? '+' : '−';
    return (
      <div style={{ position:'absolute',top:'40%',left:'50%',transform:'translate(-50%,-50%)',zIndex:5,background:'rgba(0,0,0,0.7)',backdropFilter:'blur(10px)',padding:'14px 22px',borderRadius:16,display:'flex',flexDirection:'column',alignItems:'center',gap:4,border:'1px solid rgba(255,255,255,0.08)',pointerEvents:'none' }}>
        <div style={{ fontFamily:TP.mono,fontSize:28,fontWeight:800,color:'#fff',letterSpacing:-1 }}>{fmt(info.to)}</div>
        <div style={{ fontFamily:TP.mono,fontSize:12,fontWeight:700,color:accent }}>{sign}{Math.abs(Math.round(info.delta))}s</div>
      </div>
    );
  }
  return null;
}

// ── Skip pulse ─────────────────────────────────────────────────────────
function SkipPulse({ side, amount, accent }) {
  const isRight = side === 'r';
  return (
    <>
      <style>{`@keyframes skip-ring{0%{opacity:0;transform:scale(0.6)}30%{opacity:1}100%{opacity:0;transform:scale(1.4)}} @keyframes skip-arrows{0%{opacity:0;transform:translateX(${isRight?'-':''}8px)}50%{opacity:1;transform:translateX(0)}100%{opacity:0;transform:translateX(${isRight?'':'- '}8px)}}`}</style>
      <div style={{ position:'absolute',top:0,bottom:0,[isRight?'right':'left']:0,width:'40%',display:'flex',alignItems:'center',justifyContent:'center',zIndex:4,pointerEvents:'none',background:`radial-gradient(circle at ${isRight?'right':'left'} center, rgba(255,255,255,0.10), transparent 60%)`,animation:'skip-ring 600ms ease-out forwards' }}>
        <div style={{ display:'flex',flexDirection:'column',alignItems:'center',gap:6,animation:'skip-arrows 600ms ease-out forwards' }}>
          <Icon name={isRight?'fwd10':'back10'} size={32} text={amount}/>
          <div style={{ fontFamily:TP.mono,fontSize:11,fontWeight:700,color:'#fff' }}>{amount}s</div>
        </div>
      </div>
    </>
  );
}

// ── Subtitle layer ─────────────────────────────────────────────────────
function SubtitleLayer({ style, dual }) {
  const base = { position:'absolute',left:0,right:0,textAlign:'center',zIndex:3,pointerEvents:'none',padding:'0 24px' };
  const styles = {
    cinema:  { fontSize:17,fontWeight:700,color:'#fff',textShadow:'0 2px 6px rgba(0,0,0,0.85), 0 0 2px rgba(0,0,0,0.9)' },
    netflix: { fontSize:16,fontWeight:600,color:'#fff',background:'rgba(0,0,0,0.55)',display:'inline-block',padding:'2px 8px' },
    classic: { fontSize:16,fontWeight:500,color:'#ffe45e',textShadow:'0 1px 0 #000, 0 0 2px #000' },
    minimal: { fontSize:15,fontWeight:500,color:'rgba(255,255,255,0.92)' },
  };
  const s = styles[style] || styles.cinema;
  return null; // Subtitle rendering is for real subtitle tracks — shown by <track> elements
}

// ── Speed sheet ────────────────────────────────────────────────────────
function SpeedSheet({ onClose, accent, speed, onSpeed }) {
  const speeds = [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0];
  return (
    <Sheet title="Playback speed" onClose={onClose}>
      <div style={{ display:'flex',flexDirection:'column',gap:4,paddingBottom:8 }}>
        {speeds.map(s => (
          <button key={s} onClick={() => { onSpeed(s); onClose(); }} style={{ display:'flex',alignItems:'center',gap:14,padding:'12px 14px',borderRadius:12,border:'1px solid',borderColor:speed===s?accent:TP.border,background:speed===s?accentSoftColor(accent):'transparent',color:TP.text,fontFamily:'inherit',cursor:'pointer',width:'100%' }}>
            <div style={{ fontFamily:TP.mono,fontSize:18,fontWeight:700,width:48 }}>{s}×</div>
            <div style={{ flex:1,textAlign:'left' }}>
              <div style={{ fontSize:13,color:TP.textDim }}>{s===1?'Normal':s<1?'Slower':'Faster'}</div>
            </div>
            {speed===s && <Icon name="check" size={18} color={accent}/>}
          </button>
        ))}
      </div>
    </Sheet>
  );
}

// ── Subtitle sheet ─────────────────────────────────────────────────────
function SubtitleSheet({ onClose, accent, dualSubs, setDualSubs, onAdd }) {
  const [primary, setPrimary] = React.useState(0);
  const [offset, setOffset]   = React.useState(0);
  return (
    <Sheet title="Subtitles" sub="Choose track, sync & style" onClose={onClose}>
      <div style={{ display:'flex',gap:6,marginBottom:12 }}>
        <Chip active style={{ borderColor:accent,color:accent,background:accentSoftColor(accent) }}>Primary</Chip>
        <Chip active={dualSubs} onClick={() => setDualSubs(d=>!d)} style={dualSubs?{ borderColor:accent,color:accent,background:accentSoftColor(accent) }:{}}>Dual {dualSubs?'on':'off'}</Chip>
      </div>
      <div style={{ display:'flex',flexDirection:'column',gap:4 }}>
        <div style={{ fontSize:11,color:TP.textMuted,textTransform:'uppercase',letterSpacing:1,padding:'4px 4px 6px' }}>Available tracks</div>
        {REEL_SUBTITLES.length === 0 && (
          <div style={{ padding:'20px',textAlign:'center',color:TP.textDim,fontSize:13 }}>No embedded subtitle tracks</div>
        )}
        {REEL_SUBTITLES.map((s,i) => (
          <button key={i} onClick={() => setPrimary(i)} style={{ display:'flex',alignItems:'center',gap:12,padding:'10px 12px',borderRadius:12,border:'1px solid',borderColor:primary===i?accent:TP.border,background:primary===i?accentSoftColor(accent):'transparent',color:TP.text,fontFamily:'inherit',cursor:'pointer',width:'100%' }}>
            <div style={{ width:28,height:28,borderRadius:6,background:TP.surface3,display:'flex',alignItems:'center',justifyContent:'center',fontSize:9,fontWeight:800,fontFamily:TP.mono,color:s.type==='cloud'?accent:TP.textDim }}>{s.type==='cloud'?'OS':s.type==='file'?'SRT':'EMB'}</div>
            <div style={{ flex:1,textAlign:'left' }}>
              <div style={{ fontSize:14,fontWeight:600 }}>{s.lang}</div>
              <div style={{ fontSize:11.5,color:TP.textDim,marginTop:1,fontFamily:TP.mono }}>{s.src}</div>
            </div>
            {primary===i && <Icon name="check" size={18} color={accent}/>}
          </button>
        ))}
        <button style={{ display:'flex',alignItems:'center',gap:12,padding:'10px 12px',borderRadius:12,border:'1px dashed '+TP.borderStrong,background:'transparent',color:TP.text,fontFamily:'inherit',cursor:'pointer',width:'100%' }} onClick={() => onAdd('file')}>
          <div style={{ width:28,height:28,borderRadius:6,background:TP.surface3,display:'flex',alignItems:'center',justifyContent:'center' }}><Icon name="file" size={14} color={TP.textDim}/></div>
          <div style={{ flex:1,textAlign:'left',fontSize:14,fontWeight:600 }}>Add from device file…</div>
        </button>
        <button style={{ display:'flex',alignItems:'center',gap:12,padding:'10px 12px',borderRadius:12,border:'1px dashed '+TP.borderStrong,background:'transparent',color:TP.text,fontFamily:'inherit',cursor:'pointer',width:'100%' }} onClick={() => onAdd('online')}>
          <div style={{ width:28,height:28,borderRadius:6,background:TP.surface3,display:'flex',alignItems:'center',justifyContent:'center' }}><Icon name="download" size={14} color={TP.textDim}/></div>
          <div style={{ flex:1,textAlign:'left' }}><div style={{ fontSize:14,fontWeight:600 }}>Search OpenSubtitles…</div><div style={{ fontSize:11,color:TP.textDim }}>3.4M titles · free</div></div>
        </button>
      </div>
      <div style={{ marginTop:16,padding:14,borderRadius:14,background:TP.surface2,border:'1px solid '+TP.border }}>
        <div style={{ display:'flex',alignItems:'center',justifyContent:'space-between',marginBottom:10 }}>
          <div style={{ fontSize:13,fontWeight:600 }}>Sync offset</div>
          <div style={{ fontFamily:TP.mono,fontSize:13,color:accent,fontWeight:700 }}>{offset>0?'+':''}{offset.toFixed(1)}s</div>
        </div>
        <div style={{ display:'flex',gap:6 }}>
          {[-1,-0.1,'reset','+0.1','+1'].map(k => (
            <button key={k} onClick={() => { if(k==='reset') setOffset(0); else setOffset(o=>+(o+parseFloat(k)).toFixed(1)); }} style={{ flex:1,padding:'8px 0',borderRadius:10,border:'1px solid '+TP.border,background:TP.surface,color:TP.text,fontFamily:TP.mono,fontSize:12,fontWeight:700,cursor:'pointer' }}>
              {k==='reset'?'Reset':typeof k==='string'?k:k>0?'+'+k:k}
            </button>
          ))}
        </div>
      </div>
    </Sheet>
  );
}

// ── EQ sheet ───────────────────────────────────────────────────────────
function EQSheet({ onClose, accent }) {
  const bands = [['60Hz',0],['250Hz',2],['1kHz',0],['4kHz',-1],['16kHz',1]];
  const [vals, setVals] = React.useState(bands.map(b=>b[1]));
  return (
    <Sheet title="Equalizer" sub="Drag bands to adjust" onClose={onClose}>
      <div style={{ display:'flex',gap:8,justifyContent:'center',padding:'16px 0 24px',alignItems:'flex-end',height:200 }}>
        {bands.map(([label],i) => (
          <div key={i} style={{ flex:1,display:'flex',flexDirection:'column',alignItems:'center',gap:8,height:'100%',justifyContent:'flex-end' }}>
            <div style={{ fontSize:11,fontFamily:TP.mono,color:accent,fontWeight:700 }}>{vals[i]>0?'+':''}{vals[i]}</div>
            <div style={{ flex:1,display:'flex',flexDirection:'column',alignItems:'center',justifyContent:'center',position:'relative',width:'100%' }}>
              <div style={{ width:4,height:'100%',background:TP.surface2,borderRadius:2,position:'absolute' }}/>
              <div style={{ width:4,height:`${50-(vals[i]/12)*50}%`,background:accent,borderRadius:2,position:'absolute',top:0,transition:'height .1s' }}/>
              <div style={{ width:18,height:18,borderRadius:9,background:accent,position:'absolute',top:`${50-(vals[i]/12)*50}%`,transform:'translateY(-50%)',cursor:'ns-resize',zIndex:1 }}
                onPointerDown={e => {
                  const startY=e.clientY, startVal=vals[i];
                  const move=ev => { const dy=ev.clientY-startY; setVals(v=>{const n=[...v]; n[i]=Math.max(-12,Math.min(12,Math.round(startVal-dy/4))); return n;}); };
                  const up=()=>{ window.removeEventListener('pointermove',move); window.removeEventListener('pointerup',up); };
                  e.target.setPointerCapture&&e.target.setPointerCapture(e.pointerId);
                  window.addEventListener('pointermove',move); window.addEventListener('pointerup',up);
                }}/>
            </div>
            <div style={{ fontSize:10,color:TP.textDim,fontFamily:TP.mono }}>{label}</div>
          </div>
        ))}
      </div>
      <div style={{ display:'flex',gap:8 }}>
        <button onClick={() => setVals(bands.map(b=>b[1]))} style={{ flex:1,padding:'11px',borderRadius:12,border:'1px solid '+TP.border,background:'transparent',color:TP.text,fontFamily:'inherit',fontSize:13,fontWeight:700,cursor:'pointer' }}>Reset</button>
        <button onClick={onClose} style={{ flex:2,padding:'11px',borderRadius:12,border:'none',background:accent,color:'#000',fontFamily:'inherit',fontSize:13,fontWeight:800,cursor:'pointer' }}>Apply</button>
      </div>
    </Sheet>
  );
}

// ── Sleep timer sheet ──────────────────────────────────────────────────
function SleepSheet({ onClose, accent }) {
  const [sel, setSel] = React.useState(null);
  const opts = [5,10,15,20,30,45,60,90];
  return (
    <Sheet title="Sleep timer" sub="Pause after a set time" onClose={onClose}>
      <div style={{ display:'grid',gridTemplateColumns:'repeat(4,1fr)',gap:8,padding:'8px 0 16px' }}>
        {opts.map(m => (
          <button key={m} onClick={() => setSel(m)} style={{ padding:'14px 0',borderRadius:14,border:'1px solid',borderColor:sel===m?accent:TP.border,background:sel===m?accentSoftColor(accent):'transparent',color:sel===m?accent:TP.text,fontFamily:'inherit',fontWeight:700,cursor:'pointer',display:'flex',flexDirection:'column',alignItems:'center',gap:4 }}>
            <span style={{ fontSize:22,fontFamily:TP.mono }}>{m}</span>
            <span style={{ fontSize:11,color:TP.textDim }}>min</span>
          </button>
        ))}
      </div>
      <button onClick={onClose} disabled={!sel} style={{ width:'100%',padding:'14px',borderRadius:14,border:'none',background:sel?accent:TP.surface2,color:sel?'#000':TP.textMuted,fontFamily:'inherit',fontSize:15,fontWeight:800,cursor:sel?'pointer':'default' }}>
        {sel?`Set timer for ${sel} min`:'Choose a duration'}
      </button>
    </Sheet>
  );
}

// ── Bookmarks / Chapters sheet ─────────────────────────────────────────
function BookmarksSheet({ onClose, accent, favScenes=[], bookmarks=[] }) {
  return (
    <Sheet title="Chapters & Bookmarks" onClose={onClose} height="full">
      {bookmarks.length === 0 && favScenes.length === 0 && (
        <div style={{ padding:'40px 0',textAlign:'center',color:TP.textDim }}>
          <Icon name="bookmark" size={36} color={TP.textMuted}/>
          <div style={{ fontSize:13,marginTop:12 }}>No bookmarks or favorite scenes yet</div>
          <div style={{ fontSize:11,marginTop:4 }}>Tap ♡ in the player to save a favorite scene</div>
        </div>
      )}
      {favScenes.length > 0 && (
        <div style={{ marginBottom:20 }}>
          <div style={{ fontSize:11,color:TP.textMuted,textTransform:'uppercase',letterSpacing:1,padding:'0 0 8px' }}>Favorite scenes</div>
          {favScenes.map((f,i) => (
            <div key={i} style={{ display:'flex',alignItems:'center',gap:12,padding:'10px 0',borderBottom:'1px solid '+TP.border }}>
              <div style={{ width:48,height:32,borderRadius:6,flexShrink:0,position:'relative',overflow:'hidden' }}>
                <div style={{ position:'absolute',inset:0,background:`oklch(0.22 0.04 ${(f.t||0)%360})` }}/>
              </div>
              <div style={{ flex:1,minWidth:0 }}>
                <div style={{ fontSize:13,fontWeight:600 }}>{f.label||`Scene at ${fmt(f.t)}`}</div>
                <div style={{ fontSize:11,fontFamily:TP.mono,color:TP.textDim,marginTop:2 }}>{fmt(f.t)}</div>
              </div>
              <Icon name="heart-fill" size={16} color={accent}/>
            </div>
          ))}
        </div>
      )}
      {bookmarks.length > 0 && (
        <div>
          <div style={{ fontSize:11,color:TP.textMuted,textTransform:'uppercase',letterSpacing:1,padding:'0 0 8px' }}>Bookmarks</div>
          {bookmarks.map((b,i) => (
            <div key={i} style={{ display:'flex',alignItems:'center',gap:12,padding:'10px 0',borderBottom:'1px solid '+TP.border }}>
              <div style={{ fontFamily:TP.mono,fontSize:13,fontWeight:700,color:accent,width:48,flexShrink:0 }}>{fmt(b.t)}</div>
              <div style={{ flex:1,fontSize:13 }}>{b.label||`Bookmark at ${fmt(b.t)}`}</div>
              <Icon name="bookmark-fill" size={16} color={accent}/>
            </div>
          ))}
        </div>
      )}
    </Sheet>
  );
}

// ── Audio track sheet ──────────────────────────────────────────────────
function AudioSheet({ onClose, accent }) {
  const [sel, setSel] = React.useState(0);
  const tracks = [{ label:'English (AC3 · 5.1)' },{ label:'Japanese (AAC · 2.0)' },{ label:'Commentary' }];
  return (
    <Sheet title="Audio track" onClose={onClose}>
      <div style={{ display:'flex',flexDirection:'column',gap:4,paddingBottom:8 }}>
        {tracks.map((t,i) => (
          <button key={i} onClick={() => setSel(i)} style={{ display:'flex',alignItems:'center',gap:14,padding:'12px 14px',borderRadius:12,border:'1px solid',borderColor:sel===i?accent:TP.border,background:sel===i?accentSoftColor(accent):'transparent',color:TP.text,fontFamily:'inherit',cursor:'pointer',width:'100%' }}>
            <Icon name="audio" size={20} color={sel===i?accent:TP.textDim}/>
            <div style={{ flex:1,textAlign:'left',fontSize:14,fontWeight:600 }}>{t.label}</div>
            {sel===i && <Icon name="check" size={18} color={accent}/>}
          </button>
        ))}
      </div>
    </Sheet>
  );
}

// ── Player settings sheet ──────────────────────────────────────────────
function PlayerSettingsSheet({ onClose, accent, setOverlay }) {
  return (
    <Sheet title="Player settings" onClose={onClose}>
      <div style={{ display:'flex',flexDirection:'column',gap:2,paddingBottom:8 }}>
        {[
          { icon:'speed',    label:'Playback speed',     sub:'1.0×',    action:'speed' },
          { icon:'eq',       label:'Equalizer',          sub:'Flat',     action:'eq' },
          { icon:'timer',    label:'Sleep timer',        sub:'Off',     action:'sleep' },
          { icon:'bookmark', label:'Chapters & bookmarks', sub:'',      action:'chapters' },
          { icon:'cc',       label:'Subtitles',          sub:'Off',     action:'subtitle' },
          { icon:'audio',    label:'Audio track',        sub:'Track 1', action:'audio' },
          { icon:'rotate',   label:'Rotation lock',      sub:'Auto',    action:'rotation' },
          { icon:'aspect',   label:'Aspect ratio',       sub:'Fit',     action:null },
          { icon:'pip',      label:'Picture-in-Picture', sub:'',        action:'pip' },
        ].map(item => (
          <button key={item.label} onClick={() => { if(item.action) { onClose(); setOverlay(item.action); }}} style={{ display:'flex',alignItems:'center',gap:14,padding:'13px 14px',borderRadius:12,border:'none',background:'transparent',color:TP.text,fontFamily:'inherit',cursor:item.action?'pointer':'default',width:'100%' }}>
            <Icon name={item.icon} size={20} color={TP.textDim}/>
            <div style={{ flex:1,textAlign:'left',fontSize:14 }}>{item.label}</div>
            {item.sub && <div style={{ fontSize:13,color:TP.textDim }}>{item.sub}</div>}
            <Icon name="chev-right" size={16} color={TP.textMuted}/>
          </button>
        ))}
      </div>
    </Sheet>
  );
}

// ── Rotation sheet ─────────────────────────────────────────────────────
function RotationSheet({ onClose, accent }) {
  const [sel, setSel] = React.useState('auto');
  const opts = [['auto','Auto-rotate','Follows device sensor'],['portrait','Lock portrait','Always upright'],['landscape','Lock landscape','Always wide']];
  return (
    <Sheet title="Rotation lock" onClose={onClose}>
      <div style={{ display:'flex',flexDirection:'column',gap:6,paddingBottom:8 }}>
        {opts.map(([v,l,d]) => (
          <button key={v} onClick={() => setSel(v)} style={{ display:'flex',alignItems:'center',gap:14,padding:'14px',borderRadius:14,border:'1px solid',borderColor:sel===v?accent:TP.border,background:sel===v?accentSoftColor(accent):'transparent',color:TP.text,fontFamily:'inherit',cursor:'pointer',width:'100%' }}>
            <Icon name="rotate" size={22} color={sel===v?accent:TP.textDim}/>
            <div style={{ flex:1,textAlign:'left' }}><div style={{ fontSize:14,fontWeight:600 }}>{l}</div><div style={{ fontSize:12,color:TP.textDim,marginTop:2 }}>{d}</div></div>
            <div style={{ width:18,height:18,borderRadius:9,border:`2px solid ${sel===v?accent:TP.border}`,background:sel===v?accent:'transparent',flexShrink:0 }}/>
          </button>
        ))}
      </div>
    </Sheet>
  );
}

// ── PiP overlay ────────────────────────────────────────────────────────
function PiPOverlay({ video, onClose, accent }) {
  return (
    <div style={{ position:'absolute',inset:0,zIndex:20,background:'rgba(0,0,0,0.6)',backdropFilter:'blur(4px)',display:'flex',flexDirection:'column',alignItems:'center',justifyContent:'center',gap:20 }}>
      <div style={{ width:240,height:135,borderRadius:12,overflow:'hidden',position:'relative',border:'2px solid rgba(255,255,255,0.2)' }}>
        <Thumbnail hue={video.hue} label="" aspect="auto" radius={0} style={{ position:'absolute',inset:0,aspectRatio:'auto',borderRadius:0 }}/>
        <div style={{ position:'absolute',inset:0,display:'flex',alignItems:'center',justifyContent:'center' }}>
          <Icon name="pip" size={32} color="rgba(255,255,255,0.6)"/>
        </div>
      </div>
      <div style={{ textAlign:'center' }}>
        <div style={{ fontSize:17,fontWeight:700,color:'#fff' }}>Picture-in-Picture</div>
        <div style={{ fontSize:13,color:'rgba(255,255,255,0.6)',marginTop:6 }}>Available when supported by your browser</div>
      </div>
      <div style={{ display:'flex',gap:12 }}>
        <button onClick={onClose} style={{ padding:'12px 24px',borderRadius:14,border:'1px solid rgba(255,255,255,0.2)',background:'transparent',color:'#fff',fontFamily:'inherit',fontSize:14,fontWeight:600,cursor:'pointer' }}>Cancel</button>
        <button onClick={() => { document.querySelector('video')?.requestPictureInPicture?.(); onClose(); }} style={{ padding:'12px 24px',borderRadius:14,border:'none',background:accent,color:'#000',fontFamily:'inherit',fontSize:14,fontWeight:700,cursor:'pointer' }}>Enter PiP</button>
      </div>
    </div>
  );
}

Object.assign(window, { PlayerScreen, FavToast, GestureIndicator, SkipPulse, SubtitleLayer, SpeedSheet, SubtitleSheet, EQSheet, SleepSheet, BookmarksSheet, AudioSheet, PlayerSettingsSheet, RotationSheet, PiPOverlay });
