// pipi-app.jsx — Mobile app screens (home, player, listening, choice, settings)
// Plus a small UI primitive set: ScribbleButton, ScribbleTabBar, etc.

// ── Primitives ────────────────────────────────────────────────

function ScribbleButton({ children, color = PIPI.yellow, onClick, size = 'md',
                          icon = null, fullWidth = false, seed = 1, style = {} }) {
  const h = size === 'lg' ? 64 : size === 'sm' ? 40 : 52;
  const padX = size === 'lg' ? 28 : 18;
  return (
    <button onClick={onClick} style={{
      position: 'relative', height: h, padding: `0 ${padX}px`,
      background: 'transparent', border: 'none', cursor: 'pointer',
      width: fullWidth ? '100%' : 'auto',
      fontFamily: '"Patrick Hand", cursive', color: PIPI.ink,
      ...style,
    }}>
      <svg viewBox={`0 0 200 ${h}`} preserveAspectRatio="none" width="100%" height={h}
           style={{ position: 'absolute', inset: 0, width: '100%', height: '100%' }}>
        {/* shadow offset */}
        <path d={wobblyRectPath(4, 5, 192, h - 6, { r: h / 2 - 4, amp: 1.5, seed: seed + 10 })}
              fill={PIPI.ink} opacity={0.18}/>
        <path d={wobblyRectPath(2, 2, 192, h - 6, { r: h / 2 - 4, amp: 1.8, seed })}
              fill={color} stroke={PIPI.ink} strokeWidth={3.5}/>
      </svg>
      <span style={{ position: 'relative', display: 'inline-flex', alignItems: 'center',
        gap: 8, fontSize: size === 'lg' ? 24 : 20, lineHeight: 1, paddingTop: 2 }}>
        {icon}{children}
      </span>
    </button>
  );
}

function ScribbleCard({ children, color = PIPI.paperLt, seed = 1, style = {}, r = 22, sw = 3.5 }) {
  // CSS-only equivalent of a wobbly box (used for big surfaces — SVG is too heavy)
  return (
    <div style={{
      position: 'relative', background: color,
      border: `${sw}px solid ${PIPI.ink}`, borderRadius: r,
      ...style,
    }}>
      {children}
    </div>
  );
}

// SVG-backed wobbly card (use sparingly, e.g. hero)
function ScribbleCardSvg({ w, h, color = PIPI.paperLt, seed = 1, r = 22, sw = 3.5, children, style = {} }) {
  return (
    <div style={{ position: 'relative', width: w, height: h, ...style }}>
      <svg viewBox={`0 0 ${w} ${h}`} width={w} height={h} style={{ position: 'absolute', inset: 0 }}>
        <path d={wobblyRectPath(3, 3, w - 6, h - 6, { r, amp: 2, seed })}
              fill={color} stroke={PIPI.ink} strokeWidth={sw}/>
      </svg>
      <div style={{ position: 'relative', width: '100%', height: '100%' }}>{children}</div>
    </div>
  );
}

// Tab icons (scribbly)
function IconHome({ size = 28, active = false }) {
  return (
    <svg viewBox="0 0 40 40" width={size} height={size} style={{ display: 'block' }}>
      <path d={wobblyPath([[6,20],[20,8],[34,20],[34,34],[6,34]], { amp: 1.2, seed: 1 })}
            fill={active ? PIPI.yellow : 'none'} stroke={PIPI.ink} strokeWidth={3} strokeLinejoin="round"/>
      <path d={wobblyRectPath(16, 24, 8, 10, { r: 2, amp: 0.6, seed: 2 })}
            fill={active ? PIPI.coral : 'none'} stroke={PIPI.ink} strokeWidth={2.5}/>
    </svg>
  );
}
function IconLibrary({ size = 28, active = false }) {
  return (
    <svg viewBox="0 0 40 40" width={size} height={size} style={{ display: 'block' }}>
      <path d={wobblyRectPath(7, 8, 8, 26, { r: 2, amp: 0.8, seed: 3 })}
            fill={active ? PIPI.pink : 'none'} stroke={PIPI.ink} strokeWidth={3}/>
      <path d={wobblyRectPath(17, 6, 8, 28, { r: 2, amp: 0.8, seed: 4 })}
            fill={active ? PIPI.blue : 'none'} stroke={PIPI.ink} strokeWidth={3}/>
      <path d={wobblyRectPath(27, 10, 8, 24, { r: 2, amp: 0.8, seed: 5 })}
            fill={active ? PIPI.green : 'none'} stroke={PIPI.ink} strokeWidth={3}/>
    </svg>
  );
}
function IconSearch({ size = 28, active = false }) {
  return (
    <svg viewBox="0 0 40 40" width={size} height={size} style={{ display: 'block' }}>
      <path d={wobblyCirclePath(18, 18, 9, { amp: 0.8, seed: 6, segs: 14 })}
            fill={active ? PIPI.lilac : 'none'} stroke={PIPI.ink} strokeWidth={3}/>
      <path d={wobblyLinePath(26, 26, 33, 33, { amp: 0.5, seed: 7, segs: 4 })}
            fill="none" stroke={PIPI.ink} strokeWidth={3.5} strokeLinecap="round"/>
    </svg>
  );
}
function IconParent({ size = 28, active = false }) {
  return (
    <svg viewBox="0 0 40 40" width={size} height={size} style={{ display: 'block' }}>
      <path d={wobblyCirclePath(20, 14, 6, { amp: 0.7, seed: 8, segs: 12 })}
            fill={active ? PIPI.coral : 'none'} stroke={PIPI.ink} strokeWidth={2.8}/>
      <path d={wobblyPath([[8,34],[10,24],[30,24],[32,34]], { amp: 1, seed: 9 })}
            fill={active ? PIPI.coral : 'none'} stroke={PIPI.ink} strokeWidth={2.8}/>
    </svg>
  );
}

