# GBBS Design System

Single source of truth: `resources/css/app.css` (`:root` variables, base styles, `.container-page`, type and button classes) and `tailwind.config.js` (colors, radii, shadows, breakpoints).

## Colors

Brand is the school's green. Semantic tokens are CSS variables in `:root` of `resources/css/app.css`; edit them there.

| Tailwind class | Variable | Use |
|---|---|---|
| `bg-brand-primary` / `text-brand-primary` | `--brand-primary` `#044335` | Main brand, primary buttons, headings accents |
| `bg-brand-primary-hover`, `-active` | `--brand-primary-hover/-active` | Hover and pressed states |
| `bg-brand-secondary` | `--brand-secondary` `#03624C` | Secondary surfaces, top bar |
| `bg-brand-accent` | `--brand-accent` `#FFF32F` | Highlights on dark surfaces only. Never body text on white |
| `bg-surface`, `bg-surface-muted`, `bg-surface-elevated` | `--surface*` | Page and card backgrounds |
| `text-ink`, `text-ink-secondary`, `text-ink-muted` | `--ink*` | Body text (all pass 4.5:1 on white) |
| `border-line`, `border-line-strong` | `--line*` | Borders |
| `ring-focus-ring` | `--focus-ring` | Keyboard focus |
| `text-status-success/warning/error/info` | `--status-*` | Status. Always pair with an icon or text, not color alone |
| `bg-overlay` | `--overlay` | Image and modal scrims |

The older `primary`, `secondary`, `accent` classes still work. Prefer the semantic names in new code. Semantic colors do not support opacity modifiers such as `bg-brand-primary/50`; use `bg-primary/50` for that.

## Typography

Plain CSS classes (they work even where the Tailwind CDN script compiles the page):

| Class | Size (mobile to desktop) |
|---|---|
| `.text-display` | 32 to 64 px |
| `h1` / `.text-h1` | 30 to 52 px |
| `h2` / `.text-h2` | 26 to 40 px |
| `h3` / `.text-h3` | 20 to 24 px |
| `h4` / `.text-h4` | 18 to 20 px |
| `.text-lead` | 17 to 20 px |
| `.text-body` | 15 to 18 px |
| `.text-support` | 14 to 16 px |
| `.text-meta` | 13 to 14 px |

Unstyled `h1` to `h4` already follow this scale. Explicit `text-*` utilities still win.

## Layout and spacing

- `.container-page`: centered, max 1280 px, fluid gutters (16 to 48 px).
- `.section-y` / `.section-y-sm`: vertical section padding (48 to 112 px / 32 to 64 px).
- `.grid-gap`, `.card-pad`, `.heading-gap`: fluid gap and padding tokens.
- `.measure`: caps text at a readable 68 characters.
- `.table-responsive`: wrap wide tables so only the table scrolls.

## Components

- `.btn`: 44 px tall on mobile, 48 px from `md`. Add color utilities, e.g. `btn bg-primary text-white hover:bg-secondary`.
- `.card-ui`: white card, subtle border, soft shadow, hover lift.
- Forms: inputs get a 44 px minimum height and a branded focus ring automatically.

## Accessibility

- Layout has a skip link (`Skip to main content`) and `<main id="main-content">`.
- Never use `focus:outline-none` alone. Use `focus-visible:outline-2 focus-visible:outline-primary`.
- Icon-only buttons need `aria-label`. Informative images need `alt`; decorative images use `alt=""`.
- `prefers-reduced-motion` is honored globally.

## SEO

`resources/views/frontend/layouts/app.blade.php` outputs title, description, canonical URL, Open Graph and theme color. A page can set its own text with:

```blade
@section('meta_description', 'Short, accurate description of this page.')
```

## Build

Tailwind 3.4 (JS config) through Vite. After changing tokens run `npm run build`.

## Stacking (z-index)

Never write `z-50` or `z-[9999]` for a page-level layer. Use the named classes from `resources/css/app.css`.
Highest first:

| Class | z-index | Used for |
|---|---|---|
| (preloader, `style.css`) | 99999 | page preloader |
| `z-top` | 9999 | skip link |
| `z-modal` | 110 | testimonial modal |
| `z-overlay` | 100 | popup, video modals, lightboxes |
| `z-mobile-menu` | 70 | mobile menu |
| `z-subchild` / `z-drawer` | 60 | child sub menu / side drawer panel |
| `z-submenu` | 50 | header dropdown, Apply Now dropdown |
| `z-float` | 45 | FAQ and go-to-top buttons, side quick-nav tabs |
| `z-header` | 40 | fixed header |
| `z-0` to `z-10` | 0-10 | in-page layers (cards, banners, swiper controls) |

The footer is `isolate`, so its inner layers can never rise above the header or an overlay.
Layers inside a modal or section (close buttons, badges) use `z-10` within that parent.
