Skip to main content

max / balanced_breakfast

Prune dead CSS and consolidate duplicated rules Same three passes GoingsOn just had. Dead: 25 classes across 36 rules that no markup referenced, including the entire card system (11 classes, never used once) and five unused button variants. Verified by set diff that only the targeted names went. Type: 63 font-size declarations snapped onto the 10-step scale this file defines and then almost never used, 6 token uses against 64 literals. 51 were already on-scale and only changed to token form; 12 shifted, none by more than 0.05rem. Rules: one focus treatment now covers every field kind and both focus states, replacing six identical rules scattered across the sheet, and the form label rule is stated once instead of three times. Held back deliberately: the layout and text primitives this sheet ships but never calls (stack-*, row-flex-*, mb-*, flex-1, text-sm). They are dead today and adopted in the unification pass, so deleting them now would only be churn. Classes 213 -> 188, rules 365 -> 331.
Author: Max Johnson <me@maxj.phd> · 2026-07-28 20:49 UTC
Signed with PGP, not checked
Commit: 577927c52c5410f1af14fa26b3aca68f309be061
Parent: 2d9dfc2
1 file changed, +34 insertions, -224 deletions
@@ -296,7 +296,7 @@
296 296 }
297 297
298 298 .header h1 {
299 - font-size: 1.25rem;
299 + font-size: var(--font-size-2xl);
300 300 font-weight: 700;
301 301 color: var(--action);
302 302 letter-spacing: -0.5px;
@@ -315,7 +315,7 @@
315 315 background-color: var(--surface-page);
316 316 color: var(--content);
317 317 width: 180px;
318 - font-size: 0.875rem;
318 + font-size: var(--font-size-base);
319 319 box-shadow: var(--bevel-inset);
320 320 }
321 321
@@ -336,11 +336,6 @@
336 336 }
337 337
338 338 .search-input::placeholder { color: var(--content-muted); }
339 - .search-input:focus {
340 - outline: none;
341 - border-color: var(--category-four);
342 - box-shadow: var(--bevel-inset), 0 0 0 2px var(--category-four);
343 - }
344 339
345 340 .sort-select {
346 341 padding: var(--gap-peer) var(--gap-group);
@@ -349,7 +344,7 @@
349 344 background-color: var(--surface-page);
350 345 color: var(--content);
351 346 cursor: pointer;
352 - font-size: 0.875rem;
347 + font-size: var(--font-size-base);
353 348 box-shadow: var(--bevel-inset);
354 349 }
355 350 .sort-select:focus { outline: none; border-color: var(--category-four); }
@@ -368,7 +363,7 @@
368 363
369 364 .sidebar h2 {
370 365 padding: var(--gap-peer) var(--gap-group);
371 - font-size: 0.75rem;
366 + font-size: var(--font-size-sm);
372 367 font-weight: 700;
373 368 color: var(--content-muted);
374 369 text-transform: uppercase;
@@ -444,7 +439,7 @@
444 439 opacity: 0.6;
445 440 }
446 441 .empty-state-text {
447 - font-size: 0.9rem;
442 + font-size: var(--font-size-base);
448 443 color: var(--content-secondary);
449 444 margin: 0;
450 445 }
@@ -452,7 +447,7 @@
452 447 padding: var(--gap-pane) var(--gap-group);
453 448 gap: var(--gap-peer);
454 449 }
455 - .empty-state--compact .empty-state-icon { font-size: 1.5rem; }
450 + .empty-state--compact .empty-state-icon { font-size: var(--font-size-3xl); }
456 451
457 452 /* Control stack (star / pin + read dot) passed into renderRow's icon slot.
458 453 The .row layout provides the gap to the content; no margin needed here. */
@@ -467,7 +462,7 @@
467 462 background: none;
468 463 border: none;
469 464 cursor: pointer;
470 - font-size: 1.1rem;
465 + font-size: var(--font-size-xl);
471 466 color: var(--content-muted);
472 467 padding: var(--step-tight) var(--step-snug);
473 468 margin: calc(-1 * var(--step-tight)) calc(-1 * var(--step-snug));
@@ -543,7 +538,7 @@
543 538 .item-detail { padding: var(--gap-group); }
544 539
545 540 .detail-title {
546 - font-size: 1.15rem;
541 + font-size: var(--font-size-xl);
547 542 margin-bottom: var(--gap-section);
548 543 color: var(--content);
549 544 font-weight: 700;
@@ -556,7 +551,7 @@
556 551 gap: var(--gap-peer);
557 552 margin-bottom: var(--gap-peer);
558 553 color: var(--content-secondary);
559 - font-size: 0.8rem;
554 + font-size: var(--font-size-md);
560 555 padding-bottom: var(--gap-section);
561 556 border-bottom: var(--border-width) solid var(--border);
562 557 }
@@ -581,7 +576,7 @@
581 576 color: var(--content);
582 577 cursor: pointer;
583 578 font-weight: 600;
584 - font-size: 0.875rem;
579 + font-size: var(--font-size-base);
585 580 box-shadow: var(--bevel-raised);
586 581 }
587 582 .btn:hover {
@@ -616,18 +611,9 @@
616 611 }
617 612 .btn-success:hover { background-color: var(--accent-yellow-light); border-color: var(--accent-yellow-light); }
618 613 /* .btn-sm: canonical small-button size (see wiki note `bb-design-system`). */
619 - .btn-sm { padding: var(--gap-bound) var(--gap-peer); font-size: 0.8rem; }
614 + .btn-sm { padding: var(--gap-bound) var(--gap-peer); font-size: var(--font-size-md); }
620 615 .btn-sm.active { background: var(--category-four); color: var(--content-on-action); border-color: var(--category-four); }
621 616
622 - /* .btn-secondary: explicit neutral; today's default `.btn` already plays this
623 - role, but having a named modifier lets future surfaces declare intent. */
624 - .btn-secondary {
625 - background-color: var(--surface-overlay);
626 - border-color: var(--border);
627 - color: var(--content);
628 - }
629 - .btn-secondary:hover { background-color: var(--surface-sunken); border-color: var(--border-strong); }
630 -
631 617 /* .btn-danger: destructive action. Consumes the previously-unused
632 618 --accent-red-hover token. Replaces .hp-action-danger in F5. */
633 619 .btn-danger {
@@ -637,151 +623,6 @@
637 623 }
638 624 .btn-danger:hover { background-color: var(--accent-red-hover); border-color: var(--accent-red-hover); }
639 625
640 - /* .btn-icon: square, no padding label space; used for close buttons,
641 - icon-only toolbar buttons (gear, star, more). */
642 - .btn-icon {
643 - padding: var(--gap-bound);
644 - line-height: 1;
645 - min-width: 1.75rem;
646 - min-height: 1.75rem;
647 - display: inline-flex;
648 - align-items: center;
649 - justify-content: center;
650 - }
651 -
652 - /* .btn-text: borderless, no background. Used for inline actions inside
653 - text or as a low-emphasis alternative to .btn-secondary. */
654 - .btn-text {
655 - background: none;
656 - border: none;
657 - padding: var(--gap-bound) var(--gap-peer);
658 - color: var(--content);
659 - box-shadow: none;
660 - }
661 - .btn-text:hover { background-color: var(--surface-overlay); border-color: transparent; }
662 - .btn-text:active { box-shadow: none; }
663 -
664 - /* .btn-link: looks like an anchor, behaves like a button. */
665 - .btn-link {
666 - background: none;
667 - border: none;
668 - padding: 0;
669 - color: var(--action);
670 - font-weight: 600;
671 - text-decoration: underline;
672 - text-underline-offset: 2px;
673 - box-shadow: none;
674 - }
675 - .btn-link:hover { color: var(--action-hover); background: none; border-color: transparent; }
676 - .btn-link:active { box-shadow: none; }
677 -
678 - /* .btn-loading: spinner-replacement state. Pair with disabled attr. */
679 - .btn-loading {
680 - color: transparent !important;
681 - pointer-events: none;
682 - position: relative;
683 - }
684 - .btn-loading::after {
685 - content: '';
686 - position: absolute;
687 - top: 50%; left: 50%;
688 - width: 0.875rem; height: 0.875rem;
689 - margin: -0.4375rem 0 0 -0.4375rem; /* half the spinner, not a gap */
690 - border: 2px solid currentColor; /* spinner ring thickness, not a frame */
691 - border-top-color: transparent;
692 - border-radius: var(--radius-full);
693 - animation: spin 0.6s linear infinite;
694 - color: var(--content);
695 - opacity: 0.6;
696 - }
697 - .btn-primary.btn-loading::after,
698 - .btn-success.btn-loading::after,
699 - .btn-danger.btn-loading::after { color: var(--content-on-action); opacity: 1; }
700 -
701 - /* === N. Card (F2 addition, 2026-06-02) ================================
702 - Canonical: .card. Charter target: F5 collapses .source-item,
703 - .plugin-item, .sidebar-saved, .bookmark-item onto .card with the
704 - modifier variants below.
705 - .card: default: page surface, 1px border, raised bevel
706 - .card--row: row-shaped, no bevel, used in sidebars and lists
707 - .card--shell: frame-only, no fill (for grouping)
708 - .card--muted: secondary-surface variant
709 - .card--clickable: pointer + frame recolor on hover, pressed bevel
710 - Container: .cards-grid for grid layouts.
711 - ========================================================================== */
712 - .card {
713 - background-color: var(--surface-page);
714 - border: var(--border-width) solid var(--border);
715 - border-radius: var(--radius-sm);
716 - padding: var(--gap-group);
717 - box-shadow: var(--bevel-raised);
718 - }
719 - .card--row {
720 - border-radius: 0;
721 - border-left: 0;
722 - border-right: 0;
723 - border-top: 0;
724 - box-shadow: none;
725 - padding: var(--gap-peer) var(--gap-group);
726 - display: flex;
727 - align-items: center;
728 - gap: var(--gap-bound);
729 - }
730 - .card--shell {
731 - background: none;
732 - box-shadow: none;
733 - }
734 - .card--muted {
735 - background-color: var(--surface-overlay);
736 - }
737 - .card--clickable {
738 - cursor: pointer;
739 - }
740 - /* Hover recolors the frame; it does not lift. The lift was the neobrute
741 - signal and the bevel replaces it, so a clickable card that also floated
742 - on hover would read as two objects. */
743 - .card--clickable:hover {
744 - border-color: var(--category-four);
745 - }
746 - .card--clickable:active {
747 - box-shadow: var(--bevel-inset);
748 - }
749 -
750 - .card-header {
751 - display: flex;
752 - justify-content: space-between;
753 - align-items: center;
754 - margin-bottom: var(--gap-peer);
755 - }
756 - .card-title {
757 - font-size: 0.95rem;
758 - font-weight: 700;
759 - color: var(--content);
760 - margin: 0;
761 - }
762 - .card-description {
763 - font-size: 0.85rem;
764 - color: var(--content-secondary);
765 - line-height: 1.4;
766 - }
767 - .card-meta {
768 - display: flex;
769 - flex-wrap: wrap;
770 - gap: var(--gap-peer);
771 - margin-top: var(--gap-peer);
772 - font-size: 0.75rem;
773 - color: var(--content-muted);
774 - }
775 - .card-badge {
776 - flex-shrink: 0;
777 - }
778 -
779 - .cards-grid {
780 - display: grid;
781 - grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
782 - gap: var(--gap-group);
783 - }
784 -
785 626 /* === N. Row primitive (F2-sub addition, 2026-06-02) ===================
786 627 Canonical slot layout: [icon] [primary · badges] [meta] [actions].
787 628 Used via BB.ui.renderRow(model). Per-surface classes (.plugin-item,
@@ -809,7 +650,7 @@
809 650 .row-primary {
810 651 font-weight: 600;
811 652 color: var(--content);
812 - font-size: 0.9rem;
653 + font-size: var(--font-size-base);
813 654 line-height: 1.3;
814 655 display: flex;
815 656 align-items: center;
@@ -817,14 +658,14 @@
817 658 flex-wrap: wrap;
818 659 }
819 660 .row-secondary {
820 - font-size: 0.8rem;
661 + font-size: var(--font-size-md);
821 662 color: var(--content-secondary);
822 663 line-height: 1.4;
823 664 margin-top: var(--step-hair);
824 665 }
825 666 .row-meta {
826 667 flex-shrink: 0;
827 - font-size: 0.75rem;
668 + font-size: var(--font-size-sm);
828 669 color: var(--content-muted);
829 670 align-self: center;
830 671 }
@@ -859,13 +700,6 @@
859 700 add BB.ui.renderFormField helper.
860 701 ========================================================================== */
861 702 .form-group { margin-bottom: var(--gap-section); }
862 - .form-group label {
863 - display: block;
864 - margin-bottom: var(--gap-bound);
865 - color: var(--content-secondary);
866 - font-size: 0.8rem;
867 - font-weight: 700;
868 - }
869 703
870 704 .form-input {
871 705 width: 100%;
@@ -874,25 +708,22 @@
874 708 border-radius: var(--radius-sm);
875 709 background-color: var(--surface-page);
876 710 color: var(--content);
877 - font-size: 0.875rem;
711 + font-size: var(--font-size-base);
878 712 box-shadow: var(--bevel-inset);
879 713 }
880 - .form-input:focus {
881 - outline: none;
882 - border-color: var(--category-four);
883 - box-shadow: var(--bevel-inset), 0 0 0 2px var(--category-four);
884 - }
885 714
886 715 /* F2 additions (2026-06-02): split .form-input into kind-specific
887 716 primitives so visual treatment per kind is targetable. .form-select and
888 717 .form-textarea inherit .form-input today; future surface-specific tweaks
889 718 land on the kind-specific class. .form-label replaces the unclassed
890 719 `<label>` under `.form-group`. */
720 + .form-group label,
721 + .settings-content .form-group label,
891 722 .form-label {
892 723 display: block;
893 724 margin-bottom: var(--gap-bound);
894 725 color: var(--content-secondary);
895 - font-size: 0.8rem;
726 + font-size: var(--font-size-md);
896 727 font-weight: 700;
897 728 }
898 729 .form-select {
@@ -902,15 +733,10 @@
902 733 border-radius: var(--radius-sm);
903 734 background-color: var(--surface-page);
904 735 color: var(--content);
905 - font-size: 0.875rem;
736 + font-size: var(--font-size-base);
906 737 cursor: pointer;
907 738 box-shadow: var(--bevel-inset);
908 739 }
909 - .form-select:focus {
910 - outline: none;
911 - border-color: var(--category-four);
912 - box-shadow: var(--bevel-inset), 0 0 0 2px var(--category-four);
913 - }
914 740 .form-textarea {
915 741 width: 100%;
916 742 padding: var(--gap-peer);
@@ -918,17 +744,12 @@
918 744 border-radius: var(--radius-sm);
919 745 background-color: var(--surface-page);
920 746 color: var(--content);
921 - font-size: 0.875rem;
747 + font-size: var(--font-size-base);
922 748 font-family: inherit;
923 749 resize: vertical;
924 750 min-height: 4rem;
925 751 box-shadow: var(--bevel-inset);
926 752 }
927 - .form-textarea:focus {
928 - outline: none;
929 - border-color: var(--category-four);
930 - box-shadow: var(--bevel-inset), 0 0 0 2px var(--category-four);
931 - }
932 753 /* .form-row: horizontal grouping of two related fields (e.g. label + button) */
933 754 .form-row {
934 755 display: flex;
@@ -944,7 +765,7 @@
944 765 }
945 766
946 767 .form-hint {
947 - font-size: 0.7rem;
768 + font-size: var(--font-size-xs);
948 769 color: var(--content-muted);
949 770 margin-top: var(--gap-bound);
950 771 }
@@ -985,7 +806,7 @@
985 806 background-color: var(--surface-overlay);
986 807 border-radius: var(--radius-lg) var(--radius-lg) 0 0;
987 808 }
988 - .modal-header h2 { font-size: 1.1rem; font-weight: 700; color: var(--content); }
809 + .modal-header h2 { font-size: var(--font-size-xl); font-weight: 700; color: var(--content); }
989 810
990 811 /* F3 (2026-06-02): step indicator for multi-step modal flows (OAuth,
991 812 plugin import, encryption setup). Set via BB.ui.setModalStep(n, of). */
@@ -995,7 +816,7 @@
995 816 background-color: var(--surface-sunken);
996 817 border: var(--border-width) solid var(--border);
997 818 border-radius: var(--radius-xl);
998 - font-size: 0.7rem;
819 + font-size: var(--font-size-xs);
999 820 font-weight: 600;
1000 821 color: var(--content-muted);
1001 822 white-space: nowrap;
@@ -1032,7 +853,7 @@
1032 853 .modal-intro {
1033 854 margin-bottom: var(--gap-section);
1034 855 color: var(--content-secondary);
1035 - font-size: 0.875rem;
856 + font-size: var(--font-size-base);
1036 857 }
1037 858
1038 859 /* F4 additions (2026-06-02): replace inline styles previously hard-coded
@@ -1050,7 +871,7 @@
1050 871 text-align: center;
1051 872 padding: var(--gap-pane) var(--gap-group);
1052 873 color: var(--content-muted);
1053 - font-size: 0.8rem;
874 + font-size: var(--font-size-md);
1054 875 line-height: 1.5;
1055 876 }
1056 877 .source-item--empty:hover { background-color: transparent; }
@@ -1085,7 +906,7 @@
1085 906 /* settings-sync.js pricing fine-print. Class already existed but carried
1086 907 inline styles; rules moved here. */
1087 908 .sync-sub-fine-print {
1088 - font-size: 0.85rem;
909 + font-size: var(--font-size-base);
1089 910 opacity: 0.75;
1090 911 margin-top: var(--gap-bound);
1091 912 }
@@ -1139,18 +960,10 @@
1139 960 box-shadow: var(--bevel-raised), var(--shadow-brutal);
1140 961 animation: slideIn 0.3s ease-out;
1141 962 font-weight: 500;
1142 - font-size: 0.875rem;
963 + font-size: var(--font-size-base);
1143 964 }
1144 965 .toast.success { border-left: 4px solid var(--success); background-color: color-mix(in srgb, var(--success) 8%, var(--surface-page)); }
1145 966 .toast.error { border-left: 4px solid var(--danger); background-color: color-mix(in srgb, var(--danger) 8%, var(--surface-page)); }
1146 -
1147 - /* F2 additions (2026-06-02): parity-named variants. The legacy
1148 - `.toast.success` / `.toast.error` stays during the rename window so
1149 - existing showToast calls keep working; F5 migrates everything to the
1150 - `--variant` form and removes the legacy. */
1151 - .toast-success { border-left: 4px solid var(--success); background-color: color-mix(in srgb, var(--success) 8%, var(--surface-page)); }
1152 - .toast-error { border-left: 4px solid var(--danger); background-color: color-mix(in srgb, var(--danger) 8%, var(--surface-page)); }
1153 - .toast-info { border-left: 4px solid var(--action); background-color: color-mix(in srgb, var(--action) 8%, var(--surface-page)); }
1154 967 .toast-undo {
1155 968 border-left: 4px solid var(--category-four);
1156 969 background-color: color-mix(in srgb, var(--category-four) 10%, var(--surface-page));
@@ -1166,12 +979,12 @@
1166 979 color: var(--content);
1167 980 cursor: pointer;
1168 981 padding: var(--step-tight) var(--step-roomy);
1169 - font-size: 0.8rem;
982 + font-size: var(--font-size-md);
1170 983 font-weight: 600;
1171 984 }
1172 985 .undo-btn:hover { background-color: color-mix(in srgb, var(--category-four) 20%, transparent); }
1173 986 .undo-countdown {
1174 - font-size: 0.7rem;
987 + font-size: var(--font-size-xs);
1175 988 color: var(--content-muted);
1176 989 min-width: 1.5rem;
1177 990 text-align: right;
@@ -1195,7 +1008,7 @@
1195 1008 border: var(--border-width) solid var(--border);
1196 1009 border-radius: var(--radius-sm);
1197 1010 padding: var(--step-hair) var(--step-base);
1198 - font-size: 0.75rem;
1011 + font-size: var(--font-size-sm);
1199 1012 color: var(--content-secondary);
1200 1013 box-shadow: var(--bevel-raised);
1201 1014 }
@@ -1210,7 +1023,7 @@
1210 1023 .tag[data-color="cyan"], .badge[data-color="cyan"] { border-color: var(--category-six); color: var(--category-six); background-color: color-mix(in srgb, var(--category-six) 10%, transparent); }
1211 1024 .tag[data-color="purple"], .badge[data-color="purple"] { border-color: var(--category-five); color: var(--category-five); background-color: color-mix(in srgb, var(--category-five) 10%, transparent); }
1212 1025 .tag[data-color="muted"], .badge[data-color="muted"] { border-color: var(--border); color: var(--content-muted); background-color: var(--surface-sunken); }
1213 - .tag--xs { font-size: 0.6rem; padding: 0 var(--step-snug); } /* mirrors .badge--xs */
1026 + .tag--xs { font-size: var(--font-size-xxs); padding: 0 var(--step-snug); } /* mirrors .badge--xs */
1214 1027
1215 1028 /* .badge: smaller and more compact than .tag; used for counts and inline
1216 1029 status indicators. Same color contract via [data-color]. */
@@ -1222,15 +1035,13 @@
1222 1035 border: var(--border-width) solid var(--border);
1223 1036 border-radius: var(--radius-sm);
1224 1037 padding: 0 var(--step-snug);
1225 - font-size: 0.7rem;
1038 + font-size: var(--font-size-xs);
1226 1039 font-weight: 600;
1227 1040 color: var(--content-secondary);
1228 1041 line-height: 1.3;
1229 1042 white-space: nowrap;
1230 1043 box-shadow: var(--bevel-raised);
1231 1044 }
1232 - .badge--xs { font-size: 0.6rem; padding: 0 var(--step-snug); }
1233 - .badge--pill { border-radius: var(--radius-xl); }
1234 1045 .badge--filled { border: none; box-shadow: none; }
1235 1046 .badge--filled[data-color="green"] { background-color: var(--category-two); color: var(--content-on-action); }
1236 1047 .badge--filled[data-color="yellow"] { background-color: var(--category-four); color: var(--content); }
@@ -1240,7 +1051,7 @@
1240 1051 .detail-body {
1241 1052 color: var(--content);
1242 1053 line-height: 1.7;
1243 - font-size: 0.9rem;
1054 + font-size: var(--font-size-base);
1244 1055 overflow-wrap: break-word;
1245 1056 word-break: break-word;
1246 1057 }
@@ -1284,7 +1095,7 @@
1284 1095 border-radius: var(--radius-sm);
1285 1096 background: none;
1286 1097 color: var(--content);
1287 - font-size: 0.825rem;
1098 + font-size: var(--font-size-md);
1288 1099 text-align: left;
1289 1100 cursor: pointer;
1290 1101 }
@@ -1364,7 +1175,6 @@
1364 1175 animation: shimmer 1.5s infinite;
1365 1176 }
1366 1177 .skeleton-line.short { width: 40%; }
1367 - .skeleton-line.medium { width: 70%; margin-top: var(--gap-peer); }
1368 1178 .skeleton-line.long { width: 90%; margin-top: var(--gap-peer); }
1369 1179
1370 1180 @keyframes shimmer {
@@ -1401,21 +1211,11 @@
1401 1211 color: inherit;
1402 1212 cursor: pointer;
1403 1213 padding: var(--step-hair) var(--step-base);
Lines truncated