// lineup-app.jsx — Canvas + Tweaks for Rakhtkan Lineup Builder.
//
// Sections in the design canvas:
//   1) دو متافور          — Tactical (عمودی) / Landscape (افقی) mobile screens
//   2) Card Picker        — Full-screen picker with search + sort
//   3) دسکتاپ              — Desktop mockup using the chosen metaphor
//
// Tweaks let the user cycle the global lineup state (empty/partial/complete/
// cooldown/coach-active/fan-selected/invalid) and toggle locale, breakdown
// visibility, special-bar visibility, and which metaphor the desktop renders.

const LU_TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "locale": "fa",
  "state": "complete",
  "showSpecialBar": true,
  "showBreakdown": true,
  "desktopMetaphor": "tactical",
  "primaryMetaphor": "tactical"
}/*EDITMODE-END*/;

// Map "state" tweak to: slots, fanCard, coachCard, submitState, invalidIds.
function deriveStateBundle(state) {
  let slots;
  let fanCard = null;
  let coachCard = null;
  let submitState = 'ready';
  let invalidIds = new Set();
  switch (state) {
    case 'empty':
      slots = makeEmptySlots();
      submitState = 'waiting';
      break;
    case 'partial':
      slots = makePartialSlots();
      submitState = 'waiting';
      break;
    case 'complete':
      slots = makePresetSlots();
      submitState = 'ready';
      break;
    case 'cooldown':
      slots = makePresetSlots();
      submitState = 'cooldown';
      break;
    case 'coach-active':
      slots = makePresetSlots();
      coachCard = COACH_CARDS[0]; // ×1.5
      submitState = 'ready';
      break;
    case 'fan-selected':
      slots = makePresetSlots();
      fanCard = FAN_CARDS[0]; // +250
      submitState = 'ready';
      break;
    case 'both-bonus':
      slots = makePresetSlots();
      coachCard = COACH_CARDS[0];
      fanCard = FAN_CARDS[0];
      submitState = 'ready';
      break;
    case 'invalid':
      slots = makeInvalidSlots();
      invalidIds = new Set(['MID-0']);
      submitState = 'waiting';
      break;
    default:
      slots = makeEmptySlots();
      submitState = 'waiting';
  }
  return { slots, fanCard, coachCard, submitState, invalidIds };
}

// Section label localizer
function sectionLabel(loc, fa, en, ar) {
  return { fa, en, ar }[loc] || fa;
}

