refactor(frontend): CSS pay-down, derive batch (milestone 302 step 4) — page-header, error-msg/state-msg/empty-msg, empty-title/empty-sub, required, field-hint recipes into components.css; form-buttons into rules-shared.css; scoped copies trimmed to remainders/overrides; the three views' .input becomes fs-input + width/box-sizing remainder (canon #2336)
CI & Build / TypeScript typecheck (push) Failing after 2s
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 8s
CI & Build / integration (push) Successful in 24s
CI & Build / Python tests (push) Successful in 1m2s
CI & Build / Build & push image (push) Skipped

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-23 17:30:43 -04:00
co-authored by Claude Fable 5
parent c28c87c39e
commit 6fb0cb38a5
10 changed files with 93 additions and 131 deletions
+37 -37
View File
@@ -1236,7 +1236,7 @@ async function deleteUser(userId: number) {
id="user-timezone"
v-model="userTimezone"
type="text"
class="input"
class="fs-input input"
placeholder="e.g. America/New_York"
/>
<button class="btn-secondary" type="button" @click="detectTimezone">Detect</button>
@@ -1263,7 +1263,7 @@ async function deleteUser(userId: number) {
type="number"
min="0"
step="1"
class="input"
class="fs-input input"
style="max-width: 8rem"
/>
<p class="field-hint">Set to <strong>0</strong> to keep deleted items forever (never auto-purge).</p>
@@ -1301,7 +1301,7 @@ async function deleteUser(userId: number) {
min="0"
max="1"
step="0.05"
class="input"
class="fs-input input"
style="max-width: 8rem"
/>
<p class="field-hint">Minimum similarity to surface a note. Higher = stricter (fewer, more certain). Deliberately above the 0.45 used for searches you trigger yourself.</p>
@@ -1315,7 +1315,7 @@ async function deleteUser(userId: number) {
min="1"
max="10"
step="1"
class="input"
class="fs-input input"
style="max-width: 8rem"
/>
<p class="field-hint">Ceiling on titles surfaced at once (110).</p>
@@ -1345,7 +1345,7 @@ async function deleteUser(userId: number) {
min="0"
max="1"
step="0.01"
class="input"
class="fs-input input"
style="max-width: 8rem"
/>
<p class="field-hint">
@@ -1374,7 +1374,7 @@ async function deleteUser(userId: number) {
min="0"
max="1"
step="0.01"
class="input"
class="fs-input input"
style="max-width: 8rem"
/>
<p class="field-hint">
@@ -1394,7 +1394,7 @@ async function deleteUser(userId: number) {
min="0"
max="1"
step="0.01"
class="input"
class="fs-input input"
style="max-width: 8rem"
/>
<p class="field-hint">
@@ -1415,7 +1415,7 @@ async function deleteUser(userId: number) {
min="0"
max="1"
step="0.01"
class="input"
class="fs-input input"
style="max-width: 8rem"
/>
<p class="field-hint">
@@ -1457,7 +1457,7 @@ async function deleteUser(userId: number) {
v-model="newEmail"
type="email"
placeholder="you@example.com"
class="input"
class="fs-input input"
/>
</div>
<div class="field">
@@ -1467,7 +1467,7 @@ async function deleteUser(userId: number) {
v-model="emailPassword"
type="password"
autocomplete="current-password"
class="input"
class="fs-input input"
/>
<p class="field-hint">Required to confirm the change.</p>
</div>
@@ -1491,7 +1491,7 @@ async function deleteUser(userId: number) {
v-model="currentPassword"
type="password"
autocomplete="current-password"
class="input"
class="fs-input input"
/>
</div>
<div class="field">
@@ -1501,7 +1501,7 @@ async function deleteUser(userId: number) {
v-model="newPassword"
type="password"
autocomplete="new-password"
class="input"
class="fs-input input"
/>
<p class="field-hint">Must be at least 8 characters</p>
</div>
@@ -1512,7 +1512,7 @@ async function deleteUser(userId: number) {
v-model="confirmNewPassword"
type="password"
autocomplete="new-password"
class="input"
class="fs-input input"
:class="{ 'input-error': confirmNewPassword && newPassword !== confirmNewPassword }"
/>
<p v-if="confirmNewPassword && newPassword !== confirmNewPassword" class="error-hint">
@@ -1555,20 +1555,20 @@ async function deleteUser(userId: number) {
<div class="assistant-grid">
<div class="field">
<label>Display Name</label>
<input v-model="profile.display_name" type="text" class="input" placeholder="e.g. Alex" />
<input v-model="profile.display_name" type="text" class="fs-input input" placeholder="e.g. Alex" />
<p class="field-hint">How the assistant addresses you.</p>
</div>
<div class="field">
<label>Job Title</label>
<input v-model="profile.job_title" type="text" class="input" placeholder="e.g. Product Manager" />
<input v-model="profile.job_title" type="text" class="fs-input input" placeholder="e.g. Product Manager" />
</div>
<div class="field">
<label>Industry</label>
<input v-model="profile.industry" type="text" class="input" placeholder="e.g. Technology" />
<input v-model="profile.industry" type="text" class="fs-input input" placeholder="e.g. Technology" />
</div>
<div class="field">
<label>Expertise Level</label>
<select v-model="profile.expertise_level" class="input">
<select v-model="profile.expertise_level" class="fs-input input">
<option value="novice">Novice explain things simply</option>
<option value="intermediate">Intermediate balanced explanations</option>
<option value="expert">Expert assume deep knowledge</option>
@@ -1587,7 +1587,7 @@ async function deleteUser(userId: number) {
<div class="assistant-grid">
<div class="field">
<label>Response Style</label>
<select v-model="profile.response_style" class="input">
<select v-model="profile.response_style" class="fs-input input">
<option value="concise">Concise short and direct</option>
<option value="balanced">Balanced default</option>
<option value="detailed">Detailed thorough explanations</option>
@@ -1595,7 +1595,7 @@ async function deleteUser(userId: number) {
</div>
<div class="field">
<label>Tone</label>
<select v-model="profile.tone" class="input">
<select v-model="profile.tone" class="fs-input input">
<option value="casual">Casual friendly and relaxed</option>
<option value="professional">Professional formal and precise</option>
<option value="technical">Technical jargon-friendly</option>
@@ -1637,11 +1637,11 @@ async function deleteUser(userId: number) {
<div class="assistant-grid" style="margin-top:0.75rem">
<div class="field">
<label>Start Time</label>
<input v-model="profile.work_schedule.start" type="time" class="input" />
<input v-model="profile.work_schedule.start" type="time" class="fs-input input" />
</div>
<div class="field">
<label>End Time</label>
<input v-model="profile.work_schedule.end" type="time" class="input" />
<input v-model="profile.work_schedule.end" type="time" class="fs-input input" />
</div>
</div>
<div class="actions">
@@ -1697,7 +1697,7 @@ async function deleteUser(userId: number) {
<input
v-model="searchQuery"
type="text"
class="input"
class="fs-input input"
placeholder="Enter a search query..."
@keydown="onSearchKeydown"
/>
@@ -1763,17 +1763,17 @@ async function deleteUser(userId: number) {
<div v-if="connFormOpen" class="smtp-grid">
<div class="field">
<label for="conn-kind">Forge</label>
<select id="conn-kind" v-model="connForm.kind" class="input">
<select id="conn-kind" v-model="connForm.kind" class="fs-input input">
<option v-for="k in forgeKinds" :key="k" :value="k">{{ k }}</option>
</select>
</div>
<div class="field">
<label for="conn-base-url">Base URL</label>
<input id="conn-base-url" v-model="connForm.base_url" type="text" placeholder="https://git.example.com" class="input" />
<input id="conn-base-url" v-model="connForm.base_url" type="text" placeholder="https://git.example.com" class="fs-input input" />
</div>
<div class="field">
<label for="conn-token">API Token (read scope)</label>
<input id="conn-token" v-model="connForm.token" type="password" class="input" />
<input id="conn-token" v-model="connForm.token" type="password" class="fs-input input" />
</div>
</div>
<div class="actions">
@@ -2063,7 +2063,7 @@ async function deleteUser(userId: number) {
v-model="baseUrl"
type="url"
placeholder="https://notes.example.com"
class="input"
class="fs-input input"
/>
</div>
<div class="actions">
@@ -2088,7 +2088,7 @@ async function deleteUser(userId: number) {
v-model="adminMarketplaceUrl"
type="url"
placeholder="https://git.example.com/you/Scribe.git"
class="input"
class="fs-input input"
/>
</div>
<div class="actions">
@@ -2115,7 +2115,7 @@ async function deleteUser(userId: number) {
</div>
<div class="field url-field">
<label for="db-maint-hour">Run hour (UTC)</label>
<select id="db-maint-hour" v-model.number="dbMaintHour" class="input">
<select id="db-maint-hour" v-model.number="dbMaintHour" class="fs-input input">
<option v-for="h in 24" :key="h - 1" :value="h - 1">
{{ String(h - 1).padStart(2, '0') }}:00
</option>
@@ -2185,27 +2185,27 @@ async function deleteUser(userId: number) {
<div class="smtp-grid">
<div class="field">
<label for="smtp-host">SMTP Host</label>
<input id="smtp-host" v-model="smtp.smtp_host" type="text" placeholder="smtp.example.com" class="input" />
<input id="smtp-host" v-model="smtp.smtp_host" type="text" placeholder="smtp.example.com" class="fs-input input" />
</div>
<div class="field">
<label for="smtp-port">Port</label>
<input id="smtp-port" v-model="smtp.smtp_port" type="text" placeholder="587" class="input" />
<input id="smtp-port" v-model="smtp.smtp_port" type="text" placeholder="587" class="fs-input input" />
</div>
<div class="field">
<label for="smtp-username">Username</label>
<input id="smtp-username" v-model="smtp.smtp_username" type="text" class="input" />
<input id="smtp-username" v-model="smtp.smtp_username" type="text" class="fs-input input" />
</div>
<div class="field">
<label for="smtp-password">Password</label>
<input id="smtp-password" v-model="smtp.smtp_password" type="password" class="input" />
<input id="smtp-password" v-model="smtp.smtp_password" type="password" class="fs-input input" />
</div>
<div class="field">
<label for="smtp-from-address">From Address</label>
<input id="smtp-from-address" v-model="smtp.smtp_from_address" type="email" placeholder="noreply@example.com" class="input" />
<input id="smtp-from-address" v-model="smtp.smtp_from_address" type="email" placeholder="noreply@example.com" class="fs-input input" />
</div>
<div class="field">
<label for="smtp-from-name">From Name</label>
<input id="smtp-from-name" v-model="smtp.smtp_from_name" type="text" placeholder="Fabled Scribe" class="input" />
<input id="smtp-from-name" v-model="smtp.smtp_from_name" type="text" placeholder="Fabled Scribe" class="fs-input input" />
</div>
</div>
<div class="checkbox-field">
@@ -2228,7 +2228,7 @@ async function deleteUser(userId: number) {
v-model="testRecipient"
type="email"
placeholder="test@example.com"
class="input"
class="fs-input input"
/>
<button class="btn-primary" @click="sendTestEmail" :disabled="sendingTest || !testRecipient.trim()">
{{ sendingTest ? "Sending..." : "Send Test" }}
@@ -2249,7 +2249,7 @@ async function deleteUser(userId: number) {
<div class="smtp-grid">
<div class="field">
<label for="forge-webhook-secret">Webhook Secret</label>
<input id="forge-webhook-secret" v-model="forgeWebhookSecret" type="password" class="input" />
<input id="forge-webhook-secret" v-model="forgeWebhookSecret" type="password" class="fs-input input" />
</div>
</div>
<div class="actions">
@@ -2295,7 +2295,7 @@ async function deleteUser(userId: number) {
v-model="inviteEmail"
type="email"
placeholder="Email address"
class="input invite-input"
class="fs-input input invite-input"
required
:disabled="sendingInvite"
/>