/* === tokens/_base.css === */
/* =======================================================================
   Habil — Canonical design tokens (base)

   Default token values used by all primitives + organisms.
   Each theme overrides a subset via `body.template-<name>` in tokens/<theme>.css.
   The user's brand colors are injected last via inline <style> in <head>
   (highest cascade priority).

   Cascade order :
     1. tokens/_base.css        (this file — defaults)
     2. tokens/<theme>.css      (per-theme overrides via body.template-<name>)
     3. inline <style> in <head> (brand colors per website, via :root)

   STRUCTURE-V2.md §0 rule 2 : tokens are the source of truth for design.
   Primitives and organisms read tokens via var(--name), never hex literals.
   ======================================================================= */

:root {
  /* ─── Brand colors (overridden inline per website) ────────────────── */
  --color-primary:        #0A2540;
  --color-secondary:      #D4A24C;
  --color-accent:         #00D4A3;

  /* ─── Neutrals ────────────────────────────────────────────────────── */
  --color-ink:            #0A1628;
  --color-ink-2:          #1F2937;
  --color-muted:          #6B7280;
  --color-muted-2:        #9CA3AF;
  --color-line:           #E5E7EB;
  --color-line-soft:      #F3F4F6;
  --color-bg:             #FFFFFF;
  --color-bg-alt:         #FAFAF9;
  --color-bg-dark:        #0A1628;
  --color-bg-darker:      #050B15;

  /* ─── Semantic colors ─────────────────────────────────────────────── */
  --color-success:        #15803d;
  --color-warning:        #b45309;
  --color-danger:         #b91c1c;

  /* ─── Derived from primary ────────────────────────────────────────── */
  --color-primary-tint-5:  color-mix(in srgb, var(--color-primary) 5%, white);
  --color-primary-tint-10: color-mix(in srgb, var(--color-primary) 10%, white);
  --color-primary-tint-20: color-mix(in srgb, var(--color-primary) 20%, white);
  --color-primary-soft:    color-mix(in srgb, var(--color-primary) 8%, transparent);

  /* ─── Typography ──────────────────────────────────────────────────── */
  --font-heading:         'Instrument Serif', 'Playfair Display', Georgia, serif;
  --font-body:            'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --font-mono:            'JetBrains Mono', 'Menlo', monospace;

  /* Modular scale — ratio 1.25 (major third) */
  --fs-xs:                0.75rem;
  --fs-sm:                0.875rem;
  --fs-base:              1rem;
  --fs-lg:                1.125rem;
  --fs-xl:                1.375rem;
  --fs-2xl:               1.75rem;
  --fs-3xl:               2.25rem;
  --fs-4xl:               3rem;
  --fs-5xl:               4rem;
  --fs-6xl:               5.25rem;
  --fs-7xl:               7rem;

  --lh-tight:             1.05;
  --lh-snug:              1.2;
  --lh-normal:            1.5;
  --lh-relaxed:           1.7;

  --tracking-tight:       -0.025em;
  --tracking-normal:      0;
  --tracking-wide:        0.04em;
  --tracking-wider:       0.08em;

  /* ─── Spacing scale (base 4px) ────────────────────────────────────── */
  --s-1:                  0.25rem;
  --s-2:                  0.5rem;
  --s-3:                  0.75rem;
  --s-4:                  1rem;
  --s-5:                  1.25rem;
  --s-6:                  1.5rem;
  --s-8:                  2rem;
  --s-10:                 2.5rem;
  --s-12:                 3rem;
  --s-16:                 4rem;
  --s-20:                 5rem;
  --s-24:                 6rem;
  --s-32:                 8rem;
  --s-40:                 10rem;
  --s-48:                 12rem;

  /* ─── Layout ──────────────────────────────────────────────────────── */
  --container-max:        1440px;
  --container-md:         1200px;
  --container-narrow:     960px;
  --container-text:       680px;
  --gutter:               clamp(1.25rem, 4vw, 2.5rem);

  /* ─── Shape ───────────────────────────────────────────────────────── */
  --radius-sm:            6px;
  --radius-md:            12px;
  --radius-lg:            20px;
  --radius-xl:            32px;
  --radius-pill:          999px;

  /* ─── Effects ─────────────────────────────────────────────────────── */
  --shadow-xs:            0 1px 2px rgba(10, 22, 40, 0.04);
  --shadow-sm:            0 2px 8px rgba(10, 22, 40, 0.05);
  --shadow-md:            0 8px 24px rgba(10, 22, 40, 0.08);
  --shadow-lg:            0 20px 48px rgba(10, 22, 40, 0.12);
  --shadow-xl:            0 40px 80px rgba(10, 22, 40, 0.18);

  /* ─── Motion ──────────────────────────────────────────────────────── */
  --ease-out:             cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out:          cubic-bezier(0.83, 0, 0.17, 1);
  --ease-spring:          cubic-bezier(0.34, 1.56, 0.64, 1);
  --t-fast:               0.2s;
  --t-base:               0.4s;
  --t-slow:               0.7s;
  --t-slower:             1.1s;

  /* ─── Z-index scale ───────────────────────────────────────────────── */
  --z-below:              -1;
  --z-base:               0;
  --z-sticky:             10;
  --z-fixed:              20;
  --z-overlay:            30;
  --z-modal:              40;
  --z-toast:              50;

  /* ─── Layout chrome ───────────────────────────────────────────────── */
  --header-h:             80px;
}

/* -----------------------------------------------------------------------
   Reset & defaults — normalized cross-browser baseline
   ----------------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
  padding: 0;
}

[hidden] {
  display: none !important;
}

html {
  -webkit-text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  scroll-padding-top: var(--header-h);
}

body {
  min-height: 100vh;
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: var(--lh-normal);
  color: var(--color-ink);
  background: var(--color-bg);
  overflow-x: hidden;
}

img,
picture,
video,
canvas,
svg {
  display: block;
  max-width: 100%;
  height: auto;
}

input,
button,
textarea,
select {
  font: inherit;
  color: inherit;
}

button {
  background: none;
  border: none;
  cursor: pointer;
}

a {
  color: inherit;
  text-decoration: none;
}

ul,
ol {
  list-style: none;
}

:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 3px;
  border-radius: 2px;
}

::selection {
  background: var(--color-primary);
  color: #fff;
}

/* Respect reduced-motion preference globally */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}


/* === tokens/signature.css === */
/* =======================================================================
   Theme tokens : signature
   Identité : éditorial premium, serif italique, espacement aéré.

   Source visuelle : templates/signature/signature.css (legacy, ~157 lignes).
   En V1 ce fichier ne contient que les VARIABLES (tokens) de signature.
   Les RÈGLES de style spécifiques (radial gradients hero, dark testimonials,
   serif italic emphasis) restent dans le legacy signature.css pendant la
   migration. Elles seront migrées en V2 vers styles/themes/signature.css
   (selectors `body.template-signature .X`) si on veut atteindre la pureté
   Choix B complète.
   ======================================================================= */

body.template-signature {
  /* Signature utilise les couleurs primaires du website telles quelles
     (injectées inline dans head.ejs depuis website.primaryColor/secondary/accent).
     Pas d'override de couleurs ici — préserve la flexibilité de marque. */

  /* Border-radius : signature aime le large radius arrondi pour les images */
  --radius-md: 12px;
  --radius-lg: 24px;
  --radius-xl: 32px;
}


/* === styles/primitives === */

/* =======================================================================
   Primitive: AccordionItem (FAQ)
   Source : extrait de templates/css/sections-extra.css :171-229
   Lu par : api/src/app/features/website/templates/primitives/AccordionItem.ejs
   ======================================================================= */

.faq-item {
  border-bottom: 1px solid var(--color-line);
}

.faq-item:first-child { border-top: 1px solid var(--color-line); }

