/* global React, Ico, STR, Button, Label, Card, Avatar, TierBadge, tierFor */
// NEXT XI · v3 — Login + Role select + Coach dashboard

const { useState: useS3, useEffect: useE3 } = React;
const nxLangKey = (lang) => lang === 'ru' ? 'ru' : lang === 'en' ? 'en' : 'tr';
const nxTxt = (lang, tr, en, ru) => {
  const key = nxLangKey(lang);
  return key === 'ru' ? (ru ?? tr ?? en ?? '') : key === 'en' ? (en ?? tr ?? ru ?? '') : (tr ?? en ?? ru ?? '');
};

// ────────────────────────────────────────────────────────────
// ACADEMY CODE ENTRY — validates academy code before signup
// ────────────────────────────────────────────────────────────
const AcademyCodeEntryScreen = ({ lang, onBack, preselectedRole, onSelect }) => {
  const [code,    setCode]    = useS3('');
  const [loading, setLoading] = useS3(false);
  const [error,   setError]   = useS3(null);
  const [academy, setAcademy] = useS3(null);
  const langKey = nxLangKey(lang);
  const isTr = langKey === 'tr';
  const isRu = langKey === 'ru';

  const handleValidate = async () => {
    const trimmed = code.trim().toUpperCase();
    if (!trimmed) return;
    setLoading(true);
    setError(null);
    try {
      const found = await window.NX.getAcademyByCode(trimmed);
      if (!found) {
        setError(lang === 'ru'
          ? 'Недействительный код академии. Проверьте код или обратитесь к администратору.'
          : isTr
          ? 'Geçersiz akademi kodu. Lütfen kodunu kontrol et veya yöneticinle iletişime geç.'
          : 'Invalid academy code. Check the code or contact your admin.');
        return;
      }
      setAcademy(found);
      setCode('');
    } catch (e) {
      console.error('[NX][code-entry] getAcademyByCode threw:', e?.code, e?.message);
      if (e?.code === 'permission-denied') {
        setError(lang === 'ru'
          ? 'Доступ запрещён. Правила Firestore могут быть ещё не опубликованы.'
          : isTr
          ? 'Erişim reddedildi (permission-denied). Firestore kuralları henüz yayımlanmamış olabilir.'
          : 'Access denied (permission-denied). Firestore rules may not be deployed yet.');
      } else if (e?.code === 'failed-precondition') {
        setError(lang === 'ru'
          ? 'Запрос не выполнен (возможно, отсутствует индекс). Попробуйте ещё раз.'
          : isTr
          ? 'Veritabanı sorgusu başarısız (index eksik olabilir). Lütfen tekrar deneyin.'
          : 'Query failed (index may be missing). Please try again.');
      } else if (e?.code === 'unavailable') {
        setError(lang === 'ru'
          ? 'Нет связи с сервером. Проверьте интернет-соединение.'
          : isTr
          ? 'Sunucuya bağlanılamıyor. İnternet bağlantını kontrol et.'
          : 'Cannot reach server. Check your internet connection.');
      } else {
        setError(lang === 'ru'
          ? `Ошибка: ${e?.code || 'unknown'}. Попробуйте ещё раз.`
          : isTr
          ? `Hata: ${e?.code || 'unknown'}. Lütfen tekrar deneyin.`
          : `Error: ${e?.code || 'unknown'}. Please try again.`);
      }
    } finally {
      setLoading(false);
    }
  };

  const isSwimming = academy?.sportType === 'swimming';
  const accent = isSwimming ? '#38E8FF' : '#00FF88';
  const sportLabel = isSwimming
    ? (lang === 'ru' ? 'Плавание' : isTr ? 'Yüzme' : 'Swimming')
    : (lang === 'ru' ? 'Футбол' : isTr ? 'Futbol' : 'Football');
  const coachLabel = isSwimming
    ? (lang === 'ru' ? 'Инструктор' : isTr ? 'Eğitmen' : 'Instructor')
    : (lang === 'ru' ? 'Тренер' : isTr ? 'Koç' : 'Coach');

  return (
    <div style={{ display:'flex', flexDirection:'column', height:'100%', background:'#0B0B0B', overflowY:'auto' }}>
      <div style={{ padding:'68px 20px 0', display:'flex', alignItems:'center', gap: 12 }}>
        <button onClick={onBack} style={{
          width:32, height:32, borderRadius:999, background:'#1C1C1C',
          border:'1px solid rgba(255,255,255,0.06)', color:'#fff', cursor:'pointer',
          display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0,
        }}>
          <Ico name="chev" size={16}/>
        </button>
        <div>
          <Label color="#00FF88">{nxTxt(lang, 'Akademi Kaydı', 'Academy Sign Up', 'Регистрация в академии')}</Label>
          <h1 style={{ fontFamily:'Oswald', fontWeight:700, fontSize:26, lineHeight:1.0,
            textTransform:'uppercase', letterSpacing:'0.02em', color:'#fff', margin:'4px 0 0' }}>
            {nxTxt(lang, 'Akademi kodunu gir', 'Enter academy code', 'Введите код академии')}
            <span style={{ color:'#00FF88' }}>.</span>
          </h1>
        </div>
      </div>

      <div style={{ padding:20, display:'flex', flexDirection:'column', gap:14 }}>
        {!academy ? (
          <>
            <div style={{ padding:12, borderRadius:10, background:'rgba(0,255,136,0.04)',
              border:'1px solid rgba(0,255,136,0.15)' }}>
              <div style={{ fontFamily:'Manrope', fontSize:12, color:'#B8B8B8', lineHeight:1.5 }}>
                {nxTxt(lang,
                  'Akademin tarafından verilen kayıt kodunu gir. Koç veya yöneticinden alabilirsin.',
                  'Enter the registration code provided by your academy. Get it from your coach or admin.',
                  'Введите регистрационный код, выданный академией. Его можно получить у тренера или администратора.')}
              </div>
            </div>
            <div>
              <Label style={{ display:'block', marginBottom:6 }}>
                {nxTxt(lang, 'Akademi kayıt kodu', 'Academy registration code', 'Регистрационный код академии')}
              </Label>
              <input
                placeholder="NX-XXXX"
                value={code}
                onChange={e => { setCode(e.target.value.toUpperCase()); setError(null); }}
                onKeyDown={e => e.key === 'Enter' && handleValidate()}
                maxLength={7}
                style={{
                  width:'100%', boxSizing:'border-box',
                  background:'#141414', border:'1px solid rgba(255,255,255,0.10)',
                  borderRadius:12, padding:'16px 16px', minHeight:54,
                  fontFamily:'JetBrains Mono', fontWeight:700, fontSize:18,
                  color:'#fff', outline:'none', letterSpacing:'0.14em',
                  textTransform:'uppercase', textAlign:'center',
                }}
              />
            </div>
            {error && (
              <div style={{ padding:'10px 14px', borderRadius:10,
                background:'rgba(255,80,80,0.08)', border:'1px solid rgba(255,80,80,0.30)' }}>
                <span style={{ fontFamily:'Manrope', fontSize:12, color:'#FF6B6B' }}>{error}</span>
              </div>
            )}
            <Button kind="primary" full size="lg" icon={loading?null:'arrow'}
              onClick={handleValidate} disabled={loading || !code.trim()}>
              {loading ? nxTxt(lang, 'Doğrulanıyor…', 'Verifying…', 'Проверка…') : nxTxt(lang, 'Devam et', 'Continue', 'Продолжить')}
            </Button>
          </>
        ) : (
          <>
            <div style={{ padding:14, borderRadius:12,
              background:`${accent}0A`, border:`1px solid ${accent}40` }}>
              <div style={{ fontFamily:'JetBrains Mono', fontSize:8, color:accent,
                letterSpacing:'0.14em', textTransform:'uppercase', marginBottom:6 }}>
                {nxTxt(lang, '✓ Akademi doğrulandı', '✓ Academy verified', '✓ Академия подтверждена')}
              </div>
              <div style={{ fontFamily:'Oswald', fontWeight:700, fontSize:20, color:'#fff' }}>
                {academy.name}
              </div>
              <div style={{ fontFamily:'Manrope', fontSize:12, color:'#7A7A7A', marginTop:4 }}>
                {sportLabel}
              </div>
            </div>
            <div>
              <Label style={{ display:'block', marginBottom:8 }}>
                {nxTxt(lang, 'Hesap türünü seç', 'Select account type', 'Выберите тип аккаунта')}
              </Label>
              <div style={{ display:'flex', flexDirection:'column', gap:8 }}>
                {[
                  { role:'player', label: lang==='ru'?'Спортсмен':isTr?'Sporcu':'Athlete',   color:'#00FF88' },
                  { role:'coach',  label: coachLabel,                                          color:'#FFB800' },
                  { role:'parent', label: lang==='ru'?'Родитель':isTr?'Veli':'Parent',        color:'#4F8DFF' },
                ].map(({ role, label, color }) => (
                  <button key={role} onClick={() => onSelect(role, academy)} style={{
                    padding:'13px 14px', borderRadius:10, cursor:'pointer',
                    background: preselectedRole===role ? `${color}12` : '#141414',
                    border:`1px solid ${preselectedRole===role ? `${color}60` : 'rgba(255,255,255,0.06)'}`,
                    display:'flex', alignItems:'center', justifyContent:'space-between',
                  }}>
                    <span style={{ fontFamily:'Manrope', fontWeight:700, fontSize:13, color }}>
                      {label}
                    </span>
                    <span style={{ fontFamily:'Manrope', fontSize:11, color:'#5A5A5A' }}>
                      {isRu?'Требует одобрения →':isTr?'Onay bekler →':'Requires approval →'}
                    </span>
                  </button>
                ))}
              </div>
            </div>
            <button onClick={() => setAcademy(null)} style={{
              background:'none', border:'none', padding:0, cursor:'pointer',
              fontFamily:'Manrope', fontWeight:600, fontSize:11, color:'#5A5A5A',
              letterSpacing:'0.08em', textAlign:'left',
            }}>
              ← {nxTxt(lang, 'Farklı bir kod gir', 'Try a different code', 'Ввести другой код')}
            </button>
          </>
        )}
      </div>
    </div>
  );
};

// ────────────────────────────────────────────────────────────
// LOGIN / SIGN UP
// ────────────────────────────────────────────────────────────
// Demo-only roles (no admin)
const DEMO_ROLES = [
  { key:'player', tr:'Sporcu',  en:'Athlete', ru:'Спортсмен', color:'#00FF88' },
  { key:'coach',  tr:'Koç',     en:'Coach',   ru:'Тренер',    color:'#FFB800' },
  { key:'parent', tr:'Veli',    en:'Parent',  ru:'Родитель',  color:'#4F8DFF' },
];

// Firebase error code → user-facing message
const FB_ERRORS = {
  'auth/invalid-credential':    { tr:'E-posta veya parola hatalı.',         en:'Incorrect email or password.',         ru:'Неверный e-mail или пароль.' },
  'auth/user-not-found':        { tr:'Bu e-posta ile kayıtlı hesap yok.',   en:'No account found for this email.',     ru:'Аккаунт с таким e-mail не найден.' },
  'auth/wrong-password':        { tr:'Parola hatalı.',                      en:'Incorrect password.',                  ru:'Неверный пароль.' },
  'auth/too-many-requests':     { tr:'Çok fazla deneme. Lütfen bekle.',     en:'Too many attempts. Please wait.',      ru:'Слишком много попыток. Пожалуйста, подождите.' },
  'auth/network-request-failed':{ tr:'Ağ hatası. İnternet bağlantını kontrol et.', en:'Network error. Check your connection.', ru:'Ошибка сети. Проверьте интернет-соединение.' },
  'auth/email-already-in-use':  { tr:'Bu e-posta zaten kullanılıyor.',      en:'This email is already in use.',        ru:'Этот e-mail уже используется.' },
  'auth/weak-password':         { tr:'Parola en az 6 karakter olmalı.',     en:'Password must be at least 6 characters.', ru:'Пароль должен содержать не менее 6 символов.' },
  'auth/invalid-email':         { tr:'Geçersiz e-posta adresi.',             en:'Invalid email address.',                  ru:'Некорректный e-mail адрес.' },
};

const fbMsg = (code, lang) => {
  const langKey = nxLangKey(lang);
  const isTr = langKey === 'tr';
  const isRu = langKey === 'ru';
  const entry = FB_ERRORS[code];
  if (entry) return lang === 'ru' ? entry.ru : (isTr ? entry.tr : entry.en);
  return lang === 'ru' ? 'Произошла ошибка. Попробуйте снова.' : (isTr ? 'Bir hata oluştu. Tekrar dene.' : 'Something went wrong. Try again.');
};

const codeErrorMsg = (reason, lang) => {
  const langKey = nxLangKey(lang);
  const isTr = langKey === 'tr';
  if (reason === 'not_found') return lang === 'ru' ? 'Код не найден.' : (isTr ? 'Kod bulunamadı.' : 'Code not found.');
  if (reason === 'wrong_type') return lang === 'ru' ? 'Этот код недействителен для данной роли.' : (isTr ? 'Bu kod bu rol için geçerli değil.' : 'This code is not valid for this role.');
  if (reason === 'claimed')   return lang === 'ru' ? 'Этот код уже использован.' : (isTr ? 'Bu kod zaten kullanılmış.' : 'This code has already been used.');
  if (reason === 'revoked')   return lang === 'ru' ? 'Этот код отозван.' : (isTr ? 'Bu kod iptal edilmiş.' : 'This code has been revoked.');
  return lang === 'ru' ? 'Недействительный код.' : (isTr ? 'Geçersiz kod.' : 'Invalid code.');
};

const LoginScreen = ({ lang, onSubmit, onLangChange, onBack }) => {
  const [mode,     setMode]     = useS3('login'); // login | signup
  const [email,    setEmail]    = useS3('');
  const [pw,       setPw]       = useS3('');
  const [loading,          setLoading]          = useS3(false);
  const [error,            setError]            = useS3(null);
  const [resetLoading,     setResetLoading]     = useS3(false);
  const [resetSent,        setResetSent]        = useS3(false);
  const [resetError,       setResetError]       = useS3(null);
  const [demoRole,         setDemoRole]         = useS3('player');
  const [demoBranch,       setDemoBranch]       = useS3('football');
  const [showDemo,         setShowDemo]         = useS3(false);
  const [showAdminApp,     setShowAdminApp]     = useS3(false);
  const [signupRole,       setSignupRole]       = useS3(null); // 'player'|'coach'|'parent'
  const [showSignupPicker, setShowSignupPicker] = useS3(false);
  const [signupAcademy,    setSignupAcademy]    = useS3(null); // validated academy from code entry
  // "Remember me" — defaults to true (LOCAL persistence) when no preference is stored,
  // preserving behaviour for existing users who already have a persisted session.
  const [remember, setRemember] = useS3(() => localStorage.getItem('athloryxRememberMe') !== 'false');

  const langKey = nxLangKey(lang);
  const isTr = langKey === 'tr';

  // Academy code entry — intercepts before role-specific signup
  if (signupRole && !signupAcademy) {
    return (
      <AcademyCodeEntryScreen
        lang={lang}
        preselectedRole={signupRole}
        onBack={() => setSignupRole(null)}
        onSelect={(r, acad) => { setSignupAcademy(acad); setSignupRole(r); }}
      />
    );
  }
  const backFromSignup = () => { setSignupRole(null); setSignupAcademy(null); };
  if (signupRole === 'player') return <PlayerRegistrationScreen lang={lang} onBack={backFromSignup} sportType={signupAcademy?.sportType || demoBranch} academyInfo={signupAcademy}/>;
  if (signupRole === 'coach')  return <CoachSignupScreen lang={lang} onBack={backFromSignup} academyInfo={signupAcademy}/>;
  if (signupRole === 'parent') return <ParentSignupScreen lang={lang} onBack={backFromSignup} sportType={signupAcademy?.sportType || demoBranch} academyInfo={signupAcademy}/>;
  if (showAdminApp) return <AdminApplicationScreen lang={lang} onBack={() => setShowAdminApp(false)}/>;

  const handleSignIn = async () => {
    if (!email.trim() || !pw) return;
    setLoading(true);
    setError(null);
    try {
      // Apply persistence before sign-in so the new credential is stored accordingly.
      await window.NX.setAuthPersistence(remember);
      await window.NX.signIn(email.trim(), pw);
      // onAuthStateChanged in App handles routing — nothing more to do here
    } catch (e) {
      setError(fbMsg(e.code, lang));
    } finally {
      setLoading(false);
    }
  };

  const handleDemoEnter = () => {
    if (demoRole === 'parent') {
      onSubmit('parent', window.DEFAULT_CHILD_KEY, demoBranch);
    } else {
      onSubmit(demoRole, null, demoBranch);
    }
  };

  const handleForgotPassword = async () => {
    setResetError(null);
    setResetSent(false);
    if (!email.trim()) {
      setResetError(nxTxt(lang, 'Önce e-posta adresinizi girin.', 'Enter your email address above first.', 'Сначала введите e-mail.'));
      return;
    }
    setResetLoading(true);
    try {
      await window.NX.resetPassword(email.trim());
      setResetSent(true);
    } catch (e) {
      // Don't reveal whether the email is registered — treat user-not-found as success
      if (e.code === 'auth/user-not-found') {
        setResetSent(true);
      } else {
        setResetError(fbMsg(e.code, lang));
      }
    } finally {
      setResetLoading(false);
    }
  };

  return (
    <div className="nx-auth-screen nx-login-screen" style={{ display:'flex', flexDirection:'column', height:'100%', padding:'68px 24px 24px',
      background:'#0B0B0B', overflowY:'auto' }}>

      {/* Top: back + brand + lang switch */}
      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom: 36 }}>
        <div style={{ display:'flex', alignItems:'center', gap: 10 }}>
          <button onClick={onBack} style={{
            width: 32, height: 32, borderRadius: 999, background:'#1C1C1C',
            border:'1px solid rgba(255,255,255,0.06)', color:'#fff', cursor:'pointer',
            display:'flex', alignItems:'center', justifyContent:'center', flexShrink: 0 }}>
            <Ico name="chev" size={16} style={{ transform:'scaleX(-1)' }}/>
          </button>
          <div style={{ display:'flex', alignItems:'center', gap: 8 }}>
            <BrandMark size={30}/>
            <span style={{ fontFamily:'Manrope', fontWeight: 800, fontSize: 11,
              letterSpacing:'0.18em', textTransform:'uppercase', color:'#fff' }}>ATHLORYX</span>
          </div>
        </div>
        <div style={{ display:'flex', gap: 0, background:'#1C1C1C',
          border:'1px solid rgba(255,255,255,0.06)', borderRadius: 999, padding: 2 }}>
          {[['tr','TR'],['en','EN'],['ru','RU']].map(([c,label]) => (
            <button key={c} onClick={() => onLangChange(c)} style={{
              padding:'5px 10px', borderRadius: 999, cursor:'pointer',
              background: lang===c ? '#fff' : 'transparent',
              color: lang===c ? '#0B0B0B' : '#7A7A7A',
              border:'none', fontFamily:'Manrope', fontWeight: 800, fontSize: 10,
              letterSpacing:'0.14em', textTransform:'uppercase',
            }}>{label}</button>
          ))}
        </div>
      </div>

      {/* Title */}
      <h1 style={{ fontFamily:'Oswald', fontWeight: 700, fontSize: 38, lineHeight: 1.0,
        textTransform:'uppercase', letterSpacing:'0.02em', color:'#fff', margin:'0 0 8px' }}>
        {nxTxt(lang, 'Giriş yap', 'Sign in', 'Войти')}
        <span style={{ color:'#00FF88' }}>.</span>
      </h1>
      <div style={{ fontFamily:'Manrope', fontSize: 14, color:'#B8B8B8', marginBottom: 28 }}>
        {nxTxt(lang, 'Antrenmana kaldığın yerden devam et.', 'Pick up where you left off.', 'Продолжите с того места, где остановились.')}
      </div>

      {/* Fields */}
      <div style={{ display:'flex', flexDirection:'column', gap: 10 }}>
        <FieldInput placeholder={nxTxt(lang, 'E-posta', 'Email', 'E-mail')} value={email} onChange={v => { setEmail(v); setError(null); }} type="email"/>
        <FieldInput placeholder={nxTxt(lang, 'Parola', 'Password', 'Пароль')} value={pw} onChange={v => { setPw(v); setError(null); }} type="password"/>
        <div style={{ display:'flex', justifyContent:'flex-end' }}>
          <button onClick={handleForgotPassword} disabled={resetLoading} style={{
            background:'none', border:'none', padding: 0, cursor:'pointer',
            fontFamily:'Manrope', fontWeight:600, fontSize: 11, color: resetLoading ? '#4A4A4A' : '#7A7A7A',
            letterSpacing:'0.10em', textTransform:'uppercase',
          }}>
            {resetLoading
              ? nxTxt(lang, 'Gönderiliyor…', 'Sending…', 'Отправка…')
              : nxTxt(lang, 'Parolamı unuttum', 'Forgot password', 'Забыли пароль?')}
          </button>
        </div>
      </div>

      {/* Remember me */}
      <div style={{ display:'flex', alignItems:'center', gap: 10, marginTop: 14 }}>
        <button
          role="checkbox"
          aria-checked={remember}
          onClick={() => setRemember(v => !v)}
          style={{
            width: 20, height: 20, borderRadius: 5, flexShrink: 0, cursor:'pointer',
            background: remember ? '#00FF88' : 'transparent',
            border: `1.5px solid ${remember ? '#00FF88' : 'rgba(255,255,255,0.18)'}`,
            display:'flex', alignItems:'center', justifyContent:'center',
            padding: 0, outline:'none', WebkitTapHighlightColor:'transparent',
            transition:'background 0.15s, border-color 0.15s',
          }}
        >
          {remember && (
            <svg width="12" height="12" viewBox="0 0 12 12" fill="none" aria-hidden="true">
              <path d="M2 6l3 3 5-5" stroke="#050505" strokeWidth="1.8"
                strokeLinecap="round" strokeLinejoin="round"/>
            </svg>
          )}
        </button>
        <div style={{ cursor:'pointer' }} onClick={() => setRemember(v => !v)}>
          <div style={{ fontFamily:'Manrope', fontWeight:600, fontSize: 12, color:'#B8B8B8' }}>
            {nxTxt(lang, 'Beni hatırla', 'Remember me', 'Запомнить меня')}
          </div>
          <div style={{ fontFamily:'Manrope', fontSize: 10, color:'#5A5A5A', marginTop: 1 }}>
            {nxTxt(lang, 'Bu cihazda oturumunu açık tutar.', 'Keeps you signed in on this device.', 'Сохраняет вход на этом устройстве.')}
          </div>
        </div>
      </div>

      {/* Reset password feedback */}
      {resetSent && (
        <div style={{ marginTop: 12, padding:'10px 14px', borderRadius: 10,
          background:'rgba(0,255,136,0.06)', border:'1px solid rgba(0,255,136,0.25)' }}>
          <span style={{ fontFamily:'Manrope', fontSize: 12, color:'#00FF88' }}>
            {nxTxt(lang, 'Sıfırlama bağlantısı gönderildi. E-postanızı kontrol edin.', 'Reset link sent. Check your email.', 'Ссылка для сброса отправлена. Проверьте почту.')}
          </span>
        </div>
      )}
      {resetError && (
        <div style={{ marginTop: 12, padding:'10px 14px', borderRadius: 10,
          background:'rgba(255,80,80,0.08)', border:'1px solid rgba(255,80,80,0.30)' }}>
          <span style={{ fontFamily:'Manrope', fontSize: 12, color:'#FF6B6B' }}>{resetError}</span>
        </div>
      )}

      {/* Sign-in error message */}
      {error && (
        <div style={{ marginTop: 12, padding:'10px 14px', borderRadius: 10,
          background:'rgba(255,80,80,0.08)', border:'1px solid rgba(255,80,80,0.30)' }}>
          <span style={{ fontFamily:'Manrope', fontSize: 12, color:'#FF6B6B' }}>{error}</span>
        </div>
      )}

      {/* Sign in button */}
      <div style={{ marginTop: 20 }}>
        <Button kind="primary" full size="lg" icon={loading ? null : 'arrow'}
          onClick={handleSignIn} disabled={loading || !email.trim() || !pw}>
          {loading ? nxTxt(lang, 'Giriş yapılıyor…', 'Signing in…', 'Вход…') : nxTxt(lang, 'Giriş yap', 'Sign in', 'Войти')}
        </Button>
      </div>

      {/* Sign up section */}
      <div style={{ marginTop: 12 }}>
        <div style={{ textAlign:'center', fontFamily:'Manrope', fontSize: 12, color:'#B8B8B8', marginBottom: showSignupPicker ? 10 : 0 }}>
          {nxTxt(lang, 'Hesabın yok mu? ', "Don't have an account? ", 'Нет аккаунта? ')}
          <span onClick={() => setShowSignupPicker(v => !v)}
            style={{ color:'#00FF88', fontWeight: 700, cursor:'pointer' }}>
            {nxTxt(lang, `Kayıt ol ${showSignupPicker?'↑':'↓'}`, `Sign up ${showSignupPicker?'↑':'↓'}`, `Зарегистрироваться ${showSignupPicker?'↑':'↓'}`)}
          </span>
        </div>
        {showSignupPicker && (
          <div style={{ display:'flex', flexDirection:'column', gap: 6 }}>
            {[
              { role:'coach',  label: lang==='ru'?'Тренер':isTr?'Koç':'Coach',       color:'#FFB800', hint: lang==='ru'?'Требует одобрения':isTr?'Onay bekler':'Requires approval' },
              { role:'player', label: lang==='ru'?'Спортсмен':isTr?'Sporcu':'Athlete', color:'#00FF88', hint: lang==='ru'?'Требует одобрения':isTr?'Onay bekler':'Requires approval' },
              { role:'parent', label: lang==='ru'?'Родитель':isTr?'Veli':'Parent',    color:'#4F8DFF', hint: lang==='ru'?'Требует одобрения':isTr?'Onay bekler':'Requires approval' },
            ].map(({ role, label, color, hint }) => (
              <button key={role} onClick={() => setSignupRole(role)} style={{
                padding:'11px 14px', borderRadius: 10, cursor:'pointer',
                background:'#141414', border:`1px solid rgba(255,255,255,0.06)`,
                display:'flex', alignItems:'center', justifyContent:'space-between',
              }}>
                <span style={{ fontFamily:'Manrope', fontWeight: 700, fontSize: 13, color }}>
                  {label}
                </span>
                <span style={{ fontFamily:'Manrope', fontSize: 11, color:'#5A5A5A' }}>{hint} →</span>
              </button>
            ))}
          </div>
        )}
      </div>

      {/* Divider */}
      <div style={{ display:'flex', alignItems:'center', gap: 12, margin:'20px 0 0' }}>
        <div style={{ flex:1, height: 1, background:'rgba(255,255,255,0.06)' }}/>
        <span style={{ fontFamily:'Manrope', fontWeight:700, fontSize: 9,
          letterSpacing:'0.18em', textTransform:'uppercase', color:'#4A4A4A' }}>
          {nxTxt(lang, 'veya', 'or', 'или')}
        </span>
        <div style={{ flex:1, height: 1, background:'rgba(255,255,255,0.06)' }}/>
      </div>

      {/* Demo mode toggle */}
      <div style={{ marginTop: 14 }}>
        <button onClick={() => setShowDemo(v => !v)} style={{
          width:'100%', padding:'10px 14px', borderRadius: 10, cursor:'pointer',
          background: showDemo ? 'rgba(255,184,0,0.06)' : '#141414',
          border:`1px solid ${showDemo ? 'rgba(255,184,0,0.30)' : 'rgba(255,255,255,0.06)'}`,
          display:'flex', alignItems:'center', justifyContent:'space-between',
        }}>
          <span style={{ fontFamily:'JetBrains Mono', fontSize: 9, color:'#FFB800',
            letterSpacing:'0.14em', textTransform:'uppercase' }}>
            {nxTxt(lang, '⚡ Demo Modu — hesap oluşturmadan dene', '⚡ Demo Mode — try without an account', '⚡ Демо-режим — попробуйте без аккаунта')}
          </span>
          <span style={{ fontFamily:'JetBrains Mono', fontSize: 9, color:'#FFB800' }}>
            {showDemo ? '▲' : '▼'}
          </span>
        </button>

        {showDemo && (
          <div style={{ marginTop: 8, padding: 14, borderRadius: 10,
            background:'rgba(255,184,0,0.04)', border:'1px solid rgba(255,184,0,0.20)' }}>
            <div style={{ fontFamily:'JetBrains Mono', fontSize: 8, color:'#7A7A7A',
              letterSpacing:'0.12em', textTransform:'uppercase', marginBottom: 10 }}>
              {nxTxt(lang, 'Rol seç · Firebase hesabı oluşturulmaz', 'Select role · No Firebase account created', 'Выберите роль · аккаунт Firebase не создаётся')}
            </div>
            <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr 1fr', gap: 6, marginBottom: 10 }}>
              {DEMO_ROLES.map(r => (
                <button key={r.key} onClick={() => setDemoRole(r.key)} style={{
                  padding:'8px 4px', borderRadius: 8, cursor:'pointer',
                  background: demoRole===r.key ? `${r.color}12` : '#141414',
                  border:`1px solid ${demoRole===r.key ? r.color+'60' : 'rgba(255,255,255,0.06)'}`,
                  color: demoRole===r.key ? r.color : '#7A7A7A',
                  fontFamily:'Manrope', fontWeight: 700, fontSize: 10,
                  letterSpacing:'0.08em', textTransform:'uppercase', textAlign:'center',
                }}>{lang === 'ru' ? r.ru : isTr ? r.tr : r.en}</button>
              ))}
            </div>
            <div style={{ marginBottom: 10 }}>
              <div style={{ fontFamily:'JetBrains Mono', fontSize:8, color:'#7A7A7A',
                letterSpacing:'0.12em', textTransform:'uppercase', marginBottom:6 }}>
                {nxTxt(lang, 'Demo branşı seç', 'Select demo sport', 'Выберите вид спорта для демо')}
              </div>
              <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:6 }}>
                {[['football',nxTxt(lang, 'Futbol', 'Football', 'Футбол')],['swimming',nxTxt(lang, 'Yüzme', 'Swimming', 'Плавание')]].map(([b,n]) => (
                  <button key={b} onClick={() => setDemoBranch(b)} style={{
                    padding:'7px 4px', borderRadius:8, cursor:'pointer',
                    background: demoBranch===b ? (b==='swimming'?'rgba(56,232,255,0.10)':'rgba(0,255,136,0.10)') : '#141414',
                    border:`1px solid ${demoBranch===b ? (b==='swimming'?'rgba(56,232,255,0.40)':'rgba(0,255,136,0.40)') : 'rgba(255,255,255,0.06)'}`,
                    color: demoBranch===b ? (b==='swimming'?'#38E8FF':'#00FF88') : '#7A7A7A',
                    fontFamily:'Manrope', fontWeight:700, fontSize:10,
                    letterSpacing:'0.08em', textTransform:'uppercase', textAlign:'center',
                  }}>{n}</button>
                ))}
              </div>
            </div>
            <Button kind="secondary" full size="md" onClick={handleDemoEnter}>
              {lang === 'ru'
                ? `Демо (${DEMO_ROLES.find(r=>r.key===demoRole)?.ru})`
                : isTr
                ? `Demo olarak gir (${DEMO_ROLES.find(r=>r.key===demoRole)?.tr})`
                : `Enter as demo (${DEMO_ROLES.find(r=>r.key===demoRole)?.en})`}
            </Button>
          </div>
        )}
      </div>

      {/* Admin access link */}
      <div style={{ marginTop: 18, textAlign:'center' }}>
        <span style={{ fontFamily:'Manrope', fontSize: 11, color:'#5A5A5A' }}>
          {nxTxt(lang, 'Akademi yöneticisi misin? ', 'Are you an academy admin? ', 'Вы администратор академии? ')}
        </span>
        <span onClick={() => setShowAdminApp(true)}
          style={{ fontFamily:'Manrope', fontWeight: 700, fontSize: 11,
            color:'#B26BFF', cursor:'pointer', letterSpacing:'0.02em' }}>
          {nxTxt(lang, 'Yönetici erişimi iste →', 'Request admin access →', 'Запросить доступ администратора →')}
        </span>
      </div>

      <div style={{ minHeight: 20 }}/>
    </div>
  );
};

