creation site static coupe du monde 2026 sans Hugo
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="gs" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0" stop-color="#2f7bff"/>
|
||||
<stop offset=".55" stop-color="#a81fc4"/>
|
||||
<stop offset="1" stop-color="#6a1fae"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="gw" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0" stop-color="#19d39a"/>
|
||||
<stop offset="1" stop-color="#0e9e8a"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<circle cx="50" cy="52" r="34" fill="url(#gs)"/>
|
||||
<g stroke="#fff" stroke-width="1.2" fill="none" opacity=".8">
|
||||
<ellipse cx="50" cy="52" rx="34" ry="13"/>
|
||||
<ellipse cx="50" cy="52" rx="22" ry="34"/>
|
||||
<ellipse cx="50" cy="52" rx="11" ry="34"/>
|
||||
<line x1="16" y1="52" x2="84" y2="52"/>
|
||||
</g>
|
||||
<path d="M22 84 C40 70 64 64 86 34 C70 60 46 70 22 84 Z" fill="url(#gw)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 863 B |
Binary file not shown.
|
After Width: | Height: | Size: 61 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
@@ -0,0 +1,90 @@
|
||||
/* ---------------- launch countdown i18n ---------------- */
|
||||
const DICT = {
|
||||
fr: {
|
||||
meta_title: "TutoSport Expert — Ouverture le 22 juin 2026",
|
||||
meta_description:
|
||||
"Les académies de Dimitri Payet & Yannick Dyduch arrivent. Offre Coupe du Monde : les 2 académies à 7,90€. Ouverture le 22 juin 2026.",
|
||||
tag: "Ouverture · 22 juin 2026",
|
||||
h1a: "Le compte à rebours",
|
||||
h1b: "est lancé.",
|
||||
sub: "Les académies de Dimitri Payet & Yannick Dyduch arrivent. Préparez-vous à l'offre Coupe du Monde.",
|
||||
l_d: "Jours",
|
||||
l_h: "Heures",
|
||||
l_m: "Minutes",
|
||||
l_s: "Secondes",
|
||||
offer_a: "Les 2 académies à",
|
||||
offer_b: "au lieu de 80€ · offre limitée Coupe du Monde",
|
||||
ph: "Ton adresse e-mail",
|
||||
btn: "Préviens-moi",
|
||||
thanks: "Merci ! On te prévient dès l'ouverture.",
|
||||
note: "Sois prévenu·e en premier et garde l'offre 7,90€.",
|
||||
rights: "© 2026 TutoSport Expert. Tous droits réservés.",
|
||||
cd_d: "j",
|
||||
},
|
||||
en: {
|
||||
meta_title: "TutoSport Expert — Opening June 22, 2026",
|
||||
meta_description:
|
||||
"The academies of Dimitri Payet & Yannick Dyduch are coming. World Cup offer: both academies for €7.90. Opening June 22, 2026.",
|
||||
tag: "Opening · June 22, 2026",
|
||||
h1a: "The countdown",
|
||||
h1b: "has started.",
|
||||
sub: "The academies of Dimitri Payet & Yannick Dyduch are coming. Get ready for the World Cup offer.",
|
||||
l_d: "Days",
|
||||
l_h: "Hours",
|
||||
l_m: "Minutes",
|
||||
l_s: "Seconds",
|
||||
offer_a: "Both academies for",
|
||||
offer_b: "instead of €80 · limited World Cup offer",
|
||||
ph: "Your email address",
|
||||
btn: "Notify me",
|
||||
thanks: "Thanks! We'll let you know at launch.",
|
||||
note: "Be the first in and keep the €7.90 offer.",
|
||||
rights: "© 2026 TutoSport Expert. All rights reserved.",
|
||||
cd_d: "d",
|
||||
},
|
||||
es: {
|
||||
meta_title: "TutoSport Expert — Apertura el 22 de junio de 2026",
|
||||
meta_description:
|
||||
"Las academias de Dimitri Payet y Yannick Dyduch llegan. Oferta Mundial: las 2 academias por 7,90€. Apertura el 22 de junio de 2026.",
|
||||
tag: "Apertura · 22 de junio de 2026",
|
||||
h1a: "La cuenta atrás",
|
||||
h1b: "ha comenzado.",
|
||||
sub: "Las academias de Dimitri Payet y Yannick Dyduch llegan. Prepárate para la oferta del Mundial.",
|
||||
l_d: "Días",
|
||||
l_h: "Horas",
|
||||
l_m: "Minutos",
|
||||
l_s: "Segundos",
|
||||
offer_a: "Las 2 academias por",
|
||||
offer_b: "en vez de 80€ · oferta limitada del Mundial",
|
||||
ph: "Tu correo electrónico",
|
||||
btn: "Avísame",
|
||||
thanks: "¡Gracias! Te avisamos en la apertura.",
|
||||
note: "Entra el primero y conserva la oferta de 7,90€.",
|
||||
rights: "© 2026 TutoSport Expert. Todos los derechos reservados.",
|
||||
cd_d: "d",
|
||||
},
|
||||
pt: {
|
||||
meta_title: "TutoSport Expert — Abertura em 22 de junho de 2026",
|
||||
meta_description:
|
||||
"As academias de Dimitri Payet e Yannick Dyduch chegam. Oferta Copa do Mundo: as 2 academias por 7,90€. Abertura em 22 de junho de 2026.",
|
||||
tag: "Abertura · 22 de junho de 2026",
|
||||
h1a: "A contagem regressiva",
|
||||
h1b: "começou.",
|
||||
sub: "As academias de Dimitri Payet e Yannick Dyduch chegam. Prepare-se para a oferta da Copa do Mundo.",
|
||||
l_d: "Dias",
|
||||
l_h: "Horas",
|
||||
l_m: "Minutos",
|
||||
l_s: "Segundos",
|
||||
offer_a: "As 2 academias por",
|
||||
offer_b: "em vez de 80€ · oferta limitada da Copa",
|
||||
ph: "Seu e-mail",
|
||||
btn: "Avise-me",
|
||||
thanks: "Obrigado! Avisamos na abertura.",
|
||||
note: "Seja o primeiro e garanta a oferta de 7,90€.",
|
||||
rights: "© 2026 TutoSport Expert. Todos os direitos reservados.",
|
||||
cd_d: "d",
|
||||
},
|
||||
};
|
||||
|
||||
const DEFAULT_LANG = "en";
|
||||
const LANG_STORAGE_KEY = "tutosport_lang";
|
||||
@@ -0,0 +1,372 @@
|
||||
const SUPPORTED_LANGS = Object.keys(DICT);
|
||||
let LANG = DEFAULT_LANG;
|
||||
|
||||
function getStripePricingTableHtml(lang) {
|
||||
const pricingTableId =
|
||||
SITE_CONFIG.stripe.pricingTableIds[lang] ||
|
||||
SITE_CONFIG.stripe.pricingTableIds.en;
|
||||
|
||||
return (
|
||||
`<stripe-pricing-table pricing-table-id="${pricingTableId}" ` +
|
||||
`publishable-key="${SITE_CONFIG.stripe.publishableKey}"></stripe-pricing-table>`
|
||||
);
|
||||
}
|
||||
|
||||
function normalizeLang(value) {
|
||||
if (!value) return null;
|
||||
const lang = String(value).toLowerCase().split(/[-_]/)[0];
|
||||
return DICT[lang] ? lang : null;
|
||||
}
|
||||
|
||||
function getStoredLang() {
|
||||
const cookieMatch = document.cookie.match(
|
||||
new RegExp(`(?:^|; )${LANG_STORAGE_KEY}=([^;]*)`),
|
||||
);
|
||||
try {
|
||||
return (
|
||||
normalizeLang(localStorage.getItem(LANG_STORAGE_KEY)) ||
|
||||
normalizeLang(cookieMatch && decodeURIComponent(cookieMatch[1]))
|
||||
);
|
||||
} catch (e) {
|
||||
return normalizeLang(cookieMatch && decodeURIComponent(cookieMatch[1]));
|
||||
}
|
||||
}
|
||||
|
||||
function getUrlLang() {
|
||||
return normalizeLang(new URLSearchParams(location.search).get("lang"));
|
||||
}
|
||||
|
||||
function getBrowserLang() {
|
||||
const browserLangs = navigator.languages && navigator.languages.length
|
||||
? navigator.languages
|
||||
: [navigator.language];
|
||||
for (const lang of browserLangs) {
|
||||
const normalized = normalizeLang(lang);
|
||||
if (normalized) return normalized;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function getInitialLang() {
|
||||
return getUrlLang() || getStoredLang() || getBrowserLang() || DEFAULT_LANG;
|
||||
}
|
||||
|
||||
function getRootPrefix() {
|
||||
if (document.body && document.body.dataset.rootPrefix) {
|
||||
return document.body.dataset.rootPrefix;
|
||||
}
|
||||
const pathParts = location.pathname.split("/").filter(Boolean);
|
||||
const parentDir = pathParts.length > 1 ? pathParts[pathParts.length - 2] : "";
|
||||
return SUPPORTED_LANGS.includes(parentDir) ? "../" : "./";
|
||||
}
|
||||
|
||||
function withLangParam(href, lang) {
|
||||
const [pathWithSearch, hash = ""] = href.split("#");
|
||||
const [path, search = ""] = pathWithSearch.split("?");
|
||||
const params = new URLSearchParams(search);
|
||||
params.set("lang", lang);
|
||||
return `${path}?${params.toString()}${hash ? `#${hash}` : ""}`;
|
||||
}
|
||||
|
||||
function getLocalizedPageUrl(lang) {
|
||||
const pathParts = location.pathname.split("/").filter(Boolean);
|
||||
const parentDir = pathParts.length > 1 ? pathParts[pathParts.length - 2] : "";
|
||||
const fileName = pathParts[pathParts.length - 1] || "";
|
||||
if (!SUPPORTED_LANGS.includes(parentDir)) return null;
|
||||
if (fileName !== "cgv.html" && fileName !== "legals.html") return null;
|
||||
return withLangParam(`../${lang}/${fileName}`, lang);
|
||||
}
|
||||
|
||||
function updateInternalLinks(lang) {
|
||||
const rootPrefix = getRootPrefix();
|
||||
const homeHref = withLangParam(rootPrefix, lang);
|
||||
const offerHref = withLangParam(`${rootPrefix}offre.html`, lang);
|
||||
const legalPrefix = `${rootPrefix}${lang}/`;
|
||||
const anchors = {
|
||||
nav_offer: `${homeHref}#offre`,
|
||||
nav_acad: `${homeHref}#academies`,
|
||||
nav_how: `${homeHref}#how`,
|
||||
nav_faq: `${homeHref}#faq`,
|
||||
legal1: withLangParam(`${legalPrefix}cgv.html`, lang),
|
||||
legal2: withLangParam(`${legalPrefix}legals.html`, lang),
|
||||
};
|
||||
|
||||
Object.entries(anchors).forEach(([key, href]) => {
|
||||
document
|
||||
.querySelectorAll(`a[data-i18n="${key}"]`)
|
||||
.forEach((link) => link.setAttribute("href", href));
|
||||
});
|
||||
|
||||
document.querySelectorAll("a.brand, a.foot-logo-wrap").forEach((link) => {
|
||||
link.setAttribute("href", homeHref);
|
||||
});
|
||||
|
||||
document.querySelectorAll("a[href]").forEach((link) => {
|
||||
const href = link.getAttribute("href");
|
||||
if (!href || href.startsWith("http") || href.startsWith("mailto:")) return;
|
||||
if (href.includes("offre.html")) {
|
||||
link.setAttribute("href", offerHref);
|
||||
} else if (href === "#offre" || href === "./#offre") {
|
||||
link.setAttribute("href", `${homeHref}#offre`);
|
||||
} else if (href === "#academies" || href === "./#academies") {
|
||||
link.setAttribute("href", `${homeHref}#academies`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updateGoogleTagManagerNoScript() {
|
||||
const gtmId = SITE_CONFIG.googleTagManagerId;
|
||||
if (!gtmId) return;
|
||||
|
||||
document
|
||||
.querySelectorAll('iframe[src*="googletagmanager.com/ns.html"]')
|
||||
.forEach((iframe) => {
|
||||
iframe.setAttribute(
|
||||
"src",
|
||||
`https://www.googletagmanager.com/ns.html?id=${gtmId}`,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function loadGoogleTagManagerScript() {
|
||||
const gtmId = SITE_CONFIG.googleTagManagerId;
|
||||
if (!gtmId) return;
|
||||
if (
|
||||
document.querySelector(
|
||||
`script[src*="googletagmanager.com/gtm.js?id=${gtmId}"]`,
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
(function (w, d, s, l, i) {
|
||||
w[l] = w[l] || [];
|
||||
w[l].push({ "gtm.start": new Date().getTime(), event: "gtm.js" });
|
||||
const f = d.getElementsByTagName(s)[0];
|
||||
const j = d.createElement(s);
|
||||
const dl = l !== "dataLayer" ? `&l=${l}` : "";
|
||||
j.async = true;
|
||||
j.src = `https://www.googletagmanager.com/gtm.js?id=${i}${dl}`;
|
||||
f.parentNode.insertBefore(j, f);
|
||||
})(window, document, "script", "dataLayer", gtmId);
|
||||
}
|
||||
|
||||
function updateConfiguredSiteUrl() {
|
||||
const siteUrl = SITE_CONFIG.siteUrl;
|
||||
const siteUrlAliases = SITE_CONFIG.siteUrlAliases || [];
|
||||
if (!siteUrl) return;
|
||||
|
||||
document.querySelectorAll("[href], [src]").forEach((el) => {
|
||||
["href", "src"].forEach((attr) => {
|
||||
const value = el.getAttribute(attr);
|
||||
const alias = siteUrlAliases.find(
|
||||
(item) => value && value.includes(item),
|
||||
);
|
||||
if (alias) {
|
||||
el.setAttribute(attr, value.replaceAll(alias, siteUrl));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (!document.createTreeWalker || !document.body) return;
|
||||
const walker = document.createTreeWalker(document.body, 4);
|
||||
let node = walker.nextNode();
|
||||
while (node) {
|
||||
const alias = siteUrlAliases.find((item) =>
|
||||
node.nodeValue.includes(item),
|
||||
);
|
||||
if (alias) {
|
||||
node.nodeValue = node.nodeValue.replaceAll(alias, siteUrl);
|
||||
}
|
||||
node = walker.nextNode();
|
||||
}
|
||||
}
|
||||
|
||||
function updateSocialLinks() {
|
||||
const socialLinks = SITE_CONFIG.socialLinks || {};
|
||||
const selectors = {
|
||||
instagram: 'a[aria-label="Instagram"]',
|
||||
facebook: 'a[aria-label="Facebook"]:not([data-disabled="true"])',
|
||||
tiktok: 'a[aria-label="TikTok"]:not([data-disabled="true"])',
|
||||
linkedin: 'a[aria-label="LinkedIn"]:not([data-disabled="true"])',
|
||||
};
|
||||
|
||||
Object.entries(selectors).forEach(([key, selector]) => {
|
||||
const href = socialLinks[key];
|
||||
if (!href) return;
|
||||
document
|
||||
.querySelectorAll(selector)
|
||||
.forEach((link) => {
|
||||
link.setAttribute("href", href);
|
||||
link.setAttribute("target", "_blank");
|
||||
link.setAttribute("rel", "noopener noreferrer");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getFooterPath() {
|
||||
return `${getRootPrefix()}footer.html`;
|
||||
}
|
||||
|
||||
async function loadFooter() {
|
||||
const placeholders = document.querySelectorAll('[data-include="footer"]');
|
||||
if (!placeholders.length || !window.fetch) return;
|
||||
|
||||
try {
|
||||
const response = await fetch(getFooterPath());
|
||||
if (!response.ok) return;
|
||||
|
||||
const rootPrefix = getRootPrefix();
|
||||
const footerHtml = (await response.text()).replaceAll(
|
||||
'src="assets/',
|
||||
`src="${rootPrefix}assets/`,
|
||||
);
|
||||
|
||||
placeholders.forEach((placeholder) => {
|
||||
placeholder.innerHTML = footerHtml;
|
||||
});
|
||||
|
||||
setLang(LANG);
|
||||
updateConfiguredSiteUrl();
|
||||
updateSocialLinks();
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
function setLang(l, options = {}) {
|
||||
const normalizedLang = normalizeLang(l);
|
||||
if (!normalizedLang) return;
|
||||
LANG = normalizedLang;
|
||||
if (options.persist) {
|
||||
try {
|
||||
localStorage.setItem(LANG_STORAGE_KEY, normalizedLang);
|
||||
} catch (e) {}
|
||||
document.cookie = `${LANG_STORAGE_KEY}=${encodeURIComponent(
|
||||
normalizedLang,
|
||||
)};path=/;max-age=31536000;SameSite=Lax`;
|
||||
}
|
||||
const localizedPageUrl = options.navigate
|
||||
? getLocalizedPageUrl(normalizedLang)
|
||||
: null;
|
||||
if (localizedPageUrl && localizedPageUrl !== location.pathname + location.search) {
|
||||
location.href = localizedPageUrl;
|
||||
return;
|
||||
}
|
||||
document.documentElement.lang = normalizedLang;
|
||||
document.querySelectorAll("[data-i18n]").forEach((el) => {
|
||||
const v = DICT[normalizedLang][el.getAttribute("data-i18n")];
|
||||
if (v != null) el.textContent = v;
|
||||
});
|
||||
document.querySelectorAll("[data-i18n-html]").forEach((el) => {
|
||||
const key = el.getAttribute("data-i18n-html");
|
||||
const v =
|
||||
key === "pricing"
|
||||
? getStripePricingTableHtml(normalizedLang)
|
||||
: DICT[normalizedLang][key];
|
||||
if (v != null) el.innerHTML = v;
|
||||
});
|
||||
document.querySelectorAll("[data-i18n-content]").forEach((el) => {
|
||||
const v = DICT[normalizedLang][el.getAttribute("data-i18n-content")];
|
||||
if (v != null) el.setAttribute("content", v);
|
||||
});
|
||||
document.querySelectorAll("[data-i18n-ph]").forEach((el) => {
|
||||
const v = DICT[normalizedLang][el.getAttribute("data-i18n-ph")];
|
||||
if (v != null) el.setAttribute("placeholder", v);
|
||||
});
|
||||
document
|
||||
.querySelectorAll(".langsw button")
|
||||
.forEach((b) => {
|
||||
const isActive = b.dataset.lang === normalizedLang;
|
||||
b.classList.toggle("on", isActive);
|
||||
b.setAttribute("aria-pressed", String(isActive));
|
||||
});
|
||||
updateInternalLinks(normalizedLang);
|
||||
renderCountdown();
|
||||
}
|
||||
document
|
||||
.querySelectorAll(".langsw button")
|
||||
.forEach((b) =>
|
||||
b.addEventListener("click", () =>
|
||||
setLang(b.dataset.lang, { persist: true, navigate: true }),
|
||||
)
|
||||
);
|
||||
|
||||
loadGoogleTagManagerScript();
|
||||
updateGoogleTagManagerNoScript();
|
||||
updateConfiguredSiteUrl();
|
||||
updateSocialLinks();
|
||||
loadFooter();
|
||||
|
||||
/* ---------------- countdown ---------------- */
|
||||
const TARGET = new Date("2026-07-19T23:59:59+02:00").getTime();
|
||||
function renderCountdown() {
|
||||
const now = Date.now();
|
||||
let diff = Math.max(0, TARGET - now);
|
||||
const d = Math.floor(diff / 86400000);
|
||||
diff -= d * 86400000;
|
||||
const h = Math.floor(diff / 3600000);
|
||||
diff -= h * 3600000;
|
||||
const m = Math.floor(diff / 60000);
|
||||
diff -= m * 60000;
|
||||
const s = Math.floor(diff / 1000);
|
||||
const p = (n) => String(n).padStart(2, "0");
|
||||
const du = (DICT[LANG] && DICT[LANG].cd_d) || "d";
|
||||
const str = `${d}${du} ${p(h)}h ${p(m)}m ${p(s)}s`;
|
||||
document.querySelectorAll(".js-cd").forEach((e) => (e.textContent = str));
|
||||
}
|
||||
setLang(getInitialLang());
|
||||
setInterval(renderCountdown, 1000);
|
||||
|
||||
/* ---------------- header scroll ---------------- */
|
||||
const hd = document.getElementById("hd");
|
||||
if (hd) {
|
||||
addEventListener(
|
||||
"scroll",
|
||||
() => hd.classList.toggle("scrolled", scrollY > 10),
|
||||
{ passive: true },
|
||||
);
|
||||
}
|
||||
|
||||
/* ---------------- mobile menu ---------------- */
|
||||
const burger = document.getElementById("burger");
|
||||
if (burger && hd) {
|
||||
burger.addEventListener("click", () => {
|
||||
const open = hd.classList.toggle("menu-open");
|
||||
burger.setAttribute("aria-expanded", open);
|
||||
});
|
||||
}
|
||||
document.querySelectorAll("#navlinks a").forEach((a) =>
|
||||
a.addEventListener("click", () => {
|
||||
if (hd) hd.classList.remove("menu-open");
|
||||
if (burger) burger.setAttribute("aria-expanded", "false");
|
||||
}),
|
||||
);
|
||||
|
||||
/* ---------------- faq accordion ---------------- */
|
||||
document.querySelectorAll(".qa button").forEach((btn) => {
|
||||
btn.addEventListener("click", () => {
|
||||
const qa = btn.parentElement,
|
||||
ans = qa.querySelector(".ans"),
|
||||
open = qa.classList.toggle("open");
|
||||
btn.setAttribute("aria-expanded", open);
|
||||
ans.hidden = !open;
|
||||
});
|
||||
});
|
||||
|
||||
/* ---------------- reveal on scroll ---------------- */
|
||||
const reduce = matchMedia("(prefers-reduced-motion:reduce)").matches;
|
||||
if (!reduce && "IntersectionObserver" in window) {
|
||||
const io = new IntersectionObserver(
|
||||
(es) => {
|
||||
es.forEach((e) => {
|
||||
if (e.isIntersecting) {
|
||||
e.target.classList.add("in");
|
||||
io.unobserve(e.target);
|
||||
}
|
||||
});
|
||||
},
|
||||
{ threshold: 0.14 },
|
||||
);
|
||||
document.querySelectorAll(".rv").forEach((el) => io.observe(el));
|
||||
} else {
|
||||
document.querySelectorAll(".rv").forEach((el) => el.classList.add("in"));
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
const SITE_CONFIG = {
|
||||
googleTagManagerId: "GTM-MFN88L24",
|
||||
siteUrl: "https://www.tutosportexpert.com",
|
||||
siteUrlAliases: [
|
||||
"https://tutosportexpert.com",
|
||||
"https://www.tutosportexpert.com",
|
||||
],
|
||||
stripe: {
|
||||
publishableKey:
|
||||
"pk_live_51QblVdAVnr0yCjVxfn0VB0H62Kjdpfly5Cg8mVenw34xBvSavUoWCmDZJISEYme3y3nf9SXrA2GUFngt5dHHPa0N00mCehFE2N",
|
||||
pricingTableIds: {
|
||||
fr: "prctbl_1TjY4mAVnr0yCjVxprPlzN6a",
|
||||
en: "prctbl_1TjYLDAVnr0yCjVxbfn2vzkN",
|
||||
es: "prctbl_1TjYM8AVnr0yCjVx3hmFKXx3",
|
||||
pt: "prctbl_1TjYMtAVnr0yCjVxKNiktdBr",
|
||||
},
|
||||
},
|
||||
socialLinks: {
|
||||
instagram: "https://instagram.com/tutosportexpert",
|
||||
facebook: "#",
|
||||
tiktok: "#",
|
||||
linkedin: "#",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
const SITE_CONFIG = {
|
||||
googleTagManagerId: "GTM-WTMNS3J8",
|
||||
siteUrl: "https://preprod.tutosportexpert.com",
|
||||
siteUrlAliases: [
|
||||
"https://tutosportexpert.com",
|
||||
"https://preprod.tutosportexpert.com",
|
||||
],
|
||||
stripe: {
|
||||
publishableKey:
|
||||
"pk_test_51QblVdAVnr0yCjVxvGKVEnsFExwJ5MJHrfpZha3hUdu6M1boWMVfo69sBvsaMAKPsnusWqI4JoDzsxgxjYOnzEot00ESickqIW",
|
||||
pricingTableIds: {
|
||||
fr: "prctbl_1TihgyAVnr0yCjVxitGGF6te",
|
||||
en: "prctbl_1Tif1XAVnr0yCjVxU6YR803D",
|
||||
es: "prctbl_1Tif20AVnr0yCjVxkV0GyCMy",
|
||||
pt: "prctbl_1TifbgAVnr0yCjVxxjJTNQfC",
|
||||
},
|
||||
},
|
||||
socialLinks: {
|
||||
instagram: "https://instagram.com/tutosportexpert",
|
||||
facebook: "#",
|
||||
tiktok: "#",
|
||||
linkedin: "#",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,147 @@
|
||||
<!doctype html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title data-i18n="meta_title">TutoSport Expert — Ouverture le 22 juin 2026</title>
|
||||
<meta name="description" content="Les académies de Dimitri Payet & Yannick Dyduch arrivent. Offre Coupe du Monde : les 2 académies à 7,90€. Ouverture le 22 juin 2026." data-i18n-content="meta_description">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Archivo:wght@600;700;800;900&family=Inter:wght@400;500;600&family=Space+Mono:wght@400;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root{--ink:#160827;--ink2:#2a1257;--blue:#2563e6;--violet:#a81fc4;--teal:#10c79a;--teal-d:#0aa982;--paper:#f5f4fb;--lav:#d7cdf0;--lav2:#b0a4d2;--grad:linear-gradient(100deg,var(--blue),var(--violet) 52%,var(--teal));}
|
||||
*{box-sizing:border-box}
|
||||
html,body{margin:0;height:100%}
|
||||
body{min-height:100vh;display:flex;flex-direction:column;color:#fff;font-family:'Inter',system-ui,sans-serif;
|
||||
background:radial-gradient(120% 80% at 85% -10%,rgba(168,31,196,.22),transparent 55%),radial-gradient(90% 70% at -10% 110%,rgba(37,99,230,.20),transparent 55%),linear-gradient(180deg,#160827,#22104a 60%,#190b3a);
|
||||
overflow-x:hidden;position:relative}
|
||||
.globe{position:fixed;right:-12%;top:50%;transform:translateY(-50%);width:760px;max-width:90vw;opacity:.09;pointer-events:none;z-index:0}
|
||||
@media(prefers-reduced-motion:no-preference){.globe{animation:spin 90s linear infinite}@keyframes spin{to{transform:translateY(-50%) rotate(360deg)}}}
|
||||
header{display:flex;justify-content:space-between;align-items:center;padding:22px clamp(20px,5vw,54px);position:relative;z-index:3}
|
||||
.brand img{height:38px;display:block}
|
||||
.langsw{display:flex;gap:3px;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.12);border-radius:999px;padding:4px}
|
||||
.langsw button{border:none;background:none;color:var(--lav2);font-family:'Space Mono',monospace;font-size:.72rem;font-weight:700;text-transform:uppercase;padding:.35em .65em;border-radius:999px;cursor:pointer;transition:.15s}
|
||||
.langsw button.on{background:#fff;color:var(--ink)}
|
||||
main{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;
|
||||
padding:clamp(24px,5vw,40px) clamp(20px,5vw,40px) 50px;position:relative;z-index:2}
|
||||
.tag{font-family:'Space Mono',monospace;font-size:.8rem;letter-spacing:.26em;text-transform:uppercase;color:#fff;
|
||||
background:rgba(16,199,154,.14);border:1px solid rgba(16,199,154,.35);padding:.55em 1.1em;border-radius:999px;display:inline-flex;align-items:center;gap:.6em}
|
||||
.tag .dot{width:9px;height:9px;border-radius:50%;background:var(--teal);box-shadow:0 0 0 0 rgba(16,199,154,.6)}
|
||||
@media(prefers-reduced-motion:no-preference){.tag .dot{animation:pulse 1.6s infinite}@keyframes pulse{70%{box-shadow:0 0 0 10px rgba(16,199,154,0)}100%{box-shadow:0 0 0 0 rgba(16,199,154,0)}}}
|
||||
h1{font-family:'Archivo',sans-serif;font-weight:900;letter-spacing:-.02em;line-height:1.02;
|
||||
font-size:clamp(2.4rem,7vw,4.6rem);margin:.7em 0 .35em;max-width:16ch}
|
||||
h1 .g{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
|
||||
.sub{color:var(--lav);font-size:clamp(1rem,2vw,1.2rem);max-width:46ch;margin:0 auto 2.2em;line-height:1.55}
|
||||
.cd{display:flex;gap:clamp(10px,2.4vw,22px);justify-content:center;flex-wrap:wrap;margin-bottom:2.4em}
|
||||
.cd .b{background:#fff;color:var(--ink);border-radius:20px;min-width:clamp(78px,18vw,140px);padding:clamp(14px,2.4vw,26px) clamp(8px,2vw,18px);
|
||||
box-shadow:0 30px 60px -30px rgba(0,0,0,.6);position:relative;overflow:hidden}
|
||||
.cd .b::before{content:"";position:absolute;inset:0 0 auto 0;height:5px;background:var(--grad)}
|
||||
.cd .num{font-family:'Archivo',sans-serif;font-weight:900;font-size:clamp(2.4rem,7vw,4rem);line-height:1;letter-spacing:-.03em;font-variant-numeric:tabular-nums}
|
||||
.cd .lbl{font-family:'Space Mono',monospace;font-size:clamp(.56rem,1.4vw,.72rem);letter-spacing:.18em;text-transform:uppercase;color:var(--violet);font-weight:700;margin-top:8px}
|
||||
.offer{display:inline-flex;align-items:center;gap:.6em;font-family:'Space Mono',monospace;font-size:.92rem;color:var(--lav);margin-bottom:2em}
|
||||
.offer b{color:#fff}.offer .price{color:var(--teal);font-weight:700}
|
||||
.capture{display:flex;gap:10px;flex-wrap:wrap;justify-content:center;width:min(520px,92vw)}
|
||||
.capture input{flex:1;min-width:200px;background:rgba(255,255,255,.08);border:1.5px solid rgba(255,255,255,.18);border-radius:999px;
|
||||
padding:1em 1.3em;color:#fff;font-family:inherit;font-size:1rem;outline:none;transition:.15s}
|
||||
.capture input::placeholder{color:var(--lav2)}
|
||||
.capture input:focus{border-color:var(--teal);background:rgba(255,255,255,.12)}
|
||||
.btn{font-family:'Archivo',sans-serif;font-weight:800;font-size:1rem;border:none;cursor:pointer;border-radius:999px;
|
||||
padding:1em 1.7em;background:var(--teal);color:#04261d;box-shadow:0 12px 26px -8px rgba(16,199,154,.7);transition:transform .15s,box-shadow .15s;white-space:nowrap}
|
||||
.btn:hover{transform:translateY(-2px);box-shadow:0 18px 34px -8px rgba(16,199,154,.85);background:#16d6a7}
|
||||
.note{font-size:.8rem;color:var(--lav2);margin-top:1em}
|
||||
.thanks{display:none;align-items:center;gap:.6em;font-weight:600;color:#eafff8;background:rgba(16,199,154,.14);border:1px solid rgba(16,199,154,.4);padding:1em 1.4em;border-radius:16px}
|
||||
.thanks.show{display:inline-flex}
|
||||
footer{display:flex;justify-content:space-between;align-items:center;gap:14px;flex-wrap:wrap;
|
||||
padding:18px clamp(20px,5vw,54px);border-top:1px solid rgba(255,255,255,.1);color:var(--lav2);font-size:.82rem;position:relative;z-index:3}
|
||||
.socials{display:flex;gap:10px}
|
||||
.socials a{width:36px;height:36px;border-radius:10px;display:grid;place-items:center;background:rgba(255,255,255,.07);color:#fff;transition:.15s}
|
||||
.socials a:hover{background:var(--grad)}.socials svg{width:17px;height:17px}
|
||||
:focus-visible{outline:3px solid var(--teal);outline-offset:3px}
|
||||
</style>
|
||||
</head>
|
||||
<body data-root-prefix="../">
|
||||
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-WTMNS3J8"
|
||||
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
|
||||
<img class="globe" src="./assets/images/globe.svg" alt="" aria-hidden="true">
|
||||
|
||||
<header>
|
||||
<span class="brand"><img src="./assets/images/tutosport-logo.png" alt="TutoSport Expert"></span>
|
||||
<div aria-label="Langue" class="langsw" role="group">
|
||||
<button class="on" data-lang="fr">FR</button>
|
||||
<button data-lang="en">EN</button>
|
||||
<button data-lang="es">ES</button>
|
||||
<button data-lang="pt">PT</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<span class="tag"><span class="dot"></span><span data-i18n="tag">Ouverture · 22 juin 2026</span></span>
|
||||
<h1><span data-i18n="h1a">Le compte à rebours</span> <span class="g" data-i18n="h1b">est lancé.</span></h1>
|
||||
<p class="sub" data-i18n="sub">Les académies de Dimitri Payet & Yannick Dyduch arrivent. Préparez-vous à l'offre Coupe du Monde.</p>
|
||||
|
||||
<div class="cd" id="cd" role="timer" aria-live="off">
|
||||
<div class="b"><div class="num" id="d">00</div><div class="lbl" data-i18n="l_d">Jours</div></div>
|
||||
<div class="b"><div class="num" id="h">00</div><div class="lbl" data-i18n="l_h">Heures</div></div>
|
||||
<div class="b"><div class="num" id="m">00</div><div class="lbl" data-i18n="l_m">Minutes</div></div>
|
||||
<div class="b"><div class="num" id="s">00</div><div class="lbl" data-i18n="l_s">Secondes</div></div>
|
||||
</div>
|
||||
|
||||
<p class="offer"><span data-i18n="offer_a">Les 2 académies à</span> <span class="price">7,90€</span> <span data-i18n="offer_b">au lieu de 80€ · offre limitée Coupe du Monde</span></p>
|
||||
|
||||
<!--form class="capture" id="form" novalidate>
|
||||
<input type="email" id="email" required data-i18n-ph="ph" placeholder="Ton adresse e-mail">
|
||||
<button class="btn" type="submit" data-i18n="btn">Préviens-moi</button>
|
||||
</form-->
|
||||
<!--iframe data-w-type="embedded" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://14u8z.mjt.lu/wgt/14u8z/0qr4/form?c=eb5323b7" width="100%" style="height: 0;"></iframe>
|
||||
<script type="text/javascript" src="https://app.mailjet.com/pas-nc-embedded-v2.js"></script>
|
||||
<div class="thanks" id="thanks"><svg viewBox="0 0 24 24" width="18" fill="none" stroke="#10c79a" stroke-width="2.6"><path d="M20 6 9 17l-5-5"/></svg> <span data-i18n="thanks">Merci ! On te prévient dès l'ouverture.</span></div>
|
||||
<p class="note" data-i18n="note">Sois prévenu·e en premier et garde l'offre 7,90€.</p-->
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<span data-i18n="rights">© 2026 TutoSport Expert. Tous droits réservés.</span>
|
||||
<div class="socials">
|
||||
<a href="https://instagram.com/tutosportexpert" aria-label="Instagram"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="5"/><circle cx="12" cy="12" r="4"/><circle cx="17.5" cy="6.5" r="1" fill="currentColor" stroke="none"/></svg></a>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script defer src="./assets/js/site-config.js"></script>
|
||||
<script defer src="./assets/js/launch-constants.js"></script>
|
||||
<script defer src="./assets/js/main.js"></script>
|
||||
<script>
|
||||
(() => {
|
||||
const launchTarget = new Date("2026-06-22T07:00:00+02:00").getTime();
|
||||
const p = (n) => String(Math.max(0, n)).padStart(2, "0");
|
||||
function tick() {
|
||||
let diff = Math.max(0, launchTarget - Date.now());
|
||||
const d = Math.floor(diff / 864e5);
|
||||
diff -= d * 864e5;
|
||||
const h = Math.floor(diff / 36e5);
|
||||
diff -= h * 36e5;
|
||||
const m = Math.floor(diff / 6e4);
|
||||
diff -= m * 6e4;
|
||||
const s = Math.floor(diff / 1e3);
|
||||
document.getElementById("d").textContent = p(d);
|
||||
document.getElementById("h").textContent = p(h);
|
||||
document.getElementById("m").textContent = p(m);
|
||||
document.getElementById("s").textContent = p(s);
|
||||
}
|
||||
tick();
|
||||
setInterval(tick, 1000);
|
||||
|
||||
const form = document.getElementById("form");
|
||||
if (form) {
|
||||
form.addEventListener("submit", (e) => {
|
||||
e.preventDefault();
|
||||
const em = document.getElementById("email");
|
||||
if (!em.value || !em.validity.valid) {
|
||||
em.focus();
|
||||
return;
|
||||
}
|
||||
form.style.display = "none";
|
||||
document.getElementById("thanks").classList.add("show");
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user