/* SUNSHINE YARD DOCTORS - home
   Order: two big before/afters on landing → a short clickable index of every
   job → what each job actually is → quote form → the rotating showcase.

   The work is the loudest thing on every screen. Whitespace separates the
   showcases; it doesn't replace them.
*/

:root{
  --edge:clamp(var(--space-4),3vw,var(--space-10));
  /* one section rhythm for the whole site: 96px desktop, 64px mobile */
  --air:var(--space-24);
  --hero-h:min(66vh,640px);
  --stage-h:min(66vh,660px);
}
@media (max-width:768px){:root{--air:var(--space-16)}}
@media (max-width:860px){:root{--hero-h:min(48vh,420px);--stage-h:min(56vh,470px)}}

body{font-family:var(--font-body);color:var(--ink-900);background:var(--white)}
.shell{max-width:1520px;margin-inline:auto;padding-inline:var(--edge)}
[id]{scroll-margin-top:112px}

/* header lives in header.css - every page loads the same one */

/* ---------- hero ----------
   The words earn only as much room as they need; the showcases are what the
   visitor is meant to land on, so they start as high up the page as possible. */
.hero{padding-top:var(--air)}
/* region, price and insurance answered before the headline - the three things
   a local customer checks first */
.eyebrow{
  display:flex;align-items:center;flex-wrap:wrap;gap:var(--space-2) var(--space-3);
  margin-bottom:var(--space-4);
  font-weight:var(--weight-heavy);font-size:var(--text-xs);
  letter-spacing:var(--tracking-caps);text-transform:uppercase;color:var(--ink-500);
}
.eyebrow i{
  font-style:normal;width:6px;height:6px;border-radius:var(--radius-pill);
  background:var(--sun-500);flex:none;
}
.eyebrow span{color:var(--ink-500)}
.hero__say{
  display:grid;gap:var(--space-5);
  padding-bottom:clamp(var(--space-5),2vw,var(--space-8));
}
@media (min-width:1000px){
  /* buttons share the subline's baseline; nothing floats at its own height */
  .hero__say{grid-template-columns:minmax(0,1fr) max-content;align-items:end;gap:var(--space-12)}
}
.hero__h{
  font-family:var(--font-display);font-weight:var(--weight-black);
  font-size:clamp(var(--text-2xl),4.4vw,calc(var(--text-5xl) * 1.02));
  line-height:1.03;letter-spacing:-.02em;max-width:16ch;
}
/* the two brand accent words, shared by the H1 and the gallery heading so
   both stay in step: blue is --sky-600 (3.93:1, clears the large-text
   floor), gold is --sun-700 */
.hero__h em,.grand__h em{font-style:normal;color:var(--sky-600)}
/* H1 carries the service and the place for search. The brand line keeps its
   exact styling; the second line is set at the existing lede size so the hero
   reads as it did. */
.hero__h-brand{display:block}
.hero__h-sub{
  display:block;margin-top:var(--space-4);
  font-family:var(--font-body);font-weight:var(--weight-body);
  font-size:var(--text-lg);line-height:var(--leading-body);
  letter-spacing:normal;text-transform:none;
  color:var(--ink-500);max-width:46ch;
}

/* the system's 1% gold, spent on the one word that matters. --sun-700 rather
   than --sun-500: gold type on white is 1.79:1 at --sun-500 and 3.18:1 here,
   and only the second clears the 3:1 floor this size of display type needs. */
.hero__h u,.grand__h u{text-decoration:none;color:var(--sun-700)}
.hero__btns{display:flex;flex-wrap:wrap;gap:var(--space-3);margin-top:var(--space-6)}
@media (min-width:1000px){.hero__btns{margin-top:0}}
.btn-ghost{
  padding:var(--space-3) var(--space-6);border-radius:var(--radius-pill);
  border:1px solid var(--ink-150);font-weight:var(--weight-bold);font-size:var(--text-sm);
  transition:border-color var(--speed-fast) var(--ease-out),background-color var(--speed-fast) var(--ease-out);
}
.btn-ghost:hover{background:var(--ink-075);border-color:var(--ink-300)}

/* The two headline services stay paired side by side, but the row steps out of
   the container and runs almost the full viewport - a 32px margin each side -
   so both showcases grow proportionally. The sliders inside are untouched. */
/* the drag instruction sits with the photos it describes, not up in the hero */
.showcase__hint{
  grid-column:1/-1;justify-self:center;text-align:center;
  color:var(--ink-500);font-size:var(--text-sm);
}
.showcase{
  /* minmax(0,1fr), never a bare auto or 1fr: an aspect-ratio box with a height
     cap reports a max-content width of 600px+, and an auto grid column honours
     it, so the row blew out to 636px inside a 390px phone. minmax(0,...) lets
     the column shrink below its content's intrinsic width. */
  display:grid;grid-template-columns:minmax(0,1fr);
  gap:var(--space-3);                       /* 12px gutter between the pair */
  padding-inline:var(--edge);               /* stacked: unchanged from before */
  padding-bottom:var(--air);
}
@media (min-width:900px){
  /* columns in proportion to each pair's aspect ratio, so two portrait
     washes and one wide landscape build land at exactly the same height */
  .showcase{grid-template-columns:minmax(0,1fr) minmax(0,1fr) minmax(0,1.97fr);padding-inline:var(--space-8)}
  /* labels stack as one fixed-height block so a wrapping label can never
     push its frame out of line with the other two */
  .show__label{flex-direction:column;align-items:flex-start;gap:2px;min-height:56px;justify-content:flex-end}
}
.show{position:relative;margin:0}
/* The stamped ratio sizes the frame before any photo arrives, and the cap
   keeps all three pairs inside one screen on shorter monitors - past it the
   photos centre-crop a little instead of pushing the row under the fold. */
