Renommer lib/ en state/ pour plus de clarté
All checks were successful
Deploy / Deploy to Production (push) Successful in 13s

- Renommage du dossier src/lib/ en src/state/
- Mise à jour de l'alias @lib vers @state dans vite.config.js
- Suppression de l'alias @stores devenu obsolète
- Mise à jour de tous les imports dans les composants et vues

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
isUnknown 2026-02-07 08:26:28 +01:00
parent a12c2df8f9
commit 9ab6344835
28 changed files with 383 additions and 179 deletions

View file

@ -1,5 +1,5 @@
<script> <script>
import { pageStore } from '@stores/page' import { page } from '@state/page.svelte'
import Header from '@components/layout/Header.svelte' import Header from '@components/layout/Header.svelte'
import Footer from '@components/layout/Footer.svelte' import Footer from '@components/layout/Footer.svelte'
@ -29,9 +29,9 @@
'default': Default 'default': Default
} }
const template = $derived($pageStore.template || 'default') const template = $derived(page.template || 'default')
const component = $derived(templates[template] || Default) const view = $derived(templates[template] || Default)
const data = $derived($pageStore.data) const pageData = $derived(page.data)
const showFooter = $derived(template !== 'home') const showFooter = $derived(template !== 'home')
</script> </script>
@ -40,9 +40,8 @@
<Header /> <Header />
<main class="main"> <main class="main">
{#if data && component} {#if pageData && view}
{@const Component = component} <view data={pageData} />
<Component {data} />
{/if} {/if}
</main> </main>

View file

@ -1,8 +1,8 @@
<script> <script>
import { siteStore } from '@stores/site' import { site } from '@state/site.svelte'
$: siteTitle = $siteStore.title || 'World Game' const siteTitle = $derived(site.title || 'World Game')
$: currentYear = new Date().getFullYear() const currentYear = $derived(new Date().getFullYear())
</script> </script>
<footer class="footer"> <footer class="footer">

View file

@ -1,12 +1,12 @@
<script> <script>
import { navigationStore } from '@stores/navigation' import { navigation } from '@state/navigation.svelte'
import { localeStore } from '@stores/locale' import { locale } from '@state/locale.svelte'
import { pageStore } from '@stores/page' import { page } from '@state/page.svelte'
import { navigateTo } from '@lib/router' import { navigateTo } from '@state/router'
const isMenuOpen = $derived($navigationStore.isMenuOpen) const isMenuOpen = $derived(navigation.isMenuOpen)
const currentLang = $derived($localeStore.current) const currentLang = $derived(locale.current)
const currentPage = $derived($pageStore.template || 'home') const currentPage = $derived(page.template || 'home')
const translations = { const translations = {
expertise: { fr: 'EXPERTISE', en: 'EXPERTISE' }, expertise: { fr: 'EXPERTISE', en: 'EXPERTISE' },
@ -25,7 +25,7 @@
} }
function toggleMenu() { function toggleMenu() {
navigationStore.toggleMenu() navigation.toggleMenu()
} }
</script> </script>

View file

@ -1,8 +1,8 @@
<script> <script>
export let variant = 'primary' // primary, secondary, outline let { variant = 'primary' // primary, secondary, outline } = $props()
export let size = 'medium' // small, medium, large let { size = 'medium' // small, medium, large } = $props()
export let disabled = false let { disabled = false } = $props()
export let href = null let { href = null } = $props()
</script> </script>
{#if href} {#if href}

View file

@ -1,9 +1,9 @@
<script> <script>
import { onMount } from 'svelte' import { onMount } from 'svelte'
export let src let { src } = $props()
export let poster = '' let { poster = '' } = $props()
export let overlay = true let { overlay = true } = $props()
let videoElement let videoElement

View file

@ -1,7 +1,7 @@
import './styles/index.css' import './styles/index.css'
import App from './App.svelte' import App from './App.svelte'
import { mount } from 'svelte' import { mount } from 'svelte'
import { initRouter } from './lib/router' import { initRouter } from './state/router'
initRouter() initRouter()

View file

@ -0,0 +1,13 @@
let current = $state('fr')
let languages = $state([])
export const locale = {
get current() { return current },
get languages() { return languages },
setLanguage: (code) => current = code,
initialize: (language, langs) => {
current = language
languages = langs
}
}

View file

@ -0,0 +1,12 @@
let isMenuOpen = $state(false)
let isLoading = $state(false)
export const navigation = {
get isMenuOpen() { return isMenuOpen },
get isLoading() { return isLoading },
toggleMenu: () => isMenuOpen = !isMenuOpen,
openMenu: () => isMenuOpen = true,
closeMenu: () => isMenuOpen = false,
setLoading: (value) => isLoading = value
}

35
src/state/page.svelte.js Normal file
View file

@ -0,0 +1,35 @@
let data = $state(null)
let template = $state(null)
let url = $state(null)
let loading = $state(false)
let error = $state(null)
export const page = {
get data() { return data },
get template() { return template },
get url() { return url },
get loading() { return loading },
get error() { return error },
set: (pageData) => {
data = pageData.data
template = pageData.template
url = pageData.url
loading = pageData.loading ?? false
error = pageData.error ?? null
},
setLoading: (value) => loading = value,
setError: (err) => {
error = err
loading = false
},
reset: () => {
data = null
template = null
url = null
loading = false
error = null
}
}

View file

@ -1,19 +1,18 @@
import navaid from "navaid"; import navaid from "navaid";
import { pageStore } from "@stores/page"; import { page } from "./page.svelte";
import { navigationStore } from "@stores/navigation"; import { navigation } from "./navigation.svelte";
import { siteStore } from "@stores/site"; import { site } from "./site.svelte";
import { localeStore } from "@stores/locale"; import { locale } from "./locale.svelte";
export const router = navaid("/", () => { export const router = navaid("/", () => {
// Default handler // Default handler
}); });
async function loadPage(path) { async function loadPage(path) {
navigationStore.setLoading(true); navigation.setLoading(true);
pageStore.setLoading(true); page.setLoading(true);
try { try {
// Fetch JSON data for this page
const response = await fetch(`${path}.json`); const response = await fetch(`${path}.json`);
if (!response.ok) { if (!response.ok) {
@ -22,14 +21,12 @@ async function loadPage(path) {
const data = await response.json(); const data = await response.json();
// Update site store with site data (from genericData)
if (data.site) { if (data.site) {
siteStore.set(data.site); site.set(data.site);
localeStore.initialize(data.site.language, data.site.languages); locale.initialize(data.site.language, data.site.languages);
} }
// Update page store with page data page.set({
pageStore.set({
data, data,
template: data.template || "default", template: data.template || "default",
url: path, url: path,
@ -37,13 +34,12 @@ async function loadPage(path) {
error: null, error: null,
}); });
// Scroll to top
window.scrollTo(0, 0); window.scrollTo(0, 0);
} catch (error) { } catch (error) {
console.error("Failed to load page:", error); console.error("Failed to load page:", error);
pageStore.setError(error); page.setError(error);
} finally { } finally {
navigationStore.setLoading(false); navigation.setLoading(false);
} }
} }

24
src/state/site.svelte.js Normal file
View file

@ -0,0 +1,24 @@
let title = $state('')
let url = $state('')
let language = $state('fr')
let languages = $state([])
let logo = $state(null)
let navigation = $state([])
export const site = {
get title() { return title },
get url() { return url },
get language() { return language },
get languages() { return languages },
get logo() { return logo },
get navigation() { return navigation },
set: (data) => {
title = data.title || ''
url = data.url || ''
language = data.language || 'fr'
languages = data.languages || []
logo = data.logo || null
navigation = data.navigation || []
}
}

View file

@ -1,17 +0,0 @@
import { writable } from 'svelte/store'
function createLocaleStore() {
const { subscribe, set, update } = writable({
current: 'fr',
languages: []
})
return {
subscribe,
set,
setLanguage: (code) => update(s => ({ ...s, current: code })),
initialize: (language, languages) => set({ current: language, languages })
}
}
export const localeStore = createLocaleStore()

View file

@ -1,18 +0,0 @@
import { writable } from 'svelte/store'
function createNavigationStore() {
const { subscribe, update } = writable({
isLoading: false,
isMenuOpen: false
})
return {
subscribe,
setLoading: (loading) => update(s => ({ ...s, isLoading: loading })),
toggleMenu: () => update(s => ({ ...s, isMenuOpen: !s.isMenuOpen })),
openMenu: () => update(s => ({ ...s, isMenuOpen: true })),
closeMenu: () => update(s => ({ ...s, isMenuOpen: false }))
}
}
export const navigationStore = createNavigationStore()

View file

@ -1,27 +0,0 @@
import { writable } from 'svelte/store'
function createPageStore() {
const { subscribe, set, update } = writable({
data: null,
template: null,
url: null,
loading: false,
error: null
})
return {
subscribe,
set,
setLoading: (loading) => update(s => ({ ...s, loading })),
setError: (error) => update(s => ({ ...s, error, loading: false })),
reset: () => set({
data: null,
template: null,
url: null,
loading: false,
error: null
})
}
}
export const pageStore = createPageStore()

View file

@ -1,19 +0,0 @@
import { writable } from 'svelte/store'
function createSiteStore() {
const { subscribe, set } = writable({
title: 'World Game',
url: '',
logo: null,
language: 'fr',
languages: [],
navigation: []
})
return {
subscribe,
set
}
}
export const siteStore = createSiteStore()

View file

@ -1,60 +1,267 @@
/* Global Styles */ /* FONT SIZING SYSTEM - Consistent typography across the site */
:root {
/* Base font sizes for desktop */
--font-size-paragraph: 18px;
--font-size-paragraph-small: 16px;
--font-size-subtitle: 20px;
--font-size-title-section: 32px;
--font-size-title-main: 48px;
--font-size-title-hero: 96px;
--font-size-button: 13px;
--font-size-caption: 12px;
/* Custom fonts */ /* Mobile font sizes */
@font-face { --font-size-paragraph-mobile: 16px;
font-family: 'Danzza'; --font-size-paragraph-small-mobile: 12px;
src: url('/assets/fonts/danzza.woff2') format('woff2'), --font-size-subtitle-mobile: 16px;
url('/assets/fonts/danzza.woff') format('woff'); --font-size-title-section-mobile: 24px;
font-weight: normal; --font-size-title-main-mobile: 32px;
font-style: normal; --font-size-title-hero-mobile: 48px;
font-display: swap; --font-size-button-mobile: 11px;
--font-size-caption-mobile: 10px;
/* Tablet font sizes */
--font-size-paragraph-tablet: 16px;
--font-size-paragraph-small-tablet: 14px;
--font-size-subtitle-tablet: 18px;
--font-size-title-section-tablet: 28px;
--font-size-title-main-tablet: 40px;
--font-size-title-hero-tablet: 64px;
--font-size-button-tablet: 12px;
--font-size-caption-tablet: 11px;
} }
/* Reset */ html,
* { body {
margin: 0; height: 100%;
padding: 0; min-height: 100vh;
box-sizing: border-box; min-height: -webkit-fill-available;
} min-height: calc(var(--vh, 1vh) * 100);
user-select: none;
html {
scroll-behavior: smooth;
} }
body { body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; margin: 0;
background: #000; font-family: "Danzza Regular", "Danzza", -apple-system, BlinkMacSystemFont,
color: #fff; "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans",
line-height: 1.6; "Droid Sans", "Helvetica Neue", sans-serif;
overflow-x: hidden;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
cursor: none;
background: #000;
overflow-x: hidden;
} }
/* Typography */ * {
h1, h2, h3, h4, h5, h6 { box-sizing: border-box;
font-weight: 700; margin: 0;
line-height: 1.2; padding: 0;
cursor: none;
} }
/* Links */ /* Font faces */
a { @font-face {
color: inherit; font-family: "Terminal";
text-decoration: none; font-weight: bold;
src: local("terminal-grotesque"),
url("/assets/fonts/terminal-grotesque.ttf") format("truetype");
}
@font-face {
font-family: "Danzza";
src: local("Danzza Regular"),
url("/assets/fonts/Danzza-Regular.woff") format("woff"),
url("/assets/fonts/Danzza-Regular.otf") format("opentype");
font-display: swap;
}
@font-face {
font-family: "Danzza Light";
src: local("Danzza Light"),
url("/assets/fonts/Danzza-Light.woff") format("woff"),
url("/assets/fonts/Danzza-Light.otf") format("opentype");
font-display: swap;
}
@font-face {
font-family: "Danzza Medium";
src: local("Danzza Medium"),
url("/assets/fonts/Danzza-Medium.woff") format("woff"),
url("/assets/fonts/Danzza-Medium.otf") format("opentype");
font-display: swap;
}
@font-face {
font-family: "Danzza Bold";
src: local("Danzza Bold"),
url("/assets/fonts/Danzza-Bold.woff") format("woff"),
url("/assets/fonts/Danzza-Bold.otf") format("opentype");
font-display: swap;
}
.font-face-terminal {
font-family: "Terminal";
}
.font-face-danzza {
font-family: "Danzza";
}
.font-face-danzza-light {
font-family: "Danzza Light";
}
.font-face-danzza-medium {
font-family: "Danzza Medium";
}
.font-face-danzza-bold {
font-family: "Danzza Bold";
}
/* Golden Grid */
.golden-grid {
height: 100% !important;
min-height: 100% !important;
display: grid !important;
position: relative;
grid-template-rows: 1fr 1fr 2fr 4fr 2.66fr 5.33fr 5.33fr 4.33fr 2.83fr 3.5fr 3.5fr 2.83fr 4.33fr 5.33fr 5.33fr 2.66fr 4fr 2fr 1fr 1fr;
grid-template-columns: 1fr 1fr 2fr 4fr 2.66fr 5.33fr 5.33fr 4.33fr 2.83fr 3.5fr 3.5fr 2.83fr 4.33fr 5.33fr 5.33fr 2.66fr 4fr 2fr 1fr 1fr;
text-align: center;
}
.slide {
overflow-y: hidden;
}
/* Vertical Lines */
.vertical-line {
z-index: 1;
border-left: 0.1px solid rgba(238, 238, 238, 0.2);
height: 150%;
}
.vertical-line-start {
z-index: 1;
border-left: 0.1px solid rgba(238, 238, 238, 0.2);
grid-area: 1/6 / span 20 / span 1;
height: 150%;
}
.vertical-line-center {
z-index: 1;
border-left: 0.1px solid rgba(238, 238, 238, 0.2);
grid-area: 1/11 / span 20 / span 1;
height: 150%;
}
.vertical-line-end {
z-index: 1;
border-left: 0.1px solid rgba(238, 238, 238, 0.2);
grid-area: 1/16 / span 20 / span 1;
height: 150%;
}
/* Button */
.button {
width: 14vmax;
min-width: 130px;
display: flex;
align-items: center;
justify-content: center;
position: sticky;
z-index: 1;
padding: 12px 16px;
transition: 0.5s ease-out;
font-family: "Danzza Bold";
background-color: #04fea0;
border: none;
cursor: pointer;
}
.button:hover {
background-position: left;
background-color: transparent;
outline: solid 2px #04fea0;
}
.button p {
color: black;
margin: 0;
transition: color 0.3s; transition: color 0.3s;
} }
/* Images */ .button:hover p {
img { color: #04fea0 !important;
max-width: 100%;
height: auto;
display: block;
} }
/* Buttons */ .earth-icon {
button { width: 24px;
font-family: inherit; height: 24px;
background-image: url('/assets/img/icon-earth-green.png');
background-size: contain;
background-repeat: no-repeat;
background-position: center;
margin-right: 8px;
transition: filter 0.3s;
}
.button:hover .earth-icon {
filter: brightness(0) saturate(100%) invert(77%) sepia(82%) saturate(507%) hue-rotate(91deg) brightness(101%) contrast(97%);
}
/* Clickable elements */
.clickable {
cursor: pointer; cursor: pointer;
user-select: none;
}
/* Cursor */
#cursor-dot,
#cursor-dot-outline,
#cursor-circle {
position: absolute;
top: 50%;
left: 50%;
z-index: 99999;
transform: translate(-50%, -50%);
transition: opacity 0.15s ease-in-out, transform 0.15s ease-in-out;
border-radius: 50%;
pointer-events: none;
opacity: 0;
}
#cursor-dot {
width: 14px;
height: 14px;
background-color: white;
}
#cursor-circle {
width: 50px;
height: 50px;
border-width: 3px;
border-style: solid;
border-color: #04fea0;
}
#cursor-dot-outline {
width: 13px;
height: 13px;
background-color: white;
}
@media (pointer: coarse) {
#cursor-dot,
#cursor-dot-outline,
#cursor-circle {
display: none;
}
body,
* {
cursor: auto;
}
} }
/* Selection */ /* Selection */

