// prediction-app.jsx — Mounts the Prediction Hub design canvas + Tweaks panel.
//
// Sections shown on the canvas (top → bottom):
//   1. Mobile · Layout Explorations (3 candidates at 420×920 each — A/B/C)
//   2. Mobile · States (5 mini artboards showing match-row state matrix)
//   3. Desktop · 1400 layout (2-col main + sidebar)
//   4. Primitives reference (for Foundation.html cross-link)

const { useState: prUseState, useMemo: prUseMemo, useEffect: prUseEffect } = React;

// ─── PR phone frame ─────────────────────────────────────────────────────────
function PRPhone({ w = 420, h = 920, children }) {
  return (
    <div className="pr-phone" style={{ width: w, height: h }}>
      <div className="pr-phone-inner">{children}</div>
    </div>
  );
}

// ─── Deep-clone matches so each artboard can have its own expand state ─────
function clonePRMatches(matches) {
  return matches.map((m) => ({ ...m, userAnswers: { ...(m.userAnswers || {}) } }));
}

const PR_TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "locale": "fa",
  "fiveTabs": false,
  "dateMode": "hybrid",
  "showEmpty": false,
  "expandFeatured": false
}/*EDITMODE-END*/;

// ─── Filter helpers ────────────────────────────────────────────────────────
function counts(matches) {
  const c = { all: matches.length, today: 0, featured: 0, finished: 0 };
  const now = Date.now();
  matches.forEach((m) => {
    if (m.featured) c.featured++;
    if (m.state === 'settled' || m.state === 'locked') c.finished++;
    // "today" — for the mock, anything with countdown < 24h
    if (m.state !== 'settled' && m.state !== 'locked' && (m.hours || 0) < 24) c.today++;
  });
  return c;
}
function applyFilter(matches, filter) {
  if (filter === 'all')      return matches;
  if (filter === 'featured') return matches.filter((m) => m.featured);
  if (filter === 'finished') return matches.filter((m) => m.state === 'settled' || m.state === 'locked');
  if (filter === 'today')    return matches.filter((m) => (m.state !== 'settled' && m.state !== 'locked' && (m.hours || 0) < 24));
  return matches;
}

// ─── Shared hook: bottom-sheet state for mobile match list ─────────────────
// Behavior change (Design Log §14.0, v1.3): inline-expand on mobile was
// replaced by a 90vh bottom sheet built on MyCardsDetailModal sheetCustom.
// `sheetMatchId` is the currently-open match in the sheet; `null` = closed.
function usePRMatchSheet(initialId = null) {
  const [matches, setMatches] = prUseState(() => clonePRMatches(PR_MATCHES));
  const [sheetMatchId, setSheetMatchId] = prUseState(initialId);
  const openSheet  = (id) => setSheetMatchId(id);
  const closeSheet = () => setSheetMatchId(null);
  const onChange = (matchId, qid, value) => setMatches((cur) =>
    cur.map((m) => m.id === matchId ? { ...m, userAnswers: { ...m.userAnswers, [qid]: value } } : m));
  const activeMatch = matches.find((m) => m.id === sheetMatchId) || null;
  return { matches, setMatches, sheetMatchId, openSheet, closeSheet, onChange, activeMatch };
}

