// Shared header, footer, illustrations for Prajna hi-fi prototype

const NAV = [
  { label: 'Home', href: 'index.html' },
  { label: 'About', href: 'about.html' },
  { label: 'Syllabus', href: 'modules.html' },
  { label: 'Centers', href: 'centers.html' },
  { label: 'Showcase', href: 'showcase.html' },
  { label: 'FAQ', href: 'faq.html' },
  { label: 'Register', href: 'register.html' },
];

// Announcements posted by coordinators (public-facing). Seeded with real
// example content from the live site (prajna4me.org/announcements/.../96) so
// the prototype shows how a posted announcement looks. The actual posting
// backend is wired by the integrating team; here the list is static.
//   - `title`  : full headline, Title Case (used on archive + detail pages)
//   - `short`  : trimmed headline for the thin utility bar
//   - `date`   : ISO so it sorts lexicographically, newest-first
//   - coordinator + center => the "By {coordinator} @ {center}" attribution
// FEATURE FLAG. The announcements feature is fully built (announcement.html +
// announcements.html), but the team has not yet decided whether to add an
// announcements / events section to the live site. While it's `false`, nothing
// in the live UI links to those pages (utility-bar headline, "View All", and the
// footer link all key off this). Flip to `true` to surface it everywhere at once.
const ANNOUNCEMENTS_LIVE = false;

// Pin ONE announcement to the top utility bar WITHOUT turning on the full
// announcements section. The archive page, "View All", and footer link all stay
// gated on ANNOUNCEMENTS_LIVE (off); this only surfaces a single featured post
// in the utility bar, linking straight to its detail page. Set to an
// announcement id to feature it, or null to show none.
const FEATURED_ANN_ID = 200;

const ANNOUNCEMENTS = [
  {
    id: 96,
    slug: 'prajna-national-championship-pnc-2026-usa-finalists-and-winners',
    title: 'Prajna National Championship (PNC) 2026 USA Finalists and Winners',
    short: 'PNC 2026 USA: Finalists and Winners Announced',
    date: '2026-06-15',
    coordinator: 'Rajesh Kalidindi',
    center: 'Global LMiG',
    category: 'Results',
  },
  {
    id: 84,
    slug: 'prajna-national-championship-2025-finalists-and-winners',
    title: 'Prajna National Championship 2025 Finalists and Winners',
    short: 'PNC 2025 Finalists and Winners',
    date: '2025-05-14',
    coordinator: 'Rajesh Kalidindi',
    center: 'Global LMiG',
    category: 'Results',
  },
  {
    id: 77,
    slug: 'career-oriented-internships',
    title: 'Exciting Career-Oriented Internships: Join Us',
    short: 'Career-Oriented Internships: Join Us',
    date: '2025-01-11',
    coordinator: 'Prajna Team',
    center: 'JETUSA',
    category: 'Programs',
  },
  {
    id: 69,
    slug: 'prajna-uchcharana-certification-program',
    title: 'Prajna Uchcharana Certification Program',
    short: 'Uchcharana Certification Program',
    date: '2024-10-31',
    coordinator: 'Prajna Team',
    center: 'Teacher Training',
    category: 'Programs',
  },
  {
    // DRAFT — content sourced from the Bruhat Soma reel already on the homepage.
    // Confirm/adjust the wording, student, and date with the team.
    id: 200,
    slug: 'prajna-alumnus-bruhat-soma-2024-scripps-national-spelling-bee-champion',
    title: 'Prajna Alumnus Bruhat Soma: 2024 Scripps National Spelling Bee Champion',
    short: 'Congratulations to Prajna alumnus Bruhat Soma, 2024 Scripps National Spelling Bee Champion',
    date: '2024-05-30',
    coordinator: 'Prajna Team',
    center: 'JETUSA',
    category: 'Achievement',
  },
];

// Newest first. ISO date strings sort correctly as plain strings, so no Date.
const announcementsNewestFirst = () =>
  [...ANNOUNCEMENTS].sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));