.faq-item__trigger {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-6);
  padding: var(--s-6) 0;
  text-align: left;
  color: var(--color-ink);
  transition: color var(--t-fast) var(--ease-out);
}

.faq-item__trigger:hover { color: var(--color-primary); }

.faq-item__question {
  font-family: var(--font-heading);
  font-size: clamp(1.125rem, 1.8vw, 1.375rem);
  line-height: 1.3;
  letter-spacing: var(--tracking-tight);
}

.faq-item__icon {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--color-line);
  border-radius: 50%;
  transition: transform var(--t-base) var(--ease-out);
}

.faq-item.is-open .faq-item__icon {
  transform: rotate(45deg);
  background: var(--color-ink);
  color: #fff;
  border-color: var(--color-ink);
}

.faq-item__panel {
  max-height: 0;
  overflow: hidden;
  transition: max-height var(--t-base) var(--ease-out);
}

.faq-item__answer {
  padding-bottom: var(--s-6);
  font-size: var(--fs-base);
  line-height: var(--lh-relaxed);
  color: var(--color-muted);
  max-width: 560px;
}


/* =======================================================================
   Primitive: AidCard
   Source : extrait de templates/css/sections-extra.css :370-441
   Lu par : api/src/app/features/website/templates/primitives/AidCard.ejs
   ======================================================================= */

.aide-card {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-8);
  padding: clamp(2rem, 4vw, 3rem);
  background: #fff;
  border: 1px solid var(--color-line);
  border-radius: var(--radius-lg);
  transition: border-color var(--t-base) var(--ease-out), box-shadow var(--t-base) var(--ease-out);
}

.aide-card:hover {
  border-color: var(--color-primary);
  box-shadow: var(--shadow-md);
}

@media (max-width: 639px) {
  .aide-card { grid-template-columns: 1fr; gap: var(--s-4); }
}

.aide-card__number {
  font-family: var(--font-heading);
  font-size: clamp(2.5rem, 5vw, 4rem);
  line-height: 1;
  color: var(--color-primary);
  opacity: 0.3;
  letter-spacing: var(--tracking-tight);
}

.aide-card__name {
  font-family: var(--font-heading);
  font-size: var(--fs-2xl);
  line-height: 1.2;
  letter-spacing: var(--tracking-tight);
  margin-bottom: var(--s-3);
}

.aide-card__description {
  font-size: var(--fs-base);
  line-height: var(--lh-relaxed);
  color: var(--color-muted);
  margin-bottom: var(--s-5);
}

.aide-card__details {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  padding-top: var(--s-5);
  border-top: 1px solid var(--color-line);
}

.aide-card__detail {
  display: grid;
  grid-template-columns: 120px 1fr;
  gap: var(--s-4);
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: var(--color-ink-2);
}

@media (max-width: 479px) {
  .aide-card__detail { grid-template-columns: 1fr; gap: var(--s-1); }
}

.aide-card__label {
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--color-muted);
}


/* =======================================================================
   Primitive: Button
   Source : extrait de templates/css/base.css :298-393
   Lu par : api/src/app/features/website/templates/primitives/Button.ejs
   ======================================================================= */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  padding: 0.875rem 1.5rem;
  font-size: var(--fs-base);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.01em;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  transition:
    background-color var(--t-fast) var(--ease-out),
    color var(--t-fast) var(--ease-out),
    border-color var(--t-fast) var(--ease-out),
    transform var(--t-fast) var(--ease-out),
    box-shadow var(--t-fast) var(--ease-out);
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
}

.btn--primary {
  background: var(--color-ink);
  color: #fff;
}

.btn--primary:hover {
  background: var(--color-primary);
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
}

.btn--secondary {
  background: var(--color-primary);
  color: #fff;
}

.btn--secondary:hover {
  background: color-mix(in srgb, var(--color-primary) 88%, black);
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
}

.btn--ghost {
  background: transparent;
  color: var(--color-ink);
  border-color: var(--color-line);
}

.btn--ghost:hover {
  background: var(--color-ink);
  color: #fff;
  border-color: var(--color-ink);
}

.btn--light {
  background: #fff;
  color: var(--color-ink);
}

.btn--light:hover {
  background: var(--color-bg-alt);
  transform: translateY(-1px);
}

.btn--link {
  padding: 0;
  border-radius: 0;
  background: transparent;
  color: var(--color-ink);
  border-bottom: 1px solid currentColor;
  padding-bottom: 2px;
}

.btn--link:hover {
  color: var(--color-primary);
}

.btn--lg {
  padding: 1.125rem 2rem;
  font-size: var(--fs-lg);
}

.btn__arrow {
  display: inline-block;
  transition: transform var(--t-fast) var(--ease-out);
}

.btn:hover .btn__arrow {
  transform: translateX(3px);
}


/* =======================================================================
   Primitive: CertificationBadge
   Source : extrait de templates/css/sections.css :149-175 (.trust-bar__cert-badge)
   Lu par : api/src/app/features/website/templates/primitives/CertificationBadge.ejs

   Génère un badge pilule blanc avec un check vert au début + le nom de la
   certification. Si un `logo` est fourni, on rend `<img>` à la place
   (classe .cert-badge__logo).
   ======================================================================= */

.cert-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-5);
  background: #fff;
  border: 1px solid var(--color-line);
  border-radius: var(--radius-pill);
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--color-ink-2);
  letter-spacing: var(--tracking-tight);
}

.cert-badge::before {
  content: '✓';
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  background: var(--color-primary);
  color: #fff;
  border-radius: 50%;
  font-size: 10px;
  font-weight: 700;
}

.cert-badge__logo {
  height: 32px;
  width: auto;
  object-fit: contain;
}


/* =======================================================================
   Primitive: Eyebrow
   Source : extrait de templates/css/base.css :230-249
   Lu par : api/src/app/features/website/templates/primitives/Eyebrow.ejs
   ======================================================================= */

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--color-primary);
}

.eyebrow::before {
  content: '';
  display: inline-block;
  width: 24px;
  height: 1px;
  background: currentColor;
  opacity: 0.5;
}


/* =======================================================================
   Primitive: FormField
   Source : extrait de templates/css/base.css :429-473
   Lu par : api/src/app/features/website/templates/primitives/FormField.ejs

   Inclut aussi .form-row (utilisé par ContactBlock pour mettre 2 fields
   côte à côte) — vient de css/sections.css :810-818.
   ======================================================================= */

.form-group {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}

.form-label {
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--color-ink-2);
}

.form-input,
.form-textarea,
.form-select {
  width: 100%;
  padding: 0.875rem 1rem;
  font-size: var(--fs-base);
  font-family: var(--font-body);
  color: var(--color-ink);
  background: #fff;
  border: 1px solid var(--color-line);
  border-radius: var(--radius-md);
  transition:
    border-color var(--t-fast) var(--ease-out),
    box-shadow var(--t-fast) var(--ease-out);
}

.form-input:focus,
.form-textarea:focus,
.form-select:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 15%, transparent);
}

.form-textarea {
  min-height: 140px;
  resize: vertical;
}

.form-input::placeholder,
.form-textarea::placeholder {
  color: var(--color-muted-2);
}

/* Helper : 2-column grid for fields placed side-by-side */
.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-5);
}

@media (max-width: 639px) {
  .form-row { grid-template-columns: 1fr; }
}

/* Form feedback (success/error toasts inside contact form) */
.form-feedback {
  padding: var(--s-4);
  border-radius: var(--radius-md);
  font-size: var(--fs-sm);
  line-height: 1.5;
  display: flex;
  align-items: center;
  gap: var(--s-3);
}

.form-feedback--success {
  background: color-mix(in srgb, var(--color-accent) 10%, white);
  color: color-mix(in srgb, var(--color-accent) 60%, black);
}

