Room list wash and name line: undo the solid slabs and the boxed pill (#39)
All checks were successful
Rat dev preview / Build dev preview (push) Successful in 3m45s
All checks were successful
Rat dev preview / Build dev preview (push) Successful in 3m45s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
dfc74c252a
commit
9794714f97
2 changed files with 40 additions and 37 deletions
|
|
@ -198,25 +198,19 @@ export const BubbleHeaderOwn = style({
|
|||
alignSelf: 'flex-end',
|
||||
});
|
||||
|
||||
// Phone: the name is a pill straddling the bubble's top edge, on the side opposite the portrait.
|
||||
// Phone: name and time are one plain line in flow above the bubble, on the side opposite the
|
||||
// portrait. It is as wide as the full name needs, up to the room beside the portrait; only a name
|
||||
// longer than that wraps (and then the time drops below it). It is capped by the viewport, not by
|
||||
// the column: a short bubble's column is narrower than its own name, and a percentage cap there
|
||||
// truncated names to one letter.
|
||||
export const BubbleHeaderPose = style({
|
||||
'@media': {
|
||||
[PHONE]: {
|
||||
position: 'absolute',
|
||||
zIndex: 2,
|
||||
// Anchored by its bottom edge, 13px inside the bubble: a name that wraps grows upward, out of
|
||||
// the bubble, instead of down over the first line of text.
|
||||
bottom: `calc(100% - ${toRem(13)})`,
|
||||
right: toRem(14),
|
||||
padding: `0 ${toRem(13)}`,
|
||||
background: color.Secondary.Container,
|
||||
border: `1px solid ${color.Secondary.ContainerLine}`,
|
||||
// The pill is as wide as the full name needs, up to the room beside the portrait, then the
|
||||
// name wraps. It is capped by the viewport, not by the column: a short bubble's column is
|
||||
// narrower than its own name, and a percentage cap there truncated names to one letter.
|
||||
alignSelf: 'flex-end',
|
||||
margin: `0 ${toRem(14)} ${toRem(2)}`,
|
||||
width: 'max-content',
|
||||
maxWidth: `calc(100vw - ${PHONE_PORTRAIT} - ${toRem(64)})`,
|
||||
borderRadius: toRem(14),
|
||||
textAlign: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
@ -224,8 +218,8 @@ export const BubbleHeaderPose = style({
|
|||
export const BubbleHeaderPoseAlt = style({
|
||||
'@media': {
|
||||
[PHONE]: {
|
||||
right: 'auto',
|
||||
left: toRem(14),
|
||||
alignSelf: 'flex-start',
|
||||
textAlign: 'left',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
@ -398,9 +392,8 @@ globalStyle(`${BubbleContentPose} > div`, {
|
|||
},
|
||||
});
|
||||
|
||||
// The name inside the pill wraps instead of ellipsising: the pill already caps its own width, and
|
||||
// Username's own nowrap + ellipsis, and the truncate on the Text inside it, clipped long names to
|
||||
// "Heimdall o…" inside it.
|
||||
// The name wraps instead of ellipsising: the header already caps its own width, and Username's own
|
||||
// nowrap + ellipsis, and the truncate on the Text inside it, clipped long names to "Heimdall o…".
|
||||
globalStyle(`${BubbleHeaderPose} ${Username}, ${BubbleHeaderPose} ${Username} *`, {
|
||||
'@media': {
|
||||
[PHONE]: {
|
||||
|
|
@ -413,11 +406,21 @@ globalStyle(`${BubbleHeaderPose} ${Username}, ${BubbleHeaderPose} ${Username} *`
|
|||
});
|
||||
|
||||
// A name too long for one line takes its own lines and the time drops below it, instead of the
|
||||
// name shrinking to a sliver beside the time (the pill's one child is the flex row of both).
|
||||
// name shrinking to a sliver beside the time (the header's one child is the flex row of both). The
|
||||
// row hugs the side the header sits on, so a dropped time stays under the name's edge.
|
||||
globalStyle(`${BubbleHeaderPose} > div`, {
|
||||
'@media': {
|
||||
[PHONE]: {
|
||||
flexWrap: 'wrap',
|
||||
justifyContent: 'flex-end',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
globalStyle(`${BubbleHeaderPoseAlt} > div`, {
|
||||
'@media': {
|
||||
[PHONE]: {
|
||||
justifyContent: 'flex-start',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
@ -446,14 +449,6 @@ globalStyle(`${scene} ${BubbleContent}`, {
|
|||
globalStyle(`${scene} ${BubbleContentOwn}`, {
|
||||
backgroundColor: [color.Primary.Container, half(color.Primary.Container)],
|
||||
});
|
||||
globalStyle(`${scene} ${BubbleHeaderPose}`, {
|
||||
'@media': {
|
||||
[PHONE]: {
|
||||
backgroundColor: [color.Secondary.Container, half(color.Secondary.Container)],
|
||||
backdropFilter: 'blur(12px)',
|
||||
},
|
||||
},
|
||||
});
|
||||
globalStyle(`${scene} ${BubbleLeftArrow}`, {
|
||||
display: 'none',
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,6 +3,14 @@ import { RecipeVariants, recipe } from '@vanilla-extract/recipes';
|
|||
import { ContainerColor, DefaultReset, Disabled, RadiiVariant, color, config, toRem } from 'folds';
|
||||
import { surfaceInk } from '../../features/scene/sceneShell.css';
|
||||
|
||||
// Wash strengths over the scene: rows and labels are faint, and hover, selected and pressed rows
|
||||
// are three distinct steps above them.
|
||||
const SCRIM_LABEL = '12%';
|
||||
const SCRIM_ROW = '16%';
|
||||
const SCRIM_HOVER = '26%';
|
||||
const SCRIM_SELECTED = '36%';
|
||||
const SCRIM_PRESSED = '48%';
|
||||
|
||||
export const NavCategory = style([
|
||||
DefaultReset,
|
||||
{
|
||||
|
|
@ -13,9 +21,9 @@ export const NavCategory = style([
|
|||
export const NavCategoryHeader = style({
|
||||
gap: config.space.S100,
|
||||
selectors: {
|
||||
// Category labels sit on the scene like the rows do, and need the same scrim to be read.
|
||||
// Category labels sit on the scene like the rows do, and need a wash to be read.
|
||||
':root[data-scene] &': {
|
||||
backgroundColor: `color-mix(in srgb, ${surfaceInk} 62%, transparent)`,
|
||||
backgroundColor: `color-mix(in srgb, ${surfaceInk} ${SCRIM_LABEL}, transparent)`,
|
||||
borderRadius: config.radii.R400,
|
||||
},
|
||||
},
|
||||
|
|
@ -69,21 +77,21 @@ const NavItemBase = style({
|
|||
'&[data-hover=true]': {
|
||||
backgroundColor: ContainerHover,
|
||||
},
|
||||
// While the background scene runs the shell is clear (sceneShell.css.ts); a row is a steady
|
||||
// scrim of the theme's own surface, so ridges never show through its text. Hover, the selected row and a
|
||||
// press each strengthen it a step.
|
||||
// While the background scene runs the shell is clear (sceneShell.css.ts); a row is a faint
|
||||
// wash of the theme's own surface: the terrain stays visible, the text stays readable. Hover,
|
||||
// the selected row and a press each strengthen it a step.
|
||||
':root[data-scene] &': {
|
||||
backgroundColor: `color-mix(in srgb, ${surfaceInk} 62%, transparent)`,
|
||||
backgroundColor: `color-mix(in srgb, ${surfaceInk} ${SCRIM_ROW}, transparent)`,
|
||||
},
|
||||
':root[data-scene] &:hover, :root[data-scene] &:focus-visible, :root[data-scene] &[data-hover=true]':
|
||||
{
|
||||
backgroundColor: `color-mix(in srgb, ${surfaceInk} 74%, transparent)`,
|
||||
backgroundColor: `color-mix(in srgb, ${surfaceInk} ${SCRIM_HOVER}, transparent)`,
|
||||
},
|
||||
':root[data-scene] &[aria-selected=true]': {
|
||||
backgroundColor: `color-mix(in srgb, ${surfaceInk} 84%, transparent)`,
|
||||
backgroundColor: `color-mix(in srgb, ${surfaceInk} ${SCRIM_SELECTED}, transparent)`,
|
||||
},
|
||||
[`:root[data-scene] &:has(.${NavLink}:active)`]: {
|
||||
backgroundColor: `color-mix(in srgb, ${surfaceInk} 92%, transparent)`,
|
||||
backgroundColor: `color-mix(in srgb, ${surfaceInk} ${SCRIM_PRESSED}, transparent)`,
|
||||
},
|
||||
[`&:has(.${NavLink}:active)`]: {
|
||||
backgroundColor: ContainerActive,
|
||||
|
|
|
|||
Loading…
Reference in a new issue