diff --git a/.squad/agents/legolas/history.md b/.squad/agents/legolas/history.md index 1ca1f89d..f72929eb 100644 --- a/.squad/agents/legolas/history.md +++ b/.squad/agents/legolas/history.md @@ -649,3 +649,85 @@ Fix theme color selector persistence — selected color not surviving page reloa ### Outcome ✅ Theme color and brightness now persist correctly across page reloads and sessions. PR #239 opened, ready for review. + +## Learnings + +### 2025-07 — Button Variant Styling (Issue #292, branch squad/291-input-css-fine-tuning) + +**Source of truth for app button styles:** `src/Web/Styles/input.css` under `@layer components`. This compiles to `src/Web/wwwroot/css/tailwind.css` (gitignored — regenerated by `npm run tw:build`). + +**Tailwind v4 grouped selector pattern:** Use a shared multi-class selector to avoid duplicating base styles across variants: + +```css +.btn-primary, .btn-secondary, .btn-warning, .btn-destructive { + @apply inline-flex items-center gap-2 ... focus-visible:ring-2 disabled:opacity-50; +} +``` + +Then each variant only declares its colour-specific overrides. This is idiomatic Tailwind v4 component authoring. + +**Fixed colour palette — all four variants:** All button variants use fixed Tailwind palette classes, not `var(--primary-*)` theme tokens. `.btn-primary` is green, `.btn-secondary` is blue, `.btn-warning` is amber, and `.btn-destructive` is red. None shift when the user picks a different colour theme — the palette is intentionally static to give each variant a clear, invariant semantic meaning. + +**Bootstrap-like interactive states checklist:** + +- `cursor-pointer` + `select-none` — Bootstrap sets these on buttons +- `focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:ring-{color}` — replaces Bootstrap's box-shadow focus ring +- `disabled:opacity-50 disabled:cursor-not-allowed` — Bootstrap uses `opacity: 0.65` +- `active:scale-[0.98]` — subtle press affordance (Bootstrap uses active filter) + +**ConfirmDeleteDialog.razor:** Was using hardcoded inline Tailwind for delete/cancel buttons (`bg-red-600 text-white ...`). Migrated to `.btn-destructive` / `.btn-secondary`. File: `src/Web/Features/BlogPosts/Delete/ConfirmDeleteDialog.razor`. + +**ManageRoles.razor inline role chip buttons:** Left as-is — they are compact chip/badge-style elements (px-3 py-1 text-sm) with a different visual purpose. Not the same pattern as action buttons. + +**Pre-existing branch changes:** The `squad/291-input-css-fine-tuning` branch had uncommitted Profile.razor changes that upgraded role badges from soft pastel (`bg-red-100 text-red-800`) to solid (`bg-red-700 text-white`). Three bUnit tests in `tests/Web.Tests.Bunit/Features/ProfileTests.cs` needed updating to match the current Profile.razor output. + +**Key files:** + +- Button CSS source: `src/Web/Styles/input.css` +- Confirm delete dialog: `src/Web/Features/BlogPosts/Delete/ConfirmDeleteDialog.razor` +- Profile badge tests: `tests/Web.Tests.Bunit/Features/ProfileTests.cs` +- Tailwind build: `npm run tw:build` + +## Learnings + +### 2026-05-07 — Issue #292 follow-up: btn-destructive consistency + +**Task:** The inline delete button in `src/Web/Features/BlogPosts/List/Index.razor` had hardcoded Tailwind classes (`bg-red-600 text-white hover:bg-red-700 ...`) instead of the shared `btn-destructive` utility defined in `input.css`. The delete dialog already used `btn-destructive` (from the #292 main work), but the list page was inconsistent. + +**Change:** + +- Replaced `class="inline-block px-3 py-1 text-sm rounded font-medium bg-red-600 text-white hover:bg-red-700 transition"` with `class="btn-destructive"` on the delete button in `Index.razor`. +- Added bUnit test `BlogIndexUsesBtnDestructiveForInlineDeleteButton` to `RazorSmokeTests.cs` to lock the variant in place and prevent regression. + +**Rule reinforced:** Any destructive action (delete) must always use `.btn-destructive`, never raw Tailwind. This keeps colour/dark-mode and spacing behaviour consistent across all delete surfaces. + +**Test results:** Architecture.Tests 16/16, Web.Tests.Bunit 74/74 — all green. + +## Learnings + +### 2025-07 — PR #295 Review (dark-mode colours + PageHeadingComponent) + +**What I reviewed:** + +- `input.css` centralised button variants, fixed dark-mode heading/paragraph contrast, migrated body/table/form colours to primary palette +- New `PageHeadingComponent.razor` (shared heading + PageTitle wrapper) +- All feature pages (Create, Edit, Index, ManageRoles, Profile) adopt the new component +- `NavMenu.razor` switched from inline Tailwind utility string on `