/* JC Brasil Tour — tour page. Sections follow the required order:
   header, hero and status, proof strip, quick fit, reel, value, itinerary, price,
   Julio and supervision, testimonials, gallery, FAQ, inquiry, footer. */
const { SiteFooter, WaveField, WaveSplit, AngularField, Button, Tag, SectionHeading, MediaFigure,
  MetricBand, TourStatus, ItineraryList, TourPricing, FAQAccordion, VideoStage, RouteLine } = window.JCBrasilTourLinhaCarioca_903c90;

const T_PHOTOS = '/jc-soccer-camp/uploads/Media/JC-Brasil-Tour/';
const T_VIDEO = '/jc-soccer-camp/uploads/Media/JC-Brasil-Tour/';
const T_TESTIMONIALS = '/jc-soccer-camp/uploads/Media/Testimonials/';
const HOTEL = '/jc-soccer-camp/assets/hotel/';
const HOTEL_VIDEO = '/jc-soccer-camp/uploads/Videos/Rio-Othon-Palace/';

const STAY_FACTS = [
  ['Location', 'Copacabana, facing the beach, with the rest of Rio a short organized drive away.'],
  ['Planned inclusions', 'Room, meals, and organized transportation.'],
  ['Rooftop', 'Pool, terrace, and a restaurant above the beach.'],
  ['Family', 'Parents and guardians who travel with the group stay in the same hotel.']
];

const TOUR_NAV = [
  { label: 'Upcoming', href: '/jc-soccer-camp/#upcoming' },
  { label: 'Programs', href: '/jc-soccer-camp/#programs' },
  { label: 'About', href: '/jc-soccer-camp/#julio' },
  { label: 'Testimonials', href: '/jc-soccer-camp/#stories' },
  { label: 'FAQs', href: '/jc-soccer-camp/#faq' },
  { label: 'JC Brasil Tour', href: '/jc-soccer-camp/brasil-tour/' }
];

const TOUR_SECTIONS = [
  { label: 'Who it is for', href: '#experience' },
  { label: 'Itinerary', href: '#itinerary' },
  { label: 'Accommodation', href: '#stay' },
  { label: 'Planning details', href: '#pricing' },
  { label: 'Testimonials', href: '#stories' },
  { label: 'Gallery', href: '#gallery' },
  { label: 'FAQs', href: '#faq' }
];

const FIT = [
  { who: 'For Parents And Guardians', title: 'Know what your player is stepping into.',
    body: 'See who leads the group, where everyone stays, how the days are organized, what is planned to be included, and how players are supervised. Parents are welcome to join the trip.',
    image: '/jc-soccer-camp/uploads/CleanShot%202026-08-17%20at%2016.09.56.png', alt: 'Julio with two of the adults who travel with the group, on the pitch at a Rio stadium' },
  { who: 'For Coaches And Team Organizers', title: 'Bring the group into a new football culture.',
    body: 'Talk directly with Julio about your roster, age group, playing level, travel window, and how a future departure could work for your team.',
    image: '/jc-soccer-camp/uploads/CleanShot%202026-08-17%20at%2016.10.22.png', alt: 'The full squad and staff lined up for a team photo in a Brazilian stadium' },
  { who: 'For Players', title: 'Come ready to train, compete, and adapt.',
    body: 'Players experience new coaching ideas, different opponents, futsal, club settings, stadiums, and the daily rhythm of football in Rio.',
    image: '/jc-soccer-camp/uploads/CleanShot%202026-08-17%20at%2016.21.41.png', focus: 'center 72%', alt: 'A young player driving at the ball in a camp session' }
];

const GAINS = [
  { tab: 'Train Outside The Familiar', body: 'Adapt to different coaching, tempo, space, and expectations while receiving direct feedback.',
    image: '/jc-soccer-camp/uploads/CleanShot 2026-08-18 at 10.18.00.png', alt: 'Tour squad together on the field outside a Rio stadium' },
  { tab: 'Put The Game To The Test', body: 'Move from training into competitive matches where players have to read, decide, communicate, and adjust.',
    image: '/jc-soccer-camp/uploads/CleanShot%202026-08-17%20at%2016.10.22.png', alt: 'The squad lined up before a match in a Brazilian stadium' },
  { tab: 'Step Inside Brazilian Football', body: "Every departure includes youth training, club access, and a stadium experience. Julio's relationships include Fluminense, Flamengo, Botafogo, and Vasco da Gama.",
    image: T_PHOTOS + 'tour-past-fluminense-training-center.jpg', alt: 'The group at a Brazilian club training centre' },
  { tab: 'Grow Together', body: 'Training, travel, recovery, meals, and shared responsibility give a team more time together than a normal tournament weekend.',
    image: '/jc-soccer-camp/uploads/CleanShot 2026-08-18 at 10.27.45.png', alt: 'Players together on Copacabana beach' },
  { tab: 'Experience Rio As A Family', body: 'Parents can share Copacabana, landmarks, meals, music, and the cultural side of the week while the player lives the football.',
    image: '/jc-soccer-camp/uploads/CleanShot 2026-08-18 at 10.30.25.png', fit: 'contain', alt: 'Families and players sharing meals, matches, and Rio views together' }
];

const T_ARCHIVE = '/jc-soccer-camp/assets/';

