Site components

25 Blade components power this site. Everything below is rendered by the real thing, so it follows your realm and colour mode: try the realm switcher and the Light/Dark toggle in the header, then open any demo's code.

Foundations

Design tokens are CSS variables, so all 9 realms and their 18 light and dark themes work everywhere.

Colour tokens

Live OKLCH values: change the realm or switch Light/Dark in the header and these update.

  • --bg

     

  • --bg-alt

     

  • --surface

     

  • --surface-strong

     

  • --text

     

  • --muted

     

  • --accent

     

  • --accent-2

     

  • --accent-text

     

  • --on-accent

     

  • --success

     

  • --danger

     

  • --warning

     

  • --info

     

Typography

Each realm brings its own fonts. This one uses its display font for headings and its body font for text. Fluid sizes, balanced wrapping.

Display heading

Heading two

Heading three

Lead paragraph: larger, muted, comfortable line length.

Body text in accessible accent links and strong emphasis.

Small, muted supporting text.

Eyebrow label

Radius and elevation

sm 10px
md 16px
lg 22px

Motion tokens

Hover each box. Reduced-motion users get no movement at all.

--dur-fast 150ms

--dur-base 300ms

--dur-slow 600ms

Actions

Buttons, badges, chips and pills.

Buttons

Start a project Browse projects External link
<x-btn href="/contact">Start a project</x-btn>
<x-btn href="/projects" variant="ghost">Browse projects</x-btn>
<x-btn size="sm">Small</x-btn>
<x-btn href="https://example.com" :external="true">Opens in a new tab</x-btn>
<x-btn disabled>Disabled</x-btn>

Badges

Default Hot Active Expired In progress Muted
<x-badge>Default</x-badge>
<x-badge variant="hot">Hot</x-badge>
<x-badge variant="success">Active</x-badge>
<x-badge variant="danger">Expired</x-badge>
<x-badge variant="info">In progress</x-badge>
<x-badge variant="muted">Muted</x-badge>

Chips and pills

Chips are toggleable (aria-pressed); pills are read-only.

Read-only pill
{{-- Toggle chips: aria-pressed drives the style --}}
<button type="button" class="chip" :aria-pressed="selected.includes('Laravel')" @click="toggle('Laravel')">Laravel</button>
<span class="pill">Pill (read-only)</span>

Navigation

The header, footer and these primitives are all keyboard operable.

Breadcrumbs

<x-breadcrumbs :items="[['Projects', route('projects.index')], ['HR Management System', null]]" />

Tabs

Focus a tab and use the arrow keys, Home and End.

A short overview of the thing. Tabs follow the WAI-ARIA pattern.
Specs: lightweight, accessible, themeable.
Reviews: one tab stop, roving tabindex, automatic activation.
<x-tabs :ids="['overview', 'specs']" :hash="false">
    <x-tabs.list :tabs="['overview' => 'Overview', 'specs' => 'Specs']" label="Product" />
    <x-tabs.panel id="overview">...</x-tabs.panel>
    <x-tabs.panel id="specs">...</x-tabs.panel>
</x-tabs>
{{-- Arrow keys, Home and End move between tabs. --}}

Pagination

Use for finite lists. (The project browser uses Load more instead.)

Timeline

  1. Discovery

    Week 1: goals, content, constraints

  2. Design system

    Week 2: tokens and components

  3. Build

    Weeks 3 to 5: pages, admin, tests

  4. Launch

    Week 6: deploy, monitor, iterate

<x-timeline :items="[
    ['title' => 'Discovery', 'meta' => 'Week 1'],
    ['title' => 'Build', 'meta' => 'Weeks 2 to 5'],
]" />

Forms

Always-visible labels, hints, and errors wired to inputs with aria-describedby.

Field states

Default, valid and error.

We never share it.

Looks good

<x-field name="email" label="Email" type="email" :required="true" />
<x-field name="email" label="Email" :valid="true" value="ada@example.com" />
<x-field name="email" label="Email" message="Enter a valid email." value="ada@" />
<x-field name="type" label="Project type" as="select" :options="['Web app', 'Landing page']" />
<x-field name="details" label="Details" as="textarea" hint="Be as specific as you can." />

Select and textarea

  • No results found.
  • No results found.

Be as specific as you can.

Toggle switch

Email me updates

At most one a month.

