DryUI Page Layout: Lint Tight
Build the supplied design image as a finished DryUI app page. Use mobile-first layout, tablet refinement, then desktop.
Three Stages
- Identify the screen type, primary task, shell regions, mobile order, and whether panes touch or have gutters.
- Implement the page with DryUI components and meaningful
data-layouthooks. - Run
bun run build; repair lint or compile errors before stopping.
File Contract
src/routes/+page.svelte: markup, imports, data arrays, and DryUI components only. No<style>block.src/layout.css: structural layout only.src/app.css: visual styling only.- Do not edit other files unless
bun run buildfails because an import is missing.
Shell Markup
Use one shell and one page grid:
svelte<main data-layout="<screen>-shell"> <div data-layout-area="page"> <header data-layout-area="topbar">...</header> <nav data-layout-area="navigation">...</nav> <section data-layout-area="primary">...</section> <aside data-layout-area="secondary">...</aside> </div> </main>
- Required:
page,primary, andtopbarornavigation. - Optional direct areas:
rail,summary,secondary,utility,actions. data-layout-areaappears only on the page grid and its direct children.- Everything nested uses
data-layout="<specific-purpose>"; never generic names likewrapper,inner,box,container,layout, orui.
DryUI Components
- Use
Button,Input,Badge,Separator,Table, andTabsfrom@dryui/ui. - Do not pass
class=orclass:to DryUI components. - Use static
data-layoutblocks for charts, kanban boards, preview panes, timelines, metrics, and maps. - Do not inspect
node_modulesunlessbun run buildreports an import error.
src/layout.css Rules
Start with this exact container contract:
css[data-layout='<screen>-shell'] { container: page / inline-size; min-block-size: 100dvh; } [data-layout='<screen>-shell'] > [data-layout-area='page'] { display: grid; min-block-size: 100dvh; grid-template-areas: ...; grid-template-columns: minmax(0, 1fr); } @container page (min-width: 48rem) { ... } @container page (min-width: 72rem) { ... }
Only use these selector forms in src/layout.css:
[data-layout='name'][data-layout-area='name']- direct-child shell selectors using
>
Never use these in src/layout.css:
display: none,display: block,display: contents,display: inline-flex, or any display value exceptgridandflex[data-ui], element selectors, pseudo selectors,:first-child,:last-child,span,button, or descendant selectors used to reach unnamed childrenwidth,inline-size,min-inline-size,max-inline-size,height,position,z-index, color, background, border, shadow, text, transform, transition, opacity@media,:global(),!important, inlinestyle=, or Sveltestyle:
If an item should disappear at a breakpoint, prefer one content model that works across sizes. Do not hide/show alternate copies with CSS.
Visual CSS
Use src/app.css for color, surfaces, borders, radius, typography, chart fills, and readable foreground/background pairs. Keep it free of display: grid, display: flex, container, @container, and grid/flex track rules.
Final Audit
Before final, bun run build must pass.
Then run:
shrg -n "<style|display:|@container|container:|grid-|flex" src/routes/+page.svelte rg -n "display: *(none|block|contents|inline-flex)|data-ui|:first-child|:last-child|inline-size|position:|width:|height:" src/layout.css rg -n "display: *(grid|flex)|@container|container:|grid-template|grid-area|flex-" src/app.css
Fix any output. The 390px, 820px, and 1440px captures must have no horizontal overflow, no blank shell, readable contrast, dominant primary content, and a compact mobile summary.


