feat(desktop): a sleeker sign-in that waits in place, not in a notch slot

Merged
DA
10d ago
+399-405

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-height and --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's expand() 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 and useMeasuredHeight in app.tsx
  • PANEL_PRESENTATION.SLOT (panel-state.ts) and its branch in use-panel-presentation.ts's leave handler
  • SURFACE_PROPERTY.SLOT_HEIGHT / --slot-height (packages/surface/src/react-css.ts)
  • base.css: the .slot-stage / .key-slot* stage block, the slot .panel-surface shape, --slot-width, --slot-mark-size, --slot-gutter-gap, and the reduced-motion .slot-stage entry
  • desktop.css: the slot's scrim selector, the slot stage's z-index, and the old onboarding card/face/glow rules
  • sign-in.css: .sign-in-slot-*
  • AccountProviderMark (account-marks.tsx), which only the slot used
  • useSignIn no longer takes the panel-entry surface or expand, and drops signInWaitNow from 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):
before

After, at rest (1200×800):
after

After, waiting on the browser:
waiting

After, when the attempt failed:
failure

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

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 useSignIn with 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


Open workspace in Conductor


Devin Review