On this page
- The 2026 design landscape
- Path A: Neo-editorial
- Path B: Neo-minimal dark
- What both paths reject
- The AI-generated tell
- Element-by-element decisions
- 1. Border radius
- 2. Typography
- 3. Color
- 4. Buttons
- 5. Cards
- 6. Shadows
- 7. Spacing
- 8. Links and navigation
- 9. Dark mode
- 10. Forms and inputs
- 11. Code blocks
- 12. Images and media
- 13. Tables
- 14. Responsive behavior
- 15. Micro-interactions and animation
- 16. Print styles
- 17. Performance considerations
- 18. Alerts and notifications
- 19. Badges and tags
- 20. Breadcrumbs
- 21. Tooltips
- 22. Pagination
- 23. Skeleton loading screens
- 24. Dividers
- 25. Search input
- 26. Modals and dialogs
- 27. Progress indicators
- 28. Accessibility baseline
- 29. Design tokens summary (all elements)
- 30. Migration guide for existing Wire sites
- 31. Sources and references
This guide exists so Wire can make opinionated default CSS decisions backed by evidence, not taste. Every element section includes what premium sites actually ship, the trade-offs, and what Wire should default to.
Wire serves B2B content sites. Not developer tools, not creative agencies, not e-commerce. Every recommendation filters through that lens.
For live rendered examples of every component, see the Components page.
Sections: Design landscape | Border radius | Typography | Color | Buttons | Cards | Shadows | Spacing | Links & navigation | Dark mode | Forms & inputs | Code blocks | Images & media | Tables | Responsive | Animation | Print | Performance | Alerts | Badges | Breadcrumbs | Tooltips | Pagination | Skeletons | Dividers | Search | Modals | Progress | Accessibility | Design tokens | Migration | Sources
The 2026 design landscape
Two clear paths have emerged. Which one you choose determines every CSS decision downstream.
Path A: Neo-editorial
Sharp corners or barely-there radius. Serif headings paired with sans-serif body text. Generous whitespace contrasted with dense content blocks. Subtle borders at low opacity instead of shadows. Restrained color (one accent, used sparingly). Warm neutral backgrounds (stone, sand) instead of pure white. Typography IS the design.
Who uses it: IBM Think, Bloomberg, Financial Times, Monocle, Stripe (recent redesign), pitch.com.
Best for: B2B, editorial, content-heavy sites, consulting, professional services.
Path B: Neo-minimal dark
Near-black backgrounds with blue or purple tint. Opacity-based everything: text hierarchy via rgba, borders at 5% opacity, hovers at 2.5% change. Glass and blur effects on interactive elements. Larger border-radius on buttons (16-32px), smaller on cards. Monochrome with single neon accent.
Who uses it: Linear, Resend, Vercel, Cal.com, most developer tools.
Best for: Developer tools, SaaS dashboards, technical products.
What both paths reject
Heavy drop shadows. The Tailwind-blue-gradient-8px-radius default look. Stock photography. Excessive animation. The "friendly SaaS" aesthetic that dominated 2020-2024 and now reads as generic or AI-generated.
The AI-generated tell
Every AI page generator produces the same output: 8px corners, blue gradients, uniform shadows, Tailwind defaults. Premium brands are moving away from these signals. The more a design looks like it was prompted into existence, the lower its perceived value.
Signals that read as AI-generated in 2026:
border-radius: 8pxon everything (the universal default)- Blue gradients (
linear-gradient(135deg, #667eea, #764ba2)) - Card hover with
translateY(-2px)shadow lift - Hero sections with centered text + two buttons + abstract illustration
- Uniform spacing and perfect symmetry everywhere
- Generic sans-serif (system-ui or basic Inter) with no typographic personality
Signals that read as human-designed and high-value:
- Intentional, specific border-radius choices (0px, 2px, or very large 32px+, not the middle)
- Restrained color palette with one accent, used precisely
- Typographic hierarchy through weight, size, and font pairing, not color
- Asymmetric or editorial layouts (not everything centered)
- Warm neutral tones instead of pure gray
- Custom or curated typefaces (not just "whatever ships with the framework")
Element-by-element decisions
1. Border radius
The single most visible design decision. It sets the entire tone.
What premium sites actually ship
| Site | Buttons | Cards | Inputs | Philosophy |
|---|---|---|---|---|
| Stripe | 6px | 8px | 6px | Subtle, consistent |
| Linear | 4-8px | 4-8px | 4px | Sharp, intentional |
| IBM Think | 0px | 8-16px | 0px | Sharp buttons, softer cards |
| Tailwind (2025) | 32px (pill) | 16px | - | Fully rounded buttons, medium cards |
| Resend | 16px | 16px | 16px | Consistent medium-large |
| shadcn/ui | 10px default | 10px | 10px | Configurable, ships medium |
| WPEngine | 50px (pill) | 32px | - | Fully rounded everything |
| Bloomberg | 0px | 0px | 0px | Zero radius, pure editorial |
| rauno.me (Linear designer) | 4px small, 8px medium, 16px large | - | - | Proportional scale |
The spectrum and what it communicates
0px: Brutalist/editorial. Says: "We are serious, authoritative, institutional." Bloomberg, newspapers, IBM buttons. Risk: can feel cold or dated if not paired with excellent typography.
2-4px: Sharp modern. Says: "We made a deliberate choice." Linear, Stripe inputs. The sweet spot for editorial sites that want to feel contemporary without being soft. Low risk of feeling generic.
6-8px: Comfortable default. This is where most of the web lives. Says nothing in particular. It's the absence of a decision. Risk: reads as "template" or "AI-generated" because every tool defaults here.
10-16px: Friendly SaaS. Resend, shadcn/ui. Says: "We're approachable." Works for consumer products. Risk: for B2B editorial, it softens authority.
32px+ / pill: Bold statement. Tailwind marketing, WPEngine. Says: "We're playful and confident." Works for CTAs that need to pop. Risk: can feel trendy, may date quickly.
Pros and cons for B2B content sites
Going sharp (0-2px):
- Pro: Immediately differentiates from the 8px default sea. Authority signal.
- Pro: Ages well. Sharp corners never look dated; they look intentional.
- Pro: Pairs naturally with serif typography and editorial layouts.
- Con: Requires stronger typography and spacing to avoid feeling stark.
- Con: Mobile tap targets need extra padding to compensate for visual sharpness.
- Surprise: Sharp corners actually increase perceived content density. The same page feels like it contains more information.
Staying medium (6-8px):
- Pro: Safe. Nobody will complain.
- Pro: Works with any typography or color scheme.
- Con: Invisible. Communicates nothing about brand identity.
- Con: In 2026, this is the "I used a template" signal.
- Surprise: A/B tests show no conversion difference between 4px and 8px radius; the choice is purely about brand perception.
Going large (16px+):
- Pro: Friendly, approachable, works for consumer-facing B2B.
- Pro: Pill buttons create strong visual hierarchy; they demand attention.
- Con: For content-heavy sites, large radius fights the content. Readers focus on the shape instead of the text.
- Con: Ages fastest. The pill button trend will date like the 2015 ghost button.
- Surprise: Large radius cards need more internal padding to look balanced, increasing overall page height by 10-15%.
Wire's recommendation for B2B content sites
--radius: 2px. Sharp enough to signal intentionality, soft enough to avoid brutalist coldness. Use 0px for buttons (editorial authority) and 2px for cards and containers (slight warmth without softness).
Exception: pill radius (9999px) for tags, badges, and small status indicators. These benefit from full rounding to signal "label" vs "container."
Dark mode: border-radius needs no adjustment between modes, but the visual effect changes. Sharp corners (0-2px) feel more prominent in dark mode because dark backgrounds make edges more visible. This actually reinforces the editorial tone. Dark mode with sharp corners feels like a newspaper's evening edition.
2. Typography
Typography makes or breaks a content site. For B2B editorial, it IS the design.
What premium sites actually ship
| Site | Headings | Body | Code | Approach |
|---|---|---|---|---|
| Linear | Inter Variable | Inter Variable | 0.9em monospace | Single family, weight hierarchy |
| Resend | Domaine (serif) | Inter Variable | Commit Mono | Serif+sans pairing |
| Cal.com | Cal Sans (display) | Inter | Paper Mono | Custom display + neutral body |
| Vercel | Geist | Geist | Geist Mono | Custom family throughout |
| IBM Think | IBM Plex Sans | IBM Plex Sans | IBM Plex Mono | Branded family |
| Stripe | Custom sans | Custom sans | - | Branded, proprietary |
| Tailwind marketing | Inter Variable | Inter Variable | - | Industry standard sans |
The serif question
Serifs are making a strong comeback for editorial and B2B content. Multiple trend analyses call it out explicitly. DesignShack lists "So Many Serifs" as a standalone 2026 trend. The pairing pattern is clear: serif headings for authority + sans-serif body for readability.
Why serifs work for B2B content:
- They signal editorial authority (newspapers, journals, books all use serifs)
- They create visual hierarchy without needing color or size differences
- They differentiate from the sans-serif-everything SaaS look
- They make long-form content feel like it was written by humans, not generated
- They pair naturally with sharp corners and restrained color palettes
Why you might avoid serifs:
- They require more careful font loading (performance budget)
- Bad serifs (Georgia, Times New Roman) look dated; good serifs (Domaine, Canela, Editorial Old) are often commercial
- They can feel pretentious if the content doesn't match the authority signal
- They work poorly at small sizes on low-DPI screens (less relevant in 2026)
Popular serif options for headings:
- Domaine (Resend uses it): clean, modern serif
- Canela (Typewolf top 10): warm, slightly quirky
- Editorial Old: classic editorial feel
- Lora (Google Fonts, free): professional, well-hinted for screens
- Playfair Display (Google Fonts, free): high contrast, dramatic
- Source Serif Pro (Google Fonts, free): Adobe's clean option
Variable fonts are now mandatory
Every premium site uses variable fonts. The performance benefit is clear: one file replaces 4-6 weight files. But the design benefit matters more: you get exact weight control for fine-tuned hierarchy.
Weight scale for B2B content:
| Element | Weight | Size | Purpose |
|---|---|---|---|
| H1 | 700 (or 600 for serif headings) | 2.25-2.5rem | Page title, one per page |
| H2 | 600 | 1.5-1.75rem | Section headers |
| H3 | 600 | 1.25rem | Subsections |
| Body | 400 | 1rem (16-18px) | Running text |
| Strong/Bold | 600 (not 700) | inherit | Emphasis without screaming |
| Caption/Meta | 400 | 0.875rem | Dates, labels, secondary info |
| Navigation | 500 | 0.875rem | Slightly heavier than body |
Surprise: using font-weight: 600 instead of 700 for bold text is a subtle quality signal. It's heavy enough to stand out but doesn't create jarring contrast in body text. Every premium site does this.
Type scale
Mathematical ratios create harmonious size relationships.
| Ratio | Name | Scale (base 16px) | Feel |
|---|---|---|---|
| 1.200 | Minor Third | 16, 19.2, 23, 27.6 | Tight, editorial |
| 1.250 | Major Third | 16, 20, 25, 31.25 | Balanced, versatile |
| 1.333 | Perfect Fourth | 16, 21.3, 28.4, 37.9 | Dramatic, magazine |
For B2B content sites, Major Third (1.250) hits the balance: enough contrast to create hierarchy, not so much that body text feels small next to headings.
Fluid typography with clamp()
Fixed font sizes are 2024. Every premium site now uses clamp() for fluid scaling.
h1 { font-size: clamp(1.75rem, 1.5rem + 1.25vw, 2.5rem); }
h2 { font-size: clamp(1.25rem, 1.1rem + 0.75vw, 1.75rem); }
body { font-size: clamp(1rem, 0.95rem + 0.25vw, 1.125rem); }
This eliminates breakpoint-based font size changes. Text scales smoothly from mobile to desktop.
Dark mode: typography needs no direct changes when using CSS custom properties for color, but contrast perception shifts. In dark mode, font-weight: 400 body text can appear thinner due to subpixel rendering on dark backgrounds. Some sites compensate with -webkit-font-smoothing: antialiased in dark mode, which produces more consistent weight rendering at the cost of slightly thinner text on macOS.
Text wrapping
Two new CSS properties that every premium site now uses:
h1, h2, h3 { text-wrap: balance; }
p { text-wrap: pretty; }
balance distributes heading text evenly across lines (no orphan words on the last line). pretty prevents orphans in paragraphs. Linear uses both. These are small details that separate hand-crafted from template.
Line height
| Element | Line height | Why |
|---|---|---|
| Headings | 1.1-1.2 | Tight. Headings are short, tight leading looks confident. |
| Body text | 1.5-1.6 | Generous. Long-form readability requires air between lines. |
| Navigation | 1 | Single line, no leading needed. |
| Code | 1.5 | Matches body text for visual consistency. |
Common mistake: using line-height: 1.5 for everything. Headings at 1.5 line-height look loose and uncommitted.
Wire's recommendation for B2B content sites
Ship a system font stack as default (fast, zero FOUT), but make it easy for sites to add a serif heading font:
--font-heading: system-ui, -apple-system, sans-serif;
--font-body: system-ui, -apple-system, sans-serif;
--font-code: ui-monospace, 'Cascadia Code', 'Fira Code', monospace;
Sites that want the editorial look add one line to their wire.yml theme:
theme:
font_heading: "'Lora', serif"
This ships fast by default and upgrades gracefully.
The type system should reinforce the rest of the design language: font-weight: 600 for emphasis (not 700) matches the restrained approach of 2px radius and no-shadow cards. Bold 700 headings feel like a different design system than subtle border-only cards. Keep the weight moderate; the hierarchy comes from size and spacing, not heaviness.
3. Color
What premium sites actually ship
| Site | Background | Text | Primary accent | Gray base | Approach |
|---|---|---|---|---|---|
| IBM Think | #f5f5f5 off-white | #161616 | #0043ce blue | Warm neutral | Monochrome + one accent |
| Linear | #08090a near-black | white via opacity | Blue | - | Dark, opacity-based |
| Resend | Black | White | #00A3FF blue | - | Forced dark |
| Cal.com | White | Dark | #6349ea purple | Neutral | Light + purple accent |
| Stripe | White | Dark gray | Blue | Cool gray | Classic corporate |
| shadcn/ui | oklch(1 0 0) | oklch(0.145 0 0) | Near-black | 6 tint options | Neutral, configurable |
| Tailwind | White | Near-black | Various | OKLCH-based | Design system |
Selection and highlight colors
A detail most sites skip: the text selection color should match the design system.
::selection {
background: color-mix(in srgb, var(--primary) 25%, transparent);
color: var(--text);
}
This uses a tinted version of your primary color instead of the browser's default blue. It is a small detail that signals attention to craft.
The shift to warm neutrals
Pure white (#fff) and pure gray (#f3f4f6) are out for editorial sites. Premium brands use warm-tinted neutrals:
| Name | Value | When to use |
|---|---|---|
| Stone | #f5f5f4 / #1c1917 | Natural, editorial feel |
| Sand | #fafaf5 / #1a1a17 | Warm, premium, print-like |
| Zinc | #fafafa / #18181b | Cool but not cold, tech editorial |
| Slate | #f8fafc / #0f172a | Blue-tinted, slightly corporate |
| Mauve | #faf9fb / #1a1523 | Purple-tinted, creative/luxury |
Surprise: the difference between pure gray and warm gray is almost invisible in isolation. But side-by-side, warm gray feels "designed" and pure gray feels "default." Users can't articulate why, but they feel it.
Opacity-based color systems
The biggest shift in how premium sites handle color: instead of defining 10 shades of gray, they use one color at different opacities.
/* Old way — hard-coded grays */
--border: #e5e7eb;
--text-muted: #6b7280;
--bg-subtle: #f3f4f6;
/* New way — opacity-based */
--border: oklch(0 0 0 / 0.08); /* 8% black */
--text-muted: oklch(0 0 0 / 0.55); /* 55% black */
--bg-subtle: oklch(0 0 0 / 0.03); /* 3% black */
Benefits: automatically works on any background color, automatically adapts to light/dark mode, fewer variables to maintain. Tailwind's latest marketing site uses borders at 5% opacity (gray-950/5).
Trade-off: opacity-based borders look slightly different on colored backgrounds. For B2B content sites with mostly white/neutral backgrounds, this is fine.
One accent color, used precisely
Every premium site uses one primary accent color, never more than two. The accent appears on:
- Primary CTA buttons (and only primary CTAs)
- Active navigation states
- Links (sometimes; some sites use underline instead of color)
- Focus rings
The accent does NOT appear on: secondary buttons, borders, backgrounds, icons, text headings. Restraint is the signal.
Surprise: many B2B sites use their brand's primary color as the accent, but the brand color often has poor contrast ratios for interactive elements. Test your accent against both --bg and --text for WCAG AA compliance (4.5:1 for text, 3:1 for large text and UI components). A brand-adjacent color with better contrast is a smarter choice than the exact brand hex.
OKLCH is the new standard
Both shadcn/ui and Tailwind have moved to OKLCH color space. Benefits:
- Perceptually uniform (same lightness value = same visual lightness across hues)
- Better for generating consistent color scales
color-mix()works correctly in OKLCH- Wider gamut on P3 displays
Trade-off: OKLCH has wide support (Chrome 111+, Safari 15.4+, Firefox 113+). The main gap is older corporate browsers still on auto-update policies. For B2B sites targeting professional users on managed machines, provide hex fallbacks for critical colors (text, background) and use OKLCH for derived colors via color-mix().
Wire's recommendation for B2B content sites
Move from pure gray to warm stone/zinc tones. Use opacity-based borders. Keep one accent color.
--bg: #fafaf9; /* warm off-white, not pure white */
--text: #1c1917; /* warm near-black, not pure black */
--text-muted: #57534e; /* warm medium gray */
--border: #e7e5e4; /* warm light gray */
--bg-subtle: #f5f5f4; /* warm subtle background */
This is stone-tinted. The difference from pure gray is subtle but the page feels more like a printed publication and less like a web app.
Trade-off: warm neutrals can clash with brand colors that have cool undertones. If a client's primary color is cool blue or violet, zinc (cool gray) may be a better base than stone (warm gray). Test the accent color against the neutral background; they should feel like they belong in the same room.
4. Buttons
Buttons are the highest-stakes design element. They're the one thing users must interact with.
What premium sites actually ship
| Site | Radius | Padding | Style | Hover |
|---|---|---|---|---|
| Tailwind marketing | 32px (pill) | px-4 py-2 | bg-black, text-sm font-semibold | - |
| Resend | 16px | h-12 px-5 | Frosted glass, gradient overlay, border-2 border-white/5 | Color inversion (bg-white/90 text-black) |
| WPEngine | 50px (pill) | 12px 24px | Solid color | Background color change |
| IBM Think | 0px | Large, full-width on mobile | Chevron arrow suffix | Background darken |
| Pitch | 6-8px | 12-16px / 24-32px | Solid or outlined | Shadow or darken |
| Linear | 4-8px | Compact | Subtle, dark | Opacity shift |
| Stripe | 6px | Medium | Solid with subtle gradient | Darken |
Button patterns and what they communicate
Pill buttons (32px+)
- Says: "I'm a call to action, I demand attention"
- Works for: hero CTAs, pricing page actions, marketing pages
- Fails for: inline content buttons, form submits, navigation
- Surprise: anecdotal A/B evidence suggests pill buttons can get higher click rates in hero sections but perform worse in forms. Users perceive them as less "serious" for transactional actions. The effect varies by audience; B2B buyers with enterprise backgrounds tend to trust squared-off buttons more
Sharp buttons (0-4px)
- Says: "I'm a professional interface element"
- Works for: editorial sites, form actions, toolbars, navigation
- Fails for: sites targeting consumers under 25 (feels too corporate)
- Pairs with: serif typography, sharp cards, restrained color
Ghost/outlined buttons
- Says: "I'm secondary, the solid button next to me is primary"
- Rule: never use a ghost button alone; it needs a solid sibling for contrast
- Common mistake: making ghost buttons too subtle (1px border, light gray). They disappear
Icon-suffixed buttons (IBM pattern)
- IBM uses a chevron arrow (→) at the end of every CTA
- Creates a strong directional signal: "this takes you somewhere"
- Wire already does this in
.related-cardwith arrow links
Hover states: what's changed
The translateY(-2px) shadow-lift hover is the 2022 pattern. Premium sites in 2026 use:
- Color shift only. Background darkens 10-15%. No movement, no shadow change. (Stripe, IBM)
- Opacity shift. Button goes from 100% to 90% opacity. Extremely subtle. (Linear)
- Color inversion. Dark button inverts to light on hover. Dramatic but controlled. (Resend)
- Underline reveal. For text-style links/buttons, an underline slides in from left. (Editorial sites)
Rule: hover transitions should be 150-200ms with ease-out. Anything longer feels sluggish. Anything shorter feels nervous.
Button padding proportions
This is where many designs fail. The ratio matters more than the absolute values.
| Type | Vertical | Horizontal | Ratio (H:V) |
|---|---|---|---|
| Small | 6px | 12px | 2:1 |
| Default | 10px | 20px | 2:1 |
| Large | 14px | 28px | 2:1 |
The 2:1 horizontal-to-vertical ratio is consistent across premium sites. Some go to 2.5:1 for wider buttons. Never go below 1.5:1 (buttons look square and cramped).
Wire's recommendation for B2B content sites
Sharp buttons with color-shift hover:
.btn {
border-radius: 2px;
padding: 10px 20px;
font-weight: 600;
font-size: 0.875rem;
letter-spacing: 0.01em;
transition: background-color 150ms ease-out, color 150ms ease-out;
}
.btn-primary {
background: var(--primary);
color: #fff;
}
.btn-primary:hover {
background: var(--primary-dark);
}
No translateY. No shadow lift. No gradient. Just a confident color shift.
Dark mode: buttons should maintain contrast ratios. For primary buttons, color-mix(in srgb, var(--primary) 80%, white) lightens the primary color for dark backgrounds. Ghost/outlined buttons need their border opacity increased from 20% to 35% in dark mode to remain visible.
Trade-off: flat buttons with only a color shift can feel unresponsive on slower connections or when the transition is missed. Consider adding an :active state that darkens further or slightly scales down (transform: scale(0.98)) to give tactile feedback on press. Also, the 2px radius on buttons can feel inconsistent if your site uses 0px elsewhere, so commit to one or the other for interactive elements.
5. Cards
Cards are the workhorse of content sites: article previews, feature blocks, pricing plans.
What premium sites actually ship
| Site | Border | Shadow | Radius | Hover | Approach |
|---|---|---|---|---|---|
| IBM Think | None | 0 2px 8px rgba(0,0,0,0.12) | 8-16px | Shadow increase | Shadow-based |
| Tailwind | outline gray-950/5 | None | 16px | - | Outline-based |
| WPEngine | 1px solid #cfdde9 | None | 32px | - | Border-based |
| Linear | None | None | 4-8px | Opacity shift | Borderless |
| Stripe | 1px solid subtle | Light shadow | 8px | Shadow increase | Mixed |
Three card schools
Shadow-based (IBM). Cards float above the page. Creates depth hierarchy. Risk: on pages with many cards, shadows create visual noise. Dark mode shadows need careful adjustment.
Border-based (Tailwind 2025). Cards are outlined containers. Cleaner than shadows, especially in grids. The trend is toward very low opacity borders. gray-950/5 is 5% black, barely visible but enough to define the boundary.
Borderless (Linear). Cards are defined by whitespace alone. Background color difference or subtle tint separates card from page. Cleanest look but requires careful spacing. Without borders, cards need more internal padding and more gap between them.
Hover effects for cards
Shadow lift (fading out): The translateY(-2px) + shadow increase pattern is being abandoned by premium sites. It was everywhere in 2020-2023 and now reads as "Bootstrap template."
What's replacing it:
- Background tint shift (card background goes from
#fffto#fafaf9on hover) - Border color intensify (border opacity goes from 5% to 15%)
- Title color shift (title changes from text color to primary accent)
- No hover state at all (the entire card is a link, cursor change is enough)
Surprise: removing card hover effects entirely often improves perceived quality. Premium publications (Bloomberg, FT) have zero card hover animation. The content speaks for itself.
Wire's recommendation for B2B content sites
Border-based with low-opacity borders, no shadows, subtle hover:
.card {
border: 1px solid var(--border);
border-radius: 2px;
padding: 1.5rem;
transition: border-color 150ms ease-out;
}
.card:hover {
border-color: var(--text-muted);
}
No shadow. No lift. The border just gets slightly more visible on hover. This is the 2026 editorial pattern.
Trade-off: border-only cards with subtle hover can feel static on pages with many cards. If a page shows 12+ cards in a grid, consider adding a background tint shift on hover (background: var(--bg-subtle)) alongside the border change. It makes the active card easier to identify in a dense grid.
Button sizing for B2B contexts
B2B sites have specific button contexts that consumer sites do not:
| Context | Size | Why |
|---|---|---|
| Inline article CTA | Default (10px 20px) | Must not overpower the content around it |
| Hero CTA | Large (14px 28px) | Needs to be the clear primary action |
| Form submit | Default | Should feel transactional, not promotional |
| Sidebar CTA | Small (6px 12px) | Space-constrained, secondary importance |
| Table action | Small | Dense context, must not disrupt scan pattern |
.btn-sm { padding: 6px 12px; font-size: 0.8125rem; }
.btn-lg { padding: 14px 28px; font-size: 1rem; }
6. Shadows
The decline of shadows
Shadows were the primary depth signal in 2018-2023 (Material Design influence). Premium sites are replacing them with:
- Borders at low opacity. Same container definition, less visual weight.
- Background color shifts. Card sits on a slightly different shade.
- Whitespace. Generous gaps between elements replace the need for visual separation.
When shadows still work
- Dropdowns and popovers. Elements that truly float above the page.
- Sticky headers. A thin shadow on scroll signals "I'm above the content."
- Modals and dialogs. Overlay contexts need depth.
- Tooltips. Small floating elements benefit from shadow.
Shadow values that read as premium
| Use case | Value | Notes |
|---|---|---|
| Sticky header (on scroll) | 0 1px 0 rgba(0,0,0,0.08) | Almost invisible, a hairline |
| Dropdown | 0 4px 12px rgba(0,0,0,0.12) | Moderate, focused |
| Modal overlay | 0 8px 30px rgba(0,0,0,0.15) | Larger, softer |
| Tooltip | 0 2px 4px rgba(0,0,0,0.1) | Tiny, close to element |
Rule: if you need a shadow larger than 30px blur, reconsider the design. Large shadows look like Photoshop drop shadows from 2010.
Surprise: shadows with a slight Y-offset and no X-offset (e.g., 0 4px 12px) feel more natural than equal X/Y shadows because they mimic overhead light. Premium sites almost never use X-offset in their shadows.
Wire's recommendation for B2B content sites
Remove shadows from cards and static elements. Keep shadows only for floating UI (dropdowns, sticky headers, modals). Reduce --shadow-sm and --shadow values:
--shadow-sm: 0 1px 0 rgba(0,0,0,0.06);
--shadow: 0 2px 8px rgba(0,0,0,0.08);
--shadow-lg: 0 4px 16px rgba(0,0,0,0.1);
7. Spacing
What premium sites actually ship
| Site | Section gap | Card gap | Content max-width | Approach |
|---|---|---|---|---|
| IBM Think | 48-64px | 16-24px | 1200-1536px grid | 12-column with gutters |
| Tailwind | 96-160px (gap-24 to gap-40) | - | 80rem (1280px) | Very generous |
| Pitch | 60-120px | 24px | - | Generous |
| WPEngine | 40-80px | 20px | - | Standard |
| Linear | 64-96px | 32px | - | Generous with dense blocks |
The premium spacing pattern
Generous between sections, dense within sections. This is the universal pattern across every premium site. The contrast between open space and packed information signals editorial confidence: "we have room to breathe, but when we speak, we say a lot."
Specific ratios that work:
- Section spacing: 4-6x the base unit (if base is 16px, sections are 64-96px apart)
- Card grid gaps: 1-1.5x the base unit (16-24px)
- Internal card padding: 1.5-2x the base unit (24-32px)
- Body text paragraphs: 1.5em margin-bottom (matches line-height)
Surprise: the most common spacing mistake on B2B content sites is too little space between sections and too much space between elements within a section. Flip the ratio: if your card gap is 24px, your section gap should be at least 64px (roughly 3x). This creates a clear visual hierarchy of "these things go together" vs. "this is a new topic."
Content max-width
The 740px content column is the standard for readable long-form text (roughly 65-75 characters per line). This should not change.
The page max-width (including sidebar, nav) is where sites differ:
| Width | Feel | Used by |
|---|---|---|
| 960px | Tight, focused | Blog-only sites |
| 1100px | Standard | Most editorial sites |
| 1200px | Spacious | Sites with sidebars |
| 1400px | Wide | Dashboard-style, multi-column |
| 1536px | Full | IBM Think (12-column grid) |
For B2B content with a sidebar nav, 1200px is the sweet spot. Wire already uses this (--page-max: 1200px).
Wire's recommendation for B2B content sites
Increase section spacing to match premium sites. The current spacing may be too tight.
section, .section { margin-block: 4rem; } /* 64px between sections */
Keep --content-max: 740px (proven readable width). Keep --page-max: 1200px.
Complete spacing system using a consistent 4px base:
--space-1: 0.25rem; /* 4px — tight inline gaps */
--space-2: 0.5rem; /* 8px — compact element spacing */
--space-3: 0.75rem; /* 12px — input padding */
--space-4: 1rem; /* 16px — card gap, paragraph spacing */
--space-6: 1.5rem; /* 24px — card padding, component gap */
--space-8: 2rem; /* 32px — section padding */
--space-12: 3rem; /* 48px — section spacing */
--space-16: 4rem; /* 64px — major section spacing */
--space-24: 6rem; /* 96px — hero/page-level spacing */
Use named tokens rather than raw values. When every spacing value traces back to the same scale, components look like they belong together even when designed independently.
8. Links and navigation
Link styling in 2026
The trend is away from colored links and toward underline-based links.
| Pattern | Used by | When |
|---|---|---|
| Color only (no underline) | Legacy SaaS | Fading out |
| Underline always | Bloomberg, FT | Editorial authority |
| Underline on hover | Stripe, Linear | Clean default, clear affordance |
| Underline slide-in | Premium editorial | Micro-interaction polish |
For B2B content sites, underline on hover is the safe choice. Underline always signals "newspaper." The key detail: use text-decoration-thickness and text-underline-offset for refined underlines:
a {
text-decoration: none;
text-underline-offset: 3px;
text-decoration-thickness: 1.5px;
}
a:hover {
text-decoration: underline;
}
The text-underline-offset: 3px moves the underline slightly below the text baseline. This prevents the underline from cutting through descenders (g, p, y). It's a detail that most templates miss.
Navigation patterns
Two-row header (IBM Think pattern):
- Row 1: Business offerings, utility links (search, contact, login). NOT sticky; scrolls away.
- Row 2: Content navigation (topics). STICKY; always accessible.
- Benefit: separates "what we sell" from "what you're reading"
Single-row sticky (current default):
- Logo + nav links + CTA. Simple, proven.
- Benefit: less complexity, less vertical space consumed.
- Downside: mixes business and content navigation.
For content-heavy sites, the two-row pattern is superior. It gives content navigation permanent visibility while letting business links scroll away (users who want to buy will find the nav in the footer or scroll up).
Active state
The trend is away from background-pill active states and toward bottom-border indicators:
.nav-active {
border-bottom: 2px solid var(--primary);
padding-bottom: 2px;
}
This is cleaner than a background pill and works better in horizontal navigation.
Full navigation CSS for B2B content sites
.nav {
display: flex;
align-items: center;
gap: 1.5rem;
font-size: 0.875rem;
font-weight: 500;
}
.nav a {
color: var(--text-muted);
text-decoration: none;
padding: 0.5rem 0;
border-bottom: 2px solid transparent;
transition: color var(--transition-fast), border-color var(--transition-fast);
}
.nav a:hover {
color: var(--text);
}
.nav a[aria-current="page"],
.nav a.nav-active {
color: var(--text);
border-bottom-color: var(--primary);
}
Dark mode: navigation needs no special treatment when using CSS custom properties. Colors adapt automatically. The bottom border indicator remains visible because --primary typically has enough contrast in both modes.
Mobile navigation
B2B content sites should not use hamburger menus as a first resort. Priority+ navigation (show what fits, put the rest in a "More" dropdown) preserves discoverability. If a hamburger is necessary:
.nav-mobile {
position: fixed;
inset: 0;
z-index: 100;
background: var(--bg);
padding: 2rem;
transform: translateX(-100%);
transition: transform 300ms ease-out;
}
.nav-mobile.open {
transform: translateX(0);
}
.nav-mobile a {
display: block;
padding: 0.75rem 0;
font-size: 1.125rem;
border-bottom: 1px solid var(--border);
}
Trade-off: slide-in panels feel more premium than dropdown overlays, but they obscure the entire page. For sites with fewer than 8 nav items, a simple vertical dropdown beneath the header is simpler and less disorienting.
9. Dark mode
Implementation patterns
Class-based (Tailwind, shadcn/ui, Vercel):
[data-theme="dark"] { ... }
.dark { ... }
Requires JS toggle. Respects user preference via localStorage.
Media query (current Wire approach):
@media (prefers-color-scheme: dark) { ... }
Automatic, no JS needed. Follows system setting.
Forced dark (Linear, Resend):
One theme only. No toggle. The brand IS dark mode.
For B2B content sites, media query is correct. Business users on corporate laptops may have system-wide dark mode. Forcing light mode on them is hostile. Forcing dark mode is even worse; printed pages look terrible.
Dark mode color adjustments most sites miss
- Reduce image brightness.
img { filter: brightness(0.9); }in dark mode prevents images from blinding readers. - Soften white text.
#e5e7ebnot#ffffff. Pure white on dark backgrounds is harsh. - Increase border opacity. Borders need to be slightly more visible in dark mode because the contrast range is smaller.
- Shadows become invisible in dark mode. Replace with subtle borders or brighter-tinted shadows.
- Code blocks need separate attention. If your light mode code block is dark-on-light, dark mode should NOT invert to light-on-dark. That's jarring. Keep code blocks dark in both modes.
10. Forms and inputs
What premium sites actually ship
| Site | Input radius | Input border | Focus state | Button style |
|---|---|---|---|---|
| Linear | 4px | Subtle gray | Blue ring | Match system |
| Stripe | 6px | 1px solid #e0e0e0 | Blue shadow ring | Rounded blue |
| Cal.com | 6px | Light gray | Purple ring | Purple solid |
| shadcn/ui | 10px | Light gray | Ring + border change | System |
The focus ring pattern
outline has replaced box-shadow for focus rings. Modern browsers support outline-offset and outline respects border-radius:
input:focus-visible {
outline: 2px solid var(--primary);
outline-offset: 2px;
}
This is accessible (visible focus for keyboard users), not visible on click (:focus-visible vs :focus), and works in both light and dark mode.
Input height and padding
| Size | Height | Padding | Font size | Use |
|---|---|---|---|---|
| Small | 32px | 6px 10px | 14px | Dense forms, filters |
| Default | 40px | 8px 12px | 14-16px | Standard forms |
| Large | 48px | 12px 16px | 16px | Hero inputs, subscribe forms |
The 40px input height is the standard. Match button height to input height for inline form layouts (input + button side by side).
Surprise: label placement above the input (not beside it) completes forms 20-30% faster in UX studies. For B2B forms with many fields (contact forms, demo requests), top-aligned labels also work better on mobile without any layout changes. Never use placeholder text as the label. It disappears on focus and creates an accessibility failure.
Wire's recommendation for B2B content sites
input, textarea, select {
border: 1px solid var(--border);
border-radius: 2px;
padding: 8px 12px;
font-size: 0.875rem;
transition: border-color 150ms ease-out;
}
input:focus-visible {
outline: 2px solid var(--primary);
outline-offset: 2px;
border-color: var(--primary);
}
input:disabled, textarea:disabled, select:disabled {
opacity: 0.5;
cursor: not-allowed;
background: var(--bg-subtle);
}
Error and validation states
input[aria-invalid="true"],
.input-error {
border-color: oklch(0.6 0.2 25);
}
input[aria-invalid="true"]:focus-visible {
outline-color: oklch(0.6 0.2 25);
}
.input-error-message {
color: oklch(0.5 0.2 25);
font-size: 0.8125rem;
margin-top: 0.375rem;
}
Use aria-invalid="true" as the CSS hook rather than a custom class. It gives you accessibility semantics and styling in one attribute. Pair with aria-describedby pointing to the error message element.
Dark mode: error red needs to shift toward a lighter, more saturated value in dark mode. oklch(0.7 0.2 25) for borders and oklch(0.8 0.15 25) for text maintains readability without the alarm-bell intensity that red-on-dark can create.
11. Code blocks
What premium sites actually ship for technical content
| Site | Background | Text | Radius | Extras |
|---|---|---|---|---|
| Linear | #08090a (same as page) | Slightly muted | 4-8px | - |
| Vercel | Dark | Light gray | 8px | Copy button |
| Tailwind | Dark | Syntax highlighted | 8px | Language label |
| GitHub | #f6f8fa (light) / #161b22 (dark) | Dark / Light | 6px | Copy button, line numbers |
Light vs dark code blocks
Dark code blocks on a light page create a strong visual anchor. They draw the eye and break up running text. This is usually desirable for technical content.
Light code blocks (GitHub-style) are less intrusive but also less attention-grabbing. For inline code, light backgrounds are clearly better.
Recommendation: keep dark code blocks. They're an established convention. Add a copy button (Wire already has this). Consider language labels for multi-language docs.
Wire's recommendation for B2B content sites
pre {
background: var(--code-bg);
color: var(--code-text);
border-radius: var(--radius);
padding: 1.25rem 1.5rem;
font-size: 0.875rem;
line-height: 1.5;
overflow-x: auto;
border: 1px solid var(--border);
}
code {
font-family: var(--font-code);
font-size: 0.875em;
}
/* Inline code */
:not(pre) > code {
background: var(--bg-subtle);
padding: 0.15em 0.35em;
border-radius: var(--radius);
font-size: 0.85em;
}
The var(--radius) on code blocks keeps them consistent with cards and inputs. The border provides definition in both light and dark mode, compensating for the shadow-free design approach used everywhere else.
12. Images and media
The 2026 approach
Full-bleed hero images are fading. Premium editorial sites are moving toward:
- Contained images with consistent aspect ratios (16:9 or 3:2)
object-fit: coverwith fixed-height containers- Subtle border-radius on images (matching card radius)
filter: brightness(0.9)in dark mode
Image aspect ratio enforcement:
.article-hero {
aspect-ratio: 16 / 9;
object-fit: cover;
border-radius: 2px;
width: 100%;
}
This prevents layout shift and ensures consistency across pages.
Lazy loading
loading="lazy" for images below the fold. loading="eager" for hero images. decoding="async" for all images. These are table stakes in 2026.
B2B image considerations
B2B content sites face unique image challenges. Stock photography destroys credibility; buyers recognize generic "team in a meeting" photos instantly. Better alternatives:
- Diagrams and flowcharts: show process understanding, not stock emotion
- Screenshots with annotations: prove you know the product/domain
- Data visualizations: charts and graphs signal analytical capability
- Custom illustrations: even simple line drawings beat stock photos
- No image: a well-typeset page with no hero image outperforms a page with a bad stock hero
For Wire's default theme, images should be opt-in, not required. A page without a hero image should look intentional, not broken.
13. Tables
Tables in content sites are often ugly because nobody styles them. Premium sites handle tables with:
table {
width: 100%;
border-collapse: collapse;
}
th {
text-align: left;
font-weight: 600;
font-size: 0.875rem;
text-transform: uppercase;
letter-spacing: 0.05em;
padding: 0.75rem 1rem;
border-bottom: 2px solid var(--border);
color: var(--text-muted);
}
td {
padding: 0.75rem 1rem;
border-bottom: 1px solid var(--border);
}
tr:last-child td {
border-bottom: none;
}
No vertical borders. No zebra striping (that's a 2015 pattern). Just clean horizontal lines with a heavier header border.
B2B table specifics
B2B content sites use comparison tables heavily (vendor vs. vendor, feature matrices, pricing tiers). These tables need:
- Sticky headers for long tables:
th { position: sticky; top: var(--header-height); background: var(--bg); z-index: 10; } - Horizontal scroll on mobile: wrap tables in a
divwithoverflow-x: autorather than squeezing columns - Alignment: numbers right-aligned (
text-align: right), text left-aligned, checkmarks/icons centered - Row hover for scanning wide tables:
tr:hover td { background: var(--bg-subtle); }. Use this only for comparison tables with 5+ columns, not for simple data tables
.table-responsive {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
margin: 1.5rem 0;
}
.table-responsive table {
min-width: 600px;
}
Dark mode: table borders should use var(--border) which automatically adapts. The header border (2px solid) remains visible in both modes because of the weight difference.
14. Responsive behavior
Breakpoints in 2026
| Width | Name | Layout |
|---|---|---|
| <640px | Mobile | Single column, stacked |
| 640-900px | Tablet | Reduced sidebar or hidden |
| 900-1200px | Desktop | Full layout |
| >1200px | Wide | Max-width container kicks in |
Container queries are replacing some media queries. The concept: components respond to their container width, not viewport width. This matters for sidebar/no-sidebar layouts where content area width changes.
.card-grid {
container-type: inline-size;
}
@container (min-width: 600px) {
.card-grid { grid-template-columns: repeat(2, 1fr); }
}
Wire can adopt this gradually. For now, media queries work fine for the layout-level decisions.
Mobile-first is still correct
The debate is settled. Base CSS is the mobile layout; complexity adds with min-width queries. Every framework agrees. The practical benefit for B2B sites: corporate users increasingly review content on phones during commutes and in meetings. If your mobile layout is an afterthought, you lose the executive audience.
15. Micro-interactions and animation
What premium sites actually do
Transition duration scale:
| Speed | Value | Use |
|---|---|---|
| Instant | 0ms | Active/pressed states |
| Fast | 100-150ms | Button hover, focus, opacity |
| Normal | 200-300ms | Color changes, border changes |
| Slow | 400-600ms | Layout transitions, entrance animations |
| Cinematic | 800ms+ | Page transitions, hero animations |
Most premium B2B sites stay in the 150-200ms range. Anything slower feels like a consumer app.
Easing functions:
| Function | Feel | Use |
|---|---|---|
ease-out | Quick start, gentle stop | Most hover/focus transitions |
ease-in-out | Smooth both ends | Layout changes |
cubic-bezier(.37,0,.63,1) | Custom ease | Wix-style smooth interactions |
steps(1, end) | Discrete | Loading indicators (Linear) |
Rule: ease-out for 90% of transitions. ease-in-out for layout shifts. Never linear (feels mechanical).
Scroll-based animations (CSS-only in 2026)
@keyframes fade-in {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.section { animation: fade-in linear; animation-timeline: view(); }
This is CSS-only scroll animation, no JavaScript library needed. Elements fade in as they enter the viewport. Support is good enough for progressive enhancement (Chrome 115+, Firefox 120+).
Trade-off: animation-timeline: view() is not supported in Safari as of early 2026 (WebKit has partial implementation behind a flag). Use @supports (animation-timeline: view()) to prevent broken layouts. The animation simply won't play in unsupported browsers, which is an acceptable progressive enhancement.
Reduced motion
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
This is accessibility law in many jurisdictions (WCAG 2.3.3). Always include it.
Scrollbar styling
Custom scrollbars signal attention to detail. Both Chrome/Edge and Firefox now support styling:
/* Chromium + Safari */
::-webkit-scrollbar { width: 8px; }
::-webkit-scrollbar-track { background: var(--bg-subtle); }
::-webkit-scrollbar-thumb {
background: var(--border);
border-radius: var(--radius-pill);
}
::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }
/* Firefox */
* {
scrollbar-width: thin;
scrollbar-color: var(--border) var(--bg-subtle);
}
Trade-off: custom scrollbars override OS-level accessibility settings. Users who have enlarged scrollbars for motor accessibility will lose that customization. Use scrollbar-width: thin rather than a fixed pixel width; it respects user preferences while still looking refined.
16. Print styles
Often forgotten. B2B content gets printed and PDF'd more than consumer content.
@media print {
nav, footer, .toc, .sidebar, .back-to-top, .cta,
.search-input, .pagination, .progress-bar, dialog,
.skip-link, .reading-progress { display: none; }
body { font-size: 12pt; line-height: 1.5; color: #000; background: #fff; }
a { color: #000; text-decoration: underline; }
a[href]::after { content: " (" attr(href) ")"; font-size: 0.8em; }
h1, h2, h3 { page-break-after: avoid; }
img { max-width: 100% !important; }
}
The a[href]::after rule prints URLs next to links. This is essential for printed B2B content where readers can't click.
Surprise: B2B content is printed or PDF'd at 5-10x the rate of consumer content. Executives share printed articles in meetings, compliance teams archive content as PDFs, and procurement teams print comparison pages. A solid print stylesheet is not optional for B2B. It is a feature.
17. Performance considerations
Font loading
Variable fonts reduce HTTP requests. But loading strategy matters:
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>
font-display: swap for body text (show text immediately, swap font in). font-display: optional for display/heading fonts (don't swap if font hasn't loaded, preventing layout shift).
For Wire's default (system fonts), this entire section is irrelevant. Performance is already optimal. But when sites add custom fonts via theme.font_heading, document the loading strategy.
CSS size
Wire's wire.css is a single file. This is correct for sites under 50 pages. For larger sites, consider extracting critical CSS (above-the-fold styles) inline in <head> and loading the rest asynchronously.
Current wire.css should stay under 80KB uncompressed. With gzip, CSS compresses to roughly 15-20% of its original size, so even 80KB becomes ~15KB over the wire. This is well within budget, but monitor growth; each new component adds CSS weight that every page carries.
18. Alerts and notifications
B2B content sites need four alert levels: info, success, warning, and error. These appear in documentation, status pages, and form validation.
What premium sites actually ship
Most design systems (shadcn/ui, Radix, GitHub Primer) use left-border alerts: a colored left border on a tinted background. This pattern works because it signals severity without screaming.
.alert {
padding: 1rem 1.25rem;
border-radius: var(--radius);
border-left: 3px solid;
font-size: 0.875rem;
line-height: 1.5;
}
.alert-info {
background: oklch(0.95 0.02 250);
border-color: oklch(0.55 0.15 250);
color: oklch(0.35 0.1 250);
}
.alert-success {
background: oklch(0.95 0.03 155);
border-color: oklch(0.55 0.15 155);
color: oklch(0.3 0.1 155);
}
.alert-warning {
background: oklch(0.95 0.04 85);
border-color: oklch(0.7 0.15 85);
color: oklch(0.35 0.1 85);
}
.alert-error {
background: oklch(0.95 0.03 25);
border-color: oklch(0.6 0.2 25);
color: oklch(0.35 0.15 25);
}
Trade-off: OKLCH gives perceptually consistent alert backgrounds, but you need hex fallbacks for older browsers. The left-border pattern also breaks in RTL layouts; use border-inline-start instead of border-left if you serve RTL languages.
Dark mode: invert the relationship. Use dark tinted backgrounds with lighter border and text colors. Reduce background lightness from 0.95 to 0.2 and increase text lightness from 0.35 to 0.85.
19. Badges and tags
Small inline indicators for categories, statuses, and labels. B2B content sites use them for article categories, version labels, and content status.
.badge {
display: inline-flex;
align-items: center;
padding: 2px 8px;
font-size: 0.75rem;
font-weight: 600;
line-height: 1.5;
border-radius: var(--radius-pill);
letter-spacing: 0.02em;
}
.badge-default {
background: var(--bg-subtle);
color: var(--text-muted);
}
.badge-primary {
background: var(--primary-light);
color: var(--primary);
}
The pill radius (9999px) is correct here; badges should look distinct from buttons and containers. This is the one place large radius is universally appropriate.
Trade-off: badges with text longer than 3-4 words look awkward as pills. For longer labels, switch to a rectangular shape with var(--radius).
20. Breadcrumbs
Essential for content sites with topic hierarchies. B2B readers use breadcrumbs for orientation more than navigation.
.breadcrumb {
display: flex;
flex-wrap: wrap;
gap: 0.25rem;
font-size: 0.8125rem;
color: var(--text-muted);
list-style: none;
padding: 0;
margin: 0 0 1.5rem;
}
.breadcrumb li + li::before {
content: "/";
margin-right: 0.25rem;
color: var(--border);
}
.breadcrumb a {
color: var(--text-muted);
text-decoration: none;
}
.breadcrumb a:hover {
color: var(--text);
text-decoration: underline;
}
Use / as separator, not > or ›. The slash is the most widely understood hierarchy indicator and matches URL structure. Keep breadcrumbs small (0.8125rem / 13px); they are orientation, not primary navigation.
Trade-off: breadcrumbs consume vertical space. On mobile, consider hiding them or truncating intermediate levels with an ellipsis.
21. Tooltips
For B2B content, tooltips serve abbreviation definitions, feature explanations, and data point context. Keep them simple.
.tooltip {
position: absolute;
z-index: 50;
padding: 6px 10px;
font-size: 0.8125rem;
line-height: 1.4;
color: var(--bg);
background: var(--text);
border-radius: var(--radius);
box-shadow: var(--shadow);
max-width: 240px;
pointer-events: none;
opacity: 0;
transition: opacity var(--transition-fast);
}
.tooltip.visible {
opacity: 1;
}
Inverted color (dark background, light text) is the standard for tooltips; it creates a clear visual layer separation. Dark mode: swap to light background with dark text (background: var(--bg-subtle); color: var(--text)).
Trade-off: CSS-only tooltips (using ::after and :hover) avoid JavaScript but cannot be repositioned to stay within the viewport. For content sites with edge-placed tooltips, a lightweight JS solution is worth the cost.
22. Pagination
B2B content archives and search results need pagination. The current trend is minimal.
.pagination {
display: flex;
align-items: center;
gap: 0.25rem;
font-size: 0.875rem;
}
.pagination a, .pagination span {
display: flex;
align-items: center;
justify-content: center;
min-width: 36px;
height: 36px;
padding: 0 8px;
border-radius: var(--radius);
color: var(--text-muted);
text-decoration: none;
transition: background-color var(--transition-fast);
}
.pagination a:hover {
background: var(--bg-subtle);
color: var(--text);
}
.pagination .active {
background: var(--text);
color: var(--bg);
font-weight: 600;
}
The active page uses inverted colors (dark background) rather than the primary accent. This keeps pagination neutral. The content is the focus, not the navigation controls.
Trade-off: numbered pagination adds cognitive load. For blog-style archives, "Load more" or infinite scroll may convert better. But for reference content (documentation, guides), numbered pagination lets readers bookmark specific pages.
23. Skeleton loading screens
For B2B sites with dynamic content loading (search results, filtered views), skeleton screens reduce perceived wait time.
.skeleton {
background: var(--bg-subtle);
border-radius: var(--radius);
position: relative;
overflow: hidden;
}
.skeleton::after {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(
90deg,
transparent,
oklch(1 0 0 / 0.04),
transparent
);
animation: shimmer 1.5s infinite;
}
@keyframes shimmer {
from { transform: translateX(-100%); }
to { transform: translateX(100%); }
}
.skeleton-text {
height: 1rem;
margin-bottom: 0.75rem;
width: 80%;
}
.skeleton-heading {
height: 1.5rem;
margin-bottom: 1rem;
width: 60%;
}
The shimmer animation signals "loading" without being distracting. Use prefers-reduced-motion to disable the animation; show a static gray block instead.
Dark mode: change the shimmer highlight to oklch(1 0 0 / 0.06), slightly more visible against dark backgrounds.
Trade-off: skeleton screens only matter for JavaScript-rendered content. Wire's static-first approach means skeletons are rarely needed. Include them if your site has client-side search or filtered content.
24. Dividers
Horizontal rules and section separators. Simple but often over-styled.
hr, .divider {
border: none;
border-top: 1px solid var(--border);
margin: 2rem 0;
}
.divider-subtle {
border-top-color: var(--border-light);
}
.divider-heavy {
border-top-width: 2px;
}
One weight for most dividers, a heavier variant for major section breaks. Never use decorative dividers (gradients, icons, flourishes) on B2B content sites; they undermine editorial authority.
25. Search input
Content sites need search. The search input pattern is distinct from form inputs; it is a navigation element, not a form field.
.search-input {
width: 100%;
max-width: 480px;
padding: 10px 12px 10px 36px;
font-size: 0.875rem;
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--bg) url("data:image/svg+xml,...") 12px center / 16px no-repeat;
transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}
.search-input:focus-visible {
outline: 2px solid var(--primary);
outline-offset: 2px;
border-color: var(--primary);
}
.search-input::placeholder {
color: var(--text-light);
}
The left-padded search icon (via inline SVG in background) is the established pattern. Avoid placing the icon as a separate element; it complicates click-to-focus behavior.
For B2B sites, consider the Ctrl+K / Cmd+K keyboard shortcut pattern (used by Stripe, Linear, Vercel). Display a subtle ⌘K hint inside the search input. This signals to technical and power users that the site respects their workflow.
Dark mode: search inputs need a slightly lighter background than the page (var(--bg-subtle)) to remain visible against dark backgrounds.
26. Modals and dialogs
B2B content sites use modals sparingly (newsletter signups, confirmation dialogs, and image lightboxes). The native <dialog> element is now the correct approach.
dialog {
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 2rem;
max-width: 520px;
width: calc(100% - 2rem);
box-shadow: var(--shadow-lg);
background: var(--bg);
color: var(--text);
}
dialog::backdrop {
background: oklch(0 0 0 / 0.5);
backdrop-filter: blur(2px);
}
dialog[open] {
animation: dialog-in 200ms ease-out;
}
@keyframes dialog-in {
from { opacity: 0; transform: translateY(8px); }
to { opacity: 1; transform: translateY(0); }
}
The native <dialog> element handles focus trapping, Escape key, and backdrop clicks automatically. This eliminates the need for modal JavaScript libraries.
Trade-off: <dialog> cannot be animated on close without JavaScript (the close event fires after the element is hidden). For B2B content sites, closing without animation is acceptable. The content behind the modal is what matters.
Dark mode: the backdrop should use higher opacity in dark mode (oklch(0 0 0 / 0.7)) because light modals on dark pages create less natural contrast than dark modals on light pages.
27. Progress indicators
For multi-step forms, onboarding flows, or content series navigation.
.progress-bar {
height: 4px;
background: var(--bg-subtle);
border-radius: var(--radius-pill);
overflow: hidden;
}
.progress-bar-fill {
height: 100%;
background: var(--primary);
border-radius: var(--radius-pill);
transition: width 300ms ease-out;
}
.progress-steps {
display: flex;
justify-content: space-between;
counter-reset: step;
}
.progress-step {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.5rem;
font-size: 0.8125rem;
color: var(--text-muted);
}
.progress-step.active {
color: var(--primary);
font-weight: 600;
}
.progress-step::before {
counter-increment: step;
content: counter(step);
display: flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
border-radius: 50%;
border: 2px solid var(--border);
font-size: 0.75rem;
font-weight: 600;
}
.progress-step.active::before {
border-color: var(--primary);
background: var(--primary);
color: #fff;
}
.progress-step.completed::before {
border-color: var(--primary);
background: var(--primary);
color: #fff;
content: "\2713";
}
For reading progress (Wire already has this), a thin 3px bar at the top of the viewport is the standard. Keep it unobtrusive; the reader should notice it peripherally, not focus on it.
28. Accessibility baseline
Accessibility is not a feature. It is a legal requirement in most B2B markets (ADA, EAA, WCAG 2.2 AA). These CSS rules form the minimum baseline.
Focus visibility
Every interactive element needs a visible focus indicator for keyboard users:
:focus-visible {
outline: 2px solid var(--primary);
outline-offset: 2px;
}
:focus:not(:focus-visible) {
outline: none;
}
The :focus-visible selector shows focus rings only for keyboard navigation, not mouse clicks. This is the correct behavior; click users do not need focus indicators.
Minimum touch targets
WCAG 2.5.8 requires 24x24px minimum target size (44x44px recommended). For B2B sites on touch devices:
button, a, input, select, textarea {
min-height: 44px; /* recommended */
}
/* Or use padding to achieve it */
.nav a {
padding: 0.75rem 1rem; /* increases tap area without visual bloat */
}
Trade-off: 44px touch targets consume more vertical space. For dense data tables or compact navigation, 32px is acceptable if spacing between targets is at least 8px.
Color contrast
Minimum contrast ratios (WCAG AA):
- Body text: 4.5:1 against background
- Large text (18px+ or 14px+ bold): 3:1
- UI components (borders, icons): 3:1
- Placeholder text: exempt, but 3:1 is good practice
Test your warm neutral palette. --text-muted: #57534e on --bg: #fafaf9 achieves 5.7:1, which passes. But --text-light: #78716c on --bg: #fafaf9 is 3.6:1, which only passes for large text and UI components.
Skip navigation
.skip-link {
position: absolute;
top: -100%;
left: 1rem;
padding: 0.75rem 1.5rem;
background: var(--primary);
color: #fff;
border-radius: var(--radius);
z-index: 200;
font-weight: 600;
}
.skip-link:focus {
top: 1rem;
}
Place a <a href="#main" class="skip-link">Skip to content</a> as the first element in <body>. Screen reader and keyboard users expect this.
29. Design tokens summary (all elements)
If Wire were to update its defaults based on all the above evidence, here's the complete token set:
:root {
/* Typography */
--font-heading: system-ui, -apple-system, sans-serif;
--font-body: system-ui, -apple-system, sans-serif;
--font-code: ui-monospace, 'Cascadia Code', 'Fira Code', monospace;
/* Colors — warm stone palette */
--primary: #1d4ed8;
--primary-dark: color-mix(in srgb, var(--primary) 80%, black);
--primary-light: color-mix(in srgb, var(--primary) 12%, white);
--accent: #047857;
--text: #1c1917;
--text-muted: #57534e;
--text-light: #78716c;
--bg: #fafaf9;
--bg-subtle: #f5f5f4;
--bg-code: #1c1917;
--border: #e7e5e4;
--border-light: #f5f5f4;
--code-bg: #1c1917;
--code-text: #e7e5e4;
/* Spacing — 4px base scale */
--space-1: 0.25rem;
--space-2: 0.5rem;
--space-3: 0.75rem;
--space-4: 1rem;
--space-6: 1.5rem;
--space-8: 2rem;
--space-12: 3rem;
--space-16: 4rem;
--space-24: 6rem;
/* Layout */
--sidebar-width: 260px;
--content-max: 740px;
--header-height: 56px;
--page-max: 1200px;
/* Shape */
--radius: 2px;
--radius-pill: 9999px;
/* Shadows — minimal, only for floating UI */
--shadow-sm: 0 1px 0 rgba(0,0,0,0.06);
--shadow: 0 2px 8px rgba(0,0,0,0.08);
--shadow-lg: 0 4px 16px rgba(0,0,0,0.1);
/* Motion */
--transition-fast: 150ms ease-out;
--transition-normal: 200ms ease-out;
--transition-slow: 300ms ease-out;
/* Z-index scale */
--z-dropdown: 10;
--z-sticky: 20;
--z-overlay: 50;
--z-modal: 100;
--z-skip: 200;
}
@media (prefers-color-scheme: dark) {
:root {
--text: #e7e5e4;
--text-muted: #a8a29e;
--text-light: #78716c;
--bg: #1c1917;
--bg-subtle: #292524;
--bg-code: #0c0a09;
--border: #44403c;
--border-light: #292524;
--code-bg: #0c0a09;
--code-text: #e7e5e4;
--primary-light: color-mix(in srgb, var(--primary) 20%, black);
--shadow-sm: 0 1px 0 rgba(0,0,0,0.2);
--shadow: 0 2px 8px rgba(0,0,0,0.3);
--shadow-lg: 0 4px 16px rgba(0,0,0,0.4);
}
}
30. Migration guide for existing Wire sites
When Wire ships updated defaults, existing sites should not break. The approach:
- Version the defaults. Sites pin to a CSS version. New sites get new defaults.
- Override via wire.yml theme. Sites can set
theme.radius: 8pxto keep the old look. - Document changes. This guide becomes the reference.
For Wire's own site (wire.wise-relations.com), apply the new defaults immediately. It is the reference implementation.
For customer sites, the change is transparent: new sites get the 2026 defaults, existing sites keep their current theme config.
What specifically changes from Wire's pre-2026 defaults
| Element | Old default | New default | Impact |
|---|---|---|---|
| Border radius | 4-8px | 2px | Visual tone shifts from generic to editorial |
| Card style | Shadow-based | Border-based | Lighter, cleaner page feel |
| Hover effects | translateY lift | Color/border shift | Less animation, more restraint |
| Color palette | Pure grays | Warm stone tones | Warmer, more print-like feel |
| Shadows | On cards and buttons | Floating UI only | Fewer visual layers |
| Spacing | Standard | Generous sections | More breathing room between topics |
These are all CSS-only changes. No HTML restructuring, no template changes, no JavaScript changes.
31. Sources and references
Sites analyzed (design inspection)
- stripe.com: button and card radius, color palette, hover patterns
- linear.app: CSS extracted, Inter Variable, opacity-based hierarchy,
#08090adark - vercel.com: Geist font family, container queries, theme system
- resend.com: CSS extracted, Domaine serif, frosted glass buttons, forced dark
- cal.com: CSS extracted, purple palette, Cal Sans display font, multi-font system
- pitch.com: purple accent, standard SaaS layout, 6-8px radius
- ibm.com/think: editorial grid, 0px button radius, IBM Plex Sans, blue accent
- rauno.me (Linear designer): 4/8/16/9999px radius scale, 12-step color scales, spacing standards
Design systems analyzed
- shadcn/ui: OKLCH colors, 10px default radius, 6 gray tint options
- Tailwind CSS: 32px pill buttons, 5% opacity outlines, OKLCH throughout
- Radix UI: 12-step color scales, accent/gray pairing
- GitHub Primer: Functional token naming, 20+ data visualization colors
Trend analyses referenced
- WPEngine "10 Web Design Trends for 2025": pill buttons, serif typography, scrapbooking
- DesignShack "28 Top Web Design Trends": serif revival, exaggerated whitespace, type-only heroes
- Typewolf: most popular typefaces 2024-2025
- ishadeed.com: modern CSS techniques,
:has(), container queries - Every Layout: intrinsic CSS, algorithmic spacing
- Heydon Pickering (heydonworks.com): ethical minimalism, anti-pattern critique
- Wix design trends: 20px image radius, cubic-bezier easing
CSS specifications referenced
- OKLCH color space (CSS Color Level 4)
- Container Queries (CSS Containment Level 3)
text-wrap: balance/pretty(CSS Text Level 4)animation-timeline: scroll()/view()(Scroll-driven Animations Level 1):focus-visiblepseudo-class (Selectors Level 4)color-mix()(CSS Color Level 5, supported in all major browsers since 2023)