.form-feedback--success svg { color: var(--color-accent); }

.form-feedback--error {
  background: #fef2f2;
  color: #b91c1c;
}

.form-feedback[hidden] { display: none !important; }


/* =======================================================================
   Primitive: Heading
   Source : extrait de templates/css/base.css :203-217
   Lu par : api/src/app/features/website/templates/primitives/Heading.ejs
   ======================================================================= */

h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5 {
  font-family: var(--font-heading);
  font-weight: 400;
  line-height: var(--lh-tight);
  letter-spacing: var(--tracking-tight);
  color: var(--color-ink);
  text-wrap: balance;
}

h1, .h1 { font-size: clamp(2.5rem, 7vw, var(--fs-6xl)); }
h2, .h2 { font-size: clamp(2rem, 5vw, var(--fs-4xl)); }
h3, .h3 { font-size: clamp(1.5rem, 3.2vw, var(--fs-3xl)); }
h4, .h4 { font-size: clamp(1.25rem, 2.4vw, var(--fs-2xl)); line-height: var(--lh-snug); }
h5, .h5 { font-size: var(--fs-xl); line-height: var(--lh-snug); }

/* Paragraphs (de-facto headings sibling — kept here as basic typography) */
p {
  text-wrap: pretty;
  max-width: var(--container-text);
}


/* =======================================================================
   Primitive: ImageWithLabel
   Source : extrait/factorisé de templates/css/sections.css :91-116
   (.hero__image-wrap, .hero__image-wrap img, .hero__image-label)
   Lu par : api/src/app/features/website/templates/primitives/ImageWithLabel.ejs

   Pattern : image avec un badge flottant (en bas à gauche par défaut).
   Réutilisable hors hero (showcases, etc.) — d'où la classe générique.
   ======================================================================= */

.image-with-label {
  position: relative;
  width: 100%;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-xl);
}

.image-with-label img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.05);
}

.image-with-label__badge {
  position: absolute;
  left: var(--s-6);
  bottom: var(--s-6);
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(8px);
  padding: var(--s-3) var(--s-4);
  border-radius: var(--radius-pill);
  z-index: 2;
}

.image-with-label__badge-line {
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--color-primary);
}

.image-with-label__badge-sub {
  font-size: var(--fs-xs);
  font-weight: 400;
  color: var(--color-muted);
}


/* =======================================================================
   Primitive: Lead
   Source : extrait de templates/css/base.css :224-228
   Lu par : api/src/app/features/website/templates/primitives/Lead.ejs
   ======================================================================= */

.lead {
  font-size: clamp(var(--fs-lg), 1.6vw, var(--fs-xl));
  color: var(--color-muted);
  line-height: var(--lh-relaxed);
}


/* =======================================================================
   Primitive: MapEmbed
   Lu par : primitives/MapEmbed.ejs
   ======================================================================= */

.map-embed {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 10;
  border-radius: var(--radius-lg, 12px);
  overflow: hidden;
  background: var(--color-surface-2, #f4f4f4);
  box-shadow: var(--shadow-sm, 0 1px 2px rgba(0, 0, 0, 0.04));
}

.map-embed__frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

.map-embed__fallback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-body);
  font-size: var(--fs-base, 1rem);
  color: var(--color-primary, #1a1a1a);
  text-decoration: underline;
  text-underline-offset: 4px;
}

.map-embed__fallback:hover {
  opacity: 0.75;
}

/* Slightly taller on narrow screens so the map keeps its readability. */
@media (max-width: 640px) {
  .map-embed {
    aspect-ratio: 4 / 3;
  }
}


/* =======================================================================
   Primitive: ProcessStep
   Source : extrait de templates/css/sections.css :879-911
   Lu par : api/src/app/features/website/templates/primitives/ProcessStep.ejs
   ======================================================================= */

.process-step {
  position: relative;
  padding: var(--s-6, 1.5rem) var(--s-5, 1.25rem);
  background: var(--color-surface, #ffffff);
  border: 1px solid rgba(15, 23, 42, 0.08);
  border-radius: var(--radius-md, 12px);
}

.process-step__number {
  display: inline-block;
  font-family: var(--font-heading);
  font-size: var(--fs-lg, 1.25rem);
  font-weight: 600;
  color: var(--color-accent);
  letter-spacing: 0.06em;
  margin-bottom: var(--s-3, 0.75rem);
}

.process-step__title {
  font-family: var(--font-heading);
  font-size: var(--fs-lg, 1.25rem);
  font-weight: 600;
  color: var(--color-ink);
  margin-bottom: var(--s-2, 0.5rem);
  line-height: 1.3;
}

.process-step__text {
  font-size: var(--fs-sm, 0.95rem);
  line-height: 1.6;
  color: var(--color-ink-soft, #475569);
  margin: 0;
}


/* =======================================================================
   Primitive: QuoteBlock (testimonial)
   Source : extrait de templates/css/sections.css :530-584
   Lu par : api/src/app/features/website/templates/primitives/QuoteBlock.ejs
   ======================================================================= */

.testimonial {
  max-width: var(--container-text);
  margin-inline: auto;
  text-align: center;
  padding: var(--s-8);
}

.testimonial__rating {
  display: inline-flex;
  gap: 2px;
  color: var(--color-secondary);
  margin-bottom: var(--s-6);
}

.testimonial__text {
  font-family: var(--font-heading);
  font-size: clamp(1.25rem, 2.5vw, 1.875rem);
  line-height: 1.4;
  color: var(--color-ink);
  letter-spacing: var(--tracking-tight);
  margin-bottom: var(--s-8);
  text-wrap: balance;
}

.testimonial__text::before,
.testimonial__text::after {
  content: '"';
  color: var(--color-primary);
  font-family: serif;
}

.testimonial__author {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
}

.testimonial__author img {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  object-fit: cover;
}

.testimonial__name {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--color-ink);
}

.testimonial__role {
  font-size: var(--fs-xs);
  color: var(--color-muted);
  letter-spacing: var(--tracking-wide);
}


/* =======================================================================
   Primitive: ServiceAreaChip
   Source : extrait de templates/css/sections-extra.css :552-584
   Lu par : api/src/app/features/website/templates/primitives/ServiceAreaChip.ejs
   ======================================================================= */

.service-areas__chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border: 1px solid var(--color-line, #e2e8f0);
  border-radius: 999px;
  background: var(--color-surface, #fff);
  color: var(--color-text, #0e1422);
  text-decoration: none;
  font-size: 0.875rem;
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.15s ease;
}

.service-areas__chip:hover {
  border-color: var(--color-primary);
  background: var(--color-primary-soft, rgba(91, 124, 250, 0.06));
  transform: translateY(-1px);
}

.service-areas__chip svg {
  flex-shrink: 0;
  color: var(--color-primary);
}

.service-areas__city {
  font-weight: 500;
}

.service-areas__zip {
  color: var(--color-text-soft, #94a3b8);
  font-size: 0.75rem;
}


/* =======================================================================
   Primitive: ServiceCard
   Source : extrait de templates/css/sections.css :237-288
   Lu par : api/src/app/features/website/templates/primitives/ServiceCard.ejs
   ======================================================================= */

.service-card {
  padding: var(--s-10) var(--s-8);
  border-right: 1px solid var(--color-line);
  border-bottom: 1px solid var(--color-line);
  transition: background var(--t-base) var(--ease-out);
  position: relative;
}

.service-card:hover {
  background: var(--color-bg-alt);
}

.service-card__icon {
  color: var(--color-primary);
  margin-bottom: var(--s-6);
  transition: transform var(--t-base) var(--ease-out);
}

.service-card:hover .service-card__icon {
  transform: translateY(-4px);
}

.service-card__title {
  font-family: var(--font-heading);
  font-size: var(--fs-2xl);
  line-height: 1.15;
  letter-spacing: var(--tracking-tight);
  margin-bottom: var(--s-3);
}

.service-card__text {
  font-size: var(--fs-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-muted);
  margin-bottom: var(--s-5);
  max-width: none;
}

.service-card__link {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--color-primary);
}

.service-card__link:hover span {
  transform: translateX(3px);
  transition: transform var(--t-fast);
  display: inline-block;
}


/* =======================================================================
   Primitive: ShowcaseCard
   Source : extrait de templates/css/sections.css :352-505
   Lu par : api/src/app/features/website/templates/primitives/ShowcaseCard.ejs
   ======================================================================= */

.showcase-card {
  transition: transform var(--t-base) var(--ease-out);
}

.showcase-card:hover {
  transform: translateY(-4px);
}

.showcase-card--featured {
  grid-column: span 2;
}

@media (max-width: 1023px) {
  .showcase-card--featured { grid-column: span 2; }
}

@media (max-width: 639px) {
  .showcase-card--featured { grid-column: auto; }
}

.showcase-card__link {
  display: block;
}

.showcase-card__media {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-bg-alt);
  margin-bottom: var(--s-5);
}

.showcase-card--featured .showcase-card__media {
  aspect-ratio: 16 / 10;
}

.showcase-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--t-slower) var(--ease-out);
}