.show .frame{width:100%;max-height:min(54vh,520px)}
.show .frame img{width:100%;height:100%;object-fit:cover}
.show__label{
  display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-4);
  padding-bottom:var(--space-3);
}
.show__label b{
  font-family:var(--font-display);font-weight:var(--weight-heavy);
  font-size:var(--text-xl);letter-spacing:var(--tracking-display);
}
.show__label span{color:var(--ink-500)}
/* side by side wraps into four ragged lines on a phone - stack it instead */
@media (max-width:620px){
  .show__label{display:block}
  .show__label b{font-size:var(--text-lg)}
  .show__label span{display:block;margin-top:2px}
}

/* ---------- the compare frame (shared) ---------- */
.frame{
  --pos:50%;
  position:relative;overflow:hidden;
  border-radius:var(--radius-lg);
  background:var(--ink-075);
  touch-action:pan-y;                 /* drag sideways, still scroll the page */
  user-select:none;-webkit-user-select:none;
  cursor:ew-resize;
}
.show .frame{height:var(--hero-h)}
.show .frame img{width:100%;height:100%;object-fit:cover;display:block;-webkit-user-drag:none}
.frame__before{position:absolute;inset:0;clip-path:inset(0 calc(100% - var(--pos)) 0 0)}
/* eased for taps, keys and the arrival wipe - switched off while dragging so
   the divider tracks the finger exactly */
.frame.is-easing .frame__before{transition:clip-path .5s var(--ease-out)}
.frame.is-easing .handle{transition:left .5s var(--ease-out)}

.tag{
  position:absolute;top:var(--space-4);z-index:2;
  padding:var(--space-2) var(--space-4);border-radius:var(--radius-pill);
  font-weight:var(--weight-bold);font-size:var(--text-xs);line-height:1;
  letter-spacing:.18em;text-transform:uppercase;
  transition:opacity var(--speed-base) var(--ease-out);
}
.tag--before{left:var(--space-4);background:var(--ink-900);color:var(--white)}
.tag--after{right:var(--space-4);background:var(--sky-500);color:var(--ink-900)}

.handle{
  position:absolute;top:0;bottom:0;left:var(--pos);z-index:3;
  width:56px;margin-left:-28px;
  display:grid;place-items:center;
  cursor:ew-resize;touch-action:none;
}
.handle::before{
  content:"";position:absolute;top:0;bottom:0;left:50%;
  width:2px;margin-left:-1px;background:var(--white);
}
.grip{
  width:48px;height:48px;border-radius:var(--radius-pill);
  display:grid;place-items:center;
  background:var(--white);color:var(--ink-900);
  box-shadow:var(--shadow-raised);
  transform:translateX(var(--grip-shift,0px));
  transition:transform var(--speed-base) var(--ease-out),
             background-color var(--speed-fast) var(--ease-out),
             color var(--speed-fast) var(--ease-out);
}
.handle:hover .grip{transform:translateX(var(--grip-shift,0px)) scale(1.06)}
/* Body copy saying "drag the handle" is a weak signal. The grip nudges itself
   a few times when a comparison first appears, then stops for good - and stops
   immediately if the visitor has already worked it out. */
@keyframes grabhint{
  0%,100%{transform:none;box-shadow:var(--shadow-raised)}
  35%{transform:translateX(-7px)}
  65%{transform:translateX(7px)}
}
.frame.is-hinting .grip{animation:grabhint 1.9s var(--ease-out) 2}
@media (prefers-reduced-motion:reduce){.frame.is-hinting .grip{animation:none}}
.handle:focus-visible .grip,.frame:active .grip{background:var(--sky-500);color:var(--ink-900)}
.grip svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}

/* Body copy caps at a 68-character measure. Longer lines than that make the
   eye lose its place on the return sweep. Measure only - no font changes. */
.review blockquote,.door ul,.faq details p,
.quote__p,.form-note,.foot__cols p{max-width:68ch}

/* headings balance their own lines and supporting copy avoids one-word last
   lines - the codebase already did this for review quotes, now it is uniform */
.pick__h,.quote__h,.grand__h,.faq__h,.trade__h{text-wrap:balance}
.trade__p,.job p,.door li,.faq details p,.quote__p{text-wrap:pretty}

/* ---------- phone-only shortcut strip ----------
   A slim band between the hero and the reviews, for someone who already knows
   what they want and does not need to be sold. Desktop keeps the full nav and
   the four door cards, so it is display:none above the phone breakpoint and
   the desktop layout is untouched.

   Ground is --sky-100, not --sky-050: the reviews band directly below is
   sky-050, so a sky-050 strip merged straight into it and read as that
   section's padding rather than as a control. sky-100 separates from the white
   hero above and the wash below, without becoming another blue band competing
   with the quote section. */
.quicklink{display:none}
@media (max-width:767px){
  .quicklink{
    display:flex;align-items:center;justify-content:space-between;
    gap:var(--space-4);
    min-height:60px;                       /* a full-width tap target */
    padding-block:var(--space-3);
    padding-inline:var(--edge);
    background:var(--sky-100);
    border-top:1px solid var(--sky-300);
    border-bottom:1px solid var(--sky-300);
    color:var(--ink-900);
    font-size:var(--text-md);
    /* body weight, deliberately: at --text-md anything heavier wraps the copy
       to a second line at 390 and the band stops being slim. The sky-100
       ground and the darker chevron carry the visibility instead. */
    line-height:var(--leading-body);
    transition:background-color var(--speed-fast) var(--ease-out);
  }
  .quicklink:active{background:var(--sky-300)}
  .quicklink svg{
    width:22px;height:22px;flex:none;
    fill:none;stroke:var(--sky-700);stroke-width:2.5;
    stroke-linecap:round;stroke-linejoin:round;
  }
}

