Stylizacja i poprawki w układzie

This commit is contained in:
dm
2025-11-26 08:00:00 +01:00
parent d3040f4917
commit 284009d411
56 changed files with 328 additions and 621 deletions

View File

@@ -15,6 +15,7 @@
"better-sqlite3": "^12.4.6", "better-sqlite3": "^12.4.6",
"globby": "^16.0.0", "globby": "^16.0.0",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"jsdom": "^27.2.0",
"marked": "^17.0.1", "marked": "^17.0.1",
"nodemailer": "^7.0.10", "nodemailer": "^7.0.10",
"preact": "^10.27.2" "preact": "^10.27.2"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 169 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 169 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 KiB

After

Width:  |  Height:  |  Size: 90 KiB

View File

@@ -38,7 +38,7 @@ const isLCP = true;
fetchpriority={isLCP ? "high" : "auto"} fetchpriority={isLCP ? "high" : "auto"}
decoding="async" decoding="async"
format="webp" format="webp"
widths={[640, 960, 1280, 1920]} widths={[640, 960, 1280, 1350, 1920]}
sizes="100vw" sizes="100vw"
/> />
)} )}

View File

@@ -15,6 +15,7 @@ const footer = yaml.load(
{footer.company.address.line1}<br /> {footer.company.address.line1}<br />
{footer.company.address.line2} {footer.company.address.line2}
</p> </p>
<a href="/polityka-prywatnosci" title="Polityka prywatności">Polityka prywatności</a>
</div> </div>
<div class="f-footer-col"> <div class="f-footer-col">

View File

@@ -20,7 +20,7 @@ const links = [
<nav class="f-navbar"> <nav class="f-navbar">
<div class="f-navbar-inner"> <div class="f-navbar-inner">
<a href="/" class="flex items-center gap-2 font-semibold"> <a href="/" class="flex items-center gap-2 font-semibold">
<img src="/assets/logo.webp" alt="FUZ Logo" class="my-0" /> <img src="/assets/logo.webp" alt="FUZ Logo" class="f-navbar-logo" />
</a> </a>
<div class="hidden md:flex f-navbar-links"> <div class="hidden md:flex f-navbar-links">

View File

@@ -7,13 +7,11 @@ const { section, index } = Astro.props;
const hasImage = !!section.image; const hasImage = !!section.image;
const reverse = index % 2 === 1; const reverse = index % 2 === 1;
// Automatyczny import obrazów sekcji
const sectionImages = import.meta.glob<{ default: ImageMetadata }>( const sectionImages = import.meta.glob<{ default: ImageMetadata }>(
"/src/assets/sections/**/*.{png,jpg,jpeg,webp,avif}", "/src/assets/sections/**/*.{png,jpg,jpeg,webp,avif}",
{ eager: true }, { eager: true },
); );
// Znajdź obraz zgodnie z YAML
let sectionImage: ImageMetadata | null = null; let sectionImage: ImageMetadata | null = null;
if (section.image) { if (section.image) {
@@ -23,17 +21,16 @@ if (section.image) {
} }
--- ---
<section class="fuz-section"> <section class="f-section">
<div <div
class={`fuz-section-grid ${hasImage ? "md:grid-cols-2" : "md:grid-cols-1"}`} class={`f-section-grid ${hasImage ? "md:grid-cols-2" : "md:grid-cols-1"}`}
> >
{ {
sectionImage && ( sectionImage && (
<Image <Image
src={sectionImage} src={sectionImage}
alt={section.title} alt={section.title}
class={`fuz-section-image ${reverse ? "md:order-1" : "md:order-2"} class={`f-section-image ${reverse ? "md:order-1" : "md:order-2"} ${section.dimmed ? "f-image-dimmed" : ""}`}
${section.dimmed ? "fuz-image-dimmed" : ""}`}
loading="lazy" loading="lazy"
decoding="async" decoding="async"
format="webp" format="webp"
@@ -44,15 +41,16 @@ if (section.image) {
} }
<div <div
class={`fuz-section text-center ${hasImage ? (reverse ? "md:order-2" : "md:order-1") : ""}`} class={`f-section-grid ${hasImage ? (reverse ? "md:order-2" : "md:order-1") : ""}`}
> >
<h2 class="fuz-section-title">{section.title}</h2> <!-- TODO: Styl nagłowka powinien byc trochę niżej -->
<h2 class="f-section-title">{section.title}</h2>
<Markdown text={section.content} /> <Markdown text={section.content} />
{ {
section.button && ( section.button && (
<div class="mt-8 flex justify-center"> <div class="f-section-nav">
<a <a
href={section.button.url} href={section.button.url}
class="btn btn-outline" class="btn btn-outline"

View File

@@ -8,10 +8,8 @@ import SectionIframeChannels from "./SectionIframeChannels.astro";
const { src } = Astro.props; const { src } = Astro.props;
// Load YAML
const data = yaml.load(fs.readFileSync(src, "utf8")) ?? { sections: [] }; const data = yaml.load(fs.readFileSync(src, "utf8")) ?? { sections: [] };
// Markdown → HTML
const sections = (data.sections as any[]).map((s: any) => ({ const sections = (data.sections as any[]).map((s: any) => ({
...s, ...s,
html: marked(s.content || "") html: marked(s.content || "")

View File

@@ -1,27 +0,0 @@
title:
- Internet radiowy Wyszków i okolice
subtitle:
- DLACZEGO INTERNET RADIOWY FUZ ?
- To szybkie i stabilne łącze bezprzewodowe
- Idealny dla domów i firm w miejscach, gdzie inne technologie zawodzą
- Szybka instalacja
description: |
Internet radiowy to bezprzewodowa technologia dostępu do sieci, która sprawdza się idealnie tam, gdzie doprowadzenie kabli nie jest możliwe.
Dzięki niezależności od nadajników GSM, nasza usługa jest często dostępna w miejscach, gdzie zasięg LTE czy 3G zawodzi.
imageUrl: "section-radiowy.webp"
ctas:
- label: "Zobacz ofertę internetu światłowodowego"
href: "/internet-swiatlowodowy"
title: "Przejdź do oferty Internetu światłowodowego"
primary: false
- label: "Zobacz ofertę Internetu + Telewizji"
href: "/internet-telewizja"
title: "Przejdź do oferty Internet + Telewizja w FUZ"
primary: false
- label: "Sprawdź dostępność"
href: "/mapa-zasiegu"
title: "Sprawdź zasięg Internetu światłowodowego i radiowego FUZ"
primary: false

View File

@@ -1,82 +0,0 @@
przelaczniki:
- id: "umowa"
etykieta: "Okres umowy"
domyslny: "24m"
title: Wybierz okres umowy by zobaczyć odpowiednie ceny
opcje:
- id: "24m"
nazwa: "24 miesiące"
- id: "12m"
nazwa: "12 miesięcy"
- id: "bezterminowa"
nazwa: "Bezterminowa"
funkcje:
- id: "predkosc"
etykieta: "Prędkość pobierania"
- id: "wysylanie"
etykieta: "Prędkość wysyłania"
- id: "instalacja"
etykieta: "Aktywacja"
- id: "umowa_info"
etykieta: "Umowa"
- id: "adres_ip"
etykieta: "Adres IP"
plany:
- id: "fuz-4"
nazwa: "FUZ-4"
predkosc: "4 Mb/s"
popularny: false
ceny:
24m: "38 zł/mc"
12m: "45 zł/mc"
bezterminowa: "80 zł/mc"
funkcje:
predkosc: "4 Mb/s"
wysylanie: "1 Mb/s"
sprzet: "W zestawie"
instalacja: "199 zł"
adres_ip: "Dynamiczny"
- id: "fuz-6"
nazwa: "FUZ-6"
predkosc: "6 Mb/s"
popularny: true
ceny:
24m: "45 zł/mc"
12m: "60 zł/mc"
bezterminowa: "110 zł/mc"
funkcje:
predkosc: "6 Mb/s"
wysylanie: "1 Mb/s"
instalacja: "199 zł"
adres_ip: "Dynamiczny"
- id: "fuz-8"
nazwa: "FUZ-8"
predkosc: "8 Mb/s"
popularny: false
ceny:
24m: "55 zł/mc"
12m: "75 zł/mc"
bezterminowa: "120 zł/mc"
funkcje:
predkosc: "8 Mb/s"
wysylanie: "1.5 Mb/s"
instalacja: "199 zł"
adres_ip: "Dynamiczny"
- id: "fuz-10"
nazwa: "FUZ-10"
predkosc: "10 Mb/s"
popularny: false
ceny:
24m: "80 zł/mc"
12m: "110 zł/mc"
bezterminowa: "160 zł/mc"
funkcje:
predkosc: "10 Mb/s"
wysylanie: "2 Mb/s"
instalacja: "199 zł"
adres_ip: "Dynamiczny"

View File

@@ -1,23 +0,0 @@
title:
- PAKIET RADIOWY WYSZKÓW I OKOLICE
paragraphs:
- title:
content: |
Internet radiowy to bezprzewodowa technologia dostępu do sieci, która sprawdza się idealnie tam, gdzie doprowadzenie kabli nie jest możliwe.
Dzięki niezależności od nadajników GSM, nasza usługa jest często dostępna w miejscach, gdzie zasięg LTE czy 3G zawodzi.
W przeciwieństwie do internetu mobilnego, oferujemy nielimitowany dostęp do sieci.
Możesz korzystać z internetu bez obaw o wyczerpanie pakietu danych oglądaj, pobieraj i surfuj bez żadnych ograniczeń.
Sprawdź dostępność internetu radiowego FUZ w Twojej okolicy i ciesz się swobodą dostępu do sieci.
- title:
content:
Dostępność usług zależy od lokalizacji abonenta.
Zapraszamy do kontaktu w celu sprawdzenia zasięgu.
# Kolejne sekcje mozna dodawać poja wiać się bedą pod tabela produktów

View File

@@ -1,17 +0,0 @@
site:
name: "FUZ Internet światłowodowy i radiowy w Wyszkowie"
description: "Stabilny i szybki internet"
url: "https://www.fuz.pl"
lang: "pl"
company:
name: "FUZ Adam Rojek"
phone: "+48 (29) 643 80 55"
email: "biuro@fuz.pl"
street: "ul. Świętojańska 46"
city: "Wyszków"
postal: "07-200"
country: "PL"
lat: 52.597385
lon: 21.456797
logo: "/images/logo-fuz.webp"

View File

@@ -8,21 +8,21 @@ subtitle:
- Lokalny operator, znamy Twoją okolicę - Lokalny operator, znamy Twoją okolicę
description: | description: |
Szybki i stabilny Internet światłowodowy i radiowy w Wyszkowie oraz okolicach. Szybki i stabilny Internet światłowodowy w Wyszkowie oraz okolicach.
Sprawdź zasięg usług i wybierz najlepsze łącze dla swojego domu. Sprawdź zasięg usług i wybierz najlepsze łącze dla swojego domu.
imageUrl: "section-fiber.webp" imageUrl: "section-fiber.webp"
ctas: ctas:
- label: "Zobacz ofertę Internetu Radiowego"
href: "/internet-radiowy"
primary: false
title: "Przejdź do oferty Internetu radiowego"
- label: "Zobacz ofertę Internetu + Telewizja" - label: "Zobacz ofertę Internetu + Telewizja"
href: "/internet-telewizja" href: "/internet-telewizja"
title: "Przejdź do oferty Internet + Telewizja w FUZ" title: "Przejdź do oferty Internet + Telewizja w FUZ"
primary: false primary: false
- label: "Zobacz ofertę telefonu "
href: "/telefon"
primary: false
title: "Przejdź do oferty telefonu"
- label: "Sprawdź dostępność" - label: "Sprawdź dostępność"
href: "/mapa-zasiegu" href: "/mapa-zasiegu"
title: "Sprawdź zasięg Internetu światłowodowego i radiowego FUZ" title: "Sprawdź zasięg Internetu światłowodowego FUZ"
primary: false primary: false

View File

@@ -36,7 +36,7 @@ funkcje:
- id: "adres_ip" - id: "adres_ip"
etykieta: "Adres IP" etykieta: "Adres IP"
# PLANY jedna lista, ceny zależą od kombinacji przełączników plany_title:
plany: plany:
- id: "fiber100" - id: "fiber100"
nazwa: "FIBER 100" nazwa: "FIBER 100"
@@ -44,13 +44,13 @@ plany:
popularny: false popularny: false
ceny: ceny:
jednorodzinny: jednorodzinny:
# 12m: "59 zł/mies." # 12m: "59 zł/mc"
24m: "64 zł/mies." 24m: "64 zł/mc"
bezterminowa: "84 zł/mies." bezterminowa: "84 zł/mc"
wielorodzinny: wielorodzinny:
# 12m: "55 zł/mies." # 12m: "55 zł/mc"
24m: "54 zł/mies." 24m: "54 zł/mc"
bezterminowa: "74 zł/mies." bezterminowa: "74 zł/mc"
funkcje: funkcje:
pobieranie: "do 100 Mb/s" pobieranie: "do 100 Mb/s"
wysylanie: "do 50 Mb/s" wysylanie: "do 50 Mb/s"
@@ -66,13 +66,13 @@ plany:
popularny: true popularny: true
ceny: ceny:
jednorodzinny: jednorodzinny:
# 12m: "79 zł/mies." # 12m: "79 zł/mc"
24m: "75 zł/mies." 24m: "75 zł/mc"
bezterminowa: "95 zł/mies." bezterminowa: "95 zł/mc"
wielorodzinny: wielorodzinny:
# 12m: "69 zł/mies." # 12m: "69 zł/mc"
24m: "65 zł/mies." 24m: "65 zł/mc"
bezterminowa: "85 zł/mies." bezterminowa: "85 zł/mc"
funkcje: funkcje:
pobieranie: "do 300 Mb/s" pobieranie: "do 300 Mb/s"
wysylanie: "do 150 Mb/s" wysylanie: "do 150 Mb/s"
@@ -87,11 +87,11 @@ plany:
popularny: false popularny: false
ceny: ceny:
jednorodzinny: jednorodzinny:
24m: "85 zł/mies." 24m: "85 zł/mc"
bezterminowa: "105 zł/mies." bezterminowa: "105 zł/mc"
wielorodzinny: wielorodzinny:
24m: "75 zł/mies." 24m: "75 zł/mc"
bezterminowa: "95 zł/mies." bezterminowa: "95 zł/mc"
funkcje: funkcje:
pobieranie: "do 600 Mb/s" pobieranie: "do 600 Mb/s"
wysylanie: "do 300 Mb/s" wysylanie: "do 300 Mb/s"
@@ -100,6 +100,13 @@ plany:
instalacja: "149 zł" instalacja: "149 zł"
adres_ip: "Dynamiczny" adres_ip: "Dynamiczny"
uslugi:
title: Usługi dodatkowe
description: Do wybranej opcji możesz dokupić dotakowe usługi.
items:
- Nazwa usługi
- Cena
- Szczegóły
uslugi_dodatkowe: uslugi_dodatkowe:
- id: "public_ip" - id: "public_ip"
nazwa: "Publiczny adres IP" nazwa: "Publiczny adres IP"

View File

@@ -6,13 +6,13 @@ paragraphs:
content: | content: |
Światłowody to najbardziej zaawansowana technologia przesyłu danych. Światłowody to najbardziej zaawansowana technologia przesyłu danych.
Gwarantują błyskawiczną prędkość, stabilność i niezawodność bez względu na warunki. Gwarantują błyskawiczną prędkość, stabilność i niezawodność bez względu na warunki.
Dedykowane pasmo,pełna prędkość tylko dla Ciebie. Dedykowane pasmo,pełna prędkość tylko dla Ciebie.
Stała jakość, pogoda ani liczba użytkowników w sieci nie mają znaczenia. Stała jakość, pogoda ani liczba użytkowników w sieci nie mają znaczenia.
Wiele urządzeń jednocześnie, komputer, telefon, tablet, konsola wszystko działa płynnie. Wiele urządzeń jednocześnie, komputer, telefon, tablet, konsola wszystko działa płynnie.
Światłowód to również dostęp do telewizji i telefonu w najwyższej jakości. Światłowód to również dostęp do telewizji i telefonu w najwyższej jakości.

View File

@@ -1,18 +1,16 @@
sections: sections:
- title: Sprawdź dostępność usługi - title: Sprawdź dostępność usługi
image: "internet.webp" image: section-range.webp
button: button:
text: "Sprawdź dostępność pod Twoim adresem →" text: "Sprawdź dostępność pod Twoim adresem →"
url: "/mapa-zasiegu" url: "/mapa-zasiegu"
title: "Sprawdź zasięg Internetu światłowodowego i radiowego FUZ" title: "Sprawdź zasięg Internetu światłowodowego FUZ"
content: | content: |
Światłowody nie dociera jeszcze niestety do wszystkich domów. Naszą sieć światłowodową systematycznie rozbudowujemy, ale infrastruktura nie dociera jeszcze do wszystkich adresów.
[Sprawdź](/mapa-zasięgu "Sprawdź zasięg Internetu światłowodowego i radiowego FUZ") czy pod Twoim adresem dostępna jest nasza usługa internetu światłowodowego. Proces budowy wymaga czasu może jednak akurat Twoja lokalizacja jest już podłączona?
Tam gdzie nie docierają światłowody stosuje się inne technologie. [Sprawdź](/mapa-zasięgu "Sprawdź zasięg naszego Internetu") na interaktywnej mapie, czy internet światłowodowy jest już dostępny pod Twoim adresem.
Jeśli pod Twoim adresem nie ma jeszcze usług światłowodowych, to sprawdź czy dociera tam nasz [internet radiowy](/internet-radiowy "Przejdź do oferty Internetu radiowego").
- title: Router WiFi 5 AC1200 - title: Router WiFi 5 AC1200
image: "E5400.webp" image: "E5400.webp"

View File

@@ -1,5 +1,5 @@
site: site:
name: "FUZ Internet światłowodowy i radiowy w Wyszkowie" name: "FUZ Internet światłowodowy w Wyszkowie"
description: "Stabilny i szybki internet w Wyszkowie i okolicach" description: "Stabilny i szybki internet w Wyszkowie i okolicach"
url: "https://www.fuz.pl" url: "https://www.fuz.pl"
lang: "pl" lang: "pl"
@@ -17,13 +17,13 @@ company:
logo: "/images/logo-fuz.webp" logo: "/images/logo-fuz.webp"
page: page:
title: "FUZ Internet światłowodowy i radiowy w Wyszkowie" title: "FUZ Internet światłowodowy w Wyszkowie"
description: "Szybki, stabilny internet światłowodowy i radiowy w Wyszkowie. Lokalny operator, realny serwis, błyskawiczne wsparcie." description: "Szybki, stabilny internet światłowodowy w Wyszkowie. Lokalny operator, realny serwis, błyskawiczne wsparcie."
image: "/images/og-home.webp" image: "/images/og-home.webp"
url: "/" url: "/"
keywords: keywords:
- internet Wyszków - internet Wyszków
- światłowód Wyszków - światłowód Wyszków
- internet radiowy Wyszków - internet światłowodowy Wyszków
- lokalny operator internetu - lokalny operator internetu
schema: {} schema: {}

View File

@@ -23,5 +23,5 @@ ctas:
- label: "Sprawdź dostępność" - label: "Sprawdź dostępność"
href: "/mapa-zasiegu" href: "/mapa-zasiegu"
title: "Sprawdź zasięg Internetu światłowodowego i radiowego FUZ" title: "Sprawdź zasięg Internetu światłowodowego FUZ"
primary: false primary: false

View File

@@ -35,6 +35,7 @@ funkcje:
- id: "instalacja" - id: "instalacja"
etykieta: "Aktywacja" etykieta: "Aktywacja"
plany_title:
plany: plany:
- id: "pakiet-1" - id: "pakiet-1"
nazwa: "SMART" nazwa: "SMART"
@@ -150,6 +151,13 @@ plany:
umowa_info: "24 / Bezterminowa" umowa_info: "24 / Bezterminowa"
instalacja: "99 zł" instalacja: "99 zł"
uslugi:
title: Usługi dodatkowe
description: Do wybranej opcji możesz dokupić dotakowe usługi.
items:
- Nazwa usługi
- Cena
- Szczegóły
uslugi_dodatkowe: uslugi_dodatkowe:
- id: "public_ip" - id: "public_ip"
nazwa: "Publiczny adres IP" nazwa: "Publiczny adres IP"

View File

@@ -10,7 +10,7 @@ paragraphs:
Jedna umowa, jeden rachunek, jedno miejsce kontaktu. Internet, telewizja i telefon wszystko w jednym miejscu. Jeśli masz pytania lub potrzebujesz pomocy, jesteśmy do Twojej dyspozycji. Jedna umowa, jeden rachunek, jedno miejsce kontaktu. Internet, telewizja i telefon wszystko w jednym miejscu. Jeśli masz pytania lub potrzebujesz pomocy, jesteśmy do Twojej dyspozycji.
Oszczędzaj czas i ciesz się prostotą wszystko, czego potrzebujesz, w jednym miejscu. Oszczędzaj czas i ciesz się prostotą, wszystko czego potrzebujesz, w jednym miejscu.
# Kolejne sekcje mozna dodawać poja wiać się bedą pod tabela produktów # Kolejne sekcje mozna dodawać poja wiać się bedą pod tabela produktów

View File

@@ -1,5 +1,5 @@
site: site:
name: "FUZ Internet światłowodowy i radiowy w Wyszkowie" name: "FUZ Internet światłowodowy w Wyszkowie"
description: "Stabilny i szybki internet" description: "Stabilny i szybki internet"
url: "https://www.fuz.pl" url: "https://www.fuz.pl"
lang: "pl" lang: "pl"

View File

@@ -24,19 +24,6 @@ sections:
Korzystaj z internetu bez limitów i oglądaj swoje ulubione programy w perfekcyjnej jakości — w jednym prostym pakiecie. Korzystaj z internetu bez limitów i oglądaj swoje ulubione programy w perfekcyjnej jakości — w jednym prostym pakiecie.
- title: "Internet Radiowy"
image: "section-radiowy.webp"
dimmed: true
type: default
button:
text: "Zobacz ofertę Internetu Radiowego →"
url: "/internet-radiowy/"
title: "Przejdź do oferty Internetu radiowego"
content: |
Nowoczesna technologia radiowa gwarantuje stabilny internet o wysokiej wydajności tam, gdzie inne łącza nie mają szans.
To szybki start w świat cyfrowej pracy i rozrywki — bez konieczności instalacji kabli.
- title: "Telefon" - title: "Telefon"
image: "section-telefon.webp" image: "section-telefon.webp"
dimmed: true dimmed: true

View File

@@ -7,7 +7,7 @@ subtitle:
- Wszystko, czego potrzebujesz w jednym miejscu - Wszystko, czego potrzebujesz w jednym miejscu
description: | description: |
Dziś dla wielu to niezbędne narzędzie pełne funkcji „bez telefonu jak bez ręki". Dziś dla wielu to niezbędne narzędzie pełne funkcji „bez telefonu jak bez ręki".
imageUrl: "section-telefon.webp" imageUrl: section-telefon.webp
ctas: ctas:
- label: "Zobacz ofertę internetu światłowodowego" - label: "Zobacz ofertę internetu światłowodowego"
href: "/internet-swiatlowodowy" href: "/internet-swiatlowodowy"
@@ -21,5 +21,5 @@ ctas:
- label: "Sprawdź dostępność" - label: "Sprawdź dostępność"
href: "/mapa-zasiegu" href: "/mapa-zasiegu"
title: "Sprawdź zasięg Internetu światłowodowego i radiowego FUZ" title: "Sprawdź zasięg Internetu światłowodowego FUZ"
primary: false primary: false

View File

@@ -8,6 +8,7 @@ funkcje:
- id: "instalacja" - id: "instalacja"
etykieta: "Aktywacja" etykieta: "Aktywacja"
plany_title:
plany: plany:
- id: "tele30" - id: "tele30"
nazwa: "TELE 30" nazwa: "TELE 30"

View File

@@ -1,5 +1,5 @@
site: site:
name: "FUZ Internet światłowodowy i radiowy w Wyszkowie" name: "FUZ Internet światłowodowy w Wyszkowie"
description: "Stabilny i szybki internet" description: "Stabilny i szybki internet"
url: "https://www.fuz.pl" url: "https://www.fuz.pl"
lang: "pl" lang: "pl"

View File

@@ -6,39 +6,41 @@ export default function OffersExtraServices({
extraServices, extraServices,
openId, openId,
toggle, toggle,
services
}) { }) {
if (!extraServices.length) return null; if (!extraServices.length) return null;
return ( return (
<div class="fuz-extra-services"> <div class="f-extra-services">
<h1 class="fuz-title-small">Usługi dodatkowe</h1> <h1 class="f-services-title">{services.title}</h1>
<p class="f-services-body">{services.description}</p>
<div class="fuz-table-wrapper"> <div class="f-table-wrapper">
<table class="fuz-table"> <table class="f-table">
<thead class="fuz-table-head"> <thead class="f-table-head">
<tr> <tr>
<th class="fuz-table-heading">Usługa</th> <th class="f-table-heading">{services.items[0]}</th>
<th class="fuz-table-heading center">Cena</th> <th class="f-table-heading center">{services.items[1]}</th>
<th class="fuz-table-heading center w-32">Więcej</th> <th class="f-table-heading center w-32">{services.items[2]}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{extraServices.map((srv, i) => ( {extraServices.map((srv, i) => (
<> <>
<tr class={i % 2 === 0 ? "fuz-row-even" : "fuz-row-odd"}> <tr class={i % 2 === 0 ? "f-row-even" : "f-row-odd"}>
<td class="fuz-feature-name">{srv.nazwa}</td> <td class="f-feature-name">{srv.nazwa}</td>
<td class="fuz-feature-cell center">{srv.cena}</td> <td class="f-feature-cell center">{srv.cena}</td>
<td class="fuz-feature-cell-btn center"> <td class="f-feature-cell-btn center">
<button class="btn-link" onClick={() => toggle(srv.id)} title={openId === srv.id ? "Zwiń opis usługi" : "Rozwiń opis usługi"}> <button class="f-feature-link" onClick={() => toggle(srv.id)} title={openId === srv.id ? "Zwiń opis usługi" : "Rozwiń opis usługi"}>
{openId === srv.id ? "Zwiń" : "Więcej"} {openId === srv.id ? "Zwiń" : "Przeczytaj ..."}
</button> </button>
</td> </td>
</tr> </tr>
{openId === srv.id && ( {openId === srv.id && (
<tr> <tr>
<td colSpan={3} class="fuz-expand-details"> <td colSpan={3} class="f-expand-details">
<FuzMarkdown text={srv.opis} ctx={{ kanaly: srv.kanaly }} /> <FuzMarkdown text={srv.opis} ctx={{ kanaly: srv.kanaly }} />
</td> </td>
</tr> </tr>

View File

@@ -1,17 +1,17 @@
import "../../styles/offers/offers-switches.css"; // import "../../styles/offers/offers-switches.css";
export default function OffersSwitches({ switches, selected, onSwitch }) { export default function OffersSwitches({ switches, selected, onSwitch }) {
if (!switches.length) return null; if (!switches.length) return null;
return ( return (
<div class="fuz-switches-wrapper"> <div class="f-switches-wrapper">
{switches.map((sw) => ( {switches.map((sw) => (
<div class="fuz-switch-block"> <div class="f-switch-box">
<div class="fuz-switch-group"> <div class="f-switch-group">
{sw.opcje.map((op) => ( {sw.opcje.map((op) => (
<button <button
type="button" type="button"
class={`fuz-switch ${selected[sw.id] === op.id ? "active" : "" class={`f-switch ${selected[sw.id] === op.id ? "active" : ""
}`} }`}
onClick={() => onSwitch(sw.id, op.id)} onClick={() => onSwitch(sw.id, op.id)}
title={sw.title} title={sw.title}

View File

@@ -3,25 +3,24 @@ import { getActiveLabel } from "../../helpers/getActiveLabel";
import "../../styles/offers/offers-table.css"; import "../../styles/offers/offers-table.css";
export default function OffersTable({ switches, selected, plans, features }) { export default function OffersTable({ switches, selected, plans, features, plan_title }) {
return ( return (
<div class="fuz-table-wrapper"> <div class="f-table-wrapper">
<table class="fuz-table"> <table class="f-table">
<thead class="fuz-table-head"> <thead class="f-table-head">
<tr> <tr>
<th class="fuz-table-heading">Parametr</th> <th class="f-table-heading">{plan_title}</th>
{plans.map((plan) => ( {plans.map((plan) => (
<th <th
class={`fuz-plan-heading ${ class={`f-plan-heading ${plan.popularny ? "is-popular f-popular-top" : ""
plan.popularny ? "is-popular fuz-popular-top" : "" }`}
}`}
> >
<div class="fuz-plan-title">{plan.nazwa}</div> {/* {plan.popularny && (<div class="f-popular-badge">Popularny</div>)} */}
<div class="fuz-plan-price"> <div class="f-plan-title">{plan.nazwa}</div>
<div class="f-plan-price">
{getPrice(plan, switches, selected)} {getPrice(plan, switches, selected)}
</div> </div>
<div class="fuz-plan-speed">{plan.predkosc}</div> {/* <div class="f-plan-speed">{plan.predkosc}</div> */}
</th> </th>
))} ))}
</tr> </tr>
@@ -29,8 +28,8 @@ export default function OffersTable({ switches, selected, plans, features }) {
<tbody> <tbody>
{features.map((f, rowIndex) => ( {features.map((f, rowIndex) => (
<tr class={rowIndex % 2 === 0 ? "fuz-row-even" : "fuz-row-odd"}> <tr class={rowIndex % 2 === 0 ? "f-row-even" : "f-row-odd"}>
<td class="fuz-feature-name">{f.etykieta}</td> <td class="f-feature-name">{f.etykieta}</td>
{plans.map((plan) => { {plans.map((plan) => {
const isPopular = plan.popularny; const isPopular = plan.popularny;
@@ -39,13 +38,11 @@ export default function OffersTable({ switches, selected, plans, features }) {
if (f.id === "umowa_info") { if (f.id === "umowa_info") {
return ( return (
<td <td
class={`fuz-feature-cell ${ class={`f-feature-cell ${isPopular
isPopular ? `is-popular ${isLastRow ? "f-popular-bottom" : ""
? `is-popular ${ }`
isLastRow ? "fuz-popular-bottom" : ""
}`
: "" : ""
}`} }`}
> >
{getActiveLabel(switches, selected, "umowa")} {getActiveLabel(switches, selected, "umowa")}
</td> </td>
@@ -56,26 +53,24 @@ export default function OffersTable({ switches, selected, plans, features }) {
const baseClass = const baseClass =
val === true val === true
? "fuz-feature-yes" ? "f-feature-yes"
: val === false || val == null : val === false || val == null
? "fuz-feature-no" ? "f-feature-no"
: "fuz-feature-cell"; : "f-feature-cell";
return ( return (
<td <td
class={`${baseClass} ${ class={`${baseClass} ${isPopular
isPopular ? `is-popular ${isLastRow ? "f-popular-bottom" : ""
? `is-popular ${ }`
isLastRow ? "fuz-popular-bottom" : ""
}`
: "" : ""
}`} }`}
> >
{val === true {val === true
? "✓" ? "✓"
: val === false || val == null : val === false || val == null
? "✕" ? "✕"
: val} : val}
</td> </td>
); );
})} })}

View File

@@ -4,13 +4,15 @@ import FuzMarkdown from "./Markdown.jsx";
import OffersSwitches from "./Offers/OffersSwitches.jsx"; import OffersSwitches from "./Offers/OffersSwitches.jsx";
import OffersTable from "./Offers/OffersTable.jsx"; import OffersTable from "./Offers/OffersTable.jsx";
import OffersExtraServices from "./Offers/OffersExtraServices.jsx"; import OffersExtraServices from "./Offers/OffersExtraServices.jsx";
import "../styles/offers/offers-main.css"; // import "../styles/offers/offers-main.css";
export default function InternetOffersIsland({ data }) { export default function InternetOffersIsland({ data }) {
const switches = data.przelaczniki ?? []; const switches = data.przelaczniki ?? [];
const features = data.funkcje ?? []; const features = data.funkcje ?? [];
const plans = data.plany ?? []; const plans = data.plany ?? [];
const plan_title = data.plany_title ?? "";
const extraServices = data.uslugi_dodatkowe ?? []; const extraServices = data.uslugi_dodatkowe ?? [];
const services = data.uslugi ?? [];
const initialSelected = {}; const initialSelected = {};
switches.forEach((sw) => { switches.forEach((sw) => {
@@ -27,10 +29,10 @@ export default function InternetOffersIsland({ data }) {
setSelected((prev) => ({ ...prev, [switchId]: optionId })); setSelected((prev) => ({ ...prev, [switchId]: optionId }));
return ( return (
<section class="fuz-offers-section"> <section class="f-offers-section">
<div class="fuz-offers-container"> <div class="f-offers-container">
{data.opis_gorny && ( {data.opis_gorny && (
<div class="fuz-offers-description"> <div class="f-offers-description">
<FuzMarkdown text={data.opis_gorny} /> <FuzMarkdown text={data.opis_gorny} />
</div> </div>
)} )}
@@ -46,12 +48,14 @@ export default function InternetOffersIsland({ data }) {
selected={selected} selected={selected}
plans={plans} plans={plans}
features={features} features={features}
plan_title={plan_title}
/> />
<OffersExtraServices <OffersExtraServices
extraServices={extraServices} extraServices={extraServices}
openId={openServiceId} openId={openServiceId}
toggle={toggleService} toggle={toggleService}
services={services}
/> />
{data.opis_dolny && ( {data.opis_dolny && (

View File

@@ -1,54 +0,0 @@
---
import DefaultLayout from "../../layouts/DefaultLayout.astro";
import Hero from "../../components/hero/Hero.astro";
import Markdown from "../../islands/Markdown.jsx";
import OffersIsland from "../../islands/OffersIsland.jsx";
import yaml from "js-yaml";
import fs from "fs";
const seo = yaml.load(
fs.readFileSync("./src/content/internet-radiowy/seo.yaml", "utf8"),
);
const hero = yaml.load(
fs.readFileSync("./src/content/internet-radiowy/hero.yaml", "utf8"),
);
const page = yaml.load(
fs.readFileSync("./src/content/internet-radiowy/page.yaml", "utf8"),
);
type Paragraph = {
title?: string;
content: string;
};
const data = yaml.load(
fs.readFileSync("./src/content/internet-radiowy/offers.yaml", "utf8"),
);
const first = page.paragraphs[0];
const rest = page.paragraphs.slice(1);
---
<DefaultLayout seo={seo}>
<Hero {...hero} />
<section class="fuz-section text-center">
<div class="fuz-section-grid md:grid-cols-1">
{page.title.map((line: any) => <h1 class="fuz-section-title">{line}</h1>)}
{first.title && <h3>{first.title}</h3>}
<Markdown text={first.content} />
</div>
</section>
<OffersIsland client:load data={data} />
{
rest.map((p: Paragraph) => (
<section class="fuz-section text-center">
<div class="fuz-section-grid md:grid-cols-1">
{p.title && <h3 class="fuz-section-title">{p.title}</h3>}
<Markdown text={p.content.replace(/\n/g, "\n\n")} />
</div>
</section>
))
}
</DefaultLayout>

View File

@@ -33,9 +33,9 @@ const rest = page.paragraphs.slice(1);
<DefaultLayout seo={seo}> <DefaultLayout seo={seo}>
<Hero {...hero} /> <Hero {...hero} />
<section class="fuz-section text-center"> <section class="f-section">
<div class="fuz-section-grid md:grid-cols-1"> <div class="f-section-grid-single md:grid-cols-1">
{page.title.map((line: any) => <h1 class="fuz-section-title">{line}</h1>)} {page.title.map((line: any) => <h1 class="f-section-title">{line}</h1>)}
{first.title && <h3>{first.title}</h3>} {first.title && <h3>{first.title}</h3>}
<Markdown text={first.content} /> <Markdown text={first.content} />
</div> </div>
@@ -44,21 +44,14 @@ const rest = page.paragraphs.slice(1);
<OffersIsland client:load data={data} /> <OffersIsland client:load data={data} />
{rest.map((p: Paragraph) => ( {rest.map((p: Paragraph) => (
<section class="fuz-section text-center"> <section class="f-section">
<div class="fuz-section-grid md:grid-cols-1"> <div class="f-section-grid-single md:grid-cols-1">
{p.title && <h3 class="fuz-section-title">{p.title}</h3>} {p.title && <h3 class="f-section-title">{p.title}</h3>}
<Markdown text={p.content.replace(/\n/g, "\n\n")} /> <Markdown text={p.content.replace(/\n/g, "\n\n")} />
</div> </div>
</section> </section>
))} ))}
<SectionRenderer src="./src/content/internet-swiatlowodowy/section.yaml" /> <SectionRenderer src="./src/content/internet-swiatlowodowy/section.yaml" />
<!-- <section class="fuz-section">
<div class="fuz-container">
<h1 class="fuz-hero-title">Internet FUZ</h1>
<p class="mt-4 text-gray-600 dark:text-gray-300">
Ta podstrona jest na razie szkieletem. Możemy tu później wczytać treść z YAML.
</p>
</div>
</section> -->
</DefaultLayout> </DefaultLayout>

View File

@@ -37,9 +37,9 @@ const rest = page.paragraphs.slice(1);
<DefaultLayout seo={seo}> <DefaultLayout seo={seo}>
<Hero {...hero} /> <Hero {...hero} />
<section class="fuz-section text-center"> <section class="f-section">
<div class="fuz-section-grid md:grid-cols-1"> <div class="f-section-grid-single md:grid-cols-1">
{page.title.map((line: any) => <h1 class="fuz-section-title">{line}</h1>)} {page.title.map((line: any) => <h1 class="f-section-title">{line}</h1>)}
{first.title && <h3>{first.title}</h3>} {first.title && <h3>{first.title}</h3>}
<Markdown text={first.content} /> <Markdown text={first.content} />
</div> </div>
@@ -48,9 +48,9 @@ const rest = page.paragraphs.slice(1);
<OffersIsland client:load data={data} /> <OffersIsland client:load data={data} />
{ {
rest.map((p: Paragraph) => ( rest.map((p: Paragraph) => (
<section class="fuz-section text-center"> <section class="f-section">
<div class="fuz-section-grid md:grid-cols-1"> <div class="f-section-grid-single md:grid-cols-1">
{p.title && <h3 class="fuz-section-title">{p.title}</h3>} {p.title && <h3 class="f-section-title">{p.title}</h3>}
<Markdown text={p.content.replace(/\n/g, "\n\n")} /> <Markdown text={p.content.replace(/\n/g, "\n\n")} />
</div> </div>
</section> </section>

View File

@@ -10,9 +10,9 @@ const privacy = yaml.load(
--- ---
<DefaultLayout title={privacy.title}> <DefaultLayout title={privacy.title}>
<section class="fuz-section"> <section class="f-section">
<div class="fuz-section-grid"> <div class="f-section-grid-single">
<h1 class="text-3xl font-bold"> <h1 class="f-section-title">
{privacy.title} {privacy.title}
</h1> </h1>
<Markdown text={privacy.content} /> <Markdown text={privacy.content} />

View File

@@ -33,9 +33,9 @@ const rest = page.paragraphs.slice(1);
<DefaultLayout seo={seo}> <DefaultLayout seo={seo}>
<Hero {...hero} /> <Hero {...hero} />
<section class="fuz-section text-center"> <section class="f-section">
<div class="fuz-section-grid md:grid-cols-1"> <div class="f-section-grid-single md:grid-cols-1">
{page.title.map((line: any) => <h1 class="fuz-section-title">{line}</h1>)} {page.title.map((line: any) => <h1 class="f-section-title">{line}</h1>)}
{first.title && <h3>{first.title}</h3>} {first.title && <h3>{first.title}</h3>}
<Markdown text={first.content} /> <Markdown text={first.content} />
</div> </div>
@@ -44,9 +44,9 @@ const rest = page.paragraphs.slice(1);
<OffersIsland client:load data={data} /> <OffersIsland client:load data={data} />
{ {
rest.map((p: Paragraph) => ( rest.map((p: Paragraph) => (
<section class="fuz-section text-center"> <section class="f-section">
<div class="fuz-section-grid md:grid-cols-1"> <div class="f-section-grid-single md:grid-cols-1">
{p.title && <h3 class="fuz-section-title">{p.title}</h3>} {p.title && <h3 class="f-section-title">{p.title}</h3>}
<Markdown text={p.content.replace(/\n/g, "\n\n")} /> <Markdown text={p.content.replace(/\n/g, "\n\n")} />
</div> </div>
</section> </section>

View File

@@ -1,3 +1,7 @@
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;500;600;700&display=swap');
/* @import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap'); */
/* @import url('https://fonts.googleapis.com/css2?family=Lora:ital,wght@0,400..700;1,400..700&display=swap'); */
@import "./tailwind.css"; @import "./tailwind.css";
@import "./theme.css"; @import "./theme.css";
@import "./navbar.css"; @import "./navbar.css";
@@ -8,6 +12,21 @@
@import "./footer.css"; @import "./footer.css";
@import "./cookie.css"; @import "./cookie.css";
@import "./contact.css"; @import "./contact.css";
@import "./offers/offers-main.css";
@import "./offers/offers-switches.css";
html {
font-family: 'Nunito', sans-serif;
/* font-family: "Lora", sans-serif; */
font-optical-sizing: auto;
font-weight: 500;
scroll-behavior: smooth;
}
body {
/* @apply bg-white text-gray-900 dark:bg-slate-900 dark:text-gray-100 antialiased; */
}
.grecaptcha-badge { .grecaptcha-badge {
display: none !important; display: none !important;

View File

@@ -1,6 +1,6 @@
@layer components { @layer components {
.f-footer { .f-footer {
@apply mt-0 border-t border-[var(--fuz-border)] bg-[var(--f-background)] text-[var(--f-text)] pt-2; @apply mt-2 border-t border-[var(--f-input-border)] bg-[var(--f-background-o)] text-[var(--f-text)] pt-2;
} }
.f-footer-inner { .f-footer-inner {

View File

@@ -8,7 +8,7 @@
} }
.f-hero-bg { .f-hero-bg {
@apply absolute top-0 left-0 w-full h-full object-cover opacity-[0.7]; @apply absolute top-0 left-0 w-full h-full object-cover opacity-[0.4];
} }
.f-hero-inner { .f-hero-inner {

View File

@@ -41,8 +41,7 @@
} }
.fuz-markdown a { .fuz-markdown a {
@apply no-underline hover:no-underline; @apply no-underline hover:no-underline text-[var(--f-link-text)];
color: var(--fuz-accent);
} }
.fuz-markdown button.modal-link { .fuz-markdown button.modal-link {

View File

@@ -31,3 +31,7 @@
@apply text-lg py-2 border-b text-[var(--f-text)] hover:text-[var(--fuz-accent)]; @apply text-lg py-2 border-b text-[var(--f-text)] hover:text-[var(--fuz-accent)];
border-color: var(--f-border-color); border-color: var(--f-border-color);
} }
.f-navbar-logo{
@apply w-[70] h-[36];
}

View File

@@ -1,27 +1,22 @@
.fuz-extra-services { .f-extra-services {
@apply mt-16; @apply mt-6 max-w-6xl mx-auto;
color: var(--f-text);
} }
.fuz-title-small { .f-services-title {
@apply text-xl font-semibold mb-4; @apply text-2xl font-semibold mb-4 ml-10;
color: var(--f-text); }
.f-services-body {
@apply text-lg font-semibold mb-4 ml-10;
} }
.fuz-expand-details { .f-expand-details {
@apply px-4 py-4; @apply px-4 py-4;
background: rgba(0, 0, 0, 0.04);
} }
:root.dark .fuz-expand-details { .f-feature-link {
background: rgba(255, 255, 255, 0.04); @apply underline cursor-pointer w-full h-full text-[var(--f-link-text)];
} }
.btn-link { .f-feature-link:hover {
@apply underline cursor-pointer; @apply text-[var(--f-link-text-hover)];
color: var(--fuz-accent);
}
.btn-link:hover {
opacity: 0.7;
} }

View File

@@ -1,14 +1,11 @@
.fuz-offers-section { .fuz-offers-section {
@apply py-12; @apply py-6;
background: var(--f-background);
color: var(--f-text);
} }
.fuz-offers-container { .f-offers-container {
@apply max-w-7xl mx-auto px-6; @apply max-w-7xl mx-auto px-6;
} }
.fuz-offers-description { .f-offers-description {
@apply mb-10 text-base leading-relaxed; @apply mb-10 text-base leading-relaxed;
color: var(--f-text);
} }

View File

@@ -1,31 +1,19 @@
.fuz-switches-wrapper { .f-switches-wrapper {
@apply flex flex-wrap justify-center gap-6 mb-12; @apply flex flex-wrap justify-center gap-6 mb-12;
} }
.fuz-switch-group { .f-switch-group {
@apply inline-flex overflow-hidden relative; @apply inline-flex overflow-hidden relative bg-[var(--f-background-switch)];
background: rgba(0, 0, 0, 0.08);
} }
:root.dark .fuz-switch-group { .f-switch {
background: rgba(255, 255, 255, 0.12);
}
.fuz-switch {
@apply px-6 py-2 text-sm font-semibold cursor-pointer select-none transition-all; @apply px-6 py-2 text-sm font-semibold cursor-pointer select-none transition-all;
color: var(--f-text);
/* opacity: 0.7; */
} }
.fuz-switch:hover { .f-switch.active {
/* opacity: 0.9; */ @apply text-[var(--f-text-switcher)] bg-[var(--f-background-switcher)] ;
} }
.fuz-switch.active { .f-switch:hover {
background: var(--fuz-accent); @apply opacity-[0.6]
color: var(--btn-text);
/* opacity: 1; */
/* box-shadow: 0 2px 8px rgba(0,0,0,0.18); */
} }

View File

@@ -1,212 +1,96 @@
/* ========================================= .f-table-wrapper {
TABELA — KONTENER @apply overflow-x-auto rounded-3xl shadow-lg mb-0 border border-[var(--f-offers-border)];
========================================= */
.fuz-table-wrapper {
@apply overflow-x-auto rounded-3xl shadow-lg mb-0;
background: var(--f-background);
border: 1px solid rgba(0,0,0,0.07);
} }
:root.dark .fuz-table-wrapper { .f-table {
border: 1px solid rgba(255,255,255,0.12);
}
.fuz-table {
@apply min-w-full border-collapse; @apply min-w-full border-collapse;
color: var(--f-text);
} }
.f-table-head {
/* =========================================
NAGŁÓWEK
========================================= */
.fuz-table-head {
background: color-mix(in srgb, var(--f-text) 6%, transparent); background: color-mix(in srgb, var(--f-text) 6%, transparent);
} }
:root.dark .fuz-table-head { .f-table-heading {
background: color-mix(in srgb, var(--f-text) 12%, transparent); @apply text-center font-semibold text-xl py-4 px-4 text-wrap;
} }
.fuz-table-heading { .f-plan-heading {
@apply text-center font-semibold py-4 px-4 text-lg; @apply text-center py-4 px-4 align-bottom relative;
color: var(--f-text);
} }
.f-plan-title {
@apply text-xl font-semibold mb-1;
/* =========================================
NAGŁÓWEK PLANU
========================================= */
.fuz-plan-heading {
@apply text-center py-4 px-4 align-bottom;
position: relative;
} }
.fuz-plan-title { .f-plan-price {
@apply text-lg font-semibold mb-1; @apply text-2xl font-extrabold mb-1 text-[var(--f-offers-price)];
color: var(--f-text);
} }
.fuz-plan-price { /* Na ten moment ukryte */
@apply text-2xl font-extrabold mb-1; .f-plan-speed {
color: var(--fuz-accent); @apply text-xs opacity-[0.7];
} }
.fuz-plan-speed { .f-row-even {
@apply text-xs;
opacity: 0.7;
}
/* Badge popularności jeśli używasz */
.fuz-plan-badge {
@apply text-[10px] px-2 py-0.5 rounded-full uppercase tracking-wide inline-block mb-2;
background: var(--fuz-accent);
color: var(--fuz-accent-text);
}
/* =========================================
WIERSZE
========================================= */
.fuz-row-even {
background: color-mix(in srgb, var(--f-text) 4%, transparent);
}
:root.dark .fuz-row-even {
background: color-mix(in srgb, var(--f-text) 10%, transparent);
}
.fuz-row-odd {
background: transparent; background: transparent;
} }
.fuz-feature-name { .f-row-odd {
@apply py-3 px-4 text-lg font-medium; background: color-mix(in srgb, var(--f-text) 4%, transparent);
color: var(--f-text);
border-top: 1px solid rgba(0,0,0,0.07);
} }
:root.dark .fuz-feature-name { .f-feature-name {
border-top: 1px solid rgba(255,255,255,0.12); @apply py-3 px-4 text-lg font-medium ;
} }
.fuz-feature-cell { .f-feature-cell {
@apply py-3 px-4 text-center text-lg; @apply py-3 px-4 text-center text-lg;
color: var(--f-text);
border-top: 1px solid rgba(0,0,0,0.07);
} }
:root.dark .fuz-feature-cell { .f-feature-yes {
border-top: 1px solid rgba(255,255,255,0.12);
}
.fuz-feature-cell-btn {
@apply py-3 px-4 text-center text-sm;
}
/* =========================================
CHECKMARKS
========================================= */
/* ✔ = kolor accent */
.fuz-feature-yes {
@apply py-3 px-4 text-center font-bold text-base; @apply py-3 px-4 text-center font-bold text-base;
color: var(--fuz-accent);
border-top: 1px solid rgba(0,0,0,0.07);
} }
:root.dark .fuz-feature-yes { .f-feature-no {
border-top: 1px solid rgba(255,255,255,0.12); @apply py-3 px-4 text-center font-bold text-base opacity-[0.45];
} }
/* ✕ = szary / low opacity */ /* Popularny */
.fuz-feature-no {
@apply py-3 px-4 text-center font-bold text-base;
opacity: 0.45;
border-top: 1px solid rgba(0,0,0,0.07);
}
:root.dark .fuz-feature-no {
border-top: 1px solid rgba(255,255,255,0.12);
}
/* =========================================
POPULARNY PLAN — WARIANT C (MOCNY)
========================================= */
/* pełne tło pastel na ACCENT (mocniejsze C) */
.is-popular, .is-popular,
.fuz-popular-col { .f-popular-col {
background: color-mix(in srgb, var(--fuz-accent) 22%, transparent) !important; background: var(--f-offers-popular-bg);
border-left: 2px solid var(--fuz-accent); /* color-mix(in srgb, var(--f-offers-popular) 22%, transparent) !important; */
border-right: 2px solid var(--fuz-accent); border-left: 2px solid var(--f-offers-popular);
border-right: 2px solid var(--f-offers-popular);
position: relative; position: relative;
z-index: 10; z-index: 10;
} }
:root.dark .is-popular, .f-popular-top {
:root.dark .fuz-popular-col { border-top: 2px solid var(--f-offers-popular);
background: color-mix(in srgb, var(--fuz-accent) 32%, transparent) !important;
} }
/* górny border */ .f-popular-bottom {
.fuz-popular-top { border-bottom: 2px solid var(--f-offers-popular);
border-top: 2px solid var(--fuz-accent);
} }
/* dolny border */ /* .f-popular-col.f-feature-cell,
.fuz-popular-bottom { .f-popular-col.f-feature-yes,
border-bottom: 2px solid var(--fuz-accent); .f-popular-col.f-feature-no {
}
/* zbijamy border wewnątrz popularnych */
.fuz-popular-col.fuz-feature-cell,
.fuz-popular-col.fuz-feature-yes,
.fuz-popular-col.fuz-feature-no {
border-top: none !important; border-top: none !important;
} } */
/* USŁUGI DODATKOWE */
/* Górny border pierwszego wiersza sekcji */
.fuz-extra-services table tbody tr:first-child td {
border-top: 1px solid rgba(0,0,0,0.07);
}
:root.dark .fuz-extra-services table tbody tr:first-child td {
border-top: 1px solid rgba(255,255,255,0.15);
}
/* Wiersz "Szczegóły" (opis) — zawsze pełny border-top */ .f-popular-badge {
.fuz-expand-details { @apply bg-blue-500 text-white text-xs font-semibold px-3 py-1 rounded-full inline-block mb-2 uppercase tracking-wide;
border-top: 0px solid rgba(0,0,0,0.1); /* background: #3b82f6;
} color: white;
:root.dark .fuz-expand-details { font-size: 0.75rem;
border-top: 1px solid rgba(255,255,255,0.15); font-weight: 600;
} padding: 0.25rem 0.75rem;
border-radius: 9999px;
/* I zawsze ładny border-bottom na końcu sekcji */ display: inline-block;
.fuz-extra-services table tbody tr:last-child td { margin-bottom: 0.5rem;
border-bottom: 1px solid rgba(0,0,0,0.1); text-transform: uppercase;
} letter-spacing: 0.025em; */
:root.dark .fuz-extra-services table tbody tr:last-child td {
border-bottom: 1px solid rgba(255,255,255,0.15);
}
/* Usunięcie "pustych" borderów kolumny szczegóły */
.fuz-feature-cell-btn {
border-top: 1px solid rgba(0,0,0,0.07);
}
:root.dark .fuz-feature-cell-btn {
border-top: 1px solid rgba(255,255,255,0.12);
} }

View File

@@ -1,42 +1,50 @@
@layer components{ @layer components {
.f-section-header{ .f-section-header {
@apply text-3xl md:text-4xl font-bold mb-6 text-[var(--f-header)]; @apply text-3xl md:text-4xl font-bold mb-6 text-[var(--f-header)];
} }
}
.f-section{ .f-section {
@apply pt-10 pb-1 mx-2; @apply pt-10 pb-1 mx-2;
} }
.fuz-section {
@apply py-10 mx-2;
}
.fuz-section-grid { .f-section-center {
@apply grid items-center gap-5 max-w-7xl mx-auto; @apply f-section text-center;
} }
.fuz-section-image { .f-section-grid {
/* @apply w-full h-5/6 object-cover ; */ @apply grid items-center gap-5 max-w-7xl mx-auto;
@apply w-full object-contain; }
}
.fuz-image-dimmed { .f-section-grid-single {
opacity: 0.75; @apply grid items-center gap-5 max-w-6xl mx-auto;
} }
.fuz-section-title { .f-section-grid-single-center {
@apply text-4xl md:text-5xl font-bold mb-6; @apply f-section-grid-single text-center;
} }
.f-section-image {
@apply w-full object-contain;
}
.f-image-dimmed {
@apply opacity-[1];
}
.f-section-title {
@apply text-4xl md:text-5xl font-bold mb-2 text-[var(--f-header)];
}
.f-section-nav {
@apply mt-0 flex justify-center;
}
.fuz-section-text {
@apply max-w-4xl mx-auto;
} }
.fuz-iframe-box { .fuz-iframe-box {
@apply bg-white dark:bg-slate-800 p-4 rounded-xl @apply bg-white dark:bg-slate-800 p-4 rounded-xl border border-gray-200 dark:border-slate-700 shadow;
border border-gray-200 dark:border-slate-700 shadow;
} }
.fuz-iframe-wrapper { .fuz-iframe-wrapper {

View File

@@ -1,11 +1,3 @@
@tailwind base; @tailwind base;
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
html {
scroll-behavior: smooth;
}
body {
@apply bg-white text-gray-900 dark:bg-slate-900 dark:text-gray-100 antialiased;
}

View File

@@ -27,22 +27,34 @@
--surface-shadow-dark: var(--brand-hue) 50% 3%; --surface-shadow-dark: var(--brand-hue) 50% 3%;
--shadow-strength-dark: .8; --shadow-strength-dark: .8;
--border1-dark: hsl(var(--brand-hue) 40% 70%); --border1-dark: hsl(var(--brand-hue) 40% 70%);
--brand-dim: hsl(var(--brand-hue) calc(var(--brand-saturation) / 1.25) calc(var(--brand-lightness) / 1.25));
} }
:root { :root {
--f-background: var(--surface2-light); --f-background: var(--surface2-light);
--f-header: var(--brand-light); --f-background-switch: var(--surface3-light);
--f-text-switcher: var(--brand-dark);
--f-background-switcher: var(--surface4-dark);
--f-header: var(--text1-light);
--f-header-2: var(--text1-light); --f-header-2: var(--text1-light);
--f-header-items: (var(--text2-light)); --f-header-items: (var(--text2-light));
--f-text: var(--text2-light); --f-text: var(--text2-light);
--f-link-text: var(--f-header); --f-text-1: var(--text1-light);
--f-link-text: var(--brand-dim);
/* var(--brand-light); */
--f-link-text-hover: var(--f-text2-light); --f-link-text-hover: var(--f-text2-light);
--btn-background: var(--surface2-light); --btn-background: var(--surface2-light);
--btn-text: var(--text1-light); --btn-text: var(--text1-light);
--f-background-o: var(--surface4-light);
--btn-outline-background: transparent; --btn-outline-background: transparent;
--btn-outline-border: var(--border1-light); --btn-outline-border: var(--border1-light);
--btn-outline-text: var(--text1-light); --btn-outline-text: var(--text1-light);
@@ -52,39 +64,49 @@
--f-input-border: var(--surface1-light); --f-input-border: var(--surface1-light);
--f-offers-border: var(--surface4-light);
--f-offers-price: var(--brand-light);
--f-offers-popular: var(--brand-light);
--f-offers-popular-bg: color-mix(in srgb, var(--f-offers-popular) 22%, transparent);
/* Invert Color */ /* Invert Color */
--f-background-invert: #0d1117; /* --f-background-invert: #0d1117;
--f-text-invert: #e6edf3; --f-text-invert: #e6edf3;
--btn-bg-invert: #58a6ff; --btn-bg-invert: #58a6ff;
--btn-text-invert: #0d1117; --btn-text-invert: #0d1117;
--btn-outline-invert: #58a6ff; --btn-outline-invert: #58a6ff;
--btn-outline-bg-invert: rgba(88, 166, 255, 0.15); --btn-outline-bg-invert: rgba(88, 166, 255, 0.15); */
/* Links */ /* Links */
--fuz-link: #0050c8; /* --fuz-link: #0050c8;
--fuz-link-hover: #003f9a; --fuz-link-hover: #003f9a; */
/* Accent (buttons, highlights) */ /* Accent (buttons, highlights) */
--fuz-accent: #0066ff; /* --fuz-accent: #0066ff;
--fuz-accent-hover: #004bcc; --fuz-accent-hover: #004bcc;
--fuz-accent-text: #ffffff; --fuz-accent-text: #ffffff;
--btn-ghost-text: var(--f-text); --btn-ghost-text: var(--f-text);
--btn-ghost-hover-bg: rgba(0, 0, 0, 0.05); --btn-ghost-hover-bg: rgba(0, 0, 0, 0.05);
---f-border-color: rgb(209 213 219); ---f-border-color: rgb(209 213 219); */
/* / var(--tw-border-opacity, 1)); */ /* / var(--tw-border-opacity, 1)); */
} }
:root.dark { :root.dark {
--f-background: var(--surface1-dark); --f-background: var(--surface1-dark);
--f-background-switch: var(--surface2-dark);
--f-header: var(--brand-dark); --f-background-switch: var(--surface3-dark);
--f-text-switcher: var(--brand-dark);
--f-background-switcher: var(--text2-light);
--f-header: var(--text1-dark);
--f-header-2: var(--text1-dark); --f-header-2: var(--text1-dark);
--f-header-items: (var(--text2-dark)); --f-header-items: (var(--text2-dark));
--f-text: var(--text1-dark); --f-text: var(--text1-dark);
--f-link-text: var(--f-header); --f-text-1: var(--text1-dark);
--f-link-text: var(--brand-dark);
--f-link-text-hover: var(--f-text2-dark); --f-link-text-hover: var(--f-text2-dark);
--btn-background: var(--surface4-dark); --btn-background: var(--surface4-dark);
@@ -97,7 +119,16 @@
--btn-outline-background-hover: var(--surface4-dark); --btn-outline-background-hover: var(--surface4-dark);
--btn-outline-text-hover: var(--brand-dark); --btn-outline-text-hover: var(--brand-dark);
--f-input-border: var(--surface4-dark); --f-background-o: var(--surface2-dark);
--f-input-border: var(--surface4-dark);
--f-offers-border: var(--surface4-dark);
--f-offers-price: var(--brand-dark);
--f-offers-popular: var(--brand-dark);
--f-offers-popular-bg: color-mix(in srgb, var(--f-offers-popular) 22%, transparent);
/* Invert Color */ /* Invert Color */
--f-background-invert: #ffffff; --f-background-invert: #ffffff;