Royal Glow internal docs · now fully interactive — Steps, API tables, file trees & live status
Royal Glow Docs

Frontend

Component architecture, design system, styling conventions, and accessibility standards for Royal Glow.

Frontend

The frontend is server-first: components are React Server Components by default, and 'use client' is added only when browser APIs, state, or event handlers are needed. WCAG 2.1 AA and a Lighthouse Accessibility score of 100 are hard CI gates.

Component Architecture

The structure under apps/web/src/ separates routes, owned UI primitives, feature components, and framework-glue libraries.

This page covers the customer web app (apps/webtheroyalglow.in). The admin portal is a separate Next.js app at apps/admin (served from admin.theroyalglow.in, root-path routes with no /admin prefix) — its pages, admin components, and admin data helpers all live under apps/admin/src/, not in apps/web. apps/web only keeps lib/admin-redirect.ts, which 301-redirects legacy theroyalglow.in/admin/* URLs to the subdomain.

(customer) — public + authenticated customer pages
(auth) — sign-in, onboarding
(landing) — /book Meta ad lead capture
(legal) — privacy, terms, refund policy

Design System

Design Tokens

Tailwind CSS v4 design tokens are defined in apps/web/src/styles/globals.css.

Prop

Type

Typography

Prop

Type

Spacing & Layout

  • Max content width: 1278px (max-w-[1278px])
  • Horizontal padding: px-5 (20px) on mobile, px-8 on desktop
  • Mobile-first: customer pages designed for 375px–428px first

shadcn/ui Components

Components are copy-pasted into components/ui/ — you own 100% of the code. Built on Radix UI primitives for production-tested accessibility.

Key components in use:

  • Button, Input, Label, Select, Textarea
  • Dialog, Sheet, Popover, Tooltip
  • Badge, Card, Separator, Skeleton
  • Tabs, Accordion
  • Calendar, DatePicker

Booking Dialog

The booking dialog is a 4-step modal that opens over the homepage. It is never a separate page — it's always a modal overlay.

Step 1 — Branch, date & time

Branch selector plus a date and time-slot picker.

Step 2 — Service type & category

Salon/SPA toggle and category selection (one service type per booking).

Step 3 — Services

Service multi-select with a running total.

Step 4 — Summary & submission

Review and submit the booking.

Entry points:

  • Homepage "Book Now" button
  • /?book=1 deep-link (auto-opens dialog)
  • /?book=1&utm_source=gmb (dialog + GMB attribution)
  • /?book=1&utm_source=walkin (dialog + walk-in attribution)

The dialog has a full focus trap, aria-modal="true", and Escape key handling. It uses BookingDialogProvider (React context) to share open/close state across the page.

Animation

motion (motion.dev) handles all animations:

import { motion } from 'motion/react'

// Page transitions
<motion.div
  initial={{ opacity: 0, y: 20 }}
  animate={{ opacity: 1, y: 0 }}
  transition={{ duration: 0.4, ease: 'easeOut' }}
>

// Staggered list reveals
const container = {
  hidden: { opacity: 0 },
  show: { opacity: 1, transition: { staggerChildren: 0.1 } }
}

All animations respect prefers-reduced-motion:

@media (prefers-reduced-motion: reduce) {
  /* motion handles this automatically via its built-in hook */
}

Accessibility Standards

WCAG 2.1 AA compliance is non-negotiable. Lighthouse Accessibility = 100 is a hard CI gate.

  • <button> for actions (never <div onClick>)
  • type="button" on all buttons not inside a form
  • aria-label on icon-only buttons
  • Visible focus ring (focus-visible:ring-2)
  • Keyboard navigation support
  • Every <input> has a <label> with matching htmlFor/id
  • aria-required="true" on required fields
  • aria-describedby linking input to error message
  • <fieldset> + <legend> for grouped fields
  • aria-live="polite" on booking availability updates
  • aria-live="polite" on loading states (use the <output> element)
  • role="alert" on error messages
  • Focus management on modal open/close
  • Normal text: 4.5:1 minimum
  • Large text (18px+ or 14px+ bold): 3:1 minimum
  • UI components and graphical objects: 3:1 minimum

PWA

The app is installable as a Progressive Web App:

  • manifest.ts — app name, icons, theme colour, display mode
  • sw.js — service worker for offline support
  • ServiceWorkerRegistrar — registers the service worker on first load
  • Offline page at /offline — shows when user is offline

Offline capabilities:

  • Service menu and prices (cached on first visit)
  • Contact information and address
  • Booking history (cached)

Performance Targets

Prop

Type

Coding Conventions

  • Files: kebab-case.ts for utilities, PascalCase.tsx for React components
  • Server Components by default — only add 'use client' when needed
  • Zero business logic in components — presentation only
  • No any — TypeScript strict mode enforced by Biome
  • Single quotes, no semicolons — Biome formatter
  • Import sorting — handled automatically by Biome
OpenReport an issue

Was this page helpful?

On this page