const FieldInput = ({ placeholder, value, onChange, type = 'text' }) => (
  <input type={type} placeholder={placeholder} value={value}
    onChange={e => onChange(e.target.value)}
    style={{
      width:'100%', boxSizing:'border-box',
      background:'#141414', border:'1px solid rgba(255,255,255,0.06)',
      borderRadius: 12, padding:'16px 16px', minHeight: 54,
      fontFamily:'Manrope', fontWeight: 500, fontSize: 16, color:'#fff', outline:'none',
    }}/>
);

const SocialBtn = ({ label, icon }) => (
  <button style={{
    width:'100%', background:'#141414', border:'1px solid rgba(255,255,255,0.06)',
    borderRadius: 12, padding:'13px 16px', cursor:'pointer',
    color:'#fff', fontFamily:'Manrope', fontWeight: 600, fontSize: 13,
    display:'flex', alignItems:'center', justifyContent:'center', gap: 10,
  }}>
    <SocialIcon name={icon}/>
    {label}
  </button>
);
const SocialIcon = ({ name }) => name === 'apple' ? (
  <svg width="14" height="14" viewBox="0 0 24 24" fill="#fff"><path d="M16.4 12.6c0-2.7 2.2-4 2.3-4-1.3-1.8-3.2-2.1-3.9-2.1-1.6-.2-3.2.9-4.1.9-.8 0-2.2-.9-3.5-.9C5 6.6 3 8 3 11.4c0 1 .2 2 .5 3.1.5 1.4 2.3 4.9 4.2 4.9.9 0 1.5-.6 2.7-.6 1.1 0 1.7.6 2.7.6 1.9 0 3.5-3.2 4-4.6-2.4-1.1-2.7-3.2-2.7-3.2zm-3-7.6c.7-.9 1.2-2.1 1-3.3-1 .1-2.3.7-3 1.6-.7.8-1.3 2-1.1 3.2 1.2.1 2.4-.6 3.1-1.5z"/></svg>
) : (
  <svg width="14" height="14" viewBox="0 0 24 24"><path fill="#fff" d="M22 12.2c0-.8-.1-1.4-.2-2.1H12v3.9h5.6c-.2 1.3-1 2.4-2 3.1v2.6h3.3C20.8 18 22 15.4 22 12.2zM12 22c2.7 0 5-.9 6.7-2.4l-3.3-2.6c-.9.6-2 1-3.4 1-2.6 0-4.8-1.7-5.6-4.1H3.1v2.7C4.7 19.9 8.1 22 12 22zM6.4 13.9c-.2-.6-.3-1.3-.3-2s.1-1.3.3-2V7.3H3.1C2.4 8.7 2 10.3 2 12s.4 3.3 1.1 4.7l3.3-2.6v-.2zM12 5.9c1.4 0 2.7.5 3.7 1.5l2.8-2.8C16.9 3 14.7 2 12 2 8.1 2 4.7 4.1 3.1 7.3l3.3 2.6c.8-2.4 3-4 5.6-4z"/></svg>
);

// ────────────────────────────────────────────────────────────
// ROLE SELECT
// ────────────────────────────────────────────────────────────
const ROLE_DESC = {
  tr: {
    player: 'Antrenmanlarını takip et, XP kazan, seviyeni yükselt.',
    coach:  'Sporcuları değerlendir, yoklama al, geri bildirim ver.',
    parent: 'Çocuğunun gelişimini ve antrenman durumunu takip et.',
  },
  en: {
    player: 'Track training, earn XP, level up your game.',
    coach:  'Rate players, take attendance, give feedback.',
    parent: "Follow your child's development and training.",
  },
  ru: {
    player: 'Следи за тренировками, зарабатывай XP, повышай уровень.',
    coach:  'Оценивай спортсменов, отмечай посещаемость, давай обратную связь.',
    parent: 'Следи за развитием ребёнка и его тренировками.',
  },
};
const ROLE_LABEL = {
  tr: { player:'Sporcu', coach:'Koç', parent:'Veli' },
  en: { player:'Athlete', coach:'Coach', parent:'Parent' },
  ru: { player:'Спортсмен', coach:'Тренер', parent:'Родитель' },
};

const POSITION_OPTIONS = [
  { code:'GK',  tr:'Kaleci',             en:'Goalkeeper',            ru:'Вратарь' },
  { code:'CB',  tr:'Stoper',             en:'Centre Back',           ru:'Центральный защитник' },
  { code:'RB',  tr:'Sağ bek',            en:'Right Back',            ru:'Правый защитник' },
  { code:'LB',  tr:'Sol bek',            en:'Left Back',             ru:'Левый защитник' },
  { code:'CM',  tr:'Orta saha',          en:'Midfielder',            ru:'Полузащитник' },
  { code:'CAM', tr:'Ofansif orta saha',  en:'Attacking Midfielder',  ru:'Атакующий полузащитник' },
  { code:'ST',  tr:'Forvet',             en:'Striker',               ru:'Нападающий' },
  { code:'LW',  tr:'Sol kanat',          en:'Left Wing',             ru:'Левый вингер' },
  { code:'RW',  tr:'Sağ kanat',          en:'Right Wing',            ru:'Правый вингер' },
];

const SWIM_STYLE_OPTIONS = [
  { code:'serbest',    tr:'Serbest',           en:'Freestyle',    ru:'Вольный стиль' },
  { code:'sirtüstü',   tr:'Sırtüstü',          en:'Backstroke',   ru:'На спине' },
  { code:'kurbağalama',tr:'Kurbağalama',        en:'Breaststroke', ru:'Брасс' },
  { code:'kelebek',    tr:'Kelebek',            en:'Butterfly',    ru:'Баттерфляй' },
  { code:'karışık',    tr:'Karışık',            en:'Medley',       ru:'Комплексное плавание' },
  { code:'belirsiz',   tr:'Henüz belli değil',  en:'Not yet set',  ru:'Пока не определено' },
];

const positionLabel = (code, lang) => {
  const p = POSITION_OPTIONS.find(x => x.code === code);
  if (!p) return '';
  return lang === 'ru' ? p.ru : lang === 'tr' ? p.tr : p.en;
};

const swimStyleLabel = (code, lang) => {
  const s = SWIM_STYLE_OPTIONS.find(x => x.code === code);
  if (!s) return code || '';
  return lang === 'ru' ? s.ru : lang === 'tr' ? s.tr : s.en;
};

const calculateAgeFromDOB = (dateOfBirth) => {
  if (!dateOfBirth) return null;
  const dob = new Date(`${dateOfBirth}T00:00:00`);
  if (Number.isNaN(dob.getTime())) return null;
  const today = new Date();
  let age = today.getFullYear() - dob.getFullYear();
  const monthDelta = today.getMonth() - dob.getMonth();
  if (monthDelta < 0 || (monthDelta === 0 && today.getDate() < dob.getDate())) age -= 1;
  return age >= 0 ? age : null;
};

const formatDOBDisplay = (dateOfBirth) => {
  if (!dateOfBirth) return '';
  const [yyyy, mm, dd] = dateOfBirth.split('-');
  if (!yyyy || !mm || !dd) return '';
  return `${dd}.${mm}.${yyyy}`;
};

const parseDOBText = (text) => {
  const cleaned = text.trim();
  const match = cleaned.match(/^(\d{2})\.(\d{2})\.(\d{4})$/);
  if (!match) return { iso:null, complete: cleaned.length >= 10 };
  const [, dd, mm, yyyy] = match;
  const iso = `${yyyy}-${mm}-${dd}`;
  const d = new Date(`${iso}T00:00:00`);
  const valid = !Number.isNaN(d.getTime()) &&
    d.getFullYear() === Number(yyyy) &&
    d.getMonth() + 1 === Number(mm) &&
    d.getDate() === Number(dd);
  return { iso: valid ? iso : null, complete:true };
};

const todayISO = () => new Date().toISOString().slice(0, 10);

const DateOfBirthField = ({ lang, value, onChange, optional = false, onValidityChange }) => {
  const [focused, setFocused] = useS3(false);
  const [text, setText] = useS3(formatDOBDisplay(value));
  const [localError, setLocalError] = useS3(null);
  const nativeRef = React.useRef(null);
  const langKey = nxLangKey(lang);
  const isTr = langKey === 'tr';
  const isRu = langKey === 'ru';
  const placeholder = isTr ? 'GG.AA.YYYY' : 'DD.MM.YYYY';
  const label = optional
    ? (isRu ? 'Дата рождения (необязательно)' : isTr ? 'Doğum tarihi (opsiyonel)' : 'Date of birth (optional)')
    : (isRu ? 'Дата рождения' : isTr ? 'Doğum tarihi' : 'Date of birth');
  const invalidMsg = isRu ? 'Введите дату в формате ДД.ММ.ГГГГ' : isTr ? 'Geçerli bir tarih gir: GG.AA.YYYY' : 'Enter a valid date: DD.MM.YYYY';

  useE3(() => {
    if (!focused) {
      if (value) setText(formatDOBDisplay(value));
      else if (!localError) setText('');
    }
  }, [value, lang, focused, localError]);

  const openPicker = () => {
    const input = nativeRef.current;
    if (!input) return;
    try {
      if (input.showPicker) input.showPicker();
      else input.click();
    } catch {
      input.click();
    }
  };

  const commitText = (nextText) => {
    const { iso, complete } = parseDOBText(nextText);
    if (!nextText.trim()) {
      setLocalError(null);
      onValidityChange && onValidityChange(true);
      onChange('');
      return;
    }
    if (iso) {
      if (calculateAgeFromDOB(iso) == null) {
        setLocalError(invalidMsg);
        onValidityChange && onValidityChange(false);
        onChange('');
      } else {
        setLocalError(null);
        onValidityChange && onValidityChange(true);
        onChange(iso);
      }
      return;
    }
    if (complete) {
      setLocalError(invalidMsg);
      onValidityChange && onValidityChange(false);
      onChange('');
    } else {
      setLocalError(null);
      onValidityChange && onValidityChange(true);
    }
  };

  const handleTextChange = (raw) => {
    const digits = raw.replace(/\D/g, '').slice(0, 8);
    const nextText = digits.length <= 2
      ? digits
      : digits.length <= 4
      ? `${digits.slice(0,2)}.${digits.slice(2)}`
      : `${digits.slice(0,2)}.${digits.slice(2,4)}.${digits.slice(4)}`;
    setText(nextText);
    commitText(nextText);
  };

  return (
    <label style={{ display:'block' }}>
      <div style={{ fontFamily:'JetBrains Mono', fontSize:9, color:'#7A7A7A',
        letterSpacing:'0.14em', textTransform:'uppercase', marginBottom:6 }}>
        {label}
      </div>
      <div onClick={openPicker} style={{ position:'relative', width:'100%', boxSizing:'border-box',
        background:'#141414',
        border:`1px solid ${localError ? 'rgba(255,107,107,0.45)' : focused ? 'rgba(0,255,136,0.55)' : 'rgba(255,255,255,0.06)'}`,
        borderRadius:12, padding:'0 14px', minHeight:50,
        display:'flex', alignItems:'center', justifyContent:'space-between',
        boxShadow: focused ? '0 0 0 1px rgba(0,255,136,0.18)' : 'none' }}>
        <input
          type="text"
          inputMode="numeric"
          value={text}
          onChange={e => handleTextChange(e.target.value)}
          onFocus={() => { setFocused(true); setTimeout(openPicker, 0); }}
          onBlur={() => { setFocused(false); commitText(text); }}
          onClick={e => { e.stopPropagation(); openPicker(); }}
          onKeyDown={e => {
            if (e.key === 'ArrowDown') openPicker();
          }}
          placeholder={placeholder}
          aria-label={label}
          style={{
            flex:1, minWidth:0, height:48, background:'transparent', border:'none',
            outline:'none', color:'#fff', fontFamily:'Manrope', fontWeight:700,
            fontSize:16, letterSpacing:'0.08em',
          }}
        />
        <button type="button" onClick={e => { e.preventDefault(); e.stopPropagation(); openPicker(); }}
          style={{ background:'transparent', border:'none', padding:'8px 0 8px 10px',
            cursor:'pointer', fontFamily:'JetBrains Mono', fontWeight:800, fontSize:10,
            color:focused ? '#00FF88' : '#7A7A7A', letterSpacing:'0.10em' }}>
          {isRu ? 'ВЫБРАТЬ' : isTr ? 'SEÇ' : 'PICK'}
        </button>
        <input
          ref={nativeRef}
          type="date"
          value={value || ''}
          max={todayISO()}
          onChange={e => {
            const next = e.target.value;
            if (next && calculateAgeFromDOB(next) == null) {
              setText(formatDOBDisplay(next));
              setLocalError(invalidMsg);
              onValidityChange && onValidityChange(false);
              onChange('');
              return;
            }
            setLocalError(null);
            onValidityChange && onValidityChange(true);
            onChange(next);
          }}
          tabIndex={-1}
          aria-hidden="true"
          style={{
            position:'absolute', width:1, height:1, right:12, bottom:8,
            opacity:0, pointerEvents:'none', colorScheme:'dark',
          }}
        />
      </div>
      {localError && (
        <div style={{ marginTop:6, fontFamily:'Manrope', fontSize:11, color:'#FF6B6B', lineHeight:1.4 }}>
          {localError}
        </div>
      )}
    </label>
  );
};

const RoleSelectScreen = ({ lang, onPick, onBack }) => {
  const [picked, setPicked] = useS3(null);
  const langKey = nxLangKey(lang);
  const isTr = langKey === 'tr';
  const isRu = langKey === 'ru';

  const handleContinue = () => {
    if (!picked) return;
    onPick(picked, null);
  };

  return (
    <div style={{ display:'flex', flexDirection:'column', height:'100%', padding: 24,
      background:'#0B0B0B', overflowY:'auto' }}>

      {/* Back button */}
      {onBack && (
        <div style={{ marginBottom: 8 }}>
          <button onClick={onBack} style={{
            width: 32, height: 32, borderRadius: 999, background:'#1C1C1C',
            border:'1px solid rgba(255,255,255,0.06)', color:'#fff', cursor:'pointer',
            display:'flex', alignItems:'center', justifyContent:'center', flexShrink: 0 }}>
            <Ico name="chev" size={16} style={{ transform:'scaleX(-1)' }}/>
          </button>
        </div>
      )}

      <div style={{ paddingTop: 4, marginBottom: 20 }}>
        <Label>{isRu ? 'Шаг 2 / 2' : isTr ? 'Adım 2 / 2' : 'Step 2 / 2'}</Label>
        <h1 style={{ fontFamily:'Oswald', fontWeight: 700, fontSize: 30, lineHeight: 1.0,
          textTransform:'uppercase', letterSpacing:'0.02em', color:'#fff', margin:'6px 0 6px' }}>
          {isRu ? 'Тип аккаунта' : isTr ? 'Hesap türü' : 'Account type'}<span style={{ color:'#00FF88' }}>.</span>
        </h1>
        <div style={{ fontFamily:'Manrope', fontSize: 13, color:'#B8B8B8', lineHeight: 1.5 }}>
          {isRu ? 'Администрация академии назначает роль каждому аккаунту. Роли нельзя изменить позже.'
                : isTr ? 'Akademi yönetimi her hesaba bir rol atar. Roller sonradan değiştirilemez.'
                : 'The academy assigns a role to every account. Roles cannot be changed later.'}
        </div>
      </div>

      <div style={{ display:'flex', flexDirection:'column', gap: 10 }}>
        <RoleCard role="coach" picked={picked==='coach'} onPick={() => setPicked('coach')}
          accent="#FFB800" title={ROLE_LABEL[lang].coach} desc={ROLE_DESC[lang].coach}
          icon="lightning" tag={isRu?'Требует одобрения':isTr?'Onay bekler':'Requires approval'}/>
        <RoleCard role="player" picked={picked==='player'} onPick={() => setPicked('player')}
          accent="#00FF88" title={ROLE_LABEL[lang].player} desc={ROLE_DESC[lang].player}
          icon="trophy" tag={isRu?'Требует одобрения':isTr?'Onay bekler':'Requires approval'}/>
        <RoleCard role="parent" picked={picked==='parent'} onPick={() => setPicked('parent')}
          accent="#4F8DFF" title={ROLE_LABEL[lang].parent} desc={ROLE_DESC[lang].parent}
          icon="chart" tag={isRu?'Требует одобрения':isTr?'Onay bekler':'Requires approval'}/>
      </div>

      <div style={{ marginTop: 18, marginBottom: 4 }}>
        <Button kind={picked?'primary':'secondary'} full size="lg" icon="arrow"
          onClick={handleContinue}>
          {isRu ? 'Продолжить' : isTr ? 'Devam et' : 'Continue'}
        </Button>
      </div>

      <div style={{ marginTop: 12, fontFamily:'Manrope', fontSize: 11, color:'#5A5A5A',
        textAlign:'center', lineHeight: 1.5 }}>
        {isRu ? 'Нужен аккаунт тренера? Обратитесь к администрации академии.'
              : isTr ? 'Koç hesabı mı gerekiyor? Akademi yönetimine başvur.'
              : 'Need a coach account? Contact academy management.'}
      </div>
    </div>
  );
};

