Bloque 3 · Componentes 8–14

Section, stats, quote, chip, mockup, logo, cookies.

Las piezas estructurales y los wrappers que el equipo combina para construir páginas reales sin tocar utilidades sueltas.

08 / 14 · Layout

Section wrapper

Patrón Websalia · obligatorio

Toda página usa .sec + .sec__inner. .sec controla padding vertical clamp(48 px, 8 vw, 96 px) y el fondo (cream/paper/navy). .sec__inner aplica max-width 1240 px y padding horizontal clamp(20 px, 4 vw, 32 px).

Variantes · cream · paper · navy
sec--cream

Fondo por defecto.

sec--paper

Pausa elevada.

sec--navy

Bloque invertido.

HTML
<section class="sec sec--paper">
  <div class="sec__inner">
    <!-- contenido -->
  </div>
</section>
.astro · Section.astro
---
interface Props {
  bg?: 'cream' | 'paper' | 'navy';
  id?: string;
}
const { bg='cream', id } = Astro.props;
---
<section id={id} class={`sec sec--${bg}`}>
  <div class="sec__inner">
    <slot />
  </div>
</section>
Cómo usar
  • Alternar cream/paper para crear ritmo vertical en una página larga.
  • Una sola sec--navy por encima del footer crea cierre.
  • Encadenar secciones sin contenedores extra en medio.
Cómo NO
  • Sin .sec__inner el contenido pega al borde — siempre van juntos.
  • Custom max-width interno: tu max-width es 1240 px, no negociable.
  • Alternar 5 fondos seguidos — máximo 2 colores intercalados.
09 / 14 · Data

Stat / Number

Cifras del torneo · 160 · 95 · 290 · 3.300

Grid de 4 columnas en desktop, 2 en mobile. Número en display 900 navy (o ball sobre navy), etiqueta en mono-tag steel arriba con borde superior 2 px.

Sobre cream
160
Jugadores torneo principal
95
Jugadores BeachTennis
290
Comensales cena clausura
3.300
Newsletter CN El Balís
Sobre navy · acento amarillo legal
160
Jugadores torneo principal
95
Jugadores BeachTennis
290
Comensales cena clausura
3.300
Newsletter CN El Balís
HTML
<div class="stats">
  <div class="stat">
    <div class="stat__num">160</div>
    <div class="stat__lab">Jugadores torneo principal</div>
  </div>
  <!-- 3 más -->
</div>
.astro · Stat.astro
---
interface Props { num: string | number; label: string; }
const { num, label } = Astro.props;
---
<div class="stat">
  <div class="stat__num">{num}</div>
  <div class="stat__lab">{label}</div>
</div>
Cómo usar
  • Las 4 cifras canónicas del torneo: 160 / 95 / 290 / 3.300.
  • Separador de millares en español: punto (3.300, no 3,300).
  • Label en imperativo corto.
Cómo NO
  • Animar los números (counter-up) sin justificación.
  • Mezclar cifras del torneo con stats decorativas inventadas.
  • Iconos al lado de cada cifra — el número es protagonista.
10 / 14 · Editorial

Quote

Sin comillas decorativas

Cita editorial sin comillas tipográficas grandes. Línea navy 2 px arriba como marca. Texto en display 900 con line-height 1.1.

El sábado a las 7 en pista 3. Lleva la bola que se gana siempre.

— Padelgazar · voz de marca

Cinco veranos jugando juntos. Este es el sexto.

— Padelgazar 2026
HTML
<blockquote class="quote">
  <p class="quote__text">
    Cinco veranos jugando juntos. Este es el sexto.
  </p>
  <footer class="quote__cite">
    — Padelgazar 2026
  </footer>
</blockquote>
.astro · Quote.astro
---
interface Props { cite?: string; }
const { cite } = Astro.props;
---
<blockquote class="quote">
  <p class="quote__text"><slot /></p>
  {cite && <footer class="quote__cite">— {cite}</footer>}
</blockquote>
Cómo usar
  • Frases cortas con tono propio. Máximo dos por página.
  • Citar a la marca, no inventar testimonios falsos.
