// About, Modules, Centers, Showcase, FAQ, Register pages

// ─── ABOUT ───────────────────────────────────────────────
// Focused on PRAJNA itself (timeline, mission, learning). Swamiji has his own
// site at chinnajeeyar.org — we link there but don't dedicate a full section.
// Any unverified data is wrapped in [BRACKETS] so it's obvious it's a placeholder.
const AboutPage = () => (
  <>
    <Header active="About" />
    <section className="page-hero page-hero--sm">
      <div className="container">
        <div className="breadcrumbs"><a href="index.html">Home</a> · <span>About</span></div>
        <h1 className="h-1" style={{ marginTop: 8 }}>About</h1>
      </div>
    </section>

    {/* About PRAJNA — text on left, Swamiji photo on right (vertically centered).
        Photo links to chinnajeeyar.org per original site behavior. */}
    <section className="about-block">
      <div className="container about-grid">
        <div className="about-copy">
          <h2 className="about-copy__h">About PRAJNA</h2>
          <p className="about-copy__p">
            Prajna is a program empowering our kids with rich knowledge. Prajna is a part of our
            parent organization Jeeyar Educational Trust and was established to promote moral
            values and to share our culture and heritage. Prajna is the ability to translate
            knowledge into action. Prajna makes our life a joyful voyage. Prajna is a series of
            classes that provides holistic personality development through Vedic education.
            Prajna is conducted locally at each center or chapter.
          </p>
          <p className="about-copy__p">
            Centers choose how they complete the Prajna year end. Registration for Prajna will
            begin as outlined in the Centers page. Come, let us all join this movement. A person
            who gets benefited in this process, can lead others too in the proper direction thus
            empowering the entire society at large. Children will learn to care about the
            environment and to serve all beings as service to GOD.
          </p>
          <p className="about-copy__p">
            Prajna fees are specific to each center. For specific center costs please click on
            the center from the <a href="centers.html" className="about-link">Centers page</a>.
          </p>
        </div>

        <a
          href="https://chinnajeeyar.org/about-chinna-jeeyar-swamiji/"
          target="_blank"
          rel="noopener noreferrer"
          className="about-photo"
          aria-label="Read about Sri Chinna Jeeyar Swamiji on chinnajeeyar.org"
        >
          <img
            src="photos/chinnajeeyarswami.jpg"
            alt="Sri Sri Sri Tridandi Chinna Srimannarayana Ramanuja Jeeyar Swamiji"
            className="about-photo__img"
          />
          <span className="about-photo__caption">
            <span className="about-photo__caption-name">Sri Chinna Jeeyar Swamiji</span>
            <span className="about-photo__caption-link">Read more on chinnajeeyar.org</span>
          </span>
        </a>
      </div>
    </section>

    {/* What Does One Learn Through PRAJNA? — full-width section on warm cream */}
    <section className="about-learn">
      <div className="container">
        <h2 className="about-copy__h">What Does One Learn Through PRAJNA?</h2>
        <div className="about-learn__grid">
          <p className="about-copy__p">
            Our mission is to empower our students with commendable knowledge. Our vision is to
            preserve and to spread moral values and cultural heritage. We learn our rich Vedic
            culture and heritage and knowledge of usages, customs, and practices. We also learn
            meaningful prayers for different situations, public speaking, leadership skills, and
            management skills. We learn what it service to society means and learn to respect
            others and care for nature.
          </p>
          <p className="about-copy__p">
            This learning to the kids is brought about through a well defined structure. We
            provide authentic overview of Vedic literature in the form of supporting textbooks
            and workbook activities. We teach the kids selected chapters of Bhagavad Gi:tha and the
            Upanishads. They also learn stories of rushis, seers and acharyas. Kids do yoga and
            meditation. They sing bhajans, listen to stories and practice daily prayers.
          </p>
        </div>
      </div>
    </section>

    {/* Closing CTA — clear next step after reading About */}
    <section className="about-cta">
      <div className="container about-cta__inner">
        <div>
          <h2 className="about-cta__h">Visit a Center Near You</h2>
          <p className="about-cta__p">Register to join a class at a center near you.</p>
        </div>
        <div className="about-cta__actions">
          <a href="centers.html" className="btn btn--primary btn--lg">Find a center</a>
          <a href="modules.html" className="btn btn--ghost btn--lg">Explore the curriculum</a>
        </div>
      </div>
    </section>

    <Footer />
  </>
);

// ─── MODULES ─────────────────────────────────────────────
// Real curriculum content lifted verbatim from prajna4me.org per-module pages.
const TRACKS = [
  {
    id: 'foundation', name: 'Foundation', color: 'var(--orange)', tint: 'var(--orange-50)',
    children: [
      {
        name: 'Module 1',
        prereq: 'Interest to learn Vedic science and culture',
        overview: [
          'Enriching all activities of the day',
          'Important festivals in the year',
        ],
        objectives: [
          'Learn how to pronounce Sanskrit vowels and consonant sounds',
          'Learn to chant important slokas (slokas for showing gratitude to Nature and God, removing hindrances, excelling in studies, improving memory skills, improving health, etc.)',
          'Understand the importance of Festivals (Level 1)',
          'Discover the traditions and culture of Vedic Lineage (Level 1)',
          'An introduction to Devotees (Level 1)',
          'Learn about sages and their contributions to mankind (Level 1)',
          'Learn bhajans',
          'Learn how to meditate',
          'Learn to serve our community',
          'Participate in Community Service programs',
        ],
        covers: [
          { src: 'photos/syllabus/m1-prayers.jpg', label: 'Our Prayers (Sloka Book)' },
          { src: 'photos/syllabus/m1-festivals.jpg', label: 'Our Festivals (Story Work Book)' },
          { src: 'photos/syllabus/m1-lmig.jpg', label: 'Life Management: Lessons from the Bhagavad Gi:tha (Volume 1)' },
        ],
      },
      {
        name: 'Module 2',
        prereq: 'Complete Module 1',
        overview: [
          'Importance of Mother and Father',
          'Meaningful prayers for achieving goals',
          'Few aspects of Yoga and service',
        ],
        objectives: [
          'Learn Sanskrit phonetics',
          'Learn to chant Sri Krishna Astakam, Hari Astakam, Pancha:yudha Stho:thram',
          'Understand the importance of Festivals (Level 2)',
          'Discover the traditions and culture of Vedic Lineage (Level 2)',
          'An introduction to Devotees and stories (Level 2)',
          'Learn about sages and their contributions to mankind (Level 2)',
          'Ma:thru Bhakthi',
          'Pithru Bhakthi',
          'Practice Meditation',
          'Learn Indian National Anthem',
          'Learn bhajans',
          'Participate in Community Service programs',
        ],
        covers: [
          { src: 'photos/syllabus/m2-parents.jpg', label: 'Devotion Towards Parents (Text Book)' },
          { src: 'photos/syllabus/m2-twilight.jpg', label: 'Twilight Prayers (Part 2 Work Book)' },
          { src: 'photos/syllabus/m2-lmig.jpg', label: 'Life Management: Lessons from the Bhagavad Gi:tha (Volume 2)' },
        ],
      },
      {
        name: 'Module 3',
        prereq: 'Complete Module 2',
        overview: [
          'Importance of guru',
          'Friendship skills',
          'Suryanamaskaras',
          'Prayers for good memory and focus',
        ],
        objectives: [
          'Learn Sri Hayagri:va Sthothram',
          'Understand the importance and role of a Guru in our life',
          'Acha:rya De:vo Bhava: stories from Scriptures',
          "Stories of disciples who were renowned by Acha:rya's grace",
          'Learn about real friendship',
          'Learn bhajans',
          'Practice Meditation',
          'Learn Vande: Ma:tharam',
          'Participate in Community Service programs',
        ],
        covers: [
          { src: 'photos/syllabus/m3-hayagriva.jpg', label: 'Sri Hayagri:va Sthothram (Sloka Work Book)' },
          { src: 'photos/syllabus/m3-lmig.jpg', label: 'Life Management: Lessons from the Bhagavad Gi:tha (Volume 3)' },
        ],
      },
    ],
  },
  {
    id: 'adv-1', name: 'Advanced · Track 1', color: 'var(--blue)', tint: 'var(--blue-50)',
    children: [
      {
        name: 'Module 4',
        prereq: 'Complete Module 3',
        overview: [
          'Communication skills, gratitude and knowledge',
          'A journey towards victory: Bhagavad Gi:tha Chapter 1',
        ],
        objectives: [
          'Learn 1st Chapter of Gi:tha',
          'Learn why Sri Krishna taught Sri:mad Bhagavad Gi:tha',
          'Understand how to approach elders when in dilemma',
          'Understand how the guidance of elders leads us to victory',
          'Learn the significance of the first chapter’s name',
          'Learn about the benefit of chanting or listening to the first chapter',
          'Learn the stories from Scriptures about knowledge (Jnanam)',
          'Learn the stories from Scriptures about the Power of Speech',
          'Understand how to talk (sathyam bru:ya:th priyam bru:ya:th…)',
          'Understand the five characteristics a word should have while we talk',
          'Learn stories about how to show gratitude',
          'Learn brief info about our Vedic scriptures',
          'Participate in Community Service programs',
        ],
      },
      {
        name: 'Module 5',
        prereq: 'Complete Module 4',
        overview: [
          'An introduction to rushis (Vedic scientists)',
          'ABCs of bliss: Bhagavad Gi:tha Chapter 2',
        ],
        objectives: [
          'Learn Sa:nkhya Yo:gam Chapter 2 of Bhagavad Gi:tha',
          'Why this chapter is the quintessence of the entire Bhagavad Gi:tha',
          'Get a direction for sorrow free life',
          'Stories: learn stories about great sages and their contributions to the world',
          'Avata:ra:s: learn stories about various incarnations of God; the secret behind those astonishing forms and the purpose of those incarnations',
          'Learn stories about worshipping parents and understand that parents are another form of God',
          'Meditation',
          'Participate in Community Service programs',
        ],
        covers: [
          { src: 'photos/syllabus/m5-ch1.jpg',  label: 'Sri:mad Bhagavad Gi:tha, Chapter 1: Arjuna Vishada Yogaha' },
          { src: 'photos/syllabus/m5-ch2.jpg',  label: 'Sri:mad Bhagavad Gi:tha, Chapter 2: Sankya Yogaha (Workbook)' },
          { src: 'photos/syllabus/m5-ch3.jpg',  label: 'Sri:mad Bhagavad Gi:tha, Chapter 3: Karma Yogaha' },
          { src: 'photos/syllabus/m5-ch4.jpg',  label: 'Sri:mad Bhagavad Gi:tha, Chapter 4: Jnana Yogaha' },
          { src: 'photos/syllabus/m5-ch15.jpg', label: 'Sri:mad Bhagavad Gi:tha, Chapter 15: Purushoththama Prapthi Yogaha' },
        ],
      },
      {
        name: 'Module 6',
        prereq: 'Complete Module 5',
        overview: [
          'Learn Karma Yoga: Chapter 3 of Bhagavad Gi:tha',
          'Learn about Karma Yoga and why we should perform it',
          'Learn Karma Sanyasa Yoga: Chapter 5 of Bhagavad Gi:tha',
          'Learn how Karma Yoga must be known in order to perform Jnana Yoga',
        ],
      },
      {
        name: 'Module 7',
        prereq: 'Complete Module 6',
        overview: [
          'Learn Bhagavad Gi:tha Chapter 15: Purushottama Prapti Yogam',
          "Learn about Ramanuja's life and teachings",
        ],
      },
      {
        name: 'Module 8',
        prereq: 'Complete Module 7',
        overview: [
          'Gi:thadhyayanam: learn to chant all 18 chapters of Bhagavad Gi:tha',
          'Electives',
        ],
      },
    ],
  },
  {
    id: 'adv-2', name: 'Advanced · Track 2', color: 'var(--green-700)', tint: '#f1ffd6',
    children: [
      {
        name: 'Life Management Gi:tha 1',
        ageNote: '10+ years old',
        prereq: 'PRAJNA Module 1 Course or Orientation Session completion',
        overview: [
          'Highly interactive module geared towards empowering students with values, tools, and techniques from the Bhagavad Gi:tha, which they can apply in daily life at home, school, and work',
          'Multiple workshops (group discussions and individual) to prepare students for real-world situations with wisdom from the Bhagavad Gi:tha',
        ],
        discussionStart: 1,
        discussion: [
          'Introduction',
          'Justification',
          'Know Yourself',
          'Discipline Always Wins',
          'Cosmos in a Cup',
          'The Master Controller',
          'At the Crossroads',
          'Search Where You Lost',
          'Surrender',
          "Don't be Oppressed by Obsessions!",
          'Password to Gi:tha',
          'Qualities of Soul',
          'Flow of Life',
          'Dharma',
          'However Tiny a Droplet',
          'Focus on the Duty',
          'Learn... Limits',
          'Realize the Goal',
        ],
      },
      {
        name: 'Life Management Gi:tha 2',
        prereq: 'Life Management Gi:tha 1',
        overview: [
          'Highly interactive module geared towards empowering students with values, tools, and techniques from the Bhagavad Gi:tha, which they can apply in daily life at home, school, and work',
          'Multiple workshops (group discussions and individual) to prepare students for real-world situations with wisdom from the Bhagavad Gi:tha',
        ],
        discussionStart: 18,
        discussion: [
          'Taming the Mind 1',
          'Taming the Mind 2',
          'Taming the Mind 3',
          'Taming the Mind 4',
          'Taming the Mind 5',
          'Ocean Teaches',
          'Upgrade Duty Into Yoga',
          'Why Karma... Karma... and again Karma',
          'Karma sync with Team Spirit',
          'Yajna: hub of the Life Cycle',
          'Karma is a need... not an option',
          'Sva Dharma and Para Dharma',
          'The Invincible Enemy',
          'Change your tools... Plug into Krushna',
        ],
      },
      {
        name: 'Life Management Gi:tha 3',
        prereq: 'Life Management Gi:tha 2',
        overview: [
          'Highly interactive module geared towards empowering students with values, tools, and techniques from the Bhagavad Gi:tha, which they can apply in daily life at home, school, and work',
          'Multiple workshops (group discussions and individual) to prepare students for real-world situations with wisdom from the Bhagavad Gi:tha',
        ],
        discussionStart: 32,
        discussion: [
          'A Mind Boggling Timeline',
          "The Lord's Births... When... Why... and How",
          'You Can See God, Believe Me',
          'Be Free from Bondage... Here Is the Clue',
          'Karma, Akarma, Vikarma... Dharma... Then...',
          'Perfect Way to Convert Karma into Jnana',
          'Approach Through Acharya... Recommended by Krushna',
          'Threefold Path to Peace',
          'Qualified Jnanam... A Plava... A Fire... A Sword',
          'Art of Reaching the Goal Faster',
          'Enjoy the Fruit, Leave the Seed',
          'No Stress... Be a Better Tool',
          'I Do Nothing',
          'Caring Friend',
          'Stay Focused on What Matters',
          'A Smooth Sail',
          'Initial Goal',
          'Become Strong',
        ],
      },
    ],
  },
  {
    id: 'special', name: 'Special Courses', color: 'var(--gold)', tint: '#fff7d1',
    children: [
      {
        name: 'Sume:dha 2.5P',
        subtitle: 'Sri:mad Bhagavad Gi:tha Avadhanam Online Class',
        kind: 'online',
        intro: 'Jai Srimannarayana!',
        flyerUrl: 'https://drive.google.com/file/d/1RfUGNSciv6EndXiueFwLZq6zgvkp-AAd/view',
        flyerEmbedUrl: 'https://drive.google.com/file/d/1RfUGNSciv6EndXiueFwLZq6zgvkp-AAd/preview',
      },
      {
        name: 'Sri Vishnu Sahasranama Avadhanam',
        subtitle: 'Online Class',
        kind: 'online',
        intro: 'Jai Srimannarayana!',
        flyerUrl: 'https://drive.google.com/file/d/1O_HSRbr_PfHwZhvshC5HVHTDNUcLd-G0/view',
        flyerEmbedUrl: 'https://drive.google.com/file/d/1O_HSRbr_PfHwZhvshC5HVHTDNUcLd-G0/preview',
      },
    ],
  },
];

