const LUMA_CURTAIN_VERSION = '0.1.0'; class LumaCurtainCard extends HTMLElement { set hass(hass) { this._hass = hass; this._render(); } setConfig(config) { if (!config.entity) throw new Error('Entity is required'); this._config = { entity: config.entity, name: config.name || '', size: config.size || '1x1', accent_color: config.accent_color || '', icon: config.icon || '', tap_action: config.tap_action || { action: 'more-info' }, hold_action: config.hold_action || { action: 'more-info' }, ...config }; this._render(); } getCardSize() { return 2; } static getStubConfig() { return { entity: '', name: '', size: '1x1' }; } connectedCallback() { if (!this.shadowRoot) this.attachShadow({ mode: 'open' }); this._render(); } _getState() { return this._hass?.states?.[this._config?.entity]; } _getPosition() { const s = this._getState(); return parseFloat(s?.attributes?.current_position) || 0; } _isOpen() { return this._getPosition() > 5; } _handleClick() { if (!this._hass || !this._config) return; const ev = new Event('hass-more-info', { composed: true }); ev.detail = { entityId: this._config.entity }; this.dispatchEvent(ev); } _render() { if (!this.shadowRoot || !this._config) return; const pos = this._getPosition(); const isOpen = this._isOpen(); const name = this._config.name || this._getState()?.attributes?.friendly_name || ''; const icon = this._config.icon || 'mdi:curtains'; const accent = isOpen ? '#dcd2b4' : 'rgba(187,187,187,0.5)'; const label = pos > 0 ? `${Math.round(pos)}%` : 'Closed'; const closedPct = 1 - Math.min(pos / 100, 1); const closedOverlay = closedPct > 0.05 ? `rgba(12,16,36,${(0.5 * closedPct).toFixed(2)})` : 'transparent'; this.shadowRoot.innerHTML = `
Curtain
${name}
${label}
`; this.shadowRoot.querySelector('.card').addEventListener('click', () => this._handleClick()); } } customElements.define('luma-curtain-card', LumaCurtainCard); window.customCards = window.customCards || []; window.customCards.push({ type: 'luma-curtain-card', name: 'Luma Curtain', description: 'Luma-style cover/curtain card with position display.', preview: true }); console.info(`%c LUMA-CURTAIN-CARD %c v${LUMA_CURTAIN_VERSION} `, 'background:#dcd2b4;color:#111;font-weight:bold', 'background:#161a22;color:#dcd2b4');