/* Joel Works: single stylesheet. Mobile-first, no framework, no build step. */

/* ---------- Tokens ---------- */
:root {
  /* sampled from the navy cabinetry in the hero photo (hue 217) */
  --brand: #2b4369;
  --brand-dark: #17273f;
  --brand-tint: #e9eef6;
  --accent: #b8501c;
  --accent-dark: #94400f;
  --ink: #231f20;          /* matches the logo charcoal */
  --muted: #545f6b;
  --line: #ded7cd;
  --paper: #fffdfa;
  --paper-2: #f4efe8;
  --radius: 10px;
  --wrap: 1080px;
  --bar-h: 64px;
}

/* ---------- Base ---------- */
*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 17px;
  line-height: 1.6;
  color: var(--ink);
  background: var(--paper);
  /* room for the sticky call bar on phones */
  padding-bottom: calc(var(--bar-h) + env(safe-area-inset-bottom, 0px));
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

a { color: var(--brand); }
a:hover { color: var(--accent-dark); }

h1, h2, h3 {
  line-height: 1.2;
  margin: 0 0 .5em;
  letter-spacing: -0.01em;
}

h1 { font-size: clamp(1.75rem, 6vw, 2.6rem); }
h2 { font-size: clamp(1.35rem, 4.5vw, 1.9rem); }
h3 { font-size: 1.1rem; }

p { margin: 0 0 1em; }

:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin: 0 auto;
  /* generous on phones, where content otherwise crowds the bezel */
  padding: 0 26px;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--brand);
  color: #fff;
  padding: 12px 16px;
  z-index: 100;
}
.skip:focus { left: 0; }

.lede {
  font-size: 1.075rem;
  color: var(--muted);
  max-width: 60ch;
}

.section {
  padding: 44px 0;
  border-top: 1px solid var(--line);
}
.section:first-of-type { border-top: 0; }
.section--tint { background: var(--paper-2); }

.section__head { margin-bottom: 22px; }
.section__head p { margin-bottom: 0; }

/* ---------- Header ---------- */
.site-header {
  background: #fff;
  color: var(--ink);
  border-bottom: 1px solid var(--line);
}

.site-header .wrap {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-top: 10px;
  padding-bottom: 10px;
}

.brand {
  display: flex;
  align-items: center;
  flex: none;
  color: var(--ink);
  text-decoration: none;
}
.brand:hover { color: var(--ink); }
.brand img { flex: none; }
.brand img { width: 46px; height: 46px; }


/* Header phone: hidden on phones, where the sticky bar does the job */
.header-phone {
  display: none;
  color: var(--brand);
  font-size: 1.05rem;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}
