diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml
new file mode 100644
index 0000000..2a73372
--- /dev/null
+++ b/.gitea/workflows/ci.yml
@@ -0,0 +1,66 @@
+name: Flutter CI/CD — PluriWave
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ branches:
+ - main
+
+jobs:
+ flutter-ci:
+ name: Test + Build
+ runs-on: macmini-flutter
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Flutter pub get
+ run: flutter pub get
+
+ - name: Run tests
+ run: flutter test
+
+ - name: Build APK (release)
+ run: flutter build apk --release
+
+ - name: Build AppBundle (release)
+ run: flutter build appbundle --release
+
+ - name: Upload APK artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: pluriwave-apk-${{ gitea.sha }}
+ path: build/app/outputs/apk/release/app-release.apk
+ if-no-files-found: error
+
+ - name: Upload AppBundle artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: pluriwave-aab-${{ gitea.sha }}
+ path: build/app/outputs/bundle/release/app-release.aab
+ if-no-files-found: error
+
+ - name: Notify Telegram — éxito
+ if: success()
+ run: |
+ curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
+ -d chat_id="${TELEGRAM_CHAT_ID}" \
+ -d parse_mode="HTML" \
+ -d text="✅ PluriWave CI OK%0ABranch: ${{ gitea.ref_name }}%0ACommit: ${{ gitea.sha }}%0AAPKs subidos como artifacts en Gitea."
+ env:
+ TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
+ TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
+
+ - name: Notify Telegram — fallo
+ if: failure()
+ run: |
+ curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
+ -d chat_id="${TELEGRAM_CHAT_ID}" \
+ -d parse_mode="HTML" \
+ -d text="❌ PluriWave CI FALLÓ%0ABranch: ${{ gitea.ref_name }}%0ACommit: ${{ gitea.sha }}%0ARevisa el log en Gitea."
+ env:
+ TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
+ TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
diff --git a/ARQ-REVISION-F1.md b/ARQ-REVISION-F1.md
new file mode 100644
index 0000000..a563e90
--- /dev/null
+++ b/ARQ-REVISION-F1.md
@@ -0,0 +1,143 @@
+# Revisión Arquitectura — PluriWave Fase 1
+**Arq | 2026-04-04**
+
+---
+
+## Decisión: stack APROBADO con ajustes menores
+
+El stack propuesto es sólido para una app de radio Flutter. Sin conflictos bloqueantes de dependencias. Sin problemas de licencia.
+
+---
+
+## Stack analizado
+
+| Paquete | Versión declarada | Latest | Licencia |
+|---------|------------------|--------|----------|
+| `just_audio` | `^0.9.42` | 0.10.5 | Apache-2.0 + MIT ✅ |
+| `audio_service` | `^0.18.15` | 0.18.18 | MIT ✅ |
+| `audio_session` | `^0.1.21` | 0.2.3 | N/A (OSI) ✅ |
+| `sqflite` | `^2.4.1` | 2.4.2 | BSD-2 ✅ |
+| `flutter_animate` | `^4.5.2` | 4.5.2 | BSD-3 ✅ |
+| `google_mobile_ads` | comentado | 7.0.0 | Apache-2.0 ✅ |
+
+---
+
+## Análisis de compatibilidad de versiones
+
+### Dependencia crítica: `audio_session`
+
+Tres paquetes compiten por `audio_session`:
+
+- `just_audio 0.9.42` requiere: `^0.1.14` → ≥0.1.14 <0.2.0
+- `audio_service 0.18.15` requiere: `^0.1.20` → ≥0.1.20 <0.2.0
+- `pubspec.yaml` declara: `^0.1.21` → ≥0.1.21 <0.2.0
+
+**Intersección**: ≥0.1.21 <0.2.0 → disponibles hasta 0.1.25 → **SIN CONFLICTO ✅**
+
+### `rxdart`
+
+Ambos paquetes requieren `>=0.26.0 <0.29.0`. rxdart latest es 0.28.0. **SIN CONFLICTO ✅**
+
+### `js` (dep transitiva de `audio_service`)
+
+`audio_service` requiere `js >=0.6.3 <0.8.0`. Esto es solo para la plataforma web. Si no hay web target, es irrelevante. Si en el futuro se añade web: aceptable, `js 0.7.2` es la latest en ese rango.
+
+---
+
+## Ajustes recomendados
+
+### 🟠 1. Actualizar `just_audio` a `^0.10.0` (importante)
+
+`just_audio 0.9.x` está en mantenimiento. La rama `0.10.x` (latest: 0.10.5) tiene:
+- Soporte Flutter ≥3.27.0 (el runner macmini-flutter probablemente lo cumple)
+- API compatible para streaming de radio (URLs HTTP/HTTPS directas)
+- `audio_session` requiere `>=0.1.24 <0.3.0` con 0.10.x — compatible con la gama completa
+
+**Acción**: cambiar `just_audio: ^0.9.42` → `just_audio: ^0.10.0` en pubspec.yaml.
+Si el runner tiene Flutter <3.27.0, mantener 0.9.42.
+
+### 🟡 2. Actualizar `audio_service` a `^0.18.18` (menor)
+
+La 0.18.18 actualiza `audio_session` a `>=0.1.25 <0.3.0`, lo que permite usar versiones 0.2.x en el futuro sin romper nada.
+
+### 🟡 3. `google_mobile_ads` — descomentarlo con cuidado
+
+Actualmente comentado (correcto para Fase 1). Cuando se active:
+- Usar `^5.3.0` (ya declarado) si el runner tiene Flutter ≥3.7.0 — ✅
+- **Evitar `^7.0.0`** por ahora: requiere actualización de `compileSdk` en Android y puede romper el CI
+- Necesitará `ad_unit_id` real en secrets de CI antes de activar en release builds
+- Play Store requiere declarar uso de datos de anuncios en el Data Safety form
+
+### 🔴 4. Signing config para release builds — BLOQUEANTE para CI
+
+`android/app/build.gradle.kts` tiene:
+```kotlin
+signingConfig = signingConfigs.getByName("debug") // TODO: fix
+```
+
+Esto firma el APK/AAB release con la clave debug. **No es aceptable para Play Store**, pero sí funciona para artifacts internos de CI (distribución interna, testing).
+
+Para CI de Fase 1: aceptable como está.
+Para producción: añadir keystore como secret en Gitea CI y configurar signing real.
+
+---
+
+## Estructura de app — observación
+
+`lib/main.dart` es el scaffold por defecto de Flutter (contador demo). Los devs deberán reemplazarlo con la arquitectura real de PluriWave antes de que los tests sean útiles.
+
+Sugerencia de estructura para Fase 1:
+
+```
+lib/
+├── main.dart
+├── app.dart # MaterialApp + Provider setup
+├── core/
+│ ├── servicios/
+│ │ ├── servicio_audio.dart # just_audio + audio_service wrapper
+│ │ └── servicio_radio.dart # fetch streams/stations API
+│ └── db/
+│ └── db_helper.dart # sqflite setup
+├── modelos/
+│ ├── emisora.dart
+│ └── favorito.dart
+└── ui/
+ ├── pantalla_inicio.dart
+ ├── pantalla_reproductor.dart
+ └── widgets/
+```
+
+`Provider` (ya en pubspec) es correcto para este scope. No hace falta Riverpod ni Bloc para Fase 1.
+
+---
+
+## Licencias — veredicto
+
+| Paquete | Licencia | Uso comercial | Distribución |
+|---------|----------|--------------|-------------|
+| `just_audio` | Apache-2.0 + MIT | ✅ libre | ✅ libre |
+| `audio_service` | MIT | ✅ libre | ✅ libre |
+| `sqflite` | BSD-2 | ✅ libre | ✅ libre |
+| `flutter_animate` | BSD-3 | ✅ libre | ✅ libre |
+| `google_mobile_ads` | Apache-2.0 | ✅ (con cuenta AdMob) | ✅ libre |
+
+Sin restricciones de licencia para app comercial en Play Store. ✅
+
+---
+
+## Resumen ejecutivo
+
+| Ítem | Estado |
+|------|--------|
+| Conflictos de dependencias | ✅ Ninguno |
+| Licencias incompatibles | ✅ Ninguna |
+| Stack adecuado para radio en streaming | ✅ Sí |
+| Signing release para Play Store | ⚠️ Pendiente (keystore) |
+| just_audio versión óptima | 🟠 Actualizar a ^0.10.0 si Flutter ≥3.27 |
+| google_mobile_ads | 🟡 Descomentarlo solo cuando haya Ad Unit IDs reales |
+| Estructura de código | 🟡 Scaffold vacío — devs deben estructurar lib/ |
+
+**El stack puede profundizarse sin riesgo. Sin bloqueos.**
+
+---
+*Arq — revisión sin acceso al analisis.md de Obsidian (fichero no sincronizado localmente). Revisión realizada directamente desde pub.dev API + pubspec.yaml del repo.*