const DAYS = [
  ['00', 'Travel Together', 'Group check-in and the overnight flight.',
    'Players and families meet Julio and the staff at the designated departure airport. The group checks in together and stays organized from the terminal through the overnight flight to Rio.',
    [['luggage', 'Group meet and check-in'], ['plane', 'Overnight flight to Rio de Janeiro']],
    [['/jc-soccer-camp/assets/tour-airport-terminal-group.png', 'The group walking through the terminal on travel day'], ['/jc-soccer-camp/assets/tour-airport-curbside-luggage.png', 'Players with their luggage at the airport on travel day']]],
  ['01', 'Land, Settle In, Meet Rio', 'Organized transfer, hotel check-in, and the first team dinner.',
    'The group is met at the airport and driven to Rio Othon Palace. The first day stays light: settle into the rooms, walk the Copacabana beachfront, and share dinner before the football begins.',
    [['van', 'Organized airport transfer'], ['bed', 'Hotel check-in on Copacabana'], ['clock', 'Time to settle in'], ['meal', 'Team dinner']],
    [['/jc-soccer-camp/assets/tour-van-copacabana.png', 'The tour van on the Copacabana beachfront'], ['/jc-soccer-camp/assets/tour-rooftop-pool-night.png', 'The rooftop pool above Copacabana at night']]],
  ['02', 'Two Sessions On The Ball', 'Training, assessment, and recovery.',
    'The first full day sets the standard for the week. Julio assesses the group, sharpens key technical ideas, and finishes with recovery so the players are ready to compete.',
    [['coffee', 'Breakfast at the hotel'], ['training', 'Morning training session'], ['meal', 'Lunch'], ['whistle', 'Afternoon training session'], ['meal', 'Dinner and recovery']],
    [['/jc-soccer-camp/assets/tour-botafogo-squad-stadium.png', 'The full group with staff on the pitch at a Brazilian club stadium'], ['/jc-soccer-camp/assets/tour-team-dinner-pizza.png', 'Players together over dinner after training']]],
  ['03', 'First Match, Then The Maracana', 'A recent tour played at Fluminense before a professional match.',
    'Players enter a Brazilian club setting and compete. That evening, the group experiences a professional match from the stands - the moment the trip starts to feel like Brazilian football from the inside.',
    [['coffee', 'Breakfast'], ['whistle', 'Friendly match'], ['meal', 'Lunch'], ['stadium', 'Stadium visit and professional match']],
    [[T_PHOTOS + 'tour-past-fluminense-training-center.jpg', 'The group at the Fluminense training centre'], [T_PHOTOS + 'tour-group-inside-rio-stadium.jpg', 'Players and families in the stands for a professional match']]],
  ['04', 'Second Match, Then Sugarloaf', 'Football in the morning. Rio from above in the afternoon.',
    'A recent group played at Botafogo before riding the cable car to Sugarloaf for the view across the bay and the city.',
    [['coffee', 'Breakfast'], ['whistle', 'Friendly match'], ['meal', 'Lunch'], ['mountain', 'Sugarloaf Mountain'], ['meal', 'Dinner']],
    [['/jc-soccer-camp/assets/tour-squad-stadium-lineup.png', 'The squad lined up on the pitch before a match at a Rio stadium'], [T_ARCHIVE + 'tour-group-sugarloaf.jpg', 'The group in front of Sugarloaf Mountain']]],
  ['05', 'Third Match, Then Corcovado', "Another competitive test followed by one of Rio's defining views.",
    'A recent departure played Tigres do Brasil before visiting Corcovado and Christ the Redeemer. Exact opponents and cultural order vary by tour.',
    [['coffee', 'Breakfast'], ['whistle', 'Friendly match'], ['meal', 'Lunch'], ['landmark', 'Corcovado and Christ the Redeemer'], ['meal', 'Dinner']],
    [['/jc-soccer-camp/uploads/pasted-1786990616592-0.png', 'Julio speaking to the squad before kickoff'], ['/jc-soccer-camp/assets/tour-group-christ-redeemer-wide.png', 'The group during the Corcovado visit']]],
  ['06', 'Futsal And Time To Reset', 'A futsal clinic and an open afternoon.',
    'Futsal asks players to think and act in tight spaces. After the clinic, the group has time to recover at the hotel, visit the pool or beach, and spend time with family.',
    [['coffee', 'Breakfast'], ['futsal', 'Futsal clinic'], ['meal', 'Lunch'], ['clock', 'Free time and recovery'], ['meal', 'Dinner']],
    [[T_VIDEO + 'tour-futsal-session.mp4', 'Players in a futsal session in tight space'], [HOTEL + 'othon-rooftop-pool-sunset.png', 'The rooftop pool above Copacabana']]],
  ['07', 'Beach Football And A Final Night Together', 'Copacabana, the city, and a farewell dinner.',
    'The final full day brings football to Copacabana. Beach soccer starts the morning, the afternoon opens for the city and shopping, and the group finishes with dinner and live music.',
    [['waves', 'Beach soccer on Copacabana'], ['shopping', 'Shopping and the city'], ['meal', 'Farewell dinner']],
    [['/jc-soccer-camp/assets/tour-copacabana-beach-football.png', 'Beach soccer on Copacabana in front of the hotel'], [T_PHOTOS + 'tour-live-music-night.jpg', 'Live Brazilian music at a beachfront restaurant']]],
  ['08', 'Breakfast, Checkout, Home', 'Organized transfer and the flight home.',
    'After one last breakfast, the group checks out and travels together to the airport. Players leave with nine days of Brazilian football, Rio, and shared experience behind them.',
    [['coffee', 'Breakfast'], ['luggage', 'Hotel checkout'], ['van', 'Organized airport transfer'], ['plane', 'Flight home']],
    [['/jc-soccer-camp/assets/tour-departure-plane-sugarloaf.jpg', 'A flight lifting off past Sugarloaf at the end of the tour']]]
];

const PENDING_OPS = ['Chaperone ratio', 'Rooming approach', 'Parent communication rhythm', 'Emergency contact process', 'Safeguarding and medical-response procedures', 'Travel insurance requirements'];

const PRE_LAUNCH = ['Included for this departure', 'Not included for this departure', 'Departure airport and baggage terms', 'Parent/guardian price', 'Insurance, cancellation, and refund terms'];

const GALLERY = [
  { src: T_VIDEO + 'tour-experience-reel.mp4', type: 'video', alt: 'Past-tour footage of training, matches and Rio', caption: 'The tour reel', h: 'lg' },
  { src: '/jc-soccer-camp/uploads/CleanShot%202026-08-17%20at%2016.21.41.png', alt: 'A young player driving at the ball in a camp session', caption: 'Train', h: 'md' },
  { src: T_PHOTOS + 'tour-team-huddle.jpg', alt: 'Team huddle during a training session in Brazil', caption: 'Train', h: 'lg' },
  { src: T_PHOTOS + 'tour-past-fluminense-training-center.jpg', alt: 'Past tour visit to a Brazilian training centre', caption: 'Club environments', h: 'sm' },
  { src: '/jc-soccer-camp/uploads/CleanShot%202026-08-17%20at%2016.10.22.png', alt: 'The squad and staff lined up for a team photo in a Brazilian stadium', caption: 'Play', h: 'md' },
  { src: T_VIDEO + 'tour-futsal-session.mp4', type: 'video', alt: 'Players in a futsal session in tight space', caption: 'Futsal', h: 'lg' },
  { src: T_PHOTOS + 'tour-group-inside-rio-stadium.jpg', alt: 'Players and families in the stands for a professional match', caption: 'Stadium nights', h: 'md' },
  { src: T_PHOTOS + 'tour-past-vasco-stadium.jpg', alt: 'Past tour stadium experience in Rio', caption: 'Club environments', h: 'sm' },
  { src: '/jc-soccer-camp/assets/tour-copacabana-beach-football.png', alt: 'Beach soccer on Copacabana in front of the hotel', caption: 'Copacabana', h: 'lg' },
  { src: T_PHOTOS + 'tour-scrimmage-club-environment.jpg', alt: 'Scrimmage inside a Brazilian club environment', caption: 'Play', h: 'md' },
  { src: T_VIDEO + 'tour-club-training-reel.mp4', type: 'video', alt: 'Past-tour footage of training inside a Brazilian club environment', caption: 'Club session', h: 'lg' },
  { src: '/jc-soccer-camp/uploads/CleanShot 2026-08-18 at 10.18.00.png', alt: 'Tour squad together on the field outside a Rio stadium', caption: 'Together', h: 'md' },
  { src: T_PHOTOS + 'tour-past-botafogo-team-photo.jpg', alt: 'Group team photo from a past tour', caption: 'Together', h: 'sm' },
  { src: '/jc-soccer-camp/uploads/pasted-1786990616592-0.png', alt: 'Julio speaking to the squad before kickoff', caption: 'Match day', h: 'lg' },
  { src: T_PHOTOS + 'tour-group-beach-soccer.jpg', alt: 'Beach soccer with the group in Rio', caption: 'Together / Rio', h: 'md' },
  { src: '/jc-soccer-camp/uploads/CleanShot 2026-08-18 at 10.27.45.png', alt: 'Players together on Copacabana beach', caption: 'Copacabana', h: 'lg' },
  { src: '/jc-soccer-camp/assets/tour-group-christ-redeemer-wide.png', alt: 'The group during the Corcovado visit', caption: 'Explore Rio', h: 'md' },
  { src: T_PHOTOS + 'tour-group-christ-redeemer.jpg', alt: 'Group during a cultural visit in Rio', caption: 'Explore Rio', h: 'sm' },
  { src: T_PHOTOS + 'tour-group-rio-tram.jpg', alt: 'Group travelling on a Rio tram', caption: 'Explore Rio', h: 'md' },
  { src: T_PHOTOS + 'tour-live-music-night.jpg', alt: 'Cultural night with live music', caption: 'Explore Rio', h: 'lg' },
  { src: T_PHOTOS + 'tour-hero-drone-match.jpg', alt: 'Aerial view of a match during a past tour', caption: 'Match day', h: 'md' }
];
/* Two marquee rows drifting left to right, each looping its own half of the set. Items keep
   their native aspect ratio - the row fixes the height and the width follows. */
