#!/usr/bin/env python3
"""Générateur du site statique Les Techniciens.
Modifiez les textes ici puis lancez : python3 build.py  → le dossier site/ est régénéré."""
import json, os, datetime

OUT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "site")
DOMAINE = "https://www.lestechniciens.fr"
TEL = "05 24 84 78 00"
TEL_LIEN = "+33524847800"
EMAIL = "contact@lestechniciens.fr"   # n'apparaît jamais en clair dans le HTML (voir mail())
DIRECTEUR = "Philippe Giraudel"   # directeur de la publication (masqué comme l'e-mail)
def _code(texte):
    import base64
    return base64.b64encode(texte[::-1].encode()).decode()
def masque(texte, libelle, cls=""):
    # Le texte n'est jamais écrit dans le HTML : il est inversé puis encodé en base64, et n'est
    # reconstitué qu'au clic d'un visiteur sur le bouton (les robots ne cliquent pas).
    return f'<button type="button" class="js-masque lien-bouton{(" " + cls) if cls else ""}" data-m="{_code(texte)}">{libelle}</button>'
def mail(cls=""):
    return masque(EMAIL, "Afficher l'adresse e-mail", ("js-lien-mail " + cls).strip())
CGV_URL = None   # lien vers le PDF des conditions générales des contrats, ex. "assets/cgv-contrats.pdf"
ADRESSE = "19 rue du Président Coty"
CP, VILLE = "33440", "Ambarès-et-Lagrave"   # siège social
FACEBOOK = "https://www.facebook.com/lestechniciensinformatique/"
# ---------- Magasins ----------
def _semaine(matin, aprem, mercredi):
    j = f"{matin} · {aprem}"
    return [("Lundi", j), ("Mardi", j), ("Mercredi", mercredi), ("Jeudi", j), ("Vendredi", j), ("Samedi", "Fermé"), ("Dimanche", "Fermé")]
_JOURS = ["Monday", "Tuesday", "Thursday", "Friday"]
MAGASINS = [
    {"id": "ambares", "ville": "Ambarès-et-Lagrave", "rue": "19 rue du Président Coty", "complement": "", "cp": "33440",
     "maps": "https://www.google.com/maps/search/?api=1&query=Les+Techniciens+19+rue+du+Pr%C3%A9sident+Coty+33440+Ambar%C3%A8s-et-Lagrave",
     "horaires": _semaine("9h30 – 12h00", "13h30 – 18h30", "13h30 – 18h30"),
     "court": "Lun, mar, jeu, ven : 9h30 – 12h et 13h30 – 18h30. Mer : 13h30 – 18h30",
     "spec": [(_JOURS, "09:30", "12:00"), (_JOURS, "13:30", "18:30"), (["Wednesday"], "13:30", "18:30")]},
    {"id": "pompignac", "ville": "Pompignac", "rue": "1 avenue du Périgord", "complement": "Parc d'activité de Lauduc", "cp": "33370",
     "maps": "https://www.google.com/maps/search/?api=1&query=1+avenue+du+P%C3%A9rigord+Parc+d%27activit%C3%A9+de+Lauduc+33370+Pompignac",
     "horaires": _semaine("9h00 – 12h00", "14h00 – 18h30", "13h30 – 18h30"),
     "court": "Lun, mar, jeu, ven : 9h – 12h et 14h – 18h30. Mer : 13h30 – 18h30",
     "spec": [(_JOURS, "09:00", "12:00"), (_JOURS, "14:00", "18:30"), (["Wednesday"], "13:30", "18:30")]},
]
def adr(m, sep="<br>"):
    return sep.join(x for x in [m["rue"], m["complement"], f'{m["cp"]} {m["ville"]}'] if x)
def table_horaires(m):
    return '<table class="horaires"><tbody>' + "".join(f"<tr><td>{j}</td><td>{h}</td></tr>" for j, h in m["horaires"]) + "</tbody></table>"
def cartes_magasins(titre_niveau="h3"):
    out = ""
    for m in MAGASINS:
        ups = '<p class="note" style="margin:.8em 0 0"><strong>Relais Pickup</strong> : déposez ou récupérez vos colis.</p>'
        out += f'''<div class="encart magasin" id="magasin-{m["id"]}">
  <span class="surtitre">Magasin</span>
  <{titre_niveau} style="margin-top:0">{m["ville"]}</{titre_niveau}>
  <div class="coord"><div>{ico("lieu")}<p style="margin:0">{adr(m)}<br><a href="{m["maps"]}" rel="noopener">Itinéraire</a></p></div></div>
  <h4 style="margin:1.2em 0 .4em;font-size:1.05rem">Horaires</h4>
  {table_horaires(m)}{ups}
</div>'''
    return f'<div class="grille grille--2">{out}</div>'
VILLES = ["Ambarès-et-Lagrave", "Pompignac", "Saint-Loubès", "Carbon-Blanc", "Sainte-Eulalie", "Bassens", "Saint-Vincent-de-Paul",
          "Saint-Louis-de-Montferrand", "Lormont", "Montussan", "Yvrac", "Tresses", "Fargues-Saint-Hilaire", "Salleboeuf",
          "Bonnetan", "Carignan-de-Bordeaux", "Artigues-près-Bordeaux", "Izon", "Cenon", "Saint-Sulpice-et-Cameyrac",
          "Beychac-et-Caillau", "Bordeaux Rive droite"]
CUR = ' aria-current="page"'
PRINC = ' class="principal"'
ANNEE = datetime.date.today().year

# ---------- Icônes (traits) ----------
def ico(name):
    p = {
        "outil": '<path d="M14.7 6.3a4 4 0 0 0-5.4 5.2L3.6 17.2a1.9 1.9 0 0 0 2.7 2.7l5.7-5.7a4 4 0 0 0 5.2-5.4l-2.4 2.4-2.3-.4-.4-2.3z"/>',
        "ordi": '<rect x="4" y="5" width="16" height="11" rx="1.5"/><path d="M2 19h20"/>',
        "mobile": '<rect x="7" y="2.5" width="10" height="19" rx="2"/><path d="M11 18.5h2"/>',
        "carton": '<path d="M3.5 7.5 12 3l8.5 4.5v9L12 21l-8.5-4.5z"/><path d="M3.5 7.5 12 12l8.5-4.5M12 12v9"/>',
        "entreprise": '<path d="M4 21V5.5L12 3v18M12 8h8v13M2.5 21h19"/><path d="M7.5 8.5h1M7.5 12h1M7.5 15.5h1M15.5 12h1M15.5 15.5h1"/>',
        "maison": '<path d="M3.5 11 12 4l8.5 7"/><path d="M5.5 9.5V20h13V9.5"/><path d="M10 20v-5h4v5"/>',
        "distance": '<rect x="3" y="4" width="18" height="12" rx="1.5"/><path d="M8 20h8M12 16v4"/><path d="M9 10.5l2 2 4-4"/>',
        "formation": '<path d="M2.5 9 12 4.5 21.5 9 12 13.5z"/><path d="M6.5 11v4.5c0 1.4 2.5 3 5.5 3s5.5-1.6 5.5-3V11"/><path d="M21.5 9v5"/>',
        "lieu": '<path d="M12 21s-7-6.2-7-11.5A7 7 0 0 1 19 9.5C19 14.8 12 21 12 21z"/><circle cx="12" cy="9.5" r="2.5"/>',
        "horloge": '<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/>',
        "tel": '<path d="M5 3.5h3.5l1.8 4.5-2.3 1.4a11 11 0 0 0 6.6 6.6l1.4-2.3 4.5 1.8V19a1.5 1.5 0 0 1-1.6 1.5A17 17 0 0 1 3.5 5.1 1.5 1.5 0 0 1 5 3.5z"/>',
        "mail": '<rect x="3" y="5" width="18" height="14" rx="1.5"/><path d="m3.5 6 8.5 7 8.5-7"/>',
        "colis": '<path d="M3.5 7.5 12 3l8.5 4.5v9L12 21l-8.5-4.5z"/><path d="m7.8 5.2 8.4 4.6v3.4"/>',
        "boucle": '<path d="M20 12a8 8 0 0 1-13.7 5.6M4 12a8 8 0 0 1 13.7-5.6"/><path d="M18 2.5v4h-4M6 21.5v-4h4"/>',
        "donnees": '<ellipse cx="12" cy="5.5" rx="7.5" ry="2.5"/><path d="M4.5 5.5v13c0 1.4 3.4 2.5 7.5 2.5s7.5-1.1 7.5-2.5v-13M4.5 12c0 1.4 3.4 2.5 7.5 2.5s7.5-1.1 7.5-2.5"/>',
        "bouclier": '<path d="M12 3 4.5 6v5.5c0 4.6 3.2 8.2 7.5 9.5 4.3-1.3 7.5-4.9 7.5-9.5V6z"/><path d="m9 12 2 2 4-4"/>',
        "menu": '<path d="M4 7h16M4 12h16M4 17h16"/>',
        "facebook": '<path d="M14 8.5V7c0-.8.5-1.5 1.5-1.5H17V2.5h-2.5C11.9 2.5 11 4.3 11 6.6v1.9H8.5v3H11v10h3v-10h2.6l.4-3z"/>',
    }[name]
    return f'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">{p}</svg>'

NAV = [("reparation-informatique.html", "Réparation"), ("vente-materiel.html", "Vente"),
       ("assistance-informatique-particuliers.html", "Particuliers"), ("entreprises.html", "Entreprises"), ("depannage-domicile-distance.html", "À domicile"),
       ("formation-informatique.html", "Formation"), ("emploi.html", "Emploi"),
       ("contact.html", "Contact")]

