Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions assets/hmp-commerce.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,11 @@
date: '2026-08-09',
label_es: 'domingo 9 de agosto',
label_en: 'Sunday, August 9',
free: true,
sessions: Object.freeze({
'en-1600-cr': '8820853'
}),
options: Object.freeze({
en: Object.freeze({ session_code: 'en-1600-cr', label: 'English · 16:00 Costa Rica · FREE', time: '16:00', price: 'FREE' })
en: Object.freeze({ session_code: 'en-1600-cr', label: 'English · 16:00 Costa Rica · US$50', time: '16:00', price: 'US$50' })
})
}),
'hmp-logos-2026-08-07': Object.freeze({
Expand Down
1 change: 0 additions & 1 deletion eventos/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@ <h2><span data-lang="es">Encuentros virtuales · Proyección Armónica del Mito<
<article class="ev-feat reveal" id="virtual-en-2026-08-09" data-event-lang="en">
<div class="tags">
<span class="pill"><span data-lang="es">Inscripción abierta</span><span data-lang="en">Registration open</span></span>
<span class="pill"><span data-lang="es">Gratis</span><span data-lang="en">Free</span></span>
<span class="pill pill-sky"><span class="d"></span> <span data-lang="es">Online · en inglés</span><span data-lang="en">Online · in English</span></span>
</div>
<h2><span data-lang="es">Proyección Armónica del Mito · en inglés</span><span data-lang="en">Harmonic Myth Projection · in English</span></h2>
Expand Down
27 changes: 13 additions & 14 deletions inscripcion/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,11 @@ <h3 data-copy="es">Inscripciones próximamente</h3><h3 data-copy="en">Registrati
<ol class="flow-progress" id="registrationProgress" aria-label="Progreso de inscripción">
<li data-flow-step="1" class="is-active" aria-current="step"><span class="flow-progress-number">01</span><span class="flow-progress-copy"><strong><span data-copy="es">Datos y sesión</span><span data-copy="en">Details and session</span></strong><small><span data-copy="es">Tu reserva</span><span data-copy="en">Your booking</span></small></span></li>
<li data-flow-step="2"><span class="flow-progress-number">02</span><span class="flow-progress-copy"><strong><span data-copy="es">Confirmá tu email</span><span data-copy="en">Confirm your email</span></strong><small><span data-copy="es">Código de 6 dígitos</span><span data-copy="en">6-digit code</span></small></span></li>
<li data-flow-step="3"><span class="flow-progress-number">03</span><span class="flow-progress-copy"><strong><span id="ticketStepEs" data-copy="es">Entrada gratuita</span><span id="ticketStepEn" data-copy="en">Free ticket</span></strong><small>Ticket Tailor</small></span></li>
<li data-flow-step="3"><span class="flow-progress-number">03</span><span class="flow-progress-copy"><strong><span id="ticketStepEs" data-copy="es">Entrada y pago</span><span id="ticketStepEn" data-copy="en">Ticket and payment</span></strong><small>Ticket Tailor</small></span></li>
<li data-flow-step="4"><span class="flow-progress-number">04</span><span class="flow-progress-copy"><strong><span data-copy="es">Confirmación</span><span data-copy="en">Confirmation</span></strong><small><span data-copy="es">Todo por email</span><span data-copy="en">Everything by email</span></small></span></li>
</ol>
<div class="session-zone">
<div id="registrationIntro"><h3 data-copy="es">Datos y sesión</h3><h3 data-copy="en">Details and session</h3><p class="form-intro" id="introCopyEs" data-copy="es">Primero dejanos tu nombre y correo. Después elegí el idioma y revisá el horario.</p><p class="form-intro" id="introCopyEn" data-copy="en">First leave your name and email. Then choose the language and review the time.</p><p class="timezone"><span data-copy="es">PASO 1 DE 4 · ESTA INSCRIPCIÓN ES GRATUITA</span><span data-copy="en">STEP 1 OF 4 · THIS REGISTRATION IS FREE</span></p></div>
<div id="registrationIntro"><h3 data-copy="es">Datos y sesión</h3><h3 data-copy="en">Details and session</h3><p class="form-intro" id="introCopyEs" data-copy="es">Primero dejanos tu nombre y correo. Después elegí el idioma, revisá el horario y el precio.</p><p class="form-intro" id="introCopyEn" data-copy="en">First leave your name and email. Then choose the language and review the time and price.</p><p class="timezone"><span data-copy="es">PASO 1 DE 4 · TODAVÍA NO SE REALIZA NINGÚN PAGO</span><span data-copy="en">STEP 1 OF 4 · NO PAYMENT IS MADE YET</span></p></div>
<div id="sessionStep" hidden><h3 data-copy="es">Elegí tu sesión</h3><h3 data-copy="en">Choose your session</h3><p class="form-intro" data-copy="es">Seleccioná el idioma y el horario. En el próximo paso vas a confirmar tu correo.</p><p class="form-intro" data-copy="en">Select the language and time. In the next step, you will confirm your email.</p><div class="session-list"><button class="session" type="button" data-session="es" aria-pressed="false"><span class="radio" aria-hidden="true"></span><span class="session-copy"><b data-option-name>ESPAÑOL</b><small><span data-option-detail data-copy="es">sábado · hora Costa Rica</span><span data-option-detail data-copy="en">Saturday · Costa Rica time</span></small></span><span class="session-side"><b>08:30</b><small>US$20</small></span></button><button class="session" type="button" data-session="en" aria-pressed="false"><span class="radio" aria-hidden="true"></span><span class="session-copy"><b data-option-name>ENGLISH</b><small><span data-option-detail data-copy="es">domingo · hora Costa Rica</span><span data-option-detail data-copy="en">Sunday · Costa Rica time</span></small></span><span class="session-side"><b>16:00</b><small>US$50</small></span></button></div><p class="timezone">◷ COSTA RICA · UTC−6</p><div class="session-stage-actions"><button class="cta submit" id="paymentButton" type="submit" form="registrationForm" hidden><span id="paymentButtonLabel">continuar</span><i>↗</i></button><button class="change-details" id="changeDetails" type="button"><span data-copy="es">Corregir mis datos</span><span data-copy="en">Edit my details</span></button></div></div>
</div>
<div class="form-zone">
Expand All @@ -216,15 +216,15 @@ <h3 data-copy="es">Tu nombre en este viaje</h3><h3 data-copy="en">Your name in t
<input type="text" name="_honey" tabindex="-1" autocomplete="off" style="display:none">
<div class="form-row"><label><span data-copy="es">nombre</span><span data-copy="en">first name</span><input name="firstName" autocomplete="given-name" required></label><label><span data-copy="es">apellido</span><span data-copy="en">last name</span><input name="lastName" autocomplete="family-name" required></label></div>
<label><span data-copy="es">correo electrónico</span><span data-copy="en">email address</span><input type="email" name="email" autocomplete="email" required></label>
<p class="form-note"><span id="formNoteEs" data-copy="es">Ahí llegarán la confirmación de tu reserva y el acceso. Revisá también spam y promociones.</span><span id="formNoteEn" data-copy="en">Your booking confirmation and access will arrive there. Check spam and promotions too.</span></p>
<p class="form-note"><span id="formNoteEs" data-copy="es">Ahí llegará la confirmación, el pago y el acceso. Revisá también spam y promociones.</span><span id="formNoteEn" data-copy="en">Confirmation, payment details and access will arrive there. Check spam and promotions too.</span></p>
<label class="consent"><input type="checkbox" name="registrationTermsAccepted" value="ACEPTO" required><span data-copy="es">Acepto los <a href="/politica/" target="_blank" rel="noopener">términos y la política de esta inscripción</a>.</span><span data-copy="en">I accept the <a href="/politica/" target="_blank" rel="noopener">terms and policy for this registration</a>.</span></label>
<div id="hb-meta-consent-mount" aria-live="polite"></div>
<button class="cta submit" id="continueButton" type="button"><span data-copy="es">continuar</span><span data-copy="en">continue</span><i>↗</i></button>
<p class="legal"><span data-copy="es">Usamos tu email únicamente para esta experiencia.</span><span data-copy="en">We use your email only for this experience.</span></p>
</form>
<section class="verification-step" id="emailVerificationStep" hidden aria-live="polite">
<h3 data-copy="es">Confirmá tu correo</h3><h3 data-copy="en">Confirm your email</h3>
<p class="form-intro" id="verificationCopyEs" data-copy="es">Te enviamos un código de seis dígitos. Ingresalo para confirmar que el correo es tuyo y continuar a la entrada gratuita.</p><p class="form-intro" id="verificationCopyEn" data-copy="en">We sent you a six-digit code. Enter it to confirm that the email belongs to you and continue to the free ticket.</p>
<p class="form-intro" id="verificationCopyEs" data-copy="es">Te enviamos un código de seis dígitos. Ingresalo para confirmar que el correo es tuyo y continuar al pago.</p><p class="form-intro" id="verificationCopyEn" data-copy="en">We sent you a six-digit code. Enter it to confirm that the email belongs to you and continue to payment.</p>
<strong class="verification-destination" id="verificationDestination"></strong>
<form id="emailVerificationForm">
<label><span data-copy="es">código de verificación</span><span data-copy="en">verification code</span><input id="verificationCode" name="verificationCode" inputmode="numeric" autocomplete="one-time-code" pattern="[0-9]{6}" maxlength="6" required></label>
Expand All @@ -234,7 +234,7 @@ <h3 data-copy="es">Confirmá tu correo</h3><h3 data-copy="en">Confirm your email
</section>
<section class="checkout-step" id="checkoutStep" hidden aria-live="polite">
<h3 id="checkoutTitleEs" data-copy="es">Elegí tu entrada y pagá</h3><h3 id="checkoutTitleEn" data-copy="en">Choose your ticket and pay</h3>
<p class="form-intro" id="checkoutCopyEs" data-copy="es">Tu inscripción quedó registrada. Confirmá la entrada sin costo en el formulario seguro de Ticket Tailor. No se solicita tarjeta.</p><p class="form-intro" id="checkoutCopyEn" data-copy="en">Your registration is saved. Confirm the free ticket in Ticket Tailor's secure form. No card is required.</p>
<p class="form-intro" id="checkoutCopyEs" data-copy="es">Tu inscripción quedó registrada. Elegí tu entrada y completá el pago en el formulario seguro de Ticket Tailor.</p><p class="form-intro" id="checkoutCopyEn" data-copy="en">Your registration is saved. Choose your ticket and complete payment in Ticket Tailor's secure form.</p>
<div class="checkout-widget" id="ticketTailorWidget"></div>
</section>
</div>
Expand Down Expand Up @@ -269,18 +269,17 @@ <h3 id="checkoutTitleEs" data-copy="es">Elegí tu entrada y pagá</h3><h3 id="ch
const params=new URLSearchParams(location.search),fecha=params.get('fecha')||'2026-08-09',catalogEvent=window.HMPCommerce.CHECKOUTS['hmp-'+fecha],eventConfig=window.HMPCommerce.registrationEvent(fecha),eventAvailable=registrationOpen&&Boolean(eventConfig);
one('#registrationClosed').hidden=eventAvailable;one('#registrationFlow').hidden=!eventAvailable;
one('#eventInProgressNotice').hidden=!window.HMPCommerce.eventInProgress('hmp-'+fecha);
function applyFreeCopy(){
function applyPrivateFreeCopy(){
if(!catalogEvent?.free)return;
document.documentElement.dataset.commerce='free';
const privateEvent=catalogEvent.private===true;
one('#bookingModeEs').textContent=privateEvent?'INSCRIPCIÓN PRIVADA GRATUITA':'INSCRIPCIÓN GRATUITA';
one('#bookingModeEn').textContent=privateEvent?'FREE PRIVATE REGISTRATION':'FREE REGISTRATION';
one('#bookingSummaryEs').textContent=privateEvent?'Completá tus datos, elegí LOGOS y confirmá tu correo. Después reservá tu entrada gratuita en Ticket Tailor.':'Completá tus datos, elegí la sesión y confirmá tu correo. Después reservá tu entrada gratuita en Ticket Tailor.';
one('#bookingSummaryEn').textContent=privateEvent?'Complete your details, choose LOGOS and confirm your email. Then reserve your free ticket through Ticket Tailor.':'Complete your details, choose the session and confirm your email. Then reserve your free ticket through Ticket Tailor.';
one('#bookingModeEs').textContent='INSCRIPCIÓN PRIVADA GRATUITA';
one('#bookingModeEn').textContent='FREE PRIVATE REGISTRATION';
one('#bookingSummaryEs').textContent='Completá tus datos, elegí LOGOS y confirmá tu correo. Después reservá tu entrada gratuita en Ticket Tailor.';
one('#bookingSummaryEn').textContent='Complete your details, choose LOGOS and confirm your email. Then reserve your free ticket through Ticket Tailor.';
one('#ticketStepEs').textContent='Entrada gratuita';
one('#ticketStepEn').textContent='Free ticket';
one('#introCopyEs').textContent=privateEvent?'Primero dejanos tu nombre y correo. Después elegí LOGOS y revisá el horario de tu invitación gratuita.':'Primero dejanos tu nombre y correo. Después elegí la sesión y revisá el horario de tu entrada gratuita.';
one('#introCopyEn').textContent=privateEvent?'First leave your name and email. Then choose LOGOS and review the time of your free invitation.':'First leave your name and email. Then choose the session and review the time of your free ticket.';
one('#introCopyEs').textContent='Primero dejanos tu nombre y correo. Después elegí LOGOS y revisá el horario de tu invitación gratuita.';
one('#introCopyEn').textContent='First leave your name and email. Then choose LOGOS and review the time of your free invitation.';
one('#formNoteEs').textContent='Ahí llegarán la confirmación de tu reserva y el acceso. Revisá también spam y promociones.';
one('#formNoteEn').textContent='Your booking confirmation and access will arrive there. Check spam and promotions too.';
one('#verificationCopyEs').textContent='Te enviamos un código de seis dígitos. Ingresalo para confirmar que el correo es tuyo y continuar a la entrada gratuita.';
Expand Down Expand Up @@ -310,7 +309,7 @@ <h3 id="checkoutTitleEs" data-copy="es">Elegí tu entrada y pagá</h3><h3 id="ch
if(option.detail_es||option.detail_en)button.querySelectorAll('[data-option-detail]').forEach(detail=>{detail.textContent=detail.dataset.copy==='en'?(option.detail_en||''):(option.detail_es||'')});
}
});
applyFreeCopy();
applyPrivateFreeCopy();
}else{
one('#eventCodeInput').value='';
one('#dateEs').textContent='fecha aún no disponible';
Expand Down
2 changes: 0 additions & 2 deletions tests/hmp-commerce.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,6 @@ test('matches the stable registration catalog contract and rejects series ids',
assert.equal(api.CHECKOUTS['hmp-2026-08-08'].sessions['en-1400-cr'], sessions['en-1400-cr'].ticket_tailor_checkout_event_id);
const august9 = contract.events['hmp-2026-08-09'].sessions;
assert.equal(api.CHECKOUTS['hmp-2026-08-09'].sessions['en-1600-cr'], august9['en-1600-cr'].ticket_tailor_checkout_event_id);
assert.equal(api.CHECKOUTS['hmp-2026-08-09'].free, true);
assert.equal(api.CHECKOUTS['hmp-2026-08-09'].options.en.price, 'FREE');
assert.equal(api.CHECKOUTS['hmp-logos-2026-08-07'].sessions['es-1600-cr'], '8828041');
assert.equal(api.CHECKOUTS['hmp-logos-2026-08-07'].free, true);
assert.equal(api.CHECKOUTS['hmp-logos-2026-08-07'].private, true);
Expand Down
10 changes: 4 additions & 6 deletions tests/registration-pages.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,14 @@ test('registration form requires v4 terms and never bypasses its backend', () =>
assert.equal((page.match(/data-flow-step="[1-4]"/g) || []).length, 4);
assert.match(page, /Datos y sesión/);
assert.match(page, /Confirmá tu email/);
assert.match(page, /Entrada gratuita/);
assert.match(page, /Entrada y pago/);
assert.match(page, /function setFlowStage\(step\)/);
assert.match(page, /function showVerification\(payload,result\).*setFlowStage\(2\)/);
assert.match(page, /function showCheckout\(payload,result\).*setFlowStage\(3\)/);
assert.match(page, /id="paymentButton"[^>]+form="registrationForm"/);
assert.equal((page.match(/data-session="/g) || []).length, 2);
assert.match(page, /data-session="en"/);
assert.match(page, /<b data-option-name>ENGLISH<\/b>[\s\S]*?Sunday · Costa Rica time[\s\S]*?<b>16:00<\/b>[\s\S]*?FREE/);
assert.match(page, /<b data-option-name>ENGLISH<\/b>[\s\S]*?Sunday · Costa Rica time[\s\S]*?<b>16:00<\/b>[\s\S]*?US\$50/);
assert.match(page, /id="changeDetails"/);
assert.match(page, /classList\.add\('is-session-choice'\)/);
assert.match(page, /\.booking-panel\.is-session-choice \.form-zone\{display:none\}/);
Expand All @@ -127,10 +127,8 @@ test('registration form requires v4 terms and never bypasses its backend', () =>
assert.match(page, /value="hmp-2026-08-09"/);
assert.match(page, /DOMINGO 9 DE AGOSTO/);
assert.match(page, /SUNDAY, AUGUST 9/);
assert.match(page, /applyFreeCopy/);
assert.match(page, /INSCRIPCIÓN PRIVADA GRATUITA/);
assert.match(page, /FREE PRIVATE REGISTRATION/);
assert.match(page, /No card is required/);
assert.match(page, /INSCRIPCIÓN Y PAGO/);
assert.match(page, /REGISTRATION AND PAYMENT/);
assert.doesNotMatch(page, /Registration will open soon|Las inscripciones abrirán próximamente/);
assert.doesNotMatch(page, /MARTES 11 DE AGOSTO|TUESDAY, AUGUST 11/);
assert.match(page, /catalogEvent\.options\?\.\[button\.dataset\.session\]/);
Expand Down