const GAL_STILLS = GALLERY.filter((it) => it.type !== 'video');
const GAL_ROWS = [GAL_STILLS.filter((_, i) => i % 2 === 0), GAL_STILLS.filter((_, i) => i % 2 === 1)];

const FAQ_ITEMS = [
  { question: "Who Is The JC Brasil Tour For?", answer: "Summer 2027 is being planned for competitive players ages 12-18, with a mid-to-high preferred level. Julio reviews age, current level, and group needs before confirming fit." },
  { question: "Can One Player Join Without A Full Team?", answer: "Yes. A family can inquire for one player. Julio will confirm whether the player's age, level, timing, and group needs align." },
  { question: "Can A Coach Bring A Team?", answer: "Yes. Julio speaks directly with club, academy, and high-school coaches about roster age, competitive level, timing, and group structure. Use Plan A Team Tour in the inquiry form." },
  { question: "What About College Teams?", answer: "Summer 2027 priority interest is centered on ages 12-18. Julio is also opening conversations with college coaches about future dedicated team departures built around a roster and school calendar." },
  { question: "Can Parents Or Guardians Travel With The Group?", answer: "Yes. Parents and guardians are welcome to travel and stay with the group. Parent pricing, rooming, flights, and final inclusions are provided with the confirmed departure details." },
  { question: "When Is The Next Tour?", answer: "The next planning season is Summer 2027, typically in July or August. Exact dates are coming, and priority interest is open now." },
  { question: "Where Does The Group Stay?", answer: "The group uses Rio Othon Palace in Copacabana as its Rio home base. Exact room types, bedding, and availability are confirmed for each departure." },
  { question: "What Is The Tour Planned To Include?", answer: "Current planning includes group airfare from the designated departure airport, hotel, meals, organized transportation, training, futsal, friendly games, club and stadium experiences, and Rio cultural activities. Final inclusions are provided before commitment." },
  { question: "How Will Flights Work?", answer: "The group travels together from a designated departure airport. The final airport, flight schedule, baggage terms, and parent arrangements are shared with the confirmed departure details." },
  { question: "How Are Players Supervised?", answer: "Players travel as one organized group with Julio and Futbol America Group, supported by staff, chaperones, designated drivers, planned transportation, and approved locations. Final rooming, communication, emergency, and medical-response procedures are shared before registration." },
  { question: "Which Clubs Will The Group Visit?", answer: "Every departure includes club access and a stadium experience. Past groups have trained, played, or visited settings involving Fluminense, Flamengo, Botafogo, and Vasco da Gama. Exact clubs vary with the confirmed local schedule." },
  { question: "Are Games And Professional Matches Guaranteed?", answer: "The tour is built around training, games, club access, and a stadium experience. Exact opponents and professional-match tickets depend on the local schedule and are confirmed for each departure." },
  { question: "Can The Tour Lead To A Professional Opportunity?", answer: "The right player can attract legitimate interest in the football settings the group enters. Any next step depends on level, fit, timing, eligibility, and the club. Participation does not guarantee scouting, a trial, recruitment, or a contract." },
  { question: "When Will Pricing Be Available?", answer: "Summer 2027 pricing is being finalized with the dates, flights, and group arrangements. The working payment rhythm is a first deposit about six months before travel followed by two payments. The complete price and terms will be provided before any commitment." },
  { question: "What Documents And Insurance Will Be Required?", answer: "Families receive a departure checklist covering passports, parental travel authorization, insurance requirements, forms, and deadlines. Do not send passport or medical information through the website inquiry form." },
  { question: "What Happens After I Send An Inquiry?", answer: "Julio reviews whether you are asking for one player, a family, or a team. He then confirms fit, answers questions, and shares the next Summer 2027 details. No deposit or payment is taken through the form." }
];

function TourHero({ paused }) {
  const t = window.JC.RECORD.tour;
  const videoRef = React.useRef(null);
  const [videoReady, setVideoReady] = React.useState(false);
  React.useEffect(() => {
    const v = videoRef.current;
    if (!v) return;
    v.muted = true;
    v.volume = 0;
    if (paused) { v.pause(); v.currentTime = 0; } else { const p = v.play(); if (p && p.catch) p.catch(() => {}); }
  }, [paused]);
  const attachVideo = (el) => {
    videoRef.current = el;
    if (!el) return;
    el.setAttribute('muted', '');
    el.defaultMuted = true;
    el.muted = true;
    el.volume = 0;
    const tracks = el.audioTracks;
    if (tracks) { for (let i = 0; i < tracks.length; i++) { tracks[i].enabled = false; } }
  };
  /* Hero crop: the frame starts top-aligned and eases down to centered over the clip's first
     8 seconds, then repeats with the loop. */
  React.useEffect(() => {
    const mq = window.matchMedia('(prefers-reduced-motion: reduce)');
    let raf = 0;
    const tick = () => {
      const v = videoRef.current;
      if (v) {
        const p = mq.matches ? 1 : Math.min(1, Math.max(0, v.currentTime / 8));
        const eased = 1 - Math.pow(1 - p, 3);
        v.style.objectPosition = 'right ' + (eased * 50).toFixed(1) + '%';
      }
      raf = window.requestAnimationFrame(tick);
    };
    raf = window.requestAnimationFrame(tick);
    return () => window.cancelAnimationFrame(raf);
  }, []);
  return (
    <section className="jc-hero jc-field-invert" style={{ background: 'var(--areia)' }}>
      <div className="jc-hero-copy">
        <div style={{ display: 'grid', gap: 'var(--space-6)', justifyItems: 'start' }}>
          <p style={{ ...jcLayout.eyebrow, margin: 0, color: 'var(--text-muted)' }}>JC Brasil Tour | Summer 2027</p>
          <h1 className="jc-hero-title" style={{ ...jcLayout.display('2xl'), fontWeight: 'var(--weight-extrabold)' }}>
            More than a soccer tour. <span style={{ color: 'var(--copacabana)' }}>Nine days inside Brazilian football.</span>
          </h1>
          <p style={{ margin: 0, maxWidth: '480px', fontSize: 'var(--text-lg)' }}>
            Competitive players ages 12-18 train, play local opposition, experience futsal and Brazilian club settings, and explore Rio with Julio, teammates, and family. Parents and guardians are welcome.
          </p>
          <div className="jc-cta-row jc-cta-row--hero" style={{ ...jcLayout.row, gap: '10px', width: '100%' }}>
            <Button variant="primary" href="#inquiry" style={{ gap: 'var(--space-3)', padding: '0 10px 0 18px', whiteSpace: 'nowrap' }}>Ask About 2027</Button>
            <Button variant="secondary" href="#itinerary" style={{ gap: 'var(--space-3)', padding: '0 10px 0 18px', whiteSpace: 'nowrap' }}>See Itinerary</Button>
          </div>
          <div className="jc-cred" style={{ margin: 'var(--space-4) 0 0', paddingTop: 'var(--space-6)', borderTop: 'var(--border-hairline) solid var(--line)' }}>
            <div>
              <p className="jc-cred-label">Former professional player</p>
              <div className="jc-crests">
                <img src="/jc-soccer-camp/assets/clubs/usl.png" alt="USL" style={{ height: '22px' }} />
                <img src="/jc-soccer-camp/assets/clubs/brasileirao.png" alt="Brasileirao" style={{ height: '36px' }} />
              </div>
            </div>
            <div>
              <p className="jc-cred-label">Clubs that trust Julio</p>
              <div className="jc-crests">
                <img src="/jc-soccer-camp/assets/clubs/vasco.png" alt="Vasco da Gama" style={{ height: '32px' }} />
                <img src="/jc-soccer-camp/assets/clubs/flamengo.png" alt="Flamengo" style={{ height: '32px' }} />
                <img src="/jc-soccer-camp/assets/clubs/fluminense.png" alt="Fluminense" style={{ height: '32px' }} />
                <img src="/jc-soccer-camp/assets/clubs/botafogo.png" alt="Botafogo" style={{ height: '32px' }} />
              </div>
            </div>
          </div>
        </div>
      </div>
      <div className="jc-hero-media">
        <img src={T_PHOTOS + 'tour-hero-drone-match.jpg'} alt="Aerial view of a match during a past JC Brasil Tour" style={{ opacity: videoReady && !paused ? 0 : 1 }} />
        <video ref={attachVideo} src={T_VIDEO + 'tour-experience-reel.mp4'} autoPlay muted loop playsInline disableRemotePlayback
          aria-label="Past-tour footage of training, matches and Rio"
          onLoadedMetadata={(e) => { e.target.muted = true; e.target.volume = 0; }} onCanPlay={() => setVideoReady(true)}
          style={{ opacity: videoReady && !paused ? 1 : 0 }} />
      </div>
    </section>
  );
}

