/* ============================================================
   JC Home Services — base + components (light mode only)
   Ported from the AnchorWorks component vocabulary.
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--fs-body);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img { max-width: 100%; height: auto; display: block; }
h1, h2, h3 { font-family: var(--serif); font-weight: 400; line-height: 1.1; margin: 0; letter-spacing: -0.01em; }
h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); line-height: 1.25; }
p  { margin: 0 0 var(--space-sm); }
a  { color: var(--accent-deep); }

.container { width: min(100% - var(--gutter) * 2, var(--container)); margin-inline: auto; }
.container--narrow { width: min(100% - var(--gutter) * 2, var(--container-narrow)); margin-inline: auto; }
.section { padding-block: var(--section-y); }
.section--alt { background: var(--paper-2); }
.section--tight { padding-block: calc(var(--section-y) * 0.6); }
.text-center { text-align: center; }
.measure { max-width: 62ch; }
.mx-auto { margin-inline: auto; }

/* Accessibility ------------------------------------------------ */
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--ink); color: var(--paper);
  padding: var(--space-xs) var(--space-sm); border-radius: 0 0 var(--radius) 0;
}
.skip-link:focus { left: 0; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; border-radius: 4px; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Eyebrow ------------------------------------------------------ */
.eyebrow {
  font-size: var(--fs-label); font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--accent-deep); margin: 0 0 var(--space-sm);
}

/* Buttons ------------------------------------------------------ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  font-family: var(--sans); font-size: 1.05rem; font-weight: 600;
  letter-spacing: 0.04em; text-transform: uppercase;
  padding: 1.15rem 2rem; border-radius: var(--radius); border: 1px solid transparent;
  text-decoration: none; cursor: pointer;
  transition: transform .25s var(--ease), box-shadow .25s var(--ease), background-color .25s var(--ease);
  min-height: 56px;              /* comfortable thumb target */
}
.btn--primary {
  background: var(--accent); color: #fff;
  box-shadow: 0 12px 26px -12px rgba(74, 124, 130, 0.65);
}
.btn--primary:hover {
  background: var(--accent-deep); transform: translateY(-2px);
  box-shadow: 0 18px 34px -14px rgba(74, 124, 130, 0.7);
}
.btn--primary:active { transform: translateY(0); }
.btn--block { width: 100%; }
.btn--lg { font-size: 1.15rem; padding: 1.35rem clamp(1rem, 4vw, 2.25rem); min-height: 64px; max-width: 100%; }

/* Site header — deliberately minimal on a funnel page --------- */
/* Compact on purpose: on a squeeze page the fold belongs to the headline
   and the form, not the logo.
   The logo is sized by HEIGHT, not width. The lockup is almost square, so
   sizing by width made the header 140px tall against a --gate-header of 64,
   and the "one screen" hero overflowed by 68px and grew a scrollbar. Height
   is the dimension the layout actually cares about, so height is what we set. */
.funnel-header {
  background: var(--deep); position: relative; z-index: 3;
  height: var(--gate-header);
  display: flex; align-items: center;
}
.funnel-header__inner { display: flex; align-items: center; justify-content: center; width: 100%; }
.funnel-header__logo { height: 52px; width: auto; }
@media (min-width: 768px) { .funnel-header__logo { height: 58px; } }

/* Hero --------------------------------------------------------- */
.hero {
  position: relative; overflow: hidden;
  background: var(--deep);
  color: var(--on-deep);
  /* padding-block:0 is deliberate. .hero__inner owns the spacing; two
     nested paddings doing the same job push the form past the fold and
     make the negative space read as accidental rather than composed. */
  min-height: calc(100svh - var(--gate-header));
  padding-block: 0;
  display: flex; align-items: center;
}
/* Optically centred, not mathematically: a touch more air below the stack
   than above, so the block sits on the screen instead of sinking. */
