Skip to content

Commit 3b2c16f

Browse files
wip v28
1 parent fd12233 commit 3b2c16f

10 files changed

Lines changed: 288 additions & 32 deletions

BITCODE_SPEC_V28_NOTES.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,10 @@ The active contained pane must own vertical scrolling; the overlay shell may con
163163
Selector-card state must render as visual indicators rather than `laneactive` / `laneready` prose, while retaining accessible labels and machine-readable state for tests.
164164
Async profile props must hydrate into editable local fields after mock/live data arrives, so display name, bio, company, avatar, and team data do not remain blank after the email field has already loaded.
165165
The BTC/BTD widget must render a compact wallet-reading posture while fresh lane-specific data loads or while stale anonymous zero-state is being revalidated; zero BTC/BTD may be shown only as a settled data state, not as an unceremonious hydration flash.
166+
Terminal-opened Auxillaries fullscreen must fill the operator viewport as a working overlay, not as a centered modal that leaves a navigation-height dead band below it.
167+
The contained selector/pane grid must use a single bounded row, with selector cards and the active pane owning their own internal scroll surfaces.
168+
Profile must remain long-form enough to expose identity, wallet, access-provider, and save controls, but its vertical rhythm must be tightened so scrolling feels like a contained product pane rather than a legacy onboarding form dropped into the commercial shell.
169+
The account-menu Auxillaries entry may reuse the pre-V26 solar-system visual language when it improves product legibility and polish, but the source and visible product naming must remain Auxillaries/Bitcode rather than restoring Orbitals as a commercial construct.
166170

167171
These changes remain V28 scope because they are MVP-readiness and trust issues.
168172
The deeper Auxillaries version retains hierarchy, spacing, diagnostics, recovery, and provider-management expansion after V28 proves the contained shell, mocked prerequisite reads, fail-closed testnet-readiness, and no-console-error baseline.

BITCODE_V28_QA.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ Implemented after Pass 2, pending next manual QA confirmation:
174174
| Vercel deployment build | pass after fix | Latest deployment failed because `lib/bitcode-app-context.ts` imported `@bitcode/protocol` before Next's workspace-package resolver knew how to transpile/alias the new formal protocol package. V28 now adds `@bitcode/protocol` to `transpilePackages`, aliases the root import to `packages/protocol/src/index.js`, and verifies the resolver in `tests/protocolCommercialBoundary.test.ts`. Local `pnpm run build` from `uapi` now passes. |
175175
| Mock top chrome during 1A | pass | Manual reconfirmation on 2026-05-08 accepted the fixed mock balance, notification, and profile posture. V28 now treats master mock mode as sufficient for auxillaries mock data in client and server code, explicitly exposes public mock flags through Next config, and revalidates stale module-level user data on new mount so lane transitions cannot keep anonymous/zero cached data. |
176176
| Dual-lane dev artifact isolation | pass | Manual reconfirmation on 2026-05-08 accepted the mock/testnet-readiness separation. V28 QA servers use lane-specific `NEXT_DIST_DIR` values so public mock env compilation is isolated per lane. |
177+
| Mock Terminal data classification | pass | Manual QA clarified that the currently visible Terminal data is mock data because the operator is in the mock lane. This evidence remains mock-lane evidence only, not testnet-readiness evidence. |
178+
| Testnet-readiness Terminal baseline | pass | Port `3001` API returns anonymous/empty readiness rather than mock profile/repos/balances, and browser verification renders `Bitcode Terminal` with `Connect Wallet`, no mock profile strings, no mock balances, and no product console/page errors. |
177179

178180
### 2026-05-08 Pass 3A: Auxillaries Profile And Connects Readiness
179181

