/* ═══════════════════════════════════════════════════════════════════════════
   PARTICIPA — page bundle.
   Loads after shared/components/{Nav,Footer,TweaksPanel}.jsx.

   ┌─────────────────────────────────────────────────────────────────────────┐
   │  CMS / HEADLESS INTEGRATION                                               │
   │  · Membership fees (quotes) are brand copy in code by decision ADR-06 D1. │
   │  · Membership / contact / private-area forms → POST endpoints (see each,  │
   │    GO-LIVE(F2)).                                                          │
   └─────────────────────────────────────────────────────────────────────────┘
   ═══════════════════════════════════════════════════════════════════════════ */

const { useState, useEffect, useRef } = React;

const EsbartNav = window.EsbartNav;
const EsbartFooter = window.EsbartFooter;
const EsbartTweaksPanel = window.EsbartTweaksPanel;

const ESBART_TWEAKS = /*EDITMODE-BEGIN*/{
  "accentHue": 350,
  "typeScale": 1
}/*EDITMODE-END*/;
window.ESBART_TWEAKS = ESBART_TWEAKS;

/* CMS data layer: shared/cms-data.js (window.EsbartData, ADR-06 D3). */

function Silhouette({ src }) {
  const ref = useRef(null);
  useEffect(() => {
    let cancelled = false;
    fetch(src).then((r) => r.text()).then((txt) => {
      if (cancelled || !ref.current) return;
      ref.current.innerHTML = txt;
      const svg = ref.current.querySelector("svg");
      if (svg) { svg.setAttribute("preserveAspectRatio", "xMidYMid meet"); svg.setAttribute("aria-hidden", "true"); }
    }).catch(() => {});
    return () => { cancelled = true; };
  }, [src]);
  return <div ref={ref} className="pk-silhouette" aria-hidden="true"></div>;
}

const Check = () => (
  <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4"><path d="M20 6 9 17l-5-5" /></svg>
);

/* ═══════════════════════════════════════════════════════════════════════════
   STRINGS — CA / ES / EN
   `quotes` array is the CMS seed/fallback: { id, name, price, audience }
   ═══════════════════════════════════════════════════════════════════════════ */