OFFRES = {"@type": "OfferCatalog", "name": "Services informatiques", "itemListElement": [
    {"@type": "Offer", "itemOffered": {"@type": "Service", "name": n}} for n in
    ["Réparation d'ordinateurs PC et Mac", "Réparation de smartphones et tablettes", "Vente de matériel neuf et reconditionné",
     "Maintenance informatique pour entreprises", "Dépannage à domicile et à distance", "Formation informatique"]]}
def _etab(m, principal):
    d = {"@context": "https://schema.org", "@type": "ComputerStore",
         "@id": DOMAINE + ("/#entreprise" if principal else "/#" + m["id"]),
         "name": "Les Techniciens" + ("" if principal else " " + m["ville"]),
         "alternateName": "Les Techniciens Informatique " + m["ville"], "slogan": "C'est simple, on est là !",
         "description": f"Dépannage, réparation et vente de matériel informatique (PC, Mac, smartphones) pour particuliers et professionnels, magasin de {m['ville']}.",
         "url": DOMAINE + "/", "logo": DOMAINE + "/assets/logo.svg", "image": DOMAINE + "/assets/partage.jpg",
         "telephone": "+33 5 24 84 78 00",
         "address": {"@type": "PostalAddress", "streetAddress": m["rue"] + (", " + m["complement"] if m["complement"] else ""),
                     "postalCode": m["cp"], "addressLocality": m["ville"], "addressRegion": "Nouvelle-Aquitaine", "addressCountry": "FR"},
         "openingHoursSpecification": [{"@type": "OpeningHoursSpecification", "dayOfWeek": j, "opens": o, "closes": c} for j, o, c in m["spec"]],
         "areaServed": [{"@type": "City", "name": v} for v in VILLES[:-1]],
         "sameAs": [FACEBOOK], "hasOfferCatalog": OFFRES}
    if not principal:
        d["parentOrganization"] = {"@id": DOMAINE + "/#entreprise"}
    return d
LD_MAGASINS = [_etab(m, i == 0) for i, m in enumerate(MAGASINS)]

def entete(actif):
    liens = "".join(f'<li><a href="{h}"{CUR if h == actif else ""}>{t}</a></li>' for h, t in NAV)
    return f'''<a class="saut" href="#contenu">Aller au contenu</a>
<header class="entete">
  <div class="conteneur">
    <a class="logo" href="index.html" aria-label="Les Techniciens, accueil"><img src="assets/logo-horizontal.svg" alt="Les Techniciens" width="190" height="22"></a>
    <button class="menu-btn" type="button" aria-expanded="false" aria-controls="nav" aria-label="Ouvrir le menu">{ico("menu")}</button>
    <nav class="nav" id="nav" aria-label="Navigation principale"><ul>{liens}</ul></nav>
    <a class="btn btn--rose btn--tel" href="tel:{TEL_LIEN}">{ico("tel")}{TEL}</a>
  </div>
</header>'''

def pied():
    serv = "".join(f'<li><a href="{h}">{t}</a></li>' for h, t in [
        ("reparation-informatique.html", "Réparation PC, Mac, smartphone"), ("vente-materiel.html", "Vente neuf et reconditionné"),
        ("entreprises.html", "Maintenance entreprises"), ("depannage-domicile-distance.html", "Dépannage à domicile et à distance"),
        ("formation-informatique.html", "Formation informatique")])
    return f'''<footer class="pied">
  <div class="conteneur">
    <div>
      <a class="pied__logo" href="index.html"><img src="assets/logo-blanc.svg" alt="Les Techniciens, C'est simple, on est là !" width="150" height="129"></a>
      <p>Vos magasins informatiques de proximité à Ambarès-et-Lagrave et à Pompignac, pour les particuliers et les professionnels.</p>
    </div>
    <div>
      <h2>Services</h2>
      <ul>{serv}</ul>
    </div>
    <div>
      <h2>Nos magasins</h2>
      <ul>
        <li><strong style="color:#fff">{MAGASINS[0]["ville"]}</strong><br>{adr(MAGASINS[0])}</li>
        <li><strong style="color:#fff">{MAGASINS[1]["ville"]}</strong><br>{adr(MAGASINS[1])}</li>
        <li><a href="contact.html#magasins">Horaires et itinéraires</a></li>
        <li><a href="zone-intervention.html">Secteur d'intervention</a></li>
        <li><a href="emploi.html">Emploi et stages</a></li>
      </ul>
    </div>
    <div>
      <h2>Contact</h2>
      <ul>
        <li><a href="tel:{TEL_LIEN}">{TEL}</a></li>
        <li>{mail()}</li>
        <li><a href="contact.html">Demander un devis</a></li>
        <li><a href="{FACEBOOK}" rel="noopener">Facebook</a></li>
      </ul>
    </div>
  </div>
  <div class="pied__bas"><div class="conteneur">
    <span>© {ANNEE} SAS Lestechniciens</span>
    <a href="mentions-legales.html">Mentions légales et confidentialité</a>
  </div></div>
</footer>
<div class="barre-mobile">
  <a class="btn btn--rose" href="tel:{TEL_LIEN}">{ico("tel")}Appeler</a>
  <a class="btn btn--contour" href="contact.html">Devis</a>
</div>
<script>
(function(){{var b=document.querySelector('.menu-btn'),n=document.getElementById('nav');if(!b)return;
b.addEventListener('click',function(){{var o=n.classList.toggle('ouvert');b.setAttribute('aria-expanded',o);b.setAttribute('aria-label',o?'Fermer le menu':'Ouvrir le menu');}});}})();
/* Sur le site en ligne, la barre d'adresse affiche /contact au lieu de /contact.html (le serveur sait servir les deux) */
if(/(^|\.)lestechniciens\.fr$/.test(location.hostname)&&/\.html$/.test(location.pathname)&&window.history&&history.replaceState){{history.replaceState(null,'',location.pathname.replace(/index\.html$/,'').replace(/\.html$/,'')+location.search+location.hash);}}
document.querySelectorAll('.js-masque').forEach(function(b){{b.addEventListener('click',function(){{var m=decodeURIComponent(escape(atob(b.dataset.m))).split('').reverse().join('');var e;if(b.classList.contains('js-lien-mail')){{e=document.createElement('a');e.href='mai'+'lto:'+m;}}else{{e=document.createElement('span');e.tabIndex=-1;}}e.textContent=m;b.replaceWith(e);e.focus();}});}});
</script>'''

def fil(items):
    li = ['<li><a href="index.html">Accueil</a></li>'] + [f'<li><a href="{h}">{t}</a></li>' if h else f'<li aria-current="page">{t}</li>' for h, t in items]
    return f'<nav class="fil" aria-label="Fil d’Ariane"><ol>{"".join(li)}</ol></nav>'

def propre(fichier):
    """Adresse publique d'une page : sans l'extension .html (réécrite par .htaccess)."""
    return "" if fichier == "index.html" else fichier[:-5]
import re as _re
_LIEN = _re.compile(r'href="([a-z0-9\-]+)\.html([?#][^"]*)?"')
def liens_propres(html):
    def f(m):
        nom, suite = m.group(1), m.group(2) or ""
        return f'href="{"./" if nom == "index" else nom}{suite}"'
    return _LIEN.sub(f, html)
def breadcrumb_ld(fichier, nom):
    return {"@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [
        {"@type": "ListItem", "position": 1, "name": "Accueil", "item": DOMAINE + "/"},
        {"@type": "ListItem", "position": 2, "name": nom, "item": f"{DOMAINE}/{propre(fichier)}"}]}

def page(fichier, titre, description, corps, ld=None, robots="index, follow"):
    url = DOMAINE + "/" + propre(fichier)
    ld = ld or []
    scripts = "".join(f'<script type="application/ld+json">{json.dumps(x, ensure_ascii=False)}</script>\n' for x in ld)
    html = f'''<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title>{titre}</title>
<meta name="description" content="{description}">
<meta name="robots" content="{robots}">
<link rel="canonical" href="{url}">
<meta name="theme-color" content="#1C4374">
<meta property="og:type" content="website">
<meta property="og:locale" content="fr_FR">
<meta property="og:site_name" content="Les Techniciens">
<meta property="og:title" content="{titre}">
<meta property="og:description" content="{description}">
<meta property="og:url" content="{url}">
<meta property="og:image" content="{DOMAINE}/assets/partage.jpg">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<link rel="icon" href="favicon.svg" type="image/svg+xml">
<link rel="icon" href="favicon-32.png" sizes="32x32" type="image/png">
<link rel="apple-touch-icon" href="apple-touch-icon.png">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Caveat:wght@500&family=Mulish:ital,wght@0,400;0,600;0,700;1,400&family=Saira+Semi+Condensed:wght@600;700&display=swap">
<link rel="stylesheet" href="assets/style.css">
{scripts}</head>
<body>
{entete(fichier)}
<main id="contenu">
{corps}
</main>
{pied()}
</body>
</html>
'''
    with open(os.path.join(OUT, fichier), "w", encoding="utf-8") as f:
        f.write(html)   # liens en .html : fonctionnent partout (serveur local, sous-dossier, fichier ouvert directement)
    return fichier

