Loading repository data…
Loading repository data…
arnobt78 / repository
An educational, portfolio-ready healthcare landing page that behaves like a small single-page application (SPA) using only native browser APIs: semantic HTML5, a single large CSS3 design system, and vanilla JavaScript split into ES modules. There is no React, Vue, Angular, or Next.js—so you can study routing, state, & UI polish without framework
An educational, portfolio-ready healthcare landing page that behaves like a small single-page application (SPA) using only native browser APIs: semantic HTML5, a single large CSS3 design system, and vanilla JavaScript split into ES modules. There is no React, Vue, Angular, or Next.js—so you can study routing, state, and UI polish without framework magic. It is ideal for learners who want to see how production-like patterns (History API routing, accessible modals, carousels, and shared state) look in plain JS.
Health Care Landing Page 3 (healthcare-ui-3 on npm) is a single-page healthcare marketing site you can run entirely in the browser: one index.html, shared styles.css / fonts.css, and a small set of ES module files under js/ that power navigation, animations, modals, tabs, a filterable doctors carousel, and optional hero imagery fallbacks.
Goals:
| Aspect | Details |
|---|---|
| It is | A static-first frontend demo: one index.html, rich styles.css, and modular JS that adds SPA-style navigation, animations, modals, tabs, and a doctors “reel.” |
| It is not | A full-stack app. There is no custom REST API in this repo, no database, and no server-side rendering. Forms and buttons are UI demos unless you wire them to a real backend. |
| Deploy target | Vercel (or any static host). vercel.json rewrites unknown paths to index.html so client routes work on refresh. |
<dialog>-based modal with per-service content (serviceModal.js).tabs.js).dropdown.js, doctorsCarousel.js, appState.js), doctor profile modal (doctorModal.js).resourcesLines.js).<head> — Meta description, Open Graph, Twitter cards, JSON-LD, canonical URL (see index.html).ripple.js + CSS).data-safe-src pattern tries fallbacks when an image errors (safeImage.js).| Layer | Choice | Why it matters for learners |
|---|---|---|
| Markup | HTML5 | Semantic regions (<header>, <main>, <section>, <dialog>), ARIA on tabs and modals. |
| Styling | CSS3 | Custom properties, grid/flex, animations, prefers-reduced-motion, container queries where used. |
| Behavior | JavaScript (ES modules) | import/export, no bundler required in dev if you use a local server (browser resolves modules). |
| Icons | Remix Icon (CDN) | Large set of medical/UI icons via classes like ri-heart-pulse-line. |
| Fonts | DM Sans & Fraunces | Loaded via fonts.css and local woff2 under public/fonts/ (see index.html preloads). |
| Hosting | Vercel | Static output directory + SPA-style rewrites in vercel.json. |
Runtime (in the browser): None from npm—only CDN styles for Remix Icon.
Dev dependencies (from package.json):
| Package | Role |
|---|---|
eslint | Lints js/**/*.js and scripts/**/*.mjs for common mistakes and style consistency. |
@eslint/js | ESLint’s recommended baseline rules (flat config). |
globals | Predefined browser and node global names so ESLint does not flag window, document, fs, etc. |
Example — install dev tools:
npm install
Example — run linter:
npm run lint
healthcare-ui-3/
├── index.html # Single page: all sections + dialogs + SEO meta
├── styles.css # Global design system and section styles
├── fonts.css # @font-face for self-hosted DM Sans / Fraunces
├── package.json # npm scripts: build, lint
├── package-lock.json
├── eslint.config.js # ESLint flat config
├── vercel.json # Rewrites, cache headers, security headers
├── README.md
├── js/ # ES modules (entry: main.js)
│ ├── main.js # Wires all features after DOM ready
│ ├── router.js # History API: path → scroll to section id
│ ├── appState.js # Tiny publish/subscribe state (route, department, drawer)
│ ├── sidebar.js # Mobile drawer open/close + focus trap basics
│ ├── ripple.js # Button ripple effect
│ ├── scrollReveal.js # IntersectionObserver reveal + stagger
│ ├── parallax.js # Subtle hero parallax
│ ├── tabs.js # Accessible tabs + optional carousel + min-height measure
│ ├── resourcesLines.js # Staggered lines in resources block
│ ├── dropdown.js # Department filter + outside click / Escape
│ ├── doctorsCarousel.js # Infinite reel + prev/next + filter mode
│ ├── safeImage.js # Image onerror fallback chain
│ ├── serviceModal.js # Shared modal for service details
│ └── doctorModal.js # Shared modal for doctor profiles
├── scripts/
│ └── copy-static.mjs # Copies HTML/CSS/JS/public → dist/ for deploy
└── public/ # Static assets (fonts, hero images, favicon, robots.txt, etc.)
The dist/ folder is generated by npm run build; do not treat it as the source of truth.
Routing is implemented in js/router.js with the History API (pushState / popstate). Paths map to element ids on the same page:
| URL path | Scroll target (id in index.html) |
|---|---|
/ | home (special case: scroll to top) |
/services | service |
/about | about |
/doctors | pages |
/why | blog |
| `/res |