.showcase-card:hover .showcase-card__media img {
  transform: scale(1.03);
}

.showcase-card__media-before {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.32s ease;
  pointer-events: none;
}

.showcase-card__media.has-before-after:hover .showcase-card__media-before {
  opacity: 1;
}

.showcase-card__before-tag {
  position: absolute;
  bottom: var(--s-3);
  right: var(--s-3);
  display: inline-flex;
  align-items: center;
  padding: 3px 9px;
  background: rgba(15, 23, 42, 0.78);
  color: #ffffff;
  font-size: var(--fs-xs);
  font-weight: 600;
  border-radius: var(--radius-pill);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  opacity: 0;
  transition: opacity 0.2s ease;
}

.showcase-card__media.has-before-after:hover .showcase-card__before-tag {
  opacity: 1;
}

.showcase-card__review {
  margin: var(--s-3) 0 0;
  padding: var(--s-3) 0 0;
  border-top: 1px solid rgba(15, 23, 42, 0.08);
  font-size: var(--fs-sm);
  line-height: 1.5;
  color: var(--color-ink-soft, #475569);
  font-style: italic;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.showcase-card__stars {
  font-style: normal;
  letter-spacing: 1px;
  color: #f59e0b;
  font-size: var(--fs-xs);
}

.showcase-card__review-text {
  display: block;
}

.showcase-card__review-author {
  font-style: normal;
  font-size: var(--fs-xs);
  color: var(--color-ink-muted, #64748b);
}

.showcase-card__badge {
  position: absolute;
  top: var(--s-4);
  left: var(--s-4);
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-2) var(--s-4);
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(8px);
  border-radius: var(--radius-pill);
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--color-primary);
  letter-spacing: var(--tracking-tight);
}

.showcase-card__badge svg {
  color: var(--color-accent);
}

.showcase-card__title {
  font-family: var(--font-heading);
  font-size: var(--fs-xl);
  line-height: 1.25;
  letter-spacing: var(--tracking-tight);
  margin-bottom: var(--s-2);
  color: var(--color-ink);
}

.showcase-card__meta {
  font-size: var(--fs-sm);
  color: var(--color-muted);
  display: flex;
  gap: var(--s-1);
}


/* =======================================================================
   Primitive: StatCounter
   Source : extrait/factorisé de templates/css/sections.css :69-84 (.hero__meta-value/label)
   et :188-203 (.trust-bar__stat-value/label) — patterns identiques.
   Lu par : api/src/app/features/website/templates/primitives/StatCounter.ejs
   ======================================================================= */

.stat-counter {
  display: block;
}

.stat-counter__value {
  display: block;
  font-family: var(--font-heading);
  font-size: clamp(1.75rem, 3vw, 2.5rem);
  line-height: 1;
  letter-spacing: var(--tracking-tight);
  color: var(--color-ink);
  margin-bottom: var(--s-2);
}

.stat-counter__label {
  display: block;
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--color-muted);
}


/* =======================================================================
   Primitive: TeamMemberCard
   Source : extrait de templates/css/sections-extra.css :89-146
   Lu par : api/src/app/features/website/templates/primitives/TeamMemberCard.ejs
   ======================================================================= */

.team-member__photo {
  position: relative;
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-md);
  overflow: hidden;
  margin-bottom: var(--s-5);
  background: var(--color-bg-alt);
}

.team-member__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--t-slow) var(--ease-out);
  filter: grayscale(0.2);
}

.team-member:hover .team-member__photo img {
  transform: scale(1.04);
  filter: grayscale(0);
}

.team-member__placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-heading);
  font-size: var(--fs-6xl);
  color: var(--color-primary);
  background: var(--color-primary-soft);
}

.team-member__name {
  font-family: var(--font-heading);
  font-size: var(--fs-xl);
  line-height: 1.2;
  letter-spacing: var(--tracking-tight);
  color: var(--color-ink);
  margin-bottom: var(--s-1);
}

.team-member__role {
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--color-primary);
  margin-bottom: var(--s-3);
}

.team-member__bio {
  font-size: var(--fs-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-muted);
  max-width: none;
}


/* =======================================================================
   Primitive: TimelineEntry
   Source : extrait de templates/css/sections-extra.css :330-351
   Lu par : api/src/app/features/website/templates/primitives/TimelineEntry.ejs

   Note : la classe `.about-story__year/event` est conservée pour ne pas
   dupliquer du CSS pendant la migration. Le wrapping <ol> reste dans
   l'organism AboutStory (cf .about-story__timeline + ol).
   ======================================================================= */

.about-story__year {
  font-family: var(--font-heading);
  font-size: var(--fs-3xl);
  line-height: 1;
  letter-spacing: var(--tracking-tight);
  color: var(--color-primary);
}

.about-story__event {
  font-size: var(--fs-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-ink-2);
  max-width: 240px;
}


/* === styles/organisms === */

/* =======================================================================
   Organism: AboutStory — variant 'alternating'
   Source : extrait de templates/css/sections-extra.css :234-321
   Lu par : api/src/app/features/website/templates/organisms/AboutStory/AboutStory.alternating.ejs

   Note : la primitive TimelineEntry style l'item individuel de timeline.
   Ce fichier style les wrappers de section (header, hero-image, blocks,
   timeline title + ol).
   ======================================================================= */

.about-story__header {
  max-width: var(--container-narrow);
  margin-bottom: clamp(3rem, 6vw, 5rem);
}

.about-story__header .eyebrow { margin-bottom: var(--s-5); }
.about-story__title { margin-bottom: var(--s-5); }
.about-story__subtitle { max-width: var(--container-narrow); }

.about-story__hero-image {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-lg);
  overflow: hidden;
  margin-bottom: clamp(3rem, 6vw, 5rem);
  box-shadow: var(--shadow-lg);
}

.about-story__hero-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.about-story__blocks {
  display: flex;
  flex-direction: column;
  gap: clamp(3rem, 8vw, 6rem);
}

.about-story__block {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}

.about-story__block--rtl .about-story__block-image { order: 2; }

@media (max-width: 767px) {
  .about-story__block { grid-template-columns: 1fr; }
  .about-story__block--rtl .about-story__block-image { order: 0; }
}

.about-story__block-image {
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-bg-alt);
}

.about-story__block-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.about-story__block-title {
  font-family: var(--font-heading);
  font-size: clamp(1.75rem, 3.5vw, var(--fs-3xl));
  line-height: 1.15;
  letter-spacing: var(--tracking-tight);
  margin-bottom: var(--s-5);
}