// ─── Mobile · Exploration A — STACK (all matches are big expandable cards) ──
function MobileExpA({ locale, fiveTabs, dateMode, defaultExpandedId = null }) {
  const { matches, sheetMatchId, openSheet, closeSheet, onChange, activeMatch } = usePRMatchSheet(defaultExpandedId);
  const [filter, setFilter] = prUseState('all');
  const list = applyFilter(matches, filter);
  const cs = counts(matches);

  return (
    <div className="pr-screen">
      {window.AppBar && (
        <AppBar locale={locale} user={PR_USER} density="compact"
                avatarSide="start" showStreak={false} showXP={true}
                notifications={3}/>
      )}
      <div className="pr-screen-scroll">
        <div className="pr-body">
          <PredictionHero locale={locale}/>
          <PredictionStatsStrip locale={locale} onFilter={setFilter}/>
          <PredictionFilterChips locale={locale} filter={filter} counts={cs} onChange={setFilter}/>

          <SectionHead title={PR_I18N[locale].matchwide}
            sub={PR_I18N[locale].questionsOf(
              window.toLocaleDigits ? window.toLocaleDigits(PR_STATS.answered, locale) : PR_STATS.answered,
              window.toLocaleDigits ? window.toLocaleDigits(PR_STATS.totalQs, locale) : PR_STATS.totalQs)}/>

          <div className="pr-rows">
            {list.map((m) => (
              <PredictionMatchRow key={m.id} match={m} locale={locale}
                                  dateMode={dateMode}
                                  variant={m.featured ? 'featured' : 'row'}
                                  expanded={false}
                                  onToggle={openSheet}
                                  onChangeAnswer={onChange}/>
            ))}
          </div>

          <PredictionRewardPreview locale={locale}/>
          <PredictionHistoryCard locale={locale}/>
        </div>
      </div>
      {window.BottomNav && (
        <BottomNav locale={locale} activeTab="predict" fiveTabs={fiveTabs}/>
      )}

      <PredictionMatchSheet locale={locale} dateMode={dateMode}
                            match={activeMatch} open={!!sheetMatchId}
                            onClose={closeSheet} onChangeAnswer={onChange}/>
    </div>
  );
}

// ─── Mobile · Exploration B — LIST (all matches as compact rows, no featured) ──
function MobileExpB({ locale, fiveTabs, dateMode, defaultExpandedId = null }) {
  const { matches, sheetMatchId, openSheet, closeSheet, onChange, activeMatch } = usePRMatchSheet(defaultExpandedId);
  const [filter, setFilter] = prUseState('all');
  const list = applyFilter(matches, filter);
  const cs = counts(matches);

  return (
    <div className="pr-screen">
      {window.AppBar && (
        <AppBar locale={locale} user={PR_USER} density="compact"
                avatarSide="start" showStreak={false} showXP={true}
                notifications={3}/>
      )}
      <div className="pr-screen-scroll">
        <div className="pr-body">
          <PredictionHero locale={locale}/>
          <PredictionRewardPreview locale={locale}/>
          <PredictionFilterChips locale={locale} filter={filter} counts={cs} onChange={setFilter}/>

          <div className="pr-list">
            {list.map((m) => (
              <PredictionMatchRow key={m.id} match={m} locale={locale}
                                  dateMode={dateMode}
                                  variant="row"
                                  expanded={false}
                                  onToggle={openSheet}
                                  onChangeAnswer={onChange}/>
            ))}
          </div>

          <PredictionHistoryCard locale={locale}/>
        </div>
      </div>
      {window.BottomNav && (
        <BottomNav locale={locale} activeTab="predict" fiveTabs={fiveTabs}/>
      )}

      <PredictionMatchSheet locale={locale} dateMode={dateMode}
                            match={activeMatch} open={!!sheetMatchId}
                            onClose={closeSheet} onChangeAnswer={onChange}/>
    </div>
  );
}

