# Integration Notes — CFS Homepage

Technical notes for the Drupal 10 theme developer integrating the HTML/Tailwind components.

---

## 1. Blocks vs Paragraphs vs Views — Decision Guide

### Use Blocks for:
- **Utility Bar** (01) — site-wide secondary navigation, managed as a menu block
- **Main Navigation** (02) — Drupal core menu block + custom CTA block
- **CTA Action Buttons** (10) — static 3-link row, custom block type
- **Callback Form** (14) — Webform block placed in content or sidebar region
- **Sticky Bar** (16) — fixed-position custom block in `page_bottom` region

**Rationale:** These sections are either site-wide (not page-specific) or are simple enough that a Block type with a few link/text fields is sufficient. They do not require per-item content management.

### Use Paragraphs for:
- **Hero Banner** (03) — complex layout with multiple field types (text, image, stats repeater, form reference)
- **Specialities Tabs** (05) — tab items vary per installation; Paragraph repeater gives editors control
- **Why Us** (07) — mixed content (stat items + images) best modeled as a Paragraph with nested items
- **Journey Timeline** (08) — milestone items are a classic Paragraph repeater use case
- **International Patients** (11) — split-content layout; image + rich text as a reusable Paragraph type
- **Accreditations** (12) — if not enough items to justify a content type, use Paragraph repeater

**Rationale:** Paragraphs are ideal for page-specific, editorially controlled sections that need flexible field structures. They attach to the Homepage node and render in order.

### Use Views for:
- **Centres Listing** (04) — Centre nodes filtered/sorted dynamically
- **Doctor Cards** (06) — Doctor nodes; two View displays (featured + row)
- **Testimonials** (09) — Testimonial nodes with possible taxonomy filtering
- **Blogs** (13) — Article/Blog nodes, standard teaser grid

**Rationale:** Content types that will be managed independently, require filtering/sorting, or will appear on multiple pages should be Views-driven. This decouples content entry from layout.

---

## 2. JS Interaction Hooks (Data Attributes)

The following `data-*` attributes are used as JS hooks. Do not remove them when porting to Twig templates.

| Attribute | Component | Behaviour |
|---|---|---|
| `data-tab` | 05-specialities | Identifies tab trigger buttons; value matches `data-panel` on content panels |
| `data-panel` | 05-specialities | Content panel toggled by matching `data-tab` value |
| `data-accordion` | 05-specialities (mobile) | Accordion trigger for mobile specialty items |
| `data-slider` | 06-doctor-cards, 09-testimonials | Marks slider containers; JS initialises scroll/carousel behaviour |
| `data-slide-prev` / `data-slide-next` | 06-doctor-cards, 09-testimonials | Navigation arrow buttons for sliders |
| `data-menu-toggle` | 02-main-nav | Hamburger button that toggles the mobile menu open/close |
| `data-sticky` | 16-sticky-bar | Root element of the sticky bar; JS may add/remove classes based on scroll position |

**Note:** All JS is vanilla (no jQuery, no external library dependency). Scripts are self-contained in each component's `<script>` block. When porting to Drupal, consolidate these scripts into the theme's JS file (e.g., `js/cfs-homepage.js`) and attach via `hook_page_attachments` or a Drupal library definition.

---

## 3. Special Twig Handling

### Menu rendering (02-main-nav)
- Replace the static `<ul>` nav with `{{ menus.main }}` rendered via `menu.html.twig`.
- The CTA "Book Appointment" button is a separate block; pass it as a Twig variable or place it as a block in the header region template.

### Dynamic field loops (04, 05, 06, 08, 09, 12, 13)
- Static `<div>` card/item repetitions must be replaced with `{% for item in items %}` loops.
- Use Drupal's field template system (`field--*.html.twig`) or Views row templates (`views-view-fields--*.html.twig`) for output.

### Image handling
- All `<img src="...">` tags should use `{{ file_url(node.field_image.entity.uri.value) }}` or the equivalent responsive image style function.
- Use Drupal's Responsive Image module with image styles matching the breakpoints listed in Section 6.

### Forms (14-callback-form)
- Replace the static HTML form with `{{ drupal_entity('webform', 'callback_form') }}` or the Webform block render.
- Preserve the surrounding wrapper `<div>` classes for layout; only the inner `<form>` element changes.

### Sticky bar visibility (16-sticky-bar)
- The sticky bar has two visual states: desktop (chat bubble icon) and mobile (action task bar).
- Both states are in the same template; visibility is controlled by Tailwind's `hidden md:flex` / `flex md:hidden` pattern — no Twig conditionals needed.

---

## 4. Font Loading Requirements

The design uses the following fonts, loaded via Google Fonts:

```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,300;0,400;0,700;0,900;1,700&family=Poppins:wght@300;400;500;600;700&display=swap" rel="stylesheet">
```

- **Poppins** (CSS var: `--font-heading`) — section headings, navigation, buttons (weights: 300, 400, 500, 600, 700)
- **Lato** (CSS var: `--font-body`) — body text, form labels, descriptions (weights: 300, 400, 700, 900; italic 700)

