Canvas / layout:
- Guard flex flow-children from free-drag and add a 4px drag threshold,
so a first click no longer materializes x/y on a flow child and
collapses the auto-layout frame.
Property panel:
- Gap/justify radios disable the gap input on space-between/around;
compact gap rows with vertically-centered input text.
- Padding-mode gear popover hover; the pin is anchor-scoped so it no
longer leaks into the next selection.
- Font-weight dropdown: full 100-900 numeric options + row hover.
- Stroke hex seeds the displayed swatch colour (not #000000); stroke
width now persists on commit.
Desktop:
- Traffic-light inset now applies on launch (casement windowDidBecomeKey).
- File-drop overlay; git commit caret blink.
Refactor:
- Split property_dispatch / git_panel / property-panel tests under the
800-line cap; reorganise panel tests by topic.
The Git popover is hit-tested at press block 0.9 — ahead of the align
toolbar (line 554) — but was painted at §8.2, BELOW the align toolbar
(§8.4). That was moot while the panel floated top-left, but once it
centres under the Git button it overlaps the align toolbar: paint said
the align toolbar was on top, the hit-test said the popover was, so a
click on an align button over the popover went to the popover.
Move the popover paint to §8.7 — above the align toolbar / marquee /
property overlays, still below the shape / locale pickers and modals —
so the paint z-order matches the hit-test priority.
Faithful port of apps/web's git-panel-empty-state.tsx:
- Per-card hover effect (TS hover:/group-hover:): the card lifts 1px and
recolors to border-primary/40 + bg-accent/30, the icon box to
bg-primary/10 + text-primary. Tracked via the new
GitPanelState.empty_hovered_card (0=Init / 1=Open / 2=Clone), updated
by update_git_panel_empty_hover on cursor-move.
- Disabled Init card (no saved .op): the TS opacity-50 look + a
not-allowed cursor (new CursorHint::NotAllowed → winit NotAllowed),
and the requireSavedFile hint shown only on hover (TS Tooltip
side="bottom", bg-primary text-primary-foreground).
- Gradient clock badge (from-muted/60 to-muted/20 + ring-border/60) and
the TS container spacing (pt-8 / gap-5 / pb-6).
Adds the alpha()/over() colour helpers (Tailwind /NN opacity + compositing)
and a placement test for the per-card hover + not-allowed cursor.
- Float the git panel centered under the TopBar git button (TS popover
parity) with an up-caret; git_panel_rect is the single placement source
that paint, hit-test, cursor and outside-click all read.
- git_panel_outer_rect (body + caret bridge) backs hit-test / cursor /
outside-click / diff-scroll so a click or hover on the caret is caught
by the popover instead of falling through to the canvas.
- over_floating_overlay keeps the canvas Move/Crosshair cursor from
bleeding through every floating overlay (git / status / chat / toolbar /
align-toolbar / shape / locale / file-menu / context-menu + the centered
panels).
- Onboarding empty state: Init / Open / Clone cards; Init is disabled until
the doc has a saved path, with a hover-gated "save .op first" hint pill.
- Split oversized files for the 800-line cap: git_panel -> {empty, status};
geometry -> overlay_rects; top_bar -> top_bar_paint.
- Resolve the stash-pop conflict against the upstream refactor (ai_chat_rect
now lives in ai_chat_geometry) and clear clippy-1.94 drift in upstream
files (unnecessary_map_or, too_many_arguments, match_like_matches_macro)
so the workspace gate passes.
The onboarding cards are now actionable:
- 新建/Init → `GitRepo::init` at the saved doc's directory, then
rebind the session so the doc is tracked (disabled until saved);
- 打开/Open → native folder picker → `GitRepo::discover` + a new
`GitSession::bind_repo` (tracks the doc when it's under the repo);
- 克隆/Clone → info dialog for now (needs the in-panel URL form — a
follow-up).
Adds GitPanelHit::{EmptyInit,EmptyOpen,EmptyClone},
GitPanelAction::{InitRepo,OpenRepo,CloneRepo}, host press dispatch +
binary drain, `git_panel.has_saved_file` tracked on every rebind, and
a hit-test test. EN/ZH strings for the two new messages.
Replace the bare "不是 Git 仓库。" text with the TS onboarding empty
state: a History clock glyph in a rounded box, the
"这份文件还没有版本历史" heading, three cards (新建/打开/克隆 with
FilePlus/FolderOpen/GitFork icons + descriptions), and the "Git is
optional" note — laid out centred in a 380×284 panel.
- new History/FilePlus/GitFork icons;
- `GitPanelState.has_saved_file` dims the Init card when the doc is
unsaved (matching TS);
- `empty_state_rects` shared for the upcoming card hit-test.
Card actions (init/open/clone) wired in a follow-up.
The web/wasm build has no git backend and never paints GitPanel, so
the top-bar git button toggled an invisible panel (Codex stop-time
review). Gate the button's paint + hit-test on a `GIT_BUTTON_AVAILABLE`
const (`!cfg!(target_arch = "wasm32")`) so it only exists on desktop.
The top bar had no affordance to open the git panel (only a
keyboard/menu path). Add a TS-style git button just right of the file
name: a `GitBranch` glyph + the current branch name when in a repo.
Always shown (per request) — a click toggles the git panel, which
offers `init` when the doc isn't yet a repo.
- new `Icon::GitBranch` lucide glyph;
- `TopBar.git_branch` from `git_panel.branch`; `git_button_rect`
(CJK-aware width estimate so it clears a CJK file name) shared by
paint + hit-test; `TopBarHit::ToggleGitPanel`;
- native host mirrors `main.rs` toggle bookkeeping (per-frame refresh
does the scan); web host toggles `git_panel.open`.