function IconPlay({ size = 36 }) {
  return (
    <svg viewBox="0 0 40 40" width={size} height={size}>
      <path d={wobblyPath([[12,8],[12,32],[32,20]], { amp: 1.2, seed: 30 })}
            fill={PIPI.ink} stroke={PIPI.ink} strokeWidth={3} strokeLinejoin="round"/>
    </svg>
  );
}
function IconPause({ size = 36 }) {
  return (
    <svg viewBox="0 0 40 40" width={size} height={size}>
      <path d={wobblyRectPath(11, 9, 7, 22, { r: 2, amp: 0.8, seed: 31 })}
            fill={PIPI.ink} stroke={PIPI.ink} strokeWidth={2.5}/>
      <path d={wobblyRectPath(22, 9, 7, 22, { r: 2, amp: 0.8, seed: 32 })}
            fill={PIPI.ink} stroke={PIPI.ink} strokeWidth={2.5}/>
    </svg>
  );
}
function IconBack({ size = 28 }) {
  return (
    <svg viewBox="0 0 40 40" width={size} height={size}>
      <path d={wobblyLinePath(28, 8, 14, 20, { amp: 1, seed: 33, segs: 6 })}
            fill="none" stroke={PIPI.ink} strokeWidth={4} strokeLinecap="round"/>
      <path d={wobblyLinePath(14, 20, 28, 32, { amp: 1, seed: 34, segs: 6 })}
            fill="none" stroke={PIPI.ink} strokeWidth={4} strokeLinecap="round"/>
    </svg>
  );
}
function IconSkipBack({ size = 28 }) {
  return (
    <svg viewBox="0 0 40 40" width={size} height={size}>
      <path d={wobblyPath([[26,10],[26,30],[14,20]], { amp: 1, seed: 35 })}
            fill={PIPI.ink} stroke={PIPI.ink} strokeWidth={2.5} strokeLinejoin="round"/>
      <path d={wobblyLinePath(12, 10, 12, 30, { amp: 0.6, seed: 36, segs: 4 })}
            fill="none" stroke={PIPI.ink} strokeWidth={3.5} strokeLinecap="round"/>
    </svg>
  );
}
function IconSkipFwd({ size = 28 }) {
  return (
    <svg viewBox="0 0 40 40" width={size} height={size}>
      <path d={wobblyPath([[14,10],[14,30],[26,20]], { amp: 1, seed: 37 })}
            fill={PIPI.ink} stroke={PIPI.ink} strokeWidth={2.5} strokeLinejoin="round"/>
      <path d={wobblyLinePath(28, 10, 28, 30, { amp: 0.6, seed: 38, segs: 4 })}
            fill="none" stroke={PIPI.ink} strokeWidth={3.5} strokeLinecap="round"/>
    </svg>
  );
}
function IconMic({ size = 36 }) {
  return (
    <svg viewBox="0 0 40 40" width={size} height={size}>
      <path d={wobblyRectPath(14, 7, 12, 20, { r: 6, amp: 0.8, seed: 39 })}
            fill={PIPI.paperLt} stroke={PIPI.ink} strokeWidth={3}/>
      <path d="M9 22 Q9 32 20 32 Q31 32 31 22" fill="none" stroke={PIPI.ink} strokeWidth={3} strokeLinecap="round"/>
      <path d="M20 32 L20 36" stroke={PIPI.ink} strokeWidth={3} strokeLinecap="round"/>
    </svg>
  );
}

// Tab bar
function ScribbleTabBar({ active, onChange }) {
  const tabs = [
    { id: 'home',    label: 'Domov',    Icon: IconHome },
    { id: 'library', label: 'Knižnica', Icon: IconLibrary },
    { id: 'search',  label: 'Hľadať',   Icon: IconSearch },
    { id: 'parent',  label: 'Rodič',    Icon: IconParent },
  ];
  const W = 402, H = 92;
  // Width is 100% so the bar fits both the 402-wide iPhone mockup and a
  // narrower real-mobile viewport in bare mode. The SVG keeps the
  // original 402x92 viewBox and stretches via preserveAspectRatio="none"
  // — the wobbly rounded rectangle still looks fine at any width because
  // the corner radius is large.
  return (
    <div style={{ position: 'relative', width: '100%', height: H, paddingBottom: 24, flexShrink: 0 }}>
      <svg viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="none" width="100%" height={H} style={{ position: 'absolute', inset: 0 }}>
        <path d={wobblyRectPath(10, 6, W - 20, H - 30, { r: 32, amp: 2, seed: 40 })}
              fill={PIPI.paperLt} stroke={PIPI.ink} strokeWidth={3.5}/>
      </svg>
      <div style={{
        position: 'absolute', top: 6, bottom: 24, left: 10, right: 10,
        display: 'flex', justifyContent: 'space-around', alignItems: 'center',
      }}>
        {tabs.map(t => {
          const isOn = t.id === active;
          return (
            <button key={t.id} onClick={() => onChange(t.id)} style={{
              background: 'transparent', border: 0, cursor: 'pointer',
              padding: '4px 8px', minWidth: 64,
              display: 'flex', flexDirection: 'column', alignItems: 'center',
              justifyContent: 'center', gap: 3,
              fontFamily: '"Patrick Hand", cursive', color: PIPI.ink,
              WebkitTapHighlightColor: 'transparent',
            }}>
              <span style={{
                width: 32, height: 32, display: 'inline-flex',
                alignItems: 'center', justifyContent: 'center',
              }}>
                <t.Icon active={isOn}/>
              </span>
              <span style={{
                fontSize: 14, lineHeight: 1, fontWeight: isOn ? 700 : 400,
                opacity: isOn ? 1 : 0.65,
              }}>{t.label}</span>
            </button>
          );
        })}
      </div>
    </div>
  );
}

