> ## Documentation Index
> Fetch the complete documentation index at: https://constanza101-borrissol-28.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Home page sections and landing page architecture

> The Borrissol home page is a single-page landing with 10 sections: hero, offers, workshops, process, testimonials, press strip, about, FAQ, CTA, and footer.

The home page is the primary conversion surface for Borrissol Espai Creatiu — a single-page landing assembled from ten sequential sections, each handled by its own Astro component. It is served in four languages at `/` (Catalan, the default locale), `/es`, `/en`, and `/fr`. Every language variant is a statically pre-rendered HTML file; no client-side routing is involved. All visible copy is resolved at build time through `useTranslations(lang)` — there are zero hardcoded strings in the component templates.

## Section inventory

Each section lives in `src/components/sections/` and receives translated strings via the shared `t()` helper. The ordering below matches the DOM order in `index.astro`.

| Section      | Component                   | Purpose                                                                   |
| ------------ | --------------------------- | ------------------------------------------------------------------------- |
| Hero         | `HeroSection.astro`         | H1 headline, SEO subtitle, full-bleed image with logo overlay and CTA     |
| Offer        | `OfferSection.astro`        | Workshop technique cards (Tufting, Needle Felting, Punch Needle, Weaving) |
| Workshops    | `WorkshopsSection.astro`    | Tufting format pricing accordion + other workshop cards                   |
| Process      | `ProcessSection.astro`      | 5-step "zero to piece" visual flow                                        |
| Testimonials | `TestimonialsSection.astro` | Google Maps review carousel with arrow navigation                         |
| Press Strip  | `PressStrip.astro`          | Condensed media coverage teaser linking to `/press`                       |
| About        | `AboutSection.astro`        | Studio founding story, founder video, recycled-yarn materials section     |
| FAQ          | `FAQSection.astro`          | Native `<details>`/`<summary>` accordion — zero JavaScript                |
| CTA          | `CTASection.astro`          | Final WhatsApp booking call-to-action                                     |
| Footer       | `Footer.astro`              | Navigation links, legal copy, social links                                |

<Note>
  The DOM render order in `index.astro` places **Workshops before Process** — `WorkshopsSection` renders immediately after `OfferSection`, followed by `ProcessSection`. The table above reflects the actual render order.
</Note>

## H1 copy by language

The hero headline (`hero.headline` key in `src/i18n/ui.ts`) is the page H1. It is the same phrase translated into each locale:

| Locale            | URL prefix | H1                 |
| ----------------- | ---------- | ------------------ |
| Catalan (default) | `/`        | Art que connecta   |
| Spanish           | `/es`      | Arte que conecta   |
| English           | `/en`      | Art that connects  |
| French            | `/fr`      | L'art qui connecte |

The hero also renders an SEO subtitle (`hero.seo`) — visible text beneath the H1 — and an image overlay (`hero.overlay`) positioned over the bottom-left of the full-bleed hero photograph.

## Language routing

<CardGroup cols={2}>
  <Card title="Catalan default" icon="flag">
    `src/pages/index.astro` — served at `/`. No URL prefix. `getLangFromUrl()` returns `'ca'` for this root route.
  </Card>

  <Card title="ES / EN / FR" icon="globe">
    `src/pages/[lang]/index.astro` — a single dynamic route file that handles all three non-default locales via `getStaticPaths`, generating `/es`, `/en`, and `/fr` at build time.
  </Card>
</CardGroup>

The same pattern applies to `/gallery` and `/press`. The blog is Catalan-only and has no `[lang]` variant.

## Anchor navigation

The top navbar links scroll to in-page sections using hash anchors. All section IDs are in English regardless of the active language, so the anchors are stable across locale switches:

```html theme={null}
#offer        → OfferSection
#workshops    → WorkshopsSection
#process      → ProcessSection
#testimonials → TestimonialsSection
#about        → AboutSection
#faq          → FAQSection
#contact      → CTASection
```

The language switcher in the navbar preserves the current hash via client-side JS, so switching locale mid-page keeps the user at the same section.

## Additional UX features

<CardGroup cols={2}>
  <Card title="WhatsApp FAB" icon="message-circle">
    `WhatsAppFab.astro` — a fixed floating action button stacked with the scroll-to-top button. Pre-filled WhatsApp messages are localised per language via `wa.general` / `wa.cta` keys in `ui.ts`.
  </Card>

  <Card title="Cookie banner" icon="shield">
    `CookieBanner.astro` + `PrivacySection.astro` — implements Google Consent Mode v2 Advanced. GA4 loads cookieless by default; cookies are only granted after explicit accept. Consent state is persisted in `localStorage`.
  </Card>

  <Card title="Scroll-to-top" icon="arrow-up">
    Fixed button stacked below the WhatsApp FAB. Appears after the user scrolls past the hero, implemented in vanilla JS with no framework dependency.
  </Card>

  <Card title="Scroll reveal" icon="sparkles">
    `Layout.astro` sets up an `IntersectionObserver` that adds a `.is-visible` class to elements with `reveal` or `load-anim` classes as they enter the viewport. Respects `prefers-reduced-motion`.
  </Card>
</CardGroup>

## Structured data (JSON-LD)

Two JSON-LD schemas are injected by `Seo.astro` on the home page:

```json theme={null}
// LocalBusiness schema (abridged)
{
  "@type": "LocalBusiness",
  "name": "Borrissol Espai Creatiu",
  "address": { "@type": "PostalAddress", "addressLocality": "Mataró" },
  "aggregateRating": { "@type": "AggregateRating", "ratingValue": "5.0", "reviewCount": "27" },
  "openingHours": "...",
  "sameAs": ["https://instagram.com/...", "https://tiktok.com/..."]
}

// FAQPage schema — mirrors the FAQSection content
{
  "@type": "FAQPage",
  "mainEntity": [
    { "@type": "Question", "name": "Do I need previous experience?", "acceptedAnswer": { ... } },
    ...
  ]
}
```

<Tip>
  The `FAQPage` schema is kept in sync with the `faq.q*` / `faq.a*` translation keys. If you add a new FAQ item, update both `ui.ts` and the JSON-LD block in `Seo.astro`.
</Tip>

## Component import order in `index.astro`

```astro theme={null}
---
import Layout from '../layouts/Layout.astro';
import Navbar from '../components/layout/Navbar.astro';
import HeroSection from '../components/sections/HeroSection.astro';
import OfferSection from '../components/sections/OfferSection.astro';
import ProcessSection from '../components/sections/ProcessSection.astro';
import WorkshopsSection from '../components/sections/WorkshopsSection.astro';
import TestimonialsSection from '../components/sections/TestimonialsSection.astro';
import PressStrip from '../components/sections/PressStrip.astro';
import AboutSection from '../components/sections/AboutSection.astro';
import FAQSection from '../components/sections/FAQSection.astro';
import CTASection from '../components/sections/CTASection.astro';
import Footer from '../components/layout/Footer.astro';
import PrivacySection from '../components/sections/PrivacySection.astro';
---
```

`PrivacySection` is rendered outside `<main>` — it is a visually hidden accordion that surfaces inline privacy/cookie policy text for compliance, without a dedicated `/privacy` page.

## Page-level background

The home page sets a global background override so the hero blends into the page chrome while inner sections revert to `--color-white` via their own component styles:

```astro theme={null}
<style is:global>
  body {
    background: var(--color-mid);
  }
</style>
```