// "2026-06-15" -> "15 Jun 2026". Manual parse avoids Date timezone drift.
const ANN_MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
const fmtDate = (iso) => {
  const [y, m, d] = String(iso).split('-');
  return `${parseInt(d, 10)} ${ANN_MONTHS[parseInt(m, 10) - 1]} ${y}`;
};

// Glue the last two words with a non-breaking space so a title never drops a
// single word/number onto its own line (no widows), e.g. the "2" in "(LMiG) 2".
const noWidow = (s) => {
  const t = String(s).trimEnd();
  const i = t.lastIndexOf(' ');
  return i === -1 ? t : t.slice(0, i) + ' ' + t.slice(i + 1);
};

// Student showcase — real student media. Square 1:1 cards (videos cropped from
// 9:16 portrait, image normalized). Used by the home carousel (home.jsx
// FShowcase) and the full Showcase page (pages.jsx ShowcasePage). Captions
// supplied by the team. Add more entries here as more photos/videos arrive.
const SHOWCASE_ITEMS = [
  {
    type: 'video',
    src: 'photos/showcase/harith.mp4',
    poster: 'photos/showcase/harith.jpg',
    name: 'Harith Kopperapu',
    center: 'Concord, NC',
    tag: 'Recitation',
    title: 'Maatha Pitha Guru Daivam',
    blurb: 'Our Module 2 student from Concord presents an in-depth overview of a parent’s love and our gratitude toward them.',
  },
  {
    type: 'image',
    src: 'photos/showcase/phaneendra.jpg',
    name: 'Phaneendra Bulusu',
    center: 'Charlotte, NC',
    tag: 'Achievement',
    title: 'PNC LMiG-2 Winner',
    blurb: 'Phaneendra Bulusu is our PNC LMiG-2 winner from Charlotte, and he also earned a top-10 spot in the 2026 Spelling Bee. A role model for all our Prajna students, he balances academics, his Prajna and LMiG-2 classes, and weekly Prajna volunteering as a Module 3 assistant teacher. He credits Prajna for his spelling bee win.',
  },
  {
    type: 'video',
    src: 'photos/showcase/pranav.mp4',
    poster: 'photos/showcase/pranav.jpg',
    name: 'Pranav',
    center: 'Frisco, TX',
    tag: 'Reflection',
    title: 'Lessons for Real Life',
    blurb: 'Our Frisco LMiG student credits the Prajna program for the ability to deal with real-life challenges.',
  },
  {
    type: 'video',
    src: 'photos/showcase/sudarshan.mp4',
    poster: 'photos/showcase/sudarshan.jpg',
    name: 'Sudarshan Rangarajan',
    center: 'Austin, TX',
    tag: 'Presentation',
    title: 'Karma, Akarma, and Vikarma',
    blurb: 'Sudarshan from our Austin chapter presents the three kinds of action: Karma, Akarma, and Vikarma, and the path of Karma Yoga, using a chart he made.',
  },
  {
    type: 'video',
    src: 'photos/showcase/samanvi.mp4',
    poster: 'photos/showcase/samanvi.jpg',
    name: 'Samanvi Akkineni',
    center: 'Pittsburgh, PA',
    tag: 'Recitation',
    title: 'A Prayerful Recitation',
    blurb: 'Samanvi from our Pittsburgh chapter offers a prayerful recitation.',
  },
];

const Brand = ({ light }) => (
  <a href="index.html" className="brand" aria-label="Prajna home" style={{ color: light ? '#fff' : 'var(--ink)' }}>
    <img src="assets/logo.jpg" alt="Prajna" className="brand__logo" />
  </a>
);