@@ -185,13 +187,16 @@ Implemented after Pass 2, pending next manual QA confirmation:
185187
| Mock profile fields | fixed | Manual QA confirmed email but found display name and bio missing. V28 now hydrates async initial profile props into local editable state and mock data supplies display name, bio, and company posture. |
186188
| Connected repositories | pass | Manual QA confirmed mocked connected repos; browser verification confirms `Connected Repositories (3)` and `bitcode/economic-ledger` render in Connects. |
187189
| BTD/BTC first-load posture | fixed | Manual QA found the top-right widget flashing anonymous zero-state before hydrated values. V28 now surfaces a compact `Reading wallet` posture while fresh lane-specific user data is loading or revalidating stale cached zero-state. |
190+
| Fullscreen overlay viewport fit | fixed | Manual QA found a bottom gap approximately the height of the navigation/chrome after opening Auxillaries fullscreen from Terminal. V28 now lets the overlay shell fill the available viewport height and anchors the shell to the bottom edge while keeping overlay overflow hidden. |
191+
| Profile scroll quality | fixed | Manual QA found Profile auxillary scrolling technically worked but felt poor. V28 now constrains the right pane as a true `height:100%` scroll container, prevents selector/pane grid-row overflow, and tightens Profile vertical rhythm so lower wallet/access/provider controls stay reachable in the contained pane. |
192+
| Auxillaries menu icon | fixed | Manual QA found the account-menu Auxillaries entry had lost the more elegant animated solar-system cue from the late-Engi era. V28 restores the visual language as an Auxillaries-named animated solar icon without reverting product copy or route naming to Orbitals. |
188193
| Console/page errors | pass | Manual QA reported none; focused browser verification reports no product console messages and no page errors. |
189194

190195
Automated verification for this slice:
191196

192197
- `pnpm -C uapi exec jest --runInBand tests/useUserDataHydration.test.tsx tests/btdTrackerLoading.test.tsx tests/auxillariesWorkspacePanels.test.tsx tests/featureFlagsMockMode.test.ts`: pass.
193-
- `pnpm -C uapi exec playwright test tests/e2e/commercial-mvp.auxillaries.spec.ts --project=laptop --workers=1`: 8 passed.
194-
- Focused browser verification on the mock lane: raw lane text count `0`, state indicator count `4`, Profile display name `Avery Mercer`, Profile bio `Reviewing the Bitcode commercial surface in deterministic mock mode.`, pane `scrollTop` advances, Connects repos present, no product console/page errors.
198+
- `pnpm -C uapi exec playwright test tests/e2e/commercial-mvp.auxillaries.spec.ts --project=laptop --workers=1`: 9 passed, including the Terminal fullscreen Auxillaries viewport/scroll assertion.
199+
- Focused browser verification on the mock lane: raw lane text count `0`, state indicator count `4`, Profile display name `Avery Mercer`, Profile bio `Reviewing the Bitcode commercial surface in deterministic mock mode.`, shell bottom gap `0`, pane bottom overflow `0`, pane `scrollTop` advances, Save Profile is visible at the internal scroll bottom, Connects repos present, no product console/page errors.
195200

196201
Deferred to V31 from this pass:
197202

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import React from 'react';
2+
3+
import menuStyles from '../menus/glassy-menu.module.css';
4+
5+
interface AuxillariesSolarIconProps {
6+
className?: string;
7+
}
8+
9+
export function AuxillariesSolarIcon({ className = '' }: AuxillariesSolarIconProps) {
10+
return (
11+
<span
12+
aria-hidden="true"
13+
className={`${menuStyles.auxillariesSolarIcon} ${className}`.trim()}
14+
data-testid="auxillaries-solar-icon"
15+
>
16+
<span className={menuStyles.auxillariesSolarHalo} />
17+
<span className={menuStyles.auxillariesSolarRing} data-ring="outer" />
18+
<span className={menuStyles.auxillariesSolarRing} data-ring="middle" />
19+
<span className={menuStyles.auxillariesSolarRing} data-ring="inner" />
20+
<span className={menuStyles.auxillariesSolarCore} />
21+
</span>
22+
);
23+
}
24+
25+
export default AuxillariesSolarIcon;

uapi/components/base/bitcode/layout/orbital-icon.tsx

Lines changed: 0 additions & 21 deletions
This file was deleted.

