Kinds of site
Web application
A web application: a prompt for an LLM, and recipes for its shell with a sidebar, its header and its dashboard.
Paste the prompt into any LLM. It asks about your application in short rounds, shows you the plan and writes nothing until you say "go".
Or build it yourself from the recipes below. They use the classes of core, the catalog and app only; Install LUZ lists the files to load. The view's <h1> and its main action are in the dashboard, never in the bar: the bar holds what is the same in every view.
Shell with a sidebar
The whole page: the skip link, then the catalog's sidebar beside .o-main, which holds the header and the view. .o-shell puts the sidebar in a column from 769 px of window, and makes it a drawer that the menu button opens below that, with no script. The App patterns go inside it.
The shell is the whole page, so it has no example inside this one: this page is built on it. Make the window narrower than 769 px and the sidebar becomes a drawer behind the menu button.
The catalog's script, if you load it, marks the current link of the sidebar and closes the drawer when a link is followed.
<body>
<a class="luz-skip-link" href="#main-content">Skip to content</a>
<div class="o-shell">
<nav class="luz-sidebar" id="app-nav" aria-label="Main" popover>
<a class="luz-sidebar__brand" href="/"><span class="luz-sidebar__brand-name">Bodega</span></a>
<div class="luz-sidebar__section">
<a class="luz-sidebar__link" href="/" aria-current="page">Overview</a>
<a class="luz-sidebar__link" href="/reports/">Reports</a>
<a class="luz-sidebar__link" href="/stock/">Stock</a>
</div>
</nav>
<div class="o-main">
<header class="luz-app-bar o-sticky">…</header>
<main class="luz-dashboard" id="main-content" tabindex="-1">…</main>
</div>
</div>
</body>
Header
The bar at the top of every view: the menu button, the name of the product and the account. It is the app header, in .o-main beside the sidebar. The search is the catalog's <luz-search>: leave it out if you do not load the catalog.
Beside a sidebar the product name is the sidebar's, so a wide bar shows the account alone; at 768 px of window and below the name shows beside the menu button, which this example leaves out, as it has no sidebar to open. The account list opens under its button: press it.
<header class="luz-app-bar o-sticky">
<div class="o-row">
<button class="luz-nav-toggle" type="button" popovertarget="app-nav" aria-label="Menu">
<svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 6h16M4 12h16M4 18h16"/></g></svg>
</button>
<p class="luz-app-bar__product">Bodega</p>
<div class="o-row luz-app-bar__actions">
<luz-search>…</luz-search>
<div class="luz-dropdown">
<button class="luz-btn luz-btn--ghost luz-app-bar__account" type="button" popovertarget="account-menu"><span class="luz-avatar luz-avatar--sm">AM</span> <span class="luz-app-bar__account-name">Ana Martín</span></button>
<div class="luz-dropdown__menu" id="account-menu" popover>
<ul class="luz-dropdown__list">
<li><a class="luz-dropdown__item" href="/account/">Account settings</a></li>
<li><a class="luz-dropdown__item" href="/logout/">Sign out</a></li>
</ul>
</div>
</div>
</div>
</div>
</header>
Dashboard
A view: a title row with the view's <h1> and its actions, then panels in a grid that answers to the room of the view, not the window's. It is the dashboard, on the <main>. Each panel is a card that starts with its heading; the most important one can take the room of two columns.
Overview
-
Sales this month
The sales of the month so far.
Open the sales report -
Stock alerts
Three products are below their minimum.
Review stock
The title is a paragraph and the panels' titles are <h3> here, as this page has its own <h1>.
<main class="luz-dashboard" id="main-content" tabindex="-1">
<div class="luz-dashboard__head">
<h1 class="luz-dashboard__title">Overview</h1>
<div class="o-actions">
<a class="luz-btn luz-btn--primary" href="/reports/new/">New report</a>
<a class="luz-btn luz-btn--secondary" href="/export/">Export data</a>
</div>
</div>
<ul class="o-grid o-grid--auto">
<li class="luz-card luz-dashboard__panel luz-dashboard__panel--wide">
<h2 class="luz-card__title">Sales this month</h2>
<p class="luz-card__body">The sales of the month so far.</p>
<a href="/reports/sales/">Open the sales report</a>
</li>
<li class="luz-card luz-dashboard__panel">
<h2 class="luz-card__title">Stock alerts</h2>
<p class="luz-card__body">Three products are below their minimum.</p>
<a href="/stock/alerts/">Review stock</a>
</li>
</ul>
</main>
Data in a panel
A panel that shows data holds one of five pieces, each over text, a native list or a table that stays in the page: the bar list compares a few values on one scale, the column chart compares values that have an order, the stacked bar shows how a whole is split, the ring shows one value against its goal and the heat map shows where a grid is high or low. Put one in the card of a panel, after its heading, and link the stylesheet of each one you use after luz.css. The numbers and the titles are yours.
-
Orders by channel
<ul class="o-grid o-grid--auto">
<li class="luz-card luz-dashboard__panel">
<h2 class="luz-card__title" id="by-channel">Orders by channel</h2>
<figure class="luz-bar-list" aria-labelledby="by-channel">
<ul class="luz-bar-list__rows">
<li class="luz-bar-list__row">
<span class="luz-bar-list__name">Online</span>
<span class="luz-bar-list__figure">640</span>
<meter class="luz-bar-list__meter" min="0" max="1204" value="640" aria-hidden="true">640 of 1,204</meter>
</li>
</ul>
</figure>
</li>
</ul>
Empty view
A view with nothing in it yet, on the dashboard: one wide panel that says what is missing and what to do, with the action. The title row keeps its place, so the view does not jump when the first panel arrives. The action in the panel is the view's one primary action: leave it out of the title row while the panel holds it.
Reports
-
No reports yet
Create your first report to see it here.
New report
<main class="luz-dashboard" id="main-content" tabindex="-1">
<div class="luz-dashboard__head">
<h1 class="luz-dashboard__title">Reports</h1>
</div>
<ul class="o-grid o-grid--auto">
<li class="luz-card luz-dashboard__panel luz-dashboard__panel--wide">
<h2 class="luz-card__title">No reports yet</h2>
<p class="luz-card__body">Create your first report to see it here.</p>
<a class="luz-btn luz-btn--primary" href="/reports/new/">New report</a>
</li>
</ul>
</main>