vojo/src/app/components/page/style.css.ts

203 lines
5 KiB
TypeScript

import { style } from '@vanilla-extract/css';
import { recipe, RecipeVariants } from '@vanilla-extract/recipes';
import { DefaultReset, color, config, toRem } from 'folds';
export const PageNavResizable = style({
position: 'relative',
flexShrink: 0,
flexGrow: 0,
});
export const PageNavResizeHandle = style({
position: 'absolute',
top: 0,
bottom: 0,
// Native default — sits across the (original) `<Line>` separator
// between page-nav and content. Web shifts the handle into the
// horseshoe void via an inline style override in `ResizablePageNav`.
right: -3,
width: 7,
cursor: 'col-resize',
zIndex: 1,
background: 'transparent',
touchAction: 'none',
outline: 'none',
selectors: {
'&::before': {
content: '""',
position: 'absolute',
top: '50%',
left: '50%',
width: 2,
height: toRem(36),
transform: 'translate(-50%, -50%)',
borderRadius: 1,
backgroundColor: color.Surface.OnContainer,
opacity: 0,
transition:
'opacity 140ms ease, height 140ms ease, width 140ms ease, background-color 140ms ease',
},
'&:hover::before, &:focus-visible::before': {
opacity: 0.25,
},
'&:focus-visible::before': {
backgroundColor: color.Primary.Main,
opacity: 0.45,
},
'&[data-dragging="true"]::before': {
opacity: 0.55,
height: toRem(48),
backgroundColor: color.Primary.Main,
},
// Limit feedback: when the user drags past a clamp the width stops
// moving and the indicator deforms to signal it. Min = spring crushed
// against a wall (slight squish, thicker). Max = rubber band stretched
// (taller, full opacity). Activates only during drag so the resting
// state stays calm.
'&[data-dragging="true"][data-at-min="true"]::before': {
height: toRem(28),
width: 3,
opacity: 0.85,
},
'&[data-dragging="true"][data-at-max="true"]::before': {
height: toRem(76),
width: 2,
opacity: 0.9,
},
},
});
export const PageNav = recipe({
variants: {
size: {
'500': {
width: toRem(320),
},
'400': {
width: toRem(256),
},
'300': {
width: toRem(222),
},
},
},
defaultVariants: {
size: '400',
},
});
export type PageNavVariants = RecipeVariants<typeof PageNav>;
// Web-only horseshoe shell wrapping every page-nav's inner column.
// Previously carved rounded TR / BR corners against a void backdrop;
// the rounding was reverted while keeping the 12px void gap between
// page-nav and chat panel, so this class now just enforces an opaque
// Background bg + clips overflow. The bg keeps the page-nav header /
// footer painted even on routes (Bots, Channels) that don't paint
// anything of their own; `overflow:hidden` is defensive against any
// child that might bleed past the inner column. Applied conditionally
// in `PageNav` / `ResizablePageNav` below; native skips it entirely.
export const PageNavInnerWebHorseshoe = style({
overflow: 'hidden',
backgroundColor: color.Background.Container,
});
export const PageNavHeader = recipe({
base: {
padding: `0 ${config.space.S200} 0 ${config.space.S300}`,
flexShrink: 0,
selectors: {
'button&': {
cursor: 'pointer',
},
'button&[aria-pressed=true]': {
backgroundColor: color.Background.ContainerActive,
},
'button&:hover, button&:focus-visible': {
backgroundColor: color.Background.ContainerHover,
},
'button&:active': {
backgroundColor: color.Background.ContainerActive,
},
},
},
variants: {
outlined: {
true: {
borderBottomWidth: 1,
},
},
},
defaultVariants: {
outlined: true,
},
});
export type PageNavHeaderVariants = RecipeVariants<typeof PageNavHeader>;
export const PageNavContent = style({
minHeight: '100%',
padding: config.space.S200,
paddingRight: 0,
paddingBottom: config.space.S700,
});
export const PageHeader = recipe({
base: {
paddingLeft: config.space.S400,
paddingRight: config.space.S200,
},
variants: {
balance: {
true: {
paddingLeft: config.space.S200,
},
},
outlined: {
true: {
borderBottomWidth: config.borderWidth.B300,
},
},
},
defaultVariants: {
outlined: true,
},
});
export type PageHeaderVariants = RecipeVariants<typeof PageHeader>;
export const PageContent = style([
DefaultReset,
{
paddingTop: config.space.S400,
paddingLeft: config.space.S400,
paddingRight: 0,
paddingBottom: toRem(100),
},
]);
export const PageHeroEmpty = style([
DefaultReset,
{
padding: config.space.S400,
borderRadius: config.radii.R400,
minHeight: toRem(450),
},
]);
export const PageHeroSection = style([
DefaultReset,
{
padding: '40px 0',
maxWidth: toRem(466),
width: '100%',
margin: 'auto',
},
]);
export const PageContentCenter = style([
DefaultReset,
{
maxWidth: toRem(964),
width: '100%',
margin: 'auto',
},
]);