diff --git a/server/src/wled_controller/static/css/cards.css b/server/src/wled_controller/static/css/cards.css index 8ebc505..59670dc 100644 --- a/server/src/wled_controller/static/css/cards.css +++ b/server/src/wled_controller/static/css/cards.css @@ -99,6 +99,68 @@ section { ); } +/* ── Running target: rotating gradient border ── */ +@property --border-angle { + syntax: ''; + initial-value: 0deg; + inherits: false; +} + +.card-running { + border-color: transparent; +} + +/* When card has a custom color stripe, keep it and shift the animated border away from the left edge */ +.card-running[data-has-color]::before { + inset: 0 0 0 3px; + border-left: none; + border-radius: 0 8px 8px 0; +} + +.card-running::before { + content: ''; + position: absolute; + inset: 0; + border-radius: inherit; + border: 2px solid transparent; + background: + conic-gradient( + from var(--border-angle), + var(--primary-color), + rgba(255,255,255,0.1) 25%, + var(--primary-color) 50%, + rgba(255,255,255,0.1) 75%, + var(--primary-color) + ) border-box; + -webkit-mask: + linear-gradient(#fff 0 0) padding-box, + linear-gradient(#fff 0 0); + -webkit-mask-composite: xor; + mask: + linear-gradient(#fff 0 0) padding-box, + linear-gradient(#fff 0 0); + mask-composite: exclude; + pointer-events: none; + z-index: 2; + animation: rotateBorder 4s linear infinite; +} + +@keyframes rotateBorder { + to { --border-angle: 360deg; } +} + +[data-theme="light"] .card-running::before { + background: + conic-gradient( + from var(--border-angle), + var(--primary-color), + rgba(0,0,0,0.05) 25%, + var(--primary-color) 50%, + rgba(0,0,0,0.05) 75%, + var(--primary-color) + ) border-box; +} + /* ── Card entrance animation ── */ @keyframes cardEnter { from { opacity: 0; transform: translateY(12px); } diff --git a/server/src/wled_controller/static/js/core/card-colors.js b/server/src/wled_controller/static/js/core/card-colors.js index 38a441b..65f4ed3 100644 --- a/server/src/wled_controller/static/js/core/card-colors.js +++ b/server/src/wled_controller/static/js/core/card-colors.js @@ -102,7 +102,7 @@ export function wrapCard({ const actionsClass = type === 'template-card' ? 'template-card-actions' : 'card-actions'; const colorStyle = cardColorStyle(id); return ` -
+
${topButtons} diff --git a/server/src/wled_controller/static/js/features/targets.js b/server/src/wled_controller/static/js/features/targets.js index 84c3b93..3679e72 100644 --- a/server/src/wled_controller/static/js/features/targets.js +++ b/server/src/wled_controller/static/js/features/targets.js @@ -978,6 +978,7 @@ export function createTargetCard(target, deviceMap, colorStripSourceMap, valueSo return wrapCard({ dataAttr: 'data-target-id', id: target.id, + classes: isProcessing ? 'card-running' : '', removeOnclick: `deleteTarget('${target.id}')`, removeTitle: t('common.delete'), content: `