/* Shared page parts, composed from the Linha Carioca / Ritmo design system.
   Design-system components do the visual work; these wrappers add only the
   operational behaviour the brief requires (record binding, WhatsApp, states). */
const DS = window.JCBrasilTourLinhaCarioca_903c90;
const { Wordmark, Monogram, WaveField, Button, Tag, SectionHeading,
  TextField, SelectField, CheckboxField, MobileNav } = DS;

const jcLayout = {
  section: { width: 'min(var(--max-width), calc(100% - 56px))', margin: '0 auto', padding: 'var(--section-y) 0' },
  bleed: { width: '100%', paddingLeft: 'calc(max(28px, (100% - var(--max-width)) / 2) + var(--space-6))', paddingRight: 'calc(max(28px, (100% - var(--max-width)) / 2) + var(--space-6))', paddingTop: 'var(--section-y)', paddingBottom: 'var(--section-y)' },
  eyebrow: { margin: '0 0 18px', fontSize: 'var(--text-2xs)', fontWeight: 'var(--weight-bold)', textTransform: 'uppercase', letterSpacing: 'var(--tracking-label)' },
  label: { fontSize: 'var(--text-2xs)', fontWeight: 'var(--weight-bold)', textTransform: 'uppercase', letterSpacing: 'var(--tracking-label)', color: 'var(--text-muted)' },
  display: (step) => ({ margin: 0, fontFamily: 'var(--font-display)', fontSize: 'var(--display-' + step + ')', fontWeight: 'var(--weight-bold)', lineHeight: 'var(--leading-display)', letterSpacing: 'var(--tracking-display)' }),
  card: { padding: 'var(--space-7)', background: 'var(--white)', borderRadius: 'var(--radius)', boxShadow: 'var(--shadow-card)' },
  panel: { padding: 'var(--space-8)', background: 'var(--white)', borderRadius: 'var(--radius-lg)', boxShadow: 'var(--shadow-card)' },
  row: { display: 'flex', flexWrap: 'wrap', gap: '10px' }
};

/* Content awaiting client approval. Never dressed up as published copy. */
function ApprovalNote({ children, tone }) {
  return (
    <p style={{ display: 'flex', alignItems: 'baseline', gap: '10px', margin: '14px 0 0', fontSize: 'var(--text-2xs)', lineHeight: 'var(--leading-body)', color: tone === 'paper' ? 'var(--paper-80)' : 'var(--text-muted)' }}>
      <Tag tone={tone === 'paper' ? 'sol' : 'outline'}>Approval required</Tag>
      <span>{children}</span>
    </p>
  );
}

/* WhatsApp CTAs: the DS Button wraps its children in a single span, so the icon and label are
   composed together inside one inline-flex run to keep them on the same line. */
function WhatsAppLabel({ children }) {
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: '10px' }}>
      <Glyph name="whatsapp" size={18} />{children}
    </span>
  );
}

/* Section heading: eyebrow above the headline on the left, supporting note on the right.
   The DS SectionHeading puts the eyebrow in its own column, which the client rejected —
   same type tokens and rhythm, two columns instead of three. */
function SectionHead({ eyebrow, title, note, tone, level }) {
  const Heading = 'h' + (level || 2);
  return (
    <div className="jc-sechead" style={{ color: tone === 'paper' ? 'var(--areia)' : 'var(--charcoal)' }}>
      <div>
        <p style={{ margin: '0 0 var(--space-5)', fontSize: 'var(--text-2xs)', fontWeight: 'var(--weight-bold)', lineHeight: 'var(--leading-snug)', textTransform: 'uppercase', letterSpacing: 'var(--tracking-label)' }}>{eyebrow}</p>
        <Heading style={{ margin: 0, fontFamily: 'var(--font-display)', fontSize: 'var(--display-xl)', fontWeight: 'var(--weight-bold)', lineHeight: 'var(--leading-display)', letterSpacing: 'var(--tracking-display)' }}>{title}</Heading>
      </div>
      {note ? <p style={{ margin: 0, fontSize: 'var(--text-base)' }}>{note}</p> : null}
    </div>
  );
}

function useMotionToggle() {
  const [paused, setPaused] = React.useState(false);
  React.useEffect(() => { document.body.classList.toggle('motion-off', paused); }, [paused]);
  return [paused, () => setPaused((p) => !p)];
}