// ─── Mobile · Exploration C — HYBRID (featured big + rest compact) ─────────
function MobileExpC({ locale, fiveTabs, dateMode, defaultExpandedId = 'mw28-per-est' }) {
  const { matches, sheetMatchId, openSheet, closeSheet, onChange, activeMatch } = usePRMatchSheet(defaultExpandedId);
  const [filter, setFilter] = prUseState('all');
  const list = applyFilter(matches, filter);
  const cs = counts(matches);

  const featured = list.filter((m) => m.featured);
  const rest     = list.filter((m) => !m.featured);

  return (
    <div className="pr-screen">
      {window.AppBar && (
        <AppBar locale={locale} user={PR_USER} density="compact"
                avatarSide="start" showStreak={false} showXP={true}
                notifications={3}/>
      )}
      <div className="pr-screen-scroll">
        <div className="pr-body">
          <PredictionHero locale={locale}/>
          <PredictionStatsStrip locale={locale} onFilter={setFilter}/>
          <PredictionFilterChips locale={locale} filter={filter} counts={cs} onChange={setFilter}/>

          {featured.length > 0 && (
            <React.Fragment>
              <SectionHead title={PR_I18N[locale].filterFeatured}/>
              <div className="pr-featured-stack">
                {featured.map((m) => (
                  <PredictionMatchRow key={m.id} match={m} locale={locale}
                                      dateMode={dateMode}
                                      variant="featured"
                                      expanded={false}
                                      onToggle={openSheet}
                                      onChangeAnswer={onChange}/>
                ))}
              </div>
            </React.Fragment>
          )}

          {rest.length > 0 && (
            <React.Fragment>
              <SectionHead title={PR_I18N[locale].matchwide}
                sub={PR_I18N[locale].questionsOf(
                  window.toLocaleDigits ? window.toLocaleDigits(PR_STATS.answered, locale) : PR_STATS.answered,
                  window.toLocaleDigits ? window.toLocaleDigits(PR_STATS.totalQs, locale) : PR_STATS.totalQs)}/>
              <div className="pr-rows">
                {rest.map((m) => (
                  <PredictionMatchRow key={m.id} match={m} locale={locale}
                                      dateMode={dateMode}
                                      variant="row"
                                      expanded={false}
                                      onToggle={openSheet}
                                      onChangeAnswer={onChange}/>
                ))}
              </div>
            </React.Fragment>
          )}

          <PredictionRewardPreview locale={locale}/>
          <PredictionHistoryCard locale={locale}/>
        </div>
      </div>
      {window.BottomNav && (
        <BottomNav locale={locale} activeTab="predict" fiveTabs={fiveTabs}/>
      )}

      <PredictionMatchSheet locale={locale} dateMode={dateMode}
                            match={activeMatch} open={!!sheetMatchId}
                            onClose={closeSheet} onChangeAnswer={onChange}/>
    </div>
  );
}

// ─── Mobile · Empty state ──────────────────────────────────────────────────
function MobileEmpty({ locale, fiveTabs }) {
  const fakeStats = { totalQs: 0, answered: 0, finished: 0, active: 0, rewardMax: 0, rewardEarned: 0 };
  return (
    <div className="pr-screen">
      {window.AppBar && (
        <AppBar locale={locale} user={PR_USER} density="compact"
                avatarSide="start" showStreak={false} showXP={true}
                notifications={0}/>
      )}
      <div className="pr-screen-scroll">
        <div className="pr-body">
          <PredictionHero locale={locale} stats={fakeStats}/>
          <PredictionStatsStrip locale={locale} stats={fakeStats}/>
          <PredictionFilterChips locale={locale} filter="all" counts={{ all: 0, today: 0, featured: 0, finished: 0 }}/>
          <PredictionEmptyState locale={locale}/>
          <PredictionHistoryCard locale={locale}/>
        </div>
      </div>
      {window.BottomNav && <BottomNav locale={locale} activeTab="predict" fiveTabs={fiveTabs}/>}
    </div>
  );
}