def appel(titre="Une panne, une question ?", texte="Appelez-nous : on vous dit tout de suite si on peut vous aider, et comment."):
    return f'''<section class="appel" aria-labelledby="appel-titre">
  <div class="conteneur">
    <div><h2 id="appel-titre">{titre}</h2><p>{texte}</p></div>
    <div class="actions" style="margin:0;align-items:center">
      <a class="tel" href="tel:{TEL_LIEN}">{TEL}</a>
      <a class="btn btn--blanc" href="contact.html">Demander un devis</a>
    </div>
  </div>
</section>'''

def titre_page(eyebrow, h1, chapo, fil_items):
    return f'''<section class="page-titre"><div class="conteneur">
{fil(fil_items)}
<span class="surtitre">{eyebrow}</span>
<h1>{h1}</h1>
<p class="chapo">{chapo}</p>
<div class="actions"><a class="btn btn--rose" href="tel:{TEL_LIEN}">{ico("tel")}Appeler le {TEL}</a><a class="btn btn--contour" href="contact.html">Demander un devis</a></div>
</div></section>'''

def faq(items):
    blocs = "".join(f"<details><summary>{q}</summary><p>{r}</p></details>" for q, r in items)
    return f'<div class="faq">{blocs}</div>'

pages = []

# ================= ACCUEIL =================
services = [
    ("reparation-informatique.html", "outil", "Réparation PC et Mac", "Ordinateur lent, qui ne démarre plus, écran cassé, virus : diagnostic en atelier et devis avant toute intervention."),
    ("reparation-informatique.html#smartphone", "mobile", "Smartphone et tablette", "Écran, batterie, connecteur de charge : on remet en état votre appareil au lieu de le remplacer."),
    ("vente-materiel.html", "carton", "Vente neuf et reconditionné", "Ordinateurs, écrans, imprimantes et accessoires, choisis selon votre usage et préparés avant la remise."),
    ("entreprises.html", "entreprise", "Maintenance entreprises", "Parc informatique, réseau, sauvegardes et contrats d'assistance pour les TPE, PME, artisans et associations."),
    ("depannage-domicile-distance.html", "maison", "À domicile ou à distance", "Un technicien se déplace chez vous, ou prend la main à distance sur votre ordinateur pour régler le problème."),
    ("formation-informatique.html", "formation", "Formation", "Prendre en main un ordinateur, un smartphone ou un logiciel, à votre rythme, seul ou en petit groupe."),
]
cartes = "".join(f'''<a class="service" href="{h}"><span class="service__ico">{ico(i)}</span><h3>{t}</h3><p>{d}</p><span class="service__lien">En savoir plus</span></a>''' for h, i, t, d in services)
villes_html = "".join(f'<li{PRINC if v in ("Ambarès-et-Lagrave", "Pompignac") else ""}>{v}</li>' for v in VILLES)

accueil = f'''<section class="heros">
  <div class="conteneur">
    <div>
      <span class="surtitre">Magasins informatiques · Ambarès et Pompignac</span>
      <h1>Dépannage et réparation informatique <span>à Ambarès et Pompignac</span></h1>
      <p class="chapo">PC, Mac, smartphones et tablettes : Les Techniciens réparent, entretiennent et équipent les particuliers et les entreprises de la rive droite de Bordeaux.</p>
      <p class="main">C'est simple, on est là !</p>
      <div class="actions">
        <a class="btn btn--rose" href="tel:{TEL_LIEN}">{ico("tel")}Appeler le {TEL}</a>
        <a class="btn btn--contour" href="contact.html">Demander un devis</a>
      </div>
    </div>
    <div class="heros__visuel">
      <picture>
        <source type="image/webp" srcset="assets/atelier-900.webp 900w, assets/atelier-1600.webp 1600w" sizes="(max-width:860px) 100vw, 540px">
        <img src="assets/atelier-900.jpg" srcset="assets/atelier-900.jpg 900w, assets/atelier-1600.jpg 1600w" sizes="(max-width:860px) 100vw, 540px" alt="Technicien travaillant sur un ordinateur portable" width="900" height="600" fetchpriority="high">
      </picture>
      <div class="heros__carte"><img src="assets/icone.svg" alt="" width="46" height="46"><div><strong>Label Répar'acteurs</strong><span>On répare d'abord, on remplace si besoin.</span></div></div>
    </div>
  </div>
</section>

<section class="infos" aria-label="Informations pratiques">
  <div class="conteneur"><ul>
    <li>{ico("lieu")}<div><strong>Ambarès-et-Lagrave</strong>{MAGASINS[0]["rue"]}</div></li>
    <li>{ico("lieu")}<div><strong>Pompignac</strong>{MAGASINS[1]["rue"]}, {MAGASINS[1]["complement"]}</div></li>
    <li>{ico("tel")}<div><strong>Téléphone</strong><a href="tel:{TEL_LIEN}">{TEL}</a></div></li>
    <li>{ico("colis")}<div><strong>Relais Pickup</strong>Dans nos deux magasins</div></li>
  </ul></div>
</section>

<section class="section" aria-labelledby="services-titre">
  <div class="conteneur">
    <div class="entete-section">
      <div><span class="surtitre">Nos services</span><h2 id="services-titre">Tout votre informatique, au même endroit</h2></div>
      <p>Particuliers ou professionnels : un seul interlocuteur pour réparer, équiper et entretenir.</p>
    </div>
    <div class="grille grille--3">{cartes}</div>
  </div>
</section>

<section class="bandeau-contrats" aria-labelledby="contrats-titre">
  <div class="conteneur">
    <div>
      <span class="surtitre">Particuliers · Contrats d'assistance</span>
      <h2 id="contrats-titre">Un seul numéro pour tous vos problèmes</h2>
      <p>Des solutions en illimité selon votre contrat, le diagnostic inclus et jusqu'à −50 % en magasin. Sans engagement annuel.</p>
    </div>
    <ul class="mini-prix">
      <li><span>LT</span><strong>15 €</strong><small>TTC / mois</small></li>
      <li class="vedette"><span>LT+</span><strong>20 €</strong><small>TTC / mois</small></li>
      <li><span>LT Home</span><strong>30 €</strong><small>TTC / mois</small></li>
      <li><span>Pros</span><strong>dès 24 €</strong><small>HT / mois</small></li>
    </ul>
    <a class="btn btn--rose" href="assistance-informatique-particuliers.html">Découvrir les contrats</a>
  </div>
</section>

<section class="section section--gris" aria-labelledby="etapes-titre">
  <div class="conteneur">
    <span class="surtitre">Réparation en atelier</span>
    <h2 id="etapes-titre">Comment se passe une réparation</h2>
    <p class="chapo" style="margin-bottom:2.5rem">Vous savez à chaque étape ce qui est fait sur votre appareil, et combien cela coûte.</p>
    <ol class="etapes">
      <li><h3>Dépôt</h3><p>Vous déposez votre appareil dans l'un de nos deux magasins, ou nous venons le chercher. Vous expliquez la panne, on vous écoute.</p></li>
      <li><h3>Diagnostic</h3><p>Le technicien identifie l'origine du problème et vérifie l'état général de l'appareil.</p></li>
      <li><h3>Devis</h3><p>On vous appelle avec un devis clair. Rien n'est fait sans votre accord.</p></li>
      <li><h3>Restitution</h3><p>Votre appareil vous est rendu testé, avec des explications et des conseils pour éviter la prochaine panne.</p></li>
    </ol>
  </div>
</section>

<section class="section" aria-labelledby="engagement-titre">
  <div class="conteneur duo">
    <div>
      <span class="surtitre">Notre engagement</span>
      <h2 id="engagement-titre">Réparer plutôt que jeter</h2>
      <p>La réparation représente l'essentiel de notre activité. Un ordinateur qui ralentit ou un téléphone à l'écran fêlé ont souvent encore des années devant eux : nous vous le disons franchement quand une réparation vaut le coup, et quand elle ne le vaut pas.</p>
      <p>Nous sommes labellisés <strong>Répar'acteurs</strong>, le réseau d'artisans de la réparation porté par les Chambres de Métiers et de l'Artisanat. Nous proposons aussi du matériel <strong>reconditionné</strong>, contrôlé à l'atelier, pour s'équiper sans payer le prix du neuf.</p>
      <ul class="liste-coche">
        <li>Diagnostic et devis avant toute réparation</li>
        <li>Pièces de qualité et appareils testés avant restitution</li>
        <li>Conseils pour prolonger la vie de votre matériel</li>
      </ul>
    </div>
    <aside class="encart encart--bleu">
      <div class="label"><span class="label__pastille">{ico("boucle")}</span><div><h3>Label Répar'acteurs</h3><p>Un repère pour trouver un réparateur de proximité qui privilégie la réparation et le réemploi.</p></div></div>
      <hr style="border:0;border-top:1px solid rgba(255,255,255,.2);margin:22px 0">
      <div class="label"><span class="label__pastille">{ico("carton")}</span><div><h3>Reconditionné</h3><p>Ordinateurs remis à neuf, vérifiés et prêts à l'emploi, avec nos conseils pour choisir.</p></div></div>
    </aside>
  </div>
</section>

<section class="section" id="magasins" aria-labelledby="magasins-titre">
  <div class="conteneur">
    <div class="entete-section">
      <div><span class="surtitre">Nos magasins</span><h2 id="magasins-titre">Deux adresses pour vous accueillir</h2></div>
      <p>Déposez votre appareil ou venez choisir votre matériel dans le magasin le plus proche de chez vous.</p>
    </div>
    {cartes_magasins()}
    <div class="pickup">
      <span class="pickup__ico">{ico("colis")}</span>
      <div>
        <h3>Relais Pickup dans nos deux magasins</h3>
        <p><strong>Joignez l'utile à l'agréable :</strong> déposez ou récupérez votre colis… ou votre ordinateur, au même endroit, à Ambarès-et-Lagrave comme à Pompignac.</p>
      </div>
    </div>
  </div>
</section>

<section class="section section--gris" aria-labelledby="zone-titre">
  <div class="conteneur">
    <span class="surtitre">Secteur d'intervention</span>
    <h2 id="zone-titre">Sur la rive droite de Bordeaux et alentours</h2>
    <p>Nos magasins sont à Ambarès-et-Lagrave et à Pompignac. Nous intervenons à domicile et en entreprise dans les communes voisines, et partout en France pour l'assistance à distance.</p>
    <ul class="villes">{villes_html}</ul>
    <p style="margin-top:1.5rem"><a href="zone-intervention.html">Voir le secteur d'intervention en détail</a></p>
  </div>
</section>

<section class="section" aria-labelledby="faq-titre">
  <div class="conteneur">
    <span class="surtitre">Questions fréquentes</span>
    <h2 id="faq-titre">Vous vous demandez peut-être</h2>
    {faq([
        ("Faut-il prendre rendez-vous pour déposer un appareil ?", f"Ce n'est pas obligatoire : vous pouvez passer dans l'un de nos magasins aux heures d'ouverture. Un appel au {TEL} avant de venir permet de vous accueillir dans de bonnes conditions."),
        ("Combien coûte une réparation ?", "Cela dépend de la panne et des pièces nécessaires. Après le diagnostic, nous vous donnons un devis précis, et nous ne réparons qu'avec votre accord."),
        ("Pouvez-vous récupérer mes photos et documents ?", "Dans la plupart des cas, oui : même quand l'ordinateur ne démarre plus, le disque peut souvent être lu. Nous vous expliquons les chances de récupération avant d'intervenir."),
        ("Intervenez-vous pour les entreprises ?", "Oui. Nous accompagnons les TPE, PME, artisans, professions libérales et associations : installation, maintenance, sauvegardes, réseau et contrats d'assistance."),
    ])}
  </div>
</section>
{appel()}'''
pages.append(page("index.html", "Dépannage informatique Ambarès et Pompignac | Les Techniciens",
    "Réparation PC, Mac et smartphone, vente de matériel neuf et reconditionné, maintenance pour les entreprises. Magasins à Ambarès-et-Lagrave et Pompignac.",
    accueil, LD_MAGASINS))

