Web de Gure Ametsa Bi Lagun en WordPress para Dokploy

- Docker Compose (WordPress + MariaDB) listo para Dokploy, con instalación
  automática por etapas: idiomas, páginas, menús y plugins recomendados.
- Web bilingüe castellano / euskera con Polylang.
- Tema propio «gure-ametsa»: diseño inspirado en Beargrass Animal Rescue,
  personalizable desde Apariencia → Personalizar (paletas, tipografías,
  secciones de portada ordenables) y patrones de bloques propios.
- Plugin mu «gure-ametsa-core»: animales en adopción con ficha y filtros,
  carrusel y formulario de contacto/adopción.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-24 16:21:26 +02:00
parent 97b8c1be31
commit 0b2c9f271f
64 changed files with 4561 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
<?php
get_header();
?>
<section class="ga-404">
<div class="ga-narrow">
<?php echo ga_icon( 'paw' ); ?>
<h1><?php ga_e( 'Vaya, esta página se ha escapado', 'Ai ama, orri hau ihes egin du' ); ?></h1>
<p><?php ga_e( 'No encontramos lo que buscas, pero hay muchos animales que sí te están buscando a ti.', 'Ez dugu bilatzen duzuna aurkitu, baina animalia asko zure bila dabiltza.' ); ?></p>
<p>
<a class="ga-btn" href="<?php echo esc_url( get_post_type_archive_link( 'animal' ) ); ?>"><?php ga_e( 'Ver animales en adopción', 'Ikusi adopzioko animaliak' ); ?></a>
<a class="ga-btn ga-btn--ghost" href="<?php echo esc_url( ga_home_url() ); ?>"><?php ga_e( 'Ir al inicio', 'Hasierara joan' ); ?></a>
</p>
</div>
</section>
<?php
get_footer();

View File

@@ -0,0 +1,122 @@
<?php
global $wp_query;
get_header();
$base = get_post_type_archive_link( 'animal' );
$current = is_tax( 'especie' ) ? get_queried_object() : null;
$here = $current ? get_term_link( $current ) : $base;
$fields = ga_fields();
$especies = get_terms( array( 'taxonomy' => 'especie', 'hide_empty' => false ) );
$params = array_filter( array(
'tamano' => sanitize_key( (string) get_query_var( 'tamano' ) ),
'sexo' => sanitize_key( (string) get_query_var( 'sexo' ) ),
'edad' => sanitize_key( (string) get_query_var( 'edad' ) ),
'con' => sanitize_key( (string) get_query_var( 'con' ) ),
) );
/** Chip que activa o desactiva un filtro manteniendo el resto. */
$chip = function ( $key, $value, $label ) use ( $params, $here ) {
$active = ( $params[ $key ] ?? '' ) === $value;
$args = $params;
if ( $active ) {
unset( $args[ $key ] );
} else {
$args[ $key ] = $value;
}
printf(
'<a class="ga-chip%s" href="%s"%s>%s</a>',
$active ? ' is-active' : '',
esc_url( add_query_arg( $args, $here ) ),
$active ? ' aria-current="true"' : '',
esc_html( $label )
);
};
$groups = array(
'tamano' => array( $fields['tamano']['label'], $fields['tamano']['options'] ),
'edad' => array( ga__( 'Edad', 'Adina' ), ga_age_groups() ),
'sexo' => array( $fields['sexo']['label'], $fields['sexo']['options'] ),
'con' => array( $fields['compatible']['label'], $fields['compatible']['options'] ),
);
$title = $current
? ga__( ga_plural( $current->name ) . ' en adopción', ga_plural( $current->name ) . ' adopzioan' )
: ga__( 'Animales en adopción', 'Animaliak adopzioan' );
?>
<header class="ga-page-head">
<div class="ga-wrap">
<span class="ga-eyebrow"><?php ga_e( 'Puerta uno · Adopta', 'Lehen atea · Adoptatu' ); ?></span>
<h1><?php echo esc_html( $title ); ?></h1>
<p><?php ga_e( 'Todos se entregan con microchip, vacunas al día y esterilizados. Si alguno te roba el corazón, escríbenos y te contamos todo sobre él.', 'Guztiak mikrotxiparekin, txertoak egunean eta antzututa ematen dira. Norbaitek bihotza lapurtzen badizu, idatzi iezaguzu eta dena kontatuko dizugu.' ); ?></p>
</div>
</header>
<section class="ga-section ga-section--tight">
<div class="ga-wrap">
<div class="ga-filters">
<div class="ga-filters__grid">
<div class="ga-filters__group">
<span class="ga-filters__label"><?php ga_e( 'Especie', 'Espeziea' ); ?></span>
<div class="ga-filters__chips">
<?php foreach ( (array) $especies as $term ) : ?>
<?php $active = $current && $current->term_id === $term->term_id; ?>
<a class="ga-chip<?php echo $active ? ' is-active' : ''; ?>" href="<?php echo esc_url( add_query_arg( $params, $active ? $base : get_term_link( $term ) ) ); ?>"><?php echo esc_html( ga_plural( $term->name ) ); ?></a>
<?php endforeach; ?>
</div>
</div>
<?php foreach ( $groups as $key => [ $label, $options ] ) : ?>
<div class="ga-filters__group">
<span class="ga-filters__label"><?php echo esc_html( $label ); ?></span>
<div class="ga-filters__chips">
<?php foreach ( $options as $value => $option ) : ?>
<?php $chip( $key, $value, $option ); ?>
<?php endforeach; ?>
</div>
</div>
<?php endforeach; ?>
</div>
<div class="ga-filters__footer">
<span class="ga-filters__count">
<?php
$n = (int) $wp_query->found_posts;
echo wp_kses( ga__(
sprintf( 'Mostrando <strong>%d</strong> %s', $n, 1 === $n ? 'animal' : 'animales' ),
sprintf( '<strong>%d</strong> animalia erakusten', $n )
), array( 'strong' => array() ) );
?>
</span>
<?php if ( $params || $current ) : ?>
<a class="ga-btn ga-btn--small ga-btn--outline" href="<?php echo esc_url( $base ); ?>"><?php ga_e( 'Quitar filtros', 'Kendu iragazkiak' ); ?></a>
<?php endif; ?>
</div>
</div>
<?php if ( have_posts() ) : ?>
<div class="ga-grid">
<?php
while ( have_posts() ) :
the_post();
get_template_part( 'template-parts/animal-card' );
endwhile;
?>
</div>
<nav class="ga-pagination" aria-label="<?php echo esc_attr( ga__( 'Paginación', 'Orrikatzea' ) ); ?>">
<?php echo paginate_links( array( 'prev_text' => '←', 'next_text' => '→' ) ); ?>
</nav>
<?php else : ?>
<p class="ga-empty"><?php ga_e( 'No hay animales que coincidan con estos filtros ahora mismo. ¡Prueba con otros o vuelve pronto!', 'Une honetan ez dago iragazki hauekin bat datorren animaliarik. Probatu beste batzuekin edo itzuli laster!' ); ?></p>
<?php endif; ?>
<div class="ga-panel ga-panel--soft ga-archive-help">
<div>
<h3><?php ga_e( '¿No puedes adoptar?', 'Ezin duzu adoptatu?' ); ?></h3>
<p><?php ga_e( 'Puedes ser casa de acogida, voluntario/a o ayudarnos con donaciones.', 'Harrera-etxe, boluntario izan zaitezke edo dohaintzekin lagundu.' ); ?></p>
</div>
<a class="ga-btn ga-btn--primary" href="<?php echo esc_url( ga_page_url( 'colabora' ) ); ?>"><?php ga_e( 'Descubre cómo colaborar', 'Ikusi nola lagundu' ); ?> <?php echo ga_icon( 'arrow' ); ?></a>
</div>
</div>
</section>
<?php
get_footer();

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="32" fill="#1e5b3e"/><g fill="#fffcf6"><ellipse cx="21" cy="28" rx="4" ry="5.2" transform="rotate(-18 21 28)"/><ellipse cx="27" cy="20.5" rx="3.6" ry="4.8"/><ellipse cx="35" cy="20.5" rx="3.6" ry="4.8"/><ellipse cx="41" cy="28" rx="4" ry="5.2" transform="rotate(18 41 28)"/></g><path fill="#c23b2a" d="M31 48.5s-12-7.2-12-14.6c0-3.6 2.8-6.1 6-6.1 2.6 0 4.6 1.5 6 3.6 1.4-2.1 3.4-3.6 6-3.6 3.2 0 6 2.5 6 6.1 0 7.4-12 14.6-12 14.6z"/></svg>

After

Width:  |  Height:  |  Size: 525 B

View File

@@ -0,0 +1,64 @@
( function () {
var toggle = document.querySelector( '.ga-menu-toggle' );
var nav = document.getElementById( 'ga-nav' );
if ( toggle && nav ) {
toggle.addEventListener( 'click', function () {
var open = nav.classList.toggle( 'is-open' );
toggle.setAttribute( 'aria-expanded', open ? 'true' : 'false' );
} );
document.addEventListener( 'keydown', function ( e ) {
if ( e.key === 'Escape' && nav.classList.contains( 'is-open' ) ) {
nav.classList.remove( 'is-open' );
toggle.setAttribute( 'aria-expanded', 'false' );
toggle.focus();
}
} );
}
// Filtros del listado: los <select> envían el formulario al cambiar.
document.querySelectorAll( '.ga-filters select' ).forEach( function ( select ) {
select.addEventListener( 'change', function () {
select.form.submit();
} );
} );
} )();
// Vídeo de portada: se detiene si el usuario prefiere menos movimiento.
( function () {
var video = document.querySelector( '.ga-hero__bg video' );
if ( video && window.matchMedia && window.matchMedia( '(prefers-reduced-motion: reduce)' ).matches ) {
video.removeAttribute( 'autoplay' );
video.pause();
}
} )();
// Carruseles: desplazamiento con botones, ratón/táctil nativo (scroll-snap) y teclado.
( function () {
document.querySelectorAll( '[data-ga-carousel]' ).forEach( function ( carousel ) {
var track = carousel.querySelector( '.ga-carousel__track' );
var buttons = carousel.querySelectorAll( '.ga-carousel__btn' );
if ( ! track ) {
return;
}
function update() {
var max = track.scrollWidth - track.clientWidth - 2;
buttons[ 0 ].disabled = track.scrollLeft <= 2;
buttons[ 1 ].disabled = track.scrollLeft >= max;
carousel.classList.toggle( 'is-static', max <= 0 );
}
buttons.forEach( function ( button ) {
button.addEventListener( 'click', function () {
track.scrollBy( { left: track.clientWidth * 0.9 * Number( button.dataset.dir ), behavior: 'smooth' } );
} );
} );
track.addEventListener( 'keydown', function ( e ) {
if ( e.key === 'ArrowRight' || e.key === 'ArrowLeft' ) {
e.preventDefault();
track.scrollBy( { left: ( e.key === 'ArrowRight' ? 1 : -1 ) * track.clientWidth * 0.9, behavior: 'smooth' } );
}
} );
track.addEventListener( 'scroll', update, { passive: true } );
window.addEventListener( 'resize', update );
update();
} );
} )();

View File

@@ -0,0 +1,76 @@
<?php
$colabora = ga_page_url( 'colabora' );
$columns = array(
ga__( 'Adopta', 'Adoptatu' ) => array(
ga__( 'Animales disponibles', 'Animalia eskuragarriak' ) => get_post_type_archive_link( 'animal' ),
ga__( 'Cómo adoptar', 'Nola adoptatu' ) => $colabora . '#adopcion',
ga__( 'Quiénes somos', 'Nor gara' ) => ga_page_url( 'quienes-somos' ),
ga__( 'Hotel para perros y gatos', 'Txakur eta katuentzako hotela' ) => ga_page_url( 'hotel' ),
),
ga__( 'Colabora', 'Lagundu' ) => array(
ga__( 'Casa de acogida', 'Harrera-etxea' ) => $colabora . '#acogida',
ga__( 'Voluntariado', 'Boluntariotza' ) => $colabora . '#voluntariado',
ga__( 'Donaciones', 'Dohaintzak' ) => $colabora . '#donaciones',
ga__( 'Contacto', 'Harremanetarako' ) => ga_page_url( 'contacto' ),
),
);
?>
</main>
<footer class="ga-footer">
<div class="ga-wrap">
<div class="ga-footer__grid">
<div class="ga-footer__about">
<?php ga_brand(); ?>
<p><?php ga_opt_e( 'footer', 'about' ); ?></p>
<div class="ga-footer__social"><?php echo ga_social_links(); // Escapado en la función. ?></div>
</div>
<?php foreach ( $columns as $title => $links ) : ?>
<div>
<h2><?php echo esc_html( $title ); ?></h2>
<ul>
<?php foreach ( $links as $label => $href ) : ?>
<li><a href="<?php echo esc_url( $href ); ?>"><?php echo esc_html( $label ); ?></a></li>
<?php endforeach; ?>
</ul>
</div>
<?php endforeach; ?>
<div>
<h2><?php ga_e( 'Visítanos', 'Etorri gu ikustera' ); ?></h2>
<ul>
<?php if ( ga_info( 'direccion' ) ) : ?>
<li><a href="<?php echo esc_url( ga_info( 'maps' ) ); ?>" target="_blank" rel="noopener"><?php echo esc_html( ga_info( 'direccion' ) ); ?></a></li>
<?php endif; ?>
<?php if ( ga_info( 'horario' ) ) : ?>
<li><?php echo esc_html( ga_info( 'horario' ) ); ?></li>
<?php endif; ?>
<?php if ( ga_info( 'telefono' ) ) : ?>
<li class="ga-footer__phone"><a href="<?php echo esc_attr( ga_tel_link() ); ?>"><?php echo esc_html( ga_info( 'telefono' ) ); ?></a></li>
<?php endif; ?>
<?php if ( ga_info( 'email' ) ) : ?>
<li><a href="mailto:<?php echo esc_attr( ga_info( 'email' ) ); ?>"><?php echo esc_html( ga_info( 'email' ) ); ?></a></li>
<?php endif; ?>
</ul>
</div>
</div>
<div class="ga-footer__bottom">
<span>© <?php echo esc_html( wp_date( 'Y' ) ); ?> <?php ga_opt_e( 'footer', 'copyright' ); ?></span>
<?php
ga_language_switcher( 'ga-lang ga-lang--footer' );
wp_nav_menu( array(
'theme_location' => 'footer',
'container' => false,
'fallback_cb' => false,
'depth' => 1,
) );
?>
</div>
</div>
</footer>
<?php wp_footer(); ?>
</body>
</html>

View File

@@ -0,0 +1,12 @@
<?php
/**
* Portada: las secciones se muestran, ocultan y ordenan desde
* Apariencia → Personalizar → Portada. Cada una está en template-parts/home/.
*/
get_header();
foreach ( ga_home_sections() as $section ) {
get_template_part( 'template-parts/home/' . $section );
}
get_footer();

View File

