html { scroll-behavior: smooth; }
body {
font-family: var(--sans);
font-weight: 300;
font-size: 16px;
line-height: 1.75;
color: var(--text-muted);
background: var(--white);
-webkit-font-smoothing: antialiased;
overflow-x: hidden;
}
img { display: block; max-width: 100%; height: auto; }
a { text-decoration: none; color: inherit; }
ul, ol { list-style: none; }
button { cursor: pointer; font-family: var(--sans); border: none; background: none; }
/* ═══════════════════════════════════════════════════════════
LAYOUT UTILITIES
═══════════════════════════════════════════════════════════ */
.wrap {
max-width: 1260px;
margin: 0 auto;
padding: 0 48px;
}
@media (max-width: 900px) { .wrap { padding: 0 28px; } }
@media (max-width: 600px) { .wrap { padding: 0 20px; } }
@media (max-width: 600px) {
.btn {
width: 100%;
justify-content: center;
min-height: 54px;
white-space: normal;
}
}
.section-label {
display: inline-flex;
align-items: center;
gap: 12px;
font-family: var(--sans);
font-size: 11px;
font-weight: 500;
letter-spacing: .18em;
text-transform: uppercase;
color: var(--gold);
}
.section-label::before {
content: '';
width: 32px; height: 1px;
background: var(--gold);
flex-shrink: 0;
}
h2.section-h2 {
font-family: var(--serif);
font-size: clamp(34px, 4.5vw, 54px);
font-weight: 500;
color: var(--text);
line-height: 1.18;
letter-spacing: -.01em;
}
h2.section-h2--light { color: var(--white); }
.services .section-h2 { color: #ffffff; }
.services .section-label { color: rgba(255,255,255,0.7); }
.services .services__intro { color: rgba(255,255,255,0.75); }
/* BUTTONS */
.btn {
display: inline-flex;
align-items: center;
gap: 8px;
font-family: var(--sans);
font-size: 13px;
font-weight: 500;
letter-spacing: .07em;
text-transform: uppercase;
border-radius: 0;
padding: 14px 32px;
min-height: 50px;
transition: all .28s var(--ease);
white-space: nowrap;
}
/* RH-style: square corners, solid fill */
.btn-solid {
background: var(--charcoal);
color: var(--white);
border: 1.5px solid var(--charcoal);
}
.btn-solid:hover { background: var(--charcoal-lt); border-color: var(--charcoal-lt); }
.btn-gold {
background: var(--gold);
color: var(--white);
border: 1.5px solid var(--gold);
}
.btn-gold:hover { background: var(--gold-dark); border-color: var(--gold-dark); }
.btn-outline-white {
background: transparent;
color: var(--white);
border: 1.5px solid rgba(255,255,255,.5);
}
.btn-outline-white:hover { border-color: var(--white); background: rgba(255,255,255,.08); }
.btn-outline-dark {
background: transparent;
color: var(--text);
border: 1.5px solid var(--text);
}
.btn-outline-dark:hover { background: var(--text); color: var(--white); }
/* REVEAL */
.reveal {
opacity: 0;
transform: translateY(28px);
transition: opacity .6s var(--ease-out), transform .6s var(--ease-out);
}
.reveal.in { opacity: 1; transform: none; }
.d1 { transition-delay: .08s; }
.d2 { transition-delay: .16s; }
.d3 { transition-delay: .24s; }
.d4 { transition-delay: .32s; }
.d5 { transition-delay: .40s; }
.d6 { transition-delay: .48s; }
/* ═══════════════════════════════════════════════════════════
§1 — NAVIGATION
Belle layout: white sticky, logo left, nav center, CTA right
═══════════════════════════════════════════════════════════ */
.nav {
position: fixed;
inset: 0 0 auto 0;
z-index: 900;
background: var(--white);
border-bottom: 1px solid transparent;
transition: border-color .3s, box-shadow .3s;
}
.nav.solid {
border-color: var(--stone);
box-shadow: 0 2px 24px rgba(44,40,37,.07);
}
/* On hero: transparent */
.nav.hero-mode {
background: linear-gradient(180deg, rgba(28,25,22,.65) 0%, transparent 100%);
border-color: transparent !important;
box-shadow: none !important;
}
.nav__inner {
display: flex;
align-items: center;
height: 78px;
gap: 40px;
}
.nav__logo {
flex-shrink: 0;
display: flex;
align-items: center;
}
.nav__logo img {
height: 96px;
width: auto;
transition: filter .3s;
}
.nav.hero-mode .nav__logo img { filter: brightness(0) invert(1); }
.nav__links {
display: flex;
align-items: center;
gap: 36px;
flex: 1;
justify-content: center;
}
.nav__links a {
font-size: 13px;
font-weight: 400;
letter-spacing: .04em;
color: var(--text-muted);
transition: color .2s;
}
.nav__links a:hover { color: var(--gold); }
.nav.hero-mode .nav__links a { color: rgba(255,255,255,.75); }
.nav.hero-mode .nav__links a:hover { color: var(--white); }
.nav__right {
flex-shrink: 0;
display: flex;
align-items: center;
gap: 20px;
}
.nav__phone {
font-size: 13px;
font-weight: 500;
color: var(--text);
letter-spacing: .02em;
transition: color .2s;
}
.nav__phone:hover { color: var(--gold); }
.nav.hero-mode .nav__phone { color: rgba(255,255,255,.8); }
.nav.hero-mode .nav__phone:hover { color: var(--white); }
.nav__cta {
font-size: 12px;
font-weight: 500;
letter-spacing: .1em;
text-transform: uppercase;
padding: 11px 24px;
min-height: 44px;
background: var(--charcoal);
color: var(--white);
border: 1.5px solid var(--charcoal);
transition: all .25s;
}
.nav__cta:hover { background: var(--charcoal-lt); }
.nav.hero-mode .nav__cta {
background: transparent;
border-color: rgba(255,255,255,.5);
color: var(--white);
}
.nav.hero-mode .nav__cta:hover { background: rgba(255,255,255,.12); border-color: var(--white); }
/* Hamburger */
.nav__ham {
display: none;
flex-direction: column;
justify-content: center;
gap: 5px;
width: 44px; height: 44px;
padding: 8px;
}
.nav__ham span {
display: block;
height: 1.5px;
background: var(--text);
border-radius: 2px;
transition: all .3s;
}
.nav.hero-mode .nav__ham span { background: var(--white); }
.nav__ham.open span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.nav__ham.open span:nth-child(2) { opacity: 0; }
.nav__ham.open span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }
/* Mobile drawer */
.nav__drawer {
display: none;
position: fixed;
top: 78px;
left: 0; right: 0;
background: var(--white);
border-top: 1px solid var(--stone);
padding: 24px 28px 32px;
flex-direction: column;
gap: 0;
box-shadow: 0 20px 40px rgba(0,0,0,.12);
z-index: 899;
}
.nav__drawer.open { display: flex; }
.nav__drawer a {
font-size: 16px;
font-weight: 300;
color: var(--text);
padding: 14px 0;
border-bottom: 1px solid var(--stone);
transition: color .2s;
}
.nav__drawer a:hover { color: var(--gold); }
@media (max-width: 960px) {
.nav__inner { justify-content: space-between; }
.nav__links { display: none; }
.nav__phone { display: none; }
.nav__cta { display: none; }
.nav__ham { display: flex; }
}
/* ═══════════════════════════════════════════════════════════
§2 — HERO (Split: left text / right arch image)
═══════════════════════════════════════════════════════════ */
.hero {
position: relative;
background: var(--charcoal);
width: 100%;
min-height: 100dvh;
overflow: hidden;
display: flex;
align-items: stretch;
}
.hero__inner {
position: relative;
z-index: 2;
width: 100%;
max-width: 1400px;
margin: 0 auto;
display: grid;
grid-template-columns: 1fr 1fr;
min-height: 100dvh;
}
/* Cycling background images — behind everything */
.hero__bg {
position: absolute;
top: -15%;
left: 0;
right: 0;
height: 130%;
z-index: 0;
opacity: 0;
transition: opacity 1.4s ease-in-out;
background-size: cover;
background-position: center;
will-change: transform;
transform-origin: center center;
}
.hero__bg.active { opacity: 1; }
/* Faded logo watermark */
/* Faded logo watermark — sits above dark overlay, below text */
.hero__logo-wm {
position: absolute;
inset: 0;
z-index: 2;
display: flex;
align-items: center;
justify-content: center;
pointer-events: none;
overflow: hidden;
}
.hero__logo-wm img {
width: clamp(520px, 72vw, 960px);
height: auto;
opacity: 0.07;
filter: brightness(0) invert(1);
user-select: none;
}
.hero__bg--1 { background-image: url('./hero-slide-1.avif'); }
.hero__bg--2 { background-image: url('./hero-slide-2.avif'); }
.hero__bg--3 { background-image: url('./hero-slide-3.avif'); }
/* Dark overlay above background, below content */
.hero__overlay {
position: absolute;
inset: 0;
z-index: 1;
background: linear-gradient(155deg, rgba(28,25,22,.90) 0%, rgba(28,25,22,.76) 100%);
pointer-events: none;
}
/* ── Left text panel ── */
.hero__text {
display: flex;
flex-direction: column;
justify-content: center;
padding: clamp(100px,12vh,140px) clamp(28px,4vw,60px) clamp(100px,12vh,140px) clamp(48px,7vw,96px);
position: relative;
z-index: 3;
}
/* Subtle left border accent */
.hero__text::before {
content: '';
position: absolute;
top: 0; bottom: 0; left: clamp(24px,3.5vw,48px);
width: 1px;
background: linear-gradient(180deg, transparent 0%, rgba(255,255,255,.18) 30%, rgba(255,255,255,.18) 70%, transparent 100%);
}
/* ── Right arch panel ── */
.hero__arch-wrap {
position: relative;
display: flex;
align-items: center;
justify-content: center;
padding: 64px 64px 64px 24px;
z-index: 3;
}
.hero__arch {
position: relative;
width: 100%;
aspect-ratio: 3/4.4;
border-radius: 1000px 1000px 0 0;
overflow: hidden;
box-shadow: 0 48px 96px rgba(0,0,0,.55), 0 16px 32px rgba(0,0,0,.3);
}
/* Arch images — 3 layers cycling in sync with bg */
.hero__arch-img {
position: absolute;
inset: -5%;
background-size: cover;
background-position: center;
opacity: 0;
transition: opacity 1.2s ease-in-out;
transform-origin: center;
will-change: transform;
}
.hero__arch-img.active { opacity: 1; }
.hero__arch-img--1 { background-image: url('./hero-slide-1.avif'); }
.hero__arch-img--2 { background-image: url('./hero-slide-2.avif'); }
.hero__arch-img--3 { background-image: url('./hero-slide-3.avif'); }
@keyframes hero-zoom {
from { transform: scale(1.08); }
to { transform: scale(1); }
}
/* Vignette at base of arch */
.hero__arch::after {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(to bottom, transparent 55%, rgba(28,25,22,.45) 100%);
pointer-events: none;
z-index: 1;
}
/* ── Eyebrow ── */
.hero__eyebrow {
display: inline-flex;
align-items: center;
gap: 12px;
font-size: 11px;
font-weight: 500;
letter-spacing: .2em;
text-transform: uppercase;
color: var(--gold-light);
margin-bottom: 32px;
}
.hero__eyebrow::before {
content: '';
width: 32px; height: 1px;
background: var(--gold-light);
opacity: .6;
flex-shrink: 0;
}
/* ── H1 ── */
.hero__h1 {
font-family: var(--serif);
font-size: clamp(44px, 5.2vw, 80px);
font-weight: 400;
color: var(--white);
line-height: 1.08;
letter-spacing: -.025em;
margin-bottom: 28px;
}
.hero__h1 em {
font-style: italic;
color: var(--gold-ultra);
}
/* ── Subheading ── */
.hero__sub {
font-size: 17px;
font-weight: 300;
color: rgba(255,255,255,.58);
line-height: 1.78;
max-width: 420px;
margin-bottom: 48px;
}
/* ── CTA row ── */
.hero__actions {
display: flex;
align-items: center;
gap: 20px;
flex-wrap: wrap;
}
/* ── Scroll hint — bottom left ── */
.hero__scroll {
position: absolute;
bottom: 36px;
left: clamp(48px, 7vw, 96px);
z-index: 4;
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
}
.hero__scroll-line {
width: 1px; height: 40px;
background: linear-gradient(180deg, rgba(255,255,255,.4) 0%, transparent 100%);
animation: scrollpulse 2s ease-in-out infinite;
}
@keyframes scrollpulse {
0%, 100% { opacity: .4; transform: scaleY(1); }
50% { opacity: 1; transform: scaleY(.7); transform-origin: top; }
}
/* ── Responsive ── */
@media (max-width: 900px) {
.hero__inner { grid-template-columns: 1fr; min-height: 100dvh; align-items: start; }
.hero__text { padding: 110px 28px 48px; }
.hero__arch-wrap { padding: 0 40px 80px; }
.hero__arch { max-height: 420px; }
.hero__text::before { display: none; }
}
@media (max-width: 600px) {
.hero__text { padding: 96px 20px 72px; }
.hero__scroll { display: none; }
.hero__actions { flex-direction: column; align-items: stretch; gap: 12px; }
}
/* ═══════════════════════════════════════════════════════════
§3 — AWARD-WINNING INTRO
Belle: 2-col split, text left (credentials list + CTA),
large photo right. White/light background.
═══════════════════════════════════════════════════════════ */
.intro {
background: var(--white);
padding: 120px 0;
}
.intro__grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 100px;
align-items: center;
}
.intro__label { margin-bottom: 18px; }
.intro__h2 { margin-bottom: 24px; }
.intro__body {
font-size: 16px;
font-weight: 300;
color: var(--text-muted);
line-height: 1.8;
margin-bottom: 36px;
}
/* Credential list — exactly like Belle's bullet credentials */
.intro__creds {
display: flex;
flex-direction: column;
gap: 0;
margin-bottom: 44px;
border-top: 1px solid var(--stone);
}
.intro__cred {
display: flex;
align-items: center;
gap: 14px;
padding: 13px 0;
border-bottom: 1px solid var(--stone);
font-size: 14px;
font-weight: 400;
color: var(--text);
letter-spacing: .01em;
}
.intro__cred-icon {
width: 18px; height: 18px;
flex-shrink: 0;
color: var(--gold);
}
.intro__cred-icon svg {
width: 18px; height: 18px;
stroke: var(--gold);
fill: none;
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
}
/* Right: photo with gold accent */
.intro__media {
position: relative;
}
.intro__photo {
width: 100%;
aspect-ratio: 3/4;
border-radius: var(--r-sm);
background: url('./client-assets/2/brent-carter_1776112078758.avif') center/cover no-repeat;
position: relative;
overflow: hidden;
box-shadow: 0 20px 60px rgba(28,25,22,.2);
}
/* Subtle overlay for readability */
.intro__photo::after {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(180deg, transparent 50%, rgba(28,25,22,.35) 100%);
}
/* Gold corner accent — like RH's image treatment */
.intro__media::before {
content: '';
position: absolute;
bottom: -20px;
left: -20px;
width: 55%;
height: 55%;
border: 1.5px solid var(--gold);
border-radius: var(--r-sm);
opacity: .28;
z-index: -1;
}
/* Founder overlay badge */
.intro__badge {
position: absolute;
bottom: 28px;
right: -20px;
background: var(--charcoal);
color: var(--white);
padding: 16px 20px;
border-radius: var(--r-sm);
box-shadow: 0 8px 32px rgba(28,25,22,.45);
min-width: 148px;
}
.intro__badge-name {
font-family: var(--serif);
font-size: 16px;
font-weight: 500;
color: var(--white);
margin-bottom: 3px;
line-height: 1.2;
}
.intro__badge-title {
font-size: 10px;
font-weight: 500;
letter-spacing: .11em;
text-transform: uppercase;
color: rgba(255,255,255,.5);
}
@media (max-width: 960px) {
.intro { padding: 80px 0; }
.intro__grid { grid-template-columns: 1fr; gap: 64px; }
.intro__media { max-width: 560px; }
.intro__badge { right: 0; bottom: 20px; }
}
/* ═══════════════════════════════════════════════════════════
§4 — SERVICES GRID
Belle: centered header + 3-column card grid
Each card: tall photo (portrait) + category label + link
═══════════════════════════════════════════════════════════ */
.services {
background: #869BAF;
padding: 120px 0;
}
.services__header {
text-align: center;
margin-bottom: 64px;
}
.services__header .section-label {
justify-content: center;
margin-bottom: 16px;
}
.services__header .section-label::before { background: rgba(255,255,255,0.4); }
.services__header .section-label::after {
content: '';
width: 32px; height: 1px;
background: rgba(255,255,255,0.4);
flex-shrink: 0;
}
.services__intro {
font-size: 16px;
font-weight: 300;
color: var(--text-muted);
max-width: 520px;
margin: 20px auto 0;
line-height: 1.8;
}
.services__grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 28px;
}
.svc-card {
display: block;
position: relative;
overflow: hidden;
border-radius: var(--r-sm);
box-shadow: 0 4px 24px rgba(28,25,22,.08);
transition: box-shadow .4s var(--ease), transform .4s var(--ease);
background: var(--white);
}
.svc-card:hover {
box-shadow: 0 16px 48px rgba(28,25,22,.16);
transform: translateY(-6px);
}
.svc-card__image {
width: 100%;
aspect-ratio: 2/3; /* Portrait — like Belle's service card */
position: relative;
overflow: hidden;
transition: transform .65s var(--ease);
}
.svc-card:hover .svc-card__image { transform: scale(1.07); }
.svc-card__image::after {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(180deg, transparent 50%, rgba(28,25,22,.55) 100%);
transition: opacity .4s;
}
.svc-card:hover .svc-card__image::after { opacity: .8; }
/* Individual card gradients */
.svc-card__image--1 {
background: url('./client-assets/2/IMG_8057_1775672482457.heic') center/cover no-repeat;
}
.svc-card__image--2 {
background: linear-gradient(180deg, #d4d8dc 0%, #b4bac0 30%, #8c9298 60%, #686e74 100%);
}
.svc-card__image--3 {
background: linear-gradient(225deg, #ccd8e0 0%, #a8c0cc 30%, #7898a8 60%, #506070 100%);
}
.svc-card__inner {
position: absolute;
bottom: 0; left: 0; right: 0;
padding: 28px 28px 32px;
z-index: 2;
}
.svc-card__label {
font-size: 13px;
font-weight: 500;
letter-spacing: .14em;
text-transform: uppercase;
color: #ffffff;
margin-bottom: 8px;
}
.svc-card__title {
font-family: var(--serif);
font-size: 24px;
font-weight: 500;
color: var(--white);
line-height: 1.2;
margin-bottom: 14px;
}
.svc-card__link {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 12px;
font-weight: 500;
letter-spacing: .1em;
text-transform: uppercase;
color: var(--gold-light);
transition: gap .2s;
}
.svc-card:hover .svc-card__link { gap: 10px; }
.svc-card__link::after { content: '→'; }
@media (max-width: 900px) {
.services { padding: 80px 0; }
.services__grid { grid-template-columns: 1fr; max-width: 400px; margin: 0 auto; }
}
@media (min-width: 600px) and (max-width: 900px) {
.services__grid { grid-template-columns: repeat(2, 1fr); max-width: none; }
}
/* ═══════════════════════════════════════════════════════════
§5 — OUR DIFFERENCE
Belle: 2-col — LEFT has 2 stacked images | RIGHT has
3 feature text blocks (title + paragraph each)
═══════════════════════════════════════════════════════════ */
.difference {
background: var(--white);
padding: 120px 0;
}
.difference__grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 100px;
align-items: start;
}
/* Left: 2 stacked photos */
.difference__photos {
display: grid;
grid-template-rows: auto auto;
gap: 20px;
position: relative;
}
.difference__photo {
border-radius: var(--r-sm);
overflow: hidden;
box-shadow: 0 8px 32px rgba(28,25,22,.14);
}
.difference__photo--1 {
aspect-ratio: 4/3;
background: linear-gradient(145deg, #d4d8dc 0%, #b0b8c0 40%, #8890a0 70%, #606870 100%);
}
.difference__photo--2 {
aspect-ratio: 16/9;
background: linear-gradient(135deg, #c4d8d0 0%, #a4b8b4 40%, #788e8c 70%, #546068 100%);
margin-top: 8px;
}
/* Small accent — gold square */
.difference__photos::after {
content: '';
position: absolute;
bottom: -16px;
right: -16px;
width: 80px; height: 80px;
border: 1.5px solid var(--gold);
opacity: .2;
border-radius: var(--r-sm);
z-index: -1;
}
/* Right: feature blocks */
.difference__features {
display: flex;
flex-direction: column;
gap: 48px;
padding-top: 20px;
}
.diff-feature__num {
font-size: 11px;
font-weight: 500;
letter-spacing: .16em;
color: var(--gold);
text-transform: uppercase;
margin-bottom: 12px;
}
.diff-feature__title {
font-family: var(--serif);
font-size: 24px;
font-weight: 500;
color: var(--text);
line-height: 1.25;
margin-bottom: 14px;
}
.diff-feature__body {
font-size: 15px;
font-weight: 300;
color: var(--text-muted);
line-height: 1.8;
}
.difference__header {
margin-bottom: 20px;
}
@media (max-width: 960px) {
.difference { padding: 80px 0; }
.difference__grid { grid-template-columns: 1fr; gap: 64px; }
}
/* ═══════════════════════════════════════════════════════════
§6 — OUR PROCESS
Belle: Full-width dark bg image, centered header,
3 numbered steps in a row
═══════════════════════════════════════════════════════════ */
.process {
position: relative;
padding: 120px 0;
overflow: hidden;
}
/* Dark bathroom texture bg */
.process__bg {
position: absolute;
inset: 0;
background:
linear-gradient(155deg, rgba(28,25,22,.92) 0%, rgba(28,25,22,.88) 100%),
linear-gradient(225deg, #1a1810 0%, #2e2820 30%, #4a4035 60%, #3a3028 100%);
}
.process__bg::after {
content: '';
position: absolute;
inset: 0;
background-image:
repeating-linear-gradient(0deg, rgba(255,255,255,.04) 0px, transparent 1px, transparent 59px, rgba(255,255,255,.04) 60px),
repeating-linear-gradient(90deg, rgba(255,255,255,.04) 0px, transparent 1px, transparent 59px, rgba(255,255,255,.04) 60px);
}
.process__inner {
position: relative;
z-index: 1;
}
.process__header {
text-align: center;
margin-bottom: 80px;
}
.process__header .section-label {
color: var(--gold);
justify-content: center;
margin-bottom: 16px;
}
.process__header .section-label::before { background: var(--gold); }
.process__header .section-label::after {
content: '';
width: 32px; height: 1px;
background: var(--gold);
}
.process__sub {
font-size: 16px;
font-weight: 300;
color: rgba(255,255,255,.5);
max-width: 520px;
margin: 20px auto 0;
line-height: 1.8;
}
/* Steps row — like Belle's 3-step layout */
.process__steps {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 0;
position: relative;
}
/* Connecting line */
.process__steps::before {
content: '';
position: absolute;
top: 34px;
left: 14%;
right: 14%;
height: 1px;
background: linear-gradient(90deg, transparent, rgba(255,255,255,.35) 15%, rgba(255,255,255,.35) 85%, transparent);
}
.proc-step {
text-align: center;
padding: 0 32px;
}
.proc-step__body { text-align: left; }
.proc-step__num {
display: inline-flex;
align-items: center;
justify-content: center;
width: 68px; height: 68px;
border-radius: 50%;
border: 1px solid rgba(255,255,255,.3);
background: #1c1916;
font-family: var(--serif);
font-size: 28px;
font-weight: 400;
color: #ffffff;
margin: 0 auto 32px;
position: relative;
z-index: 1;
transition: background .3s, border-color .3s;
}
.proc-step:hover .proc-step__num {
background: rgba(255,255,255,.08);
border-color: rgba(255,255,255,.6);
}
.proc-step__label {
font-size: 10px;
font-weight: 500;
letter-spacing: .18em;
text-transform: uppercase;
color: var(--gold);
margin-bottom: 10px;
}
.proc-step__title {
font-family: var(--serif);
font-size: 22px;
font-weight: 500;
color: var(--white);
line-height: 1.25;
margin-bottom: 14px;
}
.proc-step__body {
font-size: 14px;
font-weight: 300;
color: rgba(255,255,255,.5);
line-height: 1.8;
}
@media (max-width: 900px) {
.process { padding: 80px 0; }
.process__steps { grid-template-columns: 1fr; gap: 0; }
.process__steps::before { display: none; }
.proc-step {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
padding: 0 0 40px;
}
.proc-step__num { margin: 0 auto 20px; }
.proc-step__body { text-align: center; }
}
/* ═══════════════════════════════════════════════════════════
§7 — FEATURED PROJECTS
Belle: section header + carousel of project tiles
Each tile: image + location overlay + play/view icon
═══════════════════════════════════════════════════════════ */
.projects {
background: var(--off-white);
padding: 120px 0;
}
.projects__header {
display: flex;
align-items: flex-end;
justify-content: space-between;
margin-bottom: 56px;
gap: 24px;
}
.projects__header-left .section-label { margin-bottom: 16px; }
.projects__grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
.proj-card {
position: relative;
border-radius: var(--r-sm);
overflow: hidden;
aspect-ratio: 4/3;
cursor: pointer;
box-shadow: 0 4px 20px rgba(28,25,22,.1);
transition: box-shadow .4s var(--ease), transform .4s var(--ease);
}
.proj-card:hover {
box-shadow: 0 16px 48px rgba(28,25,22,.2);
transform: translateY(-4px);
}
.proj-card__bg {
position: absolute;
inset: 0;
transition: transform .6s var(--ease);
}
.proj-card:hover .proj-card__bg { transform: scale(1.04); }
.proj-card__bg--1 {
background: linear-gradient(145deg, #d8dde2 0%, #b8c0c8 40%, #909aa4 70%, #686e78 100%);
}
.proj-card__bg--2 {
background: linear-gradient(200deg, #d0d8e0 0%, #b0bcc8 35%, #8898a8 65%, #607080 100%);
}
.proj-card__bg--3 {
background: linear-gradient(160deg, #d4d8dc 0%, #b4bcc4 35%, #8c98a0 65%, #687078 100%);
}
.proj-card__bg--4 {
background: linear-gradient(130deg, #d2d6da 0%, #b4bcc4 35%, #8c949c 65%, #686e78 100%);
}
.proj-card__bg--5 {
background: linear-gradient(225deg, #d8e0d8 0%, #b8c8b8 35%, #8ca88c 65%, #647064 100%);
}
.proj-card__bg--6 {
background: linear-gradient(170deg, #d4d8de 0%, #b8bec6 35%, #9098a0 65%, #687078 100%);
}
.proj-card__overlay {
position: absolute;
inset: 0;
background: linear-gradient(180deg, transparent 40%, rgba(28,25,22,.72) 100%);
transition: background .4s;
}
.proj-card:hover .proj-card__overlay {
background: linear-gradient(180deg, rgba(28,25,22,.15) 0%, rgba(28,25,22,.8) 100%);
}
.proj-card__info {
position: absolute;
bottom: 0; left: 0; right: 0;
padding: 24px 24px 28px;
}
.proj-card__location {
font-size: 10px;
font-weight: 500;
letter-spacing: .16em;
text-transform: uppercase;
color: var(--gold-light);
margin-bottom: 6px;
}
.proj-card__name {
font-family: var(--serif);
font-size: 20px;
font-weight: 500;
color: var(--white);
line-height: 1.25;
}
.proj-card__tag {
display: inline-block;
font-size: 11px;
font-weight: 400;
color: rgba(255,255,255,.5);
margin-top: 4px;
}
/* View all CTA below grid */
.projects__cta {
text-align: center;
margin-top: 52px;
}
@media (max-width: 900px) {
.projects { padding: 80px 0; }
.projects__header { flex-direction: column; align-items: flex-start; }
.projects__grid { grid-template-columns: 1fr; }
.gallery-slider__grid { grid-template-columns: 1fr !important; }
}
@media (min-width: 600px) and (max-width: 900px) {
.projects__grid { grid-template-columns: repeat(2, 1fr); }
.gallery-slider__grid { grid-template-columns: repeat(2, 1fr) !important; }
}
/* ── Gallery Slider ── */
.gallery-slider { margin-top: 48px; }
.gallery-slider__label {
font-family: var(--sans);
font-size: 11px;
letter-spacing: .14em;
text-transform: uppercase;
color: var(--stone-dark);
margin-bottom: 20px;
}
.gallery-slider__grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
.gallery-slider__controls {
display: flex;
align-items: center;
justify-content: center;
gap: 16px;
margin-top: 32px;
}
.gallery-slider__btn {
width: 44px;
height: 44px;
border-radius: 50%;
border: 1px solid var(--stone-mid);
background: var(--white);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: background .2s, border-color .2s, color .2s;
color: var(--charcoal);
}
.gallery-slider__btn:hover { background: var(--charcoal); border-color: var(--charcoal); color: var(--white); }
.gallery-slider__btn svg { width: 18px; height: 18px; }
.gallery-dots { display: flex; gap: 8px; align-items: center; }
.gallery-dot {
width: 8px; height: 8px;
border-radius: 50%;
background: var(--stone-mid);
border: none;
cursor: pointer;
padding: 0;
transition: background .2s, transform .2s;
}
.gallery-dot.active { background: var(--charcoal); transform: scale(1.3); }
/* ── Contact form additions ── */
.file-upload-trigger {
display: flex;
align-items: center;
gap: 10px;
width: 100%;
padding: 11px 14px;
border: 1px solid var(--stone);
border-radius: var(--r-sm);
background: var(--white);
font-family: var(--sans);
font-size: 14px;
color: var(--text-muted);
cursor: pointer;
transition: border-color .2s, color .2s;
box-sizing: border-box;
margin-bottom: 16px;
}
.file-upload-trigger:hover { border-color: var(--gold); color: var(--text); }
.file-upload-trigger svg { flex-shrink: 0; opacity: .55; }
.cta-phone-btn {
display: inline-flex;
align-items: center;
gap: 10px;
padding: 16px 36px;
background: var(--gold);
color: var(--white);
border: 1.5px solid var(--gold);
border-radius: var(--r-sm);
font-family: var(--sans);
font-size: 17px;
font-weight: 500;
text-decoration: none;
margin-bottom: 32px;
transition: background .25s, border-color .25s;
}
.cta-phone-btn:hover { background: var(--gold-dark); border-color: var(--gold-dark); }
.cta-phone-btn svg { flex-shrink: 0; }
.btn-call-outline {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 14px 28px;
border: 1px solid var(--gold);
border-radius: var(--r-sm);
font-family: var(--sans);
font-size: 15px;
font-weight: 500;
color: var(--gold);
background: transparent;
text-decoration: none;
transition: background .2s, color .2s;
margin-top: 12px;
}
.btn-call-outline:hover { background: var(--gold); color: var(--white); }
.phone-icon-sm { width: 14px; height: 14px; vertical-align: middle; margin-right: 5px; }
/* ═══════════════════════════════════════════════════════════
§8 — CLIENT TESTIMONIALS
Belle: section header + grid of review/testimonial cards
═══════════════════════════════════════════════════════════ */
.testimonials {
background: var(--white);
padding: 120px 0;
}
.testimonials__header {
text-align: center;
margin-bottom: 64px;
}
.testimonials__header .section-h2 { color: #869BAF; }
.testimonials__header .section-label {
justify-content: center;
margin-bottom: 16px;
color: #869BAF;
}
.testimonials__header .section-label::before { background: var(--gold); }
.testimonials__header .section-label::after {
content: '';
width: 32px; height: 1px;
background: var(--gold);
}
.testimonials__grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 28px;
}
.testi-card {
background: #869BAF;
border: 1px solid rgba(0,0,0,.08);
border-radius: var(--r-sm);
padding: 44px 40px;
position: relative;
transition: box-shadow .35s var(--ease), transform .35s var(--ease);
}
.testi-card:hover {
box-shadow: 0 12px 40px rgba(28,25,22,.1);
transform: translateY(-4px);
}
.testi-card__quote {
font-family: var(--serif);
font-size: 120px;
color: var(--gold);
opacity: .12;
position: absolute;
top: 8px; right: 28px;
line-height: 1;
user-select: none;
}
.testi-card__stars {
display: flex;
gap: 3px;
margin-bottom: 22px;
}
.testi-card__star {
width: 14px; height: 14px;
fill: var(--gold);
}
.testi-card__text {
font-family: var(--serif);
font-size: 17px;
font-style: italic;
font-weight: 400;
color: #ffffff;
line-height: 1.7;
margin-bottom: 32px;
}
.testi-card__rule {
width: 28px; height: 1px;
background: var(--gold);
opacity: .5;
margin-bottom: 20px;
}
.testi-card__name {
font-size: 14px;
font-weight: 500;
color: #ffffff;
letter-spacing: .02em;
margin-bottom: 3px;
}
.testi-card__loc {
font-size: 12px;
font-weight: 300;
color: rgba(255,255,255,.65);
letter-spacing: .03em;
}
/* Aggregate review bar */
.testimonials__agg {
display: flex;
align-items: center;
justify-content: center;
gap: 32px;
margin-top: 56px;
padding: 32px 40px;
background: #869BAF;
border: none;
border-radius: var(--r-sm);
flex-wrap: wrap;
}
.testimonials__agg-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
}
.testimonials__agg-num {
font-family: var(--serif);
font-size: 36px;
font-weight: 500;
color: #ffffff;
}
.testimonials__agg-label {
font-size: 12px;
font-weight: 400;
color: rgba(255,255,255,.75);
text-align: center;
letter-spacing: .04em;
}
.testimonials__agg-divider {
width: 1px; height: 48px;
background: rgba(255,255,255,.25);
}
@media (max-width: 900px) {
.testimonials { padding: 80px 0; }
.testimonials__grid { grid-template-columns: 1fr; max-width: 520px; margin: 0 auto; }
.testimonials__agg { gap: 20px; }
.testimonials__agg-divider { display: none; }
}
/* ═══════════════════════════════════════════════════════════
§9 — OUR PARTNERS / TRUST BADGES
Belle: full-width horizontal logo grid
═══════════════════════════════════════════════════════════ */
.partners {
background: var(--cream);
padding: 80px 0;
border-top: 1px solid var(--stone);
border-bottom: 1px solid var(--stone);
}
.partners__header {
text-align: center;
margin-bottom: 48px;
}
.partners__label {
font-size: 11px;
font-weight: 500;
letter-spacing: .18em;
text-transform: uppercase;
color: var(--text-muted);
}
.partners__logos {
display: flex;
align-items: center;
justify-content: center;
gap: 0;
flex-wrap: wrap;
}
.partner-logo {
flex: 1;
min-width: 140px;
max-width: 200px;
padding: 20px 32px;
display: flex;
align-items: center;
justify-content: center;
border-right: 1px solid var(--stone-mid);
}
.partner-logo:last-child { border-right: none; }
.partner-logo span {
font-family: var(--serif);
font-size: 16px;
font-weight: 400;
color: var(--stone-dark);
letter-spacing: .06em;
text-align: center;
line-height: 1.4;
}
@media (max-width: 700px) {
.partners { padding: 60px 0; }
.partners__logos { gap: 0; }
.partner-logo {
min-width: 50%;
max-width: 50%;
border-bottom: 1px solid var(--stone-mid);
}
}
/* ═══════════════════════════════════════════════════════════
§10 — CTA BAND
═══════════════════════════════════════════════════════════ */
.cta-band {
background: var(--charcoal);
padding: 100px 0;
text-align: center;
position: relative;
overflow: hidden;
}
.cta-band::before {
content: '';
position: absolute;
inset: 0;
background: radial-gradient(ellipse 60% 80% at 50% 50%, rgba(255,255,255,.06) 0%, transparent 70%);
}
.cta-band__inner { position: relative; z-index: 1; }
.cta-band__label {
display: inline-flex;
align-items: center;
gap: 16px;
font-size: 11px;
font-weight: 500;
letter-spacing: .2em;
text-transform: uppercase;
color: var(--gold);
margin-bottom: 24px;
justify-content: center;
}
.cta-band__label::before,
.cta-band__label::after { content: ''; width: 32px; height: 1px; background: var(--gold); opacity: .5; }
.cta-band__h2 {
font-family: var(--serif);
font-size: clamp(36px, 5vw, 58px);
font-weight: 400;
color: var(--white);
line-height: 1.15;
letter-spacing: -.02em;
max-width: 760px;
margin: 0 auto 20px;
}
.cta-band__sub {
font-size: 16px;
font-weight: 300;
color: rgba(255,255,255,.5);
max-width: 500px;
margin: 0 auto 52px;
line-height: 1.8;
}
.cta-band__actions {
display: flex;
align-items: center;
justify-content: center;
gap: 16px;
flex-wrap: wrap;
}
@media (max-width: 768px) { .cta-band { padding: 80px 0; } }
/* ═══════════════════════════════════════════════════════════
§11 — FOOTER
Belle: dark, multi-column with accreditations + awards
═══════════════════════════════════════════════════════════ */
.footer {
background: var(--charcoal-mid);
padding: 80px 0 0;
}
.footer__top {
display: grid;
grid-template-columns: 1.8fr 1fr 1fr;
gap: 64px;
padding-bottom: 64px;
border-bottom: 1px solid rgba(255,255,255,.10);
}
.footer__logo img {
height: 120px; width: auto;
filter: brightness(0) invert(1);
opacity: 1;
margin-bottom: 24px;
}
.footer__brand-addr {
font-size: 15px;
font-weight: 300;
color: #ffffff;
line-height: 1.9;
}
.footer__brand-addr a {
color: #ffffff;
transition: color .2s;
}
.footer__brand-addr a:hover { color: var(--gold-light); }
/* Social icons row */
.footer__social {
display: flex;
gap: 12px;
margin-top: 20px;
}
.footer__social-link {
display: inline-flex;
align-items: center;
justify-content: center;
width: 36px; height: 36px;
border-radius: 50%;
border: 1px solid rgba(255,255,255,.2);
color: #ffffff;
transition: border-color .2s, background .2s;
}
.footer__social-link:hover {
border-color: var(--gold);
background: rgba(255,255,255,.12);
}
.footer__social-link svg {
width: 16px; height: 16px;
stroke: currentColor;
fill: none;
stroke-width: 1.5;
stroke-linecap: round;
stroke-linejoin: round;
}
.footer__col-title {
font-size: 12px;
font-weight: 500;
letter-spacing: .16em;
text-transform: uppercase;
color: #ffffff;
margin-bottom: 32px;
}
.footer__links {
display: flex;
flex-direction: column;
gap: 14px;
}
.footer__links a {
font-size: 15px;
font-weight: 300;
color: #ffffff;
line-height: 1.5;
transition: color .2s;
}
.footer__links a:hover { color: var(--gold-light); }
/* Accreditations col — like Belle's trust badges */
.footer__badges {
display: flex;
flex-direction: column;
gap: 12px;
margin-top: 4px;
}
.footer__badge {
display: inline-flex;
align-items: center;
gap: 10px;
padding: 10px 14px;
border: 1px solid rgba(255,255,255,.1);
border-radius: var(--r-sm);
max-width: 200px;
}
.footer__badge-icon {
width: 20px; height: 20px;
flex-shrink: 0;
}
.footer__badge-icon svg {
width: 20px; height: 20px;
stroke: var(--gold);
fill: none;
stroke-width: 1.5;
stroke-linecap: round;
stroke-linejoin: round;
}
.footer__badge-text {
font-size: 13px;
font-weight: 400;
color: rgba(255,255,255,.45);
line-height: 1.3;
}
.footer__bottom {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24px 0;
gap: 16px;
flex-wrap: wrap;
}
.footer__copy {
font-size: 13px;
font-weight: 300;
color: #ffffff;
letter-spacing: .02em;
}
.footer__powered img {
height: 28px;
width: auto;
opacity: .7;
transition: opacity .2s;
display: block;
}
.footer__powered:hover img { opacity: 1; }
@media (max-width: 960px) {
.footer__top { grid-template-columns: 1fr 1fr; gap: 48px; }
}
@media (max-width: 600px) {
.footer__top { grid-template-columns: 1fr; gap: 56px; text-align: center; }
.footer__bottom { flex-direction: column; align-items: center; gap: 24px; text-align: center; }
.footer__logo { display: flex; justify-content: center; }
.footer__social { justify-content: center; }
.footer__links { align-items: center; }
.footer__brand-addr { text-align: center; }
.footer__badges { justify-content: center; }
}
/* ═══════════════════════════════════════════════════════════
CIRCULAR ROTATING TEXT BADGE
═══════════════════════════════════════════════════════════ */
.circ-badge {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
pointer-events: none;
user-select: none;
z-index: 3;
}
/* Hero placement — bottom-left corner of arch */
.hero__arch-container {
position: relative;
width: 100%;
max-width: 460px;
}
.circ-badge--hero {
bottom: -40px;
left: -80px;
width: 200px;
height: 200px;
}
.circ-badge__ring {
position: absolute;
inset: 0;
animation: circ-spin 26s linear infinite;
transition: animation-duration .4s;
}
/* Hover: hero badge speeds up on parent hover */
.hero:hover .circ-badge--hero .circ-badge__ring {
animation-duration: 10s;
}
.circ-badge__ring svg { width: 100%; height: 100%; }
.circ-badge__dot {
position: relative;
z-index: 1;
width: 28px;
height: 28px;
border-radius: 50%;
border: 1px solid rgba(255,255,255,.40);
display: flex;
align-items: center;
justify-content: center;
}
.circ-badge__dot::after {
content: '';
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--gold);
}
.circ-badge__logo-img {
position: relative;
z-index: 1;
width: 155px;
height: auto;
filter: brightness(0) invert(1);
opacity: 0.95;
margin-top: 10px;
padding-bottom: 6px;
}
@keyframes circ-spin {
to { transform: rotate(360deg); }
}
@media (max-width: 900px) {
.circ-badge--hero { bottom: -70px; left: -70px; }
}
@media (max-width: 768px) {
.circ-badge--hero {
width: 185px;
height: 185px;
bottom: -60px;
left: -60px;
}
.circ-badge--hero .circ-badge__logo-img { width: 98px; }
}
@media (max-width: 600px) {
.circ-badge--hero {
width: 170px;
height: 170px;
bottom: -55px;
left: 50%;
transform: translateX(-50%);
}
.circ-badge--hero .circ-badge__logo-img { width: 88px; }
}
/* ═══════════════════════════════════════════════════════════
FAQ SECTION
═══════════════════════════════════════════════════════════ */
.faq {
background: var(--off-white);
padding: 100px 0;
}
.faq__header {
text-align: center;
margin-bottom: 56px;
}
.faq__header .section-label {
justify-content: center;
margin-bottom: 16px;
}
.faq__header .section-label::before { background: var(--gold); opacity: .5; }
.faq__header .section-label::after {
content: ''; width: 32px; height: 1px;
background: var(--gold); opacity: .5;
}
.faq__list {
max-width: 760px;
margin: 0 auto;
display: flex;
flex-direction: column;
}
.faq__item { border-bottom: 1px solid var(--stone); }
.faq__item:first-child { border-top: 1px solid var(--stone); }
.faq__q {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
gap: 24px;
padding: 24px 0;
background: none;
border: none;
cursor: pointer;
text-align: left;
font-family: var(--serif);
font-size: 18px;
font-weight: 500;
color: var(--text);
line-height: 1.3;
transition: color .2s;
}
.faq__q:hover { color: var(--gold-dark); }
.faq__icon {
position: relative;
flex-shrink: 0;
width: 22px; height: 22px;
border-radius: 50%;
border: 1px solid var(--stone-mid);
display: flex; align-items: center; justify-content: center;
transition: border-color .25s, background .25s, transform .35s var(--ease-out);
}
.faq__icon::before,
.faq__icon::after {
content: '';
position: absolute;
background: var(--text-muted);
border-radius: 1px;
transition: background .25s;
}
.faq__icon::before { width: 10px; height: 1.5px; }
.faq__icon::after { width: 1.5px; height: 10px; }
.faq__item.open .faq__icon {
border-color: var(--gold);
background: var(--gold);
transform: rotate(45deg);
}
.faq__item.open .faq__icon::before,
.faq__item.open .faq__icon::after { background: #fff; }
.faq__a {
max-height: 0;
overflow: hidden;
transition: max-height .45s var(--ease-out);
}
.faq__a-inner {
padding: 0 0 24px;
font-size: 15px;
font-weight: 300;
color: var(--text-muted);
line-height: 1.85;
max-width: 640px;
}
@media (max-width: 768px) {
.faq { padding: 72px 0; }
.faq__q { font-size: 16px; padding: 20px 0; }
}
/* ═══════════════════════════════════════════════════════════
SCROLL ANCHOR OFFSET
═══════════════════════════════════════════════════════════ */
#about, #services, #gallery, #process, #testimonials, #contact {
scroll-margin-top: 78px;
}
/* ── DYNAMIC CONTENT FALLBACKS ──────────────────── */
.svc-card__image--fallback {
background: linear-gradient(145deg, #2a2420 0%, #7a6850 100%);
}
.proj-card__bg--fallback {
background: linear-gradient(145deg, #1e1c18 0%, #685a4a 100%);
}
.testi-card__star.empty { opacity: 0.2; }
/* ── CONTACT FORM ────────────────────────────────── */
.contact-form {
max-width: 560px;
margin: 0 auto 8px;
display: flex;
flex-direction: column;
gap: 12px;
}
.contact-form__row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.contact-form input,
.contact-form select,
.contact-form textarea {
width: 100%;
padding: 12px 16px;
border-radius: 6px;
border: 1px solid rgba(255,255,255,.18);
background: rgba(255,255,255,.07);
color: #fff;
font-family: var(--sans);
font-size: 15px;
outline: none;
transition: border-color 0.2s;
}
.contact-form input:focus,
.contact-form select:focus,
.contact-form textarea:focus { border-color: var(--gold); }
.contact-form select option { background: var(--charcoal); color: #fff; }
.contact-form textarea { resize: vertical; min-height: 100px; }
.contact-form__confirm {
color: var(--gold-light);
text-align: center;
font-size: 15px;
margin-top: 4px;
}
@media (max-width: 600px) {
.contact-form__row { grid-template-columns: 1fr; }
}
/* ── Lightbox ─────────────────────────────────────── */
.lb-overlay { display:none; position:fixed; inset:0; z-index:9000; background:rgba(0,0,0,.92); align-items:center; justify-content:center; }
.lb-overlay.is-open { display:flex; }
.lb-img { max-width:92vw; max-height:88vh; object-fit:contain; border-radius:4px; }
.lb-close { position:absolute; top:20px; right:24px; background:none; border:none; color:#fff; font-size:36px; line-height:1; cursor:pointer; opacity:.7; }
.lb-close:hover { opacity:1; }
.lb-prev, .lb-next { position:absolute; top:50%; transform:translateY(-50%); background:rgba(255,255,255,.12); border:none; color:#fff; font-size:32px; padding:10px 16px; cursor:pointer; border-radius:4px; transition:background .2s; user-select:none; }
.lb-prev { left:16px; }
.lb-next { right:16px; }
.lb-prev:hover, .lb-next:hover { background:rgba(255,255,255,.28); }
.proj-card { cursor:pointer; }
/* ── Mobile gallery — horizontal swipe ───────────── */
@media (max-width: 768px) {
.gallery-slider__grid {
display: flex;
flex-wrap: nowrap;
overflow-x: auto;
scroll-snap-type: x mandatory;
-webkit-overflow-scrolling: touch;
gap: 12px;
padding-bottom: 8px;
}
.gallery-slider__grid .proj-card {
flex: 0 0 82vw !important;
scroll-snap-align: start;
height: 420px !important;
display: flex !important; /* override JS pagination hiding */
}
.gallery-slider__controls { display: none; }
}
</style>
</head>
<body>
<!-- ══════════════════════════════════════════════
§1 — NAVIGATION
Sticky white, transparent on hero
══════════════════════════════════════════════ -->
<header class="nav hero-mode" id="mainNav" role="banner">
<div class="wrap">
<div class="nav__inner">
<a href="/" class="nav__logo" aria-label="Dream Bath — Home">
<img src="./dream_bath.svg" alt="Dream Bath" />
</a>
<nav class="nav__links" aria-label="Main navigation">
<a href="#about">About</a>
<a href="#services">Services</a>
<a href="#gallery">Portfolio</a>
<a href="#process">Process</a>
<a href="#testimonials">Testimonials</a>
<a href="#contact">Contact</a>
</nav>
<div class="nav__right">
<a href="tel:+18124557384" class="nav__phone"><svg class="phone-icon-sm" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.69 13a19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 3.6 2h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L7.91 9.91a16 16 0 0 0 6.09 6.09l.95-.95a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 22 16.92z"/></svg>(812) 455-7384</a>
<a href="#contact" class="nav__cta">Get a Free Quote</a>
<button class="nav__ham" id="navHam" aria-label="Open menu" aria-expanded="false">
<span></span><span></span><span></span>
</button>
</div>
</div>
</div>
<!-- Mobile drawer -->
<nav class="nav__drawer" id="navDrawer" aria-label="Mobile menu">
<a href="#about">About</a>
<a href="#services">Services</a>
<a href="#gallery">Portfolio</a>
<a href="#process">Process</a>
<a href="#testimonials">Testimonials</a>
<a href="#contact" style="font-weight:500;color:var(--gold);">Get a Free Quote →</a>
<a href="tel:+18124557384" style="display:flex;align-items:center;gap:10px;font-weight:500;color:var(--text);border-bottom:none;margin-top:8px;">
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="flex-shrink:0;color:var(--gold)"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.69 13a19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 3.6 2h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L7.91 9.91a16 16 0 0 0 6.09 6.09l.95-.95a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 22 16.92z"/></svg>
(812) 455-7384
</a>
</nav>
</header>
<main>
<!-- ══════════════════════════════════════════════
§2 — HERO SLIDER
Full-viewport, cycling bg, centered serif H1,
CTA pair, slide dots, scroll hint
══════════════════════════════════════════════ -->
<section class="hero" aria-label="Dream Bath — Bathroom Remodeling">
<!-- Cycling background layers -->
<div class="hero__bg hero__bg--1 active" aria-hidden="true"></div>
<div class="hero__bg hero__bg--2" aria-hidden="true"></div>
<div class="hero__bg hero__bg--3" aria-hidden="true"></div>
<div class="hero__logo-wm" aria-hidden="true">
<img src="./dream_bath.svg" alt="">
</div>
<div class="hero__overlay" aria-hidden="true"></div>
<!-- Constrained inner grid -->
<div class="hero__inner">
<!-- LEFT: text -->
<div class="hero__text">
<p class="hero__eyebrow reveal">Showers & Bathrooms — Remodeling · Evansville, IN</p>
<h1 class="hero__h1 reveal d1" id="hero-h1">
Your bathroom,<br>
<em>reimagined</em><br>
with precision.
</h1>
<p class="hero__sub reveal d2" id="hero-sub">
Dream Bath brings 25 years of construction mastery and an artist's eye to every project — bathrooms as beautiful as they are enduring.
</p>
<div class="hero__actions reveal d3">
<a href="tel:+18124557384" class="btn btn-gold"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:middle;margin-right:7px;flex-shrink:0"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.69 13a19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 3.6 2h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L7.91 9.91a16 16 0 0 0 6.09 6.09l.95-.95a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 22 16.92z"/></svg>Call us for a Consultation</a>
<a href="#gallery" class="btn btn-outline-white">Explore Our Work</a>
</div>
</div>
<!-- RIGHT: arch image + circular badge -->
<div class="hero__arch-wrap">
<div class="hero__arch-container">
<div class="hero__arch" aria-hidden="true">
<div class="hero__arch-img hero__arch-img--1 active"></div>
<div class="hero__arch-img hero__arch-img--2"></div>
<div class="hero__arch-img hero__arch-img--3"></div>
</div>
<div class="circ-badge circ-badge--hero" aria-hidden="true">
<div class="circ-badge__ring">
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<defs>
<path id="hero-circle"
d="M 100,100 m -82,0 a 82,82 0 1,1 164,0 a 82,82 0 1,1 -164,0"/>
</defs>
<text font-size="14" font-family="DM Sans, sans-serif"
font-weight="500"
fill="rgba(255,255,255,0.75)">
<textPath href="#hero-circle" startOffset="0%"
textLength="510" lengthAdjust="spacing">
25 YEARS · CRAFTSMANSHIP · DREAM BATH · EVANSVILLE IN ·
</textPath>
</text>
</svg>
</div>
<img class="circ-badge__logo-img" src="./dream_bath.svg" alt="Dream Bath" />
</div>
</div>
</div>
</div><!-- end .hero__inner -->
<!-- Scroll hint -->
<div class="hero__scroll" aria-hidden="true">
<div class="hero__scroll-line"></div>
</div>
</section>
<!-- ══════════════════════════════════════════════
§3 — AWARD-WINNING INTRO
Left: credentials list + CTA | Right: photo + badge
══════════════════════════════════════════════ -->
<section class="intro" id="about" aria-label="About Dream Bath">
<div class="wrap">
<div class="intro__grid">
<!-- Left: text -->
<div>
<p class="section-label intro__label reveal">Precision Craftsmanship</p>
<h2 class="section-h2 intro__h2 reveal d1">
Evansville's premier<br>bathroom renovation<br>specialists.
</h2>
<p class="intro__body reveal d2">
With 25 years of construction experience, Dream Bath has transformed hundreds of Evansville homes — from modest refresh projects to complete master suite reinventions. As a licensed General Contractor, we self-perform all critical work in-house, ensuring quality at every stage.
</p>
<!-- Credential list — matching Belle's structured list format -->
<ul class="intro__creds reveal d3" aria-label="Credentials and certifications">
<li class="intro__cred">
<span class="intro__cred-icon" aria-hidden="true">
<svg viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg>
</span>
Licensed General Contractor — Indiana
</li>
<li class="intro__cred">
<span class="intro__cred-icon" aria-hidden="true">
<svg viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg>
</span>
Fully Bonded & Insured
</li>
<li class="intro__cred">
<span class="intro__cred-icon" aria-hidden="true">
<svg viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg>
</span>
Transparent, Fixed-Price Quotes
</li>
<li class="intro__cred">
<span class="intro__cred-icon" aria-hidden="true">
<svg viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg>
</span>
All Permits Arranged & Code-Compliant
</li>
<li class="intro__cred">
<span class="intro__cred-icon" aria-hidden="true">
<svg viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg>
</span>
100% Referral-Built Reputation
</li>
</ul>
<a href="tel:+18124557384" class="btn btn-solid reveal d4"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:middle;margin-right:7px;flex-shrink:0"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.69 13a19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 3.6 2h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L7.91 9.91a16 16 0 0 0 6.09 6.09l.95-.95a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 22 16.92z"/></svg>Call Us Today</a>
</div>
<!-- Right: photo -->
<div class="intro__media reveal d2">
<div class="intro__photo" role="img" aria-label="Bathroom renovation by Dream Bath"></div>
<div class="intro__badge reveal d3">
<p class="intro__badge-name">Brent Carter</p>
<p class="intro__badge-title">Founder & Owner</p>
</div>
</div>
</div>
</div>
</section>
<!-- ══════════════════════════════════════════════
§4 — SERVICES GRID
Centered header + 3 tall portrait cards
══════════════════════════════════════════════ -->
<section class="services" id="services" aria-label="Our services">
<div class="wrap">
<header class="services__header">
<p class="section-label reveal">Our Services</p>
<h2 class="section-h2 reveal d1">Every space. Every vision.<br>Flawlessly executed.</h2>
<p class="services__intro reveal d2">
From master suite transformations to guest bath makeovers — the same precision and attention to detail on every project.
</p>
</header>
<div class="services__grid" id="services-grid">
<a href="#contact" class="svc-card reveal">
<div class="svc-card__image" style="background:url('./client-assets/2/IMG_1887_1775672482431.jpg') center/cover no-repeat"></div>
<div class="svc-card__inner">
<p class="svc-card__label">Complete Renovation</p>
<h3 class="svc-card__title">Full Bathroom<br>Remodeling</h3>
</div>
</a>
<a href="#contact" class="svc-card reveal d1">
<div class="svc-card__image" style="background:url('./client-assets/2/IMG_8363_1775672482458.jpg') center/cover no-repeat"></div>
<div class="svc-card__inner">
<p class="svc-card__label">Shower & Spa</p>
<h3 class="svc-card__title">Shower & Wet Room Design</h3>
</div>
</a>
<a href="#contact" class="svc-card reveal d2">
<div class="svc-card__image" style="background:url('./client-assets/2/IMG_7836_1775672482453.jpg') center/cover no-repeat"></div>
<div class="svc-card__inner">
<p class="svc-card__label">Fixtures</p>
<h3 class="svc-card__title">Tub Replacement</h3>
</div>
</a>
</div>
</div>
</section>
<!-- ══════════════════════════════════════════════
§6 — OUR PROCESS
Full-bleed dark bg, centered header,
4 numbered steps in a row
══════════════════════════════════════════════ -->
<section class="process" id="process" aria-label="Our renovation process">
<div class="process__bg" aria-hidden="true"></div>
<div class="wrap process__inner">
<header class="process__header">
<p class="section-label reveal" style="justify-content:center;color:var(--gold);">Our Process</p>
<h2 class="section-h2 section-h2--light reveal d1">
A seamless renovation,<br>from first call to final reveal.
</h2>
<p class="process__sub reveal d2">
Four clear stages. Complete transparency. A bathroom you'll love — delivered on the day we promised.
</p>
</header>
<div class="process__steps" role="list">
<div class="proc-step reveal" role="listitem">
<div class="proc-step__num" aria-hidden="true">01</div>
<p class="proc-step__label">Discovery</p>
<h3 class="proc-step__title">Creating the Master Plan</h3>
<p class="proc-step__body">We begin with a no-pressure discovery call to understand your space, style direction, and budget. Our job at this stage is to listen — and make everything feel possible.</p>
</div>
<div class="proc-step reveal d1" role="listitem">
<div class="proc-step__num" aria-hidden="true">02</div>
<p class="proc-step__label">Assessment</p>
<h3 class="proc-step__title">The Choice Is Yours</h3>
<p class="proc-step__body">We visit your home, measure, and build a detailed project scope with full transparent pricing. You'll know every cost, every material, and every timeline milestone before we begin.</p>
</div>
<div class="proc-step reveal d2" role="listitem">
<div class="proc-step__num" aria-hidden="true">03</div>
<p class="proc-step__label">Installation</p>
<h3 class="proc-step__title">Let the Magic Begin</h3>
<p class="proc-step__body">Our licensed crew arrives on day one and doesn't leave until every tile, fixture, and finish meets our exacting standard. Your renovation is treated like it's our own home.</p>
</div>
<div class="proc-step reveal d3" role="listitem">
<div class="proc-step__num" aria-hidden="true">04</div>
<p class="proc-step__label">Reveal</p>
<h3 class="proc-step__title">Your Dream Delivered</h3>
<p class="proc-step__body">We walk you through every detail of the finished space. You don't pay the final invoice until you're completely satisfied. That's our promise — and we've never broken it.</p>
</div>
</div>
</div>
</section>
<!-- ══════════════════════════════════════════════
§7 — FEATURED PROJECTS
Section header + 2×3 project grid
══════════════════════════════════════════════ -->
<section class="projects" id="gallery" aria-label="Featured renovation projects">
<div class="wrap">
<div class="projects__header">
<div class="projects__header-left">
<p class="section-label reveal">Our Portfolio</p>
<h2 class="section-h2 reveal d1">Featured projects.</h2>
</div>
<a href="tel:+18124557384" class="btn btn-outline-dark reveal d2" style="flex-shrink:0;"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:middle;margin-right:7px;flex-shrink:0"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.69 13a19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 3.6 2h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L7.91 9.91a16 16 0 0 0 6.09 6.09l.95-.95a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 22 16.92z"/></svg>Call Us Today</a>
</div>
<div class="projects__grid" id="portfolio-grid">
<!-- content pre-rendered -->
</div>
<!-- Extended gallery — all available project photos with pagination -->
<div class="gallery-slider" id="gallery-slider">
<p class="gallery-slider__label">Browse All Projects</p>
<div class="gallery-slider__grid" id="gallery-track">
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_2241_1776439541990.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_8363_1776439542128.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_8057_1776439542121.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_8375_1776439542139.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_1882_1776439541935.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_1886_1776439541961.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_3898_1776439542047.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_2240_1776439541983.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_6091_1776439542091.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_0343_1776439541885.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_1102_1776439541897.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_8378_1776439542146.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_8379_1776439542154.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_8053_1776439542101.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_8055_1776439542113.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_1883_1776439541944.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_1885_1776439541953.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_1887_1776439541966.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_2239_1776439541976.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_2242_1776439541997.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_2243_1776439542005.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_2520_1776439542012.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_2534_1776439542027.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_2565_1776439542037.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_2574_1776439542037.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_3899_1776439542057.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_3915_1776439542067.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_3916_1776439542071.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_5121_1776439542081.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_0088_1776439541859.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_0090_1776439541867.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_0101_1776439541877.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_1659_1776439541905.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_1759_1776439541911.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_1761_1776439541917.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_1762_1776439541923.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/IMG_1763_1776439541929.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/60014056480__7661E3AA-BA70-4436-A116-BD3AB1D70589_1776439541809.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
<article class="proj-card"><div class="proj-card__bg" style="background:url('./client-assets/dream-bath/66482847232__8BA88003-E85B-461A-8B98-B6FB2808F150_1776439541842.avif') center/cover no-repeat"></div><div class="proj-card__overlay"></div></article>
</div>
<div class="gallery-slider__controls">
<button class="gallery-slider__btn" id="gallery-prev" aria-label="Previous page">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"/></svg>
</button>
<div class="gallery-dots" id="gallery-dots"></div>
<button class="gallery-slider__btn" id="gallery-next" aria-label="Next page">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>
</button>
</div>
</div>
</div>
</section>
<!-- ══════════════════════════════════════════════
§8 — CLIENT TESTIMONIALS
Section header + 3 quote cards + aggregate bar
══════════════════════════════════════════════ -->
<section class="testimonials" id="testimonials" aria-label="Client testimonials">
<div class="wrap">
<header class="testimonials__header">
<p class="section-label reveal">Client Testimonials</p>
<h2 class="section-h2 reveal d1">Our Reviews</h2>
</header>
<div class="testimonials__grid" id="testimonials-grid">
<article class="testi-card reveal">
<div class="testi-card__quote" aria-hidden="true">"</div>
<div class="testi-card__stars" aria-label="5 stars"><svg class="testi-card__star" viewBox="0 0 24 24"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg><svg class="testi-card__star" viewBox="0 0 24 24"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg><svg class="testi-card__star" viewBox="0 0 24 24"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg><svg class="testi-card__star" viewBox="0 0 24 24"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg><svg class="testi-card__star" viewBox="0 0 24 24"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg></div>
<p class="testi-card__text">Brent and his team are professional, on time and detail driven. I highly recommend these guys for your next tile project.</p>
<div class="testi-card__rule" aria-hidden="true"></div>
<div class="testi-card__name">Rick Schilb</div>
<div class="testi-card__loc"></div>
</article>
<article class="testi-card reveal d1">
<div class="testi-card__quote" aria-hidden="true">"</div>
<div class="testi-card__stars" aria-label="5 stars"><svg class="testi-card__star" viewBox="0 0 24 24"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg><svg class="testi-card__star" viewBox="0 0 24 24"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg><svg class="testi-card__star" viewBox="0 0 24 24"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg><svg class="testi-card__star" viewBox="0 0 24 24"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg><svg class="testi-card__star" viewBox="0 0 24 24"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg></div>
<p class="testi-card__text">Beautiful bathroom remodel. Brent was very detail oriented and was anxious to please. The walkin shower is the best bathing option i have ever had. The rain shower head, personal sprayer, comfortable seating and dimmable lights makes for a pleasurable experience. Thank you Brent!</p>
<div class="testi-card__rule" aria-hidden="true"></div>
<div class="testi-card__name">Cathy Carter</div>
<div class="testi-card__loc"></div>
</article>
<article class="testi-card reveal d2">
<div class="testi-card__quote" aria-hidden="true">"</div>
<div class="testi-card__stars" aria-label="5 stars"><svg class="testi-card__star" viewBox="0 0 24 24"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg><svg class="testi-card__star" viewBox="0 0 24 24"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg><svg class="testi-card__star" viewBox="0 0 24 24"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg><svg class="testi-card__star" viewBox="0 0 24 24"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg><svg class="testi-card__star" viewBox="0 0 24 24"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg></div>
<p class="testi-card__text">Such a great family owned business! They did a full bathroom remodel for us and installed a tile shower and tub that looks amazing! Would recommend to anyone wanting to find a trustworthy and reliable contractor.</p>
<div class="testi-card__rule" aria-hidden="true"></div>
<div class="testi-card__name">Hope Carrier</div>
<div class="testi-card__loc"></div>
</article>
<!-- populated by dynamic loader -->
</div>
<!-- Aggregate stats bar -->
<div class="testimonials__agg reveal" id="stats-bar" aria-label="Review statistics">
<div class="testimonials__agg-item">
<span class="testimonials__agg-num">5.0</span>
<span class="testimonials__agg-label">Google Rating</span>
</div>
<div class="testimonials__agg-divider" aria-hidden="true"></div>
<div class="testimonials__agg-item">
<span class="testimonials__agg-num">100%</span>
<span class="testimonials__agg-label">Satisfaction Rate</span>
</div>
<div class="testimonials__agg-divider" aria-hidden="true"></div>
<div class="testimonials__agg-item">
<span class="testimonials__agg-num">8/10</span>
<span class="testimonials__agg-label">Clients from Referrals</span>
</div>
</div>
</div>
</section>
<!-- ══════════════════════════════════════════════
§10 — CTA BAND
══════════════════════════════════════════════ -->
<section class="cta-band" id="contact" aria-label="Contact Dream Bath">
<div class="wrap">
<div class="cta-band__inner">
<p class="cta-band__label reveal">Start Your Project</p>
<h2 class="cta-band__h2 reveal d1">
Your dream bathroom is<br>one conversation away.
</h2>
<p class="cta-band__sub reveal d2">
No pressure. No surprises. Just honest craftsmanship and a space you'll love for decades. We respond within one business day.
</p>
<a href="tel:+18124557384" class="btn btn-gold reveal d2" style="margin-bottom:32px;">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:middle;margin-right:7px;flex-shrink:0"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.69 13a19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 3.6 2h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L7.91 9.91a16 16 0 0 0 6.09 6.09l.95-.95a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 22 16.92z"/></svg>
(812) 455-7384
</a>
<iframe name="contact-iframe" id="contact-iframe" style="display:none" aria-hidden="true"></iframe>
<form class="contact-form reveal d3" id="contact-form" action="https://formsubmit.co/dreambath.evv@gmail.com" method="POST" enctype="multipart/form-data" target="contact-iframe">
<input type="hidden" name="_subject" value="New Quote Request – Dream Bath">
<input type="hidden" name="_captcha" value="false">
<input type="hidden" name="_next" value="https://dreambath.com/thank-you">
<input type="text" name="_honey" style="display:none" tabindex="-1" autocomplete="off">
<div class="contact-form__row">
<input type="text" name="name" placeholder="Your name" required>
<input type="email" name="email" placeholder="Email address">
</div>
<div class="contact-form__row">
<input type="tel" name="phone" placeholder="Phone number">
<select name="service">
<option value="">Project type…</option>
<option value="Full Bathroom Remodeling">Full Bathroom Remodeling</option><option value="Shower & Wet Room Design">Shower & Wet Room Design</option><option value="Tub Replacement">Tub Replacement</option>
</select>
</div>
<textarea name="message" placeholder="Tell us about your project…" rows="4" required></textarea>
<input type="file" id="contact-file-input" name="attachment" accept="image/*,.pdf,.doc,.docx" multiple style="display:none">
<label for="contact-file-input" class="file-upload-trigger">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"/></svg>
<span id="file-label-text">Attach photos or files (optional)</span>
</label>
<button type="submit" class="btn btn-gold">Send Message</button>
</form>
</div>
</div>
</section>
<!-- ══════════════════════════════════════════════
FAQ
══════════════════════════════════════════════ -->
<section class="faq" aria-label="Frequently asked questions">
<div class="wrap">
<header class="faq__header">
<p class="section-label reveal">Common Questions</p>
<h2 class="section-h2 reveal d1">Everything you need<br>to know before you start.</h2>
</header>
<div class="faq__list">
<div class="faq__item">
<button class="faq__q" aria-expanded="false">
What types of bathroom remodeling services do you offer in Evansville?
<span class="faq__icon" aria-hidden="true"></span>
</button>
<div class="faq__a" role="region">
<p class="faq__a-inner">We specialize exclusively in residential bathroom transformations, ranging from minor updates with high-end finishes to full luxury remodels. Our expertise includes high-end tile showers, custom rain heads, and specialized layouts tailored to your home.</p>
</div>
</div>
<div class="faq__item">
<button class="faq__q" aria-expanded="false">
How long will it take to complete my bathroom project?
<span class="faq__icon" aria-hidden="true"></span>
</button>
<div class="faq__a" role="region">
<p class="faq__a-inner">We strive to set clear expectations for every project timeline. Basic Remodels: approximately 2 weeks. Custom & Tile Showers: approximately 2.5 to 3 weeks.</p>
</div>
</div>
<div class="faq__item">
<button class="faq__q" aria-expanded="false">
What areas do you serve near Evansville?
<span class="faq__icon" aria-hidden="true"></span>
</button>
<div class="faq__a" role="region">
<p class="faq__a-inner">We are a service-area business providing professional remodeling throughout Evansville, IN and Newburgh, IN. Please note that we do not currently offer services in Henderson due to specific licensing requirements.</p>
</div>
</div>
<div class="faq__item">
<button class="faq__q" aria-expanded="false">
How do I get an estimate for my project?
<span class="faq__icon" aria-hidden="true"></span>
</button>
<div class="faq__a" role="region">
<p class="faq__a-inner">We offer a fast, no-hassle estimate process. Reach Out — contact us via our website or phone. Send Photos — provide photos of your current space (no initial home visit needed for simple jobs). Receive Estimate — you'll receive a quick text estimate within approximately 2 days.</p>
</div>
</div>
<div class="faq__item">
<button class="faq__q" aria-expanded="false">
Why should I choose Dream Bath over a general contractor?
<span class="faq__icon" aria-hidden="true"></span>
</button>
<div class="faq__a" role="region">
<p class="faq__a-inner">While our owner, Brent Carter, has over 25 years of construction experience and 15 years as a licensed general contractor, Dream Bath focuses specifically on the bathroom niche. We bring a creative edge to every project, utilizing laser-level precision and an artist's eye for layout and color to ensure a premium, detailed finish.</p>
</div>
</div>
<div class="faq__item">
<button class="faq__q" aria-expanded="false">
How far in advance should I start planning my remodel?
<span class="faq__icon" aria-hidden="true"></span>
</button>
<div class="faq__a" role="region">
<p class="faq__a-inner">Our commitment to precision and premium craftsmanship means we dedicate the necessary time to every project to ensure perfection. Because our services are in high demand and we maintain a consistently full schedule, we recommend reaching out as early as possible to begin our estimate process and secure your preferred timing on our calendar.</p>
</div>
</div>
<div class="faq__item">
<button class="faq__q" aria-expanded="false">
What is your "Precision & Quality" guarantee?
<span class="faq__icon" aria-hidden="true"></span>
</button>
<div class="faq__a" role="region">
<p class="faq__a-inner">We are extremely detail-oriented and committed to perfection. Our philosophy is that we will take longer on a project if it is necessary to ensure every tile and fixture meets our high standards. As we like to say, "There isn't anything we can't do in a bathroom."</p>
</div>
</div>
</div>
</div>
</section>
</main>
<!-- ══════════════════════════════════════════════
§11 — FOOTER
Dark, multi-column: brand + services + company +
accreditations — matching Belle's footer structure
══════════════════════════════════════════════ -->
<footer class="footer" aria-label="Site footer">
<div class="wrap">
<div class="footer__top">
<!-- Brand + contact -->
<div>
<div class="footer__logo">
<img src="./dream_bath.svg" alt="Dream Bath" />
</div>
<address class="footer__brand-addr" style="font-style:normal;">
Licensed General Contractor · <span id="footer-state">Indiana</span><br>
<span id="footer-city">Evansville, IN</span><br>
<a href="tel:+18124557384" id="footer-phone"><svg class="phone-icon-sm" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.69 13a19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 3.6 2h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L7.91 9.91a16 16 0 0 0 6.09 6.09l.95-.95a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 22 16.92z"/></svg>(812) 455-7384</a><br>
<a href="mailto:dreambath.evv@gmail.com" id="footer-email">dreambath.evv@gmail.com</a><br>
<span id="footer-hours">Mon–Fri 8–4</span>
</address>
<div class="footer__social">
<a href="https://www.facebook.com/p/Dream-Bath-LLC-61579276388734/" target="_blank" rel="noopener noreferrer" class="footer__social-link" aria-label="Facebook">
<svg viewBox="0 0 24 24"><path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z"/></svg>
</a>
<a href="https://share.google/GyUCHdspCKXtvExQz" target="_blank" rel="noopener noreferrer" class="footer__social-link footer__social-link--google" aria-label="Google Reviews">
<svg viewBox="0 0 24 24" fill="none" stroke="none"><path d="M21.8 12.2c0-.7-.1-1.4-.2-2H12v3.8h5.5a4.7 4.7 0 0 1-2 3.1v2.5h3.3c1.9-1.8 3-4.4 3-7.4z" fill="rgba(255,255,255,.8)"/><path d="M12 22c2.7 0 5-0.9 6.7-2.4l-3.3-2.5c-.9.6-2.1 1-3.4 1-2.6 0-4.9-1.8-5.7-4.2H1v2.6C2.7 19.8 7 22 12 22z" fill="rgba(255,255,255,.8)"/><path d="M6.3 13.9A5.9 5.9 0 0 1 6 12c0-.7.1-1.3.3-1.9V7.5H3A10 10 0 0 0 2 12c0 1.6.4 3.2 1 4.5l3.3-2.6z" fill="rgba(255,255,255,.8)"/><path d="M12 6.8c1.5 0 2.8.5 3.8 1.5l2.8-2.8A9.9 9.9 0 0 0 12 2C7 2 2.7 4.2 1 7.5l3.3 2.6C5.1 8.6 7.4 6.8 12 6.8z" fill="rgba(255,255,255,.8)"/></svg>
</a>
</div>
</div>
<!-- Services links -->
<div>
<p class="footer__col-title">Services</p>
<ul class="footer__links" role="list">
<li><a href="#services">Full Bathroom Remodel</a></li>
<li><a href="#services">Shower Installation</a></li>
<li><a href="#services">Tub Replacement</a></li>
<li><a href="#services">Tile Work</a></li>
<li><a href="#services">Custom Vanities</a></li>
</ul>
</div>
<!-- Company links -->
<div>
<p class="footer__col-title">Company</p>
<ul class="footer__links" role="list">
<li><a href="#about">About Us</a></li>
<li><a href="#process">Our Process</a></li>
<li><a href="#gallery">Portfolio</a></li>
<li><a href="#testimonials">Testimonials</a></li>
<li><a href="#contact">Free Quote</a></li>
</ul>
</div>
</div>
<div class="footer__bottom">
<p class="footer__copy">© 2026 Dream Bath LLC · Licensed General Contractor · All Rights Reserved</p>
<a href="https://readysetgro.io/" class="footer__powered" target="_blank" rel="noopener noreferrer">
<img src="./client-assets/dream-bath/powered-by-gro_1776443776448.avif" alt="Powered by GRO">
</a>
</div>
</div>
</footer>
<script>
'use strict';
/* ── NAV STATE ─────────────────────────────────── */
const nav = document.getElementById('mainNav');
let navTicking = false;
function updateNavState() {
const scrolled = window.scrollY > 60;
nav.classList.toggle('hero-mode', !scrolled);
nav.classList.toggle('solid', scrolled);
navTicking = false;
}
window.addEventListener('scroll', () => {
if (!navTicking) {
requestAnimationFrame(updateNavState);
navTicking = true;
}
}, { passive: true });
/* ── HAMBURGER / MOBILE DRAWER ─────────────────── */
const ham = document.getElementById('navHam');
const drawer = document.getElementById('navDrawer');
ham.addEventListener('click', () => {
const open = ham.classList.toggle('open');
drawer.classList.toggle('open', open);
ham.setAttribute('aria-expanded', String(open));
// Lock scroll when drawer open
document.body.style.overflow = open ? 'hidden' : '';
});
drawer.querySelectorAll('a').forEach(link => {
link.addEventListener('click', () => {
ham.classList.remove('open');
drawer.classList.remove('open');
ham.setAttribute('aria-expanded', 'false');
document.body.style.overflow = '';
});
});
/* ── HERO: rotation + zoom-out + parallax (combined) ───── */
(function () {
const bgLayers = Array.from(document.querySelectorAll('.hero__bg'));
const archLayers = Array.from(document.querySelectorAll('.hero__arch-img'));
const heroText = document.querySelector('.hero__text');
if (!bgLayers.length) return;
const SLIDE_MS = 7000;
const ZOOM_FROM = 1.10;
const ZOOM_TO = 1.0;
let idx = 0;
let zoomScale = ZOOM_FROM;
let zoomRaf = null;
let zoomStart = null;
function applyTransforms() {
const py = window.scrollY * 0.22;
bgLayers.forEach(function (bg) {
bg.style.transform = 'scale(' + zoomScale + ') translateY(' + py + 'px)';
});
if (heroText && window.innerWidth > 900) heroText.style.transform = 'translateY(' + (window.scrollY * 0.14) + 'px)';
}
function startZoom() {
if (zoomRaf) cancelAnimationFrame(zoomRaf);
zoomStart = performance.now();
function tick(now) {
var t = Math.min((now - zoomStart) / SLIDE_MS, 1);
var ease = 1 - Math.pow(1 - t, 3);
zoomScale = ZOOM_FROM + (ZOOM_TO - ZOOM_FROM) * ease;
applyTransforms();
if (t < 1) zoomRaf = requestAnimationFrame(tick);
}
zoomRaf = requestAnimationFrame(tick);
}
window.addEventListener('scroll', applyTransforms, { passive: true });
startZoom();
setInterval(function () {
bgLayers[idx].classList.remove('active');
if (archLayers[idx]) archLayers[idx].classList.remove('active');
idx = (idx + 1) % bgLayers.length;
bgLayers[idx].classList.add('active');
if (archLayers[idx]) archLayers[idx].classList.add('active');
startZoom();
}, SLIDE_MS);
}());
/* ── GALLERY SLIDER ────────────────────────────── */
(function () {
const PAGE = 9;
const track = document.getElementById('gallery-track');
const dotsEl = document.getElementById('gallery-dots');
const prevBtn = document.getElementById('gallery-prev');
const nextBtn = document.getElementById('gallery-next');
if (!track || !dotsEl) return;
const cards = Array.from(track.querySelectorAll('.proj-card'));
if (!cards.length) return;
const totalPages = Math.ceil(cards.length / PAGE);
let current = 0;
function showPage(p) {
current = ((p % totalPages) + totalPages) % totalPages;
cards.forEach(function (c, i) {
c.style.display = (i >= current * PAGE && i < (current + 1) * PAGE) ? '' : 'none';
});
dotsEl.querySelectorAll('.gallery-dot').forEach(function (d, i) {
d.classList.toggle('active', i === current);
});
}
for (var i = 0; i < totalPages; i++) {
var dot = document.createElement('button');
dot.className = 'gallery-dot' + (i === 0 ? ' active' : '');
dot.setAttribute('aria-label', 'Page ' + (i + 1));
(function (idx) {
dot.addEventListener('click', function () { showPage(idx); });
}(i));
dotsEl.appendChild(dot);
}
if (prevBtn) prevBtn.addEventListener('click', function () { showPage(current - 1); });
if (nextBtn) nextBtn.addEventListener('click', function () { showPage(current + 1); });
showPage(0);
}());
/* parallax handled in rotation block above */
/* content pre-rendered */
/* ── REVEAL ANIMATIONS ─────────────────────────── */
const revealEls = document.querySelectorAll('.reveal');
if ('IntersectionObserver' in window) {
const io = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('in');
io.unobserve(entry.target);
}
});
}, { threshold: 0.1, rootMargin: '0px 0px -32px 0px' });
window._revealObserver = io;
revealEls.forEach(el => io.observe(el));
} else {
revealEls.forEach(el => el.classList.add('in'));
}
/* ── FAQ ACCORDION ─────────────────────────────── */
document.querySelectorAll('.faq__q').forEach(btn => {
btn.addEventListener('click', () => {
const item = btn.closest('.faq__item');
const panel = item.querySelector('.faq__a');
const isOpen = item.classList.contains('open');
// Close all open items
document.querySelectorAll('.faq__item.open').forEach(open => {
open.classList.remove('open');
open.querySelector('.faq__a').style.maxHeight = '0';
open.querySelector('.faq__q').setAttribute('aria-expanded', 'false');
});
// Open clicked item if it was closed
if (!isOpen) {
item.classList.add('open');
panel.style.maxHeight = panel.scrollHeight + 'px';
btn.setAttribute('aria-expanded', 'true');
}
});
});
/* ── SMOOTH SCROLL ─────────────────────────────── */
document.querySelectorAll('a[href^="#"]').forEach(a => {
a.addEventListener('click', e => {
const target = document.querySelector(a.getAttribute('href'));
if (target) {
e.preventDefault();
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
});
</script>
<!-- GSAP circular scroll animations -->
<script>
(function () {
'use strict';
/* ── inject CSS: suppress transitions on GSAP-owned elements ── */
const gStyle = document.createElement('style');
gStyle.textContent =
'.gsap-arc{transition:none!important;will-change:transform,opacity;}';
document.head.appendChild(gStyle);
/* ── sequential script loader ── */
function loadScript(src, cb) {
const s = document.createElement('script');
s.src = src; s.async = true; s.onload = cb;
document.head.appendChild(s);
}
loadScript(
'https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js',
function () {
loadScript(
'https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/ScrollTrigger.min.js',
boot
);
}
);
function boot() {
gsap.registerPlugin(ScrollTrigger);
const mobile = window.matchMedia('(max-width: 768px)').matches;
/* ─────────────────────────────────────────────────────────
takeOver(els)
Marks elements as GSAP-owned: suppresses the CSS reveal
transition and pre-hides them so GSAP controls the reveal.
───────────────────────────────────────────────────────── */
function takeOver(els) {
els.forEach(el => {
el.classList.add('in', 'gsap-arc'); // 'in' stops IntersectionObserver re-firing
});
gsap.set(els, { opacity: 0, x: 0, y: 0, rotation: 0, scale: 1 });
}
/* ─────────────────────────────────────────────────────────
arcReveal(els, trigger, opts)
Core animation: each element starts at a position on an
imaginary arc and smoothly moves to its natural position.
Arc geometry (desktop):
angle = (i − mid) / (n−1) × π × spread
startX = sin(angle) × radius ← horizontal arc
startY = (1 − cos(angle)) × radius×h + yBase ← curve depth
startR = (i − mid) × rotateDeg ← gentle tilt
───────────────────────────────────────────────────────── */
function arcReveal(els, trigger, o) {
o = o || {};
const n = els.length;
const radius = mobile ? (o.radiusMob || 70) : (o.radius || 260);
const hFactor = mobile ? 0 : (o.hFactor || 0.28);
const yBase = mobile ? (o.yBaseMob || 24) : (o.yBase || 48);
const spread = o.spread || 0.7;
const rotDeg = mobile ? 0 : (o.rotateDeg || 4);
const stagger = o.stagger || 0.08;
const dur = o.duration || 1.1;
const ease = o.ease || 'expo.out';
const scaleFrom = mobile ? 0.97 : (o.scaleFrom || 0.90);
takeOver(Array.from(els));
els.forEach((el, i) => {
const mid = (n - 1) / 2;
const t = n > 1 ? (i - mid) / (n - 1) : 0;
const angle = t * Math.PI * spread;
const startX = Math.sin(angle) * radius;
const startY = yBase + (1 - Math.cos(angle)) * radius * hFactor;
const startR = t * (n - 1) * rotDeg;
gsap.fromTo(el,
{ x: startX, y: startY, rotation: startR, opacity: 0, scale: scaleFrom },
{
x: 0, y: 0, rotation: 0, opacity: 1, scale: 1,
ease, duration: dur,
delay: i * stagger,
scrollTrigger: {
trigger,
start: o.start || 'top 78%',
toggleActions: 'play none none reverse',
}
}
);
});
}
/* ─────────────────────────────────────────────────────────
watchGrid(id, selector, opts)
Fires arcReveal once the dynamic grid is populated
(data arrives via fetch after page load).
───────────────────────────────────────────────────────── */
function watchGrid(id, selector, opts) {
const grid = document.getElementById(id);
if (!grid) return;
let done = false;
function tryAnimate() {
if (done) return;
const els = grid.querySelectorAll(selector);
if (!els.length) return;
done = true;
mo.disconnect();
arcReveal(els, grid, opts);
ScrollTrigger.refresh();
}
const mo = new MutationObserver(tryAnimate);
mo.observe(grid, { childList: true });
tryAnimate(); // in case already populated
}
/* ── Portfolio — wide circular spread ─────────── */
watchGrid('portfolio-grid', '.proj-card', {
radius: 360, radiusMob: 60,
hFactor: 0.30, spread: 0.80,
yBase: 60, yBaseMob: 20,
rotateDeg: 5, scaleFrom: 0.88,
stagger: 0.07, duration: 1.15,
start: 'top 80%'
});
/* ── Services — gentle upward arc ─────────────── */
watchGrid('services-grid', '.svc-card', {
radius: 200, radiusMob: 50,
hFactor: 0.20, spread: 0.55,
yBase: 50, yBaseMob: 20,
rotateDeg: 3, scaleFrom: 0.92,
stagger: 0.10, duration: 1.05,
start: 'top 80%'
});
/* ── Process steps — horizontal wave ──────────── */
const steps = document.querySelectorAll('.proc-step');
if (steps.length) {
arcReveal(steps, '.process__steps', {
radius: 160, radiusMob: 0,
hFactor: 0.10, spread: 0.45,
yBase: 40, yBaseMob: 20,
rotateDeg: 0, scaleFrom: 0.94,
stagger: 0.09, duration: 0.95,
ease: 'back.out(1.3)',
start: 'top 76%'
});
}
/* ── Testimonials — arc from below ────────────── */
const testiGrid = document.querySelector('.testimonials__grid');
if (testiGrid) {
let done2 = false;
const mo2 = new MutationObserver(() => {
if (done2) return;
const cards = testiGrid.querySelectorAll('.testi-card');
if (!cards.length) return;
done2 = true;
mo2.disconnect();
arcReveal(cards, testiGrid, {
radius: 180, radiusMob: 40,
hFactor: 0.18, spread: 0.50,
yBase: 44, yBaseMob: 16,
rotateDeg: 3, scaleFrom: 0.92,
stagger: 0.09, duration: 1.0,
start: 'top 78%'
});
ScrollTrigger.refresh();
});
mo2.observe(testiGrid, { childList: true });
}
/* ── Section headings — subtle perspective tilt ─ */
document.querySelectorAll('.section-h2').forEach(h => {
if (h.closest('.hero')) return;
h.classList.add('in', 'gsap-arc');
gsap.set(h, { opacity: 0 });
gsap.fromTo(h,
{ y: 22, opacity: 0, rotationX: 7, transformPerspective: 900,
transformOrigin: '50% 100%' },
{
y: 0, opacity: 1, rotationX: 0,
ease: 'expo.out', duration: 1.05,
scrollTrigger: {
trigger: h, start: 'top 88%',
toggleActions: 'play none none reverse'
}
}
);
});
/* ── Section labels (small uppercase) ─────────── */
document.querySelectorAll('.section-label').forEach(el => {
if (el.closest('.hero, .nav')) return;
el.classList.add('in', 'gsap-arc');
gsap.set(el, { opacity: 0 });
gsap.fromTo(el,
{ y: 14, opacity: 0, letterSpacing: '0.25em' },
{
y: 0, opacity: 1, letterSpacing: '',
ease: 'expo.out', duration: 0.9,
scrollTrigger: {
trigger: el, start: 'top 90%',
toggleActions: 'play none none reverse'
}
}
);
});
ScrollTrigger.refresh();
}
}());
</script>
<!-- Lightbox overlay — must be in DOM before the lightbox IIFE below -->
<div class="lb-overlay" id="lb-overlay" role="dialog" aria-modal="true" aria-label="Image viewer">
<button class="lb-close" id="lb-close" aria-label="Close">×</button>
<button class="lb-prev" id="lb-prev" aria-label="Previous">‹</button>
<img class="lb-img" id="lb-img" src="" alt="Project photo">
<button class="lb-next" id="lb-next" aria-label="Next">›</button>
</div>
<script>
// ── File upload label update ──────────────────────────
(function() {
var inp = document.getElementById('contact-file-input');
if (!inp) return;
inp.addEventListener('change', function() {
var lbl = document.getElementById('file-label-text');
if (!lbl) return;
lbl.textContent = this.files.length > 1
? this.files.length + ' files selected'
: this.files.length === 1 ? this.files[0].name : 'Attach photos or files (optional)';
});
}());
// ── Lightbox ──────────────────────────────────────────
(function() {
const overlay = document.getElementById('lb-overlay');
const img = document.getElementById('lb-img');
const closeBtn= document.getElementById('lb-close');
const prevBtn = document.getElementById('lb-prev');
const nextBtn = document.getElementById('lb-next');
let cards = [], idx = 0;
function getUrl(card) {
const bg = card.querySelector('.proj-card__bg');
if (!bg) return '';
const raw = bg.style.backgroundImage || bg.style.background
|| window.getComputedStyle(bg).backgroundImage;
const m = raw.match(/url\(["']?([^"')]+)["']?\)/);
return m ? m[1] : '';
}
function open(i) {
cards = Array.from(document.querySelectorAll('.proj-card'));
idx = ((i % cards.length) + cards.length) % cards.length;
img.src = getUrl(cards[idx]);
overlay.classList.add('is-open');
document.body.style.overflow = 'hidden';
}
function closeLb() {
overlay.classList.remove('is-open');
document.body.style.overflow = '';
img.src = '';
}
document.addEventListener('click', function(e) {
const card = e.target.closest('.proj-card');
if (card && !overlay.classList.contains('is-open')) {
cards = Array.from(document.querySelectorAll('.proj-card'));
open(cards.indexOf(card));
}
});
closeBtn.addEventListener('click', closeLb);
overlay.addEventListener('click', function(e) { if (e.target === overlay) closeLb(); });
prevBtn.addEventListener('click', function() { open(idx - 1); });
nextBtn.addEventListener('click', function() { open(idx + 1); });
document.addEventListener('keydown', function(e) {
if (!overlay.classList.contains('is-open')) return;
if (e.key === 'Escape') closeLb();
if (e.key === 'ArrowLeft') open(idx - 1);
if (e.key === 'ArrowRight') open(idx + 1);
});
}());
</script>
<!-- Contact form handler -->
<script>
(function() {
const form = document.getElementById('contact-form');
if (!form) return;
const confirmHTML = '<div class="contact-form__confirm" style="padding:40px 0;font-size:17px;display:flex;flex-direction:column;align-items:center;gap:16px"><svg viewBox="0 0 24 24" width="40" height="40" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg><span>Thanks! We\'ll be in touch within one business day.</span></div>';
// Hidden iframe: fires when a native POST completes, so we can show in-page confirmation
let iframeReady = false;
const iframe = document.getElementById('contact-iframe');
if (iframe) {
iframe.addEventListener('load', function() {
if (!iframeReady) return; // ignore initial empty load
form.innerHTML = confirmHTML;
});
}
form.addEventListener('submit', async function(e) {
const fileInput = document.getElementById('contact-file-input');
const hasFile = fileInput && fileInput.files.length > 0;
const isDashboard = window.location.pathname.startsWith('/sites/');
const btn = form.querySelector('button[type="submit"]');
const origText = btn.textContent;
btn.disabled = true;
btn.textContent = 'Sending…';
// Files present on live site: submit natively into the hidden iframe so
// FormSubmit.co receives the attachments; iframe load shows in-page confirmation.
if (hasFile && !isDashboard) {
iframeReady = true;
return; // let the native POST proceed to target="contact-iframe"
}
e.preventDefault();
try {
let res;
if (isDashboard) {
res = await fetch('/api/public/contact', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: form.querySelector('[name="name"]').value,
email: form.querySelector('[name="email"]').value,
phone: form.querySelector('[name="phone"]').value,
service: form.querySelector('[name="service"]').value,
message: form.querySelector('[name="message"]').value,
})
});
} else {
const fd = new FormData();
fd.append('name', form.querySelector('[name="name"]').value);
fd.append('email', form.querySelector('[name="email"]').value);
fd.append('phone', form.querySelector('[name="phone"]').value);
fd.append('service', form.querySelector('[name="service"]').value);
fd.append('message', form.querySelector('[name="message"]').value);
fd.append('_subject', 'New Quote Request – Dream Bath');
fd.append('_captcha', 'false');
fd.append('_honey', '');
res = await fetch('https://formsubmit.co/ajax/dreambath.evv@gmail.com', {
method: 'POST',
headers: { 'Accept': 'application/json' },
body: fd
});
}
const data = await res.json();
if (!res.ok && !data.success && !data.ok) throw new Error(data.error || 'Submission failed');
form.innerHTML = confirmHTML;
} catch (err) {
btn.disabled = false;
btn.textContent = origText;
const errEl = form.querySelector('.contact-form__error') || document.createElement('p');
errEl.className = 'contact-form__error';
errEl.style.cssText = 'color:#e05c5c;font-size:13px;margin-top:8px;text-align:center';
errEl.textContent = 'Something went wrong — please try again or call us directly.';
if (!form.querySelector('.contact-form__error')) form.appendChild(errEl);
}
});
}());
</script>
</body>
</html>