Rebeca Pal — System design v3 (tokens y decisiones)
Contexto: child theme rebeca-pal de Hello Elementor (v0.2.0) portado del
prototipo ~/Documents/rebeca-pal/01-html/ (rp.css/rp.js + RECETARIO.md,
validado pixel a pixel contra Figma a 375/1280). Fuentes LOCALES (sin CDN)
en assets/fonts/: Manrope 400–800, Lora 700 (+italic), Nanum Pen Script 400,
latin + latin-ext, font-display:swap. Precarga Manrope 500 y 800.
Tokens (escala mobile en :root, desktop en @media (min-width:1024px),
sin clamp()):
--rp-oro: #B9AE5E; --rp-oro-txt: #7D6C3E; --rp-vino: #55191B;
--rp-borgona: #600912; --rp-ciruela: #3D192E; --rp-hueso: #F8F8F6;
--rp-blanco: #FFFFFF; --rp-input: #D9D9D9; --rp-input-txt: #8E848B;
--rp-nota-txt: #432A37;Escala clave: h2 40px/ls5.2/lh43 Manrope 800 (footer 30px) · cuerpo 22/2.86/30 (15/1.95/20) · bio 20/1.26/24.5 (14) · libro Lora 700 20px ls0 uppercase · meta 15/1.4 700 · botón 21.25/h47 (18/h38) · nota Nanum 22/ls3.08/lh1.05 · legal 11/lh19. Breakpoints: 768 (carrusel→grid, puntos ocultos) y 1024. Layout: contenido 1100px, gutter 25/40/90, header 110/108, caja de portada 333×412 hueso sin sombra.
Verificado por códigos computados (probe): ficha = 39px/250×388 mobile,
50px/386×600 desktop, Comprar 26px/h71, “Leer más” solo mobile. Kit de
Elementor instalado por código (7 colores, 9 tipografías, container 1100)
escribiendo la meta _elementor_page_settings del kit activo (update_settings
lanza “Access denied” en frontend — NO usarlo).
Claves técnicas:
- Filtro
elementor/frontend/print_google_fonts→ false: Elementor no imprime su CSS de Google Fonts; las locales cubren Manrope/Lora/Nanum. - CPT
libro(slugs voragine, siete-suicidios, relatos-inconscientes) + meta con show_in_rest: rp_genero, rp_anio, rp_compra_url, rp_portada_grande. single-libro.phpcon clasees-largoen h1 si título >16 caracteres.- Carrusel móvil: contenedores
data-carrusel+data-puntos, JSassets/js/rp-carrusel.js(defer), CSS.rp-carrusel(grid ≥768). - Google Fonts css2: latin-ext es
U+0100-02BA(no 02AF); detectar por prefijoU+0100-02; Nanum no tiene latin-ext.
Pendientes de contenido (no bloquean el tema): sinopsis reales de los dos libros, URLs de compra, URLs de redes, aviso de privacidad, portada alta de “Los siete suicidios capitales”, y montar header/footer/home con Theme Builder (instrucciones en el README del tema).
Anexo: montaje 100% editable en Elementor (4.1.3 atomic + Pro)
Para que TODO (home, hero slider, libros carrusel, frases, footer, fichas)
sea editable en Elementor se construyó con JSON clásico (widgets clásicos
siguen registrados y editables con UI estándar) + plantillas Theme Builder.
Generador: ~/Documents/rebeca-pal/tooling/build_v3/build.py + push.php.
Lecciones duras (Elementor 4.1.3, formato clásico guardado a mano):
- Secciones solo contienen COLUMNAS; las secciones internas van dentro de
columnas (
sec > col > sec > col > widgets). css_classesen secciones/columnas es STRING; en widgets la clave es_css_classes(también string).- Dynamic tags clásicos:
settings.__dynamic__[nombre-control] = '[elementor-tag id="x" name="post-title" settings="%7B%7D"]'— NOsettings.control.dynamic(crashea wp_kses). update_post_metahace wp_unslash: guardar_elementor_dataconwp_slash(wp_json_encode(...)); usarwp eval-file(wp-cli) para writes con UTF-8 correcto (php CLI negocia latin1).- Condiciones Theme Builder: “todo el sitio” =
include/general(sin sub); CPT =include/singular/libro(la sub-condición se llama como el CPT); regenerar caché con Conditions_Cache::regenerate(). - image-carousel clásico usa
settings.carousel(GALLERY), noslides. - Hero slider = widget Image Carousel + CSS
.rp-hero-carousel(aspect 375/706 → 1280/699, bullets blancos posicionados). - Orden móvil de secciones con grid: clases en secciones/columnas +
display:contentsen<1024px(.rp-yosoy-grid,.rp-ficha-grid,.rp-footer-grid).
Anexo 2: hero slider sin swiper (Elementor 4.1.3 atomic)
El widget clásico image-carousel (swiper) NO se inicializa con JSON clásico
en Elementor 4.1.3 atomic: el JS del frontend ignora el widget (sin errores
en consola, wrapper sin transform, slides colapsados a 150px → el hero se
estiraba y “blanqueaba” la página en Firefox ≥1024px).
Solución: el hero se montó con el MISMO mecanismo de carrusel propio del tema
(scroll-snap + data-carrusel/data-puntos + rp-carrusel.js): 3 widgets
Image dentro de un track .rp-carrusel.rp-hero-carousel + puntos blancos
sobrepuestos (.rp-hero .rp-puntos, bottom 19/47px, visibles a todo ancho).
Para que NO pase a grid en ≥768 hay que anularlo:
.rp-hero-carousel > .elementor-container{grid-template-columns:none;gap:0; grid-auto-flow:column;grid-auto-columns:100%;overflow-x:auto}.
Verificado en Firefox headless 900/1024/1280 (bandas de color correctas) y
Chromium (rect del hero 1100×601 desktop, 900×1694 mobile).
Anexo 3: pase “perfectionist” (build Elementor vs 01-html)
Problemas del engine atomic 4.1.3 (clásico renderizado por compat) y sus fixes:
- NO aplica anchos de columna (
elementor-col-*vacío → columnas shrink-to-fit): fijar a mano.rp-X > .elementor-container > .elementor-column{width:100%}. .elementor-container{max-width:1100px}aplica a TODO contenedor (aun full): para full-bleed usar.rp-hero.elementor-section-boxed > .elementor-container{width:100%;max-width:100%}(especificidad 0,3,0).- Las clases
rp-btnde un widget Button van en el WRAPPER: estilar el interno con.elementor-widget-button.rp-btn--vino .elementor-button. - Overflow horizontal difuso (varía por carga):
html,body{overflow-x:clip}(los tracks siguen scrollando en su propio overflow-x:auto). aspect-ratiosobre secciones con hijos absolute falla a 1280 en FF: usar el trucoheight:0;padding-top:%(hero: 188.27% móvil / 54.61% desktop).- Fade slider del hero SIN swiper: 3 columnas apiladas absolute + opacity
transition +
.is-activo, puntosdata-puntosy chevrones.rp-hero-nav(JS en rp-carrusel.js). Dots rellenos por JS (la sonda los mide antes de que corra el defer — medir en el dump, no en footer scripts). - Header sutil: logo 46px desktop / 40px móvil, nav 18px/ls 2.3.
- Editor clásico: experimentos
e_opt_in_v4,atomic-widgets,global-classes,variables,components→wp option add elementor_experiment-<nombre> inactive.
Anexo 4: tablet/espaciados (pase v4)
- Yosoy y ficha: el grid 2 columnas (457/62/549 y 496/60/549) SOLO a ≥1280; entre 768-1279 se apila (orden móvil) — evitaba el solape del tablet (1068px de columnas fijas > contenedor 1024-1279).
- Hero: proporción horizontal 54.61% por defecto; vertical 188.27% solo <480px (cambio de ratio que el usuario quería para móvil pequeño).
- Libros desktop: grid
repeat(3,minmax(0,1fr))gap 20 (tarjetas ~353px, +10%), media boxwidth:100%, head con gap 40 y carrusel con margin-top 64. - Chevrones en TODOS los sliders (
.rp-hero-nav+.rp-carrusel-nav), casi invisibles (opacity .45) + puntos tinta: homogéneo. JS: scrollBy una tarjeta. - Frases móvil: nota width 212px (-30%), área de texto inset 30%/9%/14%
(+40px),
scroll-behavior:smooth+scroll-snap-stop:alwaysen los tracks. - Footer: las reglas móviles del grid deben ir en
@media(max-width:1023px)(no en el bloque 1279, o el footer se apila en tablet); form de Elementor en fila ≥1024 (flex-direction:row, input 376) / columna móvil; los grupos.elementor-field-groupconflex:1 1 376px. - Contenedores de sección: el engine deja
.elementor-containercontent-sized (.elementor-container{max-width:1100px}sin width) → fijarwidth:100%en los contenedores de hero/yosoy/libros/frases/footer ymin-width:0en las columnas de los tracks. - Herramienta de medición: MU-plugin
wp-content/mu-plugins/rp-probe.php(query?rp_probe=1), eliminado al terminar.
Anexo 5: cierre (v0.2.2) — 5 arreglos aplicados
- Aislamiento del editor: @font-face →
assets/css/rp-fonts.css(15 faces);rp-fontsencolada antes destyle.css(dependencia); el hook del editor (elementor/editor/after_enqueue_styles) encola SOLO rp-fonts. Verificado: rp-fonts.css?ver=0.2.2 antes de style.css en el frontend. - Notas: el texto se ancla al
.elementor-widget-wrap(container-type: inline-size) y la tipografía escala con7.3cqw/1.02cqw(22px/3.08px a 302px); inset 36%/11%/10%; eliminados--rp-nota-size/--rp-nota-lsy el duplicado.rp-nota__texto. - Alineación:
display:contentstambién en.elementor-widget-wrap(yosoy/footer/ficha) — los order ahora operan (orden móvil h2→regla→bio→ foto→párrafos verificado por top positions); la claserp-yosoy-reglaDEBE ir en el widget, no en el span (si no, order:0 y la regla queda encima del h2); quitadooverflow-x:clipde.rp-yosoy(recortaba la cabeza en vertical: clip+visible → visible computa clip);.rp-cabezadisplay:none base y block solo ≥1280; libros head gap 27 desktop / sub 4px móvil; tarjetas flex column +margin-top:autobotón + título min-height 2.4em (botones alineados); frases carrusel margin-top 64px en tablet (la rotación de las notas no tapa el título); menú hamburguesa <1024 (breakpoint tablet). - Editable:
inc/editable.php— CPT frase (rp_papel oro/vino), shortcodes[rp-libros](año desc, filas de tres row-gap 52, móvil carrusel N-ready) y[rp-frases](rotación cíclica),[rp-redes]y[rp-legal]desde opciones (admin → Rebeca Pal), email del form víaelementor_pro/forms/new_record, botón Comprar oculto sirp_compra_urlvacío,archive-libro.php, i18n con textdomain. Home/footer ahora consumen los shortcodes (nada de contenido estático en plantillas). - Flechas: 0 chevrones (ya eliminados antes); verificado en el DOM.
Causas raíz documentadas: los widgets cuelgan de .elementor-widget-wrap
(no de la columna) → display:contents debe cubrir ambos niveles; el engine
deja .elementor-container sin width → fijar width:100% en los contenedores
de sección; elementor-col-* no aplica en este engine → anchos a mano.
Anexo 6: sliders laterales también en escritorio (v0.2.2+)
El usuario pidió que Libros/Frases deslicen lateralmente en desktop en lugar de retícula estática cuando crezca el catálogo. Cambios:
.rp-carrusel > .elementor-containeren ≥768:grid-auto-flow:column; grid-auto-columns:333px; column-gap:20px(antes retícula repeat(3,1fr)).scroll-snap-align:start(con tarjetas de ancho fijo, center haría saltar la primera al centro).- Puntos visibles en TODOS los anchos (se quitó el display:none de ≥768) — el indicador ahora siempre existe.
- JS
marcar: el paso se calcula de los dos primeros hijos (items[1].offsetLeft - items[0].offsetLeft), no de clientWidth (con tarjetas fijas clientWidth ≠ tarjeta). Index clamp a items.length-1. - Con 3 ítems el ancho total (1039px) cabe en 1100 → sin scroll (se ven los 3); con el 4º (1392px) desliza. Comportamiento N-ready.
Anexo 7: ronda de acabado (v0.2.2 final)
- Puntos del hero: sobre la foto (bottom 19/47px), variante clara (fuera —tinta).
- Hamburguesa: panel a ancho completo bajo la barra (oro, filete, ítems centrados 18px, separadores; position:static en el widget).
- Bug rp-cabeza: la clase va en el div del widget;
.rp-cabeza imgahorawidth:308px;max-width:100%(antes la img salía a natural 1000×498 y se comía el titular de Libros; el width:100% resolvía contra un padre de 422). - Foto Yo soy: aspect-ratio y object-fit movidos al
<img>(ratio correcto 375/423 y 457/494 verificado por rects). - Tarjetas: botones Comprar a la misma altura (verificado en 6 anchos), imágenes con wp_get_attachment_image (width/height/srcset/lazy, sin salto de layout).
- Blog dentro del sistema: home.php (retícula 3 cols ≥768, tarjetas hueso) y single.php (título Manrope 800 uppercase, meta oro, contenido ciruela).
- Acabado: tokens —rp-t-rapida/.suave; focus-visible borgoña con offset (links, botones, puntos, toggle); hover de tarjetas (scale 1.03) y puntos; text-wrap:balance en titulares; prefers-reduced-motion ampliado (carruseles + fade del hero); aria region + “Ir a la obra/frase/imagen N de M”.
- Contraste —rp-oro-txt 7D6C3E sobre hueso: 4.83:1 → AA ✓ (sin cambios).
- Datos pendientes (contenido): enlaces de compra, URLs de redes, página de privacidad, sinopsis reales, portada alta de Siete suicidios.
Anexo 8: ronda de acabado — verificación contra checklist
Header alineado al contenedor (sección 5): paddings absolutos fuera (83/171); contenedor width:100%/max-width:1100/margin-inline:auto; gutters 25/40/90 con padding_tablet:40 añadido a yosoy/libros/frases/footer (sin él, a 768 y 1024 el header usaba 40 pero las secciones 90 → desalineación). Verificado por rects a 375/480/768/1024/1280/1440/1920: logo.left == contenido.left y menú al ras (3px de cola de letter-spacing). Logo 45/53, alto 108/110, hamburguesa full-width con .rp-header position:relative ✓. fetchpriority=high en el hero vía JS (sin lazy).