// p06-input.jsx — Seed input flow:
//   P06  Input method picker (+ ad CTA when pouch is full)
//   P06a Typing (with searchable lang picker sheet)
//   P06b Voice  (idle → listening with live transcript → editable)
//   P06c Screenshot (source → picker / camera / clipboard → detect → confirm)

// User language preferences — persist across screens via window globals.
// (Real app would back this with secure storage.)
window.__cpLangFavs = window.__cpLangFavs || ['ja', 'en', 'zh-CN', 'vi'];
window.__cpLangSel  = window.__cpLangSel  || ['ja'];
function useLangPrefs() {
  const [favs, _setFavs] = React.useState(window.__cpLangFavs);
  const [sel,  _setSel]  = React.useState(window.__cpLangSel);
  return {
    favs,
    setFavs: (f) => { window.__cpLangFavs = f; _setFavs(f); },
    sel,
    setSel:  (s) => { window.__cpLangSel  = s; _setSel(s);  },
  };
}

function ScreenInput({ state, onNavigate, user }) {
  const T = window.T;
  const offline = state === 'offline';
  const isFull = state === 'full' || (user && user.todayPouch >= 10);
  const remain = isFull ? 0 : (10 - (user?.todayPouch ?? 7));
  const boostLeft = user?.todayBoost ?? 2;

  return (
    <div style={{ position: 'absolute', inset: 0, background: T.bg,
                  display: 'flex', flexDirection: 'column' }}>
      <TopBar title="씨앗 담기"
        leading={<IconButton icon={<Icons.Close size={22} color={T.ink}/>}
                             onClick={() => onNavigate('back')}/>}
      />

      <div style={{ flex: 1, overflowY: 'auto', padding: '4px 20px 24px' }}>
        {/* Pouch quota meter */}
        <div style={{
          background: T.surface, borderRadius: 16,
          border: `0.5px solid ${T.hairline}`,
          padding: 16, marginBottom: isFull ? 14 : 22,
          display: 'flex', alignItems: 'center', gap: 14,
        }}>
          <div style={{ width: 48, height: 48 }}>
            <Hamster count={user?.todayPouch ?? 7} max={10} size={48} headOnly/>
          </div>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 11, fontWeight: 700, color: T.ink3,
                          letterSpacing: '0.06em', textTransform: 'uppercase',
                          marginBottom: 4 }}>오늘 볼주머니</div>
            <div style={{ fontSize: 18, fontWeight: 700, color: T.ink,
                          letterSpacing: '-0.02em' }}>
              {isFull ? '가득 찼어요' : `${remain}개 더 담을 수 있어요`}
            </div>
          </div>
          <div style={{
            fontSize: 22, fontWeight: 800,
            color: isFull ? T.danger : T.accent, letterSpacing: '-0.03em',
          }}>{user?.todayPouch ?? 7}<span style={{ color: T.ink3, fontWeight: 600, fontSize: 14 }}>/10</span></div>
        </div>

        {/* Offline banner */}
        {offline && (
          <div style={{
            background: T.dangerSoft,
            borderRadius: 12, padding: '12px 14px', marginBottom: 16,
            fontSize: 13, color: T.danger, lineHeight: 1.5, fontWeight: 600,
          }}>
            오프라인이라 새 씨앗은 못 만들어요. 담아둔 씨앗은 그대로 쓸 수 있어요
          </div>
        )}

        {/* Full-pouch ad-reward CTA — replaces the 3 method cards */}
        {isFull && !offline ? (
          <FullPouchAdCTA boostLeft={boostLeft} onNavigate={onNavigate}/>
        ) : (
          <React.Fragment>
            <div style={{ fontSize: 12.5, color: T.ink3, padding: '0 4px 12px' }}>
              어떻게 담을까요?
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
              <MethodCard
                icon={<Icons.Type size={26} color={T.ink}/>}
                title="직접 타이핑"
                desc="한국어로 직접 적어요. 여러 문장도 한 번에"
                disabled={offline}
                onClick={() => onNavigate('P06a')}
              />
              <MethodCard
                icon={<Icons.Mic size={26} color={T.ink}/>}
                title="음성으로 말하기"
                desc="마이크 한 번 누르고 말하면 끝"
                disabled={offline}
                onClick={() => onNavigate('P06b')}
              />
              <MethodCard
                icon={<Icons.Image size={26} color={T.ink}/>}
                title="스크린샷 가져오기"
                desc="사진 속 한국어 글자를 알아서 찾아드려요"
                disabled={offline}
                onClick={() => onNavigate('P06c')}
              />
            </div>
          </React.Fragment>
        )}
      </div>
    </div>
  );
}

// Ad CTA shown when pouch is full — invites user to watch an ad for more capacity.
function FullPouchAdCTA({ boostLeft, onNavigate }) {
  const T = window.T;
  const hasBoost = boostLeft > 0;
  return (
    <div style={{
      background: T.accentSoft,
      border: `0.5px solid ${T.hairlineStrong}`,
      borderRadius: 20, padding: '22px 18px 20px',
      marginBottom: 16, textAlign: 'center',
      position: 'relative', overflow: 'hidden',
    }}>
      {/* Soft accent glow */}
      <div style={{
        position: 'absolute', top: -40, left: '50%',
        transform: 'translateX(-50%)',
        width: 220, height: 110, borderRadius: '50%',
        background: `radial-gradient(circle, ${T.accentSoft} 0%, transparent 70%)`,
        pointerEvents: 'none',
      }}/>

      <div style={{ position: 'relative', display: 'flex', justifyContent: 'center', marginBottom: 14 }}>
        <div style={{ width: 88, height: 88, position: 'relative' }}>
          <Hamster count={10} max={10} size={88}/>
          {/* Sparkle badge */}
          <div style={{
            position: 'absolute', top: -4, right: -6,
            width: 32, height: 32, borderRadius: '50%',
            background: T.accent, color: '#FFF',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            boxShadow: '0 4px 12px rgba(139,111,71,0.4)',
            fontSize: 16, fontWeight: 800,
          }}>
            <Icons.Sparkle size={18} color="#FFF"/>
          </div>
        </div>
      </div>

      <div style={{ fontSize: 17, fontWeight: 800, color: T.ink,
                    letterSpacing: '-0.025em', marginBottom: 6 }}>
        볼주머니가 빵빵해요!
      </div>
      <div style={{ fontSize: 13.5, color: T.ink2, lineHeight: 1.5, marginBottom: 18,
                    maxWidth: 260, marginLeft: 'auto', marginRight: 'auto' }}>
        광고를 짧게 보고 <b style={{ color: T.accent }}>+3개</b>를 더 받아<br/>
        오늘 더 담아볼까요?
      </div>

      <Button
        kind="primary" fullWidth
        icon={<Icons.Play size={16} color="#FFF" fillTri/>}
        disabled={!hasBoost}
        onClick={() => onNavigate('P-ad-pre')}
      >
        {hasBoost ? '광고 보고 +3개 받기' : '오늘은 다 받았어요'}
      </Button>

      {/* Slot dots — show how many boosts are left today */}
      <div style={{ display: 'flex', justifyContent: 'center', gap: 6,
                    marginTop: 14, fontSize: 11.5, color: T.ink3,
                    letterSpacing: '-0.005em', alignItems: 'center' }}>
        오늘 남은 광고
        <div style={{ display: 'inline-flex', gap: 4, marginLeft: 4 }}>
          {[0,1,2].map(i => (
            <div key={i} style={{
              width: 8, height: 8, borderRadius: '50%',
              background: i < boostLeft ? T.accent : T.hairlineStrong,
            }}/>
          ))}
        </div>
      </div>

      <div style={{ marginTop: 14, paddingTop: 12,
                    borderTop: `0.5px solid ${T.hairlineStrong}`,
                    fontSize: 11.5, color: T.ink3, lineHeight: 1.5 }}>
        또는 자정에 자동으로 다시 채워져요
      </div>
    </div>
  );
}

function MethodCard({ icon, title, desc, disabled, onClick }) {
  const T = window.T;
  return (
    <button onClick={onClick} disabled={disabled} style={{
      background: T.surface, borderRadius: 16,
      border: `0.5px solid ${T.hairline}`,
      padding: '18px 16px',
      display: 'flex', alignItems: 'center', gap: 14,
      fontFamily: 'inherit', cursor: disabled ? 'default' : 'pointer',
      opacity: disabled ? 0.4 : 1,
      textAlign: 'left', width: '100%',
      WebkitTapHighlightColor: 'transparent',
    }}>
      <div style={{
        width: 52, height: 52, borderRadius: 14,
        background: T.accentSoft,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        color: T.accent, flexShrink: 0,
      }}>{React.cloneElement(icon, { color: T.accent })}</div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 15.5, fontWeight: 700, color: T.ink,
                      letterSpacing: '-0.015em', marginBottom: 3 }}>{title}</div>
        <div style={{ fontSize: 12.5, color: T.ink2, lineHeight: 1.4 }}>{desc}</div>
      </div>
      <Icons.ChevronR size={18} color={T.ink3}/>
    </button>
  );
}

// ──────────────────────────────────────────────────────────────
// Language picker (shared by P06a typing + P06b voice + P06c confirm)
// Supports MULTI-SELECT translation targets and user-managed favorites.
//
//   value      = array of language codes (translate to all of these)
//   onChange   = (newArray) => void
//   favorites  = array of starred codes  (default: ['ja','en','zh-CN','vi'])
//   onFavChange = (newArray) => void  (lifted so star state persists across screens)
//
// The chip row shows ONLY user's currently-selected target languages —
// no clutter. A single "+ 언어 추가" button opens the full sheet for
// browsing, multi-selecting, and starring favorites.
// ──────────────────────────────────────────────────────────────
function LangPickerRow({ value, onChange, favorites, onFavChange, max = 5 }) {
  const T = window.T;
  const [open, setOpen] = React.useState(false);
  const all = window.MOCK_LANGS_ALL || window.MOCK_LANGS;
  const byCode = Object.fromEntries(all.map(l => [l.code, l]));
  const sel = Array.isArray(value) ? value : (value ? [value] : []);
  const FAVS = favorites || ['ja', 'en', 'zh-CN', 'vi'];
  // Favorites that haven't been selected yet — surface as quick-add ghost chips
  // so the user can tap them inline without opening the sheet.
  const quickAdd = FAVS.filter(c => !sel.includes(c)).slice(0, 6);
  const atMax = sel.length >= max;

  const removeOne = (code) => onChange(sel.filter(c => c !== code));
  const addOne    = (code) => { if (!sel.includes(code) && !atMax) onChange([...sel, code]); };

  return (
    <React.Fragment>
      <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
        {/* Selected chips (filled, with ×) */}
        {sel.map(code => {
          const l = byCode[code];
          if (!l) return null;
          return (
            <LangChip key={code} variant="selected"
                      flag={l.flag} label={l.label}
                      onRemove={() => removeOne(code)}
                      onClick={() => setOpen(true)}/>
          );
        })}

        {/* Quick-add favorites (ghost outline, tap to add) */}
        {quickAdd.map(code => {
          const l = byCode[code];
          if (!l) return null;
          return (
            <LangChip key={code} variant="favorite"
                      flag={l.flag} label={l.label}
                      disabled={atMax}
                      onClick={() => addOne(code)}/>
          );
        })}

        {/* Sheet opener (other languages / manage favorites) */}
        <button onClick={() => setOpen(true)} style={{
          height: 36, padding: '0 12px',
          background: 'transparent', color: T.ink2,
          border: `0.5px dashed ${T.hairlineStrong}`,
          borderRadius: 18, fontFamily: 'inherit',
          fontSize: 12.5, fontWeight: 600, letterSpacing: '-0.01em',
          cursor: 'pointer', display: 'inline-flex', alignItems: 'center', gap: 4,
          WebkitTapHighlightColor: 'transparent',
        }}>
          <Icons.Plus size={14} color={T.ink2}/> 더 보기
        </button>
      </div>

      {/* Status line under the chip row */}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between',
                    fontSize: 11.5, color: T.ink3, marginTop: 8,
                    letterSpacing: '-0.005em', lineHeight: 1.4 }}>
        <span>
          {sel.length === 0
            ? '아래에서 즐겨찾기 언어를 탭하거나 · 더 보기로 골라주세요'
            : sel.length === 1
              ? <span><b style={{ color: T.ink2 }}>1개 언어</b>로 번역해요</span>
              : <span><b style={{ color: T.ink2 }}>{sel.length}개 언어</b>로 동시에 번역해드려요</span>}
        </span>
        <button onClick={() => setOpen(true)} style={{
          background: 'transparent', border: 'none',
          color: T.accent, fontFamily: 'inherit',
          fontSize: 11.5, fontWeight: 700, cursor: 'pointer',
          padding: 0, letterSpacing: '-0.005em',
          display: 'inline-flex', alignItems: 'center', gap: 2,
          WebkitTapHighlightColor: 'transparent',
        }}>
          <Icons.Star size={11} color={T.accent}/> 즐겨찾기 관리
        </button>
      </div>

      {open && (
        <LangPickerSheet
          value={sel}
          onChange={onChange}
          favorites={FAVS}
          onFavChange={onFavChange}
          max={max}
          onClose={() => setOpen(false)}
        />
      )}
    </React.Fragment>
  );
}

