diff --git a/.agents/AGENTS.md b/.agents/AGENTS.md
new file mode 100644
index 0000000..2538a8f
--- /dev/null
+++ b/.agents/AGENTS.md
@@ -0,0 +1,3 @@
+# Regole del Progetto
+
+Quando trovi dei trattini verticali `|` tra gli accordi, ricordati di inserirli all'interno della riga degli accordi (cioè racchiusi tra parentesi quadre, ad esempio come accordo `[|]`), non come testo normale.
diff --git a/parametri_canti_comunita.md b/parametri_canti_comunita.md
new file mode 100644
index 0000000..bf4744f
--- /dev/null
+++ b/parametri_canti_comunita.md
@@ -0,0 +1,144 @@
+# Parametri letti da canti.json e da Comunità
+
+Questo documento elenca tutti i parametri e i campi strutturati che vengono letti, elaborati e salvati dall'applicazione a partire dal file globale `canti.json` e dalle API/file di configurazione delle **Comunità**.
+
+---
+
+## 1. Parametri da `canti.json`
+
+Il file `canti.json` rappresenta il database globale dei canti dell'applicazione. Viene scaricato dall'endpoint configurato in `CantiService` (es. `https://www.canticristiani.it/api/canti.json`).
+
+### Struttura Principale del File
+
+Il JSON restituito contiene diversi nodi chiave, ciascuno contenente un array `data`:
+
+```json
+{
+ "canti": { "data": [...] },
+ "indice_liturgico": { "data": [...] },
+ "indice_tematico": { "data": [...] },
+ "tema": { "data": [...] },
+ "canti_eseguiti": { "data": [...] }
+}
+```
+
+#### Nodo `canti.data` (Lista dei Canti)
+Ciascun elemento rappresenta un canto e viene mappato nell'interfaccia `Canto`:
+
+| Parametro Originale | Tipo | Descrizione |
+| :--- | :--- | :--- |
+| `id_canti` | `number` | Identificativo univoco del canto (usato internamente anche come stringa `id`). |
+| `titolo` | `string` | Titolo del canto. |
+| `testo` | `string` | Testo del canto (può includere indicazioni di accordi). |
+| `accordi` | `string` (opzionale) | Accordi musicali associati al canto. |
+| `autore` | `string` (opzionale) | Autore o autori del canto. |
+| `link_youtube` | `string` (opzionale) | URL o ID del video di YouTube associato al canto. |
+| `data_update` | `string` (opzionale) | Data dell'ultimo aggiornamento (formato `YYYY-MM-DD HH:mm:ss`, formattata a schermo in `DD/MM/YYYY`). |
+| `nonValidato` | `boolean` (opzionale) | Indica se il canto è in attesa di validazione. |
+| `isPersonal` | `boolean` (opzionale) | Flag locale per identificare se si tratta di un canto personale dell'utente. |
+
+*Nota: Durante l'importazione, viene aggiunto un array `id_momenti: number[]` ricavato dalla tabella pivot `tema.data`.*
+
+#### Nodo `indice_liturgico.data` e `indice_tematico.data` (Indici/Tag)
+Mappati nell'interfaccia `Indice`:
+
+| Parametro Originale | Tipo | Descrizione |
+| :--- | :--- | :--- |
+| `id_indice_liturgico` / `id_indice_tematico` | `number` | Identificativo dell'indice/momento. |
+| `tag_name` | `string` | Nome visualizzato del tag (es. "Ingresso", "Offertorio"). |
+| `slug` | `string` | Versione ottimizzata per URL del tag. |
+
+*Nota: A livello applicativo viene aggiunto il campo `type` con valore `'liturgico'` o `'tematico'`.*
+
+#### Nodo `tema.data` (Relazione Pivot Canti-Indici)
+Utilizzato per associare a ogni canto i rispettivi momenti liturgici o tematici:
+
+| Parametro Originale | Tipo | Descrizione |
+| :--- | :--- | :--- |
+| `id_canti` | `number` | ID del canto associato. |
+| `id_momento` | `number` | ID del momento liturgico/tematico. |
+
+#### Nodo `canti_eseguiti.data`
+Informazioni sull'esecuzione dei canti:
+
+| Parametro Originale | Tipo | Descrizione |
+| :--- | :--- | :--- |
+| `id_canti` | `number` | ID del canto eseguito. |
+| `num` | `number` | Numero di esecuzioni o indicatore di frequenza. |
+
+---
+
+## 2. Parametri dalle Comunità
+
+I dati di una comunità vengono letti in due modi: tramite l'API di produzione (v3) oppure tramite un file JSON statico di fallback.
+
+### Opzione A: API di Produzione (`get_all_app_tables`)
+Endpoint: `https://libretto.mmcinet.eu/canti/api/v3/get_all_app_tables`
+
+L'API risponde con un oggetto contenente diverse tabelle relazionali:
+
+#### 1. `parrocchia.data` (Dettagli della Comunità)
+| Parametro Originale | Tipo | Descrizione |
+| :--- | :--- | :--- |
+| `id_parrocchia` | `number` | ID interno della parrocchia/comunità. |
+| `nome` | `string` | Nome della comunità (es. "Parrocchia S. Maria"). |
+| `codice` | `string` | Codice alfanumerico della comunità. |
+| `mail` | `string` | Email di riferimento della comunità. |
+| `guid_parrocchia` | `string` | GUID univoco. |
+
+#### 2. `parrocchia_canti.data` (Associazione Canti-Comunità)
+Indica quali canti del database generale appartengono al repertorio della comunità:
+
+| Parametro Originale | Tipo | Descrizione |
+| :--- | :--- | :--- |
+| `id_parrocchia` | `number` | ID della parrocchia. |
+| `id_canti` | `number` | ID del canto associato. |
+| `num_canto` | `number` | Numero progressivo o di classificazione del canto all'interno della comunità. |
+
+#### 3. `canti_settings.data` (Impostazioni di Esecuzione personalizzate)
+Configurazioni specifiche per l'esecuzione del canto in comunità:
+
+| Parametro Originale | Tipo | Descrizione |
+| :--- | :--- | :--- |
+| `id_canti` | `number` | ID del canto. |
+| `speed` | `number` | Velocità di scorrimento (auto-scroll) consigliata. |
+| `tonalita` | `number` | Semitoni di trasposizione (trasporto tonalità) consigliati. |
+
+#### 4. `canti_personali.data` (Canti personalizzati/inediti della Comunità)
+Canti inseriti direttamente dalla comunità e non presenti nel database globale:
+
+| Parametro Originale | Tipo | Descrizione / Mapping Applicativo |
+| :--- | :--- | :--- |
+| `id_canti` | `number` | ID del canto personale. |
+| `titolo` | `string` | Titolo del canto. |
+| `accordi` | `string` | Testo con gli accordi del canto. |
+| `autore` | `string` | Autore del canto. |
+| `link_youtube` | `string` | Link YouTube. |
+| `data_update` | `string` | Data dell'ultimo aggiornamento. |
+| `stato` | `number` | Se uguale a `10`, il canto viene contrassegnato come `nonValidato = true`. |
+
+*Nota: Vengono impostati automaticamente `isPersonal = true` e `id_momenti = []`.*
+
+#### 5. Scalette della Comunità (`lista_nome` + `lista_esecuzione`)
+L'applicazione ricostruisce l'elenco delle scalette (`ComunitaScaletta`):
+* **`lista_nome.data`** (Testate delle scalette):
+ * `id_lista` (`string`/`number`): ID della scaletta.
+ * `nome` (`string`): Nome della scaletta (es. "Domenica delle Palme").
+ * `progr` (`string`): Data o stringa di ordinamento (mappata in `date`).
+* **`lista_esecuzione.data`** (Canti contenuti nelle scalette):
+ * `id_lista` (`string`/`number`): Associazione alla scaletta.
+ * `id_canti` (`number`): ID del canto.
+ * `progr` (`number`): Ordine progressivo del canto all'interno della scaletta (usato per l'ordinamento).
+
+---
+
+### Opzione B: Fallback Statico (`comunita_[codice].json`)
+Se l'API di produzione non è raggiungibile, viene tentato il download di un file statico (es. `comunita_123456.json`) dall'origine del sito.
+
+La struttura attesa per questo file è molto più semplice:
+
+| Parametro JSON | Tipo | Descrizione |
+| :--- | :--- | :--- |
+| `id_comunita` | `string` | Codice identificativo della comunità. |
+| `nome_comunita` | `string` | Nome leggibile della comunità. |
+| `canti` | `(number \| string)[]` | Array contenente gli ID di tutti i canti associati a questa comunità. |
diff --git a/scratch/extract_icons.js b/scratch/extract_icons.js
new file mode 100644
index 0000000..76b0d3f
--- /dev/null
+++ b/scratch/extract_icons.js
@@ -0,0 +1,34 @@
+const fs = require('fs');
+const path = require('path');
+
+function walkDir(dir, callback) {
+ fs.readdirSync(dir).forEach(f => {
+ let dirPath = path.join(dir, f);
+ let isDirectory = fs.statSync(dirPath).isDirectory();
+ if (isDirectory) {
+ walkDir(dirPath, callback);
+ } else {
+ callback(dirPath);
+ }
+ });
+}
+
+const icons = new Set();
+
+walkDir(path.join(__dirname, '../src/app'), (filePath) => {
+ if (filePath.endsWith('.html') || filePath.endsWith('.ts')) {
+ const content = fs.readFileSync(filePath, 'utf8');
+ // Match name="icon-name"
+ const nameMatches = content.matchAll(/name=["']([a-zA-Z0-9-]+)["']/g);
+ for (const match of nameMatches) {
+ icons.add(match[1]);
+ }
+ // Match [name]="... ? 'icon-a' : 'icon-b'"
+ const ternaryMatches = content.matchAll(/'([a-zA-Z0-9-]+-outline|[a-zA-Z0-9-]+-sharp|[a-zA-Z0-9-]+)'/g);
+ for (const match of ternaryMatches) {
+ icons.add(match[1]);
+ }
+ }
+});
+
+console.log(JSON.stringify(Array.from(icons).sort(), null, 2));
diff --git a/src/app/components/qr-scanner/qr-scanner.component.html b/src/app/components/qr-scanner/qr-scanner.component.html
index cc8d944..a030978 100644
--- a/src/app/components/qr-scanner/qr-scanner.component.html
+++ b/src/app/components/qr-scanner/qr-scanner.component.html
@@ -12,8 +12,12 @@