refactor(frontend): the second sweep — scoped rules that no longer match their own template (#2962)
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 7s
CI & Build / TypeScript typecheck (push) Successful in 10s
CI & Build / integration (push) Successful in 27s
CI & Build / Python tests (push) Successful in 1m4s
CI & Build / Build & push image (push) Successful in 34s
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 7s
CI & Build / TypeScript typecheck (push) Successful in 10s
CI & Build / integration (push) Successful in 27s
CI & Build / Python tests (push) Successful in 1m4s
CI & Build / Build & push image (push) Successful in 34s
The first sweep asked "does this class token appear anywhere outside a
<style> block?". That is too generous for a `<style scoped>` rule, which can
only ever match its own template, the component's root element, or whatever
`:deep()` reaches — so a scoped rule whose name lives only in some OTHER file
is dead regardless. The server's map had this right and my local pass did
not; this closes the gap.
79 scoped classes are absent from their own file. 48 are names their own file
BUILDS — `status-${task.status}`, `pri-${p}`, `toast--${type}`,
`perm-${permission}`, `diff-${op}`, `is-${kind}` — and 12 more are Vue
transition classes. Those are the map's documented blind spot and they stay.
The remaining 19 match nothing:
- AppHeader (9, -39 lines): the whole connection-status indicator —
.status-indicator/.status-dot/.status-text and the five colour states,
plus @keyframes pulse-dot and status-pulse, which had no other user. Same
Phase 7 residue as the last commit. `.btn-icon.active` goes too: `active`
is never applied in this component (its nav uses router-link-active).
- SettingsView (6): .status-badge/.status-on/.status-off,
.perm-granted/.perm-denied, .location-row. This view renders no child
components at all, so nothing can inherit its scope.
- WorkspaceNoteEditor: .note-row:hover .btn-delete and .btn-suggest-tags —
those buttons are .btn-danger-outline/.btn-ghost now.
- ProjectListView .loading-msg; SnippetEditorView .field-row.three, whose
media-query companion keeps its live .field-row half.
Checked against child-component roots before deleting, since a child's root
element does inherit the parent's scope id — none of the 19 is one. Template
and script regions byte-identical; both style checks still pass with only
the six pre-existing reports.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -212,43 +212,6 @@ router.afterEach(() => {
|
||||
box-shadow: 0 0 16px color-mix(in srgb, var(--fs-accent) 30%, transparent);
|
||||
}
|
||||
|
||||
/* Status indicator */
|
||||
.status-indicator {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.3rem;
|
||||
cursor: default;
|
||||
padding: 0 0.25rem;
|
||||
}
|
||||
.status-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.status-text {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
color: var(--fs-text-tertiary);
|
||||
}
|
||||
/* Status dots are indicator lights, not semantic-palette buttons —
|
||||
they want to read as vital (Moss/Warning/Error are too muted for
|
||||
a "ready" indicator). Hardcoded bright values; the rest of the
|
||||
system still uses the semantic tokens. */
|
||||
.status-green .status-dot { background: #4ade80; animation: status-pulse 2.5s ease-in-out infinite; }
|
||||
.status-yellow .status-dot { background: #facc15; animation: pulse-dot 2s infinite; }
|
||||
.status-orange .status-dot { background: #f97316; }
|
||||
.status-red .status-dot { background: #ef4444; }
|
||||
.status-gray .status-dot { background: var(--fs-text-tertiary); animation: pulse-dot 2s infinite; }
|
||||
@keyframes pulse-dot {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.3; }
|
||||
}
|
||||
@keyframes status-pulse {
|
||||
0%, 100% { box-shadow: 0 0 4px rgba(74, 222, 128, 0.4); }
|
||||
50% { box-shadow: 0 0 10px rgba(74, 222, 128, 0.6); }
|
||||
}
|
||||
|
||||
/* Icon buttons (?, theme, gear) */
|
||||
.btn-icon {
|
||||
background: none;
|
||||
@@ -263,8 +226,7 @@ router.afterEach(() => {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.btn-icon:hover,
|
||||
.btn-icon.active {
|
||||
.btn-icon:hover {
|
||||
background: var(--fs-surface-raised);
|
||||
color: var(--fs-text-primary);
|
||||
border-color: var(--fs-accent);
|
||||
@@ -382,7 +344,6 @@ router.afterEach(() => {
|
||||
.nav-center {
|
||||
display: none;
|
||||
}
|
||||
.status-indicator,
|
||||
.btn-icon,
|
||||
.user-info {
|
||||
display: none;
|
||||
|
||||
@@ -471,7 +471,6 @@ defineExpose({ reload: loadProjectNotes });
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
|
||||
.rail-search-input {
|
||||
flex: 1;
|
||||
background: transparent;
|
||||
@@ -575,8 +574,6 @@ defineExpose({ reload: loadProjectNotes });
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.note-row:hover .btn-delete { opacity: 1; }
|
||||
|
||||
/* Editor UI */
|
||||
.panel-header {
|
||||
display: flex;
|
||||
@@ -624,8 +621,6 @@ defineExpose({ reload: loadProjectNotes });
|
||||
}
|
||||
.tag-row > :first-child { flex: 1; min-width: 0; }
|
||||
|
||||
.btn-suggest-tags { flex-shrink: 0; align-self: center; }
|
||||
|
||||
.tag-suggestions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@@ -653,7 +648,6 @@ defineExpose({ reload: loadProjectNotes });
|
||||
color: var(--fs-accent);
|
||||
}
|
||||
|
||||
|
||||
.link-suggest-strip {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -366,12 +366,6 @@ function overallPct(project: Project): { total: number; pct: number } {
|
||||
border-bottom-color: var(--fs-accent);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.loading-msg {
|
||||
color: var(--fs-text-tertiary);
|
||||
font-size: 0.9rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
.error-msg {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
@@ -2865,8 +2865,6 @@ async function deleteUser(userId: number) {
|
||||
align-items: center;
|
||||
max-width: 480px;
|
||||
}
|
||||
.perm-granted { background: color-mix(in srgb, var(--fs-success) 15%, transparent); color: var(--fs-success); }
|
||||
.perm-denied { background: color-mix(in srgb, var(--fs-error) 15%, transparent); color: var(--fs-error); }
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.settings-root {
|
||||
@@ -3227,13 +3225,6 @@ async function deleteUser(userId: number) {
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
|
||||
/* Profile — Locations + Journal sections */
|
||||
.location-row {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
|
||||
/* API Keys tab */
|
||||
.api-key-create-form {
|
||||
display: flex;
|
||||
@@ -3384,22 +3375,6 @@ async function deleteUser(userId: number) {
|
||||
opacity: 0.7;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.status-badge {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
padding: 0.15rem 0.55rem;
|
||||
border-radius: 999px;
|
||||
}
|
||||
.status-on {
|
||||
background: color-mix(in srgb, var(--fs-success) 15%, transparent);
|
||||
color: var(--fs-success);
|
||||
border: 1px solid color-mix(in srgb, var(--fs-success) 40%, transparent);
|
||||
}
|
||||
.status-off {
|
||||
background: color-mix(in srgb, var(--fs-text-tertiary) 10%, transparent);
|
||||
color: var(--fs-text-tertiary);
|
||||
border: 1px solid var(--fs-border-color);
|
||||
}
|
||||
|
||||
/* ── Profile tab ─────────────────────────────────────────────────────────── */
|
||||
.day-picker {
|
||||
|
||||
@@ -383,7 +383,6 @@ function cancel() {
|
||||
color: var(--fs-accent);
|
||||
}
|
||||
|
||||
|
||||
.form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -400,9 +399,6 @@ function cancel() {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 1rem;
|
||||
}
|
||||
.field-row.three {
|
||||
grid-template-columns: 1fr 1.4fr 1fr;
|
||||
}
|
||||
.field label,
|
||||
.location-set legend {
|
||||
font-size: 0.8rem;
|
||||
@@ -552,8 +548,7 @@ function cancel() {
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.field-row,
|
||||
.field-row.three {
|
||||
.field-row {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user