# ================= RÉPARATION =================
rep = titre_page("Réparation en atelier", "Réparation d'ordinateur, Mac et smartphone à Ambarès et Pompignac",
    "Panne matérielle ou logicielle, écran cassé, lenteurs, virus : nous diagnostiquons et réparons vos appareils dans notre atelier, avec un devis avant chaque intervention.",
    [(None, "Réparation")]) + f'''
<section class="section"><div class="conteneur duo">
<div class="contenu">
  <h2>Ordinateurs PC et portables</h2>
  <p>Toutes marques, fixes ou portables. Nous prenons en charge aussi bien les pannes matérielles que les problèmes de système.</p>
  <ul class="liste-coche">
    <li>Ordinateur qui ne s'allume plus ou redémarre sans cesse</li>
    <li>Lenteurs, écran bleu, Windows qui ne démarre pas</li>
    <li>Suppression de virus et logiciels indésirables</li>
    <li>Remplacement d'écran, de clavier, de batterie ou de charnière</li>
    <li>Passage à un disque SSD et ajout de mémoire pour redonner de la vitesse</li>
    <li>Nettoyage interne et changement de pâte thermique contre la surchauffe</li>
  </ul>
  <h2>Mac et MacBook</h2>
  <p>Diagnostic, remplacement de batterie ou de disque, réinstallation de macOS, nettoyage et récupération de données sur les Mac.</p>
  <h2 id="smartphone">Smartphones et tablettes</h2>
  <p>Un écran fissuré ou une batterie fatiguée ne justifient pas toujours un appareil neuf. Nous remettons en état iPhone, smartphones Android et tablettes.</p>
  <ul class="liste-coche">
    <li>Remplacement d'écran et de vitre</li>
    <li>Changement de batterie</li>
    <li>Connecteur de charge, haut-parleur, micro, boutons</li>
    <li>Transfert de données vers un nouvel appareil</li>
  </ul>
  <h2>Récupération de données</h2>
  <p>Disque dur qui ne répond plus, clé USB illisible, fichiers effacés par erreur : nous tentons la récupération de vos photos et documents, et vous indiquons les chances de succès avant d'intervenir.</p>
</div>
<aside class="encart">
  <h3>Comment ça se passe</h3>
  <ol style="padding-left:1.2em;margin:0 0 1em">
    <li>Vous déposez l'appareil en magasin.</li>
    <li>Nous faisons le diagnostic.</li>
    <li>Vous recevez un devis, et décidez.</li>
    <li>Vous récupérez votre appareil testé.</li>
  </ol>
  <p><strong>Ambarès-et-Lagrave :</strong> {adr(MAGASINS[0], ", ")}</p>
  <p><strong>Pompignac :</strong> {adr(MAGASINS[1], ", ")}</p>
  <p><a href="contact.html#magasins">Voir les horaires des magasins</a></p>
  <a class="btn btn--rose" href="tel:{TEL_LIEN}">{ico("tel")}{TEL}</a>
</aside>
</div></section>
<section class="section section--gris"><div class="conteneur">
<h2>Questions sur la réparation</h2>
{faq([
    ("Combien de temps dure une réparation ?", "Cela dépend de la panne et de la disponibilité des pièces. Nous vous donnons un délai au moment du devis, et vous prévenons dès que l'appareil est prêt."),
    ("Mes données sont-elles conservées ?", "Nous faisons attention à vos données à chaque intervention. Si une réinstallation est nécessaire, nous vous proposons une sauvegarde avant de commencer."),
    ("Mon ordinateur vaut-il la peine d'être réparé ?", "Nous vous le disons franchement. Si la réparation coûte plus cher que l'appareil ne vaut, nous vous présentons les alternatives, dont le reconditionné."),
])}
</div></section>
{appel("Votre appareil fait des siennes ?", "Décrivez-nous la panne au téléphone : on vous dit si on peut le réparer.")}'''
pages.append(page("reparation-informatique.html", "Réparation PC, Mac et smartphone à Ambarès | Les Techniciens",
    "Réparation de PC, portables, Mac, smartphones et tablettes à Ambarès-et-Lagrave : écran, batterie, virus, lenteurs, récupération de données. Diagnostic et devis avant intervention.",
    rep, [breadcrumb_ld("reparation-informatique.html", "Réparation"),
          {"@context": "https://schema.org", "@type": "Service", "serviceType": "Réparation informatique",
           "provider": {"@id": DOMAINE + "/#entreprise"}, "areaServed": ["Ambarès-et-Lagrave", "Pompignac"],
           "name": "Réparation d'ordinateurs, Mac, smartphones et tablettes"}]))

# ================= VENTE =================
vente = titre_page("Vente de matériel", "Ordinateurs neufs et reconditionnés, écrans et accessoires",
    "Besoin de vous équiper ? Nous vous conseillons le matériel adapté à votre usage et à votre budget, et nous le préparons pour qu'il soit prêt à l'emploi.",
    [(None, "Vente")]) + f'''
<section class="section"><div class="conteneur">
<div class="grille grille--3">
  <div class="service"><span class="service__ico">{ico("ordi")}</span><h3>Ordinateurs neufs</h3><p>Portables et fixes pour la bureautique, les études, le télétravail ou des usages plus exigeants.</p></div>
  <div class="service"><span class="service__ico">{ico("boucle")}</span><h3>Reconditionné</h3><p>Des ordinateurs remis en état et contrôlés à l'atelier : une solution économique et plus responsable.</p></div>
  <div class="service"><span class="service__ico">{ico("carton")}</span><h3>Accessoires et consommables</h3><p>Écrans, imprimantes, disques, claviers, souris, câbles, cartouches et pièces détachées.</p></div>
</div>
</div></section>
<section class="section section--gris"><div class="conteneur duo">
<div class="contenu">
  <h2>Un conseil avant l'achat</h2>
  <p>Inutile de payer pour de la puissance dont vous ne vous servirez pas. Nous prenons le temps de comprendre votre usage pour vous proposer le bon appareil.</p>
  <h2>Un appareil prêt à l'emploi</h2>
  <p>Sur demande, nous installons vos logiciels, transférons les données de votre ancien ordinateur et configurons vos comptes, votre imprimante et votre messagerie.</p>
  <ul class="liste-coche">
    <li>Mise en service et mises à jour</li>
    <li>Transfert des fichiers depuis l'ancien appareil</li>
    <li>Installation des logiciels et de l'antivirus</li>
  </ul>
</div>
<aside class="encart encart--bleu"><h3>Pourquoi le reconditionné ?</h3><p>Un ordinateur reconditionné coûte moins cher qu'un neuf et évite de fabriquer un appareil de plus. Chez nous, il est vérifié et préparé avant de vous être remis.</p><a class="btn btn--blanc" href="contact.html">Demander la disponibilité</a></aside>
</div></section>
{appel("Vous cherchez un appareil ?", "Dites-nous ce que vous voulez en faire, on vous propose ce qui convient.")}'''
pages.append(page("vente-materiel.html", "Ordinateurs neufs et reconditionnés à Ambarès | Les Techniciens",
    "Ordinateurs neufs et reconditionnés, écrans, imprimantes et accessoires à Ambarès-et-Lagrave. Conseil personnalisé, installation et transfert de données.",
    vente, [breadcrumb_ld("vente-materiel.html", "Vente")]))