const ModulesPage = () => {
  const [activeTrack, setActiveTrack] = React.useState('foundation');
  const [activeModule, setActiveModule] = React.useState(1);
  const [lightbox, setLightbox] = React.useState(null); // index into the current module's covers, or null when closed
  const track = TRACKS.find(t => t.id === activeTrack);
  const mod = track.children[activeModule] || track.children[0];
  const covers = mod.covers || [];
  const lbNav = (dir) => setLightbox(v => (v === null ? v : (v + dir + covers.length) % covers.length));

  // Close the cover viewer whenever the module or track changes.
  React.useEffect(() => { setLightbox(null); }, [activeModule, activeTrack]);

  // While the viewer is open: arrow keys cycle, Escape closes, and the page
  // behind it is locked from scrolling.
  React.useEffect(() => {
    if (lightbox === null) return undefined;
    const onKey = (e) => {
      if (e.key === 'Escape') setLightbox(null);
      else if (e.key === 'ArrowLeft') lbNav(-1);
      else if (e.key === 'ArrowRight') lbNav(1);
    };
    document.addEventListener('keydown', onKey);
    const prevOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => { document.removeEventListener('keydown', onKey); document.body.style.overflow = prevOverflow; };
  }, [lightbox, covers.length]);
  // Build a flat lookup of every module name → its location, longest names first
  // so longer names ("Life Management Gi:tha 1") match before shorter ("Module 1").
  const modIndex = TRACKS.flatMap(t => t.children.map((c, i) => ({ name: c.name, trackId: t.id, idx: i })))
    .sort((a, b) => b.name.length - a.name.length);

  const jumpTo = (trackId, idx) => {
    setActiveTrack(trackId); setActiveModule(idx);
    window.scrollTo({ top: 0, behavior: 'smooth' });
  };

  // If the prereq text references a known module, render the whole text as one
  // clickable pill that jumps to that module. Otherwise render as plain text.
  const renderPrereq = (text) => {
    if (!text) return null;
    const match = modIndex.find(m => text.includes(m.name));
    if (match) {
      return (
        <a
          href="#"
          onClick={(e) => { e.preventDefault(); jumpTo(match.trackId, match.idx); }}
          className="mod-prereq__pill"
        >
          {text}
        </a>
      );
    }
    return <span className="mod-prereq__plain">{text}</span>;
  };

  return (
    <>
      <Header active="Syllabus" />
      <section className="page-hero page-hero--sm">
        <div className="container">
          <div className="breadcrumbs"><a href="index.html">Home</a> · <span>Syllabus</span></div>
          <h1 className="h-1" style={{ marginTop: 8 }}>Syllabus</h1>
        </div>
      </section>

      {/* Track folder tabs */}
      <div className="track-tabs-bar">
        <div className="container">
          <div className="track-tabs">
            {TRACKS.map(t => (
              <button
                key={t.id}
                onClick={() => { setActiveTrack(t.id); setActiveModule(0); }}
                style={{ '--tab-color': t.color, '--tab-tint': t.tint }}
                className={'track-tab' + (activeTrack === t.id ? ' is-active' : '')}
              >{t.name}</button>
            ))}
          </div>
        </div>
      </div>

      <section className="section">
        <div className="container">
          <div className="mod-layout">
            <aside className="mod-layout__rail">
              <div className="eyebrow">{track.name} track</div>
              <ul className="mod-list">
                {track.children.map((c, i) => (
                  <li key={c.name}>
                    <a
                      href="#"
                      onClick={(e) => { e.preventDefault(); setActiveModule(i); }}
                      className={'mod-leaf' + (i === activeModule ? ' is-active' : '')}
                    >
                      <span className="mod-leaf__name">{c.name}</span>
                    </a>
                  </li>
                ))}
              </ul>
            </aside>

            <div>
              {/* Module metadata: track-color dot + small caps eyebrow */}
              <div className="mod-meta">
                <span className="mod-meta__dot" style={{ background: track.color }} aria-hidden="true"></span>
                <span className="mod-meta__item">{track.name}</span>
                {mod.ageNote && <>
                  <span className="mod-meta__sep">·</span>
                  <span className="mod-meta__item">{mod.ageNote}</span>
                </>}
              </div>
              <h2 className="h-1" style={{ marginTop: 14 }}>{mod.name}</h2>
              {mod.subtitle && (
                <p className="body-lg" style={{ marginTop: 8, maxWidth: 640, color: 'var(--ink-2)' }}>
                  {mod.subtitle}
                </p>
              )}

              {/* Online class card (Sumedha, Vishnu Sahasranama): show flyer embed + link */}
              {mod.kind === 'online' ? (
                <div className="mod-online">
                  {mod.intro && <p className="mod-online__intro">{mod.intro}</p>}
                  <div className="mod-online__flyer">
                    <iframe
                      src={mod.flyerEmbedUrl}
                      title={`${mod.name} flyer`}
                      className="mod-online__iframe"
                      allow="autoplay"
                    />
                  </div>
                  <a href={mod.flyerUrl} target="_blank" rel="noopener noreferrer" className="btn btn--primary" style={{ marginTop: 16 }}>
                    Open flyer in Google Drive
                  </a>
                </div>
              ) : (
                <>
                  {/* Pre-requisites */}
                  {mod.prereq && (
                    <div className="mod-prereq">
                      <span className="mod-prereq__label">Pre-requisites</span>
                      <span className="mod-prereq__text">{renderPrereq(mod.prereq)}</span>
                    </div>
                  )}

                  {/* Overview */}
                  {mod.overview && mod.overview.length > 0 && (
                    <div className="mod-section">
                      <h3 className="mod-section__h">Overview</h3>
                      <ul className="mod-bullets">
                        {mod.overview.map((item, i) => <li key={i}>{item}</li>)}
                      </ul>
                    </div>
                  )}

                  {/* Course Objectives */}
                  {mod.objectives && mod.objectives.length > 0 && (
                    <div className="mod-section">
                      <h3 className="mod-section__h">Course Objectives</h3>
                      <ul className="mod-bullets">
                        {mod.objectives.map((item, i) => <li key={i}>{item}</li>)}
                      </ul>
                    </div>
                  )}

                  {/* Discussion Topics (Life Management Gi:tha tracks) */}
                  {mod.discussion && mod.discussion.length > 0 && (
                    <div className="mod-section">
                      <h3 className="mod-section__h">Discussion Topics</h3>
                      <ol className="mod-numbered" start={mod.discussionStart || 1}>
                        {mod.discussion.map((item, i) => <li key={i}>{item}</li>)}
                      </ol>
                    </div>
                  )}

                  {/* Textbooks for this module */}
                  {mod.covers && mod.covers.length > 0 && (
                    <div className="mod-section">
                      <h3 className="mod-section__h">Textbooks</h3>
                      <div className="mod-covers">
                        {mod.covers.map((c, i) => (
                          <figure className="mod-cover" key={i}>
                            <button
                              type="button"
                              className="mod-cover__btn"
                              onClick={() => setLightbox(i)}
                              aria-label={`View ${c.label} larger`}
                            >
                              <img src={c.src} alt={c.label} className="mod-cover__img" loading="lazy" />
                              <span className="mod-cover__zoom" aria-hidden="true">
                                <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                                  <circle cx="11" cy="11" r="7" /><path d="M21 21l-4.3-4.3" /><path d="M11 8v6M8 11h6" />
                                </svg>
                              </span>
                            </button>
                            <figcaption className="mod-cover__cap">{c.label}</figcaption>
                          </figure>
                        ))}
                      </div>
                    </div>
                  )}
                </>
              )}

              {/* Enroll callout — friendlier than a bare button */}
              <div className="mod-enroll">
                <div className="mod-enroll__copy">
                  <h3 className="mod-enroll__h">Ready for {mod.name}?</h3>
                  <p className="mod-enroll__p">Register here and a coordinator will help you pick a center.</p>
                </div>
                <a
                  href={`register.html?module=${encodeURIComponent(mod.name)}`}
                  className="btn btn--primary btn--lg"
                >
                  Enroll
                </a>
              </div>

              {/* Previous link — hidden on first module of a track */}
              {activeModule > 0 && (
                <div style={{ marginTop: 20 }}>
                  <button
                    className="mod-prev"
                    onClick={() => setActiveModule(activeModule - 1)}
                  >
                    ← Previous: {track.children[activeModule - 1].name}
                  </button>
                </div>
              )}
            </div>
          </div>
        </div>
      </section>

      {/* Continue the Journey — compact track cards */}
      <section className="section--tight" style={{ background: 'var(--paper-2)', borderTop: '1px solid var(--line)', padding: '40px 0 48px' }}>
        <div className="container">
          <h2 className="h-3">Continue the Journey</h2>
          <div className="grid-3" style={{ marginTop: 20 }}>
            {TRACKS.filter(t => t.id !== activeTrack).map(t => (
              <div key={t.id} className="card mod-track-card" style={{ padding: '14px 16px', borderTop: `3px solid ${t.color}` }}>
                <div className="row" style={{ justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 8 }}>
                  <h3 style={{ fontSize: 14, fontWeight: 800, margin: 0, letterSpacing: '-0.01em' }}>{t.name}</h3>
                  <span style={{ fontSize: 11, color: 'var(--ink-3)' }}>{t.children.length} modules</span>
                </div>
                <ul className="mod-track-list">
                  {t.children.map((c, i) => (
                    <li key={c.name}>
                      <button
                        onClick={() => { setActiveTrack(t.id); setActiveModule(i); window.scrollTo({ top: 0, behavior: 'smooth' }); }}
                        className="mod-track-leaf"
                      >
                        {c.name}
                      </button>
                    </li>
                  ))}
                </ul>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* Textbook cover viewer — click a cover to enlarge; arrows/keys cycle
          through the covers of the current module. */}
      {lightbox !== null && covers[lightbox] && (
        <div
          className="mod-lb"
          role="dialog"
          aria-modal="true"
          aria-label={`Textbook cover: ${covers[lightbox].label}`}
          onClick={() => setLightbox(null)}
        >
          <button className="mod-lb__close" onClick={() => setLightbox(null)} aria-label="Close viewer">
            <svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M6 6l12 12M18 6L6 18" /></svg>
          </button>
          <div className="mod-lb__stage" onClick={(e) => e.stopPropagation()}>
            {covers.length > 1 && (
              <button className="mod-lb__nav mod-lb__nav--prev" onClick={() => lbNav(-1)} aria-label="Previous cover">
                <svg viewBox="0 0 24 24" width="26" height="26" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M15 18l-6-6 6-6" /></svg>
              </button>
            )}
            <figure className="mod-lb__figure">
              <img src={covers[lightbox].src} alt={covers[lightbox].label} className="mod-lb__img" />
              <figcaption className="mod-lb__cap">
                <span className="mod-lb__label">{covers[lightbox].label}</span>
                {covers.length > 1 && <span className="mod-lb__count">{lightbox + 1} of {covers.length}</span>}
              </figcaption>
            </figure>
            {covers.length > 1 && (
              <button className="mod-lb__nav mod-lb__nav--next" onClick={() => lbNav(1)} aria-label="Next cover">
                <svg viewBox="0 0 24 24" width="26" height="26" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M9 18l6-6-6-6" /></svg>
              </button>
            )}
          </div>
        </div>
      )}

      <Footer />
    </>
  );
};

// ─── CENTERS ─────────────────────────────────────────────
// Centers data sourced from prajna4me.org/locate/ (extracted 2026-05-06).
// All 120 centers. lat/lng need a bulk geocoding pass — those still set to
// null fall off the map but still appear in the list. Schedule isn't on
// the source page; left null until per-center detail data arrives.
// Google Sites URL per center, keyed by profileId. Anil uncle will send a
// CSV mapping centerId → Google Sites page; populate this dict from that
// data. Until then, the centers list falls back to the internal
// center-profile.html page for every entry below.
const CENTER_GOOGLE_SITES = {
  // 130: 'https://sites.google.com/...',
  // 190: 'https://sites.google.com/...',
  // ... etc
};

const CENTERS = [
  // ── Australia ─────────────────────────────────────────────
  { name: 'Sydney (Schofields)', region: 'Schofields NSW Australia', addr: '60 St Albans Rd, Schofields, NSW 2762', email: 'prajna@jaf.org.au', country: 'Australia', state: 'NSW', profileId: 130, enrollmentYear: '2026', startDate: '01-Jan-2026', lat: -33.6993, lng: 150.8694 },
  { name: 'Sydney (Austral)', region: 'Austral NSW Australia', addr: '23 Ganugan Road, Austral, NSW 2179', email: 'vasuanj@yahoo.com', country: 'Australia', state: 'NSW', profileId: 190, enrollmentYear: '2026', startDate: '01-Jan-2026', lat: -33.9434, lng: 150.8149 },
  { name: 'Sydney (Baulkham Hills)', region: 'Baulkham Hills NSW Australia', addr: '9 Forum Crescent, Baulkham Hills, NSW 2153', email: 'prajna@jaf.org.au', country: 'Australia', state: 'NSW', profileId: 96, enrollmentYear: '2026', startDate: '01-Jan-2026', lat: -33.7596, lng: 150.9618 },
  { name: 'Sydney (Box Hill)', region: 'Box Hill NSW Australia', addr: '27 Parkside Avenue, Box Hill, NSW 2765', email: 'Prajna.Sydney@jaf.org.au', country: 'Australia', state: 'NSW', profileId: 201, enrollmentYear: '2026', startDate: null, lat: -33.6687, lng: 150.9104 },
  { name: 'Sydney (Marsden Park)', region: 'Marsden Park NSW Australia', addr: '8 John Black Drive, Marsden Park, NSW 2765', email: 'vasuanj@yahoo.com', country: 'Australia', state: 'NSW', profileId: 189, enrollmentYear: '2026', startDate: '01-Jan-2026', lat: -33.6964, lng: 150.8104 },
  { name: 'Sydney (Oran Park)', region: 'Oran Park NSW Australia', addr: '11 Lawler Drive, Oran Park, NSW 2570', email: 'Prajna.Sydney@jaf.org.au', country: 'Australia', state: 'NSW', profileId: 202, enrollmentYear: '2026', startDate: null, lat: -34.0021, lng: 150.7277 },
  { name: 'Sydney (Wentworthville)', region: 'Wentworthville NSW Australia', addr: '18/41-43 Veron Street, Wentworthville, NSW 2145', email: 'vasuanj@yahoo.com', country: 'Australia', state: 'NSW', profileId: 191, enrollmentYear: '2026', startDate: '01-Jan-2026', lat: -33.8067, lng: 150.9678 },
  { name: 'Sydney (Westmead)', region: 'Westmead NSW Australia', addr: 'Domain Community Rooms, 1 Oakes St, Westmead, NSW 2145', email: 'prajna@jaf.org.au', country: 'Australia', state: 'NSW', profileId: 97, enrollmentYear: '2026', startDate: '01-Jan-2026', lat: -33.8122, lng: 150.9898 },
  { name: 'Brisbane', region: 'Carseldine QLD Australia', addr: '5 Highbridge Cct, Carseldine, QLD 4034', email: 'prajna@jaf.org.au', country: 'Australia', state: 'QLD', profileId: 143, enrollmentYear: '2026', startDate: '01-Jan-2026', lat: -27.3553, lng: 153.0260 },
  { name: 'Brisbane (Chelmer)', region: 'Chelmer QLD Australia', addr: '111 Harte Street, Chelmer, QLD 4068', email: 'vasuanj@yahoo.com', country: 'Australia', state: 'QLD', profileId: 188, enrollmentYear: '2026', startDate: '01-Jan-2026', lat: -27.5155, lng: 152.9825 },
  { name: 'Brisbane (Forest Lake)', region: 'Forest Lake QLD Australia', addr: '37 Cascade Dr, Forest Lake, QLD 4078', email: 'Prajna@jaf.org.au', country: 'Australia', state: 'QLD', profileId: 200, enrollmentYear: '2026', startDate: null, lat: -27.6307, lng: 152.9643 },
  { name: 'Brisbane (Morayfield)', region: 'Morayfield QLD Australia', addr: '40 Georgia Street, Morayfield, QLD 4506', email: 'vasuanj@yahoo.com', country: 'Australia', state: 'QLD', profileId: 192, enrollmentYear: '2026', startDate: '01-Jan-2026', lat: -27.1302, lng: 152.9231 },
  { name: 'Adelaide (Devon Park)', region: 'Manningham SA Australia', addr: 'Goda Nilayam, 2 Willow Avenue, Manningham, SA 5086', email: 'prajna@jaf.org.au', country: 'Australia', state: 'SA', profileId: 137, enrollmentYear: '2025', startDate: '15-Dec-2024', lat: -34.8830, lng: 138.6090 },
  { name: 'Melbourne (Hoppers Crossing)', region: 'Hoppers Crossing VIC Australia', addr: 'JET Centre, 689 Tarneit Road, Hoppers Crossing, VIC 3029', email: 'prajna@jaf.org.au', country: 'Australia', state: 'VIC', profileId: 128, enrollmentYear: '2026', startDate: '02-Jan-2026', lat: -37.8773, lng: 144.7029 },
  { name: 'Melbourne (Arbourlea)', region: 'Cranbourne North VIC Australia', addr: '75 Wheelers Park Dr, Cranbourne North, VIC 3977', email: 'prajna@jaf.org.au', country: 'Australia', state: 'VIC', profileId: 199, enrollmentYear: '2026', startDate: '02-Jan-2026', lat: -38.0826, lng: 145.327 },
  { name: 'Melbourne (Fawkner)', region: 'Fawkner VIC Australia', addr: 'C B Smith Reserve, 77 Jukes Rd, Fawkner, VIC 3060', email: 'Harini.rapolu@jaf.com.au', country: 'Australia', state: 'VIC', profileId: 193, enrollmentYear: '2026', startDate: '02-Jan-2026', lat: -37.7025, lng: 144.97 },
  { name: 'Melbourne (Manor Lakes)', region: 'Wyndham Vale VIC Australia', addr: '86 Manor Lakes Boulevard, Wyndham Vale, VIC 3024', email: 'prajna@jaf.org.au', country: 'Australia', state: 'VIC', profileId: 198, enrollmentYear: '2026', startDate: '02-Jan-2026', lat: -37.8722, lng: 144.6084 },
  { name: 'Melbourne (Saltwater)', region: 'Point Cook VIC Australia', addr: '3 Saltwater Promenade, Point Cook, VIC 3030', email: 'prajna@jaf.org.au', country: 'Australia', state: 'VIC', profileId: 197, enrollmentYear: '2026', startDate: '01-Jan-2026', lat: -37.9096, lng: 144.7747 },
  { name: 'Melbourne (Thornhill Park)', region: 'Thornhill Park VIC Australia', addr: '97-121 Murray Rd, Thornhill Park, VIC 3335', email: 'prajna@jaf.org.au', country: 'Australia', state: 'VIC', profileId: 196, enrollmentYear: '2026', startDate: '02-Jan-2026', lat: -37.7173, lng: 144.6337 },
  { name: 'Perth (Willetton)', region: 'Leeming WA Australia', addr: '4 Aulberry Parade, Leeming, WA 6149', email: 'prajna.perth@jaf.org.au', country: 'Australia', state: 'WA', profileId: 125, enrollmentYear: '2026', startDate: '12-Dec-2025', lat: -32.0735, lng: 115.8606 },
  { name: 'Perth (Bayswater)', region: 'Bayswater WA Australia', addr: '13 Murray St, Bayswater, WA 6053', email: 'prajna@jaf.org.au', country: 'Australia', state: 'WA', profileId: 126, enrollmentYear: '2026', startDate: '06-Jan-2026', lat: -31.9203, lng: 115.9112 },
  { name: 'Perth (Baldivis)', region: 'Baldivis WA Australia', addr: '67 Folly Rd, Baldivis, WA 6171', email: 'prajna@jaf.org.au', country: 'Australia', state: 'WA', profileId: 169, enrollmentYear: '2026', startDate: '13-Dec-2025', lat: -32.3274, lng: 115.8288 },
  // ── Canada ────────────────────────────────────────────────
  { name: 'Toronto', region: 'Mississauga ON Canada', addr: '3605 Cartmel Rd, Mississauga, ON L5L4R7', email: 'archanagopal9@gmail.com', country: 'Canada', state: 'ON', profileId: 134, enrollmentYear: '2024', startDate: '20-Oct-2024', lat: 43.5890, lng: -79.6441 },
  // ── Germany ───────────────────────────────────────────────
  { name: 'Munich', region: 'Munich Germany', addr: 'Wiesentfelser Staße 74, Munich 81249', email: 'prajna@jetgermany.org', country: 'Germany', state: null, profileId: 98, enrollmentYear: '2026', startDate: '13-Apr-2026', lat: 48.1351, lng: 11.5820 },
  { name: 'Mannheim', region: 'Ludwigshafen Germany', addr: 'Rottstrasse 1, Ludwigshafen 67061', email: 'vempativsap@gmail.com', country: 'Germany', state: null, profileId: 124, enrollmentYear: '2026', startDate: '13-Apr-2026', lat: 49.4741, lng: 8.4548 },
  // ── Global (online) ──────────────────────────────────────
  { name: 'Global LMiG', region: 'Global Online', addr: 'Online', email: 'jetseattle.prajna@jetusa.org', country: 'Global', state: null, profileId: 148, enrollmentYear: '2021', startDate: '01-Oct-2021', lat: null, lng: null },
  { name: 'Global Ramayanam', region: 'Global Online', addr: 'Online', email: 'psc@jetusa.org', country: 'Global', state: null, profileId: 206, enrollmentYear: '2026', startDate: '01-May-2026', lat: null, lng: null },
  { name: 'Global Sumedha', region: 'Global Online', addr: 'Online', email: 'psc@jetusa.org', country: 'Global', state: null, profileId: 110, enrollmentYear: '2025', startDate: '02-Sep-2025', lat: null, lng: null },
  { name: 'Global SVSN Avadhanam', region: 'Global Online', addr: 'Online', email: 'psc@jetusa.org', country: 'Global', state: null, profileId: 119, enrollmentYear: '2025', startDate: '20-Aug-2025', lat: null, lng: null },
  // ── India ─────────────────────────────────────────────────
  { name: 'Mumbai - Virar West', region: 'Mumbai India', addr: '1404 Garden Avenue K, A wing, Global City, Virar West, Mumbai 401303', email: 'Amarangi7.9.11@gmail.com', country: 'India', state: null, profileId: 161, enrollmentYear: '2026', startDate: '02-Apr-2026', lat: 19.4559, lng: 72.8118 },
  { name: 'Hyderabad - Kondapur', region: 'Hyderabad India', addr: 'Myhome Mangala, Kondapur, Hyderabad 500084', email: 'srinivas61294@gmail.com', country: 'India', state: null, profileId: 187, enrollmentYear: '2025', startDate: '21-Jul-2025', lat: 17.4685, lng: 78.3636 },
  { name: 'Hyderabad - Lansum Etania', region: 'Hyderabad India', addr: 'B 302 Lansum Etania, Puppalaguda, Hyderabad 500089', email: 'vpshobha@hotmail.com', country: 'India', state: null, profileId: 151, enrollmentYear: '2025', startDate: '25-Jul-2025', lat: 17.4, lng: 78.3862 },
  { name: 'Hyderabad - Mokila', region: 'Hyderabad India', addr: 'Sri Goda Lakshmi Venkateshwara Temple, Dontanpalli, Hyderabad 501203', email: 'Rohinichapyala@gmail.com', country: 'India', state: null, profileId: 181, enrollmentYear: '2025', startDate: '26-Mar-2025', lat: 17.3606, lng: 78.4741 },
  { name: 'Hyderabad - Tellapur', region: 'Hyderabad India', addr: 'Mohana Krishna temple, My Home Tridasa, Tellapur, Hyderabad 502300', email: 'swatibrao@gmail.com', country: 'India', state: null, profileId: 183, enrollmentYear: '2026', startDate: '09-May-2026', lat: 17.474, lng: 78.2981 },
  // ── Netherlands ──────────────────────────────────────────
  { name: 'Amsterdam', region: 'Amsterdam Netherlands', addr: 'Fregelaan 82, Amsterdam 1062KL', email: 'jeeyartrustnl@gmail.com', country: 'Netherlands', state: null, profileId: 195, enrollmentYear: '2025', startDate: null, lat: 52.3676, lng: 4.9041 },
  // ── New Zealand ──────────────────────────────────────────
  { name: 'Auckland (Henderson Heights)', region: 'Auckland New Zealand', addr: '6 Waltham Street, West Auckland 0612', email: 'mpad1966@gmail.com', country: 'New Zealand', state: null, profileId: 154, enrollmentYear: '2026', startDate: '08-Dec-2025', lat: -36.8650, lng: 174.6310 },
  { name: 'Wellington (Trentham)', region: 'Wellington New Zealand', addr: '33 Salisbury Crescent, Upper Hutt, Wellington 5018', email: 'nikhil.reddy.k@icloud.com', country: 'New Zealand', state: null, profileId: 153, enrollmentYear: '2026', startDate: '17-Dec-2025', lat: -41.1330, lng: 175.0470 },
  // ── Singapore ────────────────────────────────────────────
  { name: 'Singapore', region: 'Singapore', addr: 'No 3, Shenton Way #14-02 Shenton House, Singapore 068805', email: 'INFO@JETSINGAPORE.ORG', country: 'Singapore', state: null, profileId: 171, enrollmentYear: '2025', startDate: '01-Jan-2025', lat: 1.2792, lng: 103.8480 },
  // ── United Kingdom ───────────────────────────────────────
  { name: 'Amersham', region: 'Amersham United Kingdom', addr: 'Scouts Hub, Little Chalfont, Amersham HP7 9LW', email: 'prajna@jetuk.org', country: 'United Kingdom', state: null, profileId: 120, enrollmentYear: '2026', startDate: '18-Apr-2026', lat: 51.6707, lng: -0.5895 },
  { name: 'Milton Keynes', region: 'Milton Keynes United Kingdom', addr: '5 Longhorn Drive, Whitehouse, Milton Keynes MK8 1AH', email: 'prajna@jetuk.org', country: 'United Kingdom', state: null, profileId: 203, enrollmentYear: '2026', startDate: '18-Apr-2026', lat: 52.0276, lng: -0.8164 },
  { name: 'Manchester', region: 'Manchester United Kingdom', addr: '13 Taylor’s Road Stretford, Manchester M320JA', email: 'ranjith.srirangam@gmail.com', country: 'United Kingdom', state: null, profileId: 164, enrollmentYear: '2026', startDate: '18-Apr-2026', lat: 53.4474, lng: -2.3034 },
  { name: 'UK Online', region: 'United Kingdom Online', addr: 'Online', email: 'prajna@jetuk.org', country: 'United Kingdom', state: null, profileId: 133, enrollmentYear: '2026', startDate: '18-Apr-2026', lat: null, lng: null },
  { name: 'Yorkshire', region: 'Halifax United Kingdom', addr: '22 Savile Royd, Halifax, West Yorkshire HX12EY', email: 'prajna@jetuk.org', country: 'United Kingdom', state: null, profileId: 172, enrollmentYear: '2026', startDate: '18-Apr-2026', lat: 53.7163, lng: -1.869 },
  // ── USA ──────────────────────────────────────────────────
  { name: 'Chandler', region: 'Chandler AZ', addr: '1760 E Buffalo St, Chandler, AZ 85225', email: 'Rammohan.acharyadasa@gmail.com', country: 'USA', state: 'AZ', profileId: 76, enrollmentYear: '2025', startDate: '28-Sep-2025', lat: 33.3062, lng: -111.8413 },
  { name: 'Happy Valley', region: 'Phoenix AZ', addr: '1611 W Tombstone Trl, Phoenix, AZ 85085', email: 'rammohan.acharyadasa@gmail.com', country: 'USA', state: 'AZ', profileId: 72, enrollmentYear: '2025', startDate: '09-Feb-2025', lat: 33.7170, lng: -112.1190 },
  { name: 'Peoria', region: 'Peoria AZ', addr: '14321 N 81st Dr, Peoria, AZ 85381', email: 'jetarizona@jetusa.org', country: 'USA', state: 'AZ', profileId: 204, enrollmentYear: '2026', startDate: null, lat: 33.6143, lng: -112.2334 },
  { name: 'Bentonville', region: 'Bentonville AR', addr: '950 Winesap Dr, Bentonville, AR 72712', email: 'rahulapple9922@gmail.com', country: 'USA', state: 'AR', profileId: 177, enrollmentYear: '2024', startDate: '24-Sep-2024', lat: 36.3728, lng: -94.2088 },
  { name: 'Bay Area - Brentwood', region: 'Antioch CA', addr: 'Hames Valley Lane, Antioch, CA 94513', email: 'Prajna.JETCA1@jetusa.org', country: 'USA', state: 'CA', profileId: 166, enrollmentYear: '2026', startDate: '01-Mar-2026', lat: 37.9780, lng: -121.7060 },
  { name: 'Bay Area - Cupertino', region: 'Cupertino CA', addr: 'Odd Fellows Hall, Cupertino, CA 95014', email: 'Prajna.JETCA2@jetusa.org', country: 'USA', state: 'CA', profileId: 59, enrollmentYear: '2026', startDate: '01-Mar-2026', lat: 37.3230, lng: -122.0322 },
  { name: 'Bay Area - Fremont', region: 'Fremont CA', addr: 'Gurukul, Fremont Blvd, Fremont, CA 94555', email: 'Prajna.JETCA1@jetusa.org', country: 'USA', state: 'CA', profileId: 60, enrollmentYear: '2026', startDate: '01-Mar-2026', lat: 37.5485, lng: -121.9886 },
  { name: 'Bay Area - Fremont Mission', region: 'Fremont CA', addr: 'Enos St, Fremont, CA 94539', email: 'Prajna.JETCA1@jetusa.org', country: 'USA', state: 'CA', profileId: 61, enrollmentYear: '2026', startDate: '01-Mar-2026', lat: 37.5336, lng: -121.9267 },
  { name: 'Bay Area - Milpitas', region: 'Milpitas CA', addr: 'Online', email: 'Prajna.JETCA1@jetusa.org', country: 'USA', state: 'CA', profileId: 64, enrollmentYear: '2026', startDate: '01-Mar-2026', lat: null, lng: null },
  { name: 'Bay Area - San Ramon', region: 'San Ramon CA', addr: 'Fioli Loop, San Ramon, CA 94582', email: 'Prajna.JETCA2@jetusa.org', country: 'USA', state: 'CA', profileId: 63, enrollmentYear: '2026', startDate: '01-Mar-2026', lat: 37.7799, lng: -121.9780 },
  { name: 'Bay Area - San Jose Evergreen', region: 'San Jose CA', addr: 'Fowler Rd, San Jose, CA 95135', email: 'Prajna.JETCA2@jetusa.org', country: 'USA', state: 'CA', profileId: 44, enrollmentYear: '2026', startDate: '01-Mar-2026', lat: 37.3382, lng: -121.8863 },
  { name: 'California Online', region: 'California Online', addr: 'Online', email: 'prajna@jetcalifornia.org', country: 'USA', state: 'CA', profileId: 131, enrollmentYear: '2026', startDate: '01-Mar-2026', lat: null, lng: null },
  { name: 'Los Angeles', region: 'Los Angeles CA', addr: 'Online', email: 'prajna@jetcalifornia.org', country: 'USA', state: 'CA', profileId: 67, enrollmentYear: '2026', startDate: '01-Mar-2026', lat: 34.0522, lng: -118.2437 },
  { name: 'Mountain House', region: 'Mountain House CA', addr: 'Freeman Way, Mountain House, CA 95391', email: 'Prajna.JETCA1@jetusa.org', country: 'USA', state: 'CA', profileId: 163, enrollmentYear: '2026', startDate: '01-Mar-2026', lat: 37.7689, lng: -121.5361 },
  { name: 'San Jose', region: 'San Jose CA', addr: 'Begonia Dr, San Jose, CA 95124', email: 'Prajna.JETCA2@jetusa.org', country: 'USA', state: 'CA', profileId: 68, enrollmentYear: '2026', startDate: '01-Mar-2026', lat: 37.3382, lng: -121.8863 },
  { name: 'Connecticut - Farmington', region: 'Shelton CT', addr: '41 Windsor Rd, Shelton, CT 06484', email: 'jetct.prajna@jetusa.org', country: 'USA', state: 'CT', profileId: 29, enrollmentYear: '2025', startDate: '01-Aug-2025', lat: 41.3170, lng: -73.0930 },
  { name: 'Connecticut - Hartford', region: 'Shelton CT', addr: '41 Windsor Rd, Shelton, CT 06484', email: 'jetct.prajna@jetusa.org', country: 'USA', state: 'CT', profileId: 84, enrollmentYear: '2026', startDate: '01-May-2026', lat: 41.2957, lng: -73.173 },
  { name: 'Connecticut - Stamford', region: 'Shelton CT', addr: '41 Windsor Rd, Shelton, CT 06484', email: 'jetct.prajna@jetusa.org', country: 'USA', state: 'CT', profileId: 86, enrollmentYear: '2025', startDate: '01-Aug-2025', lat: 41.2957, lng: -73.173 },
  { name: 'Connecticut - Trumbull/Milford', region: 'Shelton CT', addr: '41 Windsor Rd, Shelton, CT 06484', email: 'jetct.prajna@jetusa.org', country: 'USA', state: 'CT', profileId: 87, enrollmentYear: '2025', startDate: '01-Aug-2025', lat: 41.2957, lng: -73.173 },
  { name: 'Orlando', region: 'Orlando FL', addr: '8937 Southern Breeze Dr, Orlando, FL 32836', email: 'prajna.orlando@gmail.com', country: 'USA', state: 'FL', profileId: 58, enrollmentYear: '2025', startDate: '05-Aug-2025', lat: 28.4220, lng: -81.4978 },
  { name: 'Tampa - Brandon', region: 'Brandon FL', addr: '1706 Acadia Harbor Pl, Brandon, FL 33511', email: 'jettampa.prajna@jetusa.org', country: 'USA', state: 'FL', profileId: 91, enrollmentYear: '2025', startDate: '01-Aug-2025', lat: 27.9378, lng: -82.2859 },
  { name: 'Tampa', region: 'Tampa FL', addr: '10215 Deercliff Dr, Tampa, FL 33647', email: 'jettampa.prajna@jetusa.org', country: 'USA', state: 'FL', profileId: 89, enrollmentYear: '2025', startDate: '01-Aug-2025', lat: 28.0930, lng: -82.3580 },
  { name: 'GA - Cumming', region: 'Cumming GA', addr: '1830 Peachtree Pkwy #530, Cumming, GA 30041', email: 'jetatlanta.prajna@jetusa.org', country: 'USA', state: 'GA', profileId: 173, enrollmentYear: '2025', startDate: '16-Jun-2025', lat: 34.2070, lng: -84.1402 },
  { name: 'Bloomingdale', region: 'Bloomingdale IL', addr: '220 Jorrie Lane, Bloomingdale, IL 60108', email: 'sampathnellutla@yahoo.com', country: 'USA', state: 'IL', profileId: 179, enrollmentYear: '2024', startDate: null, lat: 41.9576, lng: -88.0812 },
  { name: 'Bloomington', region: 'Bloomington IL', addr: '2802 Blarney Stone Ln, Bloomington, IL 61704', email: 'jetbloomington.prajna@jetusa.org', country: 'USA', state: 'IL', profileId: 52, enrollmentYear: '2025', startDate: '08-Aug-2025', lat: 40.4842, lng: -88.9937 },
  { name: 'Carpentersville', region: 'Carpentersville IL', addr: 'Balaji Mandir, 275 Skyline Dr, Carpentersville, IL 60110', email: 'sampathnellutla@yahoo.com', country: 'USA', state: 'IL', profileId: 194, enrollmentYear: '2025', startDate: '22-Sep-2025', lat: 42.1264, lng: -88.2683 },
  { name: 'Naperville', region: 'Naperville IL', addr: '1539 Bayou Path Dr, Naperville, IL 60563', email: 'praveenom@gmail.com', country: 'USA', state: 'IL', profileId: 92, enrollmentYear: '2024', startDate: '23-Sep-2024', lat: 41.7508, lng: -88.1535 },
  { name: 'New England - Lexington', region: 'Lexington MA', addr: 'Lexington Community Center, 39 Marrett Rd, Lexington, MA 02421', email: 'Priyatnk@gmail.com', country: 'USA', state: 'MA', profileId: 46, enrollmentYear: '2025', startDate: '26-Jun-2025', lat: 42.4473, lng: -71.2245 },
  { name: 'New England - Acton', region: 'Acton MA', addr: '65 Canterbury Hill Rd, Acton, MA 01720', email: 'prajnaacton@gmail.com', country: 'USA', state: 'MA', profileId: 7, enrollmentYear: '2025', startDate: '01-Jul-2025', lat: 42.4851, lng: -71.4328 },
  { name: 'New England - Northboro', region: 'Northborough MA', addr: 'Sri Shirdi Sai Baba Temple, 107 Otis St, Northborough, MA 01532', email: 'madhavi_donepudi@yahoo.com', country: 'USA', state: 'MA', profileId: 47, enrollmentYear: '2025', startDate: '26-Jun-2025', lat: 42.2907, lng: -71.656 },
  { name: 'New England - Sharon', region: 'Mansfield MA', addr: '48 Darby Drive, Mansfield, MA 02048', email: 'kurugantis@yahoo.com', country: 'USA', state: 'MA', profileId: 48, enrollmentYear: '2025', startDate: '26-Jun-2025', lat: 42.039, lng: -71.181 },
  { name: 'New England - Weymouth', region: 'Weymouth MA', addr: '5 Skyhawk Circle, Weymouth, MA 02190', email: 'ajitha0531@gmail.com', country: 'USA', state: 'MA', profileId: 112, enrollmentYear: '2025', startDate: '26-Jun-2025', lat: 42.1572, lng: -70.9515 },
  { name: 'Michigan - Kalamazoo', region: 'Kalamazoo MI', addr: '7348 Laso Ridge Dr, Kalamazoo, MI 49009', email: 'revathipvs@yahoo.com', country: 'USA', state: 'MI', profileId: 167, enrollmentYear: '2025', startDate: '01-Sep-2025', lat: 42.2917, lng: -85.5872 },
  { name: 'Michigan - Novi', region: 'Novi MI', addr: 'Schoolcraft College, 18600 Haggerty Rd, Livonia/Novi, MI 48152', email: 'jetmichigan@jetusa.org', country: 'USA', state: 'MI', profileId: 71, enrollmentYear: '2025', startDate: '27-Jul-2025', lat: 42.4084, lng: -83.3833 },
  { name: 'Michigan Online', region: 'Michigan Online', addr: 'Schoolcraft College, Livonia, MI 48375', email: 'jetmichigan@jetusa.org', country: 'USA', state: 'MI', profileId: 156, enrollmentYear: '2025', startDate: '01-Sep-2025', lat: 42.4193, lng: -83.4287 },
  { name: 'Michigan - Troy', region: 'Novi MI', addr: '1786 Farmbrook Dr, Novi, MI 48085', email: 'jetmichigan@jetusa.org', country: 'USA', state: 'MI', profileId: 115, enrollmentYear: '2023', startDate: '01-Jun-2023', lat: 42.4806, lng: -83.4755 },
  { name: 'Michigan - Troy 2', region: 'Troy MI', addr: '2945 Briarwood Dr, Troy, MI 48045', email: 'jetmichigan@jetusa.org', country: 'USA', state: 'MI', profileId: 116, enrollmentYear: '2020', startDate: '14-Jun-2020', lat: 42.6056, lng: -83.1499 },
  { name: 'MN - Edina', region: 'Edina MN', addr: 'S V Temple, 7615 Metro Blvd, Edina, MN 55439', email: 'jetmn@jetusa.org', country: 'USA', state: 'MN', profileId: 162, enrollmentYear: '2026', startDate: '15-May-2026', lat: 44.8408, lng: -93.4180 },
  { name: 'MN - Plymouth', region: 'Plymouth MN', addr: '15600 Old Rockford Rd, Plymouth, MN 55446', email: 'jetmn@jetusa.org', country: 'USA', state: 'MN', profileId: 6, enrollmentYear: '2026', startDate: '15-May-2026', lat: 45.0105, lng: -93.4555 },
  { name: 'Missouri - Nixa', region: 'Nixa MO', addr: '3111 Winged Foot Dr, Nixa, MO 65714', email: 'ram.maruudi@gmail.com', country: 'USA', state: 'MO', profileId: 180, enrollmentYear: '2025', startDate: '09-Mar-2025', lat: 37.0436, lng: -93.2861 },
  { name: 'Nebraska - Omaha', region: 'Omaha NE', addr: '3103 N 169th Ave, Omaha, NE 68116', email: 'dlsaranam@gmail.com', country: 'USA', state: 'NE', profileId: 168, enrollmentYear: '2026', startDate: '05-Apr-2026', lat: 41.2823, lng: -96.1956 },
  { name: 'New England - Nashua', region: 'Nashua NH', addr: '64 Ridge Road, Nashua, NH 03062', email: 'sgomattam@gmail.com', country: 'USA', state: 'NH', profileId: 45, enrollmentYear: '2025', startDate: '26-Jun-2025', lat: 42.7654, lng: -71.4676 },
  { name: 'NJ - Edison', region: 'Edison NJ', addr: '3775 Park Ave, Edison, NJ 08820', email: 'jrpuskur@yahoo.com', country: 'USA', state: 'NJ', profileId: 21, enrollmentYear: '2025', startDate: '21-Jun-2025', lat: 40.5187, lng: -74.4121 },
  { name: 'NJ - Cranbury (Saturday)', region: 'Cranbury NJ', addr: '222 Dey Road, Cranbury, NJ 08512', email: 'jetnj.prajna@jetusa.org', country: 'USA', state: 'NJ', profileId: 19, enrollmentYear: '2026', startDate: '17-May-2026', lat: 40.3120, lng: -74.5238 },
  { name: 'NJ - Cranbury (Sunday)', region: 'Cranbury NJ', addr: '222 Dey Road, Cranbury, NJ 08512', email: 'vmadhavmr@yahoo.com', country: 'USA', state: 'NJ', profileId: 117, enrollmentYear: '2026', startDate: '17-May-2026', lat: 40.3120, lng: -74.5238 },
  { name: 'NJ - Willingboro', region: 'Willingboro NJ', addr: '494 Beverly Rancocas Rd, Willingboro, NJ 08046', email: 'madhu74@gmail.com', country: 'USA', state: 'NJ', profileId: 22, enrollmentYear: '2025', startDate: '21-Jun-2025', lat: 40.0290, lng: -74.8810 },
  { name: 'NJ - Monroe', region: 'Monroe Township NJ', addr: '50 Green Ash St, Monroe Township, NJ 08831', email: 'jetnj.prajna@jetusa.org', country: 'USA', state: 'NJ', profileId: 186, enrollmentYear: '2025', startDate: '19-Jul-2025', lat: 40.3134, lng: -74.4296 },
  { name: 'NC - Cary', region: 'Cary NC', addr: '1807 Old London Way, Cary, NC 27513', email: 'jetusacary@gmail.com', country: 'USA', state: 'NC', profileId: 49, enrollmentYear: '2025', startDate: '10-Jul-2025', lat: 35.7915, lng: -78.7811 },
  { name: 'NC - Charlotte (Ballantyne)', region: 'Charlotte NC', addr: '11532 Golf Links Dr, Charlotte, NC 28277', email: 'jetcharlotte.prajna@jetusa.org', country: 'USA', state: 'NC', profileId: 50, enrollmentYear: '2025', startDate: '10-Aug-2025', lat: 35.0680, lng: -80.8480 },
  { name: 'NC - Charlotte (Concord)', region: 'Concord NC', addr: 'WR Odell Primary School, 1 Dragon Pride Dr, Concord, NC 28027', email: 'JETConcord.Prajna@jetusa.org', country: 'USA', state: 'NC', profileId: 51, enrollmentYear: '2026', startDate: '22-Apr-2026', lat: 35.4094, lng: -80.58 },
  { name: 'Cincinnati', region: 'Mason OH', addr: '6410 Sunny Drive, Mason, OH 45040', email: 'jetcincinnati.prajna@jetusa.org', country: 'USA', state: 'OH', profileId: 41, enrollmentYear: '2025', startDate: '26-Jan-2025', lat: 39.3601, lng: -84.3094 },
  { name: 'Columbus - Dublin', region: 'Dublin OH', addr: '7953 Tullymore Dr, Dublin, OH 43016', email: 'mmarpadga@gmail.com', country: 'USA', state: 'OH', profileId: 27, enrollmentYear: '2024', startDate: '01-Sep-2024', lat: 40.0992, lng: -83.1141 },
  { name: 'Columbus - Lewis Center', region: 'Columbus OH', addr: '1506 Sarin St, Columbus, OH 43240', email: 'jetcolumbus@jetusa.org', country: 'USA', state: 'OH', profileId: 70, enrollmentYear: '2026', startDate: '23-Jan-2026', lat: 40.1851, lng: -82.9961 },
  { name: 'Portland', region: 'Portland OR', addr: '12370 NW Hibbard Drive, Portland, OR 97229', email: 'srikanthpdx@gmail.com', country: 'USA', state: 'OR', profileId: 80, enrollmentYear: '2025', startDate: '28-Aug-2025', lat: 45.5365, lng: -122.8400 },
  { name: 'PA - Eastern', region: 'Northampton PA', addr: '3498 High Meadow Drive, Northampton, PA 18067', email: 'raghava@jetusa.org', country: 'USA', state: 'PA', profileId: 118, enrollmentYear: '2026', startDate: '29-Apr-2026', lat: 40.6857, lng: -75.4905 },
  { name: 'Pittsburgh (Sewickley)', region: 'Sewickley PA', addr: '1913 Colonial Dr, Sewickley, PA 15143', email: 'jetpittsburgh@jetusa.org', country: 'USA', state: 'PA', profileId: 33, enrollmentYear: '2026', startDate: '29-Apr-2026', lat: 40.5364, lng: -80.1839 },
  { name: 'Pittsburgh (South Fayette)', region: 'McDonald PA', addr: '7006 Sherwood Drive, McDonald, PA 15057', email: 'rsknine@gmail.com', country: 'USA', state: 'PA', profileId: 34, enrollmentYear: '2026', startDate: '29-Apr-2026', lat: 40.3873, lng: -80.2333 },
  { name: 'Nashville', region: 'Franklin TN', addr: '2220 Wolford Circle, Franklin, TN 37067', email: 'januash@gmail.com', country: 'USA', state: 'TN', profileId: 81, enrollmentYear: '2026', startDate: '11-May-2026', lat: 35.9251, lng: -86.8689 },
  { name: 'Ashtalakshmi Houston', region: 'Sugarland TX', addr: '10098 Synott Rd, Sugarland, TX 77498', email: 'jetalt.prajna@jetusa.org', country: 'USA', state: 'TX', profileId: 1, enrollmentYear: '2026', startDate: '16-May-2026', lat: 29.6196, lng: -95.6349 },
  { name: 'Cypress', region: 'Cypress TX', addr: '16407 Star Canyon, Cypress, TX 77429', email: 'swetha.ba29@gmail.com', country: 'USA', state: 'TX', profileId: 170, enrollmentYear: '2026', startDate: '20-May-2026', lat: 29.9691, lng: -95.6972 },
  { name: 'Katy', region: 'Katy TX', addr: 'Discovery School House, 4900 Falcon Landing Blvd, Katy, TX 77494', email: 'jetkaty.prajna@jetusa.org', country: 'USA', state: 'TX', profileId: 2, enrollmentYear: '2026', startDate: '01-May-2026', lat: 29.7858, lng: -95.8245 },
  { name: 'Leander', region: 'Leander TX', addr: '1699 N US Hwy 183, Leander, TX 78641', email: 'jetaustin.prajna@jetusa.org', country: 'USA', state: 'TX', profileId: 185, enrollmentYear: '2026', startDate: '27-Apr-2026', lat: 30.5788, lng: -97.8531 },
  { name: 'Pearland', region: 'Pearland TX', addr: '9415 Broadway St, Unit 121, Pearland, TX 77584', email: 'Swetha.ba29@gmail.com', country: 'USA', state: 'TX', profileId: 184, enrollmentYear: '2025', startDate: '01-Jul-2025', lat: 29.5635, lng: -95.2860 },
  { name: 'Woodlands', region: 'Woodlands TX', addr: '6707 Sterling Ridge Dr, Site C, Woodlands, TX 77382', email: 'swetha.ba29@gmail.com', country: 'USA', state: 'TX', profileId: 182, enrollmentYear: '2025', startDate: '17-Jul-2025', lat: 30.1658, lng: -95.4613 },
  { name: 'Austin', region: 'Austin TX', addr: '7301 Shasta Cv, Austin, TX 78759', email: 'jetaustin.prajna@jetusa.org', country: 'USA', state: 'TX', profileId: 53, enrollmentYear: '2026', startDate: '27-Apr-2026', lat: 30.2672, lng: -97.7431 },
  { name: 'DFW Celina', region: 'Celina TX', addr: '2913 Misty Pond Ct, Celina, TX 75009', email: 'jetdfw.prajna@jetusa.org', country: 'USA', state: 'TX', profileId: 176, enrollmentYear: '2026', startDate: '29-Apr-2026', lat: 33.3251, lng: -96.7841 },
  { name: 'DFW Coppell', region: 'Irving TX', addr: '504 Ranch Trl, Irving, TX 75063', email: 'prajnadfw@gmail.com', country: 'USA', state: 'TX', profileId: 12, enrollmentYear: '2025', startDate: '23-Mar-2025', lat: 32.9412, lng: -96.9700 },
  { name: 'DFW Frisco', region: 'Frisco TX', addr: '8501 Wade Blvd Suite 520, Frisco, TX 75034', email: 'prajnadfw@gmail.com', country: 'USA', state: 'TX', profileId: 9, enrollmentYear: '2026', startDate: '29-Apr-2026', lat: 33.1507, lng: -96.8236 },
  { name: 'DFW Lewisville', region: 'Lewisville TX', addr: '2501 Brandon Dr, Lewisville, TX 75056', email: 'prajnadfw@gmail.com', country: 'USA', state: 'TX', profileId: 14, enrollmentYear: '2025', startDate: '23-Mar-2025', lat: 33.0462, lng: -96.9942 },
  { name: 'San Antonio', region: 'San Antonio TX', addr: '21003 Encino Commons Suite #101, San Antonio, TX 78259', email: 'jetsanantonio.prajna@jetusa.org', country: 'USA', state: 'TX', profileId: 55, enrollmentYear: '2025', startDate: '15-Aug-2025', lat: 29.6300, lng: -98.4400 },
  { name: 'Ananda Nilayam - Herndon', region: 'Ashburn VA', addr: 'Online Classes, Ashburn, VA 20148', email: 'jetdc.prajna@jetusa.org', country: 'USA', state: 'VA', profileId: 3, enrollmentYear: '2026', startDate: '03-Apr-2026', lat: 39.0438, lng: -77.4874 },
  { name: 'Hindu Temple - Sterling', region: 'Sterling VA', addr: '44805 Acacia Ln, Sterling, VA 20166', email: 'nmudumbai@gmail.com', country: 'USA', state: 'VA', profileId: 205, enrollmentYear: '2026', startDate: '13-Apr-2026', lat: 39.0123, lng: -77.4030 },
  { name: 'Rama Dandu (Crozet)', region: 'Crozet VA', addr: '2227 Kendall Ct, Crozet, VA 22932', email: 'jetcharlottesville@jetusa.org', country: 'USA', state: 'VA', profileId: 28, enrollmentYear: '2024', startDate: '02-Sep-2024', lat: 38.0712, lng: -78.7000 },
  { name: 'Seattle - Bothell', region: 'Bothell WA', addr: 'Mathpath, 1729 208th St SE, Bothell, WA 98012', email: 'Jetseattle.prajna@jetusa.org', country: 'USA', state: 'WA', profileId: 37, enrollmentYear: '2025', startDate: '24-May-2025', lat: 47.7623, lng: -122.2054 },
  { name: 'Seattle Online', region: 'Seattle WA Online', addr: 'Online', email: 'Jetseattle.prajna@jetusa.org', country: 'USA', state: 'WA', profileId: 82, enrollmentYear: '2025', startDate: '24-May-2025', lat: null, lng: null },
  { name: 'Seattle - Bellevue', region: 'Bellevue WA', addr: 'Sri Balaji Temple, 12501 NE Bel Red Rd, Bellevue, WA 98005', email: 'Jetseattle.prajna@jetusa.org', country: 'USA', state: 'WA', profileId: 35, enrollmentYear: '2025', startDate: '24-May-2025', lat: 47.6244, lng: -122.1670 },
  { name: 'Seattle - Sammamish', region: 'Sammamish WA', addr: '21333 SE 20th St, Sammamish, WA 98075', email: 'Jetseattle.prajna@jetusa.org', country: 'USA', state: 'WA', profileId: 36, enrollmentYear: '2025', startDate: '24-May-2025', lat: 47.5764, lng: -122.0273 },
];

// Real interactive map using Leaflet + OpenStreetMap (free, no API key).
// Loaded via CDN in centers.html. `L` is global once leaflet.js runs.
const CentersMap = ({ centers, selected, onSelect, searchedLoc }) => {
  const containerRef = React.useRef(null);
  const mapRef       = React.useRef(null);
  const markersRef   = React.useRef([]);
  const searchMarkerRef = React.useRef(null);

  const makePin = (isSelected) => L.divIcon({
    className: 'prajna-pin' + (isSelected ? ' prajna-pin--selected' : ''),
    iconSize: [isSelected ? 26 : 18, isSelected ? 26 : 18],
    iconAnchor: [isSelected ? 13 : 9, isSelected ? 13 : 9],
    popupAnchor: [0, isSelected ? -16 : -12],
    html: `<span class="prajna-pin__shape"></span>`,
  });

  const makeSearchPin = () => L.divIcon({
    className: 'prajna-pin prajna-pin--search',
    iconSize: [22, 22],
    iconAnchor: [11, 11],
    html: `<span class="prajna-pin__shape"></span>`,
  });

  // Init map once on mount
  React.useEffect(() => {
    if (!containerRef.current || typeof L === 'undefined') return;
    // Find the first center that actually has coordinates for the initial view.
    // Centers without lat/lng (online-only, ungeocoded) still appear in the
    // list but are skipped on the map.
    const firstWithCoords = centers.find(c => c.lat != null && c.lng != null);
    const initialCenter = firstWithCoords
      ? [firstWithCoords.lat, firstWithCoords.lng]
      : [20, 0]; // fall back to a roughly global view
    const map = L.map(containerRef.current, { scrollWheelZoom: false }).setView(initialCenter, firstWithCoords ? 10 : 2);
    L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', {
      attribution: '© OpenStreetMap, © CARTO',
      maxZoom: 19,
      subdomains: 'abcd',
    }).addTo(map);
    mapRef.current = map;

    // Leaflet caches container size at init. If the container is later resized
    // (sticky header settles, fonts load, ancestor flexbox reflows), tiles
    // can render with a grey gutter on one side. invalidateSize() forces a
    // recalculation. Run once after layout settles, plus on every window resize.
    const fix = () => map.invalidateSize();
    setTimeout(fix, 50);
    setTimeout(fix, 250);
    window.addEventListener('resize', fix);
    let ro;
    if (window.ResizeObserver) {
      ro = new ResizeObserver(fix);
      ro.observe(containerRef.current);
    }

    return () => {
      window.removeEventListener('resize', fix);
      if (ro) ro.disconnect();
      map.remove();
      mapRef.current = null;
      markersRef.current = [];
    };
    // eslint-disable-next-line
  }, []);

  // Re-add center markers whenever the centers list changes (search re-orders
  // them). Each marker gets:
  //   - a hover tooltip showing "Name · distance" (visible without clicking)
  //   - a click popup with the full details + Register link
  // After a search the `dist` field on each center is the live haversine
  // distance to the searched location, so the tooltip + popup reflect it.
  React.useEffect(() => {
    if (!mapRef.current || typeof L === 'undefined') return;
    markersRef.current.forEach(m => m.remove());
    markersRef.current = [];
    centers.forEach((c, i) => {
      if (c.lat == null || c.lng == null) return; // skip centers without coords
      const m = L.marker([c.lat, c.lng], { icon: makePin(i === selected), title: c.name, alt: c.name, keyboard: true }).addTo(mapRef.current);
      const mEl = m.getElement();
      if (mEl) { mEl.setAttribute('role', 'button'); mEl.setAttribute('aria-label', `${c.name} center`); }
      const distLine = c.dist ? `<strong>${c.name}</strong> · ${c.dist}` : `<strong>${c.name}</strong>`;
      m.bindTooltip(distLine, { direction: 'top', offset: [0, -10], className: 'prajna-tooltip' });
      const subline = [c.dist, c.addr].filter(Boolean).join(' · ');
      m.bindPopup(
        `<div style="font-weight:700;font-size:14px;">${c.name}</div>
         <div style="font-size:12px;color:#555;margin-top:4px;">${subline}</div>
         <a href="register.html" style="display:inline-block;margin-top:8px;background:#ed7e1d;color:#fff;padding:6px 12px;border-radius:999px;text-decoration:none;font-size:12px;font-weight:700;">Register</a>`
      );
      m.on('click', () => onSelect(i));
      markersRef.current.push(m);
    });
    // eslint-disable-next-line
  }, [centers]);

  // Restyle markers when selection changes; pan to selected center
  React.useEffect(() => {
    if (!mapRef.current) return;
    markersRef.current.forEach((m, i) => {
      m.setIcon(makePin(i === selected));
      const el = m.getElement();
      if (el) { el.setAttribute('role', 'button'); el.setAttribute('aria-label', `${centers[i].name} center`); }
    });
    const c = centers[selected];
    if (c && c.lat != null && c.lng != null && !searchedLoc) {
      mapRef.current.flyTo([c.lat, c.lng], 11, { duration: 0.6 });
      markersRef.current[selected]?.openPopup();
    }
  }, [selected]);

  // When user searches: drop a search pin, pan to fit user location + closest 5 centers
  React.useEffect(() => {
    if (!mapRef.current || typeof L === 'undefined') return;
    if (searchMarkerRef.current) {
      searchMarkerRef.current.remove();
      searchMarkerRef.current = null;
    }
    const withCoords = centers.filter(c => c.lat != null && c.lng != null);
    if (!searchedLoc) {
      // No search: refit to all centers that have coordinates
      if (withCoords.length === 0) return;
      const bounds = L.latLngBounds(withCoords.map(c => [c.lat, c.lng]));
      mapRef.current.fitBounds(bounds, { padding: [40, 40] });
      return;
    }
    // Add a distinctive "you searched here" pin
    const sm = L.marker([searchedLoc.lat, searchedLoc.lng], { icon: makeSearchPin(), zIndexOffset: 1000, title: 'You searched here', alt: 'You searched here' })
      .addTo(mapRef.current)
      .bindPopup('<div style="font-weight:700;font-size:13px;">You searched here</div>');
    const smEl = sm.getElement();
    if (smEl) { smEl.setAttribute('role', 'img'); smEl.setAttribute('aria-label', 'Your searched location'); }
    searchMarkerRef.current = sm;

    // Fit to the search location + 5 closest centers (already at the top of the sorted list)
    const closest = withCoords.slice(0, 5);
    const bounds = L.latLngBounds([
      [searchedLoc.lat, searchedLoc.lng],
      ...closest.map(c => [c.lat, c.lng])
    ]);
    mapRef.current.fitBounds(bounds, { padding: [50, 50], maxZoom: 11 });
  }, [searchedLoc, centers]);

  return (
    <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
      <div ref={containerRef} style={{ height: 540, width: '100%' }} />
    </div>
  );
};

