066-wallet-color-scheme.rst (18384B)
1 DD 66: Wallet UI Color Scheme 2 ============================= 3 4 Summary 5 ------- 6 7 This design document defines the unified color scheme for the GNU Taler Wallet, based on the Material Design 3 color system. It provides semantic color roles used across the wallet UI for consistency, accessibility, and maintainability. 8 9 The document outlines the purpose and application of each color role in the UI design system. 10 11 Motivation 12 ---------- 13 14 The wallet UI currently lacks a consistent and documented color strategy. As the application grows and adds more features, visual coherence and accessibility become increasingly important. 15 16 By adopting Material 3 semantics and defining roles like ``primary``, ``onPrimary``, ``success``, ``errorContainer``, etc., the UI gains: 17 18 - Consistent appearance across features 19 - Easier onboarding for new contributors 20 21 Requirements 22 ------------ 23 24 - Colors must be defined semantically, not by hex codes directly in UI components. 25 - The theme must support both light and dark modes. 26 - Roles must maintain WCAG 2.1 AA contrast ratios. 27 - Roles must cover error, warning, and success states. 28 29 Proposed solution 30 ----------------- 31 32 The color system will be structured using semantic **Material 3 color roles**. Each role is explained below with its usage and associated hex values. 33 34 General concepts 35 ~~~~~~~~~~~~~~~~ 36 37 - **Primary / Secondary / Tertiary**: Accent colors used to emphasize UI elements. 38 - **Container**: A lighter or darker version of an accent color used for background fills (e.g. buttons, chips). 39 - **On \***: A foreground color (text/icon) to be placed on top of its paired color. 40 - **Surface / Background**: Base UI areas or layout surfaces. 41 - **Outline**: Used for strokes, borders, and dividers. 42 - **Error / Warning / Success**: Semantic feedback colors. 43 - **Dark \***: Role variants used in dark mode. 44 45 Color role definitions 46 ~~~~~~~~~~~~~~~~~~~~~~ 47 48 Primary 49 ^^^^^^^ 50 51 Used for the most important UI elements. 52 53 .. list-table:: 54 :widths: 20 30 50 55 :header-rows: 1 56 57 * - Role 58 - Hex 59 - Usage 60 61 * - primary 62 - .. raw:: html 63 64 <code>#0042b3</code> <div style="display:inline-block;width:14px;height:14px; 65 background:#0042b3;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 66 - Main action color (e.g. filled buttons, tabs, icons) 67 68 * - onPrimary 69 - .. raw:: html 70 71 <code>#ffffff</code> <div style="display:inline-block;width:14px;height:14px; 72 background:#ffffff;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 73 - Text/icons placed on top of ``primary`` 74 75 * - primaryContainer 76 - .. raw:: html 77 78 <code>#d3deff</code> <div style="display:inline-block;width:14px;height:14px; 79 background:#d3deff;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 80 - Background for FABs, cards, filled fields 81 82 * - onPrimaryContainer 83 - .. raw:: html 84 85 <code>#00134a</code> <div style="display:inline-block;width:14px;height:14px; 86 background:#00134a;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 87 - Foreground for ``primaryContainer`` 88 89 * - darkPrimary 90 - .. raw:: html 91 92 <code>#b4c5ff</code> <div style="display:inline-block;width:14px;height:14px; 93 background:#b4c5ff;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 94 - ``primary`` in dark mode 95 96 * - darkOnPrimary 97 - .. raw:: html 98 99 <code>#002a78</code> <div style="display:inline-block;width:14px;height:14px; 100 background:#002a78;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 101 - Text/icons on ``darkPrimary`` 102 103 * - darkPrimaryContainer 104 - .. raw:: html 105 106 <code>#0042b3</code> <div style="display:inline-block;width:14px;height:14px; 107 background:#0042b3;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 108 - Container in dark mode 109 110 * - darkOnPrimaryContainer 111 - .. raw:: html 112 113 <code>#e5ebff</code> <div style="display:inline-block;width:14px;height:14px; 114 background:#e5ebff;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 115 - Foreground on container in dark 116 117 118 119 Secondary 120 ^^^^^^^^^ 121 122 Used for less prominent or supporting elements. 123 124 .. list-table:: 125 :widths: 20 30 50 126 :header-rows: 1 127 128 * - Role 129 - Hex 130 - Usage 131 132 * - secondary 133 - .. raw:: html 134 135 <code>#586a88</code> <div style="display:inline-block;width:14px;height:14px; 136 background:#586a88;border:1px solid #aaa;margin-left:6px; 137 vertical-align:middle;"></div> 138 - Secondary buttons, chips, and passive UI states 139 140 * - onSecondary 141 - .. raw:: html 142 143 <code>#ffffff</code> <div style="display:inline-block;width:14px;height:14px; 144 background:#ffffff;border:1px solid #aaa;margin-left:6px; 145 vertical-align:middle;"></div> 146 - Foreground on ``secondary`` 147 148 * - secondaryContainer 149 - .. raw:: html 150 151 <code>#d9e3f9</code> <div style="display:inline-block;width:14px;height:14px; 152 background:#d9e3f9;border:1px solid #aaa;margin-left:6px; 153 vertical-align:middle;"></div> 154 - Background for secondary surfaces 155 156 * - onSecondaryContainer 157 - .. raw:: html 158 159 <code>#111c2b</code> <div style="display:inline-block;width:14px;height:14px; 160 background:#111c2b;border:1px solid #aaa;margin-left:6px; 161 vertical-align:middle;"></div> 162 - Foreground on ``secondaryContainer`` 163 164 * - darkSecondary 165 - .. raw:: html 166 167 <code>#a4c9ff</code> <div style="display:inline-block;width:14px;height:14px; 168 background:#a4c9ff;border:1px solid #aaa;margin-left:6px; 169 vertical-align:middle;"></div> 170 - Secondary color in dark mode 171 172 * - darkOnSecondary 173 - .. raw:: html 174 175 <code>#00315d</code> <div style="display:inline-block;width:14px;height:14px; 176 background:#00315d;border:1px solid #aaa;margin-left:6px; 177 vertical-align:middle;"></div> 178 - Foreground in dark mode 179 180 * - darkSecondaryContainer 181 - .. raw:: html 182 183 <code>#72a3e5</code> <div style="display:inline-block;width:14px;height:14px; 184 background:#72a3e5;border:1px solid #aaa;margin-left:6px; 185 vertical-align:middle;"></div> 186 - Background container in dark 187 188 * - darkOnSecondaryContainer 189 - .. raw:: html 190 191 <code>#003869</code> <div style="display:inline-block;width:14px;height:14px; 192 background:#003869;border:1px solid #aaa;margin-left:6px; 193 vertical-align:middle;"></div> 194 - Foreground for container in dark 195 196 197 198 199 200 Tertiary 201 ^^^^^^^^ 202 203 Used for accents, badges, or attention-grabbing components. 204 205 .. list-table:: 206 :widths: 20 30 50 207 :header-rows: 1 208 209 * - Role 210 - Hex 211 - Usage 212 213 * - tertiary 214 - .. raw:: html 215 216 <code>#338af0</code> <div style="display:inline-block;width:14px;height:14px; 217 background:#338af0;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 218 - Used for tags, emphasis markers 219 220 * - onTertiary 221 - .. raw:: html 222 223 <code>#ffffff</code> <div style="display:inline-block;width:14px;height:14px; 224 background:#ffffff;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 225 - Text/icons on ``tertiary`` 226 227 * - tertiaryContainer 228 - .. raw:: html 229 230 <code>#d1e4ff</code> <div style="display:inline-block;width:14px;height:14px; 231 background:#d1e4ff;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 232 - Input field backgrounds, selected indicators 233 234 * - onTertiaryContainer 235 - .. raw:: html 236 237 <code>#001c39</code> <div style="display:inline-block;width:14px;height:14px; 238 background:#001c39;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 239 - Text/icons on ``tertiaryContainer`` 240 241 * - darkTertiary 242 - .. raw:: html 243 244 <code>#8dd1e5</code> <div style="display:inline-block;width:14px;height:14px; 245 background:#8dd1e5;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 246 - Accent color in dark mode 247 248 * - darkOnTertiary 249 - .. raw:: html 250 251 <code>#003641</code> <div style="display:inline-block;width:14px;height:14px; 252 background:#003641;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 253 - Foreground in dark 254 255 * - darkTertiaryContainer 256 - .. raw:: html 257 258 <code>#166577</code> <div style="display:inline-block;width:14px;height:14px; 259 background:#166577;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 260 - Container fill in dark 261 262 * - darkOnTertiaryContainer 263 - .. raw:: html 264 265 <code>#9ce0f5</code> <div style="display:inline-block;width:14px;height:14px; 266 background:#9ce0f5;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 267 - Text/icons on dark container 268 269 270 Error 271 ^^^^^ 272 273 .. list-table:: 274 :widths: 20 30 50 275 :header-rows: 1 276 277 * - Role 278 - Hex 279 - Usage 280 281 * - error 282 - .. raw:: html 283 284 <code>#b3261e</code> <div style="display:inline-block;width:14px;height:14px; 285 background:#b3261e;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 286 - Main error color for messages or outlines 287 288 * - onError 289 - .. raw:: html 290 291 <code>#ffffff</code> <div style="display:inline-block;width:14px;height:14px; 292 background:#ffffff;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 293 - Text/icons on error surfaces 294 295 * - errorContainer 296 - .. raw:: html 297 298 <code>#f9dedc</code> <div style="display:inline-block;width:14px;height:14px; 299 background:#f9dedc;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 300 - Background fill for error components 301 302 * - onErrorContainer 303 - .. raw:: html 304 305 <code>#410e0b</code> <div style="display:inline-block;width:14px;height:14px; 306 background:#410e0b;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 307 - Text/icons on error container 308 309 * - darkError 310 - .. raw:: html 311 312 <code>#ffb4aa</code> <div style="display:inline-block;width:14px;height:14px; 313 background:#ffb4aa;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 314 - Error color in dark mode 315 316 * - darkOnError 317 - .. raw:: html 318 319 <code>#690003</code> <div style="display:inline-block;width:14px;height:14px; 320 background:#690003;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 321 - Foreground in dark mode 322 323 * - darkErrorContainer 324 - .. raw:: html 325 326 <code>#b3261e</code> <div style="display:inline-block;width:14px;height:14px; 327 background:#b3261e;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 328 - Background container in dark 329 330 * - darkOnErrorContainer 331 - .. raw:: html 332 333 <code>#ffcbc4</code> <div style="display:inline-block;width:14px;height:14px; 334 background:#ffcbc4;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 335 - Foreground on dark container 336 337 338 Success 339 ^^^^^^^ 340 341 .. list-table:: 342 :widths: 20 30 50 343 :header-rows: 1 344 345 * - Role 346 - Hex 347 - Usage 348 349 * - success 350 - .. raw:: html 351 352 <code>#337a40</code> <div style="display:inline-block;width:14px;height:14px; 353 background:#337a40;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 354 - Status indicators, confirmation icons 355 356 * - onSuccess 357 - .. raw:: html 358 359 <code>#ffffff</code> <div style="display:inline-block;width:14px;height:14px; 360 background:#ffffff;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 361 - Foreground on success 362 363 * - successContainer 364 - .. raw:: html 365 366 <code>#2e8534</code> <div style="display:inline-block;width:14px;height:14px; 367 background:#2e8534;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 368 - Background for success banners or chips 369 370 * - onSuccessContainer 371 - .. raw:: html 372 373 <code>#f7fff1</code> <div style="display:inline-block;width:14px;height:14px; 374 background:#f7fff1;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 375 - Text/icons on success container 376 377 * - darkSuccess 378 - .. raw:: html 379 380 <code>#337a40</code> <div style="display:inline-block;width:14px;height:14px; 381 background:#337a40;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 382 - Same in dark mode (stable tone) 383 384 * - darkOnSuccess 385 - .. raw:: html 386 387 <code>#ffffff</code> <div style="display:inline-block;width:14px;height:14px; 388 background:#ffffff;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 389 - Foreground for dark mode 390 391 * - darkSuccessContainer 392 - .. raw:: html 393 394 <code>#1d3522</code> <div style="display:inline-block;width:14px;height:14px; 395 background:#1d3522;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 396 - Background container in dark 397 398 * - darkOnSuccessContainer 399 - .. raw:: html 400 401 <code>#eaf6ec</code> <div style="display:inline-block;width:14px;height:14px; 402 background:#eaf6ec;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 403 - Text/icons on dark container 404 405 406 Warning 407 ^^^^^^^ 408 409 .. list-table:: 410 :widths: 20 30 50 411 :header-rows: 1 412 413 * - Role 414 - Hex 415 - Usage 416 417 * - warning 418 - .. raw:: html 419 420 <code>#f99c06</code> <div style="display:inline-block;width:14px;height:14px; 421 background:#f99c06;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 422 - Alert banners, passive warnings 423 424 * - onWarning 425 - .. raw:: html 426 427 <code>#000000</code> <div style="display:inline-block;width:14px;height:14px; 428 background:#000000;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 429 - Foreground text on warning 430 431 * - warningContainer 432 - .. raw:: html 433 434 <code>#fdedd3</code> <div style="display:inline-block;width:14px;height:14px; 435 background:#fdedd3;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 436 - Background fill for warning containers 437 438 * - onWarningContainer 439 - .. raw:: html 440 441 <code>#6b4706</code> <div style="display:inline-block;width:14px;height:14px; 442 background:#6b4706;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 443 - Foreground on warning container 444 445 * - darkWarning 446 - .. raw:: html 447 448 <code>#f99c06</code> <div style="display:inline-block;width:14px;height:14px; 449 background:#f99c06;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 450 - Warning in dark mode 451 452 * - darkOnWarning 453 - .. raw:: html 454 455 <code>#000000</code> <div style="display:inline-block;width:14px;height:14px; 456 background:#000000;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 457 - Foreground in dark 458 459 * - darkWarningContainer 460 - .. raw:: html 461 462 <code>#664200</code> <div style="display:inline-block;width:14px;height:14px; 463 background:#664200;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 464 - Background in dark 465 466 * - darkOnWarningContainer 467 - .. raw:: html 468 469 <code>#fdedd3</code> <div style="display:inline-block;width:14px;height:14px; 470 background:#fdedd3;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 471 - Foreground on container in dark 472 473 474 Background 475 ^^^^^^^^^^ 476 477 .. list-table:: 478 :widths: 20 30 50 479 :header-rows: 1 480 481 * - Role 482 - Hex 483 - Usage 484 485 * - background 486 - .. raw:: html 487 488 <code>#fdfdff</code> <div style="display:inline-block;width:14px;height:14px; 489 background:#fdfdff;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 490 - App-wide background color 491 492 * - onBackground 493 - .. raw:: html 494 495 <code>#1a1c1f</code> <div style="display:inline-block;width:14px;height:14px; 496 background:#1a1c1f;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 497 - Foreground text/icons on background 498 499 * - darkBackground 500 - .. raw:: html 501 502 <code>#11131a</code> <div style="display:inline-block;width:14px;height:14px; 503 background:#11131a;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 504 - Background in dark mode 505 506 * - darkOnBackground 507 - .. raw:: html 508 509 <code>#e2e2eb</code> <div style="display:inline-block;width:14px;height:14px; 510 background:#e2e2eb;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 511 - Text/icons in dark mode background 512 513 514 Outline 515 ^^^^^^^ 516 517 .. list-table:: 518 :widths: 20 30 50 519 :header-rows: 1 520 521 * - Role 522 - Hex 523 - Usage 524 525 * - outline 526 - .. raw:: html 527 528 <code>#767880</code> <div style="display:inline-block;width:14px;height:14px; 529 background:#767880;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 530 - Used for input borders, field outlines 531 532 * - outlineVariant 533 - .. raw:: html 534 535 <code>#c4c6d0</code> <div style="display:inline-block;width:14px;height:14px; 536 background:#c4c6d0;border:1px solid #aaa;margin-left:6px;vertical-align:middle;"></div> 537 - Decorative borders, dividers 538 539 540 541 Definition of Done 542 ------------------ 543 544 - Theming system supports all defined roles 545 - All components use semantic color tokens 546 - Tokens switch correctly in light/dark mode 547 - WCAG 2.1 AA contrast verified 548 - Color role documentation added to developer onboarding 549 - Feature flag enables color system switch before full rollout 550 551 Alternatives 552 ------------ 553 554 - Use raw hex codes per component (violates consistency and accessibility) 555 - Derive from OS/system color settings (limits branding control) 556 557 Drawbacks 558 --------- 559 560 - To be fully and correctly implemented, all ui screeens must be updated with references to the new color roles. 561 - Might requires UI refactor to override system styles 562 - Slight learning curve for developers unfamiliar with semantic roles 563 564 Discussion / Q&A 565 ---------------- 566 567 568