/* ---------- reviews ----------
   Social proof sits directly under the work, where the visitor has just been
   convinced by the photos and is looking for a reason to believe them. */
.reviews{background:var(--sky-050);padding-block:var(--air)}

/* the anchor of the section: the score, the stars, the source */
.trustline{
  display:flex;align-items:center;gap:var(--space-3);flex-wrap:wrap;
  margin-bottom:var(--space-10);
}
.trustline__v{
  font-family:var(--font-display);font-weight:var(--weight-black);
  font-size:clamp(var(--text-3xl),4vw,var(--text-5xl));line-height:1;
  letter-spacing:var(--tracking-display);
}
.trustline .stars{margin-bottom:0}
.trustline .stars svg{width:22px;height:22px}
.trustline__k{color:var(--ink-500);font-size:var(--text-lg)}

/* align-items:start, so a card is only as tall as its own review. Stuart's
   runs three times the others and the ragged edge is what reads as real. */
.reviews__grid{display:grid;gap:var(--space-6);align-items:start}
@media (min-width:820px){.reviews__grid{grid-template-columns:repeat(3,1fr);gap:var(--space-8)}}
.review{
  padding:clamp(var(--space-6),2.5vw,var(--space-8));
  background:var(--white);
  border:1px solid var(--ink-150);border-radius:var(--radius-lg);
  box-shadow:var(--shadow-card);
}
.review blockquote{
  font-size:var(--text-lg);line-height:1.5;margin-bottom:var(--space-5);
  text-wrap:pretty;
}
.review footer{color:var(--ink-500);font-size:var(--text-sm)}
.review__name{display:block;color:var(--ink-900);font-size:var(--text-md);font-weight:var(--weight-bold)}
.review__cred{display:block;margin-top:2px}
.stars{display:flex;gap:2px;margin-bottom:var(--space-4)}
.stars svg{width:16px;height:16px;fill:var(--sun-500)}

/* inline-block so the ghost pill's vertical padding actually takes up space */
.reviews__cta{margin-top:var(--space-10);text-align:center}
.reviews__cta a{display:inline-block}

/* ---------- the short index window ---------- */
.pick{background:var(--white);padding-block:var(--air)}
.pick__head{
  display:flex;justify-content:space-between;align-items:baseline;
  gap:var(--space-6);flex-wrap:wrap;margin-bottom:var(--space-6);
}
.pick__h{
  font-family:var(--font-display);font-weight:var(--weight-heavy);
  font-size:clamp(var(--text-xl),3vw,var(--text-3xl));letter-spacing:var(--tracking-display);
}
/* Four doors, not twenty-three. Asking a customer to pick their own job off a
   long list makes them self-diagnose; the full index lives on Services. */
.doors{display:grid;gap:var(--space-4)}
@media (min-width:700px){.doors{grid-template-columns:repeat(2,1fr)}}
@media (min-width:1100px){.doors{grid-template-columns:repeat(4,1fr)}}
.door{
  display:block;padding:var(--space-6);
  background:var(--white);border:1px solid var(--ink-150);border-radius:var(--radius-lg);
  transition:border-color var(--speed-base) var(--ease-out),
             box-shadow var(--speed-base) var(--ease-out),
             transform var(--speed-base) var(--ease-out);
}
.door:hover{border-color:var(--sky-300);box-shadow:var(--shadow-card);transform:translateY(-2px)}
.door h3{
  font-family:var(--font-display);font-weight:var(--weight-heavy);
  font-size:var(--text-xl);letter-spacing:var(--tracking-display);
  margin-bottom:var(--space-3);
}
.door ul{display:grid;gap:var(--space-2);color:var(--ink-500);font-size:var(--text-md)}
.door li{display:flex;gap:var(--space-2)}
.door li::before{content:"·";color:var(--ink-500);flex:none}
.door em{
  display:inline-block;margin-top:var(--space-5);font-style:normal;
  font-weight:var(--weight-bold);font-size:var(--text-sm);color:var(--sky-700);
}
/* leaves the blue ramp on hover: at 14px there is no brighter blue that
   clears 4.5:1, so the shift goes to ink instead */
.door:hover em{color:var(--ink-900)}
/* was a quiet underlined link and read as body text; it now uses the existing
   ghost button so it is findable without introducing a new style */
.doors__more{display:inline-block;margin-top:var(--space-8);color:var(--sky-700)}

/* ---------- what each job is ---------- */
.trade{padding-block:var(--air);border-top:1px solid var(--ink-150)}
.trade__head{display:grid;gap:var(--space-8);margin-bottom:var(--space-10)}
@media (min-width:1000px){
  .trade__head{grid-template-columns:minmax(0,1fr) minmax(0,42%);align-items:center;gap:var(--space-16)}
}
.trade__n{
  font-family:var(--font-display);font-weight:var(--weight-black);
  font-size:var(--text-sm);color:var(--sky-700);
  letter-spacing:var(--tracking-caps);margin-bottom:var(--space-3);
}
.trade__h{
  font-family:var(--font-display);font-weight:var(--weight-heavy);
  font-size:clamp(var(--text-2xl),4vw,var(--text-4xl));
  line-height:1.1;letter-spacing:var(--tracking-display);max-width:16ch;
}
.trade__p{margin-top:var(--space-5);font-size:var(--text-lg);
  line-height:var(--leading-body);color:var(--ink-500);max-width:46ch}
