From 74190c5a7ba59629d84cb3ce940e93300babaf6e Mon Sep 17 00:00:00 2001 From: MaryWylde Date: Mon, 17 Aug 2026 14:51:00 +0200 Subject: [PATCH 1/4] fix(library): stretch the step connector between both step circles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The connector was anchored to both circles with left/right, but also carried a fixed `width: 79.5%` that won over the right anchor — so the line stopped short of step 2 at every viewport except the one the percentage was eyeballed at. Co-Authored-By: Claude Opus 4.7 --- .../library/molecules/StepIndicator/StepIndicator.module.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/library/molecules/StepIndicator/StepIndicator.module.scss b/src/components/library/molecules/StepIndicator/StepIndicator.module.scss index e7f019e..b0029cb 100644 --- a/src/components/library/molecules/StepIndicator/StepIndicator.module.scss +++ b/src/components/library/molecules/StepIndicator/StepIndicator.module.scss @@ -103,7 +103,6 @@ top: 18px; left: 46px; right: 46px; - width: 79.5%; height: 1px; background: var(--gray-100); overflow: hidden; From ec89891b7d0697e2bfa4b8835a0c0bfd442245c7 Mon Sep 17 00:00:00 2001 From: MaryWylde Date: Mon, 17 Aug 2026 14:51:16 +0200 Subject: [PATCH 2/4] fix(library): match the tag multi-select trigger to the dropdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The two fields stack in the same form but were never given the same geometry, so they read as two unrelated controls: different heights and only the dropdown had a divider before its chevron. The multi-select now mirrors the dropdown trigger — 44px tall, 8px radius, and a chevron wrapper that carries the divider and recolors with the border on hover. Co-Authored-By: Claude Opus 4.7 --- .../TagMultiSelect/TagMultiSelect.module.scss | 30 +++++++++++++++++-- .../TagMultiSelect/TagMultiSelect.tsx | 12 ++++---- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/components/library/molecules/TagMultiSelect/TagMultiSelect.module.scss b/src/components/library/molecules/TagMultiSelect/TagMultiSelect.module.scss index b8eafd4..6dc6848 100644 --- a/src/components/library/molecules/TagMultiSelect/TagMultiSelect.module.scss +++ b/src/components/library/molecules/TagMultiSelect/TagMultiSelect.module.scss @@ -8,25 +8,35 @@ position: relative; } +// Geometry mirrors the Dropdown trigger so the two fields read as one control +// when they stack in a form: same height, padding, radius, and chevron divider. .trigger { width: 100%; + height: 44px; + box-sizing: border-box; display: flex; align-items: center; justify-content: space-between; gap: 8px; background: var(--white); border: 1px solid var(--brown-border); - border-radius: 4px; - padding: 12px 16px; + border-radius: 8px; + padding: 0 0 0 12px; cursor: pointer; + transition: all 0.2s ease; &:disabled { opacity: 0.5; cursor: not-allowed; } - &.open { + &.open, + &:not(:disabled):hover { border-color: var(--brown); + + .iconWrapper { + border-left: 1px solid var(--brown); + } } .placeholder { @@ -35,13 +45,27 @@ color: var(--black); } + .iconWrapper { + border-left: 1px solid var(--brown-border); + height: -webkit-fill-available; + padding: 0 16px; + display: flex; + align-items: center; + justify-content: center; + } + .icon { + flex-shrink: 0; transform: rotate(90deg); transition: transform 0.2s ease; &.rotated { transform: rotate(-90deg); } + + path { + fill: var(--brown); + } } } diff --git a/src/components/library/molecules/TagMultiSelect/TagMultiSelect.tsx b/src/components/library/molecules/TagMultiSelect/TagMultiSelect.tsx index 7969576..0a2e4b5 100644 --- a/src/components/library/molecules/TagMultiSelect/TagMultiSelect.tsx +++ b/src/components/library/molecules/TagMultiSelect/TagMultiSelect.tsx @@ -67,11 +67,13 @@ export function TagMultiSelect(props: TagMultiSelectProps): JSX.Element { > {value.length > 0 ? `${value.length} selected` : placeholder} - +
+ +
{isOpen && (!portal || menuPos) && From ed59c12cad5c51bab0ec786f5640c011a6ce89c2 Mon Sep 17 00:00:00 2001 From: MaryWylde Date: Mon, 17 Aug 2026 14:51:30 +0200 Subject: [PATCH 3/4] fix(library): shrink the empty tags box to 44px The placeholder row was pinned to 50px, which with the wrapper's 12px padding made a 74px box holding a single line of text. Pinning the row to its 20px line box brings the container to 44px. Co-Authored-By: Claude Opus 4.7 --- src/components/library/organisms/Sidebar/Sidebar.module.scss | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/library/organisms/Sidebar/Sidebar.module.scss b/src/components/library/organisms/Sidebar/Sidebar.module.scss index f661b41..60771ee 100644 --- a/src/components/library/organisms/Sidebar/Sidebar.module.scss +++ b/src/components/library/organisms/Sidebar/Sidebar.module.scss @@ -133,13 +133,15 @@ display: flex; flex-wrap: wrap; + // 20px row + the wrapper's 12px padding = a 44px box. &.tagsEmpty { - height: 50px; + height: 20px; align-items: center; } .emptyTags { color: var(--gray-medium); + line-height: 20px; } .button { From 65b79fce0455e91dac7484dc4d69f615ef336df4 Mon Sep 17 00:00:00 2001 From: MaryWylde Date: Mon, 17 Aug 2026 14:51:42 +0200 Subject: [PATCH 4/4] fix(library): size cover hotspots to the buildings they light up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every hit box had drifted off its artwork — up to 4% horizontally and 14% vertically — so only the rooflines answered the pointer. Each box is now measured against the silhouette its glow SVG actually draws, for the wide and panorama art independently. house-2 is the tree behind the buildings rather than a building of its own, so its box necessarily overlaps John's pagoda. Overlapping triggers share a z-index and the last declaration wins the pointer, so the tree moves to the front of the array and the buildings keep their own areas. Verified by hovering a 5x5 grid inside each building at 1024/1440/1920/ 2560px: every building resolves to its own card, and the samples where the tree loses are the ones John's pagoda sits in front of. Co-Authored-By: Claude Opus 4.7 --- .../InteractiveCover/coverHotspots.ts | 66 ++++++++++--------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/src/components/library/organisms/InteractiveCover/coverHotspots.ts b/src/components/library/organisms/InteractiveCover/coverHotspots.ts index 2140619..cab5b44 100644 --- a/src/components/library/organisms/InteractiveCover/coverHotspots.ts +++ b/src/components/library/organisms/InteractiveCover/coverHotspots.ts @@ -123,11 +123,39 @@ const makeHotspot = ( const lorem = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cih sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus'; +// Hit boxes are sized to the glow silhouette each hotspot lights up, so the +// whole building answers the pointer rather than just its roofline. +// +// Order matters: overlapping triggers share a z-index, so the last one declared +// wins the pointer. The tree (house-2) is the backdrop the buildings sit in +// front of, so it goes first and the buildings keep their own hover areas. export const coverHotspots: CoverHotspot[] = [ + makeHotspot( + 'house-2', + { + // The glow here traces the tree, not a building — hence the wide box. + hit: { left: 17.76, top: 0, width: 30.85, height: 55 }, + highlight: { + src: '/library/images/hotspots/house-2.svg', + alt: '', + left: 17.98, + top: 0, + width: 47.06, + }, + card: { left: 53.0, top: 19.01 }, + }, + { + libraryName: 'Sarah’s Library', + about: lorem, + bookCount: 88, + videoCount: 34, + songCount: 12, + }, + ), makeHotspot( 'house-1', { - hit: { left: 37.73, top: 11.9, width: 12.55, height: 35.9 }, + hit: { left: 41.45, top: 20.02, width: 13.13, height: 29.79 }, highlight: { src: '/library/images/hotspots/house-1.svg', alt: '', @@ -145,36 +173,15 @@ export const coverHotspots: CoverHotspot[] = [ songCount: 17, }, { - hit: { left: 45.8, top: 11.9, width: 6 }, + // The panorama art sits 0.33% lower here, matching the highlight offset. + hit: { top: 20.35 }, highlight: { left: 45.6, top: 7.9 }, }, ), - makeHotspot( - 'house-2', - { - hit: { left: 14.13, top: 2, width: 22.41, height: 60 }, - highlight: { - src: '/library/images/hotspots/house-2.svg', - alt: '', - left: 17.98, - top: 0, - width: 47.06, - }, - card: { left: 53.0, top: 19.01 }, - }, - { - libraryName: 'Sarah’s Library', - about: lorem, - bookCount: 88, - videoCount: 34, - songCount: 12, - }, - { hit: { left: 34.7824, top: 0 } }, - ), makeHotspot( 'house-3', { - hit: { left: 27.58, top: 43, width: 12.7, height: 34 }, + hit: { left: 31.13, top: 50.79, width: 15.57, height: 37.59 }, highlight: { src: '/library/images/hotspots/house-3.svg', alt: '', @@ -192,14 +199,14 @@ export const coverHotspots: CoverHotspot[] = [ songCount: 9, }, { - hit: { left: 41, top: 52, width: 7.096, height: 34 }, + hit: { top: 49.79 }, highlight: { left: 40.4, top: 17.5 }, }, ), makeHotspot( 'house-4', { - hit: { left: 17.12, top: 57, width: 10.46, height: 17 }, + hit: { left: 20.02, top: 61.73, width: 11.43, height: 22.42 }, highlight: { src: '/library/images/hotspots/house-4.svg', alt: '', @@ -217,7 +224,7 @@ export const coverHotspots: CoverHotspot[] = [ songCount: 6, }, { - hit: { left: 35.6, top: 66 }, + hit: { top: 60.83 }, highlight: { left: 35.552, top: 28 }, }, ), @@ -225,7 +232,7 @@ export const coverHotspots: CoverHotspot[] = [ 'house-5', { // Leader line exits to the LEFT, so the card sits left of the lantern. - hit: { left: 61.94, top: 38, width: 8.96, height: 26 }, + hit: { left: 65.44, top: 49.75, width: 8.59, height: 24.69 }, highlight: { src: '/library/images/hotspots/house-5.svg', alt: '', @@ -242,6 +249,5 @@ export const coverHotspots: CoverHotspot[] = [ videoCount: 14, songCount: 4, }, - { hit: { left: 57.7312, top: 44, width: 4.3008, height: 28 } }, ), ];