// ── Stories data ──────────────────────────────────────────────
// `rootScene` (optional) overrides the default 'start' scene-key used by
// DemoApp.openStory(). `badge` is rendered as a small ribbon on the
// HomeScreen featured + shelf cards.
const STORIES = [
  // ── Variácie product: 3 real audiobooks with authored mid-story
  //    branches. Each plays the original recording, pauses at a clean
  //    sentence boundary, asks a scene-aware Slovak question, plays an
  //    ack MP3 for the picked branch, then continues.
  // ── EN Pippi core: the three flagship books, authored English
  //    adaptations of our own licensed narration (see inputs/en-tales/
  //    *-script.json), rendered in the clone voice with the same
  //    audited split structure as their SK originals.
  {
    id: 'circus', title: 'Pippi Goes to the Circus', art: StoryFairy, color: PIPI.pink,
    mood: 'classic', age: '4–8', len: '10 min', lang: 'en',
    rootScene: 'circus_book', badge: 'Most loved',
    lesson: 'The best trick of all is noticing other people.',
    product: 'variations',
  },
  {
    id: 'outing', title: 'Pippi Goes on an Outing', art: StorySea, color: PIPI.blue,
    mood: 'adventure', age: '4–8', len: '9 min', lang: 'en',
    rootScene: 'outing_book',
    lesson: 'An adventure is best when it is shared.',
    product: 'variations',
  },
  {
    id: 'burglars', title: 'Pippi and the Burglars', art: StoryRobot, color: PIPI.lilac,
    mood: 'exciting', age: '5–8', len: '8 min', lang: 'en',
    rootScene: 'burglars_book',
    lesson: 'Courage is knowing how to stay calm.',
    product: 'variations',
  },
  // ── First English book. Public-domain source (Joseph Jacobs, 1890), so unlike
  //    the three Pipi books below it carries no IP blocker and is launchable.
  {
    id: 'goldilocks', title: 'Goldilocks and the Three Bears', art: StoryDragon, color: PIPI.green, lang: 'en',
    mood: 'classic',     age: '4-8', len: '4 min',
    rootScene: 'goldilocks_book', badge: 'New',
    lesson: 'Asking first beats sneaking in, and sorry is a brave word.',
    product: 'variations',
  },
  {
    id: 'cirkus',  title: 'Pipi ide do cirkusu', art: StoryFairy,  color: PIPI.pink, lang: 'sk',
    mood: 'klasika',     age: '4–8', len: '15 min',
    rootScene: 'cirkus_book', badge: 'Najobľúbenejšie',
    lesson: 'Najkrajší trik je všimnúť si druhých.',
    product: 'variations',
  },
  {
    id: 'vylet',   title: 'Pipi usporiada výlet', art: StorySea,  color: PIPI.blue, lang: 'sk',
    mood: 'dobrodružné', age: '4–8', len: '14 min',
    rootScene: 'vylet_book',
    lesson: 'Dobrodružstvo je lepšie, keď sa rozdelí.',
    product: 'variations',
  },
  {
    id: 'zlodeji', title: 'Pipi navštívia zlodeji', art: StoryRobot, color: PIPI.lilac, lang: 'sk',
    mood: 'napínavé',    age: '5–8', len: '12 min',
    rootScene: 'zlodeji_book',
    lesson: 'Odvaha je vedieť ostať pokojný.',
    product: 'variations',
  },
  // Cirkus-test: dense-splits 5-min sandbox version of cirkus, used to
  // iterate quickly on voice/classifier behaviour without sitting
  // through the full 15:38 audiobook. Shares the cirkus source MP3
  // but with 6 splits in the first 5 minutes and endAtSec=300.
  {
    id: 'cirkusTest', title: 'Cirkus test (5 min)', art: StoryFairy, color: PIPI.yellow, lang: 'sk',
    mood: 'test',        age: 'dev', len: '5 min',
    rootScene: 'cirkusTest_book', badge: 'TEST',
    lesson: 'Rýchla iterácia pre dev.',
    product: 'variations',
    dev: true,
  },
  // ── Custom product: one interactive book where every decision is
  //    fully AI-generated. The 3-round custom chain: scene → open
  //    question → child speaks → AI extends; ×3 rounds, lesson only at
  //    the end of the third round (not per round).
  { id: 'vila',    title: 'Pipi a tajomstvo vily',  art: StoryFairy,  color: PIPI.lilac,  mood: 'interaktívne',   age: '4–7', len: '~5 min', lang: 'sk',
    lesson: 'Čo poviete, to sa stane. Vy ste rozprávkár.',
    product: 'custom' },
].filter((s) => !s.dev || (typeof window !== 'undefined' && (
  // dev-only entries (cirkusTest) stay hidden from real users — same
  // switches as demo-app.jsx SHOW_DEV_BOOKS, evaluated here too because
  // this list renders the cards even when the scene graph is gated.
  /[?&]dev=1(\b|&|$)/.test(window.location.search) ||
  (() => { try { return localStorage.getItem('pipi.devBooks') === '1'; } catch { return false; } })()
)));
// Which stories a given UI language shows. Book audio is per-language
// (an EN child cannot follow SK narration), so the shelf filters hard
// instead of showing translated cards for unplayable books.
function visibleStories(lang) {
  const want = lang === 'sk' ? 'sk' : 'en';
  return STORIES.filter((s) => (s.lang || 'en') === want);
}


