feat(builder): item 11 — Pages panel hierarchy: neutral header/footer rows, outline Landing badge, icon+tooltip actions

Header/Footer zone rows switched from a loud amber zoneButtonStyle to a
compact neutral zoneRowStyle in the same surface language as the page
list (accent border/bg only when active, matching the page list's own
"currently open" treatment). The "Appears on all pages" subtitle moved to
a tooltip; a fa-pencil hint fades in on row hover (`.zone-row-pencil` CSS
already shipped in the previous commit) and swaps to a check icon while
editing that zone.

The "LANDING" badge (loud amber uppercase + house icon) is now a small
outline badge — muted text, 1px border, no fill, no icon.

The page-row rename button's raw `✎` HTML entity is now an FA
`fa-pencil` icon with `data-tooltip`/`aria-label`; the delete button
(already FA fa-trash) got the same tooltip/aria treatment for
consistency. Both dropped their native `title` in favor of `data-tooltip`
to avoid a double tooltip.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-12 20:56:00 -07:00
parent 613a44c4d4
commit 67228f24b4
+42 -58
View File
@@ -58,18 +58,23 @@ export const PagesPanel: React.FC = () => {
.replace(/-+/g, '-'); .replace(/-+/g, '-');
}; };
/* ---------- Zone button style ---------- */ /* ---------- Zone row style ----------
const zoneButtonStyle = (isActive: boolean): React.CSSProperties => ({ * Same neutral surface language as the page-list rows below (Item 11) --
* header/footer are just two more items in the tree, not a louder,
* differently-colored category. The active/editing state reuses the same
* accent-outline treatment the page list already uses for the active page,
* so there's one consistent "this is what's currently open" affordance. */
const zoneRowStyle = (isActive: boolean): React.CSSProperties => ({
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
gap: 8, gap: 8,
width: '100%', width: '100%',
padding: '10px 12px', padding: '7px 10px',
fontSize: 12, fontSize: 12,
fontWeight: 600, fontWeight: isActive ? 600 : 500,
color: isActive ? '#f59e0b' : '#fbbf24', color: isActive ? 'var(--color-accent)' : 'var(--color-text-muted)',
background: isActive ? 'rgba(245, 158, 11, 0.15)' : 'rgba(245, 158, 11, 0.06)', background: isActive ? 'var(--color-accent-subtle)' : 'var(--color-bg-elevated)',
border: `1px solid ${isActive ? 'rgba(245, 158, 11, 0.5)' : 'rgba(245, 158, 11, 0.2)'}`, border: `1px solid ${isActive ? 'var(--color-accent)' : 'var(--color-border)'}`,
borderRadius: 'var(--radius-md)', borderRadius: 'var(--radius-md)',
cursor: 'pointer', cursor: 'pointer',
transition: 'all var(--transition-fast)', transition: 'all var(--transition-fast)',
@@ -78,57 +83,35 @@ export const PagesPanel: React.FC = () => {
return ( return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}> <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
{/* Header/Footer zone buttons */} {/* Header/Footer zone rows */}
<div style={{ display: 'flex', flexDirection: 'column', gap: 6, marginBottom: 8 }}> <div style={{ display: 'flex', flexDirection: 'column', gap: 6, marginBottom: 8 }}>
<button <button
onClick={editHeader} onClick={editHeader}
style={zoneButtonStyle(isEditingHeader)} className="zone-row"
style={zoneRowStyle(isEditingHeader)}
title="Appears on all pages"
> >
<i className="fa fa-window-maximize" style={{ fontSize: 13 }} /> <i className="fa fa-window-maximize" style={{ fontSize: 12, width: 14, textAlign: 'center', flexShrink: 0 }} />
<div style={{ flex: 1 }}> <span style={{ flex: 1 }}>Header</span>
<div>Edit Header</div> {isEditingHeader ? (
<div style={{ fontSize: 10, opacity: 0.7, fontWeight: 400, marginTop: 1 }}> <i className="fa fa-check-circle" style={{ fontSize: 11 }} aria-hidden />
Appears on all pages ) : (
</div> <i className="fa fa-pencil zone-row-pencil" style={{ fontSize: 11 }} aria-hidden />
</div>
{isEditingHeader && (
<span style={{
fontSize: 9,
fontWeight: 700,
textTransform: 'uppercase',
letterSpacing: '0.5px',
background: 'rgba(245, 158, 11, 0.25)',
padding: '2px 6px',
borderRadius: 'var(--radius-sm)',
}}>
Editing
</span>
)} )}
</button> </button>
<button <button
onClick={editFooter} onClick={editFooter}
style={zoneButtonStyle(isEditingFooter)} className="zone-row"
style={zoneRowStyle(isEditingFooter)}
title="Appears on all pages"
> >
<i className="fa fa-window-minimize" style={{ fontSize: 13 }} /> <i className="fa fa-window-minimize" style={{ fontSize: 12, width: 14, textAlign: 'center', flexShrink: 0 }} />
<div style={{ flex: 1 }}> <span style={{ flex: 1 }}>Footer</span>
<div>Edit Footer</div> {isEditingFooter ? (
<div style={{ fontSize: 10, opacity: 0.7, fontWeight: 400, marginTop: 1 }}> <i className="fa fa-check-circle" style={{ fontSize: 11 }} aria-hidden />
Appears on all pages ) : (
</div> <i className="fa fa-pencil zone-row-pencil" style={{ fontSize: 11 }} aria-hidden />
</div>
{isEditingFooter && (
<span style={{
fontSize: 9,
fontWeight: 700,
textTransform: 'uppercase',
letterSpacing: '0.5px',
background: 'rgba(245, 158, 11, 0.25)',
padding: '2px 6px',
borderRadius: 'var(--radius-sm)',
}}>
Editing
</span>
)} )}
</button> </button>
</div> </div>
@@ -328,18 +311,17 @@ export const PagesPanel: React.FC = () => {
title="This is the landing page — published as the root URL (index.html)" title="This is the landing page — published as the root URL (index.html)"
style={{ style={{
fontSize: 9, fontSize: 9,
fontWeight: 700, fontWeight: 600,
textTransform: 'uppercase', letterSpacing: '0.3px',
letterSpacing: '0.5px', color: 'var(--color-text-muted)',
color: '#fbbf24', background: 'transparent',
background: 'rgba(245, 158, 11, 0.15)', border: '1px solid var(--color-border-light)',
border: '1px solid rgba(245, 158, 11, 0.35)',
padding: '1px 5px', padding: '1px 5px',
borderRadius: 'var(--radius-sm)', borderRadius: 'var(--radius-sm)',
flexShrink: 0, flexShrink: 0,
}} }}
> >
<i className="fa fa-home" style={{ marginRight: 3 }} />Landing Landing
</span> </span>
)} )}
</div> </div>
@@ -359,7 +341,8 @@ export const PagesPanel: React.FC = () => {
> >
<button <button
onClick={() => startEditing(page)} onClick={() => startEditing(page)}
title="Rename" data-tooltip="Rename"
aria-label={`Rename ${page.name}`}
style={{ style={{
width: 24, width: 24,
height: 24, height: 24,
@@ -374,12 +357,13 @@ export const PagesPanel: React.FC = () => {
cursor: 'pointer', cursor: 'pointer',
}} }}
> >
&#9998; <i className="fa fa-pencil" aria-hidden="true" />
</button> </button>
{pages.length > 1 && !isLanding && ( {pages.length > 1 && !isLanding && (
<button <button
onClick={() => setDeleteConfirmId(page.id)} onClick={() => setDeleteConfirmId(page.id)}
title="Delete" data-tooltip="Delete"
aria-label={`Delete ${page.name}`}
style={{ style={{
width: 24, width: 24,
height: 24, height: 24,