# ================= ENTREPRISES =================
pro = titre_page("Professionnels", "Maintenance et assistance informatique pour les entreprises",
    "TPE, PME, artisans, commerçants, professions libérales et associations : nous gérons votre informatique pour que vous puissiez vous concentrer sur votre métier.",
    [(None, "Entreprises")]) + f'''
<section class="section"><div class="conteneur">
<div class="grille grille--2">
  <div class="service"><span class="service__ico">{ico("outil")}</span><h3>Maintenance du parc</h3><p>Postes de travail, serveurs, imprimantes : entretien, mises à jour et dépannage, sur site ou à distance.</p></div>
  <div class="service"><span class="service__ico">{ico("donnees")}</span><h3>Sauvegardes</h3><p>Mise en place de sauvegardes automatiques et vérifiées, pour ne pas perdre vos fichiers clients ou votre comptabilité.</p></div>
  <div class="service"><span class="service__ico">{ico("bouclier")}</span><h3>Sécurité</h3><p>Antivirus, pare-feu, mots de passe, sensibilisation de l'équipe aux tentatives d'hameçonnage.</p></div>
  <div class="service"><span class="service__ico">{ico("distance")}</span><h3>Réseau et installation</h3><p>Installation de postes, réseau et Wi-Fi, messagerie professionnelle, équipement d'un nouveau local.</p></div>
</div>
</div></section>
<section class="section section--gris"><div class="conteneur duo">
<div class="contenu">
  <h2>Des contrats d'assistance à partir de 24 € HT par mois</h2>
  <p>Un contrat de maintenance vous donne un interlocuteur identifié, des interventions prioritaires et un entretien régulier de votre parc. Nous le construisons selon la taille de votre structure et vos besoins.</p>
  <ul class="liste-coche">
    <li>Intervention à distance rapide pour les problèmes courants</li>
    <li>Déplacement sur site quand c'est nécessaire</li>
    <li>Suivi du matériel et conseils pour son renouvellement</li>
    <li>Fourniture de matériel neuf ou reconditionné</li>
  </ul>
</div>
<aside class="encart"><p class="prix-pro">à partir de <strong>24 €</strong> HT / mois</p><h3>Parlons de votre structure</h3><p>Combien de postes, quels logiciels, quelles difficultés ? Nous passons faire le point avec vous.</p><a class="btn btn--rose" href="contact.html">Demander un rendez-vous</a></aside>
</div></section>
{appel("Une panne bloque votre activité ?", "Appelez-nous : nous intervenons à distance ou sur site dans le secteur.")}'''
pages.append(page("entreprises.html", "Maintenance informatique entreprises | Les Techniciens",
    "Maintenance informatique, sauvegardes, sécurité, réseau et contrats d'assistance pour TPE, PME, artisans et associations autour d'Ambarès-et-Lagrave.",
    pro, [breadcrumb_ld("entreprises.html", "Entreprises")]))

# ================= DOMICILE / DISTANCE =================
dom = titre_page("Intervention", "Dépannage informatique à domicile et à distance",
    "Vous ne pouvez pas vous déplacer, ou le problème concerne votre installation ? Un technicien vient chez vous ou prend la main sur votre ordinateur à distance.",
    [(None, "À domicile et à distance")]) + f'''
<section class="section"><div class="conteneur">
<div class="grille grille--2">
  <div class="encart">
    <span class="service__ico">{ico("maison")}</span>
    <h2>À domicile</h2>
    <p>Nous nous déplaçons autour de nos magasins d'Ambarès-et-Lagrave et de Pompignac, dans les communes voisines, pour les interventions qui se font mieux sur place.</p>
    <ul class="liste-coche">
      <li>Installation d'un ordinateur, d'une imprimante, d'une box</li>
      <li>Problèmes de Wi-Fi et de connexion</li>
      <li>Aide à la prise en main de votre matériel</li>
      <li>Diagnostic, et prise en charge à l'atelier si nécessaire</li>
    </ul>
    <p><a href="zone-intervention.html">Voir les communes desservies</a></p>
  </div>
  <div class="encart">
    <span class="service__ico">{ico("distance")}</span>
    <h2>À distance</h2>
    <p>Pour les problèmes logiciels, pas besoin de se déplacer : avec votre accord, le technicien se connecte à votre ordinateur et règle le problème pendant que vous suivez à l'écran.</p>
    <ul class="liste-coche">
      <li>Messagerie, logiciels, mises à jour</li>
      <li>Virus et publicités intempestives</li>
      <li>Réglages et conseils en direct</li>
      <li>Connexion sécurisée, que vous pouvez couper à tout moment</li>
    </ul>
  </div>
</div>
</div></section>
{appel("Besoin d'un technicien ?", "Appelez-nous pour convenir d'une intervention chez vous ou à distance.")}'''
pages.append(page("depannage-domicile-distance.html", "Dépannage informatique à domicile et à distance | Les Techniciens",
    "Dépannage informatique à domicile à Ambarès-et-Lagrave et sur la rive droite, ou assistance à distance : installation, Wi-Fi, virus, logiciels, prise en main.",
    dom, [breadcrumb_ld("depannage-domicile-distance.html", "À domicile et à distance")]))

# ================= FORMATION =================
form = titre_page("Formation", "Formation informatique, à votre rythme",
    "Prendre en main un ordinateur, un smartphone ou un logiciel : nous vous formons simplement, avec vos propres appareils et selon vos besoins.",
    [(None, "Formation")]) + f'''
<section class="section"><div class="conteneur duo">
<div class="contenu">
  <h2>Pour les particuliers</h2>
  <p>Des séances individuelles pour gagner en autonomie, sans jargon.</p>
  <ul class="liste-coche">
    <li>Découvrir son ordinateur, sa tablette ou son smartphone</li>
    <li>Utiliser sa messagerie, internet et les démarches en ligne</li>
    <li>Ranger et sauvegarder ses photos et documents</li>
    <li>Repérer les arnaques et se protéger en ligne</li>
  </ul>
  <h2>Pour les professionnels</h2>
  <p>Des formations pour vous ou votre équipe, sur les outils que vous utilisez au quotidien.</p>
  <ul class="liste-coche">
    <li>Bureautique : traitement de texte, tableur, messagerie</li>
    <li>Prise en main d'un nouveau poste ou d'un nouveau logiciel</li>
    <li>Bonnes pratiques de sécurité informatique</li>
  </ul>
</div>
<aside class="encart encart--bleu"><h3>Un programme sur mesure</h3><p>Dites-nous ce que vous voulez savoir faire. Nous construisons les séances autour de vos besoins, en magasin, chez vous ou dans vos locaux.</p><a class="btn btn--blanc" href="contact.html">Nous contacter</a></aside>
</div></section>
{appel("Envie d'être plus à l'aise avec l'informatique ?", "Appelez-nous pour organiser une première séance.")}'''
pages.append(page("formation-informatique.html", "Formation informatique à Ambarès-et-Lagrave | Les Techniciens",
    "Formation informatique pour particuliers et professionnels à Ambarès-et-Lagrave : ordinateur, smartphone, bureautique, sécurité en ligne. Séances sur mesure.",
    form, [breadcrumb_ld("formation-informatique.html", "Formation")]))

# ================= CONTRATS =================
FORMULES = [
    {"nom": "Assistance LT", "devise": "J'appelle uniquement quand j'ai besoin", "prix": 15, "ico": "tel", "vedette": False,
     "avantages": ["Diagnostic inclus", "Assistance par téléphone incluse", "−25 % en magasin et à l'atelier sur certaines prestations", "Déplacement à domicile au forfait"]},
    {"nom": "Assistance LT+", "devise": "On s'occupe de tout à ma place", "prix": 20, "ico": "bouclier", "vedette": True,
     "avantages": ["Diagnostic inclus", "Assistance par téléphone incluse", "−50 % en magasin et à l'atelier sur certaines prestations", "Déplacement à domicile au forfait"]},
    {"nom": "Assistance LT Home", "devise": "On s'occupe de tout pour chaque appareil", "prix": 30, "ico": "maison", "vedette": False,
     "avantages": ["Diagnostic inclus", "Assistance par téléphone incluse", "−50 % en magasin et à l'atelier sur certaines prestations", "Déplacement à domicile au forfait", "Tous les appareils du foyer"]},
]
cgv = (f'<a class="lien-cgv" href="{CGV_URL}">Conditions générales</a>' if CGV_URL
       else '<a class="lien-cgv" href="contact.html">Conditions générales sur demande</a>')