const RoleCard = ({ role, picked, onPick, title, desc, accent, icon, tag, locked }) => (
  <button onClick={onPick} style={{
    background: picked ? 'rgba(255,255,255,0.02)' : '#141414',
    border: `1px solid ${picked ? accent + 'AA' : 'rgba(255,255,255,0.06)'}`,
    borderRadius: 16, padding: 16, cursor:'pointer', textAlign:'left',
    display:'flex', alignItems:'flex-start', gap: 14, position:'relative',
    transition:'all 180ms cubic-bezier(0.22,1,0.36,1)',
    boxShadow: picked ? `0 0 0 1px ${accent}40, 0 12px 32px -16px ${accent}40` : 'none',
  }}>
    <div style={{ width: 44, height: 44, borderRadius: 12, flexShrink: 0,
      background: `${accent}14`, color: accent,
      border: `1px solid ${accent}40`,
      display:'flex', alignItems:'center', justifyContent:'center' }}>
      <Ico name={icon} size={22}/>
    </div>
    <div style={{ flex: 1, minWidth: 0 }}>
      <div style={{ display:'flex', alignItems:'center', gap: 8, marginBottom: 4 }}>
        <span style={{ fontFamily:'Oswald', fontWeight: 700, fontSize: 22,
          textTransform:'uppercase', letterSpacing:'0.02em', color:'#fff' }}>{title}</span>
        {picked && (
          <span style={{ width: 18, height: 18, borderRadius: 999, background: accent,
            color:'#0B0B0B', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}>
            <Ico name="check" size={11}/>
          </span>
        )}
      </div>
      <div style={{ fontFamily:'Manrope', fontSize: 12.5, color:'#B8B8B8', lineHeight: 1.45 }}>{desc}</div>
      <div style={{ display:'flex', alignItems:'center', gap: 6, marginTop: 8 }}>
        {locked && <Ico name="lock" size={10}/>}
        <div style={{ fontFamily:'JetBrains Mono', fontSize: 9, color: accent,
          letterSpacing:'0.10em', textTransform:'uppercase' }}>→ {tag}</div>
      </div>
    </div>
  </button>
);

// ────────────────────────────────────────────────────────────
// COACH FEEDBACK SUB-COMPONENTS
// ────────────────────────────────────────────────────────────
const RatingBar = ({ label, value, onChange, lang }) => {
  const isSwimming = window.NXT_THEME?.sportType === 'swimming';
  const langKey = nxLangKey(lang);
  const isTr = langKey === 'tr';
  const isRu = langKey === 'ru';
  const labelText = label === 'technique'
    ? (isRu ? 'Техника' : isTr ? 'Teknik' : 'Technique')
    : label === 'intensity'
    ? (isRu ? 'Интенсивность' : isTr ? 'Yoğunluk' : 'Intensity')
    : (isRu ? 'Отношение' : isTr ? 'Tutum' : 'Attitude');
  const color = value >= 4 ? 'var(--nx-accent)' : value >= 3 ? (isSwimming ? '#B8B8B8' : '#FFB800') : '#FF6B6B';
  return (
    <div>
      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'baseline', marginBottom: 8 }}>
        <span style={{ fontFamily:'Manrope', fontWeight:700, fontSize:11,
          letterSpacing:'0.12em', textTransform:'uppercase', color:'#7A7A7A' }}>{labelText}</span>
        <span style={{ fontFamily:'Oswald', fontWeight:700, fontSize:20, color }}>{value}</span>
      </div>
      <div style={{ display:'flex', gap: 6 }}>
        {[1,2,3,4,5].map(n => (
          <button key={n} onClick={() => onChange(n)} style={{
            flex:1, height:36, borderRadius:10, cursor:'pointer',
            background: n <= value ? `${color}20` : '#1C1C1C',
            border:`1px solid ${n <= value ? color+'60' : 'rgba(255,255,255,0.06)'}`,
            color: n <= value ? color : '#4A4A4A',
            fontFamily:'Oswald', fontWeight:700, fontSize:16,
            display:'flex', alignItems:'center', justifyContent:'center',
          }}>{n}</button>
        ))}
      </div>
    </div>
  );
};

const FEEDBACK_CHIPS = [
  { key:'hard_work',    tr:'Çok çalıştı',         en:'Worked hard',           ru:'Хорошо старался' },
  { key:'great_focus',  tr:'Odaklanma çok iyi',    en:'Great focus',           ru:'Отличная концентрация' },
  { key:'confidence',   tr:'Özgüven geliştirmeli', en:'Needs confidence',      ru:'Нужно больше уверенности' },
  { key:'passing',      tr:'Pas oyunu gelişti',    en:'Passing improved',      ru:'Улучшились передачи', swimRu:'Улучшилась техника дыхания', swimTr:'Nefes ritmi gelişti', swimEn:'Breath rhythm improved' },
  { key:'finishing',    tr:'Bitiricilik gelişti',  en:'Finishing improved',    ru:'Улучшилось завершение', swimRu:'Улучшился стиль', swimTr:'Teknik gelişti', swimEn:'Technique improved' },
  { key:'discipline',   tr:'Disiplin gerekli',     en:'Needs more discipline', ru:'Нужно больше дисциплины' },
  { key:'leadership',   tr:'Liderlik gösteriyor',  en:'Showing leadership',    ru:'Проявляет лидерство', swimRu:'Хороший темп', swimTr:'Tempo iyi', swimEn:'Good tempo' },
  { key:'positioning',  tr:'Pozisyon iyi',         en:'Good positioning',      ru:'Хорошее позиционирование', swimRu:'Лучше держит линию', swimTr:'Çizgiyi daha iyi koruyor', swimEn:'Holds the line better' },
];

const feedbackChipLabel = (chip, lang, isSwimming) => {
  const langKey = nxLangKey(lang);
  if (isSwimming) {
    if (langKey === 'ru') return chip.swimRu || chip.ru || chip.tr || chip.en || '';
    if (langKey === 'tr') return chip.swimTr || chip.tr || chip.en || chip.ru || '';
    return chip.swimEn || chip.en || chip.tr || chip.ru || '';
  }
  if (langKey === 'ru') return chip.ru || chip.tr || chip.en || '';
  if (langKey === 'tr') return chip.tr || chip.en || chip.ru || '';
  return chip.en || chip.tr || chip.ru || '';
};

