2026-06-19 11:21:29 -04:00
|
|
|
import { style } from '@vanilla-extract/css';
|
|
|
|
|
import { color, config, toRem } from 'folds';
|
|
|
|
|
|
|
|
|
|
// Right-side drawer that floats over the room view. 320px is wider than the
|
|
|
|
|
// 266px member/bookmark drawers because it hosts a media grid; on narrow
|
|
|
|
|
// viewports it expands to fill the screen, matching the app's other drawers.
|
|
|
|
|
export const MediaGalleryDrawer = style({
|
|
|
|
|
position: 'fixed',
|
|
|
|
|
top: 0,
|
|
|
|
|
right: 0,
|
|
|
|
|
bottom: 0,
|
|
|
|
|
width: toRem(320),
|
|
|
|
|
zIndex: 500,
|
|
|
|
|
overflow: 'hidden',
|
|
|
|
|
borderLeftWidth: config.borderWidth.B300,
|
|
|
|
|
borderLeftStyle: 'solid',
|
2026-06-19 13:07:51 -04:00
|
|
|
borderLeftColor: color.Background.ContainerLine,
|
2026-06-19 11:21:29 -04:00
|
|
|
'@media': {
|
|
|
|
|
'(max-width: 750px)': {
|
|
|
|
|
width: '100%',
|
|
|
|
|
borderLeftWidth: 0,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
export const MediaGalleryHeader = style({
|
|
|
|
|
flexShrink: 0,
|
2026-06-19 13:07:51 -04:00
|
|
|
padding: `0 ${config.space.S200} 0 ${config.space.S300}`,
|
2026-06-19 11:21:29 -04:00
|
|
|
borderBottomWidth: config.borderWidth.B300,
|
|
|
|
|
});
|
2026-06-19 13:07:51 -04:00
|
|
|
|
|
|
|
|
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',
|
|
|
|
|
});
|