View file

@ -1,12 +1,12 @@
<script> <script>
import { fade } from 'svelte/transition' import { fade } from 'svelte/transition'
export let data let { data } = $props()
$: intro = data?.intro || {} const intro = $derived(data?.intro || {})
$: mission = data?.mission || {} const mission = $derived(data?.mission || {})
$: manifesto = data?.manifesto || {} const manifesto = $derived(data?.manifesto || {})
$: team = data?.team || {} const team = $derived(data?.team || {})
</script> </script>
<div class="about" transition:fade> <div class="about" transition:fade>

View file

@ -1,6 +1,6 @@
<script> <script>
import { fade } from 'svelte/transition' import { fade } from 'svelte/transition'
export let data let { data } = $props()
</script> </script>
<div class="article" transition:fade> <div class="article" transition:fade>

View file

@ -1,6 +1,6 @@
<script> <script>
import { fade } from 'svelte/transition' import { fade } from 'svelte/transition'
export let data let { data } = $props()
</script> </script>
<div class="blog" transition:fade> <div class="blog" transition:fade>

View file

@ -1,7 +1,7 @@
<script> <script>
import { fade } from 'svelte/transition' import { fade } from 'svelte/transition'
export let data let { data } = $props()
</script> </script>
<div class="default" transition:fade> <div class="default" transition:fade>