// ─── Desktop · 2-col layout ────────────────────────────────────────────────
// v1.3.1: Replaced inline-expand with the same bottom-sheet pattern used on
// mobile. Rows no longer expand in place — tapping a row opens
// <PredictionMatchSheet/> on top of the page (Design Log §14.0).
function DesktopLayout({ locale, fiveTabs, dateMode }) {
  const [filter, setFilter] = prUseState('all');
  const { matches, sheetMatchId, openSheet, closeSheet, onChange, activeMatch } =
    usePRMatchSheet(null);

  const list = applyFilter(matches, filter);
  const cs = counts(matches);
  const featured = list.filter((m) => m.featured);
  const rest     = list.filter((m) => !m.featured);

  return (
    <div className="pr-desktop-screen">
      {window.DesktopTopbar && <DesktopTopbar locale={locale} user={PR_USER}/>}
      <div className="pr-desktop">
        <div className="pr-desktop-main">
          <PredictionHero locale={locale} desktop={true}/>
          <PredictionStatsStrip locale={locale} onFilter={setFilter}/>
          <PredictionFilterChips locale={locale} filter={filter} counts={cs} onChange={setFilter}/>

          {featured.length > 0 && (
            <React.Fragment>
              <SectionHead title={PR_I18N[locale].filterFeatured}/>
              <div className="pr-featured-stack">
                {featured.map((m) => (
                  <PredictionMatchRow key={m.id} match={m} locale={locale}
                                      dateMode={dateMode}
                                      variant="featured"
                                      expanded={false}
                                      onToggle={openSheet}
                                      onChangeAnswer={onChange}/>
                ))}
              </div>
            </React.Fragment>
          )}

          {rest.length > 0 && (
            <React.Fragment>
              <SectionHead title={PR_I18N[locale].matchwide}
                sub={PR_I18N[locale].questionsOf(
                  window.toLocaleDigits ? window.toLocaleDigits(PR_STATS.answered, locale) : PR_STATS.answered,
                  window.toLocaleDigits ? window.toLocaleDigits(PR_STATS.totalQs, locale) : PR_STATS.totalQs)}/>
              <div className="pr-rows">
                {rest.map((m) => (
                  <PredictionMatchRow key={m.id} match={m} locale={locale}
                                      dateMode={dateMode}
                                      variant="row"
                                      expanded={false}
                                      onToggle={openSheet}
                                      onChangeAnswer={onChange}/>
                ))}
              </div>
            </React.Fragment>
          )}
        </div>

        <aside className="pr-desktop-side">
          <PredictionRewardPreview locale={locale} variant="sidebar"/>
          <PredictionHistoryCard locale={locale} variant="sidebar"/>
          {window.SponsorBlock && <SponsorBlock locale={locale} variant="sky" sponsorId="mci"/>}
        </aside>
      </div>

      <PredictionMatchSheet locale={locale} match={activeMatch}
                            open={!!sheetMatchId} onClose={closeSheet}
                            onChangeAnswer={onChange}/>
    </div>
  );
}

