From c006b6cabb12a6f979c9983002b8365820e9c031 Mon Sep 17 00:00:00 2001 From: MaryWylde Date: Thu, 18 Jun 2026 14:13:28 +0200 Subject: [PATCH] library: scale interactive cover to a fixed-height band The cover keeps the art's aspect ratio: below the art's natural 1920px width the band scales down with the viewport, and at/above 1920px it caps at 1920x852 centered with a blurred fill behind the side gaps. The hotspot layer shares the art's box so hover targets track at every width. Co-Authored-By: Claude Opus 4.7 --- .../InteractiveCover.module.scss | 55 +++++++++++++------ .../InteractiveCover/InteractiveCover.tsx | 11 ++++ src/layouts/library/Home/Home.module.scss | 4 +- 3 files changed, 51 insertions(+), 19 deletions(-) diff --git a/src/components/library/organisms/InteractiveCover/InteractiveCover.module.scss b/src/components/library/organisms/InteractiveCover/InteractiveCover.module.scss index 55473ca..3193d07 100644 --- a/src/components/library/organisms/InteractiveCover/InteractiveCover.module.scss +++ b/src/components/library/organisms/InteractiveCover/InteractiveCover.module.scss @@ -1,39 +1,60 @@ -// Coordinates in coverHotspots.ts are percentages of the cover frame, so the -// frame is locked to the artwork's native aspect ratio and every hotspot tracks -// the art as it scales. No runtime measurement needed. +// The cover keeps the art's aspect ratio and is never stretched or cropped. +// Below the art's natural width (1920px) the whole band scales down with the +// viewport — width fills, height shrinks proportionally. At/above 1920px it +// caps at its natural 1920×852 size, centered, with the blurred .background +// filling the side gaps so they read as intentional rather than empty. +// +// The .image and .layer share the same box (width: 100% capped at 1920px, +// centered), so the percentage hotspot coordinates in coverHotspots.ts track +// the art exactly at every width. // // Mobile (<768px) shows the taller 3:2 library.png; 768px+ shows the wide -// library-wide.png (3840x1704). The frame matches whichever art is visible so -// the cover always fills the width edge-to-edge with no crop and the height -// stays proportional across every desktop/tablet width. -$cover-aspect: calc(3 / 2); +// library-wide.png (3840x1704). +$cover-height: 852px; +$cover-max-width: 1920px; $cover-aspect-wide: calc(3840 / 1704); .frame { position: relative; width: 100%; - aspect-ratio: $cover-aspect; + aspect-ratio: $cover-aspect-wide; + max-height: $cover-height; overflow: hidden; } -@media (min-width: 768px) { - .frame { - aspect-ratio: $cover-aspect-wide; - } -} - -.image { +// Blurred copy of the art behind everything, so the side gaps on screens wider +// than the art read as intentional rather than empty bands. +.background { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; - object-position: center; + filter: blur(24px); + transform: scale(1.1); + z-index: 0; +} + +.image { + position: absolute; + top: 0; + left: 50%; + transform: translateX(-50%); + width: 100%; + max-width: $cover-max-width; + height: auto; + z-index: 1; } .layer { position: absolute; - inset: 0; + top: 0; + left: 50%; + transform: translateX(-50%); + width: 100%; + max-width: $cover-max-width; + height: 100%; + z-index: 2; } .trigger { diff --git a/src/components/library/organisms/InteractiveCover/InteractiveCover.tsx b/src/components/library/organisms/InteractiveCover/InteractiveCover.tsx index a522c9b..1f4fdd1 100644 --- a/src/components/library/organisms/InteractiveCover/InteractiveCover.tsx +++ b/src/components/library/organisms/InteractiveCover/InteractiveCover.tsx @@ -141,6 +141,17 @@ export function InteractiveCover({ return (
+ {/* Blurred fill so the side gaps on viewports wider than the art read as + intentional. Decorative — the below carries the real alt. */} + {/* eslint-disable-next-line @next/next/no-img-element */} + + {wideSrc && }