fix(bienvenida,grabaciones): headline size, CTA radius, storage caption

Screen 14 / audit 14.3+14.7: welcome headline now 34px/ls-1.2 (was
headlineMedium's 28/ls-1.0), CTA restyled to a radius-18 rounded
rectangle instead of Material 3's default StadiumBorder (t4:696,715).

Screen 12 / audit 12.2+12.3: the recordings storage card now shows the
bold "X of Y used" headline ABOVE a 6px/radius-3 bar, followed by a
real folder-path + purge-policy caption below it -- was the bar first
with the "used" string as its only (small, generic) caption (t4:613).
New ARB key recordingsLibraryStorageFolderCaption, translated to all
13 locales.

Item 12.5 (folder/max-size settings living behind the header action
instead of inline on this screen) is a deliberate structural split
from WU15b; the audit itself scopes it out of this pass.
This commit is contained in:
2026-07-30 16:00:30 +02:00
parent 01615f9751
commit e036f99a61
31 changed files with 514 additions and 6 deletions
@@ -133,6 +133,42 @@ void main() {
},
);
testWidgets('visual fidelity (audit 14.3): the headline is 34px/w800/ls-1.2 '
'(t4 line 696), not headlineMedium\'s 28', (tester) async {
final navegacion = EstadoNavegacionRaiz();
addTearDown(navegacion.dispose);
await tester.pumpWidget(_app(navegacion: navegacion));
await tester.pumpAndSettle();
final headline = tester.widget<Text>(find.text('Tu mundo, en directo'));
expect(headline.style?.fontSize, 34);
expect(headline.style?.fontWeight, FontWeight.w800);
expect(headline.style?.letterSpacing, -1.2);
});
testWidgets('visual fidelity (audit 14.7): the CTA is a radius-18 rounded '
'rectangle (t4 line 715), not the default fully-round StadiumBorder', (
tester,
) async {
final navegacion = EstadoNavegacionRaiz();
addTearDown(navegacion.dispose);
await tester.pumpWidget(_app(navegacion: navegacion));
await tester.pumpAndSettle();
final boton = tester.widget<FilledButton>(find.byType(FilledButton));
final forma = boton.style?.shape?.resolve(<WidgetState>{});
expect(
forma,
isA<RoundedRectangleBorder>().having(
(s) => (s.borderRadius as BorderRadius).topLeft,
'topLeft radius',
const Radius.circular(18),
),
);
});
testWidgets('rendered content contains no monetization strings', (
tester,
) async {
@@ -173,6 +173,49 @@ void main() {
expect(find.text('84 MB of 200 MB used'), findsOneWidget);
});
testWidgets(
'visual fidelity (audit 12.2/12.3): the storage card shows the bold '
'"used of total" headline ABOVE the bar, then a folder-path + purge '
'caption below it (t4 line 613)',
(tester) async {
final estado = EstadoGrabacion(
servicio: _FakeServicioGrabacionConArchivos([
fijaA,
fijaB,
fijaC,
], maxBytesFijo: 200 * 1024 * 1024),
);
addTearDown(estado.dispose);
await tester.pumpWidget(
buildScreen(
estado: estado,
reproductor: _ReproductorGrabacionesFake(const {}),
),
);
await pumpStable(tester);
final headline = tester.widget<Text>(find.text('84 MB of 200 MB used'));
expect(headline.style?.fontWeight, FontWeight.w800);
expect(
find.text('Music/PluriWave · purges oldest at limit'),
findsOneWidget,
);
final headlineY = tester.getTopLeft(find.text('84 MB of 200 MB used')).dy;
final barY = tester.getTopLeft(find.byType(LinearProgressIndicator)).dy;
final captionY =
tester
.getTopLeft(find.text('Music/PluriWave · purges oldest at limit'))
.dy;
expect(
headlineY < barY && barY < captionY,
isTrue,
reason: 'headline, then bar, then caption -- top to bottom',
);
},
);
testWidgets('15.2-A: 3 recording fixtures render as 3 rows', (tester) async {
final estado = EstadoGrabacion(
servicio: _FakeServicioGrabacionConArchivos([