.about-story__block-body p {
  font-size: var(--fs-lg);
  line-height: var(--lh-relaxed);
  color: var(--color-ink-2);
}

/* Timeline wrappers (TimelineEntry primitive styles the individual items) */
.about-story__timeline {
  margin-top: clamp(4rem, 8vw, 6rem);
  padding-top: clamp(3rem, 6vw, 5rem);
  border-top: 1px solid var(--color-line);
}

.about-story__timeline-title {
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--color-muted);
  margin-bottom: var(--s-8);
}

.about-story__timeline ol {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--s-8);
  padding: 0;
}

.about-story__timeline li {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  padding-left: var(--s-5);
  border-left: 1px solid var(--color-line);
}


/* =======================================================================
   Organism: AidesInfo — variant 'cards'
   Source : extrait de templates/css/sections-extra.css :356-452 (.aides-info__*)
   Lu par : api/src/app/features/website/templates/organisms/AidesInfo/AidesInfo.cards.ejs

   Note : la primitive AidCard style l'item individuel. Ce fichier ne style
   que les wrappers de section (.aides-info__header, __list, __note).
   ======================================================================= */

.aides-info__header {
  margin-bottom: clamp(3rem, 6vw, 5rem);
  text-align: left;
}

.aides-info__header .eyebrow { margin-bottom: var(--s-5); }
.aides-info__title { margin-bottom: var(--s-5); }

.aides-info__list {
  display: flex;
  flex-direction: column;
  gap: var(--s-6);
}

.aides-info__note {
  margin-top: clamp(3rem, 5vw, 4rem);
  padding: var(--s-6);
  background: var(--color-bg-alt);
  border-left: 3px solid var(--color-primary);
  border-radius: var(--radius-md);
  font-size: var(--fs-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-muted);
}


/* =======================================================================
   Organism: CTASection — variant 'dark'
   Source : extrait de templates/css/sections.css :660-735
   Lu par : api/src/app/features/website/templates/organisms/CTASection/CTASection.dark.ejs

   Note : ce fichier contient AUSSI les variants 'primary' et 'bordered' de
   CTASection (cf .cta-final--primary, .cta-final--bordered) — ils seront
   séparés dans CTASection.primary.css / CTASection.bordered.css quand on
   les écrira. Pour l'instant le CSS reste groupé pour ne pas perdre la
   parité visuelle des sites legacy qui choisissent un autre variant via
   l'ancien field c.variant.

   Migration : quand le legacy aura entièrement basculé sur la nouvelle
   archi (fin de Vague 3), la portion .cta-final dans css/sections.css
   pourra être retirée.
   ======================================================================= */

.cta-final {
  position: relative;
  padding-block: clamp(5rem, 12vw, 9rem);
  overflow: hidden;
}

.cta-final--dark {
  background: var(--color-bg-dark);
  color: #fff;
}

.cta-final--primary {
  background: var(--color-primary);
  color: #fff;
}

.cta-final--bordered {
  background: #fff;
  border-top: 1px solid var(--color-line);
  border-bottom: 1px solid var(--color-line);
}

.cta-final__content {
  text-align: center;
  max-width: var(--container-narrow);
  margin-inline: auto;
}

.cta-final .eyebrow {
  justify-content: center;
  margin-bottom: var(--s-5);
}

.cta-final__title {
  color: inherit;
  margin-bottom: var(--s-6);
  text-wrap: balance;
}

.cta-final--dark .cta-final__title,
.cta-final--primary .cta-final__title {
  color: #fff;
}

.cta-final__subtitle {
  margin-bottom: var(--s-10);
  margin-inline: auto;
}

.cta-final--dark .cta-final__subtitle,
.cta-final--primary .cta-final__subtitle {
  color: rgba(255, 255, 255, 0.8);
}

.cta-final__actions {
  display: inline-flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--s-5);
}

.cta-final__phone {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--fs-base);
  font-weight: 500;
  color: inherit;
  opacity: 0.9;
}

.cta-final__phone:hover { opacity: 1; }


/* =======================================================================
   Organism: ContactBlock — variant 'split'
   Source : extrait de templates/css/sections.css :740-825 (.contact-block__*)
   Lu par : api/src/app/features/website/templates/organisms/ContactBlock/ContactBlock.split.ejs

   Note : la primitive FormField a son propre CSS (.form-group, .form-label,
   .form-input, .form-textarea, .form-select, .form-row, .form-feedback).
   Ce fichier ne style que les wrappers de section (.contact-block__*).
   ======================================================================= */

.contact-block__grid {
  display: grid;
  grid-template-columns: 0.9fr 1.1fr;
  gap: clamp(3rem, 6vw, 5rem);
  align-items: start;
}

@media (max-width: 1023px) {
  .contact-block__grid { grid-template-columns: 1fr; }
}

.contact-block__intro .eyebrow {
  margin-bottom: var(--s-5);
}

.contact-block__title {
  margin-bottom: var(--s-5);
}

.contact-block__details {
  display: flex;
  flex-direction: column;
  gap: var(--s-6);
  margin-top: var(--s-10);
  padding-top: var(--s-10);
  border-top: 1px solid var(--color-line);
}

.contact-block__detail {
  display: flex;
  align-items: flex-start;
  gap: var(--s-4);
  color: var(--color-ink);
  transition: transform var(--t-fast) var(--ease-out);
}

a.contact-block__detail:hover {
  transform: translateX(4px);
}

.contact-block__detail svg {
  color: var(--color-primary);
  margin-top: 2px;
  flex-shrink: 0;
}

.contact-block__detail-label {
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--color-muted);
  margin-bottom: 2px;
}

.contact-block__detail-value {
  font-size: var(--fs-base);
  line-height: 1.5;
  color: var(--color-ink);
}

.contact-block__form {
  background: var(--color-bg-alt);
  padding: clamp(2rem, 4vw, 3rem);
  border-radius: var(--radius-lg);
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
}

/* Mention sous le bouton submit (canoniquement câblé via c.responsePromise) */
.contact-block__response-promise {
  margin-top: var(--s-3);
  font-size: var(--fs-sm);
  color: var(--color-muted);
  text-align: center;
}

.contact-block__legal {
  font-size: var(--fs-xs);
  color: var(--color-muted);
  line-height: 1.6;
  margin-top: var(--s-2);
}


/* =======================================================================
   Organism: Faq — variant 'accordion'
   Source : extrait de templates/css/sections-extra.css :151-169
   Lu par : api/src/app/features/website/templates/organisms/Faq/Faq.accordion.ejs

   Note : la primitive AccordionItem style l'item individuel. Ce fichier ne
   style que les wrappers de section (.faq__grid, __intro, __title).
   ======================================================================= */

.faq__grid {
  display: grid;
  grid-template-columns: 0.9fr 1.1fr;
  gap: clamp(3rem, 6vw, 5rem);
  align-items: start;
}

@media (max-width: 1023px) { .faq__grid { grid-template-columns: 1fr; } }

.faq__intro {
  position: sticky;
  top: calc(var(--header-h) + 2rem);
}

.faq__intro .eyebrow { margin-bottom: var(--s-5); }
.faq__intro .btn { margin-top: var(--s-6); }
.faq__title { margin-bottom: var(--s-5); }

@media (max-width: 1023px) { .faq__intro { position: static; } }


/* =======================================================================
   Organism: Gallery — variant 'grid'
   Lu par : organisms/Gallery/Gallery.grid.ejs
   ======================================================================= */

.gallery {
  padding-block: clamp(3rem, 6vw, 5rem);
}

.gallery__header {
  max-width: var(--container-narrow, 760px);
  margin: 0 auto clamp(2rem, 4vw, 3rem);
  text-align: center;
}