// Chip variants:
//   selected — filled accent + × remove badge
//   favorite — outlined ghost + leading "+" hint, tap to add
function LangChip({ variant = 'selected', flag, label, onClick, onRemove, disabled }) {
  const T = window.T;
  const isSelected = variant === 'selected';
  const isFavorite = variant === 'favorite';

  if (isFavorite) {
    return (
      <button onClick={onClick} disabled={disabled} style={{
        height: 36, padding: '0 12px 0 8px',
        background: T.surface, color: T.ink,
        border: `0.5px solid ${T.hairlineStrong}`,
        borderRadius: 18, fontFamily: 'inherit',
        fontSize: 13, fontWeight: 600, letterSpacing: '-0.01em',
        cursor: disabled ? 'default' : 'pointer',
        opacity: disabled ? 0.4 : 1,
        display: 'inline-flex', alignItems: 'center', gap: 6,
        WebkitTapHighlightColor: 'transparent',
      }}>
        <span style={{
          width: 18, height: 18, borderRadius: '50%',
          background: T.accentSoft, color: T.accent,
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
          flexShrink: 0,
        }}>
          <Icons.Plus size={11} color={T.accent} strokeWidth={2.2}/>
        </span>
        <span style={{ fontSize: 15, lineHeight: 1 }}>{flag}</span>
        {label}
      </button>
    );
  }

  // selected
  return (
    <div style={{
      height: 36, padding: onRemove ? '0 4px 0 10px' : '0 12px 0 10px',
      background: T.accent,
      color: '#FFF',
      border: `1px solid ${T.accent}`,
      borderRadius: 18,
      display: 'inline-flex', alignItems: 'center', gap: 6,
    }}>
      <button onClick={onClick} style={{
        background: 'transparent', border: 'none', padding: 0,
        color: 'inherit', fontFamily: 'inherit',
        fontSize: 13, fontWeight: 600, letterSpacing: '-0.01em',
        cursor: 'pointer', display: 'inline-flex', alignItems: 'center', gap: 6,
        WebkitTapHighlightColor: 'transparent',
      }}>
        <span style={{ fontSize: 15, lineHeight: 1 }}>{flag}</span>
        {label}
      </button>
      {onRemove && (
        <button onClick={(e) => { e.stopPropagation(); onRemove(); }} style={{
          width: 22, height: 22, borderRadius: '50%',
          background: 'rgba(255,255,255,0.22)', border: 'none', padding: 0,
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
          cursor: 'pointer', flexShrink: 0,
          WebkitTapHighlightColor: 'transparent',
        }} aria-label="제거">
          <Icons.Close size={12} color="#FFF" strokeWidth={2.5}/>
        </button>
      )}
    </div>
  );
}

function LangPickerSheet({ value, onChange, favorites, onFavChange, onClose, max }) {
  const T = window.T;
  const [q, setQ] = React.useState('');
  const all = window.MOCK_LANGS_ALL || window.MOCK_LANGS;
  const regions = window.MOCK_LANG_REGIONS || [{ id: 'all', label: '전체' }];
  // Local working copies so the user can stage changes and tap "완료"
  const [draft, setDraft] = React.useState(value);
  const [favDraft, setFavDraft] = React.useState(favorites);

  const norm = (s) => (s || '').toLowerCase();
  const filtered = q.trim()
    ? all.filter(l =>
        norm(l.label).includes(norm(q)) ||
        norm(l.native).includes(norm(q)) ||
        norm(l.code).includes(norm(q)))
    : all;

  const toggleSel = (code) => {
    setDraft(d => d.includes(code)
      ? d.filter(c => c !== code)
      : (d.length >= max ? d : [...d, code]));
  };
  const toggleFav = (code) => {
    setFavDraft(f => f.includes(code) ? f.filter(c => c !== code) : [...f, code]);
  };

  const commit = () => {
    onChange(draft);
    if (onFavChange) onFavChange(favDraft);
    onClose();
  };

  return (
    <div style={{
      position: 'absolute', inset: 0, zIndex: 60,
      background: 'rgba(0,0,0,0.32)',
      display: 'flex', flexDirection: 'column', justifyContent: 'flex-end',
    }} onClick={onClose}>
      <div onClick={e => e.stopPropagation()} style={{
        background: T.bg, borderRadius: '20px 20px 0 0',
        maxHeight: '82%', display: 'flex', flexDirection: 'column',
        boxShadow: '0 -10px 40px rgba(0,0,0,0.18)',
      }}>
        {/* Drag handle */}
        <div style={{ display: 'flex', justifyContent: 'center', padding: '8px 0 4px' }}>
          <div style={{ width: 36, height: 4, borderRadius: 2,
                        background: T.hairlineStrong }}/>
        </div>

        {/* Header */}
        <div style={{ padding: '6px 16px 10px',
                      display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
          <div>
            <div style={{ fontSize: 17, fontWeight: 700, color: T.ink,
                          letterSpacing: '-0.02em' }}>번역 언어 선택</div>
            <div style={{ fontSize: 11.5, color: T.ink3, marginTop: 2 }}>
              {draft.length === 0 ? '여러 개 동시에 선택할 수 있어요'
                : `${draft.length}개 선택됨 · 최대 ${max}개`}
            </div>
          </div>
          <IconButton icon={<Icons.Close size={20} color={T.ink2}/>}
                      onClick={onClose} size={32}/>
        </div>

        {/* Search */}
        <div style={{ padding: '0 16px 10px' }}>
          <div style={{
            display: 'flex', alignItems: 'center', gap: 8,
            background: T.surface,
            border: `0.5px solid ${T.hairlineStrong}`,
            borderRadius: 12, padding: '0 12px', height: 42,
          }}>
            <Icons.Search size={18} color={T.ink3}/>
            <input
              value={q} onChange={e => setQ(e.target.value)}
              placeholder="언어 이름 · English · 日本語"
              style={{
                flex: 1, border: 'none', outline: 'none',
                background: 'transparent', color: T.ink,
                fontSize: 14.5, fontFamily: 'inherit', letterSpacing: '-0.01em',
              }}
            />
            {q && (
              <IconButton icon={<Icons.Close size={16} color={T.ink3}/>}
                          onClick={() => setQ('')} size={28}/>
            )}
          </div>
        </div>

        {/* Helper row */}
        <div style={{
          padding: '0 18px 8px',
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          fontSize: 11.5, color: T.ink3,
        }}>
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>
            <Icons.Star size={12} color={T.ink3}/>
            별표를 누르면 즐겨찾기에 추가돼요
          </span>
          {draft.length > 0 && (
            <button onClick={() => setDraft([])} style={{
              background: 'transparent', border: 'none',
              color: T.danger, fontFamily: 'inherit',
              fontSize: 12, fontWeight: 600, cursor: 'pointer', padding: 0,
            }}>전체 지우기</button>
          )}
        </div>

        {/* List */}
        <div style={{ flex: 1, overflowY: 'auto', padding: '0 8px 8px' }}>
          {q.trim() ? (
            <LangList items={filtered} value={draft} favorites={favDraft}
                      onToggle={toggleSel} onToggleFav={toggleFav}/>
          ) : (
            <React.Fragment>
              {/* Favorites section */}
              {favDraft.length > 0 && (
                <div>
                  <div style={{ padding: '12px 14px 6px',
                                fontSize: 11, fontWeight: 700, color: T.accent,
                                letterSpacing: '0.08em', textTransform: 'uppercase',
                                display: 'flex', alignItems: 'center', gap: 4 }}>
                    <Icons.Star size={12} color={T.accent} filled/>
                    내 즐겨찾기
                  </div>
                  <LangList
                    items={favDraft.map(c => all.find(l => l.code === c)).filter(Boolean)}
                    value={draft} favorites={favDraft}
                    onToggle={toggleSel} onToggleFav={toggleFav}/>
                </div>
              )}
              {/* Region sections */}
              {regions.map(r => {
                const items = all.filter(l => l.region === r.id);
                if (items.length === 0) return null;
                return (
                  <div key={r.id}>
                    <div style={{ padding: '14px 14px 6px',
                                  fontSize: 11, fontWeight: 700, color: T.ink3,
                                  letterSpacing: '0.08em', textTransform: 'uppercase' }}>
                      {r.label}
                    </div>
                    <LangList items={items} value={draft} favorites={favDraft}
                              onToggle={toggleSel} onToggleFav={toggleFav}/>
                  </div>
                );
              })}
            </React.Fragment>
          )}
          {filtered.length === 0 && (
            <div style={{ padding: '40px 20px', textAlign: 'center',
                          color: T.ink3, fontSize: 13 }}>
              "{q}"에 해당하는 언어가 없어요
            </div>
          )}
        </div>

        {/* Footer commit */}
        <div style={{
          padding: '10px 16px 18px',
          borderTop: `0.5px solid ${T.hairline}`,
          background: T.bg,
        }}>
          <Button kind="primary" fullWidth onClick={commit}
                  disabled={draft.length === 0}>
            {draft.length === 0
              ? '언어를 골라주세요'
              : `${draft.length}개 언어로 번역하기`}
          </Button>
        </div>
      </div>
    </div>
  );
}

function LangList({ items, value, favorites, onToggle, onToggleFav }) {
  const T = window.T;
  return (
    <div>
      {items.map(l => {
        const on = value.includes(l.code);
        const starred = favorites.includes(l.code);
        return (
          <div key={l.code} style={{
            width: '100%', display: 'flex', alignItems: 'center', gap: 10,
            background: on ? T.accentSoft : 'transparent',
            borderRadius: 10, padding: '4px 6px 4px 10px',
          }}>
            <button onClick={() => onToggle(l.code)} style={{
              flex: 1, display: 'flex', alignItems: 'center', gap: 12,
              background: 'transparent', border: 'none',
              padding: '8px 4px', textAlign: 'left',
              cursor: 'pointer', fontFamily: 'inherit',
              WebkitTapHighlightColor: 'transparent',
            }}>
              <span style={{ fontSize: 22, lineHeight: 1, flexShrink: 0 }}>{l.flag}</span>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 14.5, fontWeight: on ? 700 : 600,
                              color: T.ink, letterSpacing: '-0.01em' }}>{l.label}</div>
                <div style={{ fontSize: 12, color: T.ink3, marginTop: 1 }}>{l.native}</div>
              </div>
              {/* Checkbox */}
              <div style={{
                width: 22, height: 22, borderRadius: 6,
                background: on ? T.accent : 'transparent',
                border: on ? `1px solid ${T.accent}` : `1.5px solid ${T.hairlineStrong}`,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                flexShrink: 0,
              }}>
                {on && <Icons.Check size={14} color="#FFF" strokeWidth={3}/>}
              </div>
            </button>
            {/* Star */}
            <button onClick={(e) => { e.stopPropagation(); onToggleFav(l.code); }} style={{
              width: 36, height: 36, borderRadius: '50%',
              background: 'transparent', border: 'none',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              cursor: 'pointer', flexShrink: 0,
              WebkitTapHighlightColor: 'transparent',
            }} aria-label={starred ? '즐겨찾기 해제' : '즐겨찾기'}>
              <Icons.Star size={18} color={starred ? T.accent : T.ink3}
                          filled={starred}/>
            </button>
          </div>
        );
      })}
    </div>
  );
}

// ──────────────────────────────────────────────────────────────
// Direction detection helpers (shared by P06a typing + P06b voice)
//   detectDirection(text)  → 'ko->fo' | 'fo->ko' | null
//   DirectionChip          — controlled component; parent owns override state
// ──────────────────────────────────────────────────────────────
function detectDirection(text) {
  const t = (text || '').trim();
  if (!t) return null;
  const hasKo = /[\uAC00-\uD7AF\u3130-\u318F]/.test(t);
  const hasFo = /[A-Za-z]/.test(t);
  if (hasKo && !hasFo) return 'ko->fo';
  if (hasFo && !hasKo) return 'fo->ko';
  return hasKo ? 'ko->fo' : 'fo->ko';
}