function useSolidHeader() {
  const [solid, setSolid] = React.useState(false);
  React.useEffect(() => {
    const onScroll = () => setSolid(window.scrollY > 56);
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  return solid;
}

/* Header: the design system's SiteHeader carries no CTA slot, and every page here needs
   the Talk with Julio action in the bar, so the shell is composed from Wordmark and
   Button with header tokens. */
function PageHeader({ links, cta, programTag, programLogo, backHref, backLabel, solid }) {
  return (
    <header className="jc-head" style={{
      position: 'fixed', top: 0, left: 0, right: 0, zIndex: 30,
      minHeight: solid ? '64px' : '78px', padding: '0 var(--gutter)',
      color: solid ? 'var(--charcoal)' : 'var(--white)',
      background: solid ? 'rgba(242,240,230,.96)' : 'transparent',
      backdropFilter: solid ? 'blur(12px)' : undefined,
      borderBottom: 'var(--border-hairline) solid ' + (solid ? 'var(--line)' : 'rgba(255,255,255,.22)'),
      transitionProperty: 'min-height, color, background-color, border-color',
      transitionDuration: 'var(--motion-standard)', transitionTimingFunction: 'var(--ease-brand)'
    }}>
      <div className="jc-head-inner" style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-6)', width: '100%', maxWidth: 'var(--max-width)', minHeight: 'inherit', margin: '0 auto' }}>
      <Wordmark as="a" href="/jc-soccer-camp/" lockup={solid ? 'horizontal' : 'horizontalWhite'} size={solid ? 'sm' : 'md'} />
      {programLogo ? (
        <a href={programLogo.href || '#'} aria-label={programLogo.label} title={programLogo.label} style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-5)', color: 'inherit', textDecoration: 'none' }}>
          <span aria-hidden="true" style={{ width: '1px', height: '34px', background: solid ? 'var(--line)' : 'rgba(255,255,255,.34)' }} />
          <img src={programLogo.src} alt="" style={{ height: '42px', width: 'auto', display: 'block' }} />
        </a>
      ) : null}
      {programTag ? <Tag tone={solid ? 'copacabana' : 'sol'}>{programTag}</Tag> : null}
      {backHref ? (
        <a href={backHref} style={{ display: 'none', color: 'inherit', fontSize: 'var(--text-2xs)', fontWeight: 'var(--weight-semibold)', textDecoration: 'none', letterSpacing: 'var(--tracking-label)', textTransform: 'uppercase' }} className="jc-back">{backLabel}</a>
      ) : null}
      <nav aria-label="Primary" className="jc-nav" style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-6)', marginLeft: 'auto' }}>        {links.map((l) => (
          l.badge ? (
            <a key={l.label} href={l.href} className="jc-nav-feature">
              <img src={l.badge} alt="" />
              <span>{l.label}</span>
            </a>
          ) : l.logo ? (
            <a key={l.label} href={l.href} aria-label={l.label} title={l.label} style={{ display: 'flex', alignItems: 'center', color: 'inherit', textDecoration: 'none' }}>
              <img src={l.logo} alt="" style={{ height: '40px', width: 'auto', display: 'block' }} />
            </a>
          ) : (
            <a key={l.label} href={l.href} style={{ color: 'inherit', fontSize: 'var(--text-xs)', fontWeight: 'var(--weight-semibold)', textDecoration: 'none' }}>{l.label}</a>
          )
        ))}
      </nav>
      <div className="jc-head-actions" style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-3)', marginLeft: 'auto' }}>
        <LangPicker solid={solid} />
        {cta ? <Button variant="primary" size="sm" href={cta.href} onClick={cta.onClick}>{cta.label}</Button> : null}
      </div>
      </div>
    </header>
  );
}

/* Language picker. Flags are national symbols rendered as flat shapes; the control only
   records the choice — copy is not translated yet. */
const JC_LANGS = [
  { code: 'en', label: 'English', flag: 'us' },
  { code: 'pt', label: 'Português', flag: 'br' },
  { code: 'es', label: 'Español', flag: 'mx' }
];

function Flag({ kind }) {
  if (kind === 'br') {
    return (
      <svg width="22" height="16" viewBox="0 0 22 16" aria-hidden="true" style={{ display: 'block', borderRadius: '2px' }}>
        <rect width="22" height="16" fill="#11934A" /><path d="M11 2 20 8l-9 6L2 8z" fill="#FFC629" /><circle cx="11" cy="8" r="3.4" fill="#0C365D" />
      </svg>
    );
  }
  if (kind === 'mx') {
    return (
      <svg width="22" height="16" viewBox="0 0 22 16" aria-hidden="true" style={{ display: 'block', borderRadius: '2px' }}>
        <rect width="22" height="16" fill="#F6F3EC" /><rect width="7.33" height="16" fill="#11934A" /><rect x="14.67" width="7.33" height="16" fill="#C8352B" /><circle cx="11" cy="8" r="2.2" fill="none" stroke="#8A6A2F" strokeWidth="1" />
      </svg>
    );
  }
  return (
    <svg width="22" height="16" viewBox="0 0 22 16" aria-hidden="true" style={{ display: 'block', borderRadius: '2px' }}>
      <rect width="22" height="16" fill="#F6F3EC" />
      <g fill="#C8352B"><rect y="0" width="22" height="1.6" /><rect y="3.2" width="22" height="1.6" /><rect y="6.4" width="22" height="1.6" /><rect y="9.6" width="22" height="1.6" /><rect y="12.8" width="22" height="1.6" /></g>
      <rect width="10" height="8.8" fill="#2D5EAB" />
    </svg>
  );
}