.header-phone span {
  display: block;
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ---------- Nav ---------- */
.site-nav { min-width: 0; }

.site-nav ul {
  display: flex;
  gap: 0;
  list-style: none;
  margin: 0;
  padding: 0;
}

.site-nav a {
  display: block;
  padding: 12px 8px;
  font-size: .85rem;
  white-space: nowrap;
  color: var(--muted);
  text-decoration: none;
  font-size: .95rem;
  font-weight: 600;
  border-bottom: 3px solid transparent;
}
.site-nav a:hover { color: var(--ink); }
.site-nav a[aria-current="page"] {
  color: var(--brand);
  border-bottom-color: var(--accent);
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 48px;
  padding: 12px 22px;
  border: 2px solid transparent;
  border-radius: var(--radius);
  font-size: 1rem;
  font-weight: 700;
  text-decoration: none;
  cursor: pointer;
  text-align: center;
}

.btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.btn--primary:hover {
  background: var(--accent-dark);
  border-color: var(--accent-dark);
  color: #fff;
}

.btn--ghost {
  background: transparent;
  border-color: currentColor;
  color: #fff;
}
.btn--ghost:hover { background: rgba(255, 255, 255, .12); color: #fff; }

.btn--outline {
  background: #fff;
  border-color: var(--brand);
  color: var(--brand);
}
.btn--outline:hover { background: var(--brand-tint); color: var(--brand-dark); }

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* Registered so the hover zoom can transition. Unregistered custom
   properties are not animatable, they would jump. */
@property --zoom-add {
  syntax: "<number>";
  inherits: false;
  initial-value: 0;
}

/* ---------- Hero ---------- */
.hero {
  position: relative;
  background: var(--brand-dark);
  color: #fff;
  overflow: hidden;
}

.hero__img {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  /* pushes past the cover crop so the room feels closer, and leaves
     headroom for the parallax drift below */
  --zoom-base: 1.20;
  --hero-zoom: calc(var(--zoom-base) + var(--zoom-add));
  transform: scale(var(--hero-zoom));
  /* stacked: default shows, the rest fade in on trade hover */
  opacity: 0;
  transition: opacity .45s ease, --zoom-add .8s ease;
}

.hero__img--default { opacity: 1; }

/* Scrim: lets the photo read properly while keeping the text legible over it.
   On phones the text sits over the whole width, so the wash is even. */
/* Near-black rather than a navy wash: richer, and it lets the photo keep
   its own colour. Weighted to where the text actually sits, so the rest of
   the image stays open. Minimum needed for white body text over pure white
   is .57 alpha, so the text zone sits just above that. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    radial-gradient(120% 90% at 50% 40%, rgba(8, 12, 18, 0) 40%, rgba(8, 12, 18, .45) 100%),
    linear-gradient(180deg, rgba(8, 12, 18, .42) 0%, rgba(8, 12, 18, .62) 42%, rgba(8, 12, 18, .66) 72%, rgba(8, 12, 18, .60) 100%);
}

.hero__inner {
  position: relative;
  z-index: 2;
  /* vertical only: the shorthand would reset .wrap's side padding to 0
     and pin the headline to the screen edge */
  padding-top: 52px;
  padding-bottom: 48px;
}

.hero h1 {
  margin-bottom: .35em;
  text-shadow: 0 2px 18px rgba(0, 0, 0, .45);
}

.hero p {
  color: #e8eef5;
  font-size: 1.075rem;
  max-width: 46ch;
  text-shadow: 0 1px 12px rgba(0, 0, 0, .5);
}

.eyebrow {
  display: inline-block;
  margin-bottom: 14px;
  padding: 5px 12px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .14);
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
}

/* ---------- Hero parallax ---------- */
/* Scroll-driven CSS animation: no JavaScript, and browsers without support
   simply keep the static hero. Drift stays inside the zoom headroom so no
   edge of the photo is ever exposed. */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    @keyframes hero-drift {
      from { transform: scale(var(--hero-zoom)) translateY(-6%); }
      to   { transform: scale(var(--hero-zoom)) translateY(6%); }
    }

    .hero__img {
      animation: hero-drift linear both;
      animation-timeline: scroll(root block);
      /* travel completes over less scroll, so it reads as faster */
      animation-range: 0 75vh;
      will-change: transform;
    }
  }
}

/* ---------- Trade bar under the hero ---------- */
/* Sits inside the hero so the photo runs behind it. Buttons stay
   transparent; hairlines do the dividing. */
.trades {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  border-top: 1px solid rgba(255, 255, 255, .28);
  background: linear-gradient(180deg, rgba(8, 12, 18, .20) 0%, rgba(8, 12, 18, .72) 100%);
}

.trade {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 84px;
  padding: 18px 10px;
  background: transparent;
  color: #fff;
  text-decoration: none;
  text-align: center;
  font-size: .92rem;
  font-weight: 700;
  letter-spacing: .11em;
  text-transform: uppercase;
  text-shadow: 0 1px 10px rgba(0, 0, 0, .55);
  border-left: 1px solid rgba(255, 255, 255, .28);
  box-shadow: inset 0 0 0 0 rgba(255, 255, 255, .14);
  transition: background .25s ease, box-shadow .25s ease;
}