function ProofStrip() {
  return (
    <div className="jc-proof">
      <MetricBand items={[{ value: 'Since 2010', label: 'Leading tours' }, { value: 'Team / group', label: 'Format' }, { value: 'Room & board', label: 'Included' }, { value: '500+', label: 'Happy athletes' }]} />
    </div>
  );
}

function TourSubNav() {
  return (
    <nav aria-label="Tour sections" className="jc-subnav">
      <div className="jc-subnav-inner">
        {TOUR_SECTIONS.map((l) => (
          <a key={l.href} href={l.href}>{l.label}</a>
        ))}
      </div>
    </nav>
  );
}

function FitSection() {
  return (
    <section id="experience" className="jc-bleed jc-capped" style={{ ...jcLayout.bleed, background: 'var(--areia-warm)' }}>
      <SectionHead eyebrow="01 / Who It Is For" title="A serious experience for players. A clear plan for parents and coaches."
        note="Summer 2027 is being planned for competitive players ages 12-18, with a mid-to-high preferred level. Individual families and organized teams may inquire." />
      <div className="jc-upcoming">
        {FIT.map((f) => (
          <article key={f.who} className="jc-up-card">
            <div className="jc-up-copy">
              <p className="jc-up-status">{f.who}</p>
              <h3 style={{ ...jcLayout.display('sm'), margin: 0 }}>{f.title}</h3>
              <p style={{ margin: 0, fontSize: 'var(--text-sm)', textWrap: 'pretty' }}>{f.body}</p>
              <Button variant="tertiary" href="#inquiry">Ask About Summer 2027</Button>
            </div>
            <img className="jc-up-img" src={f.image} alt={f.alt} style={f.focus ? { objectPosition: f.focus } : null} />
          </article>
        ))}
      </div>
      <p className="jc-fit-note">Do not have a full team? One family can still inquire. Julio will review the player's age, current level, and the needs of the group being formed.</p>
    </section>
  );
}

function ReelSection({ paused }) {
  /* VideoStage owns the <video>. The file streams progressively, so seeking straight to the 6s
     in-point hangs on unbuffered data — instead it plays from 0 behind the poster and only
     hands over once playback has passed 6s, then re-seeks to 6 on every loop. */
  const stageRef = React.useRef(null);
  const [armed, setArmed] = React.useState(false);
  React.useEffect(() => {
    const v = stageRef.current && stageRef.current.querySelector('video');
    if (!v) return;
    const START = 6;
    let ready = false;
    const onTime = () => {
      if (!ready) {
        if (v.currentTime >= START) { ready = true; setArmed(true); }
        return;
      }
      if (v.currentTime < START) { try { v.currentTime = START; } catch (e) {} }
    };
    const kick = () => { const p = v.play(); if (p && p.catch) p.catch(() => {}); };
    v.addEventListener('canplay', kick);
    v.addEventListener('timeupdate', onTime);
    kick();
    return () => { v.removeEventListener('canplay', kick); v.removeEventListener('timeupdate', onTime); };
  }, []);
  return (
    <section id="reel" className="jc-bleed jc-field-invert" style={{ ...jcLayout.bleed, background: 'var(--charcoal)', color: 'var(--areia)' }}>
      <div className="jc-reel-split">
        <div ref={stageRef} className="jc-reel-stage" style={{ position: 'relative' }}>
        <VideoStage src={T_VIDEO + 'tour-club-training-reel.mp4'} poster={T_PHOTOS + 'tour-scrimmage-club-environment.jpg'}
          alt="Past-tour footage of training inside a Brazilian club environment" paused={paused} height="100%" overlay={false}
          style={{ borderRadius: 'var(--radius)', aspectRatio: '9 / 16' }} />
        <img src={T_PHOTOS + 'tour-scrimmage-club-environment.jpg'} alt="" aria-hidden="true"
          style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', borderRadius: 'var(--radius)', opacity: armed ? 0 : 1, pointerEvents: 'none', transition: 'opacity var(--motion-reveal) var(--ease-brand)' }} />
        </div>
        <div>
          <p style={jcLayout.eyebrow}>02 / Feel The Tour</p>
          <h2 className="jc-dxl" style={jcLayout.display('xl')}>Serious football for the player. An unforgettable Rio experience for the family.</h2>
          <p style={{ margin: 'var(--space-7) 0 0', maxWidth: '52ch', fontSize: 'var(--text-lg)' }}>
            Days move between training, matches, futsal, club grounds, and stadiums, with Copacabana, Sugarloaf, Corcovado, food, music, and time together woven in. Football is the reason for the trip. Rio makes it something the whole family can share.
          </p>
          <div className="jc-cta-row" style={{ ...jcLayout.row, marginTop: 'var(--space-8)' }}>
            <Button variant="primary" href="#inquiry">Ask About Summer 2027</Button>
            <span className="jc-btn-on-dark"><Button variant="secondary" href="#itinerary">See The 9-Day Experience</Button></span>
          </div>
        </div>
      </div>
    </section>
  );
}