// Profile button — silhouette when logged out, colored initials when logged in.
// Universally legible state cue (Gmail/Slack pattern). Click → menu/login.
const ProfileButton = ({ state, onToggle, name = 'Member', initials = 'M' }) => {
  const isIn = state === 'logged-in';
  return (
    <button
      type="button"
      className={'profile-btn' + (isIn ? ' profile-btn--in' : '')}
      onClick={onToggle}
      aria-label={isIn ? `Account menu, ${name}` : 'Sign in'}
      title={isIn ? name : 'Sign in'}
    >
      {isIn ? (
        <span className="profile-btn__initials">{initials}</span>
      ) : (
        <svg width="20" height="20" viewBox="0 0 24 24" aria-hidden="true">
          <circle cx="12" cy="9" r="3.6" stroke="currentColor" strokeWidth="1.6" fill="none"/>
          <path d="M5 19c1.4-3.2 4-4.6 7-4.6s5.6 1.4 7 4.6" stroke="currentColor" strokeWidth="1.6" fill="none" strokeLinecap="round"/>
        </svg>
      )}
    </button>
  );
};

// Language dropdown trigger — shared between utility bar + footer.
// Language list — English is default; rest in the order the client requested.
// Translation is wired through the free Google Translate widget. Picking a
// language sets the page's translation target via the widget's hidden select
// element. NOTE on quality: Google Translate is machine translation; brand /
// Sanskrit terms (Prajna, Avadhanam, Jai Srimanarayana) may get
// translated awkwardly. Consider upgrading to Weglot or community-translated
// strings post-launch if the quality matters.
const LANGUAGES = ['English', 'German', 'Hindi', 'Telegu', 'Tamil', 'Kanada'];
// Map our display names → Google Translate language codes. Empty string for
// English means "restore the page to its original (untranslated) state".
const LANG_TO_GTRANS = {
  English: '',
  German:  'de',
  Hindi:   'hi',
  Telegu:  'te',
  Tamil:   'ta',
  Kanada:  'kn',
};

// Ensure the Google Translate widget script is loaded exactly once per page
// session. Subsequent calls are no-ops.
const ensureGoogleTranslateLoaded = () => {
  if (typeof window === 'undefined' || window.__prajnaGTransInit) return;
  window.__prajnaGTransInit = true;

  // Hidden mount point. The widget renders a select.goog-te-combo inside it
  // which we drive programmatically when the user picks a language.
  if (!document.getElementById('google_translate_element')) {
    const mount = document.createElement('div');
    mount.id = 'google_translate_element';
    mount.style.display = 'none';
    document.body.appendChild(mount);
  }

  window.googleTranslateElementInit = () => {
    try {
      new window.google.translate.TranslateElement(
        { pageLanguage: 'en', includedLanguages: 'de,hi,te,ta,kn', autoDisplay: false },
        'google_translate_element'
      );
    } catch (e) { /* widget already initialized — ignore */ }
  };

  const script = document.createElement('script');
  script.src = 'https://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit';
  script.async = true;
  document.head.appendChild(script);
};

// Apply a translation by simulating a change on the hidden Google select.
// The widget script loads async, so poll for ~6 seconds before giving up.
const applyGoogleTranslate = (langName) => {
  const code = LANG_TO_GTRANS[langName] || '';
  let attempts = 0;
  const tryApply = () => {
    const select = document.querySelector('.goog-te-combo');
    if (select) {
      select.value = code;
      select.dispatchEvent(new Event('change'));
      return;
    }
    if (attempts++ < 30) setTimeout(tryApply, 200);
  };
  tryApply();
};