/* two across on phones: no left rule on the first of each row, and a rule
   above the second row. Scoped, or these outrank the desktop rules below. */
@media (max-width: 699px) {
  .trade:nth-child(2n + 1) { border-left: 0; }
  .trade:nth-child(n + 3) { border-top: 1px solid rgba(255, 255, 255, .28); }
}

/* hover keeps the photo visible rather than covering it */
.trade:hover,
.trade:focus-visible {
  background: rgba(255, 255, 255, .13);
  box-shadow: inset 0 -3px 0 0 var(--accent);
  color: #fff;
}

@media (min-width: 700px) {
  .trades { grid-template-columns: repeat(4, 1fr); }

  .trade {
    min-height: 104px;
    font-size: 1rem;
    border-left: 1px solid rgba(255, 255, 255, .3);
    border-top: 0;
  }
  .trade:first-child { border-left: 0; }
}

/* Hovering a trade swaps the hero photo. Pointer devices only, and it needs
   :has(), so anything without it simply keeps the default image. */
@media (hover: hover) {
  body:has(.trade--kitchens:hover) .hero__img--default,
  body:has(.trade--bathrooms:hover) .hero__img--default,
  body:has(.trade--basements:hover) .hero__img--default,
  body:has(.trade--tile:hover) .hero__img--default {
    opacity: 0;
  }

  body:has(.trade--kitchens:hover) .hero__img--kitchens,
  body:has(.trade--bathrooms:hover) .hero__img--bathrooms,
  body:has(.trade--basements:hover) .hero__img--basements,
  body:has(.trade--tile:hover) .hero__img--tile {
    opacity: 1;
    --zoom-add: .09;
  }
}

/* anchors from the trade bar should not land under anything */
.card[id] { scroll-margin-top: 90px; }

/* ---------- Trust strip ---------- */
.trust {
  background: var(--paper-2);
  border-bottom: 1px solid var(--line);
}

.trust ul {
  display: grid;
  gap: 10px;
  list-style: none;
  margin: 0;
  padding: 18px 0;
  font-size: .95rem;
  font-weight: 600;
}

.trust li {
  display: flex;
  align-items: center;
  gap: 10px;
}

.trust svg {
  flex: none;
  width: 20px;
  height: 20px;
  color: var(--accent);
}

/* ---------- Cards ---------- */
.grid {
  display: grid;
  gap: 18px;
}

.card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 22px;
}

.card h3 { margin-bottom: .4em; }

.card p:last-child { margin-bottom: 0; }

.card__icon {
  width: 40px;
  height: 40px;
  margin-bottom: 12px;
  color: var(--accent);
}

.card ul {
  margin: 0;
  padding-left: 1.15em;
  color: var(--muted);
  font-size: .95rem;
}
.card ul li { margin-bottom: .3em; }

/* ---------- Split (image + text) ---------- */
.split {
  display: grid;
  gap: 24px;
  align-items: center;
}

.split img {
  border-radius: var(--radius);
  width: 100%;
}

/* ---------- Steps ---------- */
.steps {
  counter-reset: step;
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 18px;
}

.steps li {
  counter-increment: step;
  position: relative;
  padding-left: 52px;
}

.steps li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: 0;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--brand);
  color: #fff;
  font-weight: 700;
}

.steps h3 { margin-bottom: .25em; }
.steps p { margin-bottom: 0; color: var(--muted); }

