Frontend improvements: CSS foundations, accessibility, UX enhancements
CSS: Add design token variables (spacing, timing, weights, z-index layers), migrate all hardcoded z-index to named vars, fix light theme contrast for WCAG AA, add skeleton loading cards, mask-composite fallback, card padding. Accessibility: aria-live on toast, aria-label on health dots, sr-only class, graph container keyboard focusable, MQTT password wrapped in form element. UX: Modal auto-focus on open, inline field validation with blur, undo toast with countdown, bulk action progress indicator, API error toast on failure. i18n: Add common.undo, validation.required, bulk.processing, api.error.* keys in EN/RU/ZH. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,59 @@ section {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
/* ── Skeleton loading placeholders ── */
|
||||
@keyframes skeletonPulse {
|
||||
0%, 100% { opacity: 0.06; }
|
||||
50% { opacity: 0.12; }
|
||||
}
|
||||
|
||||
.skeleton-card {
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 16px 20px 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
min-height: 140px;
|
||||
}
|
||||
|
||||
.skeleton-line {
|
||||
height: 14px;
|
||||
border-radius: 4px;
|
||||
background: var(--text-color);
|
||||
animation: skeletonPulse 1.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.skeleton-line-title {
|
||||
width: 60%;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.skeleton-line-short {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.skeleton-line-medium {
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
.skeleton-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-top: auto;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.skeleton-btn {
|
||||
height: 32px;
|
||||
flex: 1;
|
||||
border-radius: var(--radius-sm);
|
||||
background: var(--text-color);
|
||||
animation: skeletonPulse 1.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.displays-grid,
|
||||
.devices-grid {
|
||||
display: grid;
|
||||
@@ -54,7 +107,7 @@ section {
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 12px 20px 20px;
|
||||
padding: 16px 20px 20px;
|
||||
position: relative;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
|
||||
display: flex;
|
||||
@@ -152,6 +205,17 @@ section {
|
||||
animation: rotateBorder 4s linear infinite;
|
||||
}
|
||||
|
||||
/* Fallback for browsers without mask-composite support (older Firefox) */
|
||||
@supports not (mask-composite: exclude) {
|
||||
.card-running::before {
|
||||
-webkit-mask: none;
|
||||
mask: none;
|
||||
background: none;
|
||||
border: 2px solid var(--primary-color);
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rotateBorder {
|
||||
to { --border-angle: 360deg; }
|
||||
}
|
||||
@@ -1192,7 +1256,7 @@ ul.section-tip li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
z-index: 1000;
|
||||
z-index: var(--z-bulk-toolbar);
|
||||
box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.3);
|
||||
transition: transform 0.25s ease;
|
||||
white-space: nowrap;
|
||||
|
||||
Reference in New Issue
Block a user