@saulwade/swl-ses 2.6.1 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (268) hide show
  1. package/CLAUDE.md +14 -2
  2. package/README.md +65 -18
  3. package/agentes/_intent-spec.md +73 -73
  4. package/agentes/_propose-step.md +90 -90
  5. package/bin/swl-ses.js +10 -0
  6. package/comandos/swl/brainstorm.md +1 -0
  7. package/comandos/swl/briefing.md +119 -119
  8. package/comandos/swl/contribuir.md +233 -233
  9. package/comandos/swl/deuda-codigo.md +97 -97
  10. package/comandos/swl/mcp-status.md +1 -0
  11. package/gateway/lib/event-channel.js +191 -191
  12. package/habilidades/agent-deep-links/SKILL.md +148 -148
  13. package/habilidades/backend-async-postgres-testing/SKILL.md +216 -216
  14. package/habilidades/backend-error-design/SKILL.md +221 -221
  15. package/habilidades/backend-production-resilience/SKILL.md +288 -288
  16. package/habilidades/calidad-anti-patrones-universales/SKILL.md +105 -1
  17. package/habilidades/calidad-contract-testing/SKILL.md +165 -165
  18. package/habilidades/calidad-mutation-testing/SKILL.md +25 -1
  19. package/habilidades/checklist-seguridad/recursos/stride-cobertura.md +60 -60
  20. package/habilidades/ci-cd-pipelines/SKILL.md +5 -1
  21. package/habilidades/css-moderno/SKILL.md +7 -1
  22. package/habilidades/diagrama-arquitectura/assets/template.html +276 -276
  23. package/habilidades/doubt-driven-review/recursos/EXAMPLES.md +130 -130
  24. package/habilidades/estructura-proyecto-claude/recursos/mcp-json-template.json +57 -57
  25. package/habilidades/extractor-de-aprendizajes/SKILL.md +5 -1
  26. package/habilidades/feynman-auditor-swl/recursos/preguntas-language-agnostic.md +108 -108
  27. package/habilidades/harness-claude-code/SKILL.md +3 -2
  28. package/habilidades/meta-skills-estandar/recursos/convencion-examples.md +93 -93
  29. package/habilidades/patrones-python/recursos/patrones-avanzados.md +469 -469
  30. package/habilidades/perfil-usuario/SKILL.md +200 -200
  31. package/habilidades/prevencion-sobreingenieria/recursos/EXAMPLES.md +580 -580
  32. package/habilidades/prevencion-sobreingenieria/recursos/soluciones-nativas.md +166 -166
  33. package/habilidades/prevencion-sobreingenieria/recursos/variables-residuales-post-refactor.md +85 -85
  34. package/habilidades/proceso-ddia-streaming/SKILL.md +231 -231
  35. package/habilidades/proceso-discovery-machote/SKILL.md +157 -157
  36. package/habilidades/proceso-dynamic-workflows/SKILL.md +60 -0
  37. package/habilidades/proceso-dynamic-workflows/recursos/template-adversarial-verify.js +65 -65
  38. package/habilidades/proceso-dynamic-workflows/recursos/template-triage.js +65 -65
  39. package/habilidades/proceso-intent-engineering/SKILL.md +269 -269
  40. package/habilidades/proceso-modular-split/SKILL.md +256 -256
  41. package/habilidades/state-inconsistency-auditor-swl/recursos/coupled-state-patterns.md +147 -147
  42. package/habilidades/swl-claudemd/recursos/contrato-aprender.md +83 -83
  43. package/habilidades/swl-claudemd/recursos/duplicacion-reglas-globales.md +85 -85
  44. package/habilidades/swl-claudemd/recursos/plantillas-init.md +94 -94
  45. package/habilidades/tdd-workflow/recursos/gherkin-bdd.md +111 -111
  46. package/hooks/calidad-pre-commit.js +159 -10
  47. package/hooks/ciclo-evolucion-subagente.js +26 -26
  48. package/hooks/ciclo-evolucion.js +26 -26
  49. package/hooks/contexto-subagente.js +68 -68
  50. package/hooks/lib/auto-consolidator.js +335 -335
  51. package/hooks/lib/ciclo-evolucion.js +47 -47
  52. package/hooks/lib/deep-links.js +185 -185
  53. package/hooks/lib/error-classifier.js +308 -308
  54. package/hooks/lib/notificacion-formato.js +45 -11
  55. package/hooks/lib/provenance-tracker.js +191 -191
  56. package/hooks/lib/raiz-proyecto.js +35 -4
  57. package/hooks/lib/resource-quota.js +122 -122
  58. package/hooks/lib/retry-jitter.js +165 -165
  59. package/hooks/lib/security-net.js +201 -201
  60. package/hooks/lib/skill-auditor.js +588 -588
  61. package/hooks/lib/sync-status.js +228 -228
  62. package/hooks/lib/taint-tracker.js +107 -107
  63. package/hooks/lib/text-similarity.js +241 -241
  64. package/hooks/lib/toon-compressor.js +245 -245
  65. package/hooks/notificacion-telegram.js +5 -11
  66. package/hooks/session-briefing.js +12 -4
  67. package/instintos/autonomia.yaml +27 -27
  68. package/instintos/prompt-appendices.yaml +57 -57
  69. package/llms.txt +1 -1
  70. package/manifiestos/agent-output-schemas.json +57 -57
  71. package/manifiestos/canonical-hashes.json +662 -0
  72. package/manifiestos/harness-ir.json +47536 -0
  73. package/manifiestos/hooks-config.json +469 -469
  74. package/manifiestos/invariantes-criticos.json +30 -30
  75. package/manifiestos/policy-bundle.json +2065 -0
  76. package/manifiestos/policy-corpus-w2.json +3926 -0
  77. package/manifiestos/runtime-adapters-core3.json +208 -0
  78. package/manifiestos/runtime-conformance.json +139 -0
  79. package/manifiestos/skills-lock.json +43 -43
  80. package/package.json +2 -2
  81. package/plantillas/auditor-veto-template.md +105 -105
  82. package/plantillas/github-workflows/release-please.yml +44 -44
  83. package/plantillas/github-workflows/swl-ci.yml +107 -107
  84. package/plantillas/github-workflows/swl-security.yml +51 -51
  85. package/plugin.json +2 -2
  86. package/reglas/accesibilidad.md +10 -10
  87. package/reglas/auditorias-documentales-estructurales.md +7 -7
  88. package/reglas/cloud-infra.md +8 -8
  89. package/reglas/consultar-vault-primero.md +195 -195
  90. package/reglas/git-workflow.md +1 -0
  91. package/reglas/hooks.md +6 -6
  92. package/reglas/intent-engineering.md +218 -218
  93. package/reglas/markitdown.md +8 -8
  94. package/reglas/monitor-ci.md +12 -0
  95. package/reglas/patrones.md +6 -6
  96. package/reglas/testing.md +7 -7
  97. package/reglas/tests-cleanup.md +224 -224
  98. package/schemas/agent-message.schema.json +73 -73
  99. package/schemas/agent-output-implementacion.schema.json +114 -114
  100. package/schemas/agent-output-planificacion.schema.json +150 -150
  101. package/schemas/agent-output-review.schema.json +98 -98
  102. package/schemas/diary-entry.schema.json +112 -112
  103. package/schemas/gate-state.schema.json +76 -0
  104. package/schemas/harness-ir.schema.json +369 -0
  105. package/schemas/hook-profiles.schema.json +54 -54
  106. package/schemas/hooks-config.schema.json +89 -89
  107. package/schemas/legacy-gates.schema.json +45 -0
  108. package/schemas/modulos.schema.json +38 -38
  109. package/schemas/perfiles.schema.json +36 -36
  110. package/schemas/plugin.schema.json +77 -77
  111. package/schemas/policy-bundle.schema.json +140 -0
  112. package/schemas/policy-enforcement.schema.json +117 -0
  113. package/schemas/policy-operation.schema.json +261 -0
  114. package/schemas/runtime-adapter.schema.json +176 -0
  115. package/schemas/runtime-build-attestation.schema.json +100 -0
  116. package/schemas/runtime-conformance.schema.json +239 -0
  117. package/schemas/runtime-diagnostic.schema.json +395 -0
  118. package/schemas/skill-evals.schema.json +119 -119
  119. package/schemas/skill-frontmatter.schema.json +245 -245
  120. package/schemas/w4-certification-request.schema.json +72 -0
  121. package/schemas/w4-certification-verdict.schema.json +224 -0
  122. package/schemas/w4-corpus.schema.json +172 -0
  123. package/schemas/w4-mutation-report.schema.json +116 -0
  124. package/schemas/w4-replay-result.schema.json +164 -0
  125. package/schemas/w4-scoring-report.schema.json +89 -0
  126. package/scripts/audit-tools/audit-history.js +330 -330
  127. package/scripts/audit-tools/bundle-tracker.js +290 -290
  128. package/scripts/audit-tools/canary-monitor.js +352 -352
  129. package/scripts/audit-tools/code-profiler.js +605 -605
  130. package/scripts/audit-tools/dep-doctor.js +320 -320
  131. package/scripts/audit-tools/env-validator.js +206 -206
  132. package/scripts/audit-tools/lib/fs-walk.js +48 -48
  133. package/scripts/audit-tools/lib/output.js +23 -23
  134. package/scripts/audit-tools/migration-checker.js +392 -392
  135. package/scripts/audit-tools/pentest-scanner.js +1436 -1436
  136. package/scripts/bootstrap-instintos.js +3 -0
  137. package/scripts/cli/aprobar-plan.js +73 -73
  138. package/scripts/cli/briefing.js +23 -23
  139. package/scripts/cli/ciclo-evolucion.js +26 -26
  140. package/scripts/cli/derivar-feature-list.js +25 -25
  141. package/scripts/cli/detectar-host.js +27 -27
  142. package/scripts/cli/diary-entry.js +69 -69
  143. package/scripts/cli/execution-state.js +18 -18
  144. package/scripts/cli/gateway-notify.js +41 -41
  145. package/scripts/cli/liberar-fase.js +42 -42
  146. package/scripts/cli/mark-evolved.js +56 -56
  147. package/scripts/cli/metricas-dora.js +26 -26
  148. package/scripts/cli/near-duplicate.js +55 -55
  149. package/scripts/cli/notificaciones.js +123 -123
  150. package/scripts/cli/propose-step.js +29 -29
  151. package/scripts/cli/schedule-parse.js +19 -19
  152. package/scripts/cli/sugerir-modelo.js +20 -20
  153. package/scripts/cli/verificar-plan.js +36 -36
  154. package/scripts/cli/verificar-trazabilidad.js +35 -35
  155. package/scripts/comandos/install-asistido.js +8 -7
  156. package/scripts/configurar-branch-protection.js +418 -418
  157. package/scripts/detectar-aprendizajes-duplicados.js +151 -151
  158. package/scripts/doctor.js +61 -36
  159. package/scripts/generar-checklists-consolidados.js +273 -273
  160. package/scripts/generar-claims-runtime.js +1342 -0
  161. package/scripts/generar-harness-ir.js +257 -0
  162. package/scripts/generar-inventario.js +52 -54
  163. package/scripts/generar-policy-bundle.js +202 -0
  164. package/scripts/instalador.js +26 -7
  165. package/scripts/lib/approval-receipts.js +190 -0
  166. package/scripts/lib/artefactos-python.js +43 -43
  167. package/scripts/lib/benchmark-metrics.js +160 -160
  168. package/scripts/lib/budget-enforcer.js +252 -252
  169. package/scripts/lib/certificacion-loop-state.js +421 -0
  170. package/scripts/lib/ci-reader.js +193 -193
  171. package/scripts/lib/ciclo-autonomo/yaml-instintos.js +56 -0
  172. package/scripts/lib/clasificar-directorio.js +92 -0
  173. package/scripts/lib/contadores-inventario.js +217 -217
  174. package/scripts/lib/detectar-host-swl.js +175 -175
  175. package/scripts/lib/detectar-runtime.js +29 -20
  176. package/scripts/lib/detectar-stack-detallado.js +307 -307
  177. package/scripts/lib/detector-autoduplicacion-intra-archivo.js +234 -234
  178. package/scripts/lib/detector-reglas-duplicadas.js +220 -220
  179. package/scripts/lib/eval-metrics-store.js +218 -218
  180. package/scripts/lib/eval-quality.js +171 -171
  181. package/scripts/lib/eval-schemas.js +144 -144
  182. package/scripts/lib/eval-self-correct.js +106 -106
  183. package/scripts/lib/eval-validator.js +185 -185
  184. package/scripts/lib/evidence-verifier.js +192 -0
  185. package/scripts/lib/evidencia-release.js +322 -322
  186. package/scripts/lib/frontmatter-canonico.js +509 -0
  187. package/scripts/lib/gate-engine.js +871 -0
  188. package/scripts/lib/gate-hooks-requires.js +249 -249
  189. package/scripts/lib/gate-licencias.js +212 -212
  190. package/scripts/lib/git-config-preflight.js +48 -0
  191. package/scripts/lib/git-metricas.js +257 -257
  192. package/scripts/lib/harness-ir.js +778 -0
  193. package/scripts/lib/harness-source-snapshot.js +309 -0
  194. package/scripts/lib/integrity-ledger.js +1147 -0
  195. package/scripts/lib/jaccard-similarity.js +98 -98
  196. package/scripts/lib/legacy-gate-migration.js +324 -0
  197. package/scripts/lib/limpiar-basura-global.js +45 -2
  198. package/scripts/lib/longmemeval-runner.js +125 -125
  199. package/scripts/lib/metricas-dora.js +204 -204
  200. package/scripts/lib/notificaciones-telegram.js +1 -0
  201. package/scripts/lib/npm-version.js +1 -0
  202. package/scripts/lib/paquetes-conocidos.js +50 -50
  203. package/scripts/lib/plan-lock.js +61 -13
  204. package/scripts/lib/policy-broker.js +338 -0
  205. package/scripts/lib/policy-bundle.js +342 -0
  206. package/scripts/lib/policy-context-provider.js +310 -0
  207. package/scripts/lib/policy-contract.js +479 -0
  208. package/scripts/lib/policy-verifier-utils.js +65 -0
  209. package/scripts/lib/pr-analyzer.js +399 -399
  210. package/scripts/lib/principal-verifier.js +178 -0
  211. package/scripts/lib/prompt-builder.js +264 -264
  212. package/scripts/lib/resolver-plan-fase.js +37 -37
  213. package/scripts/lib/rrf-fusion.js +175 -175
  214. package/scripts/lib/runtime-adapter-contract.js +267 -0
  215. package/scripts/lib/runtime-artifact-verifier.js +426 -0
  216. package/scripts/lib/runtime-build-attestation.js +127 -0
  217. package/scripts/lib/runtime-bundle-installer.js +586 -0
  218. package/scripts/lib/runtime-compiler.js +327 -0
  219. package/scripts/lib/runtime-conformance.js +202 -0
  220. package/scripts/lib/runtime-doctor-core3.js +567 -0
  221. package/scripts/lib/runtime-doctor-input.js +59 -0
  222. package/scripts/lib/runtime-operation-adapter.js +267 -0
  223. package/scripts/lib/schema-version.js +164 -164
  224. package/scripts/lib/semantic-search.js +252 -252
  225. package/scripts/lib/signed-envelope.js +545 -0
  226. package/scripts/lib/single-use-store.js +359 -0
  227. package/scripts/lib/skills-externas.js +31 -0
  228. package/scripts/lib/transformadores/codex.js +15 -8
  229. package/scripts/lib/transformadores/gemini.js +79 -5
  230. package/scripts/lib/w4-attestation-adapter.js +158 -0
  231. package/scripts/lib/w4-canario.js +337 -0
  232. package/scripts/lib/w4-claims.js +182 -0
  233. package/scripts/lib/w4-corpus-generador.js +542 -0
  234. package/scripts/lib/w4-gate-c5.js +115 -0
  235. package/scripts/lib/w4-harness-bajo-prueba.js +155 -0
  236. package/scripts/lib/w4-matriz-combos.js +55 -0
  237. package/scripts/lib/w4-motor-mutacion.js +1348 -0
  238. package/scripts/lib/w4-motor-replay.js +735 -0
  239. package/scripts/lib/w4-pin-origen.js +54 -0
  240. package/scripts/lib/w4-publicar-request.js +132 -0
  241. package/scripts/lib/w4-revocacion.js +62 -0
  242. package/scripts/lib/w4-runtimes-core3.js +38 -0
  243. package/scripts/lib/w4-scorer-certificacion.js +692 -0
  244. package/scripts/lib/w4-superficie-candidato.js +49 -0
  245. package/scripts/lib/w4-veredicto.js +452 -0
  246. package/scripts/lib/w4-verificar-veredicto.js +302 -0
  247. package/scripts/limpiar-artefactos-python.js +131 -131
  248. package/scripts/migrar-csv-a-array.js +168 -168
  249. package/scripts/migrar-fase-dominio.js +200 -200
  250. package/scripts/migrar-gates-legacy.js +108 -0
  251. package/scripts/publicar-certification-request.js +115 -0
  252. package/scripts/runtime-doctor.js +107 -0
  253. package/scripts/tui/componentes/selector-multi.js +189 -189
  254. package/scripts/tui/componentes/selector-unico.js +158 -158
  255. package/scripts/tui/ejecutores.js +375 -375
  256. package/scripts/tui/lib/colores.js +129 -129
  257. package/scripts/tui/lib/render.js +264 -264
  258. package/scripts/tui/lib/teclas.js +113 -113
  259. package/scripts/tui/pantallas/install-wizard.js +12 -7
  260. package/scripts/tui/pantallas/menu-principal.js +52 -52
  261. package/scripts/tui/pantallas/progreso.js +274 -274
  262. package/scripts/tui/pantallas/resumen.js +132 -132
  263. package/scripts/validar-userland-vacio.js +110 -110
  264. package/scripts/verificar-aislamiento-swl-eval.js +87 -0
  265. package/scripts/verificar-empaquetado-downstream.js +375 -0
  266. package/scripts/verificar-loop-constructor.js +215 -0
  267. package/scripts/verificar-trazabilidad.js +13 -6
  268. package/scripts/verificar-veredicto-real.js +84 -0
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: ci-cd-pipelines
3
3
  description: CI/CD con GitHub Actions y GitLab CI. Stages de lint, test, build, deploy. Caching, artifacts, matrix builds, secrets management, deployment strategies, monorepos y quality gates.
