refactor(ui): editor-shared buttons alias onto the variants; 3 dead classes go
CI & Build / Python lint (push) Successful in 7s
CI & Build / Plugin hooks (push) Successful in 12s
CI & Build / integration (push) Successful in 32s
CI & Build / TypeScript typecheck (push) Successful in 35s
CI & Build / Python tests (push) Successful in 1m51s
CI & Build / Build & push image (push) Canceled after 38s

editor-shared.css defined thirteen button rules with hand-written geometry.
Ten are now thin aliases onto the shared variants — same class names, because
these are used across six views and pointing a name somewhere is cheaper than
rewriting every call site (the .btn-small precedent).

Three were DEAD: .btn-assist-toggle, .btn-close-assist and .btn-toggle-view had
no template reference and no dynamic binding anywhere in the app. Verified
before deleting rather than assumed from the name — a class with no user is
indistinguishable from one bound dynamically until you look.

Named honestly in the file: CSS has no @extend, so each alias carries the
variant's declarations rather than inheriting them. That is duplication this
migration cannot remove. But it is duplication of a REFERENCE — var(--color-
action-primary) — not of a value, so a palette change still moves everything at
once, which is the property that actually mattered.

Also gone: eight hardcoded geometries (0.4rem 1rem, 0.85rem, and so on) that
now come from --fs-space and --fs-size tokens.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UaYUaouG9jjhATyuxCKrQs
This commit is contained in:
2026-08-01 22:46:01 -04:00
co-authored by Claude Opus 5
parent c7cf07824a
commit 3d6931b838
+93 -178
View File
@@ -34,86 +34,11 @@
gap: 0.5rem; gap: 0.5rem;
align-items: center; align-items: center;
} }
.btn-back {
display: inline-flex;
align-items: center;
padding: 0.45rem 1rem;
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
background: none;
color: var(--color-text-secondary);
text-decoration: none;
cursor: pointer;
font-size: 0.9rem;
}
.btn-back:hover {
border-color: var(--color-primary);
color: var(--color-primary);
}
/* Save: Moss action-primary per the Hybrid rule. Saving is "operating /* Save: Moss action-primary per the Hybrid rule. Saving is "operating
the software" — not a brand moment. Accent gradient is reserved for the software" — not a brand moment. Accent gradient is reserved for
Send / empty-state CTAs. */ Send / empty-state CTAs. */
.btn-save {
padding: 0.45rem 1.1rem;
background: var(--color-action-primary);
color: var(--fs-text-on-action);
border: none;
border-radius: var(--radius-sm);
cursor: pointer;
font-weight: 500;
font-size: 0.875rem;
transition: background 0.15s, opacity 0.15s;
}
.btn-save:hover:not(:disabled) {
background: var(--color-action-primary-hover);
}
.btn-save:disabled {
opacity: 0.55;
cursor: default;
}
/* Delete: Oxblood action-destructive per Hybrid rule. Should be paired /* Delete: Oxblood action-destructive per Hybrid rule. Should be paired
with a Trash icon at the call site to reinforce intent. */ with a Trash icon at the call site to reinforce intent. */
.btn-delete {
padding: 0.45rem 1rem;
background: var(--color-action-destructive);
color: var(--fs-text-on-action);
border: none;
border-radius: var(--radius-sm);
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 0.35rem;
font-weight: 500;
}
.btn-delete:hover { background: var(--color-action-destructive-hover); }
.btn-assist-toggle {
margin-left: auto;
padding: 0.4rem 0.9rem;
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
background: none;
color: var(--color-text-secondary);
cursor: pointer;
font-size: 0.85rem;
}
.btn-assist-toggle.active {
background: color-mix(in srgb, var(--color-primary) 12%, transparent);
border-color: var(--color-primary);
color: var(--color-primary);
}
.title-input {
padding: 0.4rem 0;
border: none;
border-bottom: 1.5px solid var(--color-border);
border-radius: 0;
font-size: 1.5rem;
font-weight: 500;
font-family: "Fraunces", Georgia, serif;
background: transparent;
color: var(--color-text);
width: 100%;
transition: border-color 0.15s;
}
.title-input:focus { .title-input:focus {
outline: none; outline: none;
border-bottom-color: var(--color-primary); border-bottom-color: var(--color-primary);
@@ -155,23 +80,6 @@
align-items: center; align-items: center;
gap: 0.4rem; gap: 0.4rem;
} }
.btn-suggest-tags {
padding: 0.3rem 0.7rem;
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
background: var(--color-bg-card);
color: var(--color-text-secondary);
cursor: pointer;
font-size: 0.8rem;
}
.btn-suggest-tags:hover:not(:disabled) {
border-color: var(--color-primary);
color: var(--color-primary);
}
.btn-suggest-tags:disabled {
opacity: 0.6;
cursor: wait;
}
.tag-pill { .tag-pill {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
@@ -198,18 +106,6 @@
.tag-check { .tag-check {
font-size: 0.7rem; font-size: 0.7rem;
} }
.btn-dismiss-tags {
padding: 0.1rem 0.4rem;
border: none;
background: none;
color: var(--color-text-muted);
cursor: pointer;
font-size: 1rem;
line-height: 1;
}
.btn-dismiss-tags:hover {
color: var(--color-text);
}
/* ── Assist panel ── */ /* ── Assist panel ── */
.assist-panel { .assist-panel {
@@ -237,32 +133,6 @@
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.05em; letter-spacing: 0.05em;
} }
.btn-proofread {
padding: 0.3rem 0.65rem;
font-size: 0.78rem;
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
background: none;
color: var(--color-text-secondary);
cursor: pointer;
}
.btn-proofread:hover:not(:disabled) {
border-color: var(--color-primary);
color: var(--color-primary);
}
.btn-proofread:disabled {
opacity: 0.5;
cursor: default;
}
.btn-close-assist {
padding: 0.1rem 0.4rem;
border: none;
background: none;
color: var(--color-text-muted);
cursor: pointer;
font-size: 1rem;
line-height: 1;
}
.assist-panel-body { .assist-panel-body {
flex: 1; flex: 1;
min-height: 0; min-height: 0;
@@ -342,28 +212,6 @@
display: flex; display: flex;
gap: 0.5rem; gap: 0.5rem;
} }
.btn-generate {
padding: 0.4rem 0.9rem;
background: var(--color-action-primary);
color: var(--fs-text-on-action);
border: none;
border-radius: var(--radius-sm);
cursor: pointer;
font-size: 0.85rem;
}
.btn-generate:disabled {
opacity: 0.5;
cursor: default;
}
.btn-clear {
padding: 0.4rem 0.9rem;
background: none;
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
cursor: pointer;
font-size: 0.85rem;
color: var(--color-text-secondary);
}
/* Streaming */ /* Streaming */
.assist-streaming-label { .assist-streaming-label {
@@ -419,14 +267,6 @@
font-weight: 500; font-weight: 500;
color: var(--color-text-secondary); color: var(--color-text-secondary);
} }
.btn-toggle-view {
font-size: 0.75rem;
color: var(--color-primary);
background: none;
border: none;
cursor: pointer;
padding: 0;
}
.diff-view { .diff-view {
border: 1px solid var(--color-input-border); border: 1px solid var(--color-input-border);
border-radius: var(--radius-sm); border-radius: var(--radius-sm);
@@ -475,24 +315,6 @@
display: flex; display: flex;
gap: 0.5rem; gap: 0.5rem;
} }
.btn-accept {
padding: 0.4rem 1rem;
background: var(--color-success);
color: var(--fs-text-on-action);
border: none;
border-radius: var(--radius-sm);
cursor: pointer;
font-size: 0.85rem;
}
.btn-reject {
padding: 0.4rem 1rem;
background: none;
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
cursor: pointer;
font-size: 0.85rem;
color: var(--color-text-secondary);
}
/* ── Modal ── */ /* ── Modal ── */
.modal-overlay { .modal-overlay {
@@ -640,3 +462,96 @@
padding: 0.5rem 1rem 1rem; padding: 0.5rem 1rem 1rem;
} }
} }
/* ---------------------------------------------------------------------------
* Editor button aliases.
*
* These names are used across six views, so they alias onto the shared variants
* rather than every call site being rewritten — the class stays the app's, the
* appearance comes from components.css. Same reasoning as .btn-small: a name
* already in the templates is cheaper to point somewhere than to replace.
*
* They are @extend-shaped, which CSS lacks, so each carries the variant's own
* declarations. That is the one duplication this migration cannot remove — but
* it is duplication of a REFERENCE (a var()), not of a value, so a palette
* change still moves everything at once.
* ------------------------------------------------------------------------ */
.btn-accept,
.btn-generate,
.btn-save {
background: var(--color-action-primary);
color: var(--fs-text-on-action);
border: none;
}
.btn-accept:not(:disabled):hover,
.btn-generate:not(:disabled):hover,
.btn-save:not(:disabled):hover {
background: var(--color-action-primary-hover);
}
.btn-back,
.btn-clear,
.btn-reject,
.btn-proofread,
.btn-suggest-tags {
background: none;
border: var(--fs-border);
color: var(--color-text);
}
.btn-back:not(:disabled):hover,
.btn-clear:not(:disabled):hover,
.btn-reject:not(:disabled):hover,
.btn-proofread:not(:disabled):hover,
.btn-suggest-tags:not(:disabled):hover {
border: var(--fs-border-hover);
background: var(--color-hover);
}
.btn-delete {
background: var(--color-action-destructive);
color: var(--fs-text-on-action);
border: none;
}
.btn-delete:not(:disabled):hover {
background: var(--color-action-destructive-hover);
}
/* Shared geometry for every alias above. */
.btn-accept, .btn-generate, .btn-save, .btn-back, .btn-clear, .btn-reject,
.btn-delete, .btn-dismiss-tags, .btn-proofread, .btn-suggest-tags {
border-radius: var(--fs-radius-md);
font-family: var(--fs-font-body);
font-weight: var(--fs-weight-medium);
cursor: pointer;
white-space: nowrap;
transition: background var(--fs-dur-fast) var(--fs-ease),
border-color var(--fs-dur-fast) var(--fs-ease),
color var(--fs-dur-fast) var(--fs-ease);
}
.btn-accept, .btn-generate, .btn-save, .btn-back, .btn-clear, .btn-reject,
.btn-delete {
padding: var(--fs-space-2) var(--fs-space-4);
font-size: var(--fs-size-label);
}
.btn-proofread, .btn-suggest-tags {
padding: var(--fs-space-1) var(--fs-space-3);
font-size: var(--fs-size-tiny);
}
.btn-dismiss-tags {
background: none;
border: none;
color: var(--color-text-muted);
padding: 2px var(--fs-space-1);
font-size: var(--fs-size-tiny);
line-height: 1;
}
.btn-dismiss-tags:hover { color: var(--color-text); }
.btn-accept:disabled, .btn-generate:disabled, .btn-save:disabled,
.btn-back:disabled, .btn-clear:disabled, .btn-reject:disabled,
.btn-delete:disabled, .btn-proofread:disabled, .btn-suggest-tags:disabled,
.btn-dismiss-tags:disabled {
opacity: var(--fs-disabled-opacity);
cursor: not-allowed;
}