function GainsSection() {
  const [open, setOpen] = React.useState(0);
  const [cycling, setCycling] = React.useState(true);
  React.useEffect(() => {
    if (!cycling) return;
    const id = setTimeout(() => setOpen((o) => (o + 1) % GAINS.length), 9000);
    return () => clearTimeout(id);
  }, [open, cycling]);
  return (
    <section className="jc-gains-sec">
      <div className="jc-gains-wrap">
      <div className="jc-gains-head">
        <p style={{ ...jcLayout.eyebrow, margin: '0 0 var(--space-5)', color: 'var(--text-muted)' }}>03 / What Comes Home With Them</p>
        <h2 style={{ ...jcLayout.display('xl'), margin: 0, maxWidth: '24ch' }}>A new football environment can change what a player notices.</h2>
      </div>
      <div className="jc-gains">
        <div className="jc-gains-rail">
          {GAINS.map((g, i) => {
            const isOpen = i === open;
            return (
              <div key={g.tab} className={'jc-gn-row' + (isOpen ? ' is-open' : '')}>
                {isOpen ? <p className="jc-gn-body">{g.body}</p> : null}
                <button type="button" className="jc-gn-tab" aria-expanded={isOpen} onClick={() => { setCycling(false); setOpen(i); }}>
                  {isOpen ? <span className="jc-gn-dot" aria-hidden="true"></span> : null}
                  <span>{g.tab}</span>
                </button>
                {isOpen && cycling ? <span key={'g' + open} className="jc-gn-progress" aria-hidden="true"><i></i></span> : null}
              </div>
            );
          })}
        </div>
        <div className="jc-gains-media">
          {GAINS.map((g, i) => (
            <img key={g.tab} src={g.image} alt={i === open ? g.alt : ''} aria-hidden={i === open ? undefined : 'true'} style={{ opacity: i === open ? 1 : 0, ...(g.fit ? { objectFit: g.fit } : null) }} />
          ))}
        </div>
      </div>
      </div>
      <div className="jc-gains-wrap"><p className="jc-gains-note">Club staff have shown interest in some past participants. Any next step depends on the player's level, fit, timing, eligibility, and the club. The tour creates a real environment to be seen, not a promise of a trial or contract.</p></div>
    </section>
  );
}

const TEAM_POINTS = [
  ['Youth clubs and academies', 'Bring an existing age group into the experience together.', 'Youth team / club'],
  ['High-school teams', 'Combine preseason development, competition, and team culture.', 'High-school team'],
  ['Family-supported travel', 'Parents and guardians can join the group.', 'JC Brasil Tour - Summer 2027'],
  ['Future college departures', 'Start planning a dedicated experience around a college roster and calendar.', 'College team / future departure']
];

function pickInterest(value) {
  window.dispatchEvent(new CustomEvent('jc:interest', { detail: value }));
}

function TeamBand() {
  return (
    <section id="teams" className="jc-bleed jc-team-band" style={{ ...jcLayout.bleed, background: 'var(--copacabana)', color: 'var(--areia)' }}>
      <div className="jc-cols-2" style={{ alignItems: 'start' }}>
        <div>
          <p style={{ ...jcLayout.eyebrow, margin: 0, color: 'var(--paper-80)' }}>For Coaches And Team Leaders</p>
          <h2 className="jc-dxl" style={{ ...jcLayout.display('xl'), margin: 'var(--space-6) 0 0' }}>Give your team something a tournament cannot.</h2>
          <p style={{ margin: 'var(--space-7) 0 0', maxWidth: '52ch', fontSize: 'var(--text-base)', textWrap: 'pretty' }}>
            Instead of arriving, playing, and going home, your team spends nine days training, competing, recovering, and living the game together. Julio works directly with coaches to discuss the roster, competitive level, travel window, and goals for the experience.
          </p>
          <div style={{ ...jcLayout.row, marginTop: 'var(--space-8)' }}>
            <Button variant="primary" href="#inquiry-form" onClick={() => pickInterest('Youth team / club')}>Plan A Team Tour</Button>
          </div>
        </div>
        <ul className="jc-team-points">
          {TEAM_POINTS.map(([title, body, interest]) => (
            <li key={title}>
              <a href="#inquiry-form" onClick={() => pickInterest(interest)}>
                <p className="jc-team-title">{title}</p>
                <p className="jc-team-body">{body}</p>
              </a>
            </li>
          ))}
          <li className="jc-team-note">Summer 2027 priority interest is centered on players ages 12-18. College teams can book year round.</li>
        </ul>
      </div>
    </section>
  );
}

function DayMedia({ day }) {
  return (
    <div className="jc-itin-media" key={day[0]}>
      {day[5].map(([src, alt]) => (/\.(mp4|mov|webm)$/i.test(src) ? (
        <figure key={src} style={{ margin: 0, borderRadius: 'var(--radius)', overflow: 'hidden', aspectRatio: '3 / 2', background: 'var(--charcoal)' }}>
          <video src={src} aria-label={alt} autoPlay muted loop playsInline disableRemotePlayback style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />
        </figure>
      ) : (
        <MediaFigure key={src} src={src} alt={alt} ratio={day[5].length === 1 ? '4 / 5' : '3 / 2'} />
      )))}
    </div>
  );
}

function ItineraryDay({ day, open, onToggle }) {
  const [num, title, teaser, body, items] = day;
  return (
    <div className={'jc-day' + (open ? ' is-open' : '')}>
      <button type="button" className="jc-day-head" aria-expanded={open} onClick={onToggle}>
        <span className="jc-day-num">{num}</span>
        <span className="jc-day-title">
          <span className="jc-day-name">{title}</span>
          {open ? null : <span className="jc-day-teaser">{teaser}</span>}
        </span>
        <span className="jc-day-mark" aria-hidden="true">{open ? '\u2212' : '+'}</span>
      </button>
      {open ? (
        <div className="jc-day-body">
          <p className="jc-day-copy">{body}</p>
          <ul className="jc-day-list">
            {items.map(([icon, label]) => (
              <li key={label + icon}><Glyph name={icon} size={21} /><span>{label}</span></li>
            ))}
          </ul>
          <div className="jc-day-media-inline"><DayMedia day={day} /></div>
        </div>
      ) : null}
    </div>
  );
}

function ItinerarySection() {
  const [open, setOpen] = React.useState(1);
  const active = DAYS[open] || DAYS[1];
  return (
    <section id="itinerary" className="jc-bleed jc-capped" style={{ ...jcLayout.bleed, background: 'var(--areia-warm)' }}>
      <SectionHead eyebrow="04 / Nine days in Brasil" title="What the week actually looks like."
        note="Open a day to see the schedule, the football, and where the group goes." />
      <div className="jc-itin">
        <div className="jc-days">
          {DAYS.map((d, i) => (
            <ItineraryDay key={d[0]} day={d} open={open === i} onToggle={() => setOpen(open === i ? -1 : i)} />
          ))}
        </div>
        <DayMedia day={active} />
      </div>
      <p style={{ margin: 'var(--space-7) 0 0', maxWidth: '70ch', fontSize: 'var(--text-2xs)', color: 'var(--text-muted)' }}>
        This is the shape of a recent departure. Opponents, clubs, stadium access, cultural activities, and the order of days are subject to change with the confirmed Summer 2027 schedule.
      </p>
    </section>
  );
}

