Manipal Health Enterprises Limited
Component Library
The single source of truth for UI consistency across the MHEL Asset Management System. Every component shown here is live-rendered using the same CSS as the application.
Tech: Vanilla HTML/CSS/JS
Font: Inter
Primary: #185FA5
Radius: 14px / 9px / 6px
Foundations
Design Tokens
All color values are defined as CSS custom properties in
:root inside css/style.css. Use var(--token-name) everywhere instead of hardcoded hex.Brand & Primary Colors
Primary
#0066B2
--primary
Primary Dark
#004D8C
--primary-dk
Primary Light
#E6F0FA
--primary-lt
Blue Dark
#1E3A8A
--blue-dk
Blue
#1D4ED8
--blue
Blue Light
#DBEAFE
--blue-bg
Accent
#00D4AA
--accent
Teal
#0D9488
--teal
Semantic / State Colors
Green
#27AE60
--green
Green Bg
#ECFDF5
--green-bg
Red
#E63946
--red
Red Bg
#FEE2E2
--red-bg
Orange
#E67E22
--orange
Orange Bg
#FFF7ED
--orange-bg
Yellow
#D97706
--yellow
Yellow Bg
#FEF3C7
--yellow-bg
Purple
#8E44AD
--purple
Purple Bg
#EDE9FE
--purple-bg
Layout & Neutral Colors
App Background
#EDE8DF
--bg
Card / White
#FFFFFF
--card
Border
#E2E8F0
--border
Text
#111827
--text
Muted
#6B7280
--muted
Light
#F9FAFB
--light
Foundations
Typography
Font family: Inter (fallback: Lato, sans-serif). Applied globally via
font-family: var(--font).Type Scale
Asset Management System
Calibration Records
PPM Status Overview
Equipment breakdown reported on 2nd floor, ICU wing. Assigned to maintenance team.
Last updated: 02 May 2026 at 14:32
Asset / Instrument
Required
247
Foundations
Spacing Scale
4px base unit. Use
var(--sp-N) tokens for consistent spacing. Available: 4, 8, 12, 16, 20, 24, 32, 48, 64px.4px
--sp-1
8px
--sp-2
12px
--sp-3
16px
--sp-4
20px
--sp-5
24px
--sp-6
32px
--sp-8
48px
--sp-12
64px
--sp-16
Components
Buttons
Two button families: form buttons (
.ph-btn-*) used on form pages, and global buttons (.btn*) used across list/table pages.Form Page Buttons (.ph-btn-*) — most common
View HTML snippet
<button class="ph-btn-primary"> <svg ...checkmark.../> Save record </button> <button class="ph-btn-outline"> <svg ...download.../> Export CSV </button> <!-- Disabled --> <button class="ph-btn-primary" disabled style="opacity:.5;cursor:not-allowed;">Disabled</button>
Use: All form header action bars (calibration, work orders, AMC log, PPM log). Primary = save action. Outline = secondary/export action. Don't use: Inside history tables or sidebar.
Global Buttons (.btn, .btn-primary, .btn-outline, .btn-export)
View HTML snippet
<button class="btn">Accent Action</button> <button class="btn-primary">Primary</button> <button class="btn-outline">Outline</button> <button class="btn-export">Export</button> <button class="btn-sm btn-sm-edit">Edit</button> <button class="btn-sm btn-sm-danger">Delete</button>
Use: History table action columns (
.btn-sm-edit, .btn-sm-danger), page-level actions (.btn-primary). Don't use: .btn (accent/teal) is legacy — prefer .btn-primary or .ph-btn-primary.Work Order Buttons (.wo-btn-*)
Use: Work Orders page header only. Uses
var(--primary) and var(--primary-dk).Components
Form Fields
All form inputs use classes from the
.pl-* family. Labels always use .pl-label. Required badge uses .pl-req.Text, Textarea, Select, Date
Asset / Instrument Required
Service Type Required
Service Date
Work Description
Disabled field
Field with error
This field is required
View HTML snippet
<div>
<div class="pl-label">Label <span class="pl-req">Required</span></div>
<input class="pl-input" type="text" placeholder="..." />
</div>
<div>
<div class="pl-label">Select Field</div>
<select class="pl-select">
<option value="">Select...</option>
<option>Option 1</option>
</select>
</div>
<div>
<div class="pl-label">Text Area</div>
<textarea class="pl-textarea" rows="3" placeholder="..."></textarea>
</div>
<!-- Error state -->
<input class="pl-input" style="border-color:#DC2626;box-shadow:0 0 0 3px rgba(220,38,38,.1);" />
<div style="font-size:.7rem;color:#DC2626;margin-top:4px;">Error message</div>
Use: All data-entry forms across the app. Always pair input with
.pl-label. Grid: Use .pl-grid (2-col) or .pl-grid.full (1-col) to arrange fields. Don't use: Raw <input> without .pl-input class.Components
Status Pills & Badges
Color-coded inline labels for criticality, PPM status, and work order status.
Asset Criticality (.ar-crit-*)
Critical
High
Non-Critical
Unknown
View HTML snippet
<span class="ar-crit-critical" style="display:inline-flex;align-items:center;gap:5px;padding:2px 8px;border-radius:20px;font-size:.72rem;font-weight:600;"> <span class="ar-crit-dot" style="width:6px;height:6px;border-radius:50%;background:#991B1B;flex-shrink:0;"></span> Critical </span> <!-- Classes: ar-crit-critical | ar-crit-high | ar-crit-nc | ar-crit-unk -->
PPM Status (.ppm-*)
Overdue
Due Soon
On Track
N/A
Uses: Asset Register table PPM column. Colors map to
--red-bg/dk, --yellow-bg/dk, --green-bg/dk tokens.Work Order Status (9 states)
Reported / New
Assigned
In Progress
Waiting for Parts
On Hold
Testing / Verification
Completed
Closed
Escalated
View HTML snippet
<!-- Add these classes to style.css for WO status pills: --> <span class="wo-status-pill wo-s-new">Reported / New</span> <span class="wo-status-pill wo-s-assigned">Assigned</span> <span class="wo-status-pill wo-s-progress">In Progress</span> <span class="wo-status-pill wo-s-waiting">Waiting for Parts</span> <span class="wo-status-pill wo-s-hold">On Hold</span> <span class="wo-status-pill wo-s-testing">Testing / Verification</span> <span class="wo-status-pill wo-s-completed">Completed</span> <span class="wo-status-pill wo-s-closed">Closed</span> <span class="wo-status-pill wo-s-escalated">Escalated</span>
Note: The
.wo-status-pill base class and .wo-s-* modifiers are defined in this styleguide. Copy the CSS block from the styleguide <style> tag into style.css when ready to use app-wide.Components
Data Tables
Standard table pattern:
.tbl-card wrapper → .data-tbl table → thead/tbody. Column visibility via data-col attribute.Standard Data Table (comfortable density)
| # | ASSET | UNIT | STATUS | NEXT PPM | ACTION |
|---|---|---|---|---|---|
| 1 | Ventilator MV-01 | ICU | On Track | 15 Jun 2026 | |
| 2 | ECG Machine CG-03 | Cardiology | Overdue | 01 Apr 2026 | |
| 3 | BP Monitor BP-07 | General | Due Soon | 08 May 2026 |
View HTML snippet
<div class="tbl-card">
<div class="tbl-hd">
<h3>Asset Register</h3>
<span class="badge" id="regCount">0 records</span>
</div>
<div style="overflow-x:auto;">
<table class="data-tbl">
<thead><tr>
<th data-col="chk"><input type="checkbox"/></th>
<th data-col="code">CODE</th>
<th data-col="name">NAME</th>
</tr></thead>
<tbody id="regBody"></tbody>
</table>
</div>
</div>
Column visibility: Add
data-col="key" to both <th> and <td>. Toggle via injected <style> targeting [data-col="key"]. Frozen columns: Add position:sticky; left:Npx in CSS. Currently chk=0, code=42px, name=162px are frozen.Components
Empty States
Shown when a table or list has no data. Generated via
_emptyRow(colSpan, icon, title, subtitle, actionBtn) in app.js.No Data (search returns nothing)
No assets match your filters
Try adjusting your search term or clearing the active filters to see all records.
First Run (no data exists yet)
No assets loaded
Start by adding your first asset or upload a CSV file with your asset register.
Pattern: Icon with colored background for first-run, grey icon for no-results. Always include a brief explanation and — for first-run — a clear CTA button.
Components
Cards
Three card patterns:
.card (general content), .kpi-ring-card (dashboard KPI), .tbl-card (table container).Content Card (.card)
Calibration Due
Next 14 days
12
instruments require calibration
View HTML snippet
<div class="card">
<div class="card-hd">
<div class="card-hd-l">
<div class="card-ic ci-b"><!-- svg icon --></div>
<div><h3>Card Title</h3><p>Subtitle</p></div>
</div>
<button class="card-menu-btn">…</button>
</div>
<!-- content -->
</div>
<!-- Icon bg variants: ci-b (blue) ci-g (green) ci-o (orange)
ci-p (purple) ci-r (red) ci-t (teal) -->
Form Section Card (.pl-section)
1
Section Title
Subtitle / instructions for this section
Form fields go here…
View HTML snippet
<div class="pl-section">
<div class="pl-section-hd">
<div class="pl-section-num pl-sn-blue">1</div>
<div class="pl-section-icon pl-sn-blue"><!-- svg --></div>
<div>
<div class="pl-section-title">Section Title</div>
<div class="pl-section-sub">Subtitle text</div>
</div>
</div>
<!-- Fields using .pl-grid -->
</div>
<!-- Number/icon color variants:
pl-sn-blue | pl-sn-green | pl-sn-purple
pl-sn-orange | pl-sn-red | pl-sn-teal -->
Components
Toasts & Alerts
Inline contextual messages. Success banners are full-width cards inside the page. Dismiss alerts use
.pl-dismiss-alert.Toast / Notification Styles
Success: Calibration record saved successfully.
Error: Required fields are missing. Please fill all required fields before saving.
Warning: 3 assets are overdue for PPM. Schedule maintenance soon.
Info: Work order records are securely stored in the cloud and accessible from any device.
View HTML snippet
<!-- Success -->
<div style="display:flex;align-items:flex-start;gap:10px;padding:12px 16px;border-radius:10px;
background:#F0FDF4;border:1px solid #BBF7D0;color:#15803D;font-size:.8rem;">
<svg ...checkmark.../> Record saved successfully.
</div>
<!-- Dismissible info alert (existing class) -->
<div class="pl-dismiss-alert" id="alertId">
<svg .../> Message text
<button class="pl-dismiss-btn" onclick="this.parentElement.style.display='none'">✕</button>
</div>
Existing success banners (cb-success, wo-success, al-success) are permanent styled blocks inside pages — shown/hidden via
style.display. Toast classes above (.sg-toast-*) are styleguide-only proposals — add to style.css to use app-wide.Components
Loading States
Spinner
View HTML snippet
<div style="width:28px;height:28px;border:3px solid #E2E8F0;
border-top-color:#185FA5;border-radius:50%;
animation:sg-spin .8s linear infinite;"></div>
@keyframes sg-spin { to { transform: rotate(360deg) } }
Skeleton Loader
View HTML snippet
<!-- Add to style.css -->
.skeleton {
background: linear-gradient(90deg, #F1F5F9 25%, #E2E8F0 50%, #F1F5F9 75%);
background-size: 200%;
animation: shimmer 1.4s infinite;
border-radius: 6px;
}
@keyframes shimmer {
0% { background-position: 200% 0 }
100% { background-position: -200% 0 }
}
Progress Bar (Form)
2 of 3 required fields filled
Required fields complete · 4 optional fields filled
Use: Form pages (calibration, work orders, AMC log). Driven by
_formProgress(prefix, reqIds, optIds) in app.js. Fills based on how many required fields have values.Components
Icon Set
All icons are inline SVGs from Lucide Icons (stroke-based, 24×24 viewBox). Stroke width 2 for standard, 2.5 for emphasis. No icon font or external icon library is used.
Icons in Use (click to copy SVG)