.hero__inner { padding-top: calc(var(--gate-rhythm) * 1.1); padding-bottom: calc(var(--gate-rhythm) * 1.7); }
@media (max-height: 700px) { .hero { min-height: 0; padding-block: var(--space-xl); } }
/* A vignette does most of the cinematic work: it pulls the eye to centre
   and stops the frame ending in a hard rectangle. */
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: radial-gradient(120% 90% at 65% 40%, transparent 35%, rgba(10,12,13,0.55) 100%);
}
.hero__bg {
  position: absolute; inset: 0; z-index: 0;
  background-size: cover; background-position: 26% 32%;
  background-image: url('../assets/hero@900.webp');
  opacity: var(--hero-photo-opacity);
  filter: var(--hero-photo-filter);
  transform: scale(1.03);           /* hides any edge softness from the scrim */
}
.hero__veil { position: absolute; inset: 0; z-index: 1; background: var(--hero-veil); }
@media (min-width: 900px) { .hero__bg { background-image: url('../assets/hero.webp'); } }
/* The 105deg scrim behaves as a diagonal in a tall frame, so on a phone it
   runs top-to-bottom instead: light where the type sits, deep by the card. */
@media (max-width: 899px) {
  .hero__veil { background: linear-gradient(to bottom,
      rgba(18,23,26,0.93) 0%, rgba(18,23,26,0.80) 42%, rgba(18,23,26,0.90) 100%); }
}
.hero__inner { position: relative; z-index: 2; }

/* Type on the dark plate ---------------------------------------
   21ch keeps the headline column WIDER than the sub beneath it. Narrower
   and the headline wraps to more, shorter lines and ends up narrower than
   its own subhead, which inverts the hierarchy. */
.hero h1 {
  color: var(--on-deep); text-wrap: balance; max-width: 21ch;
  line-height: 1.06; letter-spacing: -0.018em;
  margin-bottom: var(--gate-rhythm);
}
/* One line of the headline carries the accent, in italic. The whole
   editorial voice of the house sits in this one move. */
.hero h1 em { font-style: italic; color: var(--accent-bright); }

/* The rule-mark before the eyebrow. Small, and it does a lot. */
.hero .eyebrow { color: var(--accent-bright); display: flex; align-items: center; gap: .75rem; }
.hero .eyebrow::before {
  content: ""; width: 28px; height: 1px; background: var(--accent-bright);
  opacity: .8; flex: none;
}
.hero__sub { color: var(--on-deep-dim); max-width: 44ch; }
.hero__sub strong { color: var(--on-deep); font-weight: 600; }

/* Mobile order: headline, subhead, FORM, then the reason-why.
   The form is the job of this page; it does not wait behind a quote. */
.hero__grid > * { min-width: 0; }
.hero__grid {
  display: grid; gap: var(--gate-rhythm); align-items: start;
  grid-template-areas: "copy" "form" "chips" "reason";
  width: 100%;
}
.hero__copy   { grid-area: copy; }
.hero__grid .formcard { grid-area: form; }
.hero__grid .reason   { grid-area: reason; }

@media (min-width: 900px) {
  .hero__grid {
    grid-template-columns: 1.05fr 0.95fr;
    grid-template-areas: "copy form" "chips form" "reason form";
    gap: var(--gate-rhythm) clamp(2.5rem, 1rem + 5vw, 5rem);
    align-content: center;
  }
  .hero__grid .reason { align-self: start; }
}
.hero__sub { font-size: var(--fs-lead); margin-top: 0; line-height: 1.55; }

/* The neighbour's reason-why — a quiet aside, not a shout */
/* The neighbour's line, set as the italic serif aside the market report
   uses under its display headline. Quiet, and it carries the whole angle. */
.reason {
  margin: var(--gate-rhythm) 0 0; padding: 0;
  border: 0;
  font-family: var(--serif); font-style: italic;
  color: var(--on-deep-dim);
  font-size: clamp(1.02rem, 0.96rem + 0.3vw, 1.18rem);
  line-height: 1.5; max-width: 40ch;
}
.reason::before { content: "\201C"; }
.reason::after  { content: "\201D"; }

