Brezplačno Snemanje Poroke: Ujemita Vajin Dan v Profesionalni Poročni Video
+
Iščeva zaročene pare po vsej Sloveniji, ki si želijo čustven in kinematografski poročni video – popolnoma brezplačno v zameno za uporabo posnetkov za najin portfelj. Število terminov je omejeno!
Sva strastna videografa na začetku svoje skupne poti v svetu poročne videografije. Verjameva, da ima vsaka ljubezenska zgodba moč, da navdihne. Zato iščeva pare, kot sta vidva, da nama pomagata zgraditi portfelj osupljivih poročnih zgodb. V zameno za vajino zaupanje prejmeta profesionalni poročni video, ustvarjen z najnovejšo opremo in polno mero kreativne energije, brez kakršnihkoli stroškov.
+
+
+
+
+
+
+
Kaj Vključuje Brezplačni Poročni Video Paket?
+
Najina ponudba je transparentna. Prejmeta vse, kar potrebujeta za večen spomin.
+
+
✅ Profesionalni poročni video: 3-5 minutni, čustveno zmontiran film vajinega dne.
+
✅ Snemanje z več kamerami: Za dinamične in raznolike posnetke.
+
✅ Uporaba drona: Za dih jemajoče posnetke lokacije iz zraka (kjer je to mogoče in dovoljeno).
+
✅ Kakovosten zvok: Snemanje govora in zaobljub z diskretnimi mikrofoni.
+
✅ Digitalna dostava: Končni video v visoki ločljivosti (4K) preko spletne galerije.
+
+
+
+
+
+
+
+
Najin Proces Snemanja Poroke v 3 Korakih
+
+
+
01
+
Prijava
+
Izpolnita obrazec na dnu strani z osnovnimi informacijami o vajini poroki. Bolj kot sta podrobna, lažje si vaju predstavljava.
+
+
+
02
+
Spoznavni klic
+
Če se vajina vizija ujema z najino, se dogovorimo za kratek spletni klic, kjer se spoznamo in pogovorimo o podrobnostih vajinega dne.
+
+
+
03
+
Snemanje
+
Na poročni dan sva z vama, diskretna in osredotočena na lovljenje pristnih trenutkov. Po poroki se lotiva montaže in vama dostaviva končni video.
+
+
+
+
+
+
+
+
+
Zagotovita si Svoj Termin za Brezplačno Snemanje Poroke!
+
Mesta se hitro polnijo. Ne odlašajta in izpolnita prijavo še danes. Veseliva se vajine zgodbe!
+
+
+
+
+
+
+
+
+
+
Pogosta Vprašanja
+
+
Ali so res kakšni skriti stroški?
+
Ne. Ponudba je 100% brezplačna in ne vključuje nobenih skritih stroškov. Edini pogoj je podpis pogodbe, ki nama dovoljuje uporabo posnetkov za promocijske namene. Potni stroški znotraj Slovenije so vključeni.
+
+
+
Katere lokacije v Sloveniji pokrivata?
+
Pokrivava celotno Slovenijo! Iščeva pare iz vseh regij, od Gorenjske in Primorske do Štajerske in Prekmurja. Ne glede na to, ali je vaša lokacija Ljubljana, Maribor ali skriti kotiček narave, naju zanima.
+
+
+
Kako poteka izbor parov?
+
Ker je število terminov omejeno, bomo izbrali pare, katerih poročni dan in vizija se najbolj ujemata z najinim stilom snemanja. Iščemo unikatne zgodbe, zanimive lokacije in predvsem pristno energijo.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/js/main.js b/js/main.js
new file mode 100644
index 0000000..ad45940
--- /dev/null
+++ b/js/main.js
@@ -0,0 +1,218 @@
+/**
+ * main.js
+ * Glavna JavaScript datoteka za spletno stran "Brezplačno snemanje poroke".
+ *
+ * Funkcionalnosti:
+ * 1. Inicializacija vseh skript po nalaganju DOM-a.
+ * 2. Upravljanje animacij elementov ob drsanju strani (Intersection Observer).
+ * 3. Implementacija gladkega drsanja za interne povezave.
+ * 4. Interaktivni parallax efekt v "hero" sekciji, ki se odziva na premik miške.
+ * 5. Napredna validacija in pošiljanje kontaktnega obrazca preko Fetch API.
+ */
+
+// Počakamo, da se celoten HTML dokument naloži, preden zaženemo skripte.
+document.addEventListener('DOMContentLoaded', () => {
+
+ // Inicializacija vseh glavnih funkcij
+ initScrollAnimations();
+ initSmoothScrolling();
+ initHeroParallaxEffect();
+ initContactFormHandler();
+
+ console.log("Stran je pripravljena in vsi interaktivni elementi so aktivirani.");
+
+});
+
+
+/**
+ * Funkcija za inicializacijo animacij ob drsanju (Fade-in efekt).
+ * Uporablja Intersection Observer API za optimalno delovanje.
+ * Elementi z razredom .animate-on-scroll bodo postali vidni, ko vstopijo v vidno polje.
+ */
+function initScrollAnimations() {
+ const animatedElements = document.querySelectorAll('.animate-on-scroll');
+
+ if (!animatedElements.length) return;
+
+ const observerOptions = {
+ root: null, // opazujemo glede na vidno polje brskalnika
+ rootMargin: '0px',
+ threshold: 0.1 // sproži se, ko je vsaj 10% elementa vidnega
+ };
+
+ const observer = new IntersectionObserver((entries, observer) => {
+ entries.forEach(entry => {
+ if (entry.isIntersecting) {
+ entry.target.classList.add('is-visible');
+ observer.unobserve(entry.target); // prenehamo opazovati, da se animacija zgodi samo enkrat
+ }
+ });
+ }, observerOptions);
+
+ animatedElements.forEach(element => {
+ observer.observe(element);
+ });
+}
+
+
+/**
+ * Funkcija za implementacijo gladkega drsanja do sidrnih točk.
+ * Vsi linki, ki se začnejo z '#', bodo sprožili gladko drsenje namesto skoka.
+ */
+function initSmoothScrolling() {
+ const internalLinks = document.querySelectorAll('a[href^="#"]');
+
+ internalLinks.forEach(link => {
+ link.addEventListener('click', function(e) {
+ e.preventDefault();
+ const targetId = this.getAttribute('href');
+ const targetElement = document.querySelector(targetId);
+
+ if (targetElement) {
+ targetElement.scrollIntoView({
+ behavior: 'smooth',
+ block: 'start'
+ });
+ }
+ });
+ });
+}
+
+
+/**
+ * Funkcija za parallax efekt v "hero" sekciji, ki se odziva na premik miške.
+ * Predpostavlja obstoj elementa z ID-jem #hero-section in elementa v njem z razredom .hero-background.
+ */
+function initHeroParallaxEffect() {
+ const heroSection = document.querySelector('#hero-section');
+ const heroBackground = document.querySelector('.hero-background');
+
+ if (!heroSection || !heroBackground) return;
+
+ const parallaxStrength = 15; // Manjša vrednost = bolj subtilen efekt
+
+ heroSection.addEventListener('mousemove', (e) => {
+ const { clientWidth, clientHeight } = heroSection;
+ const x = (e.clientX / clientWidth) - 0.5;
+ const y = (e.clientY / clientHeight) - 0.5;
+
+ // Uporabimo transform za premik, kar je bolj učinkovito za animacije
+ heroBackground.style.transform = `
+ translateX(${-x * parallaxStrength}px)
+ translateY(${-y * parallaxStrength}px)
+ scale(1.05)`; // Rahlo povečamo ozadje, da robovi niso vidni
+ });
+
+ heroSection.addEventListener('mouseleave', () => {
+ // Obnovimo pozicijo, ko miška zapusti območje
+ heroBackground.style.transform = 'translate(0, 0) scale(1.05)';
+ });
+}
+
+
+/**
+ * Funkcija za upravljanje kontaktnega obrazca.
+ * Vključuje validacijo na strani odjemalca in pošiljanje podatkov preko Fetch API.
+ * Predpostavlja, da ima obrazec ID #contact-form in da ga upravlja Netlify.
+ */
+function initContactFormHandler() {
+ const form = document.querySelector('#contact-form');
+ if (!form) return;
+
+ const submitButton = form.querySelector('button[type="submit"]');
+ const formResponseEl = document.querySelector('#form-response'); // Element za prikaz sporočil
+
+ form.addEventListener('submit', function(e) {
+ e.preventDefault();
+
+ // 1. Validacija polj
+ if (!validateForm(form)) {
+ return; // Ustavi pošiljanje, če validacija ne uspe
+ }
+
+ // 2. Priprava podatkov za pošiljanje
+ const formData = new FormData(form);
+ const originalButtonText = submitButton.textContent;
+ submitButton.disabled = true;
+ submitButton.textContent = 'Pošiljanje...';
+
+ // 3. Pošiljanje preko Fetch API (prilagojeno za Netlify Forms)
+ fetch('/', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+ body: new URLSearchParams(formData).toString()
+ })
+ .then(response => {
+ if (response.ok) {
+ // Uspešno poslano
+ form.style.display = 'none'; // Skrij obrazec
+ formResponseEl.innerHTML = `
Hvala za prijavo!
Oglasili se vam bova v najkrajšem možnem času. Preverite svoj e-poštni nabiralnik.
`;
+ formResponseEl.classList.add('success');
+ formResponseEl.style.display = 'block';
+ } else {
+ // Napaka pri pošiljanju
+ throw new Error('Prišlo je do napake pri pošiljanju. Poskusite znova.');
+ }
+ })
+ .catch(error => {
+ formResponseEl.innerHTML = `
Napaka: ${error.message}
`;
+ formResponseEl.classList.add('error');
+ formResponseEl.style.display = 'block';
+ })
+ .finally(() => {
+ // Ponastavi gumb samo v primeru napake, saj ob uspehu formo skrijemo
+ if (form.style.display !== 'none') {
+ submitButton.disabled = false;
+ submitButton.textContent = originalButtonText;
+ }
+ });
+ });
+}
+
+/**
+ * Pomožna funkcija za validacijo polj v obrazcu.
+ * @param {HTMLFormElement} form - Obrazec, ki ga validiramo.
+ * @returns {boolean} - Vrne `true`, če so vsa polja veljavna, sicer `false`.
+ */
+function validateForm(form) {
+ let isValid = true;
+ const requiredFields = form.querySelectorAll('[required]');
+
+ // Najprej počistimo vse prejšnje napake
+ form.querySelectorAll('.error-message').forEach(el => el.remove());
+ form.querySelectorAll('.is-invalid').forEach(el => el.classList.remove('is-invalid'));
+
+ requiredFields.forEach(field => {
+ let error = null;
+
+ if (field.value.trim() === '') {
+ error = 'To polje je obvezno.';
+ } else if (field.type === 'email' && !isValidEmail(field.value)) {
+ error = 'Prosimo, vnesite veljaven e-poštni naslov.';
+ } else if (field.type === 'date' && new Date(field.value) < new Date()) {
+ error = 'Datum poroke ne more biti v preteklosti.';
+ }
+
+ if (error) {
+ isValid = false;
+ field.classList.add('is-invalid');
+ const errorElement = document.createElement('span');
+ errorElement.className = 'error-message';
+ errorElement.textContent = error;
+ // Vstavi sporočilo o napaki za poljem
+ field.parentNode.insertBefore(errorElement, field.nextSibling);
+ }
+ });
+
+ return isValid;
+}
+
+/**
+ * Pomožna funkcija za preverjanje veljavnosti e-poštnega naslova.
+ * @param {string} email - E-poštni naslov za preverjanje.
+ * @returns {boolean}
+ */
+function isValidEmail(email) {
+ const regex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
+ return regex.test(String(email).toLowerCase());
+}
diff --git a/robots.txt b/robots.txt
new file mode 100644
index 0000000..e69de29
diff --git a/sitemap.xml b/sitemap.xml
new file mode 100644
index 0000000..e69de29