Editorial Desk

Contact Our Editorial Team

Have a question about a coastal trail, an archipelago ferry connection, or a correction for our guides? We would love to hear from you. Drop us a note below and we will get back to you promptly.

Send a Message

Fill out the form below. All fields marked with an asterisk () are required.

Direct Inquiries

We generally reply to all editorial correspondence within one to two business days.

Editorial Desk Email [email protected]
Operating Entity Story Porch Scene Coastal Media Ltd
Company Registration SC-784920-B
Registered Office 44 Harbor Strand, Suite 3B, EH6 7BD, Edinburgh, United Kingdom
Regional Coverage Map 54°–60°N / 12°–24°E
===ENDFILE=== ===FILE: styles.css=== /* ========================================================================== BALTIC SEA ESCAPES — SOFT MODERN DESIGN SYSTEM Brand & Palette Architecture ========================================================================== */ :root { /* Baltic Custom Color Palette */ --color-midnight: #10252B; --color-deep-sea: #173A42; --color-harbor-blue: #285B66; --color-sea-glass: #76AAA5; --color-coastal-sage: #8FAFA1; --color-mist-blue: #B8D0D1; --color-salt-sand: #E4DDD0; --color-dune-cream: #F1EBDD; --color-shell-white: #FAF9F4; --color-driftwood: #A58D76; --color-sunset-amber: #D39A5B; --color-sunset-hover: #BF874A; --color-coastal-coral: #C87872; --color-deep-ink: #172124; /* Typography */ --font-system: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; /* Spacing Scale */ --space-4: 4px; --space-8: 8px; --space-16: 16px; --space-24: 24px; --space-32: 32px; --space-40: 40px; --space-64: 64px; /* Radius & Shadows */ --radius-sm: 12px; --radius-md: 20px; --radius-lg: 28px; --shadow-subtle: 0 4px 20px rgba(16, 37, 43, 0.05); --shadow-card: 0 10px 30px rgba(16, 37, 43, 0.07); --shadow-hover: 0 14px 40px rgba(16, 37, 43, 0.12); --border-fine: 1px solid rgba(118, 170, 165, 0.25); } /* ========================================================================== RESET & CORE BOX MODEL ========================================================================== */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } html { font-family: var(--font-system); font-size: 16px; line-height: 1.6; color: var(--color-deep-ink); background-color: var(--color-shell-white); -webkit-text-size-adjust: 100%; } body { min-height: 100vh; display: flex; flex-direction: column; background-color: var(--color-shell-white); color: var(--color-deep-ink); } main { flex: 1 0 auto; } img, svg { display: block; max-width: 100%; height: auto; } a { color: var(--color-harbor-blue); text-decoration: none; transition: color 0.2s ease; } a:hover { color: var(--color-sunset-amber); } h1, h2, h3, h4, h5, h6 { color: var(--color-midnight); line-height: 1.25; font-weight: 700; overflow-wrap: anywhere; } p, li, th, td, label { overflow-wrap: anywhere; } ul { list-style: none; } /* ========================================================================== ACCESSIBILITY & FOCUS ========================================================================== */ :focus-visible { outline: 3px solid var(--color-sunset-amber); outline-offset: 3px; } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; } } /* ========================================================================== LAYOUT CONTAINERS ========================================================================== */ .site-container { width: 100%; max-width: 1160px; margin-left: auto; margin-right: auto; padding-left: var(--space-24); padding-right: var(--space-24); min-width: 0; } @media (max-width: 480px) { .site-container { padding-left: var(--space-16); padding-right: var(--space-16); } } .page-section { padding-top: var(--space-64); padding-bottom: var(--space-64); } .bg-dune { background-color: var(--color-dune-cream); } .bg-shell { background-color: #F6F3EB; } .bg-sage-light { background-color: rgba(143, 175, 161, 0.15); } /* ========================================================================== HEADER (NON-STICKY) ========================================================================== */ .site-header { position: relative; background-color: var(--color-shell-white); border-bottom: 1px solid rgba(118, 170, 165, 0.2); z-index: 100; } .header-container { max-width: 1160px; margin: 0 auto; padding: 0 var(--space-24); height: 64px; display: flex; align-items: center; justify-content: space-between; } .brand-link { display: flex; align-items: center; gap: var(--space-8); font-weight: 700; font-size: 1.1rem; color: var(--color-midnight); overflow-wrap: anywhere; } .brand-link:hover { color: var(--color-harbor-blue); } .brand-mark { flex-shrink: 0; } .brand-text { letter-spacing: -0.01em; } .nav-menu { display: flex; align-items: center; } .nav-list { display: flex; align-items: center; gap: var(--space-24); } .nav-link { font-size: 0.95rem; font-weight: 500; color: var(--color-deep-sea); padding: var(--space-4) var(--space-8); border-radius: var(--radius-sm); transition: color 0.2s ease, background-color 0.2s ease; } .nav-link:hover { color: var(--color-sunset-amber); background-color: rgba(118, 170, 165, 0.1); } .nav-link.active { color: var(--color-midnight); font-weight: 700; border-bottom: 2px solid var(--color-sea-glass); } .nav-cta-btn { background-color: var(--color-deep-sea); color: var(--color-shell-white); padding: 8px 18px; border-radius: var(--radius-md); font-size: 0.9rem; font-weight: 600; transition: background-color 0.2s ease; } .nav-cta-btn:hover { background-color: var(--color-sunset-amber); color: var(--color-midnight); } .nav-toggle { display: none; background: none; border: 1px solid var(--color-sea-glass); border-radius: var(--radius-sm); padding: 8px; cursor: pointer; width: 40px; height: 40px; flex-direction: column; justify-content: space-around; } .nav-toggle-bar { width: 100%; height: 2px; background-color: var(--color-deep-sea); border-radius: 2px; transition: transform 0.2s ease, opacity 0.2s ease; } @media (max-width: 840px) { .header-container { height: 52px; } .nav-toggle { display: flex; } .nav-menu { display: none; position: absolute; top: 52px; left: 0; width: 100%; background-color: var(--color-shell-white); border-bottom: 1px solid var(--color-salt-sand); box-shadow: 0 10px 25px rgba(16, 37, 43, 0.1); padding: var(--space-24); } .nav-menu.is-visible { display: block; } .nav-list { flex-direction: column; align-items: flex-start; gap: var(--space-16); } .nav-link { display: block; width: 100%; font-size: 1.05rem; padding: var(--space-8) 0; } .nav-cta-btn { display: inline-block; margin-top: var(--space-8); } } /* ========================================================================== BUTTONS & BADGES ========================================================================== */ .btn { display: inline-flex; align-items: center; justify-content: center; padding: 12px 26px; border-radius: var(--radius-md); font-size: 0.95rem; font-weight: 600; cursor: pointer; transition: all 0.2s ease; border: 1px solid transparent; text-decoration: none; text-align: center; } .btn-primary { background-color: var(--color-sunset-amber); color: var(--color-midnight); border-color: var(--color-sunset-amber); } .btn-primary:hover { background-color: var(--color-sunset-hover); border-color: var(--color-sunset-hover); color: var(--color-midnight); } .btn-secondary { background-color: var(--color-deep-sea); color: var(--color-shell-white); border-color: var(--color-deep-sea); } .btn-secondary:hover { background-color: var(--color-harbor-blue); color: var(--color-shell-white); } .btn-outline { background-color: transparent; color: var(--color-deep-sea); border-color: var(--color-deep-sea); } .btn-outline:hover { background-color: rgba(23, 58, 66, 0.08); color: var(--color-midnight); } .btn-sm { padding: 8px 16px; font-size: 0.85rem; border-radius: var(--radius-sm); } .btn-block { width: 100%; } .badge-tag { display: inline-block; background-color: rgba(118, 170, 165, 0.2); color: var(--color-deep-sea); padding: 4px 14px; border-radius: var(--radius-sm); font-size: 0.85rem; font-weight: 600; margin-bottom: var(--space-16); border: 1px solid rgba(118, 170, 165, 0.3); } /* ========================================================================== STRICT SEPARATION CARD PATTERN (NON-NEGOTIABLE DESIGN SYSTEM) Structure: IMAGE -> 32px GAP -> SEPARATE CONTENT PANEL ========================================================================== */ /* 1. Homepage Hero */ .hero-section { padding-top: var(--space-40); padding-bottom: var(--space-64); } .hero-media-wrapper { width: 100%; border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-card); margin-bottom: var(--space-32); /* STRICT 32px separation */ } .hero-image { width: 100%; max-height: 520px; object-fit: cover; } .hero-content-panel { background: var(--color-dune-cream); border: var(--border-fine); border-radius: var(--radius-lg); padding: var(--space-40); box-shadow: var(--shadow-subtle); } .hero-title { font-size: 2.5rem; margin-bottom: var(--space-16); letter-spacing: -0.02em; } .hero-lead { font-size: 1.2rem; color: #33484D; margin-bottom: var(--space-24); max-width: 820px; } .hero-actions { display: flex; flex-wrap: wrap; gap: var(--space-16); } @media (max-width: 640px) { .hero-title { font-size: 1.85rem; } .hero-lead { font-size: 1.05rem; } .hero-content-panel { padding: var(--space-24); } } /* 2. Sub-Page Hero (Separated) */ .page-intro-section { padding-top: var(--space-40); padding-bottom: var(--space-40); } .page-hero-media { width: 100%; border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-card); margin-bottom: var(--space-32); /* STRICT 32px separation */ } .page-hero-image { width: 100%; max-height: 440px; object-fit: cover; } .page-intro-panel { background: var(--color-dune-cream); border: var(--border-fine); border-radius: var(--radius-lg); padding: var(--space-40); box-shadow: var(--shadow-subtle); } .page-title { font-size: 2.2rem; margin-bottom: var(--space-16); } @media (max-width: 640px) { .page-title { font-size: 1.7rem; } .page-intro-panel { padding: var(--space-24); } } /* 3. Separated Cards Stack */ .separated-card-stack { display: flex; flex-direction: column; gap: var(--space-64); } .separated-card { display: flex; flex-direction: column; background: transparent; } .card-media { width: 100%; border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-card); margin-bottom: var(--space-32); /* STRICT 32px separation */ } .card-image { width: 100%; max-height: 420px; object-fit: cover; transition: transform 0.4s ease; } .separated-card:hover .card-image { transform: scale(1.02); } .card-content-panel { background: var(--color-shell-white); border: var(--border-fine); border-radius: var(--radius-lg); padding: var(--space-32); box-shadow: var(--shadow-subtle); } .card-category { display: inline-block; font-size: 0.85rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-harbor-blue); margin-bottom: var(--space-8); } .card-title { font-size: 1.5rem; margin-bottom: var(--space-16); } .card-title a { color: var(--color-midnight); } .card-title a:hover { color: var(--color-sunset-amber); } .card-text { font-size: 1.05rem; color: #3B4E53; margin-bottom: var(--space-24); line-height: 1.6; } .card-tags { display: flex; flex-wrap: wrap; gap: var(--space-8); margin-bottom: var(--space-24); } .tag { background-color: var(--color-dune-cream); color: var(--color-deep-sea); font-size: 0.85rem; font-weight: 500; padding: 4px 12px; border-radius: var(--radius-sm); } .card-footer-action { display: flex; } /* ========================================================================== SECTION HEADERS & 3-COLUMN FEATURES ========================================================================== */ .section-header { text-align: center; max-width: 760px; margin: 0 auto var(--space-40) auto; } .section-kicker { display: block; font-size: 0.85rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--color-harbor-blue); margin-bottom: var(--space-8); } .section-title { font-size: 2rem; margin-bottom: var(--space-16); } .section-description { font-size: 1.1rem; color: #435A60; } .features-grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-24); } @media (max-width: 800px) { .features-grid-3 { grid-template-columns: 1fr; } } .info-card { background: var(--color-shell-white); border: var(--border-fine); border-radius: var(--radius-md); padding: var(--space-32); box-shadow: var(--shadow-subtle); min-width: 0; } .info-card-icon { width: 48px; height: 48px; border-radius: var(--radius-sm); background-color: rgba(118, 170, 165, 0.2); color: var(--color-deep-sea); display: flex; align-items: center; justify-content: center; margin-bottom: var(--space-16); } .info-card-title { font-size: 1.25rem; margin-bottom: var(--space-8); } .info-card-text { font-size: 0.95rem; color: #4A5F64; } /* ========================================================================== SPLIT PLANNING & CTA BANNER ========================================================================== */ .split-planning-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-40); align-items: center; } @media (max-width: 768px) { .split-planning-grid { grid-template-columns: 1fr; } } .rounded-image { border-radius: var(--radius-lg); box-shadow: var(--shadow-card); width: 100%; } .clean-check-list { margin: var(--space-24) 0; display: flex; flex-direction: column; gap: var(--space-16); } .clean-check-list li { position: relative; padding-left: 28px; font-size: 1rem; color: #384F54; } .clean-check-list li::before { content: "✓"; position: absolute; left: 0; top: 0; color: var(--color-sea-glass); font-weight: 700; font-size: 1.1rem; } .cta-banner { background: linear-gradient(135deg, var(--color-deep-sea) 0%, var(--color-harbor-blue) 100%); color: var(--color-shell-white); border-radius: var(--radius-lg); padding: var(--space-40); display: flex; align-items: center; justify-content: space-between; gap: var(--space-24); box-shadow: var(--shadow-card); } .cta-title { color: var(--color-shell-white); font-size: 1.75rem; margin-bottom: var(--space-8); } .cta-text { color: var(--color-mist-blue); font-size: 1.05rem; max-width: 620px; } @media (max-width: 768px) { .cta-banner { flex-direction: column; align-items: flex-start; } } /* ========================================================================== ARTICLE & SUBPAGE LAYOUT ========================================================================== */ .article-layout { display: grid; grid-template-columns: 2fr 1fr; gap: var(--space-40); } @media (max-width: 860px) { .article-layout { grid-template-columns: 1fr; } } .article-content h2 { font-size: 1.6rem; margin-top: var(--space-40); margin-bottom: var(--space-16); } .article-content h3 { font-size: 1.3rem; margin-top: var(--space-24); margin-bottom: var(--space-8); } .article-content p { font-size: 1.05rem; line-height: 1.7; color: #2F4247; margin-bottom: var(--space-16); } .article-sidebar { display: flex; flex-direction: column; gap: var(--space-24); } .sidebar-card { background: var(--color-dune-cream); border: var(--border-fine); border-radius: var(--radius-md); padding: var(--space-24); } .sidebar-title { font-size: 1.2rem; margin-bottom: var(--space-16); } .sidebar-nav { display: flex; flex-direction: column; gap: var(--space-8); } .sidebar-nav li a { display: block; padding: 6px 0; font-weight: 500; color: var(--color-deep-sea); } .sidebar-nav li a:hover { color: var(--color-sunset-amber); } .sidebar-text { font-size: 0.95rem; color: #455B60; margin-bottom: var(--space-16); } /* Comparison Table */ .comparison-table-wrapper { overflow-x: auto; margin: var(--space-24) 0; border-radius: var(--radius-md); border: var(--border-fine); box-shadow: var(--shadow-subtle); } .comparison-table { width: 100%; border-collapse: collapse; background: var(--color-shell-white); font-size: 0.95rem; text-align: left; } .comparison-table th, .comparison-table td { padding: 14px 18px; border-bottom: 1px solid rgba(118, 170, 165, 0.2); } .comparison-table thead th { background-color: var(--color-deep-sea); color: var(--color-shell-white); font-weight: 600; } .comparison-table tbody tr:last-child td, .comparison-table tbody tr:last-child th { border-bottom: none; } .comparison-table tbody th { background-color: rgba(241, 235, 221, 0.5); font-weight: 600; color: var(--color-midnight); } /* Callout Box */ .callout-box { background: rgba(118, 170, 165, 0.12); border-left: 4px solid var(--color-sea-glass); border-radius: var(--radius-sm); padding: var(--space-24); margin: var(--space-32) 0; } .callout-title { font-size: 1.15rem; margin-bottom: var(--space-8); color: var(--color-deep-sea); } /* Legal layout */ .legal-layout { max-width: 840px; margin: 0 auto; } .legal-layout h2 { font-size: 1.45rem; margin-top: var(--space-32); margin-bottom: var(--space-16); } .legal-layout h3 { font-size: 1.2rem; margin-top: var(--space-24); margin-bottom: var(--space-8); } .legal-layout p { font-size: 1rem; line-height: 1.7; color: #2F4247; margin-bottom: var(--space-16); } .legal-layout ul { list-style: disc; margin-left: var(--space-24); margin-bottom: var(--space-24); } .legal-layout ul li { margin-bottom: var(--space-8); font-size: 0.95rem; color: #2F4247; } /* ========================================================================== CONTACT PAGE & STYLED STATIC MAP BLOCK ========================================================================== */ .contact-grid { display: grid; grid-template-columns: 1.2fr 1fr; gap: var(--space-40); } @media (max-width: 840px) { .contact-grid { grid-template-columns: 1fr; } } .contact-form-card { background: var(--color-shell-white); border: var(--border-fine); border-radius: var(--radius-lg); padding: var(--space-32); box-shadow: var(--shadow-subtle); } .form-heading { font-size: 1.5rem; margin-bottom: var(--space-8); } .form-subheading { font-size: 0.95rem; color: #556B70; margin-bottom: var(--space-24); } .form-group { margin-bottom: var(--space-16); } .form-label { display: block; font-size: 0.9rem; font-weight: 600; margin-bottom: var(--space-4); color: var(--color-deep-sea); } .required-mark { color: var(--color-coastal-coral); } .form-input, .form-textarea { width: 100%; padding: 12px 16px; border-radius: var(--radius-sm); border: 1px solid #C4D3D4; background-color: #FFFFFF; font-family: inherit; font-size: 0.95rem; color: var(--color-deep-ink); transition: border-color 0.2s ease, box-shadow 0.2s ease; } .form-input:focus, .form-textarea:focus { border-color: var(--color-sea-glass); box-shadow: 0 0 0 3px rgba(118, 170, 165, 0.25); outline: none; } .form-input.is-invalid, .form-textarea.is-invalid { border-color: var(--color-coastal-coral); } .field-error { display: block; font-size: 0.8rem; color: var(--color-coastal-coral); margin-top: 4px; min-height: 18px; } .form-feedback { padding: var(--space-16); border-radius: var(--radius-sm); margin-bottom: var(--space-16); font-size: 0.95rem; } .form-feedback.is-success { background-color: #E3F2E9; border: 1px solid #7BB28D; color: #174222; } .contact-info-col { display: flex; flex-direction: column; gap: var(--space-24); } .contact-details-card { background: var(--color-dune-cream); border: var(--border-fine); border-radius: var(--radius-lg); padding: var(--space-24); } .contact-meta-item { margin-top: var(--space-16); padding-top: var(--space-12); border-top: 1px solid rgba(118, 170, 165, 0.2); } .meta-label { display: block; font-size: 0.8rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-harbor-blue); } .meta-value { display: block; font-size: 0.95rem; color: var(--color-midnight); margin-top: 2px; } /* Styled Static Map Block (Pure CSS / SVG) */ .static-map-card { background: var(--color-midnight); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-card); border: var(--border-fine); } .map-header { padding: 12px 16px; background: var(--color-deep-sea); display: flex; justify-content: space-between; align-items: center; font-size: 0.8rem; color: var(--color-shell-white); } .map-badge { font-weight: 600; color: var(--color-mist-blue); } .map-coords { color: var(--color-sea-glass); } .map-graphic-wrapper { position: relative; background-color: var(--color-deep-sea); width: 100%; } .baltic-vector-map { width: 100%; height: auto; } .map-footer-text { padding: 10px 16px; background: #0E2025; color: var(--color-mist-blue); font-size: 0.8rem; text-align: center; } /* ========================================================================== FOOTER (IDENTICAL ACROSS ALL PAGES) ========================================================================== */ .site-footer { background-color: var(--color-midnight); color: var(--color-mist-blue); padding-top: var(--space-64); padding-bottom: var(--space-32); border-top: 1px solid rgba(118, 170, 165, 0.2); } .footer-grid { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: var(--space-40); margin-bottom: var(--space-40); } @media (max-width: 768px) { .footer-grid { grid-template-columns: 1fr; gap: var(--space-32); } } .footer-brand { display: inline-flex; align-items: center; gap: var(--space-8); font-size: 1.15rem; font-weight: 700; color: var(--color-shell-white); margin-bottom: var(--space-16); } .footer-bio { font-size: 0.9rem; line-height: 1.6; margin-bottom: var(--space-16); color: var(--color-mist-blue); max-width: 440px; } .footer-legal-details { font-size: 0.85rem; line-height: 1.6; color: #8CAAB0; } .footer-legal-details p { margin-bottom: 4px; } .footer-legal-details a { color: var(--color-sea-glass); } .footer-legal-details a:hover { color: var(--color-sunset-amber); } .footer-heading { color: var(--color-shell-white); font-size: 1.05rem; margin-bottom: var(--space-16); } .footer-links { display: flex; flex-direction: column; gap: var(--space-8); } .footer-links li a { color: var(--color-mist-blue); font-size: 0.9rem; transition: color 0.2s ease; } .footer-links li a:hover { color: var(--color-sunset-amber); } .footer-bottom { padding-top: var(--space-24); border-top: 1px solid rgba(118, 170, 165, 0.15); text-align: center; font-size: 0.85rem; color: #7A989E; } /* ========================================================================== COOKIE CONSENT BANNER (FIXED BOTTOM) ========================================================================== */ .cookie-banner { position: fixed; bottom: 0; left: 0; width: 100%; background-color: var(--color-midnight); color: var(--color-shell-white); border-top: 2px solid var(--color-sea-glass); box-shadow: 0 -10px 30px rgba(16, 37, 43, 0.3); z-index: 1000; padding: var(--space-24) var(--space-16); } .cookie-banner[hidden] { display: none !important; } .cookie-banner.is-visible { display: block; } .cookie-banner-container { max-width: 1160px; margin: 0 auto; display: flex; align-items: center; justify-content: space-between; gap: var(--space-24); } @media (max-width: 768px) { .cookie-banner-container { flex-direction: column; align-items: flex-start; } } .cookie-banner-title { color: var(--color-shell-white); font-size: 1.1rem; margin-bottom: 4px; } .cookie-banner-desc { font-size: 0.85rem; color: var(--color-mist-blue); max-width: 700px; line-height: 1.5; } .cookie-actions { display: flex; flex-wrap: wrap; gap: var(--space-8); flex-shrink: 0; } /* ========================================================================== UTILITY CLASSES & HELPERS ========================================================================== */ .my-40 { margin-top: var(--space-40); margin-bottom: var(--space-40); } .my-64 { margin-top: var(--space-64); margin-bottom: var(--space-64); } .mt-8 { margin-top: var(--space-8); } .mt-16 { margin-top: var(--space-16); } .mt-24 { margin-top: var(--space-24); } .text-center { text-align: center; } .mx-auto { margin-left: auto; margin-right: auto; } ===ENDFILE=== ===FILE: script.js=== /** * Baltic Sea Escapes — Script * Plain Vanilla JS: Navigation, Cookie Consent & Form Validation */ document.addEventListener('DOMContentLoaded', () => { initMobileNav(); initCookieBanner(); initContactForm(); initCookieResetButton(); }); /* ========================================================================== 1. MOBILE NAVIGATION TOGGLE ========================================================================== */ function initMobileNav() { const toggleBtn = document.querySelector('[data-nav-toggle]'); const navMenu = document.querySelector('[data-nav-menu]'); if (!toggleBtn || !navMenu) return; toggleBtn.addEventListener('click', () => { const isExpanded = toggleBtn.getAttribute('aria-expanded') === 'true'; toggleBtn.setAttribute('aria-expanded', !isExpanded); navMenu.classList.toggle('is-visible'); }); // Close menu when clicking outside document.addEventListener('click', (event) => { if (!toggleBtn.contains(event.target) && !navMenu.contains(event.target) && navMenu.classList.contains('is-visible')) { toggleBtn.setAttribute('aria-expanded', 'false'); navMenu.classList.remove('is-visible'); } }); } /* ========================================================================== 2. COOKIE CONSENT BANNER & PREFERENCE STORAGE ========================================================================== */ function initCookieBanner() { const banner = document.getElementById('cookie-banner'); if (!banner) return; const STORAGE_KEY = 'baltic_cookie_choice'; const savedChoice = localStorage.getItem(STORAGE_KEY); // If no choice stored, display banner if (!savedChoice) { banner.removeAttribute('hidden'); banner.classList.add('is-visible'); } // Bind to all choice buttons const choiceButtons = document.querySelectorAll('[data-cookie-choice]'); choiceButtons.forEach((btn) => { btn.addEventListener('click', (e) => { const choice = btn.getAttribute('data-cookie-choice'); if (choice === 'preferences') { // Allow link navigation to cookie-policy.html return; } e.preventDefault(); localStorage.setItem(STORAGE_KEY, choice); banner.classList.remove('is-visible'); banner.setAttribute('hidden', ''); }); }); } /* ========================================================================== 3. COOKIE RESET ACTION (On Cookie Policy Page) ========================================================================== */ function initCookieResetButton() { const resetBtn = document.querySelector('[data-reset-cookie-btn]'); if (!resetBtn) return; resetBtn.addEventListener('click', () => { localStorage.removeItem('baltic_cookie_choice'); alert('Cookie choices have been reset. Reloading page to display the preference banner.'); window.location.reload(); }); } /* ========================================================================== 4. CONTACT FORM VALIDATION & FEEDBACK ========================================================================== */ function initContactForm() { const form = document.querySelector('[data-contact-form]'); if (!form) return; const feedback = document.getElementById('form-feedback'); form.addEventListener('submit', (event) => { event.preventDefault(); let isValid = true; // Fields to validate const nameInput = document.getElementById('contact-name'); const emailInput = document.getElementById('contact-email'); const subjectInput = document.getElementById('contact-subject'); const messageInput = document.getElementById('contact-message'); // Error containers const nameError = document.getElementById('name-error'); const emailError = document.getElementById('email-error'); const subjectError = document.getElementById('subject-error'); const messageError = document.getElementById('message-error'); // Clear previous errors [nameInput, emailInput, subjectInput, messageInput].forEach((input) => { input.classList.remove('is-invalid'); }); [nameError, emailError, subjectError, messageError].forEach((err) => { err.textContent = ''; }); if (feedback) { feedback.setAttribute('hidden', ''); feedback.classList.remove('is-success'); } // Name validation if (!nameInput.value.trim()) { isValid = false; nameInput.classList.add('is-invalid'); nameError.textContent = 'Please enter your name.'; } // Email validation const emailValue = emailInput.value.trim(); const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailValue) { isValid = false; emailInput.classList.add('is-invalid'); emailError.textContent = 'Please enter your email address.'; } else if (!emailRegex.test(emailValue)) { isValid = false; emailInput.classList.add('is-invalid'); emailError.textContent = 'Please enter a valid email address format.'; } // Subject validation if (!subjectInput.value.trim()) { isValid = false; subjectInput.classList.add('is-invalid'); subjectError.textContent = 'Please enter a subject.'; } // Message validation if (!messageInput.value.trim()) { isValid = false; messageInput.classList.add('is-invalid'); messageError.textContent = 'Please enter your message.'; } else if (messageInput.value.trim().length < 15) { isValid = false; messageInput.classList.add('is-invalid'); messageError.textContent = 'Please provide a little more detail (at least 15 characters).'; } // If valid, display success feedback if (isValid && feedback) { feedback.removeAttribute('hidden'); feedback.classList.add('is-success'); feedback.innerHTML = 'Thank you! Your message has been received. Our editorial team will review your inquiry and get back to you shortly.'; form.reset(); } }); } ===ENDFILE===