forked from FWS/TEMPLATE-Web-site-one-page
Compare commits
19 Commits
4c958b448a
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
ae289cffa3
|
|||
|
c0fd8353a6
|
|||
|
6456859e9e
|
|||
|
85a551c0b7
|
|||
|
ca7cbf98ec
|
|||
|
59d18dfdb7
|
|||
|
6a7566e149
|
|||
|
ec2c75de33
|
|||
|
41c2c58dba
|
|||
|
07f232b70b
|
|||
|
06cef39749
|
|||
|
3b844a3718
|
|||
|
07b54a7f5d
|
|||
|
bb72082230
|
|||
|
4a7df3e5b7
|
|||
|
5ccc51e8e5
|
|||
|
bca5626096
|
|||
|
e315b511ee
|
|||
|
ba31d6447a
|
+8
-8
@@ -6,8 +6,9 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description"
|
||||
content="Site statique one-page avec navigation par URL et chargement dynamique du contenu." />
|
||||
<title>Fws Web</title>
|
||||
<title>Fws Linux</title>
|
||||
<link rel="stylesheet" href="p/assets/styles/styles.css" />
|
||||
<link rel="icon" type="image/png" href="/p/assets/img/logo.png" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -39,11 +40,10 @@
|
||||
<img class="footer-brand-mark" src="p/assets/img/logo.png" alt="Logo Fws Linux" />
|
||||
<div>
|
||||
<strong>Fws Linux</strong>
|
||||
<p>Un site simple, rapide, et pensé pour naviguer entre plusieurs pages sans quitter l'accueil.</p>
|
||||
<p>Un systeme leger, libre et compatible</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="footer-note">Contact, aide, et liens utiles au même endroit.</p>
|
||||
</div>
|
||||
|
||||
<div class="footer-links-grid">
|
||||
@@ -55,16 +55,16 @@
|
||||
|
||||
<section>
|
||||
<h2>Contact</h2>
|
||||
<a href="mailto:contact@fwslinux.fr">Envoyer un mail</a>
|
||||
<a href="tel:+33000000000">Téléphone</a>
|
||||
<!-- <a href="mailto:contact@fwslinux.fr">Envoyer un mail</a>
|
||||
<a href="tel:+33000000000">Téléphone</a> -->
|
||||
<a href="/?p/contact/" data-route="contact">Page de contact</a>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Réseaux</h2>
|
||||
<a href="https://github.com/" target="_blank" rel="noreferrer">GitHub</a>
|
||||
<a href="https://www.instagram.com/" target="_blank" rel="noreferrer">Instagram</a>
|
||||
<a href="https://www.linkedin.com/" target="_blank" rel="noreferrer">LinkedIn</a>
|
||||
<a href="https://github.com/You-re-like-Windows-a-bitch/ISO" target="_blank" rel="noreferrer">GitHub</a>
|
||||
<!-- <a href="https://www.instagram.com/" target="_blank" rel="noreferrer">Instagram</a>
|
||||
<a href="https://www.linkedin.com/" target="_blank" rel="noreferrer">LinkedIn</a> -->
|
||||
</section>
|
||||
</div>
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 524 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.4 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 550 KiB |
@@ -0,0 +1,212 @@
|
||||
(() => {
|
||||
const OWNER = "You-re-like-Windows-a-bitch";
|
||||
const REPO = "ISO";
|
||||
const RELEASES_URL = `https://api.github.com/repos/${OWNER}/${REPO}/releases?per_page=6`;
|
||||
const TAGS_URL = `https://api.github.com/repos/${OWNER}/${REPO}/tags?per_page=6`;
|
||||
const REPO_URL = `https://github.com/${OWNER}/${REPO}`;
|
||||
|
||||
const currentVersionNode = document.querySelector("[data-current-version]");
|
||||
const currentVersionDateNode = document.querySelector("[data-current-version-date]");
|
||||
const currentReleaseNoteNode = document.querySelector("[data-current-release-note]");
|
||||
const latestDownloadNode = document.querySelector("[data-latest-download]");
|
||||
const viewMoreNode = document.querySelector("[data-view-more]");
|
||||
const versionsListNode = document.querySelector("[data-versions-list]");
|
||||
|
||||
function formatDate(value) {
|
||||
if (!value) return "";
|
||||
const date = new Date(value);
|
||||
if (Number.isNaN(date.getTime())) return "";
|
||||
return date.toLocaleDateString("fr-FR", {
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
});
|
||||
}
|
||||
|
||||
function getReleaseLabel(entry) {
|
||||
return entry?.name || entry?.tag_name || entry?.ref || "Sans nom";
|
||||
}
|
||||
|
||||
function getReleasePageUrl(entry, mode) {
|
||||
if (mode === "releases") {
|
||||
return entry?.html_url || REPO_URL;
|
||||
}
|
||||
|
||||
if (entry?.name) {
|
||||
return `${REPO_URL}/releases/tag/${encodeURIComponent(entry.name)}`;
|
||||
}
|
||||
|
||||
return REPO_URL;
|
||||
}
|
||||
|
||||
function sanitizeReleaseHtml(html) {
|
||||
const wrapper = document.createElement("div");
|
||||
wrapper.innerHTML = html || "";
|
||||
|
||||
wrapper.querySelectorAll("script, iframe, object, embed, link, style").forEach((node) => node.remove());
|
||||
wrapper.querySelectorAll("*").forEach((node) => {
|
||||
Array.from(node.attributes).forEach((attribute) => {
|
||||
const name = attribute.name.toLowerCase();
|
||||
const value = attribute.value || "";
|
||||
|
||||
if (name.startsWith("on")) {
|
||||
node.removeAttribute(attribute.name);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((name === "href" || name === "src") && /^javascript:/i.test(value)) {
|
||||
node.removeAttribute(attribute.name);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return wrapper.innerHTML;
|
||||
}
|
||||
|
||||
function pickDirectDownloadUrl(release) {
|
||||
const assets = Array.isArray(release?.assets) ? release.assets : [];
|
||||
const isoAsset = assets.find((asset) => /\.iso$/i.test(asset?.name || ""));
|
||||
const directAsset = isoAsset || assets[0];
|
||||
|
||||
if (directAsset) {
|
||||
return directAsset.browser_download_url || directAsset.url || release.html_url || REPO_URL;
|
||||
}
|
||||
|
||||
return release?.zipball_url || release?.html_url || REPO_URL;
|
||||
}
|
||||
|
||||
function renderEmptyState(title, message) {
|
||||
if (!versionsListNode) return;
|
||||
versionsListNode.innerHTML = `
|
||||
<li class="version-item version-item-empty">
|
||||
<div class="version-main">
|
||||
<strong>${title}</strong>
|
||||
<span>${message}</span>
|
||||
</div>
|
||||
<div class="version-side">
|
||||
<a class="button button-secondary" href="${REPO_URL}" target="_blank" rel="noreferrer">Voir le repo</a>
|
||||
</div>
|
||||
</li>
|
||||
`;
|
||||
}
|
||||
|
||||
function renderList(items, mode) {
|
||||
if (!versionsListNode) return;
|
||||
versionsListNode.innerHTML = "";
|
||||
|
||||
const visibleItems = items.slice(1, 6);
|
||||
|
||||
if (!visibleItems.length) {
|
||||
if (items.length === 0) {
|
||||
renderEmptyState("Aucune release trouvée", "Le dépôt n'expose pas encore de release ou les releases ne sont pas accessibles.");
|
||||
} else {
|
||||
renderEmptyState(
|
||||
mode === "releases" ? "Aucune release précédente trouvée" : "Aucun tag précédent trouvé",
|
||||
mode === "releases"
|
||||
? "Il n'y a qu'une seule release publiée pour le moment."
|
||||
: "Il n'y a qu'un seul tag disponible pour le moment."
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
visibleItems.forEach((entry) => {
|
||||
const li = document.createElement("li");
|
||||
li.className = "version-item";
|
||||
|
||||
const label = getReleaseLabel(entry);
|
||||
const downloadUrl = getReleasePageUrl(entry, mode);
|
||||
const published = formatDate(entry.published_at || entry.commit?.committer?.date);
|
||||
|
||||
li.innerHTML = `
|
||||
<div class="version-main">
|
||||
<strong>${label}</strong>
|
||||
<span>${published ? `Publié le ${published}` : mode === "releases" ? "Date inconnue" : "Tag GitHub"}</span>
|
||||
</div>
|
||||
<div class="version-side">
|
||||
<a class="button button-secondary" href="${downloadUrl}" target="_blank" rel="noreferrer">Télécharger</a>
|
||||
</div>
|
||||
`;
|
||||
|
||||
versionsListNode.appendChild(li);
|
||||
});
|
||||
}
|
||||
|
||||
async function fetchJson(url) {
|
||||
const response = await fetch(url, {
|
||||
headers: { Accept: "application/vnd.github+json" },
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`GitHub API ${response.status}`);
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
async function loadReleases() {
|
||||
if (currentVersionNode) currentVersionNode.textContent = "Chargement...";
|
||||
if (currentVersionDateNode) currentVersionDateNode.textContent = "";
|
||||
if (currentReleaseNoteNode) currentReleaseNoteNode.textContent = "";
|
||||
if (latestDownloadNode) latestDownloadNode.href = REPO_URL;
|
||||
if (viewMoreNode) viewMoreNode.href = `${REPO_URL}/releases`;
|
||||
|
||||
try {
|
||||
const releases = await fetchJson(RELEASES_URL);
|
||||
|
||||
if (Array.isArray(releases) && releases.length > 0) {
|
||||
const latest = releases[0];
|
||||
const latestLabel = getReleaseLabel(latest);
|
||||
const latestDownloadUrl = pickDirectDownloadUrl(latest);
|
||||
const latestDate = formatDate(latest.published_at);
|
||||
|
||||
if (currentVersionNode) currentVersionNode.textContent = latestLabel;
|
||||
if (currentVersionDateNode) currentVersionDateNode.textContent = latestDate ? ` · ${latestDate}` : "";
|
||||
if (currentReleaseNoteNode) {
|
||||
const bodyHtml = sanitizeReleaseHtml(latest.body || "");
|
||||
currentReleaseNoteNode.innerHTML = bodyHtml || "Release GitHub la plus récente.";
|
||||
}
|
||||
if (latestDownloadNode) latestDownloadNode.href = latest.html_url || REPO_URL;
|
||||
|
||||
renderList(releases, "releases");
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
// On tente le fallback tags ci-dessous.
|
||||
}
|
||||
|
||||
try {
|
||||
const tags = await fetchJson(TAGS_URL);
|
||||
|
||||
if (Array.isArray(tags) && tags.length > 0) {
|
||||
const latestTag = tags[0];
|
||||
const latestLabel = getReleaseLabel(latestTag);
|
||||
const latestDownloadUrl = `${REPO_URL}/releases/tag/${encodeURIComponent(latestTag.name)}`;
|
||||
|
||||
if (currentVersionNode) currentVersionNode.textContent = `${latestLabel} (tag)`;
|
||||
if (currentVersionDateNode) currentVersionDateNode.textContent = "";
|
||||
if (currentReleaseNoteNode) {
|
||||
currentReleaseNoteNode.textContent = "Aucune release GitHub publiée pour le moment, affichage des tags du dépôt.";
|
||||
}
|
||||
if (latestDownloadNode) latestDownloadNode.href = latestDownloadUrl;
|
||||
|
||||
renderList(tags, "tags");
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentVersionNode) currentVersionNode.textContent = "Aucune release trouvée";
|
||||
if (currentReleaseNoteNode) {
|
||||
currentReleaseNoteNode.textContent = "Le dépôt ne renvoie ni release ni tag public.";
|
||||
}
|
||||
renderEmptyState("Aucune release trouvée", "Le dépôt ne renvoie ni release ni tag public.");
|
||||
} catch (error) {
|
||||
if (currentVersionNode) currentVersionNode.textContent = "Impossible de charger les releases";
|
||||
if (currentReleaseNoteNode) {
|
||||
currentReleaseNoteNode.textContent = `Erreur: ${error.message}. Vérifie que le repo GitHub est public et qu'il expose des releases ou des tags.`;
|
||||
}
|
||||
renderEmptyState("Impossible de charger les releases", "Ouvre le repo GitHub pour vérifier les releases ou les tags.");
|
||||
}
|
||||
}
|
||||
|
||||
loadReleases();
|
||||
})();
|
||||
@@ -0,0 +1,155 @@
|
||||
(() => {
|
||||
"use strict";
|
||||
|
||||
const existingCleanup = window.__heroCarouselCleanup;
|
||||
if (typeof existingCleanup === "function") {
|
||||
existingCleanup();
|
||||
}
|
||||
|
||||
const hero = document.querySelector(".hero-carousel");
|
||||
if (!hero) {
|
||||
return;
|
||||
}
|
||||
|
||||
const slides = Array.from(hero.querySelectorAll("[data-hero-slide]"));
|
||||
const prevButton = hero.querySelector("[data-hero-prev]");
|
||||
const nextButton = hero.querySelector("[data-hero-next]");
|
||||
const dotsContainer = hero.querySelector("[data-hero-dots]");
|
||||
|
||||
if (!slides.length || !prevButton || !nextButton || !dotsContainer) {
|
||||
return;
|
||||
}
|
||||
|
||||
let currentIndex = Math.max(
|
||||
0,
|
||||
slides.findIndex((slide) => slide.classList.contains("is-active"))
|
||||
);
|
||||
let autoRotateTimer = null;
|
||||
const rotateDelay = 5500;
|
||||
const abortController = new AbortController();
|
||||
const { signal } = abortController;
|
||||
|
||||
const dots = slides.map((_, index) => {
|
||||
const dot = document.createElement("button");
|
||||
dot.type = "button";
|
||||
dot.className = "hero-dot";
|
||||
dot.setAttribute("role", "tab");
|
||||
dot.setAttribute("aria-label", `Aller a l'image ${index + 1}`);
|
||||
dot.dataset.index = index.toString();
|
||||
dotsContainer.appendChild(dot);
|
||||
return dot;
|
||||
});
|
||||
|
||||
function updateUI() {
|
||||
slides.forEach((slide, index) => {
|
||||
const isActive = index === currentIndex;
|
||||
slide.classList.toggle("is-active", isActive);
|
||||
slide.setAttribute("aria-hidden", String(!isActive));
|
||||
});
|
||||
|
||||
dots.forEach((dot, index) => {
|
||||
const isActive = index === currentIndex;
|
||||
dot.classList.toggle("is-active", isActive);
|
||||
dot.setAttribute("aria-selected", String(isActive));
|
||||
dot.tabIndex = isActive ? 0 : -1;
|
||||
});
|
||||
}
|
||||
|
||||
function goTo(index) {
|
||||
if (index < 0) {
|
||||
currentIndex = slides.length - 1;
|
||||
} else if (index >= slides.length) {
|
||||
currentIndex = 0;
|
||||
} else {
|
||||
currentIndex = index;
|
||||
}
|
||||
updateUI();
|
||||
}
|
||||
|
||||
function stopAutoRotate() {
|
||||
if (autoRotateTimer !== null) {
|
||||
window.clearInterval(autoRotateTimer);
|
||||
autoRotateTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
function startAutoRotate() {
|
||||
stopAutoRotate();
|
||||
autoRotateTimer = window.setInterval(() => {
|
||||
goTo(currentIndex + 1);
|
||||
}, rotateDelay);
|
||||
}
|
||||
|
||||
prevButton.addEventListener(
|
||||
"click",
|
||||
() => {
|
||||
goTo(currentIndex - 1);
|
||||
startAutoRotate();
|
||||
},
|
||||
{ signal }
|
||||
);
|
||||
|
||||
nextButton.addEventListener(
|
||||
"click",
|
||||
() => {
|
||||
goTo(currentIndex + 1);
|
||||
startAutoRotate();
|
||||
},
|
||||
{ signal }
|
||||
);
|
||||
|
||||
dotsContainer.addEventListener(
|
||||
"click",
|
||||
(event) => {
|
||||
const button = event.target.closest(".hero-dot");
|
||||
if (!button) {
|
||||
return;
|
||||
}
|
||||
|
||||
const targetIndex = Number.parseInt(button.dataset.index || "0", 10);
|
||||
goTo(targetIndex);
|
||||
startAutoRotate();
|
||||
},
|
||||
{ signal }
|
||||
);
|
||||
|
||||
hero.addEventListener(
|
||||
"mouseenter",
|
||||
() => {
|
||||
stopAutoRotate();
|
||||
},
|
||||
{ signal }
|
||||
);
|
||||
|
||||
hero.addEventListener(
|
||||
"mouseleave",
|
||||
() => {
|
||||
startAutoRotate();
|
||||
},
|
||||
{ signal }
|
||||
);
|
||||
|
||||
document.addEventListener(
|
||||
"visibilitychange",
|
||||
() => {
|
||||
if (document.hidden) {
|
||||
stopAutoRotate();
|
||||
} else {
|
||||
startAutoRotate();
|
||||
}
|
||||
},
|
||||
{ signal }
|
||||
);
|
||||
|
||||
updateUI();
|
||||
startAutoRotate();
|
||||
|
||||
window.__heroCarouselCleanup = () => {
|
||||
stopAutoRotate();
|
||||
abortController.abort();
|
||||
};
|
||||
|
||||
document.addEventListener("page:before-route-change", window.__heroCarouselCleanup, {
|
||||
once: true,
|
||||
});
|
||||
})();
|
||||
@@ -2,6 +2,7 @@
|
||||
const main = document.getElementById("app-main");
|
||||
const footerYear = document.getElementById("footer-year");
|
||||
const pageStyleSelectors = "[data-page-style='true']";
|
||||
const pageScriptSelectors = "script[data-page-script='true']";
|
||||
|
||||
const links = Array.from(document.querySelectorAll("[data-route]"));
|
||||
|
||||
@@ -13,6 +14,11 @@
|
||||
document.querySelectorAll(pageStyleSelectors).forEach((node) => node.remove());
|
||||
}
|
||||
|
||||
function clearInjectedPageScripts() {
|
||||
document.dispatchEvent(new CustomEvent("page:before-route-change"));
|
||||
document.querySelectorAll(pageScriptSelectors).forEach((node) => node.remove());
|
||||
}
|
||||
|
||||
function injectPageStyles(parsedDocument, sourceUrl) {
|
||||
clearInjectedPageStyles();
|
||||
|
||||
@@ -38,6 +44,37 @@
|
||||
});
|
||||
}
|
||||
|
||||
async function injectPageScripts(parsedDocument, sourceUrl) {
|
||||
clearInjectedPageScripts();
|
||||
|
||||
const scriptNodes = Array.from(parsedDocument.querySelectorAll("script"));
|
||||
|
||||
for (const node of scriptNodes) {
|
||||
const scriptElement = document.createElement("script");
|
||||
scriptElement.setAttribute("data-page-script", "true");
|
||||
|
||||
const src = node.getAttribute("src");
|
||||
if (src) {
|
||||
scriptElement.src = new URL(src, sourceUrl).toString();
|
||||
scriptElement.async = false;
|
||||
if (node.defer) {
|
||||
scriptElement.defer = true;
|
||||
}
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
scriptElement.onload = () => resolve();
|
||||
scriptElement.onerror = () => reject(new Error(`Impossible de charger le script: ${src}`));
|
||||
document.body.appendChild(scriptElement);
|
||||
});
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
scriptElement.textContent = node.textContent;
|
||||
document.body.appendChild(scriptElement);
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeRoute(value) {
|
||||
const raw = (value ?? "").toString().trim().toLowerCase();
|
||||
if (!raw || raw === "/" || raw === "home" || raw === "index" || raw === "accueil") {
|
||||
@@ -117,6 +154,8 @@
|
||||
}
|
||||
|
||||
async function loadRoute(route) {
|
||||
clearInjectedPageScripts();
|
||||
|
||||
const source = routeToSource(route);
|
||||
const response = await fetch(source, { cache: "no-store" });
|
||||
if (!response.ok) {
|
||||
@@ -128,6 +167,14 @@
|
||||
injectPageStyles(parsed, response.url);
|
||||
const injected = parsed.querySelector("[data-page-content]") ?? parsed.body;
|
||||
main.innerHTML = injected.innerHTML.trim();
|
||||
await injectPageScripts(parsed, response.url);
|
||||
// Update document title from the fetched page if present, otherwise use generated title
|
||||
const pageTitleEl = parsed.querySelector("title");
|
||||
if (pageTitleEl && pageTitleEl.textContent && pageTitleEl.textContent.trim()) {
|
||||
document.title = pageTitleEl.textContent.trim();
|
||||
} else {
|
||||
document.title = routeToTitle(route);
|
||||
}
|
||||
}
|
||||
|
||||
function render(route, { replaceHistory = false } = {}) {
|
||||
@@ -137,7 +184,6 @@
|
||||
.then(() => {
|
||||
setActiveRoute(safeRoute);
|
||||
setCanonicalUrl(safeRoute, replaceHistory);
|
||||
document.title = routeToTitle(safeRoute);
|
||||
window.scrollTo({ top: 0, behavior: "smooth" });
|
||||
})
|
||||
.catch((error) => {
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
@import "./var.css";
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
font-family: "Trebuchet MS", "Segoe UI", sans-serif;
|
||||
color: var(--generic-text-color);
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(0, 212, 255, 0.18), transparent 24%),
|
||||
radial-gradient(circle at right center, rgba(255, 165, 0, 0.14), transparent 28%),
|
||||
linear-gradient(160deg, var(--sidebar-background) 0%, var(--sidebar-select) 50%, var(--background-color) 100%);
|
||||
}
|
||||
|
||||
.contact-header {
|
||||
max-width: 1120px;
|
||||
margin: 0 auto;
|
||||
padding: clamp(2.5rem, 6vw, 5rem) 1.25rem 1.25rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.contact-header h1 {
|
||||
margin: 0;
|
||||
font-family: "Georgia", "Times New Roman", serif;
|
||||
font-size: clamp(2.5rem, 7vw, 5.2rem);
|
||||
line-height: 0.95;
|
||||
letter-spacing: -0.05em;
|
||||
color: var(--highlighted-text-color);
|
||||
}
|
||||
|
||||
.contact-header p {
|
||||
max-width: 62ch;
|
||||
margin: 1rem auto 0;
|
||||
color: var(--generic-text-color);
|
||||
opacity: 0.84;
|
||||
font-size: 1.05rem;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
hr {
|
||||
width: min(1120px, calc(100% - 2.5rem));
|
||||
margin: 0 auto;
|
||||
border: 0;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, transparent, var(--sidebar-text-highlight), var(--warning-text-color), transparent);
|
||||
}
|
||||
|
||||
main {
|
||||
width: min(1120px, calc(100% - 2.5rem));
|
||||
margin: 1.5rem auto 0;
|
||||
padding: 0 0 3rem;
|
||||
}
|
||||
|
||||
main section {
|
||||
padding: clamp(1.4rem, 3vw, 2rem);
|
||||
border-radius: 1.6rem;
|
||||
border: 1px solid rgba(224, 224, 224, 0.16);
|
||||
background: linear-gradient(145deg, var(--sidebar-background), var(--sidebar-select));
|
||||
box-shadow: 0 24px 70px rgba(2, 6, 23, 0.42);
|
||||
}
|
||||
|
||||
main section h2 {
|
||||
margin: 0 0 0.85rem;
|
||||
color: var(--highlighted-text-color);
|
||||
font-family: "Georgia", "Times New Roman", serif;
|
||||
font-size: clamp(1.4rem, 3vw, 2.1rem);
|
||||
}
|
||||
|
||||
main section p {
|
||||
margin: 0 0 1rem;
|
||||
color: var(--generic-text-color);
|
||||
opacity: 0.9;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
main section strong {
|
||||
color: var(--highlighted-text-color);
|
||||
}
|
||||
|
||||
main section a:not(.button) {
|
||||
color: var(--sidebar-text-highlight);
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 0.15em;
|
||||
}
|
||||
|
||||
main section a:not(.button):hover,
|
||||
main section a:not(.button):focus-visible {
|
||||
color: var(--highlighted-text-color);
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
.contact-header {
|
||||
padding-top: 2rem;
|
||||
}
|
||||
|
||||
main,
|
||||
hr {
|
||||
width: min(100% - 1rem, 1120px);
|
||||
}
|
||||
|
||||
main section {
|
||||
border-radius: 1.1rem;
|
||||
}
|
||||
|
||||
main section a.button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
.versions-panel {
|
||||
margin-top: 1rem;
|
||||
padding: 1rem;
|
||||
border-radius: 1rem;
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
border: 1px solid rgba(148, 163, 184, 0.08);
|
||||
}
|
||||
|
||||
.latest-version h2 {
|
||||
margin: 0 0 0.35rem;
|
||||
}
|
||||
|
||||
.latest-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.latest-meta {
|
||||
color: var(--muted);
|
||||
font-size: 1.05rem;
|
||||
}
|
||||
|
||||
.latest-actions {
|
||||
display: flex;
|
||||
gap: 0.6rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.latest-note {
|
||||
margin: 0.85rem 0 0;
|
||||
color: var(--muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.latest-note img {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
margin: 0.75rem 0;
|
||||
border-radius: 0.65rem;
|
||||
}
|
||||
|
||||
.latest-note a {
|
||||
color: #7dd3fc;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.latest-note a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.versions-archive {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.versions-list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: grid;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.version-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
padding: 0.8rem 0.9rem;
|
||||
border-radius: 0.8rem;
|
||||
background: rgba(2, 6, 23, 0.24);
|
||||
border: 1px solid rgba(148, 163, 184, 0.08);
|
||||
}
|
||||
|
||||
.version-item-empty {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.version-main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.2rem;
|
||||
}
|
||||
|
||||
.version-main a {
|
||||
color: #7dd3fc;
|
||||
text-decoration: none;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.version-main a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.version-side {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
@media (max-width: 880px) {
|
||||
|
||||
.latest-row,
|
||||
.version-item {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.version-side {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
+268
-19
@@ -16,14 +16,51 @@ main[data-page-content] {
|
||||
|
||||
|
||||
.hero {
|
||||
background: linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01));
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: #0b1324;
|
||||
box-shadow: var(--shadow);
|
||||
border-radius: 1rem;
|
||||
padding: clamp(2rem, 4.5vw, 3.5rem);
|
||||
color: var(--text);
|
||||
min-height: clamp(24rem, 56vw, 34rem);
|
||||
}
|
||||
|
||||
.hero-inner { width: 100%; }
|
||||
.hero-carousel-track {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
}
|
||||
|
||||
.hero-slide {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
opacity: 0;
|
||||
transform: scale(1.02);
|
||||
transition: opacity 700ms ease, transform 1000ms ease;
|
||||
}
|
||||
|
||||
.hero-slide::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background:
|
||||
linear-gradient(110deg, rgba(2, 6, 23, 0.78) 18%, rgba(2, 6, 23, 0.28) 58%, rgba(2, 6, 23, 0.66) 100%),
|
||||
radial-gradient(circle at 72% 20%, rgba(56, 189, 248, 0.2), transparent 48%);
|
||||
}
|
||||
|
||||
.hero-slide.is-active {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.hero-inner {
|
||||
width: 100%;
|
||||
max-width: 52rem;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.eyebrow {
|
||||
color: var(--accent);
|
||||
@@ -36,22 +73,26 @@ main[data-page-content] {
|
||||
.hero-title {
|
||||
font-family: "Georgia", "Palatino Linotype", serif;
|
||||
font-size: clamp(3rem, 8vw, 5rem);
|
||||
line-height: 0.95;
|
||||
line-height: 1;
|
||||
margin: 0 0 0.25rem;
|
||||
color: var(--text);
|
||||
color: #f8fbff;
|
||||
text-shadow: 0 10px 28px rgba(2, 6, 23, 0.38);
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
font-size: clamp(1rem, 2.2vw, 1.3rem);
|
||||
color: var(--muted);
|
||||
color: #e7edf9;
|
||||
margin: 0 0 1rem;
|
||||
font-weight: 600;
|
||||
text-shadow: 0 4px 18px rgba(2, 6, 23, 0.35);
|
||||
}
|
||||
|
||||
.lead {
|
||||
color: var(--muted);
|
||||
color: #d8e1f3;
|
||||
max-width: 68ch;
|
||||
margin: 0 0 1.25rem;
|
||||
text-wrap: pretty;
|
||||
text-shadow: 0 2px 14px rgba(2, 6, 23, 0.34);
|
||||
}
|
||||
|
||||
.hero-actions {
|
||||
@@ -60,28 +101,63 @@ main[data-page-content] {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
|
||||
.button {
|
||||
.hero-controls {
|
||||
position: absolute;
|
||||
right: clamp(1rem, 2.5vw, 2rem);
|
||||
bottom: clamp(1rem, 2.8vw, 1.75rem);
|
||||
z-index: 3;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.8rem 1.2rem;
|
||||
gap: 0.45rem;
|
||||
padding: 0.4rem 0.55rem;
|
||||
border-radius: 999px;
|
||||
text-decoration: none;
|
||||
font-weight: 700;
|
||||
border: 1px solid transparent;
|
||||
backdrop-filter: blur(10px);
|
||||
background: rgba(2, 6, 23, 0.46);
|
||||
border: 1px solid rgba(148, 163, 184, 0.28);
|
||||
}
|
||||
|
||||
.button-primary {
|
||||
background: linear-gradient(145deg, var(--accent), var(--accent-strong));
|
||||
color: #08101d;
|
||||
.hero-control {
|
||||
width: 2.2rem;
|
||||
height: 2.2rem;
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
font-size: 1.32rem;
|
||||
color: #e2e8f0;
|
||||
background: rgba(148, 163, 184, 0.22);
|
||||
cursor: pointer;
|
||||
transition: transform 180ms ease, background 180ms ease;
|
||||
}
|
||||
|
||||
.button-secondary {
|
||||
background: rgba(255,255,255,0.03);
|
||||
color: var(--text);
|
||||
.hero-control:hover {
|
||||
transform: translateY(-1px);
|
||||
background: rgba(125, 211, 252, 0.36);
|
||||
}
|
||||
|
||||
.hero-dots {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
margin: 0 0.15rem;
|
||||
}
|
||||
|
||||
.hero-dot {
|
||||
width: 0.6rem;
|
||||
height: 0.6rem;
|
||||
border-radius: 999px;
|
||||
border: 0;
|
||||
background: rgba(226, 232, 240, 0.55);
|
||||
cursor: pointer;
|
||||
transition: transform 180ms ease, background 180ms ease;
|
||||
}
|
||||
|
||||
.hero-dot.is-active {
|
||||
background: #7dd3fc;
|
||||
transform: scale(1.18);
|
||||
}
|
||||
|
||||
|
||||
|
||||
.features {
|
||||
margin-top: 1.5rem;
|
||||
@@ -90,6 +166,144 @@ main[data-page-content] {
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.env-choices {
|
||||
margin-top: 1.8rem;
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
padding: clamp(1rem, 2.4vw, 1.5rem);
|
||||
border-radius: 1rem;
|
||||
background: rgba(255, 255, 255, 0.02);
|
||||
box-shadow: 0 8px 22px rgba(2, 6, 23, 0.35);
|
||||
}
|
||||
|
||||
.env-choices-header h2 {
|
||||
margin: 0 0 0.45rem;
|
||||
font-family: "Georgia", "Palatino Linotype", serif;
|
||||
font-size: clamp(1.6rem, 3vw, 2.2rem);
|
||||
}
|
||||
|
||||
.env-choices-header p {
|
||||
margin: 2rem 0 1rem;
|
||||
color: var(--muted);
|
||||
max-width: 78ch;
|
||||
}
|
||||
|
||||
.env-row {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(170px, 0.9fr) minmax(0, 2.1fr);
|
||||
gap: clamp(0.85rem, 2vw, 1.35rem);
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.env-row.is-reverse {
|
||||
grid-template-columns: minmax(0, 2.1fr) minmax(170px, 0.9fr);
|
||||
}
|
||||
|
||||
.env-media,
|
||||
.env-text {
|
||||
margin: 0;
|
||||
border-radius: 0.8rem;
|
||||
border: 1px solid rgba(148, 163, 184, 0.28);
|
||||
overflow: hidden;
|
||||
background: rgba(2, 6, 23, 0.22);
|
||||
}
|
||||
|
||||
.env-media {
|
||||
min-height: clamp(140px, 20vw, 190px);
|
||||
}
|
||||
|
||||
.env-media img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.env-text {
|
||||
padding: clamp(1rem, 2.4vw, 1.4rem);
|
||||
display: grid;
|
||||
align-content: center;
|
||||
gap: 0.55rem;
|
||||
}
|
||||
|
||||
.env-text h3 {
|
||||
margin: 0;
|
||||
font-family: "Georgia", "Palatino Linotype", serif;
|
||||
font-size: clamp(1.25rem, 2vw, 1.6rem);
|
||||
}
|
||||
|
||||
.env-text p {
|
||||
margin: 0;
|
||||
color: var(--muted);
|
||||
line-height: 1.65;
|
||||
}
|
||||
|
||||
/* Styles page Téléchargements */
|
||||
.downloads {
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
|
||||
.downloads-header h1 { margin: 0 0 0.35rem; }
|
||||
|
||||
.download-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 1rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.download-card {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
align-items: stretch;
|
||||
padding: 0.8rem;
|
||||
border-radius: 0.75rem;
|
||||
background: rgba(255,255,255,0.02);
|
||||
border: 1px solid rgba(148,163,184,0.06);
|
||||
}
|
||||
|
||||
.download-media { width: 220px; flex: 0 0 220px; overflow: hidden; border-radius: 0.5rem; }
|
||||
.download-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
||||
|
||||
.download-body { flex: 1 1 auto; display: flex; flex-direction: column; gap: 0.6rem; }
|
||||
|
||||
.download-actions { display: flex; gap: 0.6rem; margin-top: auto; }
|
||||
|
||||
@media (max-width: 880px) {
|
||||
.download-grid { grid-template-columns: 1fr; }
|
||||
.download-media { width: 140px; flex-basis: 140px; }
|
||||
}
|
||||
|
||||
/* Versions toolbar */
|
||||
.version-toolbar {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 0.8rem;
|
||||
}
|
||||
|
||||
.version-current { color: var(--muted); }
|
||||
|
||||
.versions-archive {
|
||||
margin-top: 0.8rem;
|
||||
padding: 0.8rem;
|
||||
border-radius: 0.6rem;
|
||||
background: rgba(255,255,255,0.01);
|
||||
border: 1px solid rgba(148,163,184,0.06);
|
||||
}
|
||||
|
||||
.versions-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.6rem; }
|
||||
.version-item { display: flex; justify-content: space-between; align-items: center; padding: 0.4rem 0.6rem; border-radius: 0.45rem; }
|
||||
.version-meta { color: var(--muted); margin-left: 0.6rem; font-size: 0.92rem; }
|
||||
.version-actions { display: flex; gap: 0.4rem; }
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.version-toolbar { flex-direction: column; align-items: flex-start; }
|
||||
.version-actions { width: 100%; display: flex; gap: 0.5rem; }
|
||||
}
|
||||
|
||||
|
||||
.features .card {
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
@@ -178,10 +392,28 @@ main[data-page-content] {
|
||||
@media (max-width: 980px) {
|
||||
.hero-title { font-size: clamp(2.2rem, 7vw, 4rem); }
|
||||
|
||||
.hero {
|
||||
min-height: 27rem;
|
||||
}
|
||||
|
||||
.hero-controls {
|
||||
left: 1rem;
|
||||
right: auto;
|
||||
}
|
||||
|
||||
.features {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.env-row,
|
||||
.env-row.is-reverse {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.env-media {
|
||||
min-height: 185px;
|
||||
}
|
||||
|
||||
.features .card {
|
||||
cursor: default;
|
||||
}
|
||||
@@ -203,3 +435,20 @@ main[data-page-content] {
|
||||
pointer-events: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.hero {
|
||||
min-height: 29rem;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.hero-inner {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.hero-controls {
|
||||
left: 0.8rem;
|
||||
right: 0.8rem;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
@@ -274,6 +274,69 @@ body::after {
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.8rem 1.2rem;
|
||||
border-radius: 999px;
|
||||
text-decoration: none;
|
||||
font-weight: 700;
|
||||
border: 1px solid transparent;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
transform 180ms ease,
|
||||
background-color 180ms ease,
|
||||
border-color 180ms ease,
|
||||
color 180ms ease,
|
||||
box-shadow 180ms ease,
|
||||
opacity 180ms ease;
|
||||
user-select: none;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
.button-primary {
|
||||
background: linear-gradient(145deg, var(--accent), var(--accent-strong));
|
||||
color: #08101d;
|
||||
box-shadow: 0 12px 28px rgba(2, 6, 23, 0.25);
|
||||
}
|
||||
|
||||
.button-secondary {
|
||||
background: rgba(255,255,255,0.04);
|
||||
color: var(--text);
|
||||
border-color: rgba(148, 163, 184, 0.18);
|
||||
}
|
||||
|
||||
.button:hover,
|
||||
.button:focus-visible {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 14px 30px rgba(2, 6, 23, 0.28);
|
||||
}
|
||||
|
||||
.button-primary:hover,
|
||||
.button-primary:focus-visible {
|
||||
background: linear-gradient(145deg, color-mix(in srgb, var(--accent) 86%, white), color-mix(in srgb, var(--accent-strong) 92%, white));
|
||||
}
|
||||
|
||||
.button-secondary:hover,
|
||||
.button-secondary:focus-visible {
|
||||
background: rgba(125, 211, 252, 0.12);
|
||||
border-color: rgba(125, 211, 252, 0.35);
|
||||
}
|
||||
|
||||
.button:focus-visible {
|
||||
outline: 2px solid rgba(125, 211, 252, 0.85);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.button[aria-disabled="true"],
|
||||
.button:disabled {
|
||||
opacity: 0.55;
|
||||
pointer-events: none;
|
||||
transform: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.grid {
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
+34
-36
@@ -1,39 +1,37 @@
|
||||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Contact</title>
|
||||
<link rel="stylesheet" href="../assets/main-styles/main.css" />
|
||||
</head>
|
||||
<body>
|
||||
<main data-page-content>
|
||||
<section class="hero">
|
||||
<p class="eyebrow">Contact</p>
|
||||
<h1>Tu veux nous joindre ?</h1>
|
||||
<p class="lead">
|
||||
Cette page centralise les moyens de contact et les liens utiles pour écrire, appeler, ou retrouver le projet ailleurs.
|
||||
</p>
|
||||
<div class="hero-actions">
|
||||
<a class="button button-primary" href="mailto:contact@fwslinux.fr">Envoyer un mail</a>
|
||||
<a class="button button-secondary" href="/?p/index/" data-route="index">Retour à l'accueil</a>
|
||||
</div>
|
||||
</section>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Contact - Linux OS</title>
|
||||
<link rel="stylesheet" href="../assets/styles/styles.css">
|
||||
<link rel="stylesheet" href="../assets/styles/contact.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<section class="grid">
|
||||
<article class="card">
|
||||
<h2>Email</h2>
|
||||
<p>contact@fwslinux.fr pour les demandes générales et les retours rapides.</p>
|
||||
</article>
|
||||
<article class="card">
|
||||
<h2>Téléphone</h2>
|
||||
<p>+33 0 00 00 00 00 pour les appels ou le support direct.</p>
|
||||
</article>
|
||||
<article class="card">
|
||||
<h2>Réseaux</h2>
|
||||
<p>Le footer te donne aussi les liens vers GitHub, Instagram et LinkedIn.</p>
|
||||
</article>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
<header class="contact-header">
|
||||
<h1>Contactez l'équipe de développement</h1>
|
||||
<p>Une question, un bug à signaler ou envie de contribuer ? Voici comment nous joindre.</p>
|
||||
</header>
|
||||
|
||||
<hr>
|
||||
|
||||
<main>
|
||||
<section>
|
||||
<h2>Notre seul canal officiel actuel</h2>
|
||||
<p>Le projet est en plein développement. Pour le moment, nous n'avons pas encore d'adresse email dédiée ni de réseaux sociaux.</p>
|
||||
<p>
|
||||
<strong>Suivez le projet et ouvrez des Issues / PR ici :</strong>
|
||||
<br>
|
||||
<a class="button button-primary" href="https://github.com/You-re-like-Windows-a-bitch/ISO" target="_blank" rel="noopener noreferrer">Notre GitHub</a>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<hr>
|
||||
|
||||
</main>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+31
-14
@@ -3,24 +3,41 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>DL</title>
|
||||
<title>FWS Linux - Téléchargements</title>
|
||||
|
||||
<link rel="stylesheet" href="../assets/styles/downloads.css" />
|
||||
<link rel="icon" type="image/png" href="/p/assets/img/logo.png" />
|
||||
</head>
|
||||
<body>
|
||||
<main data-page-content>
|
||||
<section class="hero">
|
||||
<p class="eyebrow">Route DL</p>
|
||||
<h1>Le contenu de la section DL charge ici.</h1>
|
||||
<p class="lead">
|
||||
Cette page vit dans <span>p/dl/index.html</span> et son contenu est injecté dans le
|
||||
<span>main</span> quand l'URL pointe vers <span>/?p/dl/</span>.
|
||||
</p>
|
||||
<div class="hero-actions">
|
||||
<a class="button button-primary" href="/" data-route="home">Retour à l'accueil</a>
|
||||
<a class="button button-secondary" href="/?p/dl/" data-route="dl">Recharger DL</a>
|
||||
</div>
|
||||
<section class="downloads">
|
||||
<header class="downloads-header">
|
||||
<h1>Téléchargements</h1>
|
||||
<div class="versions-panel">
|
||||
<div class="latest-version">
|
||||
<h2>Dernière version</h2>
|
||||
<div class="latest-row">
|
||||
<div class="latest-meta">
|
||||
<strong data-current-version>Chargement...</strong>
|
||||
<span data-current-version-date></span>
|
||||
</div>
|
||||
<div class="latest-actions">
|
||||
<a class="button" data-latest-download href="#" target="_blank" rel="noreferrer">Télécharger</a>
|
||||
</div>
|
||||
</div>
|
||||
<p class="latest-note" data-current-release-note></p>
|
||||
</div>
|
||||
|
||||
<div class="versions-archive">
|
||||
<h3>5 versions précédentes</h3>
|
||||
<ul class="versions-list" data-versions-list></ul>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
</main>
|
||||
|
||||
<script src="../assets/js/downloads.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
+80
-9
@@ -3,25 +3,35 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Accueil</title>
|
||||
<title>FWS Linux - Accueil</title>
|
||||
<link rel="stylesheet" href="../assets/styles/main.css" />
|
||||
<link rel="icon" type="image/png" href="/p/assets/img/logo.png" />
|
||||
</head>
|
||||
<body>
|
||||
<main data-page-content>
|
||||
<section class="hero">
|
||||
<section class="hero hero-carousel" aria-label="Présentation FWS Linux">
|
||||
<div class="hero-carousel-track" data-hero-track>
|
||||
<article class="hero-slide is-active" data-hero-slide style="background-image: url('/p/assets/img/hero/xfce.png');" aria-hidden="false"></article>
|
||||
<article class="hero-slide" data-hero-slide style="background-image: url('/p/assets/img/hero/install.png');" aria-hidden="true"></article>
|
||||
<article class="hero-slide" data-hero-slide style="background-image: url('/p/assets/img/hero/gnome.png');" aria-hidden="true"></article>
|
||||
</div>
|
||||
|
||||
<div class="hero-inner">
|
||||
<h1 class="hero-title">FWS Linux</h1>
|
||||
<h2 class="hero-subtitle">un système léger, libre et compatible</h2>
|
||||
|
||||
<p class="lead">Open-source basé sur Arch Linux, Fws facilite la transition depuis Windows sans vous déposséder de vos données. Installation simplifiée, interface épurée, et compatibilité avec vos applications Windows grâce à Wine et Winboat — tout en restant respectueux de votre vie privée.</p>
|
||||
|
||||
<h2 class="hero-subtitle">Un systeme leger, libre et compatible</h2>
|
||||
<p class="lead">Open-source base sur Arch Linux, FWS facilite la transition depuis Windows sans vous deposseder de vos donnees. Installation simplifiee, interface epuree, et compatibilite avec vos applications Windows grace a Wine et Winboat.</p>
|
||||
<div class="hero-actions">
|
||||
<a class="button button-primary" href="/?p/dl/" data-route="dl">Télécharger</a>
|
||||
<a class="button button-primary" href="/?p/dl/" data-route="dl">Telecharger</a>
|
||||
<a class="button button-secondary" href="/?p/contact/" data-route="contact">En savoir plus</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="hero-controls" aria-label="Controles du carousel">
|
||||
<button class="hero-control" type="button" data-hero-prev aria-label="Image precedente">‹</button>
|
||||
<div class="hero-dots" data-hero-dots role="tablist" aria-label="Selectionner une image"></div>
|
||||
<button class="hero-control" type="button" data-hero-next aria-label="Image suivante">›</button>
|
||||
</div>
|
||||
</section>
|
||||
<section class="features">
|
||||
<article class="card" tabindex="0">
|
||||
<h2>Installation simplifiée</h2>
|
||||
@@ -43,6 +53,67 @@
|
||||
</article>
|
||||
|
||||
</section>
|
||||
|
||||
<section class="env-choices" aria-labelledby="env-choices-title">
|
||||
<header class="env-choices-header">
|
||||
<h2 id="env-choices-title">Choisissez votre environnement a l'installation</h2>
|
||||
<p>FWS Linux vous laisse choisir l'interface qui correspond a votre usage. Vous pouvez demarrer en CLI minimale ou installer un bureau complet des le debut.</p>
|
||||
</header>
|
||||
|
||||
|
||||
<article class="env-row is-reverse">
|
||||
<div class="env-text">
|
||||
<h3>KDE Plasma</h3>
|
||||
<p>Interface moderne, complete et hautement personnalisable. Un excellent choix si vous voulez un bureau riche avec de nombreux outils integres.</p>
|
||||
</div>
|
||||
<figure class="env-media">
|
||||
<img src="/p/assets/img/hero/KDE.png" alt="Capture de l'environnement KDE Plasma" loading="lazy" />
|
||||
</figure>
|
||||
</article>
|
||||
|
||||
<article class="env-row">
|
||||
<figure class="env-media">
|
||||
<img src="/p/assets/img/hero/gnome.png" alt="Capture de l'environnement Gnome" loading="lazy" />
|
||||
</figure>
|
||||
<div class="env-text">
|
||||
<h3>Gnome</h3>
|
||||
<p>Experience epuree et orientee productivite. Gnome met l'accent sur la simplicite d'utilisation et un flux de travail propre sans surcharge visuelle.</p>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="env-row is-reverse">
|
||||
<div class="env-text">
|
||||
<h3>XFCE</h3>
|
||||
<p>Environnement leger et tres stable, ideal pour les machines modestes ou pour privilegier les performances au quotidien.</p>
|
||||
</div>
|
||||
<figure class="env-media">
|
||||
<img src="/p/assets/img/hero/xfce.png" alt="Capture de l'environnement XFCE" loading="lazy" />
|
||||
</figure>
|
||||
</article>
|
||||
|
||||
<article class="env-row">
|
||||
<figure class="env-media">
|
||||
<img src="/p/assets/img/hero/hyprland.png" alt="Capture de l'environnement Hyprland" loading="lazy" />
|
||||
</figure>
|
||||
<div class="env-text">
|
||||
<h3>Hyprland</h3>
|
||||
<p>Tiling Wayland rapide et moderne, pense pour un workflow clavier et une grande efficacite. Parfait pour les utilisateurs techniques qui aiment optimiser leur espace de travail.</p>
|
||||
</div>
|
||||
</article>
|
||||
<article class="env-row is-reverse">
|
||||
<div class="env-text">
|
||||
<h3>CLI (sans environnement)</h3>
|
||||
<p>Version minimale pour les utilisateurs avances, les serveurs ou ceux qui veulent construire leur systeme a la carte. Aucun bureau graphique n'est preinstalle.</p>
|
||||
</div>
|
||||
<figure class="env-media">
|
||||
<img src="/p/assets/img/hero/install.png" alt="Capture de l'environnement CLI" loading="lazy" />
|
||||
</figure>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
|
||||
</main>
|
||||
|
||||
<script src="../assets/js/hero-carousel.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
Reference in New Issue
Block a user