const PART_CA = {
  pageTitle: "Participa · Esbart Català de Dansaires",
  heroEyebrow: "Fes-te soci · Voluntariat · Donacions · Contacte",
  heroTitle: ["Forma part de la ", "nostra història"],
  heroLead: "L'Esbart és una entitat sense ànim de lucre que viu de la implicació de les persones. Hi ha moltes maneres de sumar-t'hi: fes-te soci, col·labora com a voluntari o dona suport al projecte.",
  heroStats: [
    { num: "1908", label: "Una comunitat centenària" },
    { num: "4", label: "Vies de participació" },
    { num: "+115", label: "Anys preservant el patrimoni" },
  ],
  heroScroll: "Comença",

  // Fes-te soci
  sociEyebrow: "Fes-te soci",
  sociTitle: ["Per què ", "fer-se soci", "?"],
  sociSub: "En fer-te soci contribueixes a la preservació i difusió de la dansa tradicional catalana. L'entitat es finança amb les quotes dels socis, subvencions i els ingressos de les activitats.",
  benefits: [
    { h: "Participa en totes les activitats", b: "Assaigs del Cos de dansa, actuacions, Ball del divendres i Ballada del soci." },
    { h: "Accés al Centre de Documentació", b: "Arxiu, biblioteca especialitzada, videoteca, fonoteca i arxiu musical." },
    { h: "Descomptes i avantatges", b: "En publicacions, cursos i tallers, i preu reduït en activitats especials." },
    { h: "Veu i vot a l'entitat", b: "Participa a les assemblees, vota les decisions i rep el butlletí informatiu." },
  ],

  quotesEyebrow: "Tipus de quotes",
  quotesTitle: ["Tria la quota ", "que t'encaixi"],
  quotesPriceNote: "Import anual · consulta'l a secretaria",
  quotes: [
    { id: "general", name: "Quota general", price: "80 € l'any", audience: "Per a persones adultes amb ingressos regulars." },
    { id: "familiar", name: "Quota familiar", price: "A consultar", audience: "Si s'inscriu més d'un membre de la mateixa família." },
    { id: "suport", name: "Quota de suport", price: "Lliure", audience: "Per a qui vulgui col·laborar més enllà de la quota regular." },
  ],

  stepsEyebrow: "Com fer-se soci",
  stepsTitle: ["Tres passos ", "i ja hi ets"],
  steps: [
    { t: "Omple el formulari", b: "Dades personals i tipus de quota. Pots indicar els teus interessos: ballar, actuacions, formació, voluntariat o documentació." },
    { t: "Fes el pagament", b: "Per transferència, domiciliació bancària anual o presencialment a la seu de l'Esbart." },
    { t: "Confirmació", b: "Rebràs el número de soci, la credencial i la informació de les activitats i convocatòries properes." },
  ],
  sociBtn: "Sol·licita fer-te soci",

  faqEyebrow: "Preguntes freqüents",
  faqTitle: ["Encara tens ", "dubtes", "?"],
  faqs: [
    { q: "Puc fer-me soci si no vull ballar?", a: "Sí! Molts socis col·laboren sense participar en les activitats de dansa i gaudeixen del Centre de Documentació, les publicacions i els esdeveniments." },
    { q: "Puc deixar de ser soci quan vulgui?", a: "Sí, pots donar-te de baixa en qualsevol moment comunicant-ho per escrit a la secretaria de l'entitat." },
    { q: "La quota és anual?", a: "Sí, la quota és anual i es renova cada any." },
  ],

  // Vine a ballar link
  vineEyebrow: "Vols començar a ballar?",
  vineTitle: ["Vine a una ", "sessió de prova", " gratuïta"],
  vineBody: "Si el que vols és ballar, a «Vine a ballar!» hi trobaràs els horaris de tots els grups (adults, juvenils i infantils), on ballem, com començar i el repertori.",
  vineBtn: "Vine a ballar!",

  // Voluntariat
  volEyebrow: "Voluntariat i col·laboració",
  volTitle: ["Dona un cop de mà ", "a l'Esbart"],
  volSub: "L'Esbart es basa en la participació activa dels seus socis i col·laboradors. Tria l'àrea on et sentis més còmode.",
  volAreas: [
    { h: "Gestió i administració", b: "Suport a secretaria, gestió de socis, comunicació." },
    { h: "Centre de Documentació", b: "Catalogació de materials, digitalització de fons, atenció a consultes." },
    { h: "Activitats i esdeveniments", b: "Organització d'actes, muntatge d'exposicions, suport logístic." },
    { h: "Comunicació i difusió", b: "Fotografia i vídeo, xarxes socials, redacció, disseny gràfic." },
    { h: "Vestuari i atrezzo", b: "Manteniment del vestuari, confecció, reparació i magatzem." },
  ],
  volNote: "Contacta'ns indicant l'àrea d'interès, la teva disponibilitat i les habilitats rellevants.",
  volBtn: "Vull col·laborar",

  // Donacions
  donEyebrow: "Donacions",
  donTitle: ["Dona ", "suport", " sense fer-te soci"],
  donBody: "Si vols col·laborar econòmicament amb l'Esbart pots fer una donació puntual o periòdica per transferència. També acceptem donacions en espècie: material bibliogràfic, audiovisual, documentació històrica o vestuari tradicional.",
  donFiscalH: "Desgrava fiscalment",
  donFiscal: "Les donacions desgraven fiscalment segons la legislació vigent, ja que som una entitat declarada d'Interès Cultural per la Generalitat de Catalunya. Sol·licita el teu certificat de donació.",
  donBtn: "Fes una donació",

  // Contacte
  conEyebrow: "Contacte",
  conTitle: ["Parlem-ne", ""],
  conSub: "Escriu-nos i et respondrem el més aviat possible. Indica el motiu del contacte perquè el missatge arribi a la persona adequada.",
  conName: "Nom i cognoms",
  conEmail: "Correu electrònic",
  conPhone: "Telèfon",
  conReasonLabel: "Motiu del contacte",
  conReasons: ["Fer-me soci/a", "Informació sobre els grups de dansa", "Voluntariat", "Donació", "Centre de Documentació", "Contractar una actuació", "Cessió d'una exposició", "Altres consultes"],
  conPrefillCessio: (titol) => `Ens agradaria acollir l'exposició «${titol}». `,
  conMsg: "Missatge",
  conSend: "Envia el missatge",
  conSuccess: "Gràcies! Hem rebut el teu missatge i et respondrem ben aviat.",
  conError: "No s'ha pogut enviar el missatge. Torneu-ho a intentar.",
  conNote: "En enviar el formulari acceptes la nostra política de privacitat.",
  conInfoTitle: "Dades de contacte",
  conInfo: [
    { k: "Adreça", v: "La Casa dels Entremesos\nPlaça de les Beates, 2, 2n\n08003 Barcelona" },
    { k: "Email", v: "info@esbartcatala.org" },
    { k: "Danses Vives", v: "dansesvives@esbartcatala.org" },
    { k: "Telèfon", v: "93 412 51 11" },
  ],
  arriveTitle: "Com arribar",
  arrive: [
    { k: "Metro", v: "L4 (groga) Jaume I · L1 (vermella) Urquinaona, a 5–10 min a peu." },
    { k: "Bus", v: "Línies 45, 120, V15, V17 · parada Pla de Palau." },
    { k: "A peu", v: "A 10 min del Parc de la Ciutadella i 15 min de la Catedral, al cor de Ciutat Vella." },
  ],
  mapLabel: "Plaça de les Beates, 2 · Barcelona",

  // Àrea privada
};

