| /* 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. |
| */ |
| /* Visual System 2.0 (T2): consume the border ladder instead of a hand-rolled |
| * 5% ink mix. `--border-soft` (6%) is DESIGN.md §4's "quiet separation inside a |
| * plate — rails, row dividers that fills can't carry", which is exactly this |
| * line's job. The 1-point alpha change is the cost of having one authority for |
| * quiet lines; a private 5% is indistinguishable from the tier it was drifting |
| * from and only made the ladder unenforceable. */ |
| .maka-session-panel { |
| --maka-rail-hairline: var(--border-soft); |
| } |
| |
| /* 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; |
| } |
| |
| /* Settings and the update action are siblings in one row (SessionSidebarFooter). |
| Everything the old chip needed from product CSS — a pill radius, an accent |
| background, hand-computed hover/pressed/downloading colors, an absolutely |
| positioned progress fill — is gone: it is an Astryx IconButton with |
| `variant="primary"` now, so shape, color and every state come from the |
| component and the theme's accent. What is left here is the one thing no |
| component can know, which is how the two controls share the row. */ |
| .maka-sidebar-footer-row { |
| display: flex; |
| align-items: center; |
| gap: var(--space-1); |
| } |
| |
| /* Collapsed the rail is 48px wide and the labels are gone; two controls cannot |
| sit side by side, so the row stacks and the update button keeps its slot. |
| Read off the frame, which is where the shell already writes the rail's |
| collapsed state (app-shell.tsx) and where the hairline rule above reads it |
| from: a second marker on this row would be the same fact written twice, free |
| to disagree with the first. */ |
| .appFrame[data-sidebar-state="collapsed"] .maka-sidebar-footer-row { |
| flex-direction: column; |
| align-items: stretch; |
| } |
| |
| .maka-sidebar-footer-row-primary { |
| flex: 1; |
| min-width: 0; |
| } |
| |
| /* Stacked, the row stretches its children to the rail's width so the settings |
| row still fills it. A 28px button stretched to 32 is a pill, not the circle |
| it is expanded, so it opts out and keeps its own width. */ |
| .appFrame[data-sidebar-state="collapsed"] .maka-sidebar-update-button { |
| align-self: center; |
| } |
| |
| .maka-sidebar-update-button { |
| flex: none; |
| /* Astryx has no shape prop — `isIconOnly` is documented as rendering a |
| SQUARE button — but Button reads `--_button-radius` for its own geometry, |
| which is how Carousel and Thumbnail reshape it too. Setting that variable |
| asks the component to be round; declaring `border-radius` here would race |
| it instead. On a 28px square this resolves to a true circle. */ |
| --_button-radius: var(--radius-pill); |
| -webkit-app-region: no-drag; |
| } |
| |
| .maka-session-row { |
| min-width: 0; |
| -webkit-app-region: no-drag; |
| } |
| |
| /* |
| * Group-header new-task trigger (session-history-list.tsx): the compact plus |
| * on the Pinned / Recent section titles. |
| * |
| * Size: Astryx IconButton ships sm/md/lg (28/32/40px) — there is no xs. The |
| * trigger deliberately takes the rail's compact control step instead |
| * (--h-control-sm, 24px — the same box the rows' trailing ⋯ column is |
| * measured in), so the section header gains almost no height; one product |
| * size override is the cost. !important for the same reason as every other |
| * StyleX override in this file. |
| * |
| * Column alignment needs no margin: the header's endContent and the rows' |
| * trailing column are both 24px boxes right-aligned to the SAME content edge |
| * (the SideNav scrollable zone's spacing-2 plus their own spacing-2 |
| * paddingInline on each side), so the plus centre lands on the ⋯ column's |
| * centre by layout. Title entry, row actions — one vertical action column, |
| * one eye sweep. |
| */ |
| .maka-group-new-task-button { |
| width: var(--h-control-sm, 24px) !important; |
| height: var(--h-control-sm, 24px) !important; |
| } |
| |
| /* |
| * Dim only this row's SideNavItem. Child combinators stop before [role=group] |
| * nests under project groups. |
| * 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; |
| } |
| |
| /* |
| * 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. Child combinator only — do not use a descendant |
| * selector that would punch deeper nest levels if any appear later. |
| * 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); |
| } |
| |
| /* #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; |
| /* Same as .settingsAboutHero: un-chroming a <kbd>, not squaring a box. With |
| no padding, border, fill or shadow there is nothing for a radius to act |
| on. */ |
| border-radius: 0; |
| background: transparent; |
| box-shadow: none; |
| color: var(--muted-foreground); |
| letter-spacing: var(--tracking-wide); |
| white-space: nowrap; |
| } |