feat: conformite enonce - explorer, favoris, stats perso, tests, slots
Some checks failed
Deploy XIP / deploy (push) Failing after 37s

Fonctionnel
- Backend messages : GET /api/messages/:id (detail) + recherche (q),
  pagination par curseur (before/limit) avec enveloppe { items, nextCursor,
  hasMore } ; le flux temps reel garde l'ancien format quand aucun parametre.
- Explorer (/explorer) : catalogue distant, recherche debouncee + annulable
  (AbortController), filtre, defilement infini, etat garde (keep-alive).
- Details par id : /message/:id et /shop/p/:id (consomment route.params).
- Favoris (/favoris) : liste perso persistee en localStorage, notation
  (note/rating/statut) via modale, refletee partout (bouton favori).
- Mes stats (/mes-stats) : agregats derives des favoris (note moyenne, top
  pays/auteurs, statuts), auto-mis a jour, route gardee si liste vide.
- Routeur : pages secondaires en lazy-load + repli, garde beforeEnter.

Technique
- Slots : PrefSection (slot defaut + slot nomme) enveloppe les 5 sections
  "Mes Persos" ; Modal (Teleport + slots).
- v-model custom : SearchBox (defineModel + debounce).
- Directive custom : v-click-outside.
- Tests Vitest : 25 tests (etat, fonctions, composants), ~86% du code metier.
- Retrait d'Ionic (inutilise). Script typecheck backend ; tsconfig @types/bun.
- Correctif type : garde stockLimit nullable dans l'achat (catalog.ts).
- README complet (URL, stack, run, tests, secrets, deploiement, mention IA).
This commit is contained in:
2026-05-31 23:57:00 +02:00
committed by kerboul
parent 9dd72b9b2d
commit cfa2eadec9
111 changed files with 9634 additions and 7875 deletions

View File

