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

211 lines
5.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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),
},
// Used by the Settings nav — ~1.43× the regular 300 (~317px =
// 1.3 × 1.1 over 222px). Settings labels are long
// ("Notifications", "Emojis & Stickers", "Developer Tools") and
// the 222px column truncated them; the wider column also gives
// the nested-horseshoe void gap on the right room to breathe.
'350': {
width: toRem(317),
},
},
},
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',
},
]);