From 893ccff94f5ecf1f46d87a5db438b66aa2c1b0c0 Mon Sep 17 00:00:00 2001 From: Matysh Date: Fri, 31 Jul 2026 09:50:52 +0300 Subject: [PATCH] Centre the puck glyph ha-icon inside the puck lacked the .dev centering recipe (flex + line-height: 0), so the glyph sat on its text baseline and floated around the circle. The smoke now measures the glyph centre against the puck centre to sub-pixel tolerance. --- .../houseplan/frontend/houseplan-card.js | 14 +++++++++++++- demo/smoke_vacuum.mjs | 7 ++++++- demo/srv/assets/houseplan-card.js | 14 +++++++++++++- dist/houseplan-card.js | 14 +++++++++++++- src/styles.ts | 14 +++++++++++++- 5 files changed, 58 insertions(+), 5 deletions(-) diff --git a/custom_components/houseplan/frontend/houseplan-card.js b/custom_components/houseplan/frontend/houseplan-card.js index a48c3cf..0578536 100755 --- a/custom_components/houseplan/frontend/houseplan-card.js +++ b/custom_components/houseplan/frontend/houseplan-card.js @@ -1262,7 +1262,19 @@ const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow } .vacpuck.jump { transition: none; } .vacpuck.stale { opacity: 0.45; animation: none; } - .vacpuck ha-icon { --mdc-icon-size: calc(var(--puck-size) * 0.68); color: var(--hp-txt); } + .vacpuck ha-icon { + --mdc-icon-size: calc(var(--puck-size) * 0.68); + color: var(--hp-txt); + /* same centering recipe as .dev ha-icon: without flex + line-height 0 + the glyph sits on its text baseline and appears to float around the + circle (owner report 2026-07-31) */ + display: flex; + align-items: center; + justify-content: center; + line-height: 0; + width: var(--mdc-icon-size); + height: var(--mdc-icon-size); + } @keyframes vacpulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--hp-accent) 45%, transparent); } 70% { box-shadow: 0 0 0 12px transparent; } diff --git a/demo/smoke_vacuum.mjs b/demo/smoke_vacuum.mjs index 4cfa6db..b849067 100644 --- a/demo/smoke_vacuum.mjs +++ b/demo/smoke_vacuum.mjs @@ -41,6 +41,11 @@ const out = await page.evaluate(async () => { o.puck80pct = Math.abs(puck.getBoundingClientRect().width - devEl.getBoundingClientRect().width * 0.8) < 2; o.noWedge = !sr().querySelector('.vacwedge'); // owner 2026-07-31: no heading arrow + // the glyph is DEAD centre (owner report: it floated on the text baseline) + const pr = puck.getBoundingClientRect(); + const ir = sr().querySelector('.vacpuck ha-icon').getBoundingClientRect(); + o.iconCentred = Math.abs(ir.left + ir.width / 2 - (pr.left + pr.width / 2)) < 0.75 + && Math.abs(ir.top + ir.height / 2 - (pr.top + pr.height / 2)) < 0.75; o.baseStaysDuringCleaning = !!sr().querySelector('.dev'); // drive: two more points -> trail polyline grows; puck moves @@ -122,7 +127,7 @@ const out = await page.evaluate(async () => { checkAll(out, { dockedNoPuck: true, baseMarkerThere: true, puckAppears: true, puckRound: true, puckPlateMatchesDev: true, puck80pct: true, - noWedge: true, baseStaysDuringCleaning: true, trailDrawn: true, + noWedge: true, iconCentred: true, baseStaysDuringCleaning: true, trailDrawn: true, trailScaledByMatrix: true, trailToggleOff: true, puckGoneWhenDocked: true, trailLingers: true, hiddenNoPuck: true, unknownMapNoPuck: true, diff --git a/demo/srv/assets/houseplan-card.js b/demo/srv/assets/houseplan-card.js index a48c3cf..0578536 100755 --- a/demo/srv/assets/houseplan-card.js +++ b/demo/srv/assets/houseplan-card.js @@ -1262,7 +1262,19 @@ const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow } .vacpuck.jump { transition: none; } .vacpuck.stale { opacity: 0.45; animation: none; } - .vacpuck ha-icon { --mdc-icon-size: calc(var(--puck-size) * 0.68); color: var(--hp-txt); } + .vacpuck ha-icon { + --mdc-icon-size: calc(var(--puck-size) * 0.68); + color: var(--hp-txt); + /* same centering recipe as .dev ha-icon: without flex + line-height 0 + the glyph sits on its text baseline and appears to float around the + circle (owner report 2026-07-31) */ + display: flex; + align-items: center; + justify-content: center; + line-height: 0; + width: var(--mdc-icon-size); + height: var(--mdc-icon-size); + } @keyframes vacpulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--hp-accent) 45%, transparent); } 70% { box-shadow: 0 0 0 12px transparent; } diff --git a/dist/houseplan-card.js b/dist/houseplan-card.js index a48c3cf..0578536 100755 --- a/dist/houseplan-card.js +++ b/dist/houseplan-card.js @@ -1262,7 +1262,19 @@ const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow } .vacpuck.jump { transition: none; } .vacpuck.stale { opacity: 0.45; animation: none; } - .vacpuck ha-icon { --mdc-icon-size: calc(var(--puck-size) * 0.68); color: var(--hp-txt); } + .vacpuck ha-icon { + --mdc-icon-size: calc(var(--puck-size) * 0.68); + color: var(--hp-txt); + /* same centering recipe as .dev ha-icon: without flex + line-height 0 + the glyph sits on its text baseline and appears to float around the + circle (owner report 2026-07-31) */ + display: flex; + align-items: center; + justify-content: center; + line-height: 0; + width: var(--mdc-icon-size); + height: var(--mdc-icon-size); + } @keyframes vacpulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--hp-accent) 45%, transparent); } 70% { box-shadow: 0 0 0 12px transparent; } diff --git a/src/styles.ts b/src/styles.ts index 14d4a9e..1a40a84 100644 --- a/src/styles.ts +++ b/src/styles.ts @@ -1259,7 +1259,19 @@ export const cardStyles = css` } .vacpuck.jump { transition: none; } .vacpuck.stale { opacity: 0.45; animation: none; } - .vacpuck ha-icon { --mdc-icon-size: calc(var(--puck-size) * 0.68); color: var(--hp-txt); } + .vacpuck ha-icon { + --mdc-icon-size: calc(var(--puck-size) * 0.68); + color: var(--hp-txt); + /* same centering recipe as .dev ha-icon: without flex + line-height 0 + the glyph sits on its text baseline and appears to float around the + circle (owner report 2026-07-31) */ + display: flex; + align-items: center; + justify-content: center; + line-height: 0; + width: var(--mdc-icon-size); + height: var(--mdc-icon-size); + } @keyframes vacpulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--hp-accent) 45%, transparent); } 70% { box-shadow: 0 0 0 12px transparent; }