fix(alarma-sonando): pulsing halo, hero-time metrics, art size, snooze icon

Tier 4 visual fidelity, audit 9.1/9.5/9.6/9.8 (t4 lines 411-428):

- 9.1: new _HaloPulsante renders the prototype's 420px amber radial
  gradient behind the hero content. Deliberately BOUNDED (one
  grow-and-settle cycle), not the prototype's literal `infinite` CSS
  animation: this screen's protected dismiss-guard test calls
  pumpAndSettle() after every mount/interaction, and a genuinely
  infinite AnimationController.repeat() would hang it forever with no
  way to fix it. Skips its Animate wrapper under reduced motion, same
  as every other entry animation in this app.
- 9.5: the hero time gets a local letterSpacing/height override
  (-4/0.95) instead of the shared heroTime token's -2.0/1.0 — the
  alarm editor's hour block is the token's other consumer and still
  wants height:1, so the shared style is untouched.
- 9.6: ringing-screen art grows from 168/radiusLg(30) to 180/36 (t4
  line 421), a local constant like the existing stop-button radius.
- 9.8: the POSPONER eyebrow regains its 19px warmCoral snooze icon.

All 5 protected files (including the dismiss-guard test) remain
empty-diff against main.
This commit is contained in:
2026-07-30 12:58:19 +02:00
parent 8fcb734ab0
commit 038ec7f3b8
3 changed files with 316 additions and 11 deletions
@@ -146,7 +146,8 @@ void main() {
group('WU11 — restyle a pantalla completa', () {
testWidgets(
'el tiempo gigante usa PluriWaveTypography.heroTime envuelto en '
'el tiempo gigante usa PluriWaveTypography.heroTime (con un ajuste '
'local de letter-spacing/height, audit 9.5) envuelto en '
'FittedBox(scaleDown)',
(tester) async {
await _montarPantalla(tester);
@@ -155,7 +156,22 @@ void main() {
expect(heroFinder, findsOneWidget);
final texto = tester.widget<Text>(heroFinder);
final contexto = tester.element(heroFinder);
expect(texto.style, contexto.pluriType.heroTime);
final base = contexto.pluriType.heroTime;
// Audit 9.5 (t4 line 417): the prototype wants 88px/w800/ls-4/lh.95
// on THIS screen only. heroTime itself must stay ls-2.0/height 1.0
// — EditorHoraInline (the alarm editor's hour block) is the other
// consumer and wants height:1 (t4 line 379) — so this is a LOCAL
// copyWith override, not a change to the shared token.
expect(texto.style?.fontSize, base.fontSize);
expect(texto.style?.fontWeight, base.fontWeight);
expect(texto.style?.letterSpacing, -4);
expect(texto.style?.height, 0.95);
expect(
base.letterSpacing,
-2.0,
reason: 'the shared token is unchanged',
);
expect(base.height, 1.0, reason: 'the shared token is unchanged');
expect(
find.ancestor(of: heroFinder, matching: find.byType(FittedBox)),
findsOneWidget,