// Haversine distance in miles between two {lat, lng} points
const haversineMi = (a, b) => {
  const R = 3958.8;
  const toRad = d => d * Math.PI / 180;
  const dLat = toRad(b.lat - a.lat);
  const dLng = toRad(b.lng - a.lng);
  const x = Math.sin(dLat / 2) ** 2 +
    Math.cos(toRad(a.lat)) * Math.cos(toRad(b.lat)) *
    Math.sin(dLng / 2) ** 2;
  return 2 * R * Math.asin(Math.sqrt(x));
};

const CentersPage = () => {
  const [selected, setSelected] = React.useState(0);
  const [searchInput, setSearchInput] = React.useState('98052');
  // searchedTerm = the query that was actually submitted (Search clicked /
  // Enter pressed / chip clicked). We keep this separate from `searchInput`
  // so that what shows below the map doesn't change as the user retypes.
  const [searchedTerm, setSearchedTerm] = React.useState('');
  const [searchedLoc, setSearchedLoc] = React.useState(null); // {lat, lng}
  const [searchedLabel, setSearchedLabel] = React.useState('');
  const [searchError, setSearchError] = React.useState('');
  const [searching, setSearching] = React.useState(false);

  const runSearch = async (queryOverride) => {
    const q = (queryOverride ?? searchInput).trim();
    if (!q) return;
    setSearching(true);
    setSearchError('');
    try {
      const url = `https://nominatim.openstreetmap.org/search?format=json&limit=1&q=${encodeURIComponent(q)}`;
      const res = await fetch(url);
      const data = await res.json();
      if (!data || data.length === 0) {
        setSearchError(`We couldn't find "${q}". Try a city, country, or ZIP.`);
        setSearching(false);
        return;
      }
      const top = data[0];
      const loc = { lat: parseFloat(top.lat), lng: parseFloat(top.lon) };
      const label = top.display_name.split(',').slice(0, 2).join(',').trim();
      setSearchedLoc(loc);
      setSearchedLabel(label);
      setSearchedTerm(q);
      setSelected(0); // re-highlight closest after sort
    } catch (e) {
      setSearchError('Search is unavailable right now. Please try again.');
    }
    setSearching(false);
  };

  const useMyLocation = () => {
    if (!navigator.geolocation) {
      setSearchError('Geolocation is not available in this browser.');
      return;
    }
    setSearching(true);
    setSearchError('');
    navigator.geolocation.getCurrentPosition(
      (pos) => {
        setSearchedLoc({ lat: pos.coords.latitude, lng: pos.coords.longitude });
        setSearchedLabel('your location');
        setSearchedTerm('your location');
        setSelected(0);
        setSearching(false);
      },
      () => {
        setSearchError('Could not get your location. Try typing a city or ZIP.');
        setSearching(false);
      },
      { timeout: 8000 }
    );
  };

  // Sort centers by distance to the searched location, with the computed
  // distance written into each center's `dist` field for display. Centers
  // without lat/lng are sorted to the end with a blank distance label.
  const orderedCenters = React.useMemo(() => {
    if (!searchedLoc) return CENTERS;
    return [...CENTERS]
      .map(c => {
        if (c.lat == null || c.lng == null) {
          return { ...c, _distance: Infinity, dist: '' };
        }
        const d = haversineMi(searchedLoc, { lat: c.lat, lng: c.lng });
        const dStr = d < 10 ? `${d.toFixed(1)} mi` : `${Math.round(d)} mi`;
        return { ...c, _distance: d, dist: dStr };
      })
      .sort((a, b) => a._distance - b._distance);
  }, [searchedLoc]);

  return (
    <>
      <Header active="Centers" />
      <section style={{ padding: '56px 0 32px', background: 'linear-gradient(180deg, var(--paper-2), var(--paper))', borderBottom: '1px solid var(--line)' }}>
        <div className="container">
          <div className="breadcrumbs"><a href="index.html">Home</a> · <span>Centers</span></div>
          <h1 className="h-1" style={{ marginTop: 8 }}>Centers</h1>
          <div className="card centers-search" style={{ padding: 8, marginTop: 18, display: 'flex', gap: 8, alignItems: 'center', maxWidth: 720 }}>
            <span style={{ paddingLeft: 12, color: 'var(--ink-3)' }}>📍</span>
            <input
              style={{ flex: 1, border: 0, outline: 0, fontSize: 15, padding: '12px 0', background: 'transparent', fontFamily: 'inherit' }}
              placeholder="ZIP, city or country"
              value={searchInput}
              onChange={(e) => setSearchInput(e.target.value)}
              onKeyDown={(e) => { if (e.key === 'Enter') runSearch(); }}
              disabled={searching}
            />
            <button className="btn btn--ghost btn--sm" onClick={useMyLocation} disabled={searching}>Use my location</button>
            <button className="btn btn--primary" onClick={() => runSearch()} disabled={searching}>{searching ? 'Searching…' : 'Search'}</button>
          </div>
          {searchError && (
            <div className="centers-search__error">{searchError}</div>
          )}
          <div className="row" style={{ marginTop: 14, gap: 6, flexWrap: 'wrap', alignItems: 'center' }}>
            <span className="body-sm">Popular:</span>
            {['Seattle', 'Bay Area', 'New Jersey', 'London', 'Hyderabad'].map(c => (
              <button
                key={c}
                className="chip"
                style={{ cursor: 'pointer', font: 'inherit', fontSize: 12 }}
                onClick={() => { setSearchInput(c); runSearch(c); }}
              >{c}</button>
            ))}
          </div>
          <div className="centers-request-line">
            Don&rsquo;t see your area?{' '}
            <a href={'request-center.html' + (searchedLoc && searchedTerm ? '?location=' + encodeURIComponent(searchedTerm) : '')}>
              Request a Prajna center in your community.
            </a>
          </div>
        </div>
      </section>

      {/* Big world map up top — pans to the searched location */}
      <div className="centers-map-wrap">
        <div className="container">
          <CentersMap
            centers={orderedCenters}
            selected={selected}
            onSelect={setSelected}
            searchedLoc={searchedLoc}
          />
        </div>
      </div>

      {/* Centers list — when searching, separate centers in/matching the
          searched place from "Other nearby centers" (sorted by distance).
          A center counts as "matched" if it's either within NEARBY_MILES of
          the searched coordinates, or its region/address/name contains the
          typed term. So a ZIP a few miles from a center still surfaces it. */}
      {(() => {
        const NEARBY_MILES = 10;
        // Filter and label off the *submitted* search, not the live input.
        const term = searchedTerm.trim().toLowerCase();
        const matched = (searchedLoc && term)
          ? orderedCenters.filter(c =>
              c._distance <= NEARBY_MILES ||
              c.region.toLowerCase().includes(term) ||
              c.addr.toLowerCase().includes(term) ||
              c.name.toLowerCase().includes(term)
            )
          : [];
        const others = orderedCenters.filter(c => !matched.includes(c));

        const renderCard = (c) => {
          const i = orderedCenters.indexOf(c);
          const slug = c.name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
          // Prefer Google Sites page when Anil's CSV has provided one;
          // otherwise fall back to the internal profile page.
          const googleSitesUrl = CENTER_GOOGLE_SITES[c.profileId];
          const href = googleSitesUrl || ('center-profile.html?center=' + slug);
          return (
            <a
              key={c.name}
              href={href}
              target={googleSitesUrl ? '_blank' : undefined}
              rel={googleSitesUrl ? 'noopener noreferrer' : undefined}
              onMouseEnter={() => setSelected(i)}
              onFocus={() => setSelected(i)}
              className={'center-card' + (i === selected ? ' center-card--active' : '')}
            >
              <div className="center-card__body">
                <div className="center-card__header">
                  <h3 className="center-card__name">{c.name}</h3>
                  {c.dist && <span className="chip chip--orange">{c.dist}</span>}
                </div>
                <div className="center-card__meta">{c.addr}</div>
                {c.email && (
                  <div className="center-card__meta">
                    <a
                      href={`mailto:${c.email}`}
                      onClick={(e) => e.stopPropagation()}
                      className="center-card__email"
                    >{c.email}</a>
                  </div>
                )}
                {c.enrollmentYear && (
                  <div className="center-card__meta center-card__meta--enroll">
                    Enrolling for <strong>{c.enrollmentYear}</strong>
                    {c.startDate && <> · starts {c.startDate}</>}
                  </div>
                )}
              </div>
              <span className="center-card__arrow" aria-hidden="true"></span>
            </a>
          );
        };

        return (
          <div className="container centers-list-wrap">
            <div className="row" style={{ justifyContent: 'space-between', alignItems: 'center', marginBottom: 20, flexWrap: 'wrap', gap: 8 }}>
              <span className="body-sm">
                {searchedLoc
                  ? <>Closest to <b style={{ color: 'var(--ink)' }}>{searchedLabel}</b>, showing <b style={{ color: 'var(--ink)' }}>{orderedCenters.length} centers</b></>
                  : <>Popular centers <span style={{ color: 'var(--ink-3)' }}>· {CENTERS.length} total worldwide</span></>
                }
              </span>
            </div>

            {matched.length > 0 ? (
              <>
                <div className="centers-section-h">Results</div>
                <div className="centers-list">{matched.map(renderCard)}</div>
                {others.length > 0 && (
                  <div className="centers-section-h centers-section-h--alt">Other centers</div>
                )}
              </>
            ) : searchedLoc ? (
              <div className="centers-empty">
                <strong>No Prajna centers near <span style={{ textTransform: 'capitalize' }}>{searchedLabel || searchedTerm}</span> yet.</strong>
                <span> The closest centers are listed below, sorted by distance.</span>
              </div>
            ) : null}

            <div className="centers-list">
              {(matched.length > 0 ? others : orderedCenters).map(renderCard)}
            </div>
          </div>
        );
      })()}

      <section className="section--tight" style={{ background: 'var(--blue-50)', borderTop: '1px solid var(--blue-100)', borderBottom: '1px solid var(--blue-100)' }}>
        <div className="container">
          <div className="row" style={{ justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 16 }}>
            <div>
              <span className="eyebrow">No center near you?</span>
              <h2 className="h-2" style={{ marginTop: 8 }}>Join an Online Classroom</h2>
            </div>
            <a href="register.html" className="btn btn--primary btn--lg">Online options</a>
          </div>
        </div>
      </section>

      <Footer />
    </>
  );
};

