144192754cb3cccf6cb3bf722249080a9ff40dca
7
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
a72605de8f |
refactor(frontend): the last pay-down, part 1 — three dead views deleted, editor rules shared, .page-container + .fs-input canon, rules-shared.css; a one-declaration CSS body is not a shape (#2903, milestone 299 step 5)
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 10s
CI & Build / TypeScript typecheck (push) Successful in 34s
CI & Build / integration (push) Successful in 34s
CI & Build / Python tests (push) Failing after 54s
CI & Build / Build & push image (push) Skipped
The derive queue said the biggest duplicate families were whole views: TaskViewerView, UserManagementView and LogsView were imported nowhere — left behind when tasks moved to the editor and users/logs became SettingsView tabs. Deleted (rule 22). Note/TaskEditorView carried six identical scoped rules -> editor-shared.css (the .tag-suggest-row gap the scoped copies actually rendered wins). Three views wrapped the page under three names -> .page-container in components.css. Three scoped input recipes -> the design system fs-input recipe (snippet #2336), verbatim, in components.css; width/ box-sizing stay with the caller. The three rules panes share .pane and the pane heading via rules-shared.css (the auth-shared pattern, #2852). Ledger: a single-declaration CSS rule keeps its selector in its fingerprint, so `color: var(--fs-text-tertiary)` under five different names is no longer a five-file "identical body" family — the first pay-down found that most of the 148 dup families were exactly this, and nobody would consolidate them. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
2a6c55dacb |
refactor(frontend): auth-shared.css, apiErrorMessage, one date helper per shape, modal canon in components.css — the frontend pass of the shape audit (#2831 #2832, milestone 296)
CI & Build / Python lint (push) Successful in 4s
CI & Build / Plugin hooks (push) Successful in 9s
CI & Build / integration (push) Successful in 22s
CI & Build / TypeScript typecheck (push) Successful in 32s
CI & Build / Python tests (push) Successful in 57s
CI & Build / Build & push image (push) Successful in 16s
- assets/auth-shared.css: the five auth views carried byte-identical scoped
copies of the page/card/brand/footer/field/input/error rules (~60 lines
each); they now load one stylesheet the way the editors load
editor-shared.css. .closed-msg/.error-block/.success-msg (identical bodies)
are one .auth-note; the form rules are scoped under .auth-card so nothing
leaks into the rest of the app.
- api/client.apiErrorMessage(e, fallback): the one place the {"error"} envelope
is unpacked; replaces ten six-line `"body" in e` catch blocks.
- utils/dateFormat: fmtDate / fmtStamp / fmtLogStamp replace eight local
formatDate/formatTime copies (three byte-identical pairs); the file’s old
Calendar/Home helpers had no callers and are gone. useRelativeTime gains
relativeTimeOrDate for the two workspace panels’ identical variant.
- components.css now owns the .modal-* shape (overlay/card/title/message/
actions/btn/primary/danger). It was copied into four views and lived in
editor-shared.css, which ConfirmDialog — styleless, teleported to <body> —
silently depended on: opened from SnippetDetailView before any editor view
had loaded, it rendered unstyled. Views keep only their own overrides.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
||
|
|
4ba544e2af |
refactor(theme): retire the --color-* shim — the sweep it promised, run
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 7s
CI & Build / integration (push) Successful in 17s
CI & Build / TypeScript typecheck (push) Successful in 34s
CI & Build / Python tests (push) Successful in 48s
CI & Build / Build & push image (push) Successful in 37s
#2533. theme.css claimed "removing this block is a rename sweep across the
components, tracked separately" — written in
|
||
|
|
4a9744172f |
fix(ui): restore four base rules a CSS sweep deleted, and check for the rest
CI & Build / Python lint (push) Failing after 3s
CI & Build / Plugin hooks (push) Successful in 9s
CI & Build / TypeScript typecheck (push) Successful in 23s
CI & Build / integration (push) Successful in 27s
CI & Build / Python tests (push) Canceled after 38s
CI & Build / Build & push image (push) Canceled after 0s
Operator reported four things looking wrong. Two were the same bug, and it is
not a design drift — it is deleted CSS.
Removing a rule from a scoped stylesheet leaves its modifiers behind. The
selector still exists, so nothing reads as unused, and the element renders with
no base styling at all:
.btn-workspace base gone, :hover survived — the Workspace link rendered
as raw browser blue, underlined
.milestone-header base gone, .clickable and :hover survived. Every child is
written for a flex ROW (.ms-name { flex: 1 }, the progress
track, .ms-pct), so without the parent they stacked and a
one-line milestone became five. That is the "projects
section uses space poorly" — a deletion, not a redesign.
.milestone-group no rule at all; the card around each milestone
.ds-header only its h1 descendant survived
vue-tsc cannot see any of it. A dead style typechecks perfectly.
scripts/check_dangling_styles.py finds the shape: an element whose every static
class has no base rule anywhere, while at least one carries modifier rules. It
reports 11 more. Reported and not gated, because a genuinely bare wrapper is
legitimate — the signal is the count growing. Runs in the lint lane, stdlib
only, and knows no class name or convention (rule #115).
Also from the same report:
- The header pill bar was `position: absolute; left: 50%`, so it did not
participate in layout: out of room, it OVERLAPPED the brand and the utility
cluster instead of pushing them. A sixth link reached that at ~1270px, an
ordinary window. Now `1fr auto 1fr` — a 1fr track has an auto minimum, so
neither side can be squeezed under its content and the two stay equal, which
is what keeps the bar centred in the viewport rather than in the leftover
space. Overflow becomes the header growing, not two things sharing pixels.
- The token preview put its checkerboard on the whole specimen stage, so every
swatch sat in a frame of checks and the pattern read as the loudest thing on
the page. The checks now sit UNDER the colour as a second background layer:
an opaque value hides them, a 15% tint shows exactly as much as it should.
Text-bearing specimens lose the box entirely, and name/value/purpose are one
line each with the full text on hover — they wrapped freely before, so a card
was two lines tall or five depending on how long its color-mix() happened to
be, and the grid had no rhythm.
- .btn-cta joins the shared button family: the gradient-and-glow brand moment
the system carries tokens for, which had been living in one view's scoped
block. That is what made it deletable. The header actions are now one size
and one family instead of four sizes and two.
- The shared button shape gained inline-flex + gap, so a button carrying an
icon centres it without each caller rebuilding the row.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UaYUaouG9jjhATyuxCKrQs
|
||
|
|
67fdf7c55b |
refactor(ui): auth views migrate onto the shared buttons; two variants added
CI & Build / Python lint (push) Successful in 4s
CI & Build / Plugin hooks (push) Successful in 12s
CI & Build / TypeScript typecheck (push) Successful in 42s
CI & Build / integration (push) Successful in 1m39s
CI & Build / Python tests (push) Successful in 2m4s
CI & Build / Build & push image (push) Canceled after 0s
The five auth views each defined .btn-submit identically — full-width, filled, 0.6rem — and LoginView additionally defined .btn-oauth. Those rules are now gone entirely rather than tokenised: the template composes `btn-primary btn-block` and `btn-ghost btn-block`, and there is nothing left per-file to drift. That is the difference between this and the earlier chunks. Consolidating the core four moved geometry into one place but left every semantic name defining its own; this removes the definition. Two variants added, both earned rather than invented: - .btn-text — no fill, no border. The most common shape in the dense surfaces (dismiss, cancel-beside-confirm, clear-search) where a border would draw a box around something that should read as an action on the adjacent text. Distinct from ghost, which IS a box. - .btn-danger-outline — already existed independently in three views before this sheet, which is what makes it a variant and not a one-off. It is what a delete looks like when it must not shout. .btn-block composes with a variant rather than being one, because width is orthogonal to appearance. Also corrected the sheet's own header, which claimed "no template changes" — true when it was written, false as of this commit. It now states the actual model: a button is variant + size, composed in the template. Semantic per-view names are named as the thing that drifted, and why: a name says what a button is FOR and nothing about what it should look like, so two buttons doing the same job in two views had no reason to match, and didn't. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UaYUaouG9jjhATyuxCKrQs |
||
|
|
37616682f0 |
feat(ui): three button sizes, because the app has three kinds of button
CI & Build / Python lint (push) Successful in 4s
CI & Build / Plugin hooks (push) Successful in 10s
CI & Build / integration (push) Successful in 31s
CI & Build / TypeScript typecheck (push) Successful in 34s
CI & Build / Python tests (push) Successful in 1m4s
CI & Build / Build & push image (push) Successful in 45s
Measured before deciding: across the ~100 bespoke button rules, vertical padding does not spread — it clusters. ~27 at 0.4–0.45rem, ~28 at 0.25–0.3rem, ~23 at 0.1–0.15rem. Those are three different components that happen to share a name prefix: a page action, a row action, and an affordance that lives inside a card. Collapsing them to the single size the shared sheet had would have visibly broken every card layout, which is why the one-off migration stopped here for a decision rather than proceeding on the assumption that a button is a button. default 8px 16px page action — what the house style specifies .btn-compact 4px 12px toolbar, table row, list item controls .btn-inline 2px 4px dismiss ×, confirm tick, add-chip .btn-small and .btn-sm already sat at the compact step, so they are kept as aliases for it — no template churn, and the two spellings stop being a third thing that might drift. .btn-inline is deliberately below the spacing scale's first step on the vertical axis: 4px of padding on an 11px label already exceeds the line box these sit in. Stated in the file so it reads as a measured exception rather than someone ignoring the scale. DesignView renders all three as real specimens. A size scale described in prose is one nobody can check; rendered from the actual classes, it cannot claim something the app does not do. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UaYUaouG9jjhATyuxCKrQs |
||
|
|
1a959b1db0 |
refactor(ui): one button definition, aligned to the design system
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 9s
CI & Build / TypeScript typecheck (push) Successful in 36s
CI & Build / integration (push) Successful in 39s
CI & Build / Python tests (push) Successful in 1m12s
CI & Build / Build & push image (push) Successful in 1m12s
`.btn-primary` was defined five times in five scoped stylesheets and all five had drifted: three paddings, three font sizes, three disabled opacities — and ProjectListView had no disabled style at all, so a disabled button there looked enabled. Nothing detected any of it. A scoped duplicate is not a rule violation, not a broken reference, and not a recorded snippet, so no existing check could see it (#2273). assets/components.css is now the single definition of the core four — primary, secondary, ghost, danger — plus the small modifier, in design-system tokens throughout. Operator's call to align to the system rather than to the majority of current values, so buttons move to the 8px radius and 12px label the system specifies, from the app's 4px/14.4px. Class names are unchanged, so there are no template edits: the existing surface is repurposed, not rebuilt. STAGING PROPERTY that makes this safe to land ahead of the rest: a Vue `<style scoped>` rule compiles to `.btn-primary[data-v-…]` (specificity 0,2,0) and beats a plain global selector (0,1,0). So the shared sheet changes nothing for a view still carrying its own copy, and every intermediate state of the remaining migration is coherent rather than half-applied. Two divergences corrected on the way, both worth naming: - SnippetEditorView's `.btn-secondary` was a GHOST in disguise — outline styling under the secondary name, while the house style says secondary is filled bronze. It now looks like what it is called. - SnippetDetailView and SnippetListView tinted a ghost button's label with the ACCENT on hover. The house style reserves the accent for identity and active state, never general chrome. DesignView reported "no shared button exists" as an honest gap and declined to draw a look-alike. That gap is closed, so it now renders the app's real classes — the specimens cannot drift from the app without drifting the app. Net -177 lines. Follows: the ~20 semantic one-offs (.btn-save, .btn-delete, .btn-toggle …) and the compound overrides in ProjectView, one of which puts the accent on a primary action button. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UaYUaouG9jjhATyuxCKrQs |