function DirectionChip({ direction, overridden, onFlip, T }) {
  if (!direction) return null;
  const isKoFo = direction === 'ko->fo';
  const label = isKoFo ? '한국어 → 외국어' : '외국어 → 뜻';
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 8,
      padding: '8px 10px 8px 12px',
      background: 'rgba(139,111,71,0.10)',
      border: '0.5px solid rgba(139,111,71,0.30)',
      borderRadius: 10,
      marginBottom: 14,
    }}>
      <span style={{ fontSize: 13, lineHeight: 1 }}>✨</span>
      <span style={{
        fontSize: 10.5, fontWeight: 800, color: T.ink3,
        letterSpacing: '0.08em', textTransform: 'uppercase',
      }}>방향 자동 감지</span>
      {overridden && (
        <span style={{
          fontSize: 10, fontWeight: 700, color: T.accent,
          letterSpacing: '-0.01em',
          background: 'rgba(139,111,71,0.18)',
          padding: '2px 6px', borderRadius: 5,
        }}>수정됨</span>
      )}
      <button onClick={onFlip} style={{
        marginLeft: 'auto',
        background: T.accent, color: '#FFF',
        border: 'none', borderRadius: 8,
        padding: '5px 10px',
        fontSize: 12, fontWeight: 700, fontFamily: 'inherit',
        cursor: 'pointer', letterSpacing: '-0.01em',
        display: 'inline-flex', alignItems: 'center', gap: 6,
      }} title="탭해서 방향 뒤집기">
        {label}
        <span style={{ fontSize: 11, opacity: 0.85 }}>⇄</span>
      </button>
    </div>
  );
}

// Target-language area for 외→뜻 direction: shows source → 한국어
// Source language is AI-auto-detected, but user can tap to pick a different one.
function detectSourceLang(text) {
  const t = (text || '').trim();
  if (!t) return null;
  // Hiragana / Katakana → Japanese
  if (/[\u3040-\u309F\u30A0-\u30FF]/.test(t)) return 'ja';
  // Hangul → Korean (defensive — shouldn’t hit in fo→ko)
  if (/[\uAC00-\uD7AF]/.test(t)) return 'ko';
  // Han characters (no kana already filtered) → Chinese simplified default
  if (/[\u4E00-\u9FFF]/.test(t)) return 'zh-CN';
  if (/[\u0400-\u04FF]/.test(t)) return 'ru';      // Cyrillic
  if (/[\u0600-\u06FF]/.test(t)) return 'ar';      // Arabic
  if (/[\u0590-\u05FF]/.test(t)) return 'he';      // Hebrew
  if (/[\u0900-\u097F]/.test(t)) return 'hi';      // Devanagari
  if (/[\u0E00-\u0E7F]/.test(t)) return 'th';      // Thai
  if (/[\u0370-\u03FF]/.test(t)) return 'el';      // Greek
  if (/[A-Za-z]/.test(t)) return 'en';              // Latin default
  return null;
}

// Per-item script chip (compact 1-char label for P06c box badges).
// Returns null when text is empty.
function detectScript(text) {
  const t = (text || '').trim();
  if (!t) return null;
  if (/[\uAC00-\uD7AF]/.test(t))             return '한';
  if (/[\u3040-\u309F\u30A0-\u30FF]/.test(t)) return '일';
  if (/[\u4E00-\u9FFF]/.test(t))             return '중';
  if (/[\u0400-\u04FF]/.test(t))             return '러';
  if (/[\u0600-\u06FF]/.test(t))             return '아';
  if (/[\u0590-\u05FF]/.test(t))             return '히';
  if (/[\u0E00-\u0E7F]/.test(t))             return '태';
  if (/[\u0370-\u03FF]/.test(t))             return '그';
  if (/[A-Za-z]/.test(t))                     return '영';
  return '?';
}

function SourceLangSheet({ value, onChange, onClose }) {
  const T = window.T;
  const [q, setQ] = React.useState('');
  const all = window.MOCK_LANGS_ALL || window.MOCK_LANGS;
  const norm = (s) => (s || '').toLowerCase();
  const filtered = q.trim()
    ? all.filter(l =>
        norm(l.label).includes(norm(q)) ||
        norm(l.native).includes(norm(q)) ||
        norm(l.code).includes(norm(q)))
    : all;
  return (
    <div style={{
      position: 'absolute', inset: 0, zIndex: 60,
      background: 'rgba(0,0,0,0.32)',
      display: 'flex', flexDirection: 'column', justifyContent: 'flex-end',
    }} onClick={onClose}>
      <div onClick={e => e.stopPropagation()} style={{
        background: T.bg, borderRadius: '20px 20px 0 0',
        maxHeight: '80%', display: 'flex', flexDirection: 'column',
        boxShadow: '0 -10px 40px rgba(0,0,0,0.18)',
      }}>
        <div style={{ display: 'flex', justifyContent: 'center', padding: '8px 0 4px' }}>
          <div style={{ width: 36, height: 4, borderRadius: 2, background: T.hairlineStrong }}/>
        </div>
        <div style={{ padding: '6px 16px 10px',
                      display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
          <div>
            <div style={{ fontSize: 17, fontWeight: 700, color: T.ink,
                          letterSpacing: '-0.02em' }}>입력 언어 선택</div>
            <div style={{ fontSize: 11.5, color: T.ink3, marginTop: 2 }}>
              자동 감지가 다르게 잡혔으면 직접 골라주세요
            </div>
          </div>
          <IconButton icon={<Icons.Close size={20} color={T.ink2}/>}
                      onClick={onClose} size={32}/>
        </div>
        <div style={{ padding: '0 16px 10px' }}>
          <div style={{
            display: 'flex', alignItems: 'center', gap: 8,
            background: T.surface, border: `0.5px solid ${T.hairlineStrong}`,
            borderRadius: 12, padding: '0 12px', height: 42,
          }}>
            <Icons.Search size={18} color={T.ink3}/>
            <input value={q} onChange={e => setQ(e.target.value)}
              placeholder="언어 이름 · English · 日本語"
              style={{ flex: 1, border: 'none', outline: 'none',
                background: 'transparent', color: T.ink,
                fontSize: 14.5, fontFamily: 'inherit', letterSpacing: '-0.01em' }}/>
            {q && <IconButton icon={<Icons.Close size={16} color={T.ink3}/>}
                              onClick={() => setQ('')} size={28}/>}
          </div>
        </div>
        <div style={{ flex: 1, overflowY: 'auto', padding: '0 8px 16px' }}>
          {filtered.map(l => {
            const selected = l.code === value;
            const code = l.code.split('-')[0].toUpperCase();
            return (
              <button key={l.code}
                onClick={() => { onChange(l.code); onClose(); }}
                style={{
                  width: '100%', display: 'flex', alignItems: 'center', gap: 12,
                  padding: '11px 14px',
                  background: selected ? T.accentSoft : 'transparent',
                  border: 'none', borderRadius: 10, cursor: 'pointer',
                  fontFamily: 'inherit', textAlign: 'left', marginBottom: 1,
                }}>
                <div style={{
                  width: 32, height: 32, borderRadius: '50%',
                  background: selected ? T.accent : T.surface,
                  color: selected ? '#FFF' : T.ink2,
                  border: selected ? 'none' : `0.5px solid ${T.hairline}`,
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  fontSize: 10.5, fontWeight: 800, letterSpacing: '0.04em',
                  flexShrink: 0,
                }}>{code}</div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 14.5, fontWeight: 700, color: T.ink,
                                letterSpacing: '-0.015em' }}>{l.label}</div>
                  <div style={{ fontSize: 11.5, color: T.ink3,
                                whiteSpace: 'nowrap', overflow: 'hidden',
                                textOverflow: 'ellipsis' }}>{l.native}</div>
                </div>
                {selected && <Icons.Check size={18} color={T.accent}/>}
              </button>
            );
          })}
        </div>
      </div>
    </div>
  );
}

function MeaningTargetCard({ sourceLang, onSourceLangChange, sourceOverridden, T }) {
  const [open, setOpen] = React.useState(false);
  const all = window.MOCK_LANGS_ALL || window.MOCK_LANGS;
  const src = all.find(l => l.code === sourceLang)
              || { label: '알 수 없음', code: '?' };
  return (
    <div style={{
      padding: '14px 14px 12px',
      background: T.surface,
      border: `0.5px solid ${T.hairline}`,
      borderRadius: 12,
    }}>
      {/* Top row: 입력 언어  →  한국어 */}
      <div style={{ display: 'flex', alignItems: 'stretch', gap: 8 }}>
        <button onClick={() => setOpen(true)} style={{
          flex: 1, display: 'flex', alignItems: 'center', gap: 8,
          padding: '10px 12px',
          background: T.bg, border: `0.5px solid ${T.hairlineStrong}`,
          borderRadius: 10, fontFamily: 'inherit', cursor: 'pointer',
          textAlign: 'left', minWidth: 0,
        }}>
          <span style={{ flex: 1, fontSize: 14, fontWeight: 700, color: T.ink,
                         letterSpacing: '-0.015em',
                         whiteSpace: 'nowrap', overflow: 'hidden',
                         textOverflow: 'ellipsis' }}>{src.label}</span>
          {sourceOverridden && (
            <span style={{
              fontSize: 9.5, fontWeight: 700, color: T.accent,
              background: 'rgba(139,111,71,0.18)',
              padding: '1.5px 5px', borderRadius: 4,
              letterSpacing: '-0.01em', flexShrink: 0,
            }}>수정됨</span>
          )}
          <span style={{ fontSize: 12, color: T.ink3, flexShrink: 0 }}>⌄</span>
        </button>
        <div style={{ display: 'flex', alignItems: 'center',
                      color: T.ink3, fontSize: 16, padding: '0 2px' }}>→</div>
        <div style={{
          display: 'flex', alignItems: 'center', gap: 8,
          padding: '10px 14px',
          background: T.accentSoft,
          border: `0.5px solid ${T.accent}`,
          borderRadius: 10,
          flexShrink: 0,
        }}>
          <div style={{ fontSize: 14, fontWeight: 700, color: T.accent,
                        letterSpacing: '-0.015em' }}>한국어</div>
        </div>
      </div>
      {/* Helper */}
      <div style={{ marginTop: 10, fontSize: 11.5, color: T.ink3,
                    lineHeight: 1.5, display: 'flex', alignItems: 'flex-start', gap: 6 }}>
        <span style={{ fontSize: 12 }}>✨</span>
        <span>AI가 자동으로 감지한 입력 언어예요. 다르면 위 칸을 탭해서 직접 골라주세요.</span>
      </div>
      {open && <SourceLangSheet value={sourceLang}
                                onChange={onSourceLangChange}
                                onClose={() => setOpen(false)}/>}
    </div>
  );
}

// Sample text for foreign-input state — lets us verify direction-detection
// chip on first paint without the user having to type.
const TYPING_FOREIGN_SAMPLE = 'Could you give me a hand?';

// ──────────────────────────────────────────────────────────────
// P06a Typing input
// ──────────────────────────────────────────────────────────────
function ScreenInputTyping({ state, onNavigate }) {
  const T = window.T;
  const offline = state === 'offline';
  const foreign = state === 'foreign';
  const [text, setText] = React.useState(foreign ? TYPING_FOREIGN_SAMPLE : '');
  const [override, setOverride] = React.useState(null);
  const [sourceLangOverride, setSourceLangOverride] = React.useState(null);
  const { favs, setFavs, sel, setSel } = useLangPrefs();

  const detected = detectDirection(text);
  const direction = override || detected;
  const isForeignSource = direction === 'fo->ko';
  const flipDir = () => setOverride(direction === 'ko->fo' ? 'fo->ko' : 'ko->fo');
  const overridden = override && override !== detected;

  const detectedSource = detectSourceLang(text);
  const sourceLang = sourceLangOverride || detectedSource || 'en';
  const sourceOverridden = !!sourceLangOverride && sourceLangOverride !== detectedSource;

  const canSubmit = !!text.trim() && !offline && (isForeignSource || sel.length > 0);

  return (
    <div style={{ position: 'absolute', inset: 0, background: T.bg,
                  display: 'flex', flexDirection: 'column' }}>
      <TopBar title="직접 타이핑"
        leading={<IconButton icon={<Icons.Back size={22} color={T.ink}/>}
                             onClick={() => onNavigate('back')}/>}
        trailing={
          <button onClick={() => onNavigate('P09')}
                  disabled={!canSubmit}
                  style={{
            background: 'transparent', border: 'none',
            color: canSubmit ? T.accent : T.ink3,
            fontSize: 15, fontWeight: 700, padding: '0 4px',
            fontFamily: 'inherit', cursor: 'pointer',
          }}>완료</button>
        }
      />
      <div style={{ flex: 1, overflowY: 'auto', padding: '4px 20px 24px',
                    display: 'flex', flexDirection: 'column' }}>
        <textarea
          value={text} onChange={e => setText(e.target.value)}
          placeholder="한국어 또는 외국어로 적어주세요…"
          autoFocus
          style={{
            width: '100%', minHeight: 160, resize: 'none',
            background: T.surface, border: `0.5px solid ${T.hairline}`,
            borderRadius: 14, padding: 14,
            fontSize: 17, color: T.ink, lineHeight: 1.5,
            letterSpacing: '-0.01em',
            fontFamily: 'inherit', outline: 'none',
            marginBottom: 10,
          }}
        />

        <DirectionChip direction={direction} overridden={overridden}
                       onFlip={flipDir} T={T}/>

        <div style={{ fontSize: 12.5, color: T.ink3, lineHeight: 1.5, marginBottom: 22 }}>
          한국어로 적으면 외국어로 만들고, 외국어로 적으면 뜻을 알려드려요. 방향이 다르게 잡혔으면 위 칩을 탭해서 바꿔주세요.
        </div>

        <div style={{ marginBottom: 18 }}>
          <div style={{ fontSize: 11.5, fontWeight: 700, color: T.ink3,
                        letterSpacing: '0.08em', textTransform: 'uppercase',
                        marginBottom: 10 }}>
            {isForeignSource ? '결과 언어' : '번역 언어'}
          </div>
          {isForeignSource
            ? <MeaningTargetCard sourceLang={sourceLang}
                                 onSourceLangChange={setSourceLangOverride}
                                 sourceOverridden={sourceOverridden}
                                 T={T}/>
            : <LangPickerRow value={sel} onChange={setSel}
                             favorites={favs} onFavChange={setFavs}/>}
        </div>
      </div>
    </div>
  );
}