@media (max-width: 899px) {
  /* Every rem saved here is another field visible before the first scroll. */
  :root { --fs-h1: clamp(2rem, 1.15rem + 3.6vw, 2.6rem); --gate-header: 56px; }
  .hero__sub { margin-top: var(--space-sm); font-size: 1rem; line-height: 1.45; }
  .hero__sub + .hero__sub { margin-top: var(--space-2xs); }
  .eyebrow { margin-bottom: var(--space-2xs); letter-spacing: 0.1em; }
  /* NO padding-block here. .hero__inner owns the spacing; adding it back
     re-creates the nested-padding bug the comment on .hero forbids, and it
     cost ~121px of mobile fold. */
}

/* Form card ---------------------------------------------------- */
/* A light island on a dark plate: reset the inherited colours explicitly,
   or the heading inherits the hero's white and vanishes. */
.formcard { color: var(--ink); }
.formcard h2, .formcard h3 { color: var(--ink); }
.formcard .field label { color: var(--ink-dim); }
.formcard .microcopy { color: var(--ink-dim); }
/* --ink-faint measures 3.99:1 on white at this size: below the 4.5:1 bar.
   The accessibility audit caught it live on this page. --ink-dim is the
   smallest token that passes. Do not use --ink-faint for text anywhere. */
.formcard .consent { color: var(--ink-dim); }
.formcard .consent a { color: var(--accent-deep); }
.formcard .proofline { color: var(--ink-dim); border-top-color: var(--hairline-2); }

.formcard {
  background: var(--surface); border: 1px solid rgba(22,23,24,0.10);
  border-radius: var(--radius-lg); padding: clamp(1.35rem, 0.9rem + 1.6vw, 2rem);
  /* A turquoise-tinted halo separates the card from the plate. The previous
     values rendered nothing: white border on a white card, black shadow on a
     near-black ground. 120px of blur for no result. */
  box-shadow: 0 30px 70px -28px rgba(127,165,170,0.28), 0 0 0 1px rgba(127,165,170,0.14);
}
.field { margin-bottom: .7rem; }
.field input { padding: .85rem 1rem; min-height: 52px; }
.formcard__head { margin-bottom: var(--space-sm); }

.field label {
  display: block; font-size: var(--fs-sm); font-weight: 600;
  color: var(--ink-dim); margin-bottom: var(--space-3xs);
}
.field input {
  width: 100%; font-family: var(--sans); font-size: 1.0625rem;
  padding: 1rem; min-height: 56px;
  border: 1px solid rgba(22,23,24,0.32); border-radius: var(--radius);
  background: var(--surface); color: var(--ink);
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.field input::placeholder { color: rgba(22,23,24,0.50); }
.field input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-glow); }
.field input:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }

.microcopy { font-size: var(--fs-sm); color: var(--ink-dim); text-align: center; margin: .7rem 0 0; }
.consent { font-size: 0.74rem; line-height: 1.5; color: var(--ink-dim); margin: .7rem 0 0; }
.consent a { color: var(--ink-dim); text-decoration: underline; display: inline-block; padding-block: .4rem; }

/* One-line proof ---------------------------------------------- */
/* Credential chips, on the dark plate. Lifted from the market report's
   chip row: small, bordered, uppercase, doing quiet work. */
.proofline {
  grid-area: chips; margin: 0;
  display: flex; flex-wrap: wrap; gap: .4rem;
}
.proofline span {
  white-space: nowrap; font-size: .66rem; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--on-deep-faint);
  border: 1px solid var(--deep-hairline); border-radius: 100px;
  padding: .36rem .75rem;
}

/* The copy permits a second CTA "only if the page needs it on mobile after
   the objection section". On desktop the form is one short scroll away and a
   second button is noise, so it is mobile-only. Rule 9, applied. */