@@ -1,247 +1,247 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720" width="1280" height="720">
<defs>
<style>
.sans { font-family: Arial, Helvetica, sans-serif; }
.mono { font-family: 'Courier New', Courier, monospace; }
</style>
<filter id="glow-gold"><feGaussianBlur stdDeviation="3"/></filter>
<filter id="glow-red"><feGaussianBlur stdDeviation="3"/></filter>
</defs>
<!-- FOND -->
<rect width="1280" height="720" fill="#090910"/>
<!-- ════════════════════ HEADER ════════════════════ -->
<rect x="0" y="0" width="1280" height="58" fill="#0e0e18" stroke="#1a1a28" stroke-width="1"/>
<text x="20" y="28" fill="#0077aa" class="sans" font-size="20" font-weight="bold" filter="url(#glow-gold)" opacity="0.4">XIP</text>
<text x="20" y="28" fill="#00aaee" class="sans" font-size="20" font-weight="bold">XIP</text>
<line x1="52" y1="10" x2="52" y2="48" stroke="#1e1e2a" stroke-width="1"/>
<text x="64" y="24" fill="#c0c0d8" class="sans" font-size="16" font-weight="bold">Shop</text>
<text x="64" y="43" fill="#383858" class="sans" font-size="10">Personnalisation · Accès · Publicité</text>
<text x="310" y="35" fill="#2a2a44" class="sans" font-size="11">Catalogue</text>
<text x="1148" y="22" fill="#383858" class="sans" font-size="10" text-anchor="end">Connecté :</text>
<text x="1148" y="40" fill="#5555aa" class="mono" font-size="11" text-anchor="end">192.168.1.45</text>
<text x="1260" y="22" fill="#3a5a2a" class="sans" font-size="10" text-anchor="end">Solde :</text>
<text x="1260" y="40" fill="#44aa44" class="sans" font-size="11" text-anchor="end" font-weight="bold">24.50 €</text>
<line x1="0" y1="58" x2="1280" y2="58" stroke="#1a1a28" stroke-width="1"/>
<!-- ════════════════════ LEFT NAV ════════════════════ -->
<rect x="0" y="58" width="185" height="662" fill="#0c0c12" stroke="#181822" stroke-width="1"/>
<line x1="184" y1="58" x2="184" y2="720" stroke="#161620" stroke-width="2"/>
<text x="16" y="84" fill="#2a2a44" class="sans" font-size="9" letter-spacing="2">CATÉGORIES</text>
<!-- Active item -->
<rect x="3" y="90" width="179" height="36" fill="#181828" stroke="#242438" rx="3"/>
<rect x="3" y="90" width="3" height="36" fill="#00aaee" rx="2"/>
<text x="20" y="113" fill="#aabbdd" class="sans" font-size="13" font-weight="bold">Tout voir</text>
<text x="20" y="153" fill="#4a4a6a" class="sans" font-size="13">Publicite</text>
<text x="20" y="188" fill="#4a4a6a" class="sans" font-size="13">Abonnements</text>
<text x="20" y="223" fill="#4a4a6a" class="sans" font-size="13">Cosmetiques</text>
<text x="20" y="258" fill="#cc3322" class="sans" font-size="13" font-weight="bold">Promotions</text>
<line x1="10" y1="272" x2="175" y2="272" stroke="#181822" stroke-width="1"/>
<text x="16" y="292" fill="#2a2a44" class="sans" font-size="9" letter-spacing="2">MON COMPTE</text>
<text x="20" y="316" fill="#4a4a6a" class="sans" font-size="13">Mes achats</text>
<text x="20" y="348" fill="#4a4a6a" class="sans" font-size="13">Paiement</text>
<!-- Solde dans nav -->
<rect x="10" y="660" width="165" height="50" fill="#111118" stroke="#1e1e28" rx="4"/>
<text x="93" y="679" fill="#2a2a44" text-anchor="middle" class="sans" font-size="9">Votre solde</text>
<text x="93" y="700" fill="#44aa44" text-anchor="middle" class="sans" font-size="16" font-weight="bold">24.50 €</text>
<!-- ════════════════════ CONTENU PRINCIPAL ════════════════════ -->
<!-- ── PROMO BANNER ── -->
<rect x="193" y="66" width="1079" height="72" fill="#180800" stroke="#bb3300" stroke-width="1.5" rx="6"/>
<rect x="193" y="66" width="170" height="72" fill="#220c00" rx="6"/>
<!-- Badge flash -->
<text x="278" y="92" fill="#ff5500" text-anchor="middle" class="sans" font-size="13" font-weight="bold">FLASH SALE</text>
<text x="278" y="112" fill="#774400" text-anchor="middle" class="sans" font-size="9">Offre limitee 2h47</text>
<line x1="363" y1="72" x2="363" y2="132" stroke="#331100" stroke-width="1"/>
<!-- Texte promo -->
<text x="380" y="90" fill="#ffcc00" class="sans" font-size="14" font-weight="bold">Pack Cosmetique — Style Dore + Pet</text>
<text x="380" y="110" fill="#cc6600" class="sans" font-size="12">14.99 € au lieu de 17.98 € —</text>
<text x="620" y="110" fill="#ff4444" class="sans" font-size="12" font-weight="bold">ECONOMISEZ 3 €</text>
<text x="380" y="128" fill="#553300" class="sans" font-size="10">Achat groupe · Stock limite : 47 restants</text>
<!-- Timer + CTA -->
<text x="880" y="92" fill="#ff8800" class="sans" font-size="11" font-weight="bold">Expire dans</text>
<text x="880" y="114" fill="#ffaa00" class="mono" font-size="16" font-weight="bold">02:47:33</text>
<rect x="1000" y="78" width="262" height="36" fill="#cc3300" rx="18"/>
<rect x="1001" y="79" width="260" height="34" fill="none" stroke="#ff6600" stroke-width="0.5" rx="18"/>
<text x="1131" y="101" fill="#ffffff" text-anchor="middle" class="sans" font-size="12" font-weight="bold">PROFITER DE L'OFFRE</text>
<!-- ── TITRE SECTION ── -->
<text x="200" y="162" fill="#7788aa" class="sans" font-size="14" font-weight="bold">Tous les articles</text>
<text x="1262" y="162" fill="#3a3a5a" text-anchor="end" class="sans" font-size="11">Trier : Popularite</text>
<!-- ══════════ CARD 1 : CADRE DE PUB ══════════ -->
<!-- x=193, y=172, w=532, h=236 -->
<rect x="193" y="172" width="532" height="236" fill="#111118" stroke="#1e1e2c" rx="6"/>
<!-- Badge promo -->
<rect x="193" y="172" width="112" height="22" fill="#bb2200" rx="6"/>
<text x="249" y="187" fill="#ffffff" text-anchor="middle" class="sans" font-size="9" font-weight="bold">-33% FLASH PROMO</text>
<!-- Image zone: mini XIP avec pub en surbrillance -->
<rect x="203" y="198" width="198" height="200" fill="#0c0c14" stroke="#181826" rx="4"/>
<rect x="209" y="204" width="186" height="20" fill="#131320" rx="2"/>
<text x="302" y="218" fill="#303055" text-anchor="middle" class="sans" font-size="8">XIP Chat</text>
<!-- Ad band highlighted -->
<rect x="209" y="228" width="44" height="158" fill="#1a1a10" stroke="#cc8800" stroke-width="2" rx="2"/>
<rect x="210" y="229" width="42" height="156" fill="none" stroke="#ffcc00" stroke-width="0.5" rx="1" opacity="0.5"/>
<text x="231" y="310" fill="#cc8800" text-anchor="middle" class="sans" font-size="8" transform="rotate(-90,231,310)">VOTRE PUB ICI</text>
<!-- Chat messages mockup -->
<rect x="259" y="232" width="120" height="10" fill="#161622" rx="1"/>
<rect x="259" y="247" width="88" height="8" fill="#131318" rx="1"/>
<rect x="259" y="260" width="100" height="8" fill="#131318" rx="1"/>
<rect x="259" y="273" width="72" height="8" fill="#131318" rx="1"/>
<rect x="259" y="290" width="110" height="10" fill="#161622" rx="1"/>
<rect x="259" y="305" width="80" height="8" fill="#131318" rx="1"/>
<rect x="259" y="318" width="95" height="8" fill="#131318" rx="1"/>
<rect x="259" y="331" width="60" height="8" fill="#131318" rx="1"/>
<rect x="209" y="372" width="186" height="12" fill="#131320" rx="2"/>
<text x="302" y="382" fill="#202040" text-anchor="middle" class="sans" font-size="7">[ saisie message ]</text>
<!-- Infos card -->
<text x="412" y="215" fill="#c8c8e0" class="sans" font-size="15" font-weight="bold">Cadre de Pub</text>
<text x="412" y="234" fill="#505070" class="sans" font-size="11">Espace publicitaire dans la bande gauche</text>
<text x="412" y="250" fill="#505070" class="sans" font-size="11">du chat, visible par tous les utilisateurs.</text>
<text x="412" y="274" fill="#3a5a3a" class="sans" font-size="11">+ 1 000 impressions garanties</text>
<text x="412" y="291" fill="#3a5a3a" class="sans" font-size="11">+ 7 jours de diffusion continue</text>
<text x="412" y="308" fill="#3a5a3a" class="sans" font-size="11">+ Format 130x180 px · lien cliquable</text>
<text x="412" y="328" fill="#884422" class="sans" font-size="10">/ Max. 1 cadre actif par compte</text>
<!-- Prix barré + promo + normal -->
<text x="412" y="355" fill="#444455" class="sans" font-size="12" text-decoration="line-through">22.50 €</text>
<text x="460" y="355" fill="#ee3333" class="sans" font-size="11" font-weight="bold">-33%</text>
<text x="412" y="380" fill="#ffdd00" class="sans" font-size="22" font-weight="bold">9.99 €</text>
<text x="412" y="397" fill="#444455" class="sans" font-size="9">Prix normal : 15.00 € | Promo expire dans 2h47</text>
<!-- Bouton acheter -->
<rect x="542" y="358" width="170" height="34" fill="#224488" rx="17"/>
<rect x="543" y="359" width="168" height="32" fill="none" stroke="#4466aa" stroke-width="0.5" rx="16"/>
<text x="627" y="380" fill="#ffffff" text-anchor="middle" class="sans" font-size="12" font-weight="bold">Acheter</text>
<!-- ══════════ CARD 2 : ABONNEMENT NOADS ══════════ -->
<!-- x=733, y=172, w=532, h=236 -->
<rect x="733" y="172" width="532" height="236" fill="#111118" stroke="#1e1e2c" rx="6"/>
<!-- Badge populaire -->
<rect x="733" y="172" width="100" height="22" fill="#2244aa" rx="6"/>
<text x="783" y="187" fill="#ffffff" text-anchor="middle" class="sans" font-size="9" font-weight="bold">POPULAIRE</text>
<!-- Image zone: XIP sans pub -->
<rect x="743" y="198" width="198" height="200" fill="#0c0c14" stroke="#181826" rx="4"/>
<rect x="749" y="204" width="186" height="20" fill="#131320" rx="2"/>
<text x="842" y="218" fill="#303055" text-anchor="middle" class="sans" font-size="8">XIP Chat — sans pubs</text>
<!-- Ad band GRISE (aucune pub) -->
<rect x="749" y="228" width="44" height="158" fill="#0e0e10" stroke="#222" stroke-width="1" rx="2"/>
<line x1="749" y1="228" x2="793" y2="386" stroke="#1e1e22" stroke-width="1"/>
<line x1="793" y1="228" x2="749" y2="386" stroke="#1e1e22" stroke-width="1"/>
<text x="771" y="310" fill="#1e1e2a" text-anchor="middle" class="sans" font-size="7" transform="rotate(-90,771,310)">PUB MASQUEE</text>
<!-- Chat normal -->
<rect x="799" y="232" width="120" height="10" fill="#161622" rx="1"/>
<rect x="799" y="247" width="88" height="8" fill="#131318" rx="1"/>
<rect x="799" y="260" width="100" height="8" fill="#131318" rx="1"/>
<rect x="799" y="273" width="72" height="8" fill="#131318" rx="1"/>
<rect x="799" y="290" width="110" height="10" fill="#161622" rx="1"/>
<rect x="799" y="305" width="80" height="8" fill="#131318" rx="1"/>
<!-- Checkmark vert sur la bande -->
<circle cx="771" cy="310" r="12" fill="#112211" stroke="#225522" stroke-width="1"/>
<text x="771" y="315" fill="#33aa44" text-anchor="middle" class="sans" font-size="14" font-weight="bold">X</text>
<!-- Infos card -->
<text x="952" y="215" fill="#c8c8e0" class="sans" font-size="15" font-weight="bold">Abonnement NoAds</text>
<text x="952" y="234" fill="#505070" class="sans" font-size="11">Supprimez toutes les publicites du</text>
<text x="952" y="250" fill="#505070" class="sans" font-size="11">chat tant que l'abonnement est actif.</text>
<text x="952" y="274" fill="#3a5a3a" class="sans" font-size="11">+ Bande gauche entierement masquee</text>
<text x="952" y="291" fill="#3a5a3a" class="sans" font-size="11">+ Annulable a tout moment</text>
<text x="952" y="308" fill="#3a5a3a" class="sans" font-size="11">+ -33% avec l'abonnement annuel</text>
<text x="952" y="328" fill="#884422" class="sans" font-size="10">/ 1 abonnement actif max par compte</text>
<!-- Prix -->
<text x="952" y="362" fill="#8888bb" class="sans" font-size="13">a partir de</text>
<text x="952" y="385" fill="#ffdd00" class="sans" font-size="22" font-weight="bold">4.99 €</text>
<text x="952" y="400" fill="#444455" class="sans" font-size="9">/mois | Annuel : 39.99 € (3.33 €/mois)</text>
<!-- Bouton -->
<rect x="1082" y="358" width="170" height="34" fill="#224488" rx="17"/>
<text x="1167" y="380" fill="#ffffff" text-anchor="middle" class="sans" font-size="12" font-weight="bold">Voir les offres</text>
<!-- ══════════ CARD 3 : STYLE DORE ══════════ -->
<!-- x=193, y=416, w=532, h=234 -->
<rect x="193" y="416" width="532" height="236" fill="#111118" stroke="#1e1e2c" rx="6"/>
<!-- Badge limité + or -->
<rect x="193" y="416" width="88" height="22" fill="#664400" rx="6"/>
<text x="237" y="431" fill="#ffcc00" text-anchor="middle" class="sans" font-size="9" font-weight="bold">LIMITE 50 ex.</text>
<!-- Image zone: nom en or -->
<rect x="203" y="442" width="198" height="200" fill="#0c0c14" stroke="#181826" rx="4"/>
<!-- Fond avec gradient doré subtil -->
<rect x="209" y="448" width="186" height="186" fill="#0e0a04" rx="2"/>
<!-- Avant/Après -->
<text x="302" y="475" fill="#303030" text-anchor="middle" class="sans" font-size="9">AVANT</text>
<text x="302" y="492" fill="#606080" class="mono" font-size="11" text-anchor="middle">192.168.1.45</text>
<line x1="215" y1="506" x2="390" y2="506" stroke="#222" stroke-width="0.5"/>
<text x="302" y="522" fill="#303030" text-anchor="middle" class="sans" font-size="9">APRES</text>
<!-- Nom en or avec glow -->
<text x="302" y="546" fill="#996600" text-anchor="middle" class="mono" font-size="12" font-weight="bold" filter="url(#glow-gold)" opacity="0.9">192.168.1.45</text>
<text x="302" y="546" fill="#ffdd44" text-anchor="middle" class="mono" font-size="12" font-weight="bold">192.168.1.45</text>
<rect x="242" y="555" width="120" height="16" fill="#1a1400" stroke="#443300" rx="2"/>
<text x="302" y="567" fill="#886600" text-anchor="middle" class="sans" font-size="8">Style Dore actif</text>
<!-- Couronne decorative -->
<text x="302" y="610" fill="#886600" text-anchor="middle" class="sans" font-size="28">&#9818;</text>
<text x="302" y="630" fill="#553300" text-anchor="middle" class="sans" font-size="8">decoration du nom</text>
<!-- Infos card -->
<text x="412" y="458" fill="#c8c8e0" class="sans" font-size="15" font-weight="bold">Style Dore</text>
<text x="412" y="477" fill="#505070" class="sans" font-size="11">Votre adresse IP s'affiche en doree</text>
<text x="412" y="493" fill="#505070" class="sans" font-size="11">avec un effet lumineux dans le chat.</text>
<text x="412" y="517" fill="#3a5a3a" class="sans" font-size="11">+ Nom en couleur or avec lueur</text>
<text x="412" y="534" fill="#3a5a3a" class="sans" font-size="11">+ Visible par tous dans le chat</text>
<text x="412" y="551" fill="#3a5a3a" class="sans" font-size="11">+ Permanant (non expirant)</text>
<text x="412" y="571" fill="#884422" class="sans" font-size="10">/ 1 style actif a la fois · non remboursable</text>
<text x="412" y="585" fill="#884422" class="sans" font-size="10">/ Stock limite : 50 exemplaires disponibles</text>
<!-- Prix -->
<text x="412" y="615" fill="#ffdd00" class="sans" font-size="22" font-weight="bold">9.99 €</text>
<text x="412" y="631" fill="#444455" class="sans" font-size="9">Achat unique · Permanent</text>
<!-- Bouton -->
<rect x="542" y="598" width="170" height="34" fill="#664400" rx="17"/>
<rect x="543" y="599" width="168" height="32" fill="none" stroke="#cc8800" stroke-width="0.5" rx="16"/>
<text x="627" y="620" fill="#ffcc00" text-anchor="middle" class="sans" font-size="12" font-weight="bold">Acheter</text>
<!-- ══════════ CARD 4 : PET ══════════ -->
<!-- x=733, y=416, w=532, h=236 -->
<rect x="733" y="416" width="532" height="236" fill="#111118" stroke="#1e1e2c" rx="6"/>
<!-- Badge NEW -->
<rect x="733" y="416" width="60" height="22" fill="#226644" rx="6"/>
<text x="763" y="431" fill="#44ffaa" text-anchor="middle" class="sans" font-size="9" font-weight="bold">NOUVEAU</text>
<!-- Image zone: nom avec pet -->
<rect x="743" y="442" width="198" height="200" fill="#0c0c14" stroke="#181826" rx="4"/>
<rect x="749" y="448" width="186" height="186" fill="#0a0c0a" rx="2"/>
<!-- Preview: IP avec pet -->
<text x="842" y="490" fill="#2a3a2a" text-anchor="middle" class="sans" font-size="8">apercu dans le chat</text>
<!-- Pet a gauche du nom -->
<text x="766" y="524" fill="#33aa66" class="sans" font-size="20">&#9829;</text>
<text x="800" y="524" fill="#606080" class="mono" font-size="11">192.168.1.45</text>
<text x="916" y="524" fill="#33aa66" class="sans" font-size="20">&#9829;</text>
<!-- Ligne 2: autre pet -->
<text x="766" y="554" fill="#aa6633" class="sans" font-size="18">&#9733;</text>
<text x="800" y="554" fill="#606080" class="mono" font-size="11">10.0.0.187</text>
<!-- Ligne 3: sans pet -->
<text x="800" y="582" fill="#404055" class="mono" font-size="11">172.31.0.5</text>
<!-- Badge "3 max" -->
<rect x="756" y="598" width="172" height="16" fill="#0a1a0a" stroke="#224422" rx="2"/>
<text x="842" y="610" fill="#226622" text-anchor="middle" class="sans" font-size="8">Max. 3 pets actifs simultanement</text>
<!-- Infos card -->
<text x="952" y="458" fill="#c8c8e0" class="sans" font-size="15" font-weight="bold">Pet de Nom</text>
<text x="952" y="477" fill="#505070" class="sans" font-size="11">Ajoutez un petit element decoratif</text>
<text x="952" y="493" fill="#505070" class="sans" font-size="11">qui s'affiche autour de votre IP.</text>
<text x="952" y="517" fill="#3a5a3a" class="sans" font-size="11">+ Visible par tous les utilisateurs</text>
<text x="952" y="534" fill="#3a5a3a" class="sans" font-size="11">+ Choix parmi 20+ designs</text>
<text x="952" y="551" fill="#3a5a3a" class="sans" font-size="11">+ Position gauche, droite ou les deux</text>
<text x="952" y="571" fill="#884422" class="sans" font-size="10">/ Max. 3 pets actifs par compte</text>
<text x="952" y="585" fill="#884422" class="sans" font-size="10">/ Non remboursable apres activation</text>
<!-- Prix -->
<text x="952" y="615" fill="#ffdd00" class="sans" font-size="22" font-weight="bold">7.99 €</text>
<text x="952" y="631" fill="#444455" class="sans" font-size="9">par pet · Achat unique · Permanent</text>
<!-- Bouton -->
<rect x="1082" y="598" width="170" height="34" fill="#226644" rx="17"/>
<rect x="1083" y="599" width="168" height="32" fill="none" stroke="#44aa88" stroke-width="0.5" rx="16"/>
<text x="1167" y="620" fill="#ffffff" text-anchor="middle" class="sans" font-size="12" font-weight="bold">Choisir un pet</text>
<!-- FOOTER INFO -->
<rect x="0" y="688" width="1280" height="32" fill="#080810" stroke="#141420" stroke-width="1"/>
<text x="640" y="708" fill="#222233" text-anchor="middle" class="sans" font-size="9">XIP Shop · Les achats sont definitifs sauf mention contraire · Voir les Conditions Generales de Vente · Support : shop@xip.local</text>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720" width="1280" height="720">
<defs>
<style>
.sans { font-family: Arial, Helvetica, sans-serif; }
.mono { font-family: 'Courier New', Courier, monospace; }
</style>
<filter id="glow-gold"><feGaussianBlur stdDeviation="3"/></filter>
<filter id="glow-red"><feGaussianBlur stdDeviation="3"/></filter>
</defs>
<!-- FOND -->
<rect width="1280" height="720" fill="#090910"/>
<!-- ════════════════════ HEADER ════════════════════ -->
<rect x="0" y="0" width="1280" height="58" fill="#0e0e18" stroke="#1a1a28" stroke-width="1"/>
<text x="20" y="28" fill="#0077aa" class="sans" font-size="20" font-weight="bold" filter="url(#glow-gold)" opacity="0.4">XIP</text>
<text x="20" y="28" fill="#00aaee" class="sans" font-size="20" font-weight="bold">XIP</text>
<line x1="52" y1="10" x2="52" y2="48" stroke="#1e1e2a" stroke-width="1"/>
<text x="64" y="24" fill="#c0c0d8" class="sans" font-size="16" font-weight="bold">Shop</text>
<text x="64" y="43" fill="#383858" class="sans" font-size="10">Personnalisation · Accès · Publicité</text>
<text x="310" y="35" fill="#2a2a44" class="sans" font-size="11">Catalogue</text>
<text x="1148" y="22" fill="#383858" class="sans" font-size="10" text-anchor="end">Connecté :</text>
<text x="1148" y="40" fill="#5555aa" class="mono" font-size="11" text-anchor="end">192.168.1.45</text>
<text x="1260" y="22" fill="#3a5a2a" class="sans" font-size="10" text-anchor="end">Solde :</text>
<text x="1260" y="40" fill="#44aa44" class="sans" font-size="11" text-anchor="end" font-weight="bold">24.50 €</text>
<line x1="0" y1="58" x2="1280" y2="58" stroke="#1a1a28" stroke-width="1"/>
<!-- ════════════════════ LEFT NAV ════════════════════ -->
<rect x="0" y="58" width="185" height="662" fill="#0c0c12" stroke="#181822" stroke-width="1"/>
<line x1="184" y1="58" x2="184" y2="720" stroke="#161620" stroke-width="2"/>
<text x="16" y="84" fill="#2a2a44" class="sans" font-size="9" letter-spacing="2">CATÉGORIES</text>
<!-- Active item -->
<rect x="3" y="90" width="179" height="36" fill="#181828" stroke="#242438" rx="3"/>
<rect x="3" y="90" width="3" height="36" fill="#00aaee" rx="2"/>
<text x="20" y="113" fill="#aabbdd" class="sans" font-size="13" font-weight="bold">Tout voir</text>
<text x="20" y="153" fill="#4a4a6a" class="sans" font-size="13">Publicite</text>
<text x="20" y="188" fill="#4a4a6a" class="sans" font-size="13">Abonnements</text>
<text x="20" y="223" fill="#4a4a6a" class="sans" font-size="13">Cosmetiques</text>
<text x="20" y="258" fill="#cc3322" class="sans" font-size="13" font-weight="bold">Promotions</text>
<line x1="10" y1="272" x2="175" y2="272" stroke="#181822" stroke-width="1"/>
<text x="16" y="292" fill="#2a2a44" class="sans" font-size="9" letter-spacing="2">MON COMPTE</text>
<text x="20" y="316" fill="#4a4a6a" class="sans" font-size="13">Mes achats</text>
<text x="20" y="348" fill="#4a4a6a" class="sans" font-size="13">Paiement</text>
<!-- Solde dans nav -->
<rect x="10" y="660" width="165" height="50" fill="#111118" stroke="#1e1e28" rx="4"/>
<text x="93" y="679" fill="#2a2a44" text-anchor="middle" class="sans" font-size="9">Votre solde</text>
<text x="93" y="700" fill="#44aa44" text-anchor="middle" class="sans" font-size="16" font-weight="bold">24.50 €</text>
<!-- ════════════════════ CONTENU PRINCIPAL ════════════════════ -->
<!-- ── PROMO BANNER ── -->
<rect x="193" y="66" width="1079" height="72" fill="#180800" stroke="#bb3300" stroke-width="1.5" rx="6"/>
<rect x="193" y="66" width="170" height="72" fill="#220c00" rx="6"/>
<!-- Badge flash -->
<text x="278" y="92" fill="#ff5500" text-anchor="middle" class="sans" font-size="13" font-weight="bold">FLASH SALE</text>
<text x="278" y="112" fill="#774400" text-anchor="middle" class="sans" font-size="9">Offre limitee 2h47</text>
<line x1="363" y1="72" x2="363" y2="132" stroke="#331100" stroke-width="1"/>
<!-- Texte promo -->
<text x="380" y="90" fill="#ffcc00" class="sans" font-size="14" font-weight="bold">Pack Cosmetique — Style Dore + Pet</text>
<text x="380" y="110" fill="#cc6600" class="sans" font-size="12">14.99 € au lieu de 17.98 € —</text>
<text x="620" y="110" fill="#ff4444" class="sans" font-size="12" font-weight="bold">ECONOMISEZ 3 €</text>
<text x="380" y="128" fill="#553300" class="sans" font-size="10">Achat groupe · Stock limite : 47 restants</text>
<!-- Timer + CTA -->
<text x="880" y="92" fill="#ff8800" class="sans" font-size="11" font-weight="bold">Expire dans</text>
<text x="880" y="114" fill="#ffaa00" class="mono" font-size="16" font-weight="bold">02:47:33</text>
<rect x="1000" y="78" width="262" height="36" fill="#cc3300" rx="18"/>
<rect x="1001" y="79" width="260" height="34" fill="none" stroke="#ff6600" stroke-width="0.5" rx="18"/>
<text x="1131" y="101" fill="#ffffff" text-anchor="middle" class="sans" font-size="12" font-weight="bold">PROFITER DE L'OFFRE</text>
<!-- ── TITRE SECTION ── -->
<text x="200" y="162" fill="#7788aa" class="sans" font-size="14" font-weight="bold">Tous les articles</text>
<text x="1262" y="162" fill="#3a3a5a" text-anchor="end" class="sans" font-size="11">Trier : Popularite</text>
<!-- ══════════ CARD 1 : CADRE DE PUB ══════════ -->
<!-- x=193, y=172, w=532, h=236 -->
<rect x="193" y="172" width="532" height="236" fill="#111118" stroke="#1e1e2c" rx="6"/>
<!-- Badge promo -->
<rect x="193" y="172" width="112" height="22" fill="#bb2200" rx="6"/>
<text x="249" y="187" fill="#ffffff" text-anchor="middle" class="sans" font-size="9" font-weight="bold">-33% FLASH PROMO</text>
<!-- Image zone: mini XIP avec pub en surbrillance -->
<rect x="203" y="198" width="198" height="200" fill="#0c0c14" stroke="#181826" rx="4"/>
<rect x="209" y="204" width="186" height="20" fill="#131320" rx="2"/>
<text x="302" y="218" fill="#303055" text-anchor="middle" class="sans" font-size="8">XIP Chat</text>
<!-- Ad band highlighted -->
<rect x="209" y="228" width="44" height="158" fill="#1a1a10" stroke="#cc8800" stroke-width="2" rx="2"/>
<rect x="210" y="229" width="42" height="156" fill="none" stroke="#ffcc00" stroke-width="0.5" rx="1" opacity="0.5"/>
<text x="231" y="310" fill="#cc8800" text-anchor="middle" class="sans" font-size="8" transform="rotate(-90,231,310)">VOTRE PUB ICI</text>
<!-- Chat messages mockup -->
<rect x="259" y="232" width="120" height="10" fill="#161622" rx="1"/>
<rect x="259" y="247" width="88" height="8" fill="#131318" rx="1"/>
<rect x="259" y="260" width="100" height="8" fill="#131318" rx="1"/>
<rect x="259" y="273" width="72" height="8" fill="#131318" rx="1"/>
<rect x="259" y="290" width="110" height="10" fill="#161622" rx="1"/>
<rect x="259" y="305" width="80" height="8" fill="#131318" rx="1"/>
<rect x="259" y="318" width="95" height="8" fill="#131318" rx="1"/>
<rect x="259" y="331" width="60" height="8" fill="#131318" rx="1"/>
<rect x="209" y="372" width="186" height="12" fill="#131320" rx="2"/>
<text x="302" y="382" fill="#202040" text-anchor="middle" class="sans" font-size="7">[ saisie message ]</text>
<!-- Infos card -->
<text x="412" y="215" fill="#c8c8e0" class="sans" font-size="15" font-weight="bold">Cadre de Pub</text>
<text x="412" y="234" fill="#505070" class="sans" font-size="11">Espace publicitaire dans la bande gauche</text>
<text x="412" y="250" fill="#505070" class="sans" font-size="11">du chat, visible par tous les utilisateurs.</text>
<text x="412" y="274" fill="#3a5a3a" class="sans" font-size="11">+ 1 000 impressions garanties</text>
<text x="412" y="291" fill="#3a5a3a" class="sans" font-size="11">+ 7 jours de diffusion continue</text>
<text x="412" y="308" fill="#3a5a3a" class="sans" font-size="11">+ Format 130x180 px · lien cliquable</text>
<text x="412" y="328" fill="#884422" class="sans" font-size="10">/ Max. 1 cadre actif par compte</text>
<!-- Prix barré + promo + normal -->
<text x="412" y="355" fill="#444455" class="sans" font-size="12" text-decoration="line-through">22.50 €</text>
<text x="460" y="355" fill="#ee3333" class="sans" font-size="11" font-weight="bold">-33%</text>
<text x="412" y="380" fill="#ffdd00" class="sans" font-size="22" font-weight="bold">9.99 €</text>
<text x="412" y="397" fill="#444455" class="sans" font-size="9">Prix normal : 15.00 € | Promo expire dans 2h47</text>
<!-- Bouton acheter -->
<rect x="542" y="358" width="170" height="34" fill="#224488" rx="17"/>
<rect x="543" y="359" width="168" height="32" fill="none" stroke="#4466aa" stroke-width="0.5" rx="16"/>
<text x="627" y="380" fill="#ffffff" text-anchor="middle" class="sans" font-size="12" font-weight="bold">Acheter</text>
<!-- ══════════ CARD 2 : ABONNEMENT NOADS ══════════ -->
<!-- x=733, y=172, w=532, h=236 -->
<rect x="733" y="172" width="532" height="236" fill="#111118" stroke="#1e1e2c" rx="6"/>
<!-- Badge populaire -->
<rect x="733" y="172" width="100" height="22" fill="#2244aa" rx="6"/>
<text x="783" y="187" fill="#ffffff" text-anchor="middle" class="sans" font-size="9" font-weight="bold">POPULAIRE</text>
<!-- Image zone: XIP sans pub -->
<rect x="743" y="198" width="198" height="200" fill="#0c0c14" stroke="#181826" rx="4"/>
<rect x="749" y="204" width="186" height="20" fill="#131320" rx="2"/>
<text x="842" y="218" fill="#303055" text-anchor="middle" class="sans" font-size="8">XIP Chat — sans pubs</text>
<!-- Ad band GRISE (aucune pub) -->
<rect x="749" y="228" width="44" height="158" fill="#0e0e10" stroke="#222" stroke-width="1" rx="2"/>
<line x1="749" y1="228" x2="793" y2="386" stroke="#1e1e22" stroke-width="1"/>
<line x1="793" y1="228" x2="749" y2="386" stroke="#1e1e22" stroke-width="1"/>
<text x="771" y="310" fill="#1e1e2a" text-anchor="middle" class="sans" font-size="7" transform="rotate(-90,771,310)">PUB MASQUEE</text>
<!-- Chat normal -->
<rect x="799" y="232" width="120" height="10" fill="#161622" rx="1"/>
<rect x="799" y="247" width="88" height="8" fill="#131318" rx="1"/>
<rect x="799" y="260" width="100" height="8" fill="#131318" rx="1"/>
<rect x="799" y="273" width="72" height="8" fill="#131318" rx="1"/>
<rect x="799" y="290" width="110" height="10" fill="#161622" rx="1"/>
<rect x="799" y="305" width="80" height="8" fill="#131318" rx="1"/>
<!-- Checkmark vert sur la bande -->
<circle cx="771" cy="310" r="12" fill="#112211" stroke="#225522" stroke-width="1"/>
<text x="771" y="315" fill="#33aa44" text-anchor="middle" class="sans" font-size="14" font-weight="bold">X</text>
<!-- Infos card -->
<text x="952" y="215" fill="#c8c8e0" class="sans" font-size="15" font-weight="bold">Abonnement NoAds</text>
<text x="952" y="234" fill="#505070" class="sans" font-size="11">Supprimez toutes les publicites du</text>
<text x="952" y="250" fill="#505070" class="sans" font-size="11">chat tant que l'abonnement est actif.</text>
<text x="952" y="274" fill="#3a5a3a" class="sans" font-size="11">+ Bande gauche entierement masquee</text>
<text x="952" y="291" fill="#3a5a3a" class="sans" font-size="11">+ Annulable a tout moment</text>
<text x="952" y="308" fill="#3a5a3a" class="sans" font-size="11">+ -33% avec l'abonnement annuel</text>
<text x="952" y="328" fill="#884422" class="sans" font-size="10">/ 1 abonnement actif max par compte</text>
<!-- Prix -->
<text x="952" y="362" fill="#8888bb" class="sans" font-size="13">a partir de</text>
<text x="952" y="385" fill="#ffdd00" class="sans" font-size="22" font-weight="bold">4.99 €</text>
<text x="952" y="400" fill="#444455" class="sans" font-size="9">/mois | Annuel : 39.99 € (3.33 €/mois)</text>
<!-- Bouton -->
<rect x="1082" y="358" width="170" height="34" fill="#224488" rx="17"/>
<text x="1167" y="380" fill="#ffffff" text-anchor="middle" class="sans" font-size="12" font-weight="bold">Voir les offres</text>
<!-- ══════════ CARD 3 : STYLE DORE ══════════ -->
<!-- x=193, y=416, w=532, h=234 -->
<rect x="193" y="416" width="532" height="236" fill="#111118" stroke="#1e1e2c" rx="6"/>
<!-- Badge limité + or -->
<rect x="193" y="416" width="88" height="22" fill="#664400" rx="6"/>
<text x="237" y="431" fill="#ffcc00" text-anchor="middle" class="sans" font-size="9" font-weight="bold">LIMITE 50 ex.</text>
<!-- Image zone: nom en or -->
<rect x="203" y="442" width="198" height="200" fill="#0c0c14" stroke="#181826" rx="4"/>
<!-- Fond avec gradient doré subtil -->
<rect x="209" y="448" width="186" height="186" fill="#0e0a04" rx="2"/>
<!-- Avant/Après -->
<text x="302" y="475" fill="#303030" text-anchor="middle" class="sans" font-size="9">AVANT</text>
<text x="302" y="492" fill="#606080" class="mono" font-size="11" text-anchor="middle">192.168.1.45</text>
<line x1="215" y1="506" x2="390" y2="506" stroke="#222" stroke-width="0.5"/>
<text x="302" y="522" fill="#303030" text-anchor="middle" class="sans" font-size="9">APRES</text>
<!-- Nom en or avec glow -->
<text x="302" y="546" fill="#996600" text-anchor="middle" class="mono" font-size="12" font-weight="bold" filter="url(#glow-gold)" opacity="0.9">192.168.1.45</text>
<text x="302" y="546" fill="#ffdd44" text-anchor="middle" class="mono" font-size="12" font-weight="bold">192.168.1.45</text>
<rect x="242" y="555" width="120" height="16" fill="#1a1400" stroke="#443300" rx="2"/>
<text x="302" y="567" fill="#886600" text-anchor="middle" class="sans" font-size="8">Style Dore actif</text>
<!-- Couronne decorative -->
<text x="302" y="610" fill="#886600" text-anchor="middle" class="sans" font-size="28">&#9818;</text>
<text x="302" y="630" fill="#553300" text-anchor="middle" class="sans" font-size="8">decoration du nom</text>
<!-- Infos card -->
<text x="412" y="458" fill="#c8c8e0" class="sans" font-size="15" font-weight="bold">Style Dore</text>
<text x="412" y="477" fill="#505070" class="sans" font-size="11">Votre adresse IP s'affiche en doree</text>
<text x="412" y="493" fill="#505070" class="sans" font-size="11">avec un effet lumineux dans le chat.</text>
<text x="412" y="517" fill="#3a5a3a" class="sans" font-size="11">+ Nom en couleur or avec lueur</text>
<text x="412" y="534" fill="#3a5a3a" class="sans" font-size="11">+ Visible par tous dans le chat</text>
<text x="412" y="551" fill="#3a5a3a" class="sans" font-size="11">+ Permanant (non expirant)</text>
<text x="412" y="571" fill="#884422" class="sans" font-size="10">/ 1 style actif a la fois · non remboursable</text>
<text x="412" y="585" fill="#884422" class="sans" font-size="10">/ Stock limite : 50 exemplaires disponibles</text>
<!-- Prix -->
<text x="412" y="615" fill="#ffdd00" class="sans" font-size="22" font-weight="bold">9.99 €</text>
<text x="412" y="631" fill="#444455" class="sans" font-size="9">Achat unique · Permanent</text>
<!-- Bouton -->
<rect x="542" y="598" width="170" height="34" fill="#664400" rx="17"/>
<rect x="543" y="599" width="168" height="32" fill="none" stroke="#cc8800" stroke-width="0.5" rx="16"/>
<text x="627" y="620" fill="#ffcc00" text-anchor="middle" class="sans" font-size="12" font-weight="bold">Acheter</text>
<!-- ══════════ CARD 4 : PET ══════════ -->
<!-- x=733, y=416, w=532, h=236 -->
<rect x="733" y="416" width="532" height="236" fill="#111118" stroke="#1e1e2c" rx="6"/>
<!-- Badge NEW -->
<rect x="733" y="416" width="60" height="22" fill="#226644" rx="6"/>
<text x="763" y="431" fill="#44ffaa" text-anchor="middle" class="sans" font-size="9" font-weight="bold">NOUVEAU</text>
<!-- Image zone: nom avec pet -->
<rect x="743" y="442" width="198" height="200" fill="#0c0c14" stroke="#181826" rx="4"/>
<rect x="749" y="448" width="186" height="186" fill="#0a0c0a" rx="2"/>
<!-- Preview: IP avec pet -->
<text x="842" y="490" fill="#2a3a2a" text-anchor="middle" class="sans" font-size="8">apercu dans le chat</text>
<!-- Pet a gauche du nom -->
<text x="766" y="524" fill="#33aa66" class="sans" font-size="20">&#9829;</text>
<text x="800" y="524" fill="#606080" class="mono" font-size="11">192.168.1.45</text>
<text x="916" y="524" fill="#33aa66" class="sans" font-size="20">&#9829;</text>
<!-- Ligne 2: autre pet -->
<text x="766" y="554" fill="#aa6633" class="sans" font-size="18">&#9733;</text>
<text x="800" y="554" fill="#606080" class="mono" font-size="11">10.0.0.187</text>
<!-- Ligne 3: sans pet -->
<text x="800" y="582" fill="#404055" class="mono" font-size="11">172.31.0.5</text>
<!-- Badge "3 max" -->
<rect x="756" y="598" width="172" height="16" fill="#0a1a0a" stroke="#224422" rx="2"/>
<text x="842" y="610" fill="#226622" text-anchor="middle" class="sans" font-size="8">Max. 3 pets actifs simultanement</text>
<!-- Infos card -->
<text x="952" y="458" fill="#c8c8e0" class="sans" font-size="15" font-weight="bold">Pet de Nom</text>
<text x="952" y="477" fill="#505070" class="sans" font-size="11">Ajoutez un petit element decoratif</text>
<text x="952" y="493" fill="#505070" class="sans" font-size="11">qui s'affiche autour de votre IP.</text>
<text x="952" y="517" fill="#3a5a3a" class="sans" font-size="11">+ Visible par tous les utilisateurs</text>
<text x="952" y="534" fill="#3a5a3a" class="sans" font-size="11">+ Choix parmi 20+ designs</text>
<text x="952" y="551" fill="#3a5a3a" class="sans" font-size="11">+ Position gauche, droite ou les deux</text>
<text x="952" y="571" fill="#884422" class="sans" font-size="10">/ Max. 3 pets actifs par compte</text>
<text x="952" y="585" fill="#884422" class="sans" font-size="10">/ Non remboursable apres activation</text>
<!-- Prix -->
<text x="952" y="615" fill="#ffdd00" class="sans" font-size="22" font-weight="bold">7.99 €</text>
<text x="952" y="631" fill="#444455" class="sans" font-size="9">par pet · Achat unique · Permanent</text>
<!-- Bouton -->
<rect x="1082" y="598" width="170" height="34" fill="#226644" rx="17"/>
<rect x="1083" y="599" width="168" height="32" fill="none" stroke="#44aa88" stroke-width="0.5" rx="16"/>
<text x="1167" y="620" fill="#ffffff" text-anchor="middle" class="sans" font-size="12" font-weight="bold">Choisir un pet</text>
<!-- FOOTER INFO -->
<rect x="0" y="688" width="1280" height="32" fill="#080810" stroke="#141420" stroke-width="1"/>
<text x="640" y="708" fill="#222233" text-anchor="middle" class="sans" font-size="9">XIP Shop · Les achats sont definitifs sauf mention contraire · Voir les Conditions Generales de Vente · Support : shop@xip.local</text>
</svg>

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB