# Recursos visuais e interactivos HTML5

Aplicar estos patrones a materiais HTML autónomos (apuntamentos, guías, fichas, contos ou recursos para Moodle). Manter o CSS e o JavaScript dentro do mesmo documento e non cargar recursos remotos.

## Disponibilidade e nome de uso

Esta é unha **referencia interna** da skill `edu-didactic-generator`, non unha segunda skill. Cando a skill estea instalada, consultala automaticamente ao solicitar un diagrama, un gráfico de datos, un comparador ou calquera dos recursos interactivos de Moodle listados na Sección 6.1 do `SKILL.md`.

Se se traballa nun Proxecto ou nun chat baseado en documentos adxuntos, subir este ficheiro xunto co `SKILL.md` e conservar o seu nome e ruta: `references/recursos-visuais-html5.md`.

Antes de xerar calquera destes patróns, comprobar a paleta indicada ou as cores base de [`sistema-visual.md`](sistema-visual.md) e adaptar as variables. Para ilustracións, personaxes ou escenas que non encaixan nestes patróns (todos baseados en SVG/HTML), usar o fluxo de prompt de imaxe da Sección 6.5 do `SKILL.md`.

## Plan de imaxes e inserción

Cando un material precise varios visuais, entrega unha táboa: identificador, apartado, finalidade pedagóxica, tipo SVG/ilustración, nome de ficheiro, texto alternativo e pé. Usa nomes como `ud03-ciclo-auga.svg` ou `ud03-escena-01.png`, sen espazos. Mantén o mesmo nome no prompt, no marcador e na inserción final.

Para esquemas, iconas e conceptos sinxelos, entrega SVG editable inline ou como ficheiro con `xmlns="http://www.w3.org/2000/svg"`, `viewBox`, título e descrición. Usa identificadores únicos cando haxa varios SVG. Nos gráficos, alturas e escalas deben representar exactamente os datos da táboa; non inventes cifras nin empregues unha imaxe xerada para representar datos exactos.

Para ilustracións, acompaña o nome de ficheiro dun prompt listo para copiar: suxeito/acción, finalidade didáctica, idade, estilo, paleta, composición e proporción, continuidade de personaxes e detalles que evitar. Exemplo de identificador: **ud03-escena-01.png · apartado 2 · 4:3**. Non afirmes que a imaxe existe se só entregaches o prompt.

### HTML

Antes de dispoñer do ficheiro, usa un marcador visible no lugar correspondente; evita unha etiqueta img cunha ruta inexistente. Entrega no anexo docente o código de substitución:

```html
<!-- Substituír o marcador cando exista images/ud03-escena-01.png -->
<figure>
  <img src="images/ud03-escena-01.png"
       alt="Descrición do contido relevante para aprender"
       width="1200" height="900" style="max-width:100%;height:auto">
  <figcaption>Pé da ilustración relacionado coa explicación.</figcaption>
</figure>
```

As dimensións son un exemplo: axústaas ao ficheiro final. Un HTML con imaxes externas locais require distribuír tamén a carpeta `images/`; se se pediu un único ficheiro autocontido, incrusta SVG ou a imaxe como data URI unha vez dispoñible. Non declares autocontido un HTML que depende de ficheiros separados.

### Markdown

Entrega o marcador visible mentres a imaxe estea pendente e a sintaxe final no anexo: `![Texto alternativo](images/ud03-escena-01.png)`. Non uses a ruta pendente como se xa fose unha ilustración dispoñible.

### Word

No punto correspondente, deixa `[IMAXE PENDENTE: ud03-escena-01.png - apartado 2 - proporción 4:3]`, seguido do pé previsto. No anexo docente indica prompt, texto alternativo e tamaño orientativo, limitado ao ancho útil da páxina. Un nome de ficheiro escrito no documento non incrusta unha imaxe.

Cando o ficheiro final exista e se xere DOCX, incrústa a imaxe no paquete Word, cunha relación válida ao recurso en `word/media`, texto alternativo e disposición en liña co texto. Usa unha ferramenta de documentos dispoñible e comproba que non sexa só unha ligazón externa. Para SVG, confirma compatibilidade do xerador e do Word de destino; se require PNG, conserva o SVG editable e converte con resolución suficiente. Non prometas incrustación ata comprobar o DOCX xerado.