function StaySection({ paused }) {
  return (
    <section id="stay" className="jc-bleed jc-capped" style={{ ...jcLayout.bleed, background: 'var(--areia)' }}>
      <div className="jc-cols-2 jc-stay-grid" style={{ alignItems: 'start' }}>
        <div>
          <p style={{ ...jcLayout.eyebrow, margin: '0 0 var(--space-5)' }}>05 / Where The Group Stays</p>
          <h2 className="jc-dxl" style={{ ...jcLayout.display('xl'), maxWidth: '20ch' }}>Stay together on Copacabana. Wake up to Rio.</h2>
          <p style={{ margin: 'var(--space-8) 0 var(--space-7)', maxWidth: '52ch', fontSize: 'var(--text-sm)' }}>
            Players and accompanying families stay at Rio Othon Palace, the tour's Copacabana home base. The group has one place to eat, recover, regroup, and prepare for each day's football, with the beach just outside.
          </p>
          <ul style={{ margin: 0, padding: 0, listStyle: 'none' }}>
            {STAY_FACTS.map(([label, detail]) => (
              <li key={label} style={{ display: 'grid', gridTemplateColumns: '190px 1fr', gap: 'var(--space-4)', padding: 'var(--space-4) 0', borderTop: 'var(--border-hairline) solid var(--line)' }}>
                <span style={jcLayout.label}>{label}</span>
                <span style={{ fontSize: 'var(--text-sm)' }}>{detail}</span>
              </li>
            ))}
          </ul>
        </div>
        <VideoStage src={HOTEL_VIDEO + 'rio-othon-official-hotel-overview-01.mp4'} poster={HOTEL + 'othon-overview-poster.jpg'}
          alt="Official Rio Othon Palace hotel overview" paused={paused} height="620px" overlay={false}
          caption="Room availability subject to booking and change" />
      </div>
      <div className="jc-cols-4" style={{ marginTop: 'var(--space-9)', border: 0, gap: 'var(--space-4)' }}>
        <MediaFigure src={HOTEL + 'othon-beach-from-hotel.jpg'} alt="Copacabana beach directly in front of the hotel" caption="Copacabana at your door step" ratio="4 / 3" />
        <MediaFigure src={HOTEL + 'othon-classic-room.jpg'} alt="A Classic room at Rio Othon Palace" caption="Room included" ratio="4 / 3" />
        <MediaFigure src={HOTEL + 'othon-breakfast-fruit.png'} alt="Fresh fruit on the hotel breakfast buffet" caption="Daily Breakfast" ratio="4 / 3" />
        <MediaFigure src={HOTEL + 'othon-rooftop-pool-sunset.png'} alt="Rooftop pool and terrace above Copacabana at sunset" caption="Rooftop pool" ratio="4 / 3" />
      </div>
      <div className="jc-cols-2" style={{ marginTop: 'var(--space-9)', alignItems: 'center' }}>
        <VideoStage src={HOTEL_VIDEO + 'rio-othon-official-skylab-rooftop-restaurant-01.mp4'} poster={HOTEL + 'othon-rooftop-restaurant-panorama.jpg'}
          alt="Official video of the rooftop restaurant at Rio Othon Palace" paused={paused} height="340px" overlay={false} caption="Rooftop restaurant" />
        <div>
          <h3 style={jcLayout.display('sm')}>Breakfast with Copacabana in view.</h3>
          <p style={{ margin: 'var(--space-5) 0 0', maxWidth: '44ch', fontSize: 'var(--text-sm)' }}>
            Breakfast is served at the hotel before the group leaves for training. Meals and organized transportation are included in current tour planning, so families are not rebuilding the day on their own.
          </p>
        </div>
      </div>
    </section>
  );
}

const PLACE_INCLUDES = [
  ['Football', 'Training, futsal, and friendly games', <g><circle cx="10" cy="10" r="7" /><path d="M10 5.5l2.6 1.9-1 3.1h-3.2l-1-3.1z" /><path d="M6.4 15.2l1.9-4.7M13.6 15.2l-1.9-4.7M3.1 8.8l4.5-1.4M16.9 8.8l-4.5-1.4" /></g>],
  ['Stay and travel', 'Hotel, meals, and organized transportation', <g><path d="M3 15V6.5A1.5 1.5 0 014.5 5h11A1.5 1.5 0 0117 6.5V15" /><path d="M2 15h16M6 9h3M11 9h3" /></g>],
  ['Culture', 'Sightseeing and cultural activities in Rio', <g><path d="M2 16h16" /><path d="M5 16V9l5-5 5 5v7" /><path d="M8.5 16v-4h3v4" /></g>],
  ['Access', 'Stadium or professional-match experiences when the schedule allows', <g><path d="M3 7c2 1.2 4.4 1.8 7 1.8S15 8.2 17 7v6c-2 1.2-4.4 1.8-7 1.8S5 14.2 3 13z" /><path d="M3 7l2-2.5h10L17 7" /></g>],
  ['Flights', 'Subject to departure-specific confirmation', <path d="M2 11.5l16-5-4.5 9-2.5-3.5-4 2 .5-3z" />]
];

const PAY_SCHEDULE = [
  ['01', 'First deposit', 'About six months before travel'],
  ['02', 'Second payment', 'After the initial deposit'],
  ['03', 'Final payment', 'Before departure; exact deadline confirmed']
];

function PricingSection() {
  const t = window.JC.RECORD.tour;
  return (
    <section id="pricing" className="jc-bleed jc-field-invert jc-price-sec" style={{ ...jcLayout.bleed }}>
      <div className="jc-price-field">
      <SectionHead eyebrow="06 / Planning details" tone="paper" title="Know what is planned before the departure is confirmed."
        note="Summer 2027 pricing is being finalized with the dates, flights, and group arrangements. Julio shares the complete number before any commitment." />
      <div className="jc-price-layout">
        <div className="jc-price-panel" style={{ ...jcLayout.panel, color: 'var(--charcoal)' }}>
          <p style={{ ...jcLayout.label, margin: 0 }}>Summer 2027 pricing</p>
          <p className="jc-price-figure">{t.planningPrice.display}</p>
          <p style={{ margin: '6px 0 0', fontSize: 'var(--text-sm)', color: 'var(--text-muted)' }}>{t.planningPrice.currencyNote} &middot; {t.planningPrice.qualifier.toLowerCase()}</p>
          <div className="jc-price-ctas">
            <Button variant="primary" href="#inquiry">Ask About The Tour</Button>
            <Button variant="secondary" href="#teams">Plan A Team Tour</Button>
          </div>
          <p style={{ margin: 'var(--space-6) 0 0', paddingTop: 'var(--space-6)', borderTop: 'var(--border-hairline) solid var(--line)', fontSize: 'var(--text-2xs)', color: 'var(--text-muted)' }}>
            Final pricing will be confirmed with the exact dates, departure plan, and included and not-included terms. No deposit or payment is taken at this stage.
          </p>
        </div>
        <div className="jc-price-side">
          <div>
            <p style={{ ...jcLayout.label, margin: 0, color: 'var(--paper-80)' }}>What planning includes</p>
            <ul className="jc-price-incl">
              {PLACE_INCLUDES.map(([label, detail, icon]) => (
                <li key={label}>
                  <svg width="24" height="24" viewBox="0 0 20 20" fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">{icon}</svg>
                  <div>
                    <p>{label}</p>
                    <p>{detail}</p>
                  </div>
                </li>
              ))}
            </ul>
          </div>
          <div>
            <p style={{ ...jcLayout.label, margin: 0, color: 'var(--paper-80)' }}>Payment schedule</p>
            <ol className="jc-price-sched">
              {PAY_SCHEDULE.map(([n, label, detail]) => (
                <li key={n}>
                  <span>{n}</span>
                  <div>
                    <p>{label}</p>
                    <p>{detail}</p>
                  </div>
                </li>
              ))}
            </ol>
            <p style={{ margin: 'var(--space-5) 0 0', fontSize: 'var(--text-2xs)', color: 'var(--paper-80)' }}>Exact amounts and deadlines are confirmed for each departure.</p>
          </div>
        </div>
      </div>
      </div>
    </section>
  );
}