@@ -0,0 +1,243 @@
<?php
/**
* Tema Gure Ametsa.
*
* - inc/customizer.php Opciones de Apariencia → Personalizar (colores, tipografía, textos…).
* - inc/dynamic-css.php CSS generado a partir de esas opciones.
* - inc/patterns.php Patrones y estilos de bloque para el editor.
*/
defined( 'ABSPATH' ) || exit;
define( 'GA_THEME_VERSION', '2.0.0' );
require_once __DIR__ . '/inc/customizer.php';
require_once __DIR__ . '/inc/dynamic-css.php';
require_once __DIR__ . '/inc/patterns.php';
add_action( 'after_setup_theme', function () {
add_theme_support( 'title-tag' );
add_theme_support( 'post-thumbnails' );
add_theme_support( 'custom-logo', array( 'height' => 120, 'width' => 120, 'flex-width' => true, 'flex-height' => true ) );
add_theme_support( 'html5', array( 'search-form', 'gallery', 'caption', 'style', 'script' ) );
add_theme_support( 'align-wide' );
add_theme_support( 'responsive-embeds' );
add_theme_support( 'editor-styles' );
add_theme_support( 'wp-block-styles' );
add_theme_support( 'customize-selective-refresh-widgets' );
add_editor_style( 'style.css' );
add_image_size( 'ga-card', 640, 544, true );
add_image_size( 'ga-square', 1000, 1000, true );
register_nav_menus( array(
'primary' => 'Menú principal',
'footer' => 'Menú legal (pie)',
) );
} );
add_action( 'wp_enqueue_scripts', function () {
wp_enqueue_style( 'gure-ametsa', get_stylesheet_uri(), array(), GA_THEME_VERSION );
wp_enqueue_script( 'gure-ametsa', get_theme_file_uri( 'assets/js/main.js' ), array(), GA_THEME_VERSION, array( 'strategy' => 'defer', 'in_footer' => true ) );
} );
add_action( 'wp_head', function () {
echo '<meta name="theme-color" content="' . esc_attr( ga_color( 'primary' ) ) . '">' . "\n";
if ( ! has_site_icon() ) {
echo '<link rel="icon" href="' . esc_url( get_theme_file_uri( 'assets/img/favicon.svg' ) ) . '" type="image/svg+xml">' . "\n";
}
}, 1 );
/** Portada en el idioma actual. */
function ga_home_url() {
return function_exists( 'pll_home_url' ) ? pll_home_url() : home_url( '/' );
}
/* ---------- Selector de idioma ---------- */
function ga_language_switcher( $class = 'ga-lang' ) {
if ( ! function_exists( 'pll_the_languages' ) || ! ga_opt( 'header', 'switcher' ) ) {
return;
}
$langs = pll_the_languages( array( 'raw' => 1, 'hide_if_empty' => 0, 'hide_if_no_translation' => 0 ) );
if ( ! $langs ) {
return;
}
echo '<ul class="' . esc_attr( $class ) . '" aria-label="' . esc_attr( ga__( 'Idioma', 'Hizkuntza' ) ) . '">';
foreach ( $langs as $lang ) {
printf(
'<li><a href="%s" hreflang="%s" lang="%s"%s title="%s">%s</a></li>',
esc_url( $lang['url'] ),
esc_attr( $lang['slug'] ),
esc_attr( $lang['slug'] ),
$lang['current_lang'] ? ' aria-current="true" class="is-current"' : '',
esc_attr( $lang['name'] ),
esc_html( strtoupper( $lang['slug'] ) )
);
}
echo '</ul>';
}
/* ---------- Iconos SVG ---------- */
function ga_icon( $name ) {
$icons = array(
'paw' => '<svg viewBox="0 0 64 64" fill="currentColor" aria-hidden="true"><ellipse cx="17" cy="24" rx="6.5" ry="8.5" transform="rotate(-18 17 24)"/><ellipse cx="47" cy="24" rx="6.5" ry="8.5" transform="rotate(18 47 24)"/><ellipse cx="26" cy="12" rx="6" ry="8"/><ellipse cx="38" cy="12" rx="6" ry="8"/><path d="M32 30c-9 0-18 11-18 19 0 6 5 8 9 7 4-1 6-3 9-3s5 2 9 3c4 1 9-1 9-7 0-8-9-19-18-19z"/></svg>',
'mark' => '<svg viewBox="0 0 64 64" aria-hidden="true"><circle cx="32" cy="32" r="32" style="fill:var(--ga-green)"/><g style="fill:var(--ga-cream)"><ellipse cx="21" cy="28" rx="4" ry="5.2" transform="rotate(-18 21 28)"/><ellipse cx="27" cy="20.5" rx="3.6" ry="4.8"/><ellipse cx="35" cy="20.5" rx="3.6" ry="4.8"/><ellipse cx="41" cy="28" rx="4" ry="5.2" transform="rotate(18 41 28)"/></g><path style="fill:var(--ga-red)" d="M31 48.5s-12-7.2-12-14.6c0-3.6 2.8-6.1 6-6.1 2.6 0 4.6 1.5 6 3.6 1.4-2.1 3.4-3.6 6-3.6 3.2 0 6 2.5 6 6.1 0 7.4-12 14.6-12 14.6z"/></svg>',
'instagram' => '<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="5"/><circle cx="12" cy="12" r="4"/><circle cx="17.5" cy="6.5" r="1" fill="currentColor"/></svg>',
'facebook' => '<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor" aria-hidden="true"><path d="M14 8h3V4h-3c-2.8 0-4.5 1.8-4.5 4.6V11H7v4h2.5v9h4v-9h3l.5-4h-3.5V8.8c0-.5.3-.8.5-.8z"/></svg>',
'tiktok' => '<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor" aria-hidden="true"><path d="M16.5 3c.4 2.2 1.8 3.7 4 4v3.2c-1.5 0-2.9-.4-4-1.2v6.2c0 3.4-2.7 5.8-5.8 5.8S5 18.6 5 15.3s2.8-5.9 6.2-5.7v3.3c-1.4-.3-2.9.8-2.9 2.4 0 1.4 1.1 2.5 2.5 2.5s2.5-1.1 2.5-2.5V3h3.2z"/></svg>',
'youtube' => '<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor" aria-hidden="true"><path d="M22 8.2c-.2-1.6-1-2.6-2.6-2.8C17 5 12 5 12 5s-5 0-7.4.4C3 5.6 2.2 6.6 2 8.2 1.8 9.5 1.8 12 1.8 12s0 2.5.2 3.8c.2 1.6 1 2.6 2.6 2.8C7 19 12 19 12 19s5 0 7.4-.4c1.6-.2 2.4-1.2 2.6-2.8.2-1.3.2-3.8.2-3.8s0-2.5-.2-3.8zM10 15V9l5.2 3L10 15z"/></svg>',
'whatsapp' => '<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor" aria-hidden="true"><path d="M12 2a10 10 0 0 0-8.6 15.1L2 22l5-1.3A10 10 0 1 0 12 2zm5.8 14.1c-.2.7-1.4 1.3-2 1.4-.5.1-1.2.1-1.9-.1-.4-.1-1-.3-1.7-.6-3-1.3-4.9-4.3-5.1-4.5-.1-.2-1.2-1.6-1.2-3.1s.8-2.2 1-2.5c.3-.3.6-.4.8-.4h.6c.2 0 .4 0 .6.5l.9 2.1c.1.1.1.3 0 .5l-.3.5-.4.5c-.1.1-.3.3-.1.6.2.3.7 1.2 1.6 1.9 1.1 1 2 1.3 2.3 1.4.3.1.4.1.6-.1l.9-1c.2-.3.4-.2.6-.1l2 1c.3.1.4.2.5.3.1.2.1.8-.2 1.4z"/></svg>',
'phone' => '<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor" aria-hidden="true"><path d="M6.6 10.8a15.1 15.1 0 0 0 6.6 6.6l2.2-2.2c.3-.3.7-.4 1-.2 1.1.4 2.3.6 3.6.6.6 0 1 .4 1 1V20c0 .6-.4 1-1 1A17 17 0 0 1 3 4c0-.6.4-1 1-1h3.5c.6 0 1 .4 1 1 0 1.3.2 2.5.6 3.6.1.3 0 .7-.2 1l-2.3 2.2z"/></svg>',
'mail' => '<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="3" y="5" width="18" height="14" rx="2"/><path d="m3 7 9 6 9-6"/></svg>',
'pin' => '<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M12 21s-7-6.2-7-11.5A7 7 0 0 1 19 9.5C19 14.8 12 21 12 21z"/><circle cx="12" cy="9.5" r="2.5"/></svg>',
'clock' => '<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>',
'arrow' => '<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg>',
'check' => '<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m5 12.5 4.5 4.5L19 7.5"/></svg>',
'menu' => '<svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true"><path d="M4 7h16M4 12h16M4 17h16"/></svg>',
);
return $icons[ $name ] ?? '';
}
/** Enlaces a redes sociales configuradas en el personalizador. */
function ga_social_links( $with_labels = false ) {
$networks = array(
'instagram' => 'Instagram',
'facebook' => 'Facebook',
'tiktok' => 'TikTok',
'youtube' => 'YouTube',
'whatsapp' => 'WhatsApp',
);
$out = '';
foreach ( $networks as $key => $label ) {
$value = ga_info( $key );
if ( ! $value ) {
continue;
}
$href = 'whatsapp' === $key ? 'https://wa.me/' . preg_replace( '/\D/', '', $value ) : $value;
$out .= sprintf(
'<a href="%s" target="_blank" rel="noopener" aria-label="%s">%s%s</a>',
esc_url( $href ),
esc_attr( $label ),
ga_icon( $key ),
$with_labels ? ' ' . esc_html( $label ) : ''
);
}
return $out;
}
function ga_tel_link() {
return 'tel:+34' . preg_replace( '/\D/', '', ga_info( 'telefono' ) );
}
function ga_brand() {
if ( has_custom_logo() ) {
the_custom_logo();
return;
}
printf(
'<a class="ga-brand" href="%s" rel="home"><span class="ga-brand__mark">%s</span><span class="ga-brand__name"><b>%s</b><b>%s</b><small>%s</small></span></a>',
esc_url( ga_home_url() ),
ga_icon( 'mark' ), // SVG estático.
esc_html( ga_opt( 'header', 'brand_line1' ) ),
esc_html( ga_opt( 'header', 'brand_line2' ) ),
esc_html( ga_opt( 'header', 'brand_line3' ) )
);
}
/* ---------- Ayudantes de animales ---------- */
function ga_status_badge( $post_id = null ) {
$post_id = $post_id ?: get_the_ID();
$estado = ga_get( $post_id, 'estado' ) ?: 'disponible';
$label = ga_label( $post_id, 'estado' ) ?: ga__( 'En adopción', 'Adopzioan' );
printf( '<span class="ga-status ga-status--%s">%s</span>', esc_attr( $estado ), esc_html( $label ) );
}
function ga_animal_photo( $size = 'ga-card', $post_id = null ) {
$post_id = $post_id ?: get_the_ID();
if ( has_post_thumbnail( $post_id ) ) {
echo get_the_post_thumbnail( $post_id, $size, array( 'loading' => 'lazy' ) );
} else {
echo '<div class="ga-card__placeholder">' . ga_icon( 'paw' ) . '</div>';
}
}
function ga_species( $post_id = null ) {
$terms = get_the_terms( $post_id ?: get_the_ID(), 'especie' );
return $terms && ! is_wp_error( $terms ) ? $terms[0]->name : '';
}
function ga_plural( $name ) {
if ( 'eu' === ga_lang() ) {
return preg_match( '/k$/i', $name ) ? $name : $name . 'k'; // Txakurra → Txakurrak, Katua → Katuak.
}
return preg_match( '/s$/i', $name ) ? $name : $name . 's';
}
/** «Bien con niños» / «Haurrekin ondo» a partir de la etiqueta «Niños» / «Haurrak». */
function ga_compat_label( $label ) {
$label = mb_strtolower( $label );
if ( 'eu' === ga_lang() ) {
return mb_strtoupper( mb_substr( $label, 0, 1 ) ) . mb_substr( preg_replace( '/ak$/u', 'ekin', $label ), 1 ) . ' ondo';
}
return 'Bien con ' . $label;
}
/** URL de la página de contacto con el animal preseleccionado. */
function ga_adopt_url( $post_id = null ) {
return add_query_arg( 'adoptar', $post_id ?: get_the_ID(), ga_page_url( 'contacto' ) ) . '#formulario';
}
/** Escapa un texto y convierte *entre asteriscos* en palabras resaltadas. */
function ga_highlight( $text ) {
return preg_replace( '/\*(.+?)\*/u', '<span class="ga-hl">$1</span>', esc_html( $text ) );
}
/**
* Encabezado de sección: rayita + antetítulo + título + texto, leídos del personalizador.
*
* @param string $section Sección del registro.
* @param array $args 'center' => bool, 'h' => nivel, 'extra' => HTML a la derecha (p. ej. un botón).
*/
function ga_section_head( $section, $args = array() ) {
$args = wp_parse_args( $args, array( 'center' => false, 'h' => 2, 'extra' => '' ) );
$eyebrow = ga_opt( $section, 'eyebrow' );
$title = ga_opt( $section, 'title' );
$text = ga_opt( $section, 'text' );
if ( ! $eyebrow && ! $title && ! $text ) {
return;
}
printf( '<div class="ga-head%s">', $args['center'] ? ' ga-head--center' : '' );
echo '<div class="ga-head__main">';
if ( $eyebrow ) {
echo '<span class="ga-eyebrow">' . esc_html( $eyebrow ) . '</span>';
}
if ( $title ) {
printf( '<h%1$d>%2$s</h%1$d>', (int) $args['h'], ga_highlight( $title ) );
}
if ( $text ) {
echo '<p class="ga-head__text">' . esc_html( $text ) . '</p>';
}
echo '</div>';
echo $args['extra']; // HTML ya escapado por quien llama.
echo '</div>';
}
/** Lista de líneas de un textarea del personalizador. */
function ga_lines( $text ) {
return array_values( array_filter( array_map( 'trim', explode( "\n", (string) $text ) ) ) );
}
/** URL configurable: vacía → valor por defecto; relativa → se respeta. */
function ga_link( $value, $fallback ) {
return '' !== trim( (string) $value ) ? $value : $fallback;
}
/* Título de archivo sin prefijo "Archivo:" */
add_filter( 'get_the_archive_title_prefix', '__return_empty_string' );
/* Extracto corto */
add_filter( 'excerpt_length', fn() => 24 );
add_filter( 'excerpt_more', fn() => '…' );
/* Formato de fecha según idioma */
add_filter( 'option_date_format', fn( $f ) => is_admin() ? $f : ga__( 'j \\d\\e F \\d\\e Y', 'Y\\(\\e\\)\\k\\o F\\r\\e\\n j\\a' ) );

View File

@@ -0,0 +1,54 @@
<!doctype html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
<?php wp_body_open(); ?>
<a class="skip-link screen-reader-text" href="#contenido"><?php ga_e( 'Saltar al contenido', 'Joan edukira' ); ?></a>
<?php if ( ga_opt( 'header', 'topbar' ) ) : ?>
<div class="ga-topbar">
<div class="ga-wrap">
<?php if ( ga_info( 'horario' ) ) : ?>
<span class="ga-topbar__hours"><?php echo ga_icon( 'clock' ); ?> <?php echo esc_html( ga_info( 'horario' ) ); ?></span>
<?php endif; ?>
<span class="ga-topbar__social"><?php echo ga_social_links(); // Escapado en la función. ?></span>
</div>
</div>
<?php endif; ?>
<header class="ga-header">
<div class="ga-wrap">
<?php ga_brand(); ?>
<nav id="ga-nav" class="ga-nav" aria-label="<?php echo esc_attr( ga__( 'Menú principal', 'Menu nagusia' ) ); ?>">
<?php
wp_nav_menu( array(
'theme_location' => 'primary',
'container' => false,
'fallback_cb' => false,
'depth' => 1,
) );
?>
</nav>
<div class="ga-header__actions">
<?php if ( ga_opt( 'header', 'phone' ) && ga_info( 'telefono' ) ) : ?>
<a class="ga-header__phone" href="<?php echo esc_attr( ga_tel_link() ); ?>"><?php echo ga_icon( 'phone' ); ?> <span><?php echo esc_html( ga_info( 'telefono' ) ); ?></span></a>
<?php endif; ?>
<?php ga_language_switcher( 'ga-lang ga-lang--header' ); ?>
<?php if ( ga_opt( 'header', 'cta2' ) ) : ?>
<a class="ga-btn ga-btn--small ga-btn--accent ga-header__cta2" href="<?php echo esc_url( ga_link( ga_opt( 'header', 'cta2_url' ), ga_page_url( 'colabora', '#donaciones' ) ) ); ?>"><?php ga_opt_e( 'header', 'cta2' ); ?></a>
<?php endif; ?>
<?php if ( ga_opt( 'header', 'cta1' ) ) : ?>
<a class="ga-btn ga-btn--small ga-btn--primary ga-header__cta" href="<?php echo esc_url( ga_link( ga_opt( 'header', 'cta1_url' ), get_post_type_archive_link( 'animal' ) ) ); ?>"><?php ga_opt_e( 'header', 'cta1' ); ?></a>
<?php endif; ?>
<button class="ga-menu-toggle" aria-controls="ga-nav" aria-expanded="false"><?php echo ga_icon( 'menu' ); ?> <span><?php ga_e( 'Menú', 'Menua' ); ?></span></button>
</div>
</div>
</header>
<main id="contenido">

View File

@@ -0,0 +1,191 @@
<?php
/**
* Personalizador: colores, tipografías, cabecera, contacto, portada y pie.
*
* Todas las opciones se definen en ga_customizer_registry(). Los textos marcados
* como 'i18n' se guardan dos veces: en castellano (clave) y en euskera (clave + '_eu').
*/
defined( 'ABSPATH' ) || exit;
require_once __DIR__ . '/registry.php';
/** Color efectivo: el de la paleta elegida o, si es «Personalizada», el elegido a mano. */
function ga_color( $key ) {
$palette = ga_opt( 'colors', 'palette' );
$palettes = ga_palettes();
if ( isset( $palettes[ $palette ][ $key ] ) ) {
return $palettes[ $palette ][ $key ];
}
return ga_opt( 'colors', $key );
}
/** Clave del theme_mod para un campo (y un idioma). */
function ga_mod_key( $section, $field, $lang = 'es' ) {
return "ga_{$section}_{$field}" . ( 'eu' === $lang ? '_eu' : '' );
}
/** Valor por defecto de un campo. */
function ga_field_default( $field, $lang = 'es' ) {
if ( ! empty( $field['i18n'] ) ) {
return $field[ $lang ] ?? '';
}
return $field['default'] ?? '';
}
/**
* Valor de una opción. Los textos 'i18n' se devuelven en el idioma actual.
*/
function ga_opt( $section, $field ) {
$registry = ga_customizer_registry();
$def = $registry[ $section ]['fields'][ $field ] ?? null;
if ( ! $def ) {
return '';
}
$lang = ! empty( $def['i18n'] ) ? ga_lang() : 'es';
$key = ga_mod_key( $section, $field, $lang );
return get_theme_mod( $key, ga_field_default( $def, $lang ) );
}
/** Imprime un texto del personalizador escapado. */
function ga_opt_e( $section, $field ) {
echo esc_html( ga_opt( $section, $field ) );
}
/** Secciones de portada visibles, ordenadas. */
function ga_home_sections() {
$sections = array();
foreach ( ga_customizer_registry() as $id => $section ) {
if ( ! empty( $section['section'] ) && ga_opt( $id, 'show' ) ) {
$sections[ $id ] = (int) ga_opt( $id, 'order' );
}
}
asort( $sections );
return array_keys( $sections );
}
/* Los datos de contacto y redes del personalizador sustituyen a los predeterminados. */
add_filter( 'ga_info', function ( $info ) {
foreach ( array( 'direccion', 'maps', 'telefono', 'email', 'horario' ) as $key ) {
$info[ $key ] = ga_opt( 'contact', $key );
}
foreach ( array( 'instagram', 'facebook', 'tiktok', 'youtube', 'whatsapp' ) as $key ) {
$info[ $key ] = ga_opt( 'social', $key );
}
return $info;
} );
/* ---------- Registro en el personalizador ---------- */
add_action( 'customize_register', function ( WP_Customize_Manager $c ) {
$c->add_panel( 'ga_design', array( 'title' => 'Diseño (Gure Ametsa)', 'priority' => 25 ) );
$c->add_panel( 'ga_info', array( 'title' => 'Contacto y redes', 'priority' => 26 ) );
$c->add_panel( 'ga_home', array(
'title' => 'Portada',
'priority' => 27,
'description' => 'Muestra, oculta y reordena las secciones de la portada. Los textos se escriben en castellano y en euskera.',
) );
$sanitizers = array(
'text' => 'sanitize_text_field',
'textarea' => 'sanitize_textarea_field',
'url' => 'esc_url_raw',
'email' => 'sanitize_email',
'color' => 'sanitize_hex_color',
'checkbox' => fn( $v ) => (bool) $v,
'number' => 'absint',
'range' => 'absint',
'image' => 'absint',
'video' => 'absint',
);
foreach ( ga_customizer_registry() as $sid => $section ) {
$section_id = "ga_section_$sid";
$c->add_section( $section_id, array(
'title' => $section['title'],
'panel' => $section['panel'],
'description' => $section['description'] ?? '',
) );
foreach ( $section['fields'] as $fid => $field ) {
$langs = ! empty( $field['i18n'] ) ? array( 'es', 'eu' ) : array( 'es' );
foreach ( $langs as $lang ) {
$key = ga_mod_key( $sid, $fid, $lang );
$sanitize = $sanitizers[ $field['type'] ] ?? null;
if ( 'select' === $field['type'] ) {
$choices = $field['choices'];
$default = $field['default'];
$sanitize = fn( $v ) => array_key_exists( $v, $choices ) ? $v : $default;
}
$c->add_setting( $key, array(
'default' => ga_field_default( $field, $lang ),
'sanitize_callback' => $sanitize,
) );
$label = $field['label'] . ( ! empty( $field['i18n'] ) ? ( 'eu' === $lang ? ' · EU' : ' · ES' ) : '' );
$args = array(
'label' => $label,
'section' => $section_id,
'description' => $field['description'] ?? '',
'priority' => empty( $field['i18n'] ) ? 50 : ( 'eu' === $lang ? 200 : 100 ),
);
switch ( $field['type'] ) {
case 'color':
$c->add_control( new WP_Customize_Color_Control( $c, $key, $args ) );
break;
case 'image':
case 'video':
$c->add_control( new WP_Customize_Media_Control( $c, $key, $args + array( 'mime_type' => $field['type'] ) ) );
break;
case 'range':
case 'number':
$args['type'] = $field['type'];
$args['input_attrs'] = array_filter( array(
'min' => $field['min'] ?? null,
'max' => $field['max'] ?? null,
'step' => $field['step'] ?? 1,
), fn( $v ) => null !== $v );
if ( 'range' === $field['type'] ) {
$args['description'] = trim( $args['description'] . ' Por defecto: ' . $field['default'] . '.' );
}
$c->add_control( $key, $args );
break;
case 'select':
$c->add_control( $key, $args + array( 'type' => 'select', 'choices' => $field['choices'] ) );
break;
default:
$c->add_control( $key, $args + array( 'type' => $field['type'] ) );
}
}
}
// Separador visual entre castellano y euskera.
$has_i18n = (bool) array_filter( $section['fields'], fn( $f ) => ! empty( $f['i18n'] ) );
if ( $has_i18n ) {
foreach ( array( 'es' => array( 99, 'Castellano' ), 'eu' => array( 199, 'Euskara' ) ) as $lang => [ $priority, $title ] ) {
$c->add_setting( "ga_sep_{$sid}_{$lang}", array( 'sanitize_callback' => '__return_empty_string' ) );
$c->add_control( new GA_Customize_Heading_Control( $c, "ga_sep_{$sid}_{$lang}", array(
'label' => $title,
'section' => $section_id,
'priority' => $priority,
) ) );
}
}
}
} );
add_action( 'customize_register', function () {
if ( class_exists( 'GA_Customize_Heading_Control' ) ) {
return;
}
/** Encabezado sin campo, para separar idiomas. */
class GA_Customize_Heading_Control extends WP_Customize_Control {
public $type = 'ga-heading';
public function render_content() {
printf(
'<h3 style="margin:18px 0 4px;padding:6px 10px;background:#1e5b3e;color:#fff;border-radius:4px;font-size:13px;letter-spacing:.06em;text-transform:uppercase">%s</h3>',
esc_html( $this->label )
);
}
}
}, 1 );

View File