// ──────────────────────────────────────────────────────────────
// P06b Voice input
//   States: default (idle) → recording (live transcript) → transcribed (editable)
//   Each state is a distinct visual; URL state forces remount via key=
// ──────────────────────────────────────────────────────────────
const VOICE_TRANSCRIPT_FULL = '한국 음식 추천해주실 수 있나요?';
const VOICE_TRANSCRIPT_FOREIGN = 'Could you give me a hand?';
// progressively-revealed substrings shown while "listening"
const VOICE_LIVE_STEPS = [
  '한국',
  '한국 음식',
  '한국 음식 추천',
  '한국 음식 추천해주실',
  '한국 음식 추천해주실 수',
  '한국 음식 추천해주실 수 있나요',
  '한국 음식 추천해주실 수 있나요?',
];

function ScreenInputVoice({ state, onNavigate }) {
  const T = window.T;
  const denied = state === 'denied';
  // initial mode from URL state
  const initialMode =
    state === 'recording'   ? 'recording'
    : state === 'transcribed' || state === 'transcribed-foreign' ? 'done'
    : 'idle';
  const initialText =
    state === 'transcribed-foreign' ? VOICE_TRANSCRIPT_FOREIGN
    : initialMode === 'done' ? VOICE_TRANSCRIPT_FULL
    : '';
  const [mode, setMode] = React.useState(initialMode);
  const [text, setText] = React.useState(initialText);
  const [liveIdx, setLiveIdx] = React.useState(0);

  // Animate live transcript while recording
  React.useEffect(() => {
    if (mode !== 'recording') return;
    setLiveIdx(0);
    setText('');
    const timers = [];
    VOICE_LIVE_STEPS.forEach((s, i) => {
      timers.push(setTimeout(() => {
        setLiveIdx(i + 1);
        setText(s);
      }, 380 + i * 480));
    });
    return () => timers.forEach(clearTimeout);
  }, [mode]);

  const start = () => setMode('recording');
  const stop  = () => setMode('done');
  const retry = () => { setText(''); setMode('recording'); };

  const isDone = mode === 'done';

  return (
    <div style={{ position: 'absolute', inset: 0, background: T.bg,
                  display: 'flex', flexDirection: 'column' }}>
      <TopBar title="음성으로 말하기"
        leading={<IconButton icon={<Icons.Back size={22} color={T.ink}/>}
                             onClick={() => onNavigate('back')}/>}
        trailing={
          isDone ? (
            <button onClick={() => onNavigate('P09')}
                    disabled={!text.trim()}
                    style={{
              background: 'transparent', border: 'none',
              color: text.trim() ? T.accent : T.ink3,
              fontSize: 15, fontWeight: 700, padding: '0 4px',
              fontFamily: 'inherit', cursor: 'pointer',
            }}>완료</button>
          ) : null
        }
      />

      <div style={{ flex: 1, padding: '4px 20px 24px',
                    display: 'flex', flexDirection: 'column' }}>
        {denied ? (
          <EmptyState
            icon={<div style={{ width: 80, height: 80, borderRadius: '50%',
                                background: T.dangerSoft,
                                display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
              <Icons.Mic size={36} color={T.danger}/>
            </div>}
            title="마이크 권한이 필요해요"
            message="설정에서 마이크 사용을 허용해주세요"
            action={<Button kind="primary" icon={<Icons.Cog size={16} color="#FFF"/>}>설정 열기</Button>}
          />
        ) : isDone ? (
          <VoiceDoneView text={text} onChange={setText} onRetry={retry} T={T}/>
        ) : mode === 'recording' ? (
          <VoiceRecordingView text={text} liveIdx={liveIdx}
                              onStop={stop} T={T}/>
        ) : (
          <VoiceIdleView onStart={start} T={T}/>
        )}
      </div>
    </div>
  );
}

function VoiceIdleView({ onStart, T }) {
  return (
    <div style={{
      flex: 1,
      display: 'flex', flexDirection: 'column',
      alignItems: 'center', justifyContent: 'center',
      textAlign: 'center', padding: '20px 0',
    }}>
      <button onClick={onStart} style={{
        width: 120, height: 120, borderRadius: '50%',
        background: T.accent,
        border: 'none', cursor: 'pointer', padding: 0,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        boxShadow: '0 8px 24px rgba(139,111,71,0.4)',
      }}>
        <Icons.Mic size={44} color="#FFF"/>
      </button>
      <div style={{ fontSize: 16, fontWeight: 700, color: T.ink,
                    letterSpacing: '-0.02em', marginTop: 24, marginBottom: 6 }}>
        마이크를 누르고 말해주세요
      </div>
      <div style={{ fontSize: 13, color: T.ink2, lineHeight: 1.5, maxWidth: 240 }}>
        한 문장씩, 또는 여러 문장 한 번에 OK
      </div>
    </div>
  );
}

function VoiceRecordingView({ text, liveIdx, onStop, T }) {
  // Live transcript bubble. Highlights the most-recent word.
  const words = text.split(' ').filter(Boolean);
  const lastIdx = words.length - 1;
  const totalSteps = VOICE_LIVE_STEPS.length;

  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column' }}>
      {/* Status pill */}
      <div style={{
        alignSelf: 'center',
        display: 'inline-flex', alignItems: 'center', gap: 6,
        background: T.dangerSoft, color: T.danger,
        padding: '5px 11px', borderRadius: 999,
        fontSize: 12, fontWeight: 700, letterSpacing: '-0.01em',
        marginBottom: 14, marginTop: 6,
      }}>
        <span style={{ width: 8, height: 8, borderRadius: '50%',
                       background: T.danger,
                       animation: 'cp-mic-pulse 1.4s ease-in-out infinite' }}/>
        듣고 있어요
      </div>

      {/* Live transcript bubble */}
      <div style={{
        background: T.surface, border: `0.5px solid ${T.hairline}`,
        borderRadius: 16, padding: '18px 18px 16px',
        minHeight: 130, position: 'relative',
        marginBottom: 14,
      }}>
        <div style={{ fontSize: 11, fontWeight: 700, color: T.ink3,
                      letterSpacing: '0.06em', textTransform: 'uppercase',
                      marginBottom: 8 }}>
          지금 들리는 말
        </div>
        {text ? (
          <div style={{ fontSize: 18, color: T.ink, lineHeight: 1.5,
                        letterSpacing: '-0.01em' }}>
            {words.map((w, i) => (
              <span key={i} style={{
                color: i === lastIdx ? T.ink : T.ink2,
                fontWeight: i === lastIdx ? 700 : 500,
                background: i === lastIdx ? T.accentSoft : 'transparent',
                padding: i === lastIdx ? '1px 4px' : '0',
                borderRadius: 4,
                marginRight: 4, transition: 'all .2s',
              }}>{w}</span>
            ))}
            <span style={{
              display: 'inline-block',
              width: 2, height: 18, marginLeft: 2,
              background: T.accent, verticalAlign: 'middle',
              animation: 'cp-cursor 0.9s steps(2) infinite',
            }}/>
          </div>
        ) : (
          <div style={{ fontSize: 14, color: T.ink3, fontStyle: 'italic' }}>
            말씀을 시작해주세요…
          </div>
        )}
        {/* Progress hint */}
        <div style={{
          position: 'absolute', top: 18, right: 18,
          fontSize: 10.5, color: T.ink3, fontWeight: 600,
          letterSpacing: '0.02em',
        }}>
          {liveIdx > 0 ? `${liveIdx}/${totalSteps}` : ''}
        </div>
      </div>

      <div style={{ fontSize: 11.5, color: T.ink3, lineHeight: 1.5,
                    padding: '0 4px 18px' }}>
        잘못 들렸으면 멈춘 뒤 텍스트를 직접 고칠 수 있어요
      </div>

      {/* Waveform + stop */}
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column',
                    alignItems: 'center', justifyContent: 'center' }}>
        <div style={{ display: 'flex', alignItems: 'flex-end', gap: 4,
                      marginBottom: 24, height: 44 }}>
          {[0,1,2,3,4,5,6,7,8,9,10,11].map(i => (
            <div key={i} style={{
              width: 4, borderRadius: 2,
              background: T.danger,
              height: 8 + ((i * 7) % 28),
              animation: `cp-wave ${0.55 + (i % 4) * 0.18}s ease-in-out infinite ${i * 0.06}s`,
              transformOrigin: 'bottom',
            }}/>
          ))}
        </div>
        <button onClick={onStop} style={{
          width: 80, height: 80, borderRadius: '50%',
          background: T.danger, border: 'none', cursor: 'pointer', padding: 0,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          boxShadow: '0 0 0 12px rgba(181,72,60,0.16), 0 8px 28px rgba(181,72,60,0.4)',
          animation: 'cp-mic-pulse 1.4s ease-in-out infinite',
        }}>
          <Icons.Stop size={32} color="#FFF"/>
        </button>
        <div style={{ fontSize: 12.5, color: T.ink2, fontWeight: 600,
                      marginTop: 10, letterSpacing: '-0.01em' }}>
          다 말했으면 탭해서 멈추기
        </div>
      </div>
    </div>
  );
}

function VoiceDoneView({ text, onChange, onRetry, T }) {
  const { favs, setFavs, sel, setSel } = useLangPrefs();
  const [override, setOverride] = React.useState(null);
  const [sourceLangOverride, setSourceLangOverride] = React.useState(null);

  const detected = detectDirection(text);
  const direction = override || detected;
  const isForeignSource = direction === 'fo->ko';
  const flipDir = () => setOverride(direction === 'ko->fo' ? 'fo->ko' : 'ko->fo');
  const overridden = override && override !== detected;

  const detectedSource = detectSourceLang(text);
  const sourceLang = sourceLangOverride || detectedSource || 'en';
  const sourceOverridden = !!sourceLangOverride && sourceLangOverride !== detectedSource;

  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column',
                  overflowY: 'auto', paddingBottom: 12 }}>
      {/* Success pill */}
      <div style={{
        alignSelf: 'center',
        display: 'inline-flex', alignItems: 'center', gap: 6,
        background: T.accentSoft, color: T.accent,
        padding: '5px 11px', borderRadius: 999,
        fontSize: 12, fontWeight: 700, letterSpacing: '-0.01em',
        marginBottom: 14, marginTop: 6, flexShrink: 0,
      }}>
        <Icons.Check size={14} color={T.accent}/>
        듣기 완료 · 필요하면 고쳐주세요
      </div>

      {/* Editable textarea */}
      <div style={{ position: 'relative', marginBottom: 8 }}>
        <textarea
          value={text} onChange={e => onChange(e.target.value)}
          style={{
            width: '100%', minHeight: 120,
            background: T.surface, border: `0.5px solid ${T.hairline}`,
            borderRadius: 16, padding: '16px 14px 30px',
            fontSize: 17, color: T.ink, lineHeight: 1.5,
            letterSpacing: '-0.01em',
            fontFamily: 'inherit', outline: 'none', resize: 'none',
          }}/>
        <div style={{
          position: 'absolute', bottom: 8, right: 12,
          fontSize: 11, color: T.ink3, fontWeight: 600,
          letterSpacing: '-0.005em',
        }}>
          {text.length}자
        </div>
      </div>

      <DirectionChip direction={direction} overridden={overridden}
                     onFlip={flipDir} T={T}/>

      <div style={{ fontSize: 12, color: T.ink3, lineHeight: 1.5,
                    padding: '0 4px 12px' }}>
        음성 인식이 잘 못 알아들었으면 위 칸을 탭해서 직접 고치세요. 방향이 다르게 잡혔으면 칩을 탭해서 바꿔주세요.
      </div>

      {/* Actions */}
      <div style={{ display: 'flex', gap: 8, marginBottom: 22, flexShrink: 0 }}>
        <Button kind="secondary" onClick={onRetry}
                icon={<Icons.Refresh size={16} color={T.ink}/>}
                style={{ flex: 1 }}>
          다시 녹음
        </Button>
        <Button kind="ghost" onClick={() => onChange('')}
                disabled={!text}
                style={{ flex: 1 }}>
          지우기
        </Button>
      </div>

      {/* Translation target — hidden when direction is foreign→meaning */}
      <div style={{ marginBottom: 18 }}>
        <div style={{ fontSize: 11.5, fontWeight: 700, color: T.ink3,
                      letterSpacing: '0.08em', textTransform: 'uppercase',
                      marginBottom: 10 }}>
          {isForeignSource ? '결과 언어' : '번역 언어'}
        </div>
        {isForeignSource
          ? <MeaningTargetCard sourceLang={sourceLang}
                               onSourceLangChange={setSourceLangOverride}
                               sourceOverridden={sourceOverridden}
                               T={T}/>
          : <LangPickerRow value={sel} onChange={setSel}
                           favorites={favs} onFavChange={setFavs}/>}
      </div>
    </div>
  );
}

