diff --git a/docusaurus.config.ts b/docusaurus.config.ts
index dd9e2a7..9896d9f 100644
--- a/docusaurus.config.ts
+++ b/docusaurus.config.ts
@@ -69,34 +69,6 @@ export default async function createConfigAsync() {
es: '/es/',
pt: '/pt/'
},
- legal: {
- fr: '/legal',
- en: '/en/legal',
- de: '/de/legal',
- es: '/es/legal',
- pt: '/pt/legal'
- },
- terms: {
- fr: '/terms',
- en: '/en/terms',
- de: '/de/terms',
- es: '/es/terms',
- pt: '/pt/terms'
- },
- privacy: {
- fr: '/privacy',
- en: '/en/privacy',
- de: '/de/privacy',
- es: '/es/privacy',
- pt: '/pt/privacy'
- },
- cookies: {
- fr: '/cookies',
- en: '/en/cookies',
- de: '/de/cookies',
- es: '/es/cookies',
- pt: '/pt/cookies'
- },
geranium: {
fr: 'https://i.dfr.gg/geranium.webm',
en: 'https://i.dfr.gg/en-geranium.webm',
@@ -356,7 +328,7 @@ export default async function createConfigAsync() {
},
{
label: 'Documentation',
- to: '/',
+ to: '/docs',
target: '_self'
},
{
@@ -376,22 +348,22 @@ export default async function createConfigAsync() {
items: [
{
label: 'Mentions légales',
- to: 'legal',
+ to: '/legal',
target: '_self'
},
{
label: 'Conditions d\'utilisation',
- to: 'terms',
+ to: '/terms',
target: '_self'
},
{
label: 'Politique de confidentialité',
- to: 'privacy',
+ to: '/privacy',
target: '_self'
},
{
label: 'Politique des cookies',
- to: 'cookies',
+ to: '/cookies',
target: '_self'
}
],
diff --git a/src/components/landing/Hero/index.tsx b/src/components/landing/Hero/index.tsx
new file mode 100644
index 0000000..912654b
--- /dev/null
+++ b/src/components/landing/Hero/index.tsx
@@ -0,0 +1,58 @@
+import React, {type ReactNode} from 'react';
+import clsx from 'clsx';
+import shared from '../styles/shared.module.css';
+import styles from './styles.module.css';
+
+type HeroProps = {
+ /** Nombre brut de serveurs, arrondi à la dizaine de milliers inférieure
+ * (pallier 50 000) pour produire un chiffre stable façon checkpoint. */
+ serverCount?: number;
+};
+
+const PRE_TITLE_FALLBACK = 350_000;
+const PRE_TITLE_STEP = 50_000;
+
+function roundedServerCount(raw: number | undefined): number {
+ if (raw == null || !Number.isFinite(raw)) return PRE_TITLE_FALLBACK;
+ return Math.floor(raw / PRE_TITLE_STEP) * PRE_TITLE_STEP;
+}
+
+export default function Hero({serverCount}: HeroProps): ReactNode {
+ const formatted = roundedServerCount(serverCount).toLocaleString('fr-FR');
+ return (
+
+
+
+
+
+ Utilisé par plus de {formatted} serveurs
+
+
+
+ Le meilleur bot Discord de{' '}
+ sécurité
+
+
+ Empêchez les utilisateurs malintentionnés de nuire à votre serveur
+ Discord.
+
+
+
+
+
+ );
+}
diff --git a/src/components/landing/Hero/styles.module.css b/src/components/landing/Hero/styles.module.css
new file mode 100644
index 0000000..3015b24
--- /dev/null
+++ b/src/components/landing/Hero/styles.module.css
@@ -0,0 +1,85 @@
+.section {
+ padding-top: 90px;
+ padding-bottom: 150px;
+ position: relative;
+ overflow-x: clip;
+}
+
+.content {
+ z-index: 2;
+ text-align: center;
+ display: flex;
+ flex-flow: column;
+ justify-content: space-between;
+ align-items: center;
+ position: relative;
+}
+
+.preTitleWrap {
+ border-radius: 50px;
+ background-color: #1b1a25;
+ background-image: linear-gradient(180deg, #d35f5f 40%, #a561a3);
+ margin-bottom: 20px;
+ padding: 1px;
+ display: inline-block;
+ overflow: hidden;
+}
+
+.preTitleText {
+ border-radius: 50px;
+ background-color: #1b1a25;
+ padding: 7px 14px 5px;
+ font-size: 16px;
+ font-weight: 400;
+ line-height: 1.5em;
+ color: #fff;
+ text-align: center;
+}
+
+.title {
+ margin: 0 0 10px 0;
+ font-family: var(--ifm-heading-font-family);
+ color: #fff;
+ font-size: 68px;
+ font-weight: 600;
+ line-height: 1.2em;
+}
+
+.description {
+ width: 75%;
+ font-family: var(--ifm-font-family-base);
+ margin-top: 0;
+ margin-bottom: 50px;
+ color: #e1e0e9;
+ font-size: 18px;
+}
+
+.buttonList {
+ display: flex;
+ flex-flow: wrap;
+ justify-content: center;
+ align-items: center;
+ column-gap: 30px;
+ row-gap: 15px;
+}
+
+@media screen and (max-width: 991px) {
+ .section {
+ padding-top: 50px;
+ padding-bottom: 100px;
+ }
+ .description {
+ width: 100%;
+ margin-bottom: 30px;
+ }
+}
+
+@media screen and (max-width: 767px) {
+ .section {
+ padding-top: 30px;
+ padding-bottom: 80px;
+ }
+ .title {
+ font-size: 48px;
+ }
+}
diff --git a/src/components/landing/Servers/index.tsx b/src/components/landing/Servers/index.tsx
new file mode 100644
index 0000000..4d8090a
--- /dev/null
+++ b/src/components/landing/Servers/index.tsx
@@ -0,0 +1,210 @@
+import React, {type ReactNode} from 'react';
+import clsx from 'clsx';
+import shared from '../styles/shared.module.css';
+import styles from './styles.module.css';
+
+type Badge = 'verified' | 'partner' | null;
+
+type Server = {
+ name: string;
+ icon: string;
+ alt: string;
+ href: string;
+ members: string;
+ badge: Badge;
+};
+
+const SERVERS: Server[] = [
+ {
+ name: 'Wankil Studio',
+ icon: '/img/landing/iconWankilStudio.webp',
+ alt: 'Wankil Studio Discord server icon',
+ href: 'https://discord.com/invite/wankilstudio',
+ members: '40 000 membres',
+ badge: 'verified',
+ },
+ {
+ name: 'Rocket League France',
+ icon: '/img/landing/iconRocketLeagueFrance.webp',
+ alt: 'Rocket League France Discord server icon',
+ href: 'https://discord.com/invite/rlfr',
+ members: '196 500 membres',
+ badge: 'partner',
+ },
+ {
+ name: 'Slash FR',
+ icon: '/img/landing/iconSlashFR.webp',
+ alt: 'Slash FR Discord server icon',
+ href: 'https://discord.com/invite/fr',
+ members: '48 500 membres',
+ badge: null,
+ },
+ {
+ name: "ZetFar's Family",
+ icon: '/img/landing/iconZetFar.webp',
+ alt: 'ZetFar Discord server icon',
+ href: 'https://discord.com/invite/zetfar',
+ members: '135 000 membres',
+ badge: 'verified',
+ },
+ {
+ name: 'Ligue 1 McDonald’s',
+ icon: '/img/landing/iconLigue1.webp',
+ alt: 'Ligue 1 Discord server icon',
+ href: 'https://discord.com/invite/ligue1',
+ members: '15 000 membres',
+ badge: 'verified',
+ },
+ {
+ name: 'Jobless',
+ icon: '/img/landing/iconJobless.webp',
+ alt: 'Jobless Discord server icon',
+ href: 'https://discord.com/invite/jobless',
+ members: '56 500 membres',
+ badge: 'partner',
+ },
+ {
+ name: 'Blox Fruits FR',
+ icon: '/img/landing/iconBloxFruitsFR.webp',
+ alt: 'Blox Fruits FR Discord server icon',
+ href: 'https://discord.com/invite/bloxfruitsfr',
+ members: '124 000 membres',
+ badge: null,
+ },
+ {
+ name: 'CYRILmp4',
+ icon: '/img/landing/iconCyrilmp4.webp',
+ alt: 'CYRILmp4 Discord server icon',
+ href: 'https://discord.com/invite/cyrilmp4',
+ members: '22 500 membres',
+ badge: 'partner',
+ },
+ {
+ name: 'Fortnite House',
+ icon: '/img/landing/iconFortniteHouse.webp',
+ alt: 'Fortnite House Discord server icon',
+ href: 'https://discord.com/invite/officiel',
+ members: '66 500 membres',
+ badge: 'partner',
+ },
+ {
+ name: 'PUBG MOBILE FRANCE',
+ icon: '/img/landing/iconPUBGMobileFrance.webp',
+ alt: 'PUBG MOBILE FRANCE Discord server icon',
+ href: 'https://discord.com/invite/pubgmfr',
+ members: '18 000 membres',
+ badge: 'verified',
+ },
+ {
+ name: 'NationGlory',
+ icon: '/img/landing/iconNationsGlory.webp',
+ alt: 'NationsGlory server icon',
+ href: 'https://discord.com/invite/nationsglory',
+ members: '51 000 membres',
+ badge: 'partner',
+ },
+ {
+ name: 'MASTU',
+ icon: '/img/landing/iconMastu.webp',
+ alt: 'MASTU Discord server icon',
+ href: 'https://discord.com/invite/mastu',
+ members: '17 000 membres',
+ badge: 'partner',
+ },
+ {
+ name: 'Clash Royale FR',
+ icon: '/img/landing/iconClashRoyaleFR.webp',
+ alt: 'Clash Royale FR Discord server icon',
+ href: 'https://discord.com/invite/clashfr',
+ members: '34 000 membres',
+ badge: 'partner',
+ },
+ {
+ name: 'TEAM VITALITY',
+ icon: '/img/landing/iconTeamVitality.webp',
+ alt: 'TEAM VITALITY Discord server icon',
+ href: 'https://discord.com/invite/teamvitality',
+ members: '19 500 membres',
+ badge: null,
+ },
+ {
+ name: 'Genshin Impact FR',
+ icon: '/img/landing/iconGenshinImpactFR.webp',
+ alt: 'Genshin Impact FR Discord server icon',
+ href: 'https://discord.com/invite/genshinimpactfr',
+ members: '55 000 membres',
+ badge: 'partner',
+ },
+];
+
+function BadgeImg({badge}: {badge: Badge}) {
+ if (!badge) return null;
+ const src =
+ badge === 'verified'
+ ? '/img/landing/serverBadgeVerified.svg'
+ : '/img/landing/serverBadgePartner.svg';
+ const alt =
+ badge === 'verified'
+ ? 'Discord server badge verified'
+ : 'Discord server badge partner';
+ return (
+
+ );
+}
+
+function ServerCard({server}: {server: Server}) {
+ return (
+
+
+
+
+
+
+ );
+}
+
+export default function Servers(): ReactNode {
+ return (
+
+
+
Nous protégeons les plus grands
+
+
+
+ {SERVERS.map((server) => (
+
+ ))}
+
+
+ {SERVERS.map((server) => (
+
+ ))}
+
+
+
+
+
+ );
+}
diff --git a/src/components/landing/Servers/styles.module.css b/src/components/landing/Servers/styles.module.css
new file mode 100644
index 0000000..b3be400
--- /dev/null
+++ b/src/components/landing/Servers/styles.module.css
@@ -0,0 +1,145 @@
+.section {
+ z-index: 3;
+ position: relative;
+}
+
+.title {
+ text-align: center;
+ margin: 0 0 20px 0;
+ color: #e1e0e9;
+ font-family: var(--ifm-font-family-base);
+ font-size: 18px;
+ font-weight: 400;
+}
+
+.marqueeWrap {
+ position: relative;
+ width: 100%;
+ overflow: hidden;
+ display: flex;
+ align-items: center;
+ --marquee-fade-width: 80px;
+ -webkit-mask-image: linear-gradient(
+ 90deg,
+ transparent,
+ #000 var(--marquee-fade-width),
+ #000 calc(100% - var(--marquee-fade-width)),
+ transparent
+ );
+ mask-image: linear-gradient(
+ 90deg,
+ transparent,
+ #000 var(--marquee-fade-width),
+ #000 calc(100% - var(--marquee-fade-width)),
+ transparent
+ );
+}
+
+.track {
+ display: flex;
+ flex: none;
+ align-items: center;
+ width: max-content;
+ color: #fff;
+ opacity: 0.85;
+ animation: marquee 60s linear infinite;
+}
+
+.marqueeWrap:hover .track {
+ animation-play-state: paused;
+}
+
+.group {
+ display: flex;
+ align-items: center;
+}
+
+.server {
+ display: flex;
+ flex-flow: column;
+ align-items: flex-start;
+ justify-content: flex-start;
+ min-width: 275px;
+ margin-right: 30px;
+ padding: 30px;
+ border: 1px solid #444950;
+ border-radius: 0.8rem;
+ background-color: #242328;
+ color: #fff;
+ text-decoration: none;
+ transition: border-color 0.2s ease-in-out;
+}
+
+.server:hover {
+ border-color: #d35f5f;
+ text-decoration: none;
+ color: #fff;
+}
+
+.avatarInfo {
+ display: flex;
+ align-items: center;
+ column-gap: 15px;
+ row-gap: 15px;
+ font-size: 14px;
+ line-height: 1.5em;
+}
+
+.avatar {
+ flex: none;
+ width: 50px;
+ height: 50px;
+ object-fit: cover;
+ border-radius: 50%;
+}
+
+.infos {
+ display: flex;
+ flex-flow: column;
+ align-items: flex-start;
+ justify-content: center;
+ row-gap: 6px;
+}
+
+.nameRow {
+ display: flex;
+ align-items: center;
+}
+
+.name {
+ color: #fff;
+ font-size: 18px;
+ font-weight: 600;
+ font-family: var(--ifm-font-family-base);
+}
+
+.badge {
+ margin-left: 10px;
+}
+
+.memberCount {
+ color: #e1e0e9;
+ font-size: 14px;
+}
+
+@keyframes marquee {
+ from {
+ transform: translate3d(0, 0, 0);
+ }
+ to {
+ transform: translate3d(-50%, 0, 0);
+ }
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .track {
+ animation: none;
+ }
+}
+
+@media screen and (max-width: 767px) {
+ .server {
+ min-width: 240px;
+ padding: 20px;
+ }
+}
diff --git a/src/components/landing/styles/shared.module.css b/src/components/landing/styles/shared.module.css
new file mode 100644
index 0000000..0a2a1cf
--- /dev/null
+++ b/src/components/landing/styles/shared.module.css
@@ -0,0 +1,164 @@
+/* Shared landing-page tokens & utilities, mirroring the Webflow source */
+
+.landing {
+ /* Colors from raidprotectbot.webflow.css */
+ --color-black: #040114;
+ --color-gray-1: #070417;
+ --color-gray-2: #1b1a25;
+ --color-gray-3: #242328;
+ --color-gray-4: #e1e0e9;
+ --color-white: #ffffff;
+ --color-primary-1: #726cb3;
+ --color-primary-4: #a561a3;
+ --color-primary-rp: #d35f5f;
+ --color-darker-primary: #bd5454;
+ --color-border-doc: #444950;
+ --color-founder: #ffab22;
+ --color-enterprise: #5f6fd3;
+
+ --radius-sm: 10px;
+ --radius-md: 20px;
+ --radius-lg: 50px;
+ --radius-doc: 0.8rem;
+
+ --gradient-1: linear-gradient(180deg, var(--color-primary-rp) 40%, var(--color-primary-4));
+ --gradient-feature-icon: linear-gradient(
+ 135deg,
+ var(--color-primary-1),
+ var(--color-primary-rp) 60%,
+ var(--color-primary-4)
+ );
+
+ color: var(--color-gray-4);
+ font-size: 18px;
+ line-height: 1.5em;
+ background-color: var(--color-black);
+}
+
+.container {
+ max-width: 1360px;
+ margin-left: auto;
+ margin-right: auto;
+ padding-left: 30px;
+ padding-right: 30px;
+}
+
+.sectionSpacing {
+ padding-top: 150px;
+ padding-bottom: 150px;
+}
+
+.sectionSpacingTop {
+ padding-top: 150px;
+}
+
+.sectionSpacingBottom {
+ padding-bottom: 150px;
+}
+
+.textGradient {
+ background-image: var(--gradient-1);
+ -webkit-text-fill-color: transparent;
+ -webkit-background-clip: text;
+ background-clip: text;
+}
+
+.btnPrimary {
+ display: inline-block;
+ border: 1px solid var(--color-darker-primary);
+ border-radius: var(--radius-lg);
+ background-color: var(--color-darker-primary);
+ color: #fff;
+ text-align: center;
+ padding: 20px 28px 18px;
+ font-size: 18px;
+ font-weight: 500;
+ line-height: 1.1em;
+ text-decoration: none;
+ transition: border-color 0.3s, background-color 0.3s, transform 0.3s, color 0.3s;
+}
+
+.btnPrimary:hover {
+ text-decoration: none;
+ color: #fff;
+ border-color: var(--color-darker-primary);
+ background-color: var(--color-darker-primary);
+ transform: translate3d(0, -3px, 0.01px);
+}
+
+.btnPrimaryFounder {
+ border-color: var(--color-founder);
+ background-color: var(--color-founder);
+ color: #fff;
+}
+
+.btnPrimaryFounder:hover {
+ border-color: var(--color-founder);
+ background-color: var(--color-founder);
+}
+
+.btnSecondary {
+ display: inline-block;
+ border: 1px solid var(--color-darker-primary);
+ border-radius: var(--radius-lg);
+ background-color: transparent;
+ color: var(--color-white);
+ text-align: center;
+ padding: 20px 28px 18px;
+ font-size: 18px;
+ line-height: 1.1em;
+ text-decoration: none;
+ transition: border-color 0.3s, transform 0.3s, background-color 0.3s, color 0.3s;
+}
+
+.btnSecondary:hover {
+ text-decoration: none;
+ color: #fff;
+ border-color: var(--color-darker-primary);
+ background-color: var(--color-darker-primary);
+ transform: translate3d(0, -3px, 0.01px);
+}
+
+.btnSecondaryEnterprise {
+ border-color: var(--color-enterprise);
+}
+
+.btnSecondaryEnterprise:hover {
+ border-color: var(--color-enterprise);
+ background-color: var(--color-enterprise);
+}
+
+@media screen and (max-width: 991px) {
+ .sectionSpacing {
+ padding-top: 100px;
+ padding-bottom: 100px;
+ }
+ .sectionSpacingTop {
+ padding-top: 100px;
+ }
+ .sectionSpacingBottom {
+ padding-bottom: 100px;
+ }
+}
+
+@media screen and (max-width: 767px) {
+ .container {
+ padding-left: 20px;
+ padding-right: 20px;
+ }
+ .sectionSpacing {
+ padding-top: 80px;
+ padding-bottom: 80px;
+ }
+ .sectionSpacingTop {
+ padding-top: 80px;
+ }
+ .sectionSpacingBottom {
+ padding-bottom: 80px;
+ }
+ .btnPrimary,
+ .btnSecondary {
+ padding: 20px 26px 16px;
+ font-size: 16px;
+ }
+}
diff --git a/src/css/custom.css b/src/css/custom.css
index 21f433d..9b3423f 100644
--- a/src/css/custom.css
+++ b/src/css/custom.css
@@ -4,6 +4,12 @@
* work well for content-centric websites.
*/
+@media (prefers-reduced-motion: no-preference) {
+ html {
+ scroll-behavior: smooth;
+ }
+}
+
/* You can override the default Infima variables here. */
html[data-theme='dark'] {
--ifm-background-color: #040114;
diff --git a/src/pages/index.module.css b/src/pages/index.module.css
new file mode 100644
index 0000000..bec9b26
--- /dev/null
+++ b/src/pages/index.module.css
@@ -0,0 +1,509 @@
+/* ===== About section ===== */
+
+.aboutSection {
+ overflow-x: clip;
+}
+
+.aboutTitleGrid {
+ display: grid;
+ grid-template-rows: auto;
+ grid-template-columns: 1.25fr 1fr;
+ grid-column-gap: 100px;
+ grid-row-gap: 100px;
+ margin-bottom: 30px;
+}
+
+.aboutTitle {
+ font-family: var(--ifm-heading-font-family);
+ color: #fff;
+ font-size: 50px;
+ font-weight: 600;
+ line-height: 1.2em;
+ margin: 0;
+}
+
+.counterGrid {
+ display: grid;
+ grid-template-rows: auto;
+ grid-template-columns: 1fr 1fr;
+ grid-column-gap: 100px;
+ grid-row-gap: 100px;
+ align-items: center;
+}
+
+.imageWrap {
+ position: relative;
+}
+
+.curve {
+ width: 100%;
+ height: auto;
+ display: block;
+}
+
+.curveLine {
+ stroke-dasharray: 1400;
+ stroke-dashoffset: 1400;
+ animation: rpDraw 1.5s cubic-bezier(0.4, 0, 0.2, 1) forwards;
+}
+
+@keyframes rpDraw {
+ to {
+ stroke-dashoffset: 0;
+ }
+}
+
+.curvePulse {
+ transform-origin: 860px 28px;
+ animation: rpPulse 1.8s ease-out infinite;
+}
+
+@keyframes rpPulse {
+ 0% {
+ transform: scale(1);
+ opacity: 0.9;
+ }
+ 70% {
+ transform: scale(2.8);
+ opacity: 0;
+ }
+ 100% {
+ transform: scale(2.8);
+ opacity: 0;
+ }
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .curveLine,
+ .curvePulse {
+ animation: none !important;
+ }
+ .curveLine {
+ stroke-dashoffset: 0;
+ }
+}
+
+.stats {
+ display: grid;
+ grid-template-rows: auto auto;
+ grid-template-columns: 1fr 1fr;
+ grid-column-gap: 60px;
+ grid-row-gap: 60px;
+ align-items: start;
+}
+
+.counterItem {
+ display: flex;
+ flex-flow: column;
+}
+
+.counterTitle {
+ font-family: var(--ifm-heading-font-family);
+ margin-bottom: 0;
+ font-size: 44px;
+ font-weight: 600;
+ line-height: 1.3em;
+ color: #fff;
+}
+
+.counterLabel {
+ color: #e1e0e9;
+ font-size: 18px;
+ margin-top: 4px;
+}
+
+@media screen and (max-width: 991px) {
+ .aboutTitleGrid {
+ grid-template-columns: 1fr;
+ grid-column-gap: 10px;
+ grid-row-gap: 10px;
+ }
+ .counterGrid {
+ grid-template-columns: 1fr;
+ }
+ .stats {
+ grid-column-gap: 50px;
+ grid-row-gap: 50px;
+ }
+}
+
+@media screen and (max-width: 767px) {
+ .aboutTitle {
+ font-size: 42px;
+ }
+ .counterTitle {
+ font-size: 30px;
+ }
+ .stats {
+ grid-column-gap: 30px;
+ grid-row-gap: 30px;
+ }
+}
+
+/* ===== Features section ===== */
+
+.featuresSection {
+ position: relative;
+}
+
+.featuresTitleWrap {
+ z-index: 2;
+ position: relative;
+ margin: 0 auto 70px auto;
+ width: 50%;
+ text-align: center;
+ display: flex;
+ flex-flow: column;
+}
+
+.featuresTitle {
+ margin: 0 0 10px 0;
+ font-family: var(--ifm-heading-font-family);
+ color: #fff;
+ font-size: 50px;
+ font-weight: 600;
+ line-height: 1.2em;
+}
+
+.featuresSubtitle {
+ margin: 0;
+ color: #e1e0e9;
+ font-size: 18px;
+ font-weight: 400;
+}
+
+.featuresGrid {
+ position: relative;
+ display: grid;
+ grid-template-rows: auto;
+ grid-template-columns: 1fr 1fr 1fr;
+ grid-column-gap: 50px;
+ grid-row-gap: 50px;
+}
+
+.featuresDecoration {
+ background-image: linear-gradient(180deg, #d35f5f 40%, #a561a3);
+ opacity: 0.5;
+ filter: blur(140px);
+ width: 450px;
+ height: 100px;
+ margin: auto;
+ position: absolute;
+ inset: 0;
+ z-index: 0;
+ pointer-events: none;
+}
+
+.featuresItem {
+ z-index: 2;
+ position: relative;
+ display: flex;
+ flex-flow: column;
+ align-items: center;
+ text-align: center;
+ text-decoration: none;
+ transition: transform 0.3s;
+ column-gap: 20px;
+ row-gap: 20px;
+ color: inherit;
+}
+
+.featuresItem:hover {
+ transform: scale(1.04);
+ text-decoration: none;
+ color: inherit;
+}
+
+.featuresIconWrap {
+ flex: none;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 80px;
+ height: 80px;
+ padding: 1px;
+ border-radius: 50%;
+ background-image: linear-gradient(
+ 135deg,
+ #726cb3,
+ #d35f5f 60%,
+ #a561a3
+ );
+}
+
+.featuresIconBg {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ height: 100%;
+ border-radius: 50%;
+ background-color: #1b1a25;
+}
+
+.featuresIcon {
+ width: 32px;
+ height: 32px;
+}
+
+.featuresItemTitle {
+ margin: 0 0 10px 0;
+ font-family: var(--ifm-heading-font-family);
+ color: #fff;
+ font-size: 26px;
+ font-weight: 600;
+ line-height: 1.3em;
+}
+
+.featuresItemDescription {
+ margin: 0;
+ color: #e1e0e9;
+ font-size: 18px;
+}
+
+@media screen and (max-width: 1279px) {
+ .featuresGrid {
+ grid-column-gap: 50px;
+ grid-row-gap: 50px;
+ }
+}
+
+@media screen and (min-width: 1280px) {
+ .featuresGrid {
+ grid-column-gap: 90px;
+ grid-row-gap: 100px;
+ }
+ .featuresTitleWrap {
+ width: 95%;
+ }
+}
+
+@media screen and (max-width: 991px) {
+ .featuresTitleWrap {
+ width: 100%;
+ }
+ .featuresGrid {
+ grid-template-columns: 1fr 1fr;
+ }
+ .featuresIconWrap {
+ width: 70px;
+ height: 70px;
+ }
+}
+
+@media screen and (max-width: 767px) {
+ .featuresTitle {
+ font-size: 42px;
+ }
+ .featuresItemTitle {
+ font-size: 22px;
+ }
+ .featuresGrid {
+ grid-column-gap: 30px;
+ }
+}
+
+/* ===== Pricing section ===== */
+
+.pricingSection {
+ overflow-x: clip;
+ padding-top: 150px;
+ padding-bottom: 150px;
+}
+
+.pricingTitleWrap {
+ text-align: center;
+ width: 60%;
+ margin: 0 auto 40px auto;
+ position: relative;
+}
+
+.pricingTitleInner {
+ z-index: 2;
+ position: relative;
+}
+
+.pricingTitle {
+ margin: 0 0 10px 0;
+ font-family: var(--ifm-heading-font-family);
+ color: #fff;
+ font-size: 50px;
+ font-weight: 600;
+ line-height: 1.2em;
+}
+
+.pricingDescription {
+ margin: 0 0 40px 0;
+ color: #e1e0e9;
+ font-size: 18px;
+}
+
+.pricingDecoration {
+ background-image: linear-gradient(180deg, #d35f5f 40%, #a561a3);
+ filter: blur(110px);
+ width: 50%;
+ height: 90px;
+ margin: 179px auto auto auto;
+ position: absolute;
+ inset: 0;
+ z-index: 0;
+ pointer-events: none;
+}
+
+.pricingGrid {
+ z-index: 2;
+ position: relative;
+ display: grid;
+ grid-template-rows: auto;
+ grid-template-columns: 1fr 1fr 1fr;
+ grid-column-gap: 30px;
+ grid-row-gap: 30px;
+ margin-bottom: 30px;
+}
+
+.pricingItem {
+ display: flex;
+ flex-flow: column;
+ justify-content: flex-start;
+ align-items: flex-start;
+ border: 1px solid #242328;
+ border-radius: 20px;
+ background-color: #070417;
+ padding: 30px;
+}
+
+.pricingItemCenter {
+ border-color: #d35f5f;
+ background-color: #1b1a25;
+}
+
+.preTitle {
+ border: 1px solid #d35f5f;
+ border-radius: 50px;
+ background-color: #242328;
+ color: #fff;
+ text-align: center;
+ margin-bottom: 20px;
+ padding: 8px 20px;
+ font-size: 16px;
+ line-height: 1.3em;
+ font-family: var(--ifm-font-family-base);
+}
+
+.preTitleFounder {
+ border-color: #ffab22;
+ background-color: #1b1a25;
+}
+
+.preTitleEnterprise {
+ border-color: #5f6fd3;
+}
+
+.priceWrap {
+ display: flex;
+ flex-flow: wrap;
+ justify-content: flex-start;
+ align-items: baseline;
+ width: 100%;
+ column-gap: 10px;
+ row-gap: 5px;
+ margin-bottom: 20px;
+}
+
+.price {
+ margin: 0;
+ font-family: var(--ifm-heading-font-family);
+ color: #fff;
+ font-size: 30px;
+ font-weight: 600;
+ line-height: 1.2em;
+}
+
+.priceCenter {
+ text-align: right;
+ background-image: linear-gradient(180deg, #d35f5f 40%, #a561a3);
+ -webkit-text-fill-color: transparent;
+ -webkit-background-clip: text;
+ background-clip: text;
+}
+
+.itemTagline {
+ margin: 0;
+ color: #e1e0e9;
+ font-size: 18px;
+ line-height: 1.5em;
+}
+
+.featureList {
+ display: flex;
+ flex-flow: column;
+ width: 100%;
+ margin-top: 50px;
+ margin-bottom: 50px;
+ column-gap: 15px;
+ row-gap: 15px;
+}
+
+.featureItem {
+ display: flex;
+ align-items: flex-start;
+ justify-content: flex-start;
+ column-gap: 8px;
+ row-gap: 8px;
+ color: #e1e0e9;
+}
+
+.featureIcon {
+ flex: none;
+ width: 18px;
+ height: 18px;
+ margin-top: 5px;
+}
+
+.buttonList {
+ display: flex;
+ flex-flow: column;
+ align-items: stretch;
+ justify-content: flex-start;
+ width: 100%;
+ margin-top: auto;
+ text-align: center;
+ column-gap: 15px;
+ row-gap: 15px;
+}
+
+@media screen and (max-width: 991px) {
+ .pricingSection {
+ padding-top: 100px;
+ padding-bottom: 100px;
+ }
+ .pricingTitleWrap {
+ width: 100%;
+ }
+ .pricingGrid {
+ grid-template-columns: 1fr 1fr;
+ }
+ .featureList {
+ margin-top: 30px;
+ margin-bottom: 30px;
+ }
+}
+
+@media screen and (max-width: 767px) {
+ .pricingSection {
+ padding-top: 80px;
+ padding-bottom: 80px;
+ }
+ .pricingTitle {
+ font-size: 42px;
+ }
+ .pricingGrid {
+ grid-template-columns: 1fr;
+ grid-column-gap: 20px;
+ grid-row-gap: 20px;
+ margin-bottom: 20px;
+ }
+ .pricingItem {
+ padding: 20px;
+ }
+}
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index 64dc99a..69d2115 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -1,30 +1,433 @@
-import React, {type ReactNode} from 'react';
+import React, {type ReactNode, useEffect, useState} from 'react';
+import clsx from 'clsx';
import Layout from '@theme/Layout';
import Link from '@docusaurus/Link';
-import Translate, {translate} from '@docusaurus/Translate';
+import Hero from '@site/src/components/landing/Hero';
+import Servers from '@site/src/components/landing/Servers';
+import shared from '@site/src/components/landing/styles/shared.module.css';
+import styles from './index.module.css';
+
+type Counts = {
+ servers: number;
+ users: number;
+ captcha: number;
+ antispam: number;
+};
+
+type FormattedValue = {
+ value: string;
+ unit: string;
+};
+
+function formatValue(value: number): FormattedValue {
+ if (value >= 1_000_000) {
+ return {value: (value / 1_000_000).toFixed(1), unit: 'M'};
+ }
+ return {value: (value / 1_000).toFixed(1), unit: 'k'};
+}
+
+function StatCounter({
+ rawValue,
+ label,
+ fallback,
+}: {
+ rawValue?: number;
+ label: string;
+ fallback: string;
+}) {
+ if (rawValue == null) {
+ return (
+
+
+ {fallback}
+
+
{label}
+
+ );
+ }
+ const formatted = formatValue(rawValue);
+ return (
+
+
+ {formatted.value}
+ {formatted.unit}
+
+
{label}
+
+ );
+}
+
+const CHECK_ICON = '/img/landing/icon-02.svg';
+
+function FeatureItem({children}: {children: ReactNode}) {
+ return (
+
+
+
{children}
+
+ );
+}
+
+type Feature = {
+ to: string;
+ icon: string;
+ iconAlt: string;
+ title: string;
+ description: string;
+};
+
+const FEATURES: Feature[] = [
+ {
+ to: '/docs/features/anti-spam',
+ icon: '/img/landing/iconAntispamWhite.svg',
+ iconAlt: 'RaidProtect icon Antispam',
+ title: 'Protection anti-spam',
+ description:
+ 'Sanctionnez instantanément les tentatives de spam, sans aucune intervention de votre part.',
+ },
+ {
+ to: '/docs/features/raid-mode',
+ icon: '/img/landing/iconAntiraidWhite.svg',
+ iconAlt: 'RaidProtect icon Antiraid',
+ title: 'Blocage des raids',
+ description:
+ "Vous craignez un raid ? Notre bot est capable de le détecter et de le bloquer avant même qu'il impacte votre serveur.",
+ },
+ {
+ to: '/docs/features/captcha',
+ icon: '/img/landing/iconCaptchaWhite.svg',
+ iconAlt: 'RaidProtect icon Captcha',
+ title: 'Protection contre les robots',
+ description:
+ "Grâce au captcha, vos membres doivent prouver qu'ils sont humains. Dites adieu aux comptes automatisés.",
+ },
+ {
+ to: '/docs/features/utilities',
+ icon: '/img/landing/iconReportWhite.svg',
+ iconAlt: 'RaidProtect icon Report',
+ title: 'Modération & administration',
+ description:
+ "Gérez votre serveur comme un pro avec nos diverses fonctionalités de modération et d'administration.",
+ },
+ {
+ to: '/docs/features/tag-role',
+ icon: '/img/landing/iconTagWhite.svg',
+ iconAlt: 'RaidProtect icon Tag',
+ title: 'Rôle de Tag',
+ description:
+ 'Le Rôle de Tag permet d’attribuer automatiquement un rôle aux membres qui ajoutent le tag de votre serveur.',
+ },
+ {
+ to: '/docs/features/dm-lock',
+ icon: '/img/landing/iconDmlockWhite.svg',
+ iconAlt: 'RaidProtect icon DM Lock',
+ title: 'Fermeture des MP',
+ description:
+ 'Un bouclier inédit contre le spam, le scam et les arnaques par message privé.',
+ },
+];
export default function Home(): ReactNode {
+ const [counts, setCounts] = useState(null);
+
+ useEffect(() => {
+ let cancelled = false;
+ fetch('https://docs.raidprotect.bot/counts.json')
+ .then((res) => {
+ if (!res.ok) throw new Error('Erreur lors de la récupération des données');
+ return res.json();
+ })
+ .then((data: Counts) => {
+ if (!cancelled) setCounts(data);
+ })
+ .catch((err) => {
+ // Stats are best-effort; failure is non-blocking
+ // eslint-disable-next-line no-console
+ console.error('Erreur de mise à jour des statistiques :', err);
+ });
+ return () => {
+ cancelled = true;
+ };
+ }, []);
+
return (
-
-
- RaidProtect
-
-
-
- La nouvelle page d'accueil arrive bientôt. En attendant, retrouvez toute la documentation ci-dessous.
-
-
-
-
- Accéder à la documentation
-
-
+ title="RaidProtect • Sécurisez votre serveur Discord"
+ description="RaidProtect est un bot Discord français ayant pour mission de protéger simplement votre serveur des utilisateurs malintentionnés.">
+
+
+
+
+ {/* About */}
+
+
+
+
+ Nos résultats ont un{' '}
+ impact
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Features */}
+
+
+
+
+ Nos fonctionnalités
+
+
+ Découvrez ce qui fait de nous l'un des meilleurs bots pour protéger
+ votre serveur Discord des utilisateurs malintentionnés.
+
+
+
+
+ {FEATURES.map((feature) => (
+
+
+
+
+
+
+
+
{feature.title}
+
+ {feature.description}
+
+
+
+ ))}
+
+
+
+
+ {/* Pricing */}
+
+
+
+
+
+ Garder une longueur{' '}
+ d'avance
+
+
+ Ajoutez RaidProtect et commencez à protéger votre serveur dès
+ aujourd'hui.
+
+
+
+
+
+ {/* Basic */}
+
+
Basic
+
+
Gratuit
+
+
+ La sécurité essentielle assurée pour toujours
+
+
+ Protections anti-spam
+ Blocage automatique des raids
+ Filtrage des bots malveillants
+ Modération & administration
+
+ Et bien plus encore...
+
+
+
+
+
+ {/* Founder */}
+
+
+ Founder
+
+
+
Abonnement
+
+ 2,99 $
+
+
+
+ Offre de lancement réservée aux premiers abonnés
+
+
+ Profil du bot personnalisable
+ Noms de sanctions custom
+ Accès avancé à l'Auth Manager
+ Accès étendu au Display Public
+ Accès à la Bêta publique
+ Rôle exclusif sur notre serveur
+
+
+
+
+ {/* Business */}
+
+
+ Business
+
+
+
Sur demande
+
+
+ Pour les projets aux exigences de sécurité élevées
+
+
+ Les fonctionnalités Founder
+ Instance dédiée et isolée
+ Audit initial de votre serveur
+ Intégration avec vos outils
+ Fonctionnalités sur mesure
+ Suivi régulier avec un expert
+ Support prioritaire
+
+
+
+
+
+
);
diff --git a/static/img/landing/411d8a698dd15ddf.webp b/static/img/landing/411d8a698dd15ddf.webp
new file mode 100644
index 0000000..db9fa67
Binary files /dev/null and b/static/img/landing/411d8a698dd15ddf.webp differ
diff --git a/static/img/landing/RP-embed-p-1080.webp b/static/img/landing/RP-embed-p-1080.webp
new file mode 100644
index 0000000..79efe3e
Binary files /dev/null and b/static/img/landing/RP-embed-p-1080.webp differ
diff --git a/static/img/landing/RP-embed-p-500.webp b/static/img/landing/RP-embed-p-500.webp
new file mode 100644
index 0000000..e535087
Binary files /dev/null and b/static/img/landing/RP-embed-p-500.webp differ
diff --git a/static/img/landing/RP-embed-p-800.webp b/static/img/landing/RP-embed-p-800.webp
new file mode 100644
index 0000000..0b19aae
Binary files /dev/null and b/static/img/landing/RP-embed-p-800.webp differ
diff --git a/static/img/landing/RP-embed.webp b/static/img/landing/RP-embed.webp
new file mode 100644
index 0000000..88c8559
Binary files /dev/null and b/static/img/landing/RP-embed.webp differ
diff --git a/static/img/landing/favicon.png b/static/img/landing/favicon.png
new file mode 100644
index 0000000..6ab3afd
Binary files /dev/null and b/static/img/landing/favicon.png differ
diff --git a/static/img/landing/icon-02.svg b/static/img/landing/icon-02.svg
new file mode 100644
index 0000000..2746652
--- /dev/null
+++ b/static/img/landing/icon-02.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/static/img/landing/icon-geranium.svg b/static/img/landing/icon-geranium.svg
new file mode 100644
index 0000000..e1a5ad8
--- /dev/null
+++ b/static/img/landing/icon-geranium.svg
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/static/img/landing/iconAntiraidWhite.svg b/static/img/landing/iconAntiraidWhite.svg
new file mode 100644
index 0000000..df1d271
--- /dev/null
+++ b/static/img/landing/iconAntiraidWhite.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/static/img/landing/iconAntispamWhite.svg b/static/img/landing/iconAntispamWhite.svg
new file mode 100644
index 0000000..4b3f4f4
--- /dev/null
+++ b/static/img/landing/iconAntispamWhite.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/static/img/landing/iconArtofWar3.webp b/static/img/landing/iconArtofWar3.webp
new file mode 100644
index 0000000..12bb9f7
Binary files /dev/null and b/static/img/landing/iconArtofWar3.webp differ
diff --git a/static/img/landing/iconBloxFruitsFR.webp b/static/img/landing/iconBloxFruitsFR.webp
new file mode 100644
index 0000000..55d3cec
Binary files /dev/null and b/static/img/landing/iconBloxFruitsFR.webp differ
diff --git a/static/img/landing/iconCaptchaWhite.svg b/static/img/landing/iconCaptchaWhite.svg
new file mode 100644
index 0000000..2b52714
--- /dev/null
+++ b/static/img/landing/iconCaptchaWhite.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/static/img/landing/iconChatzone.webp b/static/img/landing/iconChatzone.webp
new file mode 100644
index 0000000..62d5fa5
Binary files /dev/null and b/static/img/landing/iconChatzone.webp differ
diff --git a/static/img/landing/iconClashGG.webp b/static/img/landing/iconClashGG.webp
new file mode 100644
index 0000000..c58a383
Binary files /dev/null and b/static/img/landing/iconClashGG.webp differ
diff --git a/static/img/landing/iconClashRoyaleFR.webp b/static/img/landing/iconClashRoyaleFR.webp
new file mode 100644
index 0000000..ade9f1e
Binary files /dev/null and b/static/img/landing/iconClashRoyaleFR.webp differ
diff --git a/static/img/landing/iconCyrilmp4.webp b/static/img/landing/iconCyrilmp4.webp
new file mode 100644
index 0000000..a31c0c4
Binary files /dev/null and b/static/img/landing/iconCyrilmp4.webp differ
diff --git a/static/img/landing/iconDiscord.svg b/static/img/landing/iconDiscord.svg
new file mode 100644
index 0000000..8a937d5
--- /dev/null
+++ b/static/img/landing/iconDiscord.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/static/img/landing/iconDistrict10.webp b/static/img/landing/iconDistrict10.webp
new file mode 100644
index 0000000..d945426
Binary files /dev/null and b/static/img/landing/iconDistrict10.webp differ
diff --git a/static/img/landing/iconDmlockWhite.svg b/static/img/landing/iconDmlockWhite.svg
new file mode 100644
index 0000000..eaa8a8e
--- /dev/null
+++ b/static/img/landing/iconDmlockWhite.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/static/img/landing/iconEclipse.webp b/static/img/landing/iconEclipse.webp
new file mode 100644
index 0000000..b5ced10
Binary files /dev/null and b/static/img/landing/iconEclipse.webp differ
diff --git a/static/img/landing/iconFlexingSeal.webp b/static/img/landing/iconFlexingSeal.webp
new file mode 100644
index 0000000..72aa067
Binary files /dev/null and b/static/img/landing/iconFlexingSeal.webp differ
diff --git a/static/img/landing/iconFortniteHouse.webp b/static/img/landing/iconFortniteHouse.webp
new file mode 100644
index 0000000..5f79842
Binary files /dev/null and b/static/img/landing/iconFortniteHouse.webp differ
diff --git a/static/img/landing/iconGenshinImpactFR.webp b/static/img/landing/iconGenshinImpactFR.webp
new file mode 100644
index 0000000..fdf60b9
Binary files /dev/null and b/static/img/landing/iconGenshinImpactFR.webp differ
diff --git a/static/img/landing/iconGitHub.svg b/static/img/landing/iconGitHub.svg
new file mode 100644
index 0000000..80ac1a0
--- /dev/null
+++ b/static/img/landing/iconGitHub.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/static/img/landing/iconJobless.webp b/static/img/landing/iconJobless.webp
new file mode 100644
index 0000000..b9b660d
Binary files /dev/null and b/static/img/landing/iconJobless.webp differ
diff --git a/static/img/landing/iconLigue1.webp b/static/img/landing/iconLigue1.webp
new file mode 100644
index 0000000..3aeef05
Binary files /dev/null and b/static/img/landing/iconLigue1.webp differ
diff --git a/static/img/landing/iconLinkedIn.svg b/static/img/landing/iconLinkedIn.svg
new file mode 100644
index 0000000..d730c0b
--- /dev/null
+++ b/static/img/landing/iconLinkedIn.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/static/img/landing/iconMastu.webp b/static/img/landing/iconMastu.webp
new file mode 100644
index 0000000..2152f05
Binary files /dev/null and b/static/img/landing/iconMastu.webp differ
diff --git a/static/img/landing/iconMetaLock.webp b/static/img/landing/iconMetaLock.webp
new file mode 100644
index 0000000..ab75bb5
Binary files /dev/null and b/static/img/landing/iconMetaLock.webp differ
diff --git a/static/img/landing/iconNationsGlory.webp b/static/img/landing/iconNationsGlory.webp
new file mode 100644
index 0000000..2cde6d0
Binary files /dev/null and b/static/img/landing/iconNationsGlory.webp differ
diff --git a/static/img/landing/iconPUBGMobileFrance.webp b/static/img/landing/iconPUBGMobileFrance.webp
new file mode 100644
index 0000000..832c71c
Binary files /dev/null and b/static/img/landing/iconPUBGMobileFrance.webp differ
diff --git a/static/img/landing/iconPUBGMobileUK.webp b/static/img/landing/iconPUBGMobileUK.webp
new file mode 100644
index 0000000..7712f12
Binary files /dev/null and b/static/img/landing/iconPUBGMobileUK.webp differ
diff --git a/static/img/landing/iconReportWhite.svg b/static/img/landing/iconReportWhite.svg
new file mode 100644
index 0000000..825b4bc
--- /dev/null
+++ b/static/img/landing/iconReportWhite.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/static/img/landing/iconRocketBaguette.webp b/static/img/landing/iconRocketBaguette.webp
new file mode 100644
index 0000000..56df15f
Binary files /dev/null and b/static/img/landing/iconRocketBaguette.webp differ
diff --git a/static/img/landing/iconRocketLeagueFrance.webp b/static/img/landing/iconRocketLeagueFrance.webp
new file mode 100644
index 0000000..2d44604
Binary files /dev/null and b/static/img/landing/iconRocketLeagueFrance.webp differ
diff --git a/static/img/landing/iconSlashFR.webp b/static/img/landing/iconSlashFR.webp
new file mode 100644
index 0000000..88f56ac
Binary files /dev/null and b/static/img/landing/iconSlashFR.webp differ
diff --git a/static/img/landing/iconTagWhite.svg b/static/img/landing/iconTagWhite.svg
new file mode 100644
index 0000000..44e1c07
--- /dev/null
+++ b/static/img/landing/iconTagWhite.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/static/img/landing/iconTeamVitality.webp b/static/img/landing/iconTeamVitality.webp
new file mode 100644
index 0000000..fc58127
Binary files /dev/null and b/static/img/landing/iconTeamVitality.webp differ
diff --git a/static/img/landing/iconTheForge.webp b/static/img/landing/iconTheForge.webp
new file mode 100644
index 0000000..4f0e196
Binary files /dev/null and b/static/img/landing/iconTheForge.webp differ
diff --git a/static/img/landing/iconWankilStudio.webp b/static/img/landing/iconWankilStudio.webp
new file mode 100644
index 0000000..59b21eb
Binary files /dev/null and b/static/img/landing/iconWankilStudio.webp differ
diff --git a/static/img/landing/iconWeWard.webp b/static/img/landing/iconWeWard.webp
new file mode 100644
index 0000000..dd4c769
Binary files /dev/null and b/static/img/landing/iconWeWard.webp differ
diff --git a/static/img/landing/iconX.svg b/static/img/landing/iconX.svg
new file mode 100644
index 0000000..9acfb6b
--- /dev/null
+++ b/static/img/landing/iconX.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/static/img/landing/iconYouTube.svg b/static/img/landing/iconYouTube.svg
new file mode 100644
index 0000000..fcf1429
--- /dev/null
+++ b/static/img/landing/iconYouTube.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/static/img/landing/iconZetFar.webp b/static/img/landing/iconZetFar.webp
new file mode 100644
index 0000000..81694ec
Binary files /dev/null and b/static/img/landing/iconZetFar.webp differ
diff --git a/static/img/landing/logoRaidProtect.svg b/static/img/landing/logoRaidProtect.svg
new file mode 100644
index 0000000..174d47b
--- /dev/null
+++ b/static/img/landing/logoRaidProtect.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/static/img/landing/pattern-01.svg b/static/img/landing/pattern-01.svg
new file mode 100644
index 0000000..75e229c
--- /dev/null
+++ b/static/img/landing/pattern-01.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/static/img/landing/serverBadgePartner.svg b/static/img/landing/serverBadgePartner.svg
new file mode 100644
index 0000000..9960d7b
--- /dev/null
+++ b/static/img/landing/serverBadgePartner.svg
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/static/img/landing/serverBadgeVerified.svg b/static/img/landing/serverBadgeVerified.svg
new file mode 100644
index 0000000..f677182
--- /dev/null
+++ b/static/img/landing/serverBadgeVerified.svg
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/static/img/landing/webclip.png b/static/img/landing/webclip.png
new file mode 100644
index 0000000..8eb16d3
Binary files /dev/null and b/static/img/landing/webclip.png differ