--- name: structural-grid description: Structural Grid (Exposed Grid / Rail Layout) design system for modern SaaS landing pages. Use when building dark-themed marketing sites, landing pages, or SaaS product pages inspired by Linear, Vercel, Resend, and Planetscale. Provides CSS foundations, section patterns, component recipes, and responsive border logic for the visible-grid aesthetic. metadata: author: nabinkhair42 version: "1.0.0" tags: - design-system - css - tailwind - nextjs - landing-page - saas --- # Structural Grid Design System You are implementing a **Structural Grid** (also called "Exposed Grid" or "Rail Layout") design pattern. This is the modern SaaS design pattern used by Linear, Vercel, Resend, Profound, and Planetscale — where the underlying page grid is promoted to a first-class visual element. ## Core Principles 1. **Visible structure** — Vertical rail lines and horizontal dividers are decorative elements, not hidden scaffolding 2. **Content lives inside the grid** — Components blend into the rail structure rather than floating over it 3. **Dashed internal, solid external** — Rail lines and section dividers are solid; internal grid cell dividers are dashed 4. **Alternating visual rhythm** — Sections alternate between default and dot-pattern backgrounds for depth 5. **Minimal containers** — No rounded-xl bordered cards floating inside sections. Content sits directly within the grid 6. **Consistent letter-spacing** — Use `tracking-wide` on all section labels and inline labels. Never mix `tracking-widest` and `tracking-wider` 7. **Every card hovers** — All grid cells get `transition-colors hover:bg-white/[0.02]` for interactive feedback --- ## CSS Foundation Add these to your global CSS. All measurements derive from a single `--rail-offset` variable. ```css /* Vertical rail lines */ .page-rails { --rail-offset: max(1rem, calc(50% - 36rem)); /* = max-w-6xl centered */ position: relative; overflow-x: clip; /* clip, NOT hidden — hidden breaks position:sticky */ } .page-rails::before, .page-rails::after { content: ''; position: absolute; top: 0; bottom: 0; width: 1px; background: var(--border); pointer-events: none; z-index: 1; } .page-rails::before { left: var(--rail-offset); } .page-rails::after { right: var(--rail-offset); } /* Content bounded to rail edges */ .rail-bounded { margin-left: var(--rail-offset); margin-right: var(--rail-offset); } /* Horizontal section divider between rails */ .section-divider { position: relative; height: 1px; z-index: 2; } .section-divider::before { content: ''; position: absolute; left: var(--rail-offset, max(1rem, calc(50% - 36rem))); right: var(--rail-offset, max(1rem, calc(50% - 36rem))); height: 1px; background: var(--border); } /* Subtle dot pattern for section backgrounds */ .dot-pattern { background-image: radial-gradient(rgba(255, 255, 255, 0.04) 1px, transparent 1px); background-size: 24px 24px; } /* Custom scrollbar — matches dark themes */ * { scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, 0.1) transparent; } ::-webkit-scrollbar { width: 6px; height: 6px; } ::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.1); border-radius: 3px; } ::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.2); } ``` ### Critical: overflow-x **Always use `overflow-x: clip` on `.page-rails`, NEVER `overflow-x: hidden`.** `hidden` creates a new scroll container which breaks `position: sticky` on any descendant. `clip` clips overflow visually without affecting scroll/sticky behavior. ### Smooth scroll with sticky navbar offset When using a sticky navbar with anchor links, add to `html`: ```css html { scroll-behavior: smooth; scroll-padding-top: 5rem; /* clears the sticky navbar height */ } ``` ### Adjusting rail width Change `36rem` to match your desired max content width: - `32rem` = 1024px = Tailwind `max-w-5xl` - `36rem` = 1152px = Tailwind `max-w-6xl` (recommended default) - `40rem` = 1280px = Tailwind `max-w-7xl` --- ## Page Structure ```tsx