const PART_ES = {
  pageTitle: "Participa · Esbart Català de Dansaires",
  heroEyebrow: "Hazte socio · Voluntariado · Donaciones · Contacto",
  heroTitle: ["Forma parte de ", "nuestra historia"],
  heroLead: "El Esbart es una entidad sin ánimo de lucro que vive de la implicación de las personas. Hay muchas maneras de sumarte: hazte socio, colabora como voluntario o apoya el proyecto.",
  heroStats: [
    { num: "1908", label: "Una comunidad centenaria" },
    { num: "4", label: "Vías de participación" },
    { num: "+115", label: "Años preservando el patrimonio" },
  ],
  heroScroll: "Empieza",
  sociEyebrow: "Hazte socio",
  sociTitle: ["¿Por qué ", "hacerse socio", "?"],
  sociSub: "Al hacerte socio contribuyes a la preservación y difusión de la danza tradicional catalana. La entidad se financia con las cuotas de los socios, subvenciones y los ingresos de las actividades.",
  benefits: [
    { h: "Participa en todas las actividades", b: "Ensayos del Cos de dansa, actuaciones, Ball del divendres y Ballada del soci." },
    { h: "Acceso al Centro de Documentación", b: "Archivo, biblioteca especializada, videoteca, fonoteca y archivo musical." },
    { h: "Descuentos y ventajas", b: "En publicaciones, cursos y talleres, y precio reducido en actividades especiales." },
    { h: "Voz y voto en la entidad", b: "Participa en las asambleas, vota las decisiones y recibe el boletín informativo." },
  ],
  quotesEyebrow: "Tipos de cuotas",
  quotesTitle: ["Elige la cuota ", "que te encaje"],
  quotesPriceNote: "Importe anual · consúltalo en secretaría",
  quotes: [
    { id: "general", name: "Cuota general", price: "80 € al año", audience: "Para personas adultas con ingresos regulares." },
    { id: "familiar", name: "Cuota familiar", price: "A consultar", audience: "Si se inscribe más de un miembro de la misma familia." },
    { id: "suport", name: "Cuota de apoyo", price: "Libre", audience: "Para quien quiera colaborar más allá de la cuota regular." },
  ],
  stepsEyebrow: "Cómo hacerse socio",
  stepsTitle: ["Tres pasos ", "y ya estás"],
  steps: [
    { t: "Rellena el formulario", b: "Datos personales y tipo de cuota. Puedes indicar tus intereses: bailar, actuaciones, formación, voluntariado o documentación." },
    { t: "Realiza el pago", b: "Por transferencia, domiciliación bancaria anual o presencialmente en la sede del Esbart." },
    { t: "Confirmación", b: "Recibirás el número de socio, la credencial y la información de las actividades y convocatorias próximas." },
  ],
  sociBtn: "Solicita hacerte socio",
  faqEyebrow: "Preguntas frecuentes",
  faqTitle: ["¿Aún tienes ", "dudas", "?"],
  faqs: [
    { q: "¿Puedo hacerme socio si no quiero bailar?", a: "¡Sí! Muchos socios colaboran sin participar en las actividades de danza y disfrutan del Centro de Documentación, las publicaciones y los eventos." },
    { q: "¿Puedo dejar de ser socio cuando quiera?", a: "Sí, puedes darte de baja en cualquier momento comunicándolo por escrito a la secretaría de la entidad." },
    { q: "¿La cuota es anual?", a: "Sí, la cuota es anual y se renueva cada año." },
  ],
  vineEyebrow: "¿Quieres empezar a bailar?",
  vineTitle: ["Ven a una ", "sesión de prueba", " gratuita"],
  vineBody: "Si lo que quieres es bailar, en «Vine a ballar!» encontrarás los horarios de todos los grupos (adultos, juveniles e infantiles), dónde bailamos, cómo empezar y el repertorio.",
  vineBtn: "¡Vine a ballar!",
  volEyebrow: "Voluntariado y colaboración",
  volTitle: ["Echa una mano ", "al Esbart"],
  volSub: "El Esbart se basa en la participación activa de sus socios y colaboradores. Elige el área donde te sientas más cómodo.",
  volAreas: [
    { h: "Gestión y administración", b: "Apoyo a secretaría, gestión de socios, comunicación." },
    { h: "Centro de Documentación", b: "Catalogación de materiales, digitalización de fondos, atención a consultas." },
    { h: "Actividades y eventos", b: "Organización de actos, montaje de exposiciones, apoyo logístico." },
    { h: "Comunicación y difusión", b: "Fotografía y vídeo, redes sociales, redacción, diseño gráfico." },
    { h: "Vestuario y atrezo", b: "Mantenimiento del vestuario, confección, reparación y almacén." },
  ],
  volNote: "Contáctanos indicando el área de interés, tu disponibilidad y las habilidades relevantes.",
  volBtn: "Quiero colaborar",
  donEyebrow: "Donaciones",
  donTitle: ["Da ", "apoyo", " sin hacerte socio"],
  donBody: "Si quieres colaborar económicamente con el Esbart puedes hacer una donación puntual o periódica por transferencia. También aceptamos donaciones en especie: material bibliográfico, audiovisual, documentación histórica o vestuario tradicional.",
  donFiscalH: "Desgrava fiscalmente",
  donFiscal: "Las donaciones desgravan fiscalmente según la legislación vigente, ya que somos una entidad declarada de Interés Cultural por la Generalitat de Catalunya. Solicita tu certificado de donación.",
  donBtn: "Haz una donación",
  conEyebrow: "Contacto",
  conTitle: ["Hablemos", ""],
  conSub: "Escríbenos y te responderemos lo antes posible. Indica el motivo del contacto para que el mensaje llegue a la persona adecuada.",
  conName: "Nombre y apellidos",
  conEmail: "Correo electrónico",
  conPhone: "Teléfono",
  conReasonLabel: "Motivo del contacto",
  conReasons: ["Hacerme socio/a", "Información sobre los grupos de danza", "Voluntariado", "Donación", "Centro de Documentación", "Contratar una actuación", "Cesión de una exposición", "Otras consultas"],
  conPrefillCessio: (titol) => `Nos gustaría acoger la exposición «${titol}». `,
  conMsg: "Mensaje",
  conSend: "Envía el mensaje",
  conSuccess: "¡Gracias! Hemos recibido tu mensaje y te responderemos muy pronto.",
  conError: "No se ha podido enviar el mensaje. Inténtalo de nuevo.",
  conNote: "Al enviar el formulario aceptas nuestra política de privacidad.",
  conInfoTitle: "Datos de contacto",
  conInfo: [
    { k: "Dirección", v: "La Casa dels Entremesos\nPlaça de les Beates, 2, 2º\n08003 Barcelona" },
    { k: "Email", v: "info@esbartcatala.org" },
    { k: "Danses Vives", v: "dansesvives@esbartcatala.org" },
    { k: "Teléfono", v: "93 412 51 11" },
  ],
  arriveTitle: "Cómo llegar",
  arrive: [
    { k: "Metro", v: "L4 (amarilla) Jaume I · L1 (roja) Urquinaona, a 5–10 min a pie." },
    { k: "Bus", v: "Líneas 45, 120, V15, V17 · parada Pla de Palau." },
    { k: "A pie", v: "A 10 min del Parc de la Ciutadella y 15 min de la Catedral, en el corazón de Ciutat Vella." },
  ],
  mapLabel: "Plaça de les Beates, 2 · Barcelona",
};