const LangToggle = ({ subdued }) => {
  const [open, setOpen] = React.useState(false);
  const [lang, setLang] = React.useState('English');
  const ref = React.useRef(null);

  // Mount: inject the Google Translate widget (once per page) then restore
  // whatever language the user previously picked and apply that translation.
  React.useEffect(() => {
    ensureGoogleTranslateLoaded();
    try {
      const saved = localStorage.getItem('prajna-lang');
      if (saved && LANGUAGES.includes(saved)) {
        setLang(saved);
        if (saved !== 'English') applyGoogleTranslate(saved);
      }
    } catch (e) { /* localStorage blocked — ignore */ }
  }, []);

  React.useEffect(() => {
    if (!open) return;
    const handler = (e) => {
      if (ref.current && !ref.current.contains(e.target)) setOpen(false);
    };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [open]);

  const pick = (l) => {
    setLang(l);
    try { localStorage.setItem('prajna-lang', l); } catch (e) { /* ignore */ }
    applyGoogleTranslate(l);
    setOpen(false);
  };

  return (
    <div className="lang-toggle-wrap" ref={ref}>
      <button
        type="button"
        className={'lang-toggle' + (subdued ? ' lang-toggle--subdued' : '')}
        aria-label="Change language"
        aria-haspopup="listbox"
        aria-expanded={open}
        onClick={() => setOpen(o => !o)}
      >
        <svg width="14" height="14" viewBox="0 0 24 24" aria-hidden="true" style={{ flexShrink: 0 }}>
          <circle cx="12" cy="12" r="9" stroke="currentColor" strokeWidth="1.6" fill="none"/>
          <path d="M3 12h18M12 3a14 14 0 010 18M12 3a14 14 0 000 18" stroke="currentColor" strokeWidth="1.6" fill="none"/>
        </svg>
        {lang}
        <svg width="10" height="10" viewBox="0 0 10 10" aria-hidden="true"><path d="M2 3.5l3 3 3-3" stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinecap="round"/></svg>
      </button>
      {open && (
        <ul className="lang-menu" role="listbox" aria-label="Language">
          {LANGUAGES.map(l => (
            <li key={l}>
              <button
                type="button"
                className={'lang-menu__item' + (l === lang ? ' is-active' : '')}
                onClick={() => pick(l)}
                role="option"
                aria-selected={l === lang}
              >
                {l}
              </button>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
};

// Tiny utility strip above the main header. Holds announcement + language toggle.
// Sign-in lives in the main header now (one entry point, not two).
const UtilityBar = () => {
  const all = announcementsNewestFirst();
  // Featured post pinned to the bar wins; otherwise fall back to the newest
  // (only when the full section is live). Either way the archive stays gated.
  const featured = FEATURED_ANN_ID != null
    ? ANNOUNCEMENTS.find((a) => a.id === FEATURED_ANN_ID)
    : (ANNOUNCEMENTS_LIVE ? all[0] : null);
  return (
    <div className="utility-bar">
      <div className="container utility-bar__inner">
        {featured ? (
          // Static text only — no page is linked from announcements yet.
          <div className="utility-bar__msg utility-bar__ann" aria-label={`Announcement: ${featured.title}`}>
            <span className="utility-bar__pill">Announcement</span>
            <span>{featured.short}</span>
          </div>
        ) : (
          <span className="utility-bar__msg" />
        )}
        <div className="utility-bar__right">
          {ANNOUNCEMENTS_LIVE && (
            <a className="utility-bar__link hide-on-tablet" href="announcements.html">
              View All ({all.length})
            </a>
          )}
          <LangToggle subdued />
        </div>
      </div>
    </div>
  );
};

// Reads the persisted state on mount so every page agrees with the homepage Tweak.
const useUserState = () => {
  const [state, setState] = React.useState('logged-out');
  React.useEffect(() => {
    try {
      const v = window.localStorage.getItem('prajna__user-state');
      if (v === 'logged-in' || v === 'logged-out') setState(v);
    } catch (_) {}
    const onStorage = (e) => {
      if (e.key === 'prajna__user-state') {
        setState(e.newValue === 'logged-in' ? 'logged-in' : 'logged-out');
      }
    };
    window.addEventListener('storage', onStorage);
    // Also listen to same-tab tweak updates via custom event
    const onLocal = (e) => setState(e.detail);
    window.addEventListener('prajna__user-state', onLocal);
    return () => {
      window.removeEventListener('storage', onStorage);
      window.removeEventListener('prajna__user-state', onLocal);
    };
  }, []);
  return [state, (v) => {
    try { window.localStorage.setItem('prajna__user-state', v); } catch (_) {}
    window.dispatchEvent(new CustomEvent('prajna__user-state', { detail: v }));
    setState(v);
  }];
};

const Header = ({ active, userStateProp }) => {
  const [open, setOpen] = React.useState(false);
  const [profileOpen, setProfileOpen] = React.useState(false);
  const [userState] = useUserState();
  const state = userStateProp || userState;
  const isIn = state === 'logged-in';

  // Logged out: a quiet "Log in" entry point in the header — the action item for
  //   a general visitor is account access, not a conversion CTA.
  // Logged in: no header CTA; the profile dropdown handles account actions.
  // The hero section carries any loud conversion CTA, not the persistent header.
  const secondary = isIn ? null : { label: 'Log in', href: 'login.html' };

  return (
    <>
      <UtilityBar />
      <header className="site-header">
        <div className="container site-header__inner">
          <Brand />
          <nav className="nav-links">
            {NAV.map(n => (
              <a key={n.label} href={n.href} className={active === n.label ? 'is-active' : ''}>{n.label}</a>
            ))}
          </nav>
          <div className="nav-utility">
            {secondary && <a href={secondary.href} className="btn btn--ghost btn--sm">{secondary.label}</a>}
            <div className="profile">
              <ProfileButton state={state} onToggle={() => setProfileOpen(o => !o)} />
              {profileOpen && (
                <div className="profile-menu" onMouseLeave={() => setProfileOpen(false)}>
                  <div className="profile-menu__inner">
                    {isIn ? (
                      <>
                        <div className="profile-menu__head">
                          <div className="profile-btn profile-btn--in profile-btn--lg"><span className="profile-btn__initials">PR</span></div>
                          <div>
                            <div className="profile-menu__name">Member</div>
                            <div className="profile-menu__sub">Signed in</div>
                          </div>
                        </div>
                        <a href="#" className="profile-menu__row">
                          <span>Your next class</span>
                          <span className="profile-menu__row-sub">View your schedule</span>
                        </a>
                        <a href="#" className="profile-menu__row"><span>My children</span><span className="profile-menu__row-sub">Manage</span></a>
                        <a href="#" className="profile-menu__row"><span>Schedule & calendar</span></a>
                        <a href="#" className="profile-menu__row"><span>Account & billing</span></a>
                        <hr />
                        <a href="#" className="profile-menu__row"><span>Register as a teacher</span><span className="profile-menu__row-sub">Volunteer with Prajna</span></a>
                        <hr />
                        <a href="#" className="profile-menu__row profile-menu__row--quiet"><span>Sign out</span></a>
                      </>
                    ) : (
                      <>
                        <div className="profile-menu__head">
                          <div className="profile-btn">
                            <svg width="22" height="22" viewBox="0 0 24 24" aria-hidden="true">
                              <circle cx="12" cy="9" r="3.6" stroke="currentColor" strokeWidth="1.6" fill="none"/>
                              <path d="M5 19c1.4-3.2 4-4.6 7-4.6s5.6 1.4 7 4.6" stroke="currentColor" strokeWidth="1.6" fill="none" strokeLinecap="round"/>
                            </svg>
                          </div>
                          <div>
                            <div className="profile-menu__name">Welcome to Prajna</div>
                            <div className="profile-menu__sub">Sign in to see your child's schedule.</div>
                          </div>
                        </div>
                        <a href="login.html" className="btn btn--primary btn--sm" style={{ width: '100%' }}>Sign in</a>
                        <a href="register.html" className="btn btn--ghost btn--sm" style={{ width: '100%' }}>Register a child</a>
                      </>
                    )}
                  </div>
                </div>
              )}
            </div>
            <button className="menu-btn" onClick={() => setOpen(!open)} aria-label="Open menu"><span></span></button>
          </div>
        </div>

        {open && (
          <div style={{ borderTop: '1px solid var(--line)', background: '#fff', padding: '16px 20px' }}>
            <div className="col" style={{ gap: 4 }}>
              {NAV.map(n => (
                <a key={n.label} href={n.href} style={{ padding: '12px 8px', fontWeight: 700, fontSize: 16, borderBottom: '1px solid var(--line-2)' }}>{n.label}</a>
              ))}
            </div>
          </div>
        )}
      </header>
    </>
  );
};

const SocialIcon = ({ kind }) => {
  const paths = {
    instagram: <><rect x="3" y="3" width="18" height="18" rx="5" stroke="currentColor" strokeWidth="1.6" fill="none"/><circle cx="12" cy="12" r="4" stroke="currentColor" strokeWidth="1.6" fill="none"/><circle cx="17.5" cy="6.5" r="1" fill="currentColor"/></>,
    facebook: <path d="M14 8h2.5V5H14c-2 0-3.5 1.5-3.5 3.5V11H8v3h2.5v7H14v-7h2.2l.3-3H14V8.7c0-.4.3-.7.6-.7H14z" fill="currentColor"/>,
    youtube: <><rect x="2.5" y="6" width="19" height="12" rx="3" stroke="currentColor" strokeWidth="1.6" fill="none"/><path d="M10 9.5v5l4.5-2.5L10 9.5z" fill="currentColor"/></>,
    whatsapp: <path d="M12 3a9 9 0 0 0-7.6 13.8L3 21l4.4-1.3A9 9 0 1 0 12 3zm0 16.4a7.4 7.4 0 0 1-3.8-1l-.3-.2-2.6.8.8-2.5-.2-.3a7.4 7.4 0 1 1 6.1 3.2zm4.1-5.5c-.2-.1-1.3-.6-1.5-.7-.2-.1-.4-.1-.5.1-.2.2-.6.7-.7.9-.1.1-.3.1-.5 0-.6-.3-1.2-.6-1.7-1.1-.4-.4-.8-.9-1.1-1.4-.1-.2 0-.3.1-.4l.4-.4c.1-.1.1-.3.2-.4 0-.1 0-.3 0-.4-.1-.1-.5-1.2-.7-1.6-.2-.4-.4-.4-.5-.4h-.4c-.2 0-.4.2-.5.3a2.4 2.4 0 0 0-.7 1.7c0 1 .7 2 .8 2.1.1.1 1.4 2.2 3.4 3 .5.2.8.3 1.1.4.5.1.9.1 1.3.1.4-.1 1.3-.5 1.5-1 .2-.5.2-1 .1-1z" fill="currentColor"/>,
  };
  return <svg width="20" height="20" viewBox="0 0 24 24">{paths[kind]}</svg>;
};

const Footer = () => (
  <footer className="site-footer">
    <div className="container">
      <div className="footer-grid">
        <div>
          <Brand light />
          <p style={{ marginTop: 16, color: 'rgba(255,255,255,0.7)', fontSize: 14, maxWidth: 320, lineHeight: 1.6 }}>
            A joyous journey of personality development, rooted in Vedic wisdom, for children 5 years and above.
          </p>
          <div className="social-row" style={{ marginTop: 20 }}>
            <a href="https://instagram.com" className="social-icon" aria-label="Instagram"><SocialIcon kind="instagram" /></a>
            <a href="https://facebook.com" className="social-icon" aria-label="Facebook"><SocialIcon kind="facebook" /></a>
            <a href="https://youtube.com" className="social-icon" aria-label="YouTube"><SocialIcon kind="youtube" /></a>
            <a href="https://whatsapp.com" className="social-icon" aria-label="WhatsApp"><SocialIcon kind="whatsapp" /></a>
          </div>
        </div>
        <div>
          <h4>Learn</h4>
          <ul>
            <li><a href="about.html">About Prajna</a></li>
            <li><a href="modules.html">Syllabus</a></li>
            <li><a href="showcase.html">Student Showcase</a></li>
            {ANNOUNCEMENTS_LIVE && <li><a href="announcements.html">Announcements</a></li>}
            <li><a href="faq.html">FAQ</a></li>
          </ul>
        </div>
        <div>
          <h4>Engage</h4>
          <ul>
            <li><a href="register.html">Register a child</a></li>
            <li><a href="centers.html">Find a center</a></li>
            <li><a href="request-center.html">Request a new center</a></li>
            <li><a href="https://donations.chinnajeeyar.guru" target="_blank" rel="noopener noreferrer">Donate</a></li>
          </ul>
        </div>
        <div>
          <h4>Family</h4>
          <ul>
            <li><a href="https://chinnajeeyar.org" target="_blank" rel="noopener noreferrer">Jeeyar Home</a></li>
            <li><a href="https://jetusa.org" target="_blank" rel="noopener noreferrer">JETUSA Home</a></li>
            <li><a href="http://bhakthinivedana.com" target="_blank" rel="noopener noreferrer">Bhakti Nivedana</a></li>
            <li><a href="http://vtsworld.org" target="_blank" rel="noopener noreferrer">VT Seva</a></li>
          </ul>
        </div>
        <div>
          <h4>Our Wings</h4>
          <ul>
            <li><a href="https://jaf.org.au" target="_blank" rel="noopener noreferrer">JET Australia</a></li>
            <li><a href="https://www.jettoronto.org" target="_blank" rel="noopener noreferrer">JET Canada</a></li>
            <li><a href="https://jetgermany.org" target="_blank" rel="noopener noreferrer">JET Germany</a></li>
            <li><a href="https://vtsbharath.org" target="_blank" rel="noopener noreferrer">JET India</a></li>
            <li><a href="https://www.chinnajeeyar.guru" target="_blank" rel="noopener noreferrer">Chinna Jeeyar Guru</a></li>
            <li><a href="https://jet.org.nz" target="_blank" rel="noopener noreferrer">JET New Zealand</a></li>
            <li><a href="https://jetsingapore.org" target="_blank" rel="noopener noreferrer">JET Singapore</a></li>
            <li><a href="https://jetuk.org" target="_blank" rel="noopener noreferrer">JET UK</a></li>
            <li><a href="https://jetusa.org" target="_blank" rel="noopener noreferrer">JET USA</a></li>
          </ul>
        </div>
      </div>
      <div className="footer-bottom">
        <span>© 2026 Prajna · A program of JET USA · All rights reserved</span>
        <span><a href="privacy.html">Privacy</a> · <a href="terms.html">Terms</a> · <a href="help.html">Help</a> · <a href="contact.html">Contact</a></span>
      </div>
    </div>
  </footer>
);

// ── Decorative SVG illustrations (placeholders that feel intentional) ──
const Illo = ({ kind, style }) => {
  const wrap = (children) => (
    <svg viewBox="0 0 400 300" preserveAspectRatio="xMidYMid slice" className="photo__svg" style={style}>{children}</svg>
  );
  if (kind === 'classroom') return wrap(<>
    <rect width="400" height="300" fill="#fff4e8"/>
    <circle cx="340" cy="60" r="36" fill="#ffd7ad"/>
    <path d="M0 230 Q200 200 400 230 L400 300 L0 300 Z" fill="#ace53e" opacity="0.5"/>
    <path d="M0 250 Q200 230 400 250 L400 300 L0 300 Z" fill="#7cdeff" opacity="0.4"/>
    {[80, 150, 220, 290].map((x, i) => (
      <g key={i} transform={`translate(${x} ${180})`}>
        <circle cx="0" cy="-30" r="20" fill={['#834121','#d29f30','#834121','#5a2a13'][i]}/>
        <rect x="-22" y="-12" width="44" height="56" rx="22" fill={['#ed7e1d','#57ace0','#e3ba2b','#ace53e'][i]}/>
      </g>
    ))}
    <rect x="40" y="60" width="200" height="100" rx="6" fill="#fff" stroke="#1a1410" strokeWidth="2"/>
    <text x="60" y="100" fontFamily="serif" fontSize="20" fill="#1a1410">ॐ</text>
    <line x1="60" y1="115" x2="220" y2="115" stroke="#1a1410" opacity="0.3"/>
    <line x1="60" y1="130" x2="200" y2="130" stroke="#1a1410" opacity="0.3"/>
    <line x1="60" y1="145" x2="180" y2="145" stroke="#1a1410" opacity="0.3"/>
  </>);
  if (kind === 'student') return wrap(<>
    <rect width="400" height="300" fill="#eef9ff"/>
    <circle cx="200" cy="120" r="60" fill="#834121"/>
    <circle cx="180" cy="115" r="4" fill="#fff"/>
    <circle cx="220" cy="115" r="4" fill="#fff"/>
    <path d="M180 140 Q200 152 220 140" stroke="#fff" strokeWidth="3" fill="none" strokeLinecap="round"/>
    <path d="M140 180 Q200 140 260 180 L260 300 L140 300 Z" fill="#ed7e1d"/>
    <circle cx="200" cy="60" r="8" fill="#e3ba2b"/>
  </>);
  if (kind === 'recital') return wrap(<>
    <rect width="400" height="300" fill="#fdf3e3"/>
    <path d="M0 200 Q100 180 200 200 T400 200 L400 300 L0 300 Z" fill="#834121" opacity="0.2"/>
    {[100, 200, 300].map((x, i) => (
      <g key={i} transform={`translate(${x} ${160})`}>
        <circle cx="0" cy="0" r="22" fill={['#d29f30','#834121','#5a2a13'][i]}/>
        <rect x="-26" y="14" width="52" height="80" rx="6" fill={['#ed7e1d','#e3ba2b','#834121'][i]}/>
      </g>
    ))}
    <text x="200" y="60" fontFamily="serif" fontSize="42" fill="#834121" textAnchor="middle">ॐ</text>
  </>);
  if (kind === 'service') return wrap(<>
    <rect width="400" height="300" fill="#f1ffd6"/>
    <circle cx="200" cy="150" r="80" fill="#ace53e" opacity="0.3"/>
    <path d="M170 130 L200 100 L230 130 L230 180 L170 180 Z" fill="#834121"/>
    <rect x="190" y="150" width="20" height="30" fill="#e3ba2b"/>
    <circle cx="120" cy="200" r="14" fill="#ed7e1d"/>
    <circle cx="280" cy="200" r="14" fill="#57ace0"/>
  </>);
  if (kind === 'guru') return wrap(<>
    <rect width="400" height="300" fill="#fff4e8"/>
    <ellipse cx="200" cy="280" rx="120" ry="20" fill="#834121" opacity="0.2"/>
    <path d="M150 250 Q150 160 200 160 Q250 160 250 250 Z" fill="#ed7e1d"/>
    <circle cx="200" cy="130" r="40" fill="#834121"/>
    <path d="M170 145 Q200 125 230 145" stroke="#1a1410" strokeWidth="2" fill="none"/>
    <circle cx="200" cy="80" r="48" fill="none" stroke="#e3ba2b" strokeWidth="3" opacity="0.6"/>
  </>);
  if (kind === 'art') return wrap(<>
    <rect width="400" height="300" fill="#fff7d1"/>
    <path d="M50 250 Q200 100 350 250" stroke="#834121" strokeWidth="3" fill="none"/>
    <circle cx="120" cy="180" r="30" fill="#ed7e1d"/>
    <circle cx="200" cy="140" r="40" fill="#57ace0"/>
    <circle cx="280" cy="180" r="30" fill="#ace53e"/>
    <path d="M180 200 L220 200 L200 220 Z" fill="#e3ba2b"/>
  </>);
  if (kind === 'temple') return wrap(<>
    <rect width="400" height="300" fill="#7cdeff" opacity="0.4"/>
    <path d="M200 60 L240 140 L160 140 Z" fill="#ed7e1d"/>
    <rect x="160" y="140" width="80" height="100" fill="#834121"/>
    <rect x="190" y="180" width="20" height="60" fill="#e3ba2b"/>
    <rect x="100" y="180" width="50" height="60" fill="#834121"/>
    <rect x="250" y="180" width="50" height="60" fill="#834121"/>
    <circle cx="200" cy="50" r="6" fill="#e3ba2b"/>
  </>);
  return wrap(<rect width="400" height="300" fill="#fdf3e3"/>);
};

Object.assign(window, { NAV, Brand, ProfileButton, LangToggle, UtilityBar, useUserState, Header, Footer, SocialIcon, Illo });
