- components/RichTextArea.tsx: barra de formato (negrita, cursiva, subrayado, tachado,
enlace, cita, lista, código) que envuelve la selección del textarea en HTML;
el HTML se sanea en el servidor con cleanPostHtml. Sin dependencias pesadas
(evita CKEditor y no rompe el pipeline de saneado).
- Cableado en ReplyForm, NewTopicForm y PostActions (edición).
- i18n es/en: namespace Editor.
Verificado: build OK, /forum y home 200.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reemplazo masivo de los estilos sueltos repetidos por las clases del sistema visual
en ~20 componentes/páginas (auth, cuenta, servicios de personaje, foro, admin, voto):
- inputs -> .nw-input, botones primarios -> .nw-btn, tarjetas -> .nw-card.
Cohesión visual completa con la home y la cabecera.
Verificado: build OK, páginas clave 200/redirect correctos, clases aplicadas.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- lib/forum-sanitize.ts: cleanPostHtml con sanitize-html (misma allowlist que
forum/sanitize.py de nh3: formato básico + a/img/tablas, rel nofollow, esquemas
http/https/mailto). Verificado XSS-safe (script/onclick/javascript: eliminados).
- lib/forum-write.ts: createTopic (tema + primer post), createPost (respuesta +
updated_at), forumIsPostable / topicIsReplyable.
- Routes /api/forum/topic y /api/forum/reply (guard de sesión; identidad = cuenta de
juego: poster=username, poster_id=accountId). Componentes NewTopicForm y ReplyForm
(clientes). Se muestran solo si hay sesión; el tema cerrado no admite respuesta.
Verificado: escritura 401 sin sesión, saneado correcto. Pendiente: editar/borrar,
moderación (fijar/cerrar/mover), búsqueda, editor enriquecido.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>