// ─── PRApp — root of the canvas ────────────────────────────────────────────
function PRApp() {
  const [t, setTweak] = useTweaks(PR_TWEAK_DEFAULTS);

  prUseEffect(() => {
    document.documentElement.lang = t.locale;
    document.documentElement.dir  = t.locale === 'en' ? 'ltr' : 'rtl';
  }, [t.locale]);

  return (
    <React.Fragment>
      <DesignCanvas>
        {/* === 1. Mobile · Layout Explorations === */}
        <DCSection id="mobile-explorations"
                   title="Mobile · سه گزینه‌ی چیدمان (۴۲۰)"
                   subtitle="سه نگاه متفاوت به همان داده‌ها: A بزرگ‌محور · B لیست خطی · C ترکیبی (Featured + سطرها). در نهایت C پیشنهاد می‌شود.">
          <DCArtboard id="mb-exp-a" label="A · Big Stack — همه ماچ‌ها کارت بزرگ" width={420} height={2600}>
            <PRPhone w={420} h={2600}>
              <MobileExpA locale={t.locale} fiveTabs={t.fiveTabs} dateMode={t.dateMode}
                          defaultExpandedId={t.expandFeatured ? 'mw28-per-est' : null}/>
            </PRPhone>
          </DCArtboard>
          <DCArtboard id="mb-exp-b" label="B · List — فقط سطرهای فشرده" width={420} height={2200}>
            <PRPhone w={420} h={2200}>
              <MobileExpB locale={t.locale} fiveTabs={t.fiveTabs} dateMode={t.dateMode}
                          defaultExpandedId={t.expandFeatured ? 'mw28-per-est' : null}/>
            </PRPhone>
          </DCArtboard>
          <DCArtboard id="mb-exp-c" label="C · Hybrid · ★ Recommended" width={420} height={2600}>
            <PRPhone w={420} h={2600}>
              <MobileExpC locale={t.locale} fiveTabs={t.fiveTabs} dateMode={t.dateMode}
                          defaultExpandedId={t.expandFeatured ? 'mw28-per-est' : null}/>
            </PRPhone>
          </DCArtboard>
        </DCSection>

        {/* === 2. Mobile · State matrix === */}
        <DCSection id="mobile-states"
                   title="Mobile · حالت‌های ماچ + Bottom Sheet"
                   subtitle="ردیف ماچ در ۴ حالت اصلی (open / predicted / locked / settled) + partial و empty. ضربه روی هر ردیف یک Bottom Sheet ۹۰٪ ارتفاع باز می‌کند (Design Log §۱۴.۰).">
          <DCArtboard id="st-row-states" label="States · همه‌ی حالت‌ها در یک نمای فشرده" width={420} height={920}>
            <PRPhone w={420} h={920}>
              <StatesShowcase locale={t.locale} dateMode={t.dateMode}/>
            </PRPhone>
          </DCArtboard>
          <DCArtboard id="st-open-sheet" label="Open · Sheet (5 سوال متفاوت)" width={420} height={920}>
            <PRPhone w={420} h={920}>
              <SingleMatchExpanded locale={t.locale} matchId="mw28-per-est" dateMode={t.dateMode}/>
            </PRPhone>
          </DCArtboard>
          <DCArtboard id="st-predicted-sheet" label="Predicted · Sheet (همه سوال‌ها پاسخ داده شده)" width={420} height={920}>
            <PRPhone w={420} h={920}>
              <SingleMatchExpanded locale={t.locale} matchId="mw28-mci-liv" dateMode={t.dateMode}/>
            </PRPhone>
          </DCArtboard>
          <DCArtboard id="st-locked-sheet" label="Locked · Sheet (بازی شروع شده · در حال محاسبه)" width={420} height={920}>
            <PRPhone w={420} h={920}>
              <SingleMatchExpanded locale={t.locale} matchId="mw28-bay-bvb" dateMode={t.dateMode}/>
            </PRPhone>
          </DCArtboard>
          <DCArtboard id="st-settled-sheet" label="Settled · Sheet (پایان یافت · جایزه دریافت شد)" width={420} height={920}>
            <PRPhone w={420} h={920}>
              <SingleMatchExpanded locale={t.locale} matchId="mw28-psg-mun" dateMode={t.dateMode}/>
            </PRPhone>
          </DCArtboard>
          <DCArtboard id="st-empty" label="Empty · هیچ بازی فعالی نیست" width={420} height={920}>
            <PRPhone w={420} h={920}>
              <MobileEmpty locale={t.locale} fiveTabs={t.fiveTabs}/>
            </PRPhone>
          </DCArtboard>
        </DCSection>

        {/* === 3. Desktop === */}
        <DCSection id="desktop"
                   title="Desktop · 1400 (دو ستونه)"
                   subtitle="ستون main = هیرو + استتس + فیلتر + ماچ‌ها · ستون side = Reward preview + History + Sponsor. کلیک روی هر ماچ همان bottom-sheet موبایل را باز می‌کند (v1.3.1).">
          <DCArtboard id="d-default" label="A · Default" width={1400} height={2400}>
            <div className="pr-desktop-frame">
              <DesktopLayout locale={t.locale} fiveTabs={t.fiveTabs} dateMode={t.dateMode}/>
            </div>
          </DCArtboard>
          <DCArtboard id="d-sheet-open" label="B · Sheet open (روی Featured)" width={1400} height={1100}>
            <div className="pr-desktop-frame">
              <DesktopWithSheetOpen locale={t.locale} matchId="mw28-per-est" dateMode={t.dateMode}/>
            </div>
          </DCArtboard>
        </DCSection>

        {/* === 4. Primitives reference === */}
        <DCSection id="primitives"
                   title="Primitives · مرجع برای Foundation"
                   subtitle="هر primitive جدا تا در Foundation.html همین instance‌ها showcase شوند.">
          <DCArtboard id="p-hero" label="PredictionHero" width={420} height={220}>
            <PRStack><PredictionHero locale={t.locale}/></PRStack>
          </DCArtboard>
          <DCArtboard id="p-stats" label="PredictionStatsStrip" width={420} height={120}>
            <PRStack><PredictionStatsStrip locale={t.locale}/></PRStack>
          </DCArtboard>
          <DCArtboard id="p-chips" label="PredictionFilterChips" width={420} height={80}>
            <PRStack><PredictionFilterChips locale={t.locale} filter="all"
                                            counts={counts(PR_MATCHES)} onChange={() => {}}/></PRStack>
          </DCArtboard>
          <DCArtboard id="p-row-states" label="PredictionMatchRow · همه states" width={420} height={920}>
            <PRPhone w={420} h={920}>
              <StatesShowcase locale={t.locale} dateMode={t.dateMode}/>
            </PRPhone>
          </DCArtboard>
          <DCArtboard id="p-questions" label="PredictionQuestionRow · ۵ نوع" width={420} height={1080}>
            <PRPhone w={420} h={1080}>
              <QuestionTypeShowcase locale={t.locale}/>
            </PRPhone>
          </DCArtboard>
          <DCArtboard id="p-reward" label="PredictionRewardPreview" width={420} height={220}>
            <PRStack><PredictionRewardPreview locale={t.locale}/></PRStack>
          </DCArtboard>
          <DCArtboard id="p-history" label="PredictionHistoryCard" width={420} height={300}>
            <PRStack><PredictionHistoryCard locale={t.locale}/></PRStack>
          </DCArtboard>
          <DCArtboard id="p-empty" label="PredictionEmptyState" width={420} height={300}>
            <PRStack><PredictionEmptyState locale={t.locale}/></PRStack>
          </DCArtboard>
        </DCSection>
      </DesignCanvas>

      <TweaksPanel title="Tweaks · Prediction Hub">
        <TweakSection label="نمایش">
          <TweakRadio label="زبان" value={t.locale}
            options={[
              { value: 'fa', label: 'فا' },
              { value: 'en', label: 'EN' },
              { value: 'ar', label: 'ع' },
            ]}
            onChange={(v) => setTweak('locale', v)}/>
          <TweakToggle label="ماچ ویژه از ابتدا باز باشد"
                       value={t.expandFeatured}
                       onChange={(v) => setTweak('expandFeatured', v)}/>
        </TweakSection>
        <TweakSection label="BottomNav">
          <TweakRadio label="تعداد تب" value={t.fiveTabs ? '5' : '6'}
            options={[
              { value: '6', label: '۶ تب' },
              { value: '5', label: '۵ تب' },
            ]}
            onChange={(v) => setTweak('fiveTabs', v === '5')}/>
        </TweakSection>
        <TweakSection label="تاریخ">
          <TweakRadio label="فرمت تاریخ" value={t.dateMode}
            options={[
              { value: 'jalali',    label: 'شمسی' },
              { value: 'gregorian', label: 'میلادی' },
              { value: 'hybrid',    label: 'ترکیبی' },
            ]}
            onChange={(v) => setTweak('dateMode', v)}/>
        </TweakSection>
      </TweaksPanel>
    </React.Fragment>
  );
}