Prefer dark mode
<x-toggle name="updates" label="Email me updates" hint="At most one a month." :checked="true" />

Inline validation

Leave fields empty and press Validate (nothing is sent).

<form x-data="contactForm" novalidate @submit.prevent="...">
    <x-field name="name" label="Name" :required="true" />
    <x-field name="email" label="Email" type="email" :required="true" />
    <x-field name="message" label="Details" as="textarea" :required="true" />
    <button class="btn btn-primary">Validate</button>
</form>
{{-- Inline errors, focus on the first error, aria-invalid + aria-describedby; the server stays the source of truth. --}}

Feedback

Alerts, toasts and loading states share one status palette.

Alerts

Warnings and errors are announced immediately (role=alert); info and success politely.

Heads up

Informational message with some context.

Saved

Your changes are live.
<x-alert variant="info" title="Heads up">Informational message.</x-alert>
<x-alert variant="success" title="Saved">It worked.</x-alert>
<x-alert variant="warning" :dismissible="true">Careful with this.</x-alert>
<x-alert variant="danger" title="Something failed">Try again.</x-alert>

Toasts

Spring entrance, auto-dismiss (paused on hover), Escape clears all.

{{-- Once per page --}}
<x-toast-host />

{{-- From anywhere --}}
<button @click="$dispatch('toast', { title: 'Saved', body: 'Your changes are live.', variant: 'success' })">Save</button>

Loading and empty states

Nothing here yet

Empty states say what is missing and what to do next.

Live status dot

<div class="skeleton h-24"></div>
<span class="pulse-dot text-success"></span> Live

Data display

Cards, stats, tables and disclosure.

Cards

Plain

Surface, border and soft shadow.

Clickable

For links: the border answers the pointer, nothing moves.

Realm texture

The active realm's pattern and film grain, for emphasis.

<x-card>Plain card</x-card>
<x-card :hover="true">For links: the border answers the pointer</x-card>
<x-card class="aurora grain">Realm texture + film grain</x-card>

Project card

Live: the first published project from the database.

HR Management System

Laravel · Web · Archived

Laravel and Filament HRMS covering employees, attendance, leave, payroll with PDF payslips, and recruitment.

Laravel Filament MySQL +2
View case study
<x-project-card :project="$project" :index="0" />
{{-- level="2" when the card sits directly under an h1 (keeps heading order). --}}

Stat tiles

A number only earns a tile when its label says what it counts.

Components
25
Realm themes
18
Breakpoints tested
4
% of themes passing WCAG AA
100
<dl class="grid grid-cols-2 gap-6">
    <x-stat label="Case studies" :value="3" :index="0" />
    <x-stat label="Certifications" :value="23" :index="1" />
</dl>

Table

Lighthouse scores, mobile profile
PagePerformanceAccessibilitySEO
Home98100100
Projects99100100
Case study96100100
<div class="overflow-x-auto">
    <table class="w-full text-left text-sm">
        <caption class="sr-only">Release history</caption>
        <thead>...</thead><tbody>...</tbody>
    </table>
</div>

Accordion

Height-animated disclosure; the button owns aria-expanded.

Yes: WCAG 2.2 AA, keyboard operable, reduced-motion aware.

Pick a realm and Light or Dark from the header; every colour is a theme token (a CSS variable).

In the database, edited in /admin.

<div x-data="{ open: false }">
    <button :aria-expanded="open" aria-controls="faq-1" @click="open = !open">Question</button>
    <div id="faq-1" x-show="open" x-collapse>Answer</div>
</div>

Mockups

Device frames to show work consistently.

Browser frame

Full-stack developer

I build digital realms where code, story and identity meet.

<x-device-frame url="durolord.com">
    ...any markup...
</x-device-frame>

Phone frame

Akinbo Oluwadurotiwa's Reading Report

  • Day 98 reading done
  • Day 99 reading done
  • Day 100 reading done
  • Day 101 reading done
  • Day 102 reading done
  • Day 103 reading done
  • Day 104 reading done
  • Day 105 reading undone
  • Day 106 reading undone
  • Day 107 reading undone
<x-device-frame device="phone" :flush="true">
    <p class="bg-accent px-4 py-3 text-sm font-semibold text-on-accent">Reading Report</p>
    <x-toggle name="day-98" label="Day 98 reading done" :checked="true" />
</x-device-frame>