/* each trade carries its own draggable before/after, so the proof of that
   trade sits with the description of it rather than only in the gallery */
.trade__shot .frame{aspect-ratio:4/3}
.trade__shot .frame img{width:100%;height:100%;object-fit:cover;display:block}
@media (max-width:1000px){.trade__shot .frame{aspect-ratio:3/2}}

.jobs{display:grid;gap:var(--space-4)}
@media (min-width:700px){.jobs{grid-template-columns:repeat(2,1fr)}}
@media (min-width:1100px){.jobs{grid-template-columns:repeat(3,1fr)}}
.job{
  padding:var(--space-6);
  background:var(--white);
  border:1px solid var(--ink-150);border-radius:var(--radius-lg);
  transition:border-color var(--speed-base) var(--ease-out),
             box-shadow var(--speed-base) var(--ease-out),
             transform var(--speed-base) var(--ease-out);
}
.job:hover,.job:target{border-color:var(--sky-300);box-shadow:var(--shadow-card);transform:translateY(-2px)}
.job:target{border-color:var(--sky-500)}
/* a step down, so the 48px trade heading above them clearly leads */
.job h4{
  font-family:var(--font-display);font-weight:var(--weight-heavy);
  font-size:var(--text-md);letter-spacing:var(--tracking-display);
  margin-bottom:var(--space-2);
}
.job p{color:var(--ink-500);line-height:var(--leading-body);font-size:var(--text-sm)}

/* ---------- the Yard Club hook ----------
   A hook, not a pitch: enough to make someone curious, and the whole case
   lives on its own page. It sits between the white chooser above and the blue
   quote band below, so sky-050 is the quiet step between the two rather than
   a third loud thing competing with the form. */
.club{background:var(--sky-050);padding-block:var(--air)}
.club__in{display:grid;gap:var(--space-8);align-items:center}
@media (min-width:768px){
  .club__in{grid-template-columns:minmax(0,1fr) auto;gap:var(--space-16)}
}
.club__h{
  font-family:var(--font-display);font-weight:var(--weight-heavy);
  font-size:clamp(var(--text-xl),3vw,var(--text-3xl));
  line-height:var(--leading-heading);letter-spacing:var(--tracking-display);
}
/* "Yard" in the signature blue, the same as the gallery heading and the club
   page. Gold is not used as type anywhere: it does not reach the contrast
   floor on any ground this site has. */
.club__h em{font-style:normal;color:var(--sky-600)}
.club__p{
  margin-top:var(--space-4);font-size:var(--text-md);
  line-height:var(--leading-body);color:var(--ink-700);max-width:56ch;
}
.club__go{
  display:inline-flex;align-items:center;gap:var(--space-2);
  margin-top:var(--space-6);min-height:44px;
  font-family:var(--font-display);font-weight:var(--weight-heavy);
  font-size:var(--text-md);letter-spacing:var(--tracking-display);
  color:var(--ink-900);
  border-bottom:2px solid var(--sky-500);
  transition:color var(--speed-fast) var(--ease-out),
             border-color var(--speed-fast) var(--ease-out);
}
.club__go:hover{color:var(--sky-700);border-color:var(--sky-700)}
.club__go span{transition:transform var(--speed-fast) var(--ease-out)}
.club__go:hover span{transform:translateX(3px)}
@media (prefers-reduced-motion:reduce){.club__go span{transition:none}}
/* decorative, and the first thing to go when the column gets narrow */
.club__art{display:none}
@media (min-width:768px){
  .club__art{display:grid;place-items:center;width:120px;height:120px}
  .club__art svg{width:100%;height:100%}
}
.club__art .d-sun{fill:var(--sun-500)}
.club__art .s-sky{stroke:var(--sky-500)}

/* ---------- quote ---------- */
.quote{background:var(--sky-500);padding-block:var(--air)}
.quote__grid{display:grid;gap:var(--space-10)}
@media (min-width:1000px){.quote__grid{grid-template-columns:minmax(0,34ch) minmax(0,1fr);gap:var(--space-16)}}
/* sentence case: every other h2 on the page is, and in caps at --weight-black
   this one set as a three-line slab that shouted over the form beside it */
.quote__h{
  font-family:var(--font-display);font-weight:var(--weight-black);
  font-size:clamp(var(--text-2xl),3.6vw,var(--text-4xl));
  line-height:1.08;letter-spacing:var(--tracking-display);
  color:var(--ink-900);max-width:16ch;
}
.quote__p{
  margin-top:var(--space-5);color:var(--ink-900);
  font-size:var(--text-lg);line-height:var(--leading-body);max-width:38ch;
}
/* was an underlined string in white - 2.67:1 on this band, and it read as an
   afterthought next to the form. A white pill inverts the section's own CTA
   (sky-500 pill, ink label) and makes calling the obvious second option. */