// ──────────────────────────────────────────────────────────────
// P06c Screenshot input
//   Step 1 source picker → substep (picker / camera / clipboard)
//   Step 2 detect regions
//   Step 3 confirm + lang
// ──────────────────────────────────────────────────────────────
function ScreenInputScreenshot({ state, onNavigate }) {
  const T = window.T;
  // step: 1=source select, 2=detect, 3=confirm
  // subStep (only when step=1): null | 'picker' | 'camera' | 'clipboard' | 'preview'
  const initial =
    state === 'detect'    ? { step: 2, subStep: null }
    : state === 'confirm' ? { step: 3, subStep: null }
    : state === 'confirm-foreign' ? { step: 3, subStep: null }
    : state === 'confirm-mixed'   ? { step: 3, subStep: null }
    : state === 'picker'  ? { step: 1, subStep: 'picker' }
    : state === 'camera'  ? { step: 1, subStep: 'camera' }
    : state === 'clipboard' ? { step: 1, subStep: 'clipboard' }
    : state === 'preview' ? { step: 1, subStep: 'preview' }
    : { step: 1, subStep: null };
  const [step, setStep] = React.useState(initial.step);
  const [subStep, setSubStep] = React.useState(initial.subStep);
  // The selected image — stored so the preview screen can show it.
  // {source:'picker'|'camera'|'recent', hue, label}
  const [picked, setPicked] = React.useState(
    initial.subStep === 'preview' ? { source: 'picker', hue: '#C97B5C', label: '사진 보관함' } : null
  );

  const goBack = () => {
    if (subStep === 'preview') {
      // Return to the source-specific sub-screen the user came from
      setSubStep(picked?.source === 'camera' ? 'camera' : 'picker');
      return;
    }
    if (subStep) { setSubStep(null); return; }
    if (step > 1) { setStep(step - 1); return; }
    onNavigate('back');
  };

  const title =
    subStep === 'picker'    ? '사진 보관함'
    : subStep === 'camera'  ? '카메라'
    : subStep === 'clipboard' ? '클립보드'
    : subStep === 'preview' ? '이 사진이 맞나요?'
    : `스크린샷 · ${step}/3`;

  // Picker/camera pick a photo → hand off to the preview substep
  const pickFromLibrary = (photo) => { setPicked({ source: 'picker', ...photo }); setSubStep('preview'); };
  const captureFromCam  = (photo) => { setPicked({ source: 'camera', ...photo }); setSubStep('preview'); };

  return (
    <div style={{ position: 'absolute', inset: 0, background: T.bg,
                  display: 'flex', flexDirection: 'column' }}>
      <TopBar title={title}
        leading={<IconButton icon={<Icons.Back size={22} color={T.ink}/>}
                             onClick={goBack}/>}
        trailing={step === 3 && !subStep ? (
          <button onClick={() => onNavigate('P09')} style={{
            background: 'transparent', border: 'none',
            color: T.accent, fontSize: 15, fontWeight: 700,
            padding: '0 4px', fontFamily: 'inherit', cursor: 'pointer',
          }}>완료</button>
        ) : null}
      />

      {/* Step indicator (only on main flow, not sub-screens) */}
      {!subStep && (
        <div style={{ display: 'flex', gap: 4, padding: '0 20px 12px' }}>
          {[1, 2, 3].map(s => (
            <div key={s} style={{
              flex: 1, height: 4, borderRadius: 2,
              background: s <= step ? T.accent : T.hairlineStrong,
              transition: 'background .2s',
            }}/>
          ))}
        </div>
      )}

      {step === 1 && !subStep && (
        <StepSource
          onPicker={() => setSubStep('picker')}
          onCamera={() => setSubStep('camera')}
          onClipboard={() => setSubStep('clipboard')}
          onPickRecent={(photo) => pickFromLibrary(photo)}
        />
      )}
      {step === 1 && subStep === 'picker'    && <SubPicker    onPicked={pickFromLibrary}/>}
      {step === 1 && subStep === 'camera'    && <SubCamera    onShot={captureFromCam}/>}
      {step === 1 && subStep === 'clipboard' && <SubClipboard onNext={() => { setSubStep(null); setStep(2); }} onCancel={() => setSubStep(null)}/>}
      {step === 1 && subStep === 'preview'   && <SubPreview   picked={picked}
                                                              onConfirm={() => { setSubStep(null); setStep(2); }}
                                                              onPickAgain={() => setSubStep(picked?.source === 'camera' ? 'camera' : 'picker')}/>}
      {step === 2 && <StepDetect onNext={() => setStep(3)}/>}
      {step === 3 && <StepConfirm variant={
        state === 'confirm-foreign' ? 'foreign'
        : state === 'confirm-mixed' ? 'mixed'
        : 'default'
      }/>}
    </div>
  );
}

function StepSource({ onPicker, onCamera, onClipboard, onPickRecent }) {
  const T = window.T;
  const items = [
    { id: 1, hasText: true,  hue: '#C97B5C' },
    { id: 2, hasText: false, hue: '#4A6B4F' },
    { id: 3, hasText: true,  hue: '#8B5C7A' },
    { id: 4, hasText: true,  hue: '#5A7A9B' },
    { id: 5, hasText: false, hue: '#D49B3F' },
    { id: 6, hasText: true,  hue: '#8B6F47' },
  ];
  return (
    <div style={{ flex: 1, overflowY: 'auto', padding: '4px 20px 24px' }}>
      <div style={{ fontSize: 15.5, fontWeight: 700, color: T.ink,
                    letterSpacing: '-0.02em', marginBottom: 4 }}>사진을 골라주세요</div>
      <div style={{ fontSize: 12.5, color: T.ink2, lineHeight: 1.5, marginBottom: 18 }}>
        한국어 글자가 보이는 이미지면 돼요
      </div>

      <div style={{ display: 'flex', flexDirection: 'column', gap: 8, marginBottom: 22 }}>
        <SourceRow icon={<Icons.Image size={22} color={T.ink}/>}
                   label="사진 보관함에서 고르기"
                   sub="최근 사진 · 앨범"
                   onClick={onPicker}/>
        <SourceRow icon={<Icons.Camera size={22} color={T.ink}/>}
                   label="카메라로 찍기"
                   sub="메뉴판 · 표지판 즉시 촬영"
                   onClick={onCamera}/>
        <SourceRow icon={<Icons.Clipboard size={22} color={T.ink}/>}
                   label="클립보드에서 가져오기"
                   sub="방금 캡처한 이미지 자동 감지"
                   onClick={onClipboard}/>
      </div>

      <div style={{ fontSize: 11.5, fontWeight: 700, color: T.ink3,
                    letterSpacing: '0.08em', textTransform: 'uppercase',
                    marginBottom: 10 }}>최근 스크린샷</div>
      <div style={{
        display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 8,
      }}>
        {items.map(it => (
          <div key={it.id} onClick={() => onPickRecent({ hue: it.hue, label: '최근 스크린샷' })} style={{
            aspectRatio: '9/16',
            background: `linear-gradient(135deg, ${it.hue}66 0%, ${it.hue}33 100%)`,
            borderRadius: 12, position: 'relative', cursor: 'pointer',
            overflow: 'hidden',
          }}>
            <div style={{ position: 'absolute', inset: '20% 20% auto 20%',
                          height: 6, borderRadius: 3, background: 'rgba(255,255,255,0.6)' }}/>
            <div style={{ position: 'absolute', inset: '36% 30% auto 20%',
                          height: 5, borderRadius: 3, background: 'rgba(255,255,255,0.45)' }}/>
            <div style={{ position: 'absolute', inset: '48% 24% auto 20%',
                          height: 5, borderRadius: 3, background: 'rgba(255,255,255,0.45)' }}/>
            {it.hasText && (
              <div style={{
                position: 'absolute', top: 6, right: 6,
                fontSize: 9, fontWeight: 700, color: '#FFF',
                background: 'rgba(0,0,0,0.6)', padding: '2px 6px',
                borderRadius: 8, letterSpacing: '-0.01em',
              }}>가 ㅏ</div>
            )}
          </div>
        ))}
      </div>
    </div>
  );
}

function SourceRow({ icon, label, sub, onClick }) {
  const T = window.T;
  return (
    <button onClick={onClick} style={{
      background: T.surface, borderRadius: 14,
      border: `0.5px solid ${T.hairline}`,
      padding: '14px 16px',
      display: 'flex', alignItems: 'center', gap: 12,
      fontFamily: 'inherit', cursor: 'pointer', width: '100%',
      WebkitTapHighlightColor: 'transparent',
    }}>
      <div style={{ width: 40, height: 40, borderRadius: 11,
                    background: T.inkOverlaySoft,
                    display: 'flex', alignItems: 'center', justifyContent: 'center' }}>{icon}</div>
      <div style={{ flex: 1, textAlign: 'left', minWidth: 0 }}>
        <div style={{ fontSize: 14.5, fontWeight: 600, color: T.ink,
                      letterSpacing: '-0.01em' }}>{label}</div>
        {sub && <div style={{ fontSize: 12, color: T.ink3, marginTop: 2 }}>{sub}</div>}
      </div>
      <Icons.ChevronR size={18} color={T.ink3}/>
    </button>
  );
}

// ── P06c sub-screen: photo library picker ───────────────────────
function SubPicker({ onPicked }) {
  const T = window.T;
  const [sel, setSel] = React.useState(null);
  const [album, setAlbum] = React.useState('recent');

  // Build a fake photo grid
  const photos = Array.from({ length: 18 }, (_, i) => {
    const hues = ['#C97B5C','#4A6B4F','#8B5C7A','#5A7A9B','#D49B3F','#8B6F47','#9B6B3E','#6B7A4F','#7A4F4F'];
    return { id: i, hue: hues[i % hues.length], hasText: i % 3 !== 1 };
  });
  const selectedPhoto = photos.find(p => p.id === sel);
  const confirm = () => {
    if (selectedPhoto) onPicked({ hue: selectedPhoto.hue, label: '사진 보관함' });
  };

  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', minHeight: 0 }}>
      {/* Album segment */}
      <div style={{ padding: '0 16px 12px', flexShrink: 0 }}>
        <Segment
          options={[
            { value: 'recent', label: '최근' },
            { value: 'screen', label: '스크린샷' },
            { value: 'fav',    label: '즐겨찾기' },
          ]}
          value={album} onChange={setAlbum}
        />
      </div>

      {/* Photo grid */}
      <div style={{ flex: 1, overflowY: 'auto', padding: '0 12px 16px', minHeight: 0 }}>
        <div style={{ fontSize: 11, fontWeight: 700, color: T.ink3,
                      letterSpacing: '0.06em', textTransform: 'uppercase',
                      padding: '0 4px 8px' }}>오늘 · 어제</div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 4 }}>
          {photos.map(p => {
            const on = sel === p.id;
            return (
              <div key={p.id} onClick={() => setSel(p.id)} style={{
                aspectRatio: '1/1', position: 'relative', cursor: 'pointer',
                background: `linear-gradient(135deg, ${p.hue}80 0%, ${p.hue}40 100%)`,
                borderRadius: 6, overflow: 'hidden',
                boxShadow: on ? `inset 0 0 0 3px ${T.accent}` : 'none',
              }}>
                {/* mock lines */}
                <div style={{ position: 'absolute', inset: '24% 24% auto 18%',
                              height: 4, borderRadius: 2, background: 'rgba(255,255,255,0.6)' }}/>
                <div style={{ position: 'absolute', inset: '38% 30% auto 18%',
                              height: 3, borderRadius: 2, background: 'rgba(255,255,255,0.45)' }}/>
                <div style={{ position: 'absolute', inset: '48% 24% auto 18%',
                              height: 3, borderRadius: 2, background: 'rgba(255,255,255,0.45)' }}/>
                {/* selection radial */}
                <div style={{
                  position: 'absolute', top: 6, right: 6,
                  width: 20, height: 20, borderRadius: '50%',
                  background: on ? T.accent : 'rgba(255,255,255,0.55)',
                  border: on ? `2px solid #FFF` : '1.5px solid rgba(255,255,255,0.85)',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  boxShadow: '0 1px 3px rgba(0,0,0,0.18)',
                }}>
                  {on && <Icons.Check size={12} color="#FFF" strokeWidth={3}/>}
                </div>
                {/* text marker */}
                {p.hasText && !on && (
                  <div style={{
                    position: 'absolute', bottom: 4, left: 4,
                    fontSize: 9, fontWeight: 700, color: '#FFF',
                    background: 'rgba(0,0,0,0.55)', padding: '1px 5px',
                    borderRadius: 4, letterSpacing: '-0.01em',
                  }}>가 ㅏ</div>
                )}
              </div>
            );
          })}
        </div>
      </div>

      {/* Footer action */}
      <div style={{
        padding: '12px 20px 18px', background: T.bg,
        borderTop: `0.5px solid ${T.hairline}`,
        flexShrink: 0,
      }}>
        <Button kind="primary" fullWidth onClick={confirm}
                disabled={sel == null}>
          {sel == null ? '사진을 골라주세요' : '이 사진 사용하기'}
        </Button>
      </div>
    </div>
  );
}