Cómo NO
  • Comillas tipográficas decorativas gigantes.
  • Citas en italic (cero italic en el sistema).
  • Testimonios firmados con foto-stock anónima.
11 / 14 · Inline

Tag · Pill · Chip

Incluye .accent-chip canónico

Tag mono-tag minúsculo para metadatos. Pill redondeado puntual. .accent-chip es la placa navy que permite usar amarillo sobre cream/paper.

Tag · variantes
Categoría Mixta A Sábado 18·07 Pista 3
Accent chip · única forma legal de usar amarillo sobre cream
2026 Edición VI #PADELGAZAR2026 Nuevo
Pill
Inscripciones abiertas Plazas disponibles
HTML · canónico
<!-- .accent-chip · INMUTABLE -->
<span class="accent-chip">2026</span>

<span class="tag tag--navy">Sábado 18·07</span>
<span class="pill">Inscripciones abiertas</span>
.astro · Chip.astro
---
interface Props {
  variant?: 'accent' | 'tag' | 'tag-navy'
         | 'tag-outline' | 'pill' | 'pill-navy';
}
const { variant='tag' } = Astro.props;
const map = {
  'accent':      'accent-chip',
  'tag':         'tag',
  'tag-navy':    'tag tag--navy',
  'tag-outline': 'tag tag--outline',
  'pill':        'pill',
  'pill-navy':   'pill pill--navy',
};
---
<span class={map[variant]}><slot /></span>
Cómo usar
  • .accent-chip para el año, edición, hashtag, una palabra clave.
  • .tag para metadatos compactos: jornada, pista, hora.
  • Pill solo cuando una pieza necesita un estado claramente "activo".
Cómo NO
  • Pintar .accent-chip de otro color — siempre navy + ball.
  • Cuatro chips amarillos seguidos · ≤5 % de la pieza.
  • Pills colorinches por categoría — el color no informa.
12 / 14 · Media

Image / Mockup wrapper

5 ratios · label opcional

Radius lg 8 px, overflow oculto, ratios 16:9 · 4:3 · 1:1 · 3:4 · 9:16. Placeholder con tramado paper + etiqueta. Nunca stock genérico de pádel.

Ratios · placeholders explícitos
Banner web · 16:9 Hero / categorías
Tarjeta · 4:3 Categoría
Post IG · 1:1
Retrato · 3:4
Story · 9:16 RRSS
HTML
<figure class="imgw imgw--16-9">
  <img src="/img/cena-clausura.jpg" alt="Cena de clausura 2025" />
  <span class="imgw__label">Edición 2025</span>
</figure>
.astro · Image.astro
---
interface Props {
  src?:   string;
  alt?:   string;
  ratio?: '16-9' | '4-3' | '1-1' | '3-4' | '9-16';
  label?: string;
  placeholder?: string;
}
const { src, alt='', ratio='16-9', label, placeholder } = Astro.props;
---
<figure class={`imgw imgw--${ratio}`}>
  {src
    ? <img src={src} alt={alt} loading="lazy" />
    : <span class="imgw__placeholder">{placeholder ?? 'Imagen pendiente'}</span>}
  {label && <span class="imgw__label">{label}</span>}
</figure>
Cómo usar
  • Placeholders con label explícito en producción mientras no llega la foto real.
  • Direction de arte del manual: luz mediterránea natural, sujetos haciendo algo.
  • Label opcional para identificar edición o evento.
Cómo NO
  • Stock genérico de Unsplash/Pexels con saltos cenitales y cara de esfuerzo.
  • Filtros HDR, viñeteado, B/N dramático.
  • Imagen sin alt.
13 / 14 · Brand

Logo lockup

Positivo · Negativo · Mono blanco · Co-branding

Sello circular. Tres versiones: positivo (navy sobre cream), negativo (cream sobre navy), mono blanco (overlay sobre foto). Área de respeto = 1/4 del lado del sello. Tamaño mínimo digital 32 px (favicon).