const PART_EN = {
  pageTitle: "Get Involved · Esbart Català de Dansaires",
  heroEyebrow: "Membership · Volunteering · Donations · Contact",
  heroTitle: ["Become part of ", "our story"],
  heroLead: "The Esbart is a non-profit that thrives on people's involvement. There are many ways to join in: become a member, volunteer, or support the project.",
  heroStats: [
    { num: "1908", label: "A century-old community" },
    { num: "4", label: "Ways to get involved" },
    { num: "+115", label: "Years preserving heritage" },
  ],
  heroScroll: "Start",
  sociEyebrow: "Become a member",
  sociTitle: ["Why ", "join", "?"],
  sociSub: "By becoming a member you help preserve and share Catalan traditional dance. The entity is funded by membership fees, grants and the income from its activities.",
  benefits: [
    { h: "Join every activity", b: "Cos de dansa rehearsals, performances, the Friday Dance and the members' dance." },
    { h: "Access to the Documentation Centre", b: "Archive, specialised library, video and sound libraries, and the music archive." },
    { h: "Discounts & perks", b: "On publications, courses and workshops, and reduced prices for special activities." },
    { h: "A voice and a vote", b: "Take part in assemblies, vote on decisions and receive the newsletter." },
  ],
  quotesEyebrow: "Membership fees",
  quotesTitle: ["Choose the fee ", "that fits you"],
  quotesPriceNote: "Annual fee · ask at the secretariat",
  quotes: [
    { id: "general", name: "Standard fee", price: "€80 a year", audience: "For adults with a regular income." },
    { id: "familiar", name: "Family fee", price: "On request", audience: "If more than one member of the same family joins." },
    { id: "suport", name: "Support fee", price: "Open", audience: "For those who wish to contribute beyond the standard fee." },
  ],
  stepsEyebrow: "How to join",
  stepsTitle: ["Three steps ", "and you're in"],
  steps: [
    { t: "Fill in the form", b: "Personal details and fee type. Tell us your interests: dancing, performances, training, volunteering or documentation." },
    { t: "Make the payment", b: "By transfer, annual direct debit, or in person at the Esbart's headquarters." },
    { t: "Confirmation", b: "You'll receive your membership number, credential and information about upcoming activities and events." },
  ],
  sociBtn: "Apply to become a member",
  faqEyebrow: "Frequently asked questions",
  faqTitle: ["Still have ", "questions", "?"],
  faqs: [
    { q: "Can I join even if I don't want to dance?", a: "Yes! Many members collaborate without taking part in the dance activities and enjoy the Documentation Centre, publications and events." },
    { q: "Can I stop being a member whenever I want?", a: "Yes, you can cancel at any time by writing to the entity's secretariat." },
    { q: "Is the fee annual?", a: "Yes, the fee is annual and renews each year." },
  ],
  vineEyebrow: "Want to start dancing?",
  vineTitle: ["Come to a free ", "trial session"],
  vineBody: "If you want to dance, «Vine a ballar!» has the schedules for every group (adults, youth and children), where we dance, how to start and the repertoire.",
  vineBtn: "Come and dance!",
  volEyebrow: "Volunteering & collaboration",
  volTitle: ["Lend the Esbart ", "a hand"],
  volSub: "The Esbart is built on the active participation of its members and collaborators. Choose the area you feel most at home in.",
  volAreas: [
    { h: "Management & admin", b: "Secretariat support, member management, communications." },
    { h: "Documentation Centre", b: "Cataloguing materials, digitising holdings, answering enquiries." },
    { h: "Activities & events", b: "Organising events, mounting exhibitions, logistical support." },
    { h: "Communication & outreach", b: "Photography and video, social media, writing, graphic design." },
    { h: "Costume & props", b: "Costume upkeep, making, repairs and storage." },
  ],
  volNote: "Get in touch telling us your area of interest, your availability and any relevant skills.",
  volBtn: "I want to help",
  donEyebrow: "Donations",
  donTitle: ["Show ", "support", " without joining"],
  donBody: "If you want to support the Esbart financially you can make a one-off or recurring donation by transfer. We also accept donations in kind: bibliographic and audiovisual material, historical documentation or traditional costume.",
  donFiscalH: "Tax-deductible",
  donFiscal: "Donations are tax-deductible under current law, as we are an entity declared of Cultural Interest by the Government of Catalonia. Request your donation certificate.",
  donBtn: "Make a donation",
  conEyebrow: "Contact",
  conTitle: ["Let's talk", ""],
  conSub: "Write to us and we'll reply as soon as possible. Tell us the reason for your message so it reaches the right person.",
  conName: "Full name",
  conEmail: "Email",
  conPhone: "Phone",
  conReasonLabel: "Reason for contact",
  conReasons: ["Becoming a member", "Information about the dance groups", "Volunteering", "Donation", "Documentation Centre", "Booking a performance", "Hosting an exhibition", "Other enquiries"],
  conPrefillCessio: (title) => `We would like to host the exhibition “${title}”. `,
  conMsg: "Message",
  conSend: "Send message",
  conSuccess: "Thank you! We've received your message and will reply very soon.",
  conError: "We couldn't send your message. Please try again.",
  conNote: "By submitting the form you accept our privacy policy.",
  conInfoTitle: "Contact details",
  conInfo: [
    { k: "Address", v: "La Casa dels Entremesos\nPlaça de les Beates, 2, 2nd\n08003 Barcelona" },
    { k: "Email", v: "info@esbartcatala.org" },
    { k: "Danses Vives", v: "dansesvives@esbartcatala.org" },
    { k: "Phone", v: "93 412 51 11" },
  ],
  arriveTitle: "Getting here",
  arrive: [
    { k: "Metro", v: "L4 (yellow) Jaume I · L1 (red) Urquinaona, a 5–10 min walk." },
    { k: "Bus", v: "Lines 45, 120, V15, V17 · Pla de Palau stop." },
    { k: "On foot", v: "10 min from Parc de la Ciutadella and 15 min from the Cathedral, in the heart of Ciutat Vella." },
  ],
  mapLabel: "Plaça de les Beates, 2 · Barcelona",
};

