110 lines
3.4 KiB
TypeScript
110 lines
3.4 KiB
TypeScript
import { style } from '@vanilla-extract/css';
|
|
import { color, toRem } from 'folds';
|
|
import { VOJO_HORSESHOE_RADIUS_PX } from '../../styles/horseshoe';
|
|
|
|
// Outer container — anchor for the two absolutely-positioned panes
|
|
// (`appBody` and `silhouette`). Same shape as the settings-sheet
|
|
// container, see that file for the full rationale.
|
|
export const container = style({
|
|
position: 'relative',
|
|
display: 'flex',
|
|
flex: 1,
|
|
flexDirection: 'column',
|
|
minWidth: 0,
|
|
minHeight: 0,
|
|
overflow: 'hidden',
|
|
});
|
|
|
|
// Holds the wrapped chat column. Stays put — clip-path carves the
|
|
// bottom edge so virtualized timeline rows aren't re-measured
|
|
// mid-gesture. `backgroundColor` opaque so the void colour painted
|
|
// on the container doesn't bleed through any transparent slivers
|
|
// in the wrapped tree (e.g. between bubble rows).
|
|
export const appBody = style({
|
|
position: 'absolute',
|
|
top: 0,
|
|
left: 0,
|
|
right: 0,
|
|
bottom: 0,
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
minWidth: 0,
|
|
minHeight: 0,
|
|
backgroundColor: color.Background.Container,
|
|
willChange: 'clip-path',
|
|
});
|
|
|
|
// The viewer sheet's surface. `Background.Container` (deepest Dawn
|
|
// tone) so the image floats on a near-black backdrop — closest to
|
|
// the legacy `<Overlay>` viewer's full-screen dark scrim. Rounded
|
|
// top corners (same radius as the tab curtains) with `overflow:
|
|
// hidden` clip the header / image to the curve; the carved corners
|
|
// expose the app's dark background behind, so the rounding reads
|
|
// without re-introducing a black void gap.
|
|
export const silhouette = style({
|
|
position: 'absolute',
|
|
bottom: 0,
|
|
left: 0,
|
|
right: 0,
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
overflow: 'hidden',
|
|
backgroundColor: color.Background.Container,
|
|
borderTopLeftRadius: toRem(VOJO_HORSESHOE_RADIUS_PX),
|
|
borderTopRightRadius: toRem(VOJO_HORSESHOE_RADIUS_PX),
|
|
willChange: 'height',
|
|
});
|
|
|
|
// Top-anchored — handle + viewer body reveal top-down as silhouette
|
|
// grows. Android nav-bar clearance is owned by `MainActivity.java`'s
|
|
// WindowInsets listener (the WebView is already sized above the nav
|
|
// bar), so no `padding-bottom: env(...)` here — that would stack on
|
|
// top of the native padding and lift the download / share row above
|
|
// its visible host.
|
|
export const panelContent = style({
|
|
position: 'absolute',
|
|
top: 0,
|
|
left: 0,
|
|
right: 0,
|
|
boxSizing: 'border-box',
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
});
|
|
|
|
// 20px drag-to-close band. The ONLY drag-to-close origin — touches
|
|
// on the viewer body below this strip drive zoom / pan / swipe and
|
|
// MUST NOT initiate a close gesture. `touchAction: none` blocks
|
|
// browser-native scroll on this strip.
|
|
export const panelHandle = style({
|
|
flexShrink: 0,
|
|
height: toRem(20),
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
cursor: 'grab',
|
|
touchAction: 'none',
|
|
userSelect: 'none',
|
|
selectors: {
|
|
'&:active': { cursor: 'grabbing' },
|
|
},
|
|
});
|
|
|
|
// Darker than `Background.Container` would make the grabber
|
|
// disappear — use `SurfaceVariant.Container` so the bar reads
|
|
// against the dark viewer bg. Mirror of the settings handle's
|
|
// step-up against `SurfaceVariant.Container` (where it uses the
|
|
// deeper `Background.Container`).
|
|
export const panelHandleBar = style({
|
|
width: toRem(36),
|
|
height: toRem(4),
|
|
borderRadius: toRem(4),
|
|
backgroundColor: color.SurfaceVariant.Container,
|
|
});
|
|
|
|
export const panelBody = style({
|
|
flex: 1,
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
minHeight: 0,
|
|
minWidth: 0,
|
|
});
|