mirror of
https://github.com/nexu-io/open-design.git
synced 2026-10-27 09:51:12 +01:00
refactor(web): replace entry global header with sidebar brand + reorder bottom chips
Pre-existing layout: a global \`AppChromeHeader\` strip sat across the
whole top of EntryView (logo + settings gear), then a 2-column body
below it. Visual mass concentrated in a thin horizontal bar that did
not relate to the page's column structure, and the settings gear
duplicated the bottom Local-CLI chip.
New layout matches the two-column "brand-in-sidebar + tabs-in-main"
pattern: the brand block lives at the top of \`.entry-side\` (left
column), the right tabs live at the top of \`.entry-main\`, and the
vertical divider between them is the only horizontal seam.
EntryView:
- Drop \`<AppChromeHeader actions={avatarMenu} />\` from EntryView's
render — the home page no longer renders the global chrome strip.
(ProjectView still uses AppChromeHeader for back-nav / file
actions, so the component itself stays in the codebase.)
- Add a sidebar brand block inside \`.entry-side\` using the
already-defined \`.entry-brand\` / \`.entry-brand-mark\` /
\`.entry-brand-title\` classes that were sitting dead in
index.css.
- Reorder \`.entry-side-foot\` chips so that the env-critical
Local CLI row sits on top of the row, with the secondary
toggles (language picker, pet adoption, X follow icon) compact
on a second row. The Follow @nexudotio chip drops its text
label and becomes icon-only — pure marketing content, so it no
longer earns a full-width pill.
- Settings access moves entirely to the Local CLI chip's existing
click handler; the top-right gear is gone (it was a duplicate).
CSS:
- \`.entry-shell\` grid: \`auto 1fr\` → \`1fr\` (no header row).
- \`.entry-side\` background: \`var(--bg-panel)\` → \`transparent\`,
so the sidebar shares the page beige and only the New-prototype
card reads as white. Removes the "everything on the left is on
one big white sheet" feeling.
- \`.entry-brand\` gets \`padding: 24px 20px 18px\` so the logo +
title block has breathing room at the top of the sidebar.
- \`.entry-brand-mark\` width/height \`44 → 34\`. The previous
44px gradient ring was visually heavier than the title text it
sat next to.
- \`.entry-brand-title\` weight \`600 → 450\`, color
\`var(--text-strong)\` → \`var(--text)\`. Serif title still
reads as the page anchor without the chunky "bold black" stamp.
- \`.entry-brand-actions\` added for future right-aligned actions
(carries no actual content in this commit — kept so re-adding a
settings/avatar entry point doesn't need new CSS).
- \`.entry-side-foot .foot-pill\` slim pass: padding
\`4px 10px → 3px 8px\`, font \`11.5px → 10.5px\`, gap \`6 → 5\`,
plus \`justify-content: center\` and \`min-height: 24px\` so the
icon-only Follow pill stays the same height as the text pills
next to it.
This commit is contained in:
@@ -469,7 +469,6 @@ export function EntryView({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="entry-shell">
|
<div className="entry-shell">
|
||||||
<AppChromeHeader actions={avatarMenu} />
|
|
||||||
<div
|
<div
|
||||||
className={`entry${petRailHidden ? '' : ' has-pet-rail'}`}
|
className={`entry${petRailHidden ? '' : ' has-pet-rail'}`}
|
||||||
style={{
|
style={{
|
||||||
@@ -479,6 +478,16 @@ export function EntryView({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<aside className="entry-side" style={{ width: sidebarWidth }}>
|
<aside className="entry-side" style={{ width: sidebarWidth }}>
|
||||||
|
<div className="entry-brand">
|
||||||
|
<span className="entry-brand-mark" aria-hidden>
|
||||||
|
<img src="/app-icon.svg" alt="" className="brand-mark-img" draggable={false} />
|
||||||
|
</span>
|
||||||
|
<div className="entry-brand-text">
|
||||||
|
<div className="entry-brand-title-row">
|
||||||
|
<span className="entry-brand-title">{t('app.brand')}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<NewProjectPanel
|
<NewProjectPanel
|
||||||
skills={skills}
|
skills={skills}
|
||||||
designSystems={designSystems}
|
designSystems={designSystems}
|
||||||
@@ -496,7 +505,26 @@ export function EntryView({
|
|||||||
loading={skillsLoading || designSystemsLoading}
|
loading={skillsLoading || designSystemsLoading}
|
||||||
/>
|
/>
|
||||||
<div className="entry-side-foot">
|
<div className="entry-side-foot">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="foot-pill foot-pill-env"
|
||||||
|
onClick={() => onOpenSettings()}
|
||||||
|
aria-label={t('settings.envConfigure')}
|
||||||
|
title={t('settings.envConfigure')}
|
||||||
|
>
|
||||||
|
<Icon name="settings" size={12} />
|
||||||
|
<span>
|
||||||
|
{config.mode === 'daemon'
|
||||||
|
? t('settings.localCli')
|
||||||
|
: apiProtocolLabel(config.apiProtocol)}
|
||||||
|
</span>
|
||||||
|
<span style={{ color: 'var(--text-faint)' }}>·</span>
|
||||||
|
<span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', maxWidth: 180 }}>
|
||||||
|
{envMetaLine}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
<div className="entry-side-foot-row">
|
<div className="entry-side-foot-row">
|
||||||
|
<LanguageMenu />
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`foot-pill pet-pill${config.pet?.adopted ? '' : ' pet-pill-fresh'}`}
|
className={`foot-pill pet-pill${config.pet?.adopted ? '' : ' pet-pill-fresh'}`}
|
||||||
@@ -530,28 +558,8 @@ export function EntryView({
|
|||||||
aria-label="Follow @nexudotio on X"
|
aria-label="Follow @nexudotio on X"
|
||||||
>
|
>
|
||||||
<Icon name="external-link" size={12} />
|
<Icon name="external-link" size={12} />
|
||||||
<span className="foot-pill-follow-label">Follow @nexudotio</span>
|
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="foot-pill"
|
|
||||||
onClick={() => onOpenSettings()}
|
|
||||||
aria-label={t('settings.envConfigure')}
|
|
||||||
title={t('settings.envConfigure')}
|
|
||||||
>
|
|
||||||
<Icon name="settings" size={12} />
|
|
||||||
<span>
|
|
||||||
{config.mode === 'daemon'
|
|
||||||
? t('settings.localCli')
|
|
||||||
: apiProtocolLabel(config.apiProtocol)}
|
|
||||||
</span>
|
|
||||||
<span style={{ color: 'var(--text-faint)' }}>·</span>
|
|
||||||
<span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', maxWidth: 180 }}>
|
|
||||||
{envMetaLine}
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
<LanguageMenu />
|
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
+17
-9
@@ -3656,7 +3656,7 @@ code {
|
|||||||
============================================================ */
|
============================================================ */
|
||||||
.entry-shell {
|
.entry-shell {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: auto 1fr;
|
grid-template-rows: 1fr;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
background: var(--bg);
|
background: var(--bg);
|
||||||
@@ -3672,7 +3672,7 @@ code {
|
|||||||
|
|
||||||
.entry-side {
|
.entry-side {
|
||||||
border-right: 1px solid var(--border);
|
border-right: 1px solid var(--border);
|
||||||
background: var(--bg-panel);
|
background: transparent;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
@@ -3681,10 +3681,16 @@ code {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
|
padding: 24px 20px 18px;
|
||||||
|
}
|
||||||
|
.entry-brand-actions {
|
||||||
|
margin-left: auto;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
.entry-brand-mark {
|
.entry-brand-mark {
|
||||||
width: 44px;
|
width: 34px;
|
||||||
height: 44px;
|
height: 34px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: linear-gradient(135deg, var(--accent-tint) 0%, var(--accent-soft) 100%);
|
background: linear-gradient(135deg, var(--accent-tint) 0%, var(--accent-soft) 100%);
|
||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
@@ -3711,11 +3717,11 @@ code {
|
|||||||
}
|
}
|
||||||
.entry-brand-title {
|
.entry-brand-title {
|
||||||
font-family: var(--serif);
|
font-family: var(--serif);
|
||||||
font-weight: 600;
|
font-weight: 450;
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
letter-spacing: -0.015em;
|
letter-spacing: -0.015em;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
color: var(--text-strong);
|
color: var(--text);
|
||||||
}
|
}
|
||||||
.entry-brand-pill {
|
.entry-brand-pill {
|
||||||
font-size: 10.5px;
|
font-size: 10.5px;
|
||||||
@@ -4792,12 +4798,14 @@ code {
|
|||||||
.entry-side-foot .foot-pill {
|
.entry-side-foot .foot-pill {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 6px;
|
justify-content: center;
|
||||||
padding: 4px 10px;
|
gap: 5px;
|
||||||
|
padding: 3px 8px;
|
||||||
|
min-height: 24px;
|
||||||
background: var(--bg-subtle);
|
background: var(--bg-subtle);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
font-size: 11.5px;
|
font-size: 10.5px;
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
align-self: flex-start;
|
align-self: flex-start;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|||||||
Reference in New Issue
Block a user