.gallery__header .eyebrow {
  justify-content: center;
  margin-bottom: var(--s-5, 1.25rem);
}

.gallery__title {
  margin-bottom: var(--s-3, 0.75rem);
}

.gallery__subtitle {
  color: var(--color-muted, #666);
  margin-top: var(--s-3, 0.75rem);
}

.gallery__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: clamp(0.75rem, 2vw, 1.25rem);
  align-items: stretch;
}

/* When only 1 image is provided, span it full-width for impact instead
   of leaving a lone card in a 4-col grid. */
.gallery__grid:has(> .gallery__item:only-child) {
  grid-template-columns: 1fr;
}

.gallery__grid:has(> .gallery__item:only-child) .gallery__item {
  max-width: 920px;
  margin: 0 auto;
}

.gallery__item {
  position: relative;
  margin: 0;
  background: var(--color-surface-2, #f4f4f4);
  border-radius: var(--radius-lg, 12px);
  overflow: hidden;
  aspect-ratio: 4 / 3;
}

.gallery__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.4s ease;
}

.gallery__item:hover img {
  transform: scale(1.03);
}

.gallery__caption {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 0.75rem 1rem;
  font-family: var(--font-body);
  font-size: var(--fs-sm, 0.875rem);
  color: #ffffff;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.6) 100%);
}

@media (max-width: 600px) {
  .gallery__grid {
    grid-template-columns: 1fr 1fr;
  }
}


/* =======================================================================
   Organism: Hero — variant 'split'
   Source : extrait de templates/css/sections.css :9-116
   Lu par : api/src/app/features/website/templates/organisms/Hero/Hero.split.ejs

   Note : les classes locales .hero__meta-value et .hero__meta-label sont
   conservées telles quelles (le markup conserve les classes existantes,
   plutôt que d'utiliser la primitive StatCounter avec ses classes
   .stat-counter*). Raison : conserver la parité visuelle byte-byte avec
   le legacy en V1, sans renommer les classes pendant la migration.
   À factoriser en V2 si on standardise.
   ======================================================================= */

.hero {
  position: relative;
  padding-top: clamp(6rem, 14vw, 9rem);
  padding-bottom: clamp(4rem, 10vw, 8rem);
  overflow: hidden;
}

.hero__container {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(3rem, 8vw, 5rem);
  align-items: center;
}

.hero--split .hero__container {
  grid-template-columns: 1.1fr 0.9fr;
}

@media (max-width: 1023px) {
  .hero--split .hero__container {
    grid-template-columns: 1fr;
  }
}

.hero__text {
  position: relative;
  z-index: 2;
}

.hero .eyebrow {
  margin-bottom: var(--s-6);
}

.hero__title {
  margin-bottom: var(--s-6);
  text-wrap: balance;
}

.hero__subtitle {
  margin-bottom: var(--s-10);
  max-width: 520px;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-4);
  margin-bottom: var(--s-12);
}

.hero__meta {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: var(--s-8);
  padding-top: var(--s-8);
  border-top: 1px solid var(--color-line);
  max-width: 560px;
}

.hero__meta-value {
  display: block;
  font-family: var(--font-heading);
  font-size: clamp(1.75rem, 3vw, 2.5rem);
  line-height: 1;
  letter-spacing: var(--tracking-tight);
  margin-bottom: var(--s-2);
}

.hero__meta-label {
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--color-muted);
}

.hero__visual {
  position: relative;
  align-self: stretch;
}

.hero__image-wrap {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-xl);
}

.hero__image-wrap img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.05);
}

.hero__image-label {
  position: absolute;
  left: var(--s-6);
  bottom: var(--s-6);
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(8px);
  padding: var(--s-3) var(--s-4);
  border-radius: var(--radius-pill);
  z-index: 2;
}


/* =======================================================================
   Organism: LegalContent — variant 'default'
   Source : extrait de templates/css/sections-extra.css :455-510
   Lu par : api/src/app/features/website/templates/organisms/LegalContent/LegalContent.default.ejs
   ======================================================================= */

.legal-page {
  padding-top: clamp(6rem, 14vw, 9rem);
  padding-bottom: clamp(3rem, 8vw, 6rem);
}

/* L'EJS émet `<div class="container container-text">`. Sur signature,
   chantier, patrimoine et prisme, base.css définit `.container` et
   `.container-text` (qui contraignent à 680px). Mais maison et atelier
   ne chargent PAS base.css (leur layout l'a retiré au profit d'un CSS
    préfixé .m-* / .a-*). Sans cette règle, l'article SEO d'une city
   page rendu sur maison/atelier prend toute la largeur de la fenêtre
   sans padding latéral. La règle canonique ci-dessous garantit la
   contrainte sur les 6 themes (specificity .legal-page .container =
   0,2,0 > .container = 0,1,0, donc on gagne aussi sur les themes
   qui chargent base.css). */
.legal-page .container {
  width: 100%;
  max-width: var(--container-text, 680px);
  margin-inline: auto;
  padding-inline: clamp(1rem, 4vw, 2rem);
}

.legal-page__title {
  font-size: clamp(2rem, 5vw, var(--fs-4xl));
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
  padding-bottom: var(--s-8);
  border-bottom: 1px solid var(--color-line);
}

.legal-page__content {
  font-size: var(--fs-base);
  line-height: var(--lh-relaxed);
  color: var(--color-ink-2);
}

.legal-page__content h2 {
  font-size: clamp(1.25rem, 2.5vw, 1.5rem);
  margin-top: var(--s-10);
  margin-bottom: var(--s-4);
  color: var(--color-ink);
}

.legal-page__content h3 {
  font-size: var(--fs-lg);
  margin-top: var(--s-6);
  margin-bottom: var(--s-3);
}

.legal-page__content p,
.legal-page__content ul,
.legal-page__content ol {
  margin-bottom: var(--s-4);
  max-width: none;
}

.legal-page__content ul,
.legal-page__content ol {
  padding-left: var(--s-6);
  list-style: disc;
}

.legal-page__content ol { list-style: decimal; }

.legal-page__content li {
  margin-bottom: var(--s-2);
}

