diff --git a/DESIGN.md b/DESIGN.md index e7cc406..6584c19 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -7,6 +7,7 @@ Port of the visual system for ewancroft.uk. - **Palette**: Dynamic OKLCH, predominantly neutral/earthy with primary green accents. - **Typography**: Inter (Variable) for UI/Prose, JetBrains Mono for Code/Utility. - **Spacing**: 4pt modular scale (4px, 8px, 12px, 16px, 32px, 64px, 96px). +- **Page gutters**: Fluid from 16px on phones to 32px on wide layouts; avoid breakpoint jumps that reduce usable width as the viewport grows. - **Motion**: Snap-to-standard `cubic-bezier(0.25, 1, 0.5, 1)` (Quart) for transitions; `expo` for entrances. ## Register: Brand @@ -26,6 +27,7 @@ Port of the visual system for ewancroft.uk. - Use the Selected Projects row anatomy across UI collections: a clear label, supporting detail, and trailing metadata where relevant. - Actionable rows share a primary-tinted hover and keyboard-focus highlight. Static rows do not imply interactivity. - Keep rows spatially stable on hover and focus; communicate state through colour rather than positional movement. +- On tablet and mobile widths, collapse row columns before labels, descriptions, or metadata become cramped; preserve the same raised parent and inset-row hierarchy. - Keep prose lists semantic and unstyled; this pattern is for navigational and data indexes. ## Anti-references diff --git a/src/lib/components/TableOfContents.svelte b/src/lib/components/TableOfContents.svelte index ec67e98..8dce24d 100644 --- a/src/lib/components/TableOfContents.svelte +++ b/src/lib/components/TableOfContents.svelte @@ -84,4 +84,6 @@ {/each} +{:else} +
{/if} diff --git a/src/lib/styles/components.css b/src/lib/styles/components.css index c6bd2a4..567b282 100644 --- a/src/lib/styles/components.css +++ b/src/lib/styles/components.css @@ -10,7 +10,7 @@ /* ── Navigation ─────────────────────────────────────────────── */ .nav { - padding: 0 var(--space-lg); + padding: 0 clamp(var(--space-md), 4vw, var(--space-lg)); border-bottom: 1px solid var(--surface-color); background: var(--color-background-50); position: sticky; @@ -117,14 +117,25 @@ } @media (max-width: 800px) { - .nav { - padding: 0 var(--space-md); - } - .nav-inner { min-height: var(--nav-height-compact); } + .nav-brand { + min-width: 0; + } + + .nav-brand-home { + min-width: 0; + } + + .nav-brand-name { + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + .menu-toggle { display: flex; } @@ -132,26 +143,41 @@ .nav-links { display: none; position: absolute; - top: 100%; + top: calc(100% + var(--space-xs)); left: 0; width: 100%; flex-direction: column; - background: var(--color-background-50); - padding: var(--space-md); - border-bottom: 1px solid var(--surface-color); - gap: var(--space-sm); + align-items: stretch; + gap: var(--space-2xs); + padding: var(--space-xs); + border: 1px solid var(--surface-color); + border-radius: var(--radius-md); + background: var(--surface-raised); } .nav-links.open { display: flex; } + + .nav-link { + width: 100%; + padding: var(--space-sm) var(--space-3); + border-radius: var(--radius-sm); + box-shadow: none; + } + + .nav-link:hover, + .nav-link.active { + background: var(--surface-sunken); + box-shadow: none; + } } /* ── Footer ──────────────────────────────────────────────────── */ .site-footer { border-top: 1px solid var(--surface-color); - padding: var(--space-lg); + padding: var(--space-lg) clamp(var(--space-md), 4vw, var(--space-lg)); } .footer-inner { diff --git a/src/lib/styles/pages.css b/src/lib/styles/pages.css index 22b7d5b..081a2c5 100644 --- a/src/lib/styles/pages.css +++ b/src/lib/styles/pages.css @@ -26,6 +26,7 @@ @media (max-width: 640px) { .hero-hd { flex-direction: column; + align-items: flex-start; gap: var(--space-md); } } @@ -162,13 +163,19 @@ } .home-section-hd { - display: flex; - flex-direction: column; - align-items: flex-start; - gap: var(--space-xs); + display: grid; + grid-template-columns: auto minmax(var(--space-xl), 1fr); + align-items: center; + gap: var(--space-md); margin-bottom: var(--space-lg); } + .home-section-hd::after { + content: ""; + height: 1px; + background: linear-gradient(90deg, var(--surface-color), transparent); + } + .home-section-title { margin: 0; color: var(--color-text-950); @@ -360,6 +367,28 @@ white-space: nowrap; } + @media (max-width: 720px) { + .project-card { + grid-template-columns: minmax(0, 1fr) auto; + align-items: start; + gap: var(--space-xs) var(--space-md); + } + + .project-desc { + grid-column: 1 / -1; + } + + .project-card-meta { + grid-column: 2; + grid-row: 1; + } + + .link-chip { + grid-template-columns: minmax(8rem, 0.8fr) minmax(0, 1.2fr) auto; + gap: var(--space-sm); + } + } + @media (max-width: 560px) { .hero-avatar { width: 48px; @@ -375,6 +404,12 @@ gap: var(--space-xs); } + .project-desc, + .project-card-meta { + grid-column: 1; + grid-row: auto; + } + .home-section-hd { margin-bottom: var(--space-md); } @@ -389,7 +424,7 @@ } .link-grid { - grid-template-columns: minmax(0, 1fr); + padding: var(--space-2xs); } .link-chip { @@ -756,6 +791,13 @@ color: var(--color-primary-500); } + .post-layout:has(.toc-sentinel) { + grid-template-columns: 1fr; + } + .post-layout:has(.toc-sentinel) .post-sidebar { + display: none; + } + /* Post footer */ .post-footer { margin-top: var(--space-lg); @@ -828,6 +870,10 @@ position: static; height: auto; } + + .post-layout:has(.toc-sentinel) .post-sidebar { + display: none; + } } @media (max-width: 560px) { @@ -1154,6 +1200,13 @@ overflow-y: auto; } + .spec-grid:has(.toc-sentinel) { + grid-template-columns: 1fr; + } + .spec-grid:has(.toc-sentinel) .spec-toc { + display: none; + } + .toc-list { display: flex; flex-direction: column; diff --git a/src/lib/styles/theme.css b/src/lib/styles/theme.css index 2ccfb6f..546c25e 100644 --- a/src/lib/styles/theme.css +++ b/src/lib/styles/theme.css @@ -628,28 +628,28 @@ .shell-wide { max-width: var(--shell-wide); margin-inline: auto; - padding: 0 var(--space-lg) var(--space-xl); + padding: 0 clamp(var(--space-md), 4vw, var(--space-lg)) var(--space-xl); } /* Prose shell — blog posts (wide enough for TOC sidebar + content) */ .shell-prose { max-width: var(--shell-wide); margin-inline: auto; - padding: 0 var(--space-lg) var(--space-xl); + padding: 0 clamp(var(--space-md), 4vw, var(--space-lg)) var(--space-xl); } /* Narrow shell — subscriptions, support */ .shell-narrow { max-width: var(--shell-narrow); margin-inline: auto; - padding: 0 var(--space-lg) var(--space-xl); + padding: 0 clamp(var(--space-md), 4vw, var(--space-lg)) var(--space-xl); } @media (max-width: 560px) { .shell-wide, .shell-prose, .shell-narrow { - padding: 0 var(--space-md) var(--space-12); + padding-bottom: var(--space-12); } }