Connection lost. Reconnecting… attempt 1 of 8
Paused. Your work is held on the server.
Could not reconnect.
This session has expired on the server.
DR.Simple_UI
Showing main. This can be ahead of the version your app has installed — check what a class says it needs before copying it. Releases (opens in a new tab)

Layouts

tier 2 — classes

Tier 1, like the shell itself: two more page shells, a collapsible nav group, and the skip link. All of it must look the same in every app.

Auth layout

Sign-in, sign-out, “check your e-mail”, an invitation. One centred card and nothing else: there is no navigation to offer somebody who is not signed in, and a half-populated sidebar behind a sign-in form invites them to try it.

.auth-card is capped rather than stretched. A sign-in form the width of a desktop screen has inputs nobody can aim at, and reads as an unfinished page.

Approval Console
Sign in

Use your organisation account.

Trouble signing in? Ask the service desk.

<div class="auth-layout" style="min-height:0; padding:24px">
    <div class="auth-brand">
        <span class="brand-logo" style="width:32px; height:32px; background:var(--brand)"></span>
        Approval Console
    </div>
    <div class="card auth-card">
        <div class="card-head"><strong>Sign in</strong></div>
        <div class="card-body dr-col">
            <p class="form-hint">Use your organisation account.</p>
            <button class="btn btn-primary"><i class="ri-microsoft-fill"></i> Continue with Microsoft</button>
        </div>
    </div>
    <p class="auth-foot">Trouble signing in? Ask the service desk.</p>
</div>

Full-bleed layout

For content that owns the whole area below the header — a map, a board, a diagram editor. .page is the frame's scroll container and pads its content; .full-layout replaces it, taking the padding off and handing scrolling to the child.

Used instead of .page, not alongside it — <AppShell PageClass="…"> cannot remove .page's own padding, so this one case writes the shell markup by hand.

<div class="layout">
    <aside class="sidebar">…</aside>
    <div class="content">
        <header class="topbar">…</header>
        <div class="full-layout">
            <div class="toolbar">…</div>
            <div style="flex:1; min-height:0">The map fills whatever is left.</div>
        </div>
    </div>
</div>

Collapsible nav group

For a section with more children than fits as a flat list. Built on <details>/<summary>, so the open state, the keyboard operation and the announcement come from the platform — and the group stays usable with scripting blocked, which the frame must be.

Put open on the group containing the current page, so a reader never lands on a page whose own nav entry is hidden. Sub-items indent to sit under the parent's label, not its icon. In the collapsed rail the whole group flattens to icons.

<aside class="sidebar" style="height:320px">
    <nav class="nav">
        <div class="nav-scroll">
            <a class="nav-link" href="#"><i class="ri-inbox-line"></i><span>Orders</span></a>
            <details class="nav-group" open>
                <summary><i class="ri-building-line"></i><span>Fulfilment</span></summary>
                <a class="nav-link active" href="#"><span>Ready to pick</span><span class="nav-count">41</span></a>
                <a class="nav-link" href="#"><span>On hold</span></a>
            </details>
            <details class="nav-group">
                <summary><i class="ri-settings-3-line"></i><span>Administration</span></summary>
                <a class="nav-link" href="#"><span>Warehouses</span></a>
                <a class="nav-link" href="#"><span>Audit log</span></a>
            </details>
        </div>
        <div class="nav-tools">
            <a class="nav-link nav-link-tool" href="#"><i class="ri-question-line"></i><span>Support</span></a>
            <hr class="nav-tools-sep" />
            <a class="nav-link nav-link-tool" href="#"><i class="ri-book-2-line"></i><span>Documentation</span><i class="ri-external-link-line nav-link-ext"></i></a>
        </div>
    </nav>
</aside>

The first focusable thing on the page, jumping past the navigation to the content. Without it a keyboard user tabs through every nav item on every page — which is the single most common reason a shell like this is exhausting to use without a mouse.

It is off-screen rather than hidden, so it stays focusable, and it appears above everything when focused. tabindex="-1" on <main> is not optional: without it the jump only scrolls, and focus stays back in the navigation where it was.

<body>
    <a class="skip-link" href="#main">Skip to content</a>
    <div class="layout">
        <aside class="sidebar">…</aside>
        <div class="content">
            <header class="topbar">…</header>
            <div class="page">
                <main id="main" tabindex="-1">…</main>
            </div>
        </div>
    </div>
</body>