function App() {
  const [t, setTweak] = useTweaks(LU_TWEAK_DEFAULTS);

  // Apply locale to <html>
  React.useEffect(() => {
    document.documentElement.lang = t.locale;
    document.documentElement.dir = t.locale === 'en' ? 'ltr' : 'rtl';
  }, [t.locale]);

  const bundle = deriveStateBundle(t.state);
  const score = computeDeckScore(bundle.slots,
                                 bundle.fanCard?.bonus || 0,
                                 bundle.coachCard?.multiplier || 1.0);

  // shared lineup variant props
  const variantProps = {
    locale: t.locale,
    slots: bundle.slots,
    fanCard: bundle.fanCard,
    coachCard: bundle.coachCard,
    score,
    submitState: bundle.submitState,
    showBreakdown: t.showBreakdown,
    showSpecial: t.showSpecialBar,
    deadline: '02:14:36',
    invalidIds: bundle.invalidIds,
    onPick: () => {},
    onPickFan: () => {},
    onPickCoach: () => {},
    onRemoveSlot: () => {},
    onRemoveFan: () => {},
    onRemoveCoach: () => {},
  };

  // mobile frame dimensions (matches Design Log content-max=460 with chrome)
  const M_W = 440;
  const M_H = 900;

  // desktop frame dimensions
  const D_W = 1280;
  const D_H = 900;

  const renderVariant = (key) => {
    if (key === 'landscape') return <VariantLandscape {...variantProps} />;
    return                          <VariantTactical {...variantProps} />;
  };

  return (
    <React.Fragment>
      <DesignCanvas>
        {/* ───── Notes ───── */}
        <DCSection id="notes"
                   title={sectionLabel(t.locale, 'یادداشت‌های طراحی', 'Designer notes', 'ملاحظات التصميم')}
                   subtitle={sectionLabel(t.locale,
                     'تصمیمات کلیدی · ساختار ثابت ۱-۲-۱-۱ · ترتیب FWD↓GK · sticky submit · special bar مجزا',
                     'Fixed 1-2-1-1 formation · FWD↓GK order · sticky submit · separate special bar',
                     'تشكيل ثابت ١-٢-١-١')}>
          <DCArtboard id="notes-1" label="Approach" width={520} height={620}>
            <NotesPanel locale={t.locale} />
          </DCArtboard>
        </DCSection>

        {/* ───── Section 1: Three Metaphors ───── */}
        <DCSection id="metaphors"
                   title={sectionLabel(t.locale, '۳ متافور · چیدمان موبایل', 'Three metaphors · mobile', '٣ تشكيلات · موبايل')}
                   subtitle={sectionLabel(t.locale,
                     'هر سه در یک state — می‌توان state را با Tweaks عوض کرد و مقایسه کرد',
                     'All three in the same state — switch states via Tweaks to compare',
                     'الثلاثة في نفس الحالة')}>
          <DCArtboard id="m-tactical" label={sectionLabel(t.locale, 'Mobile · پیش‌فرض عمودی', 'Mobile · default vertical', 'موبايل · افتراضي عمودي')} width={M_W} height={M_H}>
            <MobileFrame>
              <LineupSwitcher initialOrientation="vertical" {...variantProps} />
            </MobileFrame>
          </DCArtboard>
          <DCArtboard id="m-landscape" label={sectionLabel(t.locale, 'Mobile · پیش‌فرض افقی', 'Mobile · default horizontal', 'موبايل · افتراضي أفقي')} width={M_W} height={M_H}>
            <MobileFrame>
              <LineupSwitcher initialOrientation="horizontal" {...variantProps} />
            </MobileFrame>
          </DCArtboard>
        </DCSection>

        {/* ───── Section 2: Picker Variations ───── */}
        <DCSection id="pickers"
                   title={sectionLabel(t.locale, 'انتخاب کارت · ۳ ایده', 'Card picker · 3 ideas', 'اختيار البطاقة')}
                   subtitle={sectionLabel(t.locale,
                     'وقتی یک slot tap می‌شود — کدام pattern؟',
                     'When a slot is tapped — which pattern?',
                     'عند الضغط على فتحة')}>
          <DCArtboard id="pk-full"
                      label={sectionLabel(t.locale, 'Full Screen · search + sort', 'Full Screen · search + sort', 'شاشة كاملة')}
                      width={M_W} height={M_H}>
            <MobileFrame>
              <PickerFullscreenDemo locale={t.locale} position="FWD" />
            </MobileFrame>
          </DCArtboard>
        </DCSection>

        {/* ───── Section 3: Desktop ───── */}
        <DCSection id="desktop"
                   title={sectionLabel(t.locale, 'دسکتاپ · چیدمان دو ستونی', 'Desktop · two-column', 'سطح المكتب')}
                   subtitle={sectionLabel(t.locale,
                     'متافور انتخابی در ستون اصلی + پنل کنار با history، tips، state',
                     'Chosen metaphor in main col + side panel with history, tips, state',
                     'الميتافور في العمود الرئيسي')}>
          <DCArtboard id="d-main"
                      label={sectionLabel(t.locale, 'Desktop · landscape',
                                                    'Desktop · landscape',
                                                    'سطح المكتب · أفقي')}
                      width={D_W} height={D_H}>
            <DesktopMockup locale={t.locale} score={score}
                           variantKey={t.desktopMetaphor}
                           variantProps={variantProps}
                           renderVariant={renderVariant} />
          </DCArtboard>
        </DCSection>
      </DesignCanvas>

      {/* ───── Tweaks Panel ───── */}
      <TweaksPanel title={sectionLabel(t.locale, 'Tweaks · Lineup', 'Tweaks · Lineup', 'Tweaks · التشكيلة')}>
        <TweakSection label={sectionLabel(t.locale, 'نمایش · Display', 'Display', 'العرض')} />
        <TweakRadio label={sectionLabel(t.locale, 'زبان', 'Locale', 'اللغة')}
                    value={t.locale}
                    options={['fa', 'en', 'ar']}
                    onChange={(v) => setTweak('locale', v)} />

        <TweakSection label={sectionLabel(t.locale, 'وضعیت چیدمان · State', 'Lineup State', 'حالة التشكيلة')} />
        <TweakSelect label={sectionLabel(t.locale, 'state', 'state', 'state')}
                     value={t.state}
                     options={['empty', 'partial', 'complete', 'cooldown',
                               'coach-active', 'fan-selected', 'both-bonus', 'invalid']}
                     onChange={(v) => setTweak('state', v)} />

        <TweakSection label={sectionLabel(t.locale, 'پنل‌ها · Panels', 'Panels', 'اللوحات')} />
        <TweakToggle label={sectionLabel(t.locale, 'نوار کارت‌های ویژه (Fan/Coach)', 'Special bar', 'الشريط الخاص')}
                     value={t.showSpecialBar}
                     onChange={(v) => setTweak('showSpecialBar', v)} />
        <TweakToggle label={sectionLabel(t.locale, 'breakdown امتیاز', 'Score breakdown', 'تفاصيل النقاط')}
                     value={t.showBreakdown}
                     onChange={(v) => setTweak('showBreakdown', v)} />
        <TweakToggle label={sectionLabel(t.locale, 'نوار اسپانسر', 'Sponsor strip', 'شريط الراعي')}
                     value={t.showSponsor}
                     onChange={(v) => setTweak('showSponsor', v)} />

        <TweakSection label={sectionLabel(t.locale, 'دسکتاپ', 'Desktop', 'سطح المكتب')} />
      </TweaksPanel>
    </React.Fragment>
  );
}