/* ---------- Gallery ---------- */
.gallery {
  display: grid;
  gap: 16px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.gallery figure {
  margin: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: #fff;
}

.gallery img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.gallery figcaption {
  padding: 12px 14px;
  font-size: .92rem;
}

.gallery figcaption strong { display: block; }
.gallery figcaption span { color: var(--muted); }

/* ---------- Service area ---------- */
.towns {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.towns li {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 6px 14px;
  font-size: .9rem;
  font-weight: 600;
}

/* ---------- Contact ---------- */
.contact-list {
  list-style: none;
  margin: 0 0 8px;
  padding: 0;
}

.contact-list li {
  padding: 14px 0;
  border-bottom: 1px solid var(--line);
}
.contact-list li:first-child { padding-top: 0; }

.contact-list dt,
.contact-list strong {
  display: block;
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 2px;
}

.contact-list a {
  font-size: 1.15rem;
  font-weight: 700;
  text-decoration: none;
}
.contact-list a:hover { text-decoration: underline; }

/* ---------- Form ---------- */
.form { display: grid; gap: 16px; }

.field { display: grid; gap: 6px; }

.field label {
  font-weight: 600;
  font-size: .95rem;
}

.field .hint {
  font-size: .85rem;
  color: var(--muted);
  font-weight: 400;
}

.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: 48px;
  padding: 11px 12px;
  font: inherit;
  font-size: 16px; /* keeps iOS from zooming on focus */
  color: var(--ink);
  background: #fff;
  border: 1px solid #b9b2a7;
  border-radius: var(--radius);
}

.field textarea {
  min-height: 130px;
  resize: vertical;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--brand);
  outline: 3px solid rgba(27, 58, 92, .25);
  outline-offset: 0;
}

.form-note {
  font-size: .88rem;
  color: var(--muted);
}

/* ---------- CTA band ---------- */
.cta {
  background: var(--brand);
  color: #fff;
  text-align: center;
}
.cta .wrap { padding-top: 40px; padding-bottom: 40px; }
.cta h2 { margin-bottom: .35em; }
.cta p { color: #dbe5ef; margin-left: auto; margin-right: auto; max-width: 46ch; }
.cta .btn-row { justify-content: center; }

/* ---------- Footer ---------- */
.site-footer {
  background: var(--brand-dark);
  color: #c6d3df;
  font-size: .93rem;
}

.site-footer .wrap {
  display: grid;
  gap: 24px;
  padding-top: 34px;
  padding-bottom: 34px;
}

.footer-logo {
  width: 88px;
  height: 88px;
  margin-bottom: 14px;
}

.site-footer h2 {
  font-size: .78rem;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: #fff;
  margin-bottom: .8em;
}

.site-footer a { color: #fff; }

.site-footer ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
.site-footer li { margin-bottom: .45em; }

.site-footer .legal {
  border-top: 1px solid rgba(255, 255, 255, .16);
  padding-top: 18px;
  font-size: .85rem;
  color: #9db0c2;
}
.site-footer .legal p { margin: 0; }

/* ---------- Sticky tap-to-call bar (phones only) ---------- */
.callbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 50;
  display: flex;
  background: var(--brand-dark);
  border-top: 1px solid rgba(255, 255, 255, .2);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  box-shadow: 0 -2px 12px rgba(0, 0, 0, .18);
}

.callbar a {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--bar-h);
  color: #fff;
  text-decoration: none;
  font-size: 1.02rem;
  font-weight: 700;
}

.callbar a + a { border-left: 1px solid rgba(255, 255, 255, .2); }

.callbar a.is-primary { background: var(--accent); }
.callbar a.is-primary:active { background: var(--accent-dark); }

.callbar svg {
  width: 20px;
  height: 20px;
  flex: none;
}

/* ---------- Breakpoints ---------- */
@media (min-width: 560px) {
  .grid--2, .grid--3 { grid-template-columns: repeat(2, 1fr); }
  .gallery { grid-template-columns: repeat(2, 1fr); }
  .trust ul { grid-template-columns: repeat(2, 1fr); }
  .form .field--half-group {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
  }
}