def carte_formule(f):
    av = "".join(f"<li>{a}</li>" for a in f["avantages"])
    badge = '<span class="formule__badge">Le plus choisi</span>' if f["vedette"] else ""
    return f'''<article class="formule{' formule--vedette' if f['vedette'] else ''}">
  {badge}<span class="service__ico">{ico(f["ico"])}</span>
  <h3>{f["nom"]}</h3>
  <p class="formule__devise">« {f["devise"]} »</p>
  <p class="formule__prix"><strong>{f["prix"]} €</strong><span>TTC / mois</span></p>
  <p class="formule__sans">Sans engagement annuel</p>
  <ul class="liste-coche">{av}</ul>
  <div class="formule__bas"><a class="btn {'btn--rose' if f['vedette'] else 'btn--contour'}" href="contact.html?formule={f['nom'].replace(' ', '+')}">Souscrire</a>{cgv}</div>
</article>'''
formules_html = "".join(carte_formule(f) for f in FORMULES)
contrats = titre_page("Particuliers", "Assistance informatique pour les particuliers",
    "Un seul numéro pour tous vos problèmes informatiques : avec un contrat Les Techniciens, vous appelez dès qu'un souci se présente et nous trouvons la solution, en illimité selon votre formule. À partir de 15 € par mois, sans engagement annuel.",
    [(None, "Particuliers")]) + f'''
<section class="section" aria-labelledby="particuliers-titre"><div class="conteneur">
  <div class="entete-section">
    <div><span class="surtitre">Contrats d'assistance</span><h2 id="particuliers-titre">Choisissez votre formule</h2></div>
    <p>Des prix fixes chaque mois, sans engagement annuel. Le détail des solutions incluses figure dans les conditions générales de chaque contrat.</p>
  </div>
  <div class="formules">{formules_html}</div>
</div></section>

<section class="section section--gris" aria-labelledby="pourquoi-titre"><div class="conteneur duo">
<div class="contenu">
  <h2 id="pourquoi-titre">Pourquoi prendre un contrat ?</h2>
  <ul class="liste-coche">
    <li><strong>Un seul numéro</strong> pour l'ordinateur, le smartphone, l'imprimante, la box ou la messagerie.</li>
    <li><strong>Des solutions en illimité</strong> selon votre contrat : vous appelez autant que nécessaire.</li>
    <li><strong>Le diagnostic est inclus</strong> : vous savez tout de suite d'où vient le problème.</li>
    <li><strong>Des réductions en magasin</strong> sur les prestations à l'atelier, jusqu'à −50 %.</li>
    <li><strong>Un budget maîtrisé</strong> : un prix fixe chaque mois, sans mauvaise surprise.</li>
  </ul>
  <p>Quelle formule choisir ? <strong>LT</strong> si vous voulez surtout pouvoir appeler en cas de besoin, <strong>LT+</strong> pour nous confier votre ordinateur au quotidien, <strong>LT Home</strong> pour couvrir tous les appareils de la maison.</p>
</div>
<aside class="encart encart--bleu" id="professionnels">
  <span class="surtitre" style="color:#fff">Professionnels</span>
  <p class="prix-pro prix-pro--clair">à partir de <strong>24 €</strong> HT / mois</p>
  <h3>Contrats entreprises</h3>
  <p>Maintenance du parc, assistance prioritaire, sauvegardes et sécurité pour les TPE, PME, artisans et associations. Nous adaptons le contrat au nombre de postes.</p>
  <div class="actions" style="margin-top:1rem"><a class="btn btn--blanc" href="entreprises.html">Voir l'offre entreprises</a></div>
</aside>
</div></section>

<section class="section" aria-labelledby="faq-contrats"><div class="conteneur">
  <h2 id="faq-contrats">Questions sur les contrats</h2>
  {faq([
    ("Suis-je engagé pour un an ?", "Non. Les contrats particuliers sont sans engagement annuel. Les conditions de résiliation sont précisées dans les conditions générales."),
    ("Qu'est-ce qui est inclus en illimité ?", "L'assistance par téléphone et le diagnostic sont inclus. La liste exacte des solutions couvertes par chaque formule figure dans ses conditions générales ; demandez-les-nous en magasin ou par téléphone."),
    ("Comment souscrire ?", f"Passez dans l'un de nos magasins à Ambarès-et-Lagrave ou à Pompignac, appelez le {TEL}, ou envoyez-nous une demande avec le formulaire de contact."),
    ("Les déplacements à domicile sont-ils compris ?", "Les déplacements sont facturés au forfait, quelle que soit la formule."),
  ])}
</div></section>
{appel("Une question sur les contrats ?", "Appelez-nous, on vous aide à choisir la formule qui vous convient.")}'''
LD_CONTRATS = {"@context": "https://schema.org", "@type": "Service", "name": "Assistance informatique pour les particuliers", "audience": {"@type": "Audience", "audienceType": "Particuliers"},
    "provider": {"@id": DOMAINE + "/#entreprise"}, "areaServed": ["Ambarès-et-Lagrave", "Pompignac"],
    "offers": [{"@type": "Offer", "name": f["nom"], "price": str(f["prix"]), "priceCurrency": "EUR",
                "priceSpecification": {"@type": "UnitPriceSpecification", "price": f["prix"], "priceCurrency": "EUR",
                                       "unitText": "mois", "valueAddedTaxIncluded": True}} for f in FORMULES]}
pages.append(page("assistance-informatique-particuliers.html", "Assistance informatique particuliers dès 15 €/mois | Les Techniciens",
    "Assistance informatique pour les particuliers à Ambarès-et-Lagrave et Pompignac : un seul numéro pour tous vos problèmes. Contrats LT, LT+ et LT Home de 15 à 30 € TTC par mois, sans engagement annuel.",
    contrats, [breadcrumb_ld("assistance-informatique-particuliers.html", "Particuliers"), LD_CONTRATS]))

# ================= ZONE =================
zone = titre_page("Secteur d'intervention", "Votre informaticien sur la rive droite de Bordeaux",
    "Nos magasins sont à Ambarès-et-Lagrave et à Pompignac. Nous accueillons les clients de toute la rive droite de Bordeaux et de l'Entre-deux-Mers, et nous nous déplaçons dans les communes proches.",
    [(None, "Secteur d'intervention")]) + f'''
<section class="section"><div class="conteneur duo">
<div class="contenu">
  <h2>Communes desservies</h2>
  <p>Nous intervenons à domicile et en entreprise notamment dans les communes suivantes :</p>
  <ul class="villes">{villes_html}</ul>
  <p style="margin-top:1.5rem">Votre commune n'est pas dans la liste ? Appelez-nous : selon l'intervention, nous pouvons nous déplacer, ou vous aider à distance où que vous soyez.</p>
</div>
<aside class="encart"><div class="coord">
  <div>{ico("tel")}<p style="margin:0"><strong>Téléphone</strong><a href="tel:{TEL_LIEN}">{TEL}</a></p></div>
  <div>{ico("mail")}<p style="margin:0"><strong>E-mail</strong>{mail()}</p></div>
</div></div></aside>
</div></section>
<section class="section section--gris" id="magasins"><div class="conteneur">
  <h2>Venir dans nos magasins</h2>
  <p>Le magasin d'Ambarès-et-Lagrave est facile d'accès depuis Saint-Loubès, Carbon-Blanc, Bassens ou Sainte-Eulalie. Celui de Pompignac, dans le parc d'activité de Lauduc, est pratique depuis Tresses, Fargues-Saint-Hilaire, Salleboeuf ou Artigues-près-Bordeaux.</p>
  {cartes_magasins()}
</div></section>
{appel()}'''
pages.append(page("zone-intervention.html", "Dépannage informatique rive droite de Bordeaux | Les Techniciens",
    "Dépannage informatique à Ambarès-et-Lagrave, Pompignac, Saint-Loubès, Carbon-Blanc, Tresses, Bassens, Lormont et alentours. Deux magasins et intervention à domicile.",
    zone, [breadcrumb_ld("zone-intervention.html", "Secteur d'intervention")]))

# ================= EMPLOI =================
def form_candidature(t):
    p = "e-" if t == "emploi" else "s-"
    if t == "emploi":
        propres = f"""<div class="champ"><label for="{p}poste">Poste recherché</label><input id="{p}poste" name="poste" required placeholder="Ex. : technicien informatique, vendeur conseil…"></div>"""
    else:
        propres = f"""<div class="deux-champs">
      <div class="champ"><label for="{p}ecole">École et formation suivie</label><input id="{p}ecole" name="ecole" required placeholder="Ex. : BTS SIO, lycée…"></div>
      <div class="champ"><label for="{p}periode">Dates ou durée du stage</label><input id="{p}periode" name="periode" required placeholder="Ex. : du 6 janvier au 14 février"></div>
    </div>"""
    return f"""<form class="formulaire formulaire-candidature" id="form-{t}" method="POST" action="api/candidature.php" enctype="multipart/form-data">
    <input type="hidden" name="type" value="{t}">
    <input type="hidden" name="verif" class="verif" value="">
    <p class="sr"><label for="{p}site-web">Ne pas remplir</label><input id="{p}site-web" name="site-web" tabindex="-1" autocomplete="off"></p>
    <div class="deux-champs">
      <div class="champ"><label for="{p}nom">Nom et prénom</label><input id="{p}nom" name="nom" autocomplete="name" required></div>
      <div class="champ"><label for="{p}telephone">Téléphone</label><input id="{p}telephone" name="telephone" type="tel" autocomplete="tel" required></div>
    </div>
    <div class="champ"><label for="{p}email">E-mail</label><input id="{p}email" name="email" type="email" autocomplete="email" required></div>
    {propres}
    <div class="champ"><label for="{p}magasin">Magasin souhaité</label>
      <select id="{p}magasin" name="magasin"><option>Peu importe</option><option>Ambarès-et-Lagrave</option><option>Pompignac</option></select></div>
    <div class="deux-champs">
      <div class="champ fichier"><label for="{p}cv">CV <span class="oblig">obligatoire</span></label><input id="{p}cv" name="cv" type="file" accept=".pdf,.doc,.docx,.odt" required></div>
      <div class="champ fichier"><label for="{p}lettre">Lettre de motivation <span class="oblig">obligatoire</span></label><input id="{p}lettre" name="lettre" type="file" accept=".pdf,.doc,.docx,.odt" required></div>
    </div>
    <p class="note">Formats acceptés : PDF, Word ou OpenDocument, 5 Mo maximum par fichier.</p>
    <div class="champ"><label for="{p}message">Un mot pour nous (facultatif)</label><textarea id="{p}message" name="message" rows="4"></textarea></div>
    <label class="accord" for="{p}accord"><input id="{p}accord" name="accord" type="checkbox" value="1" required> <span>J'accepte que Les Techniciens conservent ma candidature et mes documents pendant 2 ans au maximum pour étudier mon profil. Voir les <a href="mentions-legales.html#donnees">mentions légales</a>.</span></label>
    <div><button class="btn btn--rose" type="submit">{"Envoyer ma candidature" if t == "emploi" else "Envoyer ma demande de stage"}</button></div>
    <p class="message-form" hidden></p>
  </form>"""

