feat(projects-ui): Quiet Luxury redesign for card-check + 5 dialog v-text-fields
ProjectCard.vue: replace 2px noir solid border on .card-check__box with 1px var(--liderra-line) idle / var(--liderra-line-strong) hover / var(--liderra-teal) checked. Checked state uses tonal 10% teal bg instead of full fill. Size 20→16px. Added :focus-visible outline for keyboard nav. NewProjectDialog.vue: add a local .ld-input-quiet class to all 5 v-text-field in the dialog (domain / phone / sms keyword / name / daily limit). The class overrides v-field outline border-color through :deep() to use the tokens.css 1px line / line-strong / teal palette, and sets border-radius to var(--radius-8). All variant/density/color values come from Vuetify global defaults in plugins/vuetify.ts:50-54. Includes opacity:1 on every override to neutralize Vuetify's --v-field-border-opacity 0.38 cascade, plus an explicit error-state rule with border-color:currentColor to preserve Vuetify's red error border. Twin elements left out of scope: .toolbar-check__box in ProjectsView.vue, v-combobox/v-autocomplete/v-btn-toggle inside the same dialog, and the filter-bar v-select inputs. Spec: docs/superpowers/specs/2026-05-12-quiet-luxury-elements-1440-896-design.md Plan: docs/superpowers/plans/2026-05-12-quiet-luxury-elements-1440-896.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,13 +2,14 @@
|
||||
<v-card class="project-card ld-hover-lift" :class="{ paused: !project.is_active }" elevation="1">
|
||||
<v-card-item>
|
||||
<template #prepend>
|
||||
<v-checkbox
|
||||
:model-value="selected"
|
||||
data-testid="card-select"
|
||||
hide-details
|
||||
density="compact"
|
||||
@change="$emit('toggle-select', project.id)"
|
||||
/>
|
||||
<label class="card-check" data-testid="card-select">
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="selected"
|
||||
@change="$emit('toggle-select', project.id)"
|
||||
/>
|
||||
<span class="card-check__box" />
|
||||
</label>
|
||||
</template>
|
||||
|
||||
<v-card-title>
|
||||
@@ -132,4 +133,49 @@ const syncStatusColor = computed(
|
||||
.project-card.paused {
|
||||
opacity: 0.75;
|
||||
}
|
||||
.card-check {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
padding: 4px;
|
||||
}
|
||||
.card-check input {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
.card-check__box {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border: 1px solid var(--liderra-line);
|
||||
border-radius: var(--radius-6);
|
||||
background: var(--liderra-surface);
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
transition:
|
||||
border-color 200ms cubic-bezier(0.16, 1, 0.3, 1),
|
||||
background-color 200ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
.card-check:hover .card-check__box {
|
||||
border-color: var(--liderra-line-strong);
|
||||
}
|
||||
.card-check input:focus-visible + .card-check__box {
|
||||
outline: 2px solid var(--liderra-teal);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
.card-check input:checked + .card-check__box {
|
||||
background: rgba(15, 110, 86, 0.10);
|
||||
border-color: var(--liderra-teal);
|
||||
}
|
||||
.card-check input:checked + .card-check__box::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 4px;
|
||||
top: 0;
|
||||
width: 5px;
|
||||
height: 9px;
|
||||
border: solid var(--liderra-teal);
|
||||
border-width: 0 1.5px 1.5px 0;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
label="Домен конкурента"
|
||||
placeholder="okna-konkurent.ru"
|
||||
:readonly="mode === 'edit'"
|
||||
class="ld-input-quiet"
|
||||
:error-messages="errors.signal_identifier"
|
||||
/>
|
||||
</v-tabs-window-item>
|
||||
@@ -33,6 +34,7 @@
|
||||
placeholder="79161234567"
|
||||
hint="Формат: 11 цифр, начинаются с 7"
|
||||
:readonly="mode === 'edit'"
|
||||
class="ld-input-quiet"
|
||||
:error-messages="errors.signal_identifier"
|
||||
/>
|
||||
</v-tabs-window-item>
|
||||
@@ -49,6 +51,7 @@
|
||||
v-model="form.sms_keyword"
|
||||
label="Ключевое слово (опционально)"
|
||||
hint="Если пусто — проект подключится только к B3"
|
||||
class="ld-input-quiet"
|
||||
:error-messages="errors.sms_keyword"
|
||||
/>
|
||||
</v-tabs-window-item>
|
||||
@@ -56,7 +59,7 @@
|
||||
|
||||
<v-divider class="my-4" />
|
||||
|
||||
<v-text-field v-model="form.name" label="Название проекта" :error-messages="errors.name" />
|
||||
<v-text-field v-model="form.name" label="Название проекта" class="ld-input-quiet" :error-messages="errors.name" />
|
||||
|
||||
<v-text-field
|
||||
v-model.number="form.daily_limit_target"
|
||||
@@ -64,6 +67,7 @@
|
||||
type="number"
|
||||
min="1"
|
||||
max="10000"
|
||||
class="ld-input-quiet"
|
||||
:error-messages="errors.daily_limit_target"
|
||||
/>
|
||||
|
||||
@@ -206,3 +210,38 @@ function close() {
|
||||
emit('update:modelValue', false);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ld-input-quiet :deep(.v-field) {
|
||||
border-radius: var(--radius-8);
|
||||
}
|
||||
.ld-input-quiet :deep(.v-field__outline__start),
|
||||
.ld-input-quiet :deep(.v-field__outline__end),
|
||||
.ld-input-quiet :deep(.v-field__outline__notch::before),
|
||||
.ld-input-quiet :deep(.v-field__outline__notch::after) {
|
||||
border-color: var(--liderra-line);
|
||||
opacity: 1;
|
||||
transition: border-color 200ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
.ld-input-quiet :deep(.v-field:hover .v-field__outline__start),
|
||||
.ld-input-quiet :deep(.v-field:hover .v-field__outline__end),
|
||||
.ld-input-quiet :deep(.v-field:hover .v-field__outline__notch::before),
|
||||
.ld-input-quiet :deep(.v-field:hover .v-field__outline__notch::after) {
|
||||
border-color: var(--liderra-line-strong);
|
||||
opacity: 1;
|
||||
}
|
||||
.ld-input-quiet :deep(.v-field--focused .v-field__outline__start),
|
||||
.ld-input-quiet :deep(.v-field--focused .v-field__outline__end),
|
||||
.ld-input-quiet :deep(.v-field--focused .v-field__outline__notch::before),
|
||||
.ld-input-quiet :deep(.v-field--focused .v-field__outline__notch::after) {
|
||||
border-color: var(--liderra-teal);
|
||||
opacity: 1;
|
||||
}
|
||||
.ld-input-quiet :deep(.v-field--error:not(.v-field--disabled) .v-field__outline__start),
|
||||
.ld-input-quiet :deep(.v-field--error:not(.v-field--disabled) .v-field__outline__end),
|
||||
.ld-input-quiet :deep(.v-field--error:not(.v-field--disabled) .v-field__outline__notch::before),
|
||||
.ld-input-quiet :deep(.v-field--error:not(.v-field--disabled) .v-field__outline__notch::after) {
|
||||
border-color: currentColor;
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user