import { style } from '@vanilla-extract/css'; import { color, config, toRem } from 'folds'; // Right-side drawer DOCKED into the room layout row (a flex sibling of the // timeline), exactly like MembersDrawer — not a floating overlay. 320px is a // little wider than the 266px member/bookmark drawers because it hosts a media // grid. On narrow viewports it becomes a full-screen fixed panel, matching the // app's other drawers. export const MediaGalleryDrawer = style({ width: toRem(320), overflow: 'hidden', '@media': { '(max-width: 750px)': { position: 'fixed', inset: 0, width: '100%', zIndex: 500, }, }, }); export const MediaGalleryHeader = style({ flexShrink: 0, padding: `0 ${config.space.S200} 0 ${config.space.S300}`, borderBottomWidth: config.borderWidth.B300, }); export const MediaGalleryTabs = style({ flexShrink: 0, padding: config.space.S200, gap: config.space.S100, borderBottomWidth: config.borderWidth.B300, borderBottomStyle: 'solid', borderBottomColor: color.Background.ContainerLine, }); export const MediaGalleryContent = style({ padding: config.space.S200, }); export const MediaGalleryGroup = style({ marginBottom: config.space.S300, }); export const MediaGalleryGroupLabel = style({ padding: `${config.space.S200} ${config.space.S100}`, }); export const MediaGalleryGrid = style({ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: config.space.S100, }); export const GalleryTile = style({ position: 'relative', aspectRatio: '1', overflow: 'hidden', borderRadius: config.radii.R300, background: color.SurfaceVariant.Container, borderWidth: config.borderWidth.B300, borderStyle: 'solid', borderColor: color.SurfaceVariant.ContainerLine, cursor: 'pointer', padding: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'border-color 100ms ease-in-out', selectors: { '&:hover, &:focus-visible': { borderColor: color.Primary.Main, }, }, }); export const GalleryTileImg = style({ width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center top', display: 'block', }); // Dark scrim is intentional: it overlays arbitrary media, so a theme surface // token would not guarantee legibility of the sender/date caption. export const GalleryTileOverlay = style({ position: 'absolute', inset: 0, background: 'linear-gradient(to top, rgba(0,0,0,0.72) 0%, transparent 55%)', opacity: 0, transition: 'opacity 100ms ease-in-out', pointerEvents: 'none', selectors: { [`${GalleryTile}:hover &, ${GalleryTile}:focus-visible &`]: { opacity: 1, }, }, }); export const GalleryTileCaption = style({ position: 'absolute', bottom: 0, left: 0, right: 0, padding: `${config.space.S100} ${config.space.S200}`, }); export const GalleryVideoBadge = style({ position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', width: toRem(28), height: toRem(28), borderRadius: '50%', background: 'rgba(0,0,0,0.6)', display: 'flex', alignItems: 'center', justifyContent: 'center', pointerEvents: 'none', });