// ─── SHOWCASE ────────────────────────────────────────────
const ShowcasePage = () => {
  const [filter, setFilter] = React.useState('All');
  const items = SHOWCASE_ITEMS;
  const filters = ['All', ...Array.from(new Set(items.map(i => i.tag)))];
  const filtered = filter === 'All' ? items : items.filter(i => i.tag === filter);
  return (
    <>
      <Header active="Showcase" />
      <section className="page-hero page-hero--sm">
        <div className="container">
          <div className="breadcrumbs"><a href="index.html">Home</a> · <span>Showcase</span></div>
          <h1 className="h-1" style={{ marginTop: 8 }}>Showcase</h1>
          <div className="row" style={{ marginTop: 18, gap: 6, flexWrap: 'wrap' }}>
            {filters.map(f => (
              <button key={f} onClick={() => setFilter(f)} className={'chip ' + (filter === f ? 'chip--ink' : '')} style={{ cursor: 'pointer', border: 0, fontFamily: 'inherit', padding: '8px 16px', fontSize: 13 }}>{f}</button>
            ))}
          </div>
        </div>
      </section>

      <section className="section">
        <div className="container">
          <div className="sc-grid">
            {filtered.map((s, i) => (
              <div key={i} className="card" style={{ overflow: 'hidden' }}>
                <div className="photo photo--ratio-1-1" style={{ borderRadius: 0 }}>
                  {s.type === 'video'
                    ? <video className="sc-media" src={s.src} poster={s.poster} controls playsInline preload="metadata"></video>
                    : <img className="sc-media" src={s.src} alt={s.title} />}
                </div>
                <div style={{ padding: 18 }}>
                  <div className="row" style={{ justifyContent: 'space-between', alignItems: 'center' }}>
                    <span className="chip chip--orange" style={{ fontSize: 11 }}>{s.tag}</span>
                    {s.center && <span className="body-sm" style={{ fontSize: 11 }}>📍 {s.center}</span>}
                  </div>
                  <h3 className="h-4" style={{ marginTop: 12 }}>{s.name}{s.age ? <>, <span style={{ fontWeight: 600, color: 'var(--ink-3)' }}>{s.age}</span></> : null}</h3>
                  <p className="body-sm" style={{ marginTop: 6 }}>{s.title}</p>
                </div>
              </div>
            ))}
          </div>
          <div className="center-col" style={{ marginTop: 32 }}>
            <button className="btn btn--ghost btn--lg">Load more</button>
          </div>
        </div>
      </section>
      <Footer />
    </>
  );
};