.legal-page__content a {
  color: var(--color-primary);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Images intercalées dans l'article (insérées via le WYSIWYG `RichTextEditor`).
   On les rend block-level, centrées et responsives. La classe `.rte-img` est
   posée par l'extension TipTap, mais on style aussi `img` brut au cas où le
   user paste un `<img>` à la main. */
.legal-page__content img,
.legal-page__content img.rte-img {
  display: block;
  max-width: 100%;
  height: auto;
  margin-block: var(--s-6);
  margin-inline: auto;
  border-radius: 8px;
}


/* =======================================================================
   Organism: Location — variant 'embed-only'
   Lu par : organisms/Location/Location.embed-only.ejs
   ======================================================================= */

.location--embed-only {
  padding: clamp(3rem, 6vw, 5rem) 0;
}

.location__head {
  text-align: center;
  max-width: 640px;
  margin: 0 auto clamp(2rem, 4vw, 3rem);
}

.location__title {
  margin-top: var(--s-3, 0.75rem);
  margin-bottom: var(--s-3, 0.75rem);
}

.location__subtitle {
  color: var(--color-muted, #666);
  margin-top: var(--s-3, 0.75rem);
}

.location--embed-only .location__map {
  max-width: 1100px;
  margin: 0 auto;
}


/* =======================================================================
   Organism: Location — variant 'featured'
   Lu par : organisms/Location/Location.featured.ejs
   ======================================================================= */

.location--featured {
  padding: clamp(3rem, 6vw, 5rem) 0;
}

.location--featured .location__head {
  text-align: center;
  max-width: 760px;
  margin: 0 auto clamp(2rem, 4vw, 3rem);
}

.location__title--featured {
  margin-top: var(--s-3, 0.75rem);
  margin-bottom: var(--s-3, 0.75rem);
}

.location__address-line {
  font-family: var(--font-body);
  font-size: var(--fs-sm, 0.875rem);
  color: var(--color-muted, #666);
  letter-spacing: var(--tracking-wide, 0.02em);
  margin-top: var(--s-3, 0.75rem);
}

.location__map--featured {
  max-width: 1280px;
  margin: 0 auto;
}

.location__map--featured .map-embed {
  aspect-ratio: 21 / 9;
}

@media (max-width: 800px) {
  .location__map--featured .map-embed {
    aspect-ratio: 4 / 3;
  }
}


/* =======================================================================
   Organism: Location — variant 'split'
   Lu par : organisms/Location/Location.split.ejs
   ======================================================================= */

.location--split {
  padding: clamp(3rem, 6vw, 5rem) 0;
}

.location--split .location__head {
  text-align: left;
  max-width: 720px;
  margin-bottom: clamp(2rem, 4vw, 3rem);
}

.location--split .location__title {
  margin-top: var(--s-2, 0.5rem);
}

.location__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(260px, 1fr);
  gap: clamp(1.5rem, 3vw, 2.5rem);
  align-items: stretch;
}

@media (max-width: 800px) {
  .location__grid {
    grid-template-columns: 1fr;
  }
}

.location__info {
  display: flex;
  flex-direction: column;
  gap: var(--s-5, 1.25rem);
  padding: clamp(1.5rem, 3vw, 2rem);
  background: var(--color-surface-2, #f7f7f5);
  border-radius: var(--radius-lg, 12px);
}

.location__info-row {
  display: flex;
  flex-direction: column;
  gap: var(--s-1, 0.25rem);
}

.location__info-label {
  font-family: var(--font-body);
  font-size: var(--fs-xs, 0.75rem);
  font-weight: 600;
  letter-spacing: var(--tracking-wider, 0.06em);
  text-transform: uppercase;
  color: var(--color-muted, #666);
}

.location__info-value {
  font-family: var(--font-body);
  font-size: var(--fs-base, 1rem);
  color: var(--color-text, #1a1a1a);
  font-style: normal;
  line-height: 1.5;
  text-decoration: none;
}

a.location__info-value:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.location__directions {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2, 0.5rem);
  padding: var(--s-3, 0.75rem) var(--s-5, 1.25rem);
  margin-top: var(--s-2, 0.5rem);
  align-self: flex-start;
  background: var(--color-primary, #1a1a1a);
  color: var(--color-on-primary, #fff);
  text-decoration: none;
  font-family: var(--font-body);
  font-size: var(--fs-sm, 0.875rem);
  font-weight: 500;
  border-radius: var(--radius-md, 8px);
  transition: opacity var(--t-base, 0.2s) var(--ease-out, ease-out);
}

.location__directions:hover {
  opacity: 0.85;
}


/* =======================================================================
   Organism: Manifesto — variant 'quote'
   Source : extrait de templates/css/sections.css :290-317 (.manifesto + variants)
   Lu par : api/src/app/features/website/templates/organisms/Manifesto/Manifesto.quote.ejs
   ======================================================================= */

.manifesto {
  text-align: center;
}

.manifesto .eyebrow {
  justify-content: center;
  margin-bottom: var(--s-8);
}

.manifesto__quote {
  font-family: var(--font-heading);
  font-size: clamp(1.75rem, 4vw, var(--fs-4xl));
  line-height: 1.25;
  letter-spacing: var(--tracking-tight);
  color: var(--color-ink);
  text-wrap: balance;
  font-style: italic;
}

.manifesto__signature {
  margin-top: var(--s-8);
  font-size: var(--fs-sm);
  letter-spacing: var(--tracking-wide);
  color: var(--color-muted);
}


/* =======================================================================
   Organism: Process — variant 'steps'
   Source : extrait de templates/css/sections.css :855-877 (.process__*)
   Lu par : api/src/app/features/website/templates/organisms/Process/Process.steps.ejs

   Note : la primitive ProcessStep style l'item individuel. Ce fichier ne
   style que les wrappers de section (.process__header, .process__steps).
   ======================================================================= */

.process__header {
  text-align: center;
  max-width: 720px;
  margin: 0 auto var(--s-10, 4rem);
}

.process__title {
  font-family: var(--font-heading);
  font-size: clamp(1.75rem, 3.5vw, 2.5rem);
  line-height: 1.2;
  margin-bottom: var(--s-4, 1rem);
  color: var(--color-ink);
}

.process__steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--s-6, 1.5rem);
  list-style: none;
  padding: 0;
  margin: 0;
  counter-reset: process-step;
}


/* =======================================================================
   Organism: ServiceAreas — variant 'chips'
   Source : extrait de templates/css/sections-extra.css :515-550
   Lu par : api/src/app/features/website/templates/organisms/ServiceAreas/ServiceAreas.chips.ejs

   Note : la primitive ServiceAreaChip a son propre CSS qui style l'item
   individuel. Ce fichier ne style que le wrapper de section.
   ======================================================================= */

.service-areas {
  padding: clamp(3rem, 6vw, 5rem) 0;
}

.service-areas__head {
  max-width: 720px;
  margin: 0 auto clamp(1.5rem, 3vw, 2.5rem);
  text-align: center;
}

.service-areas__head .eyebrow {
  display: inline-block;
  margin-bottom: var(--s-3);
}

.service-areas__title {
  font-family: var(--font-heading);
  font-size: clamp(1.6rem, 3.5vw, 2.4rem);
  line-height: 1.15;
  margin: 0 0 var(--s-3);
}

.service-areas__subtitle {
  color: var(--color-text-soft, #64748b);
  margin: 0;
}

.service-areas__grid {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  justify-content: center;
}


/* =======================================================================
   Organism: ServicesGrid — variant 'cards'
   Source : extrait de templates/css/sections.css :208-235 (.services__*)
   Lu par : api/src/app/features/website/templates/organisms/ServicesGrid/ServicesGrid.cards.ejs

   Note : .service-card item style est dans la primitive ServiceCard.
   Ce fichier ne style que le wrapper de section (.services__header, __grid).
   ======================================================================= */

.services__header {
  max-width: var(--container-narrow);
  margin-bottom: clamp(3rem, 6vw, 5rem);
}

.services__header .eyebrow {
  margin-bottom: var(--s-6);
}

.services__title {
  margin-bottom: var(--s-5);
}

.services__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0;
  border-top: 1px solid var(--color-line);
  border-left: 1px solid var(--color-line);
}

@media (max-width: 1023px) {
  .services__grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 639px) {
  .services__grid { grid-template-columns: 1fr; }
}


/* =======================================================================
   Organism: ShowcaseGallery — variant 'filterable'
   Source : extrait de templates/css/sections-extra.css :9-68
   Lu par : api/src/app/features/website/templates/organisms/ShowcaseGallery/ShowcaseGallery.filterable.ejs

   Note : la primitive ShowcaseCard style l'item individuel. Ce fichier ne
   style que les wrappers de section + les filter chips.
   ======================================================================= */

.showcase-gallery__header {
  max-width: var(--container-narrow);
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
}

.showcase-gallery__header .eyebrow {
  margin-bottom: var(--s-5);
}

.showcase-gallery__title {
  margin-bottom: var(--s-5);
}

.showcase-gallery__filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
  padding-bottom: var(--s-6);
  border-bottom: 1px solid var(--color-line);
}

.showcase-filter {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: 0.625rem 1.125rem;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--color-muted);
  background: transparent;
  border: 1px solid var(--color-line);
  border-radius: var(--radius-pill);
  transition: all var(--t-fast) var(--ease-out);
}

.showcase-filter:hover {
  color: var(--color-ink);
  border-color: var(--color-ink-2);
}

.showcase-filter.is-active {
  color: #fff;
  background: var(--color-ink);
  border-color: var(--color-ink);
}

.showcase-filter__count {
  font-size: var(--fs-xs);
  opacity: 0.6;
}

.showcase-gallery__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-8);
}

