feat(desktop): a sleeker sign-in that waits in place, not in a notch slot
Dean: "The sign in page doesn't look great either… redesign it to be sleeker and fit the style of the rest of our apps." Also, per Dean's follow-up, the sign-in no longer uses the notch-era "slot" interaction.
What changes
The screen. The card, the blue radial glow, and the big empty gap are gone. What's left is one ~320px column centred a little above the middle of the window, like the new-plan home:
- Luke's
WingFace(its introduction cycle unchanged) on the same quiet tile the sidebar draws him on. - Welcome to Luke, with one muted line: Talk a feature through and Luke writes the plan.
- The two providers at the window's
--control-heightand--control-radius, full column width, with their brand marks. Google is filled in the text colour, the way the new-plan page's start press is. GitHub is the quiet neutral button.
The drag strip stays at the top, and the buttons are no-drag. All spacing comes from the --space-* scale. sign-in.css now joins desktop.css/tooltip.css in the design contract's literal-px check, and DESIGN.md says so.
Signing in waits in place, with no slot. Pressing a provider still sends the browser off. Before, the window then dimmed under a scrim and a "Waiting for Google…" slot dropped from the top. Now the gate itself waits:
- The pressed button shows a spinner and reads Waiting for browser…, and the other button is disabled.
- Under the buttons: Finish in your browser. followed by a Cancel link. Escape does the same as Cancel.
- If the attempt fails, the existing failure sentence appears quietly in the same reserved line. That line is held open in every state, so the column never jumps.
- When the browser hands the answer back, signed in or not, the window asks main to focus it (
WINDOW_FOCUS_PANEL). The old slot'sexpand()used to do this through the window-mode round trip.
No Quit link. #1916 (Dean, merged earlier today) deliberately removed the gate's Quit Luke button, and the orchestrator confirmed that decision stands. ⌘Q and the app menu are the way out, and the existing test that the gate offers only the two providers is kept.
No Terms/Privacy footer. The repo has a /privacy page on the web app but no Terms page, and the hardened window denies link navigation. A footer would need a new act and main-process row just for one link, so it's left out rather than half-done.
Removed (notch-era sign-in slot)
apps/desktop/src/renderer/sign-in-slot.tsx(the waiting popup), plus its mount anduseMeasuredHeightinapp.tsxPANEL_PRESENTATION.SLOT(panel-state.ts) and its branch inuse-panel-presentation.ts's leave handlerSURFACE_PROPERTY.SLOT_HEIGHT/--slot-height(packages/surface/src/react-css.ts)base.css: the.slot-stage/.key-slot*stage block, theslot.panel-surfaceshape,--slot-width,--slot-mark-size,--slot-gutter-gap, and the reduced-motion.slot-stageentrydesktop.css: the slot's scrim selector, the slot stage's z-index, and the old onboarding card/face/glow rulessign-in.css:.sign-in-slot-*AccountProviderMark(account-marks.tsx), which only the slot useduseSignInno longer takes the panel-entry surface orexpand, and dropssignInWaitNowfrom its API
The rest of the notch-era cleanup (window mode / WINDOW_SET_EXPANDED, hover/leave/settle machinery, dead CSS) follows in a stacked PR. It's coordinated with the feedback-composer redo, which owns the feedback slot.
Screenshots (headless Chrome, 2x)
Before (origin/main):

After, at rest (1200×800):

After, waiting on the browser:

After, when the attempt failed:

After, in a small window (720×520):

Tests
sign-in-gate.test.ts, all through the public SignInGate and useSignIn:
- each provider's button begins that provider's sign-in
- a wait holds both buttons, and the pressed one says Waiting for browser…
- a sign-in begun from elsewhere (
SIGNING_IN) holds both buttons - a failure is announced under the buttons, which are offered again
- wired to
useSignInwith the act bridge stubbed: a refused attempt shows the failure, and Cancel asks main to withdraw the sign-in, after which the withdrawn attempt's late refusal says nothing - the gate offers only the two ways in (kept from #1916)
./scripts/check.sh exits 0.
Mac verification: CI builds nothing for the Mac and could not verify this UI. ./scripts/verify.sh was not run (this was built on a Linux VM). The screenshots above are headless Chrome renders of the real DesktopShell and stylesheet. LUKE-159 is the manual Mac pass. Session replay masking is unaffected (no new text-drawing path), and no credential or token is rendered.
🤖 Generated with Claude Code