/* ---- Tile grid (library/artist pages) + tiles (shared with the home carousels) - see tiles.ts. ---- */ /* base.css's global `input {}` rule already gives this the right look (padding/border/background) - this just bounds its width and spaces it from the grid below, shared by views/library, views/artist, views/album - see tiles.ts's wireSearchFilter. Sticky, not just top-of-page: asked for directly, so it stays reachable while scrolling a long grid instead of scrolling away with the page title above it. Its own background (base.css's input rule already gives it var(--panel), not transparent) is what keeps tiles scrolling underneath from showing through its own bounds once stuck. */ .searchBar { max-width: 320px; margin-bottom: 16px; position: sticky; top: 0; z-index: 2; } .searchEmpty { margin-top: 8px; } /* The 160px floor was too wide for a real phone once .mainContent's own side padding is subtracted - reported directly: a ~360-393px-wide viewport (a common real Android width, not a rare edge case) only ever fit one column. clamp(), not a max-width media query breakpoint: this scales the minimum continuously with the viewport instead of jumping at one arbitrary width, so it's already right at every size in between, not just "mobile" and "desktop" - 28vw lands close to 100px on a narrow phone and hits the 160px ceiling (today's exact desktop value, unchanged) well before any actual desktop width. */ .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(clamp(100px, 28vw, 160px), 1fr)); gap: 20px 16px; } .tile { position: relative; display: flex; flex-direction: column; gap: 6px; /* Without this, a long title (or an image's intrinsic size before it loads) can force this flex/grid item wider than its declared size - the classic "min-width: auto" flexbox/grid pitfall. Every tile must stay exactly the track/flex-basis size regardless of content. */ min-width: 0; } .tile img { width: 100%; aspect-ratio: 2 / 3; object-fit: cover; border-radius: 8px; background: var(--panel); display: block; } .tile img.noImage { visibility: hidden; } .tileLink { position: absolute; inset: 0 0 26px 0; z-index: 1; } .tileLabel { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* Hover-reveal overlay with the two actions, on devices that actually have hover (mouse/trackpad). Touch devices get an always-visible bar instead - see the (hover: none) block below, since :hover is unreachable there. */ .tileOverlay { position: absolute; inset: 0 0 26px 0; z-index: 2; display: flex; flex-direction: column; align-items: stretch; justify-content: center; gap: 8px; padding: 10px; background: rgba(0, 0, 0, .55); border-radius: 8px; opacity: 0; transition: opacity .15s ease; pointer-events: none; } .tile:hover .tileOverlay, .tile:focus-within .tileOverlay { opacity: 1; pointer-events: auto; } /* Base look is the same solid, high-contrast treatment as every other button in the app (see base.css's global `button {}` rule) - but that rule is tag-scoped, so it never applied to "Voir les épisodes", the one .tileBtn that's an , not a