function LangPicker({ solid }) {
  const [open, setOpen] = React.useState(false);
  const [code, setCode] = React.useState(() => {
    try { return window.localStorage.getItem('jcLang') || 'en'; } catch (e) { return 'en'; }
  });
  const boxRef = React.useRef(null);
  React.useEffect(() => {
    if (!open) return;
    const onDoc = (e) => { if (boxRef.current && !boxRef.current.contains(e.target)) setOpen(false); };
    const onKey = (e) => { if (e.key === 'Escape') setOpen(false); };
    document.addEventListener('mousedown', onDoc);
    document.addEventListener('keydown', onKey);
    return () => { document.removeEventListener('mousedown', onDoc); document.removeEventListener('keydown', onKey); };
  }, [open]);
  const pick = (c) => {
    setCode(c);
    setOpen(false);
    try { window.localStorage.setItem('jcLang', c); } catch (e) {}
    document.documentElement.setAttribute('lang', c);
  };
  const current = JC_LANGS.find((l) => l.code === code) || JC_LANGS[0];
  return (
    <div className={'jc-lang' + (solid ? ' is-solid' : '')} ref={boxRef}>
      <button type="button" className="jc-lang-btn" aria-haspopup="listbox" aria-expanded={open} aria-label={'Language: ' + current.label} onClick={() => setOpen((o) => !o)}>
        <Flag kind={current.flag} />
        <span aria-hidden="true" className="jc-lang-caret">{open ? '▲' : '▼'}</span>
      </button>
      {open ? (
        <ul className="jc-lang-menu" role="listbox">
          {JC_LANGS.map((l) => (
            <li key={l.code} role="option" aria-selected={l.code === code}>
              <button type="button" onClick={() => pick(l.code)}>
                <Flag kind={l.flag} />
                <span>{l.label}</span>
                {l.code === code ? <em aria-hidden="true">&#10003;</em> : null}
              </button>
            </li>
          ))}
        </ul>
      ) : null}
    </div>
  );
}

/* Mobile: design-system MobileNav for the menu, plus a compact sticky action.
   The sticky bar never covers content — the page reserves space for it. */
function MobileBar({ links, action }) {
  return <div className="jc-mobile-nav"><MobileNav links={links} action={action} solid /></div>;
}

function StickyAction({ primary, secondary }) {
  return (
    <div className="jc-sticky" style={{
      position: 'fixed', left: 0, right: 0, bottom: 0, zIndex: 28, display: 'none', gap: '10px',
      padding: '10px var(--gutter-mobile) calc(10px + env(safe-area-inset-bottom))',
      background: 'rgba(242,240,230,.96)', backdropFilter: 'blur(12px)',
      borderTop: 'var(--border-hairline) solid var(--line)'
    }}>
      <Button variant="primary" size="sm" fullWidth href={primary.href} onClick={primary.onClick}>{primary.label}</Button>
      {secondary ? <Button variant="secondary" size="sm" fullWidth href={secondary.href}>{secondary.label}</Button> : null}
    </div>
  );
}

/* Sticky WhatsApp bubble: present on every page, opens WhatsApp with the page's message
   pre-filled. The number lives in the shared contact record. */
function WhatsAppBubble({ message, page }) {
  const num = (window.JC.RECORD.contact.whatsappNumberE164 || '').replace(/[^0-9]/g, '');
  if (!num) return null;
  const href = 'https://wa.me/' + num + '?text=' + encodeURIComponent(message);
  return (
    <a className="jc-wa-bubble" href={href} target="_blank" rel="noopener" aria-label="Message Julio On WhatsApp" title="Quick Question For Julio" data-tip="Quick Question For Julio"
      onClick={() => window.JC.track('contact_whatsapp_click', { page: page, placement: 'bubble' })}>
      <Glyph name="whatsapp" size={28} />
    </a>
  );
}

/* Honest unavailable-contact state: the number has not been supplied, so the action
   explains itself and hands over the exact message instead of failing silently. */
function ContactDialog({ text, onClose }) {
  const boxRef = React.useRef(null);
  const [copied, setCopied] = React.useState(false);
  React.useEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    document.addEventListener('keydown', onKey);
    if (boxRef.current) boxRef.current.focus();
    return () => document.removeEventListener('keydown', onKey);
  }, [onClose]);
  if (!text) return null;
  return (
    <div role="dialog" aria-modal="true" aria-label="WhatsApp number required"
      onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}
      style={{ position: 'fixed', inset: 0, zIndex: 60, display: 'grid', placeItems: 'center', padding: 'var(--space-6)', background: 'rgba(17,17,17,.6)' }}>
      <div ref={boxRef} tabIndex={-1} style={{ ...jcLayout.panel, maxWidth: '520px', outline: 'none' }}>
        <h3 style={jcLayout.display('sm')}>WhatsApp number required</h3>
        <p style={{ margin: '12px 0 0', fontSize: 'var(--text-sm)', color: 'var(--text-muted)' }}>
          Julio's public WhatsApp number has not been supplied, so this action cannot open a conversation yet. This is the message it will send once the number is added to the contact record.
        </p>
        <p style={{ margin: 'var(--space-5) 0', padding: 'var(--space-5)', background: 'var(--copacabana-soft)', borderRadius: 'var(--radius-sm)', fontSize: 'var(--text-sm)', whiteSpace: 'pre-wrap' }}>{text}</p>
        <div style={jcLayout.row}>
          <Button variant="secondary" size="sm" arrow={false} onClick={() => { if (navigator.clipboard) navigator.clipboard.writeText(text); setCopied(true); }}>{copied ? 'Message copied' : 'Copy message'}</Button>
          <Button variant="tertiary" size="sm" arrow={false} onClick={onClose}>Close</Button>
        </div>
      </div>
    </div>
  );
}

/* Supplied brand icons from uploads/Brand/Icons, path data verbatim. Stroke is switched to
   currentColor so the mark takes its color from the design-system token, not the file's hex. */
