Two hairlines, 1320px apart
The defining structure of the whole system. Look at the left and right edges of this page: those lines are not one element. Every horizontal band — nav, main, footer — draws its own side borders at the same width, so they read as continuous while horizontal rules cross them.
The idea
The effect is a technical drawing: content sits inside a measured frame rather than floating on a page. Three things make it read as deliberate rather than as a stray container.
- The rails never break.
Every band repeats them at the same
max-width. A band that omits the pair puts a visible gap in the line, and the notches will then appear to dock onto nothing. This is the most common way to get the frame wrong. - Everything is 1px.
No 2px borders, no shadow standing in for an edge, no rounded corners on the frame. The only radius in the system is 3px, on the outer edge of a docking notch.
- Rules are full-bleed; content need not be.
A horizontal rule spans the whole band, edge to edge. The text inside it can sit in a narrower centred column. Making a rule match the text column collapses the effect entirely.
Rails
One rule, repeated on every band. That is the entire mechanism.
.shell,
.nav-inner,
.hero-footer,
.shell-foot-rule {
max-width: var(--maxw); /* 1320px */
margin: 0 auto;
border-left: 1px solid var(--hairline);
border-right: 1px solid var(--hairline);
}--maxw.Grid background
Fixed behind everything, masked with a radial gradient so it fades out below the fold. It establishes the 96px module the layout implies without ever being the thing you look at. It is on this page — look past the content at the top of the viewport.
.grid-bg {
position: fixed;
inset: 0;
z-index: 0;
pointer-events: none;
background-image:
linear-gradient(var(--hairline-faint) 1px, transparent 1px),
linear-gradient(90deg, var(--hairline-faint) 1px, transparent 1px);
background-size: 96px 96px;
mask-image: radial-gradient(ellipse 120% 75% at 50% 0%, #000 38%, transparent 80%);
opacity: 0.5;
}It is the first element in <body>, and .shell carries z-index: 1 so content sits above it. pointer-events: none is not optional — without it the grid eats every click on the page.
Docking notches
The signature detail: page-turn controls that dock onto the rails from outside the frame, appearing fused to it. There are two live on this page — at the far left and right edges, vertically centred. The right one breathes. Try the arrow keys.
| Declaration | Why it is there |
|---|---|
| - 1px in the calc() | Laps the notch's 1px border onto the rail. Without it there is a 1px gap and it reads as a floating button. |
| border-right: none | On the left notch, the side meeting the rail must not draw its own border or you get a doubled 2px line. Mirrored on the right. |
| border-radius: 3px 0 0 3px | Rounded on the outer edge only. The docked edge stays square. |
| 32px × 120px | Tall and narrow — reads as a tab on the frame, not a button beside it. |
| color: rgba(120,145,165,.5) | The chevron is dim at rest; the accent is spent on hover only. |
| [hidden] { display: none !important } | Lets JS toggle el.hidden = true at the end of a sequence. The !important beats the base display: flex. |
| @media (max-width: 760px) | Below the frame width there is no rail to dock to, so both notches go. |
<!-- direct children of <body>, outside the frame -->
<button type="button" class="svc7-arrow svc7-arrow-left" aria-label="Previous">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1">
<path d="M15 6l-6 6 6 6"/>
</svg>
</button>
<a href="/services" class="svc7-arrow svc7-arrow-right svc7-arrow-breathe" aria-label="Next">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1">
<path d="M9 6l6 6-6 6"/>
</svg>
</a>stroke-width="1" matters — the chevron is hairline-weight to match the frame. A button for an in-page move, an anchor when it navigates; nothing keys off the tag or the id.
Left/right arrows flash the notch for 170ms, then .click() it. The handler never contains navigation logic, so mouse and keyboard cannot diverge. It is inert while typing in a field, while a dialog is open, and below 760px where the notches are gone. Shipped in journeymro.js; nothing to wire up.
- The notch's border touches the rail — no gap, no doubled line.
- Rounded on the outer edge only; the docked edge is square.
- Dim at rest, accent on hover.
- Arrow keys flash the notch before the turn runs.
- Below 760px both notches are gone and the arrow keys are inert.
- No browser focus ring after clicking one and then pressing a key.
prefers-reduced-motionstops the breathe pulse.
Reticles
Crosshair ticks for a panel corner. A technical-drawing mark, not a decoration — at most one or two per screen, or they become wallpaper.
Page skeleton
Order matters — the rails only line up if every band is present and at the same width.
<body>
<div class="grid-bg"></div>
<header class="nav">
<div class="nav-inner">…</div>
</header>
<!-- drawer is a SIBLING of header, never nested inside it -->
<div class="nav-drawer" id="drawer" hidden>…</div>
<!-- notches: fixed, outside the frame -->
<button class="svc7-arrow svc7-arrow-left">…</button>
<button class="svc7-arrow svc7-arrow-right">…</button>
<main class="shell page-main">
<div class="page-scroll" tabindex="0">…</div>
</main>
<div class="page-rule"></div>
<div class="hero-footer"><span>© 2026 JOURNEYMRO</span></div>
</body>Use .page-flow instead of .page-main for a page that scrolls normally — this one does.
Viewport-locked pages
A page that must not scroll locks to the viewport and scrolls internally, which is what keeps the rails and the footer fixed while content moves.
.page-main {
min-height: calc(100vh - var(--chrome)); /* --chrome is 130px */
max-height: calc(100vh - var(--chrome));
display: flex;
flex-direction: column;
padding: clamp(1rem, 2.5vh, 1.8rem) var(--gutter) clamp(1rem, 4vh, 2.5rem);
overflow: hidden;
}
.page-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; }--chrome is for..page-scroll tabindex="0" and focus it. The page itself no longer scrolls, so arrow keys, Page Up/Down and space would otherwise do nothing at all. Suppress its focus ring — .scroll-y already does.100vh is a lie there and a locked page either clips its own footer or grows a second scrollbar. See Mobile.