.quote__tel{
  display:inline-flex;align-items:center;gap:var(--space-3);
  margin-top:var(--space-8);
  padding:var(--space-4) var(--space-6);border-radius:var(--radius-pill);
  background:var(--white);color:var(--ink-900);
  font-family:var(--font-display);font-weight:var(--weight-heavy);
  font-size:var(--text-xl);letter-spacing:var(--tracking-display);
  white-space:nowrap;box-shadow:var(--shadow-card);
  transition:transform var(--speed-fast) var(--ease-out),
             box-shadow var(--speed-base) var(--ease-out);
}
.quote__tel:hover{transform:translateY(-2px);box-shadow:var(--shadow-raised)}
.quote__tel:active{transform:scale(.98)}
.quote__tel svg{
  width:20px;height:20px;flex:none;
  fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;
}
.card{
  background:var(--white);border-radius:var(--radius-xl);
  padding:clamp(var(--space-6),3vw,var(--space-10));
  box-shadow:var(--shadow-raised);
}
.fields{display:grid;gap:var(--space-5)}
@media (min-width:640px){.fields{grid-template-columns:1fr 1fr}.f-full{grid-column:1/-1}}
.field{display:grid;gap:var(--space-2)}
.field label{font-weight:var(--weight-bold);font-size:var(--text-sm)}
.field input,.field select,.field textarea{
  width:100%;padding:var(--space-3) var(--space-4);
  font:inherit;color:inherit;
  background:var(--white);border:1px solid var(--ink-150);border-radius:var(--radius-md);
  transition:border-color var(--speed-fast) var(--ease-out);
}
.field textarea{resize:vertical;min-height:120px}
.field input:focus,.field select:focus,.field textarea:focus{outline:none;border-color:var(--sky-500)}
.field input::placeholder,.field textarea::placeholder{color:var(--ink-500)}
.field:has(select){position:relative}
.field select{appearance:none;-webkit-appearance:none;padding-right:var(--space-10)}
.field:has(select)::after{
  content:"";position:absolute;right:var(--space-5);bottom:22px;
  width:9px;height:9px;
  border-right:2px solid var(--ink-500);border-bottom:2px solid var(--ink-500);
  transform:rotate(45deg);pointer-events:none;
}
.send{
  grid-column:1/-1;justify-self:start;
  padding:var(--space-4) var(--space-8);border-radius:var(--radius-pill);
  background:var(--sky-500);color:var(--ink-900);
  font-weight:var(--weight-bold);font-size:var(--text-md);
  box-shadow:var(--shadow-button);
  transition:background-color var(--speed-fast) var(--ease-out),transform var(--speed-fast) var(--ease-out);
}
.send:hover{background:var(--sky-600);transform:translateY(-2px)}
.send:active{transform:scale(.98)}
/* the business's own first step is "send a photo", so the form has to accept one */
.drop{
  grid-column:1/-1;
  padding:var(--space-4) var(--space-5);
  border:1px dashed var(--ink-300);border-radius:var(--radius-md);
  background:var(--sky-050);
}
.drop label{display:block;font-weight:var(--weight-bold);font-size:var(--text-sm);margin-bottom:var(--space-2)}
.drop input[type=file]{
  width:100%;font-size:var(--text-sm);color:var(--ink-700);
  border:0;padding:0;background:none;
}
.drop input[type=file]::file-selector-button{
  margin-right:var(--space-4);padding:var(--space-2) var(--space-4);
  border:1px solid var(--ink-150);border-radius:var(--radius-pill);
  background:var(--white);color:var(--ink-900);
  font:inherit;font-weight:var(--weight-bold);font-size:var(--text-sm);cursor:pointer;
}
.drop input[type=file]::file-selector-button:hover{background:var(--ink-075)}
.drop small{display:block;margin-top:var(--space-3);color:var(--ink-500);font-size:var(--text-sm)}
.drop small a{color:var(--sky-700);font-weight:var(--weight-bold);text-decoration:underline;text-underline-offset:3px}

/* insurance sits with the form, not buried in the footer */
.trust{
  display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2) var(--space-4);
  margin-top:var(--space-5);padding-top:var(--space-5);
  border-top:1px solid var(--ink-150);
  font-weight:var(--weight-bold);font-size:var(--text-sm);color:var(--ink-700);
}
.trust svg{width:18px;height:18px;fill:none;stroke:var(--success);stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round;flex:none}
.trust span{color:var(--ink-500);font-weight:var(--weight-body)}

.form-note{margin-top:var(--space-4);color:var(--ink-500);font-size:var(--text-sm)}
.form-status{margin-top:var(--space-4);min-height:1.2em;font-weight:var(--weight-medium);color:var(--danger)}
.done{padding:var(--space-8);text-align:left}
.done b{
  display:inline-block;margin-bottom:var(--space-3);
  padding:var(--space-2) var(--space-4);border-radius:var(--radius-pill);
  background:var(--success);color:var(--white);
  font-weight:var(--weight-heavy);font-size:var(--text-xs);
  letter-spacing:var(--tracking-caps);text-transform:uppercase;
}
.done h3{font-family:var(--font-display);font-weight:var(--weight-heavy);
  font-size:var(--text-xl);letter-spacing:var(--tracking-display);margin-bottom:var(--space-2)}
.done p{color:var(--ink-500)}

/* ---------- the rotating showcase ---------- */
/* Home reads white -> sky-050 -> white -> sky-500 -> sky-050 -> white,
   so each section is told apart by ground colour rather than a hairline. */
.grand{background:var(--white);padding-block:var(--air)}
.grand__head{
  display:flex;justify-content:space-between;align-items:flex-end;
  gap:var(--space-8);flex-wrap:wrap;margin-bottom:var(--space-8);
}
.grand__h{
  font-family:var(--font-display);font-weight:var(--weight-black);
  font-size:clamp(var(--text-2xl),4vw,var(--text-4xl));
  line-height:1.08;letter-spacing:var(--tracking-display);max-width:16ch;
}

/* Scoped to the home gallery: services loads this sheet after c06 and its
   stacked viewers must keep c06's stage. The stage is a filmstrip, not a stack: flick it with a finger from the
   gaps and card edges, or scroll it with a trackpad or shift+wheel anywhere.
   Touching the photograph itself still drags the before/after divider - the
   frame's touch-action:pan-y blocks native horizontal panning there, so the
   two gestures never fight. Arrows, thumbnails and keyboard still rotate via
   the viewer; scripts/strip.js keeps strip position and viewer state in sync. */