// ── Phone shell wrapper ───────────────────────────────────────
// Default: renders content inside the IOSDevice mockup (status bar,
// dynamic island, home indicator, rounded outer frame) — used on the
// landing's hero preview where the iPhone-shaped mockup is the point.
// bare={true}: drops the iPhone chrome and renders fullscreen — used
// by the demo on real mobile screens so the child gets a true full-
// screen app, not a tiny mockup inside a fake iPhone.
function PhoneShell({ children, label, sublabel, w = 402, h = 874, bare = false }) {
  if (bare) {
    return (
      <div style={{ width: '100%', height: '100%', background: PIPI.paper,
        fontFamily: '"Patrick Hand", cursive', color: PIPI.ink,
        display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
        {children}
      </div>
    );
  }
  return (
    <div>
      <IOSDevice width={w} height={h}>
        <div style={{ width: '100%', height: '100%', background: PIPI.paper,
          fontFamily: '"Patrick Hand", cursive', color: PIPI.ink,
          display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
          {children}
        </div>
      </IOSDevice>
    </div>
  );
}

// Phone status row (replaces iOS dark status — already in IOSDevice).
// Just a top header row inside the app.
function AppHeader({ greeting, sub, right = null }) {
  return (
    <div style={{ padding: '18px 22px 8px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
      <div>
        <div style={{ fontFamily: '"Caveat", cursive', fontWeight: 700, fontSize: 34, lineHeight: 1 }}>
          {greeting}
        </div>
        {sub && <div style={{ fontSize: 17, opacity: 0.7, marginTop: 2 }}>{sub}</div>}
      </div>
      {right}
    </div>
  );
}

// ── 1. HOME screen ────────────────────────────────────────────
// The content (header → greeting → featured → shelf → bedtime) lives
// inside a flex:1 / overflow-y:auto wrapper so it scrolls on small
// screens while the tab bar stays pinned to the bottom of the viewport.
// `t` is the caller's DEMO_STRINGS slice. It is optional because this same
// component doubles as the landing page's hero phone mock, which has no
// dictionary loaded — so every lookup carries an English default rather than
// leaving the mock blank.
function HomeScreen({ onOpen, onTab, showTabBar = true, resume = null, onResume = null, t = null, lang = 'en' }) {
  const vis = visibleStories(lang);
  const tx = (k, d) => (t && t[k]) || d;
  // The demo passes a real per-kid `resume` ({ story, progress }); the
  // landing hero preview passes nothing and falls back to the showcase.
  const contStory = resume ? resume.story : vis[0];
  const contProgress = resume ? resume.progress : 0.42;
  const contOpen = resume && onResume ? onResume : () => onOpen(vis[0]);
  return (
    <>
      <div style={{ flex: 1, minHeight: 0, overflowY: 'auto', WebkitOverflowScrolling: 'touch' }}>
      <AppHeader
        greeting={tx('home_hello', 'Hi!')}
        sub={tx('home_sub', 'Pipi has a new story for you.')}
        right={<div style={{ width: 56, height: 56, background: PIPI.yellow, border: `3px solid ${PIPI.ink}`,
          borderRadius: 16, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <PipiMini size={46}/>
        </div>}
      />

      {/* Pipi greeting bubble */}
      <div style={{ padding: '6px 22px 14px', display: 'flex', alignItems: 'flex-end', gap: 12 }}>
        <Pipi size={86}/>
        <div style={{ flex: 1, position: 'relative' }}>
          <svg viewBox="0 0 240 80" width="100%" preserveAspectRatio="none" style={{ height: 84 }}>
            <path d={wobblyRectPath(4, 4, 232, 72, { r: 22, amp: 1.8, seed: 71 })}
                  fill={PIPI.paperLt} stroke={PIPI.ink} strokeWidth={3}/>
            <path d="M16 70 L8 80 L26 72 Z" fill={PIPI.paperLt} stroke={PIPI.ink} strokeWidth={3} strokeLinejoin="round"/>
          </svg>
          <div style={{ position: 'absolute', inset: 0, padding: '12px 18px', fontSize: 19, lineHeight: 1.2 }}>
            <b style={{ fontFamily: '"Caveat", cursive', fontWeight: 700, fontSize: 24 }}>Pipi:</b>{' '}
            {tx('home_bubble', 'Today we are off to the enchanted wood. Will you help me?')}
          </div>
        </div>
      </div>

      {/* Continue listening — large featured card */}
      <div style={{ padding: '0 22px', marginTop: 6 }}>
        <div style={{ fontFamily: '"Caveat", cursive', fontWeight: 700, fontSize: 24, marginBottom: 6 }}>
          {tx('home_continue', 'Continue listening')}
        </div>
        <FeaturedRow story={contStory} progress={contProgress} onOpen={contOpen}/>
      </div>

      {/* Shelf */}
      <div style={{ padding: '22px 22px 0' }}>
        <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 8 }}>
          <div style={{ fontFamily: '"Caveat", cursive', fontWeight: 700, fontSize: 24 }}>{tx('home_shelf', 'Story shelf')}</div>
          <div style={{ fontSize: 16, opacity: 0.6 }}>{tx('home_all', 'all →')}</div>
        </div>
      </div>
      <div style={{ display: 'flex', gap: 14, padding: '4px 22px 8px', overflowX: 'auto' }}>
        {vis.slice(1).map(s => (
          <ShelfCard key={s.id} story={s} onOpen={() => onOpen(s)}/>
        ))}
      </div>

      {/* tonight section — kept as a visible demo card so the hero phone
         preview reads as a full app screen. */}
      <div style={{ padding: '14px 22px 14px' }}>
        <div style={{ fontFamily: '"Caveat", cursive', fontWeight: 700, fontSize: 24, marginBottom: 8 }}>
          {tx('home_bedtime', 'Before bed')}
        </div>
        <ScribbleCard color={PIPI.blue} style={{ padding: '14px 16px', display: 'flex', gap: 12, alignItems: 'center' }}>
          <StoryMoon size={70}/>
          <div style={{ flex: 1 }}>
            <div style={{ fontFamily: '"Caveat", cursive', fontWeight: 700, fontSize: 22, lineHeight: 1 }}>
              {tx('home_quiet_card_t', 'A quiet story with the moon')}
            </div>
            <div style={{ fontSize: 16, opacity: 0.78, marginTop: 4 }}>
              {tx('home_quiet_card_s', '12 min · no loud scenes')}
            </div>
          </div>
          <div style={{ flexShrink: 0 }}>
            <ScribbleButton color={PIPI.paperLt} size="sm" seed={61} icon={<IconPlay size={20}/>}>
              {tx('home_play_btn', 'play')}
            </ScribbleButton>
          </div>
        </ScribbleCard>
      </div>

      {/* Bottom breathing room so the last card isn't hugging the tab bar. */}
      <div style={{ height: 18 }}/>
      </div>{/* end scrollable */}
      {showTabBar && <ScribbleTabBar active="home" onChange={onTab}/>}
    </>
  );
}

function StoryBadge({ label }) {
  if (!label) return null;
  return (
    <div style={{
      position: 'absolute', top: -10, left: 8, transform: 'rotate(-3deg)',
      background: PIPI.yellow, border: `2.5px solid ${PIPI.ink}`,
      borderRadius: 999, padding: '2px 10px',
      fontFamily: '"Caveat", cursive', fontWeight: 700, fontSize: 15,
      color: PIPI.ink, boxShadow: '2px 3px 0 rgba(0,0,0,0.18)',
      whiteSpace: 'nowrap', zIndex: 2,
    }}>★ {label}</div>
  );
}

function FeaturedRow({ story, progress = 0.4, onOpen }) {
  const Art = story.art;
  return (
    <div onClick={onOpen} style={{
      display: 'flex', gap: 14, padding: 12, cursor: 'pointer',
      background: PIPI.paperLt, border: `3.5px solid ${PIPI.ink}`,
      borderRadius: 24, position: 'relative',
    }}>
      <StoryBadge label={story.badge}/>
      <div style={{ width: 110, height: 110, background: story.color,
        border: `3px solid ${PIPI.ink}`, borderRadius: 18,
        display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
      }}>
        <Art size={100}/>
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontFamily: '"Caveat", cursive', fontWeight: 700, fontSize: 24, lineHeight: 1.05 }}>
          {story.title}
        </div>
        <div style={{ fontSize: 15, opacity: 0.7, marginTop: 2 }}>
          {story.lesson ? story.lesson : `chapter 3 · ${Math.round(18 * (1 - progress))} min left`}
        </div>
        {/* progress bar — wobbly */}
        <div style={{ marginTop: 12, height: 14, position: 'relative' }}>
          <svg viewBox="0 0 240 14" preserveAspectRatio="none" width="100%" height={14}>
            <path d={wobblyLinePath(2, 7, 238, 7, { amp: 1.2, seed: 51, segs: 18 })}
                  fill="none" stroke={PIPI.ink} strokeWidth={2.5} opacity={0.3}/>
            <path d={wobblyLinePath(2, 7, 2 + 236 * progress, 7, { amp: 1.2, seed: 51, segs: 14 })}
                  fill="none" stroke={PIPI.pink} strokeWidth={4} strokeLinecap="round"/>
          </svg>
        </div>
      </div>
    </div>
  );
}

function ShelfCard({ story, onOpen }) {
  const Art = story.art;
  return (
    <div onClick={onOpen} style={{ flexShrink: 0, width: 160, cursor: 'pointer', position: 'relative' }}>
      <StoryBadge label={story.badge}/>
      <div style={{ width: 160, height: 160, background: story.color,
        border: `3.5px solid ${PIPI.ink}`, borderRadius: 22,
        display: 'flex', alignItems: 'center', justifyContent: 'center', overflow: 'hidden',
      }}>
        <Art size={150}/>
      </div>
      <div style={{ fontFamily: '"Caveat", cursive', fontWeight: 700, fontSize: 20,
        lineHeight: 1.05, marginTop: 6,
        display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden',
      }}>
        {story.title}
      </div>
      <div style={{ fontSize: 14, opacity: 0.7 }}>{story.age} · {story.len}</div>
    </div>
  );
}

// ── 2. PLAYER screen ──────────────────────────────────────────
function PlayerScreen({ story, playing, onTogglePlay, onBack, onAskChoice, progress = 0.42 }) {
  const Art = story.art;
  return (
    <>
      <div style={{ padding: '12px 18px 0', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <button onClick={onBack} style={{ background: 'transparent', border: 0, padding: 6, cursor: 'pointer' }}>
          <IconBack size={32}/>
        </button>
        <div style={{ fontFamily: '"Patrick Hand", cursive', fontSize: 17, opacity: 0.7 }}>
          Kapitola 3 z 7
        </div>
        <button style={{ background: 'transparent', border: 0, padding: 6, cursor: 'pointer' }}>
          <Heart size={26} fill={PIPI.pink}/>
        </button>
      </div>

      {/* Hero */}
      <div style={{ display: 'flex', justifyContent: 'center', padding: '20px 22px 0' }}>
        <div style={{ width: 320, height: 320, background: story.color,
          border: `4px solid ${PIPI.ink}`, borderRadius: 28,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          transform: 'rotate(-1.2deg)',
          boxShadow: '6px 8px 0 rgba(0,0,0,0.18)',
        }}>
          <Art size={290}/>
        </div>
      </div>

      <div style={{ padding: '22px 24px 0', textAlign: 'center' }}>
        <div style={{ fontFamily: '"Caveat", cursive', fontWeight: 700, fontSize: 32, lineHeight: 1.05 }}>
          {story.title}
        </div>
        <div style={{ fontSize: 17, opacity: 0.72, marginTop: 2 }}>
          rozpráva Pipi · {story.len}
        </div>
      </div>

      {/* Timeline */}
      <div style={{ padding: '20px 28px 0' }}>
        <svg viewBox="0 0 360 22" preserveAspectRatio="none" width="100%" height={22} style={{ display: 'block' }}>
          <path d={wobblyLinePath(4, 11, 356, 11, { amp: 1.5, seed: 80, segs: 24 })}
                fill="none" stroke={PIPI.ink} strokeWidth={3} opacity={0.3}/>
          <path d={wobblyLinePath(4, 11, 4 + 352 * progress, 11, { amp: 1.5, seed: 80, segs: 18 })}
                fill="none" stroke={PIPI.pink} strokeWidth={5} strokeLinecap="round"/>
          {/* head */}
          <circle cx={4 + 352 * progress} cy="11" r="9" fill={PIPI.pink} stroke={PIPI.ink} strokeWidth={2.5}/>
          {/* choice marker upcoming */}
          <g transform={`translate(${4 + 352 * 0.55} 11)`}>
            <path d="M0 -10 L4 -2 L12 -1 L6 4 L8 12 L0 8 L-8 12 L-6 4 L-12 -1 L-4 -2 Z"
                  fill={PIPI.yellow} stroke={PIPI.ink} strokeWidth={2}/>
          </g>
        </svg>
        <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 4,
          fontFamily: '"Patrick Hand", cursive', fontSize: 16, opacity: 0.7 }}>
          <span>7:38</span>
          <span style={{ color: PIPI.red }}>{'\u2605 voľba o 2 min'}</span>
          <span>-10:22</span>
        </div>
      </div>

      {/* Controls */}
      <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', gap: 22, padding: '22px 24px 0' }}>
        <button style={{ background: 'transparent', border: 0, padding: 8, cursor: 'pointer' }}>
          <IconSkipBack size={36}/>
        </button>
        <button onClick={onTogglePlay} style={{
          background: 'transparent', border: 0, padding: 0, cursor: 'pointer',
          width: 96, height: 96, position: 'relative',
        }}>
          <svg viewBox="0 0 96 96" width={96} height={96} style={{ position: 'absolute', inset: 0 }}>
            <path d={wobblyCirclePath(48, 50, 42, { amp: 2, seed: 90, segs: 22 })}
                  fill={PIPI.ink} opacity={0.18}/>
            <path d={wobblyCirclePath(48, 48, 42, { amp: 2, seed: 91, segs: 22 })}
                  fill={PIPI.yellow} stroke={PIPI.ink} strokeWidth={4}/>
          </svg>
          <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            {playing ? <IconPause size={44}/> : <IconPlay size={44}/>}
          </div>
        </button>
        <button style={{ background: 'transparent', border: 0, padding: 8, cursor: 'pointer' }}>
          <IconSkipFwd size={36}/>
        </button>
      </div>

      {/* Try the listening state */}
      <div style={{ padding: '20px 22px 0', display: 'flex', gap: 10 }}>
        <ScribbleButton color={PIPI.pink} seed={120} fullWidth onClick={onAskChoice}>
          ▸ Skús voľbu
        </ScribbleButton>
      </div>

      <div style={{ flex: 1 }}/>
    </>
  );
}

// ── 3. LISTENING state ────────────────────────────────────────
function ListeningScreen({ story, onCancel, onHeard }) {
  const Art = story.art;
  const [rings, setRings] = React.useState(0);
  React.useEffect(() => {
    const t = setInterval(() => setRings(r => r + 1), 700);
    return () => clearInterval(t);
  }, []);
  return (
    <>
      <div style={{ padding: '12px 18px 0', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <button onClick={onCancel} style={{ background: 'transparent', border: 0, padding: 6, cursor: 'pointer' }}>
          <IconBack size={32}/>
        </button>
        <div style={{ fontFamily: '"Caveat", cursive', fontWeight: 700, fontSize: 24 }}>Pipi počúva…</div>
        <div style={{ width: 32 }}/>
      </div>

      {/* Big animated mic + pipi */}
      <div style={{ position: 'relative', height: 320, display: 'flex', alignItems: 'center', justifyContent: 'center', marginTop: 14 }}>
        {[0, 1, 2].map(i => (
          <div key={i} style={{
            position: 'absolute', width: 200 + i * 60, height: 200 + i * 60,
            borderRadius: '50%', border: `3.5px solid ${PIPI.blue}`,
            opacity: 0.85 - i * 0.25,
            animation: `pipiRing 2.1s cubic-bezier(.2,.7,.3,1) ${i * 0.25}s infinite`,
          }}/>
        ))}
        <div style={{ width: 200, height: 200, borderRadius: '50%',
          background: PIPI.blue, border: `4px solid ${PIPI.ink}`,
          display: 'flex', alignItems: 'center', justifyContent: 'center', position: 'relative', zIndex: 2,
        }}>
          <Pipi size={170}/>
        </div>
      </div>

      <div style={{ padding: '8px 36px 0', textAlign: 'center' }}>
        <div style={{ fontFamily: '"Caveat", cursive', fontWeight: 700, fontSize: 30, lineHeight: 1.1 }}>
          "Otvor dvere, alebo radšej uteč?"
        </div>
        <div style={{ fontSize: 18, opacity: 0.7, marginTop: 8 }}>
          Povedz odpoveď nahlas — alebo klikni na obrázok.
        </div>
      </div>

      {/* Waveform visualization removed by request — the rings + Pipi already
         say "listening", and the live bars implied "the browser is hearing
         your voice" which we don't want in the child-facing flow. */}

      <div style={{ padding: '36px 22px 0' }}>
        <ScribbleButton color={PIPI.yellow} fullWidth onClick={onHeard} seed={140}>
          Počul som ťa ✓ — vybrať
        </ScribbleButton>
      </div>

      <div style={{ flex: 1 }}/>

      <style>{`@keyframes pipiRing {
        0% { transform: scale(0.6); opacity: 0.85 }
        70% { opacity: 0.25 }
        100% { transform: scale(1.4); opacity: 0 }
      }`}</style>
    </>
  );
}

// ── 4. CHOICE moment ──────────────────────────────────────────
function ChoiceScreen({ story, onPick, onBack }) {
  const choices = [
    { id: 'open',  label: 'Otvor dvere', desc: 'Možno tam býva víla.',  color: PIPI.green, Icon: () => <ChoiceIconDoor/> },
    { id: 'run',   label: 'Uteč preč',   desc: 'Tam vnútri niečo škrabe.', color: PIPI.coral, Icon: () => <ChoiceIconRun/> },
    { id: 'knock', label: 'Zaklopaj',    desc: 'Kto klope, ten je slušný.', color: PIPI.blue, Icon: () => <ChoiceIconKnock/> },
  ];
  return (
    <>
      <div style={{ padding: '12px 18px 0', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <button onClick={onBack} style={{ background: 'transparent', border: 0, padding: 6, cursor: 'pointer' }}>
          <IconBack size={30}/>
        </button>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6,
          background: PIPI.yellow, padding: '4px 12px', borderRadius: 18,
          border: `2.5px solid ${PIPI.ink}` }}>
          <Sparkle size={20}/>
          <span style={{ fontSize: 16 }}>voľba</span>
        </div>
        <div style={{ width: 30 }}/>
      </div>

      <div style={{ padding: '22px 24px 8px', textAlign: 'center' }}>
        <Pipi size={120}/>
      </div>

      <div style={{ padding: '0 24px', textAlign: 'center' }}>
        <div style={{ fontFamily: '"Caveat", cursive', fontWeight: 700, fontSize: 30, lineHeight: 1.1 }}>
          Pipi stojí pred dverami<br/>v starej chalúpke.
        </div>
        <div style={{ fontSize: 19, opacity: 0.78, marginTop: 8 }}>
          Čo má urobiť?
        </div>
      </div>

      <div style={{ padding: '18px 22px 0', display: 'grid', gap: 12 }}>
        {choices.map((c, i) => (
          <button key={c.id} onClick={() => onPick(c)} style={{
            display: 'flex', gap: 14, alignItems: 'center', textAlign: 'left',
            padding: 12, background: PIPI.paperLt,
            border: `3.5px solid ${PIPI.ink}`, borderRadius: 22, cursor: 'pointer',
            fontFamily: '"Patrick Hand", cursive', color: PIPI.ink,
            transform: `rotate(${i % 2 === 0 ? -0.4 : 0.5}deg)`,
          }}>
            <div style={{ width: 64, height: 64, background: c.color,
              border: `3px solid ${PIPI.ink}`, borderRadius: 16,
              display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
              <c.Icon/>
            </div>
            <div style={{ flex: 1 }}>
              <div style={{ fontFamily: '"Caveat", cursive', fontWeight: 700, fontSize: 26, lineHeight: 1 }}>
                {c.label}
              </div>
              <div style={{ fontSize: 17, opacity: 0.75, marginTop: 2 }}>{c.desc}</div>
            </div>
            <div style={{
              width: 36, height: 36, borderRadius: 18,
              background: PIPI.yellow, border: `2.5px solid ${PIPI.ink}`,
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              fontSize: 22, transform: 'rotate(-90deg)',
            }}>→</div>
          </button>
        ))}
      </div>

      <div style={{ padding: '14px 22px 0', textAlign: 'center', fontSize: 17, opacity: 0.6 }}>
        alebo povedz nahlas: <i>"otvor dvere"</i>
      </div>

      <div style={{ flex: 1 }}/>
    </>
  );
}

function ChoiceIconDoor() {
  return (
    <svg viewBox="0 0 60 60" width="50" height="50">
      <path d={wobblyRectPath(14, 8, 32, 48, { r: 4, amp: 1, seed: 200 })}
            fill={PIPI.paperLt} stroke={PIPI.ink} strokeWidth={3}/>
      <circle cx="38" cy="32" r="3" fill={PIPI.ink}/>
    </svg>
  );
}
function ChoiceIconRun() {
  return (
    <svg viewBox="0 0 60 60" width="50" height="50">
      <circle cx="34" cy="18" r="6" fill="none" stroke={PIPI.ink} strokeWidth={3}/>
      <path d="M28 28 L40 28 L40 40" fill="none" stroke={PIPI.ink} strokeWidth={3.5} strokeLinecap="round"/>
      <path d="M40 40 L48 50" fill="none" stroke={PIPI.ink} strokeWidth={3.5} strokeLinecap="round"/>
      <path d="M34 38 L24 46" fill="none" stroke={PIPI.ink} strokeWidth={3.5} strokeLinecap="round"/>
      <path d="M28 28 L18 34" fill="none" stroke={PIPI.ink} strokeWidth={3.5} strokeLinecap="round"/>
      <path d="M48 18 L54 18 M48 24 L54 22 M48 12 L54 14" stroke={PIPI.ink} strokeWidth={2.5} strokeLinecap="round"/>
    </svg>
  );
}
function ChoiceIconKnock() {
  return (
    <svg viewBox="0 0 60 60" width="50" height="50">
      <circle cx="22" cy="22" r="8" fill={PIPI.paperLt} stroke={PIPI.ink} strokeWidth={3}/>
      <path d="M22 30 L22 42 M22 36 L14 44 M22 36 L30 44" stroke={PIPI.ink} strokeWidth={3} strokeLinecap="round"/>
      <text x="36" y="20" fontFamily="Caveat" fontSize="20" fontWeight="700" fill={PIPI.ink}>klop!</text>
    </svg>
  );
}

// ── 5. SETTINGS / Parent ──────────────────────────────────────
function ParentScreen({ onTab, devMode, setDevMode }) {
  const [voice, setVoice] = React.useState('marek');
  const [bedtime, setBedtime] = React.useState(true);
  const [voiceInput, setVoiceInput] = React.useState(true);
  return (
    <>
      <AppHeader greeting="Rodičovský režim" sub="Zadaj PIN: ✔ overené"
        right={<div style={{ width: 56, height: 56, border: `3px dashed ${PIPI.ink}`,
          borderRadius: 16, display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontFamily: '"Caveat", cursive', fontSize: 22 }}>
          🐤
        </div>}/>

      <div style={{ padding: '6px 22px 0', display: 'grid', gap: 14 }}>
        {/* voice */}
        <ScribbleCard style={{ padding: '14px 16px' }}>
          <SectionLabel>Hlas rozprávača</SectionLabel>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 8, marginTop: 6 }}>
            {[
              { id: 'marek', name: 'Pokojný', sub: 'hlboký hlas' },
              { id: 'silvia',name: 'Teplý',   sub: 'jemný hlas' },
              { id: 'pipi',  name: 'Pipi',    sub: 'nezbedný' },
            ].map(v => (
              <button key={v.id} onClick={() => setVoice(v.id)} style={{
                background: voice === v.id ? PIPI.yellow : PIPI.paper,
                border: `3px solid ${PIPI.ink}`, borderRadius: 16,
                padding: '8px 6px', fontFamily: '"Patrick Hand", cursive',
                color: PIPI.ink, cursor: 'pointer',
              }}>
                <div style={{ fontFamily: '"Caveat", cursive', fontWeight: 700, fontSize: 22, lineHeight: 1 }}>{v.name}</div>
                <div style={{ fontSize: 14, opacity: 0.75 }}>{v.sub}</div>
              </button>
            ))}
          </div>
        </ScribbleCard>

        {/* Bedtime + voice input toggles */}
        <ScribbleCard style={{ padding: '12px 16px' }}>
          <ToggleRow label="Pokojný režim pred spaním" sub="Tlmí hlasné scény po 19:30"
            on={bedtime} onChange={setBedtime}/>
          <DotDivider/>
          <ToggleRow label="Voľba hlasom" sub="Dieťa môže odpovedať nahlas"
            on={voiceInput} onChange={setVoiceInput}/>
          <DotDivider/>
          <ToggleRow label="Dev / transkript režim"
            sub="Zobrazí debug pásik s rozpoznaným textom"
            on={devMode} onChange={setDevMode}/>
        </ScribbleCard>

        {/* Time today */}
        <ScribbleCard color={PIPI.blue} style={{ padding: '14px 16px' }}>
          <SectionLabel>Dnes ste počúvali</SectionLabel>
          <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', marginTop: 8 }}>
            <div>
              <div style={{ fontFamily: '"Caveat", cursive', fontWeight: 700, fontSize: 42, lineHeight: 1 }}>
                34 min
              </div>
              <div style={{ fontSize: 16, opacity: 0.7 }}>z limitu 60 min</div>
            </div>
            <svg viewBox="0 0 90 50" width="120" height="60">
              {[5, 12, 8, 22, 18, 30, 24].map((v, i) => (
                <path key={i}
                  d={wobblyRectPath(2 + i * 12, 48 - v, 8, v, { r: 2, amp: 0.6, seed: i + 1 })}
                  fill={PIPI.paperLt} stroke={PIPI.ink} strokeWidth={2}/>
              ))}
            </svg>
          </div>
        </ScribbleCard>

        {/* PIN row */}
        <ScribbleCard style={{ padding: '12px 16px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <div>
            <div style={{ fontFamily: '"Caveat", cursive', fontWeight: 700, fontSize: 22, lineHeight: 1 }}>
              Rodičovský PIN
            </div>
            <div style={{ fontSize: 15, opacity: 0.7 }}>chráni nastavenia pred deťmi</div>
          </div>
          <div style={{ fontFamily: '"JetBrains Mono", monospace', fontSize: 22, letterSpacing: 4 }}>● ● ● ●</div>
        </ScribbleCard>
      </div>

      <div style={{ flex: 1 }}/>
      <ScribbleTabBar active="parent" onChange={onTab}/>
    </>
  );
}

function SectionLabel({ children }) {
  return (
    <div style={{ fontFamily: '"Caveat", cursive', fontWeight: 700, fontSize: 22, lineHeight: 1 }}>
      {children}
    </div>
  );
}

function ToggleRow({ label, sub, on, onChange }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '6px 0' }}>
      <div style={{ flex: 1, paddingRight: 12 }}>
        <div style={{ fontFamily: '"Patrick Hand", cursive', fontSize: 19, lineHeight: 1.1 }}>{label}</div>
        {sub && <div style={{ fontSize: 14, opacity: 0.65, marginTop: 1 }}>{sub}</div>}
      </div>
      <ScribbleToggle on={on} onChange={() => onChange(!on)}/>
    </div>
  );
}

function ScribbleToggle({ on, onChange }) {
  return (
    <button onClick={onChange} style={{
      width: 64, height: 34, position: 'relative', background: 'transparent', border: 0,
      cursor: 'pointer', padding: 0,
    }}>
      <svg viewBox="0 0 64 34" width={64} height={34} style={{ position: 'absolute', inset: 0 }}>
        <path d={wobblyRectPath(2, 2, 60, 30, { r: 15, amp: 1, seed: on ? 300 : 301 })}
              fill={on ? PIPI.green : PIPI.paperDk} stroke={PIPI.ink} strokeWidth={2.5}/>
        <path d={wobblyCirclePath(on ? 48 : 16, 17, 11, { amp: 0.7, seed: 305, segs: 14 })}
              fill={PIPI.paperLt} stroke={PIPI.ink} strokeWidth={2.5}/>
      </svg>
    </button>
  );
}

function DotDivider() {
  return <div style={{ borderTop: `2px dotted ${PIPI.inkSoft}`, margin: '6px 0' }}/>;
}

// ── INTERACTIVE PROTOTYPE — the live phone ───────────────────
function PipiPrototype() {
  const [screen, setScreen] = React.useState('home');
  const [story, setStory] = React.useState(STORIES[0]);
  const [playing, setPlaying] = React.useState(false);
  const [devMode, setDevMode] = React.useState(false);
  const [picked, setPicked] = React.useState(null);

  const onTab = (t) => {
    if (t === 'parent') setScreen('parent');
    else if (t === 'home') setScreen('home');
    else if (t === 'library') setScreen('home');
    else if (t === 'search') setScreen('home');
  };

  return (
    <div style={{ position: 'relative' }}>
      <PhoneShell>
        {screen === 'home' && (
          <HomeScreen
            onOpen={(s) => { setStory(s); setScreen('player'); setPlaying(true); }}
            onTab={onTab}
          />
        )}
        {screen === 'player' && (
          <PlayerScreen
            story={story} playing={playing}
            onTogglePlay={() => setPlaying(p => !p)}
            onBack={() => setScreen('home')}
            onAskChoice={() => setScreen('listening')}
          />
        )}
        {screen === 'listening' && (
          <ListeningScreen
            story={story}
            onCancel={() => setScreen('player')}
            onHeard={() => setScreen('choice')}
          />
        )}
        {screen === 'choice' && (
          <ChoiceScreen
            story={story}
            onPick={(c) => { setPicked(c); setScreen('player'); setPlaying(true); }}
            onBack={() => setScreen('player')}
          />
        )}
        {screen === 'parent' && (
          <ParentScreen onTab={onTab} devMode={devMode} setDevMode={setDevMode}/>
        )}
      </PhoneShell>

      {/* Dev mode debug strip */}
      {devMode && (
        <div style={{
          position: 'absolute', bottom: 110, left: 14, right: 14,
          background: 'rgba(20,20,40,0.92)', color: '#9DFFB4',
          fontFamily: '"JetBrains Mono", monospace', fontSize: 11, lineHeight: 1.45,
          padding: 10, borderRadius: 10,
        }}>
          <div>{`[STATE]   screen=${screen}  playing=${playing}`}</div>
          <div>{`[STORY]   id=${story.id}  "${story.title}"`}</div>
          {picked && <div>{`[CHOICE]  user="${picked.label}"  intent=${picked.id}  conf=0.94`}</div>}
          <div style={{ opacity: 0.6 }}>{'[NOTE]    dev mode visible — never shown to kids'}</div>
        </div>
      )}
    </div>
  );
}

Object.assign(window, {
  ScribbleButton, ScribbleCard, ScribbleCardSvg, ScribbleTabBar,
  IconHome, IconLibrary, IconSearch, IconParent,
  IconPlay, IconPause, IconBack, IconSkipBack, IconSkipFwd, IconMic,
  STORIES, visibleStories, AppHeader,
  HomeScreen, PlayerScreen, ListeningScreen, ChoiceScreen, ParentScreen,
  PhoneShell, PipiPrototype,
});