View file

@ -1,6 +1,6 @@
<script> <script>
import { fade } from 'svelte/transition' import { fade } from 'svelte/transition'
export let data let { data } = $props()
</script> </script>
<div class="expertise" transition:fade> <div class="expertise" transition:fade>

View file

@ -1,6 +1,6 @@
<script> <script>
import { fade } from 'svelte/transition' import { fade } from 'svelte/transition'
export let data let { data } = $props()
</script> </script>
<div class="game" transition:fade> <div class="game" transition:fade>

View file

@ -1,11 +1,11 @@
<script> <script>
import { onMount } from 'svelte' import { onMount } from 'svelte'
import { localeStore } from '@stores/locale' import { locale } from '@state/locale.svelte'
import { navigateTo } from '@lib/router' import { navigateTo } from '@state/router'
let { data } = $props() let { data } = $props()
const currentLang = $derived($localeStore.current) const currentLang = $derived(locale.current)
const translations = { const translations = {
homeText: { homeText: {

View file

@ -1,6 +1,6 @@
<script> <script>
import { fade } from 'svelte/transition' import { fade } from 'svelte/transition'
export let data let { data } = $props()
</script> </script>
<div class="jouer" transition:fade> <div class="jouer" transition:fade>

View file

@ -1,6 +1,6 @@
<script> <script>
import { fade } from 'svelte/transition' import { fade } from 'svelte/transition'
export let data let { data } = $props()
</script> </script>
<div class="portfolio" transition:fade> <div class="portfolio" transition:fade>

View file

@ -1,6 +1,6 @@
<script> <script>
import { fade } from 'svelte/transition' import { fade } from 'svelte/transition'
export let data let { data } = $props()
</script> </script>
<div class="project" transition:fade> <div class="project" transition:fade>

View file

@ -12,8 +12,7 @@ export default defineConfig({
alias: { alias: {
'@components': path.resolve(__dirname, 'src/components'), '@components': path.resolve(__dirname, 'src/components'),
'@views': path.resolve(__dirname, 'src/views'), '@views': path.resolve(__dirname, 'src/views'),
'@stores': path.resolve(__dirname, 'src/stores'), '@state': path.resolve(__dirname, 'src/state')
'@lib': path.resolve(__dirname, 'src/lib')
} }
}, },
server: { server: {