.grand .stage{
  position:relative;height:var(--stage-h);
  display:flex;align-items:center;gap:var(--space-4);
  overflow-x:auto;scroll-snap-type:x mandatory;
  overscroll-behavior-x:contain;
  scrollbar-width:none;
  padding-inline:var(--space-2);
}
.grand .stage::-webkit-scrollbar{display:none}
@media (prefers-reduced-motion:no-preference){.grand .stage{scroll-behavior:smooth}}
/* each card is one full page of the strip - exactly one pair on stage at a
   time, the next one arrives only as you flick or rotate. The empty space
   either side of the photo is strip-flick surface on touch. */
.grand .slide{flex:none;width:100%;height:100%;display:grid;place-items:center;scroll-snap-align:center}
/* bounded on both axes so a tall job fills the height and a wide one fills the
   width, each at its true proportions - nothing cropped, nothing letterboxed */
/* the card's box comes from its stamped aspect-ratio, so the strip is full
   width before a single photo loads and lazy images paint into place. Wide
   cards cap at the viewport on phones; object-fit absorbs the sliver. */
.grand .slide .frame{height:100%;max-width:min(92vw,100%)}
.grand .slide .frame img{display:block;width:100%;height:100%;object-fit:cover}

.rail{display:flex;align-items:center;gap:var(--space-4);margin-top:var(--space-6);flex-wrap:wrap}
.nav{
  width:48px;height:48px;border-radius:var(--radius-pill);
  display:grid;place-items:center;
  border:1px solid var(--ink-150);color:var(--ink-900);flex:none;
  transition:background-color var(--speed-fast) var(--ease-out),
             border-color var(--speed-fast) var(--ease-out),color var(--speed-fast) var(--ease-out);
}
.nav:hover{background:var(--ink-900);border-color:var(--ink-900);color:var(--white)}
.nav:active{transform:scale(.96)}
.nav svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.count{color:var(--ink-500);font-variant-numeric:tabular-nums}
.thumbs{
  display:flex;gap:var(--space-3);overflow-x:auto;scrollbar-width:none;flex:1;min-width:0;
  cursor:grab;
  /* a scrub must never start selecting or ghost-dragging the photos */
  -webkit-user-select:none;user-select:none;
}
.thumbs:active{cursor:grabbing}
.thumbs img{-webkit-user-drag:none}
.thumbs::-webkit-scrollbar{display:none}
.thumb{
  flex:none;position:relative;width:88px;height:66px;
  border-radius:var(--radius-sm);overflow:hidden;background:var(--ink-075);
  /* the ring draws inside the photo edge: outside it was clipped by the
     rail's scrollport, worst of all when the active thumb parks far left */
  opacity:.6;outline:2px solid transparent;outline-offset:-2px;
  transition:opacity var(--speed-base) var(--ease-out),outline-color var(--speed-base) var(--ease-out);
}
.thumb img{width:100%;height:100%;object-fit:cover;display:block}
.thumb:hover{opacity:.85}
.thumb.is-on{opacity:1;outline-color:var(--sky-500)}
.thumb:not(.is-on){filter:saturate(.55)}
.thumb span{
  position:absolute;left:4px;bottom:4px;
  padding:2px 5px;border-radius:var(--radius-sm);
  background:var(--ink-900);color:var(--white);
  font-weight:var(--weight-heavy);font-size:var(--text-xs);line-height:1.2;
  font-variant-numeric:tabular-nums;
  transition:background-color var(--speed-fast) var(--ease-out),
             color var(--speed-fast) var(--ease-out);
}
/* the number chip is the selection signal: signature blue, ink type on it */
.thumb.is-on span{background:var(--sky-500);color:var(--ink-900)}

/* mid-page prompts - spacing only, the pill itself is the existing .cta */
.mid-cta{margin-top:var(--space-10)}

/* ---------- FAQ ---------- */
/* The FAQ reads as a card floating above the footer, not a band butting into
   it: rounded corners, and clear of the viewport edges at every width so the
   corners always show. .shell caps it at 1520px and centres it; the second
   cap keeps a gutter on screens narrower than that. */
.faq{
  background:var(--sky-050);padding-block:var(--air);
  border-radius:var(--radius-xl);
  max-width:min(1520px,calc(100% - var(--space-8)));
  margin-inline:auto;
  margin-bottom:clamp(var(--space-10),5vw,var(--space-16));
}
.faq__h{
  font-family:var(--font-display);font-weight:var(--weight-black);
  font-size:clamp(var(--text-2xl),3.6vw,var(--text-4xl));
  line-height:1.08;letter-spacing:var(--tracking-display);max-width:16ch;
}
/* The questions used to be hairline rows two-thirds across, which left a wide
   empty gutter and read as an afterthought. Now the heading holds its own
   column and each question is a card, so the section has a shape. */
.faq__grid{display:grid;gap:var(--space-8)}
@media (min-width:1000px){
  .faq__grid{
    grid-template-columns:minmax(0,30ch) minmax(0,1fr);
    gap:var(--space-16);align-items:start;
  }
  /* the list is the long side - the heading rides along rather than scrolling away */
  .faq__aside{position:sticky;top:var(--space-24)}
}
.faq__p{margin-top:var(--space-4);color:var(--ink-500);line-height:var(--leading-body);max-width:30ch}
.faq__tel{
  display:inline-block;margin-top:var(--space-5);
  font-family:var(--font-display);font-weight:var(--weight-heavy);
  font-size:var(--text-xl);letter-spacing:var(--tracking-display);
  color:var(--ink-900);border-bottom:2px solid var(--sky-500);
  transition:border-color var(--speed-fast) var(--ease-out);
}
.faq__tel:hover{border-color:var(--sky-700)}

