From 4bab6548f79727af8bbbac2bd2c44ae1e66b2eec Mon Sep 17 00:00:00 2001 From: Esteban Date: Mon, 29 Jun 2026 16:20:59 +0200 Subject: [PATCH] =?UTF-8?q?Ajout=20d'un=20captcha=20+=20R=C3=A9actualisati?= =?UTF-8?q?on=20du=20css=20+=20ajout=20cgu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- captcha.php | 441 +++++++++++++++++++++++++++++++ database/scriptDatabase.sql | 10 +- elements/footer.php | 2 +- elements/header.php | 4 + functions/sendLogs.php | 4 +- index.php | 2 +- pages/cgu.php | 63 ++++- pages/home.php | 1 + pages/login.php | 1 + pages/projects.php | 1 + pages/skills.php | 1 + pages/xp.php | 1 + scripts/disconnect.php | 18 +- scripts/requireCaptcha.php | 7 + styles/captcha.css | 507 ++++++++++++++++++++++++++++++++++++ styles/primary_css.css | 93 ++++++- 16 files changed, 1139 insertions(+), 17 deletions(-) create mode 100644 captcha.php create mode 100644 scripts/requireCaptcha.php create mode 100644 styles/captcha.css diff --git a/captcha.php b/captcha.php new file mode 100644 index 0000000..0e48396 --- /dev/null +++ b/captcha.php @@ -0,0 +1,441 @@ + $subject) { + $normalPool[] = [ + 'id' => 'normal_' . $index, + 'sender' => $normalSenders[array_rand($normalSenders)], + 'subject' => $subject, + 'preview' => $normalPreviews[array_rand($normalPreviews)], + 'is_spam' => false, + 'time' => sprintf('%02d:%02d', random_int(8, 19), random_int(0, 59)) + ]; + } + + $spamPool = []; + foreach ($spamSubjects as $index => $subject) { + $spamPool[] = [ + 'id' => 'spam_' . $index, + 'sender' => $spamSenders[array_rand($spamSenders)], + 'subject' => $subject, + 'preview' => $spamPreviews[array_rand($spamPreviews)], + 'is_spam' => true, + 'time' => sprintf('%02d:%02d', random_int(0, 23), random_int(0, 59)) + ]; + } + + // Mélanger les tableaux + shuffle($normalPool); + shuffle($spamPool); + + // Sélectionner 9 emails normaux et 1 spam + $selected = array_slice($normalPool, 0, 9); + $selected[] = $spamPool[0]; + shuffle($selected); + + // Retourner le round + return [ + 'token' => bin2hex(random_bytes(16)), + 'correct_id' => $spamPool[0]['id'], + 'emails' => $selected, + 'attempts_left' => $maxAttempts + ]; +} + +if (!isset($_SESSION['captcha_round']) || !is_array($_SESSION['captcha_round'])) { + $_SESSION['captcha_round'] = buildInboxRound( + $normalSubjects, + $normalSenders, + $normalPreviews, + $spamSubjects, + $spamSenders, + $spamPreviews, + $maxAttempts + ); +} + +// Récupérer le round actuel +$round = $_SESSION['captcha_round']; +$error = ''; +$success = false; +$locked = false; + + +// Si formulaire soumis via POST +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + $postedToken = $_POST['captcha_token'] ?? ''; + $selectedMail = $_POST['selected_mail'] ?? ''; + // Si token invalide + if (!hash_equals($round['token'], $postedToken)) { + $error = 'Session invalide, recharge la page.'; + // Si plus d'essais + } elseif (($round['attempts_left'] ?? 0) <= 0) { + $locked = true; + $error = 'Tu n’as plus d’essais. Recharge une nouvelle série.'; + // Si mail incorrect + } elseif ($selectedMail !== $round['correct_id']) { + $_SESSION['captcha_round']['attempts_left']--; + $round = $_SESSION['captcha_round']; + // Si plus d'essais après décrémentation + if (($round['attempts_left'] ?? 0) <= 0) { + $locked = true; + $error = 'Perdu. Tu n’as plus d’essais. Recharge une nouvelle série.'; + // Sinon, message d'erreur + } else { + $error = 'Ce n’est pas le bon mail. Regarde mieux le message le plus agressif ou trop urgent.'; + } + // Si mail correct + } else { + $_SESSION['captcha_valid'] = true; + unset($_SESSION['captcha_round']); + $success = true; + } +} +// Récupérer le nombre d'essais restants +$attemptsLeft = $round['attempts_left'] ?? 0; + +// Afficher le captcha +?> + + + + + + Test anti-robot + + + +
+ +
+
+
+

Vérification réussie

+

Bravo, tu as trouvé le mail frauduleux. Redirection en cours...

+
+ +
+
+ + + +
+
🛡️ Test anti-robot
+ +
+
+

Vérification humaine

+

+ Pour continuer, cliquez sur le mail frauduleux parmi les 10 messages ci-dessous. +

+
+ +
+ Vérification demandée + Trouver le spam +
+
+ +
+
+ Essais restants + / +
+ + + Recharger une nouvelle série + +
+ + +
+ + +
+
+
+ + + +
+
Test anti-robot : trouvez le mail qui ressemble à une arnaque
+
+ +
+ + + +
+
+ + + + +
+ +
+ + + + diff --git a/database/scriptDatabase.sql b/database/scriptDatabase.sql index 37aacce..ae6434c 100644 --- a/database/scriptDatabase.sql +++ b/database/scriptDatabase.sql @@ -2,10 +2,10 @@ CREATE DATABASE IF NOT EXISTS portfolio -- On créer un utilisateur avec un mot de passe fort qui est à changer après execution dus script (voir bitwarden) -CREATE USER 'srv_portfolio'@'localhost' IDENTIFIED BY 'mdp'; +CREATE USER 'srv_portfolio'@'%' IDENTIFIED BY 'mdp'; -- On met les droits au compte sur la base portfolio à l'utilisateur -GRANT ALL ON portfolio.* TO 'srv_portfolio'@'localhost'; +GRANT ALL ON portfolio.* TO 'srv_portfolio'@'%'; -- On actualise les permissions FLUSH PRIVILEGES; @@ -14,7 +14,7 @@ FLUSH PRIVILEGES; CREATE TABLE IF NOT EXISTS users ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, username VARCHAR(50) NOT NULL, - password VARCHAR(255) NOT NULL, -- Je laisse ici de la place pour prévoir un futur hashage et sallage + password VARCHAR(255) NOT NULL, role ENUM('admin', 'user') NOT NULL DEFAULT 'user', created_at DATETIME NULL DEFAULT NULL, last_login DATETIME NULL DEFAULT NULL, @@ -29,7 +29,7 @@ CREATE TABLE IF NOT EXISTS projects ( title VARCHAR(100) NOT NULL, tags VARCHAR(255) NULL, description TEXT NOT NULL, - image_url VARCHAR(255) NOT NULL, -- Stockage de l'image par URL (exemple : par CDN) + image_url VARCHAR(255) NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ); @@ -42,7 +42,7 @@ CREATE TABLE IF NOT EXISTS experiences ( tags VARCHAR(255) NULL, description TEXT NOT NULL, duration VARCHAR(100) NOT NULL, - image_url VARCHAR(255) NOT NULL, -- Stockage de l'image par URL (exemple : par CDN) + image_url VARCHAR(255) NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ); diff --git a/elements/footer.php b/elements/footer.php index f02e66a..48d6b15 100644 --- a/elements/footer.php +++ b/elements/footer.php @@ -15,7 +15,7 @@ Instagram Git Discord - Conditions générales et d'utilisation + CGU \ No newline at end of file diff --git a/elements/header.php b/elements/header.php index d112763..1d1d668 100644 --- a/elements/header.php +++ b/elements/header.php @@ -8,6 +8,9 @@ // Ajout ici d'un démarrage de session : header étant dans toutes les pages session_start(); +// Ajout ici la vérification du captcha +require_once('../scripts/requireCaptcha.php'); + // Ajout des logs sur toutes les pages require_once('../functions/sendLogs.php'); ?> @@ -27,6 +30,7 @@ require_once('../functions/sendLogs.php'); Accueil Projets Expériences + Compétences Contact \ No newline at end of file +?> + +
+
+

Conditions générales d'utilisation

+

Dernière mise à jour : 29 juin 2026

+
+

Les présentes conditions générales d'utilisation (CGU) régissent l'utilisation du site web estebanadmin.fr. En accédant à ce site, vous acceptez les présentes conditions.

+ +

1. Objet

+

Le présent site a pour objectif de présenter le parcours, les compétences, les projets et les réalisations d’Esteban. Le site peut également contenir des moyens de contact, des liens externes et des contenus liés à son activité personnelle, associative ou professionnelle.

+ +

2. Accès au site

+

L'accès au site est gratuit et ouvert à tous. L'utilisateur s'engage à utiliser le site de manière responsable et conforme à la législation en vigueur.

+

L'éditeur se réserve le droit de suspendre, d'interrompre ou de modifier tout ou partie du site sans préavis, notamment pour des raisons techniques, légales, de sécurité, de maintenance ou en cas d'usage abusif.

+ +

3. Propriété intellectuelle

+

L’ensemble des éléments présents sur le site, notamment les textes, visuels, illustrations, logos, éléments graphiques, structure, code source et contenus originaux, est protégé par le droit de la propriété intellectuelle, sauf mention contraire.

+

Toute reproduction, représentation, diffusion, adaptation, modification ou exploitation, totale ou partielle, sans autorisation préalable écrite, est interdite, sauf dans les cas autorisés par la loi.

+ +

4. Utilisation de l’intelligence artificielle

+

Le site et certains de ses éléments ont pu être conçus avec l'assistance d'outils d’intelligence artificielle. Cela peut notamment concerner la génération ou l’adaptation de feuilles de style CSS, l’aide à la rédaction, l’autocomplétion de code, la génération de commentaires, de structures répétitives, de formulaires simples ou de requêtes basiques.

+

L’éditeur précise cependant que le développement principal du projet, notamment le code PHP, HTML et JavaScript, l’architecture générale, l’intégration, les choix techniques et la personnalisation globale du site, ont été réalisés majoritairement par un humain, à savoir Esteban MOUSSU.

+

L'utilisation d'outils tels que GitHub Copilot, Devin ou d'autres assistants similaires constitue une aide au développement et non une substitution complète au travail humain.

+ +

5. Hébergement et édition

+

Ce projet est entièrement développé par Esteban MOUSSU.

+

Le site est hébergé en 2026 par l’entreprise TerraTech Hebergement, en collaboration avec l’association Eldoria Network.

+

Les informations diffusées sur le site le sont sous la responsabilité de son éditeur.

+ +

6. Exactitude des informations

+

L’éditeur s’efforce de fournir des informations aussi exactes et à jour que possible. Toutefois, aucune garantie n’est donnée quant à l’exactitude, l’exhaustivité ou l’actualité des contenus publiés.

+

L’utilisateur reconnaît utiliser les informations disponibles sur le site sous sa seule responsabilité.

+ +

7. Liens externes

+

Le site peut contenir des liens vers des sites tiers. Ces liens sont fournis à titre informatif. L’éditeur ne saurait être tenu responsable du contenu, du fonctionnement ou des politiques de confidentialité de ces sites externes.

+ +

8. Responsabilité

+

L’éditeur ne pourra être tenu responsable des dommages directs ou indirects résultant de l’utilisation du site, d’une interruption temporaire, d’un dysfonctionnement technique ou d’une impossibilité d’accès.

+

L’utilisateur demeure seul responsable de l’usage qu’il fait du site et des informations qu’il y consulte.

+ +

9. Données personnelles

+

Le site peut proposer un ou plusieurs formulaires de contact. Les données éventuellement transmises par l’utilisateur sont uniquement destinées au traitement de sa demande, sauf mention contraire clairement indiquée.

+

Conformément à la réglementation applicable, l’utilisateur peut demander l’accès, la rectification ou la suppression de ses données en contactant l’éditeur du site.

+ +

10. Sécurité

+

L’utilisateur s’interdit de perturber le bon fonctionnement du site, d’introduire des programmes malveillants, de tenter un accès non autorisé ou de porter atteinte à l’intégrité technique du service.

+ +

11. Modification des CGU

+

L’éditeur se réserve le droit de modifier à tout moment les présentes CGU. Les modifications prennent effet dès leur publication sur cette page.

+ +

12. Droit applicable

+

Les présentes CGU sont soumises au droit français. En cas de litige, et à défaut de résolution amiable, les juridictions compétentes seront celles déterminées par les règles de droit commun.

+
+
+ + diff --git a/pages/home.php b/pages/home.php index 0060838..2c31bb2 100644 --- a/pages/home.php +++ b/pages/home.php @@ -3,6 +3,7 @@ // Page Home PortFolio Esteban // Cette page servira de page d'accueil où nous pourrons y retrouver une redirection vers les différents projets, espace de connexion, form de contact, etc... + // Insertion du header require_once('./../elements/header.php'); diff --git a/pages/login.php b/pages/login.php index 4e05086..1f6a98d 100644 --- a/pages/login.php +++ b/pages/login.php @@ -4,6 +4,7 @@ // Egalement permettre à l'utilisateur de faire retour en arrière s'il s'est trompé (croix ou header) + // On ajoute ici le Header require_once('./../elements/header.php'); diff --git a/pages/projects.php b/pages/projects.php index 6c74ebb..c6d8ab3 100644 --- a/pages/projects.php +++ b/pages/projects.php @@ -3,6 +3,7 @@ // Page affichant les différents projets personnels / scolaires / professionnels // On pourrait également rajouter des tags comme "En cours" ou même "En reflexion"... + // On ajoute le header require_once('../elements/header.php'); diff --git a/pages/skills.php b/pages/skills.php index 307af76..a81b9bd 100644 --- a/pages/skills.php +++ b/pages/skills.php @@ -2,6 +2,7 @@ // Compétences + // On ajoute ici le header require_once('./../elements/header.php'); diff --git a/pages/xp.php b/pages/xp.php index ed3745d..c050dd3 100644 --- a/pages/xp.php +++ b/pages/xp.php @@ -2,6 +2,7 @@ // Page affichant les différentes expériences pro (stages etc...) + // On ajoute le header require_once('../elements/header.php'); diff --git a/scripts/disconnect.php b/scripts/disconnect.php index db53dcd..066a7ac 100644 --- a/scripts/disconnect.php +++ b/scripts/disconnect.php @@ -2,13 +2,23 @@ // Lorsque l'utilisateur est renvoyé à cette page/fonction, il est déconnecté - // Démarrage de session session_start(); -// Destruction des variables de session +// On sauvegarde l'état du captcha avant destruction +$captchaAlreadyValid = isset($_SESSION['captcha_valid']) && $_SESSION['captcha_valid'] === true; + +// Destruction des variables de session $_SESSION = array(); session_destroy(); -// Redirection de l'utilisateur vers home.php -header('Location: ../index.php'); \ No newline at end of file +// Si le captcha avait déjà été validé, on recrée une session propre +// pour conserver uniquement cette information +if ($captchaAlreadyValid) { + session_start(); + $_SESSION['captcha_valid'] = true; +} + +// Redirection de l'utilisateur vers l'accueil +header('Location: ../index.php'); +exit; diff --git a/scripts/requireCaptcha.php b/scripts/requireCaptcha.php new file mode 100644 index 0000000..721445f --- /dev/null +++ b/scripts/requireCaptcha.php @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/styles/captcha.css b/styles/captcha.css new file mode 100644 index 0000000..a7a65fe --- /dev/null +++ b/styles/captcha.css @@ -0,0 +1,507 @@ +body { + background: + radial-gradient(circle at top, rgba(108, 99, 255, 0.18), transparent 35%), + #0d0d0d; + margin: 0; + font-family: Arial, sans-serif; + color: white; + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + padding: 24px; + box-sizing: border-box; +} + +.captcha-shell { + width: 100%; + max-width: 1100px; +} + +.captcha-card, +.success-screen { + background: linear-gradient(180deg, #111116 0%, #161622 100%); + border: 1px solid #2a2a3e; + border-radius: 24px; + box-shadow: 0 18px 40px rgba(0, 0, 0, 0.28); + padding: 30px; +} + +.captcha-badge { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 8px 14px; + border-radius: 999px; + background: rgba(108, 99, 255, 0.14); + border: 1px solid rgba(108, 99, 255, 0.28); + color: #9d97ff; + font-size: 13px; + font-weight: bold; + margin-bottom: 18px; +} + +.captcha-top { + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 24px; + margin-bottom: 18px; +} + +.captcha-title { + margin: 0 0 10px; + font-size: 34px; + font-weight: 800; +} + +.captcha-subtitle { + margin: 0; + color: #c1c1cf; + font-size: 16px; + line-height: 1.7; + max-width: 700px; +} + +.captcha-target { + min-width: 240px; + background-color: #1a1a24; + border: 1px solid #2a2a3e; + border-radius: 18px; + padding: 18px; +} + +.captcha-target span { + display: block; + color: #8f8fa8; + font-size: 12px; + text-transform: uppercase; + letter-spacing: 0.08em; + margin-bottom: 8px; +} + +.captcha-target strong { + font-size: 22px; + color: #8f88ff; +} + +.captcha-stats { + display: flex; + justify-content: space-between; + align-items: center; + gap: 16px; + margin-bottom: 18px; + flex-wrap: wrap; +} + +.captcha-attempts { + background-color: #171b28; + border: 1px solid #283049; + border-radius: 14px; + padding: 12px 16px; +} + +.captcha-attempts span { + display: block; + color: #99a0bc; + font-size: 12px; + text-transform: uppercase; + letter-spacing: 0.08em; + margin-bottom: 6px; +} + +.captcha-attempts strong { + font-size: 22px; + color: #ffffff; +} + +.captcha-reset, +.captcha-secondary-button { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 12px 18px; + border-radius: 12px; + text-decoration: none; + color: white; + background-color: #2a314a; + border: 1px solid #3d4767; + transition: transform 0.2s ease, background-color 0.2s ease; +} + +.captcha-reset:hover, +.captcha-secondary-button:hover { + background-color: #394362; + transform: translateY(-1px); +} + +.captcha-error { + margin-bottom: 18px; + background-color: rgba(161, 44, 47, 0.15); + border: 1px solid rgba(255, 84, 84, 0.45); + border-radius: 12px; + color: #ffb8bb; + padding: 14px 16px; + font-size: 14px; +} + +.mailbox { + background-color: #0f1118; + border: 1px solid #22263a; + border-radius: 20px; + overflow: hidden; +} + +.mailbox-toolbar { + display: flex; + align-items: center; + justify-content: space-between; + gap: 16px; + padding: 16px 20px; + background-color: #141825; + border-bottom: 1px solid #22263a; +} + +.mailbox-dots { + display: flex; + gap: 8px; +} + +.mailbox-dots span { + width: 10px; + height: 10px; + border-radius: 50%; + display: block; +} + +.mailbox-dots span:nth-child(1) { + background-color: #ff5f57; +} + +.mailbox-dots span:nth-child(2) { + background-color: #febc2e; +} + +.mailbox-dots span:nth-child(3) { + background-color: #28c840; +} + +.mailbox-label { + color: #d6daf0; + font-size: 14px; + font-weight: bold; +} + +.mail-list { + display: flex; + flex-direction: column; +} + +.mail-option { + position: relative; +} + +.mail-option-disabled { + pointer-events: none; +} + +.mail-option input { + position: absolute; + opacity: 0; + pointer-events: none; +} + +.mail-row { + display: grid; + grid-template-columns: 48px minmax(120px, 220px) 1fr 70px; + gap: 14px; + align-items: center; + padding: 16px 18px; + border-bottom: 1px solid #1d2234; + cursor: pointer; + transition: + background-color 0.2s ease, + border-color 0.2s ease, + transform 0.2s ease, + box-shadow 0.2s ease; +} + +.mail-row:hover { + background-color: #161b2a; + transform: translateX(2px); +} + +.mail-option input:checked + .mail-row { + background-color: rgba(108, 99, 255, 0.14); + box-shadow: inset 0 0 0 1px rgba(108, 99, 255, 0.35); +} + +.mail-avatar { + width: 42px; + height: 42px; + border-radius: 50%; + background: linear-gradient(180deg, #2f3550 0%, #1f2334 100%); + border: 1px solid #303650; + display: flex; + align-items: center; + justify-content: center; + color: #d7dcf2; + font-weight: bold; + font-size: 15px; +} + +.mail-sender { + font-weight: bold; + color: white; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.mail-content { + min-width: 0; +} + +.mail-subject { + color: #f3f4fb; + font-size: 15px; + margin-bottom: 4px; + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.mail-preview { + color: #b5b8ca; + font-size: 13px; + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.mail-time { + color: #8f8fa8; + font-size: 13px; + text-align: right; +} + +.captcha-footer { + display: flex; + justify-content: space-between; + align-items: center; + gap: 16px; + margin-top: 24px; +} + +.captcha-note { + color: #b7bbcd; + font-size: 14px; + line-height: 1.6; + max-width: 720px; +} + +.captcha-actions { + display: flex; + gap: 12px; +} + +.captcha-submit { + background: linear-gradient(180deg, #7a72ff 0%, #5e56eb 100%); + color: white; + border: none; + border-radius: 12px; + padding: 14px 24px; + font-size: 15px; + font-weight: bold; + cursor: pointer; + transition: background-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease; + box-shadow: 0 12px 24px rgba(94, 86, 235, 0.28); +} + +.captcha-submit:hover { + transform: translateY(-1px) scale(1.01); + box-shadow: 0 16px 30px rgba(94, 86, 235, 0.34); +} + +.success-mode { + overflow: hidden; +} + +.success-screen { + text-align: center; + position: relative; + overflow: hidden; + animation: successPop 0.6s ease; +} + +.success-icon { + font-size: 68px; + margin-bottom: 14px; + animation: bounceIn 0.9s ease; +} + +.success-screen h1 { + margin: 0 0 12px; + font-size: 40px; +} + +.success-screen p { + margin: 0 auto 24px; + max-width: 520px; + color: #ced2e6; + font-size: 18px; +} + +.success-loader { + width: 240px; + height: 10px; + margin: 0 auto; + background: #23283d; + border-radius: 999px; + overflow: hidden; + border: 1px solid #323a5b; +} + +.success-loader span { + display: block; + height: 100%; + width: 0; + background: linear-gradient(90deg, #62d26f 0%, #9cffaf 100%); + animation: loadingBar 1.8s linear forwards; +} + +.success-burst { + position: absolute; + inset: 0; + pointer-events: none; + background: + radial-gradient(circle at 20% 30%, rgba(255, 215, 0, 0.25), transparent 18%), + radial-gradient(circle at 80% 20%, rgba(98, 210, 111, 0.22), transparent 18%), + radial-gradient(circle at 30% 80%, rgba(122, 114, 255, 0.2), transparent 20%), + radial-gradient(circle at 75% 70%, rgba(255, 105, 180, 0.16), transparent 18%); + animation: burstPulse 1s ease-in-out infinite alternate; +} + +@keyframes successPop { + from { + opacity: 0; + transform: scale(0.96); + } + to { + opacity: 1; + transform: scale(1); + } +} + +@keyframes bounceIn { + 0% { + opacity: 0; + transform: scale(0.3) translateY(20px); + } + 60% { + opacity: 1; + transform: scale(1.08) translateY(-6px); + } + 100% { + transform: scale(1) translateY(0); + } +} + +@keyframes loadingBar { + from { + width: 0; + } + to { + width: 100%; + } +} + +@keyframes burstPulse { + from { + opacity: 0.7; + transform: scale(1); + } + to { + opacity: 1; + transform: scale(1.03); + } +} + +@media (max-width: 900px) { + .captcha-top { + flex-direction: column; + } + + .captcha-target { + width: 100%; + min-width: 0; + } + + .mail-row { + grid-template-columns: 42px 1fr 56px; + } + + .mail-sender { + display: none; + } + + .captcha-footer { + flex-direction: column; + align-items: stretch; + } + + .captcha-actions { + width: 100%; + } + + .captcha-submit, + .captcha-secondary-button { + width: 100%; + } +} + +@media (max-width: 640px) { + body { + padding: 14px; + } + + .captcha-card, + .success-screen { + padding: 20px; + border-radius: 18px; + } + + .captcha-title { + font-size: 28px; + } + + .mailbox-toolbar { + padding: 14px 16px; + } + + .mail-row { + grid-template-columns: 36px 1fr; + gap: 10px; + padding: 14px 14px; + } + + .mail-time { + grid-column: 2; + text-align: left; + margin-top: 4px; + } + + .success-screen h1 { + font-size: 30px; + } + + .success-screen p { + font-size: 16px; + } + + .success-loader { + width: 100%; + } +} diff --git a/styles/primary_css.css b/styles/primary_css.css index e92ef2e..dab5dc3 100644 --- a/styles/primary_css.css +++ b/styles/primary_css.css @@ -771,4 +771,95 @@ main { .quick-link-card p { font-size: 16px; } -} \ No newline at end of file +} + +/* ---- PAGE CGU ---- */ +.cgu-page { + max-width: 980px; + margin: 48px auto 72px; + padding: 0 24px; + box-sizing: border-box; +} + +.cgu-card { + background: linear-gradient(180deg, #111116 0%, #15151f 100%); + border: 1px solid #2a2a3e; + border-radius: 20px; + padding: 40px; + box-shadow: 0 18px 40px rgba(0, 0, 0, 0.28); +} + +.cgu-card h1 { + margin: 0 0 10px; + color: white; + font-size: 38px; + font-weight: 800; + line-height: 1.2; +} + +.cgu-card h2 { + margin: 0 0 24px; + color: #b8b8c7; + font-size: 17px; + font-weight: 500; +} + +.cgu-card hr { + border: none; + height: 1px; + background-color: #2a2a3e; + margin: 0 0 28px; +} + +.cgu-card h3 { + margin: 30px 0 12px; + color: #8f88ff; + font-size: 22px; + font-weight: 700; +} + +.cgu-card p { + margin: 0 0 14px; + color: #c7c7d4; + font-size: 16px; + line-height: 1.8; +} + +.cgu-card p:last-child { + margin-bottom: 0; +} + +.cgu-card br { + display: none; +} + +@media (max-width: 700px) { + .cgu-page { + margin: 28px auto 48px; + padding: 0 14px; + } + + .cgu-card { + padding: 24px 18px; + border-radius: 16px; + } + + .cgu-card h1 { + font-size: 28px; + } + + .cgu-card h2 { + font-size: 15px; + margin-bottom: 18px; + } + + .cgu-card h3 { + font-size: 19px; + margin-top: 24px; + } + + .cgu-card p { + font-size: 15px; + line-height: 1.7; + } +}