emploi = titre_page("Emploi et stages", "Rejoindre Les Techniciens",
    "Vous aimez l'informatique, le contact avec les clients et le travail bien fait ? Envoyez-nous votre candidature ou votre demande de stage pour nos magasins d'Ambarès-et-Lagrave et de Pompignac.",
    [(None, "Emploi")]).replace('<div class="actions"><a class="btn btn--rose" href="tel:', '<div class="actions"><a class="btn btn--rose" href="#candidature">Postuler</a><a class="btn btn--contour" href="#stage">Demander un stage</a></div><div hidden><a href="tel:', 1) + f"""
<section class="section" id="candidature" aria-labelledby="candidature-titre"><div class="conteneur duo">
<div>
  <span class="surtitre">Candidature</span>
  <h2 id="candidature-titre">Postuler chez nous</h2>
  <p>Technicien, vendeur conseil ou profil polyvalent : même sans offre publiée, nous étudions chaque candidature spontanée. Joignez votre CV et votre lettre de motivation.</p>
  {form_candidature("emploi")}
</div>
<aside class="encart encart--bleu">
  <h3>Ce que nous recherchons</h3>
  <ul class="liste-coche">
    <li>Le goût du dépannage et de la réparation</li>
    <li>Le sens du service et de la pédagogie avec les clients</li>
    <li>De la rigueur et de l'envie d'apprendre</li>
  </ul>
  <p>Nous répondons à toutes les candidatures.</p>
</aside>
</div></section>
<section class="section section--gris" id="stage" aria-labelledby="stage-titre"><div class="conteneur duo">
<div>
  <span class="surtitre">Stage</span>
  <h2 id="stage-titre">Faire un stage aux Techniciens</h2>
  <p>Collégiens en stage d'observation, lycéens, étudiants en BTS ou en formation informatique : découvrez le quotidien d'un atelier de réparation et d'un magasin. Joignez votre CV et votre lettre de motivation.</p>
  {form_candidature("stage")}
</div>
<aside class="encart">
  <h3>Bon à savoir</h3>
  <p>Précisez vos dates de stage et le nom de votre établissement : nous vous répondrons plus vite. Pensez à envoyer votre demande plusieurs semaines à l'avance.</p>
</aside>
</div></section>
<script>
(function(){{
var ERREURS={{verification:"Votre envoi n'a pas pu être vérifié. Patientez quelques secondes puis renvoyez-le.",incomplet:"Merci de remplir tous les champs obligatoires.",email:"L'adresse e-mail semble incorrecte.",telephone:"Le numéro de téléphone semble incorrect.",accord:"Merci de cocher la case d'accord pour la conservation de votre candidature.",fichier_manquant:"Le CV et la lettre de motivation sont tous les deux obligatoires.",fichier_type:"Seuls les fichiers PDF, Word (.doc, .docx) ou OpenDocument (.odt) sont acceptés.",fichier_taille:"Chaque fichier doit faire 5 Mo au maximum.",trop:"Vous avez déjà envoyé plusieurs candidatures. Appelez-nous au {TEL}.",indisponible:"Le formulaire est momentanément indisponible. Appelez-nous au {TEL}."}};
var q=new URLSearchParams(location.search),er=q.get('erreur'),fo=q.get('form');
document.querySelectorAll('.formulaire-candidature').forEach(function(f){{
  var out=f.querySelector('.message-form'),v=f.querySelector('.verif');
  function dire(t){{out.hidden=false;out.textContent=t;}}
  if(er&&ERREURS[er]&&f.id==='form-'+fo)dire(ERREURS[er]);
  fetch('api/jeton.php',{{cache:'no-store'}}).then(function(r){{return r.json();}}).then(function(d){{if(d.j)v.value=d.j;}}).catch(function(){{}});
  f.addEventListener('submit',function(e){{
    var fs=f.querySelectorAll('input[type=file]');
    for(var i=0;i<fs.length;i++){{var x=fs[i].files[0];if(!x){{e.preventDefault();return dire(ERREURS.fichier_manquant);}}
      if(!/\.(pdf|docx?|odt)$/i.test(x.name)){{e.preventDefault();return dire(ERREURS.fichier_type);}}
      if(x.size>5*1024*1024){{e.preventDefault();return dire(ERREURS.fichier_taille);}}}}
    if(location.protocol==='file:'||/claude|anthropic/.test(location.hostname)){{e.preventDefault();return dire("Aperçu : le formulaire fonctionne une fois le site installé sur un serveur PHP (hébergeur ou serveur local).");}}
    if(!v.value){{e.preventDefault();return dire("Merci de patienter quelques secondes avant d'envoyer.");}}
    f.querySelector('button[type=submit]').disabled=true;
  }});
}});
}})();
</script>"""
pages.append(page("emploi.html", "Emploi et stages en informatique à Ambarès et Pompignac | Les Techniciens",
    "Rejoignez Les Techniciens : candidature spontanée ou demande de stage dans nos magasins informatiques d'Ambarès-et-Lagrave et de Pompignac. Envoyez votre CV et votre lettre de motivation en ligne.",
    emploi, [breadcrumb_ld("emploi.html", "Emploi")]))

# ================= MERCI CANDIDATURE =================
merci_c = f"""<section class="page-titre"><div class="conteneur">
<span class="surtitre">Candidature envoyée</span>
<h1>Merci, votre candidature est bien arrivée</h1>
<p class="chapo">Nous étudions votre CV et votre lettre de motivation, et nous revenons vers vous par e-mail ou par téléphone.</p>
<div class="actions"><a class="btn btn--contour" href="index.html">Retour à l'accueil</a></div>
</div></section>"""
page("merci-candidature.html", "Merci | Les Techniciens", "Votre candidature a bien été envoyée.", merci_c, robots="noindex, follow")

# ================= CONTACT =================
contact = f'''<section class="page-titre"><div class="conteneur">
{fil([(None, "Contact")])}
<span class="surtitre">Contact</span>
<h1>Contacter Les Techniciens</h1>
<p class="chapo">Une panne, un devis, une question sur du matériel ? Le plus simple est de nous appeler. Vous pouvez aussi nous écrire avec le formulaire ci-dessous.</p>
</div></section>
<section class="section"><div class="conteneur duo">
<div>
  <h2>Demande de devis ou de rappel</h2>
  <form class="formulaire" id="formulaire" name="contact" method="POST" action="api/contact.php">
    <input type="hidden" name="verif" id="verif" value="">
    <p class="sr"><label for="site-web">Ne pas remplir</label><input id="site-web" name="site-web" tabindex="-1" autocomplete="off"></p>
    <div class="deux-champs">
      <div class="champ"><label for="nom">Nom</label><input id="nom" name="nom" autocomplete="name" required></div>
      <div class="champ"><label for="telephone">Téléphone</label><input id="telephone" name="telephone" type="tel" autocomplete="tel" required></div>
    </div>
    <div class="champ"><label for="email">E-mail</label><input id="email" name="email" type="email" autocomplete="email"></div>
    <div class="champ"><label for="sujet">Votre demande concerne</label>
      <select id="sujet" name="sujet">
        <option>Réparation d'un ordinateur ou d'un Mac</option>
        <option>Réparation d'un smartphone ou d'une tablette</option>
        <option>Achat de matériel</option>
        <option>Informatique d'entreprise</option>
        <option>Intervention à domicile ou à distance</option>
        <option>Formation</option>
        <option>Contrat d'assistance</option>
        <option>Autre</option>
      </select></div>
    <div class="champ"><label for="magasin">Magasin le plus proche</label>
      <select id="magasin" name="magasin"><option>Ambarès-et-Lagrave</option><option>Pompignac</option><option>Peu importe</option></select></div>
    <div class="champ"><label for="message">Décrivez votre besoin</label><textarea id="message" name="message" required placeholder="Marque et modèle de l'appareil, ce qui se passe, depuis quand…"></textarea></div>
    <p class="note">Vos coordonnées servent uniquement à répondre à votre demande. Voir nos <a href="mentions-legales.html#donnees">mentions légales</a>.</p>
    <div><button class="btn btn--rose" type="submit">Envoyer ma demande</button></div>
    <p class="message-form" id="message-form" hidden></p>
  </form>
</div>
<aside class="encart"><div class="coord">
  <div>{ico("tel")}<p style="margin:0"><strong>Téléphone</strong><a href="tel:{TEL_LIEN}">{TEL}</a></p></div>
  <div>{ico("mail")}<p style="margin:0"><strong>E-mail</strong>{mail()}</p></div>
  <div>{ico("facebook")}<p style="margin:0"><strong>Facebook</strong><a href="{FACEBOOK}" rel="noopener">Suivez-nous</a></p></div>
</div>
</aside>
</div></section>
<section class="section section--gris" id="magasins" aria-labelledby="magasins-titre"><div class="conteneur">
  <h2 id="magasins-titre">Nos magasins et horaires</h2>
  {cartes_magasins()}
</div></section>
<script>
(function(){{var f=document.querySelector('form.formulaire');if(!f)return;
var fm=new URLSearchParams(location.search).get('formule');if(fm){{var sj=document.getElementById('sujet');sj.value="Contrat d'assistance";var ms=document.getElementById('message');if(!ms.value)ms.value='Je souhaite souscrire au contrat '+fm+'.';}}
/* Jeton anti-robots : demandé au serveur à l'ouverture de la page, vérifié par api/contact.php */
var v=document.getElementById('verif'),out=document.getElementById('message-form');
function dire(txt){{out.hidden=false;out.textContent=txt;}}
fetch('api/jeton.php',{{cache:'no-store'}}).then(function(r){{return r.json();}}).then(function(d){{if(d.j)v.value=d.j;}}).catch(function(){{}});
var ERREURS={{verification:"Votre demande n'a pas pu être vérifiée. Patientez quelques secondes puis renvoyez-la.",incomplet:"Merci d'indiquer votre nom, votre téléphone et votre message.",email:"L'adresse e-mail semble incorrecte.",telephone:"Le numéro de téléphone semble incorrect.",liens:"Merci de retirer les liens de votre message, ou appelez-nous au {TEL}.",trop:"Vous avez déjà envoyé plusieurs demandes. Appelez-nous au {TEL}.",indisponible:"Le formulaire est momentanément indisponible. Appelez-nous au {TEL}."}};
var er=new URLSearchParams(location.search).get('erreur');if(er&&ERREURS[er])dire(ERREURS[er]);
f.addEventListener('submit',function(e){{
  if(location.protocol==='file:'||/claude|anthropic/.test(location.hostname)){{e.preventDefault();return dire("Aperçu : le formulaire fonctionne une fois le site installé sur un serveur PHP (hébergeur ou serveur local).");}}
  if(!v.value){{e.preventDefault();dire("Merci de patienter quelques secondes avant d'envoyer votre demande.");}}
}});}})();
</script>'''
pages.append(page("contact.html", "Contact et horaires | Les Techniciens, Ambarès et Pompignac",
    f"Contactez Les Techniciens, magasins à Ambarès-et-Lagrave et Pompignac : {TEL}. Demande de devis pour réparation, achat de matériel ou maintenance informatique.",
    contact, [breadcrumb_ld("contact.html", "Contact")] + LD_MAGASINS))

