From 0edeeacbe28476c89ec5e40ca833b09793adb442 Mon Sep 17 00:00:00 2001 From: ordinarthur Date: Wed, 25 Feb 2026 15:49:18 +0100 Subject: [PATCH] v3 ? --- public/main.js | 6 +-- public/style.css | 45 ++++++++++++++++-- server.ts | 120 ----------------------------------------------- 3 files changed, 45 insertions(+), 126 deletions(-) delete mode 100644 server.ts diff --git a/public/main.js b/public/main.js index 4e4a189..f8d2a35 100644 --- a/public/main.js +++ b/public/main.js @@ -57,9 +57,9 @@ document.addEventListener('DOMContentLoaded', () => { const gridContainer = document.getElementById('interactive-grid'); const CELL = 60; const COLORS = [ - 'rgba(160,160,155,0.3)', - 'rgba(140,140,135,0.22)', - 'rgba(120,120,115,0.18)', + 'rgba(232,168,0,0.45)', + 'rgba(232,168,0,0.32)', + 'rgba(232,168,0,0.18)', ]; function buildGrid() { diff --git a/public/style.css b/public/style.css index a926a81..126cf5e 100644 --- a/public/style.css +++ b/public/style.css @@ -29,7 +29,7 @@ body { /* ---- CURSOR ---- */ .cursor-dot { width: 5px; height: 5px; - background: var(--clr-black); + background: var(--clr-red); position: fixed; top: 0; left: 0; transform: translate(-50%, -50%); pointer-events: none; @@ -605,7 +605,7 @@ hr { border: none; border-top: var(--border); margin: 0; } transition: background 0.15s; pointer-events: auto; } -.nl-row button:hover { background: var(--clr-red); } +.nl-row button:hover { background: var(--clr-red); color: var(--clr-black); } /* ---- FOOTER ---- */ .footer { @@ -625,13 +625,52 @@ hr { border: none; border-top: var(--border); margin: 0; } /* ---- RESPONSIVE ---- */ @media (max-width: 900px) { .hero, .newsletter { grid-template-columns: 1fr; } - .hero-left { border-right: none; border-bottom: var(--border); min-height: 55vw; padding: 3rem var(--pad); } + .hero-left { border-right: none; border-bottom: var(--border); min-height: 70vw; padding: 3rem var(--pad); } .hero-right { height: 55vw; } .nl-left { border-right: none; border-bottom: var(--border); } .product-grid { grid-template-columns: 1fr 1fr; } .panel-inner { grid-template-columns: 1fr; } .panel-img-col { height: 50vw; } .panel-info-col { overflow-y: auto; } + + /* Floats : repositionnés pour la colonne pleine largeur */ + .hero-float:nth-child(1) { + width: clamp(80px, 22vw, 140px); + top: 6%; + left: 5%; + } + .hero-float:nth-child(2) { + width: clamp(70px, 18vw, 110px); + top: 10%; + right: 5%; + } + .hero-float:nth-child(3) { + width: clamp(90px, 24vw, 150px); + bottom: 5%; + right: 8%; + } +} +@media (max-width: 600px) { + .product-grid { grid-template-columns: 1fr; } + .header-nav { gap: 1rem; } + .hero-left { min-height: 85vw; } + + /* Floats : plus petits sur mobile, repositionnés pour ne pas couvrir le texte */ + .hero-float:nth-child(1) { + width: clamp(60px, 18vw, 90px); + top: 4%; + left: 4%; + } + .hero-float:nth-child(2) { + width: clamp(55px, 16vw, 80px); + top: 8%; + right: 4%; + } + .hero-float:nth-child(3) { + width: clamp(70px, 20vw, 100px); + bottom: 4%; + right: 6%; + } } @media (max-width: 600px) { .product-grid { grid-template-columns: 1fr; } diff --git a/server.ts b/server.ts deleted file mode 100644 index 610cad5..0000000 --- a/server.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { Elysia, t } from 'elysia' -import { cors } from '@elysiajs/cors' -import Stripe from 'stripe' - -const stripe = new Stripe(process.env.STRIPE_SECRET_KEY ?? '', { - apiVersion: '2025-01-27.acacia', -}) - -const DOMAIN = process.env.DOMAIN ?? 'http://localhost:3000' - -const PRODUCTS = { - lumiere_orbitale: { - name: 'LUMIÈRE_ORBITALE — REBOUR', - description: 'Lampe de table unique. Béton texturé coulé à la main + dôme céramique laqué. Collection 001.', - amount: 180000, - currency: 'eur', - }, -} - -const app = new Elysia() - .use(cors({ origin: '*', methods: ['GET', 'POST'] })) - - // ── SEO : robots + sitemap (nginx ne les génère pas dynamiquement) ────────── - .get('/robots.txt', () => - new Response(`User-agent: *\nAllow: /\nSitemap: ${DOMAIN}/sitemap.xml\n`, { - headers: { 'Content-Type': 'text/plain', 'Cache-Control': 'public, max-age=86400' }, - }) - ) - .get('/sitemap.xml', () => { - const today = new Date().toISOString().split('T')[0] - return new Response( - `\n\n ${DOMAIN}/${today}weekly1.0\n`, - { headers: { 'Content-Type': 'application/xml', 'Cache-Control': 'public, max-age=86400' } } - ) - }) - - // ── API Stripe : créer session checkout ─────────────────────────────────── - .post( - '/api/checkout', - async ({ body }) => { - const product = PRODUCTS[body.product as keyof typeof PRODUCTS] - if (!product) return new Response('Produit inconnu', { status: 404 }) - - const session = await stripe.checkout.sessions.create({ - mode: 'payment', - payment_method_types: ['card'], - line_items: [{ - price_data: { - currency: product.currency, - unit_amount: product.amount, - product_data: { name: product.name, description: product.description }, - }, - quantity: 1, - }], - success_url: `${DOMAIN}/success?session_id={CHECKOUT_SESSION_ID}`, - cancel_url: `${DOMAIN}/#collection`, - locale: 'fr', - customer_email: body.email ?? undefined, - custom_text: { - submit: { message: 'Pièce unique — fabriquée à Paris. Délai : 6 à 8 semaines.' }, - }, - }) - - return { url: session.url } - }, - { - body: t.Object({ - product: t.String(), - email: t.Optional(t.String()), - }), - } - ) - - // ── API : vérifier session après paiement ───────────────────────────────── - .get( - '/api/session/:id', - async ({ params }) => { - const session = await stripe.checkout.sessions.retrieve(params.id) - return { - status: session.payment_status, - amount: session.amount_total, - currency: session.currency, - customer_email: session.customer_details?.email ?? null, - } - }, - { params: t.Object({ id: t.String() }) } - ) - - // ── Webhook Stripe ───────────────────────────────────────────────────────── - .post('/api/webhook', async ({ request, headers }) => { - const sig = headers['stripe-signature'] - const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET - if (!sig || !webhookSecret) return new Response('Missing signature', { status: 400 }) - - let event: Stripe.Event - try { - event = stripe.webhooks.constructEvent( - Buffer.from(await request.arrayBuffer()), sig, webhookSecret - ) - } catch { - return new Response('Webhook Error', { status: 400 }) - } - - if (event.type === 'checkout.session.completed') { - const session = event.data.object as Stripe.Checkout.Session - if (session.payment_status === 'paid') { - console.log(`✓ Paiement — ${session.id} — ${session.customer_details?.email}`) - } - } - return { received: true } - }) - - .listen(3000) - -console.log(` - ┌──────────────────────────────────────┐ - │ REBOUR API — http://localhost:3000 │ - │ NODE_ENV: ${process.env.NODE_ENV ?? 'development'} - └──────────────────────────────────────┘ -`)