// ── P06c sub-screen: camera viewfinder ───────────────────────
function SubCamera({ onShot }) {
  const T = window.T;
  const shoot = () => onShot({ hue: '#3A2F26', label: '카메라 촬영', cam: true });
  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', minHeight: 0 }}>
      {/* Viewfinder */}
      <div style={{
        flex: 1, margin: '0 16px 12px', borderRadius: 18,
        background: 'linear-gradient(180deg, #2a241c 0%, #0a0807 100%)',
        position: 'relative', overflow: 'hidden', minHeight: 0,
      }}>
        {/* Mock scene — soft warm gradient with floating "text" blocks */}
        <div style={{ position: 'absolute', inset: 0,
                      background: 'radial-gradient(circle at 30% 40%, rgba(212,165,116,0.18) 0%, transparent 50%)' }}/>
        {/* Frame corners */}
        {['topL','topR','botL','botR'].map(c => {
          const p = {
            topL: { top: 16, left: 16, borderTop: '2.5px solid #FFF', borderLeft: '2.5px solid #FFF', borderRadius: '6px 0 0 0' },
            topR: { top: 16, right: 16, borderTop: '2.5px solid #FFF', borderRight: '2.5px solid #FFF', borderRadius: '0 6px 0 0' },
            botL: { bottom: 16, left: 16, borderBottom: '2.5px solid #FFF', borderLeft: '2.5px solid #FFF', borderRadius: '0 0 0 6px' },
            botR: { bottom: 16, right: 16, borderBottom: '2.5px solid #FFF', borderRight: '2.5px solid #FFF', borderRadius: '0 0 6px 0' },
          };
          return <div key={c} style={{ position: 'absolute', width: 28, height: 28, ...p[c] }}/>;
        })}

        {/* Mock text block being detected */}
        <div style={{
          position: 'absolute', top: '38%', left: '18%', right: '18%',
          border: '1.5px dashed rgba(255,255,255,0.55)',
          borderRadius: 6, padding: '10px 12px',
        }}>
          <div style={{ height: 6, background: 'rgba(255,255,255,0.7)', borderRadius: 3, marginBottom: 6 }}/>
          <div style={{ height: 6, background: 'rgba(255,255,255,0.55)', borderRadius: 3, width: '72%' }}/>
        </div>

        {/* Detection hint */}
        <div style={{
          position: 'absolute', top: 28, left: '50%',
          transform: 'translateX(-50%)',
          background: 'rgba(0,0,0,0.55)', color: '#FFF',
          fontSize: 11.5, fontWeight: 600, letterSpacing: '-0.01em',
          padding: '5px 10px', borderRadius: 14,
          display: 'inline-flex', alignItems: 'center', gap: 6,
        }}>
          <span style={{ width: 6, height: 6, borderRadius: '50%',
                         background: '#7BD17A',
                         animation: 'cp-mic-pulse 1.4s ease-in-out infinite' }}/>
          한국어 글자 감지 중
        </div>

        {/* Controls overlay */}
        <div style={{
          position: 'absolute', bottom: 14, left: 14, right: 14,
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        }}>
          <button style={{
            width: 40, height: 40, borderRadius: '50%',
            background: 'rgba(0,0,0,0.45)', border: 'none',
            cursor: 'pointer', color: '#FFF',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>⚡</button>
          <button onClick={shoot} style={{
            width: 64, height: 64, borderRadius: '50%',
            background: '#FFF',
            border: '4px solid rgba(255,255,255,0.5)',
            outline: '2px solid #FFF',
            cursor: 'pointer', padding: 0,
          }}/>
          <button style={{
            width: 40, height: 40, borderRadius: '50%',
            background: 'rgba(0,0,0,0.45)', border: 'none',
            cursor: 'pointer', color: '#FFF',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            <Icons.Refresh size={18} color="#FFF"/>
          </button>
        </div>
      </div>

      <div style={{ padding: '4px 20px 18px', textAlign: 'center' }}>
        <div style={{ fontSize: 13, color: T.ink2, lineHeight: 1.5 }}>
          한국어 글자가 잘 보이게 화면을 채워주세요
        </div>
      </div>
    </div>
  );
}

// ── P06c sub-screen: clipboard ───────────────────────
function SubClipboard({ onNext, onCancel }) {
  const T = window.T;
  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column',
                  padding: '4px 20px 24px', minHeight: 0 }}>
      <div style={{
        background: T.accentSoft,
        borderRadius: 12, padding: '12px 14px', marginBottom: 18,
        fontSize: 13, color: T.accent, lineHeight: 1.5, fontWeight: 600,
        display: 'flex', alignItems: 'center', gap: 10,
      }}>
        <Icons.Clipboard size={18} color={T.accent}/>
        클립보드에서 이미지를 찾았어요
      </div>

      {/* Pasted image preview */}
      <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center',
                    marginBottom: 18, minHeight: 0 }}>
        <div style={{
          width: '70%', aspectRatio: '9/16',
          background: 'linear-gradient(135deg, #C97B5C66 0%, #8B6F4733 100%)',
          borderRadius: 18, position: 'relative', overflow: 'hidden',
          boxShadow: '0 12px 32px rgba(0,0,0,0.15)',
          border: `0.5px solid ${T.hairlineStrong}`,
        }}>
          {/* Mock screenshot lines */}
          <div style={{ position: 'absolute', inset: '14% 14% auto 14%',
                        height: 8, borderRadius: 3, background: 'rgba(255,255,255,0.7)' }}/>
          <div style={{ position: 'absolute', inset: '22% 26% auto 14%',
                        height: 6, borderRadius: 3, background: 'rgba(255,255,255,0.55)' }}/>
          <div style={{ position: 'absolute', inset: '34% 14% auto 14%',
                        height: 6, borderRadius: 3, background: 'rgba(255,255,255,0.55)' }}/>
          <div style={{ position: 'absolute', inset: '42% 30% auto 14%',
                        height: 6, borderRadius: 3, background: 'rgba(255,255,255,0.55)' }}/>
          <div style={{ position: 'absolute', inset: '56% 20% auto 14%',
                        height: 6, borderRadius: 3, background: 'rgba(255,255,255,0.55)' }}/>
          <div style={{ position: 'absolute', inset: '66% 14% auto 14%',
                        height: 6, borderRadius: 3, background: 'rgba(255,255,255,0.55)' }}/>
          {/* Source meta strip */}
          <div style={{
            position: 'absolute', top: 8, right: 8,
            fontSize: 9.5, fontWeight: 700, color: '#FFF',
            background: 'rgba(0,0,0,0.55)', padding: '3px 7px',
            borderRadius: 8,
          }}>1170 × 2532</div>
        </div>
      </div>

      <div style={{ fontSize: 12.5, color: T.ink3, textAlign: 'center', lineHeight: 1.5,
                    marginBottom: 14 }}>
        이 이미지를 사용해서 씨앗을 만들까요?
      </div>

      <div style={{ display: 'flex', gap: 8 }}>
        <Button kind="secondary" onClick={onCancel} style={{ flex: 1 }}>
          다른 사진 고르기
        </Button>
        <Button kind="primary" onClick={onNext} style={{ flex: 1 }}>
          이 이미지 사용
        </Button>
      </div>
    </div>
  );
}

function StepDetect({ onNext }) {
  const T = window.T;
  const [selected, setSelected] = React.useState(new Set([0, 1, 2]));
  const regions = [
    { id: 0, top: '14%',  left: '12%', w: '76%', h: '6%',  text: '오므라이스 추천 받을 수 있을까요?' },
    { id: 1, top: '24%',  left: '12%', w: '60%', h: '5%',  text: '계산은 어디서 하나요?' },
    { id: 2, top: '34%',  left: '12%', w: '70%', h: '5%',  text: '영수증 주실 수 있어요?' },
    { id: 3, top: '50%',  left: '12%', w: '52%', h: '5%',  text: '주문 도와주세요' },
    { id: 4, top: '60%',  left: '12%', w: '66%', h: '5%',  text: '물 한 잔 더 주세요' },
  ];
  const toggle = (id) => {
    const n = new Set(selected);
    n.has(id) ? n.delete(id) : n.add(id);
    setSelected(n);
  };

  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', minHeight: 0 }}>
      <div style={{
        background: '#1A1510',
        margin: '0 16px 12px', borderRadius: 16,
        padding: '8px',
        flex: 1, minHeight: 0, position: 'relative',
        overflow: 'hidden',
      }}>
        <div style={{
          position: 'absolute', inset: 8,
          background: 'linear-gradient(180deg, #2a241c 0%, #1a1510 100%)',
          borderRadius: 10, overflow: 'hidden',
        }}>
          {regions.map(r => {
            const on = selected.has(r.id);
            return (
              <div key={r.id} onClick={() => toggle(r.id)} style={{
                position: 'absolute',
                top: r.top, left: r.left, width: r.w, height: r.h,
                background: on ? 'rgba(197,160,122,0.3)' : 'rgba(255,255,255,0.08)',
                border: on ? `1.5px solid #C5A07A` : '1.5px dashed rgba(255,255,255,0.3)',
                borderRadius: 4, cursor: 'pointer',
                display: 'flex', alignItems: 'center',
                padding: '0 6px',
                fontSize: 9, color: on ? '#FFF' : 'rgba(255,255,255,0.7)',
                fontWeight: 600,
              }}>{r.text}</div>
            );
          })}
        </div>
      </div>

      <div style={{ padding: '4px 20px 24px' }}>
        <div style={{ fontSize: 13.5, color: T.ink2, textAlign: 'center', marginBottom: 14 }}>
          담을 영역을 탭하세요 · <b style={{ color: T.ink }}>{selected.size}개</b> 선택됨
        </div>
        <div style={{ display: 'flex', gap: 8 }}>
          <Button kind="secondary" onClick={() => setSelected(new Set(regions.map(r => r.id)))} style={{ flex: 1 }}>
            전체 선택
          </Button>
          <Button kind="primary" onClick={onNext}
                  disabled={selected.size === 0} style={{ flex: 1 }}>
            다음 ({selected.size})
          </Button>
        </div>
      </div>
    </div>
  );
}

