119 lines
4.2 KiB
TypeScript
119 lines
4.2 KiB
TypeScript
import { style } from '@vanilla-extract/css';
|
||
import { color, config, toRem } from 'folds';
|
||
|
||
// Tighten the header's left gutter so the avatar + title block sits
|
||
// further left than `PageHeader`'s desktop default (`S400` = 16px). We
|
||
// match the back-arrow icon-button's natural top/bottom clearance with
|
||
// `S200` (=8px) so its hover background looks symmetrically inset on all
|
||
// four sides. Right side padding is untouched, so the action buttons
|
||
// keep their inset.
|
||
export const HeaderShell = style({
|
||
paddingLeft: config.space.S200,
|
||
});
|
||
|
||
// Tap-target wrapper for the peer avatar — opens the user-room-profile sheet
|
||
// in 1:1 chrome. Reset native button styling so it sits flush with the
|
||
// surrounding header row.
|
||
export const PeerAvatarTrigger = style({
|
||
background: 'transparent',
|
||
border: 'none',
|
||
padding: 0,
|
||
cursor: 'pointer',
|
||
display: 'inline-flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
borderRadius: '50%',
|
||
flexShrink: 0,
|
||
':focus-visible': {
|
||
outline: `2px solid ${color.Primary.Main}`,
|
||
outlineOffset: 2,
|
||
},
|
||
});
|
||
|
||
export const PeerAvatarStatic = style({
|
||
display: 'inline-flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
flexShrink: 0,
|
||
});
|
||
|
||
// Title row: name + «онлайн» presence tag on a single line, identical on
|
||
// mobile and desktop. Name truncates first; the tag never shrinks. Vertical
|
||
// alignment is `center` so the tag sits on the visual midline of the room
|
||
// name regardless of the font-size delta between the H4/H5 name and the
|
||
// T200 tag text.
|
||
export const TitleRow = style({
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: config.space.S200,
|
||
minWidth: 0,
|
||
});
|
||
|
||
export const RoomName = style({
|
||
minWidth: 0,
|
||
flexShrink: 1,
|
||
});
|
||
|
||
// Inline-flex chip with `alignItems: center` gives a true visual-center
|
||
// alignment of the lock icon with the «e2ee» glyphs (not the baseline-plus-
|
||
// x-height/2 approximation that `vertical-align: middle` produces on inline
|
||
// elements). The parent `TitleRow` is also `alignItems: center`, so the
|
||
// chip's outer midline lands on the room name's midline — both centerings
|
||
// are real, no baseline math involved.
|
||
export const E2eeChip = style({
|
||
display: 'inline-flex',
|
||
alignItems: 'center',
|
||
gap: '0.25em',
|
||
color: color.Success.Main,
|
||
flexShrink: 0,
|
||
whiteSpace: 'nowrap',
|
||
});
|
||
|
||
// Icon sized 1.1× down from the chip's font (per spec). `1em` makes it track
|
||
// the chip's text size automatically — no rem/px literal. The flex parent
|
||
// handles vertical centering, so no `vertical-align` nudge is needed here.
|
||
export const E2eeIcon = style({
|
||
width: 'calc(1em / 1.1)',
|
||
height: 'calc(1em / 1.1)',
|
||
});
|
||
|
||
// Subline row — flex container hosting the muted identifier (handle for
|
||
// 1:1, member-count for groups) and, in 1:1, the e2ee chip. The handle
|
||
// takes the flex-shrink budget so it ellipsises first under pressure;
|
||
// the chip stays at intrinsic width via its own `flex-shrink: 0`. Vertical
|
||
// alignment is `center` so the chip's icon-and-text inline-flex sits on
|
||
// the same midline as the handle text.
|
||
export const Subline = style({
|
||
marginTop: toRem(1),
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: config.space.S200,
|
||
minWidth: 0,
|
||
});
|
||
|
||
// Muted handle / member-count segment — surface-on-container with `P400`
|
||
// fade, takes the entire flex-shrink budget so it ellipsises first under
|
||
// pressure. `min-width: 0` is required for `text-overflow` to engage on
|
||
// flex children. Mono font: matches the canon (the handle reads as an
|
||
// identifier, not prose).
|
||
export const SublineMuted = style({
|
||
color: color.Surface.OnContainer,
|
||
opacity: config.opacity.P400,
|
||
minWidth: 0,
|
||
flex: '0 1 auto',
|
||
overflow: 'hidden',
|
||
whiteSpace: 'nowrap',
|
||
textOverflow: 'ellipsis',
|
||
fontFamily: 'ui-monospace, "JetBrains Mono Variable", "JetBrains Mono", monospace',
|
||
});
|
||
|
||
// «онлайн» presence tag — sibling of the room name in `TitleRow`. Same
|
||
// green as the e2ee chip (`color.Success.Main` = Dawn green `#7dd3a8`).
|
||
// `flex-shrink: 0` so the tag never collapses; `white-space: nowrap`
|
||
// prevents internal wrapping on tight viewports (the room name truncates
|
||
// first via `RoomName.flex-shrink: 1`).
|
||
export const OnlineTag = style({
|
||
color: color.Success.Main,
|
||
flexShrink: 0,
|
||
whiteSpace: 'nowrap',
|
||
});
|