// ─── FAQ ─────────────────────────────────────────────────
const FAQPage = () => {
  const groups = [
    {
      title: 'Getting Started',
      items: [
        { q: 'What age does Prajna start?', a: 'Prajna welcomes children starting at age 5. Children can join a track based on a placement conversation with the center coordinator.' },
        { q: 'How can my child experience Prajna first?', a: 'Register on the site, then connect with your local center coordinator, who will welcome your child to a class. Use the Centers page to find your nearest center.' },
        { q: 'How do I register my child?', a: 'Click "Register" in the top nav, create a parent account, add your child\'s profile, then choose a nearby center and class. The coordinator will confirm enrollment within a few days.' },
        { q: 'How much does Prajna cost?', a: 'Prajna tuition varies by the center and country. Please contact your nearest center’s coordinator.' },
      ],
    },
    {
      title: 'Curriculum & Classes',
      items: [
        { q: 'How long is each class?', a: 'Classes meet weekly for approximately 2 hours, typically on Saturdays or Sundays.' },
        { q: 'What languages are classes taught in?', a: 'Classes are taught in English, with regional languages (Telugu, Hindi, Tamil) available at many centers.' },
        { q: 'Can my child join mid-year?', a: 'Yes, enrollment is open year-round. Center coordinators will help place your child in the right module based on age and prior experience.' },
        { q: 'What is the difference between Foundation and Advanced tracks?', a: 'Foundation (ages 5–10) introduces stories, prayers, and basic concepts. Advanced Track 1 (11–14) deepens scriptural understanding. Track 2 (13–16) focuses on Life Management Gi:tha. Special Courses are offered to advanced students.' },
      ],
    },
    {
      title: 'Volunteering & Involvement',
      items: [
        { q: 'How do I become a teacher?', a: 'Create a parent account, then submit a "Request as Teacher" intent. The center coordinator will reach out to discuss training and placement.' },
        { q: 'How do I start a center in my city?', a: 'Submit a "Request New Prajna Center" via the contact page. A global coordinator will follow up to discuss feasibility and next steps.' },
        { q: 'Can I donate to Prajna?', a: 'Yes, donations support program materials, teacher training, and outreach. See the Donate link in the footer.' },
      ],
    },
  ];
  const [open, setOpen] = React.useState({ '0-0': true });
  const toggle = (k) => setOpen(o => ({ ...o, [k]: !o[k] }));
  return (
    <>
      <Header active="FAQ" />
      <section className="page-hero page-hero--sm">
        <div className="container-narrow">
          <div className="breadcrumbs"><a href="index.html">Home</a> · <span>FAQ</span></div>
          <h1 className="h-1" style={{ marginTop: 8 }}>FAQ</h1>
        </div>
      </section>

      <section className="section">
        <div className="container-narrow">
          {groups.map((g, gi) => (
            <div key={g.title} style={{ marginBottom: 48 }}>
              <h2 className="h-2">{g.title}</h2>
              <div className="col" style={{ gap: 8, marginTop: 20 }}>
                {g.items.map((it, ii) => {
                  const k = gi + '-' + ii;
                  const isOpen = open[k];
                  return (
                    <div key={ii} className="card" style={{ overflow: 'hidden' }}>
                      <button onClick={() => toggle(k)} style={{
                        display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 16,
                        width: '100%', textAlign: 'left',
                        padding: '20px 24px',
                        border: 0, background: 'transparent', cursor: 'pointer',
                        fontFamily: 'inherit', fontSize: 16, fontWeight: 700, color: 'var(--ink)',
                      }}>
                        <span>{it.q}</span>
                        <span style={{ fontSize: 24, color: 'var(--orange)', transition: 'transform .2s', transform: isOpen ? 'rotate(45deg)' : 'rotate(0)' }}>+</span>
                      </button>
                      {isOpen && (
                        <div style={{ padding: '0 24px 22px', color: 'var(--ink-2)', fontSize: 15, lineHeight: 1.65 }}>
                          {it.a}
                        </div>
                      )}
                    </div>
                  );
                })}
              </div>
            </div>
          ))}

          <div className="card card--orange" style={{ padding: 32, marginTop: 32, textAlign: 'center' }}>
            <h3 className="h-3">Still Have Questions?</h3>
            <p className="body" style={{ marginTop: 8 }}>Reach out to a center coordinator or our global support team.</p>
            <div className="row" style={{ justifyContent: 'center', gap: 12, marginTop: 20, flexWrap: 'wrap' }}>
              <a href="centers.html" className="btn btn--primary">Find a center</a>
              <a href="contact.html" className="btn btn--ghost">Contact us</a>
            </div>
          </div>
        </div>
      </section>
      <Footer />
    </>
  );
};