@@ -0,0 +1,105 @@
<?php
/**
* CSS generado a partir del personalizador: colores, tipografías, tamaños.
*/
defined( 'ABSPATH' ) || exit;
/** Luminancia relativa (WCAG) de un color hexadecimal. */
function ga_luminance( $hex ) {
$hex = ltrim( (string) $hex, '#' );
if ( 3 === strlen( $hex ) ) {
$hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
}
if ( 6 !== strlen( $hex ) ) {
return 1;
}
$channels = array_map( function ( $c ) {
$c = hexdec( $c ) / 255;
return $c <= 0.03928 ? $c / 12.92 : ( ( $c + 0.055 ) / 1.055 ) ** 2.4;
}, str_split( $hex, 2 ) );
return 0.2126 * $channels[0] + 0.7152 * $channels[1] + 0.0722 * $channels[2];
}
/** Texto legible (blanco o el color de texto) sobre un fondo dado. */
function ga_readable_on( $background ) {
$ink = ga_color( 'text' );
$lum = ga_luminance( $background );
$contrast_white = 1.05 / ( $lum + 0.05 );
$contrast_ink = ( $lum + 0.05 ) / ( ga_luminance( $ink ) + 0.05 );
return $contrast_white >= $contrast_ink ? '#ffffff' : $ink;
}
function ga_dynamic_css() {
$fonts = ga_fonts();
$heading = $fonts[ ga_opt( 'typography', 'heading_font' ) ] ?? $fonts['fraunces'];
$body = $fonts[ ga_opt( 'typography', 'body_font' ) ] ?? $fonts['karla'];
$css = '';
foreach ( array_unique( array_filter( array( $heading['file'] ?? '', $body['file'] ?? '' ) ) ) as $file ) {
$font = current( wp_list_filter( $fonts, array( 'file' => $file ) ) );
$css .= sprintf(
'@font-face{font-family:"%s";src:url("%s") format("woff2");font-weight:100 900;font-style:normal;font-display:swap;}',
$font['family'],
esc_url( get_theme_file_uri( "assets/fonts/$file.woff2" ) )
);
}
$accent = ga_color( 'accent' );
$primary = ga_color( 'primary' );
$vars = array(
'--ga-green' => $primary,
'--ga-red' => $accent,
'--ga-cream' => ga_color( 'background' ),
'--ga-sand' => ga_color( 'surface' ),
'--ga-ink' => ga_color( 'text' ),
'--ga-on-red' => ga_readable_on( $accent ),
'--ga-on-primary' => ga_readable_on( $primary ),
'--ga-serif' => $heading['stack'],
'--ga-sans' => $body['stack'],
'--ga-heading-weight' => (int) ga_opt( 'typography', 'heading_weight' ),
'--ga-radius' => (int) ga_opt( 'typography', 'radius' ) . 'px',
'--ga-size' => (int) ga_opt( 'typography', 'base_size' ) . 'px',
);
$css .= ':root{';
foreach ( $vars as $name => $value ) {
if ( '' !== $value && null !== $value ) {
$css .= $name . ':' . wp_strip_all_tags( (string) $value ) . ';';
}
}
$css .= '}';
return $css;
}
add_action( 'wp_enqueue_scripts', function () {
wp_add_inline_style( 'gure-ametsa', ga_dynamic_css() );
}, 20 );
/* El editor de bloques usa los mismos colores y tipografías. */
add_filter( 'block_editor_settings_all', function ( $settings ) {
$settings['styles'][] = array( 'css' => ga_dynamic_css() );
return $settings;
} );
/* Paleta del editor = colores del tema. */
add_action( 'after_setup_theme', function () {
add_theme_support( 'editor-color-palette', array(
array( 'name' => 'Principal', 'slug' => 'ga-green', 'color' => ga_color( 'primary' ) ),
array( 'name' => 'Acento', 'slug' => 'ga-red', 'color' => ga_color( 'accent' ) ),
array( 'name' => 'Secciones', 'slug' => 'ga-sand', 'color' => ga_color( 'surface' ) ),
array( 'name' => 'Texto', 'slug' => 'ga-ink', 'color' => ga_color( 'text' ) ),
array( 'name' => 'Blanco', 'slug' => 'white', 'color' => '#ffffff' ),
) );
}, 20 );
/* Clases en <body> según opciones de cabecera. */
add_filter( 'body_class', function ( $classes ) {
if ( ga_opt( 'header', 'sticky' ) ) {
$classes[] = 'ga-sticky-header';
}
if ( ga_opt( 'header', 'highlight_first' ) ) {
$classes[] = 'ga-nav-highlight';
}
return $classes;
} );

View File

@@ -0,0 +1,302 @@
<?php
/**
* Patrones de bloques (secciones prediseñadas) y estilos de bloque propios.
*
* Cada patrón se registra en castellano y en euskera. En el editor aparecen en
* Añadir bloque (+) → Patrones → «Gure Ametsa».
*/
defined( 'ABSPATH' ) || exit;
/* ---------- Estilos de bloque (panel lateral «Estilos» del editor) ---------- */
add_action( 'init', function () {
$styles = array(
'core/group' => array(
'ga-arena' => 'Fondo arena',
'ga-verde' => 'Fondo principal',
'ga-tarjeta' => 'Tarjeta',
'ga-aviso' => 'Aviso destacado',
),
'core/paragraph' => array(
'ga-antetitulo' => 'Antetítulo',
'ga-entradilla' => 'Entradilla',
),
'core/image' => array(
'ga-redondeada' => 'Esquinas redondeadas',
'ga-arco' => 'Arco',
),
'core/list' => array(
'ga-check' => 'Con marcas ✓',
'ga-pasos' => 'Pasos numerados',
'ga-limpia' => 'Sin viñetas',
),
'core/quote' => array(
'ga-testimonio' => 'Testimonio',
),
'core/columns' => array(
'ga-tarjetas' => 'Columnas como tarjetas',
),
);
foreach ( $styles as $block => $list ) {
foreach ( $list as $name => $label ) {
register_block_style( $block, array( 'name' => $name, 'label' => $label ) );
}
}
} );
/* ---------- Patrones ---------- */
add_action( 'init', function () {
register_block_pattern_category( 'gure-ametsa', array( 'label' => 'Gure Ametsa' ) );
foreach ( array( 'es', 'eu' ) as $lang ) {
$t = fn( $es, $eu ) => 'eu' === $lang ? $eu : $es;
$url = fn( $slug_es, $slug_eu ) => 'eu' === $lang ? "/eu/$slug_eu/" : "/$slug_es/";
$sfx = 'eu' === $lang ? ' (euskara)' : '';
foreach ( ga_pattern_definitions( $t, $url ) as $slug => [ $title, $description, $content ] ) {
register_block_pattern( "gure-ametsa/$slug-$lang", array(
'title' => $title . $sfx,
'description' => $description,
'categories' => array( 'gure-ametsa' ),
'content' => $content,
) );
}
}
} );
/** Botón de bloque. */
function ga_p_button( $text, $href, $outline = false ) {
$attrs = $outline ? ' {"className":"is-style-outline"}' : '';
$class = $outline ? ' is-style-outline' : '';
return "<!-- wp:button$attrs -->\n<div class=\"wp-block-button$class\"><a class=\"wp-block-button__link wp-element-button\" href=\"" . esc_url( $href ) . "\">$text</a></div>\n<!-- /wp:button -->";
}
function ga_p_buttons( array $buttons, $center = false ) {
$attrs = $center ? ' {"layout":{"type":"flex","justifyContent":"center"}}' : '';
return "<!-- wp:buttons$attrs -->\n<div class=\"wp-block-buttons\">" . implode( "\n\n", $buttons ) . "</div>\n<!-- /wp:buttons -->";
}
function ga_p_heading( $text, $level = 2, $center = false, $anchor = '' ) {
$attrs = array();
if ( 2 !== $level ) {
$attrs['level'] = $level;
}
if ( $center ) {
$attrs['textAlign'] = 'center';
}
if ( $anchor ) {
$attrs['anchor'] = $anchor;
}
$json = $attrs ? ' ' . wp_json_encode( $attrs ) : '';
$class = 'wp-block-heading' . ( $center ? ' has-text-align-center' : '' );
$id = $anchor ? ' id="' . esc_attr( $anchor ) . '"' : '';
return "<!-- wp:heading$json -->\n<h$level class=\"$class\"$id>$text</h$level>\n<!-- /wp:heading -->";
}
function ga_p_paragraph( $text, $style = '', $center = false ) {
$attrs = array();
if ( $center ) {
$attrs['align'] = 'center';
}
if ( $style ) {
$attrs['className'] = "is-style-$style";
}
$json = $attrs ? ' ' . wp_json_encode( $attrs ) : '';
$classes = trim( ( $center ? 'has-text-align-center ' : '' ) . ( $style ? "is-style-$style" : '' ) );
$class = $classes ? " class=\"$classes\"" : '';
return "<!-- wp:paragraph$json -->\n<p$class>$text</p>\n<!-- /wp:paragraph -->";
}
function ga_p_list( array $items, $style = '', $ordered = false ) {
$attrs = array();
if ( $ordered ) {
$attrs['ordered'] = true;
}
if ( $style ) {
$attrs['className'] = "is-style-$style";
}
$json = $attrs ? ' ' . wp_json_encode( $attrs ) : '';
$tag = $ordered ? 'ol' : 'ul';
$lis = array_map( fn( $i ) => "<!-- wp:list-item -->\n<li>$i</li>\n<!-- /wp:list-item -->", $items );
$cls = 'wp-block-list' . ( $style ? " is-style-$style" : '' );
return "<!-- wp:list$json -->\n<$tag class=\"$cls\">" . implode( "\n\n", $lis ) . "</$tag>\n<!-- /wp:list -->";
}
function ga_p_group( $inner, $style = '', $full = false ) {
$attrs = array();
if ( $full ) {
$attrs['align'] = 'full';
}
$classes = array_filter( array( $style ? "is-style-$style" : '', $full ? 'ga-pad' : '' ) );
if ( $classes ) {
$attrs['className'] = implode( ' ', $classes );
}
$attrs['layout'] = array( 'type' => 'constrained' );
$html_classes = implode( ' ', array_filter( array( 'wp-block-group', $full ? 'alignfull' : '', ...$classes ) ) );
return '<!-- wp:group ' . wp_json_encode( $attrs ) . " -->\n<div class=\"$html_classes\">$inner</div>\n<!-- /wp:group -->";
}
function ga_p_columns( array $columns, $style = '', $wide = true ) {
$attrs = array();
if ( $wide ) {
$attrs['align'] = 'wide';
}
if ( $style ) {
$attrs['className'] = "is-style-$style";
}
$json = $attrs ? ' ' . wp_json_encode( $attrs ) : '';
$class = trim( 'wp-block-columns' . ( $wide ? ' alignwide' : '' ) . ( $style ? " is-style-$style" : '' ) );
$cols = array_map( fn( $c ) => "<!-- wp:column -->\n<div class=\"wp-block-column\">$c</div>\n<!-- /wp:column -->", $columns );
return "<!-- wp:columns$json -->\n<div class=\"$class\">" . implode( "\n\n", $cols ) . "</div>\n<!-- /wp:columns -->";
}
function ga_p_shortcode( $code ) {
return "<!-- wp:shortcode -->\n$code\n<!-- /wp:shortcode -->";
}
/**
* Definición de patrones: slug => [título, descripción, contenido].
*
* @param callable $t Traductor fn( $es, $eu ).
* @param callable $url URL de página fn( $slug_es, $slug_eu ).
*/
function ga_pattern_definitions( $t, $url ) {
$adopta = $url( 'adopta', 'adopta' );
$contacto = $url( 'contacto', 'harremanetarako' ) . '#formulario';
$colabora = $url( 'colabora', 'lagundu' );
return array(
'portada' => array(
$t( 'Portada con imagen', 'Azala irudiarekin' ),
'Bloque de bienvenida a ancho completo con título, texto, botones e imagen.',
ga_p_group(
ga_p_columns( array(
ga_p_paragraph( $t( 'Protectora · Hondarribia', 'Babeslekua · Hondarribia' ), 'ga-antetitulo' )
. "\n\n" . ga_p_heading( $t( 'Adopta y cambia dos mundos', 'Adoptatu eta bi mundu aldatu' ) )
. "\n\n" . ga_p_paragraph( $t( 'Rescatamos, cuidamos y buscamos una segunda oportunidad para perros y gatos abandonados.', 'Abandonatutako txakur eta katuak erreskatatu, zaindu eta bigarren aukera bat bilatzen diegu.' ), 'ga-entradilla' )
. "\n\n" . ga_p_buttons( array(
ga_p_button( $t( 'Conoce a los animales', 'Ezagutu animaliak' ), $adopta ),
ga_p_button( $t( 'Quiero ayudar', 'Lagundu nahi dut' ), $colabora, true ),
) ),
"<!-- wp:image {\"sizeSlug\":\"large\",\"className\":\"is-style-ga-arco\"} -->\n<figure class=\"wp-block-image size-large is-style-ga-arco\"><img alt=\"\"/></figure>\n<!-- /wp:image -->",
) ),
'ga-arena',
true
),
),
'llamada' => array(
$t( 'Llamada a la acción', 'Ekintzarako deia' ),
'Franja de color con título, texto y botón centrados.',
ga_p_group(
ga_p_heading( $t( '¿Tienes sitio en casa… y en tu corazón?', 'Lekua duzu etxean… eta bihotzean?' ), 2, true )
. "\n\n" . ga_p_paragraph( $t( 'Cada adopción deja una plaza libre para rescatar a otro animal.', 'Adopzio bakoitzak beste animalia bat erreskatatzeko lekua uzten du.' ), '', true )
. "\n\n" . ga_p_buttons( array( ga_p_button( $t( 'Quiero adoptar', 'Adoptatu nahi dut' ), $contacto ) ), true ),
'ga-verde',
true
),
),
'tarjetas' => array(
$t( 'Tres tarjetas', 'Hiru txartel' ),
'Tres columnas con icono, título y texto.',
ga_p_columns( array(
ga_p_paragraph( '🏡', 'ga-antetitulo' ) . "\n\n" . ga_p_heading( $t( 'Adopta', 'Adoptatu' ), 3 ) . "\n\n" . ga_p_paragraph( $t( 'Dale un hogar para siempre a un perro o un gato.', 'Eman betiko etxe bat txakur edo katu bati.' ) ),
ga_p_paragraph( '🤝', 'ga-antetitulo' ) . "\n\n" . ga_p_heading( $t( 'Acoge', 'Harrera egin' ), 3 ) . "\n\n" . ga_p_paragraph( $t( 'Abre tu casa de forma temporal a quien más lo necesita.', 'Ireki zure etxea aldi baterako gehien behar duenari.' ) ),
ga_p_paragraph( '💚', 'ga-antetitulo' ) . "\n\n" . ga_p_heading( $t( 'Dona', 'Egin dohaintza' ), 3 ) . "\n\n" . ga_p_paragraph( $t( 'Pienso, mantas o material veterinario.', 'Pentsua, mantak edo albaitaritza-materiala.' ) ),
), 'ga-tarjetas' ),
),
'pasos' => array(
$t( 'Pasos numerados', 'Urrats zenbakidunak' ),
'Lista de pasos con números grandes.',
ga_p_heading( $t( '¿Cómo adoptar?', 'Nola adoptatu?' ) )
. "\n\n" . ga_p_list( array(
$t( '<strong>Elige.</strong> Mira las fichas o ven a conocernos.', '<strong>Aukeratu.</strong> Begiratu fitxak edo etorri gu ezagutzera.' ),
$t( '<strong>Escríbenos.</strong> Hablaremos sobre tu casa y tu rutina.', '<strong>Idatzi iezaguzu.</strong> Zure etxeaz eta ohiturez hitz egingo dugu.' ),
$t( '<strong>Conócelo.</strong> Visitas y paseos sin prisas.', '<strong>Ezagutu.</strong> Bisitak eta ibilaldiak, presarik gabe.' ),
$t( '<strong>¡A casa!</strong> Firmamos la adopción y seguimos a tu lado.', '<strong>Etxera!</strong> Adopzioa sinatu eta zure ondoan jarraituko dugu.' ),
), 'ga-pasos', true ),
),
'animales' => array(
$t( 'Animales en adopción', 'Adopzioko animaliak' ),
'Rejilla automática con los últimos animales en adopción.',
ga_p_heading( $t( 'Te están esperando', 'Zure zain daude' ) )
. "\n\n" . ga_p_shortcode( '[ga_animales numero="4"]' )
. "\n\n" . ga_p_buttons( array( ga_p_button( $t( 'Ver todos', 'Denak ikusi' ), $adopta ) ) ),
),
'carrusel' => array(
$t( 'Carrusel de animales', 'Animalien karrusela' ),
'Animales en adopción en un carrusel que se desliza.',
ga_p_heading( $t( 'Te están esperando', 'Zure zain daude' ) )
. "\n\n" . ga_p_shortcode( '[ga_animales numero="10" vista="carrusel"]' )
. "\n\n" . ga_p_buttons( array( ga_p_button( $t( 'Ver todos', 'Denak ikusi' ), $adopta ) ) ),
),
'urgentes' => array(
$t( 'Adopciones urgentes', 'Adopzio premiazkoak' ),
'Rejilla automática solo con urgentes y animales que buscan acogida.',
ga_p_group(
ga_p_heading( $t( 'Nos necesitan ya', 'Orain behar gaituzte' ) )
. "\n\n" . ga_p_paragraph( $t( 'Mayores, convalecientes o que llevan demasiado tiempo esperando.', 'Adinekoak, gaixorik daudenak edo denbora gehiegi daramatenak zain.' ) )
. "\n\n" . ga_p_shortcode( '[ga_animales numero="3" estado="urgente,acogida"]' ),
'ga-aviso'
),
),
'imagen-texto' => array(
$t( 'Imagen y texto', 'Irudia eta testua' ),
'Imagen a un lado y texto al otro.',
ga_p_columns( array(
"<!-- wp:image {\"sizeSlug\":\"large\",\"className\":\"is-style-ga-redondeada\"} -->\n<figure class=\"wp-block-image size-large is-style-ga-redondeada\"><img alt=\"\"/></figure>\n<!-- /wp:image -->",
ga_p_paragraph( $t( 'Nuestra historia', 'Gure historia' ), 'ga-antetitulo' )
. "\n\n" . ga_p_heading( $t( 'Más de 25 años cuidando', '25 urte baino gehiago zaintzen' ) )
. "\n\n" . ga_p_paragraph( $t( 'Escribe aquí vuestra historia, un rescate especial o cómo es el día a día en el refugio.', 'Idatzi hemen zuen historia, erreskate berezi bat edo babeslekuko eguneroko bizitza.' ) ),
) ),
),
'testimonio' => array(
$t( 'Testimonio de adopción', 'Adopzio-testigantza' ),
'Cita destacada de una familia adoptante.',
"<!-- wp:quote {\"className\":\"is-style-ga-testimonio\"} -->\n<blockquote class=\"wp-block-quote is-style-ga-testimonio\">"
. ga_p_paragraph( $t( 'Llegó asustado y hoy es el rey del sofá. Adoptarle ha sido lo mejor que nos ha pasado.', 'Beldurtuta iritsi zen eta gaur sofako erregea da. Adoptatzea gertatu zaigun onena izan da.' ) )
. '<cite>' . $t( 'Familia de Txuri, Irun', 'Txuriren familia, Irun' ) . "</cite></blockquote>\n<!-- /wp:quote -->",
),
'preguntas' => array(
$t( 'Preguntas frecuentes', 'Ohiko galderak' ),
'Preguntas desplegables.',
ga_p_heading( $t( 'Preguntas frecuentes', 'Ohiko galderak' ) )
. "\n\n" . implode( "\n\n", array_map(
fn( $qa ) => "<!-- wp:details -->\n<details class=\"wp-block-details\"><summary>{$qa[0]}</summary>" . ga_p_paragraph( $qa[1] ) . "</details>\n<!-- /wp:details -->",
array(
array( $t( '¿Cuánto cuesta adoptar?', 'Zenbat balio du adoptatzeak?' ), $t( 'Escribe aquí la respuesta.', 'Idatzi hemen erantzuna.' ) ),
array( $t( '¿Puedo adoptar si vivo en un piso?', 'Adopta dezaket pisu batean bizi banaiz?' ), $t( 'Escribe aquí la respuesta.', 'Idatzi hemen erantzuna.' ) ),
array( $t( '¿Hacéis seguimiento después?', 'Jarraipena egiten duzue gero?' ), $t( 'Escribe aquí la respuesta.', 'Idatzi hemen erantzuna.' ) ),
)
) ),
),
'donaciones' => array(
$t( 'Qué necesitamos', 'Zer behar dugu' ),
'Tarjeta con lista de necesidades y botón.',
ga_p_group(
ga_p_heading( $t( 'Qué necesitamos ahora', 'Zer behar dugun orain' ), 3 )
. "\n\n" . ga_p_list( array(
$t( 'Pienso para cachorros', 'Kumeentzako pentsua' ),
$t( 'Arena para gatos', 'Katuentzako harea' ),
$t( 'Mantas y toallas', 'Mantak eta eskuoihalak' ),
), 'ga-check' )
. "\n\n" . ga_p_buttons( array( ga_p_button( $t( 'Quiero colaborar', 'Lagundu nahi dut' ), $contacto ) ) ),
'ga-tarjeta'
),
),
'contacto' => array(
$t( 'Contacto con formulario', 'Harremana formularioarekin' ),
'Datos de contacto y formulario en dos columnas.',
ga_p_columns( array(
ga_p_heading( $t( 'Ven a vernos', 'Etorri gu ikustera' ), 3 )
. "\n\n" . ga_p_list( array(
'📍 Jaizubia, 44 · 20280 Hondarribia',
'📞 <a href="tel:+34943645279">943 64 52 79</a>',
'✉️ <a href="mailto:hola@gureametsabilagun.org">hola@gureametsabilagun.org</a>',
$t( '🕙 L–V: 10:00–13:00 y 14:00–19:00', '🕙 Al–Or: 10:00–13:00 eta 14:00–19:00' ),
), 'ga-limpia' ),
ga_p_heading( $t( 'Escríbenos', 'Idatzi iezaguzu' ), 3, false, 'formulario' )
. "\n\n" . ga_p_shortcode( '[ga_contacto]' ),
) ),
),
);
}

View File

