Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Cristiang1021/ErgoKawsay/llms.txt

Use this file to discover all available pages before exploring further.

ErgoKawsay’s theming system is built on Flutter Material 3. Rather than relying solely on ColorScheme, the app introduces a custom AppPalette theme extension that provides a complete, named color palette for both light and dark modes. Widgets access palette tokens directly from the BuildContext extension rather than through generic Theme.of(context).colorScheme lookups.

Color Palette

AppPalette extends ThemeExtension<AppPalette> and is an @immutable value class. It carries every color token the UI needs. Two static constants — AppPalette.light and AppPalette.dark — are the only values ever instantiated at runtime.

Core tokens

TokenLight modeDark modeUsage
canvas#FFFFFF#0D0D0DScaffold background
surface1#FFFFFF#0D0D0DCard surface
surface2#F4F7EC#1A1C14Chip, secondary surface
ink#0D0D0D#F0EDE6Primary text
inkMuted#5C5C52#8A8A82Secondary / caption text
hairline#D6DBC8#282A20Dividers, border lines
hairlineSoft#ECF0E4#1A1C14Subtle dividers
accent#97BF06#97BF06Brand green — active states, progress
primaryBtnBg#030A8C#4D5FC0Primary CTA background
primaryBtnFg#FFFFFF#FFFFFFPrimary CTA text
success#4A6800#97BF06Success states
error#C0230A#FF4835Error states

Accessing the palette

A BuildContext extension makes palette access ergonomic throughout the codebase:
import 'package:ergokawsay/core/theme/app_palette.dart';

// In any widget build method:
final palette = context.palette;

Container(color: palette.accent)         // brand green
Text('Hello', style: TextStyle(color: palette.ink))
ElevatedButton(
  style: ElevatedButton.styleFrom(backgroundColor: palette.primaryBtnBg),
  // ...
)
If the extension is somehow absent from the theme (should not happen in production), context.palette falls back to AppPalette.light.

AppTheme

AppTheme is a private-constructor utility class exposing two ThemeData getters:
MaterialApp(
  theme:     AppTheme.lightTheme,
  darkTheme:  AppTheme.darkTheme,
  themeMode:  themeController.themeMode,
)
Both are built by the private AppTheme._build(AppPalette p) factory, which configures:
ComponentWhat is configured
colorSchemeprimary = primaryBtnBg, secondary = accent, surface = surface1, error = error
appBarThemeTransparent elevation, canvas background, system overlay style matches brightness
cardThemeZero elevation, surface1 color, radiusLg (24 dp) corners
sliderThemeActive track = accent, thumb = primaryBtnBg, inactive track = surface2
switchThemeSelected track = primaryBtnBg, selected thumb = white, unselected = hairline/inkMuted
chipThemeBackground = surface2, selected = blockLime, label style = AppTypography.caption, pill shape
snackBarThemeBackground = ink, text = canvas, floating behavior, radiusMd corners
progressIndicatorThemeColor = accent (brand green)
AppTheme._build also sets useMaterial3: true, fontFamily: 'Inter', scaffoldBackgroundColor: p.canvas, and registers the palette as a ThemeExtension. A custom AppScrollBehavior (extends MaterialScrollBehavior) removes the Android overscroll stretch/glow effect and applies ClampingScrollPhysics globally.

Typography

AppTypography provides static factory methods for every text style used in the app. All styles use Inter via google_fonts, with runtime fetching disabled to ensure the app works fully offline:
GoogleFonts.config.allowRuntimeFetching = false;
MethodSizeWeightUsage
displayXl(p)48 sp400Hero numbers
displayLg(p)40 sp400Large displays
displayMd(p)28 sp600Section headers
headline(p)28 sp600Screen titles
subhead(p)24 sp400Sub-titles
cardTitle(p)22 sp700Card headings
bodyLg(p)19 sp400Lead body text
body(p)17 sp400Standard body text
bodySm(p)15 sp400Secondary body text
button(p)17 sp600CTA labels
caption(p)13 sp500Chips, labels
eyebrow(p)12 sp400JetBrains Mono — section eyebrows
micro(p)12 sp400Timestamps, micro labels
timerDisplay(p)56 sp700Active break timer
All style factory methods accept an optional color: override parameter. AppTypography.textTheme(AppPalette) maps these styles to the standard TextTheme slots used by AppTheme._build.

Spacing

AppSpacing provides a base-8pt spacing scale and named border-radius constants used throughout the codebase:
ConstantValueUsage
radiusXs2 dpTight radius
radiusSm6 dpSmall cards
radiusMd8 dpSnack bar, modal sheets
radiusLg24 dpCards, main containers
radiusXl32 dpLarge containers
radiusPill50 dpChips, pill buttons
radiusFull9999 dpFully circular

Color Blocks

AppPalette includes 7 semantic color blocks used by SpotlightCard variants. Each block has a paired text color verified for WCAG AA compliance (≥ 4.5:1 contrast ratio):
Block tokenLight bgText tokenContrast
blockLime#E8F5A8blockLimeText #182E0013:1
blockMint#C8E488blockMintText #08240011:1
blockLilac#DCE4FFblockLilacText #030A8C14:1
blockPink#BFC8FFblockPinkText #030A8C11:1
blockCream#EDE8C8blockCreamText #2A200412:1
blockCoral#EDE0A0blockCoralText #26190A12:1
blockNavy#030A8CblockNavyText #E8EEFF15:1
Dark-mode block values use much deeper shades of the same hue families (e.g., blockLime becomes #243600) with correspondingly lighter text tokens to maintain WCAG AA ratios on dark backgrounds. The SpotlightVariant enum (teal, violet, magenta, orange, coral, warm) maps to block/text token pairs via AppPalette.blockForVariant() and AppPalette.blockTextForVariant().

Colorblind Filter

When AccessibilitySettings.colorBlind == true, the root of the app wraps the entire widget tree in a ColorFiltered widget using a deuteranopia simulation matrix:
ColorFiltered(
  colorFilter: ColorFilter.matrix([
    0.625, 0.375, 0,   0, 0,
    0.700, 0.300, 0,   0, 0,
    0,     0.300, 0.7, 0, 0,
    0,     0,     0,   1, 0,
  ]),
  child: child,
)
This matrix simulates deuteranopia (green-deficiency) and is toggled via the Modo daltónico / Ñawi tullpu rikuy switch in Settings.

ThemeController

ThemeController(StorageService) is a ChangeNotifier that manages themeMode. It is provided at the root widget tree via Provider.
// Read current theme mode
final mode = context.watch<ThemeController>().themeMode;

// Persist and apply a new theme mode
context.read<ThemeController>().setThemeMode(ThemeMode.dark);
setThemeMode() writes the new value to StorageService and calls notifyListeners(), which causes MaterialApp’s themeMode parameter to rebuild with the new value.

Build docs developers (and LLMs) love