@media (min-width: 768px) {
  body { padding-bottom: 0; }          /* no sticky bar on tablet/desktop */
  .callbar { display: none; }
  .header-phone { display: block; text-align: right; margin-left: auto; }

  .site-header .wrap {
    padding-top: 12px;
    padding-bottom: 12px;
  }

  .brand img { width: 64px; height: 64px; }

  .site-nav a { padding: 14px 14px; font-size: .95rem; }
  .site-nav ul { margin-left: 12px; }

  .wrap { padding: 0 32px; }
  .section { padding: 60px 0; }
  .hero__inner { padding-top: 90px; padding-bottom: 84px; }

  /* text is left-aligned here, so the right half of the room opens right up */
  .hero::after {
    background:
      radial-gradient(100% 120% at 30% 50%, rgba(8, 12, 18, 0) 45%, rgba(8, 12, 18, .40) 100%),
      linear-gradient(90deg, rgba(8, 12, 18, .78) 0%, rgba(8, 12, 18, .66) 34%, rgba(8, 12, 18, .30) 68%, rgba(8, 12, 18, .20) 100%);
  }

  /* the wide letterbox crop pulls the room away, so zoom harder here.
     Framed above centre to keep the pendants in shot. */
  .hero__img {
    --zoom-base: 1.24;
    object-position: center 38%;
  }
  .split { grid-template-columns: 1fr 1fr; gap: 40px; }
  .split--flip img { order: 2; }
  .trust ul { grid-template-columns: repeat(4, 1fr); }
  .site-footer .wrap { grid-template-columns: 1.4fr 1fr 1fr; }
  .site-footer .legal { grid-column: 1 / -1; }
}

@media (min-width: 900px) {
  .grid--3 { grid-template-columns: repeat(3, 1fr); }
  .gallery { grid-template-columns: repeat(3, 1fr); }
  .steps { grid-template-columns: repeat(3, 1fr); }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

@media print {
  .callbar, .site-nav, .cta { display: none; }
  body { padding-bottom: 0; }
}

/* screen-reader-only text */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------- Rating / reviews ---------- */
.rating {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  font-weight: 700;
}

.stars {
  color: #d9a01a;
  letter-spacing: .08em;
  font-size: 1.05rem;
}

.rating .rating__count {
  font-weight: 500;
  color: var(--muted);
}

.quote {
  margin: 0;
  background: #fff;
  border: 1px solid var(--line);
  border-left: 4px solid var(--accent);
  border-radius: var(--radius);
  padding: 20px 22px;
}

.quote p {
  margin-bottom: .8em;
  font-size: 1rem;
}

.quote .stars { display: block; margin-bottom: 10px; }

.quote cite {
  font-style: normal;
  font-weight: 700;
  font-size: .92rem;
}
.quote cite span {
  display: block;
  font-weight: 500;
  color: var(--muted);
}

/* ---------- Before / after pairs ---------- */
.ba {
  display: grid;
  gap: 16px;
  list-style: none;
  margin: 0 0 28px;
  padding: 0;
}

.ba figure {
  margin: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: #fff;
}

.ba__pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

.ba__pair img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.ba__pair img + img { border-left: 1px solid var(--line); }

.ba figcaption {
  padding: 12px 14px;
  font-size: .92rem;
}
.ba figcaption strong { display: block; }
.ba figcaption span { color: var(--muted); }

@media (min-width: 900px) {
  .ba { grid-template-columns: repeat(3, 1fr); }
}

/* ---------- Review request page ---------- */
.wrap--narrow { max-width: 640px; }

.review-actions {
  display: grid;
  gap: 12px;
  margin: 24px 0 14px;
  max-width: 420px;
}

.btn--block { width: 100%; }

.review-actions svg {
  width: 20px;
  height: 20px;
  flex: none;
}

/* ---------- Availability note ---------- */
.availability {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-top: 20px;
  padding: 9px 16px;
  border: 1px solid rgba(255, 255, 255, .3);
  border-radius: 999px;
  font-size: .93rem;
  font-weight: 600;
}

.availability::before {
  content: "";
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #6fcf8b;
  flex: none;
}

.availability--light {
  border-color: var(--line);
  background: #fff;
  color: var(--ink);
}