@@ -0,0 +1,437 @@
<?php
/**
* Registro de opciones del tema (Apariencia → Personalizar).
*
* Cada sección: title, panel, fields. Cada campo: type (text, textarea, url, email, color,
* checkbox, number, range, select, image, video), label, default (o es/eu si 'i18n' => true).
* Las secciones con 'section' => true son bloques de la portada (se pueden ocultar y reordenar).
*/
defined( 'ABSPATH' ) || exit;
/** Tipografías incluidas en el tema (assets/fonts) y de sistema. */
function ga_fonts() {
return array(
'fraunces' => array( 'label' => 'Fraunces (serif, con carácter)', 'file' => 'fraunces', 'family' => 'Fraunces', 'stack' => 'Fraunces, Georgia, serif' ),
'karla' => array( 'label' => 'Karla (sans, cercana)', 'file' => 'karla', 'family' => 'Karla', 'stack' => 'Karla, system-ui, sans-serif' ),
'lora' => array( 'label' => 'Lora (serif, clásica)', 'file' => 'lora', 'family' => 'Lora', 'stack' => 'Lora, Georgia, serif' ),
'playfair' => array( 'label' => 'Playfair Display (serif, elegante)', 'file' => 'playfair-display', 'family' => 'Playfair Display', 'stack' => '"Playfair Display", Georgia, serif' ),
'nunito' => array( 'label' => 'Nunito (redondeada, amable)', 'file' => 'nunito', 'family' => 'Nunito', 'stack' => 'Nunito, system-ui, sans-serif' ),
'inter' => array( 'label' => 'Inter (moderna, muy legible)', 'file' => 'inter', 'family' => 'Inter', 'stack' => 'Inter, system-ui, sans-serif' ),
'opensans' => array( 'label' => 'Open Sans (neutra)', 'file' => 'open-sans', 'family' => 'Open Sans', 'stack' => '"Open Sans", system-ui, sans-serif' ),
'system-serif' => array( 'label' => 'Serif del sistema', 'stack' => '"Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif' ),
'system-sans' => array( 'label' => 'Sans del sistema', 'stack' => '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif' ),
);
}
/** Paletas rápidas. 'custom' usa los colores elegidos a mano. */
function ga_palettes() {
return array(
'ciruela' => array(
'label' => 'Ciruela y mostaza',
'primary' => '#5b2c4e',
'accent' => '#e8a317',
'background' => '#fdf8f1',
'surface' => '#f5ead9',
'text' => '#241a21',
),
'verde' => array(
'label' => 'Verde y rojo',
'primary' => '#1e5b3e',
'accent' => '#c23b2a',
'background' => '#fffcf6',
'surface' => '#f7f1e6',
'text' => '#1d2721',
),
'mar' => array(
'label' => 'Azul mar y coral',
'primary' => '#1f4e6b',
'accent' => '#f07b5a',
'background' => '#fbfaf7',
'surface' => '#eaf1f2',
'text' => '#1b2a33',
),
'bosque' => array(
'label' => 'Bosque y teja',
'primary' => '#2f4a34',
'accent' => '#d9822b',
'background' => '#fbf8f2',
'surface' => '#efe8da',
'text' => '#20261f',
),
);
}
function ga_customizer_registry() {
static $registry = null;
if ( null !== $registry ) {
return $registry;
}
$t = fn( $label, $es, $eu, $type = 'text' ) => array( 'type' => $type, 'label' => $label, 'i18n' => true, 'es' => $es, 'eu' => $eu );
$step = function ( $n, $es_t, $es_d, $eu_t, $eu_d ) use ( $t ) {
return array(
"step{$n}_title" => $t( "Paso $n · título", $es_t, $eu_t ),
"step{$n}_text" => $t( "Paso $n · texto", $es_d, $eu_d, 'textarea' ),
);
};
$door = function ( $n, $kicker, $title, $text, $link ) use ( $t ) {
return array(
"door{$n}_kicker" => $t( "Puerta $n · etiqueta", $kicker[0], $kicker[1] ),
"door{$n}_title" => $t( "Puerta $n · título", $title[0], $title[1] ),
"door{$n}_text" => $t( "Puerta $n · texto", $text[0], $text[1] ),
"door{$n}_link" => $t( "Puerta $n · enlace", $link[0], $link[1] ),
);
};
$card = function ( $prefix, $n, $title, $text ) use ( $t ) {
return array(
"{$prefix}{$n}_title" => $t( ucfirst( $prefix ) . " $n · título (vacío = ocultar)", $title[0], $title[1] ),
"{$prefix}{$n}_text" => $t( ucfirst( $prefix ) . " $n · texto", $text[0], $text[1], 'textarea' ),
);
};
$qa = function ( $n, $es_q, $es_a, $eu_q, $eu_a ) use ( $t ) {
return array(
"q{$n}" => $t( "Pregunta $n (vacío = ocultar)", $es_q, $eu_q ),
"a{$n}" => $t( "Respuesta $n", $es_a, $eu_a, 'textarea' ),
);
};
$palette_choices = array_map( fn( $p ) => $p['label'], ga_palettes() ) + array( 'custom' => 'Personalizada (colores de abajo)' );
$default = ga_palettes()['ciruela'];
$registry = array(
/* ================= Diseño ================= */
'colors' => array(
'panel' => 'ga_design',
'title' => 'Colores',
'fields' => array(
'palette' => array( 'type' => 'select', 'label' => 'Paleta', 'default' => 'ciruela', 'choices' => $palette_choices, 'description' => 'Elige una paleta lista, o «Personalizada» para usar los colores de abajo.' ),
'primary' => array( 'type' => 'color', 'label' => 'Color principal', 'default' => $default['primary'], 'description' => 'Títulos, botones de la cabecera, secciones oscuras y pie.' ),
'accent' => array( 'type' => 'color', 'label' => 'Color de acento', 'default' => $default['accent'], 'description' => 'Botones principales, detalles y palabras resaltadas.' ),
'background' => array( 'type' => 'color', 'label' => 'Fondo de la página', 'default' => $default['background'] ),
'surface' => array( 'type' => 'color', 'label' => 'Fondo de secciones alternas', 'default' => $default['surface'] ),
'text' => array( 'type' => 'color', 'label' => 'Color del texto', 'default' => $default['text'] ),
),
),
'typography' => array(
'panel' => 'ga_design',
'title' => 'Tipografía',
'fields' => array(
'heading_font' => array( 'type' => 'select', 'label' => 'Tipografía de títulos', 'default' => 'fraunces', 'choices' => wp_list_pluck( ga_fonts(), 'label' ) ),
'heading_weight' => array( 'type' => 'select', 'label' => 'Grosor de los títulos', 'default' => '800', 'choices' => array(
'500' => 'Normal',
'600' => 'Seminegrita',
'700' => 'Negrita',
'800' => 'Extra negrita',
'900' => 'Máximo',
) ),
'body_font' => array( 'type' => 'select', 'label' => 'Tipografía del texto', 'default' => 'karla', 'choices' => wp_list_pluck( ga_fonts(), 'label' ) ),
'base_size' => array( 'type' => 'range', 'label' => 'Tamaño del texto (px)', 'default' => 17, 'min' => 15, 'max' => 20, 'step' => 1 ),
'radius' => array( 'type' => 'range', 'label' => 'Redondeo de esquinas (px)', 'default' => 14, 'min' => 0, 'max' => 32, 'step' => 2 ),
),
),
'header' => array(
'panel' => 'ga_design',
'title' => 'Cabecera',
'fields' => array(
'phone' => array( 'type' => 'checkbox', 'label' => 'Mostrar el teléfono en la cabecera', 'default' => true ),
'switcher' => array( 'type' => 'checkbox', 'label' => 'Mostrar selector de idioma ES | EU', 'default' => true ),
'sticky' => array( 'type' => 'checkbox', 'label' => 'Cabecera fija al hacer scroll', 'default' => true ),
'topbar' => array( 'type' => 'checkbox', 'label' => 'Barra superior con horario y redes', 'default' => false ),
'highlight_first' => array( 'type' => 'checkbox', 'label' => 'Resaltar el primer elemento del menú como botón', 'default' => false ),
'brand_line1' => array( 'type' => 'text', 'label' => 'Nombre (si no hay logo) · línea 1', 'default' => 'Gure Ametsa' ),
'brand_line2' => array( 'type' => 'text', 'label' => 'Nombre (si no hay logo) · línea 2', 'default' => 'Bi Lagun' ),
'brand_line3' => array( 'type' => 'text', 'label' => 'Nombre (si no hay logo) · lugar', 'default' => 'Hondarribia' ),
'cta1' => $t( 'Botón de cabecera (vacío = ocultar)', 'Conoce a los animales', 'Ezagutu animaliak' ),
'cta1_url' => array( 'type' => 'text', 'label' => 'Botón · enlace (vacío = listado de adopción)', 'default' => '' ),
'cta2' => $t( 'Segundo botón (vacío = ocultar)', '', '' ),
'cta2_url' => array( 'type' => 'text', 'label' => 'Segundo botón · enlace (vacío = Colabora → Donaciones)', 'default' => '' ),
),
),
'footer' => array(
'panel' => 'ga_design',
'title' => 'Pie de página',
'fields' => array(
'about' => $t( 'Texto de presentación',
'Protectora y residencia de animales en Jaizubia, Hondarribia. Desde hace más de 25 años recogemos, cuidamos y buscamos hogar a los perros y gatos abandonados de Irun y Hondarribia.',
'Animalien babesleku eta egoitza Jaizubian, Hondarribian. 25 urte baino gehiago daramatzagu Irun eta Hondarribiko txakur eta katu abandonatuak jasotzen, zaintzen eta etxe bat bilatzen.', 'textarea' ),
'copyright' => array( 'type' => 'text', 'label' => 'Texto de copyright', 'default' => 'Gure Ametsa Bi Lagun' ),
),
),
/* ================= Contacto ================= */
'contact' => array(
'panel' => 'ga_info',
'title' => 'Datos de contacto',
'fields' => array(
'direccion' => array( 'type' => 'text', 'label' => 'Dirección', 'default' => 'Jaizubia, 44 · 20280 Hondarribia (Gipuzkoa)' ),
'maps' => array( 'type' => 'url', 'label' => 'Enlace a Google Maps', 'default' => 'https://www.google.com/maps/search/?api=1&query=Jaizubia+44+Hondarribia' ),
'telefono' => array( 'type' => 'text', 'label' => 'Teléfono', 'default' => '943 64 52 79' ),
'email' => array( 'type' => 'email', 'label' => 'Email', 'default' => 'hola@gureametsabilagun.org' ),
'horario' => $t( 'Horario', 'Lunes a viernes: 10:00–13:00 y 14:00–19:00', 'Astelehenetik ostiralera: 10:00–13:00 eta 14:00–19:00' ),
),
),
'social' => array(
'panel' => 'ga_info',
'title' => 'Redes sociales',
'fields' => array(
'instagram' => array( 'type' => 'url', 'label' => 'Instagram', 'default' => 'https://www.instagram.com/gureametsabilagun/' ),
'facebook' => array( 'type' => 'url', 'label' => 'Facebook', 'default' => 'https://www.facebook.com/gureametsabilagun/' ),
'tiktok' => array( 'type' => 'url', 'label' => 'TikTok', 'default' => '' ),
'youtube' => array( 'type' => 'url', 'label' => 'YouTube', 'default' => '' ),
'whatsapp' => array( 'type' => 'text', 'label' => 'WhatsApp (número con prefijo, p. ej. 34600111222)', 'default' => '' ),
),
),
/* ================= Portada ================= */
'hero' => array(
'panel' => 'ga_home',
'title' => 'Portada principal y «puertas»',
'section' => true,
'fields' => array_merge(
array(
'layout' => array( 'type' => 'select', 'label' => 'Diseño', 'default' => 'full', 'choices' => array(
'full' => 'Foto o vídeo a pantalla completa',
'split' => 'Texto a la izquierda, foto a la derecha',
) ),
'image' => array( 'type' => 'image', 'label' => 'Foto', 'default' => 0 ),
'video' => array( 'type' => 'video', 'label' => 'Vídeo de fondo (opcional, MP4 corto y sin sonido)', 'default' => 0, 'description' => 'Se reproduce en bucle. La foto se muestra mientras carga.' ),
'overlay' => array( 'type' => 'range', 'label' => 'Velo de color sobre la foto (%)', 'default' => 70, 'min' => 0, 'max' => 95, 'step' => 5 ),
'eyebrow' => $t( 'Etiqueta superior', 'Protectora de animales · Hondarribia', 'Animalien babeslekua · Hondarribia' ),
'title' => $t( 'Título (pon *entre asteriscos* la parte resaltada)', 'Tu mejor amigo *te está esperando*', 'Zure lagunik onena *zure zain dago*' ),
'lead' => $t( 'Texto',
'La mayoría nos conoce porque quiere adoptar. Pero adoptar es solo una de las cuatro puertas: acoger, echar una mano y donar son las que mantienen la primera abierta. Elige la que encaja con tu vida ahora.',
'Gehienek adoptatu nahi dutelako ezagutzen gaituzte. Baina adoptatzea lau ateetako bat baino ez da: harrera egitea, laguntzea eta dohaintzak egitea dira lehena irekita mantentzen dutenak. Aukeratu orain zure bizitzara hobekien egokitzen dena.', 'textarea' ),
'btn1' => $t( 'Botón 1', 'Ver quién está disponible', 'Ikusi nor dagoen zain' ),
'btn1_url' => array( 'type' => 'text', 'label' => 'Botón 1 · enlace (vacío = listado de adopción)', 'default' => '' ),
'btn2' => $t( 'Botón 2', 'Planifica tu visita', 'Antolatu zure bisita' ),
'btn2_url' => array( 'type' => 'text', 'label' => 'Botón 2 · enlace (vacío = página de contacto)', 'default' => '' ),
'doors' => array( 'type' => 'checkbox', 'label' => 'Mostrar las cuatro «puertas» bajo la portada', 'default' => true ),
),
$door( 1, array( 'Adopta', 'Adoptatu' ), array( 'Conócelos', 'Ezagutu' ), array( 'Perros y gatos que buscan una familia para siempre.', 'Betiko familia bila dabiltzan txakur eta katuak.' ), array( 'Ver animales', 'Ikusi animaliak' ) ),
$door( 2, array( 'Acoge', 'Harrera' ), array( 'Abre tu casa', 'Ireki etxea' ), array( 'Un hogar temporal mientras encuentran su familia.', 'Aldi baterako etxe bat, familia aurkitu bitartean.' ), array( 'Quiero acoger', 'Harrera egin nahi dut' ) ),
$door( 3, array( 'Voluntariado', 'Boluntariotza' ), array( 'Echa una mano', 'Eman esku bat' ), array( 'Paseos, mimos, fotos y ayuda en jornadas.', 'Ibilaldiak, laztanak, argazkiak eta laguntza jardunaldietan.' ), array( 'Apúntate', 'Eman izena' ) ),
$door( 4, array( 'Dona', 'Dohaintza' ), array( 'Colabora', 'Lagundu' ), array( 'Pienso, mantas, material o una aportación.', 'Pentsua, mantak, materiala edo ekarpen bat.' ), array( 'Cómo donar', 'Nola eman' ) )
),
),
'animals' => array(
'panel' => 'ga_home',
'title' => 'Animales en adopción',
'section' => true,
'fields' => array(
'eyebrow' => $t( 'Antetítulo', 'Puerta uno · Adopta', 'Lehen atea · Adoptatu' ),
'title' => $t( 'Título', 'Te están esperando', 'Zure zain daude' ),
'text' => $t( 'Texto', 'Todos se entregan con microchip, vacunas al día y esterilizados. Si alguno te roba el corazón, escríbenos y te contamos todo sobre él.', 'Guztiak mikrotxiparekin, txertoak egunean eta antzututa ematen dira. Norbaitek bihotza lapurtzen badizu, idatzi iezaguzu eta dena kontatuko dizugu.', 'textarea' ),
'button' => $t( 'Botón', 'Ver todos los animales', 'Ikusi animalia guztiak' ),
'count' => array( 'type' => 'number', 'label' => 'Número de animales', 'default' => 8, 'min' => 2, 'max' => 24 ),
'view' => array( 'type' => 'select', 'label' => 'Presentación', 'default' => 'carrusel', 'choices' => array(
'carrusel' => 'Carrusel (se desliza)',
'rejilla' => 'Rejilla',
) ),
'filter' => array( 'type' => 'select', 'label' => 'Qué animales mostrar', 'default' => '', 'choices' => array(
'' => 'Todos los disponibles',
'urgente,acogida' => 'Solo urgentes y los que buscan acogida',
) ),
),
),
'steps' => array(
'panel' => 'ga_home',
'title' => 'Cómo adoptar',
'section' => true,
'fields' => array_merge(
array(
'eyebrow' => $t( 'Antetítulo', 'Qué pasa después', 'Zer gertatzen da gero' ),
'title' => $t( 'Título', 'Una adopción clara, paso a paso', 'Adopzio argia, urratsez urrats' ),
'text' => $t( 'Texto', 'Queremos que la adopción salga bien para siempre. Por eso vamos sin prisas y te acompañamos en cada paso.', 'Adopzioak betirako ondo irtetea nahi dugu. Horregatik presarik gabe goaz eta urrats bakoitzean lagunduko dizugu.', 'textarea' ),
),
$step( 1, 'Escríbenos', 'Rellena el formulario o llámanos. Cuéntanos cómo es tu casa, tu día a día y qué animal buscas.',
'Idatzi iezaguzu', 'Bete formularioa edo deitu iezaguzu. Kontaiguzu nolakoa den zure etxea, zure eguneroko bizitza eta zer animalia bilatzen duzun.' ),
$step( 2, 'Hablamos', 'Te llamamos para conocerte y resolver dudas. Es una conversación, no un examen.',
'Hitz egingo dugu', 'Deituko dizugu zu ezagutzeko eta zalantzak argitzeko. Elkarrizketa bat da, ez azterketa bat.' ),
$step( 3, 'Os conocéis', 'Ven a Jaizubia a conocerle. Paseos y visitas sin prisas, con toda la familia.',
'Elkar ezagutu', 'Etorri Jaizubira hura ezagutzera. Ibilaldiak eta bisitak presarik gabe, familia osoarekin.' ),
$step( 4, '¡A casa!', 'Firmamos el contrato de adopción y seguimos a tu lado para lo que necesites.',
'Etxera!', 'Adopzio-kontratua sinatuko dugu eta behar duzun guztirako zure ondoan jarraituko dugu.' ),
array( 'button' => $t( 'Botón', 'Quiero adoptar', 'Adoptatu nahi dut' ) )
),
),
'foster' => array(
'panel' => 'ga_home',
'title' => 'Acogida',
'section' => true,
'fields' => array(
'eyebrow' => $t( 'Antetítulo', 'Puerta dos · Acoge', 'Bigarren atea · Harrera' ),
'title' => $t( 'Título', 'Acoger es lo que nos permite decir que sí', 'Harrera egiteak baietz esateko aukera ematen digu' ),
'text' => $t( 'Texto', 'Cachorros, animales mayores o convalecientes necesitan salir del centro cuanto antes. Una casa de acogida les da tiempo y cariño mientras encuentran su familia definitiva.', 'Kumeek, animalia zaharrek edo gaixorik daudenek lehenbailehen irten behar dute zentrotik. Harrera-etxe batek denbora eta maitasuna ematen die behin betiko familia aurkitu bitartean.', 'textarea' ),
'list_title' => $t( 'Título de la lista', 'Contigo en todo momento', 'Zurekin uneoro' ),
'list' => $t( 'Lista (una línea por punto)',
"Te explicamos qué necesita cada animal antes de llevarlo a casa\nResolvemos tus dudas durante toda la acogida\nBuscamos juntos su familia definitiva",
"Etxera eraman aurretik animalia bakoitzak zer behar duen azaltzen dizugu\nHarrera osoan zehar zure zalantzak argitzen ditugu\nElkarrekin bilatzen dugu haren behin betiko familia", 'textarea' ),
'image' => array( 'type' => 'image', 'label' => 'Foto', 'default' => 0 ),
'caption' => $t( 'Pie de foto', '', '' ),
'button' => $t( 'Botón', 'Quiero ser casa de acogida', 'Harrera-etxe izan nahi dut' ),
),
),
'give' => array(
'panel' => 'ga_home',
'title' => 'Donaciones',
'section' => true,
'fields' => array(
'eyebrow' => $t( 'Antetítulo', 'Puerta cuatro · Dona', 'Laugarren atea · Dohaintza' ),
'title' => $t( 'Título', 'Cada ayuda se nota', 'Laguntza oro nabaritzen da' ),
'text' => $t( 'Texto', 'Con tu aportación compramos pienso, medicinas y todo lo que necesitan mientras esperan una familia.', 'Zure ekarpenarekin pentsua, sendagaiak eta familia baten zain dauden bitartean behar duten guztia erosten dugu.', 'textarea' ),
'card_title' => $t( 'Tarjeta · título', 'Cómo donar', 'Nola eman' ),
'card_text' => $t( 'Tarjeta · texto', 'Escríbenos y te indicamos cómo hacer una aportación económica o dónde traer material. ¡Gracias!', 'Idatzi iezaguzu eta diru-ekarpena nola egin edo materiala non ekarri azalduko dizugu. Eskerrik asko!', 'textarea' ),
'shortcode' => array( 'type' => 'text', 'label' => 'Formulario de donación (opcional): pega aquí el shortcode de GiveWP, p. ej. [give_form id="12"]', 'default' => '' ),
'button' => $t( 'Botón', 'Quiero donar', 'Dohaintza egin nahi dut' ),
'needs_title' => $t( 'Necesidades · título', 'Lo que más necesitamos', 'Gehien behar duguna' ),
'needs' => $t( 'Necesidades (una línea por punto)',
"Pienso para perros y gatos\nArena para gatos\nMantas, toallas y camas\nCorreas, collares y juguetes",
"Txakur eta katuentzako pentsua\nKatuentzako harea\nMantak, eskuoihalak eta oheak\nUhalak, lepokoak eta jostailuak", 'textarea' ),
),
),
'stats' => array(
'panel' => 'ga_home',
'title' => 'Cifras',
'section' => true,
'fields' => array(
'eyebrow' => $t( 'Antetítulo', 'Nuestro impacto', 'Gure eragina' ),
'title' => $t( 'Título', 'Cada número es una vida', 'Zenbaki bakoitza bizitza bat da' ),
'num1' => array( 'type' => 'text', 'label' => 'Cifra 1', 'default' => '+25' ),
'label1' => $t( 'Cifra 1 · texto', 'años cuidando animales', 'urte animaliak zaintzen' ),
'num2' => array( 'type' => 'text', 'label' => 'Cifra 2', 'default' => '2' ),
'label2' => $t( 'Cifra 2 · texto', 'municipios: Irun y Hondarribia', 'udalerri: Irun eta Hondarribia' ),
'num3' => array( 'type' => 'text', 'label' => 'Cifra 3', 'default' => '100%' ),
'label3' => $t( 'Cifra 3 · texto', 'con microchip, vacunas y esterilización', 'mikrotxip, txerto eta antzutzearekin' ),
'num4' => array( 'type' => 'text', 'label' => 'Cifra 4 (vacío = ocultar)', 'default' => '' ),
'label4' => $t( 'Cifra 4 · texto', '', '' ),
),
),
'stories' => array(
'panel' => 'ga_home',
'title' => 'Historias con final feliz',
'section' => true,
'description' => 'Muestra automáticamente los últimos animales marcados como «Adoptado». Si no hay ninguno, la sección no aparece.',
'fields' => array(
'eyebrow' => $t( 'Antetítulo', 'Ya están en casa', 'Etxean daude jada' ),
'title' => $t( 'Título', 'Historias con final feliz', 'Amaiera zoriontsuko istorioak' ),
'text' => $t( 'Texto', 'Gracias a las familias que les abrieron su casa.', 'Eskerrik asko etxeko ateak ireki zizkieten familiei.', 'textarea' ),
'count' => array( 'type' => 'number', 'label' => 'Número de animales', 'default' => 8, 'min' => 1, 'max' => 24 ),
'view' => array( 'type' => 'select', 'label' => 'Presentación', 'default' => 'carrusel', 'choices' => array(
'carrusel' => 'Carrusel (se desliza)',
'rejilla' => 'Rejilla',
) ),
),
),
'intake' => array(
'panel' => 'ga_home',
'title' => 'Si necesitas ayuda (perdidos, encontrados…)',
'section' => true,
'fields' => array_merge(
array(
'eyebrow' => $t( 'Antetítulo', 'Si eres tú quien necesita ayuda', 'Laguntza behar duzuna zu bazara' ),
'title' => $t( 'Título', 'Perdidos, encontrados y entregas', 'Galduak, aurkituak eta entregak' ),
),
$card( 'caso', 1, array( 'He perdido a mi animal', 'Nire animalia galdu dut' ),
array( 'Llámanos cuanto antes y avisa a la Policía Municipal. Los animales que se recogen en Irun y Hondarribia llegan a nuestras instalaciones: el microchip actualizado es la forma más rápida de volver a casa.',
'Deitu iezaguzu lehenbailehen eta jakinarazi Udaltzaingoari. Irunen eta Hondarribian jasotzen diren animaliak gure instalazioetara iristen dira: mikrotxipa eguneratuta izatea da etxera itzultzeko modurik azkarrena.' ) ),
$card( 'caso', 2, array( 'He encontrado un animal', 'Animalia bat aurkitu dut' ),
array( 'Si está en la calle en Irun u Hondarribia, avisa a la Policía Municipal: ellos lo recogen y lo traen a Gure Ametsa, donde pasa control veterinario y le buscamos a su familia.',
'Irunen edo Hondarribian kalean badago, jakinarazi Udaltzaingoari: haiek jaso eta Gure Ametsara ekartzen dute, non albaitari-kontrola egiten zaion eta bere familia bilatzen diogun.' ) ),
$card( 'caso', 3, array( 'No puedo seguir cuidándolo', 'Ezin dut gehiago zaindu' ),
array( 'Escríbenos o llámanos antes de tomar una decisión. Te escucharemos sin juzgarte y buscaremos juntos la mejor salida para él.',
'Idatzi edo deitu iezaguzu erabaki bat hartu aurretik. Epaitu gabe entzungo dizugu eta elkarrekin bilatuko dugu harentzat irtenbiderik onena.' ) )
),
),
'faq' => array(
'panel' => 'ga_home',
'title' => 'Preguntas frecuentes',
'section' => true,
'fields' => array_merge(
array(
'eyebrow' => $t( 'Antetítulo', 'Dudas', 'Zalantzak' ),
'title' => $t( 'Título', 'Preguntas frecuentes', 'Ohiko galderak' ),
),
$qa( 1, '¿Qué incluye la adopción?', 'Todos los animales se entregan con microchip, vacunas al día, desparasitados y esterilizados, como marca la Ley de Bienestar Animal.',
'Zer barne hartzen du adopzioak?', 'Animalia guztiak mikrotxiparekin, txertoak egunean, desparasitatuta eta antzututa ematen dira, Animalien Ongizaterako Legeak agintzen duen bezala.' ),
$qa( 2, '¿Puedo ir a conocerlos?', 'Sí. Estamos en Jaizubia, 44 (Hondarribia), de lunes a viernes de 10:00 a 13:00 y de 14:00 a 19:00. Llámanos antes para organizar la visita.',
'Joan naiteke haiek ezagutzera?', 'Bai. Jaizubian gaude, 44 (Hondarribia), astelehenetik ostiralera 10:00etatik 13:00etara eta 14:00etatik 19:00etara. Deitu aurretik bisita antolatzeko.' ),
$qa( 3, '¿Puedo ser casa de acogida o voluntario/a?', 'Sí, nos ayuda muchísimo. Escríbenos desde el formulario de contacto y te contamos cómo empezar.',
'Harrera-etxe edo boluntario izan naiteke?', 'Bai, asko laguntzen digu. Idatzi iezaguzu harremanetarako formularioaren bidez eta nola hasi kontatuko dizugu.' ),
$qa( 4, '¿Cuidáis de mi perro o gato en vacaciones?', 'Sí, tenemos hotel para perros y gatos. Consulta disponibilidad con antelación, sobre todo en verano.',
'Nire txakurra edo katua zaintzen duzue oporretan?', 'Bai, txakur eta katuentzako hotela dugu. Galdetu erabilgarritasuna aldez aurretik, batez ere udan.' ),
$qa( 5, '', '', '', '' )
),
),
'content' => array(
'panel' => 'ga_home',
'title' => 'Contenido libre de la página «Inicio»',
'section' => true,
'description' => 'Lo que escribáis en la página Inicio (y en «Hasiera» para euskera) con el editor de bloques. Ideal para añadir patrones de «Gure Ametsa».',
'fields' => array(),
),
'visit' => array(
'panel' => 'ga_home',
'title' => 'Hotel y visita',
'section' => true,
'fields' => array(
'eyebrow' => $t( 'Antetítulo', 'Visítanos', 'Etorri gu ikustera' ),
'title' => $t( 'Título', 'Estamos en Jaizubia', 'Jaizubian gaude' ),
'text' => $t( 'Texto', 'Ven a conocer a los animales. Y si te vas de vacaciones, también cuidamos de tu perro o gato en nuestro hotel.', 'Etorri animaliak ezagutzera. Eta oporretara bazoaz, zure txakurra edo katua ere zaintzen dugu gure hotelean.', 'textarea' ),
'image' => array( 'type' => 'image', 'label' => 'Foto del hotel o las instalaciones', 'default' => 0 ),
'button' => $t( 'Botón del hotel', 'Hotel para perros y gatos', 'Txakur eta katuentzako hotela' ),
),
),
'talk' => array(
'panel' => 'ga_home',
'title' => 'Contacto con formulario',
'section' => true,
'fields' => array(
'eyebrow' => $t( 'Antetítulo', 'Hablemos', 'Hitz egin dezagun' ),
'title' => $t( 'Título', 'Habla con una persona', 'Hitz egin pertsona batekin' ),
'text' => $t( 'Texto', 'Adopciones, acogidas, voluntariado, hotel o un animal perdido: escríbenos y te responde alguien del equipo.', 'Adopzioak, harrerak, boluntariotza, hotela edo animalia galdu bat: idatzi iezaguzu eta taldeko norbaitek erantzungo dizu.', 'textarea' ),
'form_title' => $t( 'Título del formulario', 'Escríbenos', 'Idatzi iezaguzu' ),
),
),
'help' => array(
'panel' => 'ga_home',
'title' => 'Formas de ayudar (tarjetas)',
'section' => true,
'hidden' => true,
'fields' => array(
'eyebrow' => $t( 'Antetítulo', 'Colabora', 'Lagundu' ),
'title' => $t( 'Título', 'Hay muchas formas de ayudar', 'Laguntzeko modu asko daude' ),
'text' => $t( 'Texto', 'No hace falta adoptar para cambiar la vida de un animal.', 'Ez da beharrezkoa adoptatzea animalia baten bizitza aldatzeko.', 'textarea' ),
),
),
'species' => array(
'panel' => 'ga_home',
'title' => 'Perros y gatos (accesos con foto)',
'section' => true,
'hidden' => true,
'fields' => array(
'title' => $t( 'Título (vacío = ocultar)', '¿A quién vas a conocer hoy?', 'Nor ezagutuko duzu gaur?' ),
'dog_label' => $t( 'Perros · texto', 'Conoce a los perros', 'Ezagutu txakurrak' ),
'dog_image' => array( 'type' => 'image', 'label' => 'Perros · foto', 'default' => 0 ),
'cat_label' => $t( 'Gatos · texto', 'Conoce a los gatos', 'Ezagutu katuak' ),
'cat_image' => array( 'type' => 'image', 'label' => 'Gatos · foto', 'default' => 0 ),
),
),
);
// Cada sección de portada tiene «Mostrar» y «Orden» (el orden del registro es el inicial).
$order = 10;
foreach ( $registry as $id => &$section ) {
if ( ! empty( $section['section'] ) ) {
$section['fields'] = array(
'show' => array( 'type' => 'checkbox', 'label' => 'Mostrar esta sección', 'default' => empty( $section['hidden'] ) ),
'order' => array( 'type' => 'number', 'label' => 'Orden (menor = más arriba)', 'default' => $order, 'min' => 0, 'max' => 200 ),
) + $section['fields'];
$order += 10;
}
}
unset( $section );
return $registry;
}