Versiones
Positivo · uso por defecto
Negativo · fondos oscuros
Mono blanco · overlay foto (cumple AA)
Escala digital
32 · favicon
48 · avatar
80 · header
200 · hero
Co-branding Websalia · obligatorio en footer
· Diseñado por Websalia
HTML
<a class="lockup lockup--md" href="/">
  <img class="lockup__sello"
       src="/logos/padelgazar-positivo.svg"
       alt="Padelgazar" />
</a>

<span class="cobrand">
  Diseñado por
  <img src="/logos/websalia.svg" alt="Websalia" />
</span>
.astro · Logo.astro
---
interface Props {
  version?: 'positivo' | 'negativo' | 'mono-blanco';
  size?:    'xs' | 'sm' | 'md' | 'lg' | 'xl';
  href?:    string;
}
const { version='positivo', size='md', href } = Astro.props;
const Tag = href ? 'a' : 'span';
---
<Tag href={href} class={`lockup lockup--${size}`}>
  <img class="lockup__sello"
       src={`/logos/padelgazar-${version}.svg`}
       alt="Padelgazar" />
</Tag>
Cómo usar
  • Positivo navy/cream por defecto. Negativo solo en navy. Mono-blanco solo en foto con contraste AA.
  • Área de respeto = 1/4 del sello en cada lado.
  • Co-branding Websalia 32 px alto en footer de TODAS las páginas.
Cómo NO
  • Recolorear, deformar, rotar, espejar, sombra, glow, neon.
  • Logo sobre amarillo. Logo bajo el tamaño mínimo.
  • Logo sobre foto ruidosa sin contraste suficiente.
14 / 14 · System

Cookie banner

Nativo · sin Cookiebot

Implementación propia. Fondo navy, dos botones — Aceptar primary y Solo necesarias secondary. Consent persistido en localStorage, sin servicios externos.

Mockup inline
HTML + JS · vanilla
<div id="cookies" class="cookie" hidden>
  <p class="cookie__text">
    <strong>Cookies.</strong>
    Usamos cookies propias…
  </p>
  <div class="cookie__actions">
    <button class="btn btn--accent btn--sm"
            data-consent="all">Aceptar</button>
    <button class="btn btn--secondary on-navy btn--sm"
            data-consent="essential">Solo necesarias</button>
  </div>
</div>
<script>
  const el = document.getElementById('cookies');
  if (!localStorage.getItem('pg-consent')) el.hidden = false;
  el.addEventListener('click', e => {
    const v = e.target.dataset.consent;
    if (!v) return;
    localStorage.setItem('pg-consent', v);
    el.hidden = true;
  });
</script>
.astro · CookieBanner.astro
---
// src/components/CookieBanner.astro
---
<div id="cookies" class="cookie" hidden>
  <p class="cookie__text">
    <strong>Cookies.</strong> Usamos cookies propias para que la web funcione
    y para entender qué páginas se visitan más. Sin terceros, sin publicidad.
    <a href="/cookies">Más detalle</a>.
  </p>
  <div class="cookie__actions">
    <button class="btn btn--accent btn--sm"      data-consent="all">Aceptar</button>
    <button class="btn btn--secondary on-navy btn--sm" data-consent="essential">Solo necesarias</button>
  </div>
</div>
<script>
  const el = document.getElementById('cookies');
  if (!localStorage.getItem('pg-consent')) el.hidden = false;
  el.addEventListener('click', e => {
    const v = (e.target as HTMLElement).dataset.consent;
    if (!v) return;
    localStorage.setItem('pg-consent', v); el.hidden = true;
  });
</script>
Cómo usar
  • Mostrar solo si no hay valor en pg-consent.
  • Texto en voz Padelgazar: directo, sin "estimado usuario".
  • "Aceptar" en accent (estamos sobre navy, es legal).
Cómo NO
  • Modal bloqueante que cubre toda la página.
  • Servicios externos tipo Cookiebot que cargan scripts antes del consent.
  • Texto legal kilométrico — el detalle vive en /cookies.