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
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
Typography
Font family: Inter (fallback: Lato, sans-serif). Applied globally via font-family: var(--font).
Type Scale
Page Title
18px · 800

Asset Management System

Section Title
16px · 800

Calibration Records

Card Heading
13px · 800

PPM Status Overview

Body / Default
14px · 400
Equipment breakdown reported on 2nd floor, ICU wing. Assigned to maintenance team.
Small Text
12px · 400
Last updated: 02 May 2026 at 14:32
Form Label
12px · 700
Asset / Instrument
Caption / Tag
11px · 600
Required
KPI Value
26px · 900
247
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
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).
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.
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.
Data Tables
Standard table pattern: .tbl-card wrapper → .data-tbl table → thead/tbody. Column visibility via data-col attribute.
Standard Data Table (comfortable density)
#ASSETUNITSTATUSNEXT PPMACTION
1Ventilator MV-01ICUOn Track15 Jun 2026
2ECG Machine CG-03CardiologyOverdue01 Apr 2026
3BP Monitor BP-07GeneralDue Soon08 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.
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.
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 -->
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'">&#10005;</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.
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.
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)