Compare commits

..

1 commit

Author SHA1 Message Date
Dariusz Niemczyk 50ded1089c
feat: add favicons 2025-01-29 20:03:39 +01:00
16 changed files with 88 additions and 150 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 135 KiB

View file

@ -19,7 +19,7 @@ export default async function RootLayout({
const { locale } = await params
const currentLang = locales.includes(locale) ? locale : "en"
return (
<html lang={currentLang} className={`${oxanium.className} dark`}>
<html lang={currentLang} className={oxanium.className}>
<Head>
<link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />

View file

@ -40,9 +40,9 @@ export default function Home() {
</video>
</div>
<div className="relative z-10 container mx-auto px-4 h-full flex items-center justify-center">
<div className="text-center font-[JGS7]">
<h1 className="text-5xl sm:text-6xl md:text-8xl font-bold tracking-tighter mb-6 light:text-background">{t.hero.title}</h1>
<p className="text-3xl sm:text-4xl md:text-5xl lg:text-6xl xl-text:7xl 2xl:text-8xl text-primary">{t.hero.subtitle}</p>
<div className="text-center">
<h1 className="text-6xl md:text-8xl font-bold tracking-tighter mb-6 light:text-background">{t.hero.title}</h1>
<p className="text-xl md:text-2xl text-primary">{t.hero.subtitle}</p>
</div>
</div>
</section>
@ -69,7 +69,7 @@ export default function Home() {
<div className="container mx-auto px-4">
<h2 className="text-4xl font-bold mb-8 tracking-tighter">{t.when.title}</h2>
<div className="text-lg text-muted-foreground">
<p className="text-primary text-3xl font-[JGS7]">{t.when.date}</p>
<p className="text-primary text-3xl">{t.when.date}</p>
<p className="mt-4">{t.when.extra}</p>
</div>
</div>
@ -112,17 +112,6 @@ export default function Home() {
</div>
</div>
</section>
<section id="credits" className="py-24 bg-background">
<div className="container mx-auto px-4">
<h2 className="text-4xl font-bold mb-8 tracking-tighter">{t.credits.title}</h2>
<div className="text-lg text-muted-foreground">
<p>{t.credits.usedFonts}</p>
<p><a className="hover:underline" href="https://velvetyne.fr/fonts/jgs-font/">{t.credits.jgs7}</a> {` ${t.credits.jgs7RemovedGlyphs}`}</p>
<p><a className="hover:underline" href="https://fonts.google.com/specimen/Oxanium">{t.credits.oxanium}</a></p>
</div>
</div>
</section>
</main>
</div>
)

View file

@ -2,18 +2,15 @@
import { Button } from "@/components/ui/button"
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from "@/components/ui/sheet"
import type { Sections, translations } from "@/i18n/translations"
import { cn } from "@/lib/utils"
import type { translations } from "@/i18n/translations"
import { Menu } from "lucide-react"
export function MobileNav({
t,
linksOrder,
activeSection
}: {
t: typeof translations.pl
linksOrder: Array<Sections>
activeSection: Sections
linksOrder: Array<keyof (typeof translations.pl)["nav"]>
}) {
return (
<Sheet>
@ -29,9 +26,7 @@ export function MobileNav({
</SheetHeader>
<nav className="flex flex-col gap-4 mt-8">
{linksOrder.map((value) => (
<a key={value} href={`#${value}`} className={cn("text-lg hover:text-primary transition-colors", {
'text-primary': activeSection === value
})}>
<a key={value} href={`#${value}`} className="text-lg hover:text-primary transition-colors">
{t.nav[value]}
</a>
))}

View file

@ -1,9 +1,9 @@
"use client"
import { Button } from "@/components/ui/button"
import { Sections, type translations } from "@/i18n/translations"
import type { translations } from "@/i18n/translations"
import { cn } from "@/lib/utils"
import { MoonIcon, SunIcon } from "lucide-react"
import { useCallback, useEffect, useState } from "react"
import { useEffect, useState } from "react"
import { MobileNav } from "./mobile-nav"
const linksOrder: Array<keyof (typeof translations.pl)["nav"]> = [
@ -16,43 +16,29 @@ const linksOrder: Array<keyof (typeof translations.pl)["nav"]> = [
"contact",
]
function useTheme(): [theme: "light" | "dark", setTheme: (theme: "light" | "dark") => void] {
/* eslint-disable react-hooks/rules-of-hooks */
if (typeof window === "undefined") return ["dark", () => { }]
export function Nav({
t,
}: {
t: typeof translations.pl
}) {
const [theme, setTheme] = useState<"light" | "dark">("dark")
const root = window.document.documentElement
const changeTheme = useCallback((theme: "light" | "dark") => {
root.classList.remove("light", "dark")
root.classList.add(theme)
}, [root])
const [activeSection, setActiveSection] = useState<keyof (typeof translations.pl)["nav"]>("about")
useEffect(() => {
// Determine the user's preferred color scheme
const preferredTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"
setTheme(preferredTheme)
changeTheme(preferredTheme)
}, [changeTheme])
const updateTheme = useCallback((theme: "light" | "dark") => {
setTheme(theme)
changeTheme(theme)
}, [changeTheme, setTheme])
return [theme, updateTheme]
/* eslint-enable react-hooks/rules-of-hooks */
}
export function Nav({
t,
}: {
t: typeof translations.pl
}) {
const [theme, setTheme] = useTheme()
const [activeSection, setActiveSection] = useState<Sections>("about")
const root = window.document.documentElement
root.classList.remove("light", "dark")
root.classList.add(preferredTheme)
}, [])
useEffect(() => {
const root = window.document.documentElement
root.classList.remove("light", "dark")
root.classList.add(theme)
}, [theme])
useEffect(() => {
const options = {
@ -94,7 +80,7 @@ export function Nav({
<div className="container mx-auto px-4">
<div className="flex items-center justify-between h-16">
<a href="#" className="text-xl font-bold tracking-tighter hover:text-primary transition-colors">
{t.siteTitle}
CEBULACAMP
</a>
<div className="flex items-center">
{/* Desktop Navigation */}
@ -103,14 +89,12 @@ export function Nav({
<a
key={value}
href={`#${value}`}
className={cn("text-sm md:text-md hover:text-primary transition-colors relative group", {
className={cn("text-sm hover:text-primary transition-colors relative group", {
'text-primary': activeSection === value
})}
>
{t.nav[value]}
<span className={cn("absolute inset-x-0 -bottom-1 h-0.5 bg-primary transform scale-x-0 group-hover:scale-x-100 transition-transform", {
'scale-x-100': activeSection === value
})} />
<span className="absolute inset-x-0 -bottom-1 h-0.5 bg-primary transform scale-x-0 group-hover:scale-x-100 transition-transform" />
</a>
))}
</div>
@ -127,7 +111,7 @@ export function Nav({
{/* Mobile Navigation */}
<div className="md:hidden ml-2">
<MobileNav t={t} linksOrder={linksOrder} activeSection={activeSection} />
<MobileNav t={t} linksOrder={linksOrder} />
</div>
</div>
</div>

View file

@ -2,15 +2,6 @@
@tailwind components;
@tailwind utilities;
@font-face {
font-family: "JGS7";
src: url("/fonts/jgs7.woff2") format("woff2"),
url("/fonts/jgs7.woff") format("woff"),
url("/fonts/jgs7.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}
html {
@media (prefers-reduced-motion: no-preference) {
scroll-behavior: smooth;
@ -81,7 +72,9 @@ html {
--input: hsl(0 0% 14.9%);
--ring: hsl(0 0% 83.1%);
}
}
@layer base {
* {
@apply border-border;
}
@ -96,7 +89,3 @@ html {
.parallax-video {
transition: transform 0.25s ease-out;
}
.jgs7 {
font-family: "JGS7" !important;
}

View file

@ -1,78 +1,59 @@
const common = {
jgs7: "JGS7",
oxanium: "Oxanium",
};
const pl = {
siteTitle: "CEBULACAMP",
nav: {
about: "O nas",
when: "Kiedy",
where: "Gdzie",
food: "Wyżywienie",
contact: "Kontakt",
tickets: "Bilety",
accommodation: "Nocleg",
export const translations = {
pl: {
nav: {
about: "O nas",
when: "Kiedy",
where: "Gdzie",
food: "Wyżywienie",
contact: "Kontakt",
tickets: "Bilety",
accommodation: "Nocleg",
},
mobileNav: {
toggleMenu: "Aktywnuj menu",
menu: "Menu",
},
hero: {
title: "CEBULACAMP 2025",
subtitle: "REAKTYWACJA",
},
about: {
title: "O nas",
description:
"Zjazd hakerów, miłośników open source, wolnych duchów. Organizowany przez hakerów dla hakerów. Będzie mate, będzie utopia, będzie chillera.\n\nSpodziewaj się ciekawych prezentacji, dziwnych instalacji artystycznych i mnóstwa dyskusji. Możesz opowiedzieć o swoim projekcie, zademonstrować skonstruowane zabawki, albo wspólnie coś stworzyć podczas eventu.",
},
where: {
title: "Gdzie",
location:
"klub Łącznik, Tramwajowa 1-3, Wrocław, obok Hackerspace Wrocław",
},
when: {
title: "Kiedy",
date: "28-31.08.2025",
extra:
"chętnych do pomocy w przygotowaniach zapraszamy już na *Day 0* 27 sierpnia",
},
tickets: {
title: "Bilety",
status: "soon",
},
accommodation: {
title: "Nocleg",
description:
"w duchu prawdziwego campu przygotowujemy ogrodzone miejsce do rozbicia namiotu z toaletami i prysznicem. Ilość miejsc namiotowych ograniczona, obowiązuje kolejność rezerwacji. Jest także możliwość zakwaterowania we własnym zakresie w pobliskim hotelu lub akademikach.",
},
food: {
title: "Wyżywienie",
description:
"we własnym zakresie, w okolicy dostępne są knajpy z dowozem, wieczory planujemy umilić wspólnym grillowaniem.",
},
contact: {
title: "Kontakt",
email: "contact@cebula.camp",
},
},
mobileNav: {
toggleMenu: "Aktywnuj menu",
menu: "Menu",
},
hero: {
title: "CEBULACAMP 2025",
subtitle: "REAKTYWACJA",
},
about: {
title: "O nas",
description:
"Zjazd hakerów, miłośników open source, wolnych duchów. Organizowany przez hakerów dla hakerów. Będzie mate, będzie utopia, będzie chillera.\n\nSpodziewaj się ciekawych prezentacji, dziwnych instalacji artystycznych i mnóstwa dyskusji. Możesz opowiedzieć o swoim projekcie, zademonstrować skonstruowane zabawki, albo wspólnie coś stworzyć podczas eventu.",
},
where: {
title: "Gdzie",
location: "klub Łącznik, Tramwajowa 1-3, Wrocław, obok Hackerspace Wrocław",
},
when: {
title: "Kiedy",
date: "28-31.08.2025",
extra:
"chętnych do pomocy w przygotowaniach zapraszamy już na *Day 0* 27 sierpnia",
},
tickets: {
title: "Bilety",
status: "soon",
},
accommodation: {
title: "Nocleg",
description:
"w duchu prawdziwego campu przygotowujemy ogrodzone miejsce do rozbicia namiotu z toaletami i prysznicem. Ilość miejsc namiotowych ograniczona, obowiązuje kolejność rezerwacji. Jest także możliwość zakwaterowania we własnym zakresie w pobliskim hotelu lub akademikach.",
},
food: {
title: "Wyżywienie",
description:
"we własnym zakresie, w okolicy dostępne są knajpy z dowozem, wieczory planujemy umilić wspólnym grillowaniem.",
},
contact: {
title: "Kontakt",
email: "contact@cebula.camp",
},
credits: {
title: "Uznania",
usedFonts: "Użyte fonty:",
oxanium: common.oxanium,
jgs7: common.jgs7,
jgs7RemovedGlyphs: "z usuniętymi znakami",
en: {
// English translations would go here
},
};
const en = {};
export const translations: {
en: typeof pl;
pl: typeof pl;
} = {
pl: pl,
// @ts-expect-error This should fail so far, remove me when translations are properly added to "en" object.
en: en,
};
export type Sections = keyof (typeof pl)["nav"];