View File

@@ -0,0 +1,36 @@
<?php
get_header();
?>
<header class="ga-page-head">
<div class="ga-wrap">
<h1><?php echo is_home() ? ga__( 'Noticias', 'Albisteak' ) : wp_kses_post( get_the_archive_title() ?: get_the_title() ); ?></h1>
</div>
</header>
<section class="ga-section">
<div class="ga-narrow">
<?php if ( have_posts() ) : ?>
<?php
while ( have_posts() ) :
the_post();
?>
<article <?php post_class( 'ga-box' ); ?>>
<?php if ( is_singular() ) : ?>
<h2><?php the_title(); ?></h2>
<p><small><?php echo esc_html( get_the_date() ); ?></small></p>
<?php the_content(); ?>
<?php else : ?>
<h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<p><small><?php echo esc_html( get_the_date() ); ?></small></p>
<?php the_excerpt(); ?>
<?php endif; ?>
</article>
<?php endwhile; ?>
<nav class="ga-pagination"><?php echo paginate_links(); ?></nav>
<?php else : ?>
<p class="ga-empty"><?php ga_e( 'No hay contenido que mostrar.', 'Ez dago erakusteko edukirik.' ); ?></p>
<?php endif; ?>
</div>
</section>
<?php
get_footer();

View File

@@ -0,0 +1,21 @@
<?php
get_header();
while ( have_posts() ) :
the_post();
?>
<header class="ga-page-head">
<div class="ga-wrap">
<h1><?php the_title(); ?></h1>
<?php if ( has_excerpt() ) : ?>
<p><?php echo esc_html( get_the_excerpt() ); ?></p>
<?php endif; ?>
</div>
</header>
<article class="ga-content">
<?php the_content(); ?>
</article>
<?php
endwhile;
get_footer();

View File

@@ -0,0 +1,100 @@
<?php
get_header();
while ( have_posts() ) :
the_post();
$id = get_the_ID();
$estado = ga_get( $id, 'estado' ) ?: 'disponible';
$fields = ga_fields();
$facts = array_filter( array(
ga__( 'Especie', 'Espeziea' ) => ga_species(),
$fields['sexo']['label'] => ga_label( $id, 'sexo' ),
$fields['edad']['label'] => ga_age( $id ),
$fields['tamano']['label'] => ga_label( $id, 'tamano' ),
$fields['raza']['label'] => ga_get( $id, 'raza' ),
ga__( 'Llegó el', 'Iritsiera' ) => ga_label( $id, 'llegada' ),
) );
$salud = ga_label( $id, 'salud' ) ?: array();
$compatible = ga_label( $id, 'compatible' ) ?: array();
$archive = get_post_type_archive_link( 'animal' );
?>
<section class="ga-section" style="padding-top:48px">
<div class="ga-wrap">
<p><a href="<?php echo esc_url( $archive ); ?>"><?php ga_e( '← Todos los animales', '← Animalia guztiak' ); ?></a></p>
<article class="ga-animal">
<div class="ga-animal__photo"><?php ga_animal_photo( 'ga-square' ); ?></div>
<div>
<?php ga_status_badge(); ?>
<h1 style="margin-top:14px"><?php the_title(); ?></h1>
<?php if ( $facts ) : ?>
<ul class="ga-animal__facts">
<?php foreach ( $facts as $label => $value ) : ?>
<li><span><?php echo esc_html( $label ); ?></span><strong><?php echo esc_html( $value ); ?></strong></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<?php if ( $salud ) : ?>
<ul class="ga-tags" aria-label="<?php echo esc_attr( $fields['salud']['label'] ); ?>">
<?php foreach ( $salud as $s ) : ?><li><?php echo esc_html( $s ); ?></li><?php endforeach; ?>
</ul>
<?php endif; ?>
<?php if ( $compatible ) : ?>
<p><strong><?php echo esc_html( $fields['compatible']['label'] ); ?>:</strong> <?php echo esc_html( implode( ', ', $compatible ) ); ?></p>
<?php endif; ?>
<div class="ga-animal__content"><?php the_content(); ?></div>
<?php if ( 'adoptado' === $estado ) : ?>
<div class="ga-box">
<h3><?php echo esc_html( ga__( '¡' . get_the_title() . ' ya tiene familia! 🎉', get_the_title() . ': familia du jada! 🎉' ) ); ?></h3>
<p>
<?php ga_e( 'Pero muchos otros siguen esperando.', 'Baina beste asko zain daude oraindik.' ); ?>
<a href="<?php echo esc_url( $archive ); ?>"><?php ga_e( 'Conócelos aquí', 'Ezagutu hemen' ); ?></a>.
</p>
</div>
<?php else : ?>
<div class="ga-cta-box">
<h3><?php echo esc_html( ga__( '¿Quieres conocer a ' . get_the_title() . '?', get_the_title() . ' ezagutu nahi duzu?' ) ); ?></h3>
<p>
<?php ga_e( 'Escríbenos y te contaremos todo sobre su carácter y cuidados.', 'Idatzi iezaguzu eta bere izaera eta zaintzari buruzko guztia kontatuko dizugu.' ); ?>
<?php if ( 'acogida' === $estado ) { ga_e( 'Busca una casa de acogida temporal.', 'Aldi baterako harrera-etxe bat behar du.' ); } ?>
</p>
<a class="ga-btn" href="<?php echo esc_url( ga_adopt_url() ); ?>">
<?php 'acogida' === $estado ? ga_e( 'Quiero acogerle', 'Harrera egin nahi diot' ) : ga_e( 'Quiero adoptarle', 'Adoptatu nahi dut' ); ?>
</a>
</div>
<?php endif; ?>
</div>
</article>
</div>
</section>
<?php
$related = ga_query_animals( array( 'numero' => 4 ) );
$related->posts = array_values( array_filter( $related->posts, fn( $p ) => $p->ID !== $id ) );
$related->post_count = min( 3, count( $related->posts ) );
if ( $related->post_count ) :
?>
<section class="ga-section ga-section--sand">
<div class="ga-wrap">
<h2><?php ga_e( 'También buscan hogar', 'Hauek ere etxe bila dabiltza' ); ?></h2>
<div class="ga-grid">
<?php
while ( $related->have_posts() ) :
$related->the_post();
get_template_part( 'template-parts/animal-card' );
endwhile;
wp_reset_postdata();
?>
</div>
</div>
</section>
<?php
endif;
endwhile;
get_footer();

View File

