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.
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>
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>
Dropdowns (Glass Menus)
<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>
Breadcrumbs
<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>
Sidebar Navigation
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
?page=ui-guide renders every component above with the active theme applied. View the live UI guide (requires login).