diff --git a/assets/version.json b/assets/version.json index c5c880d..f7ce931 100644 --- a/assets/version.json +++ b/assets/version.json @@ -1 +1 @@ -{"version": "0.1.11"} +{"version": "0.1.12"} diff --git a/lib/app.dart b/lib/app.dart index 13087ff..385e3cc 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -14,6 +14,29 @@ class EmerKitApp extends StatelessWidget { darkTheme: AppTheme.dark, themeMode: ThemeMode.system, routerConfig: appRouter, + builder: (context, child) { + final data = MediaQuery.of(context); + final shortSide = data.size.shortestSide; + // Tablets have shortestSide >= 600dp + // Scale text proportionally, composing with user preference + double extraScale; + if (shortSide >= 720) { + extraScale = 1.3; + } else if (shortSide >= 600) { + extraScale = 1.2; + } else { + extraScale = 1.0; + } + if (extraScale == 1.0) return child!; + // Compose: user's textScaler * our tablet factor + final userScale = data.textScaler.scale(1.0); + return MediaQuery( + data: data.copyWith( + textScaler: TextScaler.linear(userScale * extraScale), + ), + child: child!, + ); + }, ); } } diff --git a/lib/features/about/presentation/about_screen.dart b/lib/features/about/presentation/about_screen.dart index 76ac592..02effa7 100644 --- a/lib/features/about/presentation/about_screen.dart +++ b/lib/features/about/presentation/about_screen.dart @@ -54,9 +54,12 @@ class AboutScreen extends StatelessWidget { ), ), const SizedBox(height: 20), - const Text( + Text( 'EmerKit', - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + style: Theme.of(context) + .textTheme + .headlineLarge! + .copyWith(fontWeight: FontWeight.bold), ), const SizedBox(height: 4), FutureBuilder( @@ -65,7 +68,10 @@ class AboutScreen extends StatelessWidget { final version = snapshot.data ?? '...'; return Text( 'v$version', - style: TextStyle(fontSize: 14, color: Colors.grey.shade600), + style: Theme.of(context) + .textTheme + .bodyLarge! + .copyWith(color: Colors.grey.shade600), ); }, ), @@ -74,20 +80,23 @@ class AboutScreen extends StatelessWidget { // Disclaimer Card( color: AppColors.severityModerate.withValues(alpha: 0.08), - child: const Padding( - padding: EdgeInsets.all(16), + child: Padding( + padding: const EdgeInsets.all(16), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Icon(Icons.info_outline, + const Icon(Icons.info_outline, size: 20, color: AppColors.severityModerate), - SizedBox(width: 12), + const SizedBox(width: 12), Expanded( child: Text( 'Esta aplicaci\u00f3n es una herramienta de referencia y apoyo. ' 'No sustituye el juicio cl\u00ednico profesional ni la formaci\u00f3n sanitaria. ' 'Los protocolos y valores deben contrastarse con las gu\u00edas oficiales vigentes.', - style: TextStyle(fontSize: 12, height: 1.4), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(height: 1.4), ), ), ], @@ -106,9 +115,12 @@ class AboutScreen extends StatelessWidget { padding: const EdgeInsets.all(20), child: Column( children: [ - const Text( + Text( 'Desarrollado por', - style: TextStyle(fontSize: 12, color: Colors.grey), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Colors.grey), ), const SizedBox(height: 12), Container( @@ -132,20 +144,24 @@ class AboutScreen extends StatelessWidget { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text( + Text( 'Global Emergency', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - color: Colors.white, - ), + style: Theme.of(context) + .textTheme + .titleLarge! + .copyWith( + fontWeight: FontWeight.bold, + color: Colors.white, + ), ), Text( 'globalemergency.online', - style: TextStyle( - fontSize: 12, - color: AppColors.accent - .withValues(alpha: 0.8)), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith( + color: AppColors.accent + .withValues(alpha: 0.8)), ), ], ), @@ -162,10 +178,12 @@ class AboutScreen extends StatelessWidget { const SizedBox(width: 4), Text( 'Visitar web', - style: TextStyle( - fontSize: 12, - color: - AppColors.accent.withValues(alpha: 0.7)), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith( + color: AppColors.accent + .withValues(alpha: 0.7)), ), ], ), diff --git a/lib/features/adr/presentation/adr_screen.dart b/lib/features/adr/presentation/adr_screen.dart index 437f6a0..65f7278 100644 --- a/lib/features/adr/presentation/adr_screen.dart +++ b/lib/features/adr/presentation/adr_screen.dart @@ -114,17 +114,19 @@ class AdrScreen extends StatelessWidget { child: ListView( padding: const EdgeInsets.all(12), children: [ - const Card( + Card( child: Padding( - padding: EdgeInsets.all(16), + padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Panel naranja', - style: TextStyle( - fontWeight: FontWeight.bold, fontSize: 16)), - SizedBox(height: 8), - Text('Número superior: Código de peligro (Kemler)\n' + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith(fontWeight: FontWeight.bold)), + const SizedBox(height: 8), + const Text('Número superior: Código de peligro (Kemler)\n' 'Número inferior: Número ONU (identifica la materia)\n\n' 'X delante = reacción peligrosa con agua\n' 'Repetición de cifra = intensificación del peligro'), @@ -133,10 +135,13 @@ class AdrScreen extends StatelessWidget { ), ), const SizedBox(height: 8), - const Padding( - padding: EdgeInsets.symmetric(horizontal: 4, vertical: 8), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 8), child: Text('Clases ADR', - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16)), + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith(fontWeight: FontWeight.bold)), ), ..._classes.map((c) => Card( margin: const EdgeInsets.only(bottom: 6), @@ -144,20 +149,22 @@ class AdrScreen extends StatelessWidget { leading: CircleAvatar( backgroundColor: c.color, child: Text(c.code, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 12, - color: c.color == Colors.white || - c.color == Colors.yellow - ? Colors.black - : Colors.white, - )), + style: + Theme.of(context).textTheme.bodySmall!.copyWith( + fontWeight: FontWeight.bold, + color: c.color == Colors.white || + c.color == Colors.yellow + ? Colors.black + : Colors.white, + )), ), title: Text('Clase ${c.code}: ${c.name}', - style: const TextStyle( - fontWeight: FontWeight.bold, fontSize: 14)), + style: Theme.of(context) + .textTheme + .bodyLarge! + .copyWith(fontWeight: FontWeight.bold)), subtitle: Text(c.description, - style: const TextStyle(fontSize: 12)), + style: Theme.of(context).textTheme.bodySmall), ), )), ], diff --git a/lib/features/cincinnati/presentation/cincinnati_screen.dart b/lib/features/cincinnati/presentation/cincinnati_screen.dart index 9fcdad8..e1b6d75 100644 --- a/lib/features/cincinnati/presentation/cincinnati_screen.dart +++ b/lib/features/cincinnati/presentation/cincinnati_screen.dart @@ -52,6 +52,7 @@ class _CincinnatiScreenState extends State { label: r.suspectedStroke ? 'SOSPECHA DE ICTUS' : 'SIN SOSPECHA', subtitle: r.suspectedStroke ? 'Activar Codigo Ictus' : null, color: r.severity.level.color, + severityLevel: r.severity.level, ) : null, toolBody: ListView( @@ -115,13 +116,18 @@ class _CincinnatiScreenState extends State { const SizedBox(width: 8), Expanded( child: Text(title, - style: const TextStyle( - fontSize: 16, fontWeight: FontWeight.bold)), + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith(fontWeight: FontWeight.bold)), ), ]), const SizedBox(height: 4), Text(instruction, - style: const TextStyle(fontSize: 12, color: Colors.grey)), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Colors.grey)), const SizedBox(height: 12), Row(children: [ Expanded( @@ -178,7 +184,7 @@ class _CincinnatiScreenState extends State { fontWeight: FontWeight.bold, color: selected ? color : Colors.grey)), Text(description, - style: const TextStyle(fontSize: 10), + style: Theme.of(context).textTheme.labelSmall, textAlign: TextAlign.center), ], ), diff --git a/lib/features/comm/presentation/comm_screen.dart b/lib/features/comm/presentation/comm_screen.dart index 4568596..df07aca 100644 --- a/lib/features/comm/presentation/comm_screen.dart +++ b/lib/features/comm/presentation/comm_screen.dart @@ -39,19 +39,26 @@ class CommScreen extends StatelessWidget { child: ListView( padding: const EdgeInsets.all(16), children: [ - const Text( + Text( 'Técnica SBAR', - style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + style: Theme.of(context) + .textTheme + .headlineSmall! + .copyWith(fontWeight: FontWeight.bold), textAlign: TextAlign.center, ), const SizedBox(height: 4), - const Text( + Text( 'Herramienta de comunicación estructurada para transmisión de información clínica', - style: TextStyle(color: Colors.grey, fontSize: 13), + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith(color: Colors.grey), textAlign: TextAlign.center, ), const SizedBox(height: 20), _buildSbarCard( + context, 'S', 'Situation (Situación)', 'Identificación y motivo de la comunicación', @@ -65,6 +72,7 @@ class CommScreen extends StatelessWidget { '"Soy [nombre], TES de la ambulancia [X]. Le llamo por el paciente [nombre], varón de 65 años, con dolor torácico de 30 minutos de evolución."', ), _buildSbarCard( + context, 'B', 'Background (Antecedentes)', 'Contexto clínico relevante', @@ -78,6 +86,7 @@ class CommScreen extends StatelessWidget { '"Antecedentes de HTA y diabetes tipo 2. Medicación: Enalapril, Metformina. Sin alergias conocidas. Estaba realizando esfuerzo físico."', ), _buildSbarCard( + context, 'A', 'Assessment (Evaluación)', 'Hallazgos de la valoración actual', @@ -91,6 +100,7 @@ class CommScreen extends StatelessWidget { '"TA 160/90, FC 95, FR 20, SpO₂ 96%, Glasgow 15. Dolor opresivo centrotorácico irradiado a brazo izquierdo. Sudoración. ECG: elevación ST en II, III, aVF."', ), _buildSbarCard( + context, 'R', 'Recommendation (Recomendación)', 'Qué se necesita o se solicita', @@ -110,6 +120,7 @@ class CommScreen extends StatelessWidget { } Widget _buildSbarCard( + BuildContext context, String letter, String title, String subtitle, @@ -130,10 +141,12 @@ class CommScreen extends StatelessWidget { radius: 20, backgroundColor: color, child: Text(letter, - style: const TextStyle( - color: Colors.white, - fontSize: 22, - fontWeight: FontWeight.bold)), + style: Theme.of(context) + .textTheme + .headlineMedium! + .copyWith( + color: Colors.white, + fontWeight: FontWeight.bold)), ), const SizedBox(width: 12), Expanded( @@ -141,11 +154,15 @@ class CommScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(title, - style: const TextStyle( - fontWeight: FontWeight.bold, fontSize: 15)), + style: Theme.of(context) + .textTheme + .titleSmall! + .copyWith(fontWeight: FontWeight.bold)), Text(subtitle, - style: const TextStyle( - fontSize: 12, color: Colors.grey)), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Colors.grey)), ], ), ), @@ -159,7 +176,8 @@ class CommScreen extends StatelessWidget { children: [ const Text('• '), Expanded( - child: Text(p, style: const TextStyle(fontSize: 13))), + child: Text(p, + style: Theme.of(context).textTheme.bodyMedium)), ], ), )), @@ -176,14 +194,16 @@ class CommScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Ejemplo:', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 12, - color: color)), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(fontWeight: FontWeight.bold, color: color)), const SizedBox(height: 4), Text(example, - style: const TextStyle( - fontSize: 12, fontStyle: FontStyle.italic)), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(fontStyle: FontStyle.italic)), ], ), ), diff --git a/lib/features/ecg/presentation/ecg_leads_screen.dart b/lib/features/ecg/presentation/ecg_leads_screen.dart index 65e6fcc..1572425 100644 --- a/lib/features/ecg/presentation/ecg_leads_screen.dart +++ b/lib/features/ecg/presentation/ecg_leads_screen.dart @@ -51,8 +51,8 @@ class EcgLeadsScreen extends StatelessWidget { top: false, child: TabBarView( children: [ - _buildEuropean(), - _buildAmerican(), + _buildEuropean(context), + _buildAmerican(context), ], ), ), @@ -60,81 +60,90 @@ class EcgLeadsScreen extends StatelessWidget { ); } - Widget _buildEuropean() { + Widget _buildEuropean(BuildContext context) { return ListView( padding: const EdgeInsets.all(16), children: [ - const Text('Código de colores europeo (IEC)', - style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), + Text('Código de colores europeo (IEC)', + style: Theme.of(context) + .textTheme + .titleLarge! + .copyWith(fontWeight: FontWeight.bold)), const SizedBox(height: 12), - _buildImageCard('assets/images/ecg_pinzas.png', + _buildImageCard(context, 'assets/images/ecg_pinzas.png', 'Derivaciones de extremidades (EU)'), const SizedBox(height: 16), - _buildSection('Monitor 3 derivaciones', [ - _lead('Rojo', 'Hombro derecho (RA)', Colors.red), - _lead('Amarillo', 'Hombro izquierdo (LA)', Colors.amber), - _lead('Verde', 'Costilla izquierda inferior (LL)', Colors.green), + _buildSection(context, 'Monitor 3 derivaciones', [ + _lead(context, 'Rojo', 'Hombro derecho (RA)', Colors.red), + _lead(context, 'Amarillo', 'Hombro izquierdo (LA)', Colors.amber), + _lead(context, 'Verde', 'Costilla izquierda inferior (LL)', + Colors.green), ]), const SizedBox(height: 16), - _buildImageCard('assets/images/ecg_base_usa.png', + _buildImageCard(context, 'assets/images/ecg_base_usa.png', 'Colocación de electrodos precordiales'), const SizedBox(height: 12), - _buildSection('ECG 12 derivaciones - Precordiales', [ - _lead('V1 (Rojo)', '4º espacio intercostal, borde esternal derecho', - Colors.red), - _lead('V2 (Amarillo)', + _buildSection(context, 'ECG 12 derivaciones - Precordiales', [ + _lead(context, 'V1 (Rojo)', + '4º espacio intercostal, borde esternal derecho', Colors.red), + _lead(context, 'V2 (Amarillo)', '4º espacio intercostal, borde esternal izquierdo', Colors.amber), - _lead('V3 (Verde)', 'Entre V2 y V4', Colors.green), + _lead(context, 'V3 (Verde)', 'Entre V2 y V4', Colors.green), _lead( + context, 'V4 (Marrón)', '5º espacio intercostal, línea medioclavicular izq.', Colors.brown), - _lead('V5 (Negro)', 'Mismo nivel V4, línea axilar anterior', + _lead(context, 'V5 (Negro)', 'Mismo nivel V4, línea axilar anterior', Colors.black), - _lead('V6 (Violeta)', 'Mismo nivel V4-V5, línea axilar media', - Colors.purple), + _lead(context, 'V6 (Violeta)', + 'Mismo nivel V4-V5, línea axilar media', Colors.purple), ]), const SizedBox(height: 16), - _buildImageCard( - 'assets/images/ecg_posterior.png', 'Derivaciones posteriores'), + _buildImageCard(context, 'assets/images/ecg_posterior.png', + 'Derivaciones posteriores'), const SizedBox(height: 12), - _buildSection('Derivaciones posteriores', [ - _lead('V7', 'Línea axilar posterior izquierda', Colors.blue), - _lead('V8', 'Punta de escápula izquierda', Colors.blue), - _lead('V9', 'Borde vertebral izquierdo', Colors.blue), + _buildSection(context, 'Derivaciones posteriores', [ + _lead(context, 'V7', 'Línea axilar posterior izquierda', Colors.blue), + _lead(context, 'V8', 'Punta de escápula izquierda', Colors.blue), + _lead(context, 'V9', 'Borde vertebral izquierdo', Colors.blue), ]), ], ); } - Widget _buildAmerican() { + Widget _buildAmerican(BuildContext context) { return ListView( padding: const EdgeInsets.all(16), children: [ - const Text('Código de colores americano (AHA)', - style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), + Text('Código de colores americano (AHA)', + style: Theme.of(context) + .textTheme + .titleLarge! + .copyWith(fontWeight: FontWeight.bold)), const SizedBox(height: 12), - _buildImageCard('assets/images/ecg_pinzas_usa.png', + _buildImageCard(context, 'assets/images/ecg_pinzas_usa.png', 'Derivaciones de extremidades (AHA)'), const SizedBox(height: 16), - _buildSection('Monitor 3 derivaciones', [ - _lead('Blanco (RA)', 'Hombro derecho', Colors.grey.shade300), - _lead('Negro (LA)', 'Hombro izquierdo', Colors.black), - _lead('Verde (LL)', 'Costilla izquierda inferior', Colors.green), + _buildSection(context, 'Monitor 3 derivaciones', [ + _lead(context, 'Blanco (RA)', 'Hombro derecho', Colors.grey.shade300), + _lead(context, 'Negro (LA)', 'Hombro izquierdo', Colors.black), + _lead(context, 'Verde (LL)', 'Costilla izquierda inferior', + Colors.green), ]), const SizedBox(height: 16), - _buildImageCard('assets/images/ecg_base_usa.png', + _buildImageCard(context, 'assets/images/ecg_base_usa.png', 'Colocación de electrodos precordiales (AHA)'), const SizedBox(height: 16), - _buildSection('Mnemotecnia', [ - const ListTile( + _buildSection(context, 'Mnemotecnia', [ + ListTile( dense: true, - leading: Icon(Icons.lightbulb_outline, color: Colors.amber), - title: Text('"White is right, smoke over fire"'), + leading: const Icon(Icons.lightbulb_outline, color: Colors.amber), + title: const Text('"White is right, smoke over fire"'), subtitle: Text( 'Blanco a la derecha, Negro sobre Verde\n' '(humo sobre fuego)', - style: TextStyle(fontSize: 12), + style: Theme.of(context).textTheme.bodySmall, ), ), ]), @@ -142,7 +151,8 @@ class EcgLeadsScreen extends StatelessWidget { ); } - Widget _buildImageCard(String assetPath, String caption) { + Widget _buildImageCard( + BuildContext context, String assetPath, String caption) { return Card( clipBehavior: Clip.antiAlias, child: Column( @@ -159,10 +169,9 @@ class EcgLeadsScreen extends StatelessWidget { padding: const EdgeInsets.all(8), child: Text( caption, - style: const TextStyle( - fontSize: 13, - fontWeight: FontWeight.w500, - ), + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + fontWeight: FontWeight.w500, + ), textAlign: TextAlign.center, ), ), @@ -171,7 +180,8 @@ class EcgLeadsScreen extends StatelessWidget { ); } - Widget _buildSection(String title, List children) { + Widget _buildSection( + BuildContext context, String title, List children) { return Card( child: Padding( padding: const EdgeInsets.all(12), @@ -179,8 +189,10 @@ class EcgLeadsScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(title, - style: - const TextStyle(fontSize: 15, fontWeight: FontWeight.bold)), + style: Theme.of(context) + .textTheme + .titleSmall! + .copyWith(fontWeight: FontWeight.bold)), const Divider(), ...children, ], @@ -189,12 +201,13 @@ class EcgLeadsScreen extends StatelessWidget { ); } - static Widget _lead(String label, String position, Color color) { + static Widget _lead( + BuildContext context, String label, String position, Color color) { return ListTile( dense: true, leading: CircleAvatar(backgroundColor: color, radius: 12), title: Text(label, style: const TextStyle(fontWeight: FontWeight.w600)), - subtitle: Text(position, style: const TextStyle(fontSize: 12)), + subtitle: Text(position, style: Theme.of(context).textTheme.bodySmall), ); } } diff --git a/lib/features/epi/presentation/epi_screen.dart b/lib/features/epi/presentation/epi_screen.dart index 79d3145..390bbb1 100644 --- a/lib/features/epi/presentation/epi_screen.dart +++ b/lib/features/epi/presentation/epi_screen.dart @@ -135,8 +135,8 @@ class EpiScreen extends StatelessWidget { ), title: Text(step.title, style: const TextStyle(fontWeight: FontWeight.bold)), - subtitle: - Text(step.description, style: const TextStyle(fontSize: 13)), + subtitle: Text(step.description, + style: Theme.of(context).textTheme.bodyMedium), trailing: Icon(step.icon, color: accentColor), ), ); diff --git a/lib/features/feedback/presentation/feedback_screen.dart b/lib/features/feedback/presentation/feedback_screen.dart index e87fed4..d6f4bec 100644 --- a/lib/features/feedback/presentation/feedback_screen.dart +++ b/lib/features/feedback/presentation/feedback_screen.dart @@ -25,22 +25,28 @@ class FeedbackScreen extends StatelessWidget { const Icon(Icons.lightbulb_outline, size: 48, color: AppColors.accent), const SizedBox(height: 12), - const Text( + Text( '¿Echas en falta alguna herramienta?', textAlign: TextAlign.center, - style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold), + style: Theme.of(context) + .textTheme + .headlineMedium! + .copyWith(fontWeight: FontWeight.bold), ), const SizedBox(height: 8), Text( 'Ayúdanos a mejorar. Puedes solicitar nuevas calculadoras, escalas, protocolos o cualquier funcionalidad que te sea útil en tu trabajo.', textAlign: TextAlign.center, - style: TextStyle( - fontSize: 14, color: Colors.grey.shade600, height: 1.4), + style: Theme.of(context) + .textTheme + .bodyLarge! + .copyWith(color: Colors.grey.shade600, height: 1.4), ), const SizedBox(height: 28), // Option 1: Google Form _buildOption( + context: context, icon: Icons.assignment, color: AppColors.accent, title: 'Formulario de sugerencias', @@ -52,6 +58,7 @@ class FeedbackScreen extends StatelessWidget { // Option 2: Email _buildOption( + context: context, icon: Icons.email_outlined, color: AppColors.primary, title: 'Enviar por email', @@ -65,6 +72,7 @@ class FeedbackScreen extends StatelessWidget { // Option 3: GitHub _buildOption( + context: context, icon: Icons.code, color: const Color(0xFF333333), title: 'GitHub Issues', @@ -77,16 +85,20 @@ class FeedbackScreen extends StatelessWidget { const SizedBox(height: 24), Card( color: AppColors.primary.withValues(alpha: 0.08), - child: const Padding( - padding: EdgeInsets.all(16), + child: Padding( + padding: const EdgeInsets.all(16), child: Row( children: [ - Icon(Icons.favorite, color: AppColors.accent, size: 20), - SizedBox(width: 12), + const Icon(Icons.favorite, + color: AppColors.accent, size: 20), + const SizedBox(width: 12), Expanded( child: Text( 'Cada sugerencia nos ayuda a construir una herramienta mejor para todos los profesionales sanitarios.', - style: TextStyle(fontSize: 12, height: 1.4), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(height: 1.4), ), ), ], @@ -100,6 +112,7 @@ class FeedbackScreen extends StatelessWidget { } Widget _buildOption({ + required BuildContext context, required IconData icon, required Color color, required String title, @@ -129,12 +142,16 @@ class FeedbackScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(title, - style: const TextStyle( - fontSize: 16, fontWeight: FontWeight.bold)), + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith(fontWeight: FontWeight.bold)), const SizedBox(height: 2), Text(subtitle, - style: TextStyle( - fontSize: 12, color: Colors.grey.shade600)), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Colors.grey.shade600)), ], ), ), diff --git a/lib/features/glasgow/presentation/glasgow_screen.dart b/lib/features/glasgow/presentation/glasgow_screen.dart index b1aa3c0..6e0d631 100644 --- a/lib/features/glasgow/presentation/glasgow_screen.dart +++ b/lib/features/glasgow/presentation/glasgow_screen.dart @@ -39,6 +39,7 @@ class _GlasgowScreenState extends State { label: r.severity.label, subtitle: 'O: ${r.eye} V: ${r.verbal} M: ${r.motor}', color: r.severity.level.color, + severityLevel: r.severity.level, ), toolBody: ListView( padding: const EdgeInsets.all(12), diff --git a/lib/features/glosario/presentation/glosario_screen.dart b/lib/features/glosario/presentation/glosario_screen.dart index 5b75170..672d87e 100644 --- a/lib/features/glosario/presentation/glosario_screen.dart +++ b/lib/features/glosario/presentation/glosario_screen.dart @@ -81,7 +81,10 @@ class _GlosarioScreenState extends State { alignment: Alignment.centerRight, child: Text( '${results.length} terminos', - style: TextStyle(fontSize: 12, color: Colors.grey.shade600), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Colors.grey.shade600), ), ), ), @@ -115,18 +118,18 @@ class _GlosarioScreenState extends State { children: [ Text( entry.term, - style: const TextStyle( - fontSize: 15, - fontWeight: FontWeight.bold, - ), + style: Theme.of(context) + .textTheme + .titleSmall! + .copyWith(fontWeight: FontWeight.bold), ), const SizedBox(height: 6), Text( entry.definition, - style: const TextStyle( - fontSize: 13, - height: 1.5, - ), + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith(height: 1.5), ), ], ), diff --git a/lib/features/glucemia/presentation/glucemia_screen.dart b/lib/features/glucemia/presentation/glucemia_screen.dart index b15ee1c..41266fd 100644 --- a/lib/features/glucemia/presentation/glucemia_screen.dart +++ b/lib/features/glucemia/presentation/glucemia_screen.dart @@ -41,30 +41,35 @@ class GlucemiaScreen extends StatelessWidget { padding: const EdgeInsets.all(16), children: [ _buildCard( + context, 'Hipoglucemia grave', '<40 mg/dL', AppColors.severitySevere, 'Pérdida de consciencia, convulsiones.\nTratamiento: Glucagón IM / Glucosa IV.'), _buildCard( + context, 'Hipoglucemia', '40-70 mg/dL', AppColors.severityModerate, 'Temblor, sudoración, taquicardia, confusión.\nTratamiento: Glucosa oral si consciente.'), - _buildCard( - 'Normal en ayunas', '70-100 mg/dL', AppColors.severityMild, ''), - _buildCard('Normal postprandial', '70-140 mg/dL', + _buildCard(context, 'Normal en ayunas', '70-100 mg/dL', + AppColors.severityMild, ''), + _buildCard(context, 'Normal postprandial', '70-140 mg/dL', AppColors.severityMild, '2 horas después de comer.'), _buildCard( + context, 'Hiperglucemia', '140-250 mg/dL', AppColors.severityModerate, 'Poliuria, polidipsia, polifagia.\nControl y seguimiento.'), _buildCard( + context, 'Hiperglucemia grave', '>250 mg/dL', AppColors.severitySevere, 'Riesgo de cetoacidosis diabética o síndrome hiperosmolar.\nBuscar cetonuria. Valorar traslado.'), _buildCard( + context, 'Cetoacidosis diabética', '>300 mg/dL + cetonas', AppColors.severitySevere, @@ -75,8 +80,8 @@ class GlucemiaScreen extends StatelessWidget { ); } - Widget _buildCard( - String title, String range, Color color, String description) { + Widget _buildCard(BuildContext context, String title, String range, + Color color, String description) { return Card( margin: const EdgeInsets.only(bottom: 8), child: ListTile( @@ -96,7 +101,7 @@ class GlucemiaScreen extends StatelessWidget { style: TextStyle(fontWeight: FontWeight.w600, color: color)), if (description.isNotEmpty) ...[ const SizedBox(height: 4), - Text(description, style: const TextStyle(fontSize: 12)), + Text(description, style: Theme.of(context).textTheme.bodySmall), ], ], ), diff --git a/lib/features/gps_converter/presentation/gps_converter_screen.dart b/lib/features/gps_converter/presentation/gps_converter_screen.dart index ea1d9d0..c9f329d 100644 --- a/lib/features/gps_converter/presentation/gps_converter_screen.dart +++ b/lib/features/gps_converter/presentation/gps_converter_screen.dart @@ -313,16 +313,19 @@ class _GpsConverterScreenState extends State ], if (_currentFormats == null && _error == null && !_loading) - const Padding( - padding: EdgeInsets.only(top: 48), + Padding( + padding: const EdgeInsets.only(top: 48), child: Column( children: [ - Icon(Icons.explore, size: 64, color: Colors.grey), - SizedBox(height: 16), + const Icon(Icons.explore, size: 64, color: Colors.grey), + const SizedBox(height: 16), Text( 'Pulsa el boton para obtener\ntu ubicacion actual', textAlign: TextAlign.center, - style: TextStyle(color: Colors.grey, fontSize: 16), + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith(color: Colors.grey), ), ], ), @@ -399,16 +402,14 @@ class _GpsConverterScreenState extends State SizedBox( width: 130, child: Text(label, - style: TextStyle( - fontSize: 13, + style: Theme.of(context).textTheme.bodyMedium!.copyWith( color: highlight ? AppColors.severityModerate : Colors.grey.shade700)), ), Expanded( child: Text(value, - style: TextStyle( - fontSize: 13, + style: Theme.of(context).textTheme.bodyMedium!.copyWith( fontWeight: FontWeight.w600, fontFamily: 'monospace', color: highlight ? AppColors.severityModerate : null)), @@ -526,17 +527,20 @@ class _GpsConverterScreenState extends State ], if (_convertedFormats == null && _convertError == null) - const Padding( - padding: EdgeInsets.only(top: 48), + Padding( + padding: const EdgeInsets.only(top: 48), child: Column( children: [ - Icon(Icons.swap_horiz, size: 64, color: Colors.grey), - SizedBox(height: 16), + const Icon(Icons.swap_horiz, size: 64, color: Colors.grey), + const SizedBox(height: 16), Text( 'Introduce coordenadas en cualquier\n' 'formato para convertirlas', textAlign: TextAlign.center, - style: TextStyle(color: Colors.grey, fontSize: 16), + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith(color: Colors.grey), ), ], ), diff --git a/lib/features/heart_rate/presentation/heart_rate_screen.dart b/lib/features/heart_rate/presentation/heart_rate_screen.dart index f5d1a85..31f5705 100644 --- a/lib/features/heart_rate/presentation/heart_rate_screen.dart +++ b/lib/features/heart_rate/presentation/heart_rate_screen.dart @@ -73,6 +73,7 @@ class _HeartRateScreenState extends State { label: result != null ? 'lpm' : 'Toca la pantalla con cada latido', subtitle: '${_taps.length} pulsaciones en ${_elapsedSeconds}s', color: color, + severityLevel: result?.severity.level, ), toolBody: GestureDetector( onTap: _tap, @@ -89,15 +90,17 @@ class _HeartRateScreenState extends State { const SizedBox(height: 16), Text( _isRunning ? 'Toca con cada latido' : 'Toca para empezar', - style: TextStyle( - fontSize: 18, + style: Theme.of(context).textTheme.titleLarge!.copyWith( color: _isRunning ? AppColors.soporteVital : Colors.grey), ), const SizedBox(height: 8), - const Text( + Text( 'Palpa el pulso y toca la pantalla\ncon cada pulsacion', textAlign: TextAlign.center, - style: TextStyle(fontSize: 13, color: Colors.grey), + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith(color: Colors.grey), ), ], ), diff --git a/lib/features/heridas/presentation/heridas_screen.dart b/lib/features/heridas/presentation/heridas_screen.dart index ec44e85..7dda394 100644 --- a/lib/features/heridas/presentation/heridas_screen.dart +++ b/lib/features/heridas/presentation/heridas_screen.dart @@ -134,8 +134,10 @@ class HeridasScreen extends StatelessWidget { Icon(w.icon, color: w.color), const SizedBox(width: 8), Text(w.name, - style: const TextStyle( - fontSize: 18, fontWeight: FontWeight.bold)), + style: Theme.of(context) + .textTheme + .titleLarge! + .copyWith(fontWeight: FontWeight.bold)), ], ), const SizedBox(height: 8), @@ -157,9 +159,7 @@ class HeridasScreen extends StatelessWidget { padding: const EdgeInsets.only(bottom: 4), child: Text.rich( TextSpan( - style: TextStyle( - fontSize: 13, - color: Theme.of(context).textTheme.bodyMedium?.color), + style: Theme.of(context).textTheme.bodyMedium, children: [ TextSpan( text: '$label: ', diff --git a/lib/features/hipertermia/presentation/hipertermia_screen.dart b/lib/features/hipertermia/presentation/hipertermia_screen.dart index 1710ce9..5239b2d 100644 --- a/lib/features/hipertermia/presentation/hipertermia_screen.dart +++ b/lib/features/hipertermia/presentation/hipertermia_screen.dart @@ -45,6 +45,7 @@ class _HipertermiaScreenState extends State { value: '${_temperature.toStringAsFixed(1)} C', label: result.label, color: color, + severityLevel: result.severity.level, ), toolBody: ListView( padding: const EdgeInsets.all(16), @@ -61,15 +62,18 @@ class _HipertermiaScreenState extends State { const Icon(Icons.thermostat, size: 20, color: AppColors.primary), const SizedBox(width: 8), - const Text('Temperatura corporal', - style: TextStyle( - fontSize: 15, fontWeight: FontWeight.bold)), + Text('Temperatura corporal', + style: Theme.of(context) + .textTheme + .titleSmall! + .copyWith(fontWeight: FontWeight.bold)), const Spacer(), Text('${_temperature.toStringAsFixed(1)} C', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - color: color)), + style: Theme.of(context) + .textTheme + .titleLarge! + .copyWith( + fontWeight: FontWeight.bold, color: color)), ], ), const SizedBox(height: 12), @@ -86,11 +90,15 @@ class _HipertermiaScreenState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('36 C', - style: TextStyle( - fontSize: 12, color: Colors.grey.shade600)), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Colors.grey.shade600)), Text('43 C', - style: TextStyle( - fontSize: 12, color: Colors.grey.shade600)), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Colors.grey.shade600)), ], ), ], @@ -134,8 +142,10 @@ class _HipertermiaScreenState extends State { borderRadius: BorderRadius.circular(8), ), child: Text(title, - style: TextStyle( - fontWeight: FontWeight.bold, fontSize: 16, color: color)), + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith(fontWeight: FontWeight.bold, color: color)), ), const SizedBox(height: 12), const Text('Sintomas:', @@ -147,7 +157,8 @@ class _HipertermiaScreenState extends State { children: [ const Text('\u2022 '), Expanded( - child: Text(s, style: const TextStyle(fontSize: 13))), + child: Text(s, + style: Theme.of(context).textTheme.bodyMedium)), ], ), )), @@ -161,7 +172,8 @@ class _HipertermiaScreenState extends State { children: [ const Text('\u2022 '), Expanded( - child: Text(t, style: const TextStyle(fontSize: 13))), + child: Text(t, + style: Theme.of(context).textTheme.bodyMedium)), ], ), )), diff --git a/lib/features/hipotermia/presentation/hipotermia_screen.dart b/lib/features/hipotermia/presentation/hipotermia_screen.dart index 95394ca..b264ae1 100644 --- a/lib/features/hipotermia/presentation/hipotermia_screen.dart +++ b/lib/features/hipotermia/presentation/hipotermia_screen.dart @@ -53,6 +53,7 @@ class _HipotermiaScreenState extends State { label: result.label, subtitle: _gradeRange, color: color, + severityLevel: result.severity.level, ), toolBody: ListView( padding: const EdgeInsets.all(16), @@ -64,13 +65,16 @@ class _HipotermiaScreenState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text('Temperatura corporal', - style: - TextStyle(fontWeight: FontWeight.bold, fontSize: 15)), + Text('Temperatura corporal', + style: Theme.of(context) + .textTheme + .titleSmall! + .copyWith(fontWeight: FontWeight.bold)), const SizedBox(height: 8), Row( children: [ - const Text('25 C', style: TextStyle(fontSize: 12)), + Text('25 C', + style: Theme.of(context).textTheme.bodySmall), Expanded( child: Slider( value: _temperature, @@ -82,7 +86,8 @@ class _HipotermiaScreenState extends State { onChanged: (v) => setState(() => _temperature = v), ), ), - const Text('37 C', style: TextStyle(fontSize: 12)), + Text('37 C', + style: Theme.of(context).textTheme.bodySmall), ], ), ], @@ -127,8 +132,10 @@ class _HipotermiaScreenState extends State { ), child: Text( title, - style: TextStyle( - fontWeight: FontWeight.bold, fontSize: 16, color: color), + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith(fontWeight: FontWeight.bold, color: color), ), ), const SizedBox(height: 12), @@ -139,9 +146,11 @@ class _HipotermiaScreenState extends State { child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text('\u2022 ', style: TextStyle(fontSize: 14)), + Text('\u2022 ', + style: Theme.of(context).textTheme.bodyLarge), Expanded( - child: Text(s, style: const TextStyle(fontSize: 13))), + child: Text(s, + style: Theme.of(context).textTheme.bodyMedium)), ], ), )), @@ -153,9 +162,11 @@ class _HipotermiaScreenState extends State { child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text('\u2022 ', style: TextStyle(fontSize: 14)), + Text('\u2022 ', + style: Theme.of(context).textTheme.bodyLarge), Expanded( - child: Text(t, style: const TextStyle(fontSize: 13))), + child: Text(t, + style: Theme.of(context).textTheme.bodyMedium)), ], ), )), diff --git a/lib/features/home/presentation/home_screen.dart b/lib/features/home/presentation/home_screen.dart index 4749416..e842fd3 100644 --- a/lib/features/home/presentation/home_screen.dart +++ b/lib/features/home/presentation/home_screen.dart @@ -139,9 +139,9 @@ class _HomeScreenState extends State { shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), gridDelegate: - const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 3, - childAspectRatio: 0.9, + const SliverGridDelegateWithMaxCrossAxisExtent( + maxCrossAxisExtent: 160, + childAspectRatio: 0.95, crossAxisSpacing: 8, mainAxisSpacing: 8, ), diff --git a/lib/features/lund_browder/presentation/lund_browder_screen.dart b/lib/features/lund_browder/presentation/lund_browder_screen.dart index c53a593..75011a4 100644 --- a/lib/features/lund_browder/presentation/lund_browder_screen.dart +++ b/lib/features/lund_browder/presentation/lund_browder_screen.dart @@ -65,6 +65,7 @@ class _LundBrowderScreenState extends State { label: result.severity.label, subtitle: 'SCQ - Superficie Corporal Quemada', color: color, + severityLevel: result.severity.level, ), toolBody: Column( children: [ @@ -81,11 +82,12 @@ class _LundBrowderScreenState extends State { label: Text(LundBrowderData.ageGroups[i]), selected: _selectedAge == i, selectedColor: AppColors.tecnicas, - labelStyle: TextStyle( - color: _selectedAge == i ? Colors.white : null, - fontWeight: _selectedAge == i ? FontWeight.bold : null, - fontSize: 12, - ), + labelStyle: + Theme.of(context).textTheme.bodySmall!.copyWith( + color: _selectedAge == i ? Colors.white : null, + fontWeight: + _selectedAge == i ? FontWeight.bold : null, + ), onSelected: (_) => setState(() => _selectedAge = i), ), ); @@ -115,8 +117,10 @@ class _LundBrowderScreenState extends State { style: const TextStyle(fontWeight: FontWeight.w500)), subtitle: Text( '$pct% \u00b7 ${LundBrowderData.burnLabels[degree]}', - style: - TextStyle(fontSize: 12, color: _burnColors[degree]), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: _burnColors[degree]), ), trailing: SizedBox( width: 160, @@ -142,13 +146,15 @@ class _LundBrowderScreenState extends State { child: Center( child: Text( '$d', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 13, - color: degree == d - ? Colors.white - : Colors.black54, - ), + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith( + fontWeight: FontWeight.bold, + color: degree == d + ? Colors.white + : Colors.black54, + ), ), ), ), @@ -174,7 +180,7 @@ class _LundBrowderScreenState extends State { Container(width: 12, height: 12, color: _burnColors[d]), const SizedBox(width: 4), Text(LundBrowderData.burnLabels[d], - style: const TextStyle(fontSize: 10)), + style: Theme.of(context).textTheme.labelSmall), ], ), ); diff --git a/lib/features/madrid_direct/presentation/madrid_direct_screen.dart b/lib/features/madrid_direct/presentation/madrid_direct_screen.dart index 7deb086..9b6bb96 100644 --- a/lib/features/madrid_direct/presentation/madrid_direct_screen.dart +++ b/lib/features/madrid_direct/presentation/madrid_direct_screen.dart @@ -63,14 +63,18 @@ class _MadridDirectScreenState extends State { ? '>= 2 puntos: sospecha de oclusion de gran vaso' : '< 2 puntos: trasladar al hospital con UI mas cercano', color: r.severity.level.color, + severityLevel: r.severity.level, ), toolBody: ListView( padding: const EdgeInsets.all(12), children: [ - const Padding( - padding: EdgeInsets.only(left: 4, bottom: 4), + Padding( + padding: const EdgeInsets.only(left: 4, bottom: 4), child: Text('Items clinicos (+1 punto cada uno)', - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14)), + style: Theme.of(context) + .textTheme + .bodyLarge! + .copyWith(fontWeight: FontWeight.bold)), ), _buildClinicalItem( 'Brazo - No vence gravedad', @@ -115,10 +119,13 @@ class _MadridDirectScreenState extends State { }), ), const SizedBox(height: 16), - const Padding( - padding: EdgeInsets.only(left: 4, bottom: 4), + Padding( + padding: const EdgeInsets.only(left: 4, bottom: 4), child: Text('Modificadores (restan puntos)', - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14)), + style: Theme.of(context) + .textTheme + .bodyLarge! + .copyWith(fontWeight: FontWeight.bold)), ), // TAS modifier Card( @@ -153,8 +160,11 @@ class _MadridDirectScreenState extends State { _tas >= 180 ? Colors.orange : AppColors.primary, onChanged: (v) => setState(() => _tas = v.round()), ), - const Text('Restar 1 punto por cada 10 mmHg > 180', - style: TextStyle(fontSize: 11, color: Colors.grey)), + Text('Restar 1 punto por cada 10 mmHg > 180', + style: Theme.of(context) + .textTheme + .labelSmall! + .copyWith(color: Colors.grey)), ], ), ), @@ -191,29 +201,31 @@ class _MadridDirectScreenState extends State { activeColor: _age >= 85 ? Colors.purple : AppColors.primary, onChanged: (v) => setState(() => _age = v.round()), ), - const Text('Restar 1 punto por cada ano a partir de 85', - style: TextStyle(fontSize: 11, color: Colors.grey)), + Text('Restar 1 punto por cada ano a partir de 85', + style: Theme.of(context) + .textTheme + .labelSmall! + .copyWith(color: Colors.grey)), ], ), ), ), // Age caveat if (!r.requiresThrombectomy && _age >= 85) - const Padding( - padding: EdgeInsets.only(top: 8), + Padding( + padding: const EdgeInsets.only(top: 8), child: Card( - color: Color(0xFFFFF8E1), + color: const Color(0xFFFFF8E1), child: Padding( - padding: EdgeInsets.all(12), + padding: const EdgeInsets.all(12), child: Text( 'Si la puntuacion es < 2 solo por la edad y el paciente ' 'tiene excelente situacion basal, valorar con neurologo ' 'la posibilidad de traslado directo a TM.', - style: TextStyle( - fontSize: 12, - color: Colors.orange, - fontStyle: FontStyle.italic, - ), + style: Theme.of(context).textTheme.bodySmall!.copyWith( + color: Colors.orange, + fontStyle: FontStyle.italic, + ), ), ), ), @@ -240,8 +252,12 @@ class _MadridDirectScreenState extends State { secondary: Icon(icon, color: value ? AppColors.severitySevere : Colors.grey), title: Text(title, - style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w600)), - subtitle: Text(description, style: const TextStyle(fontSize: 11)), + style: Theme.of(context) + .textTheme + .bodyLarge! + .copyWith(fontWeight: FontWeight.w600)), + subtitle: + Text(description, style: Theme.of(context).textTheme.labelSmall), value: value, activeThumbColor: AppColors.severitySevere, onChanged: (v) => onChanged(v), diff --git a/lib/features/nihss/presentation/nihss_screen.dart b/lib/features/nihss/presentation/nihss_screen.dart index f77981f..92a71b4 100644 --- a/lib/features/nihss/presentation/nihss_screen.dart +++ b/lib/features/nihss/presentation/nihss_screen.dart @@ -69,6 +69,7 @@ class _NihssScreenState extends State { value: '${r.total}', label: r.severity.label, color: r.severity.level.color, + severityLevel: r.severity.level, ), toolBody: ListView.builder( controller: _scrollController, @@ -93,21 +94,19 @@ class _NihssScreenState extends State { children: [ Text( '${index + 1}. ', - style: TextStyle( - fontSize: 13, - fontWeight: FontWeight.w600, - color: isExpanded - ? Theme.of(context).colorScheme.primary - : Colors.grey, - ), + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + fontWeight: FontWeight.w600, + color: isExpanded + ? Theme.of(context).colorScheme.primary + : Colors.grey, + ), ), Expanded( child: Text( item.name, - style: const TextStyle( - fontSize: 13, - fontWeight: FontWeight.w600, - ), + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + fontWeight: FontWeight.w600, + ), ), ), ], @@ -119,11 +118,10 @@ class _NihssScreenState extends State { : AppColors.severityMild, child: Text( '${_scores[index]}', - style: const TextStyle( - color: Colors.white, - fontSize: 12, - fontWeight: FontWeight.bold, - ), + style: Theme.of(context).textTheme.bodySmall!.copyWith( + color: Colors.white, + fontWeight: FontWeight.bold, + ), ), ), children: [ @@ -135,7 +133,7 @@ class _NihssScreenState extends State { return RadioListTile( title: Text( item.options[optIndex].label, - style: const TextStyle(fontSize: 12), + style: Theme.of(context).textTheme.bodySmall, ), value: item.options[optIndex].score, dense: true, diff --git a/lib/features/o2_calculator/presentation/o2_calculator_screen.dart b/lib/features/o2_calculator/presentation/o2_calculator_screen.dart index e2c4c55..e902583 100644 --- a/lib/features/o2_calculator/presentation/o2_calculator_screen.dart +++ b/lib/features/o2_calculator/presentation/o2_calculator_screen.dart @@ -57,12 +57,16 @@ class _O2CalculatorScreenState extends State { ? '${O2CalculatorData.bottles[_selectedBottle].label} \u00b7 ${_pressure.round()} bar \u00b7 ${_flowRate.round()} L/min' : null, color: color, + severityLevel: result.severity.level, ), toolBody: ListView( padding: const EdgeInsets.all(16), children: [ - const Text('Tamano de botella', - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16)), + Text('Tamano de botella', + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith(fontWeight: FontWeight.bold)), const SizedBox(height: 8), Wrap( spacing: 8, @@ -125,11 +129,12 @@ class _O2CalculatorScreenState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(label, - style: - const TextStyle(fontWeight: FontWeight.bold, fontSize: 16)), + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith(fontWeight: FontWeight.bold)), Text(valueText, - style: const TextStyle( - fontSize: 16, + style: Theme.of(context).textTheme.titleMedium!.copyWith( fontWeight: FontWeight.w600, color: AppColors.oxigenoterapia)), ], diff --git a/lib/features/oxigenoterapia/presentation/oxigenoterapia_screen.dart b/lib/features/oxigenoterapia/presentation/oxigenoterapia_screen.dart index fa08f43..1064ae0 100644 --- a/lib/features/oxigenoterapia/presentation/oxigenoterapia_screen.dart +++ b/lib/features/oxigenoterapia/presentation/oxigenoterapia_screen.dart @@ -106,22 +106,24 @@ class OxigenoterapiaScreen extends StatelessWidget { const SizedBox(width: 12), Expanded( child: Text(device.name, - style: const TextStyle( - fontSize: 18, fontWeight: FontWeight.bold)), + style: Theme.of(context) + .textTheme + .titleLarge! + .copyWith(fontWeight: FontWeight.bold)), ), ], ), const SizedBox(height: 12), Row( children: [ - _buildInfoChip('Flujo', device.flowRange), + _buildInfoChip(context, 'Flujo', device.flowRange), const SizedBox(width: 8), - _buildInfoChip('FiO₂', device.fio2Range), + _buildInfoChip(context, 'FiO₂', device.fio2Range), ], ), const SizedBox(height: 12), Text(device.description, - style: const TextStyle(fontSize: 13)), + style: Theme.of(context).textTheme.bodyMedium), ], ), ), @@ -132,7 +134,7 @@ class OxigenoterapiaScreen extends StatelessWidget { ); } - Widget _buildInfoChip(String label, String value) { + Widget _buildInfoChip(BuildContext context, String label, String value) { return Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6), decoration: BoxDecoration( @@ -143,10 +145,12 @@ class OxigenoterapiaScreen extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ Text('$label: ', - style: const TextStyle(fontSize: 12, color: Colors.grey)), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Colors.grey)), Text(value, - style: const TextStyle( - fontSize: 13, + style: Theme.of(context).textTheme.bodyMedium!.copyWith( fontWeight: FontWeight.bold, color: AppColors.oxigenoterapia)), ], diff --git a/lib/features/posiciones/presentation/posiciones_screen.dart b/lib/features/posiciones/presentation/posiciones_screen.dart index 65d3107..c074da6 100644 --- a/lib/features/posiciones/presentation/posiciones_screen.dart +++ b/lib/features/posiciones/presentation/posiciones_screen.dart @@ -144,8 +144,10 @@ class PosicionesScreen extends StatelessWidget { title: Text(pos.name, style: const TextStyle(fontWeight: FontWeight.bold)), subtitle: Text(pos.indication, - style: - TextStyle(fontSize: 12, color: Colors.orange.shade700)), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Colors.orange.shade700)), children: [ if (pos.imagePath != null) Padding( diff --git a/lib/features/rankin/presentation/rankin_screen.dart b/lib/features/rankin/presentation/rankin_screen.dart index 33d7927..9bb9660 100644 --- a/lib/features/rankin/presentation/rankin_screen.dart +++ b/lib/features/rankin/presentation/rankin_screen.dart @@ -71,7 +71,7 @@ class _RankinScreenState extends State { subtitle: level.description != null && level.description!.isNotEmpty ? Text(level.description!, - style: const TextStyle(fontSize: 12)) + style: Theme.of(context).textTheme.bodySmall) : null, ), ); diff --git a/lib/features/rcp/presentation/plan_rcp_screen.dart b/lib/features/rcp/presentation/plan_rcp_screen.dart index a0b187c..1d867cd 100644 --- a/lib/features/rcp/presentation/plan_rcp_screen.dart +++ b/lib/features/rcp/presentation/plan_rcp_screen.dart @@ -56,6 +56,7 @@ class PlanRcpScreen extends StatelessWidget { child: TabBarView( children: [ _buildAlgorithm( + context, 'SVB Adultos (ERC 2025)', [ const _AlgorithmStep( @@ -101,6 +102,7 @@ class PlanRcpScreen extends StatelessWidget { ], ), _buildAlgorithm( + context, 'SVB Pediátrico (ERC 2025)', [ const _AlgorithmStep('Seguridad', 'Garantizar seguridad', @@ -146,12 +148,13 @@ class PlanRcpScreen extends StatelessWidget { ); } - Widget _buildAlgorithm(String title, List<_AlgorithmStep> steps) { + Widget _buildAlgorithm( + BuildContext context, String title, List<_AlgorithmStep> steps) { return ListView( padding: const EdgeInsets.all(16), children: [ Text(title, - style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + style: Theme.of(context).textTheme.titleLarge, textAlign: TextAlign.center), const SizedBox(height: 16), ...List.generate(steps.length, (index) { @@ -169,10 +172,12 @@ class PlanRcpScreen extends StatelessWidget { radius: 14, backgroundColor: step.color, child: Text('${index + 1}', - style: const TextStyle( - color: Colors.white, - fontSize: 12, - fontWeight: FontWeight.bold)), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith( + color: Colors.white, + fontWeight: FontWeight.bold)), ), const SizedBox(width: 12), Expanded( @@ -186,7 +191,8 @@ class PlanRcpScreen extends StatelessWidget { if (step.description.isNotEmpty) ...[ const SizedBox(height: 4), Text(step.description, - style: const TextStyle(fontSize: 13)), + style: + Theme.of(context).textTheme.bodyMedium), ], ], ), diff --git a/lib/features/rcp/presentation/rcp_screen.dart b/lib/features/rcp/presentation/rcp_screen.dart index 39b55c2..a407d9f 100644 --- a/lib/features/rcp/presentation/rcp_screen.dart +++ b/lib/features/rcp/presentation/rcp_screen.dart @@ -317,19 +317,17 @@ class _RcpScreenState extends State { children: [ Text( _bannerValue, - style: TextStyle( - fontSize: 36, - fontWeight: FontWeight.bold, - color: _bannerColor, - ), + style: Theme.of(context).textTheme.displayMedium!.copyWith( + fontWeight: FontWeight.bold, + color: _bannerColor, + ), ), Text( _bannerLabel, - style: TextStyle( - fontSize: 15, - fontWeight: FontWeight.w600, - color: _bannerColor, - ), + style: Theme.of(context).textTheme.titleSmall!.copyWith( + fontWeight: FontWeight.w600, + color: _bannerColor, + ), ), ], ), @@ -347,29 +345,29 @@ class _RcpScreenState extends State { padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), color: Colors.orange.shade700, - child: const Row( + child: Row( children: [ - Icon(Icons.warning_amber, color: Colors.white, size: 24), - SizedBox(width: 10), + const Icon(Icons.warning_amber, + color: Colors.white, size: 24), + const SizedBox(width: 10), Expanded( child: Text( 'COMPROBAR PULSO / CAMBIO REANIMADOR', - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - fontSize: 13, - ), + style: + Theme.of(context).textTheme.bodyMedium!.copyWith( + color: Colors.white, + fontWeight: FontWeight.bold, + ), ), ), Text( 'CONFIRMAR', - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - fontSize: 12, - decoration: TextDecoration.underline, - decorationColor: Colors.white, - ), + style: Theme.of(context).textTheme.bodySmall!.copyWith( + color: Colors.white, + fontWeight: FontWeight.bold, + decoration: TextDecoration.underline, + decorationColor: Colors.white, + ), ), ], ), @@ -417,20 +415,19 @@ class _RcpScreenState extends State { // SVA medications if (_session.mode == RcpMode.sva && _isRunning) ...[ - const Padding( - padding: EdgeInsets.fromLTRB(16, 0, 16, 8), + Padding( + padding: const EdgeInsets.fromLTRB(16, 0, 16, 8), child: Row( children: [ - Icon(Icons.medication, + const Icon(Icons.medication, size: 20, color: AppColors.soporteVital), - SizedBox(width: 8), + const SizedBox(width: 8), Text( 'Medicacion SVA', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: AppColors.soporteVital, - ), + style: Theme.of(context).textTheme.titleMedium!.copyWith( + fontWeight: FontWeight.bold, + color: AppColors.soporteVital, + ), ), ], ), @@ -459,14 +456,14 @@ class _RcpScreenState extends State { const Icon(Icons.list_alt, size: 20, color: AppColors.primary), const SizedBox(width: 8), - const Expanded( + Expanded( child: Text( 'Registro de acciones', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: AppColors.primary, - ), + style: + Theme.of(context).textTheme.titleMedium!.copyWith( + fontWeight: FontWeight.bold, + color: AppColors.primary, + ), ), ), IconButton( @@ -499,8 +496,10 @@ class _RcpScreenState extends State { child: Text( '120 bpm \u00b7 Ratio 30:2 \u00b7 Comprimir fuerte ' '(5-6 cm) \u00b7 Permitir reexpansion completa', - style: TextStyle( - fontSize: 12, color: Colors.grey.shade600), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Colors.grey.shade600), ), ), ], @@ -571,11 +570,10 @@ class _RcpScreenState extends State { ), child: Text( 'x$count', - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.bold, - color: Colors.green.shade700, - ), + style: Theme.of(context).textTheme.bodySmall!.copyWith( + fontWeight: FontWeight.bold, + color: Colors.green.shade700, + ), ), ) : null, @@ -655,20 +653,18 @@ class _RcpScreenState extends State { Text( label, textAlign: TextAlign.center, - style: TextStyle( - fontSize: 15, - fontWeight: FontWeight.bold, - color: color, - ), + style: Theme.of(context).textTheme.titleSmall!.copyWith( + fontWeight: FontWeight.bold, + color: color, + ), ), const SizedBox(height: 4), Text( subtitle, textAlign: TextAlign.center, - style: TextStyle( - fontSize: 11, - color: color.withValues(alpha: 0.8), - ), + style: Theme.of(context).textTheme.labelSmall!.copyWith( + color: color.withValues(alpha: 0.8), + ), ), ], ), @@ -692,12 +688,11 @@ class _RcpScreenState extends State { children: [ const Icon(Icons.favorite, color: AppColors.soporteVital), const SizedBox(width: 8), - const Text( + Text( 'Comprobar pulso', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - ), + style: Theme.of(context).textTheme.titleLarge!.copyWith( + fontWeight: FontWeight.bold, + ), ), if (pulseCount > 0) ...[ const SizedBox(width: 8), @@ -711,11 +706,10 @@ class _RcpScreenState extends State { ), child: Text( 'x$pulseCount', - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.bold, - color: Colors.green.shade700, - ), + style: Theme.of(context).textTheme.bodySmall!.copyWith( + fontWeight: FontWeight.bold, + color: Colors.green.shade700, + ), ), ), ], @@ -809,11 +803,10 @@ class _RcpScreenState extends State { ), child: Text( 'x${_countOf('rhythm')}', - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.bold, - color: Colors.green.shade700, - ), + style: Theme.of(context).textTheme.bodySmall!.copyWith( + fontWeight: FontWeight.bold, + color: Colors.green.shade700, + ), ), ) : null, @@ -851,8 +844,10 @@ class _RcpScreenState extends State { children: [ Text( 'Analisis DEA #${_countOf('rhythm') + 1}', - style: - const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + style: Theme.of(context) + .textTheme + .titleLarge! + .copyWith(fontWeight: FontWeight.bold), ), const SizedBox(height: 16), Row( @@ -902,23 +897,28 @@ class _RcpScreenState extends State { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text( + Text( 'Ritmo identificado', - style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + style: Theme.of(context) + .textTheme + .titleLarge! + .copyWith(fontWeight: FontWeight.bold), ), const SizedBox(height: 4), Text( 'Analisis #${_countOf('rhythm') + 1}', - style: TextStyle(fontSize: 13, color: Colors.grey.shade600), + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith(color: Colors.grey.shade600), ), const SizedBox(height: 12), - const Text( + Text( 'DESFIBRILABLE', - style: TextStyle( - fontSize: 13, - fontWeight: FontWeight.bold, - color: Colors.red, - ), + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + fontWeight: FontWeight.bold, + color: Colors.red, + ), ), const SizedBox(height: 6), Row( @@ -947,13 +947,12 @@ class _RcpScreenState extends State { ], ), const SizedBox(height: 16), - const Text( + Text( 'NO DESFIBRILABLE', - style: TextStyle( - fontSize: 13, - fontWeight: FontWeight.bold, - color: Colors.blue, - ), + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + fontWeight: FontWeight.bold, + color: Colors.blue, + ), ), const SizedBox(height: 6), Row( @@ -982,13 +981,12 @@ class _RcpScreenState extends State { ], ), const SizedBox(height: 16), - const Text( + Text( 'OTROS', - style: TextStyle( - fontSize: 13, - fontWeight: FontWeight.bold, - color: Colors.grey, - ), + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + fontWeight: FontWeight.bold, + color: Colors.grey, + ), ), const SizedBox(height: 6), Row( @@ -1064,18 +1062,19 @@ class _RcpScreenState extends State { const SizedBox(height: 6), Text( label, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: color, - ), + style: Theme.of(context).textTheme.titleMedium!.copyWith( + fontWeight: FontWeight.bold, + color: color, + ), ), const SizedBox(height: 2), Text( subtitle, textAlign: TextAlign.center, - style: - TextStyle(fontSize: 10, color: color.withValues(alpha: 0.8)), + style: Theme.of(context) + .textTheme + .labelSmall! + .copyWith(color: color.withValues(alpha: 0.8)), ), ], ), @@ -1203,7 +1202,10 @@ class _RcpScreenState extends State { const SizedBox(height: 4), Text( label, - style: TextStyle(fontSize: 10, color: color), + style: Theme.of(context) + .textTheme + .labelSmall! + .copyWith(color: color), ), ], ), @@ -1224,10 +1226,9 @@ class _RcpScreenState extends State { label: const Text('SVB'), selected: _session.mode == RcpMode.svb, selectedColor: AppColors.soporteVital, - labelStyle: TextStyle( - color: _session.mode == RcpMode.svb ? Colors.white : null, - fontSize: 12, - ), + labelStyle: Theme.of(context).textTheme.bodySmall!.copyWith( + color: _session.mode == RcpMode.svb ? Colors.white : null, + ), onSelected: (_) => _onModeChanged(RcpMode.svb), visualDensity: VisualDensity.compact, ), @@ -1235,10 +1236,9 @@ class _RcpScreenState extends State { label: const Text('SVA'), selected: _session.mode == RcpMode.sva, selectedColor: AppColors.soporteVital, - labelStyle: TextStyle( - color: _session.mode == RcpMode.sva ? Colors.white : null, - fontSize: 12, - ), + labelStyle: Theme.of(context).textTheme.bodySmall!.copyWith( + color: _session.mode == RcpMode.sva ? Colors.white : null, + ), onSelected: (_) => _onModeChanged(RcpMode.sva), visualDensity: VisualDensity.compact, ), @@ -1271,9 +1271,9 @@ class _RcpScreenState extends State { Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), child: SwitchListTile( - title: const Text( + title: Text( 'Parada para ventilaciones (30:2)', - style: TextStyle(fontSize: 14), + style: Theme.of(context).textTheme.bodyLarge, ), value: _session.ventilationEnabled, onChanged: _onVentilationChanged, diff --git a/lib/features/respiratory_rate/presentation/respiratory_rate_screen.dart b/lib/features/respiratory_rate/presentation/respiratory_rate_screen.dart index 03bd1ca..ad403ce 100644 --- a/lib/features/respiratory_rate/presentation/respiratory_rate_screen.dart +++ b/lib/features/respiratory_rate/presentation/respiratory_rate_screen.dart @@ -148,6 +148,7 @@ class _RespiratoryRateScreenState extends State label: bannerLabel, subtitle: bannerSubtitle, color: color, + severityLevel: analysis?.severity.level, ), toolBody: GestureDetector( onTapDown: _onPressStart, @@ -176,30 +177,34 @@ class _RespiratoryRateScreenState extends State if (_isInspiring) Text( 'Inspirando... ${(_inspMs / 1000).toStringAsFixed(1)}s', - style: const TextStyle( - fontSize: 18, - fontWeight: FontWeight.w600, - color: AppColors.soporteVital, - ), + style: Theme.of(context).textTheme.titleLarge!.copyWith( + fontWeight: FontWeight.w600, + color: AppColors.soporteVital, + ), ) else if (_isRunning) Text( 'Espirando...', - style: TextStyle( - fontSize: 18, - color: AppColors.signosValores.withValues(alpha: 0.7), - ), + style: Theme.of(context).textTheme.titleLarge!.copyWith( + color: AppColors.signosValores.withValues(alpha: 0.7), + ), ) else - const Text( + Text( 'Manten pulsado para empezar', - style: TextStyle(fontSize: 18, color: Colors.grey), + style: Theme.of(context) + .textTheme + .titleLarge! + .copyWith(color: Colors.grey), ), const SizedBox(height: 8), - const Text( + Text( 'Pulsa mientras el paciente inspira\ny suelta cuando espire', textAlign: TextAlign.center, - style: TextStyle(fontSize: 13, color: Colors.grey), + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith(color: Colors.grey), ), ], ), diff --git a/lib/features/splash/presentation/splash_screen.dart b/lib/features/splash/presentation/splash_screen.dart index 2bbd336..bbcd908 100644 --- a/lib/features/splash/presentation/splash_screen.dart +++ b/lib/features/splash/presentation/splash_screen.dart @@ -102,14 +102,13 @@ class _SplashScreenState extends State ), const SizedBox(height: 32), // App name - const Text( + Text( 'EmerKit', - style: TextStyle( - fontSize: 36, - fontWeight: FontWeight.bold, - color: Colors.white, - letterSpacing: 1, - ), + style: Theme.of(context).textTheme.displayMedium!.copyWith( + fontWeight: FontWeight.bold, + color: Colors.white, + letterSpacing: 1, + ), ), const SizedBox(height: 8), Container( @@ -120,13 +119,12 @@ class _SplashScreenState extends State color: AppColors.accent.withValues(alpha: 0.5)), borderRadius: BorderRadius.circular(20), ), - child: const Text( + child: Text( 'Herramientas para profesionales sanitarios', - style: TextStyle( - fontSize: 12, - color: Colors.white70, - letterSpacing: 0.5, - ), + style: Theme.of(context).textTheme.bodySmall!.copyWith( + color: Colors.white70, + letterSpacing: 0.5, + ), ), ), const SizedBox(height: 60), @@ -145,8 +143,7 @@ class _SplashScreenState extends State children: [ Text( 'Desarrollado por', - style: TextStyle( - fontSize: 11, + style: Theme.of(context).textTheme.labelSmall!.copyWith( color: Colors.white.withValues(alpha: 0.4)), ), const SizedBox(height: 4), @@ -159,11 +156,13 @@ class _SplashScreenState extends State const SizedBox(width: 6), Text( 'Global Emergency', - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - color: Colors.white.withValues(alpha: 0.7), - ), + style: Theme.of(context) + .textTheme + .bodyLarge! + .copyWith( + fontWeight: FontWeight.w600, + color: Colors.white.withValues(alpha: 0.7), + ), ), ], ), diff --git a/lib/features/tep/presentation/tep_screen.dart b/lib/features/tep/presentation/tep_screen.dart index 01eead2..ddfd35c 100644 --- a/lib/features/tep/presentation/tep_screen.dart +++ b/lib/features/tep/presentation/tep_screen.dart @@ -62,6 +62,7 @@ class _TepScreenState extends State { ? 'Sin alteraciones' : '${result.abnormalCount} lado${result.abnormalCount > 1 ? 's' : ''} alterado${result.abnormalCount > 1 ? 's' : ''}', color: result.severity.level.color, + severityLevel: result.severity.level, ) : null, toolBody: ListView.builder( @@ -81,13 +82,17 @@ class _TepScreenState extends State { Icon(_icons[index], color: AppColors.primary), const SizedBox(width: 8), Text(side.title, - style: const TextStyle( - fontSize: 16, fontWeight: FontWeight.bold)), + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith(fontWeight: FontWeight.bold)), ]), const SizedBox(height: 4), Text(side.description, - style: - const TextStyle(fontSize: 12, color: Colors.grey)), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Colors.grey)), const SizedBox(height: 12), Row(children: [ Expanded( diff --git a/lib/features/triage/presentation/triage_screen.dart b/lib/features/triage/presentation/triage_screen.dart index c046256..4fce898 100644 --- a/lib/features/triage/presentation/triage_screen.dart +++ b/lib/features/triage/presentation/triage_screen.dart @@ -100,7 +100,10 @@ class _TriageScreenState extends State { Text( _currentNode.question, textAlign: TextAlign.center, - style: const TextStyle(fontSize: 22, fontWeight: FontWeight.bold), + style: Theme.of(context) + .textTheme + .headlineMedium! + .copyWith(fontWeight: FontWeight.bold), ), const SizedBox(height: 40), Row( @@ -112,8 +115,11 @@ class _TriageScreenState extends State { style: FilledButton.styleFrom( backgroundColor: AppColors.severityMild), onPressed: () => _answer(true), - child: const Text('SI', - style: TextStyle(fontSize: 20, color: Colors.white)), + child: Text('SI', + style: Theme.of(context) + .textTheme + .headlineSmall! + .copyWith(color: Colors.white)), ), ), ), @@ -125,8 +131,11 @@ class _TriageScreenState extends State { style: FilledButton.styleFrom( backgroundColor: AppColors.severitySevere), onPressed: () => _answer(false), - child: const Text('NO', - style: TextStyle(fontSize: 20, color: Colors.white)), + child: Text('NO', + style: Theme.of(context) + .textTheme + .headlineSmall! + .copyWith(color: Colors.white)), ), ), ), @@ -190,17 +199,18 @@ class _TriageScreenState extends State { const SizedBox(height: 24), Text( label, - style: TextStyle( - fontSize: 28, - fontWeight: FontWeight.bold, - color: color == AppColors.triageYellow ? Colors.black87 : color, - ), + style: Theme.of(context).textTheme.displaySmall!.copyWith( + fontWeight: FontWeight.bold, + color: color == AppColors.triageYellow + ? Colors.black87 + : color, + ), ), const SizedBox(height: 16), Text( description, textAlign: TextAlign.center, - style: const TextStyle(fontSize: 16), + style: Theme.of(context).textTheme.titleMedium, ), const SizedBox(height: 32), FilledButton.icon( diff --git a/lib/features/vendajes/presentation/vendajes_screen.dart b/lib/features/vendajes/presentation/vendajes_screen.dart index e528d40..a24ff32 100644 --- a/lib/features/vendajes/presentation/vendajes_screen.dart +++ b/lib/features/vendajes/presentation/vendajes_screen.dart @@ -103,7 +103,10 @@ class VendajesScreen extends StatelessWidget { title: Text(v.name, style: const TextStyle(fontWeight: FontWeight.bold)), subtitle: Text(v.indication, - style: const TextStyle(fontSize: 12, color: Colors.grey)), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Colors.grey)), children: [ if (v.imagePath != null) Padding( @@ -120,8 +123,8 @@ class VendajesScreen extends StatelessWidget { ), Padding( padding: const EdgeInsets.fromLTRB(16, 0, 16, 16), - child: - Text(v.technique, style: const TextStyle(fontSize: 14)), + child: Text(v.technique, + style: Theme.of(context).textTheme.bodyLarge), ), ], ), diff --git a/lib/features/vital_signs/presentation/vital_signs_screen.dart b/lib/features/vital_signs/presentation/vital_signs_screen.dart index e11261e..34573da 100644 --- a/lib/features/vital_signs/presentation/vital_signs_screen.dart +++ b/lib/features/vital_signs/presentation/vital_signs_screen.dart @@ -84,8 +84,10 @@ class VitalSignsScreen extends StatelessWidget { const SizedBox(width: 8), Expanded( child: Text(g.name, - style: const TextStyle( - fontSize: 16, fontWeight: FontWeight.bold)), + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith(fontWeight: FontWeight.bold)), ), ], ), @@ -94,13 +96,17 @@ class VitalSignsScreen extends StatelessWidget { spacing: 8, runSpacing: 8, children: [ - _buildVitalChip('FC', g.fc, 'lpm', Colors.red), - _buildVitalChip('FR', g.fr, 'rpm', Colors.blue), - _buildVitalChip('TAS', g.tas, 'mmHg', Colors.orange), + _buildVitalChip(context, 'FC', g.fc, 'lpm', Colors.red), _buildVitalChip( - 'TAD', g.tad, 'mmHg', Colors.orange.shade700), - _buildVitalChip('SpO₂', g.spo2, '', Colors.cyan), - _buildVitalChip('Tª', g.temp, '', Colors.purple), + context, 'FR', g.fr, 'rpm', Colors.blue), + _buildVitalChip( + context, 'TAS', g.tas, 'mmHg', Colors.orange), + _buildVitalChip(context, 'TAD', g.tad, 'mmHg', + Colors.orange.shade700), + _buildVitalChip( + context, 'SpO₂', g.spo2, '', Colors.cyan), + _buildVitalChip( + context, 'Tª', g.temp, '', Colors.purple), ], ), ], @@ -113,7 +119,8 @@ class VitalSignsScreen extends StatelessWidget { ); } - Widget _buildVitalChip(String label, String value, String unit, Color color) { + Widget _buildVitalChip(BuildContext context, String label, String value, + String unit, Color color) { return Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8), decoration: BoxDecoration( @@ -125,15 +132,22 @@ class VitalSignsScreen extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ Text(label, - style: TextStyle( - fontSize: 11, color: color, fontWeight: FontWeight.bold)), + style: Theme.of(context) + .textTheme + .labelSmall! + .copyWith(color: color, fontWeight: FontWeight.bold)), const SizedBox(height: 2), Text(value, - style: - const TextStyle(fontSize: 14, fontWeight: FontWeight.w600)), + style: Theme.of(context) + .textTheme + .bodyLarge! + .copyWith(fontWeight: FontWeight.w600)), if (unit.isNotEmpty) Text(unit, - style: const TextStyle(fontSize: 10, color: Colors.grey)), + style: Theme.of(context) + .textTheme + .labelSmall! + .copyWith(color: Colors.grey)), ], ), ); diff --git a/lib/features/wallace/presentation/wallace_screen.dart b/lib/features/wallace/presentation/wallace_screen.dart index ac0506e..d5205a0 100644 --- a/lib/features/wallace/presentation/wallace_screen.dart +++ b/lib/features/wallace/presentation/wallace_screen.dart @@ -88,6 +88,7 @@ class _WallaceScreenState extends State { label: result.severity.label, subtitle: subtitle, color: color, + severityLevel: result.severity.level, ), toolBody: ListView( padding: const EdgeInsets.only(bottom: 24), @@ -105,11 +106,12 @@ class _WallaceScreenState extends State { label: Text(WallaceData.ageGroups[i]), selected: _selectedAge == i, selectedColor: AppColors.valoracion, - labelStyle: TextStyle( - color: _selectedAge == i ? Colors.white : null, - fontWeight: _selectedAge == i ? FontWeight.bold : null, - fontSize: 13, - ), + labelStyle: + Theme.of(context).textTheme.bodyMedium!.copyWith( + color: _selectedAge == i ? Colors.white : null, + fontWeight: + _selectedAge == i ? FontWeight.bold : null, + ), onSelected: (_) => setState(() => _selectedAge = i), ), ); @@ -198,11 +200,10 @@ class _WallaceScreenState extends State { ? 'SCQ inferior al umbral de reposicion hidrica ' '(${_selectedAge > 0 ? "10" : "20"}%)' : 'Introduce el peso para calcular la reposicion hidrica', - style: TextStyle( - fontSize: 13, - color: Colors.grey[600], - fontStyle: FontStyle.italic, - ), + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + color: Colors.grey[600], + fontStyle: FontStyle.italic, + ), ), ), ], @@ -253,16 +254,16 @@ class _WallaceScreenState extends State { color: AppColors.severityModerate.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(6), ), - child: const Row( + child: Row( children: [ - Icon(Icons.info_outline, + const Icon(Icons.info_outline, size: 16, color: AppColors.severityModerate), - SizedBox(width: 6), + const SizedBox(width: 6), Expanded( child: Text( 'Ritmos iniciales. Titular segun diuresis. ' 'Fluido: Ringer Lactato.', - style: TextStyle(fontSize: 11), + style: Theme.of(context).textTheme.labelSmall, ), ), ], @@ -280,13 +281,12 @@ class _WallaceScreenState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text(label, style: const TextStyle(fontSize: 13)), + Text(label, style: Theme.of(context).textTheme.bodyMedium), Text( value, - style: const TextStyle( - fontSize: 13, - fontWeight: FontWeight.bold, - ), + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + fontWeight: FontWeight.bold, + ), ), ], ), diff --git a/lib/shared/presentation/theme/app_colors.dart b/lib/shared/presentation/theme/app_colors.dart index 24a5968..39cdf0e 100644 --- a/lib/shared/presentation/theme/app_colors.dart +++ b/lib/shared/presentation/theme/app_colors.dart @@ -34,4 +34,10 @@ class AppColors { // Backgrounds static const surfaceLight = Color(0xFFF1F5F9); // Slate 100 static const surfaceDark = Color(0xFF0F172A); // Slate 900 + + // Text colors with WCAG AA contrast (>= 4.5:1 on white) + static const textPrimary = Color(0xFF1A1A1A); // ~16:1 + static const textSecondary = Color(0xFF4A4A4A); // ~8:1 + static const textTertiary = Color(0xFF6B6B6B); // ~5:1 + static const textOnDarkSecondary = Color(0xFFB0B0B0); // ~5:1 on dark } diff --git a/lib/shared/presentation/theme/app_theme.dart b/lib/shared/presentation/theme/app_theme.dart index 097b968..65e6590 100644 --- a/lib/shared/presentation/theme/app_theme.dart +++ b/lib/shared/presentation/theme/app_theme.dart @@ -4,11 +4,100 @@ import 'app_colors.dart'; class AppTheme { AppTheme._(); + static const _textThemeLight = TextTheme( + displayLarge: TextStyle( + fontSize: 40, + fontWeight: FontWeight.bold, + color: AppColors.textPrimary), + displayMedium: TextStyle( + fontSize: 36, + fontWeight: FontWeight.bold, + color: AppColors.textPrimary), + displaySmall: TextStyle( + fontSize: 28, + fontWeight: FontWeight.bold, + color: AppColors.textPrimary), + headlineLarge: TextStyle( + fontSize: 24, + fontWeight: FontWeight.w600, + color: AppColors.textPrimary), + headlineMedium: TextStyle( + fontSize: 22, + fontWeight: FontWeight.w600, + color: AppColors.textPrimary), + headlineSmall: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w600, + color: AppColors.textPrimary), + titleLarge: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + color: AppColors.textPrimary), + titleMedium: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: AppColors.textPrimary), + titleSmall: TextStyle( + fontSize: 15, + fontWeight: FontWeight.w600, + color: AppColors.textPrimary), + bodyLarge: TextStyle(fontSize: 14, color: AppColors.textPrimary), + bodyMedium: TextStyle(fontSize: 13, color: AppColors.textSecondary), + bodySmall: TextStyle(fontSize: 12, color: AppColors.textSecondary), + labelLarge: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + color: AppColors.textPrimary), + labelMedium: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w500, + color: AppColors.textSecondary), + labelSmall: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: AppColors.textSecondary), + ); + + static const _textThemeDark = TextTheme( + displayLarge: TextStyle( + fontSize: 40, fontWeight: FontWeight.bold, color: Colors.white), + displayMedium: TextStyle( + fontSize: 36, fontWeight: FontWeight.bold, color: Colors.white), + displaySmall: TextStyle( + fontSize: 28, fontWeight: FontWeight.bold, color: Colors.white), + headlineLarge: TextStyle( + fontSize: 24, fontWeight: FontWeight.w600, color: Colors.white), + headlineMedium: TextStyle( + fontSize: 22, fontWeight: FontWeight.w600, color: Colors.white), + headlineSmall: TextStyle( + fontSize: 20, fontWeight: FontWeight.w600, color: Colors.white), + titleLarge: TextStyle( + fontSize: 18, fontWeight: FontWeight.w600, color: Colors.white), + titleMedium: TextStyle( + fontSize: 16, fontWeight: FontWeight.w500, color: Colors.white), + titleSmall: TextStyle( + fontSize: 15, fontWeight: FontWeight.w600, color: Colors.white), + bodyLarge: TextStyle(fontSize: 14, color: Colors.white), + bodyMedium: TextStyle(fontSize: 13, color: AppColors.textOnDarkSecondary), + bodySmall: TextStyle(fontSize: 12, color: AppColors.textOnDarkSecondary), + labelLarge: TextStyle( + fontSize: 14, fontWeight: FontWeight.w600, color: Colors.white), + labelMedium: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w500, + color: AppColors.textOnDarkSecondary), + labelSmall: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: AppColors.textOnDarkSecondary), + ); + static final light = ThemeData( useMaterial3: true, brightness: Brightness.light, colorSchemeSeed: AppColors.primary, scaffoldBackgroundColor: AppColors.surfaceLight, + textTheme: _textThemeLight, appBarTheme: const AppBarTheme( centerTitle: true, elevation: 0, @@ -43,6 +132,7 @@ class AppTheme { brightness: Brightness.dark, colorSchemeSeed: AppColors.primary, scaffoldBackgroundColor: AppColors.surfaceDark, + textTheme: _textThemeDark, appBarTheme: const AppBarTheme( centerTitle: true, elevation: 0, diff --git a/lib/shared/presentation/widgets/action_log_viewer.dart b/lib/shared/presentation/widgets/action_log_viewer.dart index 38f3750..5a545a8 100644 --- a/lib/shared/presentation/widgets/action_log_viewer.dart +++ b/lib/shared/presentation/widgets/action_log_viewer.dart @@ -105,27 +105,25 @@ class _ActionLogViewerState extends State { ), Text( '$clockHh:$clockMm:$clockSs', - style: TextStyle( - fontSize: 11, - color: Colors.grey.shade600, - fontFamily: 'monospace', - ), + style: Theme.of(context).textTheme.labelSmall!.copyWith( + color: Colors.grey.shade600, + fontFamily: 'monospace', + ), ), const SizedBox(width: 4), Text( '+$relMm:$relSs', - style: TextStyle( - fontSize: 11, - fontWeight: FontWeight.w600, - color: color, - fontFamily: 'monospace', - ), + style: Theme.of(context).textTheme.labelSmall!.copyWith( + fontWeight: FontWeight.w600, + color: color, + fontFamily: 'monospace', + ), ), const SizedBox(width: 8), Expanded( child: Text( entry.action, - style: const TextStyle(fontSize: 12), + style: Theme.of(context).textTheme.bodySmall, ), ), ], diff --git a/lib/shared/presentation/widgets/info_bottom_sheet.dart b/lib/shared/presentation/widgets/info_bottom_sheet.dart index 22ea313..b8122f1 100644 --- a/lib/shared/presentation/widgets/info_bottom_sheet.dart +++ b/lib/shared/presentation/widgets/info_bottom_sheet.dart @@ -41,9 +41,7 @@ void showInfoSheet( Icon(Icons.menu_book, color: Theme.of(context).colorScheme.primary, size: 22), const SizedBox(width: 8), - Text(title, - style: const TextStyle( - fontSize: 18, fontWeight: FontWeight.bold)), + Text(title, style: Theme.of(context).textTheme.titleLarge), const Spacer(), IconButton( icon: const Icon(Icons.close, size: 20), diff --git a/lib/shared/presentation/widgets/info_card.dart b/lib/shared/presentation/widgets/info_card.dart index b9c83e7..31f6711 100644 --- a/lib/shared/presentation/widgets/info_card.dart +++ b/lib/shared/presentation/widgets/info_card.dart @@ -23,10 +23,16 @@ class InfoCard extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(title, - style: TextStyle( - fontSize: 15, fontWeight: FontWeight.bold, color: color)), + style: Theme.of(context) + .textTheme + .titleSmall! + .copyWith(color: color)), const SizedBox(height: 8), - Text(content, style: const TextStyle(fontSize: 13, height: 1.5)), + Text(content, + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith(height: 1.5)), ], ), ), diff --git a/lib/shared/presentation/widgets/medication_alert_card.dart b/lib/shared/presentation/widgets/medication_alert_card.dart index 3b14aac..177c99f 100644 --- a/lib/shared/presentation/widgets/medication_alert_card.dart +++ b/lib/shared/presentation/widgets/medication_alert_card.dart @@ -61,15 +61,16 @@ class MedicationAlertCard extends StatelessWidget { children: [ Text( medication.name, - style: const TextStyle( - fontWeight: FontWeight.bold, - fontSize: 14, - ), + style: Theme.of(context).textTheme.bodyLarge!.copyWith( + fontWeight: FontWeight.bold, + ), ), const SizedBox(height: 2), Text( medication.dose, - style: TextStyle(fontSize: 12, color: Colors.grey.shade700), + style: Theme.of(context).textTheme.bodySmall!.copyWith( + color: Colors.grey.shade700, + ), ), const SizedBox(height: 4), Row( @@ -79,19 +80,19 @@ class MedicationAlertCard extends StatelessWidget { const SizedBox(width: 4), Text( _formatDuration(timeSince), - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w600, - fontFamily: 'monospace', - color: border, - ), + style: + Theme.of(context).textTheme.bodySmall!.copyWith( + fontWeight: FontWeight.w600, + fontFamily: 'monospace', + color: border, + ), ), const SizedBox(width: 12), ], Text( 'Dosis: ${tracker.dosesGiven}' '${medication.maxDoses != null ? '/${medication.maxDoses}' : ''}', - style: const TextStyle(fontSize: 11), + style: Theme.of(context).textTheme.labelSmall, ), ], ), @@ -110,7 +111,11 @@ class MedicationAlertCard extends StatelessWidget { minimumSize: Size.zero, tapTargetSize: MaterialTapTargetSize.shrinkWrap, ), - child: const Text('Administrar', style: TextStyle(fontSize: 12)), + child: Text('Administrar', + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Colors.white)), ), ], ), @@ -135,30 +140,36 @@ class MedicationAlertCard extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - Text( - medication.name, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 14, - color: Colors.grey.shade600, - ), - ), + Builder(builder: (context) { + return Text( + medication.name, + style: Theme.of(context).textTheme.bodyLarge!.copyWith( + fontWeight: FontWeight.bold, + color: Colors.grey.shade600, + ), + ); + }), const SizedBox(height: 2), - Text( - medication.dose, - style: TextStyle(fontSize: 12, color: Colors.grey.shade500), - ), + Builder(builder: (context) { + return Text( + medication.dose, + style: Theme.of(context).textTheme.bodySmall!.copyWith( + color: Colors.grey.shade500, + ), + ); + }), ], ), ), - Text( - 'Maximo alcanzado', - style: TextStyle( - fontSize: 12, - fontStyle: FontStyle.italic, - color: Colors.grey.shade600, - ), - ), + Builder(builder: (context) { + return Text( + 'Maximo alcanzado', + style: Theme.of(context).textTheme.bodySmall!.copyWith( + fontStyle: FontStyle.italic, + color: Colors.grey.shade600, + ), + ); + }), ], ), ), diff --git a/lib/shared/presentation/widgets/result_banner.dart b/lib/shared/presentation/widgets/result_banner.dart index 1d8544e..284f6c2 100644 --- a/lib/shared/presentation/widgets/result_banner.dart +++ b/lib/shared/presentation/widgets/result_banner.dart @@ -1,12 +1,15 @@ import 'package:flutter/material.dart'; +import 'package:emerkit/shared/domain/entities/severity.dart'; /// Banner de resultado que se muestra siempre en la parte superior de cada herramienta. /// Muestra un valor grande, una etiqueta y opcionalmente un subtítulo. +/// Opcionalmente muestra un icono de severidad para accesibilidad (daltonismo). class ResultBanner extends StatelessWidget { final String value; final String label; final String? subtitle; final Color color; + final SeverityLevel? severityLevel; const ResultBanner({ super.key, @@ -14,10 +17,26 @@ class ResultBanner extends StatelessWidget { required this.label, this.subtitle, required this.color, + this.severityLevel, }); + IconData? get _severityIcon { + switch (severityLevel) { + case SeverityLevel.mild: + return Icons.check_circle_outline; + case SeverityLevel.moderate: + return Icons.warning_amber_rounded; + case SeverityLevel.severe: + return Icons.error_outline; + case null: + return null; + } + } + @override Widget build(BuildContext context) { + final tt = Theme.of(context).textTheme; + final icon = _severityIcon; return Container( width: double.infinity, padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 20), @@ -26,13 +45,20 @@ class ResultBanner extends StatelessWidget { children: [ Text( value, - style: TextStyle( - fontSize: 40, fontWeight: FontWeight.bold, color: color), + style: tt.displayLarge!.copyWith(color: color), ), - Text( - label, - style: TextStyle( - fontSize: 15, fontWeight: FontWeight.w600, color: color), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (icon != null) ...[ + Icon(icon, size: 18, color: color), + const SizedBox(width: 4), + ], + Text( + label, + style: tt.titleSmall!.copyWith(color: color), + ), + ], ), if (subtitle != null) Padding( @@ -40,8 +66,9 @@ class ResultBanner extends StatelessWidget { child: Text( subtitle!, textAlign: TextAlign.center, - style: TextStyle( - fontSize: 12, color: color.withValues(alpha: 0.7)), + style: tt.bodySmall!.copyWith( + color: color.withValues(alpha: 0.7), + ), ), ), ], diff --git a/lib/shared/presentation/widgets/scored_item_selector.dart b/lib/shared/presentation/widgets/scored_item_selector.dart index 6836317..ec3ec5f 100644 --- a/lib/shared/presentation/widgets/scored_item_selector.dart +++ b/lib/shared/presentation/widgets/scored_item_selector.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import '../../domain/entities/scored_item.dart'; class ScoredItemSelector extends StatelessWidget { @@ -33,9 +34,7 @@ class ScoredItemSelector extends StatelessWidget { children: [ Icon(icon, size: 20, color: color), const SizedBox(width: 8), - Text(title, - style: const TextStyle( - fontSize: 15, fontWeight: FontWeight.bold)), + Text(title, style: Theme.of(context).textTheme.titleSmall), ], ), ), @@ -50,7 +49,7 @@ class ScoredItemSelector extends StatelessWidget { fontWeight: isSelected ? FontWeight.bold : null)), subtitle: item.description != null ? Text(item.description!, - style: const TextStyle(fontSize: 11)) + style: Theme.of(context).textTheme.labelSmall) : null, trailing: Container( width: 32, @@ -68,7 +67,10 @@ class ScoredItemSelector extends StatelessWidget { ), ), ), - onTap: () => onChanged(item.score), + onTap: () { + HapticFeedback.selectionClick(); + onChanged(item.score); + }, ); }), ], diff --git a/lib/shared/presentation/widgets/screen_info_helper.dart b/lib/shared/presentation/widgets/screen_info_helper.dart index e6794e9..e1f2252 100644 --- a/lib/shared/presentation/widgets/screen_info_helper.dart +++ b/lib/shared/presentation/widgets/screen_info_helper.dart @@ -49,8 +49,7 @@ void showScreenInfo(BuildContext context, String title, List children) { Expanded( child: Text( title, - style: const TextStyle( - fontSize: 18, fontWeight: FontWeight.bold), + style: Theme.of(context).textTheme.titleLarge, ), ), IconButton( @@ -86,11 +85,17 @@ Widget buildInfoCard(String title, String body) { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text(title, - style: - const TextStyle(fontSize: 15, fontWeight: FontWeight.bold)), + Builder(builder: (context) { + return Text(title, style: Theme.of(context).textTheme.titleSmall); + }), const SizedBox(height: 8), - Text(body, style: const TextStyle(fontSize: 13, height: 1.5)), + Builder(builder: (context) { + return Text(body, + style: Theme.of(context) + .textTheme + .bodyMedium + ?.copyWith(height: 1.5)); + }), ], ), ), @@ -106,35 +111,41 @@ Widget buildReferencesCard(List references) { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Row( - children: [ - Icon(Icons.library_books, size: 18, color: Colors.grey), - SizedBox(width: 8), - Text('Referencias', - style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold)), - ], - ), - const SizedBox(height: 8), - ...references.map( - (ref) => Padding( - padding: const EdgeInsets.only(bottom: 6), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Text('• ', style: TextStyle(fontSize: 13)), - Expanded( - child: Text( - ref, - style: const TextStyle( - fontSize: 12, - fontStyle: FontStyle.italic, - height: 1.4), + Builder(builder: (context) { + final tt = Theme.of(context).textTheme; + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + const Icon(Icons.library_books, + size: 18, color: Colors.grey), + const SizedBox(width: 8), + Text('Referencias', style: tt.titleSmall), + ], + ), + const SizedBox(height: 8), + ...references.map( + (ref) => Padding( + padding: const EdgeInsets.only(bottom: 6), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('\u2022 ', style: tt.bodyMedium), + Expanded( + child: Text( + ref, + style: tt.bodySmall?.copyWith( + fontStyle: FontStyle.italic, height: 1.4), + ), + ), + ], ), ), - ], - ), - ), - ), + ), + ], + ); + }), ], ), ), diff --git a/lib/shared/presentation/widgets/section_header.dart b/lib/shared/presentation/widgets/section_header.dart index 7889d33..1374829 100644 --- a/lib/shared/presentation/widgets/section_header.dart +++ b/lib/shared/presentation/widgets/section_header.dart @@ -27,12 +27,11 @@ class SectionHeader extends StatelessWidget { const SizedBox(width: 10), Text( title, - style: TextStyle( - fontSize: 15, - fontWeight: FontWeight.w700, - color: color, - letterSpacing: 0.3, - ), + style: Theme.of(context).textTheme.titleSmall!.copyWith( + color: color, + fontWeight: FontWeight.w700, + letterSpacing: 0.3, + ), ), ], ), diff --git a/lib/shared/presentation/widgets/tool_card.dart b/lib/shared/presentation/widgets/tool_card.dart index 813b610..55c01fe 100644 --- a/lib/shared/presentation/widgets/tool_card.dart +++ b/lib/shared/presentation/widgets/tool_card.dart @@ -23,56 +23,63 @@ class ToolCard extends StatelessWidget { clipBehavior: Clip.antiAlias, child: InkWell( onTap: onTap, - child: Container( - decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topLeft, - end: Alignment.bottomRight, - colors: [ - color.withValues(alpha: isDark ? 0.25 : 0.08), - color.withValues(alpha: isDark ? 0.1 : 0.02), - ], - ), - ), - padding: const EdgeInsets.all(8), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - Stack( + child: LayoutBuilder( + builder: (context, constraints) { + final cardWidth = constraints.maxWidth; + final iconSize = (cardWidth * 0.28).clamp(24.0, 40.0); + final iconPadding = (cardWidth * 0.08).clamp(8.0, 14.0); + final externalIconSize = (cardWidth * 0.1).clamp(10.0, 16.0); + return Container( + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [ + color.withValues(alpha: isDark ? 0.25 : 0.08), + color.withValues(alpha: isDark ? 0.1 : 0.02), + ], + ), + ), + padding: const EdgeInsets.all(8), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, children: [ - Container( - padding: const EdgeInsets.all(10), - decoration: BoxDecoration( - color: color.withValues(alpha: 0.15), - shape: BoxShape.circle, - ), - child: Icon(icon, size: 26, color: color), + Stack( + children: [ + Container( + padding: EdgeInsets.all(iconPadding), + decoration: BoxDecoration( + color: color.withValues(alpha: 0.15), + shape: BoxShape.circle, + ), + child: Icon(icon, size: iconSize, color: color), + ), + if (isExternal) + Positioned( + right: 0, + bottom: 0, + child: Icon(Icons.open_in_new, + size: externalIconSize, color: color), + ), + ], ), - if (isExternal) - Positioned( - right: 0, - bottom: 0, - child: Icon(Icons.open_in_new, size: 12, color: color), + const SizedBox(height: 6), + Flexible( + child: Text( + title, + textAlign: TextAlign.center, + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: Theme.of(context).textTheme.labelSmall!.copyWith( + color: isDark ? Colors.white : Colors.black87, + ), ), - ], - ), - const SizedBox(height: 6), - Flexible( - child: Text( - title, - textAlign: TextAlign.center, - maxLines: 2, - overflow: TextOverflow.ellipsis, - style: TextStyle( - fontSize: 11, - fontWeight: FontWeight.w600, - color: isDark ? Colors.white : Colors.black87, ), - ), + ], ), - ], - ), + ); + }, ), ), ); diff --git a/lib/shared/presentation/widgets/tool_screen_base.dart b/lib/shared/presentation/widgets/tool_screen_base.dart index 5fceb2b..8630f40 100644 --- a/lib/shared/presentation/widgets/tool_screen_base.dart +++ b/lib/shared/presentation/widgets/tool_screen_base.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'info_bottom_sheet.dart'; /// Widget base para todas las herramientas interactivas de la app. @@ -25,6 +26,33 @@ class ToolScreenBase extends StatelessWidget { this.extraActions, }); + void _confirmReset(BuildContext context) { + HapticFeedback.mediumImpact(); + showDialog( + context: context, + builder: (ctx) => AlertDialog( + title: const Text('Reiniciar'), + content: const Text( + '\u00bfDescartar todos los valores y empezar de nuevo?', + ), + actions: [ + TextButton( + onPressed: () => Navigator.pop(ctx), + child: const Text('Cancelar'), + ), + FilledButton( + onPressed: () { + Navigator.pop(ctx); + onReset!(); + HapticFeedback.lightImpact(); + }, + child: const Text('Reiniciar'), + ), + ], + ), + ); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -40,9 +68,10 @@ class ToolScreenBase extends StatelessWidget { ), if (onReset != null) IconButton( - icon: const Icon(Icons.refresh), - tooltip: 'Reiniciar', - onPressed: onReset), + icon: const Icon(Icons.refresh), + tooltip: 'Reiniciar', + onPressed: () => _confirmReset(context), + ), ], ), body: SafeArea( @@ -57,7 +86,9 @@ class ToolScreenBase extends StatelessWidget { child: Text( emptyResultText, textAlign: TextAlign.center, - style: TextStyle(fontSize: 14, color: Colors.grey.shade500), + style: Theme.of(context).textTheme.bodyLarge!.copyWith( + color: Colors.grey.shade500, + ), ), ), Expanded(child: toolBody), diff --git a/pubspec.yaml b/pubspec.yaml index 922bc8c..43ebee2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: emerkit description: EmerKit - Herramientas clinicas para profesionales de emergencias publish_to: 'none' -version: 0.1.11+111 +version: 0.1.12+112 environment: sdk: ^3.5.0 diff --git a/version.json b/version.json index c5c880d..f7ce931 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version": "0.1.11"} +{"version": "0.1.12"}