a lightweight, interval-based utility to combat digital strain through "Ma" (intentional pauses) for the eyes and body.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(ui): add accessible labels and color contrast

+ expand unit labelks
+ improve IntervalCard spacing

+147 -106
+147 -106
ui/settings.slint
··· 69 69 70 70 height: 28px; 71 71 min-width: 80px; 72 + accessible-role: spinbox; 73 + accessible-label: root.field-label; 74 + accessible-value: "\{root.value}"; 75 + accessible-value-minimum: root.minimum; 76 + accessible-value-maximum: root.maximum; 72 77 73 78 Rectangle { 74 79 border-radius: 6px; ··· 80 85 HorizontalLayout { 81 86 btn-minus := TouchArea { 82 87 width: 26px; 88 + accessible-role: button; 89 + accessible-label: "Decrease " + root.field-label; 83 90 clicked => { 84 91 if root.value > root.minimum { 85 92 root.value = root.value - 1; ··· 124 131 125 132 btn-plus := TouchArea { 126 133 width: 26px; 134 + accessible-role: button; 135 + accessible-label: "Increase " + root.field-label; 127 136 clicked => { 128 137 if root.value < root.maximum { 129 138 root.value = root.value + 1; ··· 255 264 callback break-secs-changed(int); 256 265 callback label-changed(string); 257 266 258 - height: 58px; 267 + height: 82px; 259 268 260 269 Rectangle { 261 270 border-radius: 8px; ··· 263 272 border-width: 1px; 264 273 border-color: #2320281A; 265 274 266 - HorizontalLayout { 267 - padding: 12px; 275 + VerticalLayout { 268 276 padding-left: 16px; 269 - padding-right: 16px; 270 - spacing: 12px; 271 - alignment: center; 277 + padding-right: 12px; 278 + padding-top: 10px; 279 + padding-bottom: 10px; 280 + spacing: 6px; 272 281 273 - Text { 274 - text: root.index; 275 - font-size: 18px; 276 - color: #8A9A82; 277 - width: 22px; 278 - horizontal-alignment: center; 279 - vertical-alignment: center; 280 - } 282 + // Row 1 — work interval 283 + HorizontalLayout { 284 + spacing: 8px; 285 + alignment: start; 281 286 282 - Text { 283 - text: "every"; 284 - font-size: 12px; 285 - color: #23202880; 286 - vertical-alignment: center; 287 - } 287 + Text { 288 + text: root.index; 289 + font-size: 16px; 290 + color: #5A7055; 291 + width: 20px; 292 + horizontal-alignment: center; 293 + vertical-alignment: center; 294 + } 288 295 289 - NumberField { 290 - width: 84px; 291 - value: root.work-mins; 292 - minimum: 1; 293 - maximum: 240; 294 - field-label: "work interval minutes"; 295 - edited(v) => { 296 - root.work-mins-changed(v); 296 + Text { 297 + text: "every"; 298 + font-size: 12px; 299 + color: #232028AA; 300 + vertical-alignment: center; 297 301 } 298 - } 299 302 300 - Text { 301 - text: "min · pause"; 302 - font-size: 12px; 303 - color: #23202880; 304 - vertical-alignment: center; 305 - } 303 + NumberField { 304 + width: 84px; 305 + value: root.work-mins; 306 + minimum: 1; 307 + maximum: 240; 308 + field-label: "work interval minutes"; 309 + edited(v) => { 310 + root.work-mins-changed(v); 311 + } 312 + } 306 313 307 - NumberField { 308 - width: 76px; 309 - value: root.break-mins; 310 - minimum: 0; 311 - maximum: 120; 312 - field-label: "break minutes"; 313 - edited(v) => { 314 - root.break-mins-changed(v); 314 + Text { 315 + text: "min"; 316 + font-size: 12px; 317 + color: #232028AA; 318 + vertical-alignment: center; 315 319 } 316 320 } 317 321 318 - Text { 319 - text: "m"; 320 - font-size: 12px; 321 - color: #23202880; 322 - vertical-alignment: center; 323 - } 322 + // Row 2 — break duration + label 323 + HorizontalLayout { 324 + spacing: 8px; 325 + alignment: start; 326 + 327 + Rectangle { width: 28px; } 324 328 325 - NumberField { 326 - width: 76px; 327 - value: root.break-secs; 328 - minimum: 0; 329 - maximum: 59; 330 - field-label: "break seconds"; 331 - edited(v) => { 332 - root.break-secs-changed(v); 329 + Text { 330 + text: "pause"; 331 + font-size: 12px; 332 + color: #232028AA; 333 + vertical-alignment: center; 333 334 } 334 - } 335 335 336 - Text { 337 - text: "s"; 338 - font-size: 12px; 339 - color: #23202880; 340 - vertical-alignment: center; 341 - } 336 + NumberField { 337 + width: 76px; 338 + value: root.break-mins; 339 + minimum: 0; 340 + maximum: 120; 341 + field-label: "break minutes"; 342 + edited(v) => { 343 + root.break-mins-changed(v); 344 + } 345 + } 342 346 343 - LineEdit { 344 - width: 120px; 345 - height: 28px; 346 - placeholder-text: "label"; 347 - text: root.label; 348 - edited(v) => { 349 - root.label-changed(v); 347 + Text { 348 + text: "min"; 349 + font-size: 12px; 350 + color: #232028AA; 351 + vertical-alignment: center; 350 352 } 351 - } 352 353 353 - // Spacer 354 - Rectangle { 355 - horizontal-stretch: 1; 356 - } 354 + NumberField { 355 + width: 76px; 356 + value: root.break-secs; 357 + minimum: 0; 358 + maximum: 59; 359 + field-label: "break seconds"; 360 + edited(v) => { 361 + root.break-secs-changed(v); 362 + } 363 + } 357 364 358 - // Remove button 359 - ta-rm := TouchArea { 360 - width: 36px; 361 - height: 36px; 362 - clicked => { 363 - root.remove-clicked(); 365 + Text { 366 + text: "sec"; 367 + font-size: 12px; 368 + color: #232028AA; 369 + vertical-alignment: center; 364 370 } 365 371 366 372 Text { 367 - text: "×"; 368 - font-size: 16px; 369 - color: ta-rm.has-hover ? #232028 : #23202860; 370 - horizontal-alignment: center; 373 + text: "·"; 374 + font-size: 12px; 375 + color: #23202888; 371 376 vertical-alignment: center; 372 - animate color { duration: 120ms; } 377 + } 378 + 379 + LineEdit { 380 + width: 120px; 381 + height: 28px; 382 + placeholder-text: "label"; 383 + text: root.label; 384 + edited(v) => { 385 + root.label-changed(v); 386 + } 387 + } 388 + 389 + Rectangle { horizontal-stretch: 1; } 390 + 391 + ta-rm := TouchArea { 392 + width: 28px; 393 + height: 28px; 394 + accessible-role: button; 395 + accessible-label: "Remove interval"; 396 + clicked => { 397 + root.remove-clicked(); 398 + } 399 + 400 + Text { 401 + text: "×"; 402 + font-size: 15px; 403 + color: ta-rm.has-hover ? #232028 : #232028AA; 404 + horizontal-alignment: center; 405 + vertical-alignment: center; 406 + animate color { duration: 120ms; } 407 + } 373 408 } 374 409 } 375 410 } ··· 398 433 text: root.text; 399 434 font-size: 13px; 400 435 font-weight: root.active ? 600 : 400; 401 - color: root.active ? #232028 : #23202888; 436 + color: root.active ? #232028 : #232028AA; 402 437 horizontal-alignment: left; 403 438 vertical-alignment: center; 404 439 } ··· 586 621 Text { 587 622 text: "The cadence ioma follows today."; 588 623 font-size: 11.5px; 589 - color: #23202880; 624 + color: #232028AA; 590 625 } 591 626 } 592 627 ··· 654 689 Text { 655 690 text: "Full-screen break. Emergency unlock requires a password."; 656 691 font-size: 11.5px; 657 - color: #23202880; 692 + color: #232028AA; 658 693 } 659 694 } 660 695 ··· 699 734 Text { 700 735 text: "If you've stepped away, ioma waits."; 701 736 font-size: 11.5px; 702 - color: #23202880; 737 + color: #232028AA; 703 738 } 704 739 } 705 740 ··· 720 755 Text { 721 756 text: "threshold"; 722 757 font-size: 12px; 723 - color: #23202880; 758 + color: #232028AA; 724 759 vertical-alignment: center; 725 760 } 726 761 ··· 730 765 value <=> root.idle-threshold-mins; 731 766 minimum: 1; 732 767 maximum: 60; 768 + accessible-label: "Idle threshold minutes"; 733 769 } 734 770 735 771 Text { 736 772 text: "minutes"; 737 773 font-size: 12px; 738 - color: #23202880; 774 + color: #232028AA; 739 775 vertical-alignment: center; 740 776 } 741 777 } ··· 761 797 Text { 762 798 text: "A single, gentle tone."; 763 799 font-size: 11.5px; 764 - color: #23202880; 800 + color: #232028AA; 765 801 } 766 802 } 767 803 ··· 782 818 Text { 783 819 text: "volume"; 784 820 font-size: 12px; 785 - color: #23202880; 821 + color: #232028AA; 786 822 vertical-alignment: center; 787 823 } 788 824 ··· 827 863 828 864 // Interaction 829 865 TouchArea { 866 + accessible-role: slider; 867 + accessible-label: "Volume"; 868 + accessible-value: "\{Math.round(root.sound-volume * 100)}%"; 869 + accessible-value-minimum: 0; 870 + accessible-value-maximum: 100; 830 871 moved => { 831 872 if self.pressed { 832 873 root.sound-volume = max(0.0, min(1.0, self.mouse-x / parent.width)); ··· 862 903 Text { 863 904 text: "ioma starts quietly at login."; 864 905 font-size: 11.5px; 865 - color: #23202880; 906 + color: #232028AA; 866 907 } 867 908 } 868 909 ··· 910 951 Text { 911 952 text: "Each row is an interval. ioma cycles through them in order."; 912 953 font-size: 11.5px; 913 - color: #23202880; 954 + color: #232028AA; 914 955 } 915 956 916 957 Rectangle { ··· 1025 1066 Text { 1026 1067 text: "A longer pause after several cycles."; 1027 1068 font-size: 11.5px; 1028 - color: #23202880; 1069 + color: #232028AA; 1029 1070 } 1030 1071 } 1031 1072 ··· 1054 1095 Text { 1055 1096 text: "after"; 1056 1097 font-size: 12.5px; 1057 - color: #23202880; 1098 + color: #232028AA; 1058 1099 vertical-alignment: center; 1059 1100 } 1060 1101 ··· 1069 1110 Text { 1070 1111 text: "cycles, take"; 1071 1112 font-size: 12.5px; 1072 - color: #23202880; 1113 + color: #232028AA; 1073 1114 vertical-alignment: center; 1074 1115 } 1075 1116 ··· 1084 1125 Text { 1085 1126 text: "min"; 1086 1127 font-size: 12.5px; 1087 - color: #23202880; 1128 + color: #232028AA; 1088 1129 vertical-alignment: center; 1089 1130 } 1090 1131 1091 1132 Text { 1092 1133 text: "—"; 1093 1134 font-size: 12.5px; 1094 - color: #23202860; 1135 + color: #23202888; 1095 1136 vertical-alignment: center; 1096 1137 } 1097 1138 ··· 1114 1155 Text { 1115 1156 text: "Reset after"; 1116 1157 font-size: 11.5px; 1117 - color: #23202880; 1158 + color: #232028AA; 1118 1159 vertical-alignment: center; 1119 1160 } 1120 1161 ··· 1129 1170 Text { 1130 1171 text: "min away."; 1131 1172 font-size: 11.5px; 1132 - color: #23202880; 1173 + color: #232028AA; 1133 1174 vertical-alignment: center; 1134 1175 } 1135 1176 } ··· 1221 1262 Text { 1222 1263 text: "v0.4.2 · the space between"; 1223 1264 font-size: 12px; 1224 - color: #23202880; 1265 + color: #232028AA; 1225 1266 horizontal-alignment: center; 1226 1267 } 1227 1268 ··· 1232 1273 Text { 1233 1274 text: "間 (ma) is the Japanese notion of the pause between —\nthe rest in music, the silence between words.\nioma gives that pause back to your eyes and body."; 1234 1275 font-size: 12.5px; 1235 - color: #23202880; 1276 + color: #232028AA; 1236 1277 horizontal-alignment: center; 1237 1278 vertical-alignment: center; 1238 1279 wrap: word-wrap;