## Patróns dispoñibles

| Necesidade | Patrón | Etapa habitual |
|---|---|---|
| Mostrar un ciclo, proceso ou relación | Diagrama SVG inline | ESO / Bacharelato, Primaria superior |
| Contrastar dúas alternativas | Comparador con botóns | ESO / Bacharelato |
| Comparar cantidades ou datos | Gráfico de barras SVG + táboa accesible | ESO / Bacharelato |
| Memorizar termo-definición | Tarxetas flash (flashcards) | Primaria - Bacharelato |
| Revisar vocabulario ou repasar | Cuestionario autoavaliable | ESO / Bacharelato |
| Ilustrar un conto, personaxe ou escena | Prompt de imaxe para IA externa (`SKILL.md`, Sección 6.5) | Infantil / Primaria |

Cada visual debe ter unha finalidade explícita no texto: «O diagrama amosa...». Manter a alternativa textual próxima, non só en atributos ARIA.

## Diagrama SVG inline

```html
<figure class="concept-map">
  <svg viewBox="0 0 720 220" role="img" aria-labelledby="diagram-title diagram-desc">
    <title id="diagram-title">O ciclo da auga</title>
    <desc id="diagram-desc">A auga evapórase, forma nubes, precipita como choiva e regresa ao mar polos ríos.</desc>
    <defs>
      <marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
        <path d="M 0 0 L 10 5 L 0 10 z" fill="currentColor"></path>
      </marker>
    </defs>
    <g class="node"><rect x="20" y="70" width="170" height="80" rx="10"></rect><text x="105" y="115" text-anchor="middle">Evaporación</text></g>
    <path class="connector" d="M190 110H270" marker-end="url(#arrow)"></path>
    <g class="node"><rect x="280" y="70" width="170" height="80" rx="10"></rect><text x="365" y="115" text-anchor="middle">Nubes</text></g>
    <path class="connector" d="M450 110H530" marker-end="url(#arrow)"></path>
    <g class="node"><rect x="540" y="70" width="160" height="80" rx="10"></rect><text x="620" y="115" text-anchor="middle">Choiva</text></g>
  </svg>
  <figcaption>Ciclo simplificado: evaporación → nubes → choiva → mar (polos ríos).</figcaption>
</figure>
```

```css
.concept-map svg { display:block; width:100%; height:auto; color:var(--primary); }
.concept-map .node rect { fill:#fff; stroke:currentColor; stroke-width:2; }
.concept-map text { fill:var(--text-main); font:600 16px system-ui,sans-serif; }
.concept-map .connector { fill:none; stroke:currentColor; stroke-width:2.5; }
@media print { .concept-map { break-inside:avoid; } }
```

Usar `viewBox` para que escale, texto real dentro do SVG (nunca convertido en trazado) e conectores con marcadores, non só con cor. Para Infantil/Primaria, simplificar a 2-3 nodos e usar iconos recoñecibles en vez de texto técnico.

## Comparador (contrastar alternativas)

Útil en ESO/Bacharelato para contrastar dous conceptos, dous períodos históricos ou dous métodos.

```html
<div class="comparator" data-default="opt-a">
  <div role="group" aria-label="Elixir alternativa a comparar">
    <button type="button" data-target="opt-a" aria-pressed="true">Fotosíntese</button>
    <button type="button" data-target="opt-b" aria-pressed="false">Respiración celular</button>
  </div>
  <div id="opt-a" class="comparator-panel">
    <p><strong>Fotosíntese:</strong> as plantas transforman luz, auga e CO₂ en glicosa e osíxeno.</p>
  </div>
  <div id="opt-b" class="comparator-panel" hidden>
    <p><strong>Respiración celular:</strong> as células transforman glicosa e osíxeno en enerxía, auga e CO₂.</p>
  </div>
</div>
```

```css
.comparator [role="group"] { display:flex; gap:.5rem; flex-wrap:wrap; margin-bottom:1rem; }
.comparator button[aria-pressed="true"] { background:var(--primary); color:#fff; }
.comparator-panel { border:1px solid var(--border); border-radius:8px; padding:1rem; }
@media print { .comparator-panel[hidden] { display:block !important; } }
```