function Glyph({ name, size }) {
  const paths = {
    plane: <><path d="M17.8 19.2 16 11l3.5-3.5a2.5 2.5 0 1 0-3.5-3.5L12.5 7.5 4.2 5.7a1 1 0 0 0-.9 1.7l6.2 4.4-2.1 3.1H4.3a1 1 0 0 0-.7 1.7l2.4 2.4a1 1 0 0 0 1.7-.7v-3.1l3.1-2.1 4.4 6.2a1 1 0 0 0 1.7-.9z" /></>,
    van: <><path d="M2 17h1.5" /><path d="M8.5 17h7" /><path d="M20.5 17H22" /><path d="M3 17V7a1 1 0 0 1 1-1h9l4 4h3a1 1 0 0 1 1 1v6" /><circle cx="6" cy="18" r="2" /><circle cx="18" cy="18" r="2" /></>,
    bed: <><path d="M2 20v-8h20v8" /><path d="M2 12V6" /><path d="M6 12V9h5v3" /><path d="M22 20H2" /></>,
    coffee: <><path d="M4 8h13v5a5 5 0 0 1-5 5H9a5 5 0 0 1-5-5z" /><path d="M17 9h2a2.5 2.5 0 0 1 0 5h-2" /><path d="M6 3.5c0 .8.8 1.2.8 2M10 3.5c0 .8.8 1.2.8 2M14 3.5c0 .8.8 1.2.8 2" /></>,
    meal: <><path d="M6 3v8a2 2 0 0 0 4 0V3" /><path d="M8 11v10" /><path d="M16 21V3c2 .6 3.5 2.6 3.5 5.2S18 12.8 16 13" /></>,
    stadium: <><path d="M4 9v9h16V9" /><path d="M2 9c0-1.7 4.5-3 10-3s10 1.3 10 3-4.5 3-10 3S2 10.7 2 9z" /><path d="M9 12.5V18" /><path d="M15 12.5V18" /></>,
    mountain: <><path d="m3 20 6.5-11 4 6.5 2-3L21 20z" /><path d="M9.5 9 12 5l2.5 4" /></>,
    landmark: <><path d="M12 3v4" /><path d="M8 7h8" /><path d="M12 7v13" /><path d="M5 20h14" /><path d="M9 11c-1.6.7-2.6 2-3 3.6M15 11c1.6.7 2.6 2 3 3.6" /></>,
    clock: <><circle cx="12" cy="12" r="9" /><path d="M12 7v5l3.5 2" /></>,
    waves: <><path d="M2 8c1.6 0 2.4-1.5 4-1.5S8.4 8 10 8s2.4-1.5 4-1.5S16.4 8 18 8s2.4-1.5 4-1.5" /><path d="M2 13c1.6 0 2.4-1.5 4-1.5S8.4 13 10 13s2.4-1.5 4-1.5S16.4 13 18 13s2.4-1.5 4-1.5" /><path d="M2 18c1.6 0 2.4-1.5 4-1.5S8.4 18 10 18s2.4-1.5 4-1.5S16.4 18 18 18s2.4-1.5 4-1.5" /></>,
    shopping: <><path d="M5 8h14l-1.2 12H6.2z" /><path d="M9 8V6a3 3 0 0 1 6 0v2" /></>,
    luggage: <><rect x="5" y="7" width="14" height="13" rx="2" /><path d="M9 7V4h6v3" /><path d="M12 11v5" /></>,
    calendar: <><path d="M8 2v3" /><path d="M16 2v3" /><rect x="3" y="3" width="18" height="18" rx="2" /><path d="M3 9h18" /><path d="M8 13h.01" /><path d="M12 13h.01" /><path d="M16 13h.01" /><path d="M8 17h.01" /><path d="M12 17h.01" /><path d="M16 17h.01" /></>,
    family: <><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" /><path d="M16 3.128a4 4 0 0 1 0 7.744" /><path d="M22 21v-2a4 4 0 0 0-3-3.87" /><circle cx="9" cy="7" r="4" /></>,
    whatsapp: <path d="M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719" />,
    training: <><path d="M17.596 12.768a2 2 0 1 0 2.829-2.829l-1.768-1.767a2 2 0 0 0 2.828-2.829l-2.828-2.828a2 2 0 0 0-2.829 2.828l-1.767-1.768a2 2 0 1 0-2.829 2.829z" /><path d="m2.5 21.5 1.4-1.4" /><path d="m20.1 3.9 1.4-1.4" /><path d="M5.343 21.485a2 2 0 1 0 2.829-2.828l1.767 1.768a2 2 0 1 0 2.829-2.829l-6.364-6.364a2 2 0 1 0-2.829 2.829l1.768 1.767a2 2 0 0 0-2.828 2.829z" /><path d="m9.6 14.4 4.8-4.8" /></>,
    futsal: <><path d="M10.1 2.18a9.93 9.93 0 0 1 3.8 0" /><path d="M17.6 3.71a9.95 9.95 0 0 1 2.69 2.7" /><path d="M21.82 10.1a9.93 9.93 0 0 1 0 3.8" /><path d="M20.29 17.6a9.95 9.95 0 0 1-2.7 2.69" /><path d="M13.9 21.82a9.94 9.94 0 0 1-3.8 0" /><path d="M6.4 20.29a9.95 9.95 0 0 1-2.69-2.7" /><path d="M2.18 13.9a9.93 9.93 0 0 1 0-3.8" /><path d="M3.71 6.4a9.95 9.95 0 0 1 2.7-2.69" /><circle cx="12" cy="12" r="1" /></>,
    'player-fit': <path d="M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2" />,
    /* Whistle and soccer ball drawn to match the supplied icons' geometry; the athlete is the
       client-supplied 16×16 running-player mark, path data verbatim. */
    whistle: <><path d="M13.5 10.5H21a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1h-7.5" /><path d="M9 6.5V5h5.5" /><circle cx="8.5" cy="13.5" r="5.5" /><circle cx="8.5" cy="13.5" r="1.5" /></>,
    ball: <><circle cx="12" cy="12" r="9" /><path d="M12 7.5 8.6 10l1.3 4h4.2l1.3-4z" /><path d="M12 3v4.5M4.1 9.4 8.6 10M19.9 9.4 15.4 10M7.2 20.2l2.7-6.2M16.8 20.2l-2.9-6.2" /></>,
    player: <><circle cx="12" cy="5" r="1" /><path d="m9 20 3-6 3 6" /><path d="m6 8 6 2 6-2" /><path d="M12 10v4" /></>
  };
  /* Filled marks carry their own viewBox and use fill rather than stroke. */
  const filled = {
    whatsapp: {
      viewBox: '0 0 24 24',
      body: <path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.347-.347.52-.52.174-.174.232-.298.347-.497.116-.198.058-.371-.03-.52-.087-.148-.66-1.594-.905-2.183-.233-.583-.47-.5-.65-.51-.174-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 0 1-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 0 1-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 0 1 2.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0 0 12.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 0 0 5.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 0 0-3.48-8.413z" />
    },
    athlete: {
      viewBox: '0 0 16 16',
      body: <>
        <path d="M8.5 15C9.05228 15 9.5 14.5523 9.5 14C9.5 13.4477 9.05228 13 8.5 13C7.94772 13 7.5 13.4477 7.5 14C7.5 14.5523 7.94772 15 8.5 15Z" />
        <path d="M4 10.293L6.793 7.5L7.5 8.207L4.707 11L4 10.293Z" />
        <path d="M14 8.292L9.707 4H3V5H9.293L10.793 6.5L3 14.293L3.707 15L11.5 7.2075L13.292 9L11.5 10.793L12.207 11.5L14 9.708C14.1876 9.52013 14.293 9.26549 14.293 9C14.293 8.73451 14.1876 8.47987 14 8.292ZM12.25 4.5C11.9039 4.5 11.5655 4.39737 11.2778 4.20507C10.99 4.01278 10.7657 3.73947 10.6332 3.4197C10.5008 3.09993 10.4661 2.74806 10.5336 2.40859C10.6011 2.06913 10.7678 1.75731 11.0126 1.51256C11.2573 1.26782 11.5691 1.10115 11.9086 1.03363C12.2481 0.966102 12.5999 1.00076 12.9197 1.13321C13.2395 1.26566 13.5128 1.48997 13.7051 1.77775C13.8974 2.06554 14 2.40388 14 2.75C13.9995 3.21397 13.8149 3.65878 13.4869 3.98685C13.1588 4.31493 12.714 4.49947 12.25 4.5ZM12.25 2C12.1017 2 11.9567 2.04399 11.8333 2.1264C11.71 2.20881 11.6139 2.32594 11.5571 2.46299C11.5003 2.60003 11.4855 2.75083 11.5144 2.89632C11.5433 3.0418 11.6148 3.17544 11.7197 3.28033C11.8246 3.38522 11.9582 3.45665 12.1037 3.48559C12.2492 3.51453 12.4 3.49968 12.537 3.44291C12.6741 3.38614 12.7912 3.29002 12.8736 3.16668C12.956 3.04334 13 2.89834 13 2.75C13 2.55109 12.921 2.36032 12.7803 2.21967C12.6397 2.07902 12.4489 2 12.25 2Z" />
      </>
    }
  };
  if (filled[name]) {
    return (
      <svg width={size || 20} height={size || 20} viewBox={filled[name].viewBox} fill="currentColor" aria-hidden="true" style={{ flex: 'none' }}>
        {filled[name].body}
      </svg>
    );
  }
  return (
    <svg width={size || 20} height={size || 20} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" style={{ flex: 'none' }}>
      {paths[name]}
    </svg>
  );
}

