diff --git a/messages/pl.json b/messages/pl.json index 721a0be..a6a89d1 100644 --- a/messages/pl.json +++ b/messages/pl.json @@ -1,30 +1,97 @@ { "metadata": { + "defaultTitle": "Konfiguratory 3D | Ultifide", + "defaultDescription": "Konfiguratory 3D dla produktów, wnętrz i sprzedaży B2B.", "homeTitle": "Konfiguratory 3D dla e-commerce i B2B | Ultifide", "homeDescription": "Landing Ultifide dla konfiguratorów 3D: produktowych, wnętrzarskich i modułowych. Zobacz dema i sprawdź, jak możemy wdrożyć konfigurator w Twoim sklepie.", + "demosPageTitle": "Dema konfiguratorów 3D | Ultifide", + "demosPageDescription": "Lista interaktywnych dem konfiguratorów 3D Ultifide z podglądem biurka, wnętrz i drzwi.", "deskTitle": "Konfigurator 3D biurka | Ultifide", + "deskDescription": "Poznaj konfigurator 3D, który zwiększa konwersję i pozwala klientom tworzyć własne biurka regulowane w czasie rzeczywistym.", "roomTitle": "Konfigurator 3D wnętrz | Ultifide", - "doorTitle": "Konfigurator 3D drzwi | Ultifide" + "roomDescription": "Poznaj konfigurator 3D, który pozwala klientom projektować całe pomieszczenia i zestawy mebli w czasie rzeczywistym.", + "doorTitle": "Konfigurator 3D drzwi | Ultifide", + "doorDescription": "Poznaj konfigurator 3D drzwi, który pozwala klientom dobrać model, kolor, przeszklenie, klamkę i detale w czasie rzeczywistym." }, "navigation": { + "dema": "Dema", "platform": "Platforma", "demos": "Demo", "features": "Funkcje", "faq": "FAQ", "contact": "Kontakt", - "menu": "Menu" + "menu": "Menu", + "mainNav": "Nawigacja główna", + "mobileNav": "Nawigacja mobilna", + "openMenu": "Otwórz menu", + "closeMenu": "Zamknij menu", + "logoAriaLabel": "Ultifide konfiguratory 3D" }, "common": { "seeDemo": "Zobacz demo", + "seeMore": "Zobacz więcej", "openDemo": "Otwórz demo", "contactUs": "Porozmawiajmy", "learnMore": "Dowiedz się więcej", "preview": "Podgląd konfiguratora", - "fullscreen": "Pełny ekran" + "fullscreen": "Pełny ekran", + "openInNewTab": "Otwórz demo w nowej karcie", + "close": "Zamknij", + "backToList": "< Wróć do listy" }, + "contact": { + "eyebrow": "Kontakt", + "title": "Porozmawiajmy!", + "description": "Opisz katalog produktów, zakres wariantów albo pierwszy pomysł na demo. Wrócimy z konkretną ścieżką wdrożenia.", + "schedulerTitle": "Umów rozmowę z Ultifide", + "schedulerFallback": "Umów rozmowę online w kalendarzu", + "schedulerUrl": "https://42min.us/kubapyla", + "email": "contact@ultifide.com", + "phones": ["+48 733 226 544", "+48 664 565 858"], + "address": ["Kraków, Polska", "ul. św. Wawrzyńca 19/2", "31-060 Kraków"] + }, + "footer": { + "copyright": "Copyright © 2026, Ultifide" + }, + "notFound": { + "title": "Nie znaleziono strony", + "backHome": "Wróć do strony głównej" + }, + "demosPage": { + "title": "Nasze konfiguratory 3D", + "description": "Wybierz demo z listy, przetestuj je od razu w podglądzie, lub przejdź do podstrony z opisem zastosowania.", + "selectDemo": "Wybierz demo", + "demoListAriaLabel": "Lista dem" + }, + "demoSubnav": { + "ariaLabel": "Dema konfiguratorów", + "labels": { + "demo-pokoj": "Wnętrza", + "demo-drzwi": "Drzwi", + "demo-biurko": "Biurko" + } + }, + "heroVisual": { + "configuration": "Konfiguracja", + "premiumMaterial": "Materiał premium", + "productRules": "Reguły produktu" + }, + "marketingFaq": [ + {"question": "Czy możemy zacząć od jednego produktu?", "answer": "Tak. V1 może obejmować jeden produkt, jedną kolekcję albo jedno demo, a potem rosnąć o kolejne warianty, reguły i integracje."}, + {"question": "Czy konfigurator może być częścią mojego sklepu?", "answer": "Tak. Może działać jako widżet, dedykowana podstrona, kreator zestawów, moduł koszyka albo element panelu B2B."}, + {"question": "Jak wygląda integracja ze sprzedażą, CRM lub ERP?", "answer": "Konfiguracja może trafiać do koszyka, formularza zapytania, CRM, ERP albo panelu B2B. Integrujemy przez API, webhooki i popularne platformy e-commerce."}, + {"question": "Czy mogę dodać własne modele 3D, materiały i warianty?", "answer": "Tak. Możemy pracować na dostarczonych modelach albo przygotować i zoptymalizować je pod konfigurator, a potem rozwijać katalog o nowe kolory, materiały, dodatki i akcesoria."}, + {"question": "Czy konfigurator obsługuje zależności i reguły produktu?", "answer": "Tak. Obsługujemy warunki, ograniczenia, wariantowe SKU, zgodność modułów i zależności między modelem, rozmiarem, kolorem, okuciami, dodatkami lub dostępnością."}, + {"question": "Czy konfigurator działa na urządzeniach mobilnych?", "answer": "Tak. Interfejs jest responsywny, a w wybranych wdrożeniach można dodać tryb AR."}, + {"question": "Czy wygląd konfiguratora można dopasować do mojej marki?", "answer": "Tak. UI, kolory, branding, układ opcji, sposób interakcji, modele 3D i środowisko sceny mogą wyglądać jak natywna część Twojego sklepu."}, + {"question": "Czy konfigurator sprawdzi się dla mebli modułowych i całych kolekcji?", "answer": "Tak. System można rozwijać o meble modułowe, zestawy, kolekcje aranżacyjne, nowe produkty i kolejne układy pomieszczeń bez przebudowy całości."}, + {"question": "Czy można odwzorować całe pomieszczenia?", "answer": "Tak. Możemy stworzyć pełne sceny 3D od pustego pokoju po gotowe aranżacje z konfigurowalnymi meblami, kolorami i materiałami."}, + {"question": "Czy klient może zmieniać układ mebli i elementów?", "answer": "Tak. Konfigurator może pozwalać na ustawianie elementów, zmianę układu, dobór dodatków i dopasowanie konfiguracji do przestrzeni."}, + {"question": "Jakie są główne korzyści z wdrożenia konfiguratora 3D?", "answer": "Konfigurator pozwala prezentować produkty w jakości premium, personalizować je w czasie rzeczywistym, ograniczać liczbę zwrotów i pytań oraz skracać proces decyzji zakupowej."}, + {"question": "Czy konfigurator nadaje się do produktów takich jak drzwi, fronty lub zabudowy?", "answer": "Tak. Sprawdza się przy produktach wymagających precyzyjnego dopasowania wariantów, takich jak drzwi, fronty, zabudowy, oświetlenie, wyposażenie i inne produkty custom."} + ], "home": { "hero": { - "eyebrow": "Konfiguratory produktów i przestrzeni", "title": "Konfiguratory 3D dla sprzedaży produktów i wnętrz", "description": "Projektujemy i wdrażamy interaktywne konfiguratory 3D, które pozwalają klientom zobaczyć wariant produktu, zbudować zestaw i szybciej podjąć decyzję zakupową.", "primaryCta": "Zobacz dema", @@ -35,8 +102,8 @@ {"value": "35%", "label": "mniej pytań o warianty i specyfikację"}, {"value": "3x", "label": "szybsze podejmowanie decyzji zakupowej"} ], - "demosTitle": "Aktualne dema konfiguratorów", - "demosDescription": "Trzy gotowe kierunki, które można rozbudować o Twoje produkty, reguły biznesowe i integracje z systemem sprzedaży.", + "demosTitle": "Dema konfiguratorów", + "demosDescription": "Gotowe kierunki, które można rozbudować o Twoje produkty, reguły biznesowe i integracje z systemem sprzedaży.", "benefitsTitle": "Platforma przygotowana pod realną sprzedaż", "benefitsDescription": "Nie chodzi o efektowny model 3D na stronie. Konfigurator ma skrócić proces decyzji, zmniejszyć liczbę niejasności i dostarczyć kompletne dane do koszyka, CRM lub ERP.", "benefits": [ @@ -51,7 +118,7 @@ {"title": "Wnętrza i kolekcje", "description": "Pokoje, zestawy mebli, systemy modułowe i gotowe aranżacje."}, {"title": "Produkty custom", "description": "Drzwi, oświetlenie, wyposażenie i inne produkty wymagające dopasowania."} ], - "featuresTitle": "Funkcje, które zwykle są potrzebne w konfiguratorze", + "featuresTitle": "Funkcje niezbędne w konfiguratorze idealnym!", "features": [ "Realistyczne materiały i oświetlenie sceny", "Widok 360 stopni, zoom i praca na detalach", @@ -60,7 +127,8 @@ "Integracje API, webhooki i eksport danych", "Motyw graficzny dopasowany do marki" ], - "processTitle": "Jak pracujemy", + "faqTitle": "FAQ - często zadawane pytania", + "processTitle": "Jak pracujemy?", "process": [ {"title": "Analiza katalogu", "description": "Porządkujemy warianty, zależności, dane produktowe i zakres konfiguracji."}, {"title": "Model 3D i UX", "description": "Przygotowujemy modele, materiały oraz interfejs dobrany do sposobu zakupu."}, @@ -80,11 +148,11 @@ "demos": { "desk": { "slug": "demo-biurko", - "eyebrow": "Demo produktowe", + "eyebrow": "", "title": "Konfigurator - Biurko", "intro": "Pozwalaj klientom tworzyć własne biurka regulowane w czasie rzeczywistym.", "description": "Klient może zobaczyć swoje biurko w naturalnym oświetleniu, obrócić je o 360 stopni, powiększyć detale, zmienić dodatki i sprawdzić jak całość będzie wyglądała w jego przestrzeni.", - "imageUrl": "https://backend.ultifide.com/uploads/offer/page-header-element/optimized/b64b9dddfb838bfafea9da0ee5c04c68.png?width=1000&height=1000", + "imageUrl": "/demo-desk-preview.png", "openLabel": "Otwórz konfigurator biurka", "benefitsIntro": "Rozwiązanie dla producentów i sklepów, które sprzedają produkty z wieloma wariantami, dodatkami i zależnościami.", "stats": [ @@ -118,11 +186,11 @@ }, "room": { "slug": "demo-pokoj", - "eyebrow": "Demo wnętrzarskie", - "title": "Konfigurator - Wnętrze", + "eyebrow": "", + "title": "Konfigurator - Wnętrza", "intro": "Twórz i prezentuj kompletne aranżacje pomieszczeń oraz meble w interaktywnym środowisku 3D.", "description": "Klient może zaprojektować pokój od podstaw, ustawić meble, zmienić kolory ścian, materiały, dodatki i zobaczyć wszystko w realistycznym oświetleniu.", - "imageUrl": "https://backend.ultifide.com/uploads/offer/page-header-element/optimized/e78aac1388ff07761422e12272690878.png?width=1000&height=1000", + "imageUrl": "/demo-room-preview.png", "openLabel": "Otwórz konfigurator wnętrz", "benefitsIntro": "Dla producentów mebli i marek wnętrzarskich, które chcą sprzedawać całe doświadczenie przestrzeni.", "stats": [ @@ -156,7 +224,7 @@ }, "door": { "slug": "demo-drzwi", - "eyebrow": "Demo produktowe", + "eyebrow": "", "title": "Konfigurator - Drzwi", "intro": "Pozwól klientom dobrać model, kolor, przeszklenie, klamkę i detale drzwi w interaktywnym podglądzie 3D.", "description": "Konfigurator drzwi ułatwia sprzedaż produktów z wieloma wariantami. Klient widzi efekt wyborów od razu, a konfiguracja może zostać przekazana do koszyka, zapytania ofertowego albo systemu sprzedaży.", diff --git a/public/demo-desk-preview.png b/public/demo-desk-preview.png new file mode 100644 index 0000000..983286a Binary files /dev/null and b/public/demo-desk-preview.png differ diff --git a/public/demo-room-preview.png b/public/demo-room-preview.png new file mode 100644 index 0000000..2960320 Binary files /dev/null and b/public/demo-room-preview.png differ diff --git a/src/app/[locale]/dema/page.tsx b/src/app/[locale]/dema/page.tsx index 57de6cf..37adb18 100644 --- a/src/app/[locale]/dema/page.tsx +++ b/src/app/[locale]/dema/page.tsx @@ -1,25 +1,26 @@ import type {Metadata} from 'next'; +import {getTranslations} from 'next-intl/server'; import {DemoBrowser} from '@/components/DemoBrowser'; -import {DemoSubnav} from '@/components/DemoSubnav'; import {SectionHeader} from '@/components/SectionHeader'; import {orderedDemos} from '@/config/content'; -export const metadata: Metadata = { - title: 'Dema konfiguratorów 3D | Ultifide', - description: 'Lista interaktywnych dem konfiguratorów 3D Ultifide z podglądem biurka, wnętrz i drzwi.' -}; +export async function generateMetadata(): Promise { + const t = await getTranslations('metadata'); + + return { + title: t('demosPageTitle'), + description: t('demosPageDescription') + }; +} + +export default async function DemosPage() { + const t = await getTranslations('demosPage'); -export default function DemosPage() { return (
- - +
diff --git a/src/app/[locale]/demo-biurko/page.tsx b/src/app/[locale]/demo-biurko/page.tsx index 85f3c97..4b2378a 100644 --- a/src/app/[locale]/demo-biurko/page.tsx +++ b/src/app/[locale]/demo-biurko/page.tsx @@ -5,8 +5,7 @@ import messages from '../../../../messages/pl.json'; export const metadata: Metadata = { title: messages.metadata.deskTitle, - description: - 'Poznaj konfigurator 3D, który zwiększa konwersję i pozwala klientom tworzyć własne biurka regulowane w czasie rzeczywistym.' + description: messages.metadata.deskDescription }; export default function DeskDemoPage() { diff --git a/src/app/[locale]/demo-drzwi/page.tsx b/src/app/[locale]/demo-drzwi/page.tsx index 9df2189..fc4e3ba 100644 --- a/src/app/[locale]/demo-drzwi/page.tsx +++ b/src/app/[locale]/demo-drzwi/page.tsx @@ -5,8 +5,7 @@ import messages from '../../../../messages/pl.json'; export const metadata: Metadata = { title: messages.metadata.doorTitle, - description: - 'Poznaj konfigurator 3D drzwi, który pozwala klientom dobrać model, kolor, przeszklenie, klamkę i detale w czasie rzeczywistym.' + description: messages.metadata.doorDescription }; export default function DoorDemoPage() { diff --git a/src/app/[locale]/demo-pokoj/page.tsx b/src/app/[locale]/demo-pokoj/page.tsx index 3a84c90..32b2b93 100644 --- a/src/app/[locale]/demo-pokoj/page.tsx +++ b/src/app/[locale]/demo-pokoj/page.tsx @@ -5,8 +5,7 @@ import messages from '../../../../messages/pl.json'; export const metadata: Metadata = { title: messages.metadata.roomTitle, - description: - 'Poznaj konfigurator 3D, który pozwala klientom projektować całe pomieszczenia i zestawy mebli w czasie rzeczywistym.' + description: messages.metadata.roomDescription }; export default function RoomDemoPage() { diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx index 50c4ee2..bff5531 100644 --- a/src/app/[locale]/layout.tsx +++ b/src/app/[locale]/layout.tsx @@ -1,5 +1,6 @@ import type {Metadata} from 'next'; import localFont from 'next/font/local'; +import messages from '../../../messages/pl.json'; import {NextIntlClientProvider} from 'next-intl'; import {getMessages} from 'next-intl/server'; import {notFound} from 'next/navigation'; @@ -36,7 +37,7 @@ const poppins = localFont({ export const metadata: Metadata = { title: { - default: 'Konfiguratory 3D | Ultifide', + default: messages.metadata.defaultTitle, template: '%s' } }; diff --git a/src/app/[locale]/page.tsx b/src/app/[locale]/page.tsx index 9fa4174..421625c 100644 --- a/src/app/[locale]/page.tsx +++ b/src/app/[locale]/page.tsx @@ -24,7 +24,6 @@ export default function HomePage() {
-

{homeContent.hero.eyebrow}

{homeContent.hero.title}

{homeContent.hero.description}

@@ -139,7 +138,7 @@ export default function HomePage() {
- +
diff --git a/src/app/globals.scss b/src/app/globals.scss index 86fbd71..97d2ad4 100644 --- a/src/app/globals.scss +++ b/src/app/globals.scss @@ -95,12 +95,12 @@ p { } .siteHeader { + --site-header-height: 78px; position: sticky; top: 0; z-index: 20; border-bottom: 1px solid rgba(157, 158, 180, 0.22); - background: rgba(255, 255, 255, 0.94); - backdrop-filter: blur(14px); + background: $white; } .siteHeader__inner { @@ -118,6 +118,12 @@ p { width: 154px; } +.siteHeader__logo svg { + width: 100%; + height: auto; + max-height: 44px; +} + .logoMark { width: 100%; height: auto; @@ -240,13 +246,14 @@ p { } .hero__content, -.demoHero__grid > div { +.demoHero__content { display: grid; gap: 24px; + align-self: center; } .hero__content > p:not(.eyebrow), -.demoHero__grid > div > p:not(.eyebrow), +.demoHero__content > p:not(.eyebrow), .sectionHeader > p { max-width: 680px; color: $gray-light; @@ -449,7 +456,6 @@ p { border: 1px solid rgba(0, 28, 68, 0.12); border-radius: 8px; background: $white; - box-shadow: 0 22px 60px rgba(0, 28, 68, 0.12); } @media (min-width: 1024px) { @@ -483,7 +489,8 @@ p { gap: 8px; } -.demoFrame__actions a { +.demoFrame__actions a, +.demoFrame__actions button { display: inline-flex; width: 34px; height: 34px; @@ -491,6 +498,42 @@ p { justify-content: center; border: 1px solid rgba(0, 28, 68, 0.12); border-radius: 6px; + background: $white; + color: inherit; + cursor: pointer; +} + +.demoFrameOverlay { + position: fixed; + inset: 0; + z-index: 100; + display: grid; + padding: 12px; + background: rgba(0, 28, 68, 0.55); +} + +.demoFrameOverlay__panel { + display: grid; + grid-template-rows: auto 1fr; + overflow: hidden; + min-height: 0; + height: 100%; + border-radius: 8px; +} + +.demoFrameOverlay__viewport { + position: relative; + min-height: 0; + background: #edf5ff; +} + +.demoFrameOverlay__viewport iframe { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + border: 0; + background: transparent; } .demoFrame__viewport { @@ -731,7 +774,8 @@ p { } .demoHero__visual { - min-height: 420px; + width: 100%; + min-height: min(420px, 52vh); } .demoCard > div { @@ -793,19 +837,28 @@ p { } .demoSubnavBar { + --demo-subnav-height: 53px; position: sticky; - top: 78px; + top: var(--site-header-height, 78px); z-index: 19; + min-height: var(--demo-subnav-height); border-bottom: 1px solid rgba(0, 28, 68, 0.1); - background: rgba(255, 255, 255, 0.94); - backdrop-filter: blur(14px); + background: $white; +} + +.demoSubnavBar .container { + display: flex; + align-items: center; + width: min(1180px, calc(100% - 40px)); + min-height: var(--demo-subnav-height); + margin: 0 auto; } .demoSubnavBar .demoSubnav { display: flex; gap: 24px; align-items: center; - justify-content: center; + justify-content: flex-start; margin-bottom: 0; } @@ -967,11 +1020,76 @@ p { } .demoHero { - padding-top: clamp(56px, 8vw, 92px); + padding: clamp(20px, 2.5vw, 32px) 0 clamp(20px, 3vw, 32px); } .demoHero__grid { grid-template-columns: minmax(0, 1.1fr) minmax(300px, 0.9fr); + align-items: center; +} + +.demoHero__media { + display: flex; + align-items: center; + justify-content: center; + align-self: center; + min-height: 0; +} + +.demoHero__media > span { + display: flex; + width: 100%; + align-items: center; + justify-content: center; +} + +.demoHero__media img { + width: 100%; + max-height: min(420px, 52vh); + height: auto; + object-fit: contain; +} + +.demoHero__media .demoHero__visual { + width: 100%; +} + +.demoPreview { + --hero-content-width: min(1180px, calc(100% - 40px)); + --demo-frame-width: calc((var(--hero-content-width) + 100vw) / 2); + --demo-frame-bar-height: 52px; + --demo-editor-chrome: calc(var(--site-header-height, 78px) + var(--demo-subnav-height, 53px) + var(--demo-frame-bar-height) + 40px); + display: flex; + justify-content: center; + scroll-margin-top: calc(var(--site-header-height, 78px) + var(--demo-subnav-height, 53px)); + padding: 0 0 clamp(12px, 1.5vw, 20px); +} + +.demoPage .sectionHeader h2, +.demoPage .finalCta h2 { + max-width: 820px; + font-size: clamp(1.45rem, 2.4vw, 2.1rem); + line-height: 1.22; +} + +.demoPage .sectionHeader { + margin-bottom: 24px; +} + +.demoPage .demoPreview + .sectionBand { + padding-top: clamp(24px, 3vw, 40px); +} + +.demoPreview .demoFrame { + width: var(--demo-frame-width); + max-width: 100%; +} + +.demoPreview .demoFrame__viewport { + aspect-ratio: unset; + width: 100%; + height: calc(120svh - var(--demo-editor-chrome)); + min-height: min(90svh, 900px); } .contactSection { @@ -1011,9 +1129,10 @@ p { } .contactSection__scheduler { + --contact-scheduler-height: 555px; width: 100%; - height: 555px; - max-height: 555px; + height: var(--contact-scheduler-height); + max-height: var(--contact-scheduler-height); border: 1px solid rgba(0, 28, 68, 0.1); border-radius: 8px; background: $tertiary; @@ -1122,7 +1241,13 @@ p { @media (max-width: 980px) { .siteHeader__inner { - grid-template-columns: 150px 1fr auto; + display: flex; + align-items: center; + justify-content: space-between; + gap: 0; + width: 100%; + max-width: none; + padding-inline: 14px; } .siteHeader__nav, @@ -1132,13 +1257,13 @@ p { .siteHeader__menu { display: inline-flex; - justify-self: end; + flex-shrink: 0; } .siteHeader__mobileNav { display: grid; gap: 4px; - padding: 10px 20px 20px; + padding: 10px 14px 20px; border-top: 1px solid rgba(0, 28, 68, 0.08); background: $white; } @@ -1148,14 +1273,16 @@ p { font-weight: 600; } - .demoSubnavBar { - top: 68px; + .demoSubnavBar .container { + width: 100%; + max-width: none; + padding-inline: 14px; overflow-x: auto; + -webkit-overflow-scrolling: touch; } .demoSubnavBar .demoSubnav { width: max-content; - min-width: 100%; justify-content: flex-start; } @@ -1164,11 +1291,40 @@ p { .demoBrowser, .splitSection, .contactSection__grid, - .contactSection__intro, - .footer__inner { + .contactSection__intro { grid-template-columns: 1fr; } + .contactSection__schedulerWrap, + .contactSection__scheduler { + width: 100%; + } + + .footer__inner { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 16px; + } + + .footer__brand { + display: contents; + } + + .footer__brand a { + order: 1; + } + + .footer__contact { + order: 2; + justify-self: start; + text-align: left; + } + + .footer__brand p { + order: 3; + } + .demoBrowser__sidebar { position: static; } @@ -1202,11 +1358,14 @@ p { @media (max-width: 720px) { .container, .narrow, - .siteHeader__inner, .footer__inner { width: min(100% - 28px, 1180px); } + .siteHeader { + --site-header-height: 68px; + } + .siteHeader__inner { min-height: 68px; } @@ -1215,6 +1374,22 @@ p { width: 138px; } + .siteHeader__logo svg { + max-height: 40px; + } + + .contactSection__scheduler { + --contact-scheduler-height: 370px; + } + + .contactSection.sectionBand { + padding-bottom: 24px; + } + + .contactSection__schedulerWrap { + gap: 10px; + } + .statsGrid, .demoCards, .demoSubnav, @@ -1240,6 +1415,16 @@ p { min-height: 480px; } + .demoPreview { + --hero-content-width: min(1180px, calc(100% - 28px)); + } + + .demoPreview .demoFrame__viewport { + aspect-ratio: unset; + height: calc(120svh - var(--demo-editor-chrome)); + min-height: min(85svh, 800px); + } + .heroVisual__scene { grid-template-columns: 1fr; min-height: auto; diff --git a/src/app/layout.tsx b/src/app/layout.tsx index c5522c2..405c8e5 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,10 +1,11 @@ import type {Metadata} from 'next'; +import messages from '../../messages/pl.json'; import './globals.scss'; export const metadata: Metadata = { metadataBase: new URL('https://ultifide.com'), - title: 'Konfiguratory 3D | Ultifide', - description: 'Konfiguratory 3D dla produktów, wnętrz i sprzedaży B2B.' + title: messages.metadata.defaultTitle, + description: messages.metadata.defaultDescription }; export default function RootLayout({children}: Readonly<{children: React.ReactNode}>) { diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx index 8688ed9..7bca73b 100644 --- a/src/app/not-found.tsx +++ b/src/app/not-found.tsx @@ -1,11 +1,12 @@ import Link from 'next/link'; +import messages from '../../messages/pl.json'; export default function NotFound() { return (
-

Nie znaleziono strony

+

{messages.notFound.title}

- Wróć do strony głównej + {messages.notFound.backHome}
); diff --git a/src/components/ContactSection.tsx b/src/components/ContactSection.tsx index b4f4b61..e666655 100644 --- a/src/components/ContactSection.tsx +++ b/src/components/ContactSection.tsx @@ -1,21 +1,22 @@ import {Mail, Phone} from 'lucide-react'; +import {getTranslations} from 'next-intl/server'; import {contact} from '@/config/contact'; -const schedulerUrl = 'https://42min.us/kubapyla'; - function phoneHref(phone: string) { return `tel:${phone.replaceAll(' ', '')}`; } -export function ContactSection() { +export async function ContactSection() { + const t = await getTranslations('contact'); + return (
-

Kontakt

-

Porozmawiajmy o konfiguratorze 3D

-

Opisz katalog produktów, zakres wariantów albo pierwszy pomysł na demo. Wrócimy z konkretną ścieżką wdrożenia.

+

{t('eyebrow')}

+

{t('title')}

+

{t('description')}

@@ -37,13 +38,13 @@ export function ContactSection() {