const PART_STRINGS = { ca: PART_CA, es: PART_ES, en: PART_EN };

/* ═══════════════════════════════════════════════════════════════════════════
   SECTIONS
   ═══════════════════════════════════════════════════════════════════════════ */
function Hero({ t }) {
  return (
    <header className="pk-hero" id="inici">
      <div className="pk-hero__bg" aria-hidden="true"></div>
      <Silhouette src="assets/ecd-silhouette.svg" />
      <div className="wrap">
        <div className="pk-hero__eyebrow">{t.heroEyebrow}</div>
        <h1 className="pk-hero__title">{t.heroTitle[0]}<em>{t.heroTitle[1]}</em></h1>
        <p className="pk-hero__lead">{t.heroLead}</p>
        <div className="pk-hero__meta">
          {t.heroStats.map((s, i) => (
            <div key={i} className="pk-hero__meta-item">
              <div className="pk-hero__meta-num">{s.num}</div>
              <div className="pk-hero__meta-label">{s.label}</div>
            </div>
          ))}
        </div>
      </div>
      <div className="pk-hero__scroll" aria-hidden="true">{t.heroScroll}</div>
    </header>
  );
}

function SociSection({ t }) {
  // Membership fees are brand copy that lives in code by client decision
  // (ADR-06 D1): no `quotes` CMS collection exists, on purpose. Fee changes
  // are made here, per commit, with review.
  const quotes = t.quotes;

  return (
    <section className="pk-section pk-section--cream" id="soci">
      <div className="wrap">
        <div className="pk-head">
          <div className="pk-head__eyebrow">{t.sociEyebrow}</div>
          <div className="pk-head__grid">
            <h2 className="pk-head__title">{t.sociTitle[0]}<em>{t.sociTitle[1]}</em>{t.sociTitle[2]}</h2>
            <p className="pk-head__sub">{t.sociSub}</p>
          </div>
        </div>

        <div className="pk-checks part-benefits">
          {t.benefits.map((b, i) => (
            <div key={i} className="pk-check">
              <span className="pk-check__mark"><Check /></span>
              <span className="pk-check__text"><strong>{b.h}</strong><span>{b.b}</span></span>
            </div>
          ))}
        </div>

        {/* Quotes */}
        <div className="part-quotes-head">
          <div className="pk-head__eyebrow">{t.quotesEyebrow}</div>
          <h3 className="part-quotes-title">{t.quotesTitle[0]}<em>{t.quotesTitle[1]}</em></h3>
        </div>
        <div className="pk-grid pk-grid--4">
          {quotes.map((q) => (
            <article key={q.id} className="pk-card part-quota">
              <h4 className="pk-card__title" style={{ fontSize: 21 }}>{q.name}</h4>
              <div className="part-quota__price">{q.price}</div>
              <p className="pk-card__body">{q.audience}</p>
            </article>
          ))}
        </div>
        <p className="pk-form__note" style={{ marginTop: 16 }}>{t.quotesPriceNote}</p>

        {/* Steps */}
        <div className="part-quotes-head" style={{ marginTop: 80 }}>
          <div className="pk-head__eyebrow">{t.stepsEyebrow}</div>
          <h3 className="part-quotes-title">{t.stepsTitle[0]}<em>{t.stepsTitle[1]}</em></h3>
        </div>
        <div className="pk-steps">
          {t.steps.map((s, i) => (
            <div key={i} className="pk-step">
              <div className="pk-step__num">{String(i + 1).padStart(2, "0")}</div>
              <h4 className="pk-step__title">{s.t}</h4>
              <p className="pk-step__body">{s.b}</p>
            </div>
          ))}
        </div>
        <div style={{ marginTop: 40 }}>
          <a href="#contacte" className="btn">{t.sociBtn}</a>
        </div>
      </div>
    </section>
  );
}