// ─── Mobile frame chrome ───────────────────────────────────────────────────
// Subtle phone bezel + status bar to make mobile screens feel "real" in the
// canvas. Status bar shows time + signal/battery.
function MobileFrame({ children }) {
  return (
    <div className="lu-mob">
      <div className="lu-mob-status" aria-hidden="true">
        <span className="lu-mob-time">9:41</span>
        <span className="lu-mob-notch"></span>
        <span className="lu-mob-icons">
          <svg width="14" height="10" viewBox="0 0 14 10" fill="currentColor"><rect x="0" y="6" width="2" height="4" rx=".5"/><rect x="3" y="4" width="2" height="6" rx=".5"/><rect x="6" y="2" width="2" height="8" rx=".5"/><rect x="9" y="0" width="2" height="10" rx=".5"/></svg>
          <svg width="14" height="10" viewBox="0 0 14 10" fill="none" stroke="currentColor" strokeWidth="1"><rect x=".5" y="2" width="10" height="6" rx="1.5"/><rect x="2" y="3.5" width="6" height="3" rx=".5" fill="currentColor" stroke="none"/><line x1="12" y1="4" x2="12" y2="6"/></svg>
        </span>
      </div>
      <div className="lu-mob-screen">{children}</div>
    </div>
  );
}

// Wrapper for the fullscreen picker — renders it in context.
function PickerFullscreenDemo({ locale, position }) {
  return (
    <div className="lu-pk-host">
      <PickerFullscreen locale={locale} position={position}
                        onPick={() => {}} onClose={() => {}} />
    </div>
  );
}

// ─── Designer notes panel ─────────────────────────────────────────────────
function NotesPanel({ locale }) {
  const isFa = locale === 'fa';
  const isAr = locale === 'ar';

  const items = isFa ? [
    { k: 'ساختار', v: '۱ FWD · ۱ MID · ۲ DEF · ۱ GK — ثابت در MVP طبق سند' },
    { k: 'ترتیب', v: 'از بالا به پایین: FWD → MID → DEF → GK (مثل FUT/Football Manager — کاربر پشت تیم خود ایستاده)' },
    { k: 'Special', v: 'Fan + Coach در یک نوار جدا زیر زمین — اعمال در submit، نه deck اصلی' },
    { k: 'Picker', v: '۳ ایده — Sheet (پیشنهادی · سریع‌ترین)، Full-screen (برای collection بزرگ)، Strip (کارت‌بازی)' },
    { k: 'Interaction', v: 'Tap → picker · Long-press → drag (در نسخه‌ی production)' },
    { k: 'Submit', v: 'sticky پایین + Free Submit indicator چپ، countdown اگر آماده نیست' },
    { k: 'Score', v: '(Base × Mult) + Bonus = Final  →  XP = Final × 1.6' },
    { k: 'Empty', v: 'Outline dashed با position icon + label + + (مطابق نظر شما)' },
    { k: 'Invalid', v: 'border قرمز + label هشدار بالای کارت — حالا که هیچ صفحه‌ای position-check ندارد، useful برای drag از reserve' },
  ] : isAr ? [
    { k: 'تشكيل', v: '١ FWD · ١ MID · ٢ DEF · ١ GK' },
    { k: 'الترتيب', v: 'من الأعلى للأسفل: FWD → GK' },
    { k: 'الخاصة', v: 'Fan + Coach في شريط منفصل' },
    { k: 'الإختيار', v: '٣ أنماط picker' },
  ] : [
    { k: 'Formation', v: '1 FWD · 1 MID · 2 DEF · 1 GK — fixed per MVP spec' },
    { k: 'Order', v: 'Top-to-bottom: FWD → MID → DEF → GK (FIFA-style, you stand behind your own team)' },
    { k: 'Special', v: 'Fan + Coach in a separate bar below the field — applied at submit, not part of the 5-card deck' },
    { k: 'Picker', v: '3 ideas — Sheet (recommended · fastest), Full-screen (for big collections), Strip (card-game vibe)' },
    { k: 'Interaction', v: 'Tap → picker · Long-press → drag (in production)' },
    { k: 'Submit', v: 'sticky bottom + Free Submit indicator on the left, countdown when not ready' },
    { k: 'Score', v: '(Base × Mult) + Bonus = Final  →  XP = Final × 1.6' },
    { k: 'Empty', v: 'Dashed outline with position icon + label + plus' },
    { k: 'Invalid', v: 'Red border + warn label above the card' },
  ];

  return (
    <div className="lu-notes">
      <div className="lu-notes-title">
        {isFa ? 'مبنای طراحی این sprint' : isAr ? 'أساس التصميم' : 'Design rationale'}
      </div>
      <ul className="lu-notes-list">
        {items.map((it, i) => (
          <li key={i} className="lu-notes-item">
            <span className="lu-notes-k">{it.k}</span>
            <span className="lu-notes-v">{it.v}</span>
          </li>
        ))}
      </ul>
      <div className="lu-notes-foot">
        {isFa
          ? 'برای دیدن state دیگر — Tweaks → state'
          : isAr ? 'لرؤية حالات أخرى — Tweaks'
                 : 'To see other states — open Tweaks → state'}
      </div>
    </div>
  );
}