// ─── StatesShowcase — compact list of one row per state, for state matrix ──
// v1.3.2: post-bottom-sheet, this no longer toggles inline expand. Tap on
// any row opens the canonical sheet (same as MobileExp* and DesktopLayout).
function StatesShowcase({ locale, dateMode }) {
  const { matches, sheetMatchId, openSheet, closeSheet, onChange, activeMatch } =
    usePRMatchSheet(null);
  // Pick one match per state for the compact showcase
  const ids = ['mw28-per-est', 'mw28-rma-bar', 'mw28-mci-liv', 'mw28-bay-bvb', 'mw28-psg-mun'];
  const shown = ids.map((id) => matches.find((m) => m.id === id)).filter(Boolean);

  return (
    <div className="pr-screen">
      <div className="pr-screen-scroll">
        <div className="pr-body">
          {shown.map((m) => (
            <div key={m.id}>
              <SectionHead title={<span style={{ textTransform: 'capitalize' }}>{m.state}</span>}
                           sub={m.leagueShort?.[locale] || m.league[locale]}/>
              <PredictionMatchRow match={m} locale={locale} dateMode={dateMode}
                                  variant="row"
                                  expanded={false}
                                  onToggle={openSheet}
                                  onChangeAnswer={onChange}/>
            </div>
          ))}
        </div>
      </div>
      <PredictionMatchSheet locale={locale} dateMode={dateMode}
                            match={activeMatch} open={!!sheetMatchId}
                            onClose={closeSheet} onChangeAnswer={onChange}/>
    </div>
  );
}

