AMPERION_Webpage/layouts/_default/leistung.html
2025-08-30 13:10:37 +02:00

774 lines
24 KiB
HTML

{{ define "main" }}
{{ partial "page-title.html" . }}
{{/* ==== BILDER SAMMELN (Front-Matter oder Auto-Discovery) ==== */}}
{{ $photos := .Params.images }}
{{ if not $photos }}
{{ $slug := .Params.slug | default .File.TranslationBaseName }}
{{ $cands := slice
(printf "static/images/leistungen/%s1.webp" $slug)
(printf "static/images/leistungen/%s2.webp" $slug)
}}
{{ $auto := slice }}
{{ range $cands }}
{{ if fileExists . }}
{{ $auto = $auto | append (dict "src" (replace . "static" "") "alt" $slug ) }}
{{ end }}
{{ end }}
{{ $photos = $auto }}
{{ end }}
{{/* Erstes Bild für Hero, zweites fürs Ergebnis vormerken */}}
{{ $heroPhoto := cond (gt (len $photos) 0) (index $photos 0) nil }}
{{ $ergebnisPhoto := cond (gt (len $photos) 1) (index $photos 1) nil }}
{{ $.Scratch.Set "ergebnisPhoto" $ergebnisPhoto }}
<!-- ===== Styles (optimiert für 1 oder 3 Spalten) ===== -->
<style>
.container-wide {
width: 100%;
margin-left: auto;
margin-right: auto;
padding-left: 16px;
padding-right: 16px;
}
@media (min-width:1200px){.container-wide{max-width:1280px}}
@media (min-width:1400px){.container-wide{max-width:1360px}}
@media (min-width:1600px){.container-wide{max-width:1440px}}
.service-hero__media {
border-radius: 12px;
overflow: hidden;
box-shadow: 0 6px 30px rgba(0,0,0,.06);
}
.service-hero__media img {
display: block;
width: 100%;
height: auto;
}
.service-hero__text p { margin-bottom: 1rem }
/* USP Grid */
.usp-container {
display: grid;
grid-template-columns: 1fr; /* Standard: Handy -> untereinander */
gap: 2rem;
margin-top: 2rem;
justify-items: center;
text-align: center;
}
/* Desktop: immer 3 nebeneinander */
@media (min-width: 992px) {
.usp-container {
grid-template-columns: repeat(3, 1fr);
}
}
.usp-item {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
gap: 8px;
padding: 12px 14px;
border-radius: 12px;
background: #fff;
box-shadow: 0 2px 12px rgba(0,0,0,.05);
}
.usp-icon {
color: #F5A623;
background: rgba(245,166,35,.12);
width: 44px; height: 44px;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 8px;
}
.usp-icon svg {
display: block;
width: 24px;
height: 24px;
}
.usp-text {
font-weight: 500;
margin: 0;
}
</style>
<!-- =========================
HERO: Bild links, Intro rechts (breit)
========================= -->
<section class="service-hero section" style="margin-top:-24px; padding-top:16px;">
<div class="container-wide">
<div class="row align-items-center gx-5">
<!-- Bild links -->
<div class="col-lg-6 order-1 order-lg-1" data-reveal>
{{ with $heroPhoto }}
<figure class="service-hero__media">
<img src='{{ .src | default . | relURL }}'
alt='{{ .alt | default $.Title }}'
width="1200" height="800"
loading="eager" decoding="async" class="img-fluid">
</figure>
{{ end }}
</div>
<!-- Intro-Text rechts -->
<div class="col-lg-6 order-2 order-lg-2" data-reveal>
{{ if .Content }}
<div class="service-hero__text">
{{ .Content }}
</div>
{{ end }}
</div>
</div>
<!-- USP-Container -->
{{ with .Params.usp }}
<div class="usp-container">
{{ range $i, $u := . }}
<div class="usp-item">
<div class="usp-icon" aria-hidden="true">
{{ if eq (mod $i 3) 0 }}
<!-- Shield -->
<svg viewBox="0 0 24 24" role="img" focusable="false">
<path d="M12 3l7 3v6c0 4.97-3.58 9.43-7 10-3.42-.57-7-5.03-7-10V6l7-3z" fill="currentColor" opacity=".2"/>
<path d="M12 3l7 3v6c0 4.97-3.58 9.43-7 10-3.42-.57-7-5.03-7-10V6l7-3z" fill="none" stroke="currentColor" stroke-width="1.5"/>
</svg>
{{ else if eq (mod $i 3) 1 }}
<!-- Badge -->
<svg viewBox="0 0 24 24" role="img" focusable="false">
<circle cx="12" cy="9" r="5" fill="currentColor" opacity=".2"/>
<circle cx="12" cy="9" r="5" fill="none" stroke="currentColor" stroke-width="1.5"/>
<path d="M8 14l-2 7 6-3 6 3-2-7" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/>
</svg>
{{ else }}
<!-- Target -->
<svg viewBox="0 0 24 24" role="img" focusable="false">
<circle cx="12" cy="12" r="9" fill="currentColor" opacity=".15"/>
<circle cx="12" cy="12" r="6" fill="none" stroke="currentColor" stroke-width="1.5"/>
<circle cx="12" cy="12" r="2" fill="currentColor"/>
</svg>
{{ end }}
</div>
<p class="usp-text">{{ $u | markdownify }}</p>
</div>
{{ end }}
</div>
{{ end }}
</div>
</section>
<!-- =========================
FEATURES CAROUSEL (Große Cards mit Auto-Play)
Quelle: .Params.features (array of {title, text, icon?})
========================= -->
{{ with .Params.features }}
<section class="section service-features" aria-label="Leistungen">
<style>
/* ===== Features Carousel Styles ===== */
.service-features {
background-color: #f3f3f3;
padding: 60px 0;
}
.sf-carousel {
position: relative;
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
.sf-title {
text-align: center;
margin: 0 0 40px;
}
/* Viewport & Track */
.sf-viewport {
overflow: hidden;
border-radius: 20px;
position: relative;
}
.sf-track {
display: flex;
transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
will-change: transform;
}
/* Cards - Always one card visible */
.sf-card {
flex: 0 0 100%;
padding: 10px;
box-sizing: border-box;
}
.sf-card-inner {
background: #fff;
border-radius: 16px;
padding: 40px 30px;
height: 100%;
min-height: 320px;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
transition: transform 0.3s, box-shadow 0.3s;
cursor: grab;
}
.sf-carousel.is-dragging .sf-card-inner {
cursor: grabbing;
}
/* Icon */
.sf-icon {
width: 80px;
height: 80px;
background: linear-gradient(135deg, #F5A623 0%, #FFC947 100%);
border-radius: 20px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 24px;
box-shadow: 0 8px 24px rgba(245, 166, 35, 0.3);
}
.sf-icon svg {
width: 40px;
height: 40px;
color: #fff;
}
/* Content */
.sf-card h3 {
margin: 0 0 16px;
line-height: 1.3;
}
.sf-card p {
margin: 0;
line-height: 1.6;
}
/* Navigation Dots */
.sf-dots {
display: flex;
justify-content: center;
gap: 8px;
margin-top: 32px;
padding: 0;
list-style: none;
}
.sf-dot {
width: 12px;
height: 12px;
border-radius: 50%;
background: rgba(0,0,0,0.2);
border: none;
cursor: pointer;
transition: all 0.3s;
padding: 0;
}
.sf-dot:hover {
background: rgba(245, 166, 35, 0.5);
transform: scale(1.2);
}
.sf-dot.active {
background: #F5A623;
width: 32px;
border-radius: 6px;
}
/* Arrow Navigation */
.sf-arrow {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 48px;
height: 48px;
background: #fff;
border: none;
border-radius: 50%;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
z-index: 2;
transition: all 0.3s;
font-size: 20px;
color: #333;
}
.sf-arrow:hover {
background: #F5A623;
color: #fff;
transform: translateY(-50%) scale(1.1);
}
.sf-arrow.prev {
left: 20px;
}
.sf-arrow.next {
right: 20px;
}
/* Hide arrows on mobile */
@media (max-width: 767px) {
.sf-arrow {
display: none;
}
}
/* Touch feedback */
@media (hover: none) {
.sf-card-inner:active {
transform: scale(0.98);
}
}
/* Progress bar for autoplay */
.sf-progress {
position: absolute;
bottom: -4px;
left: 0;
height: 3px;
background: #F5A623;
border-radius: 3px;
width: 0;
transition: width 8s linear;
z-index: 3;
}
.sf-carousel.autoplay .sf-progress {
width: 100%;
}
/* Pause on hover */
.sf-carousel:hover .sf-progress {
animation-play-state: paused;
}
</style>
{{/* Store the features list and count */}}
{{ $features := . }}
{{ $totalFeatures := len $features }}
<div class="sf-carousel" id="sfCarousel">
<h2 class="sf-title">Unsere Leistungen</h2>
<button class="sf-arrow prev" aria-label="Vorherige Leistung">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
<path d="M15 18l-6-6 6-6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
<button class="sf-arrow next" aria-label="Nächste Leistung">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
<path d="M9 18l6-6-6-6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
<div class="sf-viewport" role="region" aria-roledescription="carousel" aria-label="Leistungen Carousel">
<div class="sf-track" id="sfTrack">
{{ range $i, $f := $features }}
<div class="sf-card" role="group" aria-roledescription="slide" aria-label='{{ printf "Leistung %d von %d" (add $i 1) $totalFeatures }}'>
<div class="sf-card-inner">
<div class="sf-icon" aria-hidden="true">
{{ $icon := $f.icon | default (printf "i-%d" (mod $i 5)) }}
{{ if or (eq $icon "pv") (eq $icon "i-0") }}
<!-- PV/Solar -->
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M3.55 18.54L4.96 19.95L6.76 18.16L5.34 16.74M11 22.45C11.32 22.45 13 22.45 13 22.45V19.5H11M12 5.5C8.14 5.5 5 8.64 5 12.5C5 16.36 8.14 19.5 12 19.5C15.86 19.5 19 16.36 19 12.5C19 8.64 15.86 5.5 12 5.5M20 12.5H23V10.5H20M17.24 18.16L19.04 19.95L20.45 18.54L18.66 16.74M20.45 6.46L19.04 5.05L17.24 6.84L18.66 8.26M13 0.55H11V3.5H13M4 10.5H1V12.5H4M6.76 6.84L4.96 5.05L3.55 6.46L5.34 8.26"/>
</svg>
{{ else if or (eq $icon "speicher") (eq $icon "i-1") }}
<!-- Battery/Speicher -->
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M16 10V8H15V6C15 4.89 14.11 4 13 4H5C3.89 4 3 4.89 3 6V18C3 19.11 3.89 20 5 20H13C14.11 20 15 19.11 15 18V16H16V14H19V10H16M5 6H13V18H5V6M16.5 12.5H18V11.5H16.5V12.5Z"/>
</svg>
{{ else if or (eq $icon "lade") (eq $icon "i-2") }}
<!-- EV Charging -->
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M18 7V4C18 2.9 17.1 2 16 2H5C3.9 2 3 2.9 3 4V20C3 21.1 3.9 22 5 22H16C17.1 22 18 21.1 18 20V18H20C21.1 18 22 17.1 22 16V12C22 10.9 21.1 10 20 10H18V7M5 4H16V20H5V4M18 12H20V16H18V12M11 5H7L11 13V9H15L11 17V13Z"/>
</svg>
{{ else if or (eq $icon "study") (eq $icon "i-3") }}
<!-- Analytics/Study -->
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M22 12C22 6.48 17.52 2 12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12M6.5 13L10 9.5L13 12.5L16.5 9L18 10.5L13 15.5L10 12.5L6.5 16L5 14.5L6.5 13Z"/>
</svg>
{{ else }}
<!-- Check/Service -->
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2M10 17L5 12L6.41 10.59L10 14.17L17.59 6.58L19 8L10 17Z"/>
</svg>
{{ end }}
</div>
<h3>{{ $f.title }}</h3>
{{ with $f.text }}<p>{{ . | $.Page.RenderString (dict "display" "inline") }}</p>{{ end }}
</div>
</div>
{{ end }}
</div>
<div class="sf-progress"></div>
</div>
<div class="sf-dots" role="tablist" aria-label="Carousel Navigation">
{{ range $i, $f := $features }}
<button class="sf-dot{{ if eq $i 0 }} active{{ end }}"
role="tab"
aria-selected="{{ if eq $i 0 }}true{{ else }}false{{ end }}"
aria-label="Gehe zu Leistung {{ add $i 1 }}"
data-slide="{{ $i }}">
</button>
{{ end }}
</div>
</div>
<script>
(function () {
const carousel = document.getElementById('sfCarousel');
if (!carousel) return;
const track = document.getElementById('sfTrack');
const cards = track.querySelectorAll('.sf-card');
const dots = carousel.querySelectorAll('.sf-dot');
const prevBtn = carousel.querySelector('.sf-arrow.prev');
const nextBtn = carousel.querySelector('.sf-arrow.next');
const progress = carousel.querySelector('.sf-progress');
let currentIndex = 0;
let autoplayInterval;
let touchStartX = 0;
let touchEndX = 0;
let isDragging = false;
let isAnimating = false; // blockiert neue Aktionen
const AUTOPLAY_DELAY = 20000;
function setupInfiniteLoop() {
const firstClone = cards[0].cloneNode(true);
const lastClone = cards[cards.length - 1].cloneNode(true);
firstClone.setAttribute('aria-hidden', 'true');
lastClone.setAttribute('aria-hidden', 'true');
track.appendChild(firstClone);
track.insertBefore(lastClone, cards[0]);
}
function updateCarousel(animate = true) {
const translateX = -(currentIndex + 1) * 100;
track.style.transition = animate
? 'transform 0.5s cubic-bezier(0.4, 0, 0.2, 1)'
: 'none';
track.style.transform = `translateX(${translateX}%)`;
const realIndex = (currentIndex + cards.length) % cards.length;
dots.forEach((dot, index) => {
dot.classList.toggle('active', index === realIndex);
dot.setAttribute('aria-selected', index === realIndex);
});
// Buttons während Animation blockieren
prevBtn.disabled = animate;
nextBtn.disabled = animate;
}
track.addEventListener('transitionend', () => {
if (currentIndex === cards.length) currentIndex = 0;
if (currentIndex === -1) currentIndex = cards.length - 1;
updateCarousel(false);
isAnimating = false;
prevBtn.disabled = false;
nextBtn.disabled = false;
});
function goToSlide(index) {
if (isAnimating) return;
isAnimating = true;
currentIndex = index;
updateCarousel();
resetAutoplay();
}
function nextSlide() {
if (isAnimating) return;
isAnimating = true;
currentIndex++;
updateCarousel();
}
function prevSlide() {
if (isAnimating) return;
isAnimating = true;
currentIndex--;
updateCarousel();
}
function startAutoplay() {
carousel.classList.add('autoplay');
progress.style.transition = 'none';
progress.style.width = '0%';
requestAnimationFrame(() => {
progress.style.transition = `width ${AUTOPLAY_DELAY}ms linear`;
progress.style.width = '100%';
});
autoplayInterval = setInterval(nextSlide, AUTOPLAY_DELAY);
}
function stopAutoplay() {
carousel.classList.remove('autoplay');
clearInterval(autoplayInterval);
progress.style.transition = 'none';
progress.style.width = '0%';
}
function resetAutoplay() {
stopAutoplay();
startAutoplay();
}
// Touch/Swipe
function handleTouchStart(e) {
if (isAnimating) return;
touchStartX = e.type.includes('mouse') ? e.clientX : e.touches[0].clientX;
isDragging = true;
carousel.classList.add('is-dragging');
stopAutoplay();
}
function handleTouchEnd(e) {
if (!isDragging) return;
isDragging = false;
carousel.classList.remove('is-dragging');
touchEndX = e.type.includes('mouse')
? e.clientX
: e.changedTouches[0]?.clientX || touchStartX;
handleSwipe();
resetAutoplay();
}
function handleSwipe() {
const diff = touchStartX - touchEndX;
if (Math.abs(diff) > 50) diff > 0 ? nextSlide() : prevSlide();
}
// Events
prevBtn.addEventListener('click', () => prevSlide());
nextBtn.addEventListener('click', () => nextSlide());
dots.forEach((dot, i) => dot.addEventListener('click', () => goToSlide(i)));
track.addEventListener('touchstart', handleTouchStart, { passive: true });
track.addEventListener('touchend', handleTouchEnd, { passive: true });
track.addEventListener('mousedown', handleTouchStart);
track.addEventListener('mouseup', handleTouchEnd);
carousel.addEventListener('mouseenter', stopAutoplay);
carousel.addEventListener('mouseleave', startAutoplay);
carousel.addEventListener('keydown', (e) => {
if (e.key === 'ArrowLeft') prevSlide();
if (e.key === 'ArrowRight') nextSlide();
});
setupInfiniteLoop();
updateCarousel(false);
startAutoplay();
})();
</script>
</section>
{{ end }}
<!-- =========================
OUTCOMES (Nutzen/Ergebnisse)
Quelle: .Params.outcomes (array of strings)
========================= -->
{{ with .Params.outcomes }}
<section class="service-outcomes section" aria-label="Ergebnis & Mehrwert">
<style>
.out-row{align-items:center}
.out-media{border-radius:12px;overflow:hidden;box-shadow:0 6px 30px rgba(0,0,0,.06)}
.out-media img{display:block;width:100%;height:auto}
.checklist{list-style:none;padding:0;margin:0;display:grid;gap:12px}
.checklist li{display:flex;gap:10px;align-items:flex-start}
.checklist .check{flex:0 0 22px;color:#0AA8A7;margin-top:2px}
</style>
<div class="container-wide" >
<div class="row out-row gx-5">
<!-- Text links -->
<div class="col-lg-6" data-reveal>
<h2 class="mb-3">Ergebnis & Mehrwert</h2>
<ul class="checklist">
{{ range . }}
<li data-reveal>
<svg class="check" viewBox="0 0 24 24" width="22" height="22" aria-hidden="true">
<path d="M20 6L9 17l-5-5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
</svg>
<span>{{ . | markdownify }}</span>
</li>
{{ end }}
</ul>
</div>
<!-- Bild rechts (nimmt das 2. Bild aus dem Hero-Setup) -->
<div class="col-lg-6" data-reveal>
{{ $erg := $.Scratch.Get "ergebnisPhoto" }}
{{ with $erg }}
<figure class="out-media">
<img src='{{ .src | relURL }}' alt='{{ .alt | default $.Title }}'
width="1200" height="800" loading="lazy" decoding="async">
</figure>
{{ else }}
{{ with $heroPhoto }}
<figure class="out-media">
<img src='{{ .src | relURL }}' alt='{{ .alt | default $.Title }}'
width="1200" height="800" loading="lazy" decoding="async">
</figure>
{{ end }}
{{ end }}
</div>
</div>
</div>
</section>
{{ end }}
<!-- =========================
CTA (animierter Hintergrund wie auf Index),
aber: TEXT/Buttons aus Front-Matter binden.
========================= -->
{{ $impressum := site.GetPage "page" "impressum" }}
{{ $ctaEnabled := or (.Params.cta.enable) (or .Params.cta_text .Params.cta_label) }}
{{ if $ctaEnabled }}
<section id="cta" class="cta">
<!-- Animierter Hintergrund (DEIN bestehendes Markup) -->
<div class="cta__bg" aria-hidden="true">
<div class="cta__grid"></div>
<div class="cta__energy-lines">
<div class="energy-line-h energy-line-h2"></div>
<div class="energy-line-h energy-line-h3"></div>
<div class="energy-line-v energy-line-v1"></div>
<div class="energy-line-v energy-line-v2"></div>
<div class="energy-node energy-node1"></div>
<div class="energy-node energy-node2"></div>
</div>
<div class="cta__gradient-top"></div>
<div class="cta__gradient-bottom"></div>
</div>
<!-- Inhalt: jetzt dynamisch aus Front-Matter -->
<div class="my-container">
<div class="cta__wrap" data-reveal>
<h3 class="cta__title">
{{ .Params.cta_text | default "Lassen Sie uns Ihre Vision mit unserer Expertise zur Realität machen." }}
</h3>
<div class="cta__actions">
{{ with .Params.cta_label }}
<a class="cta__btn" href="{{ $.Params.cta_href | default "/contact/" }}">
<span aria-hidden="true"></span><span>{{ . }}</span>
</a>
{{ end }}
</div>
<div class="cta__social">
<a class="cta__social-link" href="https://www.instagram.com/amperion.at/" target="_blank" rel="noopener" aria-label="Instagram">
<img src="/images/social/instagram.svg" alt="">
</a>
<a class="cta__social-link" href="https://www.linkedin.com/company/amperion-gmbh/" target="_blank" rel="noopener" aria-label="LinkedIn">
<img src="/images/social/linkedin.svg" alt="">
</a>
<a class="cta__social-link" href="https://www.facebook.com/share/1CZ7xm6cdw/?mibextid=wwXIfr" target="_blank" rel="noopener" aria-label="Facebook">
<img src="/images/social/facebook.svg" alt="">
</a>
</div>
</div>
</div>
</section>
{{ end }}
<!-- =========================
Micro-Animationen (IntersectionObserver)
- fügt 'is-visible' hinzu, wenn Elemente ins Viewport kommen
========================= -->
<script>
(function(){
if (window.__serviceRevealInit) return; // vermeiden, dass mehrfach registriert wird
window.__serviceRevealInit = true;
var els = document.querySelectorAll("[data-reveal]");
if (!('IntersectionObserver' in window) || !els.length) {
els.forEach(function(el){ el.classList.add('is-visible'); });
return;
}
var io = new IntersectionObserver(function(entries){
entries.forEach(function(entry){
if (entry.isIntersecting) {
entry.target.classList.add('is-visible');
io.unobserve(entry.target);
}
});
}, { threshold: 0.12 });
els.forEach(function(el){ io.observe(el); });
})();
</script>
<!-- =========================
Minimal CSS-Hooks (optional, an deine SCSS anpassen)
========================= -->
<style>
/* Typo hooks */
.kicker{letter-spacing:.08em;text-transform:uppercase;opacity:.85;margin-bottom:.25rem}
.lead{opacity:.9}
/* Media items (icon-left) */
.media-item{display:flex;gap:.9rem;align-items:flex-start}
.media-item .media-icon{flex:0 0 auto;line-height:0;opacity:.9}
.media-item .media-body{flex:1}
/* Features grid spacing */
.service-features .feature{padding:14px 8px;border-radius:12px;transition:transform .25s ease, box-shadow .25s ease}
.service-features .feature:hover{transform:translateY(-2px);box-shadow:0 6px 24px rgba(0,0,0,.06)}
/* Outcomes checklist */
.checklist{list-style:none;padding:0;margin:0}
.checklist li{display:flex;gap:.6rem;align-items:flex-start;margin:.5rem 0}
.checklist .check{color:#F5A623; margin-top:.2rem}
/* Reveal animation */
[data-reveal]{opacity:0;transform:translateY(12px);transition:opacity .5s ease, transform .5s ease}
[data-reveal].is-visible{opacity:1;transform:none}
.service-photo{border-radius:12px;overflow:hidden}
.service-photo img{display:block;width:100%;height:auto}
.service-hero__media{border-radius:12px;overflow:hidden;box-shadow:0 6px 30px rgba(0,0,0,.06)}
.service-hero__media img{display:block;width:100%;height:auto}
.service-hero__text p{margin-bottom:1rem}
</style>
{{ end }}