// ─── Desktop mockup — horizontal layout ───────────────────────────────────
// Single layout (the one approved): topbar + 3-col grid where
//   • right sidebar (RTL start) — deadline, recent history, tips
//   • center column — title, special bar, horizontal pitch, sponsor banner
//   • left sidebar (RTL end) — deck summary, submit area, sponsor block
function DesktopMockup({ locale, variantKey, renderVariant, score, variantProps }) {
  const ll = LU_I18N[locale];
  const isFa = locale === 'fa';
  const isAr = locale === 'ar';

  const recentDecks = [
    { id: 'r1', label: isFa ? 'هفته ۲۷' : isAr ? 'الأسبوع ٢٧' : 'Week 27', score: 412, xp: 660, status: 'won' },
    { id: 'r2', label: isFa ? 'هفته ۲۶' : isAr ? 'الأسبوع ٢٦' : 'Week 26', score: 388, xp: 620, status: 'won' },
    { id: 'r3', label: isFa ? 'گلدن میشن' : isAr ? 'مهمة ذهبية' : 'Golden Mission', score: 521, xp: 980, status: 'gm' },
  ];
  const tips = isFa ? [
    'با ۳ بازیکن از یک کشور، شرط فعال‌سازی مربی ایران را برآورده می‌کنید.',
    'Coach Card فعلاً غیرفعال است؛ یکی را روی این دک امتحان کنید.',
  ] : isAr ? [
    'مع ٣ لاعبين من نفس البلد، تفعّل شرط مدرب إيران.',
    'بطاقة المدرب غير مفعلة حالياً.',
  ] : [
    'With 3 players from the same country, you trigger the Iran Coach.',
    'No Coach Card active — try one from your inventory.',
  ];

  const dh = variantProps.slots;
  const scale = 0.70;

  return (
    <div className="lu-desk">
      <div className="lu-desk-topbar">
        <div className="lu-desk-topbar-left">
          <div className="lu-desk-logo">رختکن</div>
          <nav className="lu-desk-nav">
            <a className="lu-desk-nav-link">{isFa ? 'پیش‌بینی' : isAr ? 'التنبؤات' : 'Predictions'}</a>
            <a className="lu-desk-nav-link is-active">{ll.title}</a>
            <a className="lu-desk-nav-link">{isFa ? 'فروشگاه' : isAr ? 'المتجر' : 'Shop'}</a>
            <a className="lu-desk-nav-link">{isFa ? 'جدول' : isAr ? 'الجدول' : 'Leaderboard'}</a>
            <a className="lu-desk-nav-link">{isFa ? 'رختکن' : isAr ? 'خزانة' : 'Locker'}</a>
          </nav>
        </div>
        <div className="lu-desk-topbar-right">
          <div className="lu-desk-coin">
            <span>{toLocaleDigits(2840, locale)}</span>
            <span className="lu-desk-coin-label">{isFa ? 'سکه' : isAr ? 'عملة' : 'Coin'}</span>
          </div>
          <div className="lu-desk-avatar">آ</div>
        </div>
      </div>

      <div className="lu-desk-grid">
        {/* RTL start (right side) — deadline, summary, submit, sponsor block */}
        <aside className="lu-desk-side lu-desk-side--summary">
          <div className="lu-desk-panel">
            <div className="lu-desk-panel-title">
              {isFa ? 'مهلت ثبت' : isAr ? 'الموعد النهائي' : 'Deadline'}
            </div>
            <div className="lu-desk-deadline">
              <div className="lu-desk-deadline-time">{toLocaleDigits('02:14:36', locale)}</div>
              <div className="lu-desk-deadline-label">
                {isFa ? 'تا ثبت چیدمان' : isAr ? 'لتأكيد التشكيلة' : 'until submit closes'}
              </div>
            </div>
          </div>
          <DeckSummary locale={locale} score={score}
                       showBreakdown={variantProps.showBreakdown}
                       complete={variantProps.submitState === 'ready'} />
          <SubmitBar locale={locale} state={variantProps.submitState} cooldown="03:42" />
          <SponsorStrip locale={locale} visible={variantProps.showSponsor} variant="block" sponsorId="mili" />
        </aside>

        {/* Center — title, special bar, pitch */}
        <main className="lu-desk-h-main">
          <header className="lu-desk-h-pitch-header">
            <div className="lu-desk-h-pitch-title">
              {isFa ? 'چیدمان تیم' : isAr ? 'التشكيلة' : 'Lineup'}
            </div>
            <FormationChip locale={locale} />
          </header>

          <SpecialBar locale={locale}
                      fanCard={variantProps.fanCard} coachCard={variantProps.coachCard}
                      onPickFan={variantProps.onPickFan} onPickCoach={variantProps.onPickCoach}
                      onRemoveFan={variantProps.onRemoveFan} onRemoveCoach={variantProps.onRemoveCoach}
                      visible={variantProps.showSpecial} compact />

          <div className="lu-desk-h-pitch">
            <PitchBillboards locale={locale} side="top" />
            <PitchBillboards locale={locale} side="bottom" />
            <LandscapePitchMarkings />
            <div className="lu-landscape-grid">
              <div className="lu-landscape-col lu-landscape-col--gk">
                {renderSlot({ player: dh.GK[0], position: 'GK', locale, scale,
                              onPick: () => variantProps.onPick('GK', 0),
                              onRemove: dh.GK[0] ? () => variantProps.onRemoveSlot('GK', 0) : null,
                              invalid: variantProps.invalidIds.has('GK-0') })}
              </div>
              <div className="lu-landscape-col lu-landscape-col--def">
                {renderSlot({ player: dh.DEF[0], position: 'DEF', locale, scale,
                              onPick: () => variantProps.onPick('DEF', 0),
                              onRemove: dh.DEF[0] ? () => variantProps.onRemoveSlot('DEF', 0) : null,
                              invalid: variantProps.invalidIds.has('DEF-0') })}
              </div>
              <div className="lu-landscape-col lu-landscape-col--mid">
                {renderSlot({ player: dh.MID[0], position: 'MID', locale, scale,
                              onPick: () => variantProps.onPick('MID', 0),
                              onRemove: dh.MID[0] ? () => variantProps.onRemoveSlot('MID', 0) : null,
                              invalid: variantProps.invalidIds.has('MID-0') })}
                {renderSlot({ player: dh.MID[1], position: 'MID', locale, scale,
                              onPick: () => variantProps.onPick('MID', 1),
                              onRemove: dh.MID[1] ? () => variantProps.onRemoveSlot('MID', 1) : null,
                              invalid: variantProps.invalidIds.has('MID-1') })}
              </div>
              <div className="lu-landscape-col lu-landscape-col--fwd">
                {renderSlot({ player: dh.FWD[0], position: 'FWD', locale, scale,
                              onPick: () => variantProps.onPick('FWD', 0),
                              onRemove: dh.FWD[0] ? () => variantProps.onRemoveSlot('FWD', 0) : null,
                              invalid: variantProps.invalidIds.has('FWD-0') })}
              </div>
            </div>
          </div>

          <SponsorStrip locale={locale} visible={variantProps.showSponsor} variant="banner" sponsorId="blu" />
        </main>

        {/* RTL end (left side) — history, tips, sponsor block */}
        <aside className="lu-desk-side lu-desk-side--info">
          <div className="lu-desk-panel">
            <div className="lu-desk-panel-title">
              {isFa ? 'تاریخچه دک‌های اخیر' : isAr ? 'سجل التشكيلات' : 'Recent History'}
            </div>
            <ul className="lu-desk-history">
              {recentDecks.map((d) => (
                <li key={d.id} className={`lu-desk-history-item is-${d.status}`}>
                  <div className="lu-desk-history-row">
                    <span className="lu-desk-history-label">{d.label}</span>
                    <span className="lu-desk-history-score">{toLocaleDigits(d.score, locale)}</span>
                  </div>
                  <div className="lu-desk-history-row">
                    <span className="lu-desk-history-meta">XP {toLocaleDigits(d.xp, locale)}</span>
                    <span className={`lu-desk-history-status lu-desk-history-status--${d.status}`}>
                      {d.status === 'gm' ? (isFa ? 'گلدن' : 'Golden') : (isFa ? 'ثبت شد' : 'Submitted')}
                    </span>
                  </div>
                </li>
              ))}
            </ul>
          </div>

          <div className="lu-desk-panel">
            <div className="lu-desk-panel-title">
              {isFa ? 'پیشنهادها' : isAr ? 'اقتراحات' : 'Tips'}
            </div>
            <ul className="lu-desk-tips">
              {tips.map((tip, i) => (
                <li key={i} className="lu-desk-tip">
                  <span className="lu-desk-tip-marker">•</span>
                  <span>{tip}</span>
                </li>
              ))}
            </ul>
          </div>

          <SponsorStrip locale={locale} visible={variantProps.showSponsor} variant="block" sponsorId="mci" />
        </aside>
      </div>
    </div>
  );
}