function JulioTourSection() {
  return (
    <section id="julio-tour" className="jc-bleed jc-field-invert jc-julio-sec" style={{ ...jcLayout.bleed, background: 'var(--tropical)', color: 'var(--areia)' }}>
      <div className="jc-julio-head">
        <p style={{ ...jcLayout.eyebrow, margin: 0 }}>07 / Led By Julio</p>
        <h2 className="jc-dxl" style={{ ...jcLayout.display('xl'), margin: 'var(--space-6) 0 0' }}>Brazilian roots. Proven experience. Present for the whole tour.</h2>
        <p style={{ margin: 'var(--space-7) 0 0', fontSize: 'var(--text-lg)' }}>
          Developed at Vasco da Gama and later a two-time USL D3 Pro League MVP and scoring champion, Julio brings decades of playing and coaching experience to every tour. He travels with the group and remains families&rsquo; direct contact throughout the trip.
        </p>
        <p style={{ margin: 'var(--space-6) 0 0', fontSize: 'var(--text-sm)', fontWeight: 'var(--weight-semibold)' }}>
          Vasco da Gama development &middot; 2x USL MVP and scoring champion &middot; Brasil tours since 2010
        </p>
      </div>
      <div className="jc-julio-body">
        <div className="jc-julio-collage">
          <MediaFigure src="/jc-soccer-camp/uploads/pasted-1787169001369-0.png" alt="Julio training as a young player in Brazil" caption="Brazil / Playing years" ratio="3 / 4" />
          <div className="jc-julio-collage-mid">
            <MediaFigure src={T_PHOTOS + 'tour-julio-and-supervision-team.jpg'} alt="Julio with the tour supervision team during a past departure" caption="Past tour / Julio and the supervision team" ratio="3 / 2" />
            <MediaFigure src="/jc-soccer-camp/uploads/CleanShot 2026-08-19 at 15.44.34.png" alt="Julio with his professional squad before a match in 2000" caption="2000 / Squad photo" ratio="5 / 3" />
          </div>
          <MediaFigure src="/jc-soccer-camp/uploads/CleanShot 2026-08-19 at 15.50.29.png" alt="Julio coaching from the touchline in a stadium" caption="Coaching today" ratio="3 / 4" />
        </div>
      </div>
    </section>
  );
}

const VOICES = [
  { id: '01', file: '/jc-soccer-camp/uploads/JC-Player-Testimonial-01-4x5.mp4', quote: 'This trip is a unique experience. It gives you the opportunity to play against some of the best players in Brazil and bond with your teammates.', name: 'Past tour player' },
  { id: '02', file: '/jc-soccer-camp/uploads/JC-Player-Testimonial-02-4x5.mp4', quote: "It showed me the talent in other parts of the world and let me experience something I can't experience anywhere else.", name: 'Past tour player' },
  { id: '03', file: '/jc-soccer-camp/uploads/JC-Player-Testimonial-03-4x5.mp4', quote: 'This trip creates a unique experience. It helped me get better at the sport, and the views and atmosphere were amazing.', name: 'Past tour player' },
  { id: '04', file: '/jc-soccer-camp/uploads/JC-Player-Testimonial-04-4x5.mp4', quote: 'The Brazilians are really technical.', name: 'Past tour player' },
  { id: '05', file: '/jc-soccer-camp/uploads/JC-Player-Testimonial-05-4x5.mp4', quote: 'This trip helped me grow and realize that I can take my abilities to a higher level.', name: 'Past tour player' },
  { id: '06', file: '/jc-soccer-camp/uploads/JC-Player-Testimonial-06-4x5.mp4', quote: 'This trip was a fun learning experience where soccer players could learn about Brazilian culture and how soccer is played.', name: 'Past tour player' },
  { id: '07', file: '/jc-soccer-camp/uploads/JC-Player-Testimonial-07-4x5.mp4', quote: 'This trip was fun and unforgettable. I made memories that will last the rest of my life.', name: 'Past tour player' }
];

function VoiceCard({ voice, paused }) {
  const ref = React.useRef(null);
  const [sound, setSound] = React.useState(false);
  React.useEffect(() => {
    const v = ref.current;
    if (!v) return;
    if (paused) { v.pause(); } else { v.play().catch(() => {}); }
  }, [paused]);
  const toggle = () => {
    const v = ref.current;
    if (!v) return;
    if (sound) { v.muted = true; setSound(false); }
    else {
      document.querySelectorAll('.jc-voice-stage video').forEach((o) => { if (o !== v) o.muted = true; });
      v.muted = false; v.currentTime = 0; v.play().catch(() => {}); setSound(true);
      window.JC.track('tour_media_engagement', { media_id: 'voice_' + voice.id, placement: 'stories', action: 'play' });
    }
  };
  return (
    <figure className="jc-voice" style={{ margin: 0 }}>
      <figcaption style={{ display: 'grid', gap: '10px' }}>
        <p className="jc-voice-quote">&ldquo;{voice.quote}&rdquo;</p>
        <p className="jc-voice-name">{voice.name} / Past tour</p>
      </figcaption>
    </figure>
  );
}

function TestimonialSection({ paused }) {
  const loop = VOICES.concat(VOICES);
  return (
    <section id="stories" className="jc-bleed jc-capped" style={jcLayout.bleed}>
      <SectionHead eyebrow="08 / Player Stories" title="They came to play. They left with more."
        note="New competition, new friendships, and a new view of the game&mdash;told by the players who lived it." />
      <div className="jc-voices">
        <div className="jc-voices-track">
          {loop.map((v, i) => <VoiceCard key={v.id + '-' + i} voice={v} paused={paused} />)}
        </div>
      </div>
      <div className="jc-voices-cta">
        <div style={{ display: 'flex', flexWrap: 'wrap', justifyContent: 'center', gap: 'var(--space-5)' }}>
          <Button href="#inquiry">Ask About Summer 2027</Button>
          <Button variant="secondary" href="#itinerary">See The Itinerary</Button>
        </div>
      </div>
    </section>
  );
}

function GallerySection() {
  const [index, setIndex] = React.useState(null);
  const move = (d) => setIndex((i) => (i + d + GAL_STILLS.length) % GAL_STILLS.length);
  const open = (item) => {
    setIndex(GAL_STILLS.indexOf(item));
    window.JC.track('tour_media_engagement', { media_id: 'gallery', placement: 'gallery', action: 'open_lightbox' });
  };
  const frozen = index !== null;
  return (
    <section id="gallery" className="jc-bleed jc-capped" style={{ ...jcLayout.bleed, background: 'var(--areia)' }}>
      <SectionHead eyebrow="09 / Past tour moments" title="Train. Play. Together. Rio."
        note="Past-tour media. Exact clubs, facilities, games, and activities vary by departure." />
      <div className="jc-galm" data-frozen={frozen ? 'true' : 'false'}>
        {GAL_ROWS.map((row, r) => (
          <div key={'row' + r} className="jc-galm-row">
            <div className="jc-galm-track" style={{ animationDuration: r === 0 ? '64s' : '82s' }}>
              {[0, 1].map((pass) => row.map((item, i) => (
                <button key={'p' + pass + '-' + i} type="button" className={'jc-galm-cell is-' + (item.h || 'md')}
                  onClick={() => open(item)} aria-hidden={pass === 1 ? 'true' : undefined}
                  tabIndex={pass === 1 ? -1 : undefined} aria-label={'Open: ' + item.alt}>
                  {item.type === 'video'
                    ? <video src={item.src} muted loop playsInline autoPlay={!frozen} disableRemotePlayback aria-label={item.alt}
                        ref={(el) => { if (!el) return; if (frozen) el.pause(); else el.play().catch(() => {}); }} />
                    : <img src={item.src} alt={pass === 1 ? '' : item.alt} />}
                  <span className="jc-gal-tag">{item.caption}</span>
                </button>
              )))}
            </div>
          </div>
        ))}
      </div>
      <GalleryLightbox items={GAL_STILLS} index={index} onClose={() => setIndex(null)} onMove={move} onPick={setIndex} />
    </section>
  );
}