@media (min-width: 900px) { #second-cta { display: none; } }

/* Objections --------------------------------------------------- */
.objections { display: grid; gap: var(--space-lg); }
@media (min-width: 820px) { .objections { grid-template-columns: repeat(3, 1fr); gap: var(--space-xl); } }
.objection h3 { margin-bottom: var(--space-2xs); }
.objection h3::before {
  content: ""; display: block; width: 28px; height: 2px;
  background: var(--accent-bright); margin-bottom: var(--space-sm);
}
.objection p { color: var(--ink-dim); margin: 0; }

/* Footer ------------------------------------------------------- */

/* Print -------------------------------------------------------- */
@media print {
  .hero__bg, .hero__veil { display: none !important; }
  .funnel-header, .btn, .formcard { break-inside: avoid; }
  body { background: #fff; color: #000; font-size: 11pt; }
  .btn { border: 1px solid #000; color: #000 !important; background: #fff !important; box-shadow: none; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; color: #555; }
  .section { padding-block: 1rem; }
}

/* ============================================================
   Motion — pure CSS, no JavaScript in the critical path.

   Deliberately NOT the AnchorWorks .js-anim/.reveal pattern. That one
   hides content in CSS and reveals it with an IntersectionObserver, which
   is right for a long scrolling page. On a one-screen money page it means
   a slow, blocked or backgrounded script leaves a homeowner staring at an
   empty screen. Tested: the JS version left all five elements at opacity 0.

   animation-fill-mode:backwards holds the start state only during the
   delay. If the animation never runs for any reason, the element is simply
   visible. There is no failure mode where the page is blank.

   Big type travels less than small type (10px vs 16px): large objects
   moving far read as cheap; small objects moving far read as precise.
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  .rise { animation: riseIn .8s var(--ease) backwards; }
  .rise--lg { animation-name: riseInLg; }
  .rise[data-delay="1"] { animation-delay: .08s; }
  .rise[data-delay="2"] { animation-delay: .20s; }
  .rise[data-delay="3"] { animation-delay: .34s; }
  .rise[data-delay="4"] { animation-delay: .46s; }

  /* The photograph breathes. 26s, 1.03 -> 1.075: below the threshold where
     anyone consciously notices, above the one where the frame feels dead.
     Cinematic comes from the slowness. */
  .hero__bg { animation: heroDrift 26s ease-in-out infinite alternate; }
}

@keyframes riseIn   { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes riseInLg { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes heroDrift { from { transform: scale(1.03); } to { transform: scale(1.075); } }

/* ============================================================
   Footer — the AnchorWorks four-column grid, at JC's scale.
   ============================================================ */
.site-footer {
  background: var(--deep); color: var(--on-deep-faint);
  padding-block: clamp(2.5rem, 1.8rem + 2.4vw, 3.75rem) 1.75rem;
  font-size: .9rem;
}
.footer__grid {
  display: grid; grid-template-columns: 1.7fr 1fr 1fr;
  gap: 2.25rem; margin-bottom: 2.25rem;
}
.footer__brand img { width: 108px; height: auto; margin-bottom: .9rem; }
.footer__brand p { color: var(--on-deep-faint); max-width: 34ch; line-height: 1.65; margin: 0; }
.footer__col h4 {
  font-family: var(--sans); font-size: .7rem; font-weight: 600;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--accent-bright); margin: 0 0 .85rem;
}
.footer__col a, .footer__col p {
  display: block; color: var(--on-deep-dim); font-size: .9rem;
  padding-block: .3rem; margin: 0; text-decoration: none;
  transition: color .3s var(--ease);
}
.footer__col a:hover { color: var(--accent-bright); }
.footer__legal {
  padding-top: 1.5rem; border-top: 1px solid var(--deep-hairline);
  display: flex; flex-wrap: wrap; gap: .6rem 1.5rem;
  align-items: center; justify-content: space-between;
  font-size: .78rem; color: var(--on-deep-faint);
}
.footer__legal p { margin: 0; }
.footer__legal a { color: var(--on-deep-faint); }
.footer__legal a:hover { color: var(--accent-bright); }
@media (max-width: 760px) {
  .footer__grid { grid-template-columns: 1fr 1fr; gap: 1.75rem; }
  .footer__brand { grid-column: 1 / -1; }
}
@media print { .site-footer { display: none !important; } }

::selection { background: var(--accent-bright); color: var(--deep); }