// ─── Styles for the App-level chrome (mobile frame, desktop, notes) ────────
const APP_CSS = `
  /* ──── Mobile frame ──── */
  .lu-mob {
    width: 100%;
    height: 100%;
    background: #02020A;
    border-radius: 36px;
    overflow: hidden;
    position: relative;
    box-shadow: 0 1px 0 rgba(255,255,255,0.04) inset,
                0 0 0 2px rgba(255,255,255,0.04),
                0 30px 60px -20px rgba(0,0,0,0.6);
    display: flex;
    flex-direction: column;
  }
  .lu-mob-status {
    height: 38px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 4px 22px 0;
    background: var(--bg-deep);
    color: var(--text-primary);
    font-size: 13px;
    font-weight: 600;
    font-family: -apple-system, system-ui, sans-serif;
    position: relative;
    z-index: 10;
  }
  .lu-mob-time {
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.01em;
  }
  .lu-mob-notch {
    position: absolute;
    top: 6px;
    left: 50%;
    transform: translateX(-50%);
    width: 100px;
    height: 24px;
    background: #000;
    border-radius: 999px;
  }
  .lu-mob-icons {
    display: flex; align-items: center; gap: 6px;
    color: var(--text-primary);
  }
  .lu-mob-screen {
    flex: 1;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    position: relative;
  }
  /* The lineup variant fills the screen */
  .lu-mob-screen > .lu { width: 100%; height: 100%; }
  .lu-mob-screen > .lu-pk-host { width: 100%; height: 100%; position: relative; overflow: hidden; }
  .lu-pk-host > .lu, .lu-pk-host > .lu-pk--full { position: absolute; inset: 0; }

  /* ──── Notes panel ──── */
  .lu-notes {
    width: 100%; height: 100%;
    padding: 22px 24px;
    border-radius: 18px;
    background: linear-gradient(180deg, rgba(20,20,30,0.65), rgba(7,7,12,0.65));
    border: 1px solid rgba(255,255,255,0.05);
    display: flex; flex-direction: column;
    overflow: hidden;
  }
  .lu-notes-title {
    font-size: 18px;
    font-weight: 700;
    color: var(--text-primary);
    margin-bottom: 12px;
  }
  .lu-notes-list {
    list-style: none;
    padding: 0;
    margin: 0;
    overflow-y: auto;
    flex: 1;
    display: flex; flex-direction: column;
    gap: 8px;
  }
  .lu-notes-item {
    display: flex; flex-direction: column;
    gap: 4px;
    padding: 10px 12px;
    border-radius: 10px;
    background: rgba(255,255,255,0.02);
    border: 1px solid rgba(255,255,255,0.04);
  }
  .lu-notes-k {
    font-size: 11px;
    color: var(--accent);
    font-weight: 700;
    letter-spacing: 0.02em;
    text-transform: uppercase;
  }
  html[lang="fa"] .lu-notes-k,
  html[lang="ar"] .lu-notes-k { text-transform: none; }
  .lu-notes-v {
    font-size: 13px;
    color: var(--text-secondary);
    line-height: 1.5;
  }
  .lu-notes-foot {
    margin-top: 12px;
    font-size: 11px;
    color: var(--text-tertiary);
    text-align: center;
  }

  /* ──── Desktop mockup ──── */
  .lu-desk {
    width: 100%; height: 100%;
    background: var(--bg-deep);
    color: var(--text-primary);
    display: flex; flex-direction: column;
    overflow: hidden;
    position: relative;
  }
  .lu-desk-topbar {
    display: flex; align-items: center; justify-content: space-between;
    padding: 14px 24px;
    border-bottom: 1px solid rgba(255,255,255,0.04);
    background: rgba(7,7,12,0.6);
    backdrop-filter: blur(20px);
  }
  .lu-desk-topbar-left { display: flex; align-items: center; gap: 28px; }
  .lu-desk-logo {
    font-size: 18px;
    font-weight: 800;
    color: var(--text-primary);
    letter-spacing: -0.01em;
  }
  .lu-desk-nav { display: flex; gap: 18px; align-items: center; }
  .lu-desk-nav-link {
    font-size: 13px;
    color: var(--text-tertiary);
    cursor: pointer;
    padding: 6px 10px;
    border-radius: 8px;
    transition: color .12s, background .12s;
  }
  .lu-desk-nav-link:hover { color: var(--text-secondary); background: rgba(255,255,255,0.02); }
  .lu-desk-nav-link.is-active {
    color: var(--text-primary);
    background: rgba(113,99,217,0.10);
  }
  .lu-desk-topbar-right { display: flex; align-items: center; gap: 14px; }
  .lu-desk-coin {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 6px 12px;
    border-radius: 999px;
    border: 1px solid rgba(252,211,77,0.18);
    background: rgba(252,211,77,0.05);
    color: var(--tier-gold);
    font-size: 13px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
  }
  .lu-desk-coin-label { color: var(--text-tertiary); font-size: 11px; font-weight: 500; }
  .lu-desk-avatar {
    width: 34px; height: 34px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--accent), var(--accent-2));
    color: white;
    display: flex; align-items: center; justify-content: center;
    font-weight: 700;
    font-size: 14px;
    border: 1px solid rgba(255,255,255,0.10);
  }
  .lu-desk-grid {
    flex: 1;
    display: grid;
    grid-template-columns: 320px 1fr 320px;
    gap: 20px;
    padding: 22px;
    overflow: hidden;
    min-height: 0;
  }
  .lu-desk-side {
    display: flex; flex-direction: column;
    gap: 14px;
    min-width: 0;
    overflow-y: auto;
  }
  .lu-desk-side--summary .lu-summary { margin: 0; }
  .lu-desk-side--summary .lu-submit { border-radius: 16px; overflow: hidden; }
  .lu-desk-h-main {
    display: flex;
    flex-direction: column;
    gap: 12px;
    min-width: 0;
    overflow: hidden;
  }
  .lu-desk-h-pitch-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    padding: 0 4px;
  }
  .lu-desk-h-pitch-title {
    font-size: 24px;
    font-weight: 800;
    color: var(--text-primary);
    letter-spacing: -0.01em;
  }
  .lu-desk-h-pitch {
    position: relative;
    flex: 1;
    border-radius: 18px;
    overflow: hidden;
    border: 1px solid rgba(255,255,255,0.05);
    background:
      radial-gradient(ellipse 90% 70% at 50% 50%, #2D5A3E 0%, #1A3326 50%, #0C1812 85%, #060A07 100%);
    min-height: 460px;
  }
  .lu-desk-h-pitch::after {
    content: '';
    position: absolute;
    inset: 0;
    background-image: repeating-linear-gradient(
      90deg,
      rgba(255,255,255,0.022) 0 50px,
      transparent 50px 100px);
    pointer-events: none;
    z-index: 1;
  }
  .lu-desk-h-pitch::before {
    content: '';
    position: absolute;
    inset: 0;
    background:
      radial-gradient(ellipse 50% 80% at 0% 50%, rgba(0,0,0,0.35), transparent 60%),
      radial-gradient(ellipse 50% 80% at 100% 50%, rgba(0,0,0,0.35), transparent 60%);
    pointer-events: none;
    z-index: 2;
  }
  .lu-desk-h-pitch .lu-landscape-svg {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    z-index: 3;
    pointer-events: none;
  }
  .lu-desk-h-pitch .lu-landscape-grid {
    position: absolute;
    inset: 0;
    z-index: 4;
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    align-items: center;
    justify-items: center;
    padding: 18px 16px;
  }
  /* Bigger LED billboards on desktop pitch */
  .lu-desk-h-pitch .lu-billboards--horizontal { height: 18px; }
  .lu-desk-h-pitch .lu-billboards--horizontal.lu-billboards--top    { top: 14px; left: 20px; right: 20px; }
  .lu-desk-h-pitch .lu-billboards--horizontal.lu-billboards--bottom { bottom: 14px; left: 20px; right: 20px; }
  .lu-desk-h-pitch .lu-billboards--horizontal .lu-billboard-slot { flex: 0 0 220px; }
  .lu-desk-h-pitch .lu-billboard-text { font-size: 11px; }
  .lu-desk-panel {
    border-radius: 16px;
    border: 1px solid rgba(255,255,255,0.04);
    background: rgba(20,20,30,0.4);
    padding: 16px 18px;
    flex-shrink: 0;
  }
  .lu-desk-panel-title {
    font-size: 12px;
    font-weight: 700;
    color: var(--text-tertiary);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    margin-bottom: 10px;
  }
  html[lang="fa"] .lu-desk-panel-title,
  html[lang="ar"] .lu-desk-panel-title {
    text-transform: none;
    letter-spacing: 0;
    font-size: 13px;
  }
  .lu-desk-history {
    list-style: none; padding: 0; margin: 0;
    display: flex; flex-direction: column;
    gap: 6px;
  }
  .lu-desk-history-item {
    border-radius: 10px;
    border: 1px solid rgba(255,255,255,0.03);
    background: rgba(255,255,255,0.015);
    padding: 10px 12px;
  }
  .lu-desk-history-row {
    display: flex; align-items: center; justify-content: space-between;
    line-height: 1.2;
  }
  .lu-desk-history-row + .lu-desk-history-row { margin-top: 4px; }
  .lu-desk-history-label {
    font-size: 12px;
    font-weight: 600;
    color: var(--text-primary);
  }
  .lu-desk-history-score {
    font-size: 14px;
    font-weight: 700;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
  }
  .lu-desk-history-meta {
    font-size: 11px;
    color: var(--text-tertiary);
    font-variant-numeric: tabular-nums;
  }
  .lu-desk-history-status {
    font-size: 10px;
    font-weight: 700;
    padding: 2px 7px;
    border-radius: 999px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
  }
  html[lang="fa"] .lu-desk-history-status,
  html[lang="ar"] .lu-desk-history-status {
    text-transform: none; letter-spacing: 0; font-size: 11px;
  }
  .lu-desk-history-status--won { background: rgba(52,211,153,0.10); color: var(--success); }
  .lu-desk-history-status--gm  { background: rgba(252,211,77,0.10);  color: var(--tier-gold); }
  .lu-desk-tips {
    list-style: none; padding: 0; margin: 0;
    display: flex; flex-direction: column;
    gap: 8px;
  }
  .lu-desk-tip {
    display: flex; gap: 8px;
    font-size: 12px;
    color: var(--text-secondary);
    line-height: 1.5;
  }
  .lu-desk-tip-marker { color: var(--accent); flex-shrink: 0; }
  .lu-desk-deadline {
    display: flex; flex-direction: column;
    align-items: center;
    padding: 4px 0 4px;
  }
  .lu-desk-deadline-time {
    font-size: 32px;
    font-weight: 800;
    color: var(--warning);
    font-variant-numeric: tabular-nums;
    line-height: 1;
  }
  .lu-desk-deadline-label {
    font-size: 11px;
    color: var(--text-tertiary);
    margin-top: 6px;
  }
`;

const __luAppStyle = document.createElement('style');
__luAppStyle.textContent = APP_CSS;
document.head.appendChild(__luAppStyle);

// ─── Exports for unified app shell (Phase 1) ─────────────────────────────────
// Lineup module uses LineupSwitcher (lineup-variants.jsx, already exported)
// for mobile and desktop. The app shell can use VariantLandscape directly
// for the desktop variant. We also export the helpers used to compose them.
Object.assign(window, {
  deriveStateBundle, sectionLabel, MobileFrame, DesktopMockup,
});

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