Fixed sidebar width (never concedes), figma session-row rail (16px twist + status slots, triangle arrows, mount fade), exact brand wordmark svg with tooltip'd rail controls, form controls inheriting the app font stack, and inlined the twist button reset since the tsdown CSS pipeline drops composes.
205 lines
4.3 KiB
CSS
205 lines
4.3 KiB
CSS
/* Tree rows (figma Cell set 14:3080): project 54px two-line, session 34px
|
|
single-line, radius 8, indent step 22px (16px slot + 6px gap). Hover swaps
|
|
are pure CSS: project folder -> chevron + action buttons; session time ->
|
|
ellipsis button. */
|
|
|
|
.projectRow,
|
|
.sessionRow {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
border-radius: 8px;
|
|
padding: 0 8px;
|
|
cursor: pointer;
|
|
user-select: none;
|
|
color: var(--dsw-alias-label-primary);
|
|
}
|
|
|
|
.projectRow:hover,
|
|
.sessionRow:hover {
|
|
background: var(--dsw-alias-interactive-bg-hover);
|
|
}
|
|
|
|
.sessionRow.selected {
|
|
background: var(--dsw-alias-interactive-bg-active);
|
|
}
|
|
|
|
/* Two-line row: the leading slot (folder/chevron), title, and trailing
|
|
actions all top-align on the 20px first text line (figma cell) — content
|
|
is 42px (20 + 2 + 20), so 6px vertical padding centers the block. */
|
|
.projectRow {
|
|
height: 54px;
|
|
align-items: flex-start;
|
|
padding-top: 6px;
|
|
padding-bottom: 6px;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.projectRow .rowActions {
|
|
height: 20px;
|
|
}
|
|
|
|
/* Session cell (figma): pad 8, adjacent 16px twist + status slots, then a 4px
|
|
gap to the title — the slots butt together, so the row gap is zeroed and
|
|
the title carries its own margins. */
|
|
.sessionRow {
|
|
height: 34px;
|
|
gap: 0;
|
|
/* Mount fade: session rows appear by unfolding a group (or the tree
|
|
mounting). Stable row keys keep already-visible rows from replaying it. */
|
|
animation: row-in 150ms var(--ds-ease-in-out);
|
|
}
|
|
|
|
.sessionRow .title {
|
|
margin: 0 6px 0 4px;
|
|
}
|
|
|
|
@keyframes row-in {
|
|
from { opacity: 0; }
|
|
}
|
|
|
|
.slot {
|
|
flex: none;
|
|
width: 16px;
|
|
height: 20px;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: var(--dsw-alias-label-tertiary);
|
|
}
|
|
|
|
|
|
.folderActive {
|
|
color: var(--dsw-alias-state-business-primary);
|
|
}
|
|
|
|
/* Project leading slot: folder by default, expand arrow on row hover. */
|
|
.projectRow .chevron { display: none; }
|
|
.projectRow:hover .chevron { display: inline-flex; }
|
|
.projectRow:hover .folder { display: none; }
|
|
|
|
/* Expand arrow (filled triangle): points right closed, rotates to point down open. */
|
|
.arrow {
|
|
transition: transform 150ms var(--ds-ease-in-out);
|
|
}
|
|
|
|
.arrowOpen {
|
|
transform: rotate(90deg);
|
|
}
|
|
|
|
.projectText {
|
|
flex: 1;
|
|
min-width: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 2px;
|
|
}
|
|
|
|
.title {
|
|
min-width: 0;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
font-size: 14px;
|
|
line-height: 20px;
|
|
}
|
|
|
|
.sessionRow .title {
|
|
flex: 1;
|
|
}
|
|
|
|
.meta {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
font-size: 12px;
|
|
line-height: 20px;
|
|
color: var(--dsw-alias-label-tertiary);
|
|
}
|
|
|
|
.time {
|
|
flex: none;
|
|
font-size: 12px;
|
|
line-height: 20px;
|
|
color: var(--dsw-alias-label-tertiary);
|
|
}
|
|
|
|
.dot {
|
|
flex: none;
|
|
}
|
|
|
|
/* Trailing action buttons surface on hover only (figma 27:4668 / 27:4656):
|
|
bare 16px glyphs, gap 12, tertiary grey. */
|
|
.rowActions {
|
|
flex: none;
|
|
display: none;
|
|
align-items: center;
|
|
gap: 12px;
|
|
}
|
|
|
|
.projectRow:hover .rowActions,
|
|
.sessionRow:hover .rowActions {
|
|
display: inline-flex;
|
|
}
|
|
|
|
.sessionRow:hover .time {
|
|
display: none;
|
|
}
|
|
|
|
.iconButton {
|
|
flex: none;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 16px;
|
|
height: 16px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
padding: 0;
|
|
background: transparent;
|
|
cursor: pointer;
|
|
color: var(--dsw-alias-label-tertiary);
|
|
}
|
|
|
|
.iconButton:hover {
|
|
color: var(--dsw-alias-label-primary);
|
|
}
|
|
|
|
/* Session expand twist occupies the leading 16px slot; keep a spacer when absent
|
|
so titles align across sibling rows. Duplicates the .iconButton reset instead
|
|
of `composes:` — the tsdown CSS-modules pipeline drops composes mappings, which
|
|
left the raw UA button box showing. */
|
|
.twist {
|
|
flex: none;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 16px;
|
|
height: 20px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
padding: 0;
|
|
background: transparent;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.twist:hover {
|
|
color: var(--dsw-alias-label-primary);
|
|
}
|
|
|
|
/* Chevrons and tree twists ride the caption grey (#ADB2B8); the folder glyph
|
|
stays one step darker (tertiary, #81858C) per the cell spec. Declared last
|
|
to win over the composed .iconButton color. */
|
|
.chevron,
|
|
.twist {
|
|
color: var(--dsw-alias-label-caption);
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.sessionRow,
|
|
.arrow {
|
|
animation: none;
|
|
transition: none;
|
|
}
|
|
}
|