/* Featured opportunity: operational UI driven by the shared record. Renders nothing at all
   when disabled, expired or incomplete — no reserved height, no automatic substitute. */
function OpportunityPanel({ page, onWhatsApp, formHref, inline, image }) {
  const o = window.JC.RECORD.featuredOpportunity;
  const valid = window.JC.opportunityIsValid(o);
  React.useEffect(() => {
    if (valid) window.JC.track('opportunity_engagement', { opportunity_id: o.id, program: o.programId, status: o.statusLabel, action: 'view' });
  }, [valid]);
  if (!valid) return null;
  const cta = (
    <Button variant={inline ? 'secondary' : 'primary'} size="sm" href={formHref || '#start'} onClick={() => {
      window.JC.track('opportunity_engagement', { opportunity_id: o.id, program: o.programId, status: o.statusLabel, action: 'cta_click' });
    }}>{o.ctaLabel}</Button>
  );

  /* Compact form: a thumbnail beside two metadata rows, sized to sit inside the hero column. */
  if (inline) {
    return (
      <section aria-label="Featured opportunity" className="jc-opp jc-opp-inline">
        {image ? <img src={image} alt="" className="jc-opp-thumb" /> : null}
        <div className="jc-opp-body">
          <p style={{ ...jcLayout.label, margin: 0, fontSize: 'var(--text-3xs)' }}>Upcoming camp</p>
          <p style={{ margin: '4px 0 0', fontFamily: 'var(--font-display)', fontSize: 'var(--text-base)', fontWeight: 'var(--weight-bold)', letterSpacing: 'var(--tracking-display)', lineHeight: 1.2 }}>
            {o.identity} {o.dateOrSeason}
          </p>
          <p style={{ margin: '6px 0 0', fontFamily: 'var(--font-body)', fontSize: 'var(--text-3xs)', fontWeight: 'var(--weight-bold)', textTransform: 'uppercase', letterSpacing: 'var(--tracking-label)', color: 'var(--copacabana)' }}>{o.message}</p>
          <p style={{ display: 'flex', alignItems: 'center', gap: '8px', margin: '8px 0 0', fontSize: 'var(--text-2xs)', color: 'var(--text-muted)' }}><Glyph name="calendar" size={15} />{o.timing}</p>
          <p style={{ display: 'flex', alignItems: 'center', gap: '8px', margin: '4px 0 0', fontSize: 'var(--text-2xs)', color: 'var(--text-muted)' }}><Glyph name="family" size={15} />{o.fit}</p>
          <div style={{ marginTop: 'var(--space-4)' }}>{cta}</div>
        </div>
      </section>
    );
  }

  return (
    <section aria-label="Featured opportunity" className="jc-opp" style={{ width: 'min(var(--max-width), calc(100% - 56px))', margin: '-72px auto 0', position: 'relative', zIndex: 6 }}>
      <div style={{ ...jcLayout.panel, borderTop: 'var(--border-mark) solid var(--sol)', display: 'grid', gap: 'var(--space-8)', alignItems: 'center' }} className="jc-opp-grid">
        <div>
          <p style={{ ...jcLayout.label, margin: 0 }}>Upcoming camp</p>
          <p style={{ ...jcLayout.display('md'), margin: '10px 0 0' }}>{o.identity} {o.dateOrSeason} <span style={{ color: 'var(--copacabana)' }}>{o.message}</span></p>
        </div>
        <div style={{ display: 'grid', gap: 'var(--space-3)', alignContent: 'center' }}>
          <p style={{ display: 'flex', alignItems: 'center', gap: '10px', margin: 0, fontSize: 'var(--text-sm)' }}><Glyph name="calendar" />{o.timing}</p>
          <p style={{ display: 'flex', alignItems: 'center', gap: '10px', margin: 0, fontSize: 'var(--text-sm)' }}><Glyph name="family" />{o.fit}</p>
        </div>
        <div style={{ display: 'grid', gap: '10px', alignContent: 'center', justifyItems: 'start', minWidth: '200px' }}>{cta}</div>
      </div>
    </section>
  );
}