/* ─── Acordió únic (shared/components/Accordion.jsx) ─────────────────── */
const EsbartAccordion = window.EsbartAccordion;

function FaqSection({ t }) {
  return (
    <section className="pk-section pk-section--paper part-faq" id="faq">
      <div className="wrap">
        <div className="pk-head">
          <div className="pk-head__eyebrow">{t.faqEyebrow}</div>
          <div className="pk-head__grid">
            <h2 className="pk-head__title">{t.faqTitle[0]}<em>{t.faqTitle[1]}</em>{t.faqTitle[2]}</h2>
          </div>
        </div>
        <EsbartAccordion
          idPrefix="faq"
          items={t.faqs.map((f, i) => ({
            id: "faq-" + (i + 1),
            title: f.q,
            titleStyle: { fontSize: "clamp(20px,2vw,26px)" },
            content: <p className="pk-card__body" style={{ fontSize: 17, maxWidth: "62ch" }}>{f.a}</p>,
          }))}
        />
      </div>
    </section>
  );
}

function VineSection({ t }) {
  return (
    <section className="pk-section pk-section--dark" id="vine">
      <div className="wrap">
        <div className="pk-feature pk-feature--flip">
          <div className="pk-feature__media"><img src="assets/hero-jump.jpg" alt="" /></div>
          <div className="pk-feature__text">
            <div className="pk-feature__kicker">{t.vineEyebrow}</div>
            <h2 className="pk-feature__title">{t.vineTitle[0]}<em>{t.vineTitle[1]}</em>{t.vineTitle[2]}</h2>
            <div className="pk-feature__body"><p>{t.vineBody}</p></div>
            <div className="pk-feature__actions">
              <a href="Vine-a-ballar.html" className="btn light">{t.vineBtn}</a>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

function VoluntariatSection({ t }) {
  return (
    <section className="pk-section pk-section--bone" id="voluntariat">
      <div className="wrap">
        <div className="pk-head">
          <div className="pk-head__eyebrow">{t.volEyebrow}</div>
          <div className="pk-head__grid">
            <h2 className="pk-head__title">{t.volTitle[0]}<em>{t.volTitle[1]}</em></h2>
            <p className="pk-head__sub">{t.volSub}</p>
          </div>
        </div>
        <div className="pk-grid pk-grid--3">
          {t.volAreas.map((a, i) => (
            <article key={i} className="pk-card">
              <div className="pk-card__index">{String(i + 1).padStart(2, "0")}</div>
              <h3 className="pk-card__title" style={{ fontSize: 21 }}>{a.h}</h3>
              <p className="pk-card__body">{a.b}</p>
            </article>
          ))}
        </div>
        <div className="part-vol-note">
          <p>{t.volNote}</p>
          <a href="#contacte" className="btn ghost">{t.volBtn}</a>
        </div>
      </div>
    </section>
  );
}

function DonacionsSection({ t }) {
  return (
    <section className="pk-section pk-section--paper" id="donacions">
      <div className="wrap">
        <div className="pk-feature">
          <div className="pk-feature__media"><img src="assets/g-couple2.jpg" alt="" /></div>
          <div className="pk-feature__text">
            <div className="pk-feature__kicker">{t.donEyebrow}</div>
            <h2 className="pk-feature__title">{t.donTitle[0]}<em>{t.donTitle[1]}</em>{t.donTitle[2]}</h2>
            <div className="pk-feature__body"><p>{t.donBody}</p></div>
            <div className="part-fiscal">
              <h4>{t.donFiscalH}</h4>
              <p>{t.donFiscal}</p>
            </div>
            <div className="pk-feature__actions">
              {/* DYNAMIC · CMS — donation flow / payment gateway link */}
              <a href="#contacte" className="btn">{t.donBtn}</a>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ╔═══════════════════════════════════════════════════════════════════════════╗
   ║  DYNAMIC · CMS — CONTACT FORM                                              ║
   ║  Submit : POST /api/v1/contacte  body { name, email, phone, reason, msg } ║
   ║  Contact details (address/email/phone) also editable via                  ║
   ║          GET /api/v1/contact-info?lang={lang}                             ║
   ╚═══════════════════════════════════════════════════════════════════════════╝ */
function ContacteSection({ t, lang }) {
  const [status, setStatus] = useState("idle"); // idle | loading | success | error
  const [reason, setReason] = useState("");

  // Enllaç profund des d'una pàgina d'exposició («Demana la cessió»):
  // preselecciona el motiu i deixa el títol ja escrit al missatge.
  useEffect(() => {
    const q = new URLSearchParams(window.location.search);
    if (q.get("motiu") !== "cessio") return;
    setReason(t.conReasons[6]);
    const exp = q.get("exposicio");
    const msg = document.getElementById("cf-msg");
    if (exp && msg && !msg.value) msg.value = t.conPrefillCessio(exp);
  }, [lang]);
  const Spinner = () => <span className="pk-spinner" aria-hidden="true" />;
  const loading = status === "loading";
  const loadingLabel = lang === "en" ? "Sending…" : lang === "es" ? "Enviando…" : "Enviant…";
  const retryLabel   = lang === "en" ? "Retry"    : lang === "es" ? "Reintentar" : "Torna a intentar";

  const onSubmit = (e) => {
    e.preventDefault();
    // eslint-disable-next-line no-unused-vars -- `data` és el cos del POST comentat (GO-LIVE, F2)
    const data = Object.fromEntries(new FormData(e.target).entries());
    setStatus("loading");
    // GO-LIVE: POST the contact message
    // fetch('/api/v1/contacte', {
    //   method: 'POST', headers: { 'Content-Type': 'application/json' },
    //   body: JSON.stringify({ ...data, reason, lang })
    // }).then((r) => r.ok ? setStatus("success") : setStatus("error"))
    //   .catch(() => setStatus("error"));
    setTimeout(() => setStatus("success"), 800); // demo
  };

  return (
    <section className="pk-section pk-section--cream" id="contacte">
      <div className="wrap">
        <div className="pk-head">
          <div className="pk-head__eyebrow">{t.conEyebrow}</div>
          <div className="pk-head__grid">
            <h2 className="pk-head__title">{t.conTitle[0]}<em>{t.conTitle[1]}</em></h2>
            <p className="pk-head__sub">{t.conSub}</p>
          </div>
        </div>

        <div className="part-contact">
          {/* Form */}
          <div className="part-contact__form">
            {status === "success" ? (
              <div className="pk-form__success">{t.conSuccess}</div>
            ) : (
              <form className="pk-form" onSubmit={onSubmit}>
                {status === "error" && (
                  <div className="pk-form__error">
                    <span>{t.conError}</span>
                    <button type="button" className="pk-form__error-retry"
                      onClick={() => setStatus("idle")}>{retryLabel}</button>
                  </div>
                )}
                <div className="pk-field">
                  <label htmlFor="cf-name">{t.conName}</label>
                  <input id="cf-name" name="name" type="text" required />
                </div>
                <div className="pk-field pk-field--row">
                  <div className="pk-field">
                    <label htmlFor="cf-email">{t.conEmail}</label>
                    <input id="cf-email" name="email" type="email" required />
                  </div>
                  <div className="pk-field">
                    <label htmlFor="cf-phone">{t.conPhone}</label>
                    <input id="cf-phone" name="phone" type="tel" />
                  </div>
                </div>
                <div className="pk-field">
                  <label>{t.conReasonLabel}</label>
                  <div className="pk-checkbox-grid">
                    {t.conReasons.map((r, i) => (
                      <label key={i} className="pk-checkbox">
                        <input type="radio" name="reason" value={r} checked={reason === r}
                          onChange={() => setReason(r)} style={{ accentColor: "var(--burgundy)" }} />
                        {r}
                      </label>
                    ))}
                  </div>
                </div>
                <div className="pk-field">
                  <label htmlFor="cf-msg">{t.conMsg}</label>
                  <textarea id="cf-msg" name="msg" required></textarea>
                </div>
                <div>
                  <button type="submit" className={`btn${loading ? " btn--loading" : ""}`} disabled={loading}>
                    {loading ? <><Spinner />{loadingLabel}</> : t.conSend}
                  </button>
                </div>
                <p className="pk-form__note">{t.conNote}</p>
              </form>
            )}
          </div>

          {/* Contact details + how to arrive */}
          <aside className="part-contact__aside">
            <h3 className="part-aside-title">{t.conInfoTitle}</h3>
            <div className="pk-info">
              {t.conInfo.map((it, i) => (
                <div key={i} className="pk-info__item">
                  <div className="pk-info__k">{it.k}</div>
                  <div className="pk-info__v">{it.v.split("\n").map((l, j) => <div key={j}>{l}</div>)}</div>
                </div>
              ))}
            </div>

            <h3 className="part-aside-title" style={{ marginTop: 40 }}>{t.arriveTitle}</h3>
            <div className="pk-info">
              {t.arrive.map((it, i) => (
                <div key={i} className="pk-info__item">
                  <div className="pk-info__k">{it.k}</div>
                  <div className="pk-info__v">{it.v}</div>
                </div>
              ))}
            </div>

            {/* DYNAMIC · CMS — embed Google Maps iframe here (lat/lng from CMS) */}
            <div className="pk-map" style={{ marginTop: 28 }}>
              <div className="pk-map__pin">
                <span className="pk-map__dot"></span>
                <span className="pk-map__label">{t.mapLabel}</span>
              </div>
            </div>
          </aside>
        </div>
      </div>
    </section>
  );
}

/* ═══════════════════════════════════════════════════════════════════════════
   APP
   ═══════════════════════════════════════════════════════════════════════════ */
/* ─── Sub-navegació de pàgina (shared/components/Subnav.jsx) ──────────── */
const EsbartSubnav = window.EsbartSubnav;
const PART_SUBNAV = {
  ca: [
    { id: "soci", label: "Fes-te soci" },
    { id: "faq", label: "Preguntes" },
    { id: "vine", label: "Vine a ballar" },
    { id: "voluntariat", label: "Voluntariat" },
    { id: "donacions", label: "Donacions" },
    { id: "contacte", label: "Contacte" },
  ],
  es: [
    { id: "soci", label: "Hazte socio" },
    { id: "faq", label: "Preguntas" },
    { id: "vine", label: "Ven a bailar" },
    { id: "voluntariat", label: "Voluntariado" },
    { id: "donacions", label: "Donaciones" },
    { id: "contacte", label: "Contacto" },
  ],
  en: [
    { id: "soci", label: "Join us" },
    { id: "faq", label: "FAQ" },
    { id: "vine", label: "Come dance" },
    { id: "voluntariat", label: "Volunteering" },
    { id: "donacions", label: "Donations" },
    { id: "contacte", label: "Contact" },
  ],
};

function App() {
  const { lang, setLang, t } = window.EsbartI18n.useI18n(PART_STRINGS);
  const tweaks = window.EsbartTweaks.useTweaks();
  const [heroMode] = useState(false);
  useEffect(() => { if (t.pageTitle) document.title = t.pageTitle; }, [lang, t]);

  return (
    <>
      <EsbartNav lang={lang} setLang={setLang} t={t} heroMode={heroMode} current="participa" />
      <main id="main-content" tabIndex={-1}>
        <Hero t={t} />
        <EsbartSubnav items={PART_SUBNAV[lang] || PART_SUBNAV.ca} />
        <SociSection t={t} />
        <FaqSection t={t} />
        <VineSection t={t} />
        <VoluntariatSection t={t} />
        <DonacionsSection t={t} />
        <ContacteSection t={t} lang={lang} />
      </main>
      <EsbartFooter t={t} />
      <EsbartTweaksPanel {...tweaks} />
    </>
  );
}

ReactDOM.createRoot(document.getElementById("app")).render(<App />);