**Drupal integration:** Add the Google Fonts `<link>` tags to the theme's `html.html.twig` template, or declare them in `THEMENAME.libraries.yml` as an external CSS library attached to all pages:

```yaml
global-fonts:
  css:
    theme:
      'https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,300;0,400;0,700;0,900;1,700&family=Poppins:wght@300;400;500;600;700&display=swap': { type: external, minified: true }
```

---

## 5. Tailwind Theme Token Usage

The project uses **Tailwind CSS v4** with an `@theme` block in `css/input.css` (not a `tailwind.config.js` file). The following design tokens are defined:

```css
@theme {
  /* Colors */
  --color-primary: #2b286f;
  --color-primary-light: #4b479a;
  --color-accent: #ffcb05;
  --color-gray-50: #f8f8f8;
  --color-gray-100: #f1f1f1;
  --color-gray-200: #f0f0f0;
  --color-gray-300: #d9d9d9;
  --color-gray-400: #cccbcb;
  --color-gray-500: #909090;
  --color-text-dark: #434343;
  --color-text-muted: #bcbbbb;
  --color-text-body: #1a1a1a;

  /* Fonts */
  --font-heading: 'Poppins', sans-serif;
  --font-body: 'Lato', sans-serif;

  /* Font sizes with line heights */
  --text-section-title: 69px;
  --text-section-title--line-height: 81px;
  --text-section-title-mobile: 37px;
  --text-section-title-mobile--line-height: 90px;
  --text-hero-heading: 66px;
  --text-hero-heading--line-height: 81px;
  --text-hero-heading-mobile: 38px;
  --text-stat-number: 52px;
  --text-stat-number--line-height: 40px;
  --text-hero-subtitle: 36px;
  --text-hero-subtitle--line-height: 81px;
  --text-card-heading: 29px;
  --text-card-heading--line-height: 45px;
  --text-subtitle: 21px;
  --text-subtitle--line-height: 27px;
  --text-cta-button: 25px;
  --text-cta-button--line-height: 37px;
  --text-nav: 15px;
  --text-nav--line-height: 24px;

  /* Border Radii */
  --radius-sm: 2px;
  --radius-md: 6px;
  --radius-card: 7px;
  --radius-btn: 8px;
  --radius-input: 7px;
  --radius-lg: 13px;
  --radius-card-lg: 17px;
  --radius-section: 21px;
  --radius-section-lg: 30px;

  /* Spacing / Container */
  --container-site: 1440px;
  --container-inner: 1380px;
}
```

Tailwind v4 uses the `@source` directive instead of a `content` glob. The project includes `@source "../html";` in `css/input.css` to scan all HTML component files for utility classes. Rebuild CSS with:

```bash
npx @tailwindcss/cli -i ./css/input.css -o ./css/output.css
```

---

## 6. Responsive Breakpoint Strategy

All components are built mobile-first. The breakpoint strategy follows Tailwind's defaults with the following usage conventions:

| Breakpoint | Tailwind Prefix | Viewport | Usage in this project |
|---|---|---|---|
| Mobile (base) | (none) | < 640px | Single column, stacked layout, accordion menus |
| Small | `sm:` | >= 640px | Slight padding/font adjustments |
| Medium | `md:` | >= 768px | Two-column layouts begin, hamburger hides |
| Large | `lg:` | >= 1024px | Full desktop grid, utility bar visible, multi-column |
| XL | `xl:` | >= 1280px | Max-width container locks at 1280px |

**Key patterns used:**
- Navigation: hamburger at mobile → full horizontal menu at `md:`
- Hero: stacked (image below text) at mobile → side-by-side at `lg:`
- Centres grid: 1 col → 2 col (`sm:`) → 3 col (`lg:`) → 4 col (`xl:`)
- Blogs: compact list at mobile → card grid at `md:`
- Utility bar: `hidden lg:flex` — not rendered in mobile DOM flow
- Sticky bar: separate layout per breakpoint in same element using `hidden`/`flex` pairs

---

## 7. Deviations from Figma Design

The following intentional deviations were made during implementation:

| Section | Figma Spec | Implementation | Reason |
|---|---|---|---|
| 02-main-nav | Mega-dropdown on hover | Simple dropdown via CSS + JS toggle | Mega-menu requires content data not available at HTML prototype stage; structure is in place for Drupal menu blocks |
| 03-hero-banner | Animated counter for stats | Static numbers | Animation can be added via IntersectionObserver in production; kept static for prototype clarity |
| 05-specialities | Figma shows desktop-only tabs | Mobile accordion added | Accessibility and UX requirement; accordion mirrors tab content, no data duplication |
| 06-doctor-cards | Custom carousel library implied | Vanilla JS scroll-snap slider | Avoids external dependency; Swiper.js can replace if richer features needed |
| 09-testimonials | Auto-advancing carousel | Manual navigation only | Auto-advance can cause accessibility issues; manual is WCAG-safer default |
| 13-blogs | Figma shows 3-col grid only | 1-col list on mobile added | Responsive requirement not in Figma; list layout derived from design system patterns |
| 15-footer | Single footer layout | Sub-regions split into logical blocks | Drupal region architecture requires this split; visual output matches Figma |
