blob: ab0a473f578ada5d39a84aae4dc436f3df6ca20c [file]
/* Sidebar — SideNav shell, session rows, footer update chip.
* Session rows are Astryx SideNavItem; this file only owns product-only chrome. */
.maka-session-panel {
min-width: 0;
min-height: 0;
height: 100%;
}
/*
* Astryx 0.2.0 ResizeHandle: when pillPlacement is not "center", hitAreaOffsetX
* applies translateY(-50%) without a matching top: 50%. The grab zone then only
* covers the top half of the handle, so a pointer drag at the vertical center
* (where the pill sits) hits the handle root — which has no pointerdown — and
* no-ops. SideNav uses pillPlacement="end" (sub-pixel X bias) and mounts the
* handle as a sibling of <nav.maka-session-panel>, not a descendant — target the
* handle test id. Remove once Astryx fixes hitAreaOffsetX.
*/
[data-testid="astryx-sidenav-resize-handle"] > div:not(.astryx-resize-handle-pill) {
/* !important: Astryx StyleX injects the bad transform unlayered, which
otherwise beats every rule in @layer maka.legacy. */
transform: none !important;
}
.maka-session-list {
min-width: 0;
max-width: 100%;
width: 100%;
box-sizing: border-box;
}
/*
* One type size for the whole rail. SideNavSection draws its title from the
* `supporting` tier (12px), one step below the session rows it labels; against
* Maka's 14px body that reads as a caption rather than a peer of the list, and
* CJK loses more apparent size at 12px than Latin does. Put 会话 / 最近 / 置顶
* on the rows' 14px and let weight and color carry the hierarchy instead — the
* title is already semibold against the rows' medium, and secondary against
* their primary foreground.
*
* Rebinding Astryx's own tier variables, rather than pinning font-size on the
* title span: the size still flows through Astryx's rule, so title and subtitle
* stay in step and an upgrade that restructures the header keeps working.
*
* Bound on the header, NOT on the section root. SideNavSection wraps the whole
* list body — every row, badge, and pill — in the same element as its title
* (session-history-list.tsx), and custom properties inherit, so a rebind on the
* root reaches all of it: measured live, the project session-count Badge went
* 12px → 14px, and `.maka-list-row-stale-pill` would have taken a 17.14px line
* box on its 12px font. The header is SideNavSection's first child and holds
* exactly the title and subtitle.
*
* Both halves of the tier move together. Size alone would leave the supporting
* leading multiplier on a larger font and land the line box at 23.33px, off the
* theme's 4px grid.
*/
.maka-session-panel .astryx-side-nav-section > :first-child {
--text-supporting-size: var(--text-label-size);
--text-supporting-leading: var(--text-label-leading);
}
.maka-session-group {
min-width: 0;
}
/*
* The rail's two hairlines: nav chrome above the history, footer below it. Both
* are drawn the same way, on the sticky shell that owns the zone rather than as
* an element inside it, so they are the same 1px at the same alpha and both run
* the full panel width. One custom property carries the line so "the same" is a
* fact about the code rather than something a test has to keep checking; the
* collapsed state then hides both by retuning that one value.
*
* Astryx 0.2.0 has no seam for this — SideNav's five zone wrappers carry no
* border and no `hasDivider`, and they are the only elements in its tree that
* `themeProps()` never labels, so the product both draws the line and reaches
* the zone by structure.
*
* The top one used to be an Astryx <Divider> placed as the last child of
* `topContent`, which made it a different line in every respect: --color-border
* is twice the alpha of the footer's rule, and the divider sat inside the
* sticky shell's 8px inline padding, so it stopped 8px short at each end
* (measured x=8 w=244 against the footer's x=0 w=260). Read together, one was a
* separator and the other a box edge. Drawing it as this zone's border-bottom
* also drops an element and a component from the tree, and the sticky padding
* that the footer rule already relies on becomes the breathing room the divider
* needed a margin for.
*
* The footer half additionally equalizes padding: Astryx defaults are
* asymmetric (spacing-1 top / spacing-2 bottom) and the section adds another
* paddingBlock, so Settings sat tight under the line and airy above the window
* edge.
*/
.maka-session-panel {
--maka-rail-hairline: oklch(from var(--foreground) l c h / 0.05);
}
/* Continuous Collapse: the hairlines separate the history column from the
* chrome above and the footer below. At 48px there is no column left to
* separate — they read as orphan rules floating on a rail that is otherwise
* ink-only. Retuning the shared value rather than nulling each border keeps the
* two lines a single decision in the collapsed state too. */
.appFrame[data-sidebar-state="collapsed"] .maka-session-panel {
--maka-rail-hairline: transparent;
}
.astryx-side-nav.maka-session-panel > div:has(.maka-session-panel-top) {
border-bottom: var(--border-width-hairline) solid var(--maka-rail-hairline);
}
.astryx-side-nav.maka-session-panel > div:has(> .maka-session-panel-footer) {
/* !important: StyleX stickyBottom is unlayered. */
padding-block: var(--space-2) !important;
gap: 0 !important;
border-top: var(--border-width-hairline) solid var(--maka-rail-hairline);
background: transparent;
}
/* Empty footerRow still mounts when hasButton:false; hide so it cannot
* reserve flex gap under Settings. */
.astryx-side-nav.maka-session-panel > div:has(> .maka-session-panel-footer) > div:empty {
display: none;
}
/* Both nav groups are SideNavSections, so both bring the section's own
* paddingBlock; the sticky zone shells above already own the rail's clearance,
* and leaving the section copy in place makes the two hairlines sit at
* different distances from the rows they separate (measured 9px vs 13px).
* !important: SideNavSection paddingBlock is StyleX/unlayered. */
.maka-session-panel-top,
.maka-session-panel-footer {
padding: 0 !important;
}
.maka-session-panel-footer {
border-top: 0 !important;
background: transparent;
}
.maka-session-panel-footer .maka-sidebar-update-button {
margin-block-start: var(--space-1);
}
/* #1879: this rule used to force `height: 34px` onto an Astryx Button. It is a
`<Button size="md">` now (session-sidebar-nav.tsx), so the 32px comes from
the component's own `--size-element-md` — the same token the 32px nav rows
it stacks under already read. Overriding a component's size from product CSS
is the drift the control ruler exists to end; declaring no height here is
what makes the two agree by derivation instead of by coincidence. */
.maka-sidebar-update-button {
font: var(--maka-text-heading-4);
position: relative;
min-width: 0;
display: inline-grid;
grid-template-columns: auto;
align-items: center;
gap: var(--space-1);
/* Astryx Button reads `--_button-radius` for its own shape (Carousel and
Thumbnail set it the same way); declaring `border-radius` here would be a
product rule racing the component again. */
--_button-radius: var(--radius-pill);
padding: 0 var(--space-3);
/* `background-color`, not the `background` shorthand — here and in EVERY
state rule below. The shorthand also resets `background-image`, which is
where Button's ghost variant keeps its hover and pressed overlays, so a
single shorthand anywhere in this file cancels the `variant` the component
was given. Product CSS is in the last cascade layer, so it wins that reset
regardless of specificity; fixing only the base rule left the overlays
dead on hover and in both download states, which is where they are most
visible. `border: 0` and `box-shadow: none` used to sit here too; both
restated what Button already computes. */
background-color: var(--control);
color: var(--control-foreground);
overflow: hidden;
-webkit-app-region: no-drag;
transition:
background-color var(--duration-base) var(--ease-out-strong),
transform var(--duration-quick) var(--ease-out-strong);
}
.maka-sidebar-update-button > span:not(.maka-sidebar-update-progress) {
position: relative;
}
.maka-sidebar-update-button[data-update-state="downloading"] {
cursor: default;
background-color: oklch(from var(--control) calc(l + 0.04) calc(c * 0.68) h);
opacity: 1;
}
.maka-sidebar-update-button[data-update-state="downloaded"] {
background-color: var(--control);
}
.maka-sidebar-update-progress {
position: absolute;
inset: 0;
transform: scaleX(var(--maka-update-progress, 0));
transform-origin: left center;
background-color: oklch(from var(--control) calc(l - 0.08) c h);
transition: transform var(--duration-base) var(--ease-out-strong);
}
.maka-sidebar-update-button:hover {
background-color: oklch(from var(--control) calc(l - 0.04) c h);
}
.maka-sidebar-update-button:disabled:hover {
background-color: oklch(from var(--control) calc(l + 0.04) calc(c * 0.68) h);
}
.maka-sidebar-update-button:focus-visible {
outline: var(--focus-ring-width) solid var(--focus-ring);
outline-offset: var(--focus-ring-offset);
}
.maka-session-row {
min-width: 0;
-webkit-app-region: no-drag;
}
/* SideNavItem needs a truthy child to retain its disclosure control. Collapsed
* session trees provide this sentinel instead of mounting every Swarm child. */
.maka-session-lazy-children-sentinel {
display: none;
}
/*
* Dim only this row's SideNavItem. Child combinators stop before [role=group]
* nests, so a stale parent never mutes healthy subagent rows underneath.
* DOM: .maka-session-row > SideNavItem root > .astryx-side-nav-item
* (leaf: button; collapsible parent: split-action row that may host the
* primary control with aria-current).
*/
.maka-session-row[data-stale="true"] > div > .astryx-side-nav-item {
opacity: var(--opacity-muted);
}
.maka-session-row[data-stale="true"] > div > .astryx-side-nav-item[aria-current="page"],
.maka-session-row[data-stale="true"] > div > .astryx-side-nav-item:has(> [aria-current="page"]) {
opacity: 1;
}
.maka-session-row[data-subagent="true"] .astryx-side-nav-item {
color: var(--foreground-secondary);
}
/*
* Project groups are a section label + peer sessions, not a deep tree.
* Astryx SideNavItem always pads children with spacing-6 (24px); that is the
* shell-side-nav workspace pattern, but it wastes a full icon column in a
* narrow session rail. Zero only the project item's own nest so sessions share
* the time-sort left edge. Do not use a descendant selector — that would also
* punch through subagent trees under session rows inside the project.
* DOM: .maka-project-row > SideNavItem root > [role=group] > childrenInner
*/
.maka-project-row > div > [role="group"] > div {
/* !important: StyleX childrenInner paddingInlineStart is unlayered. */
padding-inline-start: 0 !important;
}
.maka-session-row-end,
.maka-project-item-end {
display: inline-flex;
align-items: center;
justify-content: flex-end;
gap: var(--space-1);
flex-shrink: 0;
}
/* Fixed trailing column so StatusDot ↔ MoreMenu swaps do not reflow the label
* (hover used to steal ~28px and shove the title left). */
.maka-session-row-trailing {
display: inline-flex;
align-items: center;
justify-content: center;
flex: 0 0 auto;
width: var(--h-control-sm, 24px);
min-height: var(--h-control-sm, 24px);
}
.maka-session-row-trailing-spacer {
display: block;
width: 8px;
height: 8px;
}
.maka-session-worktree-icon {
flex: 0 0 auto;
color: var(--muted-foreground);
}
.maka-session-row--editing {
padding-inline: var(--space-2);
padding-block: var(--space-1);
}
.maka-session-rename-input {
font: var(--maka-text-heading-4);
width: 100%;
min-width: 0;
border: 0;
border-bottom: var(--border-width-hairline) solid oklch(from var(--focus-ring) l c h / 0.4);
background: transparent;
color: var(--foreground);
outline: 0;
padding: 1px 0;
}
.maka-session-rename-input:focus {
border-bottom-color: var(--focus-ring);
}
/* #1879: an Astryx `Badge variant="yellow"` now. Box, radius, padding and
caption type all come from the component (20px off `--spacing-5`), so the
only thing product CSS still owns is that it must not be squeezed by the
row's flex layout. */
.maka-list-row-stale-pill {
flex-shrink: 0;
}
/* ⌘N hint on the 新任务 row — quiet text, no chip chrome. */
/* #1879: no chrome, but still a box, and it had no height of its own —
measured, its own leading at 40px took it from 20px to 40px and pushed the
32px nav row with it. Pinned to `--h-control-xs` (20px), which is what the
supporting leading already resolves to, so nothing moves today. */
.maka-nav-kbd {
/* A <kbd> composes the mono variant of every role (maka-tokens.css anchors
the role table on the code group too), and this hint has always opted out
— it read `font-family: inherit` before the roles landed. Naming the
family axis re-composes the role the element already carries, so the
opt-out stays one declaration instead of reopening the triplet. */
--maka-font-family: var(--font-family-body);
font: var(--maka-text-supporting);
height: var(--h-control-xs);
display: inline-flex;
align-items: center;
margin-left: auto;
padding: 0;
border: 0;
border-radius: 0;
background: transparent;
box-shadow: none;
color: var(--muted-foreground);
letter-spacing: var(--tracking-wide);
white-space: nowrap;
}