function StepConfirm({ variant = 'default' }) {
  const T = window.T;
  const { favs, setFavs, sel, setSel } = useLangPrefs();

  // Each detected phrase gets an AI-suggested category (auto-applied).
  // User can tap the chip to swap, or open the picker for more options.
  const ITEMS = React.useMemo(() => {
    if (variant === 'foreign') return [
      { text: 'Could you give me a hand?',  autoCats: ['food'] },
      { text: 'Sorry to bother you',         autoCats: ['food'] },
      { text: 'Thanks for waiting',          autoCats: ['food'] },
    ];
    if (variant === 'mixed') return [
      { text: '오므라이스 추천 받을 수 있을까요?', autoCats: ['food'] },
      { text: 'Could you give me a hand?',         autoCats: ['food'] },
      { text: '계산은 어디서 하나요?',              autoCats: ['food'] },
      { text: 'Thanks for waiting',                autoCats: ['food'] },
    ];
    return [
      { text: '오므라이스 추천 받을 수 있을까요?', autoCats: ['food'] },
      { text: '계산은 어디서 하나요?',             autoCats: ['food'] },
      { text: '영수증 주실 수 있어요?',            autoCats: ['food'] },
    ];
  }, [variant]);

  const [drop, setDrop] = React.useState(new Set());
  const [perItemCats, setPerItemCats] = React.useState(
    () => ITEMS.map(i => i.autoCats)
  );
  const [pickerFor, setPickerFor] = React.useState(null); // item idx or null
  const [dismissedHint, setDismissedHint] = React.useState(false);
  const [dismissedMixed, setDismissedMixed] = React.useState(false);

  // Direction + source-lang override (mirrors P06a / P06b done view)
  const [dirOverride, setDirOverride] = React.useState(null);
  const [sourceLangOverride, setSourceLangOverride] = React.useState(null);

  // Compute direction from currently-selected (non-dropped) items combined
  const activeTexts = ITEMS.map((it, i) => drop.has(i) ? '' : it.text).filter(Boolean);
  const concat      = activeTexts.join(' ');
  const detectedDir = detectDirection(concat);
  const direction   = dirOverride || detectedDir;
  const isForeignSrc = direction === 'fo->ko';
  const dirOverridden = dirOverride && dirOverride !== detectedDir;
  const flipDir = () => setDirOverride(direction === 'ko->fo' ? 'fo->ko' : 'ko->fo');

  const detectedSource = detectSourceLang(concat);
  const sourceLang     = sourceLangOverride || detectedSource || 'en';
  const sourceOverridden = !!sourceLangOverride && sourceLangOverride !== detectedSource;

  // Mixed-script detection — only among non-dropped items
  const activeScripts = new Set(activeTexts.map(detectScript).filter(Boolean));
  const isMixed = activeScripts.size > 1;

  // For mixed case: split into Korean group + foreign group
  // "All" = includes dropped items (for visual grouping in the item list)
  // "Idx" = only non-dropped (used for picker count / source-lang detection)
  const koItemsAll  = ITEMS.map((it, i) => ({it, i}))
    .filter(({it}) => detectScript(it.text) === '한');
  const foItemsAll  = ITEMS.map((it, i) => ({it, i}))
    .filter(({it}) => detectScript(it.text) !== '한' && detectScript(it.text));
  const koreanIdx   = koItemsAll.filter(({i}) => !drop.has(i));
  const foreignIdx  = foItemsAll.filter(({i}) => !drop.has(i));
  const foreignConcat = foreignIdx.map(({it}) => it.text).join(' ');
  const detectedSourceFo = detectSourceLang(foreignConcat);
  const sourceLangFo     = sourceLangOverride || detectedSourceFo || 'en';
  const sourceFoOverridden = !!sourceLangOverride && sourceLangOverride !== detectedSourceFo;

  const remaining = ITEMS.filter((_, i) => !drop.has(i));
  const liveCats = window.__cpCats || window.MOCK_CATEGORIES;
  const catById = Object.fromEntries(liveCats.map(c => [c.id, c]));

  // Did the user touch ANY auto suggestion? Hides the "1회 안내".
  const anyAutoUntouched = perItemCats.some((cats, i) =>
    !drop.has(i) && cats.length === ITEMS[i].autoCats.length &&
    cats.every(c => ITEMS[i].autoCats.includes(c))
  );

  const setCatsFor = (idx, newCats) => {
    setPerItemCats(p => p.map((c, i) => i === idx ? newCats : c));
  };

  // Single-item card renderer — reused in both flat and grouped layouts
  const renderItem = (it, i) => {
    const removed = drop.has(i);
    const cats = perItemCats[i] || [];
    const isAuto = (cats.length === it.autoCats.length &&
                   cats.every(c => it.autoCats.includes(c)));
    const scriptChip = detectScript(it.text);
    return (
      <div key={i} style={{
        background: T.surface, borderRadius: 14,
        border: `0.5px solid ${T.hairline}`,
        padding: '12px 14px',
        opacity: removed ? 0.4 : 1,
        textDecoration: removed ? 'line-through' : 'none',
      }}>
        <div style={{
          display: 'flex', alignItems: 'flex-start', gap: 10,
          marginBottom: removed ? 0 : 10,
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 6,
                        paddingTop: 1, flexShrink: 0 }}>
            <div style={{ fontSize: 11, fontWeight: 700, color: T.ink3,
                          letterSpacing: '0.05em', minWidth: 14 }}>{i + 1}</div>
            <div style={{
              fontSize: 10, fontWeight: 800, color: T.ink2,
              background: T.bg, padding: '2px 6px', borderRadius: 5,
              letterSpacing: 0, lineHeight: 1.2,
            }} title="감지된 언어 스크립트">{scriptChip}</div>
          </div>
          <div style={{ flex: 1, fontSize: 14, color: T.ink, lineHeight: 1.4 }}>{it.text}</div>
          <IconButton icon={removed ? <Icons.Plus size={16} color={T.ink3}/> : <Icons.Close size={16} color={T.ink3}/>}
                      onClick={() => {
                        const n = new Set(drop);
                        n.has(i) ? n.delete(i) : n.add(i);
                        setDrop(n);
                      }}
                      size={32}/>
        </div>
        {!removed && (
          <div style={{
            paddingLeft: 50,
            display: 'flex', flexWrap: 'wrap', gap: 6, alignItems: 'center',
          }}>
            {cats.map(cid => {
              const c = catById[cid];
              if (!c) return null;
              return (
                <button key={cid}
                        onClick={() => setPickerFor(i)}
                        style={{
                  height: 26, padding: '0 10px 0 8px', borderRadius: 13,
                  background: isAuto ? T.accentSoft : T.accent,
                  color: isAuto ? T.accent : '#FFF',
                  border: 'none', cursor: 'pointer',
                  fontFamily: 'inherit', fontSize: 11.5, fontWeight: 700,
                  letterSpacing: '-0.005em', whiteSpace: 'nowrap',
                  display: 'inline-flex', alignItems: 'center', gap: 4,
                }}>
                  {isAuto && <Icons.Sparkle size={10} color={T.accent}/>}
                  {c.icon ? <span style={{ fontSize: 12 }}>{c.icon}</span>
                          : <span style={{ fontSize: 10, fontWeight: 800 }}>{window.monogramOf(c.label)}</span>}
                  {c.label}
                </button>
              );
            })}
            <button onClick={() => setPickerFor(i)} style={{
              height: 26, padding: '0 9px',
              background: 'transparent',
              border: `1px dashed ${T.hairlineStrong}`,
              borderRadius: 13, color: T.ink3,
              fontFamily: 'inherit', fontSize: 11.5, fontWeight: 600,
              cursor: 'pointer', whiteSpace: 'nowrap',
              display: 'inline-flex', alignItems: 'center', gap: 3,
            }}>
              <Icons.Edit size={11} color={T.ink3}/> 분류 바꾸기
            </button>
          </div>
        )}
      </div>
    );
  };

  return (
    <div style={{ flex: 1, overflowY: 'auto', padding: '4px 20px 24px' }}>
      <div style={{ fontSize: 15.5, fontWeight: 700, color: T.ink,
                    letterSpacing: '-0.02em', marginBottom: 4 }}>이대로 담을까요?</div>
      <div style={{ fontSize: 12.5, color: T.ink2, lineHeight: 1.5, marginBottom: 14 }}>
        {remaining.length}개의 씨앗을 만들 거예요. 마음에 안 드는 건 빼도 돼요.
      </div>

      {/* Mixed-language notice */}
      {isMixed && !dismissedMixed && (
        <div style={{
          background: '#FFF5E0',
          border: '0.5px solid #E5C68A',
          borderRadius: 12, padding: '10px 12px 10px 14px',
          marginBottom: 12, display: 'flex', gap: 10, alignItems: 'flex-start',
        }}>
          <span style={{ fontSize: 14, lineHeight: 1.2 }}>⚠️</span>
          <div style={{ flex: 1, fontSize: 12.5, color: '#7A5A1F', lineHeight: 1.5 }}>
            <b style={{ color: '#5A3F15' }}>서로 다른 언어가 섞여있어요 — 각자 알맞게 만들어드려요.</b>
            <br/>한국어 박스는 외국어로, 외국어 박스는 한국어 뜻으로 한 번에 만들어져요. 아래에 두 그룹의 설정이 각각 보여요.
          </div>
          <IconButton icon={<Icons.Close size={14} color={T.ink3}/>}
                      onClick={() => setDismissedMixed(true)} size={26}/>
        </div>
      )}

      {/* One-time auto-classify nudge */}
      {anyAutoUntouched && !dismissedHint && (
        <div style={{
          background: T.accentSoft,
          border: `0.5px solid ${T.hairlineStrong}`,
          borderRadius: 12, padding: '10px 12px 10px 14px',
          marginBottom: 14, display: 'flex', gap: 10, alignItems: 'flex-start',
        }}>
          <Icons.Sparkle size={16} color={T.accent}/>
          <div style={{ flex: 1, fontSize: 12.5, color: T.ink2, lineHeight: 1.5,
                        letterSpacing: '-0.005em' }}>
            <b style={{ color: T.ink }}>AI가 분류를 자동으로 골랐어요.</b>
            <br/>아래 ✨ 칩을 탭하면 바꿀 수 있어요.
          </div>
          <IconButton icon={<Icons.Close size={14} color={T.ink3}/>}
                      onClick={() => setDismissedHint(true)} size={26}/>
        </div>
      )}

      {/* Item list + picker — combined per-direction card when mixed,
          flat items with separate picker when single-language */}
      {isMixed ? (
        <React.Fragment>
          {koItemsAll.length > 0 && (
            <div style={{
              background: 'rgba(139,111,71,0.06)',
              border: '0.5px solid rgba(139,111,71,0.25)',
              borderRadius: 14, padding: 12, marginBottom: 14,
            }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8,
                            marginBottom: 10, padding: '0 2px' }}>
                <div style={{
                  width: 24, height: 24, borderRadius: '50%',
                  background: T.accent, color: '#FFF',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  fontSize: 11, fontWeight: 800, flexShrink: 0,
                }}>한</div>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 13.5, fontWeight: 700, color: T.ink,
                                letterSpacing: '-0.015em' }}>
                    한국어 박스 {koreanIdx.length}개 → 외국어로 만들기
                  </div>
                  <div style={{ fontSize: 11, color: T.ink3, marginTop: 1 }}>
                    {Math.max(sel.length, 1)}개 언어 × {koreanIdx.length} = <b>{Math.max(sel.length, 1) * koreanIdx.length}개 씨앗</b>
                  </div>
                </div>
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 8,
                            marginBottom: 12 }}>
                {koItemsAll.map(({it, i}) => renderItem(it, i))}
              </div>
              <div style={{ height: 0.5, background: 'rgba(139,111,71,0.25)',
                            margin: '4px 2px 12px' }}/>
              <div style={{ padding: '0 2px' }}>
                <div style={{ fontSize: 11, fontWeight: 700, color: T.ink3,
                              letterSpacing: '0.08em', textTransform: 'uppercase',
                              marginBottom: 8 }}>번역 언어</div>
                <LangPickerRow value={sel} onChange={setSel}
                               favorites={favs} onFavChange={setFavs}/>
              </div>
            </div>
          )}
          {foItemsAll.length > 0 && (
            <div style={{
              background: 'rgba(107,93,74,0.06)',
              border: '0.5px solid rgba(107,93,74,0.25)',
              borderRadius: 14, padding: 12, marginBottom: 22,
            }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8,
                            marginBottom: 10, padding: '0 2px' }}>
                <div style={{
                  width: 24, height: 24, borderRadius: '50%',
                  background: '#6B5D4A', color: '#FFF',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  fontSize: 10, fontWeight: 800, flexShrink: 0,
                }}>외</div>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 13.5, fontWeight: 700, color: T.ink,
                                letterSpacing: '-0.015em' }}>
                    외국어 박스 {foreignIdx.length}개 → 한국어 뜻 만들기
                  </div>
                  <div style={{ fontSize: 11, color: T.ink3, marginTop: 1 }}>
                    <b>{foreignIdx.length}개 씨앗</b> (뜻·뉘앙스·예문·대화)
                  </div>
                </div>
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 8,
                            marginBottom: 12 }}>
                {foItemsAll.map(({it, i}) => renderItem(it, i))}
              </div>
              <div style={{ height: 0.5, background: 'rgba(107,93,74,0.25)',
                            margin: '4px 2px 12px' }}/>
              <div style={{ padding: '0 2px' }}>
                <div style={{ fontSize: 11, fontWeight: 700, color: T.ink3,
                              letterSpacing: '0.08em', textTransform: 'uppercase',
                              marginBottom: 8 }}>결과 언어</div>
                <MeaningTargetCard sourceLang={sourceLangFo}
                                   onSourceLangChange={setSourceLangOverride}
                                   sourceOverridden={sourceFoOverridden}
                                   T={T}/>
              </div>
            </div>
          )}
        </React.Fragment>
      ) : (
        <React.Fragment>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8, marginBottom: 14 }}>
            {ITEMS.map((it, i) => renderItem(it, i))}
          </div>
          <DirectionChip direction={direction} overridden={dirOverridden}
                         onFlip={flipDir} T={T}/>
          <div style={{ marginBottom: 16 }}>
            <div style={{ fontSize: 11.5, fontWeight: 700, color: T.ink3,
                          letterSpacing: '0.08em', textTransform: 'uppercase',
                          marginBottom: 10 }}>
              {isForeignSrc ? '결과 언어 (전체 적용)' : '번역 언어 (전체 적용)'}
            </div>
            {isForeignSrc
              ? <MeaningTargetCard sourceLang={sourceLang}
                                   onSourceLangChange={setSourceLangOverride}
                                   sourceOverridden={sourceOverridden}
                                   T={T}/>
              : <LangPickerRow value={sel} onChange={setSel}
                               favorites={favs} onFavChange={setFavs}/>}
          </div>
        </React.Fragment>
      )}

      {/* Per-item category picker sheet */}
      <BottomSheet open={pickerFor !== null}
                   onClose={() => setPickerFor(null)}
                   title="이 씨앗의 분류">
        {pickerFor !== null && (
          <ConfirmCatPicker
            initial={perItemCats[pickerFor]}
            onChange={(next) => setCatsFor(pickerFor, next)}
            onClose={() => setPickerFor(null)}
            itemText={ITEMS[pickerFor].text}
          />
        )}
      </BottomSheet>
    </div>
  );
}