// ─── REGISTER ────────────────────────────────────────────
// Registration form — text from prajna4me.org register page.
// Reads ?module=<name> from URL so the user knows which module they came from.
// Paired tab control between Log in and Register — the same UI sits on both
// pages so visitors can switch without losing context. Each tab is a real link
// (not an in-page toggle) so each page can stay focused on a single form.
const AuthTabs = ({ active }) => (
  <div className="auth-tabs">
    <a href="login.html" className={'auth-tab' + (active === 'login' ? ' auth-tab--active' : '')}>Log in</a>
    <a href="register.html" className={'auth-tab' + (active === 'register' ? ' auth-tab--active' : '')}>Create an account</a>
  </div>
);

// Eye icons for the show/hide password toggle.
const EyeOpenSvg = () => (
  <svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
    <path d="M1 12s4-7 11-7 11 7 11 7-4 7-11 7-11-7-11-7z"/>
    <circle cx="12" cy="12" r="3"/>
  </svg>
);
const EyeOffSvg = () => (
  <svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
    <path d="M17.94 17.94A10.07 10.07 0 0 1 12 19c-7 0-11-7-11-7a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 7 11 7a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/>
    <line x1="1" y1="1" x2="23" y2="23"/>
  </svg>
);

// Password input with a show/hide toggle button on the right edge.
// Forwards all other props (placeholder, required, aria-*, className, etc.)
// to the underlying <input>.
const PasswordToggleInput = (props) => {
  const [visible, setVisible] = React.useState(false);
  return (
    <div className="pw-wrap">
      <input {...props} type={visible ? 'text' : 'password'} />
      <button
        type="button"
        className="pw-toggle"
        onClick={() => setVisible(v => !v)}
        aria-label={visible ? 'Hide password' : 'Show password'}
        aria-pressed={visible}
      >
        {visible ? <EyeOffSvg /> : <EyeOpenSvg />}
      </button>
    </div>
  );
};

// "Continue with Google" button — UI stub. Click is a no-op until the
// OAuth backend is wired. Used on both Login and Register.
const GoogleButton = ({ label }) => (
  <button
    type="button"
    className="auth-google"
    onClick={(e) => e.preventDefault()}
    aria-label={label}
  >
    <svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true">
      <path fill="#4285F4" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"/>
      <path fill="#34A853" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"/>
      <path fill="#FBBC05" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09 0-.73.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"/>
      <path fill="#EA4335" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"/>
    </svg>
    <span>{label}</span>
  </button>
);
const AuthDivider = () => <div className="auth-divider"><span>or</span></div>;

const LoginPage = () => {
  const [error, setError] = React.useState('');
  // Stubbed sign-in handler. Until Anil uncle's auth API is wired, every
  // submit shows the invalid-credentials state so the UX is reviewable.
  const handleSubmit = (e) => {
    e.preventDefault();
    setError('Invalid email or password. Please double-check and try again.');
  };
  return (
  <>
    <Header />
    <section className="page-hero page-hero--sm">
      <div className="container">
        <div className="breadcrumbs"><a href="index.html">Home</a> · <span>Log in</span></div>
        <h1 className="h-1" style={{ marginTop: 8 }}>Welcome Back</h1>
      </div>
    </section>

    <section className="reg-section">
      <div className="container auth-narrow">
        <div className="reg-form">
          <AuthTabs active="login" />
          {error && (
            <div className="auth-error" role="alert" aria-live="polite">
              <strong>We couldn't sign you in.</strong>
              <p>{error}</p>
            </div>
          )}
          <GoogleButton label="Continue with Google" />
          <AuthDivider />
          <form onSubmit={handleSubmit}>
            <div className="field">
              <label>Email</label>
              <input
                type="email"
                placeholder="Email address"
                required
                aria-invalid={error ? 'true' : 'false'}
                className={error ? 'is-invalid' : ''}
              />
            </div>
            <div className="field">
              <label>Password</label>
              <PasswordToggleInput
                placeholder="Password"
                required
                aria-invalid={error ? 'true' : 'false'}
                className={error ? 'is-invalid' : ''}
              />
              <div className="auth-row-right">
                <a href="forgot-password.html" className="auth-link">Forgot password?</a>
              </div>
            </div>
            {/* Cloudflare Turnstile widget — auto-rendered by the script tag
                in login.html. Test sitekey 1x00000000000000000000AA always passes. */}
            <div className="cf-turnstile auth-turnstile" data-sitekey="1x00000000000000000000AA" data-size="flexible"></div>
            <button type="submit" className="btn btn--primary btn--lg auth-submit">Sign in</button>
            <p className="auth-footer">
              Don't have an account? <a href="register.html" className="auth-link">Create one</a>
            </p>
            <p className="auth-fineprint">Protected by Cloudflare Turnstile to keep bots out.</p>
          </form>

          <div className="auth-help">
            <p>Need help signing in?</p>
            <a href="contact.html" className="btn btn--ghost btn--sm">Contact Us</a>
          </div>
        </div>
      </div>
    </section>
    <Footer />
  </>
  );
};