/* Lightbox with a thumbnail rail: click any tile, then browse the whole set from the strip. */
function GalleryLightbox({ items, index, onClose, onMove, onPick }) {
  const closeRef = React.useRef(null);
  React.useEffect(() => {
    if (index === null) return;
    const onKey = (e) => {
      if (e.key === 'Escape') onClose();
      if (e.key === 'ArrowRight') onMove(1);
      if (e.key === 'ArrowLeft') onMove(-1);
    };
    document.addEventListener('keydown', onKey);
    if (closeRef.current) closeRef.current.focus();
    document.body.style.overflow = 'hidden';
    return () => { document.removeEventListener('keydown', onKey); document.body.style.overflow = ''; };
  }, [index, onClose, onMove]);
  if (index === null) return null;
  const item = items[index];
  return (
    <div role="dialog" aria-modal="true" aria-label="Tour gallery" className="jc-lbx"
      onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <figure className="jc-lbx-fig">
        {item.type === 'video'
          ? <video key={item.src} src={item.src} muted loop playsInline autoPlay controls aria-label={item.alt}
              ref={(el) => { if (el) { el.load(); el.play().catch(() => {}); } }}
              onError={(e) => { const v = e.currentTarget; setTimeout(() => { v.load(); v.play().catch(() => {}); }, 120); }} />
          : <img key={item.src} src={item.src} alt={item.alt} />}
        <figcaption>
          <span className="jc-lbx-cap">{item.caption}</span>
          <span>Past-tour media. Exact clubs, facilities, games, and activities vary by departure.</span>
          <span>{index + 1} / {items.length}</span>
        </figcaption>
      </figure>
      <div className="jc-lbx-rail" role="tablist" aria-label="Gallery thumbnails">
        {items.map((it, i) => (
          <button key={it.src + i} type="button" role="tab" aria-selected={i === index} aria-label={it.alt}
            className={i === index ? 'is-on' : ''} onClick={() => onPick(i)}>
            {it.type === 'video'
              ? <video src={it.src} muted playsInline preload="metadata" aria-hidden="true" />
              : <img src={it.src} alt="" aria-hidden="true" />}
          </button>
        ))}
      </div>
      <div className="jc-lbx-close">
        <button ref={closeRef} type="button" onClick={onClose} aria-label="Close gallery">&times;</button>
      </div>
      <div className="jc-lbx-nav">
        <button type="button" onClick={() => onMove(-1)} aria-label="Previous item">&#8249;</button>
        <button type="button" onClick={() => onMove(1)} aria-label="Next item">&#8250;</button>
      </div>
    </div>
  );
}

function FAQSection() {
  return (
    <section id="faq" className="jc-bleed jc-capped" style={{ ...jcLayout.bleed, background: 'var(--white)' }}>
      <div className="jc-cols-2 jc-faq-cols">
        <div>
          <p style={jcLayout.eyebrow}>10 / Questions Parents And Coaches Ask</p>
          <h2 className="jc-dxl" style={jcLayout.display('xl')}>Before you decide.</h2>
          <p style={{ margin: 'var(--space-6) 0 0', maxWidth: '360px', fontSize: 'var(--text-sm)', color: 'var(--text-muted)' }}>
            The essentials are here. Julio can answer the details that depend on the final group and departure.
          </p>
        </div>
        <FAQAccordion items={FAQ_ITEMS} />
      </div>
    </section>
  );
}

function InquirySection() {
  return (
    <section id="inquiry" className="jc-bleed jc-field-invert" style={{ ...jcLayout.bleed, background: 'var(--copacabana)', color: 'var(--areia)' }}>
      <div className="jc-cols-2 jc-inquiry-cols">
        <div>
          <p style={jcLayout.eyebrow}>11 / Summer 2027</p>
          <h2 className="jc-dxl" style={jcLayout.display('xl')}>Start with a question, not a commitment.</h2>
          <p style={{ margin: 'var(--space-7) 0 0', maxWidth: '440px', fontSize: 'var(--text-lg)' }}>
            Tell Julio whether you are inquiring for one player, a family, a youth team, or a college program. He will confirm fit, answer your questions, and share dates and next steps as the departure comes together.
          </p>
          <div style={{ ...jcLayout.row, marginTop: 'var(--space-8)' }}>
            <Button variant="primary" href="#inquiry-form">Go to the form</Button>
          </div>
          <p style={{ margin: 'var(--space-5) 0 0', fontSize: 'var(--text-2xs)', color: 'var(--paper-80)' }}>Julio replies personally. No deposit or payment is taken through this form.</p>
          <div style={{ marginTop: 'var(--space-8)' }}>
            <MediaFigure src={T_PHOTOS + 'tour-rio-lagoon-mountains.jpg'} alt="Rio lagoon and mountains" caption="Rio / The city around the football" ratio="3 / 2" />
          </div>
        </div>
        <InquiryPanel id="inquiry-form" page="brasil_tour" program="brasil_tour" title="Ask Julio About The Tour" note="Adult contact details only."
          interestLabel="I am inquiring for" phoneRequired emailRequired={false}
          ageLabel="Player age or team age group" submitLabel="Send My Tour Inquiry"
          updatesLabel="Send me Summer 2027 updates."
          interestOptions={['One player / family', 'Youth team / club', 'High-school team', 'College team / future departure']}
          defaultInterest="One player / family" showUpdatesOptIn />
      </div>
    </section>
  );
}

function TourPage() {
  const [paused] = useMotionToggle();
  const solid = useSolidHeader();
  return (
    <div>
      <PageHeader links={TOUR_NAV} solid
        programLogo={{ src: '/jc-soccer-camp/assets/brand/jc-brasil-tour-crest.png', label: 'JC Brasil Tour', href: '/jc-soccer-camp/brasil-tour/' }} backHref="/jc-soccer-camp/" backLabel="Julio Cesar Soccer Camp"
        cta={{ label: 'Ask About Summer 2027', href: '#inquiry' }} />
      <MobileBar links={TOUR_SECTIONS} action={{ label: 'Ask About Summer 2027', href: '#inquiry' }} />
      <TourHero paused={paused} />
      <ProofStrip />
      <TourSubNav />
      <div className="jc-field">
        <FitSection />
        <ReelSection paused={paused} />
        <GainsSection />
      <TeamBand />
        <ItinerarySection />
        <StaySection paused={paused} />
        <PricingSection />
        <JulioTourSection />
        <TestimonialSection paused={paused} />
        <GallerySection />
        <FAQSection />
        <InquirySection />
      </div>
      <PageFooter tagline="Play with rhythm. Train in Rio spirit."
        cta={{ label: 'Find the Right Program', href: '/jc-soccer-camp/#programs' }}
        links={[{ label: 'The Experience', href: '#experience' }, { label: 'Itinerary', href: '#itinerary' }, { label: 'Where you stay', href: '#stay' }, { label: 'Planning details', href: '#pricing' }, { label: 'FAQ', href: '#faq' }, { label: 'Julio Cesar Soccer Camp', href: '/jc-soccer-camp/' }]}
        note="JC Brasil Tour / By Julio Cesar Soccer Camp / Rio de Janeiro since 2010" />
      <StickyAction primary={{ label: 'Register interest', href: '#inquiry' }} />
      <WhatsAppBubble page="brasil_tour" message="Hi Julio, I found the JC Brasil Tour website and have a quick question." />
    </div>
  );
}

Object.assign(window, { TourPage });
