// Album card for the Discover sections. // // Mirrors the Svelte AlbumCardLite: 220px column, 220px square artwork // with a bottom-left award ribbon, then a tight title / artist stack // alongside an icon-only quality badge. Deterministic height (274px) so // the section row never scrolls vertically. import { Theme } from "../foundation/semantic-colors.slint"; import { Typography } from "../foundation/typography.slint"; import { Radius } from "../foundation/radius.slint"; import { Spacing } from "../foundation/spacing.slint"; import { AlbumCardItem } from "../state.slint"; export component AlbumCard inherits Rectangle { in property album; // Fully deterministic height: artwork 220 + 6 spacer + 40 meta. width: 220px; height: 266px; VerticalLayout { alignment: start; spacing: 0px; // --- Artwork ------------------------------------------------------ Rectangle { width: 220px; height: 220px; border-radius: Radius.sm; background: Theme.surface-elevated; clip: true; // Cover art. Empty until the artwork pipeline resolves it, // leaving the elevated placeholder visible underneath. Image { width: 100%; height: 100%; source: root.album.artwork; image-fit: cover; } if root.album.ribbon != "": Rectangle { x: 0px; y: parent.height - self.height - 8px; height: 20px; background: root.album.ribbon-kind == "press" ? #d49511 : #000000e0; border-top-right-radius: 3px; border-bottom-right-radius: 3px; // Left accent stripe (not on the gold press ribbon). Rectangle { x: 0px; width: root.album.ribbon-kind == "press" ? 0px : 3px; background: root.album.ribbon-kind == "qobuzissime" ? #8b5cf6 : #eab308; } HorizontalLayout { padding-left: 10px; padding-right: 10px; Text { text: root.album.ribbon; color: root.album.ribbon-kind == "press" ? #1f1407 : #ffffff; font-size: 10px; font-weight: Typography.semibold; vertical-alignment: center; overflow: elide; } } } } Rectangle { height: 6px; } // --- Title / artist + quality badge ------------------------------ HorizontalLayout { height: 40px; spacing: Spacing.sm; VerticalLayout { alignment: center; spacing: 2px; horizontal-stretch: 1; Text { text: root.album.title; height: 20px; color: Theme.text-primary; font-size: Typography.body; font-weight: Typography.medium; vertical-alignment: center; overflow: elide; } Text { text: root.album.artist; height: 18px; color: Theme.text-muted; font-size: Typography.link; vertical-alignment: center; overflow: elide; } } // Icon-only quality badge. VerticalLayout { alignment: center; if root.album.quality-tier == "hires": Image { source: @image-url("../assets/hi-res.svg"); width: 42px; height: 28px; image-fit: contain; } if root.album.quality-tier == "cd": Rectangle { width: 30px; height: 30px; border-radius: 3px; background: Theme.surface-elevated; border-width: 1px; border-color: Theme.border-subtle; Image { x: (parent.width - self.width) / 2; y: (parent.height - self.height) / 2; width: 16px; height: 16px; source: @image-url("../assets/cd.svg"); image-fit: contain; } } } } } }