fix(phasefinal-web): clean up the multi-page site
The 2026-09-28 expansion grew the one-page design to nine pages by bolting a nav band under each hero. This makes the cluster one site: - One site header on every page: the wordmark (home link) and a single row of short, consistent labels (Applications, Systems, Hosting, AI, Engagement, Track record, Contact). The nav no longer wraps into two rows at desktop width or four on a phone. - A real <h1> on every page (the title was a <p>), a skip link, and one footer outside <main> on every page, home included. - The contact page was unreadable: its section borrowed the home page's dark contact-card id, so its copy was grey on near-black (2.3:1) and its headings measured 1.0:1. It is an ordinary section now. - Section numbers only where there is a sequence (home, engagement). - The spec bar names all four services; it stacks cleanly on a phone. - Contrast: --text-tertiary 4.3:1 -> 4.96:1, --accent-text 4.36:1 -> 4.74:1 on paper. Track-record labels drop tracked capitals. - The grid behind the hero and the contact card is its own layer; the contact card loses its left side-tab stripe. - The stylesheet link is versioned (style.css?v=2026-09-28): CSS is cached for an hour, and the new markup must not meet the old styles. - README: nine pages, the shared structure, the CSS-version rule, and the operator's anti-slop waivers (the hero's volt rule, Space Grotesk). Copy is unchanged apart from nav labels (the brief's legal constraints hold). Still zero JavaScript and zero external requests. Impeccable detector (controls 7/0, static + rendered at 1280 and 390, light and dark): 200 unwaived -> 54, all of them the two waived brand devices; two identical runs. Operator: "ship the site cleanup, keep the rule and the font".
This commit is contained in:
@@ -13,16 +13,17 @@
|
||||
@font-face { font-family: "IBM Plex Mono"; src: url("fonts/IBMPlexMono-SemiBold.woff2") format("woff2"); font-weight: 600; font-display: swap; }
|
||||
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
--ink: #0f1318;
|
||||
--ink-2: #181d22;
|
||||
--text: #0f1318;
|
||||
--text-secondary: #4d5763;
|
||||
--text-tertiary: #6b7682;
|
||||
--text-tertiary: #626d78; /* 4.96:1 on paper (was #6b7682, 4.3:1) */
|
||||
--paper: #f6f8f9;
|
||||
--border: #c2cad2;
|
||||
--border-subtle: #dde2e7;
|
||||
--accent: #90c73e;
|
||||
--accent-text: #588021; /* AA on light */
|
||||
--accent-text: #527a1e; /* 4.74:1 on paper (was #588021, 4.36:1) */
|
||||
--volt-200: #d0e8a0;
|
||||
--volt-300: #b8db72;
|
||||
--volt-400: #a3d052;
|
||||
@@ -65,6 +66,52 @@ body {
|
||||
::selection { background: var(--volt-200); color: #0f1318; }
|
||||
|
||||
a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 3px; }
|
||||
:focus-visible { outline: 2px solid var(--volt-500); outline-offset: 3px; }
|
||||
|
||||
/* ---- Skip link: first stop for the keyboard, off-screen until focused ---- */
|
||||
.skip {
|
||||
position: absolute; left: 16px; top: 12px; z-index: 10;
|
||||
transform: translateY(-200%);
|
||||
padding: 8px 12px; border-radius: 6px;
|
||||
background: var(--paper); color: var(--text);
|
||||
font-family: var(--mono); font-size: 12.5px;
|
||||
}
|
||||
.skip:focus-visible { transform: none; }
|
||||
|
||||
/* ---- Site header: the brand and the whole site's nav, one row, every page ---- */
|
||||
.site-header { background: var(--ink); color: #f6f8f9; }
|
||||
.site-header-inner {
|
||||
max-width: 920px;
|
||||
margin: 0 auto;
|
||||
padding: 18px 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 14px 32px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.brand { display: block; line-height: 0; }
|
||||
.brand img { height: 28px; width: auto; display: block; }
|
||||
.site-nav ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px 22px;
|
||||
}
|
||||
.site-nav a {
|
||||
display: inline-block;
|
||||
padding: 6px 0;
|
||||
font-family: var(--mono);
|
||||
font-size: 12px;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
text-decoration: none;
|
||||
color: var(--slate-300);
|
||||
}
|
||||
.site-nav a:hover { color: var(--volt-300); }
|
||||
.site-nav a[aria-current="page"] { color: #ffffff; box-shadow: inset 0 -2px 0 var(--volt-500); }
|
||||
p { margin: 0; text-wrap: pretty; }
|
||||
|
||||
/* ---- Hero: ink console surface with engineering grid ---- */
|
||||
@@ -72,28 +119,37 @@ p { margin: 0; text-wrap: pretty; }
|
||||
background: var(--ink);
|
||||
color: #f6f8f9;
|
||||
position: relative;
|
||||
isolation: isolate;
|
||||
overflow: hidden;
|
||||
border-bottom: 3px solid var(--volt-500);
|
||||
}
|
||||
/* The engineering grid is its own layer, so the text's background is the ink it
|
||||
actually sits on (a detector reading the gradient as the background saw 1.1:1). */
|
||||
#hero::before, .contact-card::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: -1;
|
||||
pointer-events: none;
|
||||
background-image:
|
||||
linear-gradient(rgba(246,248,249,0.05) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(246,248,249,0.05) 1px, transparent 1px);
|
||||
background-size: 48px 48px;
|
||||
border-bottom: 3px solid var(--volt-500);
|
||||
}
|
||||
|
||||
.hero-inner {
|
||||
max-width: 920px;
|
||||
margin: 0 auto;
|
||||
padding: clamp(56px, 9vw, 104px) 28px clamp(56px, 8vw, 96px);
|
||||
padding: clamp(40px, 7vw, 80px) 28px clamp(52px, 8vw, 88px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: clamp(40px, 6vw, 64px);
|
||||
}
|
||||
|
||||
.wordmark { height: clamp(48px, 7.5vw, 72px); width: auto; display: block; align-self: flex-start; }
|
||||
|
||||
.hero-copy { max-width: 800px; }
|
||||
|
||||
.lede {
|
||||
margin: 0;
|
||||
font-family: var(--display);
|
||||
font-size: clamp(32px, 5.6vw, 54px);
|
||||
line-height: 1.1;
|
||||
@@ -128,6 +184,11 @@ p { margin: 0; text-wrap: pretty; }
|
||||
.spec-bar span { padding: 0 18px; border-left: 1px solid var(--slate-700); }
|
||||
.spec-bar span:first-child { padding-left: 0; border-left: none; }
|
||||
.spec-bar .spec-accent { color: var(--volt-300); }
|
||||
@media (max-width: 600px) {
|
||||
/* stacked, a divider would only ever start a line: drop it */
|
||||
.spec-bar { flex-direction: column; gap: 6px; }
|
||||
.spec-bar span { padding: 0; border-left: none; }
|
||||
}
|
||||
|
||||
/* ---- Body ---- */
|
||||
main {
|
||||
@@ -143,7 +204,7 @@ section {
|
||||
flex-wrap: wrap;
|
||||
gap: 32px;
|
||||
}
|
||||
#services { border-top: none; padding-top: clamp(52px, 7vw, 76px); }
|
||||
main > section:first-of-type { border-top: none; padding-top: 72px; }
|
||||
|
||||
h2 {
|
||||
margin: 0;
|
||||
@@ -191,9 +252,7 @@ h2 .num { color: var(--accent-text); margin-right: 12px; }
|
||||
.record + .record { border-top: 1px solid var(--border-subtle); }
|
||||
.record dt {
|
||||
font-family: var(--mono);
|
||||
font-size: 12.5px;
|
||||
letter-spacing: 0.05em;
|
||||
text-transform: uppercase;
|
||||
font-size: 13px;
|
||||
color: var(--text-tertiary);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
@@ -201,22 +260,20 @@ h2 .num { color: var(--accent-text); margin-right: 12px; }
|
||||
.record dd { margin: 0; font-size: 17.5px; }
|
||||
.record strong { font-family: var(--display); font-weight: 600; }
|
||||
|
||||
/* Contact — ink console panel */
|
||||
#contact {
|
||||
/* Contact — ink console panel (the home page's closing card) */
|
||||
.contact-card {
|
||||
display: block;
|
||||
position: relative;
|
||||
isolation: isolate;
|
||||
overflow: hidden;
|
||||
border-top: none;
|
||||
background: var(--ink-2);
|
||||
background-image:
|
||||
linear-gradient(rgba(246,248,249,0.05) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(246,248,249,0.05) 1px, transparent 1px);
|
||||
background-size: 48px 48px;
|
||||
border-left: 3px solid var(--volt-500);
|
||||
border-radius: 16px;
|
||||
padding: clamp(40px, 6vw, 72px);
|
||||
padding: 64px;
|
||||
color: #f6f8f9;
|
||||
}
|
||||
#contact h2 { color: var(--slate-400); margin-bottom: 20px; }
|
||||
#contact h2 .num { color: var(--volt-400); }
|
||||
.contact-card h2 { color: var(--slate-400); margin-bottom: 20px; }
|
||||
.contact-card h2 .num { color: var(--volt-400); }
|
||||
.contact-address {
|
||||
font-size: clamp(23px, 4vw, 38px);
|
||||
line-height: 1.25;
|
||||
@@ -237,67 +294,49 @@ h2 .num { color: var(--accent-text); margin-right: 12px; }
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
footer {
|
||||
/* Footer — the same on every page */
|
||||
.site-footer {
|
||||
max-width: 864px;
|
||||
width: calc(100% - 56px);
|
||||
margin: 0 auto;
|
||||
padding: 28px 0 48px;
|
||||
border-top: 1px solid var(--border-subtle);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
gap: 16px;
|
||||
gap: 12px 24px;
|
||||
flex-wrap: wrap;
|
||||
padding-top: 28px;
|
||||
font-family: var(--mono);
|
||||
font-size: 12.5px;
|
||||
color: var(--text-tertiary);
|
||||
}
|
||||
.site-footer nav { display: flex; flex-wrap: wrap; gap: 4px 18px; }
|
||||
.site-footer nav a { color: var(--text-tertiary); text-decoration: none; }
|
||||
.site-footer nav a:hover { color: var(--accent-text); text-decoration: underline; }
|
||||
.site-footer nav a[aria-current="page"] { color: var(--text); }
|
||||
|
||||
@media (max-width: 480px) {
|
||||
main { padding: 0 20px 56px; }
|
||||
.hero-inner { padding-left: 20px; padding-right: 20px; }
|
||||
.hero-inner, .site-header-inner { padding-left: 20px; padding-right: 20px; }
|
||||
.site-footer { width: calc(100% - 40px); }
|
||||
section { padding: 40px 0 48px; }
|
||||
main > section:first-of-type { padding-top: 48px; }
|
||||
.contact-card { padding: 36px 28px; }
|
||||
.site-nav ul { gap: 2px 18px; }
|
||||
}
|
||||
|
||||
/* ---- Multi-page additions (2026-09-28) ---- */
|
||||
|
||||
/* Top nav: monospace strip under the hero rule, matching the spec-bar voice */
|
||||
.site-nav {
|
||||
background: var(--ink-2);
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.site-nav ul {
|
||||
max-width: 920px;
|
||||
margin: 0 auto;
|
||||
padding: 0 28px;
|
||||
list-style: none;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px 0;
|
||||
}
|
||||
.site-nav a {
|
||||
display: block;
|
||||
padding: 12px 16px;
|
||||
font-family: var(--mono);
|
||||
font-size: 12px;
|
||||
letter-spacing: 0.09em;
|
||||
text-transform: uppercase;
|
||||
text-decoration: none;
|
||||
color: var(--slate-400);
|
||||
}
|
||||
.site-nav a:hover { color: var(--volt-300); }
|
||||
.site-nav a[aria-current="page"] {
|
||||
color: #f6f8f9;
|
||||
box-shadow: inset 0 -2px 0 var(--volt-500);
|
||||
}
|
||||
|
||||
/* Sub-pages get a compact page header instead of the full hero */
|
||||
.page-header {
|
||||
background: var(--ink);
|
||||
border-bottom: 3px solid var(--volt-500);
|
||||
color: #f6f8f9;
|
||||
}
|
||||
.page-header .hero-inner { gap: 20px; padding-bottom: clamp(36px, 5vw, 56px); padding-top: clamp(36px, 5vw, 56px); }
|
||||
.page-header .hero-inner { gap: 20px; padding-bottom: clamp(36px, 5vw, 56px); padding-top: clamp(28px, 4vw, 44px); }
|
||||
.page-header .lede { font-size: clamp(26px, 4.4vw, 40px); }
|
||||
.page-header .sublede { margin-top: 14px; }
|
||||
.page-header .wordmark { height: clamp(30px, 4.5vw, 40px); }
|
||||
.page-header .lede { line-height: 1.18; }
|
||||
|
||||
/* Service detail pages */
|
||||
.detail-lede { font-size: 18.5px; max-width: 62ch; }
|
||||
@@ -330,9 +369,4 @@ footer {
|
||||
text-transform: uppercase;
|
||||
color: var(--text-tertiary);
|
||||
}
|
||||
.related a { margin-right: 18px; }
|
||||
|
||||
/* Footer grows a nav echo */
|
||||
footer nav { display: flex; flex-wrap: wrap; gap: 4px 18px; }
|
||||
footer nav a { color: var(--text-tertiary); text-decoration: none; }
|
||||
footer nav a:hover { color: var(--accent-text); }
|
||||
.related a { margin-right: 18px; display: inline-block; white-space: nowrap; }
|
||||
|
||||
Reference in New Issue
Block a user