// ─── SingleMatchExpanded — focuses on one match with the bottom sheet open ─
// Post-§14.0 (v1.3): the inline-expand pattern was replaced by a bottom sheet.
// This artboard now renders the row in its closed state PLUS the sheet open
// over it — that's the live UX. The artboard frame is viewport-sized
// (≈ 920 height) so the 90% sheet looks natural.
function SingleMatchExpanded({ locale, matchId, dateMode }) {
  const [matches, setMatches] = prUseState(() => clonePRMatches(PR_MATCHES));
  const m = matches.find((mm) => mm.id === matchId);
  if (!m) return null;
  const onChange = (mid, qid, value) => setMatches((cur) =>
    cur.map((mm) => mm.id === mid ? { ...mm, userAnswers: { ...mm.userAnswers, [qid]: value } } : mm));

  return (
    <div className="pr-screen">
      <div className="pr-screen-scroll">
        <div className="pr-body">
          <PredictionMatchRow match={m} locale={locale} dateMode={dateMode}
                              variant={m.featured ? 'featured' : 'row'}
                              expanded={false}
                              onToggle={() => {}}
                              onChangeAnswer={onChange}/>
        </div>
      </div>
      <PredictionMatchSheet locale={locale} dateMode={dateMode}
                            match={m} open={true}
                            onClose={() => {}} onChangeAnswer={onChange}/>
    </div>
  );
}

// ─── DesktopWithSheetOpen ──────────────────────────────────────────────────
// v1.3.1: artboard for the desktop layout showing the bottom-sheet open.
// Identical to DesktopLayout but with one match forced-open in the sheet, and
// the artboard height clipped so the open sheet docks naturally to the bottom
// of the visible viewport (rather than to the bottom of a very tall page).
function DesktopWithSheetOpen({ locale, matchId, dateMode }) {
  const [matches, setMatches] = prUseState(() => clonePRMatches(PR_MATCHES));
  const [filter, setFilter] = prUseState('all');
  const onChange = (mid, qid, value) => setMatches((cur) =>
    cur.map((mm) => mm.id === mid ? { ...mm, userAnswers: { ...mm.userAnswers, [qid]: value } } : mm));
  const active = matches.find((m) => m.id === matchId);
  const list = applyFilter(matches, filter);
  const cs = counts(matches);
  const featured = list.filter((m) => m.featured);
  const rest     = list.filter((m) => !m.featured);
  return (
    <div className="pr-desktop-screen">
      {window.DesktopTopbar && <DesktopTopbar locale={locale} user={PR_USER}/>}
      <div className="pr-desktop">
        <div className="pr-desktop-main">
          <PredictionHero locale={locale} desktop={true}/>
          <PredictionStatsStrip locale={locale} onFilter={setFilter}/>
          <PredictionFilterChips locale={locale} filter={filter} counts={cs} onChange={setFilter}/>
          {featured.length > 0 && (
            <React.Fragment>
              <SectionHead title={PR_I18N[locale].filterFeatured}/>
              <div className="pr-featured-stack">
                {featured.map((m) => (
                  <PredictionMatchRow key={m.id} match={m} locale={locale}
                                      dateMode={dateMode}
                                      variant="featured"
                                      expanded={false}
                                      onToggle={() => {}}
                                      onChangeAnswer={onChange}/>
                ))}
              </div>
            </React.Fragment>
          )}
          {rest.length > 0 && (
            <div className="pr-rows">
              {rest.slice(0, 2).map((m) => (
                <PredictionMatchRow key={m.id} match={m} locale={locale}
                                    dateMode={dateMode}
                                    variant="row"
                                    expanded={false}
                                    onToggle={() => {}}
                                    onChangeAnswer={onChange}/>
              ))}
            </div>
          )}
        </div>
        <aside className="pr-desktop-side">
          <PredictionRewardPreview locale={locale} variant="sidebar"/>
          <PredictionHistoryCard locale={locale} variant="sidebar"/>
          {window.SponsorBlock && <SponsorBlock locale={locale} variant="sky" sponsorId="mci"/>}
        </aside>
      </div>
      <PredictionMatchSheet locale={locale} dateMode={dateMode}
                            match={active} open={!!active}
                            onClose={() => {}} onChangeAnswer={onChange}/>
    </div>
  );
}