# ================= MERCI =================
merci = f'''<section class="page-titre"><div class="conteneur">
<span class="surtitre">Message envoyé</span>
<h1>Merci, votre demande est bien partie</h1>
<p class="chapo">Nous vous recontactons au plus vite pendant nos horaires d'ouverture. Pour une urgence, appelez le {TEL}.</p>
<div class="actions"><a class="btn btn--contour" href="index.html">Retour à l'accueil</a></div>
</div></section>'''
pages.append(page("merci.html", "Merci | Les Techniciens", "Votre demande a bien été envoyée.", merci, robots="noindex, follow"))

# ================= MENTIONS =================
ml = f'''<section class="page-titre"><div class="conteneur">
{fil([(None, "Mentions légales")])}
<h1>Mentions légales et confidentialité</h1>
</div></section>
<section class="section"><div class="conteneur contenu">
<h2>Éditeur du site</h2>
<p>SAS LESTECHNICIENS, SIREN 812 515 724<br>Siège social : 19 rue du Président Coty, {CP} {VILLE}<br>Téléphone : {TEL}. E-mail : {mail()}<br>Directeur de la publication : {masque(DIRECTEUR, "Afficher le nom")}<br>Capital social et numéro de TVA : [À COMPLÉTER]</p>
<h2>Hébergement</h2>
<p>[NOM DE L'HÉBERGEUR, ADRESSE, TÉLÉPHONE : À COMPLÉTER]</p>
<h2>Propriété intellectuelle</h2>
<p>Le logo, la charte graphique et les contenus de ce site appartiennent à SAS Lestechniciens. Toute reproduction sans autorisation est interdite.</p>
<h2 id="donnees">Données personnelles</h2>
<p>Les informations envoyées par le formulaire de contact (nom, téléphone, e-mail, message) servent uniquement à répondre à votre demande. Elles sont enregistrées dans une base de données chez notre hébergeur, consultables par la seule équipe Les Techniciens, ni vendues ni transmises à des tiers, et supprimées automatiquement au bout de trois ans.</p>
<p>Les candidatures (formulaires Emploi et Stage) et les documents joints (CV, lettre de motivation) sont conservés au maximum deux ans, puis supprimés automatiquement. Ils ne sont consultés que par les personnes chargées du recrutement.</p>
<p>Conformément au RGPD, vous pouvez demander l'accès, la rectification ou la suppression de vos données en nous écrivant à {mail()}. Vous pouvez aussi adresser une réclamation à la CNIL (cnil.fr).</p>
<h2>Cookies</h2>
<p>Ce site ne dépose pas de cookie publicitaire ni de mesure d'audience. Les polices de caractères sont chargées depuis Google Fonts. Un cookie technique est utilisé uniquement pour la connexion à l'espace de gestion réservé à l'équipe.</p>
</div></section>'''
pages.append(page("mentions-legales.html", "Mentions légales | Les Techniciens", "Mentions légales et politique de confidentialité du site Les Techniciens.", ml, robots="noindex, follow"))

# ================= 404 =================
p404 = f'''<section class="page-titre"><div class="conteneur">
<span class="surtitre">Erreur 404</span>
<h1>Cette page n'existe pas (ou plus)</h1>
<p class="chapo">Le site a fait peau neuve et certaines adresses ont changé. Retrouvez nos services depuis l'accueil, ou appelez-nous au {TEL}.</p>
<div class="actions"><a class="btn btn--rose" href="index.html">Retour à l'accueil</a><a class="btn btn--contour" href="contact.html">Nous contacter</a></div>
</div></section>'''
page("404.html", "Page introuvable | Les Techniciens", "Cette page n'existe pas.", p404, robots="noindex")

# ================= robots / sitemap / redirections =================
aujourd = datetime.date.today().isoformat()
indexables = [p for p in pages if p not in ("merci.html", "mentions-legales.html")]
prio = {"index.html": "1.0", "contact.html": "0.8"}
urls = "".join(f"<url><loc>{DOMAINE}/{propre(p)}</loc><lastmod>{aujourd}</lastmod><priority>{prio.get(p, '0.7')}</priority></url>\n" for p in indexables)
open(os.path.join(OUT, "sitemap.xml"), "w").write(f'<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n{urls}</urlset>\n')
open(os.path.join(OUT, "robots.txt"), "w").write(f"User-agent: *\nDisallow: /admin/\nDisallow: /api/\nDisallow: /lib/\nDisallow: /fichiers/\nDisallow: /install.php\n\nSitemap: {DOMAINE}/sitemap.xml\n")
# Anciennes adresses Wix connues → nouvelles pages (compléter avec la liste des anciennes pages)
REDIR = [("/d%C3%A9pannage", "/reparation-informatique.html"), ("/dépannage", "/reparation-informatique.html")]
if os.path.exists(os.path.join(OUT, "_redirects")): os.remove(os.path.join(OUT, "_redirects"))   # Netlify non utilisé
HTACCESS = """# Les Techniciens - configuration Apache (OVH, o2switch, Hostinger...)
# Volontairement sans directive « Options » : certains hébergeurs l'interdisent et renvoient alors une erreur 500.
DirectoryIndex index.html index.php
ErrorDocument 404 /404.html

# Fichiers techniques jamais servis
<FilesMatch "\.(sqlite|log|bak|ini|md|py)$">
  <IfModule mod_authz_core.c>
    Require all denied
  </IfModule>
  <IfModule !mod_authz_core.c>
    Order allow,deny
    Deny from all
  </IfModule>
</FilesMatch>

<IfModule mod_rewrite.c>
RewriteEngine On

# HTTPS et www : seulement sur le vrai domaine (une adresse de test provisoire n'est pas redirigée).
# Si le certificat HTTPS n'est pas encore actif, mettez un # devant les 6 lignes suivantes.
RewriteCond %{HTTP_HOST} ^lestechniciens\.fr$ [NC]
RewriteRule ^(.*)$ https://www.lestechniciens.fr/$1 [R=301,L]
RewriteCond %{HTTP_HOST} ^www\.lestechniciens\.fr$ [NC]
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP:X-Forwarded-Proto} !=https
RewriteRule ^(.*)$ https://www.lestechniciens.fr/$1 [R=301,L]

# Ancienne page du site Wix
RewriteRule ^dépannage/?$ /reparation-informatique [R=301,L]

# Adresses courtes : /contact affiche le fichier contact.html
# (les liens du site pointent vers les .html ; un petit script retire « .html » de la barre d'adresse sur le site en ligne)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.+?)/?$ $1.html [L]
</IfModule>

<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 month"
ExpiresByType image/webp "access plus 6 months"
ExpiresByType image/jpeg "access plus 6 months"
ExpiresByType image/png "access plus 6 months"
ExpiresByType image/svg+xml "access plus 6 months"
</IfModule>
"""
open(os.path.join(OUT, ".htaccess"), "w", encoding="utf-8").write(HTACCESS)
print("Pages générées :", ", ".join(pages + ["404.html"]))