@media (max-width: 1023px) { .showcase-gallery__grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 639px) { .showcase-gallery__grid { grid-template-columns: 1fr; } }


/* =======================================================================
   Organism: Showcases — variant 'grid'
   Source : extrait de templates/css/sections.css :320-350
   Lu par : api/src/app/features/website/templates/organisms/Showcases/Showcases.grid.ejs

   Note : la primitive ShowcaseCard style l'item individuel. Ce fichier ne
   style que les wrappers de section (.showcases__header, __title, __grid).
   ======================================================================= */

.showcases__header {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: var(--s-8);
  margin-bottom: clamp(3rem, 6vw, 4.5rem);
  flex-wrap: wrap;
}

.showcases__header .eyebrow {
  margin-bottom: var(--s-4);
}

.showcases__title {
  margin-bottom: var(--s-4);
}

.showcases__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-6);
}

@media (max-width: 1023px) {
  .showcases__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 639px) {
  .showcases__grid { grid-template-columns: 1fr; }
}


/* =======================================================================
   Organism: Simulator — variant 'embedded'
   Source : extrait de templates/css/sections.css :630-658 (.simulator__*)
   Lu par : api/src/app/features/website/templates/organisms/Simulator/Simulator.embedded.ejs
   ======================================================================= */

.simulator__intro {
  max-width: var(--container-narrow);
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
}

.simulator__intro .eyebrow {
  margin-bottom: var(--s-5);
}

.simulator__title {
  color: #fff;
  margin-bottom: var(--s-5);
}

/* Iframe-mode (alternative non utilisée par variant 'embedded' actuel,
   conservé pour compatibilité avec d'éventuels variants futurs) */
.simulator__frame {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: #fff;
  box-shadow: var(--shadow-xl);
  aspect-ratio: 16 / 10;
  min-height: 600px;
}

.simulator__frame iframe {
  width: 100%;
  height: 100%;
  border: 0;
}


/* =======================================================================
   Organism: TeamGrid — variant 'cards'
   Source : extrait de templates/css/sections-extra.css :73-87
   Lu par : api/src/app/features/website/templates/organisms/TeamGrid/TeamGrid.cards.ejs

   Note : la primitive TeamMemberCard style l'item individuel. Ce fichier
   ne style que les wrappers de section (.team-grid__header, __list).
   ======================================================================= */

.team-grid__header {
  max-width: var(--container-narrow);
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
}

.team-grid__header .eyebrow { margin-bottom: var(--s-5); }

.team-grid__list {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(1.5rem, 3vw, 2.5rem);
}

@media (max-width: 1023px) { .team-grid__list { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 479px) { .team-grid__list { grid-template-columns: 1fr; } }


/* =======================================================================
   Organism: Testimonials — variant 'carousel'
   Source : extrait de templates/css/sections.css :510-625
   Lu par : api/src/app/features/website/templates/organisms/Testimonials/Testimonials.carousel.ejs

   Note : la primitive QuoteBlock style l'item individuel. Ce fichier ne
   style que les wrappers (header, swiper, controls).
   ======================================================================= */

.testimonials__header {
  max-width: var(--container-narrow);
  margin-bottom: clamp(2rem, 4vw, 3rem);
  text-align: center;
  margin-inline: auto;
}

.testimonials__header .eyebrow {
  justify-content: center;
  margin-bottom: var(--s-5);
}

.testimonials__title {
  margin-bottom: var(--s-3);
}

.testimonials__swiper {
  padding-block: var(--s-8);
}

.testimonials__controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-5);
  margin-top: var(--s-6);
}

.testimonials__prev,
.testimonials__next {
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  border: 1px solid var(--color-line);
  border-radius: 50%;
  color: var(--color-ink);
  transition:
    background var(--t-fast) var(--ease-out),
    border-color var(--t-fast) var(--ease-out),
    color var(--t-fast) var(--ease-out);
}

.testimonials__prev:hover,
.testimonials__next:hover {
  background: var(--color-ink);
  border-color: var(--color-ink);
  color: #fff;
}

.testimonials__pagination {
  font-size: var(--fs-sm);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--color-muted);
  min-width: 60px;
  text-align: center;
}


/* =======================================================================
   Organism: Testimonials — variant 'grid'
   Lu par : organisms/Testimonials/Testimonials.grid.ejs

   Note : la primitive QuoteBlock style l'item individuel (.testimonial).
   Ce fichier ne style que les wrappers (header, grid) + quelques règles
   défensives sur le markup interne (blockquote natif, image avatar).
   Les themes chantier / patrimoine / prisme overrident la look des cartes
   via leurs sélecteurs `.template-<theme> .testimonial`.
   ======================================================================= */

/* Header : centré (override les themes chantier/patrimoine/prisme qui
   forcent flex space-between pour le carousel — non pertinent en grid).
   Canonical.css est chargé après <theme>.css, donc ces règles gagnent à
   spécificité égale. */
.testimonials--grid .testimonials__header {
  display: block;
  max-width: var(--container-narrow, 760px);
  margin: 0 auto clamp(2rem, 4vw, 3rem);
  text-align: center;
}

.testimonials--grid .testimonials__header .eyebrow {
  justify-content: center;
  margin-bottom: var(--s-5, 1.25rem);
}

.testimonials--grid .testimonials__title {
  margin-bottom: var(--s-3, 0.75rem);
}

.testimonials--grid .testimonials__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: clamp(1rem, 2.5vw, 1.75rem);
  align-items: stretch;
}

/* The QuoteBlock primitive renders <figure class="testimonial">. Make
   sure each card fills its grid cell so cards line up regardless of
   text length. */
.testimonials--grid .testimonial {
  height: 100%;
}

/* Reset native browser quotes on <blockquote> — by default WebKit / Gecko
   inject empty " glyphs around the content, which look like orphan marks
   on the card. */
.testimonials--grid .testimonial__text {
  quotes: none;
}

.testimonials--grid .testimonial__text::before,
.testimonials--grid .testimonial__text::after {
  content: '';
}

/* Avatar : circular thumbnail, sized small enough to keep the card
   compact. Google profile photos are 128px native — without sizing they
   would blow up the card. */
.testimonials--grid .testimonial__author img {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}

/* Tame the role line — themes that style .testimonial__role with
   uppercase are fine for short labels (e.g. "Client 2024") but get
   shouty with longer ones like "il y a un an". Default to sentence case
   in grid mode; themes can re-override per template if desired. */
.testimonials--grid .testimonial__role {
  text-transform: none;
  letter-spacing: 0;
}


/* =======================================================================
   Organism: TrustBar — variant 'grid'
   Source : extrait de templates/css/sections.css :121-186
   Lu par : api/src/app/features/website/templates/organisms/TrustBar/TrustBar.grid.ejs

   Note : les primitives CertificationBadge et StatCounter ont leurs propres
   CSS qui stylent les items individuels. Ce fichier ne style que les wrappers
   et le layout de section.
   ======================================================================= */

.trust-bar {
  padding-block: var(--s-10) var(--s-16);
  border-bottom: 1px solid var(--color-line);
}

.trust-bar__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-10);
  align-items: center;
}

@media (max-width: 767px) {
  .trust-bar__grid {
    grid-template-columns: 1fr;
  }
}

.trust-bar__certifications .eyebrow {
  margin-bottom: var(--s-4);
}

.trust-bar__certs-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
}

.trust-bar__stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: var(--s-6);
}

.trust-bar__stat {
  border-left: 1px solid var(--color-line);
  padding-left: var(--s-5);
}