/* Email-first inquiry form. WhatsApp remains available separately as a subtle page action. */
const JC_INTEREST_OPTIONS = ['Camps & Clinics', 'Private or Small-Group Training', 'Team Training', 'JC Brasil Tour', 'College Team Experience', 'Not Sure Yet'];

function InquiryPanel({ id, page, program, title, note, interestOptions, defaultInterest, showUpdatesOptIn, onWhatsApp, submitLabel, successText, interestLabel, phoneRequired, emailRequired = true, ageLabel, updatesLabel }) {
  const [values, setValues] = React.useState({ interest: defaultInterest || '', name: '', phone: '', age: '', level: '', email: '', message: '', consent: false, updates: false });
  const [errors, setErrors] = React.useState({});
  /* CTAs elsewhere on the page can preselect the interest via a custom event. */
  React.useEffect(() => {
    const onPick = (e) => setValues((v) => ({ ...v, interest: e.detail }));
    window.addEventListener('jc:interest', onPick);
    return () => window.removeEventListener('jc:interest', onPick);
  }, []);
  const [status, setStatus] = React.useState(null);
  const set = (k) => (e) => {
    const v = e.target.type === 'checkbox' ? e.target.checked : e.target.value;
    setValues((s) => Object.assign({}, s, { [k]: v }));
    setErrors((s) => Object.assign({}, s, { [k]: null }));
  };
  function submit(path) {
    const next = {};
    if (!values.interest) next.interest = 'Choose the program you are asking about.';
    if (!values.name.trim()) next.name = 'Enter the parent, guardian, or coach name.';
    if (emailRequired && !values.email.trim()) next.email = 'Enter an adult email address so Julio can reply.';
    if (phoneRequired && !values.phone.trim()) next.phone = 'Enter a phone number Julio can reach you on.';
    if (!values.age.trim()) next.age = 'Enter the player age or team age group.';
    if (!values.consent) next.consent = 'Consent is required before Julio can reply.';
    setErrors(next);
    if (Object.keys(next).length) {
      setStatus({ kind: 'error', text: 'Some required details are missing. Check the highlighted fields.' });
      window.JC.track('inquiry_submit', { page, interest: values.interest, submission_path: path, result: 'validation_error' });
      return;
    }
    const destination = window.JC.RECORD.contact.formDestination;
    if (!destination) {
      setStatus({ kind: 'unavailable', text: 'Form destination not configured. Your details are kept on this page \u2014 the developer must connect the destination before launch.' });
      window.JC.track('inquiry_submit', { page, interest: values.interest, submission_path: path, result: 'destination_unavailable' });
    } else if (destination.indexOf('mailto:') === 0) {
      const subject = 'Website inquiry: ' + values.interest;
      const body = [
        'Adult contact: ' + values.name,
        'Phone: ' + values.phone,
        'Email: ' + (values.email || 'Not provided'),
        'Player age or team age group: ' + values.age,
        'Current level: ' + (values.level || 'Not provided'),
        'Interest: ' + values.interest,
        'Updates requested: ' + (values.updates ? 'Yes' : 'No'),
        '',
        values.message || 'No additional message.'
      ].join('\n');
      window.location.href = destination + '?subject=' + encodeURIComponent(subject) + '&body=' + encodeURIComponent(body);
      setStatus({ kind: 'success', text: 'Your email app has opened with the inquiry ready to send to Julio.' });
      window.JC.track('inquiry_submit', { page, interest: values.interest, submission_path: 'email', result: 'email_opened' });
    } else {
      setStatus({ kind: 'success', text: successText || 'Thanks. Your inquiry has been emailed to Julio. He will use the contact details you provided to follow up.' });
      window.JC.track('inquiry_submit', { page, interest: values.interest, submission_path: path, result: 'success' });
    }
    if (path === 'form_then_whatsapp' && onWhatsApp) onWhatsApp({ program, placement: 'form', page, extra: window.JC.enrichedMessage(values) });
  }
  const statusTone = { success: 'var(--copacabana-soft)', unavailable: 'rgba(255,198,41,.28)', error: 'rgba(17,17,17,.06)' };
  return (
    <form id={id} noValidate onSubmit={(e) => { e.preventDefault(); submit('form'); }} style={{ ...jcLayout.panel, color: 'var(--charcoal)', display: 'grid', gap: 'var(--space-5)' }}>
      <div>
        <h3 style={jcLayout.display('sm')}>{title}</h3>
        <p style={{ margin: '8px 0 0', fontSize: 'var(--text-sm)', color: 'var(--text-muted)' }}>{note}</p>
      </div>
      {status ? (
        <p role="status" aria-live="polite" style={{ margin: 0, padding: 'var(--space-5)', background: statusTone[status.kind], borderRadius: 'var(--radius-sm)', fontSize: 'var(--text-sm)', fontWeight: 'var(--weight-semibold)' }}>{status.text}</p>
      ) : null}
      <div className="jc-form-grid">
        <label className="jc-fld jc-fld-wide">
          <span><b>*</b> {interestLabel || 'Interest'}</span>
          <select name="interest" value={values.interest} onChange={set('interest')}>
            <option value="">Select the program</option>
            {(interestOptions || JC_INTEREST_OPTIONS).map((o) => <option key={o} value={o}>{o}</option>)}
          </select>
          {errors.interest ? <em>{errors.interest}</em> : null}
        </label>
        <label className="jc-fld">
          <span><b>*</b> {phoneRequired ? 'Adult or coach name' : 'Adult contact name'}</span>
          <input name="name" autoComplete="name" value={values.name} onChange={set('name')} />
          {errors.name ? <em>{errors.name}</em> : null}
        </label>
        <label className="jc-fld">
          <span>{phoneRequired ? <b>*</b> : null} {phoneRequired ? 'Phone' : 'Phone'}</span>
          <input name="phone" type="tel" autoComplete="tel" value={values.phone} onChange={set('phone')} />
          {errors.phone ? <em>{errors.phone}</em> : null}
        </label>
        <label className="jc-fld">
          <span>{emailRequired ? <b>*</b> : null} {emailRequired ? 'Email' : 'Email (recommended)'}</span>
          <input name="email" type="email" autoComplete="email" value={values.email} onChange={set('email')} />
          {errors.email ? <em>{errors.email}</em> : null}
        </label>
        <label className="jc-fld">
          <span><b>*</b> {ageLabel || 'Player age or team age group'}</span>
          <input name="age" value={values.age} onChange={set('age')} />
          {errors.age ? <em>{errors.age}</em> : null}
        </label>
        <label className="jc-fld jc-fld-wide">
          <span>Current level</span>
          <input name="level" value={values.level} onChange={set('level')} />
        </label>
        <label className="jc-fld jc-fld-wide">
          <span>What would you like Julio to know?</span>
          <textarea name="message" rows={3} value={values.message} onChange={set('message')}></textarea>
        </label>
      </div>
      <CheckboxField name="consent" checked={values.consent} onChange={set('consent')}
        label="I am an adult and I agree to be contacted about this inquiry. I have read the privacy notice."
        hint={errors.consent || undefined} />
      {showUpdatesOptIn ? <CheckboxField name="updates" checked={values.updates} onChange={set('updates')} label={updatesLabel || 'Optional: email me Summer 2027 updates.'} /> : null}
      <Button type="submit" variant="primary" style={{ width: '100%', justifyContent: 'center' }}>{submitLabel || 'Send My Inquiry'}</Button>
      <p style={{ margin: 0, padding: 'var(--space-5)', background: 'var(--areia-warm)', borderRadius: 'var(--radius-sm)', fontSize: 'var(--text-2xs)', lineHeight: 'var(--leading-body)' }}>
        Use an adult's contact information. Do not send passport, medical, or payment information through this form.
      </p>
    </form>
  );
}

