Diwa Design System

Grid

Diwa uses a 12-column CSS grid with fluid gutters and page margins that scale with the viewport — ranging from 320px to 1440px. All grid values are exposed as CSS tokens so layouts stay consistent without hardcoded numbers.

Example

The layout below illustrates common column patterns on a 12-column grid. Each tile shows the column span and its recommended use.

Full — 12/12Hero background, full-width media
Main — 8/12Page content, article body
Sidebar — 4/12Navigation, filters
Half — 6/12Large teaser, image grid
Half — 6/12Large teaser, image grid
Third — 4/12Content tile
Third — 4/12Content tile
Third — 4/12Content tile
Quarter — 3/12Small card
Quarter — 3/12Small card
Quarter — 3/12Small card
Quarter — 3/12Small card
Narrow — 8/12Focused copy, forms, small components
TokenValueDescription
--diwa-grid-columns12Column count
--diwa-grid-guttervar(--diwa-space-fluid-lg)Gap between columns — 16–28px fluid
--diwa-grid-marginvar(--diwa-space-fluid-xl)Page-edge horizontal margin — 24–40px fluid
--diwa-grid-max-width1440pxMaximum content width before centring

Usage

12-column (default): All productive content — copy, graphics, descriptive imagery. Headlines should align to the left edge of the 12-column grid.

Full-bleed: Immersive moments — background images and colours can stretch to the full viewport width. This falls outside the column grid.

Do

  • Use the grid for a consistent appearance across all pages and breakpoints.
  • Align all left-aligned headlines to the left edge of the content grid.
  • Ensure images are at least focused within the 12-column content area even if they bleed to full width.
  • Use a grid at the top level — wrap page sections in the grid wrapper, not individual components.

Don't

  • Don't nest one grid inside another — the Diwa grid is a top-level layout primitive.
  • Don't scale elements beyond the 1440px maximum — they should centre within the page.
  • Don't use hardcoded pixel gutters or margins; always consume the grid tokens.
  • Don't create ad-hoc column counts outside the token scale.

Styles

Import the grid style helper from @diwacopilot/components/styles, or use the CSS tokens directly for full control:

import { gridStyle } from '@diwacopilot/components/styles';

// Returns { display: 'grid', gridTemplateColumns: 'repeat(12, 1fr)', gap: '...' }
const grid = gridStyle();

/* ── CSS ─────────────────────────────────────── */

/* Page wrapper */
.page {
  display: grid;
  grid-template-columns: repeat(var(--diwa-grid-columns), 1fr);
  gap: var(--diwa-grid-gutter);
  padding-inline: var(--diwa-grid-margin);
  max-width: var(--diwa-grid-max-width);
  margin-inline: auto;
}

/* Main content + sidebar */
.main    { grid-column: span 8; }
.sidebar { grid-column: span 4; }

/* Halves, thirds */
.half   { grid-column: span 6; }
.third  { grid-column: span 4; }

/* Centred narrow content */
.narrow {
  grid-column: 3 / span 8; /* 8 cols, offset by 2 */
}

/* Collapse all to full-width on mobile */
@media (max-width: 759px) {
  .main, .sidebar, .half, .third, .narrow {
    grid-column: span 12;
  }
}
@use '@diwacopilot/components/styles' as *;

.page {
  display: grid;
  grid-template-columns: repeat($diwa-grid-columns, 1fr);
  gap: $diwa-grid-gutter;
  padding-inline: $diwa-grid-margin;
  max-width: $diwa-grid-max-width;
  margin-inline: auto;
}

.content { grid-column: span 8; }
.sidebar { grid-column: span 4; }

@media (max-width: $diwa-breakpoint-sm) {
  .content, .sidebar { grid-column: span 12; }
}