// Country data — drives the country dropdown + cascading state dropdown +
// per-country ZIP/postal-code validation. Only the 8 JET-served countries
// + Global option. State/region lists are the canonical subdivisions
// (ISO 3166-2 in most cases). ZIP "max" is the maximum input length.
const COUNTRY_DATA = {
  Australia:     { states: ['ACT', 'NSW', 'NT', 'QLD', 'SA', 'TAS', 'VIC', 'WA'], stateLabel: 'State/Territory',     zip: { max: 4,  label: 'Postcode',     placeholder: 'e.g. 2000' } },
  Canada:        { states: ['AB', 'BC', 'MB', 'NB', 'NL', 'NS', 'NT', 'NU', 'ON', 'PE', 'QC', 'SK', 'YT'], stateLabel: 'Province/Territory', zip: { max: 7,  label: 'Postal Code',  placeholder: 'e.g. K1A 0B1' } },
  Germany:       { states: ['Baden-Württemberg', 'Bavaria', 'Berlin', 'Brandenburg', 'Bremen', 'Hamburg', 'Hesse', 'Lower Saxony', 'Mecklenburg-Vorpommern', 'North Rhine-Westphalia', 'Rhineland-Palatinate', 'Saarland', 'Saxony', 'Saxony-Anhalt', 'Schleswig-Holstein', 'Thuringia'], stateLabel: 'State', zip: { max: 5, label: 'Postal Code', placeholder: 'e.g. 10115' } },
  India:         { states: ['Andhra Pradesh', 'Arunachal Pradesh', 'Assam', 'Bihar', 'Chhattisgarh', 'Goa', 'Gujarat', 'Haryana', 'Himachal Pradesh', 'Jharkhand', 'Karnataka', 'Kerala', 'Madhya Pradesh', 'Maharashtra', 'Manipur', 'Meghalaya', 'Mizoram', 'Nagaland', 'Odisha', 'Punjab', 'Rajasthan', 'Sikkim', 'Tamil Nadu', 'Telangana', 'Tripura', 'Uttar Pradesh', 'Uttarakhand', 'West Bengal', 'Andaman and Nicobar Islands', 'Chandigarh', 'Dadra and Nagar Haveli and Daman and Diu', 'Delhi', 'Jammu and Kashmir', 'Ladakh', 'Lakshadweep', 'Puducherry'], stateLabel: 'State/Union Territory', zip: { max: 6, label: 'PIN Code', placeholder: 'e.g. 110001' } },
  'New Zealand': { states: ['Auckland', 'Bay of Plenty', 'Canterbury', 'Gisborne', "Hawke's Bay", 'Manawatū-Whanganui', 'Marlborough', 'Nelson', 'Northland', 'Otago', 'Southland', 'Taranaki', 'Tasman', 'Waikato', 'Wellington', 'West Coast'], stateLabel: 'Region', zip: { max: 4, label: 'Postcode', placeholder: 'e.g. 1010' } },
  Singapore:     { states: ['Central', 'East', 'North', 'North-East', 'West'], stateLabel: 'Region', zip: { max: 6, label: 'Postal Code', placeholder: 'e.g. 238872' } },
  UK:            { states: ['England', 'Northern Ireland', 'Scotland', 'Wales'], stateLabel: 'Country', zip: { max: 8, label: 'Postcode', placeholder: 'e.g. SW1A 1AA' } },
  USA:           { states: ['AL', 'AK', 'AZ', 'AR', 'CA', 'CO', 'CT', 'DE', 'FL', 'GA', 'HI', 'ID', 'IL', 'IN', 'IA', 'KS', 'KY', 'LA', 'ME', 'MD', 'MA', 'MI', 'MN', 'MS', 'MO', 'MT', 'NE', 'NV', 'NH', 'NJ', 'NM', 'NY', 'NC', 'ND', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC', 'SD', 'TN', 'TX', 'UT', 'VT', 'VA', 'WA', 'WV', 'WI', 'WY', 'DC'], stateLabel: 'State', zip: { max: 10, label: 'ZIP Code', placeholder: 'e.g. 98004' } },
  Global:        { states: ['Global'], stateLabel: 'State/Region', zip: { max: 12, label: 'Postal Code', placeholder: 'Postal code (any format)' } },
};
const COUNTRY_LIST = ['Australia', 'Canada', 'Germany', 'India', 'New Zealand', 'Singapore', 'UK', 'USA', 'Global'];
// Phone Country Code dropdown — alphabetical by country name, matches the
// original site's list. Note: UK appears as both "Scotland" and "United
// Kingdom" because the original site lists them separately even though
// both use +44.
const PHONE_CODES = [
  { country: 'Australia',      code: '+61'  },
  { country: 'Canada',         code: '+1'   },
  { country: 'Germany',        code: '+49'  },
  { country: 'Global',         code: '+00'  },
  { country: 'India',          code: '+91'  },
  { country: 'Netherlands',    code: '+31'  },
  { country: 'New Zealand',    code: '+64'  },
  { country: 'Scotland',       code: '+44'  },
  { country: 'Singapore',      code: '+65'  },
  { country: 'UAE',            code: '+971' },
  { country: 'United Kingdom', code: '+44'  },
  { country: 'USA',            code: '+1'   },
];

const RegisterPage = () => {
  const params = new URLSearchParams(window.location.search);
  const fromModule = params.get('module') || '';
  const [country, setCountry] = React.useState('');
  const [state, setState] = React.useState('');
  const countryInfo = country ? COUNTRY_DATA[country] : null;

  // When the user picks a different country, blank the previously selected
  // state so the form doesn't show e.g. "California" while Country = India.
  const handleCountryChange = (e) => {
    setCountry(e.target.value);
    setState('');
  };
  return (
    <>
      <Header active="Register" />
      <section className="page-hero page-hero--sm">
        <div className="container">
          <div className="breadcrumbs"><a href="index.html">Home</a> · <span>Register</span></div>
          <h1 className="h-1" style={{ marginTop: 8 }}>Register</h1>
        </div>
      </section>

      {/* Walkthrough video — plays above the form */}
      <section className="reg-video-section">
        <div className="container">
          <div className="reg-video">
            <iframe
              src="https://www.youtube.com/embed/qeRdmkueEOA"
              title="Prajna registration walkthrough"
              frameBorder="0"
              allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
              referrerPolicy="strict-origin-when-cross-origin"
              allowFullScreen
            />
          </div>
        </div>
      </section>

      <section className="reg-section">
        <div className="container reg-grid">
          <div className="reg-form">
            <AuthTabs active="register" />
            <GoogleButton label="Sign up with Google" />
            <AuthDivider />
            <p className="reg-intro">
              By filling this form, you will be registering with the website. After successful login,
              you will be able to enroll children. You can also request to become a teacher or center
              coordinator.
            </p>
            {fromModule && (
              <div className="reg-from-module">
                Coming from <strong>{fromModule}</strong>. After signing in you can complete enrollment for this module.
              </div>
            )}

            <form onSubmit={(e) => e.preventDefault()}>
              <fieldset className="reg-fieldset">
                <legend className="reg-legend">Personal Information</legend>
                <div className="reg-grid-2">
                  <div className="field">
                    <label>First Name <span className="req">*</span></label>
                    <input placeholder="First Name" required />
                  </div>
                  <div className="field">
                    <label>Last Name <span className="req">*</span></label>
                    <input placeholder="Last Name" required />
                  </div>
                  <div className="field">
                    <label htmlFor="reg-phonecode">Country Code <span className="req">*</span></label>
                    <select id="reg-phonecode" required defaultValue="">
                      <option value="" disabled>-- Select Country Code --</option>
                      {PHONE_CODES.map((p) => (
                        <option key={p.country} value={p.code}>{p.country} {p.code}</option>
                      ))}
                    </select>
                  </div>
                  <div className="field">
                    <label>Contact Number <span className="req">*</span></label>
                    <input placeholder="ex: 82-5343-4568 (Only Mobile Number)" required />
                  </div>
                  <div className="field" style={{ gridColumn: '1 / -1' }}>
                    <label>Your Email <span className="req">*</span></label>
                    <input type="email" placeholder="Email Address" required />
                    <small className="reg-help">We use this email for further communications, please input valid &amp; active email.</small>
                  </div>
                </div>
              </fieldset>

              <fieldset className="reg-fieldset">
                <legend className="reg-legend">Address Information</legend>
                <div className="reg-grid-2">
                  <div className="field" style={{ gridColumn: '1 / -1' }}>
                    <label>Address <span className="req">*</span></label>
                    <input placeholder="Enter Address" required />
                  </div>
                  <div className="field">
                    <label>City / Area Name <span className="req">*</span></label>
                    <input placeholder="City" required />
                  </div>
                  <div className="field">
                    <label htmlFor="reg-country">Country <span className="req">*</span></label>
                    <select id="reg-country" required value={country} onChange={handleCountryChange}>
                      <option value="" disabled>-- Select Country --</option>
                      {COUNTRY_LIST.map(c => <option key={c} value={c}>{c}</option>)}
                    </select>
                  </div>
                  <div className="field">
                    <label htmlFor="reg-state">{countryInfo ? countryInfo.stateLabel : 'State/Region'} <span className="req">*</span></label>
                    <select
                      id="reg-state"
                      required
                      value={state}
                      onChange={(e) => setState(e.target.value)}
                      disabled={!country || (countryInfo && countryInfo.states.length === 0)}
                    >
                      <option value="" disabled>
                        {!country
                          ? '-- Pick a country first --'
                          : countryInfo && countryInfo.states.length === 0
                            ? '-- Not applicable --'
                            : '-- Select ' + countryInfo.stateLabel + ' --'}
                      </option>
                      {countryInfo && countryInfo.states.map(s => <option key={s} value={s}>{s}</option>)}
                    </select>
                  </div>
                  <div className="field">
                    <label htmlFor="reg-zip">{countryInfo ? countryInfo.zip.label : 'ZIP Code / Postal Code'} <span className="req">*</span></label>
                    <input
                      id="reg-zip"
                      placeholder={countryInfo ? countryInfo.zip.placeholder : 'ZIP Code'}
                      maxLength={countryInfo ? countryInfo.zip.max : 12}
                      required
                    />
                  </div>
                </div>
              </fieldset>

              <fieldset className="reg-fieldset">
                <legend className="reg-legend">Account Security</legend>
                <div className="reg-grid-2">
                  <div className="field">
                    <label>Choose Password <span className="req">*</span></label>
                    <PasswordToggleInput placeholder="Password" required />
                  </div>
                  <div className="field">
                    <label>Re-Enter Password <span className="req">*</span></label>
                    <PasswordToggleInput placeholder="Re-Type Password" required />
                  </div>
                  <div className="field">
                    <label>Your secret question? <span className="req">*</span></label>
                    <input placeholder="Secret Question" required />
                  </div>
                  <div className="field">
                    <label>Your answer to secret question? <span className="req">*</span></label>
                    <input placeholder="Secret Answer" required />
                  </div>
                </div>
              </fieldset>

              <fieldset className="reg-fieldset">
                <legend className="reg-legend">Just so we know</legend>
                <div className="field">
                  <label htmlFor="reg-heard">How did you hear about Prajna? <span className="req">*</span></label>
                  <select id="reg-heard" required defaultValue="">
                    <option value="" disabled>-- Select an option --</option>
                    <option value="search">Search engine</option>
                    <option value="friend">Friend or family</option>
                    <option value="coordinator">Center coordinator</option>
                    <option value="social">Social media</option>
                    <option value="event">Local event or temple</option>
                    <option value="other">Other</option>
                  </select>
                </div>
              </fieldset>

              {/* Cloudflare Turnstile widget — auto-rendered by the script tag
                  in register.html. Test sitekey 1x00000000000000000000AA always passes. */}
              <div className="cf-turnstile auth-turnstile" data-sitekey="1x00000000000000000000AA" data-size="flexible" style={{ marginTop: 18 }}></div>
              <button type="submit" className="btn btn--primary btn--lg" style={{ marginTop: 24 }}>Register</button>
              <p className="auth-fineprint">Protected by Cloudflare Turnstile to keep bots out.</p>
            </form>
          </div>

          <aside className="reg-aside">
            <div className="reg-side-card">
              <h3 className="h-4">After Registering</h3>
              <ul className="reg-side-list">
                <li>Sign in with your email and password</li>
                <li>Enroll one or more children</li>
                <li>Pick a center and module</li>
              </ul>
            </div>
            <div className="reg-side-card reg-side-card--soft">
              <h3 className="h-4">Want to Help?</h3>
              <p className="body-sm" style={{ marginTop: 6 }}>You can also request to become a teacher or center coordinator after signing in.</p>
            </div>
            <div className="reg-side-card auth-help">
              <strong>Need Help?</strong>
              <p className="body-sm" style={{ margin: '6px 0 12px' }}>
                Having trouble registering? Reach out and we'll walk you through it.
              </p>
              <a href="contact.html" className="btn btn--ghost btn--sm">Contact Us</a>
            </div>
          </aside>
        </div>
      </section>
      <Footer />
    </>
  );
};

// Forgot Password — email entry, then a success state once the user submits.
// API hook is stubbed; submit always advances to the "Check your email" state
// until Anil uncle's auth backend is wired.
const ForgotPasswordPage = () => {
  const [sent, setSent] = React.useState(false);
  const [email, setEmail] = React.useState('');
  const handleSubmit = (e) => {
    e.preventDefault();
    setSent(true);
  };

  if (sent) {
    return (
      <>
        <Header />
        <section className="page-hero page-hero--sm">
          <div className="container">
            <div className="breadcrumbs"><a href="index.html">Home</a> · <a href="login.html">Log in</a> · <span>Forgot password</span></div>
            <h1 className="h-1" style={{ marginTop: 8 }}>Check Your Email</h1>
          </div>
        </section>
        <section className="reg-section">
          <div className="container auth-narrow">
            <div className="reg-form">
              <div className="rc-success">
                <div className="rc-success__check" aria-hidden="true">✓</div>
                <p className="rc-success__p">
                  If an account exists for <b>{email}</b>, we&rsquo;ve sent a password reset link.
                  Click the link in the email to choose a new password. The link will expire after 24 hours.
                </p>
                <p className="rc-success__note">
                  Didn&rsquo;t receive an email? Check your spam folder, or
                  <> </><a href="contact.html" className="auth-link">contact us</a> for help.
                </p>
                <p style={{ marginTop: 24 }}>
                  <a href="login.html" className="btn btn--ghost">Back to log in</a>
                </p>
              </div>
            </div>
          </div>
        </section>
        <Footer />
      </>
    );
  }

  return (
    <>
      <Header />
      <section className="page-hero page-hero--sm">
        <div className="container">
          <div className="breadcrumbs"><a href="index.html">Home</a> · <a href="login.html">Log in</a> · <span>Forgot password</span></div>
          <h1 className="h-1" style={{ marginTop: 8 }}>Reset Your Password</h1>
        </div>
      </section>

      <section className="reg-section">
        <div className="container auth-narrow">
          <div className="reg-form">
            <p className="reg-intro">
              Enter the email address you used to register. We&rsquo;ll send you a link to reset your password.
            </p>
            <form onSubmit={handleSubmit}>
              <div className="field">
                <label htmlFor="fp-email">Email</label>
                <input
                  id="fp-email"
                  type="email"
                  placeholder="Email address"
                  value={email}
                  onChange={(e) => setEmail(e.target.value)}
                  required
                />
              </div>
              <button type="submit" className="btn btn--primary btn--lg auth-submit">Send Reset Link</button>
              <p className="auth-footer">
                Remembered it? <a href="login.html" className="auth-link">Back to log in</a>
              </p>
            </form>

            <div className="auth-help">
              <strong>Still stuck?</strong>
              <p style={{ margin: '4px 0 12px', fontSize: 13.5, color: 'var(--ink-2)' }}>
                If you no longer have access to the email you registered with, we can verify your identity another way.
              </p>
              <a href="contact.html" className="btn btn--ghost btn--sm">Contact Us</a>
            </div>
          </div>
        </div>
      </section>
      <Footer />
    </>
  );
};

// Center profile — opened when a user clicks a location in the centers list.
// Reads ?center=<slug> from the URL and renders the matched center.
// ─── PRIVACY / TERMS ─────────────────────────────────────
// Interim honest stubs. Full legal copy comes from JET; these remove the dead
// footer links and clearly mark themselves as interim until the real text lands.
const LegalPage = ({ title, children }) => (
  <>
    <Header />
    <section className="page-hero page-hero--sm">
      <div className="container">
        <div className="breadcrumbs"><a href="index.html">Home</a> · <span>{title}</span></div>
        <h1 className="h-1" style={{ marginTop: 8 }}>{title}</h1>
      </div>
    </section>
    <section className="section">
      <div className="container-narrow legal">{children}</div>
    </section>
    <Footer />
  </>
);

const PrivacyPage = () => (
  <LegalPage title="Privacy Policy">
    <p className="legal__note">This is an interim summary. Prajna is finalizing its full privacy policy; the complete version will be published here before launch.</p>
    <p>Prajna is a program of Jeeyar Educational Trust (JET USA). We collect only the information you choose to provide when you register a child, request a center, or contact us, such as your name, email address, location, and the details entered on those forms.</p>
    <h2 className="legal__h">How We Use Your Information</h2>
    <p>We use your information to process enrollment, connect you with your local center, and respond to your requests. We do not sell your personal information.</p>
    <h2 className="legal__h">Questions</h2>
    <p>For any questions about your information or to request a change, please <a href="contact.html">contact us</a>.</p>
  </LegalPage>
);

const TermsPage = () => (
  <LegalPage title="Terms of Use">
    <p className="legal__note">This is an interim summary. Prajna is finalizing its full terms of use; the complete version will be published here before launch.</p>
    <p>By using this website you agree to use it for lawful purposes and in a way that respects the rights of others. The content here is provided for information about the Prajna program.</p>
    <h2 className="legal__h">Program Participation</h2>
    <p>Enrollment, fees, and schedules are set by each local center. Details shown on this site may vary by center and are subject to change.</p>
    <h2 className="legal__h">Contact</h2>
    <p>Questions about these terms? Please <a href="contact.html">contact us</a>.</p>
  </LegalPage>
);

const CenterProfilePage = () => {
  const params = new URLSearchParams(window.location.search);
  const slug = params.get('center') || '';
  const center = CENTERS.find(c => c.name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '') === slug)
              || CENTERS[0];
  const isOnline = /online/i.test(center.addr || '');

  // Mini-map for the profile (single pin)
  const mapRef = React.useRef(null);
  const containerRef = React.useRef(null);
  React.useEffect(() => {
    if (!containerRef.current || typeof L === 'undefined') return;
    // Many centers have no lat/lng yet. Skip the map for them — passing null
    // to Leaflet's setView throws and (with no error boundary) blanks the page.
    if (center.lat == null || center.lng == null) return undefined;
    const map = L.map(containerRef.current, { scrollWheelZoom: false, zoomControl: false }).setView(
      [center.lat, center.lng], 13
    );
    L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', {
      attribution: '© OpenStreetMap, © CARTO',
      maxZoom: 19,
      subdomains: 'abcd',
    }).addTo(map);
    const profileMarker = L.marker([center.lat, center.lng], {
      icon: L.divIcon({
        className: 'prajna-pin prajna-pin--selected',
        iconSize: [26, 26],
        iconAnchor: [13, 13],
        html: `<span class="prajna-pin__shape"></span>`,
      }),
      title: center.name,
      alt: center.name,
    }).addTo(map);
    const pmEl = profileMarker.getElement();
    if (pmEl) { pmEl.setAttribute('role', 'img'); pmEl.setAttribute('aria-label', `${center.name} location`); }
    mapRef.current = map;
    return () => { map.remove(); mapRef.current = null; };
  }, [center.lat, center.lng]);

  return (
    <>
      <Header active="Centers" />
      <section className="page-hero page-hero--sm">
        <div className="container">
          <div className="breadcrumbs">
            <a href="index.html">Home</a> · <a href="centers.html">Centers</a> · <span>{center.name}</span>
          </div>
          <h1 className="h-1" style={{ marginTop: 8 }}>{center.name}</h1>
          <div className="row" style={{ marginTop: 10, gap: 10, alignItems: 'center', flexWrap: 'wrap' }}>
            {center.dist && <span className="chip chip--orange">{center.dist}</span>}
            <span className="body-sm">{center.addr}</span>
          </div>
        </div>
      </section>

      <section className="cp-section">
        <div className="container cp-grid">
          <div className="cp-main">
            <div className="cp-card">
              <h2 className="cp-card__h">Schedule</h2>
              <div className="cp-schedule">
                <div className="cp-schedule__row">
                  <span className="cp-schedule__day">{center.sched ? center.sched.split(' ')[0] : 'Class times'}</span>
                  <span className="cp-schedule__time">{center.sched ? center.sched.split(' ').slice(1).join(' ') : 'Contact the center for the current schedule'}</span>
                </div>
                <div className="cp-schedule__row cp-schedule__row--muted">
                  <span className="cp-schedule__day">Modules offered</span>
                  <span className="cp-schedule__time">Foundation · Advanced</span>
                </div>
                <div className="cp-schedule__row cp-schedule__row--muted">
                  <span className="cp-schedule__day">Languages</span>
                  <span className="cp-schedule__time">English · Telugu</span>
                </div>
              </div>
            </div>

            <div className="cp-card">
              <h2 className="cp-card__h">Coordinator</h2>
              <div className="cp-coord">
                <div className="cp-coord__avatar" aria-hidden="true">
                  <svg viewBox="0 0 24 24" width="28" height="28" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
                    <circle cx="12" cy="9" r="3.6"/>
                    <path d="M5 19c1.4-3.2 4-4.6 7-4.6s5.6 1.4 7 4.6"/>
                  </svg>
                </div>
                <div>
                  <div className="cp-coord__name">Center Coordinator</div>
                  <div className="cp-coord__sub">Reach out with questions before your first visit.</div>
                </div>
              </div>
              <div className="cp-coord__actions">
                <a href={`mailto:${center.email}`} className="btn btn--ghost btn--sm">Email coordinator</a>
              </div>
            </div>

            <div className="cp-card">
              <h2 className="cp-card__h">What to Expect on Your First Visit</h2>
              <ul className="cp-list">
                <li>Arrive 10 minutes before class starts</li>
                <li>Sit in, watch, or join in. No prior knowledge needed</li>
                <li>Children ages 5 and up</li>
                <li>Stay for snacks and conversation afterward</li>
              </ul>
            </div>
          </div>

          <aside className="cp-aside">
            <div className="cp-card cp-card--cta">
              <h3 className="cp-card__h" style={{ marginTop: 0 }}>Join a Class</h3>
              <p className="cp-card__p">Register your child to join a class at this center.</p>
              <a href={'register.html?center=' + slug} className="btn btn--primary" style={{ width: '100%' }}>
                Register a child
              </a>
              <a href={`https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(center.addr)}`} target="_blank" rel="noopener noreferrer" className="btn btn--ghost" style={{ width: '100%', marginTop: 8 }}>
                Get directions
              </a>
            </div>

            <div className="cp-mapwrap">
              {center.lat != null && center.lng != null ? (
                <div ref={containerRef} className="cp-map" />
              ) : (
                <div className="cp-map cp-map--none">
                  {isOnline ? (
                    <>
                      <svg viewBox="0 0 24 24" width="26" height="26" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                        <rect x="2" y="4" width="20" height="14" rx="2" /><path d="M8 21h8M12 18v3" />
                      </svg>
                      <span>This is an online class. Register to receive the joining details.</span>
                    </>
                  ) : (
                    <>
                      <svg viewBox="0 0 24 24" width="26" height="26" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                        <path d="M21 10c0 6-9 12-9 12s-9-6-9-12a9 9 0 0 1 18 0z" /><circle cx="12" cy="10" r="3" />
                      </svg>
                      <span>Map pin coming soon. Use the address below or “Get directions.”</span>
                    </>
                  )}
                </div>
              )}
              <div className="cp-mapwrap__addr">{center.addr}</div>
            </div>
          </aside>
        </div>
      </section>

      <Footer />
    </>
  );
};