/* Gallery lightbox — keyboard navigable, focus trapped, no auto-rotation. */
function Lightbox({ items, index, onClose, onMove }) {
  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="Gallery image"
      onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}
      style={{ position: 'fixed', inset: 0, zIndex: 60, display: 'grid', placeItems: 'center', padding: '56px 24px', background: 'rgba(17,17,17,.96)' }}>
      <figure style={{ margin: 0, maxWidth: '1080px' }}>
        <img src={item.src} alt={item.alt} style={{ maxHeight: '76vh', width: 'auto', margin: '0 auto', borderRadius: 'var(--radius)' }} />
        <figcaption style={{ display: 'flex', flexWrap: 'wrap', gap: 'var(--space-5)', justifyContent: 'space-between', marginTop: 'var(--space-4)', color: 'var(--paper-80)', fontSize: 'var(--text-2xs)' }}>
          <span style={{ color: 'var(--white)', fontWeight: 'var(--weight-semibold)', textTransform: 'uppercase', letterSpacing: 'var(--tracking-label)' }}>{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 style={{ position: 'absolute', top: '16px', right: '16px', color: 'var(--white)' }}>
        <button ref={closeRef} type="button" onClick={onClose} aria-label="Close gallery" style={jcLightboxCtl}>&times;</button>
      </div>
      <div style={{ position: 'absolute', left: '16px', right: '16px', top: '50%', display: 'flex', justifyContent: 'space-between', transform: 'translateY(-50%)', pointerEvents: 'none' }}>
        <button type="button" onClick={() => onMove(-1)} aria-label="Previous image" style={{ ...jcLightboxCtl, pointerEvents: 'auto' }}>&#8249;</button>
        <button type="button" onClick={() => onMove(1)} aria-label="Next image" style={{ ...jcLightboxCtl, pointerEvents: 'auto' }}>&#8250;</button>
      </div>
    </div>
  );
}
const jcLightboxCtl = { minWidth: '44px', minHeight: '44px', border: 'var(--border-control) solid var(--paper-24)', borderRadius: 'var(--radius-pill)', background: 'rgba(246,243,236,.08)', color: 'var(--white)', fontSize: '20px', cursor: 'pointer' };