.faq__list{display:grid;gap:var(--space-3)}
.faq details{
  background:var(--white);
  border:1px solid var(--ink-150);border-radius:var(--radius-lg);
  transition:border-color var(--speed-base) var(--ease-out),
             box-shadow var(--speed-base) var(--ease-out);
}
.faq details:hover{border-color:var(--sky-300)}
.faq details[open]{border-color:var(--sky-300);box-shadow:var(--shadow-card)}
.faq summary{
  display:flex;justify-content:space-between;align-items:center;gap:var(--space-5);
  padding:var(--space-5) var(--space-6);cursor:pointer;list-style:none;
  border-radius:var(--radius-lg);
  font-family:var(--font-display);font-weight:var(--weight-heavy);
  font-size:var(--text-lg);letter-spacing:var(--tracking-display);
  transition:color var(--speed-fast) var(--ease-out);
}
.faq summary::-webkit-details-marker{display:none}
.faq summary:hover{color:var(--sky-700)}
/* a real element, not a pseudo, so the disc and the arrow centre on each other
   with place-items instead of hand-tuned offsets */
.faq__chev{
  flex:none;display:grid;place-items:center;
  width:34px;height:34px;border-radius:var(--radius-pill);
  background:var(--sky-050);
  transition:background-color var(--speed-fast) var(--ease-out);
}
.faq__chev::after{
  content:"";width:9px;height:9px;
  border-right:2px solid var(--sky-700);border-bottom:2px solid var(--sky-700);
  transform:rotate(45deg) translate(-2px,-2px);
  transition:transform var(--speed-base) var(--ease-out),
             border-color var(--speed-fast) var(--ease-out);
}
.faq details[open] .faq__chev{background:var(--sky-500)}
.faq details[open] .faq__chev::after{
  border-color:var(--ink-900);
  transform:rotate(-135deg) translate(-3px,-3px);
}
.faq details p{
  padding:0 var(--space-6) var(--space-6);
  color:var(--ink-500);line-height:var(--leading-body);max-width:62ch;
}
@keyframes faqreveal{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
.faq details[open] p{animation:faqreveal var(--speed-base) var(--ease-out)}
@media (prefers-reduced-motion:reduce){.faq details[open] p{animation:none}}

/* ---------- floating call bubble (phones only) ----------
   Replaces the sticky action bar. The bar took a permanent 56px strip off
   every phone screen; this takes a circle in the bottom-left corner, which is
   the thumb's easiest reach on a right-handed grip and the one corner nothing
   else on this site uses.

   sky-500 ground with an ink-900 glyph - 7.37:1, and the site's own colour
   law: never white on sky-500. */
.callbub{display:none}
@media (max-width:767px){
  .callbub{
    position:fixed;z-index:50;                 /* over the page, under the header at 60 */
    left:var(--space-4);
    bottom:calc(env(safe-area-inset-bottom,0px) + var(--space-4));
    display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-3);
    /* hidden with visibility, not just opacity: that takes it out of the tab
       order and the accessibility tree in one move, with no aria to keep in
       sync */
    opacity:0;visibility:hidden;
    transition:opacity var(--speed-base) var(--ease-out),
               visibility 0s linear var(--speed-base);
  }
  .callbub.is-on{
    opacity:1;visibility:visible;
    transition:opacity var(--speed-base) var(--ease-out),visibility 0s;
  }

  .callbub__btn,.callbub__tel{
    display:grid;place-items:center;flex:none;
    border-radius:var(--radius-pill);
    background:var(--sky-500);color:var(--ink-900);
    box-shadow:var(--shadow-button);
  }
  .callbub__btn{width:56px;height:56px}
  .callbub__tel{width:72px;height:72px}
  .callbub__btn svg{width:24px;height:24px}
  .callbub__tel svg{width:30px;height:30px}
  .callbub svg{
    fill:none;stroke:currentColor;stroke-width:2;
    stroke-linecap:round;stroke-linejoin:round;
  }
  .callbub__btn:active,.callbub__tel:active{background:var(--sky-600)}

  /* the large bubble springs out of the small one: the origin sits on its own
     bottom edge, which is the edge nearest the button */
  .callbub__tel{
    visibility:hidden;opacity:0;transform:scale(.6);
    transform-origin:50% 100%;
  }
  .callbub.is-open .callbub__tel{
    visibility:visible;
    animation:callbub-pop 260ms var(--ease-out) forwards;
  }
  .callbub.is-closing .callbub__tel{
    visibility:visible;
    animation:callbub-drop 180ms var(--ease-out) forwards;
  }
}
/* the overshoot is what makes it read as a spring rather than a fade */
@keyframes callbub-pop{
  0%{opacity:0;transform:scale(.6)}
  60%{opacity:1;transform:scale(1.06)}
  100%{opacity:1;transform:scale(1)}
}
@keyframes callbub-drop{
  from{opacity:1;transform:scale(1)}
  to{opacity:0;transform:scale(.6)}
}
@media (prefers-reduced-motion:reduce){
  .callbub{transition:none}
  .callbub.is-open .callbub__tel{animation:none;opacity:1;transform:none}
  .callbub.is-closing .callbub__tel{animation:none;opacity:0;visibility:hidden}
}

/* the small footer's links, on the pages that use it */
.base__nav{display:flex;flex-wrap:wrap;gap:var(--space-2) var(--space-5)}
.base__nav a{
  color:var(--ink-500);
  border-bottom:1px solid transparent;
  transition:color var(--speed-fast) var(--ease-out),
             border-color var(--speed-fast) var(--ease-out);
}
.base__nav a:hover{color:var(--ink-900);border-color:var(--sky-500)}
.base__nav a[aria-current="page"]{color:var(--ink-900);border-color:var(--ink-150)}

