Merge Workstream E: ritual mini-game + judgment UI + consequences

Resolved conflict in types.ts: dropped the duplicate EntityTraits
definition (D and E both added it identically) and combined both
workstreams' new ServerFrame variants (tell/ritual_complete from D,
judgment_result from E). 223/223 frontend tests pass, tsc clean.
This commit is contained in:
Indiana
2026-07-24 09:39:08 +00:00
17 changed files with 1904 additions and 17 deletions

View File

@@ -180,6 +180,78 @@
"mythic": "mythic"
}
},
"ritual": {
"title": "focus the channel",
"none": "no presence to focus on",
"noneHint": "summon a spirit before attempting the rite",
"begin": "begin the rite",
"retry": "attempt again",
"hold": "hold to focus",
"awaiting": "awaiting the veil's answer…",
"successTitle": "the channel holds — the truth surfaces",
"failureTitle": "the channel collapses",
"failureHint": "the truth stays hidden — the rite may be tried again",
"traits": {
"alignment": "alignment",
"power": "power",
"volatility": "volatility",
"deceptiveness": "deceptiveness"
},
"steps": {
"align": {
"command": "> aligning the wire…",
"locked": "> wire aligned ✓"
},
"breath": {
"command": "> steadying the breath…",
"locked": "> breath steadied ✓"
},
"trace": {
"command": "> tracing the sigil…",
"locked": "> sigil traced ✓"
},
"lock": {
"command": "> locking the channel…",
"locked": "> channel locked ✓"
}
}
},
"judgment": {
"title": "render judgment",
"none": "no presence to judge",
"noneHint": "summon a spirit first",
"trust": "trust",
"banish": "banish",
"crossOver": "cross over",
"test": "test",
"pending": "awaiting the verdict…",
"favor": "favor",
"essence": "essence",
"reward": {
"title": "the bond holds",
"body": "the spirit answers your trust in kind."
},
"escalation": {
"title": "a reckoning",
"body": "wrongly trusted, it turns — the haunting sharpens."
},
"withdrawal": {
"title": "it recoils",
"body": "banished in error, the presence withdraws, wounded."
},
"crossedOver": {
"title": "at peace",
"body": "the spirit lets go, and the line falls quiet."
},
"resisted": {
"title": "it will not go",
"body": "a demon does not cross over — it claws back to stay."
},
"neutral": {
"title": "no verdict rendered",
"body": "a diagnostic pulse only — nothing risked, nothing gained."
}
},
"toast": {
"rate_limited": "the veil is thin — slow your knocking",
"veil_crowded": "too many spirits crowd the line"

View File

@@ -180,6 +180,78 @@
"mythic": "mítico"
}
},
"ritual": {
"title": "enfoca el canal",
"none": "ninguna presencia que enfocar",
"noneHint": "invoca un espíritu antes de intentar el rito",
"begin": "comenzar el rito",
"retry": "intentar de nuevo",
"hold": "mantén para enfocar",
"awaiting": "esperando la respuesta del velo…",
"successTitle": "el canal se sostiene — la verdad emerge",
"failureTitle": "el canal colapsa",
"failureHint": "la verdad permanece oculta — el rito puede intentarse de nuevo",
"traits": {
"alignment": "alineación",
"power": "poder",
"volatility": "volatilidad",
"deceptiveness": "engaño"
},
"steps": {
"align": {
"command": "> alineando el cable…",
"locked": "> cable alineado ✓"
},
"breath": {
"command": "> serenando el aliento…",
"locked": "> aliento sereno ✓"
},
"trace": {
"command": "> trazando el sigilo…",
"locked": "> sigilo trazado ✓"
},
"lock": {
"command": "> cerrando el canal…",
"locked": "> canal cerrado ✓"
}
}
},
"judgment": {
"title": "dicta juicio",
"none": "ninguna presencia que juzgar",
"noneHint": "invoca un espíritu primero",
"trust": "confiar",
"banish": "desterrar",
"crossOver": "cruzar al más allá",
"test": "poner a prueba",
"pending": "esperando el veredicto…",
"favor": "favor",
"essence": "esencia",
"reward": {
"title": "el vínculo se sostiene",
"body": "el espíritu responde a tu confianza de igual manera."
},
"escalation": {
"title": "un ajuste de cuentas",
"body": "confiado en error, se revuelve — la aparición se agudiza."
},
"withdrawal": {
"title": "se retrae",
"body": "desterrado en error, la presencia se retira, herida."
},
"crossedOver": {
"title": "en paz",
"body": "el espíritu se suelta, y la línea queda en silencio."
},
"resisted": {
"title": "no se irá",
"body": "un demonio no cruza al más allá — se aferra para quedarse."
},
"neutral": {
"title": "ningún veredicto emitido",
"body": "solo un pulso de diagnóstico — no se arriesga ni se gana nada."
}
},
"toast": {
"rate_limited": "el velo es delgado — golpea más despacio",
"veil_crowded": "demasiados espíritus se apiñan en la línea"