{"id":49267215,"url":"https://github.com/f17mkx/superpro-shutter-card","last_synced_at":"2026-04-25T11:01:40.461Z","repository":{"id":353614911,"uuid":"1219975337","full_name":"f17mkx/superpro-shutter-card","owner":"f17mkx","description":"Branded Home Assistant Lovelace card for animated shutter/cover control with first-class dark-mode theming and accessibility. Fork of marcelhoogantink/enhanced-shutter-card.","archived":false,"fork":false,"pushed_at":"2026-04-24T17:06:19.000Z","size":4726,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-24T18:25:25.824Z","etag":null,"topics":["cover","hacs","hacs-default","home-assistant","home-automation","lovelace-card","lovelace-custom-cards","shutter"],"latest_commit_sha":null,"homepage":"https://github.com/f17mkx/superpro-shutter-card","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/f17mkx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-24T12:17:02.000Z","updated_at":"2026-04-24T17:06:11.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/f17mkx/superpro-shutter-card","commit_stats":null,"previous_names":["f17mkx/superpro-shutter-card"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/f17mkx/superpro-shutter-card","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f17mkx%2Fsuperpro-shutter-card","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f17mkx%2Fsuperpro-shutter-card/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f17mkx%2Fsuperpro-shutter-card/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f17mkx%2Fsuperpro-shutter-card/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/f17mkx","download_url":"https://codeload.github.com/f17mkx/superpro-shutter-card/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f17mkx%2Fsuperpro-shutter-card/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32259472,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-25T09:15:33.318Z","status":"ssl_error","status_checked_at":"2026-04-25T09:15:31.997Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cover","hacs","hacs-default","home-assistant","home-automation","lovelace-card","lovelace-custom-cards","shutter"],"created_at":"2026-04-25T11:01:39.176Z","updated_at":"2026-04-25T11:01:40.447Z","avatar_url":"https://github.com/f17mkx.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# superpro-shutter-card\n\n\u003e Branded Home Assistant Lovelace card for animated shutter/cover control. First-class dark-mode theming, accessibility, and internationalisation.\n\n![Superpro Shutter Card](example.png)\n\n**Status**: v1.0 - HACS default store\n**Upstream base**: [marcelhoogantink/enhanced-shutter-card](https://github.com/marcelhoogantink/enhanced-shutter-card) @ v1.5.2\n**Author**: Stefan Volk ([@f17mkx](https://github.com/f17mkx))\n\n## Install\n\n### Via HACS (recommended)\n\n1. Open HACS in Home Assistant\n2. Search for \"Superpro Shutter Card\"\n3. Download\n4. Restart HA (or refresh resources)\n\n### Manual\n\nDrop `dist/superpro-shutter-card.js` into `\u003cconfig\u003e/www/community/superpro-shutter-card/`, then add it as a Lovelace resource:\n\n```yaml\nurl: /hacsfiles/superpro-shutter-card/superpro-shutter-card.js\ntype: module\n```\n\n### Use it in your Lovelace YAML\n\n```yaml\ntype: custom:superpro-shutter-card\nentities:\n  - entity: cover.your_shutter\n```\n\nFor full configuration options see the upstream [enhanced-shutter-card docs](https://github.com/marcelhoogantink/enhanced-shutter-card#configuration) - all YAML options are forward-compatible; only the `type:` prefix changes from `custom:enhanced-shutter-card` to `custom:superpro-shutter-card`.\n\n## Why this fork\n\n`enhanced-shutter-card` is the active fork of the classic `Deejayfool/hass-shutter-card` and already covers the functional baseline. `superpro-shutter-card` adds signature features that would be scope-creep upstream:\n\n1. **True dark-mode theming** - SVG slats + CSS-vars from HA theme, not hardcoded hex PNGs\n2. **Accessibility** - ARIA labels on all buttons, position announcements, keyboard focus\n3. **Clean console** - fixes the known „Could not find div.card\" / „Could not find grid container\" noise\n4. **Performance budget** - bundle \u003c 100KB gzipped, render memoisation per entity\n5. **Test harness** - Vitest unit tests + Playwright smoke tests against an HA-stub\n6. **i18n** - DE + EN + FR + ES translations via HA's localize API\n\n## Roadmap\n\n- **v0.1** - Rebranded fork of enhanced-shutter-card v1.5.2, no behavior change ✅\n- **v0.2** - Dark-mode theming (CSS theme tokens + PNG dark-filter) ✅\n- **v0.3** - Accessibility + clean console ✅\n- **v0.4** - i18n (DE/EN/FR/ES) ✅\n- **v0.5** - Test harness (Vitest + Playwright + Rollup build, CI green-bar) ✅\n- **v1.0** - HACS default store submission + public launch ✅\n- **v1.x** - Performance budget (bundle \u003c100KB gzipped, render memoisation), additional locales (it/nl/pt), translation file split\n\n### v0.2 theming knobs\n\nThe card now honours these CSS custom properties. Set them in your HA theme YAML to override:\n\n| Property | Default | Purpose |\n|---|---|---|\n| `--esc-tilt-container-bg` | `var(--secondary-background-color, #f9f9f9)` | Tilt widget background |\n| `--esc-tilt-container-border` | `var(--divider-color, grey)` | Tilt widget border |\n| `--esc-tilt-line-color` | `var(--error-color, red)` | Tilt-angle indicator line |\n| `--esc-movement-overlay-bg` | `rgba(0,0,0,0.3)` | \"Shutter moving\" overlay tint |\n| `--esc-dark-asset-filter` | `brightness(0.82) contrast(1.08) saturate(0.92)` | CSS filter applied to legacy PNG assets under `prefers-color-scheme: dark` |\n\nOpt out of the dark filter for a single card: set `data-force-light=\"1\"` on the card element. Force the filter on regardless of OS pref: `data-force-dark=\"1\"`.\n\n### v0.3 a11y knobs\n\nThe card is now navigable by keyboard, announces position changes politely to screen readers, and stops emitting harmless console warnings in panel-view dashboards.\n\n| Aspect | Behaviour |\n|---|---|\n| Keyboard focus ring | `outline: 2px solid var(--focus-ring-color, currentColor)` on `:focus-visible` only (mouse clicks stay clean) |\n| ARIA labels | Up / Stop / Down / Tilt / Partial / position-grid buttons each carry `aria-label` mirroring the localised tooltip; decorative icons are `aria-hidden=\"true\"` |\n| Live region | A visually-hidden `role=\"status\" aria-live=\"polite\"` element announces \"{Friendly name}: {position text}\" on settled-state changes, debounced 500ms so dragging or rapid streams don't spam |\n| Lock indicator | `passive_mode: true` renders the lock icon with `role=\"img\" aria-label=\"locked\"` |\n| Console hygiene | The two upstream warnings „Could not find div.card\" and „Could not find grid container\" are now silently no-op'd in panel layouts where they're expected. Set `SILENCE = false` at the top of `dist/superpro-shutter-card.js` to bring them back for debugging |\n| Group label | Each shutter is wrapped in `role=\"group\" aria-label=\"{Friendly name}\"` so screen readers can navigate by entity |\n\nTested manually with macOS VoiceOver against an HA dashboard. v0.5's Playwright harness will codify this as automated regression coverage.\n\n### v0.4 i18n (DE / EN / FR / ES)\n\nThe card follows your HA UI language automatically: switch HA to Deutsch, Français, or Español and every label re-renders without a page reload. Other locales fall back to English.\n\n| Source | What's translated |\n|---|---|\n| `hass.localize()` (HA core) | Cover states (`open`, `closed`, `opening`, `closing`), action verbs on the up/stop/down/tilt buttons, `unavailable` |\n| Card-private `TRANSLATIONS` dict | \"Battery\"/\"Signal\" aria-prefixes, \"locked\" (passive-mode lock), \"Fully open / closed\", \"Partially open / closed\", \"Tilt\" position-text prefix |\n| `Intl.NumberFormat(locale, { style: 'percent' })` | Position percentage display - `de` and `fr` get the locale-correct non-breaking space (\"55 %\"); `en` and `es` stay compact (\"55%\") |\n\n**Out of scope on purpose:** preset config tokens (`awning`, `curtain`, `roller-shutter`, `shade`, `blind`) are NOT translated - they are YAML config keys and translating them would break existing users' dashboards. Console warnings stay English (developer-facing).\n\n#### Contributing a new locale\n\n1. Open `dist/superpro-shutter-card.js`, find the `TRANSLATIONS` const (just below `LOCALIZE_TEXT`).\n2. Add a new top-level entry keyed by ISO 639-1 lowercase code (e.g. `it`, `nl`, `pt`).\n3. Translate all keys present in the `en` block - the lookup is `TRANSLATIONS[lang]?.[key] ?? TRANSLATIONS.en?.[key]`, so any missing key silently falls back to English (graceful, but you do want full coverage).\n4. Test locally: change HA → Profile → Language to your new locale, reload the dashboard, eyeball each shutter card.\n5. PR with a screenshot per state (open / partial / closed / locked).\n\nA future v0.6+ release will split these into `translations/\u003clang\u003e.json` files behind the build pipeline; until then the inline dict keeps the per-card YAML migration simple.\n\n## Development\n\nv0.5 introduced a proper toolchain: source lives in `src/`, Rollup bundles it into `dist/superpro-shutter-card.js` (Lit 3.x inlined), and CI runs the full test suite on every PR.\n\n```bash\nnpm install         # one-time\nnpm run build       # src/ -\u003e dist/superpro-shutter-card.js (IIFE, ~165KB)\nnpm test            # vitest unit suite (60+ tests on pure logic)\nnpm run test:e2e    # playwright smoke against an HA-stub HTML page\n```\n\n`dist/` is committed - HACS users grab it raw, no install step on their side. CI rebuilds and byte-compares against the committed copy to catch drift (see `scripts/check-dist-drift.mjs`).\n\nTo iterate against a live HA instance: `npm run build`, then `scp dist/superpro-shutter-card.js dist/images/* hassio:/config/www/community/superpro-shutter-card/` and reload.\n\n## Credits\n\nUpstream lineage:\n\n- `Deejayfool/hass-shutter-card` - original card (2022-)\n- `marcelhoogantink/enhanced-shutter-card` - active fork with Tilt + presets (2024-, GPL-3.0)\n- `f17mkx/superpro-shutter-card` - this branded fork adding signature features (2026-, GPL-3.0)\n\n## License\n\nGPL-3.0-or-later - see [LICENSE](LICENSE). Our direct upstream `enhanced-shutter-card` is GPL-3.0 as of its 2024-10 initial commit; this fork inherits that license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ff17mkx%2Fsuperpro-shutter-card","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ff17mkx%2Fsuperpro-shutter-card","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ff17mkx%2Fsuperpro-shutter-card/lists"}