/* ---------- footer ----------
   Crisp close on ink: a CTA row where the phone number is the hero, the
   detail columns under a hairline, and a meta bar to finish. Sky accents,
   nothing under AA on the dark ground. */
.foot{background:var(--ink-900);color:var(--white);padding-block:var(--air)}
.foot .t-micro{color:var(--sky-300)}

.foot__cta{
  display:grid;gap:var(--space-8);
  padding-bottom:clamp(var(--space-8),4vw,var(--space-12));
  border-bottom:1px solid var(--ink-700);
}
@media (min-width:900px){
  .foot__cta{grid-template-columns:minmax(0,1fr) auto;align-items:end}
}
.foot__ready{margin-bottom:var(--space-3)}
.foot__tel{
  font-family:var(--font-display);font-weight:var(--weight-black);
  font-size:clamp(var(--text-3xl),6vw,calc(var(--text-5xl) * 1.15));
  letter-spacing:var(--tracking-display);line-height:1;white-space:nowrap;
  transition:color var(--speed-fast) var(--ease-out);
}
.foot__tel:hover{color:var(--sky-500)}
.foot__mail{margin-top:var(--space-4)}
.foot__mail a{
  color:var(--ink-150);text-decoration:underline;
  text-decoration-color:var(--ink-700);text-underline-offset:4px;
  transition:color var(--speed-fast) var(--ease-out),
             text-decoration-color var(--speed-fast) var(--ease-out);
}
.foot__mail a:hover{color:var(--white);text-decoration-color:var(--sky-500)}
.foot__acts{display:flex;flex-wrap:wrap;gap:var(--space-3);align-items:center}
/* quiet outline pills beside the loud one */
.foot__pill{
  padding:var(--space-3) var(--space-6);border-radius:var(--radius-pill);
  border:1px solid var(--ink-700);color:var(--white);
  font-weight:var(--weight-bold);font-size:var(--text-sm);
  transition:border-color var(--speed-fast) var(--ease-out),
             color var(--speed-fast) var(--ease-out),
             transform var(--speed-fast) var(--ease-out);
}
.foot__pill:hover{border-color:var(--sky-300);color:var(--sky-300);transform:translateY(-2px)}

.foot__cols{
  display:grid;gap:var(--space-8);
  padding-block:clamp(var(--space-8),4vw,var(--space-12));
}
@media (min-width:700px){.foot__cols{grid-template-columns:repeat(3,1fr);gap:var(--space-10)}}
.foot__k{margin-bottom:var(--space-4)}
.foot__cols ul{display:grid;gap:var(--space-2)}
.foot__cols a{color:var(--white);transition:color var(--speed-fast) var(--ease-out)}
.foot__cols a:hover{color:var(--sky-300)}
.foot__cols p,.foot__cols li{color:var(--ink-150);line-height:var(--leading-body)}
.foot__ins{margin-top:var(--space-5)}
/* the footer shows the headline suburbs; the full list lives in the FAQ */
.foot__more{margin-top:var(--space-4)}
.foot__more a{text-decoration:underline;text-underline-offset:4px;text-decoration-color:var(--ink-700)}
.foot__more a:hover{text-decoration-color:var(--sky-300)}

.foot__meta{
  display:flex;justify-content:space-between;align-items:baseline;
  gap:var(--space-4);flex-wrap:wrap;
  padding-top:var(--space-6);border-top:1px solid var(--ink-700);
}
.foot__top{transition:color var(--speed-fast) var(--ease-out)}
.foot__top:hover{color:var(--white)}

/* ---------- the footer on a phone ----------
   Nothing is removed: the hours, the ABN, the insured line and the suburb
   list are local search signals and the page is indexed mobile-first. The
   height comes out of rhythm instead - desktop spacing repeated down a 390px
   column reads as a second page.

   The three detail columns go two-up. Services and Hours are short lists and
   sit side by side; the suburb list needs the full measure to stay readable,
   so it spans both. Detail type drops one step to --text-sm, which is the
   floor - anything under it stops being a paragraph on a phone.

   Ordered after the min-width:700px rule above so it wins between 700 and
   767, which this pass counts as mobile. */
@media (max-width:767px){
  .foot{padding-top:var(--space-5);padding-bottom:var(--space-4)}

  .foot__cta{gap:var(--space-4);padding-bottom:var(--space-3)}
  .foot__ready{margin-bottom:var(--space-1)}
  /* one step down and still the loudest thing in the footer by a wide
     margin: nothing else here is display-black or over 16px */
  .foot__tel{font-size:var(--text-2xl)}
  .foot__mail{margin-top:var(--space-2);font-size:var(--text-sm)}

  .foot__cols{
    grid-template-columns:repeat(2,minmax(0,1fr));
    gap:var(--space-5);
    padding-block:var(--space-3);
  }
  .foot__cols > div:nth-child(3){grid-column:1/-1}
  .foot__k{margin-bottom:var(--space-2)}
  /* --text-sm is the floor here, not a preference: below it a footer
     paragraph stops being readable on a phone. The leading comes in to
     --leading-heading, which is what buys most of the height back, and the
     link lists get their gap widened so the rows keep their separation. */
  .foot__cols p,.foot__cols li{font-size:var(--text-sm);line-height:var(--leading-heading)}
  .foot__cols ul{gap:var(--space-3)}
  .foot__ins{margin-top:var(--space-3)}
  .foot__more{margin-top:var(--space-3)}

  .foot__meta{gap:var(--space-2);padding-top:var(--space-3)}
}

.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