uapi/components/base/bitcode/layout/user-menu.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import * as Avatar from "@radix-ui/react-avatar";
66
import classNames from "classnames";
77
import menuStyles from '../menus/glassy-menu.module.css';
88
import { ArrowRightOnRectangleIcon } from '@heroicons/react/24/outline';
9-
import { OrbitalIcon } from './orbital-icon';
9+
import { AuxillariesSolarIcon } from './auxillaries-solar-icon';
1010
import {
1111
OPEN_AUXILLARIES_FULLSCREEN_LABEL,
1212
AUXILLARIES_LIST_COMPACT_LABEL,
@@ -122,7 +122,7 @@ export function UserMenu({ user, onOpenAuxillaries, onSignOut }: UserMenuProps)
122122
}}
123123
className={`${menuStyles.item}`}
124124
>
125-
<OrbitalIcon className="h-5 w-5 flex-shrink-0 mr-2" variant="green" />
125+
<AuxillariesSolarIcon className="mr-2" />
126126
<div className="min-w-0">
127127
<span className="block">{OPEN_AUXILLARIES_FULLSCREEN_LABEL}</span>
128128
<span className="mt-0.5 block text-[0.64rem] uppercase tracking-[0.18em] text-emerald-200/60">

uapi/components/base/bitcode/menus/glassy-menu.module.css

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,137 @@
6161
.item:hover::before { opacity: 1; }
6262
.item:active { transform: scale(0.98); }
6363