// ─── REQUEST A NEW CENTER ────────────────────────────────
// Bot defenses (in order of strength):
//   1. Cloudflare Turnstile (silent CAPTCHA, runs invisibly in the bg)
//   2. Honeypot field "website" — hidden via CSS, real users skip it,
//      bots auto-fill anything that looks like a field. If filled, drop.
//   3. Time-based check — submits in <3s after page load are bot-like.
//   4. Email confirmation round-trip (link clicked = real human / valid inbox).
//   5. Server-side IP rate limiting (placeholder note for the backend dev).
const RequestCenterPage = () => {
  // Read ?location= from URL so the empty-state link can pre-fill the city.
  const initialLocation = (() => {
    if (typeof window === 'undefined') return '';
    const p = new URLSearchParams(window.location.search);
    return (p.get('location') || '').slice(0, 80);
  })();

  const [form, setForm] = React.useState({
    firstName: '',
    lastName: '',
    contact: '',
    email: '',
    city: initialLocation,
    state: '',
    country: '',
    students: '',
    teachers: '',
    startDate: '',
    heard: '',
    website: '', // honeypot — must stay empty
  });
  const [submitted, setSubmitted] = React.useState(false);
  const [error, setError] = React.useState('');
  const loadedAt = React.useRef(Date.now());

  const update = (k) => (e) => setForm({ ...form, [k]: e.target.value });

  const onSubmit = (e) => {
    e.preventDefault();
    setError('');

    // Honeypot tripped — silently pretend success so bots don't iterate.
    if (form.website) { setSubmitted(true); return; }

    // Too fast = bot. Real humans take more than 3 seconds to fill a form.
    if (Date.now() - loadedAt.current < 3000) {
      setError('Please take a moment to review your request before submitting.');
      return;
    }

    // Required-field check (browsers also enforce via "required" attr).
    const missing = ['firstName', 'lastName', 'contact', 'email', 'city', 'country', 'students', 'teachers', 'startDate']
      .filter(k => !String(form[k]).trim());
    if (missing.length) {
      setError('Please fill out every required field marked with an asterisk.');
      return;
    }

    // In production: POST { ...form, turnstileToken } to the backend.
    // Backend verifies token with Cloudflare, applies IP rate limit,
    // sends email-confirmation link, and only writes to the DB once
    // that link is clicked.
    setSubmitted(true);
  };

  if (submitted) {
    return (
      <>
        <Header active="Centers" />
        <section className="rc-section">
          <div className="container rc-success-wrap">
            <div className="rc-success">
              <div className="rc-success__check" aria-hidden="true">✓</div>
              <h1 className="h-1" style={{ marginTop: 0 }}>Request Received</h1>
              <p className="rc-success__p">
                Thank you for your interest in starting a Prajna center in your community.
                We&rsquo;ve sent a confirmation email to <b>{form.email}</b>.
                Please click the link inside to verify your address and finish your request.
              </p>
              <p className="rc-success__note">
                Once verified, our team typically responds within 7&ndash;10 days.
                In the meantime, you can <a href="centers.html">explore existing centers</a> or
                <> </><a href="register.html">enroll a child in an online class</a>.
              </p>
            </div>
          </div>
        </section>
        <Footer />
      </>
    );
  }

  return (
    <>
      <Header active="Centers" />
      <section style={{ padding: '40px 0 16px', background: 'linear-gradient(180deg, var(--paper-2), var(--paper))', borderBottom: '1px solid var(--line)' }}>
        <div className="container">
          <div className="breadcrumbs"><a href="index.html">Home</a> · <a href="centers.html">Centers</a> · <span>Request a center</span></div>
          <h1 className="h-1" style={{ marginTop: 8 }}>Request a New Prajna Center</h1>
          <p className="rc-lede">
            Thank you for your interest. To bring Prajna to your community, please fill out the form below.
            Our team will review your request and reach out within 7&ndash;10 days. We will need volunteer teachers
            and a small group of committed families to help us launch a new center.
          </p>
        </div>
      </section>

      <section className="rc-section">
        <div className="container rc-grid">
          <form className="rc-form" onSubmit={onSubmit} noValidate>
            {/* Honeypot field — hidden from real users via CSS.
                Bots that auto-fill every input will trip this. */}
            <div className="rc-honeypot" aria-hidden="true">
              <label htmlFor="rc-website">Website (leave blank)</label>
              <input
                id="rc-website"
                name="website"
                type="text"
                tabIndex="-1"
                autoComplete="off"
                value={form.website}
                onChange={update('website')}
              />
            </div>

            <fieldset className="rc-fieldset">
              <legend className="rc-legend">Your contact information</legend>
              <div className="rc-grid-2">
                <div className="field">
                  <label htmlFor="rc-first">First name <span className="req">*</span></label>
                  <input id="rc-first" type="text" autoComplete="given-name" required
                    value={form.firstName} onChange={update('firstName')} />
                </div>
                <div className="field">
                  <label htmlFor="rc-last">Last name <span className="req">*</span></label>
                  <input id="rc-last" type="text" autoComplete="family-name" required
                    value={form.lastName} onChange={update('lastName')} />
                </div>
                <div className="field">
                  <label htmlFor="rc-contact">Contact number (WhatsApp preferred) <span className="req">*</span></label>
                  <input id="rc-contact" type="tel" autoComplete="tel" required
                    placeholder="+1 555 123 4567"
                    value={form.contact} onChange={update('contact')} />
                </div>
                <div className="field">
                  <label htmlFor="rc-email">Email address <span className="req">*</span></label>
                  <input id="rc-email" type="email" autoComplete="email" required
                    placeholder="you@example.com"
                    value={form.email} onChange={update('email')} />
                  <small className="rc-help">We will send a confirmation link to this address.</small>
                </div>
              </div>
            </fieldset>

            <fieldset className="rc-fieldset">
              <legend className="rc-legend">Where would the center be located?</legend>
              <div className="rc-grid-2">
                <div className="field">
                  <label htmlFor="rc-city">City <span className="req">*</span></label>
                  <input id="rc-city" type="text" autoComplete="address-level2" required
                    value={form.city} onChange={update('city')} />
                </div>
                <div className="field">
                  <label htmlFor="rc-state">State or region</label>
                  <input id="rc-state" type="text" autoComplete="address-level1"
                    value={form.state} onChange={update('state')} />
                </div>
                <div className="field" style={{ gridColumn: '1 / -1' }}>
                  <label htmlFor="rc-country">Country <span className="req">*</span></label>
                  <input id="rc-country" type="text" autoComplete="country-name" required
                    value={form.country} onChange={update('country')} />
                </div>
              </div>
            </fieldset>

            <fieldset className="rc-fieldset">
              <legend className="rc-legend">About your community</legend>
              <div className="field">
                <label htmlFor="rc-students">How many students are you expecting? <span className="req">*</span></label>
                <input id="rc-students" type="number" min="0" max="100" required
                  placeholder="0 to 100"
                  value={form.students} onChange={update('students')} />
              </div>
              <div className="field" style={{ marginTop: 14 }}>
                <label>Are voluntary teachers available in your area? <span className="req">*</span></label>
                <div className="rc-radio-row">
                  <label className="rc-radio">
                    <input type="radio" name="teachers" value="yes"
                      checked={form.teachers === 'yes'} onChange={update('teachers')} />
                    <span>Yes</span>
                  </label>
                  <label className="rc-radio">
                    <input type="radio" name="teachers" value="no"
                      checked={form.teachers === 'no'} onChange={update('teachers')} />
                    <span>No</span>
                  </label>
                  <label className="rc-radio">
                    <input type="radio" name="teachers" value="maybe"
                      checked={form.teachers === 'maybe'} onChange={update('teachers')} />
                    <span>Not yet, but I can help find them</span>
                  </label>
                </div>
              </div>
              <div className="field" style={{ marginTop: 14 }}>
                <label htmlFor="rc-start">Expected start date <span className="req">*</span></label>
                <input id="rc-start" type="date" required
                  value={form.startDate} onChange={update('startDate')} />
                <small className="rc-help">Approximate is fine. We will plan training and onboarding around this.</small>
              </div>
              <div className="field" style={{ marginTop: 14 }}>
                <label htmlFor="rc-heard">How did you hear about Prajna?</label>
                <select id="rc-heard" value={form.heard} onChange={update('heard')}>
                  <option value="">Choose one</option>
                  <option value="friend">A friend or family member</option>
                  <option value="existing">An existing Prajna center</option>
                  <option value="jeeyar">Sri Chinna Jeeyar Swami / JET USA</option>
                  <option value="social">Instagram, Facebook, or YouTube</option>
                  <option value="search">Search engine</option>
                  <option value="event">A community event</option>
                  <option value="other">Other</option>
                </select>
              </div>
            </fieldset>

            {/* Cloudflare Turnstile widget — invisible captcha. Auto-rendered
                by the script in request-center.html via the data-sitekey div.
                Test sitekey 1x00000000000000000000AA always passes. */}
            <div className="cf-turnstile" data-sitekey="1x00000000000000000000AA" data-size="flexible" style={{ marginTop: 22 }}></div>

            {error && <div className="rc-error">{error}</div>}

            <div className="rc-actions">
              <button type="submit" className="btn btn--primary btn--lg">Submit request</button>
              <a href="centers.html" className="btn btn--ghost">Cancel</a>
            </div>

            <p className="rc-fineprint">
              We use Cloudflare Turnstile to protect this form from spam.
              Your information is shared only with the Prajna coordinator team and is never sold.
            </p>
          </form>

          <aside className="rc-aside">
            <div className="rc-side-card">
              <h3 className="h-4" style={{ margin: '0 0 10px' }}>What Happens Next</h3>
              <ol className="rc-steps">
                <li><b>Confirm your email.</b> We send a link to the address you provide. Clicking it verifies your request.</li>
                <li><b>Coordinator outreach.</b> A regional coordinator reaches out within 7 to 10 days for a first conversation.</li>
                <li><b>Find your team.</b> Together, we identify volunteer teachers and a small group of founding families.</li>
                <li><b>Training and launch.</b> Teachers complete Prajna training. Your center opens and begins welcoming students.</li>
              </ol>
            </div>

            <div className="rc-side-card rc-side-card--soft">
              <h3 className="h-4" style={{ margin: '0 0 8px' }}>Already Have a Center Nearby?</h3>
              <p style={{ margin: 0, fontSize: 13.5, color: 'var(--ink-2)', lineHeight: 1.5 }}>
                Search the <a href="centers.html">centers map</a> first.
                If a center exists within 30 miles, we usually point new families there before opening another location.
              </p>
            </div>
          </aside>
        </div>
      </section>

      <Footer />
    </>
  );
};

// ─── HELP ────────────────────────────────────────────────
// Walkthrough videos for Parent and Coordinator modules. The original
// site had only embedded YouTube links; we wrap them in a responsive
// 16:9 frame and surround with light context.
const HelpPage = () => (
  <>
    <Header active="Help" />
    <section style={{ padding: '40px 0 16px', background: 'linear-gradient(180deg, var(--paper-2), var(--paper))', borderBottom: '1px solid var(--line)' }}>
      <div className="container">
        <div className="breadcrumbs"><a href="index.html">Home</a> · <span>Help</span></div>
        <h1 className="h-1" style={{ marginTop: 8 }}>Help Center</h1>
        <p className="rc-lede">
          Walk through the parts of the Prajna program with these short videos.
          Need something a video doesn&rsquo;t cover? <a href="contact.html" style={{ color: 'var(--orange-700)', fontWeight: 700 }}>Contact us</a> and we will reply within 1 to 2 business days.
        </p>
      </div>
    </section>

    <section className="rc-section">
      <div className="container">
        <div className="help-grid">
          <article className="help-card">
            <h2 className="help-card__h">Walkthrough on the Parent Module</h2>
            <p className="help-card__p">
              How parents register a child, track classes, and reach their teacher through the Prajna site.
            </p>
            <div className="help-video">
              <iframe
                src="https://www.youtube.com/embed/qeRdmkueEOA"
                title="Walkthrough on the parent module"
                allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
                allowFullScreen
              ></iframe>
            </div>
          </article>

          <article className="help-card">
            <h2 className="help-card__h">Walkthrough on the Coordinator Module</h2>
            <p className="help-card__p">
              For center coordinators: how to manage rosters, schedule classes, and invite teachers.
            </p>
            <div className="help-video">
              <iframe
                src="https://www.youtube.com/embed/BudesDJ46iU"
                title="Walkthrough on the coordinator module"
                allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
                allowFullScreen
              ></iframe>
            </div>
          </article>
        </div>

        <div className="help-more">
          <h3 className="help-more__h">Looking for Something Else?</h3>
          <ul className="help-more__list">
            <li><a href="faq.html">Browse the FAQ</a> for common questions about classes, fees, and what to expect</li>
            <li><a href="centers.html">Find a center near you</a> and reach out to a coordinator directly</li>
            <li><a href="contact.html">Contact us</a> for technical issues or anything not covered above</li>
          </ul>
        </div>
      </div>
    </section>

    <Footer />
  </>
);

// ─── CONTACT ─────────────────────────────────────────────
// Same anti-bot stack as the request-center page: Cloudflare Turnstile,
// hidden honeypot, 3-second time check, and an email-confirmation
// round-trip on the backend before the message is forwarded.
const ContactPage = () => {
  const [form, setForm] = React.useState({
    about: '',
    name: '',
    email: '',
    remarks: '',
    file: null,
    website: '', // honeypot
  });
  const [submitted, setSubmitted] = React.useState(false);
  const [error, setError] = React.useState('');
  const loadedAt = React.useRef(Date.now());

  const update = (k) => (e) =>
    setForm({ ...form, [k]: k === 'file' ? (e.target.files?.[0] || null) : e.target.value });

  const onSubmit = (e) => {
    e.preventDefault();
    setError('');
    if (form.website) { setSubmitted(true); return; }
    if (Date.now() - loadedAt.current < 3000) {
      setError('Please take a moment before submitting.');
      return;
    }
    const missing = ['about', 'name', 'email', 'remarks'].filter(k => !String(form[k]).trim());
    if (missing.length) {
      setError('Please fill out every required field marked with an asterisk.');
      return;
    }
    // Production: POST to backend with Turnstile token; backend sends an
    // email-confirmation link before the message is forwarded.
    setSubmitted(true);
  };

  if (submitted) {
    return (
      <>
        <Header active="Contact" />
        <section className="rc-section">
          <div className="container rc-success-wrap">
            <div className="rc-success">
              <div className="rc-success__check" aria-hidden="true">✓</div>
              <h1 className="h-1" style={{ marginTop: 0 }}>Message Received</h1>
              <p className="rc-success__p">
                Thank you for reaching out. We&rsquo;ve sent a confirmation email to <b>{form.email}</b>.
                Click the link inside to verify your address and our team will reply within 1 to 2 business days.
              </p>
              <p className="rc-success__note">
                In the meantime, you can <a href="faq.html">browse the FAQ</a> or
                <> </><a href="help.html">watch the walkthrough videos</a>.
              </p>
            </div>
          </div>
        </section>
        <Footer />
      </>
    );
  }

  return (
    <>
      <Header active="Contact" />
      <section style={{ padding: '40px 0 16px', background: 'linear-gradient(180deg, var(--paper-2), var(--paper))', borderBottom: '1px solid var(--line)' }}>
        <div className="container">
          <div className="breadcrumbs"><a href="index.html">Home</a> · <span>Contact us</span></div>
          <h1 className="h-1" style={{ marginTop: 8 }}>Contact Us</h1>
          <p className="rc-lede">
            If you have a technical issue with the website, or if you would like to know more about the Prajna program,
            please share your details below and we will reach out to you at the earliest.
          </p>
        </div>
      </section>

      <section className="rc-section">
        <div className="container rc-grid">
          <form className="rc-form" onSubmit={onSubmit} noValidate>
            <div className="rc-honeypot" aria-hidden="true">
              <label htmlFor="ct-website">Website (leave blank)</label>
              <input id="ct-website" name="website" type="text" tabIndex="-1" autoComplete="off"
                value={form.website} onChange={update('website')} />
            </div>

            <fieldset className="rc-fieldset">
              <legend className="rc-legend">Tell us what this is about</legend>
              <div className="field">
                <label htmlFor="ct-about">About <span className="req">*</span></label>
                <select id="ct-about" required value={form.about} onChange={update('about')}>
                  <option value="">Choose one</option>
                  <option value="register">Register account</option>
                  <option value="forgot">Forgot password</option>
                  <option value="reset">Reset password</option>
                  <option value="other">Other</option>
                </select>
              </div>
              <div className="rc-grid-2" style={{ marginTop: 14 }}>
                <div className="field">
                  <label htmlFor="ct-name">Full name <span className="req">*</span></label>
                  <input id="ct-name" type="text" autoComplete="name" required
                    value={form.name} onChange={update('name')} />
                </div>
                <div className="field">
                  <label htmlFor="ct-email">Email address <span className="req">*</span></label>
                  <input id="ct-email" type="email" autoComplete="email" required
                    placeholder="you@example.com"
                    value={form.email} onChange={update('email')} />
                  <small className="rc-help">We will send a confirmation link to this address.</small>
                </div>
              </div>
              <div className="field" style={{ marginTop: 14 }}>
                <label htmlFor="ct-remarks">Remarks <span className="req">*</span></label>
                <textarea id="ct-remarks" rows="5" required
                  placeholder="Describe the issue or question in as much detail as you can"
                  value={form.remarks} onChange={update('remarks')}></textarea>
              </div>
              <div className="field" style={{ marginTop: 14 }}>
                <label htmlFor="ct-file">Attach a screenshot or file (optional)</label>
                <input id="ct-file" type="file" onChange={update('file')}
                  accept="image/*,.pdf,.txt,.log" />
                <small className="rc-help">Up to 5 MB. Images, PDF, or plain text.</small>
              </div>
            </fieldset>

            <div className="cf-turnstile" data-sitekey="1x00000000000000000000AA" data-size="flexible" style={{ marginTop: 22 }}></div>

            {error && <div className="rc-error">{error}</div>}

            <div className="rc-actions">
              <button type="submit" className="btn btn--primary btn--lg">Continue</button>
              <a href="index.html" className="btn btn--ghost">Cancel</a>
            </div>

            <p className="rc-fineprint">
              We use Cloudflare Turnstile to protect this form from spam.
              Your information is shared only with the Prajna support team and is never sold.
            </p>
          </form>

          <aside className="rc-aside">
            <div className="rc-side-card">
              <h3 className="h-4" style={{ margin: '0 0 10px' }}>Faster Answers</h3>
              <p style={{ margin: '0 0 12px', fontSize: 13.5, color: 'var(--ink-2)', lineHeight: 1.55 }}>
                Many common questions are already answered. You may not need to wait for us at all.
              </p>
              <ul className="rc-steps" style={{ paddingLeft: 18, listStyle: 'disc' }}>
                <li><a href="faq.html">Read the FAQ</a></li>
                <li><a href="help.html">Watch the walkthrough videos</a></li>
                <li><a href="centers.html">Find your local center coordinator</a></li>
              </ul>
            </div>

            <div className="rc-side-card rc-side-card--soft">
              <h3 className="h-4" style={{ margin: '0 0 8px' }}>Response Time</h3>
              <p style={{ margin: 0, fontSize: 13.5, color: 'var(--ink-2)', lineHeight: 1.5 }}>
                We typically reply within 1 to 2 business days. Technical issues are prioritized.
              </p>
            </div>
          </aside>
        </div>
      </section>

      <Footer />
    </>
  );
};

Object.assign(window, { AboutPage, ModulesPage, CentersPage, ShowcasePage, FAQPage, LoginPage, RegisterPage, CenterProfilePage, RequestCenterPage, HelpPage, ContactPage });