// ─── QuestionTypeShowcase — render each of the 5 question types separately ──
function QuestionTypeShowcase({ locale }) {
  const [m, setM] = prUseState(() => ({ ...clonePRMatches(PR_MATCHES)[0] }));
  const setAns = (qid, value) => setM((cur) => ({ ...cur, userAnswers: { ...cur.userAnswers, [qid]: value } }));
  const renderQ = (qid, label) => {
    const q = m.questions.find((qq) => qq.id === qid);
    if (!q) return null;
    return (
      <div>
        <SectionHead title={label}/>
        <PredictionQuestionRow locale={locale}
                               question={q}
                               match={m}
                               answer={m.userAnswers[qid]}
                               onChange={(v) => setAns(qid, v)}/>
      </div>
    );
  };
  return (
    <div className="pr-screen">
      <div className="pr-screen-scroll">
        <div className="pr-body">
          {renderQ('score',  'Score — نتیجه نهایی (ScrollNumber wheels)')}
          {renderQ('3way',   '3-way — تیم برتر')}
          {renderQ('total',  'Range — تعداد گل')}
          {renderQ('btts',   'Boolean — BTTS')}
          {renderQ('scorer', 'Scorer — اولین گل‌زن')}
        </div>
      </div>
    </div>
  );
}

// ─── Helpers ───────────────────────────────────────────────────────────────
function PRStack({ children }) {
  return (
    <div style={{
      width: '100%', height: '100%',
      padding: 14,
      overflow: 'auto',
      background: 'var(--bg-deep)',
      display: 'flex', flexDirection: 'column',
    }}>{children}</div>
  );
}

// ─── Exports for unified app shell (Phase 1) ─────────────────────────────────
Object.assign(window, {
  MobileExpC, MobileExpA, MobileExpB, MobileEmpty,
  DesktopLayout: DesktopLayout, StatesShowcase, SingleMatchExpanded,
  PRPhone,
});

const __prRoot = document.getElementById('root');
if (__prRoot && !window.__APP_SHELL_MODE) {
  ReactDOM.createRoot(__prRoot).render(<PRApp />);
}

// ─── Local frame styles ────────────────────────────────────────────────────
const PR_APP_CSS = `
  .pr-phone {
    position: relative;
    background: var(--bg-deep);
    overflow: hidden;
    border-radius: 0;
  }
  .pr-phone-inner {
    position: absolute;
    inset: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
  }
  .pr-phone-inner > * { flex: 1 1 auto; min-height: 0; }

  .pr-desktop-frame {
    width: 100%; height: 100%;
    overflow: hidden;
    background: var(--bg-deep);
    color: var(--text-primary);
    display: flex; flex-direction: column;
  }
  .pr-desktop-screen {
    position: relative;       /* anchors the inline bottom-sheet (sheetCustom) */
    display: flex; flex-direction: column;
    width: 100%; height: 100%;
    overflow-y: auto;
    background: var(--bg-deep);
  }
`;
const __prAppStyle = document.createElement('style');
__prAppStyle.textContent = PR_APP_CSS;
document.head.appendChild(__prAppStyle);
