[1.3.0] — 2026-06-11
Added
Absolute-seconds thresholds — warning_threshold_sec and critical_threshold_sec trigger zones at a fixed number of remaining seconds, OR-combined with the existing percentage thresholds. A 4-hour sleep timer can now go critical at 60 s instead of at "5 % = 12 minutes".
Extend buttons — extend_buttons: [10, 30] renders +10m / +30m chips on active timers, calling the timer.change service.
Timestamp-sensor support — the card now counts down to any sensor with a future timestamp state (device_class: timestamp): washers, dryers, voice-assistant timers. Optional per-entity duration enables the progress bar; tap falls back to more-info.
Finished flash — a localized "✓ Done" badge shown for 5 s when a timer finishes naturally (detected locally at zero-crossing, with a state-transition fallback for throttled background tabs). Cancelling does not trigger it. show_finished / finished_label.
End-time display — show_ends_at: true shows the wall-clock finish time (→ 23:45), locale-formatted, refreshed live after extends.
more_info tap/hold action — now available in the visual editor and documented.
Localized default labels — Cancel/Pause/Resume/Paused/Done default to the HA UI language (en, cs, sk, de, fr, es, it, nl, pl); explicit *_label options still override.
use_ha_card option — render inside ha-card so theme card background, border, and radius apply.
Keyboard accessibility — rows are focusable (role="button", tabindex), Enter/Space triggers the tap action, visible focus ring; animations honor prefers-reduced-motion.
Sections layout support — implemented getGridOptions().
Visual editor: entity suggestions from your instance; new fields for seconds thresholds, extend buttons, end time, finished badge, and use_ha_card.
Console version banner and documentationURL in the card registry entry.
Changed
Countdown uses Math.ceil — a 30:00 timer starts at 30:00 (not 29:59) and never shows 0:00 while still running.
Paused timers keep their warning/critical zone color (dimmed) instead of reverting to base.
Card accent follows the most severe zone of all visible timers in stacked mode, not just the first row.
Server↔client clock-skew compensation — countdown calibrated against last_updated on live start transitions.
Theme integration — typography via --ha-font-family-body/--primary-font-family instead of hard-coded sans-serif; theme-neutral color fallbacks; alpha tints via color-mix().
Idle rows no longer duplicate the duration when show_duration is on; badge font bumped 9 → 10 px.
Tick refined to 250 ms with change-detection (DOM touched only when a rendered value changes); ticks also fire on tab-visibility restore.
Fixed
Warning/critical colors now switch on time — zones are evaluated by the internal ticker. Previously they were only re-evaluated when any entity in HA pushed a state update, so on a quiet instance the color could change late or never.
Per-entity tap/hold overrides in entities: were silently ignored — both the executed action and the badge always used the global setting.
All display options are now overridable per entity in stacked mode — previously only colors and labels were.
Stale hold flag on touch devices — after a long-press with a suppressed click, the next tap was swallowed; the flag now auto-resets.
Orphaned hold timeout after rebuild — a rebuild during a long-press could fire the hold action (e.g. cancel) ~500 ms later; hold timers are now instance-owned and cleared on rebuild.
unavailable entities rendered as idle and silently disappeared — they now show the ! error badge.
HTML injection / markup breakage — names, labels, and entity IDs are escaped everywhere; config colors validated before entering generated CSS.
3-digit hex colors parsed correctly; invalid colors fall back to the default accent.
Progress percentage clamped 0–100 — clock drift could yield negative bar widths.
Performance: unrelated hass updates ignored entirely; entity configs cached at setConfig; per-tick querySelector replaced by cached references; zone changes patch CSS custom properties instead of rebuilding the DOM.
Duplicate customElements.define guarded; CARD_VERSION aligned with the release tag