@@ -0,0 +1,636 @@
/*
Theme Name: Gure Ametsa
Theme URI: https://www.instagram.com/gureametsabilagun/
Author: Gure Ametsa Bi Lagun
Description: Tema a medida para la protectora Gure Ametsa Bi Lagun (Hondarribia). Personalizable desde Apariencia → Personalizar, con patrones de bloques propios y web bilingüe castellano / euskera.
Version: 2.0.0
Requires at least: 6.4
Requires PHP: 8.1
License: GPL-2.0-or-later
Text Domain: gure-ametsa
*/
/* =========================================================================
Variables
Los colores base se sobrescriben desde Apariencia → Personalizar → Diseño.
(Por compatibilidad: --ga-green = color principal, --ga-red = color de acento.)
========================================================================= */
:root {
--ga-green: #5b2c4e;
--ga-red: #e8a317;
--ga-cream: #fdf8f1;
--ga-sand: #f5ead9;
--ga-ink: #241a21;
--ga-on-red: #241a21;
--ga-on-primary: #ffffff;
--ga-serif: Fraunces, Georgia, serif;
--ga-sans: Karla, system-ui, sans-serif;
--ga-heading-weight: 800;
--ga-radius: 14px;
--ga-size: 17px;
/* Derivados */
--ga-green-dark: color-mix(in srgb, var(--ga-green) 68%, #000);
--ga-green-soft: color-mix(in srgb, var(--ga-green) 11%, #fff);
--ga-red-dark: color-mix(in srgb, var(--ga-red) 60%, #000);
--ga-red-soft: color-mix(in srgb, var(--ga-red) 22%, #fff);
--ga-red-hover: color-mix(in srgb, var(--ga-red) 88%, #000);
--ga-muted: color-mix(in srgb, var(--ga-ink) 75%, var(--ga-cream));
--ga-line: color-mix(in srgb, var(--ga-ink) 13%, var(--ga-cream));
--ga-on-dark: color-mix(in srgb, var(--ga-green) 12%, #fff);
--ga-on-dark-muted: color-mix(in srgb, var(--ga-green) 28%, #fff);
--ga-footer-bg: color-mix(in srgb, var(--ga-ink) 88%, var(--ga-green));
--ga-shadow: 0 1px 2px rgba(0, 0, 0, .04), 0 12px 30px -16px color-mix(in srgb, var(--ga-green-dark) 45%, transparent);
--ga-wrap: 1180px;
}
/* =========================================================================
Base
========================================================================= */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 100px; }
body {
margin: 0;
background: var(--ga-cream);
color: var(--ga-ink);
font: var(--ga-size)/1.65 var(--ga-sans);
-webkit-font-smoothing: antialiased;
}
img { max-width: 100%; height: auto; display: block; }
svg { flex: none; }
a { color: var(--ga-green); text-underline-offset: 3px; }
a:hover { color: var(--ga-green-dark); }
h1, h2, h3, h4 {
font-family: var(--ga-serif);
font-weight: var(--ga-heading-weight);
line-height: 1.08;
color: var(--ga-green-dark);
margin: 0 0 .45em;
letter-spacing: -.02em;
text-wrap: balance;
}
h1 { font-size: clamp(2.4rem, 5.5vw, 4.4rem); }
h2 { font-size: clamp(2rem, 4vw, 3.1rem); }
h3 { font-size: 1.35rem; letter-spacing: -.01em; }
p { margin: 0 0 1.1em; }
.ga-hl { color: var(--ga-red); }
.screen-reader-text {
position: absolute !important; width: 1px; height: 1px; overflow: hidden;
clip: rect(1px, 1px, 1px, 1px); white-space: nowrap;
}
.skip-link:focus {
clip: auto; width: auto; height: auto; z-index: 1000;
top: 8px; left: 8px; padding: 10px 16px; background: #fff; border-radius: 8px;
}
:focus-visible { outline: 3px solid var(--ga-red); outline-offset: 3px; }
.ga-wrap { width: min(100% - 32px, var(--ga-wrap)); margin-inline: auto; }
.ga-narrow { width: min(100% - 32px, 820px); margin-inline: auto; }
.ga-center { text-align: center; }
/* Antetítulo con rayita */
.ga-eyebrow {
display: block;
font: 700 .78rem/1.3 var(--ga-sans);
text-transform: uppercase;
letter-spacing: .14em;
color: var(--ga-red-dark);
margin-bottom: 14px;
}
.ga-eyebrow::before {
content: ""; display: block; width: 56px; height: 4px; border-radius: 4px;
background: var(--ga-red); margin-bottom: 26px;
}
.ga-head--center .ga-eyebrow::before { margin-inline: auto; }
/* Encabezado de sección */
.ga-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 24px 40px; flex-wrap: wrap; margin-bottom: 40px; }
.ga-head__main { max-width: 760px; }
.ga-head__main > :last-child { margin-bottom: 0; }
.ga-head__text { font-size: 1.1rem; color: var(--ga-muted); }
.ga-head--center { justify-content: center; text-align: center; }
.ga-head--center .ga-head__main { margin-inline: auto; }
/* Etiqueta con borde (portada) */
.ga-pill {
display: inline-block; padding: 8px 16px; border: 1.5px solid var(--ga-red); border-radius: 999px;
font: 700 .76rem/1 var(--ga-sans); text-transform: uppercase; letter-spacing: .14em; color: var(--ga-red);
margin-bottom: 28px;
}
/* =========================================================================
Botones
========================================================================= */
.ga-btn,
.wp-block-button__link {
display: inline-flex; align-items: center; justify-content: center; gap: .55em;
padding: .85em 1.5em;
border-radius: 999px;
background: var(--ga-red);
color: var(--ga-on-red);
font: 700 1rem/1.2 var(--ga-sans);
text-decoration: none;
border: 2px solid var(--ga-red);
cursor: pointer;
transition: background .2s, border-color .2s, color .2s, transform .2s;
}
.ga-btn:hover,
.wp-block-button__link:hover { background: var(--ga-red-hover); border-color: var(--ga-red-hover); color: var(--ga-on-red); transform: translateY(-1px); }
.ga-btn svg { transition: transform .2s; }
.ga-btn:hover svg { transform: translateX(3px); }
.ga-btn--primary { background: var(--ga-green); border-color: var(--ga-green); color: var(--ga-on-primary); }
.ga-btn--primary:hover { background: var(--ga-green-dark); border-color: var(--ga-green-dark); color: var(--ga-on-primary); }
.ga-btn--outline,
.is-style-outline .wp-block-button__link { background: transparent; color: var(--ga-green); border-color: color-mix(in srgb, var(--ga-green) 55%, transparent); }
.ga-btn--outline:hover,
.is-style-outline .wp-block-button__link:hover { background: var(--ga-green); border-color: var(--ga-green); color: var(--ga-on-primary); }
.ga-btn--ghost { background: transparent; color: #fff; border-color: rgba(255, 255, 255, .7); }
.ga-btn--ghost:hover { background: #fff; border-color: #fff; color: var(--ga-green-dark); }
.ga-btn--small { padding: .65em 1.2em; font-size: .92rem; }
.ga-btn--block { width: 100%; }
/* =========================================================================
Cabecera
========================================================================= */
.ga-topbar { background: var(--ga-green-dark); color: var(--ga-on-dark-muted); font-size: .85rem; }
.ga-topbar .ga-wrap { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding-block: 7px; }
.ga-topbar__hours { display: inline-flex; align-items: center; gap: 8px; }
.ga-topbar__social { display: flex; gap: 14px; }
.ga-topbar a { color: #fff; display: inline-flex; }
.ga-header {
position: relative; z-index: 50;
background: color-mix(in srgb, var(--ga-cream) 96%, transparent);
backdrop-filter: saturate(1.4) blur(10px);
border-bottom: 1px solid var(--ga-line);
}
.ga-sticky-header .ga-header { position: sticky; top: 0; }
.ga-header .ga-wrap { display: flex; align-items: center; gap: 24px; min-height: 80px; }
.ga-brand { display: flex; align-items: center; gap: 12px; text-decoration: none; color: var(--ga-green-dark); flex: none; }
.ga-brand:hover { color: var(--ga-green-dark); }
.ga-brand img, .ga-brand .custom-logo, .custom-logo-link img { max-height: 58px; width: auto; }
.ga-brand__mark { width: 46px; height: 46px; flex: none; }
.ga-brand__name { display: flex; flex-direction: column; }
.ga-brand__name b { font: 800 1.08rem/1.02 var(--ga-serif); letter-spacing: -.01em; }
.ga-brand__name small { margin-top: 4px; font: 700 .66rem/1 var(--ga-sans); letter-spacing: .16em; text-transform: uppercase; color: var(--ga-muted); }
.ga-nav { margin-inline: auto; }
.ga-nav ul { list-style: none; margin: 0; padding: 0; display: flex; align-items: center; gap: 2px; }
.ga-nav a {
display: block; padding: 8px 13px; border-radius: 999px;
color: var(--ga-ink); text-decoration: none; font-weight: 600; font-size: .96rem;
}
.ga-nav a:hover, .ga-nav .current-menu-item > a, .ga-nav .current_page_item > a { background: var(--ga-green-soft); color: var(--ga-green-dark); }
.ga-nav-highlight .ga-nav .menu-item:first-child a { background: var(--ga-red); color: var(--ga-on-red); }
.ga-header__actions { display: flex; align-items: center; gap: 12px; flex: none; }
.ga-header__phone { display: inline-flex; align-items: center; gap: 7px; color: var(--ga-green); font-weight: 700; text-decoration: none; font-size: .95rem; white-space: nowrap; }
.ga-header__phone:hover { color: var(--ga-green-dark); }
.ga-lang { display: flex; gap: 2px; list-style: none; margin: 0; padding: 3px; border-radius: 999px; background: var(--ga-green-soft); }
.ga-lang a { display: block; padding: 3px 9px; border-radius: 999px; font-weight: 700; font-size: .74rem; letter-spacing: .06em; color: var(--ga-green-dark); text-decoration: none; }
.ga-lang a.is-current { background: var(--ga-green); color: var(--ga-on-primary); }
.ga-footer .ga-lang { background: rgba(255, 255, 255, .1); margin: 0; }
.ga-footer .ga-lang a { color: #fff; }
.ga-footer .ga-lang a.is-current { background: #fff; color: var(--ga-ink); }
.ga-menu-toggle {
display: none; align-items: center; gap: 8px;
background: none; border: 2px solid var(--ga-green); border-radius: 999px;
padding: 8px 14px; font: 700 .92rem var(--ga-sans); color: var(--ga-green); cursor: pointer;
}
@media (max-width: 1180px) {
.ga-header__phone span { display: none; }
}
@media (max-width: 1060px) {
.ga-menu-toggle { display: inline-flex; }
.ga-nav {
position: absolute; inset: 100% 0 auto 0; margin: 0;
background: var(--ga-cream); border-bottom: 1px solid var(--ga-line);
display: none; padding: 12px 16px 20px; box-shadow: var(--ga-shadow);
}
.ga-nav.is-open { display: block; }
.ga-nav ul { flex-direction: column; align-items: stretch; }
.ga-nav a { padding: 12px 16px; font-size: 1.05rem; }
.ga-header__actions { margin-left: auto; }
}
@media (max-width: 640px) {
.ga-header__cta, .ga-header__cta2 { display: none; }
.ga-brand__name small { display: none; }
.ga-header .ga-wrap { gap: 10px; min-height: 68px; }
.ga-brand { gap: 9px; }
.ga-brand__mark { width: 40px; height: 40px; }
.ga-brand__name b { font-size: .96rem; }
.ga-header__actions { gap: 8px; }
.ga-menu-toggle { padding: 8px 10px; }
.ga-menu-toggle span { display: none; }
}
@media (max-width: 370px) {
.ga-header__phone { display: none; }
}
body { overflow-x: clip; }
/* =========================================================================
Portada (hero) y «puertas»
========================================================================= */
.ga-hero { position: relative; overflow: hidden; isolation: isolate; }
.ga-hero__inner { position: relative; z-index: 2; }
/* Pantalla completa */
.ga-hero--full {
display: flex; align-items: center; min-height: min(86vh, 780px);
padding: clamp(80px, 11vw, 150px) 0;
background: linear-gradient(135deg, var(--ga-green-dark), var(--ga-green));
color: #fff;
}
.ga-hero--full.has-doors { padding-bottom: clamp(150px, 14vw, 200px); }
.ga-hero--full .ga-hero__text { max-width: 720px; }
.ga-hero--full h1 { color: #fff; font-size: clamp(2.7rem, 7vw, 5.2rem); line-height: 1.02; letter-spacing: -.035em; }
.ga-hero--full .ga-hero__lead { font-size: clamp(1.1rem, 1.6vw, 1.3rem); color: rgba(255, 255, 255, .9); max-width: 640px; margin-top: 26px; }
.ga-hero__actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 34px; }
.ga-hero__bg { position: absolute; inset: 0; z-index: 0; }
.ga-hero__bg img, .ga-hero__bg video { width: 100%; height: 100%; object-fit: cover; }
.ga-hero--full.has-media::after {
content: ""; position: absolute; inset: 0; z-index: 1;
background: linear-gradient(90deg,
color-mix(in srgb, var(--ga-green-dark) calc(var(--ga-overlay, .7) * 100%), transparent) 0%,
color-mix(in srgb, var(--ga-green) calc(var(--ga-overlay, .7) * 80%), transparent) 55%,
color-mix(in srgb, var(--ga-green) calc(var(--ga-overlay, .7) * 35%), transparent) 100%);
}
.ga-hero__paw { position: absolute; right: -40px; bottom: -60px; width: min(46vw, 540px); color: #fff; opacity: .07; transform: rotate(-16deg); z-index: 1; }
/* Dos columnas */
.ga-hero--split { background: var(--ga-sand); padding: clamp(56px, 8vw, 110px) 0; }
.ga-hero--split.has-doors { padding-bottom: clamp(150px, 14vw, 200px); }
.ga-hero--split .ga-hero__inner { display: grid; grid-template-columns: 1.1fr .9fr; gap: 48px; align-items: center; }
.ga-hero--split .ga-hero__lead { font-size: 1.15rem; color: var(--ga-muted); }
.ga-hero--split .ga-btn--ghost { color: var(--ga-green); border-color: var(--ga-green); }
.ga-hero--split .ga-btn--ghost:hover { background: var(--ga-green); color: var(--ga-on-primary); }
.ga-hero__media img, .ga-hero__art { width: 100%; aspect-ratio: 4/5; object-fit: cover; border-radius: 240px 240px var(--ga-radius) var(--ga-radius); box-shadow: var(--ga-shadow); }
.ga-hero__art { background: var(--ga-green); color: var(--ga-cream); display: grid; place-items: center; }
.ga-hero__art svg { width: 55%; }
@media (max-width: 860px) {
.ga-hero--split .ga-hero__inner { grid-template-columns: 1fr; }
.ga-hero__media { max-width: 420px; }
}
/* Puertas */
.ga-doors { position: relative; z-index: 3; margin-top: clamp(-130px, -11vw, -100px); }
.ga-doors__grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; }
.ga-door {
position: relative; display: flex; flex-direction: column; gap: 6px;
background: #fff; border-radius: var(--ga-radius); padding: 26px 24px 24px;
box-shadow: var(--ga-shadow); text-decoration: none; color: var(--ga-ink);
border-top: 5px solid var(--ga-red); transition: transform .25s, box-shadow .25s;
}
.ga-door--2, .ga-door--4 { border-top-color: var(--ga-green); }
.ga-door:hover { transform: translateY(-4px); color: var(--ga-ink); }
.ga-door__kicker { font: var(--ga-heading-weight) 1.2rem/1.1 var(--ga-serif); color: var(--ga-green-dark); }
.ga-door__title { font: var(--ga-heading-weight) clamp(1.7rem, 2.4vw, 2.1rem)/1.05 var(--ga-serif); color: var(--ga-green); letter-spacing: -.02em; }
.ga-door__text { color: var(--ga-muted); font-size: .95rem; flex: 1; }
.ga-door__link { display: inline-flex; align-items: center; gap: 8px; margin-top: 12px; font-weight: 700; font-size: .8rem; letter-spacing: .12em; text-transform: uppercase; color: var(--ga-green); }
.ga-door:hover .ga-door__link svg { transform: translateX(3px); }
.ga-door__link svg { transition: transform .2s; }
.ga-doors__grid--static .ga-door { box-shadow: none; border: 1px solid var(--ga-line); border-top-width: 5px; }
@media (max-width: 960px) { .ga-doors__grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) {
.ga-doors__grid { gap: 12px; }
.ga-doors { margin-top: -90px; }
.ga-door { padding: 18px 16px; }
.ga-door__kicker { font-size: 1rem; }
.ga-door__title { font-size: 1.35rem; }
.ga-door__text { display: none; }
.ga-door__link { font-size: .7rem; letter-spacing: .08em; }
.ga-hero--full.has-doors, .ga-hero--split.has-doors { padding-bottom: 130px; }
}
/* =========================================================================
Secciones
========================================================================= */
.ga-section { padding: clamp(64px, 9vw, 120px) 0; }
.ga-section--tight { padding-top: 40px; }
.ga-section--sand { background: var(--ga-sand); }
.ga-section--dark { background: var(--ga-green-dark); color: var(--ga-on-dark); }
.ga-section--dark :is(h1, h2, h3) { color: #fff; }
.ga-section--dark .ga-eyebrow { color: var(--ga-red); }
.ga-section--dark .ga-head__text { color: var(--ga-on-dark-muted); }
.ga-section--dark a:not(.ga-btn) { color: #fff; }
.ga-section__cta { margin: 40px 0 0; }
.ga-doors + .ga-section { padding-top: clamp(64px, 8vw, 100px); }
.ga-page-head { background: var(--ga-sand); padding: clamp(48px, 7vw, 88px) 0; border-bottom: 1px solid var(--ga-line); }
.ga-page-head p { color: var(--ga-muted); font-size: 1.12rem; max-width: 46em; margin: 0; }
.ga-split { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: clamp(32px, 6vw, 72px); align-items: center; }
.ga-photo { margin: 0; }
.ga-photo img, .ga-photo__placeholder { width: 100%; aspect-ratio: 3/2; object-fit: cover; border-radius: var(--ga-radius); box-shadow: var(--ga-shadow); }
.ga-photo__placeholder { display: grid; place-items: center; background: var(--ga-green-soft); color: var(--ga-green); }
.ga-photo__placeholder svg { width: 28%; opacity: .35; }
.ga-photo figcaption { margin-top: 10px; font-size: .85rem; color: var(--ga-muted); }
.ga-list-title { font-size: 1.25rem; margin-top: 28px; }
.ga-checklist, .ga-iconlist { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.ga-checklist li, .ga-iconlist li { display: flex; gap: 12px; align-items: flex-start; }
.ga-checklist svg { color: var(--ga-red-dark); margin-top: 4px; }
.ga-iconlist svg { color: var(--ga-red); margin-top: 3px; }
.ga-iconlist--big { gap: 22px; margin-top: 8px; }
.ga-iconlist--big strong { display: block; color: #fff; }
.ga-iconlist--big span { display: flex; flex-direction: column; }
/* Paneles */
.ga-panel { background: #fff; border: 1px solid var(--ga-line); border-radius: var(--ga-radius); padding: clamp(24px, 3vw, 34px); box-shadow: var(--ga-shadow); }
.ga-panel > :last-child { margin-bottom: 0; }
.ga-panel--dark { background: var(--ga-green); border-color: var(--ga-green); color: var(--ga-on-dark); }
.ga-panel--dark h3 { color: #fff; }
.ga-panel--soft { background: var(--ga-green-soft); border-color: transparent; box-shadow: none; }
/* Pasos */
.ga-steps { counter-reset: paso; list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; }
.ga-step { counter-increment: paso; background: #fff; border: 1px solid var(--ga-line); border-radius: var(--ga-radius); padding: 26px 24px; }
.ga-step::before {
content: counter(paso); display: grid; place-items: center; width: 42px; height: 42px; border-radius: 50%;
background: var(--ga-green); color: var(--ga-on-primary); font: 800 1.15rem var(--ga-serif); margin-bottom: 16px;
}
.ga-step h3 { font-size: 1.3rem; margin-bottom: .35em; }
.ga-step p { margin: 0; color: var(--ga-muted); font-size: .96rem; }
@media (max-width: 960px) { .ga-steps { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 540px) { .ga-steps { grid-template-columns: 1fr; } }
/* Donaciones */
.ga-give { display: grid; grid-template-columns: 1.1fr 1fr; gap: 28px; align-items: start; }
.ga-needs { list-style: none; margin: 18px 0 0; padding: 0; }
.ga-needs li { display: flex; gap: 22px; align-items: baseline; padding: 14px 0; border-top: 1px solid rgba(255, 255, 255, .16); }
.ga-needs strong { font: 800 1.8rem/1 var(--ga-serif); color: var(--ga-red); min-width: 1.2em; }
@media (max-width: 820px) { .ga-give { grid-template-columns: 1fr; } }
/* Cifras */
.ga-stats { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 18px; }
.ga-stats li { border: 1px solid rgba(255, 255, 255, .16); background: rgba(255, 255, 255, .05); border-radius: var(--ga-radius); padding: 26px 24px; text-align: center; }
.ga-stats strong { display: block; font: 800 clamp(2.6rem, 5vw, 3.6rem)/1 var(--ga-serif); color: var(--ga-red); margin-bottom: 10px; letter-spacing: -.02em; }
.ga-stats span { color: var(--ga-on-dark-muted); }
/* Casos (perdidos, encontrados…) */
.ga-cases { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 18px; }
.ga-case { background: #fff; border: 1px solid var(--ga-line); border-left: 5px solid var(--ga-red); border-radius: var(--ga-radius); padding: 26px 24px; }
.ga-case h3 { font-size: 1.25rem; }
.ga-case p { margin: 0; color: var(--ga-muted); }
.ga-cases__phone { margin: 28px 0 0; font-weight: 700; display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.ga-cases__phone a { display: inline-flex; align-items: center; gap: 6px; font-size: 1.15rem; }
/* Visita */
.ga-location { display: grid; grid-template-columns: 1.1fr 1fr; background: #fff; border: 1px solid var(--ga-line); border-radius: var(--ga-radius); overflow: hidden; box-shadow: var(--ga-shadow); }
.ga-location__photo img, .ga-location__photo .ga-photo__placeholder { width: 100%; height: 100%; min-height: 300px; object-fit: cover; border-radius: 0; box-shadow: none; aspect-ratio: auto; }
.ga-location__info { padding: clamp(26px, 4vw, 44px); }
.ga-location__actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
@media (max-width: 820px) { .ga-location { grid-template-columns: 1fr; } }
/* Contacto */
.ga-talk { display: grid; grid-template-columns: 1fr 1.15fr; gap: clamp(32px, 6vw, 72px); align-items: start; }
.ga-panel--form { color: var(--ga-ink); }
.ga-panel--form h3 { color: var(--ga-green-dark); }
.ga-section--dark .ga-panel--form a:not(.ga-btn) { color: var(--ga-green); }
@media (max-width: 900px) { .ga-talk { grid-template-columns: 1fr; } }
/* Perros y gatos */
.ga-species { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.ga-species__tile {
position: relative; display: block; aspect-ratio: 16/10; overflow: hidden; border-radius: var(--ga-radius);
background: var(--ga-green); color: #fff; text-decoration: none; isolation: isolate;
}
.ga-species__tile--cat { background: var(--ga-green-dark); }
.ga-species__tile img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform .6s; z-index: -1; }
.ga-species__tile::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, transparent 45%, rgba(0, 0, 0, .55)); z-index: -1; }
.ga-species__tile:hover img { transform: scale(1.05); }
.ga-species__paw { position: absolute; right: 8%; top: 12%; width: 32%; opacity: .2; }
.ga-species__label { position: absolute; left: 24px; bottom: 22px; right: 24px; font: var(--ga-heading-weight) clamp(1.4rem, 3vw, 2.1rem)/1.1 var(--ga-serif); color: #fff; }
@media (max-width: 640px) { .ga-species { grid-template-columns: 1fr; } .ga-species__tile { aspect-ratio: 2/1; } }
/* Preguntas frecuentes */
.ga-faq details { background: #fff; border: 1px solid var(--ga-line); border-radius: var(--ga-radius); padding: 0 24px; margin-bottom: 12px; }
.ga-faq summary { cursor: pointer; list-style: none; padding: 20px 36px 20px 0; font: 700 1.1rem/1.3 var(--ga-serif); color: var(--ga-green-dark); position: relative; }
.ga-faq summary::-webkit-details-marker { display: none; }
.ga-faq summary::after { content: "+"; position: absolute; right: 0; top: 50%; transform: translateY(-50%); font: 400 1.6rem var(--ga-sans); color: var(--ga-red-dark); transition: transform .2s; }
.ga-faq details[open] summary::after { transform: translateY(-50%) rotate(45deg); }
.ga-faq details p { margin: 0 0 20px; color: var(--ga-muted); }
/* =========================================================================
Animales: tarjetas, carrusel, filtros, ficha
========================================================================= */
.ga-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 22px; margin: 0 0 1.5em; }
.ga-card {
position: relative; display: flex; flex-direction: column;
background: #fff; border: 1px solid var(--ga-line); border-radius: var(--ga-radius); overflow: hidden;
box-shadow: 0 1px 2px rgba(0, 0, 0, .04); transition: transform .25s, box-shadow .25s;
}
.ga-card:hover { transform: translateY(-4px); box-shadow: var(--ga-shadow); }
.ga-card__img { aspect-ratio: 4/3; background: var(--ga-green-soft); overflow: hidden; }
.ga-card__img img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s; }
.ga-card:hover .ga-card__img img { transform: scale(1.04); }
.ga-card__placeholder { width: 100%; height: 100%; display: grid; place-items: center; color: var(--ga-green); }
.ga-card__placeholder svg { width: 36%; opacity: .3; }
.ga-card__body { padding: 16px 18px 18px; flex: 1; display: flex; flex-direction: column; }
.ga-card__title { margin: 0 0 4px; font-size: 1.45rem; }
.ga-card__title a { color: inherit; text-decoration: none; }
.ga-card__title a::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.ga-card__meta { margin: 0 0 12px; font-size: .88rem; color: var(--ga-muted); }
.ga-badges { list-style: none; margin: 0 0 12px; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.ga-badges li { padding: 4px 10px; border-radius: 999px; background: var(--ga-green-soft); color: var(--ga-green-dark); font-size: .74rem; font-weight: 700; }
.ga-card__more { margin-top: auto; display: inline-flex; align-items: center; gap: 6px; font-size: .76rem; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--ga-green); }
.ga-status {
display: inline-block; padding: 5px 11px; border-radius: 999px;
font: 800 .7rem/1 var(--ga-sans); letter-spacing: .08em; text-transform: uppercase;
background: #fff; color: var(--ga-green-dark);
}
.ga-card .ga-status { position: absolute; top: 12px; left: 12px; z-index: 2; box-shadow: 0 2px 10px rgba(0, 0, 0, .14); }
.ga-status--urgente { background: var(--ga-red); color: var(--ga-on-red); }
.ga-status--acogida { background: var(--ga-red-soft); color: var(--ga-red-dark); }
.ga-status--reservado { background: var(--ga-green-soft); color: var(--ga-green); }
.ga-status--adoptado { background: var(--ga-green); color: var(--ga-on-primary); }
.ga-empty { padding: 32px; background: var(--ga-sand); border-radius: var(--ga-radius); text-align: center; color: var(--ga-muted); }
/* Carrusel */
.ga-carousel { position: relative; margin: 0 0 1.5em; }
.ga-carousel__track {
display: grid; grid-auto-flow: column; gap: 22px;
grid-auto-columns: calc((100% - 3 * 22px) / 4);
overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory;
scrollbar-width: none; padding: 6px 4px 16px; margin: -6px -4px 0;
}
.ga-carousel__track::-webkit-scrollbar { display: none; }
.ga-carousel__track > * { scroll-snap-align: start; }
.ga-carousel__track:focus-visible { outline-offset: 6px; }
.ga-carousel__nav { display: flex; justify-content: flex-end; gap: 10px; margin-top: 10px; }
.ga-carousel.is-static .ga-carousel__nav { display: none; }
.ga-carousel__btn {
width: 48px; height: 48px; border-radius: 50%; border: 2px solid var(--ga-green); background: transparent;
color: var(--ga-green); font-size: 1.2rem; cursor: pointer; transition: background .2s, color .2s;
}
.ga-carousel__btn:hover:not(:disabled) { background: var(--ga-green); color: var(--ga-on-primary); }
.ga-carousel__btn:disabled { opacity: .3; cursor: default; }
.ga-section--dark .ga-carousel__btn { border-color: #fff; color: #fff; }
@media (max-width: 1080px) { .ga-carousel__track { grid-auto-columns: calc((100% - 2 * 22px) / 3); } }
@media (max-width: 760px) { .ga-carousel__track { grid-auto-columns: calc((100% - 22px) / 1.6); gap: 16px; } }
@media (max-width: 480px) { .ga-carousel__track { grid-auto-columns: 82%; } }
.ga-content .ga-carousel__track { grid-auto-columns: calc((100% - 22px) / 2.3); }
/* Filtros */
.ga-filters { background: #fff; border: 1px solid var(--ga-line); border-radius: var(--ga-radius); padding: clamp(20px, 3vw, 30px); margin-bottom: 28px; box-shadow: var(--ga-shadow); }
.ga-filters__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 22px 40px; }
.ga-filters__label { display: block; font-size: .8rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--ga-muted); margin-bottom: 10px; }
.ga-filters__chips { display: flex; flex-wrap: wrap; gap: 8px; }
.ga-chip {
padding: 9px 18px; border-radius: 999px; border: 1.5px solid color-mix(in srgb, var(--ga-ink) 30%, transparent);
color: var(--ga-ink); text-decoration: none; font-weight: 600; font-size: .95rem; background: #fff; transition: all .15s;
}
.ga-chip:hover { border-color: var(--ga-green); color: var(--ga-green); }
.ga-chip.is-active { background: var(--ga-green); border-color: var(--ga-green); color: var(--ga-on-primary); }
.ga-filters__footer { display: flex; justify-content: space-between; align-items: center; gap: 16px; flex-wrap: wrap; margin-top: 24px; padding-top: 18px; border-top: 1px solid var(--ga-line); }
.ga-filters__count { font-weight: 600; }
.ga-filters__count strong { color: var(--ga-red-dark); }
.ga-pagination { margin-top: 32px; display: flex; gap: 8px; justify-content: center; }
.ga-pagination .page-numbers { padding: 8px 15px; border-radius: 10px; border: 1px solid var(--ga-line); text-decoration: none; background: #fff; }
.ga-pagination .current { background: var(--ga-green); color: var(--ga-on-primary); border-color: var(--ga-green); }
.ga-archive-help { display: flex; justify-content: space-between; align-items: center; gap: 20px; flex-wrap: wrap; margin-top: 56px; }
.ga-archive-help h3 { margin-bottom: .2em; }
.ga-archive-help p { margin: 0; color: var(--ga-muted); }
/* Ficha individual */
.ga-animal { display: grid; grid-template-columns: 1.05fr .95fr; gap: 48px; align-items: start; }
.ga-animal__photo { border-radius: var(--ga-radius); overflow: hidden; background: var(--ga-green-soft); aspect-ratio: 1; position: sticky; top: 110px; }
.ga-animal__photo img { width: 100%; height: 100%; object-fit: cover; }
.ga-animal__photo .ga-card__placeholder svg { width: 30%; }
.ga-animal__facts { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin: 24px 0; padding: 0; list-style: none; }
.ga-animal__facts li { background: #fff; border: 1px solid var(--ga-line); border-radius: calc(var(--ga-radius) * .8); padding: 12px 16px; }
.ga-animal__facts span { display: block; font-size: .74rem; font-weight: 700; text-transform: uppercase; letter-spacing: .1em; color: var(--ga-muted); }
.ga-animal__facts strong { font-size: 1.05rem; }
.ga-tags { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 1.2em; padding: 0; list-style: none; }
.ga-tags li { padding: 5px 12px; border-radius: 999px; background: var(--ga-green-soft); color: var(--ga-green-dark); font-size: .86rem; font-weight: 700; }
.ga-tags li::before { content: "✓ "; }
.ga-cta-box { margin-top: 28px; padding: 28px; border-radius: var(--ga-radius); background: var(--ga-green); color: var(--ga-on-dark); }
.ga-cta-box h3 { color: #fff; }
.ga-box { padding: 26px 28px; border-radius: var(--ga-radius); background: var(--ga-sand); border: 1px solid var(--ga-line); margin-block: 1.6em; }
.ga-box h3 { margin-top: 0; }
.ga-box > :last-child { margin-bottom: 0; }
@media (max-width: 860px) {
.ga-animal { grid-template-columns: 1fr; }
.ga-animal__photo { position: static; }
}
/* =========================================================================
Formularios
========================================================================= */
.ga-form { display: grid; gap: 16px; margin-top: 1em; }
.ga-form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
@media (max-width: 640px) { .ga-form__row { grid-template-columns: 1fr; } }
.ga-form label { display: grid; gap: 7px; font-weight: 700; font-size: .78rem; letter-spacing: .1em; text-transform: uppercase; color: var(--ga-green-dark); }
.ga-form input[type=text], .ga-form input[type=email], .ga-form input[type=tel], .ga-form select, .ga-form textarea {
width: 100%; padding: 13px 15px; border-radius: calc(var(--ga-radius) * .6); border: 1.5px solid var(--ga-line);
background: var(--ga-cream); font: 400 1rem var(--ga-sans); color: var(--ga-ink); text-transform: none; letter-spacing: 0;
}
.ga-form input:focus, .ga-form select:focus, .ga-form textarea:focus { border-color: var(--ga-green); outline: none; box-shadow: 0 0 0 3px var(--ga-green-soft); background: #fff; }
.ga-form .ga-form__check { display: flex; gap: 10px; align-items: flex-start; font-weight: 400; font-size: .95rem; letter-spacing: 0; text-transform: none; color: var(--ga-ink); }
.ga-form .ga-form__check input { margin-top: 5px; }
.ga-form button { justify-self: start; background: var(--ga-green); border-color: var(--ga-green); color: var(--ga-on-primary); }
.ga-form button:hover { background: var(--ga-green-dark); border-color: var(--ga-green-dark); color: var(--ga-on-primary); }
.ga-hp { position: absolute; left: -9999px; }
.ga-notice { padding: 16px 20px; border-radius: calc(var(--ga-radius) * .7); margin-bottom: 16px; }
.ga-notice--ok { background: var(--ga-green-soft); color: var(--ga-green-dark); }
.ga-notice--error { background: var(--ga-red-soft); color: var(--ga-red-dark); }
/* =========================================================================
Contenido de páginas (editor de bloques)
========================================================================= */
.ga-content { padding: clamp(48px, 7vw, 88px) 0; }
.ga-content > * { width: min(100% - 32px, 780px); margin-inline: auto; }
.ga-content > .alignwide { width: min(100% - 32px, var(--ga-wrap)); }
.ga-content > .alignfull { width: 100%; margin-block: clamp(32px, 5vw, 56px); }
.ga-content > .alignfull:first-child { margin-top: calc(-1 * clamp(48px, 7vw, 88px)); }
.ga-content > .alignfull.is-layout-constrained > * { max-width: min(100%, 780px); margin-inline: auto; }
.ga-content > .alignfull.is-layout-constrained > :is(.alignwide, .wp-block-columns) { max-width: min(100%, var(--ga-wrap)); }
.ga-content > * + :is(.wp-block-group, .wp-block-columns, .wp-block-quote, .wp-block-media-text) { margin-top: 2.5rem; }
.ga-content > :is(.wp-block-group, .wp-block-columns, .wp-block-quote) + * { margin-top: 2.5rem; }
.ga-content h2 { margin-top: 1.4em; }
.ga-content h2:first-child { margin-top: 0; }
.ga-content ul, .ga-content ol { padding-left: 1.3em; }
.ga-content li { margin-bottom: .4em; }
.ga-content .wp-block-buttons { margin-block: 1.4em; }
.ga-content .wp-block-image img { border-radius: var(--ga-radius); }
.ga-content .ga-grid { margin-block: 1.5em; }
.ga-pad { padding: clamp(48px, 7vw, 96px) 16px; }
/* Estilos de bloque «Gure Ametsa» (editor → Estilos) */
.is-style-ga-arena { background: var(--ga-sand); }
.is-style-ga-verde { background: var(--ga-green-dark); color: var(--ga-on-dark); }
.is-style-ga-verde :is(h1, h2, h3, h4, a:not(.wp-block-button__link)) { color: #fff; }
.is-style-ga-verde .is-style-outline .wp-block-button__link { color: #fff; border-color: #fff; }
.is-style-ga-tarjeta { background: #fff; border: 1px solid var(--ga-line); border-radius: var(--ga-radius); padding: 28px !important; box-shadow: var(--ga-shadow); }
.is-style-ga-aviso { background: var(--ga-red-soft); border-left: 6px solid var(--ga-red); border-radius: var(--ga-radius); padding: 28px !important; }
.is-style-ga-tarjeta > :last-child, .is-style-ga-aviso > :last-child { margin-bottom: 0; }
p.is-style-ga-antetitulo { font: 700 .78rem/1.3 var(--ga-sans); text-transform: uppercase; letter-spacing: .14em; color: var(--ga-red-dark); margin-bottom: 12px; }
p.is-style-ga-antetitulo::before { content: ""; display: block; width: 56px; height: 4px; border-radius: 4px; background: var(--ga-red); margin-bottom: 22px; }
.has-text-align-center.is-style-ga-antetitulo::before { margin-inline: auto; }
p.is-style-ga-entradilla { font-size: 1.2em; color: var(--ga-muted); }
.is-style-ga-verde p.is-style-ga-entradilla { color: var(--ga-on-dark-muted); }
.wp-block-image.is-style-ga-redondeada img { border-radius: var(--ga-radius); }
.wp-block-image.is-style-ga-arco img { border-radius: 999px 999px var(--ga-radius) var(--ga-radius); aspect-ratio: 4/5; object-fit: cover; box-shadow: var(--ga-shadow); }
ul.is-style-ga-check, ul.is-style-ga-limpia { list-style: none; padding-left: 0 !important; }
ul.is-style-ga-check li { position: relative; padding-left: 1.9em; }
ul.is-style-ga-check li::before { content: "✓"; position: absolute; left: 0; top: 0; font-weight: 800; color: var(--ga-red-dark); }
ol.is-style-ga-pasos { list-style: none; counter-reset: ga-paso; padding-left: 0 !important; display: grid; gap: 18px; }
ol.is-style-ga-pasos li { counter-increment: ga-paso; position: relative; padding-left: 62px; min-height: 44px; }
ol.is-style-ga-pasos li::before {
content: counter(ga-paso); position: absolute; left: 0; top: 0; width: 44px; height: 44px; border-radius: 50%;
display: grid; place-items: center; background: var(--ga-green); color: var(--ga-on-primary); font: 800 1.15rem var(--ga-serif);
}
.wp-block-quote { border-left: 4px solid var(--ga-red); padding-left: 20px; margin-left: 0; font: italic 1.25rem/1.5 var(--ga-serif); }
.wp-block-quote.is-style-ga-testimonio { border: 1px solid var(--ga-line); background: #fff; margin-inline: auto; padding: 32px 32px 26px; border-radius: var(--ga-radius); font-style: normal; font-family: var(--ga-sans); font-size: 1.1rem; }
.wp-block-quote.is-style-ga-testimonio::before { content: "“"; display: block; font: 800 3.4rem/.6 var(--ga-serif); color: var(--ga-red); margin-bottom: 8px; }
.wp-block-quote.is-style-ga-testimonio cite { display: block; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--ga-line); font: 800 1rem var(--ga-serif); font-style: normal; color: var(--ga-green-dark); }
.wp-block-columns.is-style-ga-tarjetas > .wp-block-column { background: #fff; border: 1px solid var(--ga-line); border-radius: var(--ga-radius); padding: 26px; }
.wp-block-columns.is-style-ga-tarjetas > .wp-block-column > :last-child { margin-bottom: 0; }
.wp-block-details { border-bottom: 1px solid var(--ga-line); padding: 14px 0; }
.wp-block-details summary { cursor: pointer; font-weight: 700; font-size: 1.05rem; }
.wp-block-details[open] summary { margin-bottom: 8px; color: var(--ga-green); }
/* =========================================================================
Pie
========================================================================= */
.ga-footer { background: var(--ga-footer-bg); color: color-mix(in srgb, #fff 72%, var(--ga-footer-bg)); padding: 72px 0 28px; font-size: .95rem; }
.ga-footer a { color: #fff; text-decoration: none; }
.ga-footer a:hover { text-decoration: underline; color: #fff; }
.ga-footer__grid { display: grid; grid-template-columns: 1.5fr 1fr 1fr 1.1fr; gap: 40px; }
.ga-footer h2 { color: #fff; font: 800 .76rem/1 var(--ga-sans); letter-spacing: .16em; text-transform: uppercase; margin-bottom: 1.4em; }
.ga-footer ul { list-style: none; margin: 0; padding: 0; }
.ga-footer li { margin-bottom: 10px; }
.ga-footer .ga-brand { color: #fff; margin-bottom: 18px; }
.ga-footer .ga-brand__name small { color: color-mix(in srgb, #fff 60%, transparent); display: block; }
.ga-footer__about p { max-width: 34em; }
.ga-footer__social { display: flex; gap: 8px; margin-top: 18px; }
.ga-footer__social a { display: grid; place-items: center; width: 38px; height: 38px; border: 1px solid rgba(255, 255, 255, .25); border-radius: 8px; }
.ga-footer__social a:hover { background: rgba(255, 255, 255, .1); }
.ga-footer__phone a { font: 700 1.1rem var(--ga-sans); }
.ga-footer__bottom { margin-top: 56px; padding-top: 22px; border-top: 1px solid rgba(255, 255, 255, .14); display: flex; justify-content: space-between; align-items: center; gap: 16px; flex-wrap: wrap; font-size: .85rem; }
.ga-footer__bottom ul { display: flex; gap: 18px; }
.ga-footer__bottom li { margin: 0; }
@media (max-width: 960px) { .ga-footer__grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .ga-footer__grid { grid-template-columns: 1fr; } }
/* =========================================================================
Varios
========================================================================= */
.ga-404 { text-align: center; padding: 110px 0; }
.ga-404 svg { width: 90px; margin: 0 auto 20px; color: var(--ga-green); }
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
}

View File

@@ -0,0 +1,2 @@
<?php
require __DIR__ . '/archive-animal.php';

View File

@@ -0,0 +1,30 @@
<?php
/**
* Tarjeta de animal (dentro del loop).
*/
$id = get_the_ID();
$meta = array_filter( array(
ga_get( $id, 'raza' ) ?: ga_species(),
ga_age( $id ),
ga_label( $id, 'tamano' ),
) );
$compatible = ga_label( $id, 'compatible' ) ?: array();
?>
<article class="ga-card">
<?php ga_status_badge(); ?>
<div class="ga-card__img"><?php ga_animal_photo(); ?></div>
<div class="ga-card__body">
<h3 class="ga-card__title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
<?php if ( $meta ) : ?>
<p class="ga-card__meta"><?php echo esc_html( implode( ' · ', $meta ) ); ?></p>
<?php endif; ?>
<?php if ( $compatible ) : ?>
<ul class="ga-badges">
<?php foreach ( $compatible as $c ) : ?>
<li><?php echo esc_html( ga_compat_label( $c ) ); ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<span class="ga-card__more"><?php ga_e( 'Ver ficha', 'Ikusi fitxa' ); ?> <?php echo ga_icon( 'arrow' ); ?></span>
</div>
</article>

View File

@@ -0,0 +1,18 @@
<?php
$button = ga_opt( 'animals', 'button' )
? sprintf( '<a class="ga-btn ga-btn--primary" href="%s">%s %s</a>', esc_url( get_post_type_archive_link( 'animal' ) ), esc_html( ga_opt( 'animals', 'button' ) ), ga_icon( 'arrow' ) )
: '';
?>
<section class="ga-section" id="animales">
<div class="ga-wrap">
<?php ga_section_head( 'animals', array( 'extra' => $button ) ); ?>
<?php
echo do_shortcode( sprintf(
'[ga_animales numero="%d" estado="%s" vista="%s"]',
max( 1, (int) ga_opt( 'animals', 'count' ) ),
esc_attr( ga_opt( 'animals', 'filter' ) ),
esc_attr( ga_opt( 'animals', 'view' ) )
) );
?>
</div>
</section>

View File

@@ -0,0 +1,11 @@
<?php
/* Contenido de la página «Inicio» / «Hasiera» hecho con el editor de bloques. */
while ( have_posts() ) :
the_post();
if ( trim( get_the_content() ) ) :
?>
<section class="ga-content"><?php the_content(); ?></section>
<?php
endif;
endwhile;
rewind_posts();

View File

@@ -0,0 +1,24 @@
<?php
$items = array();
for ( $i = 1; $i <= 5; $i++ ) {
if ( ga_opt( 'faq', "q$i" ) ) {
$items[] = array( ga_opt( 'faq', "q$i" ), ga_opt( 'faq', "a$i" ) );
}
}
if ( ! $items ) {
return;
}
?>
<section class="ga-section">
<div class="ga-narrow">
<?php ga_section_head( 'faq', array( 'center' => true ) ); ?>
<div class="ga-faq">
<?php foreach ( $items as [ $q, $a ] ) : ?>
<details>
<summary><?php echo esc_html( $q ); ?></summary>
<p><?php echo esc_html( $a ); ?></p>
</details>
<?php endforeach; ?>
</div>
</div>
</section>

View File

@@ -0,0 +1,35 @@
<?php
$image = (int) ga_opt( 'foster', 'image' );
$items = ga_lines( ga_opt( 'foster', 'list' ) );
$url = add_query_arg( 'motivo', 'acogida', ga_page_url( 'contacto' ) ) . '#formulario';
?>
<section class="ga-section" id="acogida">
<div class="ga-wrap ga-split">
<div>
<?php ga_section_head( 'foster' ); ?>
<?php if ( $items ) : ?>
<?php if ( ga_opt( 'foster', 'list_title' ) ) : ?>
<h3 class="ga-list-title"><?php ga_opt_e( 'foster', 'list_title' ); ?></h3>
<?php endif; ?>
<ul class="ga-checklist">
<?php foreach ( $items as $item ) : ?>
<li><?php echo ga_icon( 'check' ); ?><span><?php echo esc_html( $item ); ?></span></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<?php if ( ga_opt( 'foster', 'button' ) ) : ?>
<p class="ga-section__cta"><a class="ga-btn ga-btn--primary" href="<?php echo esc_url( $url ); ?>"><?php ga_opt_e( 'foster', 'button' ); ?> <?php echo ga_icon( 'arrow' ); ?></a></p>
<?php endif; ?>
</div>
<figure class="ga-photo">
<?php if ( $image ) : ?>
<?php echo wp_get_attachment_image( $image, 'large', false, array( 'loading' => 'lazy' ) ); ?>
<?php else : ?>
<div class="ga-photo__placeholder"><?php echo ga_icon( 'paw' ); ?></div>
<?php endif; ?>
<?php if ( ga_opt( 'foster', 'caption' ) ) : ?>
<figcaption><?php ga_opt_e( 'foster', 'caption' ); ?></figcaption>
<?php endif; ?>
</figure>
</div>
</section>

View File

@@ -0,0 +1,33 @@
<?php
$needs = ga_lines( ga_opt( 'give', 'needs' ) );
$shortcode = trim( (string) ga_opt( 'give', 'shortcode' ) );
$url = add_query_arg( 'motivo', 'donaciones', ga_page_url( 'contacto' ) ) . '#formulario';
?>
<section class="ga-section ga-section--sand" id="dona">
<div class="ga-wrap">
<?php ga_section_head( 'give' ); ?>
<div class="ga-give">
<div class="ga-panel">
<?php if ( $shortcode && preg_match( '/^\[[a-z_]+[^\]]*\]$/i', $shortcode ) ) : ?>
<?php echo do_shortcode( $shortcode ); ?>
<?php else : ?>
<h3><?php ga_opt_e( 'give', 'card_title' ); ?></h3>
<p><?php ga_opt_e( 'give', 'card_text' ); ?></p>
<?php if ( ga_opt( 'give', 'button' ) ) : ?>
<a class="ga-btn ga-btn--accent ga-btn--block" href="<?php echo esc_url( $url ); ?>"><?php ga_opt_e( 'give', 'button' ); ?> <?php echo ga_icon( 'arrow' ); ?></a>
<?php endif; ?>
<?php endif; ?>
</div>
<?php if ( $needs ) : ?>
<div class="ga-panel ga-panel--dark">
<h3><?php ga_opt_e( 'give', 'needs_title' ); ?></h3>
<ul class="ga-needs">
<?php foreach ( $needs as $i => $need ) : ?>
<li><strong><?php echo (int) $i + 1; ?></strong><span><?php echo esc_html( $need ); ?></span></li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
</div>
</div>
</section>

View File

@@ -0,0 +1,27 @@
<?php
/* Variante en tarjetas de las «puertas» (usa los textos de Portada principal). */
$colabora = ga_page_url( 'colabora' );
$links = array(
1 => get_post_type_archive_link( 'animal' ),
2 => $colabora . '#acogida',
3 => $colabora . '#voluntariado',
4 => $colabora . '#donaciones',
);
?>
<section class="ga-section ga-section--sand">
<div class="ga-wrap">
<?php ga_section_head( 'help' ); ?>
<div class="ga-doors__grid ga-doors__grid--static">
<?php foreach ( $links as $n => $href ) : ?>
<?php if ( ga_opt( 'hero', "door{$n}_title" ) ) : ?>
<a class="ga-door ga-door--<?php echo (int) $n; ?>" href="<?php echo esc_url( $href ); ?>">
<span class="ga-door__kicker"><?php ga_opt_e( 'hero', "door{$n}_kicker" ); ?></span>
<span class="ga-door__title"><?php ga_opt_e( 'hero', "door{$n}_title" ); ?></span>
<span class="ga-door__text"><?php ga_opt_e( 'hero', "door{$n}_text" ); ?></span>
<span class="ga-door__link"><?php ga_opt_e( 'hero', "door{$n}_link" ); ?> <?php echo ga_icon( 'arrow' ); ?></span>
</a>
<?php endif; ?>
<?php endforeach; ?>
</div>
</div>
</section>

View File

@@ -0,0 +1,88 @@
<?php
$image = (int) ga_opt( 'hero', 'image' );
$video = (int) ga_opt( 'hero', 'video' );
$full = 'full' === ga_opt( 'hero', 'layout' );
$overlay = min( 95, (int) ga_opt( 'hero', 'overlay' ) ) / 100;
$btn1 = ga_link( ga_opt( 'hero', 'btn1_url' ), get_post_type_archive_link( 'animal' ) );
$btn2 = ga_link( ga_opt( 'hero', 'btn2_url' ), ga_page_url( 'contacto', '#formulario' ) );
$doors = ga_opt( 'hero', 'doors' );
$colabora = ga_page_url( 'colabora' );
$door_links = array(
1 => get_post_type_archive_link( 'animal' ),
2 => $colabora . '#acogida',
3 => $colabora . '#voluntariado',
4 => $colabora . '#donaciones',
);
$classes = array( 'ga-hero', $full ? 'ga-hero--full' : 'ga-hero--split' );
if ( $full && ( $image || $video ) ) {
$classes[] = 'has-media';
}
if ( $doors ) {
$classes[] = 'has-doors';
}
?>
<section class="<?php echo esc_attr( implode( ' ', $classes ) ); ?>" style="--ga-overlay:<?php echo esc_attr( $overlay ); ?>">
<?php if ( $full && ( $image || $video ) ) : ?>
<div class="ga-hero__bg" aria-hidden="true">
<?php if ( $video && wp_get_attachment_url( $video ) ) : ?>
<video autoplay muted loop playsinline preload="metadata"
<?php echo $image ? 'poster="' . esc_url( wp_get_attachment_image_url( $image, 'full' ) ) . '"' : ''; ?>>
<source src="<?php echo esc_url( wp_get_attachment_url( $video ) ); ?>" type="<?php echo esc_attr( get_post_mime_type( $video ) ); ?>">
</video>
<?php else : ?>
<?php echo wp_get_attachment_image( $image, 'full', false, array( 'fetchpriority' => 'high', 'alt' => '' ) ); ?>
<?php endif; ?>
</div>
<?php elseif ( $full ) : ?>
<div class="ga-hero__paw" aria-hidden="true"><?php echo ga_icon( 'paw' ); ?></div>
<?php endif; ?>
<div class="ga-wrap ga-hero__inner">
<div class="ga-hero__text">
<?php if ( ga_opt( 'hero', 'eyebrow' ) ) : ?>
<span class="ga-pill"><?php ga_opt_e( 'hero', 'eyebrow' ); ?></span>
<?php endif; ?>
<h1><?php echo ga_highlight( ga_opt( 'hero', 'title' ) ); // Escapado en la función. ?></h1>
<?php if ( ga_opt( 'hero', 'lead' ) ) : ?>
<p class="ga-hero__lead"><?php ga_opt_e( 'hero', 'lead' ); ?></p>
<?php endif; ?>
<div class="ga-hero__actions">
<?php if ( ga_opt( 'hero', 'btn1' ) ) : ?>
<a class="ga-btn ga-btn--accent" href="<?php echo esc_url( $btn1 ); ?>"><?php ga_opt_e( 'hero', 'btn1' ); ?> <?php echo ga_icon( 'arrow' ); ?></a>
<?php endif; ?>
<?php if ( ga_opt( 'hero', 'btn2' ) ) : ?>
<a class="ga-btn ga-btn--ghost" href="<?php echo esc_url( $btn2 ); ?>"><?php ga_opt_e( 'hero', 'btn2' ); ?></a>
<?php endif; ?>
</div>
</div>
<?php if ( ! $full ) : ?>
<div class="ga-hero__media">
<?php if ( $image ) : ?>
<?php echo wp_get_attachment_image( $image, 'large', false, array( 'fetchpriority' => 'high' ) ); ?>
<?php else : ?>
<div class="ga-hero__art"><?php echo ga_icon( 'paw' ); ?></div>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
</section>
<?php if ( $doors ) : ?>
<nav class="ga-doors" aria-label="<?php echo esc_attr( ga__( 'Formas de ayudar', 'Laguntzeko moduak' ) ); ?>">
<div class="ga-wrap ga-doors__grid">
<?php foreach ( $door_links as $n => $href ) : ?>
<?php if ( ga_opt( 'hero', "door{$n}_title" ) ) : ?>
<a class="ga-door ga-door--<?php echo (int) $n; ?>" href="<?php echo esc_url( $href ); ?>">
<span class="ga-door__kicker"><?php ga_opt_e( 'hero', "door{$n}_kicker" ); ?></span>
<span class="ga-door__title"><?php ga_opt_e( 'hero', "door{$n}_title" ); ?></span>
<span class="ga-door__text"><?php ga_opt_e( 'hero', "door{$n}_text" ); ?></span>
<span class="ga-door__link"><?php ga_opt_e( 'hero', "door{$n}_link" ); ?> <?php echo ga_icon( 'arrow' ); ?></span>
</a>
<?php endif; ?>
<?php endforeach; ?>
</div>
</nav>
<?php endif; ?>

View File

@@ -0,0 +1,28 @@
<?php
$cases = array();
for ( $i = 1; $i <= 3; $i++ ) {
if ( ga_opt( 'intake', "caso{$i}_title" ) ) {
$cases[] = array( ga_opt( 'intake', "caso{$i}_title" ), ga_opt( 'intake', "caso{$i}_text" ) );
}
}
if ( ! $cases ) {
return;
}
?>
<section class="ga-section ga-section--sand" id="ayuda">
<div class="ga-wrap">
<?php ga_section_head( 'intake' ); ?>
<div class="ga-cases">
<?php foreach ( $cases as [ $title, $text ] ) : ?>
<div class="ga-case">
<h3><?php echo esc_html( $title ); ?></h3>
<p><?php echo esc_html( $text ); ?></p>
</div>
<?php endforeach; ?>
</div>
<p class="ga-cases__phone">
<?php ga_e( '¿Es urgente? Llámanos:', 'Premiazkoa da? Deitu iezaguzu:' ); ?>
<a href="<?php echo esc_attr( ga_tel_link() ); ?>"><?php echo ga_icon( 'phone' ); ?> <?php echo esc_html( ga_info( 'telefono' ) ); ?></a>
</p>
</div>
</section>

View File

@@ -0,0 +1,35 @@
<?php
/* Accesos grandes a perros y gatos (inspirado en «Meet our dogs / Meet our cats»). */
$tiles = array();
foreach ( array( 'dog' => 'perro', 'cat' => 'gato' ) as $key => $slug ) {
$term = get_term_by( 'slug', $slug, 'especie' );
if ( $term && function_exists( 'pll_get_term' ) ) {
$translated = pll_get_term( $term->term_id, ga_lang() );
$term = $translated ? get_term( $translated, 'especie' ) : $term;
}
$tiles[ $key ] = array(
'url' => $term && ! is_wp_error( $term ) ? get_term_link( $term ) : get_post_type_archive_link( 'animal' ),
'label' => ga_opt( 'species', "{$key}_label" ),
'image' => (int) ga_opt( 'species', "{$key}_image" ),
);
}
?>
<section class="ga-section ga-species-section">
<div class="ga-wrap">
<?php if ( ga_opt( 'species', 'title' ) ) : ?>
<h2 class="ga-center"><?php ga_opt_e( 'species', 'title' ); ?></h2>
<?php endif; ?>
<div class="ga-species">
<?php foreach ( $tiles as $key => $tile ) : ?>
<a class="ga-species__tile ga-species__tile--<?php echo esc_attr( $key ); ?>" href="<?php echo esc_url( $tile['url'] ); ?>">
<?php if ( $tile['image'] ) : ?>
<?php echo wp_get_attachment_image( $tile['image'], 'large', false, array( 'loading' => 'lazy', 'alt' => '' ) ); ?>
<?php else : ?>
<span class="ga-species__paw"><?php echo ga_icon( 'paw' ); ?></span>
<?php endif; ?>
<span class="ga-species__label"><?php echo esc_html( $tile['label'] ); ?> <span aria-hidden="true">→</span></span>
</a>
<?php endforeach; ?>
</div>
</div>
</section>

View File

@@ -0,0 +1,21 @@
<?php
$items = array();
for ( $i = 1; $i <= 4; $i++ ) {
if ( '' !== trim( (string) ga_opt( 'stats', "num$i" ) ) ) {
$items[] = array( ga_opt( 'stats', "num$i" ), ga_opt( 'stats', "label$i" ) );
}
}
if ( ! $items ) {
return;
}
?>
<section class="ga-section ga-section--dark">
<div class="ga-wrap">
<?php ga_section_head( 'stats' ); ?>
<ul class="ga-stats">
<?php foreach ( $items as [ $num, $label ] ) : ?>
<li><strong><?php echo esc_html( $num ); ?></strong><span><?php echo esc_html( $label ); ?></span></li>
<?php endforeach; ?>
</ul>
</div>
</section>

View File

@@ -0,0 +1,18 @@
<section class="ga-section ga-section--sand" id="como-adoptar">
<div class="ga-wrap">
<?php ga_section_head( 'steps' ); ?>
<ol class="ga-steps">
<?php for ( $i = 1; $i <= 4; $i++ ) : ?>
<?php if ( ga_opt( 'steps', "step{$i}_title" ) ) : ?>
<li class="ga-step">
<h3><?php ga_opt_e( 'steps', "step{$i}_title" ); ?></h3>
<p><?php ga_opt_e( 'steps', "step{$i}_text" ); ?></p>
</li>
<?php endif; ?>
<?php endfor; ?>
</ol>
<?php if ( ga_opt( 'steps', 'button' ) ) : ?>
<p class="ga-section__cta"><a class="ga-btn ga-btn--primary" href="<?php echo esc_url( ga_page_url( 'contacto', '#formulario' ) ); ?>"><?php ga_opt_e( 'steps', 'button' ); ?> <?php echo ga_icon( 'arrow' ); ?></a></p>
<?php endif; ?>
</div>
</section>

View File

@@ -0,0 +1,25 @@
<?php
/* Últimos animales adoptados: se oculta si todavía no hay ninguno. */
$adopted = ga_query_animals( array(
'numero' => max( 1, (int) ga_opt( 'stories', 'count' ) ),
'estado' => 'adoptado',
) );
if ( ! $adopted->have_posts() ) {
return;
}
?>
<section class="ga-section">
<div class="ga-wrap">
<?php ga_section_head( 'stories', array( 'center' => true ) ); ?>
<?php
$carousel = 'carrusel' === ga_opt( 'stories', 'view' );
$carousel ? ga_carousel_open( ga_opt( 'stories', 'title' ) ) : print( '<div class="ga-grid">' );
while ( $adopted->have_posts() ) :
$adopted->the_post();
get_template_part( 'template-parts/animal-card' );
endwhile;
wp_reset_postdata();
$carousel ? ga_carousel_close() : print( '</div>' );
?>
</div>
</section>

View File

@@ -0,0 +1,25 @@
<section class="ga-section ga-section--dark" id="contacto">
<div class="ga-wrap ga-talk">
<div>
<?php ga_section_head( 'talk' ); ?>
<ul class="ga-iconlist ga-iconlist--big">
<?php if ( ga_info( 'telefono' ) ) : ?>
<li><?php echo ga_icon( 'phone' ); ?><span><strong><?php ga_e( 'Teléfono', 'Telefonoa' ); ?></strong><a href="<?php echo esc_attr( ga_tel_link() ); ?>"><?php echo esc_html( ga_info( 'telefono' ) ); ?></a></span></li>
<?php endif; ?>
<?php if ( ga_info( 'email' ) ) : ?>
<li><?php echo ga_icon( 'mail' ); ?><span><strong>Email</strong><a href="mailto:<?php echo esc_attr( ga_info( 'email' ) ); ?>"><?php echo esc_html( ga_info( 'email' ) ); ?></a></span></li>
<?php endif; ?>
<?php if ( ga_info( 'direccion' ) ) : ?>
<li><?php echo ga_icon( 'pin' ); ?><span><strong><?php ga_e( 'Dirección', 'Helbidea' ); ?></strong><?php echo esc_html( ga_info( 'direccion' ) ); ?></span></li>
<?php endif; ?>
<?php if ( ga_info( 'horario' ) ) : ?>
<li><?php echo ga_icon( 'clock' ); ?><span><strong><?php ga_e( 'Horario', 'Ordutegia' ); ?></strong><?php echo esc_html( ga_info( 'horario' ) ); ?></span></li>
<?php endif; ?>
</ul>
</div>
<div class="ga-panel ga-panel--form" id="formulario">
<h3><?php ga_opt_e( 'talk', 'form_title' ); ?></h3>
<?php echo do_shortcode( '[ga_contacto]' ); ?>
</div>
</div>
</section>

View File

@@ -0,0 +1,39 @@
<?php
$image = (int) ga_opt( 'visit', 'image' );
?>
<section class="ga-section ga-section--sand" id="visitanos">
<div class="ga-wrap">
<?php ga_section_head( 'visit' ); ?>
<div class="ga-location">
<div class="ga-location__photo">
<?php if ( $image ) : ?>
<?php echo wp_get_attachment_image( $image, 'large', false, array( 'loading' => 'lazy' ) ); ?>
<?php else : ?>
<div class="ga-photo__placeholder"><?php echo ga_icon( 'paw' ); ?></div>
<?php endif; ?>
</div>
<div class="ga-location__info">
<h3><?php echo esc_html( ga_opt( 'header', 'brand_line1' ) . ' ' . ga_opt( 'header', 'brand_line2' ) ); ?></h3>
<ul class="ga-iconlist">
<?php if ( ga_info( 'direccion' ) ) : ?>
<li><?php echo ga_icon( 'pin' ); ?><span><?php echo esc_html( ga_info( 'direccion' ) ); ?></span></li>
<?php endif; ?>
<?php if ( ga_info( 'horario' ) ) : ?>
<li><?php echo ga_icon( 'clock' ); ?><span><?php echo esc_html( ga_info( 'horario' ) ); ?></span></li>
<?php endif; ?>
<?php if ( ga_info( 'telefono' ) ) : ?>
<li><?php echo ga_icon( 'phone' ); ?><a href="<?php echo esc_attr( ga_tel_link() ); ?>"><?php echo esc_html( ga_info( 'telefono' ) ); ?></a></li>
<?php endif; ?>
</ul>
<div class="ga-location__actions">
<?php if ( ga_info( 'maps' ) ) : ?>
<a class="ga-btn ga-btn--primary" href="<?php echo esc_url( ga_info( 'maps' ) ); ?>" target="_blank" rel="noopener"><?php ga_e( 'Cómo llegar', 'Nola iritsi' ); ?> <?php echo ga_icon( 'arrow' ); ?></a>
<?php endif; ?>
<?php if ( ga_opt( 'visit', 'button' ) ) : ?>
<a class="ga-btn ga-btn--outline" href="<?php echo esc_url( ga_page_url( 'hotel' ) ); ?>"><?php ga_opt_e( 'visit', 'button' ); ?></a>
<?php endif; ?>
</div>
</div>
</div>
</div>
</section>