64+
.auxillariesSolarIcon {
65+
position: relative;
66+
display: inline-flex;
67+
width: 1.85rem;
68+
height: 1.85rem;
69+
flex: 0 0 auto;
70+
align-items: center;
71+
justify-content: center;
72+
border-radius: 999px;
73+
color: #67feb7;
74+
filter: drop-shadow(0 0 9px rgba(101, 254, 183, 0.22));
75+
}
76+
77+
.auxillariesSolarHalo {
78+
position: absolute;
79+
inset: 0.24rem;
80+
border-radius: 999px;
81+
background:
82+
radial-gradient(circle at center, rgba(101, 254, 183, 0.2), transparent 58%),
83+
radial-gradient(circle at 60% 44%, rgba(56, 189, 248, 0.12), transparent 62%);
84+
opacity: 0.78;
85+
transform: scale(0.96);
86+
transition: opacity 180ms ease, transform 180ms ease;
87+
}
88+
89+
.auxillariesSolarCore {
90+
position: absolute;
91+
width: 0.36rem;
92+
height: 0.36rem;
93+
border-radius: 999px;
94+
background: #67feb7;
95+
box-shadow:
96+
0 0 0 2px rgba(101, 254, 183, 0.14),
97+
0 0 13px rgba(101, 254, 183, 0.78);
98+
animation: auxillariesSolarPulse 2600ms ease-in-out infinite;
99+
}
100+
101+
.auxillariesSolarRing {
102+
--solar-ring-size: 1.5rem;
103+
--solar-ring-duration: 9s;
104+
position: absolute;
105+
left: 50%;
106+
top: 50%;
107+
width: var(--solar-ring-size);
108+
height: var(--solar-ring-size);
109+
border: 1px solid rgba(101, 254, 183, 0.44);
110+
border-radius: 999px;
111+
transform: translate(-50%, -50%) rotate(0deg);
112+
animation: auxillariesSolarOrbit var(--solar-ring-duration) linear infinite;
113+
box-shadow:
114+
0 0 10px rgba(101, 254, 183, 0.12),
115+
inset 0 0 8px rgba(56, 189, 248, 0.08);
116+
}
117+
118+
.auxillariesSolarRing::after {
119+
content: '';
120+
position: absolute;
121+
top: 50%;
122+
right: -0.12rem;
123+
width: 0.24rem;
124+
height: 0.24rem;
125+
border-radius: 999px;
126+
background: #eafff7;
127+
box-shadow:
128+
0 0 7px rgba(101, 254, 183, 0.8),
129+
0 0 14px rgba(56, 189, 248, 0.26);
130+
transform: translateY(-50%);
131+
}
132+
133+
.auxillariesSolarRing[data-ring='outer'] {
134+
--solar-ring-size: 1.78rem;
135+
--solar-ring-duration: 11s;
136+
border-color: rgba(101, 254, 183, 0.34);
137+
}
138+
139+
.auxillariesSolarRing[data-ring='middle'] {
140+
--solar-ring-size: 1.42rem;
141+
--solar-ring-duration: 8.2s;
142+
border-color: rgba(34, 211, 238, 0.34);
143+
animation-direction: reverse;
144+
}
145+
146+
.auxillariesSolarRing[data-ring='middle']::after {
147+
right: auto;
148+
left: -0.1rem;
149+
width: 0.2rem;
150+
height: 0.2rem;
151+
background: #a7f3d0;
152+
}
153+
154+
.auxillariesSolarRing[data-ring='inner'] {
155+
--solar-ring-size: 1.02rem;
156+
--solar-ring-duration: 6.4s;
157+
border-color: rgba(251, 191, 36, 0.28);
158+
}
159+
160+
.auxillariesSolarRing[data-ring='inner']::after {
161+
width: 0.17rem;
162+
height: 0.17rem;
163+
background: #f9c855;
164+
box-shadow:
165+
0 0 7px rgba(249, 200, 85, 0.68),
166+
0 0 11px rgba(101, 254, 183, 0.22);
167+
}
168+
169+
.item:hover .auxillariesSolarIcon {
170+
filter:
171+
drop-shadow(0 0 12px rgba(101, 254, 183, 0.44))
172+
drop-shadow(0 0 18px rgba(56, 189, 248, 0.16));
173+
}
174+
175+
.item:hover .auxillariesSolarHalo {
176+
opacity: 1;
177+
transform: scale(1.05);
178+
}
179+
180+
.item:hover .auxillariesSolarRing[data-ring='outer'] {
181+
border-color: rgba(101, 254, 183, 0.58);
182+
animation-duration: 7.2s;
183+
}
184+
185+
.item:hover .auxillariesSolarRing[data-ring='middle'] {
186+
border-color: rgba(34, 211, 238, 0.52);
187+
animation-duration: 5.8s;
188+
}
189+
190+
.item:hover .auxillariesSolarRing[data-ring='inner'] {
191+
border-color: rgba(251, 191, 36, 0.44);
192+
animation-duration: 4.6s;
193+
}
194+
64195
.danger { color: #f87171; }
65196
.danger:hover { background: rgba(248, 113, 113, 0.08); }
66197
.dangerIcon { color: #f87171; }
@@ -72,3 +203,33 @@
72203
box-shadow: 0 10px 40px rgba(0,0,0,0.45), 0 0 0 1px rgba(101, 254, 183, 0.07), inset 0 0 24px rgba(101, 254, 183, 0.04);
73204
border-radius: 12px;
74205
}
206+
207+
@keyframes auxillariesSolarOrbit {
208+
from {
209+
transform: translate(-50%, -50%) rotate(0deg);
210+
}
211+
212+
to {
213+
transform: translate(-50%, -50%) rotate(360deg);
214+
}
215+
}
216+
217+
@keyframes auxillariesSolarPulse {
218+
0%,
219+
100% {
220+
opacity: 0.84;
221+
transform: scale(0.94);
222+
}
223+
224+
50% {
225+
opacity: 1;
226+
transform: scale(1.08);
227+
}
228+
}
229+
230+
@media (prefers-reduced-motion: reduce) {
231+
.auxillariesSolarRing,
232+
.auxillariesSolarCore {
233+
animation: none;
234+
}
235+
}

uapi/jest.config.cjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ module.exports = {
130130
'<rootDir>/tests/btdStep.integration.test.tsx',
131131
'<rootDir>/tests/navPublicShell.test.tsx',
132132
'<rootDir>/tests/navBrand.test.tsx',
133+
'<rootDir>/tests/userMenu.test.tsx',
133134
'<rootDir>/tests/footerPublicShell.test.tsx',
134135
'<rootDir>/tests/bitcodeTransactionsFilterBar.test.tsx',
135136
'<rootDir>/tests/bitcodeTransactionsActiveFilters.test.tsx',

0 commit comments

Comments
 (0)