UI Reference

This page documents every Bootstrap 5 component pattern used in child apps, with the correct markup for the glassmorphism theme. Use this as a reference when building views — it matches the child-app's ?page=ui-guide living style guide.

For coding agents: When generating UI code for a child app, use these exact markup patterns. The glassmorphism theme expects specific class combinations and nesting to render correctly in both dark and light modes.

Cards (Glass Panels)

Cards are the primary container. They get automatic glassmorphism treatment — semi-transparent background with backdrop blur.

<div class="card">
    <div class="card-header">Section Title</div>
    <div class="card-body">
        <h5 class="card-title">Title</h5>
        <p class="card-text">Content here.</p>
    </div>
    <div class="card-footer text-muted small">Footer</div>
</div>

Stat Cards (Left-Accent)

Dashboard stat boxes with a colored left border:

<div class="card border-start border-primary border-4">
    <div class="card-body">
        <div class="text-uppercase text-muted">Total Items</div>
        <div class="fs-3 fw-bold"><?= $count ?></div>
    </div>
</div>

Color variants: border-primary, border-success, border-warning, border-danger, border-info

Card with Tabs

<div class="card">
    <div class="card-header">
        <ul class="nav nav-tabs card-header-tabs">
            <li class="nav-item">
                <button class="nav-link active" data-bs-toggle="tab" data-bs-target="#tab1">Tab 1</button>
            </li>
            <li class="nav-item">
                <button class="nav-link" data-bs-toggle="tab" data-bs-target="#tab2">Tab 2</button>
            </li>
        </ul>
    </div>
    <div class="card-body tab-content">
        <div class="tab-pane fade show active" id="tab1">Content 1</div>
        <div class="tab-pane fade" id="tab2">Content 2</div>
    </div>
</div>

Forms (Glass Inputs)

All form controls get glass styling automatically via _bootswatch.scss.

<form method="post">
    <input type="hidden" name="action" value="doThing">
    <div class="mb-3">
        <label class="form-label">Title</label>
        <input type="text" class="form-control" name="title" required>
    </div>
    <div class="mb-3">
        <label class="form-label">Category</label>
        <select class="form-select" name="category">
            <option>Option 1</option>
        </select>
    </div>
    <div class="mb-3">
        <label class="form-label">Description</label>
        <textarea class="form-control" name="description" rows="3"></textarea>
    </div>
    <div class="form-check form-switch mb-3">
        <input class="form-check-input" type="checkbox" name="active" id="active">
        <label class="form-check-label" for="active">Active</label>
    </div>
    <button type="submit" class="btn btn-primary">Save</button>
</form>
Forms POST to the same page (no action attribute). The action handler in include/actions/memberActions/ processes the POST before the view renders.

Tables

Standard Bootstrap tables with transparent backgrounds:

<div class="card">
    <div class="card-body">
        <table class="table table-hover">
            <thead>
                <tr><th>Name</th><th>Status</th><th>Actions</th></tr>
            </thead>
            <tbody>
                <?php foreach ($items as $item) { ?>
                <tr>
                    <td><?= h($item['name']) ?></td>
                    <td><span class="badge bg-success">Active</span></td>
                    <td>
                        <button class="btn btn-sm btn-outline-light"
                                onclick="modalView('modal=edit_item&id=<?= $item['id'] ?>')">Edit</button>
                    </td>
                </tr>
                <?php } ?>
            </tbody>
        </table>
    </div>
</div>

Alerts (Accent Bar Style)

The glassmorphism theme renders alerts as glass panels with a colored left border instead of colored backgrounds:

<div class="alert alert-success alert-dismissible">
    Operation completed successfully.
    <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
<div class="alert alert-danger">Something went wrong.</div>
<div class="alert alert-warning">Check your input.</div>
<div class="alert alert-info">FYI — this is informational.</div>

Session flash messages are shown as Bootstrap toasts (via toast.js), not inline alerts. Set $_SESSION['success'], $_SESSION['error'], etc. in action files.

Buttons

<!-- Primary actions -->
<button class="btn btn-primary">Save</button>
<button class="btn btn-success">Create</button>
<button class="btn btn-danger">Delete</button>

<!-- Secondary / outline (glass-friendly) -->
<button class="btn btn-outline-light">Cancel</button>
<button class="btn btn-outline-primary">Details</button>

<!-- Small buttons (table actions, toolbar) -->
<button class="btn btn-sm btn-outline-light">Edit</button>
<button class="btn btn-sm btn-primary"><i class="bi bi-plus"></i> Add</button>

Modals (AJAX via modalView)

The template includes #largeModal. Load content via AJAX:

<!-- Trigger button -->
<button class="btn btn-primary" onclick="modalView('modal=create_item')">New Item</button>

<!-- With parameters -->
<button onclick="modalView('modal=edit_item&id=<?= $item['id'] ?>')">Edit</button>

Modal Snippet File

Create views/modals/create_item.php:

<div class="modal-header">
    <h5 class="modal-title">Create Item</h5>
    <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form id="createItemForm">
    <div class="modal-body">
        <div class="mb-3">
            <label class="form-label">Name</label>
            <input type="text" class="form-control" name="name" required>
        </div>
    </div>
    <div class="modal-footer">
        <button type="button" class="btn btn-outline-light" data-bs-dismiss="modal">Cancel</button>
        <button type="button" class="btn btn-primary"
                onclick="reloadModalThisForm('createItemForm', 'modal=create_item&action=createItem')">Create</button>
    </div>