```js
document.querySelectorAll('.comparator').forEach((comparator) => {
  const buttons = comparator.querySelectorAll('[data-target]');
  buttons.forEach((button) => {
    button.addEventListener('click', () => {
      buttons.forEach((b) => {
        b.setAttribute('aria-pressed', String(b === button));
        const panel = comparator.querySelector('#' + b.dataset.target);
        panel.hidden = b !== button;
      });
    });
  });
});
```

En impresión, amosar todos os paneis (ver regra CSS anterior): o papel non ten interacción.

## Gráfico de datos simple (barras, SVG)

Para cifras sinxelas (2-6 valores): resultados dunha enquisa de aula, datos dun proxecto. Se o contorno dispón da skill `dataviz`, aplicar os seus criterios de paleta e forma antes de fixar cores; se non, usar as variables da paleta elixida en [`sistema-visual.md`](sistema-visual.md) mantendo contraste AA. Acompañar sempre o SVG dunha táboa accesible cos mesmos datos.

```html
<figure class="bar-chart">
  <svg viewBox="0 0 300 160" role="img" aria-labelledby="chart-title">
    <title id="chart-title">Froita preferida pola clase</title>
    <g class="bar"><rect x="20" y="44" width="40" height="96"></rect><text x="40" y="150" text-anchor="middle">Mazá</text></g>
    <g class="bar"><rect x="100" y="76" width="40" height="64"></rect><text x="120" y="150" text-anchor="middle">Plátano</text></g>
    <g class="bar"><rect x="180" y="108" width="40" height="32"></rect><text x="200" y="150" text-anchor="middle">Laranxa</text></g>
  </svg>
  <figcaption>Ver táboa de datos exacta a continuación.</figcaption>
</figure>
<table class="sr-data-table">
  <caption>Froita preferida pola clase</caption>
  <thead><tr><th>Froita</th><th>Votos</th></tr></thead>
  <tbody>
    <tr><td>Mazá</td><td>12</td></tr>
    <tr><td>Plátano</td><td>8</td></tr>
    <tr><td>Laranxa</td><td>4</td></tr>
  </tbody>
</table>
```

```css
.bar-chart svg { width:100%; max-width:360px; height:auto; }
.bar-chart .bar rect { fill:var(--primary); }
.bar-chart .bar text { fill:var(--text-main); font:600 11px system-ui,sans-serif; }
```

Non usar para series longas: nese caso, unha táboa soa é máis clara.

## Tarxetas flash (flashcards)

Un dos recursos interactivos de Moodle listados en `SKILL.md`, Sección 6.1. A tarxeta xira ao facer clic ou premer Intro/Espazo; a resposta debe estar dispoñible tamén en impresión.

```html
<div class="flashcard" tabindex="0" role="button" aria-pressed="false" aria-label="Tarxeta: fotosíntese. Premer para ver a definición.">
  <div class="flashcard-face flashcard-front"><p>Fotosíntese</p></div>
  <div class="flashcard-face flashcard-back" hidden><p>Proceso polo que as plantas transforman a luz en enerxía química.</p></div>
</div>
```

```css
.flashcard { border:2px solid var(--primary); border-radius:12px; padding:1.5rem; text-align:center; cursor:pointer; max-width:320px; }
.flashcard:focus-visible { outline:3px solid var(--warning); outline-offset:3px; }
@media print { .flashcard-back { display:block !important; } .flashcard-front::after { content:" → ver resposta debaixo"; } }
```

```js
document.querySelectorAll('.flashcard').forEach((card) => {
  const front = card.querySelector('.flashcard-front');
  const back = card.querySelector('.flashcard-back');
  const flip = () => {
    const showBack = back.hidden;
    back.hidden = !showBack;
    front.hidden = showBack;
    card.setAttribute('aria-pressed', String(showBack));
  };
  card.addEventListener('click', flip);
  card.addEventListener('keydown', (e) => {
    if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); flip(); }
  });
});
```

Para os demais recursos de Moodle (liña do tempo, arrastrar e soltar, acordeón, crebacabezas), seguir os mesmos principios de accesibilidade e impresión destes patróns: contido presente no DOM dende o principio, operación completa por teclado, e solución visible ao imprimir.
