v3 : interface Svelte — accueil, groupes, lecteur du texte en vigueur, panneau contextuel, éditeur à assistant, trustinWallet

- Accueil sobre, menu complet à gauche (Décisions, Docs de référence, Mandats,
  Protocoles), intro demandée, quatre sections, connexion Ğ1.
- Lecteur : texte en vigueur en Literata, actions contextuelles par article
  (le vote, propositions, proposer), propositions en cours sous la « surface »
  avec leur niveau d'eau, aperçus « si les bien cotées passent » / « si tout
  passe », langue du texte fr/en/es (traductions éditoriales).
- Panneau : vote pour/contre, seuil et formule (MathML), inertie et son
  changement (voté en inertie +), coquille sans vote, traduction, signalement
  de contradiction, historique des corrections.
- trustinWallet (/acces) : groupes et membres, invitations à usage unique,
  administrateurs, retours d'usage.
- Contrôles : vitest (markdown, catalogues, anti-lexique), Playwright C1–C10 + M1.
- Sections du seed portées jusqu'à l'écran.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Yvv
2026-10-21 02:58:34 +02:00
co-authored by Claude Opus 5.5
parent 67ddee28b2
commit 7a022dd35e
66 changed files with 7771 additions and 15 deletions
+315
View File
@@ -0,0 +1,315 @@
import type { Messages } from './fr';
export const es: Messages = {
'app.name': 'libreDecision',
'app.skip': 'Ir al contenido',
'nav.label': 'Caja de herramientas',
'nav.home': 'Inicio',
'nav.decisions': 'Decisiones',
'nav.docs': 'Documentos de referencia',
'nav.mandates': 'Mandatos',
'nav.protocols': 'Protocolos',
'nav.soon': 'próximamente',
'nav.groups': 'Mis grupos',
'nav.access': 'Accesos',
'nav.access.hint': 'trustinWallet',
'nav.feedback': 'Dejar un comentario',
'nav.signin': 'Iniciar sesión',
'nav.signout': 'Cerrar sesión',
'nav.mood.toNight': 'Ambiente noche',
'nav.mood.toStone': 'Ambiente piedra',
'nav.lang': 'Idioma',
'nav.menu': 'Menú',
'nav.close': 'Cerrar',
'home.title': 'Hacer posible la decisión colectiva',
'home.subtitle': 'según el contexto, procesos y modalidades, caja de herramientas',
'home.decisions': 'Un recorrido guiado para elegir las modalidades de decisión adecuadas y llevar el registro de las decisiones.',
'home.docs': 'Acta de compromiso, licencia, carta, constitución: textos vivos, en votación permanente.',
'home.mandates': 'Crear y revocar todo tipo de mandato.',
'home.protocols': 'Flujos de trabajo para organizarse sin órgano estatutario: roles rotativos y automatizaciones técnicas.',
'home.open': 'abierto',
'home.soon': 'próximamente',
'home.signin': 'Iniciar sesión con tu clave Ğ1',
'home.signin.note': 'El mismo acceso que el foro Monnaie libre: firmas en Ğecko, sin contraseña.',
'home.continue': 'Abrir mis grupos',
'signin.title': 'Iniciar sesión',
'signin.g1': 'Iniciar sesión con Ğ1',
'signin.g1.how': 'Se te redirige a connect.monnaie-libre.fr, el servicio de conexión del foro Monnaie libre. Allí apruebas la conexión en Ğecko (enlace o código QR) y luego vuelves aquí. No se nos transmite ninguna contraseña ni ninguna clave.',
'signin.g1.members': 'Reservado a los miembros de la red de confianza Ğ1.',
'signin.g1.pending': 'La conexión Ğ1 llega pronto: el registro de libreDecision en connect.monnaie-libre.fr está en curso. Mientras tanto, se entra con un enlace de invitación.',
'signin.invite': '¿Has recibido un enlace de invitación? Ábrelo sin más: te conecta.',
'signin.dev': 'Conexión de desarrollo',
'signin.dev.name': 'Nombre',
'signin.dev.admin': 'administrador de accesos',
'signin.dev.go': 'Entrar',
'signin.error.refus': 'La conexión fue rechazada en connect.monnaie-libre.fr.',
'signin.error.etat': 'La conexión ha caducado o viene de otro navegador. Vuelve a empezar desde este navegador.',
'signin.error.incomplet': 'La respuesta de connect.monnaie-libre.fr llegó incompleta. Vuelve a empezar.',
'signin.error.echange': 'connect.monnaie-libre.fr no responde. Inténtalo de nuevo en un momento.',
'signin.error.interne': 'La conexión ha fallado por nuestra parte. Inténtalo de nuevo en un momento.',
'invite.title': 'Invitación',
'invite.working': 'Conectando…',
'invite.invalid': 'Este enlace de invitación ya no es válido: ya se ha usado o ha caducado. Pide un enlace nuevo a la persona que te lo envió.',
'invite.missing': 'Este enlace está incompleto. Abre el enlace de invitación completo, tal como lo recibiste.',
'groups.title': 'Mis grupos',
'groups.same.key': 'Grupos que usan la misma clave',
'groups.locked': 'Reservado a sus miembros',
'groups.locked.long': 'Este grupo se abre a sus miembros. El acceso se pide a un administrador de trustinWallet.',
'groups.test': 'Para pruebas',
'groups.open': 'Abrir',
'groups.empty': 'Por ahora no hay ningún grupo visible.',
'group.tools': 'Herramientas',
'group.tool.soon': 'Esta herramienta llegará más adelante.',
'group.docs.empty': 'Por ahora no hay ningún documento de referencia en este grupo.',
'docs.title': 'Documentos de referencia',
'docs.inForce.one': '{n} artículo en vigor',
'docs.inForce.other': '{n} artículos en vigor',
'docs.open.one': '{n} propuesta en curso',
'docs.open.other': '{n} propuestas en curso',
'doc.view.label': 'Leer',
'doc.view.inforce': 'En vigor',
'doc.view.wellrated': 'Si pasan las bien valoradas',
'doc.view.all': 'Si todo pasa',
'doc.view.wellrated.note': 'Vista previa: el texto tal como quedaría si las propuestas bien valoradas entraran en vigor. No se adopta nada.',
'doc.view.all.note': 'Vista previa: el texto tal como quedaría si todas las propuestas entraran en vigor, incluso las poco apoyadas. No se adopta nada.',
'doc.view.empty': 'Ninguna propuesta cambia el texto en esta vista previa.',
'doc.mark.added': 'añadido',
'doc.mark.replaced': 'modificado',
'doc.mark.removed': 'retirado',
'doc.lang.label': 'Idioma del texto',
'doc.lang.translation': 'Traducción editorial, sin votación. El texto que hace fe está en francés.',
'doc.lang.original': 'Leer el original',
'doc.lang.stale': 'traducción por revisar',
'doc.lang.missing': 'aún sin traducir',
'doc.seed': 'seed a minima',
'doc.seed.long': 'Entró en vigor sin votación, para no partir de una página en blanco. Sigue en votación: 0 votos por ahora.',
'doc.confirmed': 'confirmado por la votación',
'doc.adopted': 'adoptado el {date}',
'doc.action.vote': 'Votación',
'doc.action.proposals': 'Propuestas',
'doc.action.propose': 'Proponer una modificación',
'doc.empty': 'Ningún artículo está en vigor. Las propuestas de abajo suben en cuanto alcanzan su umbral.',
'doc.published': 'Publicado en el repositorio de textos',
'doc.publish.pending': 'Publicación pendiente',
'deep.title': 'Propuestas en curso',
'deep.note': 'Aún no están en vigor. Cada una sube en cuanto alcanza su umbral: al menos {floor} votos a favor y, después, la mayoría que exige su inercia.',
'deep.new': 'Proponer un artículo nuevo',
'deep.drafts': 'Tus borradores',
'deep.drafts.note': 'No sometidos a votación. Solo tú los ves.',
'deep.rival': 'reemplazaría «{title}»',
'deep.addition': 'artículo nuevo',
'deep.removal': 'retirada de «{title}»',
'deep.inertia': 'inercia: {level}',
'deep.blocked': 'bloqueada',
'deep.mine': 'tu propuesta',
'deep.stale': 'por reconfirmar',
'deep.wellrated': 'bien valorada',
'deep.filter.all': 'Todas',
'deep.filter.wellrated': 'Bien valoradas',
'deep.filter.mine': 'Las mías',
'deep.none': 'Ninguna propuesta en este filtro.',
'deep.variant': 'variante {label}',
'section.introduction': 'Introducción',
'section.fondamental': 'Compromisos fundamentales',
'section.technique': 'Compromisos técnicos',
'section.conclusion': 'Conclusión',
'section.annexe': 'Anexos',
'section.formule': 'Fórmula de votación',
'section.inertie': 'Inercia',
'section.ordonnancement': 'Ordenación',
'tally.short': '{for} a favor · {against} en contra',
'tally.required': 'Umbral: {n} votos a favor',
'tally.missing.one': 'Falta {n} voto a favor.',
'tally.missing.other': 'Faltan {n} votos a favor.',
'tally.reached': 'Umbral alcanzado.',
'tally.level': 'Nivel: {pct} % del umbral',
'inertia.low': 'inercia baja',
'inertia.standard': 'inercia estándar',
'inertia.high': 'inercia alta',
'inertia.max': 'inercia máxima',
'inertia.level.low': 'baja',
'inertia.level.standard': 'estándar',
'inertia.level.high': 'alta',
'inertia.level.max': 'máxima',
'panel.vote': 'Votación',
'panel.proposals': 'Propuestas',
'panel.propose': 'Proponer',
'panel.close': 'Cerrar el panel',
'panel.inforce': 'En vigor',
'panel.proposal': 'Propuesta',
'panel.by': 'propuesto por {name}',
'panel.seed.origin': 'texto procedente del seed',
'panel.changes': 'Ver los cambios',
'panel.text': 'Ver el texto',
'vote.yours': 'Tu voto',
'vote.for': 'A favor',
'vote.against': 'En contra',
'vote.retract': 'Retirar mi voto',
'vote.saved': 'Voto registrado.',
'vote.retracted': 'Voto retirado.',
'vote.stale': 'El texto ha cambiado de fondo desde tu voto: tu voto deja de contar hasta que lo reconfirmes.',
'vote.reconfirm': 'Reconfirmar: {choice}',
'vote.private': 'Tu voto no se muestra a nadie: solo se ven los totales.',
'vote.blocked': 'Un aviso de contradicción la retiene: no puede entrar en vigor mientras se mantenga.',
'vote.entered': '«{title}» ha entrado en vigor.',
'vote.entered.remove': '«{title}» se ha retirado del texto en vigor.',
'vote.entered.inertia': 'La inercia de «{title}» ha cambiado.',
'vote.closed': 'Esta versión ya no está en votación.',
'inertia.title': 'Inercia',
'inertia.explain': 'Cuanto más alta es la inercia, más votos hacen falta para cambiar este texto cuando vota poca gente.',
'inertia.change': 'Proponer un cambio de inercia',
'inertia.change.to': 'Nueva inercia',
'inertia.change.note': 'Un cambio de inercia se vota a su vez con la inercia superior: {level}.',
'inertia.change.submit': 'Someter a votación',
'inertia.change.open': 'Cambio de inercia en curso: a {level}',
'formula.title': 'La fórmula del umbral',
'formula.intro': 'El número de votos a favor exigido, R, depende de la participación:',
'formula.W': 'W — electorado: {n} ({source})',
'formula.W.wot': 'miembros de la red de confianza Ğ1',
'formula.W.group': 'miembros del grupo',
'formula.T': 'T — votos emitidos: {n}',
'formula.M': 'M — mayoría con participación plena: {n} %',
'formula.G': 'G — gradiente: {n}',
'formula.B': 'B — base: {n}',
'formula.C': 'C — mínimo de votos a favor: {n}',
'formula.R': 'R — umbral actual: {n} votos a favor',
'formula.reading': 'Con poca participación, hace falta casi la unanimidad; cuando vota todo el mundo, basta la mayoría M. Nada pasa con menos de C votos a favor.',
'history.title': 'Correcciones',
'history.initial': 'texto inicial',
'history.typo': 'errata corregida',
'history.substantive': 'cambio de fondo (votos por reconfirmar)',
'history.by': 'por {name}',
'typo.title': 'Corregir una errata',
'typo.note': 'Acentos, puntuación, erratas: la corrección se aplica sin votación, con su autor y su diff. Un cambio de sentido pasa por una propuesta.',
'typo.save': 'Guardar la corrección',
'typo.done': 'Errata corregida, sin tocar los votos.',
'typo.substantive': 'Este cambio afecta al sentido: proponlo como modificación.',
'typo.asProposal': 'Convertirlo en propuesta',
'signal.title': 'Contradicciones',
'signal.none': 'Ningún aviso.',
'signal.add': 'Señalar una contradicción',
'signal.target': 'Contradice',
'signal.reason': 'En qué se contradicen estos dos textos',
'signal.send': 'Señalar',
'signal.sent': 'Aviso registrado.',
'signal.note': 'Mientras un aviso se mantenga, estos dos textos no pueden estar en vigor a la vez. Su autor lo levanta; un cambio de fondo lo deja sin efecto.',
'signal.lift': 'Levantar',
'signal.lifted': 'levantado',
'signal.lifted.revision': 'sin efecto: el texto ha cambiado',
'signal.by': 'por {name}',
'propose.mode.replace': 'Modificar este texto',
'propose.mode.remove': 'Retirar este artículo',
'propose.mode.new': 'Artículo nuevo',
'propose.after': 'Colocar después de',
'propose.after.end': 'al final',
'propose.title': 'Título',
'propose.body': 'Texto',
'propose.remove.note': 'La propuesta de retirada se vota como cualquier otra; si se aprueba, el artículo sale del texto en vigor.',
'propose.draft': 'Guardar el borrador',
'propose.submit': 'Someter a votación',
'propose.drafted': 'Borrador guardado.',
'propose.submitted': 'Propuesta sometida a votación.',
'propose.rule': 'Mientras sea un borrador, lo modificas libremente. Una vez sometido, una errata se corrige sin tocar los votos; un cambio de fondo pide a los votantes que reconfirmen.',
'propose.edit': 'Modificar',
'propose.withdraw': 'Retirar mi propuesta',
'propose.withdrawn': 'Propuesta retirada.',
'propose.saved.typo': 'Corrección guardada, los votos se mantienen.',
'propose.saved.substantive': 'Nueva versión guardada: los votantes tendrán que reconfirmar.',
'assist.title': 'Asistente',
'assist.quiet': 'Todo en orden: una propuesta, una decisión.',
'assist.split': 'Este texto parece contener {n} decisiones. Una propuesta = una decisión: ¿dividirlo?',
'assist.split.do': 'Dividir en {n} borradores',
'assist.split.done': 'Dividido en {n} borradores.',
'assist.similar': 'Parecido a «{title}»{where}.',
'assist.similar.inForce': ' (en vigor)',
'assist.similar.variant': 'Convertirlo en una variante de este artículo',
'assist.long': 'Texto largo ({n} caracteres): un artículo corto se vota mejor.',
'translate.title': 'Traducir ({lang})',
'translate.save': 'Guardar la traducción',
'translate.saved': 'Traducción guardada.',
'translate.note': 'Las traducciones no se votan. Pasan a «por revisar» cuando el texto francés cambia de fondo.',
'feedback.title': 'Dejar un comentario',
'feedback.prompt': 'Lo que hiciste, lo que esperabas, lo que pasó.',
'feedback.send': 'Enviar el comentario',
'feedback.sent': 'Comentario enviado. Gracias.',
'feedback.context': 'Se adjuntan la dirección de la página, el idioma y el tamaño de la pantalla.',
'access.title': 'trustinWallet — accesos',
'access.intro': 'Quién abre qué grupo. Monnaie libre se abre por sí solo a los miembros de la red de confianza Ğ1; los demás grupos se abren uno a uno.',
'access.groups': 'Grupos',
'access.members.none': 'Ningún miembro tiene acceso.',
'access.members.wot': '+ todos los miembros de la red de confianza Ğ1',
'access.grant': 'Conceder',
'access.revoke': 'Retirar',
'access.choose': 'Elegir una identidad',
'access.invitations': 'Invitaciones',
'access.invite.label': 'Para quién',
'access.invite.groups': 'Grupos que abre el enlace',
'access.invite.admin': 'administrador de accesos',
'access.invite.create': 'Crear el enlace de invitación',
'access.invite.link': 'Enlace de invitación, de un solo uso, válido 14 días. No volverá a mostrarse: cópialo ahora.',
'access.invite.copy': 'Copiar el enlace',
'access.invite.copied': 'Enlace copiado.',
'access.invite.cancel': 'Cancelar',
'access.invite.pending': 'Pendiente',
'access.identities': 'Identidades',
'access.admin': 'administrador',
'access.admin.give': 'Nombrar administrador',
'access.admin.take': 'Retirar el rol',
'access.kind.g1': 'Ğ1',
'access.kind.invite': 'invitación',
'access.kind.dev': 'dev',
'access.member': 'miembro de la red de confianza',
'access.feedback': 'Comentarios',
'access.feedback.none': 'Ningún comentario.',
'access.feedback.seen': 'Visto',
'access.feedback.done': 'Atendido',
'access.denied': 'La gestión de accesos está reservada a los administradores de trustinWallet.',
'soon.title': 'Próximamente',
'soon.body': 'Esta herramienta llegará más adelante. Las herramientas se abren una a una: primero, los documentos de referencia.',
'error.unauthenticated': 'Inicia sesión para continuar.',
'error.forbidden': 'No tienes acceso a esta página.',
'error.not_found': 'Esta página no existe, o no es visible para ti.',
'error.network': 'El servidor no responde. Comprueba tu conexión e inténtalo de nuevo.',
'error.internal': 'Algo ha fallado por nuestra parte. Inténtalo de nuevo en un momento.',
'error.title': 'El título está vacío o es demasiado largo (120 caracteres como máximo).',
'error.body': 'El texto está vacío o es demasiado largo (4000 caracteres como máximo).',
'error.reason': 'Di en pocas palabras en qué se contradicen estos textos (de 10 a 600 caracteres).',
'error.substantive_not_author': 'Este cambio afecta al sentido: solo el autor de la propuesta puede hacerlo. Propón tu propia versión.',
'error.substantive_in_force': 'Este cambio afecta al sentido: proponlo como modificación.',
'error.same_unit': 'Estos dos textos se refieren al mismo artículo: de todos modos no pueden estar en vigor a la vez.',
'error.last_admin': 'Debe quedar al menos un administrador.',
'error.g1_not_configured': 'La conexión Ğ1 aún no está activa.',
'error.invitation_invalid': 'Este enlace de invitación ya no es válido.',
'error.retry': 'Reintentar',
'common.cancel': 'Cancelar',
'common.close': 'Cerrar',
'common.save': 'Guardar',
'common.loading': 'Cargando…',
'common.back': 'Volver',
};