</form>

Toasts (Session Flash)

Set session variables in action files — toast.js reads #toast-data and shows Bootstrap toasts automatically:

// In your action file:
$_SESSION['success'] = 'Item created.';
$_SESSION['error']   = 'Validation failed.';
$_SESSION['warning'] = 'Approaching limit.';
$_SESSION['info']    = 'New feature available.';

The template renders the data div:

<div id="toast-data" class="d-none"
     data-success="<?= h($toast_success) ?>"
     data-error="<?= h($toast_error) ?>"></div>
<div class="dropdown">
    <button class="btn btn-sm btn-outline-light dropdown-toggle" data-bs-toggle="dropdown">
        Actions
    </button>
    <ul class="dropdown-menu dropdown-menu-end">
        <li><a class="dropdown-item" href="#"><i class="bi bi-pencil me-2"></i>Edit</a></li>
        <li><a class="dropdown-item" href="#"><i class="bi bi-copy me-2"></i>Duplicate</a></li>
        <li><hr class="dropdown-divider"></li>
        <li><a class="dropdown-item text-danger" href="#"><i class="bi bi-trash me-2"></i>Delete</a></li>
    </ul>
</div>

Badges

<span class="badge bg-primary">New</span>
<span class="badge bg-success">Active</span>
<span class="badge bg-warning text-dark">Pending</span>
<span class="badge bg-danger">Error</span>
<span class="badge bg-secondary">Archived</span>

<!-- Sidebar count badge (auto-hides on collapse) -->
<span class="badge bg-primary sidebar-badge"><?= $count ?></span>
<nav aria-label="breadcrumb">
    <ol class="breadcrumb">
        <li class="breadcrumb-item"><a href="index.php?page=dashboard">Dashboard</a></li>
        <li class="breadcrumb-item"><a href="index.php?page=items">Items</a></li>
        <li class="breadcrumb-item active">Edit</li>
    </ol>
</nav>

Offcanvas (Right Panel)

The template includes a right panel triggered by the vertical dots icon. For custom offcanvas:

<button class="btn btn-sm btn-outline-light" data-bs-toggle="offcanvas" data-bs-target="#myPanel">
    <i class="bi bi-sliders"></i> Filters
</button>

<div class="offcanvas offcanvas-end" id="myPanel" tabindex="-1">
    <div class="offcanvas-header border-bottom border-secondary border-opacity-25">
        <h6 class="offcanvas-title">Filters</h6>
        <button type="button" class="btn-close" data-bs-dismiss="offcanvas"></button>
    </div>
    <div class="offcanvas-body">
        <!-- Filter controls here -->
    </div>
</div>

Add pages to the sidebar in views/template.php:

<a class="nav-link <?= ($page ?? '') === 'mypage' ? 'active bg-primary rounded' : '' ?>"
   href="index.php?page=mypage">
    <i class="bi bi-gear sidebar-icon"></i>
    <span class="sidebar-text">My Page</span>
    <span class="badge bg-primary sidebar-badge"><?= $count ?></span>
</a>

AJAX Actions (apiPost)

// POST to api/index.php, triggers action file
apiPost('deleteItem', { id: itemId }, function(response) {
    if (response.success) {
        // Remove row from UI
        document.getElementById('row-' + itemId).remove();
    }
    if (response.error) {
        alert(response.error);
    }
});

// Response format:
// { error: "", success: "Deleted.", info: "", warning: "", results: { ... } }

Layout Grid

Use Bootstrap's grid inside .container-fluid (the template's content area):

<!-- Dashboard layout: 4 stat cards + chart -->
<div class="row g-3 mb-4">
    <div class="col-md-3">
        <div class="card border-start border-primary border-4">
            <div class="card-body">
                <div class="text-uppercase text-muted">Users</div>
                <div class="fs-3 fw-bold">1,234</div>
            </div>
        </div>
    </div>
    <div class="col-md-3">...</div>
    <div class="col-md-3">...</div>
    <div class="col-md-3">...</div>
</div>

<div class="row g-3">
    <div class="col-lg-8">
        <div class="card"><!-- Main chart --></div>
    </div>
    <div class="col-lg-4">
        <div class="card"><!-- Side panel --></div>
    </div>
</div>

Icons

Bootstrap Icons are loaded via CDN. Use the bi class prefix:

<i class="bi bi-house"></i>         <!-- Navigation -->
<i class="bi bi-plus-circle"></i>   <!-- Add actions -->
<i class="bi bi-pencil"></i>        <!-- Edit -->
<i class="bi bi-trash"></i>         <!-- Delete -->
<i class="bi bi-search"></i>        <!-- Search -->
<i class="bi bi-bell"></i>          <!-- Notifications -->
<i class="bi bi-gear"></i>          <!-- Settings -->
<i class="bi bi-shield-lock"></i>   <!-- Security -->

Full icon reference: icons.getbootstrap.com

Live examples: The child-app's ?page=ui-guide renders every component above with the active theme applied. View the live UI guide (requires login).