// Compact category picker used by the P06 confirm sheet — mirrors P05c
// but scoped to per-item selection and includes inline [+ 새 카테고리].
function ConfirmCatPicker({ initial, onChange, onClose, itemText }) {
  const T = window.T;
  const liveCats = window.__cpCats || window.MOCK_CATEGORIES;
  const [cats, setCats] = React.useState(liveCats);
  const [sel, setSel] = React.useState(new Set(initial || []));
  const [addOpen, setAddOpen] = React.useState(false);
  const [newLabel, setNewLabel] = React.useState('');
  const [newIcon, setNewIcon] = React.useState(null);
  const MAX = 3;

  const sorted = window.sortCatsByUsage(cats);

  const toggle = (id) => {
    const n = new Set(sel);
    if (n.has(id)) n.delete(id);
    else if (n.size < MAX) n.add(id);
    setSel(n);
  };

  const commitNew = () => {
    const label = newLabel.trim();
    if (!label) return;
    const c = window.makeNewCat(label, newIcon);
    const next = [c, ...cats];
    setCats(next);
    window.__cpCats = next;
    const ns = new Set(sel);
    if (ns.size < MAX) ns.add(c.id);
    setSel(ns);
    setNewLabel(''); setNewIcon(null); setAddOpen(false);
  };

  const commit = () => { onChange([...sel]); onClose(); };

  return (
    <div style={{ padding: '6px 20px 24px' }}>
      <div style={{
        fontSize: 12.5, color: T.ink2, lineHeight: 1.5,
        padding: '4px 0 14px', fontStyle: 'italic',
        overflow: 'hidden', textOverflow: 'ellipsis',
        whiteSpace: 'nowrap',
      }}>"{itemText}"</div>

      <div style={{ display: 'flex', alignItems: 'center',
                    justifyContent: 'space-between', marginBottom: 10 }}>
        <div style={{ fontSize: 11.5, fontWeight: 700, color: T.ink3,
                      letterSpacing: '0.08em', textTransform: 'uppercase' }}>분류</div>
        <span style={{ fontSize: 11.5, fontWeight: 700,
                       color: sel.size >= MAX ? T.danger : T.ink3 }}>{sel.size}/{MAX}</span>
      </div>

      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, marginBottom: 14 }}>
        {sorted.map(c => {
          const on = sel.has(c.id);
          const disabled = !on && sel.size >= MAX;
          return (
            <button key={c.id} onClick={() => toggle(c.id)} disabled={disabled} style={{
              padding: '9px 12px 9px 8px', borderRadius: 14,
              background: on ? T.accent : T.surface,
              color: on ? '#FFF' : T.ink2,
              border: on ? 'none' : `0.5px solid ${T.hairline}`,
              fontFamily: 'inherit', fontSize: 13, fontWeight: 600,
              cursor: disabled ? 'default' : 'pointer',
              opacity: disabled ? 0.4 : 1,
              display: 'inline-flex', gap: 8, alignItems: 'center',
            }}>
              {c.icon
                ? <span style={{ fontSize: 14 }}>{c.icon}</span>
                : <span style={{
                    width: 18, height: 18, borderRadius: 5,
                    background: on ? 'rgba(255,255,255,0.22)' : T.accentSoft,
                    color: on ? '#FFF' : T.accent,
                    display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                    fontSize: 9.5, fontWeight: 800, letterSpacing: '-0.04em',
                  }}>{window.monogramOf(c.label)}</span>}
              {c.label}
            </button>
          );
        })}
        {!addOpen && (
          <button onClick={() => setAddOpen(true)} style={{
            padding: '9px 14px', borderRadius: 14,
            background: 'transparent',
            border: `1px dashed ${T.hairlineStrong}`,
            color: T.ink2, fontFamily: 'inherit',
            fontSize: 13, fontWeight: 600, cursor: 'pointer',
            display: 'inline-flex', gap: 4, alignItems: 'center',
          }}>
            <Icons.Plus size={14} color={T.ink2}/> 새 카테고리
          </button>
        )}
      </div>

      {addOpen && (
        <div style={{
          background: T.surface, borderRadius: 14,
          border: `0.5px solid ${T.hairlineStrong}`,
          padding: 14, marginBottom: 14,
        }}>
          <input value={newLabel}
                 onChange={e => setNewLabel(e.target.value.slice(0, 16))}
                 placeholder="새 카테고리 이름"
                 autoFocus maxLength={16}
                 onKeyDown={(e) => { if (e.key === 'Enter') commitNew(); }}
                 style={{
                   width: '100%', height: 40, padding: '0 12px',
                   background: T.bg, border: `0.5px solid ${T.hairlineStrong}`,
                   borderRadius: 10, fontSize: 14, color: T.ink,
                   fontFamily: 'inherit', outline: 'none', marginBottom: 10,
                 }}/>
          <div style={{
            display: 'grid', gridTemplateColumns: 'repeat(8, 1fr)', gap: 4,
            marginBottom: 10,
          }}>
            <button onClick={() => setNewIcon(null)} style={{
              aspectRatio: '1/1', borderRadius: 8,
              background: newIcon === null ? T.accent : T.bg,
              color: newIcon === null ? '#FFF' : T.ink2,
              border: newIcon === null ? 'none' : `0.5px solid ${T.hairlineStrong}`,
              fontFamily: 'inherit', fontSize: 11, fontWeight: 700,
              cursor: 'pointer',
            }}>글자</button>
            {(window.MOCK_CAT_EMOJI || []).slice(0, 15).map(e => {
              const on = newIcon === e;
              return (
                <button key={e} onClick={() => setNewIcon(on ? null : e)} style={{
                  aspectRatio: '1/1', borderRadius: 8,
                  background: on ? T.accentSoft : T.bg,
                  border: on ? `1.5px solid ${T.accent}` : `0.5px solid ${T.hairline}`,
                  fontFamily: 'inherit', fontSize: 15, cursor: 'pointer',
                }}>{e}</button>
              );
            })}
          </div>
          <div style={{ display: 'flex', gap: 8 }}>
            <Button kind="ghost" onClick={() => {
              setAddOpen(false); setNewLabel(''); setNewIcon(null);
            }} style={{ flex: 1, height: 38 }}>취소</Button>
            <Button kind="primary" disabled={!newLabel.trim()}
                    onClick={commitNew} style={{ flex: 2, height: 38 }}>추가</Button>
          </div>
        </div>
      )}

      <Button kind="primary" fullWidth onClick={commit} style={{ height: 52 }}>
        완료
      </Button>
    </div>
  );
}

// ── P06c sub-screen: preview the chosen photo before detection ─────
// Reached from SubPicker (after picking from library) or SubCamera (after capture).
// Shows the photo full-bleed, plus quick metadata, then offers to proceed.
function SubPreview({ picked, onConfirm, onPickAgain }) {
  const T = window.T;
  const hue = picked?.hue || '#C97B5C';
  const source = picked?.source === 'camera' ? '카메라로 방금 찍은 사진' : '사진 보관함에서 선택';
  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', minHeight: 0 }}>
      {/* Source meta */}
      <div style={{
        margin: '0 20px 14px', padding: '10px 14px',
        background: T.surface, border: `0.5px solid ${T.hairline}`,
        borderRadius: 12,
        display: 'flex', alignItems: 'center', gap: 10,
      }}>
        {picked?.source === 'camera'
          ? <Icons.Camera size={18} color={T.accent}/>
          : <Icons.Image size={18} color={T.accent}/>}
        <div style={{ flex: 1, fontSize: 12.5, color: T.ink2,
                      letterSpacing: '-0.01em' }}>{source}</div>
        <div style={{ fontSize: 11, fontWeight: 700, color: T.ink3,
                      letterSpacing: '-0.005em' }}>JPG · 1170×2532</div>
      </div>

      {/* Photo preview */}
      <div style={{ flex: 1, padding: '0 20px 12px',
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                    minHeight: 0 }}>
        <div style={{
          maxHeight: '100%', height: '100%',
          aspectRatio: '9/16',
          background: `linear-gradient(135deg, ${hue}99 0%, ${hue}44 100%)`,
          borderRadius: 18, position: 'relative', overflow: 'hidden',
          boxShadow: '0 16px 36px rgba(0,0,0,0.18)',
          border: `0.5px solid ${T.hairlineStrong}`,
        }}>
          {/* mock document content */}
          <div style={{ position: 'absolute', inset: '12% 14% auto 14%',
                        height: 12, borderRadius: 4, background: 'rgba(255,255,255,0.78)' }}/>
          <div style={{ position: 'absolute', inset: '22% 28% auto 14%',
                        height: 8, borderRadius: 4, background: 'rgba(255,255,255,0.58)' }}/>
          <div style={{ position: 'absolute', inset: '36% 14% auto 14%',
                        height: 8, borderRadius: 4, background: 'rgba(255,255,255,0.58)' }}/>
          <div style={{ position: 'absolute', inset: '44% 30% auto 14%',
                        height: 8, borderRadius: 4, background: 'rgba(255,255,255,0.58)' }}/>
          <div style={{ position: 'absolute', inset: '58% 22% auto 14%',
                        height: 8, borderRadius: 4, background: 'rgba(255,255,255,0.58)' }}/>
          <div style={{ position: 'absolute', inset: '68% 14% auto 14%',
                        height: 8, borderRadius: 4, background: 'rgba(255,255,255,0.58)' }}/>
          <div style={{ position: 'absolute', inset: '76% 36% auto 14%',
                        height: 8, borderRadius: 4, background: 'rgba(255,255,255,0.58)' }}/>

          {/* Detected-text hint badge */}
          <div style={{
            position: 'absolute', top: 12, right: 12,
            display: 'inline-flex', alignItems: 'center', gap: 5,
            background: 'rgba(0,0,0,0.62)', color: '#FFF',
            padding: '4px 9px', borderRadius: 12,
            fontSize: 10.5, fontWeight: 700, letterSpacing: '-0.005em',
          }}>
            <span style={{ width: 5, height: 5, borderRadius: '50%',
                           background: '#7BD17A' }}/>
            한국어 발견
          </div>
        </div>
      </div>

      {/* Hint */}
      <div style={{ fontSize: 12.5, color: T.ink2, textAlign: 'center',
                    padding: '0 20px 12px', lineHeight: 1.5 }}>
        다음 단계에서 글자 영역을 골라 씨앗으로 담을 수 있어요
      </div>

      {/* Actions */}
      <div style={{
        padding: '10px 20px 18px', background: T.bg,
        borderTop: `0.5px solid ${T.hairline}`,
        display: 'flex', gap: 8,
      }}>
        <Button kind="secondary" onClick={onPickAgain} style={{ flex: 1 }}
                icon={picked?.source === 'camera'
                  ? <Icons.Refresh size={16} color={T.ink}/>
                  : <Icons.Image size={16} color={T.ink}/>}>
          {picked?.source === 'camera' ? '다시 찍기' : '다른 사진'}
        </Button>
        <Button kind="primary" onClick={onConfirm} style={{ flex: 1.4 }}
                iconRight={<Icons.Forward size={16} color="#FFF"/>}>
          글자 찾기
        </Button>
      </div>
    </div>
  );
}

Object.assign(window, { ScreenInput, ScreenInputTyping, ScreenInputVoice, ScreenInputScreenshot });