4
- version: "1.0.0"
4
+ version: "1.0.2"
5
5
  herramientasPermitidas: [Read, Bash]
6
6
  exclusiones:
7
7
  - "No cargar para Kubernetes Deployments o Helm releases — para Kubernetes cargar `kubernetes-orquestacion`."
@@ -155,3 +155,7 @@ Para template de GitHub Actions reutilizable, ver [recursos/github-actions-templ
155
155
  **Secrets definidos en GitHub Actions no están disponibles en workflows de forks en PRs externas**: los workflows disparados por un PR de un fork (contribuidor externo) no tienen acceso a los secrets del repositorio por seguridad. Causa: prevención de exfiltración de secrets a forks maliciosos. Fix: usar el evento `pull_request_target` con cuidado para acceder a secrets en PRs de forks, pero solo para jobs que no ejecutan código del PR — los jobs de lint/test pueden correr sin secrets; los de deploy sí necesitan el evento `push` al branch base.
156
156
 
157
157
  **`docker/build-push-action` con `cache-from: type=gha` puede hacer el build más lento si el cache es muy grande**: el cache de GitHub Actions (10GB límite) se llena con layers de Docker — si se usan imágenes base grandes y muchos stages, el cache puede alcanzar el límite y las layers más antiguas se evictan, causando rebuilds completos. Causa: el cache de GHA tiene límite de 10GB por repositorio. Fix: usar `cache-from: type=registry,ref=ghcr.io/org/app:cache` con un registro de contenedores para cache ilimitado, o usar `mode=min` en el cache para solo guardar las layers finales en lugar de todas las intermedias.
158
+
159
+ **Un script que monitorea `gh pr checks`/`gh run list` canalizando su `--json` a `jq` externo puede fallar en silencio para siempre si `jq` no está instalado** [CONFIRMADO x2 — SIGM 2026-06-21 y 2026-07-18]: en Windows con Git Bash, `jq` frecuentemente NO está en el PATH (`which jq` → not found). Un loop de polling tipo `s=$(gh pr checks N --json ... 2>/dev/null); cur=$(echo "$s" | jq -r '...' 2>/dev/null)` con stderr suprimido en ambos comandos nunca produce error visible: `cur` queda siempre vacío, la condición de salida (`jq -e '...'`) siempre falla, y el loop de polling corre indefinidamente sin emitir NINGÚN evento — 0 bytes de output, indistinguible de "todavía no hay novedades". Causa: dos supresiones de error (`2>/dev/null`) apiladas ocultan que el binario no existe. Fix confirmado: usar el flag `--jq` PROPIO de `gh` (`gh pr checks N --json name,bucket --jq '.[] | select(...)'`) — es JSON processor vendored dentro del propio binario `gh`, no depende de `jq` externo, y acepta la misma sintaxis de filtro. Antes de confiar en que un monitor de CI sigue "esperando sin novedad", verificar con `TaskOutput(block:false)` que el output acumulado no sea 0 KB tras varios minutos — 0 KB sostenido es señal de este bug, no de que aún no hay nada que reportar.
160
+
161
+ **Suprimir un fingerprint específico de `gitleaks` en `.gitleaks.toml` bajo `[allowlist] fingerprints = [...]` no funciona en gitleaks ≥8.25** [CONFIRMADO, SIGM 2026-07-19]: desde esa versión gitleaks migró de `[allowlist]` (tabla singular) a `[[allowlists]]` (array de tablas), y el campo `fingerprints` NO existe en NINGUNA de las dos variantes del TOML — solo soporta `paths`/`regexes`/`commits`/`stopwords`/`condition`/`regexTarget`. Un `fingerprints = [...]` agregado al TOML se ignora en silencio (sin error de parseo, sin warning) y el hallazgo sigue reportándose sin cambio. Fix real: los fingerprints se suprimen en un archivo SEPARADO `.gitleaksignore` en la raíz del repo (una línea por fingerprint, texto EXACTO tal como lo imprime `gitleaks detect` en su campo `Fingerprint:`). Verificar el fix localmente ANTES de reintentar en CI: descargar el mismo binario/tag que usa el workflow (`curl -sSL -o gitleaks.zip https://github.com/gitleaks/gitleaks/releases/download/v<TAG>/gitleaks_<TAG>_windows_x64.zip` en Windows, o el tarball `linux_x64` si se prueba en WSL/Linux) y correr `gitleaks detect --source . --no-git --redact -v --config .gitleaks.toml` — el finding suprimido debe desaparecer del output antes de pushear, ahorrando una ronda completa de CI.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: css-moderno
3
3
  description: CSS moderno 2024+. Cubre Container Queries, CSS Layers (@layer), Nesting nativo, Custom Properties avanzadas, funciones min/max/clamp/color-mix, propiedades lógicas (block/inline), View Transitions API, animaciones performantes solo-compositor, dark mode patterns y anti-patrones críticos.
4
- version: "1.1.0"
4
+ version: "1.1.1"
5
5
  herramientasPermitidas: [Read, Grep]
6
6
  exclusiones:
7
7
  - "No cargar para Tailwind CSS (clases utilitarias, @theme, cva, responsive) — para Tailwind cargar `tailwind-experto`."
@@ -166,3 +166,9 @@ Para ejemplos completos de Container Queries, CSS Layers, Nesting, Custom Proper
166
166
  **`clamp()` con `vw` en la función intermedia no escala correctamente en pantallas muy anchas si no se acota con `max()`**: `font-size: clamp(1rem, 2vw, 2rem)` en un monitor de 2560px da `2vw = 51.2px`, que es mayor que el máximo de `2rem = 32px` — el clamp lo atrapa pero el cálculo puede ser confuso al depurar. Causa: el valor de `vw` crece sin límite. Fix: entender que `clamp(min, preferido, max)` garantiza que el resultado siempre está entre min y max — el valor preferido puede ser cualquier expresión, incluso mayor que max, y el clamp simplemente retorna max en ese caso. Verificar los tres valores en los tamaños de viewport objetivo.
167
167
 
168
168
  **`var(--token)` NO resuelve cuando el valor lo consume JavaScript pintando a `<canvas>`**: las librerías que renderizan a canvas (Chart.js, OpenLayers, three.js/WebGL, o `ctx.fillStyle`/`strokeStyle`/`ctx.font` directos) NO reciben el contexto CSS del documento → el color sale negro o invisible **sin error en consola**. Causa: el canvas es un buffer de píxeles fuera del árbol CSS; la cascada y `getComputedStyle` no aplican al contexto 2D/WebGL — `var()` queda como string literal que el motor de canvas no interpreta. La frontera es: un color es `var(--x)` SOLO si lo consume CSS (`.css`/`.module.scss` o `style={{}}` sobre HTML); si lo consume JS pintando a canvas, debe ser hex/rgb concreto. Fix: pasar hex/rgb literal a esos objetos, con comentario anti-recurrencia (`// canvas: NO resuelve var()`). Si el color debe ser theme-aware, resolverlo primero en JS — `getComputedStyle(document.documentElement).getPropertyValue('--color-x').trim()` — y pasar el valor ya resuelto al canvas, re-leyéndolo al cambiar de tema.
169
+
170
+ **El atributo HTML `hidden` NO oculta un elemento con `display:flex/grid`** [CONFIRMADO x4]: togglear el atributo `hidden` sobre un elemento con `.clase{display:flex}` no lo oculta, **sin error en consola**. Causa: la regla de user-agent `[hidden]{display:none}` tiene menor especificidad que cualquier regla de clase con `display` explícito → la clase gana en la cascada y el elemento sigue visible. Fix: para todo elemento colapsable con `display` distinto de `block`, agregar una regla explícita `.clase[hidden]{display:none}`. Aplica a acordeones, drawers, toggles, tabs — cualquier patrón que dependa del atributo `hidden` para colapsar. Evidencia: 4 instancias en una sola sesión (proyecto convertidor-md, 2026-07-20).
171
+
172
+ **Items flex/grid-column bajo un contenedor `max-height` + `overflow` se COMPRIMEN y recortan en vez de scrollear**: en `display:flex;flex-direction:column;max-height:N;overflow-y:auto`, los hijos con `flex-shrink:1` (default) se encogen cuando el contenido excede la altura — y si tienen `overflow:hidden`, su contenido se corta — en lugar de que el contenedor haga scroll. Causa: `flex-shrink:1` autoriza al algoritmo flex a reducir los ítems para caber en el contenedor acotado, antes de recurrir al scroll. Fix: `flex-shrink:0` (o `flex:none`) en los hijos que deben conservar su altura natural; entonces el contenedor scrollea correctamente. Síntoma típico: encabezados de acordeón "recortados a rebanadas" cuando uno se expande.
173
+
174
+ **Redefinir un nombre de clase ya usado re-estiliza el componente original en silencio**: dos reglas con el mismo selector de clase (`.chip {…}` … `.chip {…}`) en la misma hoja mezclan propiedades por cascada — la segunda definición altera el primer componente sin error. Causa: CSS no tiene scoping por defecto; el nombre de clase es global a la hoja. Fix: antes de reusar un nombre de clase para un componente nuevo, `grep` la hoja de estilos; namespacea la clase del componente nuevo (p. ej. `.grp-chip` en vez de reusar `.cfdi-chip`).
@@ -1,276 +1,276 @@
1
- <!DOCTYPE html>
2
- <html lang="es">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>[NOMBRE DEL PROYECTO] — Diagrama de Arquitectura</title>
7
- <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
8
- <style>
9
- * {
10
- margin: 0;
11
- padding: 0;
12
- box-sizing: border-box;
13
- }
14
-
15
- body {
16
- font-family: 'JetBrains Mono', monospace;
17
- background: #020617;
18
- min-height: 100vh;
19
- padding: 2rem;
20
- color: white;
21
- }
22
-
23
- .container {
24
- max-width: 1200px;
25
- margin: 0 auto;
26
- }
27
-
28
- .header {
29
- margin-bottom: 2rem;
30
- }
31
-
32
- .header-row {
33
- display: flex;
34
- align-items: center;
35
- gap: 1rem;
36
- margin-bottom: 0.5rem;
37
- }
38
-
39
- .pulse-dot {
40
- width: 12px;
41
- height: 12px;
42
- background: #22d3ee;
43
- border-radius: 50%;
44
- animation: pulse 2s infinite;
45
- }
46
-
47
- @keyframes pulse {
48
- 0%, 100% { opacity: 1; }
49
- 50% { opacity: 0.5; }
50
- }
51
-
52
- h1 {
53
- font-size: 1.5rem;
54
- font-weight: 700;
55
- letter-spacing: -0.025em;
56
- }
57
-
58
- .subtitle {
59
- color: #94a3b8;
60
- font-size: 0.875rem;
61
- margin-left: 1.75rem;
62
- }
63
-
64
- .diagram-container {
65
- background: rgba(15, 23, 42, 0.5);
66
- border-radius: 1rem;
67
- border: 1px solid #1e293b;
68
- padding: 1.5rem;
69
- overflow-x: auto;
70
- }
71
-
72
- svg {
73
- width: 100%;
74
- min-width: 900px;
75
- display: block;
76
- }
77
-
78
- .cards {
79
- display: grid;
80
- grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
81
- gap: 1rem;
82
- margin-top: 2rem;
83
- }
84
-
85
- .card {
86
- background: rgba(15, 23, 42, 0.5);
87
- border-radius: 0.75rem;
88
- border: 1px solid #1e293b;
89
- padding: 1.25rem;
90
- }
91
-
92
- .card-header {
93
- display: flex;
94
- align-items: center;
95
- gap: 0.5rem;
96
- margin-bottom: 0.75rem;
97
- }
98
-
99
- .card-dot {
100
- width: 8px;
101
- height: 8px;
102
- border-radius: 50%;
103
- }
104
-
105
- .card-dot.cyan { background: #22d3ee; }
106
- .card-dot.emerald { background: #34d399; }
107
- .card-dot.violet { background: #a78bfa; }
108
- .card-dot.amber { background: #fbbf24; }
109
- .card-dot.rose { background: #fb7185; }
110
-
111
- .card h3 {
112
- font-size: 0.875rem;
113
- font-weight: 600;
114
- }
115
-
116
- .card ul {
117
- list-style: none;
118
- color: #94a3b8;
119
- font-size: 0.75rem;
120
- }
121
-
122
- .card li {
123
- margin-bottom: 0.375rem;
124
- }
125
-
126
- .footer {
127
- text-align: center;
128
- margin-top: 1.5rem;
129
- color: #475569;
130
- font-size: 0.75rem;
131
- }
132
- </style>
133
- </head>
134
- <body>
135
- <div class="container">
136
- <!-- Encabezado -->
137
- <div class="header">
138
- <div class="header-row">
139
- <div class="pulse-dot"></div>
140
- <h1>[NOMBRE DEL PROYECTO] — Arquitectura</h1>
141
- </div>
142
- <p class="subtitle">[Descripción del subtítulo]</p>
143
- </div>
144
-
145
- <!-- Diagrama principal -->
146
- <div class="diagram-container">
147
- <svg viewBox="0 0 1000 680">
148
- <!-- Definiciones -->
149
- <defs>
150
- <marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
151
- <polygon points="0 0, 10 3.5, 0 7" fill="#64748b" />
152
- </marker>
153
- <pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
154
- <path d="M 40 0 L 0 0 0 40" fill="none" stroke="#1e293b" stroke-width="0.5"/>
155
- </pattern>
156
- </defs>
157
-
158
- <!-- Grilla de fondo -->
159
- <rect width="100%" height="100%" fill="url(#grid)" />
160
-
161
- <!-- ===============================================================
162
- COMPONENTES — Copiar y personalizar estos patrones
163
- =============================================================== -->
164
-
165
- <!-- Componente externo/genérico -->
166
- <rect x="30" y="280" width="100" height="50" rx="6" fill="rgba(30, 41, 59, 0.5)" stroke="#94a3b8" stroke-width="1.5"/>
167
- <text x="80" y="300" fill="white" font-size="11" font-weight="600" text-anchor="middle">Usuarios</text>
168
- <text x="80" y="316" fill="#94a3b8" font-size="9" text-anchor="middle">Navegador/Móvil</text>
169
-
170
- <!-- Componente de seguridad -->
171
- <rect x="30" y="80" width="100" height="60" rx="6" fill="rgba(136, 19, 55, 0.4)" stroke="#fb7185" stroke-width="1.5"/>
172
- <text x="80" y="105" fill="white" font-size="11" font-weight="600" text-anchor="middle">Auth Provider</text>
173
- <text x="80" y="121" fill="#94a3b8" font-size="9" text-anchor="middle">OAuth 2.0</text>
174
-
175
- <!-- Límite de región/cloud -->
176
- <rect x="160" y="40" width="820" height="620" rx="12" fill="rgba(251, 191, 36, 0.05)" stroke="#fbbf24" stroke-width="1" stroke-dasharray="8,4"/>
177
- <text x="172" y="58" fill="#fbbf24" font-size="10" font-weight="600">Región Cloud</text>
178
-
179
- <!-- Servicio cloud -->
180
- <rect x="200" y="280" width="110" height="50" rx="6" fill="rgba(120, 53, 15, 0.3)" stroke="#fbbf24" stroke-width="1.5"/>
181
- <text x="255" y="300" fill="white" font-size="11" font-weight="600" text-anchor="middle">CDN</text>
182
- <text x="255" y="316" fill="#94a3b8" font-size="9" text-anchor="middle">CloudFront</text>
183
-
184
- <!-- Backend -->
185
- <rect x="510" y="280" width="110" height="50" rx="6" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5"/>
186
- <text x="565" y="300" fill="white" font-size="11" font-weight="600" text-anchor="middle">API Server</text>
187
- <text x="565" y="316" fill="#94a3b8" font-size="9" text-anchor="middle">FastAPI :8000</text>
188
-
189
- <!-- Base de datos -->
190
- <rect x="700" y="280" width="120" height="50" rx="6" fill="rgba(76, 29, 149, 0.4)" stroke="#a78bfa" stroke-width="1.5"/>
191
- <text x="760" y="300" fill="white" font-size="11" font-weight="600" text-anchor="middle">Base de datos</text>
192
- <text x="760" y="316" fill="#94a3b8" font-size="9" text-anchor="middle">PostgreSQL</text>
193
-
194
- <!-- Frontend -->
195
- <rect x="200" y="520" width="200" height="110" rx="8" fill="rgba(8, 51, 68, 0.4)" stroke="#22d3ee" stroke-width="1.5"/>
196
- <text x="300" y="545" fill="white" font-size="12" font-weight="600" text-anchor="middle">Frontend</text>
197
- <text x="300" y="565" fill="#94a3b8" font-size="9" text-anchor="middle">React + TypeScript</text>
198
-
199
- <!-- ===============================================================
200
- FLECHAS
201
- =============================================================== -->
202
- <line x1="130" y1="305" x2="198" y2="305" stroke="#22d3ee" stroke-width="1.5" marker-end="url(#arrowhead)"/>
203
- <text x="164" y="299" fill="#94a3b8" font-size="9" text-anchor="middle">HTTPS</text>
204
-
205
- <line x1="310" y1="305" x2="508" y2="305" stroke="#34d399" stroke-width="1.5" marker-end="url(#arrowhead)"/>
206
- <line x1="620" y1="305" x2="698" y2="305" stroke="#a78bfa" stroke-width="1.5" marker-end="url(#arrowhead)"/>
207
- <text x="655" y="299" fill="#94a3b8" font-size="9">TLS</text>
208
-
209
- <!-- ===============================================================
210
- LEYENDA
211
- =============================================================== -->
212
- <text x="720" y="70" fill="white" font-size="10" font-weight="600">Leyenda</text>
213
-
214
- <rect x="720" y="82" width="16" height="10" rx="2" fill="rgba(8, 51, 68, 0.4)" stroke="#22d3ee" stroke-width="1"/>
215
- <text x="742" y="90" fill="#94a3b8" font-size="8">Frontend</text>
216
-
217
- <rect x="720" y="98" width="16" height="10" rx="2" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1"/>
218
- <text x="742" y="106" fill="#94a3b8" font-size="8">Backend</text>
219
-
220
- <rect x="720" y="114" width="16" height="10" rx="2" fill="rgba(120, 53, 15, 0.3)" stroke="#fbbf24" stroke-width="1"/>
221
- <text x="742" y="122" fill="#94a3b8" font-size="8">Servicio Cloud</text>
222
-
223
- <rect x="720" y="130" width="16" height="10" rx="2" fill="rgba(76, 29, 149, 0.4)" stroke="#a78bfa" stroke-width="1"/>
224
- <text x="742" y="138" fill="#94a3b8" font-size="8">Base de datos</text>
225
-
226
- <rect x="720" y="146" width="16" height="10" rx="2" fill="rgba(136, 19, 55, 0.4)" stroke="#fb7185" stroke-width="1"/>
227
- <text x="742" y="154" fill="#94a3b8" font-size="8">Seguridad</text>
228
- </svg>
229
- </div>
230
-
231
- <!-- Tarjetas informativas -->
232
- <div class="cards">
233
- <div class="card">
234
- <div class="card-header">
235
- <div class="card-dot rose"></div>
236
- <h3>Seguridad</h3>
237
- </div>
238
- <ul>
239
- <li>- Autenticación OAuth 2.0</li>
240
- <li>- TLS en tránsito</li>
241
- <li>- Cifrado en reposo</li>
242
- </ul>
243
- </div>
244
-
245
- <div class="card">
246
- <div class="card-header">
247
- <div class="card-dot amber"></div>
248
- <h3>Infraestructura</h3>
249
- </div>
250
- <ul>
251
- <li>- CDN para activos estáticos</li>
252
- <li>- Auto-scaling horizontal</li>
253
- <li>- Monitoreo centralizado</li>
254
- </ul>
255
- </div>
256
-
257
- <div class="card">
258
- <div class="card-header">
259
- <div class="card-dot violet"></div>
260
- <h3>Datos</h3>
261
- </div>
262
- <ul>
263
- <li>- PostgreSQL principal</li>
264
- <li>- Backups automatizados</li>
265
- <li>- Réplica de lectura</li>
266
- </ul>
267
- </div>
268
- </div>
269
-
270
- <!-- Pie -->
271
- <p class="footer">
272
- [Nombre del proyecto] — Generado con swl-ses
273
- </p>
274
- </div>
275
- </body>
276
- </html>
1
+ <!DOCTYPE html>
2
+ <html lang="es">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>[NOMBRE DEL PROYECTO] — Diagrama de Arquitectura</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
8
+ <style>
9
+ * {
10
+ margin: 0;
11
+ padding: 0;
12
+ box-sizing: border-box;
13
+ }
14
+
15
+ body {
16
+ font-family: 'JetBrains Mono', monospace;
17
+ background: #020617;
18
+ min-height: 100vh;
19
+ padding: 2rem;
20
+ color: white;
21
+ }
22
+
23
+ .container {
24
+ max-width: 1200px;
25
+ margin: 0 auto;
26
+ }
27
+
28
+ .header {
29
+ margin-bottom: 2rem;
30
+ }
31
+
32
+ .header-row {
33
+ display: flex;
34
+ align-items: center;
35
+ gap: 1rem;
36
+ margin-bottom: 0.5rem;
37
+ }
38
+
39
+ .pulse-dot {
40
+ width: 12px;
41
+ height: 12px;
42
+ background: #22d3ee;
43
+ border-radius: 50%;
44
+ animation: pulse 2s infinite;
45
+ }
46
+
47
+ @keyframes pulse {
48
+ 0%, 100% { opacity: 1; }
49
+ 50% { opacity: 0.5; }
50
+ }
51
+
52
+ h1 {
53
+ font-size: 1.5rem;
54
+ font-weight: 700;
55
+ letter-spacing: -0.025em;
56
+ }
57
+
58
+ .subtitle {
59
+ color: #94a3b8;
60
+ font-size: 0.875rem;
61
+ margin-left: 1.75rem;
62
+ }
63
+
64
+ .diagram-container {
65
+ background: rgba(15, 23, 42, 0.5);
66
+ border-radius: 1rem;
67
+ border: 1px solid #1e293b;
68
+ padding: 1.5rem;
69
+ overflow-x: auto;
70
+ }
71
+
72
+ svg {
73
+ width: 100%;
74
+ min-width: 900px;
75
+ display: block;
76
+ }
77
+
78
+ .cards {
79
+ display: grid;
80
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
81
+ gap: 1rem;
82
+ margin-top: 2rem;
83
+ }
84
+
85
+ .card {
86
+ background: rgba(15, 23, 42, 0.5);
87
+ border-radius: 0.75rem;
88
+ border: 1px solid #1e293b;
89
+ padding: 1.25rem;
90
+ }
91
+
92
+ .card-header {
93
+ display: flex;
94
+ align-items: center;
95
+ gap: 0.5rem;
96
+ margin-bottom: 0.75rem;
97
+ }
98
+
99
+ .card-dot {
100
+ width: 8px;
101
+ height: 8px;
102
+ border-radius: 50%;
103
+ }
104
+
105
+ .card-dot.cyan { background: #22d3ee; }
106
+ .card-dot.emerald { background: #34d399; }
107
+ .card-dot.violet { background: #a78bfa; }
108
+ .card-dot.amber { background: #fbbf24; }
109
+ .card-dot.rose { background: #fb7185; }
110
+
111
+ .card h3 {
112
+ font-size: 0.875rem;
113
+ font-weight: 600;
114
+ }
115
+
116
+ .card ul {
117
+ list-style: none;
118
+ color: #94a3b8;
119
+ font-size: 0.75rem;
120
+ }
121
+
122
+ .card li {
123
+ margin-bottom: 0.375rem;
124
+ }
125
+
126
+ .footer {
127
+ text-align: center;
128
+ margin-top: 1.5rem;
129
+ color: #475569;
130
+ font-size: 0.75rem;
131
+ }
132
+ </style>
133
+ </head>
134
+ <body>
135
+ <div class="container">
136
+ <!-- Encabezado -->
137
+ <div class="header">
138
+ <div class="header-row">
139
+ <div class="pulse-dot"></div>
140
+ <h1>[NOMBRE DEL PROYECTO] — Arquitectura</h1>
141
+ </div>
142
+ <p class="subtitle">[Descripción del subtítulo]</p>
143
+ </div>
144
+
145
+ <!-- Diagrama principal -->
146
+ <div class="diagram-container">
147
+ <svg viewBox="0 0 1000 680">
148
+ <!-- Definiciones -->
149
+ <defs>
150
+ <marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
151
+ <polygon points="0 0, 10 3.5, 0 7" fill="#64748b" />
152
+ </marker>
153
+ <pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
154
+ <path d="M 40 0 L 0 0 0 40" fill="none" stroke="#1e293b" stroke-width="0.5"/>
155
+ </pattern>
156
+ </defs>
157
+
158
+ <!-- Grilla de fondo -->
159
+ <rect width="100%" height="100%" fill="url(#grid)" />
160
+
161
+ <!-- ===============================================================
162
+ COMPONENTES — Copiar y personalizar estos patrones
163
+ =============================================================== -->
164
+
165
+ <!-- Componente externo/genérico -->
166
+ <rect x="30" y="280" width="100" height="50" rx="6" fill="rgba(30, 41, 59, 0.5)" stroke="#94a3b8" stroke-width="1.5"/>
167
+ <text x="80" y="300" fill="white" font-size="11" font-weight="600" text-anchor="middle">Usuarios</text>
168
+ <text x="80" y="316" fill="#94a3b8" font-size="9" text-anchor="middle">Navegador/Móvil</text>
169
+
170
+ <!-- Componente de seguridad -->
171
+ <rect x="30" y="80" width="100" height="60" rx="6" fill="rgba(136, 19, 55, 0.4)" stroke="#fb7185" stroke-width="1.5"/>
172
+ <text x="80" y="105" fill="white" font-size="11" font-weight="600" text-anchor="middle">Auth Provider</text>
173
+ <text x="80" y="121" fill="#94a3b8" font-size="9" text-anchor="middle">OAuth 2.0</text>
174
+
175
+ <!-- Límite de región/cloud -->
176
+ <rect x="160" y="40" width="820" height="620" rx="12" fill="rgba(251, 191, 36, 0.05)" stroke="#fbbf24" stroke-width="1" stroke-dasharray="8,4"/>
177
+ <text x="172" y="58" fill="#fbbf24" font-size="10" font-weight="600">Región Cloud</text>
178
+
179
+ <!-- Servicio cloud -->
180
+ <rect x="200" y="280" width="110" height="50" rx="6" fill="rgba(120, 53, 15, 0.3)" stroke="#fbbf24" stroke-width="1.5"/>
181
+ <text x="255" y="300" fill="white" font-size="11" font-weight="600" text-anchor="middle">CDN</text>
182
+ <text x="255" y="316" fill="#94a3b8" font-size="9" text-anchor="middle">CloudFront</text>
183
+
184
+ <!-- Backend -->
185
+ <rect x="510" y="280" width="110" height="50" rx="6" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5"/>
186
+ <text x="565" y="300" fill="white" font-size="11" font-weight="600" text-anchor="middle">API Server</text>
187
+ <text x="565" y="316" fill="#94a3b8" font-size="9" text-anchor="middle">FastAPI :8000</text>
188
+
189
+ <!-- Base de datos -->
190
+ <rect x="700" y="280" width="120" height="50" rx="6" fill="rgba(76, 29, 149, 0.4)" stroke="#a78bfa" stroke-width="1.5"/>
191
+ <text x="760" y="300" fill="white" font-size="11" font-weight="600" text-anchor="middle">Base de datos</text>
192
+ <text x="760" y="316" fill="#94a3b8" font-size="9" text-anchor="middle">PostgreSQL</text>
193
+
194
+ <!-- Frontend -->
195
+ <rect x="200" y="520" width="200" height="110" rx="8" fill="rgba(8, 51, 68, 0.4)" stroke="#22d3ee" stroke-width="1.5"/>
196
+ <text x="300" y="545" fill="white" font-size="12" font-weight="600" text-anchor="middle">Frontend</text>
197
+ <text x="300" y="565" fill="#94a3b8" font-size="9" text-anchor="middle">React + TypeScript</text>
198
+
199
+ <!-- ===============================================================
200
+ FLECHAS
201
+ =============================================================== -->
202
+ <line x1="130" y1="305" x2="198" y2="305" stroke="#22d3ee" stroke-width="1.5" marker-end="url(#arrowhead)"/>
203
+ <text x="164" y="299" fill="#94a3b8" font-size="9" text-anchor="middle">HTTPS</text>
204
+
205
+ <line x1="310" y1="305" x2="508" y2="305" stroke="#34d399" stroke-width="1.5" marker-end="url(#arrowhead)"/>
206
+ <line x1="620" y1="305" x2="698" y2="305" stroke="#a78bfa" stroke-width="1.5" marker-end="url(#arrowhead)"/>
207
+ <text x="655" y="299" fill="#94a3b8" font-size="9">TLS</text>
208
+
209
+ <!-- ===============================================================
210
+ LEYENDA
211
+ =============================================================== -->
212
+ <text x="720" y="70" fill="white" font-size="10" font-weight="600">Leyenda</text>
213
+
214
+ <rect x="720" y="82" width="16" height="10" rx="2" fill="rgba(8, 51, 68, 0.4)" stroke="#22d3ee" stroke-width="1"/>
215
+ <text x="742" y="90" fill="#94a3b8" font-size="8">Frontend</text>
216
+
217
+ <rect x="720" y="98" width="16" height="10" rx="2" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1"/>
218
+ <text x="742" y="106" fill="#94a3b8" font-size="8">Backend</text>
219
+
220
+ <rect x="720" y="114" width="16" height="10" rx="2" fill="rgba(120, 53, 15, 0.3)" stroke="#fbbf24" stroke-width="1"/>
221
+ <text x="742" y="122" fill="#94a3b8" font-size="8">Servicio Cloud</text>
222
+
223
+ <rect x="720" y="130" width="16" height="10" rx="2" fill="rgba(76, 29, 149, 0.4)" stroke="#a78bfa" stroke-width="1"/>
224
+ <text x="742" y="138" fill="#94a3b8" font-size="8">Base de datos</text>
225
+
226
+ <rect x="720" y="146" width="16" height="10" rx="2" fill="rgba(136, 19, 55, 0.4)" stroke="#fb7185" stroke-width="1"/>
227
+ <text x="742" y="154" fill="#94a3b8" font-size="8">Seguridad</text>
228
+ </svg>
229
+ </div>
230
+
231
+ <!-- Tarjetas informativas -->
232
+ <div class="cards">
233
+ <div class="card">
234
+ <div class="card-header">
235
+ <div class="card-dot rose"></div>
236
+ <h3>Seguridad</h3>
237
+ </div>
238
+ <ul>
239
+ <li>- Autenticación OAuth 2.0</li>
240
+ <li>- TLS en tránsito</li>
241
+ <li>- Cifrado en reposo</li>
242
+ </ul>
243
+ </div>
244
+
245
+ <div class="card">
246
+ <div class="card-header">
247
+ <div class="card-dot amber"></div>
248
+ <h3>Infraestructura</h3>
249
+ </div>
250
+ <ul>
251
+ <li>- CDN para activos estáticos</li>
252
+ <li>- Auto-scaling horizontal</li>
253
+ <li>- Monitoreo centralizado</li>
254
+ </ul>
255
+ </div>
256
+
257
+ <div class="card">
258
+ <div class="card-header">
259
+ <div class="card-dot violet"></div>
260
+ <h3>Datos</h3>
261
+ </div>
262
+ <ul>
263
+ <li>- PostgreSQL principal</li>
264
+ <li>- Backups automatizados</li>
265
+ <li>- Réplica de lectura</li>
266
+ </ul>
267
+ </div>
268
+ </div>
269
+
270
+ <!-- Pie -->
271
+ <p class="footer">
272
+ [Nombre del proyecto] — Generado con swl-ses
273
+ </p>
274
+ </div>
275
+ </body>
276
+ </html>