const PlayerFeedbackForm = ({ player, lang, isTr, onSave, onBack, existing }) => {
  const th = window.NXT_THEME || (window.getSportTheme ? window.getSportTheme('football') : {});
  const isSwimming = th.sportType === 'swimming';
  const langKey = nxLangKey(lang);
  const isRu = langKey === 'ru';
  const [tech,      setTech]      = useS3(existing?.ratings?.technique || 3);
  const [intens,    setIntens]    = useS3(existing?.ratings?.intensity || 3);
  const [att,       setAtt]       = useS3(existing?.ratings?.attitude  || 3);
  const [notes,     setNotes]     = useS3(existing?.notes || '');
  const [chips,     setChips]     = useS3(existing?.chips || []);

  const toggleChip = (key) =>
    setChips(prev => prev.includes(key) ? prev.filter(k => k !== key) : [...prev, key]);

  const save = () => onSave({
    playerId:   player.id,
    playerName: player.name,
    pos:        player.pos,
    ratings:    { technique: tech, intensity: intens, attitude: att },
    chips,
    notes:      notes.trim(),
    timestamp:  new Date().toISOString(),
  });

  return (
    <div style={{ padding:'0 20px', display:'flex', flexDirection:'column', gap: 16 }}>
      <div style={{ display:'flex', alignItems:'center', gap: 12 }}>
        <button onClick={onBack} style={{
          width:32, height:32, borderRadius:999, cursor:'pointer',
          background:'#1C1C1C', border:'1px solid rgba(255,255,255,0.06)',
          color:'#fff', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}>
          <Ico name="chev" size={16} style={{ transform:'scaleX(-1)' }}/>
        </button>
        <Avatar initials={player.name.split(' ').map(s=>s[0]).join('')} size={38}/>
        <div style={{ flex:1 }}>
          <div style={{ fontFamily:'Manrope', fontWeight:700, fontSize:14, color:'#fff' }}>{player.name}</div>
          <div style={{ fontFamily:'JetBrains Mono', fontSize:10, color:'#7A7A7A' }}>{player.pos} · {player.age}</div>
        </div>
      </div>

      <Card style={{ padding:14, display:'flex', flexDirection:'column', gap:14 }}>
        <RatingBar label="technique" value={tech}   onChange={setTech}   lang={lang}/>
        <RatingBar label="intensity" value={intens} onChange={setIntens} lang={lang}/>
        <RatingBar label="attitude"  value={att}    onChange={setAtt}    lang={lang}/>
      </Card>

      <div>
        <Label style={{ marginBottom:8, display:'block' }}>{isRu ? 'Быстрые метки' : isTr ? 'Hızlı değerlendirme' : 'Quick tags'}</Label>
        <div style={{ display:'flex', flexWrap:'wrap', gap: 6 }}>
          {FEEDBACK_CHIPS.map(c => {
            const on = chips.includes(c.key);
            return (
              <button key={c.key} onClick={() => toggleChip(c.key)} style={{
                padding:'6px 12px', borderRadius:999, cursor:'pointer',
                background: on ? 'var(--nx-accent-soft)' : '#1C1C1C',
                border: `1px solid ${on ? 'var(--nx-accent-glow)' : 'rgba(255,255,255,0.06)'}`,
                color: on ? 'var(--nx-accent)' : '#B8B8B8',
                fontFamily:'Manrope', fontWeight:600, fontSize:11,
                letterSpacing:'0.04em', transition:'all 120ms',
              }}>
                {feedbackChipLabel(c, lang, isSwimming)}
              </button>
            );
          })}
        </div>
      </div>

      <div>
        <Label style={{ marginBottom:8, display:'block' }}>{isRu ? 'Заметки' : isTr ? 'Not' : 'Notes'}</Label>
        <textarea
          value={notes}
          onChange={e => setNotes(e.target.value)}
          rows={3}
          placeholder={isRu ? 'Добавьте подробные заметки...' : isTr ? 'Detaylı not ekle…' : 'Add detailed notes...'}
          style={{ background:'#141414', border:'1px solid rgba(255,255,255,0.06)',
            borderRadius:12, padding:14, color:'#fff', fontFamily:'Manrope',
            fontSize:16, outline:'none', resize:'none', lineHeight:1.5,
            width:'100%', boxSizing:'border-box' }}/>
      </div>

      <Button kind="primary" full onClick={save}>
        {isRu ? 'Сохранить отзыв' : isTr ? 'Kaydet' : 'Save feedback'}
      </Button>
    </div>
  );
};

// ────────────────────────────────────────────────────────────
// CREATE REPORT FORM
// ────────────────────────────────────────────────────────────
const CreateReportForm = ({ player, lang, isTr, onSave, onBack }) => {
  const th = window.NXT_THEME || (window.getSportTheme ? window.getSportTheme('football') : {});
  const langKey = nxLangKey(lang);
  const isRu = langKey === 'ru';
  const coachLabel = isRu ? (th.sportType === 'swimming' ? 'Инструктор' : 'Тренер') : isTr ? (th.coachLabel || 'Koç') : (th.sportType === 'swimming' ? 'Instructor' : 'Coach');
  const [title,    setTitle]    = useS3('');
  const [sessNum,  setSessNum]  = useS3('');
  const [sessDen,  setSessDen]  = useS3('');
  const [effort,   setEffort]   = useS3('');
  const [form,     setForm]     = useS3('');
  const [xp,       setXp]       = useS3('');
  const [note,     setNote]     = useS3('');

  const canSave = title.trim() && note.trim();

  const handleSave = () => {
    if (!canSave) return;
    onSave({
      weekId:           title.trim().replace(/[^a-zA-Z0-9]/g, '-').toLowerCase(),
      title:            title.trim(),
      attendanceCount:  sessNum && sessDen ? `${sessNum} / ${sessDen}` : (sessNum || '–'),
      effort:           effort.trim() || '–',
      form:             form.trim() || '–',
      xpGained:         parseInt(xp, 10) || 0,
      coachNote:        note.trim(),
    });
  };

  const fieldStyle = {
    width:'100%', boxSizing:'border-box', padding:'11px 12px', background:'#0B0B0B',
    border:'1px solid rgba(255,255,255,0.10)', borderRadius:10,
    color:'#fff', fontFamily:'Manrope', fontSize:16, outline:'none',
  };

  return (
    <div style={{ padding:'0 20px', display:'flex', flexDirection:'column', gap:16 }}>
      {/* Header */}
      <div style={{ display:'flex', alignItems:'center', gap:12 }}>
        <button onClick={onBack} style={{
          width:32, height:32, borderRadius:999, cursor:'pointer',
          background:'#1C1C1C', border:'1px solid rgba(255,255,255,0.06)',
          color:'#fff', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}>
          <Ico name="chev" size={16} style={{ transform:'scaleX(-1)' }}/>
        </button>
        <Avatar initials={player.name.split(' ').map(s=>s[0]).join('').slice(0,2)} size={38}/>
        <div style={{ flex:1 }}>
          <div style={{ fontFamily:'Manrope', fontWeight:700, fontSize:14, color:'#fff' }}>{player.name}</div>
          <div style={{ fontFamily:'JetBrains Mono', fontSize:10, color:'#7A7A7A' }}>{player.pos} · {player.age}</div>
        </div>
      </div>

      {/* Week / title */}
      <div>
        <Label style={{ marginBottom:8, display:'block' }}>
          {isRu ? 'Неделя / Заголовок *' : isTr ? 'Hafta / Başlık *' : 'Week / Title *'}
        </Label>
        <input value={title} onChange={e => setTitle(e.target.value)}
          placeholder={isRu ? 'например: Неделя 19 · 13–19 мая' : isTr ? 'örn. Hafta 19 · 13–19 Mayıs' : 'e.g. Week 19 · May 13–19'}
          style={fieldStyle}/>
      </div>

      {/* Attendance */}
      <div>
        <Label style={{ marginBottom:8, display:'block' }}>{isRu ? 'Посещаемость (занятия)' : isTr ? 'Katılım (seans)' : 'Attendance (sessions)'}</Label>
        <div style={{ display:'flex', alignItems:'center', gap:8 }}>
          <input value={sessNum} onChange={e => setSessNum(e.target.value)}
            placeholder={isRu ? 'Посещено' : isTr ? 'Katıldı' : 'Attended'} type="number" min="0"
            style={{ ...fieldStyle, width:90 }}/>
          <span style={{ color:'#7A7A7A', fontFamily:'Manrope', fontSize:14 }}>/</span>
          <input value={sessDen} onChange={e => setSessDen(e.target.value)}
            placeholder={isRu ? 'Всего' : isTr ? 'Toplam' : 'Total'} type="number" min="0"
            style={{ ...fieldStyle, width:90 }}/>
        </div>
      </div>

      {/* Effort / Form / XP row */}
      <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr 1fr', gap:8 }}>
        <div>
          <Label style={{ marginBottom:6, display:'block' }}>{isRu ? 'Старание' : isTr ? 'Çaba' : 'Effort'}</Label>
          <input value={effort} onChange={e => setEffort(e.target.value)}
            placeholder="+12%" style={{ ...fieldStyle }}/>
        </div>
        <div>
          <Label style={{ marginBottom:6, display:'block' }}>{isTr ? 'Form' : 'Form'}</Label>
          <input value={form} onChange={e => setForm(e.target.value)}
            placeholder="+8%" style={{ ...fieldStyle }}/>
        </div>
        <div>
          <Label style={{ marginBottom:6, display:'block' }}>XP</Label>
          <input value={xp} onChange={e => setXp(e.target.value)}
            placeholder="320" type="number" min="0" style={{ ...fieldStyle }}/>
        </div>
      </div>

      {/* Coach note */}
      <div>
          <Label style={{ marginBottom:8, display:'block' }}>{isRu ? `Заметка ${coachLabel.toLowerCase()}а *` : isTr ? `${th.coachLabel || 'Koç'} notu *` : `${th.sportType === 'swimming' ? 'Instructor' : 'Coach'} note *`}</Label>
        <textarea value={note} onChange={e => setNote(e.target.value)} rows={4}
          placeholder={isRu ? 'Наблюдения за эту неделю...' : isTr ? 'Bu haftaki gözlemler…' : 'Observations from this week…'}
          style={{ ...fieldStyle, resize:'none', lineHeight:1.5 }}/>
      </div>

      <Button kind="primary" full onClick={handleSave} disabled={!canSave}>
        {isRu ? 'Сохранить отчёт' : isTr ? 'Raporu kaydet' : 'Save report'}
      </Button>
    </div>
  );
};

// ────────────────────────────────────────────────────────────
// CREATE SESSION FORM
// ────────────────────────────────────────────────────────────
const SESSION_TYPES = [
  { key:'training', tr:'Antrenman', en:'Training', ru:'Тренировка' },
  { key:'match',    tr:'Maç',       en:'Match',    ru:'Матч' },
];

const CreateSessionForm = ({ lang, isTr, isMock, profile, teams = [], teamsLoading = false, initialTeamId = '', onSave, onBack }) => {
  const th = window.NXT_THEME || (window.getSportTheme ? window.getSportTheme(profile?.sportType || 'football') : {});
  const langKey = nxLangKey(lang);
  const isRu = langKey === 'ru';
  const isSwimming = th.sportType === 'swimming';
  const trainingLabel = isRu ? (isSwimming ? 'Занятие' : 'Тренировка') : isTr ? (th.trainingLabel || 'Antrenman') : 'Training';
  const teamLabel = isRu ? (isSwimming ? 'Группа' : 'Команда') : isTr ? (th.teamLabel || 'Takım') : (isSwimming ? 'Group' : 'Team');
  const locationLabel = isRu ? (isSwimming ? 'Бассейн' : 'Поле') : isTr ? (th.pitchLabel || 'Saha') : (isSwimming ? 'Pool' : 'Pitch');
  const coachLabel = isRu ? (isSwimming ? 'Инструктор' : 'Тренер') : isTr ? (th.coachLabel || 'Koç') : (isSwimming ? 'Instructor' : 'Coach');
  const [title,    setTitle]    = useS3('');
  const [type,     setType]     = useS3('training');
  const [date,     setDate]     = useS3('');
  const [time,     setTime]     = useS3('');
  const [location, setLocation] = useS3('');
  const [teamId,   setTeamId]   = useS3(initialTeamId || '');
  const [xpReward, setXpReward] = useS3('100');
  const [notes,    setNotes]    = useS3('');
  const [saving,   setSaving]   = useS3(false);
  const [error,    setError]    = useS3('');

  const demoTeams = th.sportType === 'swimming'
    ? [
      { id:'demo-a', name:'Grup A' },
      { id:'demo-b', name:'Grup B' },
    ]
    : [
      { id:'demo-u16', name:'U16' },
      { id:'demo-u12', name:'U12' },
    ];
  const teamOptions = isMock ? demoTeams : teams;
  const selectedTeam = teamOptions.find(t => t.id === teamId) || null;
  const visibleSessionTypes = th.sportType === 'swimming' ? SESSION_TYPES.filter(t => t.key !== 'match') : SESSION_TYPES;
  const resolvedAcademyId = !isMock ? (profile?.academyId || selectedTeam?.academyId || '') : 'demo';
  const resolvedCoachUid  = !isMock ? (profile?.uid || '') : 'demo';
  const canSave = title.trim() && date && time && location.trim() && (isMock || (!!selectedTeam && !!resolvedAcademyId && !!resolvedCoachUid));

  const fieldStyle = {
    background:'#141414', border:'1px solid rgba(255,255,255,0.06)',
    borderRadius:12, padding:'12px 14px', color:'#fff', fontFamily:'Manrope',
    fontSize:16, outline:'none', width:'100%', boxSizing:'border-box',
  };

  const handleSave = async () => {
    setError('');
    const titleValue = title.trim();
    if (saving) return;
    if (!titleValue) {
      setError(isRu ? 'Заголовок обязателен.' : isTr ? 'Başlık zorunludur.' : 'Title is required.');
      return;
    }
    if (!date) {
      setError(isRu ? 'Дата обязательна.' : isTr ? 'Tarih zorunludur.' : 'Date is required.');
      return;
    }
    if (!time) {
      setError(isRu ? 'Время обязательно.' : isTr ? 'Saat zorunludur.' : 'Time is required.');
      return;
    }
    if (!location.trim()) {
      setError(isRu ? 'Место обязательно.' : isTr ? 'Konum zorunludur.' : 'Location is required.');
      return;
    }
    if (!isMock && !selectedTeam) {
      setError(isRu ? `Выбор "${teamLabel}" обязателен.` : isTr ? `${teamLabel} seçimi zorunludur.` : 'Team selection is required.');
      return;
    }
    if (!isMock && (!resolvedAcademyId || !resolvedCoachUid)) {
      setError(isRu ? `Профиль "${coachLabel}" неполный. Выйдите и войдите снова.` : isTr ? `${th.coachLabel || 'Koç'} profili eksik. Lütfen çıkış yapıp tekrar giriş yapın.` : `${th.sportType === 'swimming' ? 'Instructor' : 'Coach'} profile is incomplete. Please sign out and back in.`);
      return;
    }
    setSaving(true);
    let payload = null;
    try {
      if (!isMock && window.NX?.createSession) {
        payload = {
          title:      titleValue,
          type,
          date,
          time,
          location:   location.trim(),
          teamId:     selectedTeam.id,
          teamName:   selectedTeam.name,
          xpReward:   parseInt(xpReward, 10) || 100,
          xp:         parseInt(xpReward, 10) || 100,
          notes:      notes.trim(),
          coachUid:   resolvedCoachUid,
          coachName:  profile.displayName || profile.email || coachLabel,
          academyId:  resolvedAcademyId,
          status:     'scheduled',
        };
        console.debug('[NX] createSession payload:', payload);
        await window.NX.createSession(payload);
      }
      // Demo mode: no Firebase call — onSave() still fires so coach sees the toast
      onSave();
    } catch (e) {
      console.error('[NX] createSession failed:', {
        code: e?.code,
        message: e?.message,
        payload,
        profile: profile ? {
          uid: profile.uid,
          role: profile.role,
          status: profile.status,
          academyId: profile.academyId,
        } : null,
      });
      const msg = e?.code
        ? `${isRu ? 'Не удалось сохранить занятие' : isTr ? 'Seans kaydedilemedi' : 'Session could not be saved'}: ${e.code}`
        : (e?.message || (isRu ? 'Не удалось сохранить занятие. Попробуйте снова.' : isTr ? 'Seans kaydedilemedi. Lütfen tekrar deneyin.' : 'Session could not be saved. Please try again.'));
      setError(msg);
    } finally {
      setSaving(false);
    }
  };

  return (
    <div style={{ padding:'0 20px', display:'flex', flexDirection:'column', gap: 16 }}>
      <div style={{ display:'flex', alignItems:'center', gap: 12 }}>
        <button onClick={onBack} style={{
          width:32, height:32, borderRadius:999, cursor:'pointer',
          background:'#1C1C1C', border:'1px solid rgba(255,255,255,0.06)',
          color:'#fff', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}>
          <Ico name="chev" size={16} style={{ transform:'scaleX(-1)' }}/>
        </button>
        <div style={{ fontFamily:'Oswald', fontWeight:700, fontSize:20,
          textTransform:'uppercase', letterSpacing:'0.02em', color:'#fff' }}>
          {isRu ? (isSwimming ? 'Новое занятие' : 'Новая тренировка') : isTr ? 'Yeni Seans' : 'New Session'}
        </div>
      </div>

      {/* Type toggle */}
      <div>
        <Label style={{ marginBottom:8, display:'block' }}>{isRu ? 'Тип занятия' : isTr ? 'Seans türü' : 'Session type'}</Label>
        <div style={{ display:'flex', gap: 6 }}>
          {visibleSessionTypes.map(t => (
            <button key={t.key} onClick={() => setType(t.key)} style={{
              flex:1, padding:'10px 0', borderRadius:10, cursor:'pointer',
              background: type===t.key ? 'var(--nx-accent-soft)' : '#1C1C1C',
              border:`1px solid ${type===t.key ? 'var(--nx-accent-glow)' : 'rgba(255,255,255,0.06)'}`,
              color: type===t.key ? 'var(--nx-accent)' : '#B8B8B8',
              fontFamily:'Manrope', fontWeight:700, fontSize:13,
            }}>
              {t.key === 'training' ? trainingLabel : (isRu ? t.ru : isTr ? t.tr : t.en)}
            </button>
          ))}
        </div>
      </div>

      {/* Title */}
      <div>
        <Label style={{ marginBottom:6, display:'block' }}>{isRu ? 'Заголовок *' : isTr ? 'Başlık *' : 'Title *'}</Label>
        <input value={title} onChange={e => { setTitle(e.target.value); setError(''); }}
          placeholder={isRu ? (isSwimming ? 'например: Вольный стиль · Сет 4' : 'например: Завершение · Сет 4') : isTr ? `ör. ${th.mockSessionTitle || 'Bitiricilik · Set 4'}` : (th.sportType === 'swimming' ? 'e.g. Freestyle · Set 4' : 'e.g. Finishing · Set 4')}
          style={fieldStyle}/>
      </div>

      {/* Date + Time */}
      <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap: 10 }}>
        <div>
          <Label style={{ marginBottom:6, display:'block' }}>{isRu ? 'Дата *' : isTr ? 'Tarih *' : 'Date *'}</Label>
          <input type="date" value={date} onChange={e => { setDate(e.target.value); setError(''); }}
            style={{ ...fieldStyle, colorScheme:'dark' }}/>
        </div>
        <div>
          <Label style={{ marginBottom:6, display:'block' }}>{isRu ? 'Время *' : isTr ? 'Saat *' : 'Time *'}</Label>
          <input type="time" value={time} onChange={e => { setTime(e.target.value); setError(''); }}
            style={{ ...fieldStyle, colorScheme:'dark' }}/>
        </div>
      </div>

      {/* Location */}
      <div>
        <Label style={{ marginBottom:6, display:'block' }}>{isRu ? `${locationLabel} / место` : isTr ? `${locationLabel} / Konum` : `${th.sportType === 'swimming' ? 'Pool' : 'Pitch'} / Location`}</Label>
        <input value={location} onChange={e => { setLocation(e.target.value); setError(''); }}
          placeholder={isRu ? (isSwimming ? 'например: Бассейн 2' : 'например: Поле 2') : isTr ? `ör. ${th.mockLocation || 'Saha 2'}` : (th.sportType === 'swimming' ? 'e.g. Pool 2' : 'e.g. Pitch 2')}
          style={fieldStyle}/>
      </div>

      {/* Team */}
      <div>
        <Label style={{ marginBottom:8, display:'block' }}>
          {isRu ? `${teamLabel} / группа *` : isTr ? `${teamLabel} / grup *` : `${th.sportType === 'swimming' ? 'Group' : 'Team'} / group *`}
        </Label>
        {teamsLoading ? (
          <div style={{ fontFamily:'Manrope', fontSize:12, color:'#7A7A7A', padding:'10px 0' }}>
            {isRu ? 'Загрузка...' : isTr ? `${teamLabel}lar yükleniyor…` : 'Loading teams…'}
          </div>
        ) : teamOptions.length === 0 ? (
          <div style={{ padding:'11px 12px', borderRadius:10,
            background:'rgba(255,184,0,0.06)', border:'1px solid rgba(255,184,0,0.20)',
            fontFamily:'Manrope', fontSize:12, color:'#FFB800', lineHeight:1.45 }}>
            {isRu ? `Сначала создайте "${teamLabel.toLowerCase()}" в панели администратора.` : isTr ? `Önce admin panelinde ${teamLabel.toLowerCase()} oluşturulmalı.` : 'Create a team in the admin dashboard first.'}
          </div>
        ) : (
          <select value={teamId} onChange={e => { setTeamId(e.target.value); setError(''); }}
            style={{ ...fieldStyle, appearance:'none', WebkitAppearance:'none',
              color: teamId ? '#fff' : '#7A7A7A' }}>
            <option value="">{isRu ? `Выберите: ${teamLabel.toLowerCase()}` : isTr ? `${teamLabel} seç` : 'Select team'}</option>
            {teamOptions.map(t => (
              <option key={t.id} value={t.id} style={{ background:'#1C1C1C', color:'#fff' }}>
                {t.name}
              </option>
            ))}
          </select>
        )}
      </div>

      {/* XP Reward */}
      <div>
        <Label style={{ marginBottom:6, display:'block' }}>{isRu ? 'Награда XP' : isTr ? 'XP ödülü' : 'XP reward'}</Label>
        <input type="number" value={xpReward} onChange={e => { setXpReward(e.target.value); setError(''); }}
          min="0" max="500" style={fieldStyle}/>
      </div>

      {/* Notes */}
      <div>
        <Label style={{ marginBottom:6, display:'block' }}>{isRu ? 'Заметки' : isTr ? 'Notlar' : 'Notes'}</Label>
        <textarea value={notes} onChange={e => { setNotes(e.target.value); setError(''); }} rows={3}
          placeholder={isRu ? 'Детали занятия...' : isTr ? `${trainingLabel} detayları…` : 'Session details…'}
          style={{ ...fieldStyle, resize:'none', lineHeight:1.5 }}/>
      </div>

      {error && (
        <div style={{ padding:'10px 12px', borderRadius:10,
          background:'rgba(255,77,77,0.08)', border:'1px solid rgba(255,77,77,0.24)',
          color:'#FF6B6B', fontFamily:'Manrope', fontSize:12, lineHeight:1.45 }}>
          {error}
        </div>
      )}

      <Button kind="primary" full disabled={saving} onClick={handleSave}>
        {saving
          ? (isRu ? 'Сохранение...' : isTr ? 'Kaydediliyor…' : 'Saving…')
          : (isRu ? 'Сохранить занятие' : isTr ? 'Seansı kaydet' : 'Save session')}
      </Button>
    </div>
  );
};

const WEEKLY_BONUSES = [
  { key:'none',             tr:'Yok',           en:'None',             ru:'Нет',                xp:0  },
  { key:'great_effort',     tr:'Harika çaba',   en:'Great effort',     ru:'Отличное усердие',   xp:25 },
  { key:'team_spirit',      tr:'Takım ruhu',    en:'Team spirit',      ru:'Командный дух',      xp:25 },
  { key:'improved_focus',   tr:'Artan odak',    en:'Improved focus',   ru:'Улучшение фокуса',   xp:25 },
  { key:'outstanding_week', tr:'Mükemmel hafta',en:'Outstanding week', ru:'Отличная неделя',    xp:50 },
];

const nxIsoDate = (date) => date.toISOString().slice(0, 10);
const nxWeekStart = (value = new Date()) => {
  const d = value instanceof Date ? new Date(value) : new Date(value);
  if (Number.isNaN(d.getTime())) return nxIsoDate(new Date());
  const day = d.getDay() || 7;
  d.setHours(12, 0, 0, 0);
  d.setDate(d.getDate() - day + 1);
  return nxIsoDate(d);
};
const nxAddDays = (iso, days) => {
  const d = new Date(`${iso}T12:00:00`);
  d.setDate(d.getDate() + days);
  return nxIsoDate(d);
};
const nxWeeklyXp = ({ attendanceAttended, attendanceTotal, effortRating, disciplineRating, progressRating, bonusXp }) => {
  const attended = parseInt(attendanceAttended, 10) || 0;
  const total = parseInt(attendanceTotal, 10) || 0;
  const attendanceXp = total > 0 ? Math.round((Math.min(attended, total) / total) * 100) : 0;
  return attendanceXp
    + (parseInt(effortRating, 10) || 0) * 10
    + (parseInt(disciplineRating, 10) || 0) * 10
    + (parseInt(progressRating, 10) || 0) * 10
    + (parseInt(bonusXp, 10) || 0);
};
const nxBonusState = (types = [], lang = 'tr') => {
  const selected = Array.isArray(types) ? types : [];
  const bonuses = WEEKLY_BONUSES.filter(b => selected.includes(b.key));
  const total = Math.min(bonuses.reduce((sum, b) => sum + b.xp, 0), 50);
  return {
    bonusTypes: bonuses.map(b => b.key),
    bonusLabels: bonuses.map(b => lang === 'ru' ? b.ru : lang === 'tr' ? b.tr : b.en),
    bonusXp: total,
  };
};

// ────────────────────────────────────────────────────────────
// COACH DASHBOARD
// ────────────────────────────────────────────────────────────
const CoachDashboardScreen = ({ lang, onToast, profile }) => {
  const isMock = !profile;
  const [tab,            setTab]            = useS3('sessions');
  const [feedbackLog,    setFeedbackLog]    = useS3([]);
  const [feedbackPlayer, setFeedbackPlayer] = useS3(null);
  const [realPlayers,    setRealPlayers]    = useS3([]);
  const [playersLoading, setPlayersLoading] = useS3(!isMock && !!profile?.academyId);
  const [reportPlayer,    setReportPlayer]    = useS3(null);
  const [reportLog,       setReportLog]       = useS3([]);
  const [reportLoading,   setReportLoading]   = useS3(!isMock);
  const [attendanceMap,    setAttendanceMap]    = useS3({}); // { playerUid: boolean }
  const [allAttendance,    setAllAttendance]    = useS3([]);
  const [xpAwardedMap,     setXpAwardedMap]     = useS3({}); // { playerUid: boolean } — xp already granted today
  const [attendanceSaving, setAttendanceSaving] = useS3(false);
  const [sessions,         setSessions]         = useS3([]);
  const [sessionsLoading,  setSessionsLoading]  = useS3(!isMock);
  const [teams,            setTeams]            = useS3([]);
  const [teamsLoading,     setTeamsLoading]     = useS3(!isMock && !!profile?.academyId);
  const [weeklyReports,    setWeeklyReports]    = useS3([]);
  const [weeklyLoading,    setWeeklyLoading]    = useS3(!isMock);
  const [weeklyTeamId,     setWeeklyTeamId]     = useS3('');
  const [weeklyStart,      setWeeklyStart]      = useS3(nxWeekStart());
  const [weeklyDrafts,     setWeeklyDrafts]     = useS3({});
  const [weeklySaving,     setWeeklySaving]     = useS3(false);
  const [weeklyError,      setWeeklyError]      = useS3('');
  const [weeklySuccess,    setWeeklySuccess]    = useS3('');
  const [weeklyFormOpen,   setWeeklyFormOpen]   = useS3(false);
  const [selectedTeamId,   setSelectedTeamId]   = useS3('');
  const [listenerErrors,   setListenerErrors]   = useS3({});
  const [showCreateSession, setShowCreateSession] = useS3(false);
  const langKey = nxLangKey(lang);
  const isTr = langKey === 'tr';
  const isRu = langKey === 'ru';
  const th = window.NXT_THEME || (window.getSportTheme ? window.getSportTheme(profile?.sportType || 'football') : {});
  const isSwimming = th.sportType === 'swimming';
  const playerLabel = isRu ? (isSwimming ? 'Пловец' : 'Спортсмен') : isTr ? (th.playerLabel || 'Sporcu') : (isSwimming ? 'Swimmer' : 'Athlete');
  const playerLabelPl = isRu ? (isSwimming ? 'Пловцы' : 'Спортсмены') : isTr ? (th.playerLabelPlural || 'Sporcular') : (isSwimming ? 'Swimmers' : 'Athletes');
  const coachLabel = isRu ? (isSwimming ? 'Инструктор' : 'Тренер') : isTr ? (th.coachLabel || 'Koç') : (isSwimming ? 'Instructor' : 'Coach');
  const teamLabel = isRu ? (isSwimming ? 'Группа' : 'Команда') : isTr ? (th.teamLabel || 'Takım') : (isSwimming ? 'Group' : 'Team');
  const trainingLabel = isRu ? (isSwimming ? 'Сеанс' : 'Тренировка') : isTr ? (th.trainingLabel || 'Antrenman') : 'Training';
  useE3(() => {
    if (!isMock && tab === 'reports') setTab('weekly');
  }, [isMock, tab]);

  // Real players + feedback + reports listeners
  useE3(() => {
    if (isMock || !window.NX) return;
    let playersUnsub;
    if (profile.academyId) {
      setPlayersLoading(true);
      setListenerErrors(e => ({ ...e, players:null }));
      playersUnsub = window.NX.onPlayersByAcademy(profile.academyId, ps => {
        setRealPlayers(ps);
        setPlayersLoading(false);
      }, (err) => {
        console.error('[NX] coach players listener failed:', err?.code, err?.message, {
          uid: profile.uid,
          academyId: profile.academyId,
        });
        setPlayersLoading(false);
        setListenerErrors(e => ({ ...e, players: isRu ? `Не удалось загрузить: ${playerLabelPl.toLowerCase()}.` : isTr ? `${playerLabelPl} yüklenemedi.` : 'Could not load players.' }));
      });
    }
    setListenerErrors(e => ({ ...e, feedback:null, reports:null, weekly:null, attendance:null, sessions:null }));
    const feedbackUnsub = window.NX.onFeedbackByCoach(profile.uid, entries => {
      setFeedbackLog(entries.map(e => ({ ...e, playerId: e.playerUid })));
    }, (err) => {
      console.error('[NX] coach feedback listener failed:', err?.code, err?.message, {
        uid: profile.uid,
        academyId: profile.academyId,
        selectedTeamId,
      });
      setListenerErrors(e => ({ ...e, feedback: isRu ? 'Не удалось загрузить заметки.' : isTr ? 'Notlar yüklenemedi.' : 'Could not load notes.' }));
    });
    const reportsUnsub = window.NX.onReportsByCoach(profile.uid, entries => {
      const sorted = [...entries].sort((a, b) => {
        const ta = a.createdAt?.seconds || 0;
        const tb = b.createdAt?.seconds || 0;
        return tb - ta;
      });
      setReportLog(sorted);
      setReportLoading(false);
    }, (err) => {
      console.error('[NX] coach reports listener failed:', err?.code, err?.message, {
        uid: profile.uid,
        academyId: profile.academyId,
      });
      setReportLoading(false);
      setListenerErrors(e => ({ ...e, reports: isRu ? 'Не удалось загрузить отчёты.' : isTr ? 'Raporlar yüklenemedi.' : 'Could not load reports.' }));
    });

    // Load today's attendance so toggles reflect already-saved state on remount.
    // Also tracks xpAwarded to prevent double-granting XP.
    const attUnsub = window.NX.onAttendanceByCoach(profile.uid, entries => {
      setAllAttendance(entries);
      const today = new Date().toISOString().slice(0, 10);
      const todayEntries = entries.filter(e => e.date === today);
      const newAttMap = {};
      const newXPMap  = {};
      todayEntries.forEach(e => {
        newAttMap[e.playerUid] = !!e.present;
        newXPMap[e.playerUid]  = !!e.xpAwarded;
      });
      setAttendanceMap(newAttMap);
      setXpAwardedMap(newXPMap);
    }, (err) => {
      console.error('[NX] coach attendance listener failed:', err?.code, err?.message, {
        uid: profile.uid,
        academyId: profile.academyId,
        selectedTeamId,
      });
      setListenerErrors(e => ({ ...e, attendance: isRu ? 'Не удалось загрузить посещаемость.' : isTr ? 'Yoklama durumu yüklenemedi.' : 'Could not load attendance state.' }));
    });

    let teamsUnsub;
    if (profile.academyId && window.NX.onTeamsByAcademy) {
      setTeamsLoading(true);
      teamsUnsub = window.NX.onTeamsByAcademy(profile.academyId, entries => {
        setTeams(entries);
        setTeamsLoading(false);
      }, (err) => {
        console.error('[NX] coach teams listener failed:', err?.code, err?.message, {
          uid: profile.uid,
          academyId: profile.academyId,
        });
        setTeamsLoading(false);
        setListenerErrors(e => ({ ...e, teams: isRu ? `Не удалось загрузить: ${teamLabel.toLowerCase()}.` : isTr ? `${teamLabel}lar yüklenemedi.` : 'Could not load teams.' }));
      });
    }

    return () => { playersUnsub?.(); feedbackUnsub(); reportsUnsub(); attUnsub(); teamsUnsub?.(); };
  }, [isMock, profile?.uid, profile?.academyId, isTr]);

  useE3(() => {
    if (isMock || !window.NX?.onSessionsByTeam || !profile?.academyId) return;
    if (!selectedTeamId) {
      setSessions([]);
      setSessionsLoading(false);
      setListenerErrors(e => ({ ...e, sessions:null }));
      return;
    }
    setSessionsLoading(true);
    setListenerErrors(e => ({ ...e, sessions:null }));
    const unsub = window.NX.onSessionsByTeam(profile.academyId, selectedTeamId, entries => {
      const sorted = [...entries]
        .sort((a, b) => {
          const da = (a.date || '') + (a.time || '');
          const db = (b.date || '') + (b.time || '');
          return da > db ? 1 : da < db ? -1 : 0;
        });
      setSessions(sorted);
      setSessionsLoading(false);
    }, (err) => {
      console.error('[NX] sessions listener failed:', err?.code, err?.message, {
        uid: profile.uid,
        academyId: profile.academyId,
        selectedTeamId,
      });
      setSessionsLoading(false);
      setListenerErrors(e => ({ ...e, sessions: isRu ? 'Не удалось загрузить занятия.' : isTr ? 'Seanslar yüklenemedi.' : 'Could not load sessions.' }));
    });
    return () => unsub();
  }, [isMock, profile?.uid, profile?.academyId, selectedTeamId, isTr]);

  useE3(() => {
    if (isMock || !window.NX?.onWeeklyReportsByTeam) return;
    if (!selectedTeamId) {
      setWeeklyReports([]);
      setWeeklyLoading(false);
      setListenerErrors(e => ({ ...e, weekly:null }));
      return;
    }
    setWeeklyLoading(true);
    setListenerErrors(e => ({ ...e, weekly:null }));
    const unsub = window.NX.onWeeklyReportsByTeam(profile.academyId, selectedTeamId, entries => {
      const sorted = entries
        .filter(r => r.academyId === profile.academyId)
        .sort((a, b) => (b.weekStart || '').localeCompare(a.weekStart || ''));
      setWeeklyReports(sorted);
      setWeeklyLoading(false);
    }, (err) => {
      console.error('[NX] weekly reports listener failed:', err?.code, err?.message, {
        uid: profile.uid,
        academyId: profile.academyId,
        selectedTeamId,
        weeklyStart,
      });
      setWeeklyLoading(false);
      const detail = [err?.code, err?.message].filter(Boolean).join(' · ');
      setListenerErrors(e => ({
        ...e,
        weekly: detail
          ? `${isRu ? 'Не удалось загрузить еженедельные отчёты' : isTr ? 'Haftalık raporlar yüklenemedi' : 'Could not load weekly reports'}: ${detail}`
          : (isRu ? 'Не удалось загрузить еженедельные отчёты.' : isTr ? 'Haftalık raporlar yüklenemedi.' : 'Could not load weekly reports.'),
      }));
    });
    return () => unsub();
  }, [isMock, profile?.uid, profile?.academyId, selectedTeamId, isTr]);

  const swimMockStyles = isRu
    ? ['Вольный стиль', 'На спине', 'Брасс', 'Баттерфляй', 'Комплекс']
    : ['Serbest', 'Sırtüstü', 'Kurbağalama', 'Kelebek', 'Karışık'];
  const swimMockGroup = isRu ? 'Группа A' : 'Grup A';
  const MOCK_PLAYERS = [
    { id:1, name:isSwimming?'Efe Yıldız':'Efe Yıldız',        pos:isSwimming?swimMockStyles[0]:'CAM', age:isSwimming?swimMockGroup:'U16', attended:true,  rating:null, flag:false },
    { id:2, name:isSwimming?'Deniz Kaya':'Mert Kara',         pos:isSwimming?swimMockStyles[1]:'ST',  age:isSwimming?swimMockGroup:'U16', attended:true,  rating:8,    flag:false },
    { id:3, name:isSwimming?'Elif Demir':'Burak Aslan',       pos:isSwimming?swimMockStyles[2]:'CB',  age:isSwimming?swimMockGroup:'U16', attended:true,  rating:7,    flag:false },
    { id:4, name:isSwimming?'Mert Kara':'Can Demir',          pos:isSwimming?swimMockStyles[3]:'GK',  age:isSwimming?swimMockGroup:'U16', attended:false, rating:null, flag:true  },
    { id:5, name:isSwimming?'Zeynep Arslan':'Ali Şahin',      pos:isSwimming?swimMockStyles[4]:'LW',  age:isSwimming?swimMockGroup:'U16', attended:true,  rating:6,    flag:false },
    { id:6, name:isSwimming?'Lina Öz':'Deniz Öz',             pos:isSwimming?swimMockStyles[0]:'RB',  age:isSwimming?swimMockGroup:'U16', attended:true,  rating:null, flag:false },
  ];

  const assignedTeamIds = isMock
    ? ['demo-u16','demo-u12']
    : Array.isArray(profile?.assignedTeamIds) ? profile.assignedTeamIds : [];
  const assignedTeams = isMock
    ? [{ id:'demo-u16', name:'U16' }, { id:'demo-u12', name:'U12' }]
    : teams.filter(t => assignedTeamIds.includes(t.id));
  useE3(() => {
    if (isMock) return;
    if (assignedTeams.length === 1 && selectedTeamId !== assignedTeams[0].id) {
      setSelectedTeamId(assignedTeams[0].id);
      setWeeklyTeamId(assignedTeams[0].id);
      setWeeklyDrafts({});
      setWeeklyFormOpen(false);
    } else if (selectedTeamId && !assignedTeamIds.includes(selectedTeamId)) {
      setSelectedTeamId('');
      setWeeklyTeamId('');
      setWeeklyDrafts({});
      setWeeklyFormOpen(false);
    }
  }, [isMock, assignedTeamIds.join('|'), assignedTeams.length, selectedTeamId]);
  const selectedTeam = (isMock ? assignedTeams : assignedTeams).find(t => t.id === selectedTeamId) || null;

  const myRealPlayers = (() => {
    if (isMock) return [];
    if (!selectedTeamId) return [];
    return realPlayers.filter(p => p.teamId === selectedTeamId);
  })();

  const swimStyles = isRu ? swimMockStyles : (th.styleExamples || swimMockStyles);
  const players = isMock
    ? MOCK_PLAYERS
    : myRealPlayers.map((p, idx) => ({
        id:       p.uid,
        uid:      p.uid,
        name:     p.displayName || '–',
        pos:      isSwimming ? (p.swimStyle || p.style || swimStyles[idx % swimStyles.length]) : (p.positionLabel || p.position || '–'),
        age:      isSwimming ? (p.teamName || 'Grup') : (p.ageGroup   || '–'),
        attended: attendanceMap[p.uid] !== undefined ? !!attendanceMap[p.uid] : false,
        rating:   null,
        flag:     false,
      }));
  const visibleFeedbackLog = isMock || !selectedTeamId
    ? feedbackLog
    : feedbackLog.filter(e => e.teamId === selectedTeamId || players.some(p => p.uid === e.playerUid || p.id === e.playerId));

  const present = players.filter(p => p.attended).length;
  const coachSessionList = isMock ? [
    { id:'m1', title: isRu ? (isSwimming?'Вольный стиль · Сет 4':'Завершение · Сет 4') : isTr?(th.mockSessionTitle || 'Bitiricilik · Set 4'):(isSwimming?'Freestyle · Set 4':'Finishing · Set 4'), type:'training', date:'2026-05-14', time:'18:30', location:isRu?(isSwimming?'Бассейн 2':'Поле 2'):(th.mockLocation || (isSwimming?'Havuz 2':'Pitch 2')), team:isSwimming?swimMockGroup:'U16', xpReward:120 },
    { id:'m2', title: isRu ? (isSwimming?'Контроль дыхания':'Передачи в треугольниках') : isTr?(isSwimming?'Nefes kontrolü':'Pas üçgenleri'):(isSwimming?'Breath control':'Passing triangles'),       type:'training', date:'2026-05-16', time:'17:00', location:isRu?(isSwimming?'Бассейн 1':'Поле 1'):(isSwimming?'Havuz 1':'Pitch 1'), team:isSwimming?swimMockGroup:'U16', xpReward:90  },
    { id:'m3', title: isRu ? (isSwimming?'Сет на выносливость':'Матч U16') : isTr?(isSwimming?'Dayanıklılık seti':'U16 Maçı'):(isSwimming?'Endurance set':'U16 Match'),                    type:isSwimming?'training':'match',    date:'2026-05-18', time:'11:00', location:isRu?(isSwimming?'Главный бассейн':'Главное поле'):(isSwimming?'Ana Havuz':'Ana Saha'), team:isSwimming?swimMockGroup:'U16', xpReward:200 },
  ] : sessions.filter(s => !selectedTeamId || s.teamId === selectedTeamId);

  const weeklyWeekEnd = nxAddDays(weeklyStart, 6);
  const weeklyTeamOptions = assignedTeams;
  const weeklyTeam = selectedTeam || weeklyTeamOptions.find(t => t.id === weeklyTeamId) || null;
  const weeklyPlayers = isMock
    ? MOCK_PLAYERS.map(p => ({ ...p, uid:String(p.id), displayName:p.name, teamId:'demo-u16', teamName:'U16' }))
    : myRealPlayers;
  const reportsForSelectedWeek = weeklyReports.filter(r =>
    r.teamId === weeklyTeam?.id &&
    r.weekStart === weeklyStart
  );
  useE3(() => {
    if (!isMock && selectedTeamId && weeklyTeamId !== selectedTeamId) setWeeklyTeamId(selectedTeamId);
  }, [isMock, selectedTeamId, weeklyTeamId]);
  const weeklyFieldStyle = {
    background:'#141414', border:'1px solid rgba(255,255,255,0.06)',
    borderRadius:10, padding:'10px 12px', color:'#fff', fontFamily:'Manrope',
    fontSize:16, outline:'none', width:'100%', boxSizing:'border-box',
  };
  const attendanceForPlayer = (playerUid) => {
    const weekEntries = allAttendance.filter(a =>
      a.playerUid === playerUid &&
      (a.date || '') >= weeklyStart &&
      (a.date || '') <= weeklyWeekEnd
    );
    return {
      attended: weekEntries.filter(a => !!a.present).length,
      total: weekEntries.length,
    };
  };
  const draftForPlayer = (p) => {
    const existing = weeklyDrafts[p.uid] || {};
    const saved = reportsForSelectedWeek.find(r => r.playerUid === p.uid) || {};
    const auto = attendanceForPlayer(p.uid);
    return {
      attendanceAttended: existing.attendanceAttended ?? saved.attendanceAttended ?? auto.attended,
      attendanceTotal:    existing.attendanceTotal ?? saved.attendanceTotal ?? auto.total,
      effortRating:       existing.effortRating ?? saved.effortRating ?? 4,
      disciplineRating:   existing.disciplineRating ?? saved.disciplineRating ?? 4,
      progressRating:     existing.progressRating ?? saved.progressRating ?? 3,
      bonusTypes:         existing.bonusTypes ?? saved.bonusTypes ?? (saved.bonusType && saved.bonusType !== 'none' ? [saved.bonusType] : []),
      coachNote:          existing.coachNote ?? saved.coachNote ?? '',
    };
  };
  const toggleWeeklyBonus = (playerUid, bonusKey) => {
    const current = draftForPlayer({ uid:playerUid }).bonusTypes || [];
    const next = current.includes(bonusKey)
      ? current.filter(k => k !== bonusKey)
      : [...current, bonusKey];
    setWeeklySuccess('');
    updateWeeklyDraft(playerUid, { bonusTypes: next });
  };
  const updateWeeklyDraft = (playerUid, patch) =>
    {
      setWeeklySuccess('');
      setWeeklyDrafts(prev => ({ ...prev, [playerUid]: { ...(prev[playerUid] || {}), ...patch } }));
    };
  const applyWeeklyRating = (field, value) => {
    const next = {};
    weeklyPlayers.forEach(p => { next[p.uid] = { ...(weeklyDrafts[p.uid] || {}), [field]: value }; });
    setWeeklySuccess('');
    setWeeklyDrafts(prev => ({ ...prev, ...next }));
  };
  const saveWeeklyReports = async () => {
    setWeeklyError('');
    setWeeklySuccess('');
    if (weeklySaving) return;
    if (!weeklyTeam) {
      setWeeklyError(isRu ? `Выбор "${teamLabel}" обязателен.` : isTr ? `${teamLabel} seçimi zorunludur.` : 'Team selection is required.');
      return;
    }
    if (!isMock && weeklyPlayers.length === 0) {
      setWeeklyError(isRu ? `В этой ${teamLabel.toLowerCase()}е нет одобренных участников.` : isTr ? `Bu ${teamLabel.toLowerCase()}da onaylı ${playerLabel.toLowerCase()} yok.` : `This ${isSwimming ? 'group' : 'team'} has no approved ${isSwimming ? 'swimmers' : 'players'}.`);
      return;
    }
    setWeeklySaving(true);
    try {
      if (!isMock && window.NX?.saveWeeklyReports) {
        const reports = weeklyPlayers.map(p => {
          const d = draftForPlayer(p);
          const bonus = nxBonusState(d.bonusTypes, lang);
          const weeklyXp = nxWeeklyXp({ ...d, bonusXp: bonus.bonusXp });
          const existing = reportsForSelectedWeek.find(r => r.playerUid === p.uid);
          return {
            playerUid:  p.uid,
            playerName: p.displayName || p.name || '–',
            teamId:     weeklyTeam.id,
            teamName:   weeklyTeam.name,
            coachUid:   profile.uid,
            coachName:  profile.displayName || profile.email || (isSwimming ? 'Instructor' : 'Coach'),
            academyId:  profile.academyId,
            weekStart:  weeklyStart,
            weekEnd:    weeklyWeekEnd,
            attendanceAttended: parseInt(d.attendanceAttended, 10) || 0,
            attendanceTotal:    parseInt(d.attendanceTotal, 10) || 0,
            effortRating:       parseInt(d.effortRating, 10) || 1,
            disciplineRating:   parseInt(d.disciplineRating, 10) || 1,
            progressRating:     parseInt(d.progressRating, 10) || 1,
            bonusTypes:         bonus.bonusTypes,
            bonusLabels:        bonus.bonusLabels,
            bonusXp:            bonus.bonusXp,
            coachNote:          (d.coachNote || '').trim(),
            weeklyXp,
            existingId:         existing?.id || null,
            existingXpAwarded:  !!existing?.xpAwarded,
          };
        });
        const requiredFields = [
          'academyId', 'teamId', 'playerUid', 'weekStart', 'weekEnd',
          'attendanceAttended', 'attendanceTotal',
          'effortRating', 'disciplineRating', 'progressRating', 'weeklyXp',
        ];
        const missing = reports.flatMap((report, index) =>
          requiredFields
            .filter(field => report[field] === undefined || report[field] === null || report[field] === '')
            .map(field => `${report.playerName || `#${index + 1}`}: ${field}`)
        );
        if (missing.length > 0) {
          const msg = `${isRu ? 'Не заполнены поля еженедельного отчёта' : isTr ? 'Eksik haftalık rapor alanları' : 'Missing weekly report fields'}: ${missing.join(', ')}`;
          console.error('[NX] saveWeeklyReports failed:', 'validation/missing-fields', msg, reports);
          setWeeklyError(msg);
          setWeeklySaving(false);
          return;
        }
        console.debug('[NX] saveWeeklyReports payload:', reports);
        const results = await window.NX.saveWeeklyReports(reports);
        const awarded = results.filter(r => r.awarded).length;
        setWeeklySuccess(isRu ? 'Еженедельные отчёты сохранены' : isTr ? 'Haftalık raporlar kaydedildi' : 'Weekly reports saved');
        onToast && onToast({
          msg: isRu ? 'Еженедельные отчёты сохранены' : isTr ? 'Haftalık raporlar kaydedildi' : 'Weekly reports saved',
          code: isRu ? `${awarded} новых XP-наград` : isTr ? `${awarded} yeni XP ödülü` : `${awarded} new XP awards`,
        });
      } else {
        setWeeklySuccess(isRu ? 'Демо: еженедельный отчёт сохранён' : isTr ? 'Demo: Haftalık rapor kaydedildi' : 'Demo: Weekly report saved');
        onToast && onToast({ msg: isRu ? 'Демо: еженедельный отчёт сохранён' : isTr ? 'Demo: Haftalık rapor kaydedildi' : 'Demo: Weekly report saved' });
      }
    } catch (e) {
      console.error('[NX] saveWeeklyReports failed:', e?.code, e?.message, e);
      setWeeklyError(e?.code
        ? `${isRu ? 'Не удалось сохранить еженедельный отчёт' : isTr ? 'Haftalık rapor kaydedilemedi' : 'Weekly report could not be saved'}: ${e.code}${e.message ? ` · ${e.message}` : ''}`
        : (e?.message || (isRu ? 'Не удалось сохранить еженедельный отчёт.' : isTr ? 'Haftalık rapor kaydedilemedi.' : 'Weekly report could not be saved.')));
    } finally {
      setWeeklySaving(false);
    }
  };

  const LoadingDots = ({ color = '#00FF88', pad = '24px 0' }) => (
    <div style={{ display:'flex', justifyContent:'center', padding:pad }}>
      <div style={{ display:'flex', gap:8 }}>
        {[0,1,2].map(i => (
          <div key={i} style={{ width:7, height:7, borderRadius:999, background:color,
            animation:`nxpulse 1.4s ease-in-out ${i*0.22}s infinite` }}/>
        ))}
      </div>
    </div>
  );

  const SoftState = ({ message, tone = 'empty', hint }) => {
    const color = tone === 'error' ? '#FF6B6B' : '#5A5A5A';
    return (
      <div style={{ textAlign:'center', padding:'24px 0' }}>
        <div style={{ fontFamily:'Manrope', fontSize:13, color }}>{message}</div>
        {hint && (
          <div style={{ fontFamily:'Manrope', fontSize:11, color:'#4A4A4A', marginTop:6, lineHeight:1.45 }}>
            {hint}
          </div>
        )}
      </div>
    );
  };

  const saveQuickRating = (playerUid, rating) => {
    if (isMock || !window.NX || !profile?.uid) return;
    window.NX.saveFeedback({
      coachUid:    profile.uid,
      playerUid,
      academyId:   profile.academyId,
      teamId:      selectedTeam?.id || null,
      teamName:    selectedTeam?.name || null,
      quickRating: rating,
    }).catch(() => {});
  };

  const doSaveAttendance = async () => {
    if (!window.NX || !profile?.uid || myRealPlayers.length === 0) return;
    if (!isMock && !selectedTeam) return;
    setAttendanceSaving(true);
    const today = new Date().toISOString().slice(0, 10);
    try {
      await Promise.all(myRealPlayers.map(async p => {
        const present        = !!(attendanceMap[p.uid]);
        const alreadyAwarded = !!(xpAwardedMap[p.uid]);
        const grantXP        = present && !alreadyAwarded;

        await window.NX.saveAttendance({
          coachUid:   profile.uid,
          playerUid:  p.uid,
          academyId:  profile.academyId,
          teamId:     selectedTeam?.id || p.teamId || null,
          teamName:   selectedTeam?.name || p.teamName || null,
          date:       today,
          present,
          xpAwarded:  grantXP || alreadyAwarded,
        });

        if (grantXP && window.NX.addXP) {
          await window.NX.addXP(p.uid, 50);
        }
      }));

      const presentCount = myRealPlayers.filter(p => attendanceMap[p.uid]).length;
      onToast && onToast({
        msg:  isRu ? 'Посещаемость сохранена' : isTr ? 'Yoklama kaydedildi' : 'Attendance saved',
        code: `${presentCount} / ${myRealPlayers.length}`,
      });
    } catch (e) {
      onToast && onToast({ msg: isRu ? 'Ошибка' : isTr ? 'Hata' : 'Error' });
    } finally {
      setAttendanceSaving(false);
    }
  };

  if (showCreateSession) {
    return (
      <div style={{ display:'flex', flexDirection:'column', gap: 16, paddingBottom: 16, paddingTop: 12 }}>
        <CreateSessionForm
          lang={lang}
          isTr={isTr}
          isMock={isMock}
          profile={isMock ? { uid:'demo', displayName:'Demo Coach', academyId:'demo' } : profile}
          teams={isMock ? assignedTeams : assignedTeams}
          teamsLoading={teamsLoading}
          initialTeamId={selectedTeamId}
          onBack={() => setShowCreateSession(false)}
          onSave={() => {
            setShowCreateSession(false);
            onToast && onToast({ msg: isRu ? 'Занятие создано' : isTr ? 'Seans oluşturuldu' : 'Session created' });
          }}
        />
      </div>
    );
  }

  return (
    <div style={{ display:'flex', flexDirection:'column', gap: 16, paddingBottom: 16 }}>

      {/* Header */}
      <div style={{ padding:'4px 20px 0' }}>
        {isMock ? (
          <>
            <Label>{isRu ? `Сегодня · 18:30 · ${isSwimming ? 'Бассейн 2' : 'Поле 2'}` : isTr?`Bugün · 18:30 · ${th.mockLocation || 'Pitch 2'}`:`Today · 18:30 · ${isSwimming ? 'Pool 2' : 'Pitch 2'}`}</Label>
            <h1 style={{ fontFamily:'Oswald', fontWeight:700, fontSize: 22, lineHeight: 1.05,
              textTransform:'uppercase', letterSpacing:'0.02em', color:'#fff', margin:'4px 0 0' }}>
              {isRu ? (isSwimming ? 'Группа A · Вольный стиль' : 'U16 · Завершение') : isTr ? (isSwimming ? 'Grup A · Serbest stil' : 'U16 · Bitiricilik') : (isSwimming ? 'Group A · Freestyle' : 'U16 · Finishing')}
            </h1>
          </>
        ) : (() => {
          const today = new Date().toISOString().slice(0,10);
          const next = sessions.find(s => s.date >= today) || sessions[0];
          const typeText = next?.type === 'match'
            ? (isRu ? 'МАТЧ' : isTr ? 'MAÇ' : 'MATCH')
            : (isRu ? trainingLabel.toUpperCase() : isTr ? trainingLabel.toUpperCase() : 'TRAINING');
          return (
            <>
              <Label>{next ? `${next.date || ''}${next.time ? ' · '+next.time : ''}${next.location ? ' · '+next.location : ''}` : (isRu ? `Панель: ${coachLabel}` : isTr?`${coachLabel} paneli`:`${coachLabel} panel`)}</Label>
              <h1 style={{ fontFamily:'Oswald', fontWeight:700, fontSize: 22, lineHeight: 1.05,
                textTransform:'uppercase', letterSpacing:'0.02em', color:'#fff', margin:'4px 0 0' }}>
                {next ? `${next.teamName || ''} · ${typeText}` : (profile?.displayName || coachLabel)}
              </h1>
            </>
          );
        })()}
      </div>

      {!isMock && (
        <div style={{ padding:'0 20px', display:'flex', flexDirection:'column', gap:8 }}>
          <Label>{isRu ? `Выберите: ${teamLabel.toLowerCase()}` : isTr ? `${teamLabel} seç` : 'Select team'}</Label>
          {teamsLoading ? (
            <LoadingDots pad="12px 0"/>
          ) : assignedTeams.length === 0 ? (
            <Card style={{ padding:14, background:isSwimming ? 'var(--nx-accent-soft)' : 'rgba(255,184,0,0.06)', border:isSwimming ? '1px solid var(--nx-accent-glow)' : '1px solid rgba(255,184,0,0.20)' }}>
              <div style={{ fontFamily:'Manrope', fontSize:13, color:isSwimming ? 'var(--nx-accent)' : '#FFB800', lineHeight:1.45 }}>
                {isRu ? `Вам пока не назначена ${teamLabel.toLowerCase()}.` : isTr ? `Henüz size atanmış ${teamLabel.toLowerCase()} yok.` : `No ${isSwimming ? 'groups' : 'teams'} assigned yet.`}
              </div>
            </Card>
          ) : (
            <div style={{ display:'flex', gap:6, overflowX:'auto', scrollbarWidth:'none', WebkitOverflowScrolling:'touch' }}>
              {assignedTeams.map(t => (
                <button key={t.id} onClick={() => { setSelectedTeamId(t.id); setWeeklyTeamId(t.id); setWeeklyDrafts({}); setWeeklyFormOpen(false); }} style={{
                  flexShrink:0, borderRadius:999, padding:'8px 13px', cursor:'pointer',
                  background:selectedTeamId === t.id ? 'var(--nx-accent-soft)' : '#1C1C1C',
                  border:`1px solid ${selectedTeamId === t.id ? 'var(--nx-accent-glow)' : 'rgba(255,255,255,0.08)'}`,
                  color:selectedTeamId === t.id ? 'var(--nx-accent)' : '#B8B8B8',
                  fontFamily:'Manrope', fontWeight:800, fontSize:11,
                  letterSpacing:'0.08em', textTransform:'uppercase' }}>
                  {t.name}
                </button>
              ))}
            </div>
          )}
        </div>
      )}

      {/* Top metrics */}
      <div style={{ padding:'0 20px', display:'grid', gridTemplateColumns:'1fr 1fr 1fr', gap: 10 }}>
        <CoachStat label={isRu?'Посещаемость':isTr?'Katılım':'Attendance'} value={`${present}/${players.length}`} accent={isSwimming ? '#38E8FF' : '#00FF88'}/>
        <CoachStat label={isRu?'Сеансы':isTr?`${trainingLabel}lar`:'Sessions'} value={isMock ? '3' : String(coachSessionList.length)} accent={isSwimming ? '#38E8FF' : '#FFB800'}/>
        <CoachStat label={isRu?'Обратная связь':isTr?'Geri bildirim':'Feedback'} value={String(visibleFeedbackLog.length)} accent="#4F8DFF"/>
      </div>

      {/* Tabs — scrollable pill row */}
      <div style={{ padding:'0 16px', overflowX:'auto', scrollbarWidth:'none',
        WebkitOverflowScrolling:'touch', borderBottom:'1px solid rgba(255,255,255,0.06)' }}>
        <div style={{ display:'flex', gap: 4, paddingBottom: 12, minWidth:'max-content' }}>
          {[
            ['sessions', isRu?'📅 Сеансы':isTr?'📅 Seanslar':'📅 Sessions'],
            ['roster',   isRu?playerLabelPl:isTr?playerLabelPl:'Roster'],
            ['ratings',  isRu?'Баллы':isTr?'Puanlar':'Ratings'],
            ['feedback', isRu?'Заметки':isTr?'Notlar':'Notes'],
            ['weekly',   isRu?'Неделя':isTr?'Haftalık':'Weekly'],
            ...(isMock ? [['reports', isRu?'Отчёты':isTr?'Raporlar':'Reports']] : []),
          ].map(([k,l]) => (
            <button key={k} onClick={() => setTab(k)} style={{
              background: tab===k ? (k==='sessions' ? 'var(--nx-accent)' : '#fff') : '#1C1C1C',
              border: tab===k ? 'none' : '1px solid rgba(255,255,255,0.08)',
              borderRadius: 999, cursor:'pointer',
              fontFamily:'Manrope', fontWeight:700, fontSize: 11,
              letterSpacing: k==='sessions' ? '0.06em' : '0.12em',
              textTransform:'uppercase',
              color: tab===k ? '#0B0B0B' : '#7A7A7A',
              padding:'7px 14px', whiteSpace:'nowrap', flexShrink: 0,
            }}>
              {l}
            </button>
          ))}
        </div>
      </div>

      {/* Tab body */}
      {tab==='roster' && (
        <div style={{ padding:'0 20px', display:'flex', flexDirection:'column', gap: 6 }}>
          {!isMock && assignedTeams.length === 0 ? (
            <SoftState message={isRu ? `Вам пока не назначена ${teamLabel.toLowerCase()}.` : isTr ? `Henüz size atanmış ${teamLabel.toLowerCase()} yok.` : `No ${isSwimming ? 'groups' : 'teams'} assigned yet.`}/>
          ) : !isMock && !selectedTeamId ? (
            <SoftState message={isRu ? `Сначала выберите: ${teamLabel.toLowerCase()}.` : isTr ? `Önce ${teamLabel.toLowerCase()} seç.` : 'Select a team first.'}/>
          ) : !isMock && playersLoading ? (
            <LoadingDots pad="32px 0"/>
          ) : !isMock && listenerErrors.players ? (
            <SoftState tone="error" message={listenerErrors.players}
              hint={isRu ? 'Посещаемость нельзя сохранить, пока список не загрузится.' : isTr ? `${playerLabelPl} gelene kadar yoklama kaydedilemez.` : `Attendance cannot be saved until ${isSwimming ? 'swimmers' : 'players'} load.`}/>
	          ) : !isMock && players.length === 0 ? (
	            <SoftState
              message={isRu ? `Пока нет зарегистрированных участников.` : isTr ? `Henüz kayıtlı ${playerLabel.toLowerCase()} yok.` : `No ${isSwimming ? 'swimmers' : 'players'} signed up yet.`}
              hint={isRu ? `Одобренные участники появятся здесь после назначения в эту ${teamLabel.toLowerCase()}у.` : isTr ? `Admin onaylı ${playerLabelPl.toLowerCase()} bu ${teamLabel.toLowerCase()} içine atadığında burada görünecek.` : `Approved ${isSwimming ? 'swimmers' : 'players'} will appear here once the admin assigns them to this ${isSwimming ? 'group' : 'team'}.`}/>
	          ) : (
            <>
              {players.map(p => (
                <RosterRow
                  key={p.id} p={p} lang={lang}
                  attended={isMock ? undefined : p.attended}
                  onToggle={isMock ? undefined : (val) =>
                    setAttendanceMap(m => ({ ...m, [p.uid]: val }))
                  }
                />
              ))}
              <Button kind="primary" full size="md"
                disabled={attendanceSaving}
                onClick={isMock
                  ? () => onToast && onToast({ msg: isTr?'Yoklama kaydedildi':'Attendance saved', code: `${players.filter(p=>p.attended).length} / ${players.length}` })
                  : doSaveAttendance}>
                {attendanceSaving
                  ? (isRu ? 'Сохранение...' : isTr ? 'Kaydediliyor…' : 'Saving…')
                  : (isRu ? 'Сохранить посещаемость' : isTr ? 'Yoklamayı kaydet' : 'Save attendance')}
              </Button>
            </>
          )}
        </div>
      )}

      {tab==='sessions' && (
        <div style={{ padding:'0 20px', display:'flex', flexDirection:'column', gap: 12 }}>

          {/* ── Create-session CTA — visible in both demo and real mode ── */}
          <button onClick={() => setShowCreateSession(true)} disabled={!isMock && !selectedTeamId} style={{
            display:'flex', alignItems:'center', justifyContent:'center', gap: 8,
            width:'100%', padding:'14px 0', borderRadius:14, cursor:(!isMock && !selectedTeamId) ? 'not-allowed' : 'pointer',
            background:'var(--nx-accent-soft)',
            border:'1.5px dashed var(--nx-accent-glow)',
            opacity:(!isMock && !selectedTeamId) ? 0.45 : 1,
          }}>
            <span style={{ width:24, height:24, borderRadius:999,
              background:'var(--nx-accent)', display:'flex', alignItems:'center', justifyContent:'center' }}>
              <span style={{ color:'#0B0B0B', fontWeight:900, fontSize:16, lineHeight:1 }}>+</span>
            </span>
            <span style={{ fontFamily:'Manrope', fontWeight:700, fontSize:13,
              letterSpacing:'0.06em', textTransform:'uppercase', color:'var(--nx-accent)' }}>
              {isRu ? (isSwimming ? 'Добавить сеанс' : 'Добавить тренировку или матч') : isTr ? (isSwimming ? 'Yeni Seans Ekle' : `Yeni ${trainingLabel.toLowerCase()} / maç ekle`) : (isSwimming ? 'Add session' : 'Add training or match')}
            </span>
          </button>

          {/* ── Session list ── */}
          {!isMock && assignedTeams.length === 0 ? (
            <SoftState message={isRu ? `Вам пока не назначена ${teamLabel.toLowerCase()}.` : isTr ? `Henüz size atanmış ${teamLabel.toLowerCase()} yok.` : `No ${isSwimming ? 'groups' : 'teams'} assigned yet.`}/>
          ) : !isMock && !selectedTeamId ? (
            <SoftState message={isRu ? `Выберите ${teamLabel.toLowerCase()}у, чтобы увидеть занятия.` : isTr ? `Seansları görmek için ${teamLabel.toLowerCase()} seç.` : 'Select a team to view sessions.'}/>
          ) : !isMock && sessionsLoading ? (
            <LoadingDots/>
          ) : !isMock && listenerErrors.sessions ? (
            <SoftState tone="error" message={listenerErrors.sessions}
              hint={isRu ? 'Вы всё ещё можете создать новое занятие.' : isTr ? 'Yeni seans oluşturmaya devam edebilirsin.' : 'You can still create a new session.'}/>
          ) : coachSessionList.length === 0 ? (
            <SoftState
              message={isRu ? 'Пока нет занятий.' : isTr ? 'Henüz seans oluşturulmadı.' : 'No sessions yet.'}
              hint={isRu ? (isSwimming ? 'Нажмите кнопку выше, чтобы добавить занятие.' : 'Нажмите кнопку выше, чтобы добавить тренировку или матч.') : isTr ? (isSwimming ? 'Yukarıdaki butona basarak gerçek seans ekle.' : 'Yukarıdaki butona basarak gerçek antrenman veya maç ekle.') : (isSwimming ? 'Tap the button above to add a real session.' : 'Tap the button above to add a real training session or match.')}/>
          ) : (
            coachSessionList.map(s => (
              <div key={s.id} style={{ background:'#141414', border:'1px solid rgba(255,255,255,0.06)',
                borderRadius:14, padding:14, display:'flex', gap:14, alignItems:'flex-start' }}>
                <div style={{ width:36, height:36, borderRadius:10, flexShrink:0,
                  background: s.type==='match' && !isSwimming ? 'rgba(255,184,0,0.10)' : 'var(--nx-accent-soft)',
                  border:`1px solid ${s.type==='match' && !isSwimming ? 'rgba(255,184,0,0.30)' : 'var(--nx-accent-glow)'}`,
                  display:'flex', alignItems:'center', justifyContent:'center' }}>
                  <Ico name={s.type==='match' && !isSwimming?'trophy':'lightning'} size={16}
                    style={{ color: s.type==='match' && !isSwimming ? '#FFB800' : 'var(--nx-accent)' }}/>
                </div>
                <div style={{ flex:1, minWidth:0 }}>
                  <div style={{ fontFamily:'Manrope', fontWeight:700, fontSize:13, color:'#fff',
                    overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{s.title}</div>
                  <div style={{ fontFamily:'JetBrains Mono', fontSize:10, color:'#7A7A7A', marginTop:2 }}>
                    {s.date}{s.time ? ` · ${s.time}` : ''}{s.location ? ` · ${s.location}` : ''}
                  </div>
                  {(s.teamName || s.ageGroup) && (
                    <div style={{ fontFamily:'Manrope', fontSize:10, color:'#4A4A4A', marginTop:2 }}>{s.teamName || s.ageGroup}</div>
                  )}
                </div>
	                <span style={{ fontFamily:'JetBrains Mono', fontSize:10,
	                  color:s.type==='match' && !isSwimming ? '#FFB800' : 'var(--nx-accent)',
	                  flexShrink:0, letterSpacing:'0.08em', textTransform:'uppercase' }}>
	                  {s.type === 'match' && !isSwimming
                    ? (isRu ? 'Матч' : isTr ? 'Maç' : 'Match')
                    : (isRu ? 'Сеанс' : isTr ? 'Seans' : 'Session')}
	                </span>
	              </div>
            ))
          )}
        </div>
      )}

      {tab==='ratings' && (
        <div style={{ padding:'0 20px', display:'flex', flexDirection:'column', gap: 8 }}>
          <Label style={{ marginBottom: 4 }}>{isRu ? 'Быстрая оценка (1–10)' : isTr ? 'Hızlı puan (1–10)' : 'Quick rate (1–10)'}</Label>
          {!isMock && assignedTeams.length === 0 ? (
            <SoftState message={isRu ? `Вам пока не назначена ${teamLabel.toLowerCase()}.` : isTr ? `Henüz size atanmış ${teamLabel.toLowerCase()} yok.` : `No ${isSwimming ? 'groups' : 'teams'} assigned yet.`}/>
          ) : !isMock && !selectedTeamId ? (
            <SoftState message={isRu ? `Сначала выберите: ${teamLabel.toLowerCase()}.` : isTr ? `Önce ${teamLabel.toLowerCase()} seç.` : 'Select a team first.'}/>
          ) : !isMock && playersLoading ? (
            <LoadingDots/>
          ) : !isMock && (listenerErrors.players || listenerErrors.attendance) ? (
            <SoftState tone="error" message={listenerErrors.players || listenerErrors.attendance}/>
          ) : players.filter(p=>p.attended).slice(0,4).map(p => (
            <RatingRow key={p.id} p={p} lang={lang}
              onRate={!isMock && p.uid ? (r) => saveQuickRating(p.uid, r) : undefined}/>
          ))}
          {!isMock && !playersLoading && !listenerErrors.players && !listenerErrors.attendance && players.filter(p=>p.attended).length === 0 && (
            <SoftState
              message={isRu ? 'Пока некого оценивать.' : isTr ? `Puanlanacak ${playerLabel.toLowerCase()} yok.` : `No ${isSwimming ? 'swimmers' : 'players'} ready to rate.`}
              hint={isRu ? `Сначала отметьте участников как присутствующих во вкладке "${playerLabelPl}".` : isTr ? `Önce Kadro sekmesinde ${playerLabelPl.toLowerCase()}ı bugün için katıldı olarak işaretle.` : `Mark ${isSwimming ? 'swimmers' : 'players'} as present in the Roster tab first.`}/>
          )}
        </div>
      )}

      {tab==='feedback' && (
        feedbackPlayer
          ? (
            <PlayerFeedbackForm
              player={feedbackPlayer}
              lang={lang}
              isTr={isTr}
              onBack={() => setFeedbackPlayer(null)}
              onSave={async entry => {
                if (!isMock && window.NX) {
                  const isNew = !visibleFeedbackLog.find(
                    e => e.playerUid === entry.playerId || e.playerId === entry.playerId
                  );
                  try {
                    await window.NX.saveFeedback({
                      coachUid:    profile.uid,
                      coachName:   profile.displayName || '',
                      playerUid:   entry.playerId,
                      playerName:  entry.playerName,
                      academyId:   profile.academyId,
                      teamId:      selectedTeam?.id || feedbackPlayer.teamId || null,
                      teamName:    selectedTeam?.name || feedbackPlayer.teamName || null,
                      ratings:     entry.ratings,
                      notes:       entry.notes,
                      sessionDate: entry.timestamp,
                      ...(isNew ? { createdAt: window.NX.serverTimestamp() } : {}),
                    });
                  } catch (e) {
                    onToast && onToast({ msg: isTr?'Kaydetme hatası':'Save failed' });
                    return;
                  }
                  // onFeedbackByCoach listener updates feedbackLog automatically
                } else {
                  setFeedbackLog(prev => [entry, ...prev]);
                }
                setFeedbackPlayer(null);
                onToast && onToast({ msg: isTr?'Not kaydedildi':'Note saved', code: entry.playerName });
              }}
              existing={visibleFeedbackLog.find(e => e.playerId === feedbackPlayer.id || e.playerUid === feedbackPlayer.id)}
            />
          )
          : (
            <div style={{ padding:'0 20px', display:'flex', flexDirection:'column', gap: 10 }}>
              <Label>{isRu ? `Выберите: ${playerLabel.toLowerCase()}` : isTr ? `${playerLabel} seç` : 'Select player'}</Label>
              {!isMock && assignedTeams.length === 0 ? (
                <SoftState message={isRu ? `Вам пока не назначена ${teamLabel.toLowerCase()}.` : isTr ? `Henüz size atanmış ${teamLabel.toLowerCase()} yok.` : `No ${isSwimming ? 'groups' : 'teams'} assigned yet.`}/>
              ) : !isMock && !selectedTeamId ? (
                <SoftState message={isRu ? `Сначала выберите: ${teamLabel.toLowerCase()}.` : isTr ? `Önce ${teamLabel.toLowerCase()} seç.` : 'Select a team first.'}/>
              ) : !isMock && playersLoading ? (
                <LoadingDots/>
              ) : !isMock && (listenerErrors.players || listenerErrors.feedback) ? (
                <SoftState tone="error" message={listenerErrors.players || listenerErrors.feedback}/>
              ) : players.map(p => {
                const last = visibleFeedbackLog.find(e => e.playerId === p.id || e.playerUid === p.id);
                const preview = last
                  ? (last.notes || (last.ratings ? `${last.ratings.technique || '–'}/5 · ${last.ratings.intensity || '–'}/5 · ${last.ratings.attitude || '–'}/5` : (isRu ? 'Быстрая оценка сохранена' : isTr ? 'Hızlı puan kaydedildi' : 'Quick rating saved')))
                  : (isRu ? 'Пока нет заметок' : isTr ? 'Henüz not yok' : 'No note yet');
                return (
                  <button key={p.id} onClick={() => setFeedbackPlayer(p)} style={{
                    background:'#141414', border:'1px solid rgba(255,255,255,0.06)',
                    borderRadius:12, padding:'10px 12px', cursor:'pointer',
                    display:'flex', alignItems:'center', gap:12, textAlign:'left', width:'100%' }}>
                    <Avatar initials={p.name.split(' ').map(s=>s[0]).join('')} size={32}/>
                    <div style={{ flex:1, minWidth:0 }}>
                      <div style={{ fontFamily:'Manrope', fontWeight:700, fontSize:13, color:'#fff' }}>{p.name}</div>
                      <div style={{ fontFamily:'JetBrains Mono', fontSize:10,
                        color: last ? '#00FF88' : '#4A4A4A',
                        whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' }}>
                        {preview.length > 36 ? preview.slice(0,36)+'…' : preview}
                      </div>
                    </div>
                    <Ico name="chev" size={14} style={{ color:'#4A4A4A', flexShrink:0 }}/>
                  </button>
                );
              })}
              {!isMock && !playersLoading && !listenerErrors.players && !listenerErrors.feedback && players.length === 0 && (
                <SoftState
                  message={isRu ? 'Сначала добавьте участников, чтобы оставить отзыв.' : isTr ? `Not almak için önce ${playerLabel.toLowerCase()} gerekli.` : 'Add players first to record feedback.'}
                  hint={isRu ? 'Одобренные участники появятся здесь для выбора.' : isTr ? `${playerLabelPl} onaylandığında burada seçilebilir olacak.` : 'Approved players will become selectable here.'}/>
              )}

              {visibleFeedbackLog.length > 0 && (
                <>
                  <Label style={{ marginTop: 6 }}>{isRu ? 'Последние заметки' : isTr ? 'Son notlar' : 'Recent notes'}</Label>
                  {visibleFeedbackLog.slice(0,5).map((e,i) => (
                    <Card key={i} style={{ padding:12 }}>
                      <div style={{ display:'flex', justifyContent:'space-between',
                        alignItems:'baseline', gap:8, marginBottom: e.notes ? 6 : 0 }}>
                        <span style={{ fontFamily:'Manrope', fontWeight:700, fontSize:12, color:'#fff' }}>{e.playerName}</span>
                        <div style={{ display:'flex', gap:8 }}>
                          {['technique','intensity','attitude'].map(k => (
                            <span key={k} style={{ fontFamily:'JetBrains Mono', fontSize:9,
                              color: (e.ratings?.[k] || 0) >= 4 ? 'var(--nx-accent)' : (e.ratings?.[k] || 0) >= 3 ? (isSwimming ? '#B8B8B8' : '#FFB800') : '#FF6B6B' }}>
                              {e.ratings?.[k] || '–'}
                            </span>
                          ))}
                        </div>
                      </div>
                      {e.notes && (
                        <div style={{ fontFamily:'Manrope', fontSize:12, color:'#B8B8B8' }}>{e.notes}</div>
                      )}
                    </Card>
                  ))}
                </>
              )}
            </div>
          )
      )}

      {tab==='weekly' && (
        <div style={{ padding:'0 20px', display:'flex', flexDirection:'column', gap:12 }}>
          <div>
            <Label style={{ marginBottom:6, display:'block' }}>{isRu ? `${teamLabel} / группа` : isTr ? `${teamLabel} / grup` : `${isSwimming ? 'Group' : 'Team'} / group`}</Label>
            {!isMock && selectedTeam ? (
              <Card style={{ padding:12 }}>
                <div style={{ fontFamily:'Manrope', fontWeight:800, fontSize:13, color:'var(--nx-accent)' }}>{selectedTeam.name}</div>
              </Card>
            ) : teamsLoading ? (
              <LoadingDots pad="16px 0"/>
            ) : weeklyTeamOptions.length === 0 ? (
              <SoftState
                message={isRu ? `Для еженедельных отчётов сначала нужна ${teamLabel.toLowerCase()}.` : isTr ? `Haftalık rapor için önce ${teamLabel.toLowerCase()} gerekli.` : 'Create a team before weekly reports.'}
                hint={isRu ? `${teamLabel} создаётся в панели администратора.` : isTr ? `${teamLabel}lar admin panelinden oluşturulur.` : 'Teams are created from the admin dashboard.'}/>
            ) : (
              <select value={weeklyTeamId} onChange={e => { setWeeklyTeamId(e.target.value); setWeeklyError(''); }}
                style={{ ...weeklyFieldStyle, appearance:'none', WebkitAppearance:'none',
                  color: weeklyTeamId ? '#fff' : '#7A7A7A' }}>
                <option value="">{isRu ? `Выберите: ${teamLabel.toLowerCase()}` : isTr ? `${teamLabel} seç` : 'Select team'}</option>
                {weeklyTeamOptions.map(t => (
                  <option key={t.id} value={t.id} style={{ background:'#1C1C1C', color:'#fff' }}>{t.name}</option>
                ))}
              </select>
            )}
          </div>

          <div>
            <Label style={{ marginBottom:6, display:'block' }}>{isRu ? 'Начало недели' : isTr ? 'Hafta başlangıcı' : 'Week start'}</Label>
            <input type="date" value={weeklyStart} onChange={e => { setWeeklyStart(nxWeekStart(e.target.value)); setWeeklyDrafts({}); setWeeklyError(''); setWeeklyFormOpen(false); }}
              style={{ ...weeklyFieldStyle, colorScheme:'dark' }}/>
            <div style={{ fontFamily:'JetBrains Mono', fontSize:10, color:'#5A5A5A', marginTop:5 }}>
              {weeklyStart} → {weeklyWeekEnd}
            </div>
          </div>

          {!isMock && assignedTeams.length === 0 ? (
            <SoftState message={isRu ? `Вам пока не назначена ${teamLabel.toLowerCase()}.` : isTr ? `Henüz size atanmış ${teamLabel.toLowerCase()} yok.` : `No ${isSwimming ? 'groups' : 'teams'} assigned yet.`}/>
          ) : !isMock && !selectedTeamId ? (
            <SoftState
              message={isRu ? `Выберите ${teamLabel.toLowerCase()}у для еженедельных отчётов.` : isTr ? `Haftalık rapor için ${teamLabel.toLowerCase()} seç.` : 'Select a team for weekly reports.'}
              hint={isRu ? `Переключатель выше фильтрует всю панель ${coachLabel.toLowerCase()}а.` : isTr ? `Üstteki ${teamLabel.toLowerCase()} seçici tüm ${coachLabel.toLowerCase()} panelini filtreler.` : 'The team selector above filters the whole coach dashboard.'}/>
          ) : !isMock && weeklyLoading ? (
            <LoadingDots/>
          ) : !isMock && listenerErrors.weekly ? (
            <SoftState tone="error" message={listenerErrors.weekly}/>
          ) : !isMock && weeklyTeam && !weeklyFormOpen ? (
            <Card style={{ display:'flex', flexDirection:'column', alignItems:'center', gap:14,
              padding:'26px 18px', textAlign:'center' }}>
              <div style={{ width:44, height:44, borderRadius:14,
                background:reportsForSelectedWeek.length > 0 ? 'var(--nx-accent-soft)' : 'rgba(79,141,255,0.06)',
                border:`1px solid ${reportsForSelectedWeek.length > 0 ? 'var(--nx-accent-glow)' : 'rgba(79,141,255,0.20)'}`,
                display:'flex', alignItems:'center', justifyContent:'center' }}>
                <Ico name={reportsForSelectedWeek.length > 0 ? 'check' : 'chart'} size={22}
                  style={{ color:reportsForSelectedWeek.length > 0 ? 'var(--nx-accent)' : '#4F8DFF' }}/>
              </div>
              <div>
                <div style={{ fontFamily:'Oswald', fontWeight:700, fontSize:18,
                  textTransform:'uppercase', letterSpacing:'0.04em', color:'#fff', marginBottom:6 }}>
                  {reportsForSelectedWeek.length > 0
                    ? (isRu ? 'Отчёт за эту неделю готов.' : isTr ? 'Bu haftanın raporu hazırlandı.' : "This week's report has been created.")
                    : (isRu ? 'За эту неделю отчёт ещё не создан.' : isTr ? 'Bu hafta için henüz rapor oluşturulmadı.' : 'No weekly report has been created for this week yet.')}
                </div>
                <div style={{ fontFamily:'Manrope', fontSize:12, color:'#7A7A7A', lineHeight:1.5 }}>
                  {weeklyTeam.name} · {weeklyStart} → {weeklyWeekEnd}
                </div>
              </div>
              <Button kind="primary" full onClick={() => { setWeeklyDrafts({}); setWeeklyError(''); setWeeklySuccess(''); setWeeklyFormOpen(true); }}>
                {reportsForSelectedWeek.length > 0
                  ? (isRu ? 'Открыть / редактировать отчёт' : isTr ? 'Rapora bak / Düzenle' : 'View / Edit report')
                  : (isRu ? 'Создать еженедельный отчёт' : isTr ? 'Haftalık rapor oluştur' : 'Create weekly report')}
              </Button>
            </Card>
          ) : weeklyTeam && weeklyPlayers.length === 0 ? (
            <SoftState
              message={isRu ? `В этой ${teamLabel.toLowerCase()}е пока нет участников.` : isTr ? `Bu ${teamLabel.toLowerCase()}da ${playerLabel.toLowerCase()} yok.` : `No ${isSwimming ? 'swimmers in this group' : 'players in this team'}.`}
              hint={isRu ? `Назначьте участников в эту ${teamLabel.toLowerCase()}у через панель администратора.` : isTr ? `Admin panelinden ${playerLabelPl.toLowerCase()}ı ${teamLabel.toLowerCase()}a atayın.` : `Assign ${isSwimming ? 'swimmers' : 'players'} to this ${isSwimming ? 'group' : 'team'} from the admin dashboard.`}/>
          ) : weeklyTeam ? (
            <>
              <Card style={{ display:'flex', flexDirection:'column', gap:10 }}>
                <Label>{isRu ? 'Применить ко всем' : isTr ? 'Tümüne uygula' : 'Apply to all'}</Label>
                {[
                  ['effortRating', isRu ? 'Старание' : isTr ? 'Çaba' : 'Effort'],
                  ['disciplineRating', isRu ? 'Дисциплина' : isTr ? 'Disiplin' : 'Discipline'],
                  ['progressRating', isRu ? 'Прогресс' : isTr ? 'Gelişim' : 'Progress'],
                ].map(([field, label]) => (
                  <div key={field} style={{ display:'flex', alignItems:'center', justifyContent:'space-between', gap:10 }}>
                    <span style={{ fontFamily:'Manrope', fontSize:12, color:'#B8B8B8' }}>{label}</span>
                    <div style={{ display:'flex', gap:5 }}>
                      {[1,2,3,4,5].map(v => (
                        <button key={v} onClick={() => applyWeeklyRating(field, v)} style={{
                          width:28, height:28, borderRadius:8, cursor:'pointer',
                          background:'#1C1C1C', border:'1px solid rgba(255,255,255,0.08)',
                          color:'#B8B8B8', fontFamily:'JetBrains Mono', fontSize:11 }}>
                          {v}
                        </button>
                      ))}
                    </div>
                  </div>
                ))}
              </Card>

              {weeklyPlayers.map(p => {
                const d = draftForPlayer(p);
                const bonus = nxBonusState(d.bonusTypes, lang);
                const weeklyXp = nxWeeklyXp({ ...d, bonusXp: bonus.bonusXp });
                const existing = weeklyReports.find(r => r.playerUid === p.uid && r.teamId === weeklyTeam.id && r.weekStart === weeklyStart);
                const initials = (p.displayName || p.name || '–').split(' ').map(s => s[0]).join('').slice(0,2).toUpperCase();
                return (
                  <Card key={p.uid} style={{ display:'flex', flexDirection:'column', gap:12 }}>
                    <div style={{ display:'flex', alignItems:'center', gap:10 }}>
                      <Avatar initials={initials} size={34} avatarId={p.avatarId}/>
                      <div style={{ flex:1, minWidth:0 }}>
                        <div style={{ fontFamily:'Manrope', fontWeight:700, fontSize:13, color:'#fff',
                          whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' }}>
                          {p.displayName || p.name}
                        </div>
                        <div style={{ fontFamily:'JetBrains Mono', fontSize:10, color: existing ? '#00FF88' : '#7A7A7A' }}>
                          {existing
                            ? (isRu ? 'Сохранено за неделю · XP не дублируется' : isTr ? 'Bu hafta kayıtlı · XP tekrar eklenmez' : 'Saved this week · XP will not duplicate')
                            : (isRu ? 'Новый еженедельный отчёт' : isTr ? 'Yeni haftalık rapor' : 'New weekly report')}
                        </div>
                      </div>
                      <div style={{ fontFamily:'Oswald', fontWeight:700, fontSize:20, color:'#00FF88' }}>
                        +{weeklyXp}
                      </div>
                    </div>

                    <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:8 }}>
                      <div>
                        <Label style={{ marginBottom:4, display:'block' }}>{isRu ? 'Посетил' : isTr ? 'Katıldı' : 'Attended'}</Label>
                        <input type="number" min="0" value={d.attendanceAttended}
                          onChange={e => updateWeeklyDraft(p.uid, { attendanceAttended:e.target.value })}
                          style={weeklyFieldStyle}/>
                      </div>
                      <div>
                        <Label style={{ marginBottom:4, display:'block' }}>{isRu ? 'Всего' : isTr ? 'Toplam' : 'Total'}</Label>
                        <input type="number" min="0" value={d.attendanceTotal}
                          onChange={e => updateWeeklyDraft(p.uid, { attendanceTotal:e.target.value })}
                          style={weeklyFieldStyle}/>
                      </div>
                    </div>

                    {[
                      ['effortRating', isRu ? 'Старание' : isTr ? 'Çaba' : 'Effort'],
                      ['disciplineRating', isRu ? 'Дисциплина' : isTr ? 'Disiplin' : 'Discipline'],
                      ['progressRating', isRu ? 'Прогресс' : isTr ? 'Gelişim' : 'Progress'],
                    ].map(([field, label]) => (
                      <div key={field} style={{ display:'flex', alignItems:'center', justifyContent:'space-between', gap:10 }}>
                        <span style={{ fontFamily:'Manrope', fontSize:12, color:'#B8B8B8' }}>{label}</span>
                        <div style={{ display:'flex', gap:5 }}>
                          {[1,2,3,4,5].map(v => (
                            <button key={v} onClick={() => updateWeeklyDraft(p.uid, { [field]:v })} style={{
                              width:28, height:28, borderRadius:8, cursor:'pointer',
                              background: d[field] === v ? 'var(--nx-accent-soft)' : '#1C1C1C',
                              border:`1px solid ${d[field] === v ? 'var(--nx-accent-glow)' : 'rgba(255,255,255,0.08)'}`,
                              color: d[field] === v ? 'var(--nx-accent)' : '#B8B8B8',
                              fontFamily:'JetBrains Mono', fontSize:11 }}>
                              {v}
                            </button>
                          ))}
                        </div>
                      </div>
                    ))}

                    <div>
                      <Label style={{ marginBottom:6, display:'block' }}>{isRu ? 'Бонус' : isTr ? 'Bonus' : 'Bonus'}</Label>
                      <div style={{ display:'flex', gap:6, flexWrap:'wrap' }}>
                        {WEEKLY_BONUSES.map(b => {
                          const selected = (d.bonusTypes || []).includes(b.key);
                          return (
                            <button key={b.key} onClick={() => toggleWeeklyBonus(p.uid, b.key)} style={{
                              borderRadius:999, padding:'7px 10px', cursor:'pointer',
                              background: selected ? (isSwimming ? 'var(--nx-accent-soft)' : 'rgba(255,184,0,0.10)') : '#1C1C1C',
                              border:`1px solid ${selected ? (isSwimming ? 'var(--nx-accent-glow)' : 'rgba(255,184,0,0.45)') : 'rgba(255,255,255,0.06)'}`,
                              color: selected ? (isSwimming ? 'var(--nx-accent)' : '#FFB800') : '#7A7A7A',
                              fontFamily:'Manrope', fontWeight:700, fontSize:10 }}>
                              {isRu ? b.ru : isTr ? b.tr : b.en}{b.xp ? ` +${b.xp}` : ''}
                            </button>
                          );
                        })}
                        <span style={{ fontFamily:'JetBrains Mono', fontSize:10, color:isSwimming ? 'var(--nx-accent)' : '#FFB800',
                          alignSelf:'center', marginLeft:2 }}>
                          +{bonus.bonusXp} XP
                        </span>
                      </div>
                    </div>

                    <textarea value={d.coachNote} onChange={e => updateWeeklyDraft(p.uid, { coachNote:e.target.value })}
                      rows={2} placeholder={isRu ? `Необязательная заметка ${coachLabel.toLowerCase()}а...` : isTr ? 'Opsiyonel koç notu…' : 'Optional coach note…'}
                      style={{ ...weeklyFieldStyle, resize:'none', lineHeight:1.45 }}/>
                  </Card>
                );
              })}

              {weeklyError && (
                <div style={{ padding:'10px 12px', borderRadius:10,
                  background:'rgba(255,77,77,0.08)', border:'1px solid rgba(255,77,77,0.24)',
                  color:'#FF6B6B', fontFamily:'Manrope', fontSize:12, lineHeight:1.45 }}>
                  {weeklyError}
                </div>
              )}
              {weeklySuccess && (
                <div style={{ padding:'10px 12px', borderRadius:10,
                  background:'rgba(0,255,136,0.08)', border:'1px solid rgba(0,255,136,0.22)',
                  color:'#00FF88', fontFamily:'Manrope', fontSize:12, lineHeight:1.45 }}>
                  {weeklySuccess}
                </div>
              )}
              <Button kind="primary" full disabled={weeklySaving} onClick={saveWeeklyReports}>
                {weeklySaving
                  ? (isRu ? 'Сохранение...' : isTr ? 'Kaydediliyor...' : 'Saving...')
                  : (isRu ? 'Сохранить еженедельные отчёты' : isTr ? 'Haftalık raporları kaydet' : 'Save weekly reports')}
              </Button>
            </>
          ) : (
            <SoftState
              message={isRu ? `Выберите ${teamLabel.toLowerCase()}у, чтобы начать.` : isTr ? `Başlamak için ${teamLabel.toLowerCase()} seç.` : 'Select a team to start.'}
              hint={isRu ? 'XP рассчитывается автоматически при сохранении еженедельного отчёта.' : isTr ? 'XP, haftalık rapor kaydedildiğinde otomatik hesaplanır.' : 'XP is calculated automatically when weekly reports are saved.'}/>
          )}
        </div>
      )}

      {tab==='reports' && (
        reportPlayer ? (
          <CreateReportForm
            player={reportPlayer}
            lang={lang}
            isTr={isTr}
            onBack={() => setReportPlayer(null)}
            onSave={async data => {
              if (!isMock && window.NX) {
                try {
                  await window.NX.createReportAndAwardXP({
                    playerUid:      reportPlayer.uid || reportPlayer.id,
                    playerName:     reportPlayer.name,
                    academyId:      profile.academyId,
                    createdBy:      profile.uid,
                    createdByName:  profile.displayName || '',
                    ...data,
                  });
                  onToast && onToast({ msg: isRu ? 'Отчёт сохранён' : isTr ? 'Rapor kaydedildi' : 'Report saved', code: reportPlayer.name });
                } catch (e) {
                  onToast && onToast({ msg: isRu ? 'Ошибка сохранения' : isTr ? 'Kaydetme hatası' : 'Save failed' });
                  return;
                }
              } else {
                setReportLog(prev => [{ id: String(Date.now()), playerName: reportPlayer.name, ...data, createdAt: null }, ...prev]);
                onToast && onToast({ msg: isRu ? 'Демо: отчёт сохранён' : isTr ? 'Demo: Rapor kaydedildi' : 'Demo: Report saved', code: reportPlayer.name });
              }
              setReportPlayer(null);
            }}
          />
        ) : (
          <div style={{ padding:'0 20px', display:'flex', flexDirection:'column', gap:12 }}>
            <Label>{isRu ? `Создать отчёт — выберите участника` : isTr ? `Rapor oluştur — ${playerLabel.toLowerCase()} seç` : `Create report — select ${isSwimming ? 'swimmer' : 'player'}`}</Label>
            {players.map(p => (
              <button key={p.id} onClick={() => setReportPlayer(p)} style={{
                background:'#141414', border:'1px solid rgba(255,255,255,0.06)',
                borderRadius:12, padding:'10px 12px', cursor:'pointer',
                display:'flex', alignItems:'center', gap:12, textAlign:'left', width:'100%' }}>
                <Avatar initials={p.name.split(' ').map(s=>s[0]).join('').slice(0,2)} size={32}/>
                <div style={{ flex:1, minWidth:0 }}>
                  <div style={{ fontFamily:'Manrope', fontWeight:700, fontSize:13, color:'#fff' }}>{p.name}</div>
                  <div style={{ fontFamily:'JetBrains Mono', fontSize:10, color:'#7A7A7A' }}>{p.pos} · {p.age}</div>
                </div>
                <Ico name="chev" size={14} style={{ color:'#4A4A4A', flexShrink:0 }}/>
              </button>
            ))}
            {!isMock && playersLoading && (
              <LoadingDots pad="16px 0"/>
            )}
            {!isMock && (listenerErrors.players || listenerErrors.reports) && (
              <SoftState tone="error" message={listenerErrors.players || listenerErrors.reports}/>
            )}
            {!isMock && !playersLoading && !listenerErrors.players && players.length === 0 && (
              <SoftState
                message={isRu ? 'Сначала добавьте участников, чтобы создавать отчёты.' : isTr ? `Rapor oluşturmak için önce ${playerLabel.toLowerCase()} gerekli.` : `Add ${isSwimming ? 'swimmers' : 'players'} first to create reports.`}
                hint={isRu ? 'Вы сможете создавать отчёты, когда появятся одобренные участники.' : isTr ? `Onaylı ${playerLabelPl.toLowerCase()} geldiğinde rapor oluşturabilirsin.` : `You can create reports once approved ${isSwimming ? 'swimmers' : 'players'} appear.`}/>
            )}

            {/* Created reports list */}
            {!isMock && reportLoading ? (
              <LoadingDots pad="12px 0"/>
            ) : !listenerErrors.reports && reportLog.length === 0 ? (
              <SoftState
                message={isRu ? 'Отчёты пока не созданы.' : isTr ? 'Henüz rapor oluşturulmadı.' : 'No reports created yet.'}
                hint={isRu ? 'Выберите участника, чтобы создать первый отчёт.' : isTr ? `Bir ${playerLabel.toLowerCase()} seçerek ilk raporu oluştur.` : `Select a ${isSwimming ? 'swimmer' : 'player'} to create the first report.`}/>
            ) : reportLog.length > 0 && (
              <>
                <Label style={{ marginTop:4 }}>{isRu ? 'Созданные отчёты' : isTr ? 'Oluşturulan raporlar' : 'Created reports'}</Label>
                {reportLog.slice(0, 10).map((r, i) => (
                  <div key={r.id || i} style={{ background:'#141414', border:'1px solid rgba(255,255,255,0.06)',
                    borderRadius:12, padding:'10px 14px' }}>
                    <div style={{ display:'flex', justifyContent:'space-between', alignItems:'baseline', gap:8 }}>
                      <span style={{ fontFamily:'Manrope', fontWeight:700, fontSize:13, color:'#fff' }}>{r.playerName}</span>
                      <span style={{ fontFamily:'JetBrains Mono', fontSize:10, color:'#7A7A7A' }}>{r.title}</span>
                    </div>
                    {r.attendanceCount && (
                      <div style={{ fontFamily:'Manrope', fontSize:12, color:'#B8B8B8', marginTop:4 }}>
                        {isRu ? 'Посещаемость:' : isTr ? 'Katılım:' : 'Attendance:'} {r.attendanceCount}
                        {r.xpGained ? ` · XP +${r.xpGained}` : ''}
                      </div>
                    )}
                  </div>
                ))}
              </>
            )}
          </div>
        )
      )}

    </div>
  );
};

const ApprovalRow = ({ a, isTr, onToast }) => {
  const [decision, setDecision] = useS3(null); // null | 'approved' | 'rejected'
  if (decision) {
    return (
      <Card style={{ padding: 14, opacity: 0.6 }}>
        <div style={{ display:'flex', alignItems:'center', gap: 10 }}>
          <Avatar initials={a.p.split(' ').map(s=>s[0]).join('')} size={32}/>
          <div style={{ flex:1 }}>
            <div style={{ fontFamily:'Manrope', fontWeight:700, fontSize: 12, color:'#fff' }}>{a.p}</div>
            <div style={{ fontFamily:'Manrope', fontSize: 11, color:'#7A7A7A' }}>{a.c}</div>
          </div>
          <span style={{ fontFamily:'JetBrains Mono', fontSize: 9,
            letterSpacing:'0.10em', textTransform:'uppercase',
            color: decision==='approved' ? '#00FF88' : '#FF6B6B' }}>
            {decision==='approved'
              ? (isTr?'Onaylandı':'Approved')
              : (isTr?'Reddedildi':'Rejected')}
          </span>
        </div>
      </Card>
    );
  }
  return (
    <Card style={{ padding: 14 }}>
      <div style={{ display:'flex', alignItems:'center', gap: 12 }}>
        <Avatar initials={a.p.split(' ').map(s=>s[0]).join('')} size={36}/>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontFamily:'Manrope', fontWeight:700, fontSize: 12, color:'#fff' }}>{a.p}</div>
          <div style={{ fontFamily:'Manrope', fontSize: 12, color:'#B8B8B8' }}>{a.c}</div>
          <div style={{ fontFamily:'JetBrains Mono', fontSize: 10, color:'#7A7A7A', marginTop: 2 }}>{a.ev} · +{a.xp} XP</div>
        </div>
        <div style={{ display:'flex', gap: 6 }}>
          <button onClick={() => { setDecision('rejected');
            onToast && onToast({ msg: isTr?'Reddedildi':'Rejected', code: a.p }); }}
            style={{ width: 32, height: 32, borderRadius: 10, cursor:'pointer',
              background:'#1C1C1C', border:'1px solid rgba(255,255,255,0.06)', color:'#FF3B30',
              display:'flex', alignItems:'center', justifyContent:'center' }}>
            <span style={{ fontFamily:'Manrope', fontWeight: 800, fontSize: 18, lineHeight: 1 }}>×</span>
          </button>
          <button onClick={() => { setDecision('approved');
            onToast && onToast({ xp: a.xp }); }}
            style={{ width: 32, height: 32, borderRadius: 10, cursor:'pointer',
              background:'rgba(0,255,136,0.10)', border:'1px solid rgba(0,255,136,0.40)', color:'#00FF88',
              display:'flex', alignItems:'center', justifyContent:'center' }}>
            <Ico name="check" size={14}/>
          </button>
        </div>
      </div>
    </Card>
  );
};

const CoachStat = ({ label, value, accent }) => (
  <div style={{ background:'#141414', border:'1px solid rgba(255,255,255,0.06)',
    borderRadius: 12, padding: '12px 10px' }}>
    <span style={{ fontFamily:'Manrope', fontWeight: 800, fontSize: 9,
      letterSpacing:'0.12em', textTransform:'uppercase', color:'#7A7A7A',
      display:'block', whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' }}>{label}</span>
    <div style={{ fontFamily:'Oswald', fontWeight: 700, fontSize: 22, color: accent,
      lineHeight: 1, marginTop: 6 }}>{value}</div>
  </div>
);

const RosterRow = ({ p, lang, attended, onToggle }) => {
  const [localAtt, setLocalAtt] = useS3(p.attended);
  const isControlled = onToggle !== undefined;
  const att = isControlled ? !!attended : localAtt;
  const handleToggle = () => {
    if (isControlled) onToggle(!att);
    else setLocalAtt(a => !a);
  };
  return (
    <div style={{ background:'#141414', border:'1px solid rgba(255,255,255,0.06)',
      borderRadius: 12, padding:'10px 12px',
      display:'flex', alignItems:'center', gap: 12 }}>
      <Avatar initials={p.name.split(' ').map(s=>s[0]).join('')} size={32}/>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontFamily:'Manrope', fontWeight: 700, fontSize: 13, color:'#fff' }}>{p.name}</div>
        <div style={{ fontFamily:'JetBrains Mono', fontSize: 10, color:'#7A7A7A' }}>{p.pos} · {p.age}</div>
      </div>
      {p.flag && (
        <span style={{ fontFamily:'Manrope', fontWeight: 700, fontSize: 9,
          letterSpacing:'0.14em', textTransform:'uppercase', color:'#FFB800',
          background:'rgba(255,184,0,0.06)', border:'1px solid rgba(255,184,0,0.25)',
          padding:'3px 7px', borderRadius: 999 }}>
          {lang === 'ru' ? 'Есть заметка' : lang==='tr'?'Bildirim var':'Note'}
        </span>
      )}
      <button onClick={handleToggle} style={{
        width: 32, height: 32, borderRadius: 10, cursor:'pointer',
        background: att ? 'rgba(0,255,136,0.10)' : '#1C1C1C',
        border: `1px solid ${att ? 'rgba(0,255,136,0.40)' : 'rgba(255,255,255,0.06)'}`,
        color: att ? '#00FF88' : '#7A7A7A',
        display:'flex', alignItems:'center', justifyContent:'center' }}>
        <Ico name="check" size={14}/>
      </button>
    </div>
  );
};

const RatingRow = ({ p, lang, onRate }) => {
  const [r, setR] = useS3(p.rating || 0);
  const isSwimming = window.NXT_THEME?.sportType === 'swimming';
  return (
    <div style={{ background:'#141414', border:'1px solid rgba(255,255,255,0.06)',
      borderRadius: 12, padding: 12 }}>
      <div style={{ display:'flex', alignItems:'center', gap: 10, marginBottom: 10 }}>
        <Avatar initials={p.name.split(' ').map(s=>s[0]).join('')} size={32}/>
        <div style={{ flex: 1 }}>
          <div style={{ fontFamily:'Manrope', fontWeight: 700, fontSize: 13, color:'#fff' }}>{p.name}</div>
          <div style={{ fontFamily:'JetBrains Mono', fontSize: 10, color:'#7A7A7A' }}>{p.pos}</div>
        </div>
        <span style={{ fontFamily:'Oswald', fontWeight: 700, fontSize: 24,
          color: r >= 8 ? 'var(--nx-accent)' : r >= 6 ? (isSwimming ? '#B8B8B8' : '#FFB800') : r > 0 ? '#fff' : '#4A4A4A' }}>
          {r || '–'}
        </span>
      </div>
      <div style={{ display:'flex', gap: 4 }}>
        {[1,2,3,4,5,6,7,8,9,10].map(n => (
          <button key={n} onClick={() => { setR(n); onRate && onRate(n); }} style={{
            flex: 1, height: 28, borderRadius: 6, cursor:'pointer',
            background: n <= r ? (r>=8?'var(--nx-accent)':r>=6?(isSwimming?'#B8B8B8':'#FFB800'):'#fff') : '#1C1C1C',
            border:'none', color: n <= r ? '#0B0B0B' : '#7A7A7A',
            fontFamily:'JetBrains Mono', fontSize: 10, fontWeight: 600,
          }}>{n}</button>
        ))}
      </div>
    </div>
  );
};

// ────────────────────────────────────────────────────────────
// PLAYER REGISTRATION — self sign-up form (then awaits admin approval)
// ────────────────────────────────────────────────────────────
const PlayerRegistrationScreen = ({ lang, onBack, sportType: sportTypeProp, academyInfo }) => {
  const sportType   = academyInfo?.sportType || sportTypeProp || window.NXT_THEME?.sportType || 'football';
  const isSwimming  = sportType === 'swimming';
  const th          = window.getSportTheme ? window.getSportTheme(sportType) : {};
  const accent      = th.accent || (isSwimming ? '#38E8FF' : '#00FF88');

  const [email,         setEmail]         = useS3('');
  const [pw,            setPw]            = useS3('');
  const [name,          setName]          = useS3('');
  const [dateOfBirth,   setDateOfBirth]   = useS3('');
  const [position,      setPosition]      = useS3(''); // football: position code; swimming: style code
  const [parentFullName,setParentFullName]= useS3('');
  const [loading,       setLoading]       = useS3(false);
  const [error,         setError]         = useS3(null);
  const langKey = nxLangKey(lang);
  const isTr = langKey === 'tr';

  const calculatedAge = calculateAgeFromDOB(dateOfBirth);
  const isUnderage = calculatedAge != null && calculatedAge <= 11;

  const canSubmit = email.trim() && pw && name.trim() && dateOfBirth && parentFullName.trim() && !isUnderage;

  const handleSubmit = async () => {
    if (!canSubmit) return;
    setLoading(true);
    setError(null);
    try {
      console.log('[NX][signup] role: player | academy:', academyInfo?.id, academyInfo?.academyCode, 'sportType:', sportType);
      const cred = await window.NX.signUp(email.trim(), pw);
      console.log('[NX][signup] auth uid created:', cred.user.uid);
      const posLabel = isSwimming
        ? swimStyleLabel(position, lang)
        : (positionLabel(position, lang) || null);
      console.log('[NX][signup] writing profile → users/' + cred.user.uid);
      await window.NX.createUserProfile(cred.user.uid, {
        role:          'player',
        status:        'pending',
        displayName:   name.trim(),
        email:         email.trim(),
        academyId:     academyInfo?.id    || null,
        academyName:   academyInfo?.name  || null,
        academyCode:   academyInfo?.academyCode || null,
        sportType:     academyInfo?.sportType   || sportType || null,
        teamId:        null,
        coachUid:      null,
        position:      position || null,
        positionCode:  position || null,
        positionLabel: posLabel || null,
        parentFullName: parentFullName.trim(),
        dateOfBirth,
        calculatedAge,
        lang,
        xp:            0,
      });
      console.log('[NX][signup] profile write OK');
      const freshProfile = await window.NX.getUserProfile(cred.user.uid);
      window.dispatchEvent(new CustomEvent('nx-profile-created', { detail: freshProfile }));
    } catch (e) {
      console.error('[NX][signup] player signup failed:', e.code, e.message);
      setError(fbMsg(e.code, lang));
    } finally {
      setLoading(false);
    }
  };

  const fieldLabel = isSwimming
    ? (lang === 'ru' ? 'Предпочтительный стиль' : isTr ? 'Tercih edilen stil' : 'Preferred style')
    : (lang === 'ru' ? 'Предпочтительная позиция' : isTr ? 'Tercih edilen pozisyon' : 'Preferred position');

  const options = isSwimming ? SWIM_STYLE_OPTIONS : POSITION_OPTIONS;

  return (
    <div style={{ display:'flex', flexDirection:'column', height:'100%', background:'#0B0B0B',
      overflowY:'auto' }}>
      {/* Header */}
      <div style={{ padding:'68px 20px 0', display:'flex', alignItems:'center', gap: 12 }}>
        <button onClick={onBack} style={{
          width: 32, height: 32, borderRadius: 999, background:'#1C1C1C',
          border:'1px solid rgba(255,255,255,0.06)', color:'#fff', cursor:'pointer',
          display:'flex', alignItems:'center', justifyContent:'center', flexShrink: 0 }}>
          <Ico name="chev" size={16}/>
        </button>
        <div>
          <Label color={accent}>{nxTxt(lang, 'Akademi Kaydı', 'Academy Registration', 'Регистрация в академии')}</Label>
          <h1 style={{ fontFamily:'Oswald', fontWeight: 700, fontSize: 26, lineHeight: 1.0,
            textTransform:'uppercase', letterSpacing:'0.02em', color:'#fff', margin:'4px 0 0' }}>
            {lang === 'ru'
              ? (isSwimming ? 'Новый пловец' : 'Новый спортсмен')
              : isTr ? 'Yeni sporcu' : 'New athlete'}<span style={{ color: accent }}>.</span>
          </h1>
        </div>
      </div>

      <div style={{ padding: 20, display:'flex', flexDirection:'column', gap: 12 }}>
        {/* Auth fields */}
        <FieldInput placeholder={nxTxt(lang, 'E-posta', 'Email', 'E-mail')} value={email}
          onChange={v => { setEmail(v); setError(null); }} type="email"/>
        <FieldInput placeholder={nxTxt(lang, 'Parola (en az 6 karakter)', 'Password (min. 6 characters)', 'Пароль (минимум 6 символов)')} value={pw}
          onChange={v => { setPw(v); setError(null); }} type="password"/>

        {/* Profile fields */}
        <FieldInput placeholder={nxTxt(lang, 'Ad Soyad', 'Full name', 'Имя и фамилия')} value={name} onChange={setName}/>
        <DateOfBirthField lang={lang} value={dateOfBirth}
          onChange={v => { setDateOfBirth(v); setError(null); }}/>
        {calculatedAge != null && (
          <div style={{ fontFamily:'Manrope', fontSize:12, color:'#7A7A7A', marginTop:-6 }}>
            {nxTxt(lang, 'Hesaplanan yaş:', 'Calculated age:', 'Рассчитанный возраст:')} {calculatedAge}
          </div>
        )}

        {/* Position / style picker — sport-specific */}
        <div>
          <Label style={{ marginBottom: 6, display:'block' }}>{fieldLabel}</Label>
          <div style={{ display:'flex', flexWrap:'wrap', gap: 6 }}>
            {options.map(p => (
              <Chip key={p.code} on={position===p.code} color={accent} onClick={() => setPosition(p.code)}>
                {lang === 'ru' ? p.ru : isTr ? p.tr : p.en}
              </Chip>
            ))}
          </div>
        </div>

        <FieldInput placeholder={nxTxt(lang, 'Veli/vası adı soyadı', 'Parent/guardian full name', 'Имя и фамилия родителя/опекуна')}
          value={parentFullName} onChange={v => { setParentFullName(v); setError(null); }}/>

        <div style={{ padding: 12, borderRadius: 10,
          background: isUnderage ? 'rgba(255,184,0,0.06)' : 'rgba(255,255,255,0.02)',
          border:`1px solid ${isUnderage ? 'rgba(255,184,0,0.25)' : 'rgba(255,255,255,0.06)'}` }}>
          <div style={{ fontFamily:'Manrope', fontSize: 12,
            color: isUnderage ? '#FFB800' : '#7A7A7A', lineHeight: 1.5 }}>
            {nxTxt(lang,
              '11 yaş ve altındaki sporcular veli tarafından kaydedilmelidir.',
              'Athletes age 11 and under should be registered by a parent/guardian.',
              'Спортсменов 11 лет и младше должен регистрировать родитель или опекун.')}
          </div>
          {isUnderage && (
            <button onClick={onBack} style={{ marginTop:8, padding:0, background:'none', border:'none',
              fontFamily:'Manrope', fontWeight:700, fontSize:12, color:'#4F8DFF', cursor:'pointer' }}>
              {nxTxt(lang, 'Veli kaydını seçmek için geri dön →', 'Go back to choose Parent signup →', 'Вернуться и выбрать регистрацию родителя →')}
            </button>
          )}
        </div>

        {/* Error */}
        {error && (
          <div style={{ padding:'10px 14px', borderRadius: 10,
            background:'rgba(255,80,80,0.08)', border:'1px solid rgba(255,80,80,0.30)' }}>
            <span style={{ fontFamily:'Manrope', fontSize: 12, color:'#FF6B6B' }}>{error}</span>
          </div>
        )}

        <div style={{ padding: 12, borderRadius: 10,
          background:`${accent}08`, border:`1px solid ${accent}33` }}>
          <div style={{ fontFamily:'Manrope', fontSize: 12, color:'#B8B8B8', lineHeight: 1.5 }}>
            {nxTxt(lang,
              '✓ Kayıt gönderildikten sonra akademi yöneticisi hesabını onaylayacak.',
              '✓ After sign-up, an academy admin will review and approve your account.',
              '✓ После регистрации администратор академии проверит и одобрит ваш аккаунт.')}
          </div>
        </div>

        <div style={{ marginTop: 4 }}>
          <Button kind="primary" full size="lg" icon={loading ? null : 'arrow'}
            onClick={handleSubmit} disabled={loading || !canSubmit}>
            {loading ? nxTxt(lang, 'Gönderiliyor…', 'Submitting…', 'Отправка…') : nxTxt(lang, 'Kaydı gönder', 'Submit registration', 'Отправить регистрацию')}
          </Button>
        </div>
      </div>
    </div>
  );
};

// ────────────────────────────────────────────────────────────
// COACH SIGNUP — pending admin approval
// ────────────────────────────────────────────────────────────
const CoachSignupScreen = ({ lang, onBack, academyInfo }) => {
  const [email,   setEmail]   = useS3('');
  const [pw,      setPw]      = useS3('');
  const [name,    setName]    = useS3('');
  const [phone,   setPhone]   = useS3('');
  const [loading, setLoading] = useS3(false);
  const [error,   setError]   = useS3(null);
  const langKey = nxLangKey(lang);
  const isTr = langKey === 'tr';
  const isRu = langKey === 'ru';
  const isSwimming = academyInfo?.sportType === 'swimming';
  const coachLabel = isSwimming ? nxTxt(lang, 'Eğitmen', 'Instructor', 'Инструктор') : nxTxt(lang, 'Koç', 'Coach', 'Тренер');
  const coachAccent = '#FFB800';

  const canSubmit = email.trim() && pw && name.trim();

  const handleSubmit = async () => {
    if (!canSubmit) return;
    setLoading(true);
    setError(null);
    try {
      console.log('[NX][signup] role: coach | academy:', academyInfo?.id, academyInfo?.academyCode, 'sportType:', academyInfo?.sportType);
      const cred = await window.NX.signUp(email.trim(), pw);
      console.log('[NX][signup] auth uid created:', cred.user.uid);
      console.log('[NX][signup] writing profile → users/' + cred.user.uid);
      await window.NX.createUserProfile(cred.user.uid, {
        role:        'coach',
        status:      'pending',
        displayName: name.trim(),
        email:       email.trim(),
        phone:       phone.trim(),
        academyId:   academyInfo?.id          || null,
        academyName: academyInfo?.name        || null,
        academyCode: academyInfo?.academyCode || null,
        sportType:   academyInfo?.sportType   || null,
        lang,
      });
      console.log('[NX][signup] profile write OK');
      const freshProfile = await window.NX.getUserProfile(cred.user.uid);
      window.dispatchEvent(new CustomEvent('nx-profile-created', { detail: freshProfile }));
    } catch (e) {
      console.error('[NX][signup] coach signup failed:', e.code, e.message);
      setError(fbMsg(e.code, lang));
    } finally {
      setLoading(false);
    }
  };

  return (
    <div style={{ display:'flex', flexDirection:'column', height:'100%', background:'#0B0B0B', overflowY:'auto' }}>
      <div style={{ padding:'68px 20px 0', display:'flex', alignItems:'center', gap: 12 }}>
        <button onClick={onBack} style={{ width:32, height:32, borderRadius:999, background:'#1C1C1C',
          border:'1px solid rgba(255,255,255,0.06)', color:'#fff', cursor:'pointer',
          display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}>
          <Ico name="chev" size={16}/>
        </button>
        <div>
          <Label color={coachAccent}>{nxTxt(lang, `${coachLabel} Kaydı`, `${coachLabel} Sign Up`, `Регистрация: ${coachLabel}`)}</Label>
          <h1 style={{ fontFamily:'Oswald', fontWeight:700, fontSize:26, lineHeight:1.0,
            textTransform:'uppercase', letterSpacing:'0.02em', color:'#fff', margin:'4px 0 0' }}>
            {nxTxt(lang, 'Akademiye katıl', 'Join academy', 'Присоединиться к академии')}<span style={{ color:coachAccent }}>.</span>
          </h1>
        </div>
      </div>
      <div style={{ padding:20, display:'flex', flexDirection:'column', gap:12 }}>
        {/* Academy info — pre-filled from code validation */}
        {academyInfo && (
          <div style={{ padding:12, borderRadius:10, background:'rgba(255,184,0,0.05)',
            border:'1px solid rgba(255,184,0,0.20)', display:'flex', flexDirection:'column', gap:2 }}>
            <div style={{ fontFamily:'JetBrains Mono', fontSize:8, color:'#FFB800',
              letterSpacing:'0.14em', textTransform:'uppercase' }}>
              {nxTxt(lang, 'Akademi', 'Academy', 'Академия')}
            </div>
            <div style={{ fontFamily:'Manrope', fontWeight:700, fontSize:14, color:'#fff' }}>
              {academyInfo.name}
            </div>
          </div>
        )}
        <FieldInput placeholder={nxTxt(lang, 'E-posta', 'Email', 'E-mail')} value={email}
          onChange={v => { setEmail(v); setError(null); }} type="email"/>
        <FieldInput placeholder={nxTxt(lang, 'Parola (en az 6 karakter)', 'Password (min. 6 characters)', 'Пароль (минимум 6 символов)')} value={pw}
          onChange={v => { setPw(v); setError(null); }} type="password"/>
        <FieldInput placeholder={nxTxt(lang, 'Ad Soyad', 'Full name', 'Имя и фамилия')} value={name} onChange={setName}/>
        <FieldInput placeholder={nxTxt(lang, 'Telefon', 'Phone', 'Телефон')} value={phone} onChange={setPhone} type="tel"/>
        <div style={{ padding:12, borderRadius:10, background:'rgba(255,184,0,0.05)',
          border:'1px solid rgba(255,184,0,0.20)' }}>
          <div style={{ fontFamily:'Manrope', fontSize:12, color:'#B8B8B8', lineHeight:1.5 }}>
            {isRu
              ? `Ваш аккаунт ${coachLabel.toLowerCase()}а станет активным после одобрения администратором академии.`
              : isTr
              ? `${coachLabel} hesabın akademi yöneticisi tarafından onaylandıktan sonra aktif olur.`
              : `Your ${coachLabel.toLowerCase()} account becomes active after academy admin approval.`}
          </div>
        </div>
        {error && (
          <div style={{ padding:'10px 14px', borderRadius:10,
            background:'rgba(255,80,80,0.08)', border:'1px solid rgba(255,80,80,0.30)' }}>
            <span style={{ fontFamily:'Manrope', fontSize:12, color:'#FF6B6B' }}>{error}</span>
          </div>
        )}
        <Button kind="primary" full size="lg" icon={loading?null:'arrow'}
          onClick={handleSubmit} disabled={loading || !canSubmit}>
          {loading ? nxTxt(lang, 'Gönderiliyor…', 'Submitting…', 'Отправка…') : nxTxt(lang, 'Kaydı tamamla', 'Complete sign up', 'Завершить регистрацию')}
        </Button>
      </div>
    </div>
  );
};

// ────────────────────────────────────────────────────────────
// PARENT SIGNUP — pending admin approval
// ────────────────────────────────────────────────────────────
const ParentSignupScreen = ({ lang, onBack, sportType: sportTypeProp, academyInfo }) => {
  const [email,      setEmail]      = useS3('');
  const [pw,         setPw]         = useS3('');
  const [name,       setName]       = useS3('');
  const [phone,      setPhone]      = useS3('');
  const [childName,  setChildName]  = useS3('');
  const [childDateOfBirth, setChildDateOfBirth] = useS3('');
  const [childDOBValid, setChildDOBValid] = useS3(true);
  const [childPosition, setChildPosition] = useS3('');
  const [loading,    setLoading]    = useS3(false);
  const [error,      setError]      = useS3(null);
  const langKey = nxLangKey(lang);
  const isTr = langKey === 'tr';
  const sportType = academyInfo?.sportType || sportTypeProp || window.NXT_THEME?.sportType || 'football';
  const isSwimming = sportType === 'swimming';
  const preferenceOptions = isSwimming ? SWIM_STYLE_OPTIONS : POSITION_OPTIONS;

  const canSubmit = email.trim() && pw && name.trim() && phone.trim() && childName.trim() && childDOBValid;
  const childCalculatedAge = calculateAgeFromDOB(childDateOfBirth);

  const handleSubmit = async () => {
    if (!canSubmit) return;
    setLoading(true);
    setError(null);
    try {
      console.log('[NX][signup] role: parent | academy:', academyInfo?.id, academyInfo?.academyCode, 'sportType:', sportType);
      const cred = await window.NX.signUp(email.trim(), pw);
      console.log('[NX][signup] auth uid created:', cred.user.uid);
      console.log('[NX][signup] writing profile → users/' + cred.user.uid);
      await window.NX.createUserProfile(cred.user.uid, {
        role:              'parent',
        status:            'pending',
        displayName:       name.trim(),
        email:             email.trim(),
        phone:             phone.trim(),
        academyId:         academyInfo?.id          || null,
        academyName:       academyInfo?.name        || null,
        academyCode:       academyInfo?.academyCode || null,
        sportType:         academyInfo?.sportType   || sportType || null,
        childFullName:     childName.trim(),
        requestedChildName: childName.trim(),
        childDateOfBirth:  childDateOfBirth || null,
        childCalculatedAge,
        childPositionCode: childPosition || null,
        childPositionLabel: (isSwimming ? swimStyleLabel(childPosition, lang) : positionLabel(childPosition, lang)) || null,
        linkedPlayerName:  null,
        playerUid:         null,
        lang,
      });
      console.log('[NX][signup] profile write OK');
      const freshProfile = await window.NX.getUserProfile(cred.user.uid);
      window.dispatchEvent(new CustomEvent('nx-profile-created', { detail: freshProfile }));
    } catch (e) {
      console.error('[NX][signup] parent signup failed:', e.code, e.message);
      setError(fbMsg(e.code, lang));
    } finally {
      setLoading(false);
    }
  };

  return (
    <div style={{ display:'flex', flexDirection:'column', height:'100%', background:'#0B0B0B', overflowY:'auto' }}>
      <div style={{ padding:'68px 20px 0', display:'flex', alignItems:'center', gap: 12 }}>
        <button onClick={onBack} style={{ width:32, height:32, borderRadius:999, background:'#1C1C1C',
          border:'1px solid rgba(255,255,255,0.06)', color:'#fff', cursor:'pointer',
          display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}>
          <Ico name="chev" size={16}/>
        </button>
        <div>
          <Label color="#4F8DFF">{nxTxt(lang, 'Veli Kaydı', 'Parent Sign Up', 'Регистрация родителя')}</Label>
          <h1 style={{ fontFamily:'Oswald', fontWeight:700, fontSize:26, lineHeight:1.0,
            textTransform:'uppercase', letterSpacing:'0.02em', color:'#fff', margin:'4px 0 0' }}>
            {nxTxt(lang, 'Çocuğunu takip et', 'Follow your child', 'Следите за прогрессом ребёнка')}<span style={{ color:'#4F8DFF' }}>.</span>
          </h1>
        </div>
      </div>
      <div style={{ padding:20, display:'flex', flexDirection:'column', gap:12 }}>
        <div style={{ padding:12, borderRadius:10, background:'rgba(79,141,255,0.06)',
          border:'1px solid rgba(79,141,255,0.20)' }}>
          <div style={{ fontFamily:'Manrope', fontSize:12, color:'#B8B8B8', lineHeight:1.5 }}>
            {nxTxt(lang,
              'Veli hesabın onaylandıktan sonra akademi yöneticisi seni çocuğunla ilişkilendirir.',
              'After approval, the academy admin links your parent account to your child.',
              'После одобрения администратор академии свяжет ваш родительский аккаунт с ребёнком.')}
          </div>
        </div>
        <FieldInput placeholder={nxTxt(lang, 'E-posta', 'Email', 'E-mail')} value={email}
          onChange={v => { setEmail(v); setError(null); }} type="email"/>
        <FieldInput placeholder={nxTxt(lang, 'Parola (en az 6 karakter)', 'Password (min. 6 characters)', 'Пароль (минимум 6 символов)')} value={pw}
          onChange={v => { setPw(v); setError(null); }} type="password"/>
        <FieldInput placeholder={nxTxt(lang, 'Ad Soyad', 'Full name', 'Имя и фамилия')} value={name} onChange={setName}/>
        <FieldInput placeholder={nxTxt(lang, 'Telefon', 'Phone number', 'Телефон')}
          value={phone} onChange={v => { setPhone(v); setError(null); }} type="tel"/>
        <FieldInput placeholder={nxTxt(lang, 'Çocuk / Sporcu adı soyadı', 'Child / Athlete full name', 'Имя и фамилия ребёнка / спортсмена')}
          value={childName} onChange={v => { setChildName(v); setError(null); }}/>
        <DateOfBirthField lang={lang} value={childDateOfBirth} optional
          onValidityChange={setChildDOBValid}
          onChange={v => { setChildDateOfBirth(v); setError(null); }}/>
        {childCalculatedAge != null && (
          <div style={{ fontFamily:'Manrope', fontSize:12, color:'#7A7A7A', marginTop:-6 }}>
            {nxTxt(lang, 'Çocuk yaşı:', 'Child age:', 'Возраст ребёнка:')} {childCalculatedAge}
          </div>
        )}
        <div>
          <Label style={{ marginBottom: 6, display:'block' }}>
            {isSwimming
              ? (lang === 'ru' ? 'Предпочтительный стиль ребёнка (необязательно)' : isTr ? 'Çocuğun tercih ettiği stil (opsiyonel)' : "Child's preferred style (optional)")
              : (lang === 'ru' ? 'Предпочтительная позиция ребёнка (необязательно)' : isTr ? 'Çocuğun tercih ettiği pozisyon (opsiyonel)' : "Child's preferred position (optional)")}
          </Label>
          <div style={{ display:'flex', flexWrap:'wrap', gap: 6 }}>
            {preferenceOptions.map(p => (
              <Chip key={p.code} on={childPosition===p.code} onClick={() => setChildPosition(childPosition === p.code ? '' : p.code)}>
                {lang === 'ru' ? p.ru : isTr ? p.tr : p.en}
              </Chip>
            ))}
          </div>
        </div>
        {error && (
          <div style={{ padding:'10px 14px', borderRadius:10,
            background:'rgba(255,80,80,0.08)', border:'1px solid rgba(255,80,80,0.30)' }}>
            <span style={{ fontFamily:'Manrope', fontSize:12, color:'#FF6B6B' }}>{error}</span>
          </div>
        )}
        <Button kind="primary" full size="lg" icon={loading?null:'arrow'}
          onClick={handleSubmit} disabled={loading || !canSubmit}>
          {loading ? nxTxt(lang, 'Bağlanıyor…', 'Linking…', 'Связывание…') : nxTxt(lang, 'Hesap oluştur', 'Create account', 'Создать аккаунт')}
        </Button>
      </div>
    </div>
  );
};

// ────────────────────────────────────────────────────────────
// ADMIN APPLICATION — request academy admin / manager access
// ────────────────────────────────────────────────────────────
const AdminApplicationScreen = ({ lang, onBack }) => {
  const [email,       setEmail]       = useS3('');
  const [pw,          setPw]          = useS3('');
  const [name,        setName]        = useS3('');
  const [phone,       setPhone]       = useS3('');
  const [academyName, setAcademyName] = useS3('');
  const [sportType,   setSportType]   = useS3('football');
  const [reason,      setReason]      = useS3('');
  const [loading,     setLoading]     = useS3(false);
  const [error,       setError]       = useS3(null);
  const langKey = nxLangKey(lang);
  const isTr = langKey === 'tr';

  const canSubmit = email.trim() && pw && name.trim() && academyName.trim();

  const handleSubmit = async () => {
    if (!canSubmit) return;
    setLoading(true);
    setError(null);
    try {
      const normalizedEmail = email.trim().toLowerCase();

      // Check for a pending admin invite BEFORE creating Firebase Auth user.
      // If an invite exists, skip academy creation and auto-approve the admin.
      let invite = null;
      try {
        invite = window.NX.getAdminInvite ? await window.NX.getAdminInvite(normalizedEmail) : null;
        if (invite && invite.status !== 'pending') invite = null;
      } catch (_) { invite = null; }

      if (invite) {
        console.log('[NX][signup] admin invite found for', normalizedEmail, '→ academyId:', invite.academyId);
        const cred = await window.NX.signUp(normalizedEmail, pw);
        console.log('[NX][signup] auth uid:', cred.user.uid);
        await window.NX.createUserProfile(cred.user.uid, {
          role:        'admin',
          academyRole: 'admin',
          status:      'approved',
          displayName: name.trim(),
          email:       normalizedEmail,
          phone:       phone.trim(),
          academyId:   invite.academyId,
          academyName: invite.academyName,
          sportType:   invite.sportType || 'football',
          lang,
        });
        await window.NX.claimAdminInvite(normalizedEmail);
        console.log('[NX][signup] invited admin profile created + invite claimed');
        const freshProfile = await window.NX.getUserProfile(cred.user.uid);
        window.dispatchEvent(new CustomEvent('nx-profile-created', { detail: freshProfile }));
        return;
      }

      // No invite — standard new academy signup path.
      console.log('[NX][signup] role: admin | academyName:', academyName.trim(), 'sportType:', sportType);
      const cred = await window.NX.signUp(normalizedEmail, pw);
      console.log('[NX][signup] auth uid created:', cred.user.uid);
      console.log('[NX][signup] creating academy document…');
      const { id: academyId, academyCode } = await window.NX.createAcademy(cred.user.uid, academyName.trim(), sportType);
      console.log('[NX][signup] academy created:', academyId, 'code:', academyCode);
      console.log('[NX][signup] writing profile → users/' + cred.user.uid);
      await window.NX.createUserProfile(cred.user.uid, {
        role:        'admin',
        academyRole: 'owner',
        status:      'pending',
        displayName: name.trim(),
        email:       normalizedEmail,
        phone:       phone.trim(),
        academyName: academyName.trim(),
        academyId,
        academyCode,
        sportType,
        reason:      reason.trim(),
        lang,
      });
      console.log('[NX][signup] profile write OK');
      const freshProfile = await window.NX.getUserProfile(cred.user.uid);
      window.dispatchEvent(new CustomEvent('nx-profile-created', { detail: freshProfile }));
    } catch (e) {
      console.error('[NX][signup] admin signup failed:', e.code, e.message);
      setError(fbMsg(e.code, lang));
    } finally {
      setLoading(false);
    }
  };

  return (
    <div style={{ display:'flex', flexDirection:'column', height:'100%', background:'#0B0B0B',
      overflowY:'auto' }}>
      {/* Header */}
      <div style={{ padding:'68px 20px 0', display:'flex', alignItems:'center', gap: 12 }}>
        <button onClick={onBack} style={{
          width: 32, height: 32, borderRadius: 999, background:'#1C1C1C',
          border:'1px solid rgba(255,255,255,0.06)', color:'#fff', cursor:'pointer',
          display:'flex', alignItems:'center', justifyContent:'center', flexShrink: 0 }}>
          <Ico name="chev" size={16}/>
        </button>
        <div>
          <Label color="#B26BFF">{nxTxt(lang, 'Yönetici Başvurusu', 'Admin Application', 'Заявка администратора')}</Label>
          <h1 style={{ fontFamily:'Oswald', fontWeight: 700, fontSize: 24, lineHeight: 1.0,
            textTransform:'uppercase', letterSpacing:'0.02em', color:'#fff', margin:'4px 0 0' }}>
            {nxTxt(lang, 'Akademi erişimi', 'Academy access', 'Доступ к академии')}<span style={{ color:'#B26BFF' }}>.</span>
          </h1>
        </div>
      </div>

      <div style={{ padding: 20, display:'flex', flexDirection:'column', gap: 12 }}>

        {/* Info card */}
        <div style={{ padding: 12, borderRadius: 10, background:'rgba(178,107,255,0.06)',
          border:'1px solid rgba(178,107,255,0.20)' }}>
          <div style={{ fontFamily:'Manrope', fontSize: 12, color:'#B8B8B8', lineHeight: 1.5 }}>
            {nxTxt(lang,
              'Akademi yöneticisi olarak platform yönetimi için başvuruyorsunuz. Talebiniz superAdmin tarafından incelenecektir.',
              'You\'re applying for academy admin access to manage your academy on the platform. Your request will be reviewed by a superAdmin.',
              'Вы подаёте заявку на доступ администратора академии для управления академией на платформе. Запрос проверит superAdmin.')}
          </div>
        </div>

        {/* Auth */}
        <FieldInput placeholder={nxTxt(lang, 'E-posta', 'Email', 'E-mail')} value={email}
          onChange={v => { setEmail(v); setError(null); }} type="email"/>
        <FieldInput placeholder={nxTxt(lang, 'Parola (en az 6 karakter)', 'Password (min. 6 characters)', 'Пароль (минимум 6 символов)')} value={pw}
          onChange={v => { setPw(v); setError(null); }} type="password"/>

        {/* Profile */}
        <FieldInput placeholder={nxTxt(lang, 'Ad Soyad', 'Full name', 'Имя и фамилия')} value={name} onChange={setName}/>
        <FieldInput placeholder={nxTxt(lang, 'Telefon', 'Phone', 'Телефон')} value={phone} onChange={setPhone} type="tel"/>
        <FieldInput placeholder={nxTxt(lang, 'Akademi adı', 'Academy name', 'Название академии')} value={academyName} onChange={setAcademyName}/>

        <div>
          <Label style={{ marginBottom: 6, display:'block' }}>
            {nxTxt(lang, 'Spor türü', 'Sport type', 'Вид спорта')}
          </Label>
          <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:8 }}>
            {[['football', nxTxt(lang, 'Futbol', 'Football', 'Футбол'), '#00FF88'], ['swimming', nxTxt(lang, 'Yüzme', 'Swimming', 'Плавание'), '#38E8FF']].map(([type, label, color]) => {
              const on = sportType === type;
              return (
                <button key={type} onClick={() => setSportType(type)} style={{
                  padding:'12px 14px', borderRadius:10, cursor:'pointer',
                  background: on ? `${color}10` : '#1C1C1C',
                  border:`1px solid ${on ? `${color}66` : 'rgba(255,255,255,0.06)'}`,
                  color: on ? color : '#B8B8B8',
                  fontFamily:'Manrope', fontWeight:700, fontSize:13, textAlign:'left',
                }}>{label}</button>
              );
            })}
          </div>
        </div>

        {/* Reason — textarea */}
        <textarea
          placeholder={nxTxt(lang, 'Başvuru gerekçesi (opsiyonel)', 'Reason for access (optional)', 'Причина запроса доступа (необязательно)')}
          value={reason}
          onChange={e => setReason(e.target.value)}
          rows={3}
          style={{ padding:'12px', background:'#1C1C1C',
            border:'1px solid rgba(255,255,255,0.10)', borderRadius: 12,
            color:'#fff', fontFamily:'Manrope', fontSize: 16, outline:'none',
            resize:'none', width:'100%', boxSizing:'border-box' }}
        />

        {/* Error */}
        {error && (
          <div style={{ padding:'10px 14px', borderRadius: 10,
            background:'rgba(255,80,80,0.08)', border:'1px solid rgba(255,80,80,0.30)' }}>
            <span style={{ fontFamily:'Manrope', fontSize: 12, color:'#FF6B6B' }}>{error}</span>
          </div>
        )}

        <div style={{ marginTop: 4 }}>
          <Button kind="primary" full size="lg" icon={loading ? null : 'arrow'}
            onClick={handleSubmit} disabled={loading || !canSubmit}>
            {loading ? nxTxt(lang, 'Gönderiliyor…', 'Submitting…', 'Отправка…') : nxTxt(lang, 'Başvur', 'Submit application', 'Отправить заявку')}
          </Button>
        </div>
      </div>
    </div>
  );
};

// ────────────────────────────────────────────────────────────
// PENDING APPROVAL — shown after player self-registers
// ────────────────────────────────────────────────────────────
const PendingApprovalScreen = ({ lang, name, onBack }) => {
  const langKey = nxLangKey(lang);
  const isTr = langKey === 'tr';
  return (
    <div style={{ display:'flex', flexDirection:'column', height:'100%', background:'#0B0B0B',
      alignItems:'center', justifyContent:'center', padding: 28, textAlign:'center' }}>
      {/* Icon */}
      <div style={{ width: 72, height: 72, borderRadius: 20,
        background:'rgba(79,141,255,0.10)', border:'1px solid rgba(79,141,255,0.35)',
        display:'flex', alignItems:'center', justifyContent:'center', marginBottom: 24 }}>
        <Ico name="clock" size={32} style={{ color:'#4F8DFF' }}/>
      </div>

      <Label color="#4F8DFF" style={{ display:'block', marginBottom: 10 }}>
        {nxTxt(lang, 'Onay bekleniyor', 'Pending approval', 'Ожидает одобрения')}
      </Label>
      <h1 style={{ fontFamily:'Oswald', fontWeight: 700, fontSize: 28, lineHeight: 1.0,
        textTransform:'uppercase', letterSpacing:'0.02em', color:'#fff', margin:'0 0 12px' }}>
        {nxTxt(lang, 'Başvurun alındı', 'Application received', 'Заявка получена')}<span style={{ color:'#4F8DFF' }}>.</span>
      </h1>
      {name && (
        <div style={{ fontFamily:'Oswald', fontWeight: 700, fontSize: 20,
          color:'#00FF88', marginBottom: 12 }}>{name}</div>
      )}
      <div style={{ fontFamily:'Manrope', fontSize: 14, color:'#B8B8B8', lineHeight: 1.55,
        maxWidth: 300, marginBottom: 32 }}>
        {nxTxt(lang,
          'Akademi yöneticisi başvurunu inceleyecek. Onaylandığında e-posta ile bildirim alacaksın.',
          'The academy administrator will review your application. You\'ll get an email notification when approved.',
          'Администратор академии рассмотрит вашу заявку. После одобрения вы получите уведомление по e-mail.')}
      </div>

      {/* Steps */}
      <div style={{ width:'100%', maxWidth: 300, display:'flex', flexDirection:'column', gap: 10, marginBottom: 32 }}>
        {(lang === 'ru'
          ? [['check','Заявка отправлена','#00FF88'],['clock','Проверка администратором','#4F8DFF'],['lock','Активация аккаунта','#5A5A5A']]
          : isTr
          ? [['check','Başvuru gönderildi','#00FF88'],['clock','Admin incelemesi','#4F8DFF'],['lock','Hesap aktivasyonu','#5A5A5A']]
          : [['check','Application sent','#00FF88'],['clock','Admin review','#4F8DFF'],['lock','Account activation','#5A5A5A']]
        ).map(([ico,label,color],i) => (
          <div key={i} style={{ display:'flex', alignItems:'center', gap: 12 }}>
            <div style={{ width: 32, height: 32, borderRadius: 10, flexShrink: 0,
              background:`${color}12`, border:`1px solid ${color}40`,
              display:'flex', alignItems:'center', justifyContent:'center', color }}>
              <Ico name={ico} size={16}/>
            </div>
            <span style={{ fontFamily:'Manrope', fontWeight: 600, fontSize: 13, color: i<2?'#fff':'#5A5A5A' }}>
              {label}
            </span>
          </div>
        ))}
      </div>

      <Button kind="secondary" onClick={onBack}>
        {nxTxt(lang, '← Giriş ekranına dön', '← Back to sign in', '← Вернуться ко входу')}
      </Button>
    </div>
  );
};

Object.assign(window, {
  LoginScreen, RoleSelectScreen, CoachDashboardScreen, ROLE_LABEL,
  AcademyCodeEntryScreen,
  PlayerRegistrationScreen, CoachSignupScreen, ParentSignupScreen,
  AdminApplicationScreen, PendingApprovalScreen, DEMO_ROLES,
  FEEDBACK_CHIPS,
});