/* Wave-capped band closing a media or dark section. */
function WaveCap({ color, flip, height, paused }) {
  return <WaveField variant="band" color={color || 'areia'} flip={flip} height={height || 120} drift={!paused} />;
}

/* Black closing footer: full-bleed ink field with the players-outline artwork,
   content held to the page max width. */
function PageFooter({ tagline, cta, links, note }) {
  const insta = (window.JC && window.JC.RECORD.brand.instagramUrl) || '#';
  return (
    <footer className="jc-footer">
      <div className="jc-footer-inner">
        <div className="jc-footer-left">
          <p className="jc-footer-tagline">Become a more complete player.</p>
          <p className="jc-footer-hair">Player development, camps &amp; team programs</p>
          {cta ? <Button variant="primary" href={cta.href}>{cta.label}</Button> : null}
          <div className="jc-footer-mark">
            <div className="jc-footer-lockups">
              <a href="/jc-soccer-camp/" className="jc-footer-logo"><Wordmark lockup="horizontalWhite" size="lg" /></a>
              <a href="/jc-soccer-camp/brasil-tour/" className="jc-footer-crest"><img src="/jc-soccer-camp/assets/brand/jc-brasil-tour-crest.png" alt="JC Brasil Tour" /></a>
            </div>
            <div className="jc-footer-social">
              <a href={insta} target="_blank" rel="noopener">Instagram</a>
              <span aria-hidden="true">|</span>
              <a href="#privacy">Privacy</a>
              <span aria-hidden="true">|</span>
              <a href="#terms">Terms</a>
            </div>
          </div>
        </div>
        <nav className="jc-footer-nav" aria-label="Footer">
          <p className="jc-footer-navhead">Pages</p>
          {links.map((l) => (
            l.badge
              ? <a key={l.label} href={l.href} className="jc-footer-feature"><img src={l.badge} alt="" /><span>{l.label}</span></a>
              : <a key={l.label} href={l.href}>{l.label}</a>
          ))}
        </nav>
      </div>
      <div className="jc-footer-note">
        <span>&copy; 2026 SSA Brasil LLC. All rights reserved.</span>
        <span>Made by <a href="https://taurist.com/siteworks" target="_blank" rel="noopener">Siteworks</a></span>
      </div>
    </footer>
  );
}

Object.assign(window, { PageFooter, DS, jcLayout, ApprovalNote, Glyph, WhatsAppLabel, WhatsAppBubble, SectionHead, useMotionToggle, useSolidHeader, PageHeader, MobileBar, StickyAction, ContactDialog, OpportunityPanel, InquiryPanel, Lightbox, WaveCap, JC_INTEREST_OPTIONS });
