/* ==========================================================================
   Green Coat Custom Painting - mobile overrides
   Loaded AFTER site.css on every page, so everything here wins on equal
   specificity. Scope: phones first (360-430px), tablets second (768px).
   Nothing here should change the desktop layout above 1100px.
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. Universal hygiene (all widths, cheap and safe)
   -------------------------------------------------------------------------- */

html {
  /* iOS rotates portrait to landscape and inflates text without this. */
  -webkit-text-size-adjust: 100%;
}

/* Long headings, captions and link text must never push the page wider than
   the viewport. Applied to text nodes only, never to layout containers. */
h1, h2, h3, h4, p, li, a, blockquote, figcaption, summary, dd, dt {
  overflow-wrap: break-word;
}

/* Visible keyboard focus. site.css never defines one. */
a:focus-visible,
button:focus-visible,
summary:focus-visible {
  outline: 3px solid var(--leaf);
  outline-offset: 2px;
  border-radius: 8px;
}

/* Honour reduced motion for anchor jumps too (site.css sets smooth globally). */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* Any future form control: 16px minimum stops iOS Safari zooming on focus. */
input, select, textarea, button {
  font-family: inherit;
  font-size: 16px;
}


/* --------------------------------------------------------------------------
   2. Drawer breakpoint (matches site.css 1099px hamburger switch)
   -------------------------------------------------------------------------- */

@media (max-width: 1099px) {

  /* Universal horizontal-overflow guard. `clip` (not `hidden`) does NOT
     create a scroll container, so the sticky header and fixed callbar keep
     working. This protects against any full-bleed / 100vw section added
     later without having to know its class name. */
  html, body { overflow-x: clip; }

  /* Grey out the tap flash on iOS; we provide our own :active feedback. */
  a, button, summary, .nav-toggle, .car-btn {
    -webkit-tap-highlight-color: rgba(23, 90, 51, 0.12);
  }

  /* Header packing: 32px gap is wasted space once the nav is gone. */
  .site-head .wrap-wide { gap: 12px; }
  .head-cta { gap: 10px; }

  /* Nav drawer: contain its own scrolling, never scroll the page behind it,
     and never scroll sideways when a menu label runs long. */
  .nav.open {
    overflow-x: hidden;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }

  /* Drawer rows: every top-level link is a comfortable 48px+ target. */
  .nav.open > li > a {
    min-height: 48px;
    align-items: center;
  }

  /* Submenu rows need breathing room so neighbours are not mis-tapped. */
  .nav.open .mega-grid { gap: 6px; }
  .nav.open .mega-item {
    min-height: 56px;
    align-items: center;
    padding: 11px 10px;
  }
  .nav.open .mega-item span span { line-height: 1.35; }

  /* Tables (none today, but any added later) scroll inside themselves. */
  main table {
    display: block;
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  main pre, main code { overflow-x: auto; }
}


/* --------------------------------------------------------------------------
   3. Phone and small tablet (<= 767px)
   -------------------------------------------------------------------------- */

@media (max-width: 767px) {

  /* Lighter shadows: large blur radii are the most expensive paint work on
     mobile GPUs and read as muddy at this size anyway. */
  :root {
    --shadow: 0 8px 20px rgba(8, 25, 17, 0.10);
    --shadow-lg: 0 12px 28px rgba(8, 25, 17, 0.16);
  }
  .btn-solid { box-shadow: 0 4px 14px rgba(23, 90, 51, 0.22); }

  /* Gutters: 28px each side leaves only 304px of content at 360px wide. */
  .wrap, .wrap-wide { padding: 0 18px; }

  /* --- Topbar: one line, hours only ------------------------------------ */
  /* site.css already hides items 2 and 3 plus the social icon. The "Free
     Estimate" link is a duplicate of the fixed callbar, so it goes too and
     the single remaining line gets centred. */
  .topbar { font-size: 12.5px; }
  .topbar-right { display: none; }
  .topbar .wrap-wide {
    justify-content: center;
    min-height: 34px;
    gap: 0;
  }
  .topbar-left span:first-child { white-space: nowrap; }

  /* --- Header ---------------------------------------------------------- */
  /* PASS 2: site.css now ships a 64px logo (54px under 767px). The pass-1
     value of 42px silently undid that, because this file always wins on
     equal specificity. Brand + toggle only need ~215px of the 328px that a
     360px screen offers, so the bigger mark fits; the bar grows to match. */
  .site-head .wrap-wide { height: 70px; }
  .site-head.scrolled .wrap-wide { height: 64px; }
  .brand { gap: 10px; min-width: 0; }
  .brand-logo { width: 50px; height: 50px; }
  .brand-text b { font-size: 18px; }

  /* --- Hero ------------------------------------------------------------ */
  /* BUG FIX: .hero is display:flex (row) and site.css turns .hero-strip
     into position:static at this width, which makes the strip a SECOND flex
     item sitting beside the headline. Stack them instead. */
  .hero {
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
  }
  /* The 120px bottom pad existed to clear the absolutely-placed strip. */
  .hero-inner { padding: 44px 0 32px; max-width: none; }

  .hero-eyebrow {
    font-size: 10.5px;
    letter-spacing: 0.08em;
    padding: 7px 13px;
    margin-bottom: 18px;
    line-height: 1.3;
  }

  /* The typewriter cycles through "your curb appeal" (the longest phrase).
     At the site.css floor of 2.6rem that phrase does not fit 360px and the
     headline reflows on every word swap. This size keeps all five phrases
     on a single line, so the block never jumps. */
  .hero h1 {
    font-size: clamp(1.95rem, 8.4vw, 2.6rem);
    margin-bottom: 16px;
  }
  .type-caret { width: 2px; }

  .hero-sub { font-size: 16.5px; margin-bottom: 24px; max-width: none; }

  /* Hero strip sits below the copy now: two columns, tighter type. */
  .hero-strip .wrap-wide { padding-top: 14px; padding-bottom: 14px; gap: 14px; }
  .hero-strip b { font-size: 14px; line-height: 1.25; }
  .hero-strip span { font-size: 12px; line-height: 1.35; color: rgba(253, 253, 252, 0.78); }

  /* Slider dots were a 4px-tall tap target. Padding plus content-box
     background clipping keeps the 4px bar visible inside a 44px hit area. */
  .hero-dots { gap: 6px; margin-top: 10px; }
  .hero-dots button {
    height: 44px;
    padding: 20px 0;
    background-clip: content-box;
  }

  /* --- Section rhythm --------------------------------------------------- */
  .section { padding: 56px 0; }
  .section-tight { padding: 42px 0; }
  .section-head { margin-bottom: 32px; max-width: none; }
  .section-head h2 { font-size: clamp(1.55rem, 6.4vw, 2rem); }
  .section-head p { font-size: 16px; }
  .eyebrow { font-size: 11.5px; letter-spacing: 0.12em; margin-bottom: 10px; }

  /* --- Buttons ---------------------------------------------------------- */
  .btn { padding: 14px 22px; font-size: 15.5px; min-height: 48px; }
  .btn-lg { padding: 15px 24px; font-size: 16px; }

  /* Stack CTA pairs full width: side by side they wrap into ragged rows. */
  .hero-ctas { flex-direction: column; align-items: stretch; gap: 10px; }
  .hero-ctas .btn { width: 100%; justify-content: center; }

  /* --- Cards ------------------------------------------------------------ */
  .svc-grid { gap: 16px; }
  .svc-card { min-height: 220px; }
  .svc-body { padding: 20px 20px 22px; }
  .svc-body h3 { font-size: 20px; }
  .svc-body p { font-size: 14.5px; margin-bottom: 10px; }

  .svc-row { gap: 16px; margin-top: 16px; }
  .svc-mini { min-height: 158px; }
  .svc-mini .sm-body { padding: 16px; }
  .svc-mini h3 { font-size: 17px; }

  .card-grid, .card-grid.two { gap: 18px; }
  /* 210px on a full-width card is a tall, letterbox-heavy crop on a phone. */
  .link-card img { height: clamp(168px, 48vw, 210px); }
  .link-card .lc-body { padding: 18px 18px 22px; }
  .link-card h3 { font-size: 18px; }

  /* --- Band / steps / stats --------------------------------------------- */
  .band-grid, .split-2, .page-hero-grid { gap: 28px; }
  .band img { height: clamp(200px, 58vw, 280px); }
  .band-points { gap: 12px; margin-top: 20px; }
  .band-points li { font-size: 15.5px; gap: 11px; }

  .steps { gap: 14px; }
  .step { padding: 20px; }
  .step .num { font-size: 34px; margin-bottom: 10px; }
  .step h3 { font-size: 17.5px; }
  .step p { font-size: 14.5px; }

  .stats-band .wrap { padding-top: 48px; padding-bottom: 48px; gap: 22px; }
  .stat-big b { font-size: 42px; }
  .stat-big { padding-left: 16px; }
  .stat b { font-size: 32px; }

  /* --- Media rows -------------------------------------------------------- */
  .marquee { padding: 14px 0; }
  .marquee-track { gap: 30px; }
  .marquee-track span { font-size: 14.5px; gap: 30px; }

  .strip { gap: 14px; }
  .strip figure { flex: 0 0 82vw; }
  .strip img { height: clamp(200px, 60vw, 280px); }

  .masonry { gap: 14px; }
  .masonry img { height: clamp(210px, 62vw, 300px); }
  .masonry figcaption { padding: 34px 16px 13px; font-size: 13px; }

  /* NOTE: .car-track gap is hard-coded to 20px in site.js (go() computes
     translateX from itemWidth + 20), so it must stay 20px here. */
  .car-item img { height: clamp(200px, 58vw, 260px); }
  .car-item figcaption { padding: 38px 15px 13px; font-size: 13px; }
  .car-nav { margin-top: 16px; }
  .car-progress { max-width: 140px; }

  /* --- Quotes / testimonials -------------------------------------------- */
  .quotes { gap: 16px; }
  .quote-featured { padding: 26px 22px; }
  .quote-featured::before { font-size: 140px; top: -18px; right: 4px; }
  .quote-featured blockquote { font-size: 18px; margin-bottom: 20px; }
  .quote-card { padding: 22px; }

  /* 10px dots became a 10px tap target. Same content-box trick as the hero
     dots; the visible circle is unchanged, the hit area is 44x44. */
  .t-nav { gap: 0; margin-top: 14px; }
  .t-nav button {
    width: 44px;
    height: 44px;
    padding: 17px;
    background-clip: content-box;
  }

  .car-btn { width: 48px; height: 48px; }

  /* --- FAQ --------------------------------------------------------------- */
  .faq details { padding: 0 16px; margin-bottom: 10px; }
  .faq summary { font-size: 16px; padding: 15px 0; min-height: 48px; gap: 12px; }
  .faq details p { margin-bottom: 16px; font-size: 15.5px; }

  /* --- Prose / inner hero ------------------------------------------------ */
  .prose { max-width: none; }
  .prose h2 { font-size: 22px; margin-top: 32px; }
  .prose ul { padding-left: 20px; }

  .page-hero .wrap { padding-top: 52px; padding-bottom: 52px; }
  .page-hero h1 { font-size: clamp(1.7rem, 7.4vw, 2.2rem); max-width: none; }
  .page-hero .lede { font-size: 16.5px; max-width: none; margin-bottom: 22px; }
  .crumbs { font-size: 13px; margin-bottom: 14px; }
  .crumbs a { display: inline-block; padding: 5px 0; }

  /* --- Pre-footer CTA ----------------------------------------------------- */
  .cta-panel { padding: 30px 22px; border-radius: 20px; gap: 22px; }
  .cta-panel h2 { font-size: clamp(1.4rem, 5.8vw, 1.8rem); }
  .cta-panel p { font-size: 15.5px; max-width: none; }
  .cta-panel .actions { flex-direction: column; align-items: stretch; width: 100%; gap: 10px; }
  .cta-panel .actions .btn { width: 100%; justify-content: center; }

  /* --- Footer ------------------------------------------------------------- */
  /* Footer is always below the fold: let the browser skip its layout and
     paint until it is scrolled near. Intrinsic size keeps the scrollbar
     stable. */
  /* PASS 2: measured the stacked footer at ~1380px on a 360px screen, so the
     900px placeholder was making the scrollbar jump on first reveal. */
  .site-foot {
    content-visibility: auto;
    contain-intrinsic-size: 1px 1400px; /* fallback for older engines */
    contain-intrinsic-size: auto 1400px;
  }
  .foot-grid { gap: 28px; padding: 44px 0 30px; }
  .site-foot h4 { margin-bottom: 10px; }
  .foot-about { max-width: none; margin-bottom: 16px; }

  /* Link rows were ~25px tall with an 11px gap. Turn each into a block with
     vertical padding so rows are 46px and cannot be mis-tapped. */
  .foot-links { gap: 0; }
  .foot-links a { display: block; padding: 11px 0; }

  .foot-contact { gap: 6px; }
  .foot-contact li { align-items: flex-start; }
  .foot-contact svg { margin-top: 12px; }
  .foot-contact span { padding: 8px 0; }
  .foot-phone-big { display: inline-block; padding: 8px 0; font-size: 21px; }

  .foot-social a { width: 44px; height: 44px; }
  .foot-base { padding: 8px 0 14px; }
  .foot-base .wrap-wide { gap: 0; }
  .foot-base a { display: inline-block; padding: 10px 0; }

  /* --- Fixed call bar ------------------------------------------------------ */
  /* site.css already pads the bottom for the home indicator; add the side
     insets for landscape notches and make the buttons a solid 50px. */
  .callbar {
    padding-left: max(14px, env(safe-area-inset-left));
    padding-right: max(14px, env(safe-area-inset-right));
  }
  .callbar .btn { min-height: 50px; padding: 13px 8px; font-size: 15px; }

  /* site.css reserves a flat 74px, which the home indicator then eats into. */
  body { padding-bottom: calc(76px + env(safe-area-inset-bottom)); }
}


/* --------------------------------------------------------------------------
   4. Narrow phones (<= 480px) - the 360 to 430px target band
   -------------------------------------------------------------------------- */

@media (max-width: 480px) {

  .wrap, .wrap-wide { padding: 0 16px; }

  .section { padding: 46px 0; }
  .section-tight { padding: 36px 0; }
  .section-head { margin-bottom: 26px; }

  /* Drawer: keep a visible strip of scrim so the close gesture is discoverable. */
  .nav.open { width: min(330px, 90vw); padding: 76px 18px 32px; }

  .hero-inner { padding: 36px 0 28px; }
  .hero h1 { font-size: clamp(1.85rem, 8.6vw, 2.3rem); }
  .hero-strip .wrap-wide { gap: 12px; }

  .svc-body { padding: 18px; }
  .svc-body h3 { font-size: 18.5px; }
  .link-card .lc-body { padding: 16px 16px 20px; }

  .quote-featured { padding: 22px 18px; }
  .cta-panel { padding: 26px 18px; }
  .step { padding: 18px; }
  .foot-grid { padding: 36px 0 26px; }

  .page-hero .wrap { padding-top: 42px; padding-bottom: 42px; }
}


/* --------------------------------------------------------------------------
   5. Very narrow (<= 360px) - iPhone SE and similar
   -------------------------------------------------------------------------- */

@media (max-width: 360px) {

  .wrap, .wrap-wide { padding: 0 14px; }
  .topbar { font-size: 11.5px; }
  .brand-logo { width: 46px; height: 46px; }
  .brand-text b { font-size: 17px; }
  .site-head .wrap-wide { height: 66px; }

  .hero h1 { font-size: 1.72rem; }
  .hero-eyebrow { font-size: 10px; letter-spacing: 0.06em; padding: 6px 11px; }

  /* PASS 2: stacking these four into one column pushed the strip to ~190px
     and left it looking sparse. Keep the 2x2 block and shrink the type
     instead; a two-line label is fine here. */
  .hero-strip .wrap-wide { gap: 10px 12px; }
  .hero-strip b { font-size: 13px; }
  .hero-strip span { font-size: 11.5px; }

  .btn-lg, .btn { padding: 13px 16px; font-size: 15px; }
  .callbar { gap: 8px; padding-left: 10px; padding-right: 10px; }
  .callbar .btn { font-size: 14px; padding: 13px 4px; }
}


/* --------------------------------------------------------------------------
   6. Touch devices - kill sticky hover states
   -------------------------------------------------------------------------- */
/* On iOS a :hover style latches after a tap and stays until the next tap
   elsewhere, so lift/zoom effects leave cards visibly stuck. Neutralise the
   motion but keep colour changes that double as press feedback. */

@media (hover: none) {

  .svc-card:hover,
  .svc-mini:hover,
  .step:hover,
  .quote-card:hover,
  .car-btn:hover,
  .foot-social a:hover,
  .brand:hover .brand-logo,
  .brand:hover .brand-mark,
  .mega-item:hover {
    transform: none;
  }

  .link-card:hover {
    transform: none;
    box-shadow: none;
    border-color: var(--line);
  }

  .svc-card:hover img,
  .svc-mini:hover img,
  .link-card:hover img,
  .strip figure:hover img,
  .masonry figure:hover img,
  .car-item:hover img,
  .mega-item:hover .mega-thumb img {
    transform: none;
  }

  /* Padding shift on hover makes footer rows twitch under a thumb. */
  .foot-links a:hover { padding-left: 0; }

  /* The directional button fill would stay filled after a tap. Reset the
     fill AND the hover colours together, or ghost buttons go invisible. */
  .btn:hover::before { transform: scaleX(0); }
  .btn:hover .arr { transform: none; }
  .btn-ghost:hover { color: var(--ink); border-color: rgba(16, 35, 26, 0.25); }
  .btn-ghost-light:hover { color: var(--white); border-color: rgba(253, 253, 252, 0.4); }
  .btn-light:hover { color: var(--pine-deep); }
  .svc-card:hover .svc-more .arr,
  .svc-mini:hover .arr { transform: none; }

  /* Give a real pressed state back, since hover no longer signals anything. */
  .svc-card:active,
  .svc-mini:active,
  .link-card:active,
  .step:active { transform: scale(0.99); }
}


/* --------------------------------------------------------------------------
   7. Landscape phones - short viewports
   -------------------------------------------------------------------------- */

@media (max-height: 480px) and (orientation: landscape) {
  .hero-inner { padding: 28px 0 20px; }
  .hero h1 { font-size: clamp(1.6rem, 4.6vw, 2.2rem); }
  .page-hero .wrap { padding-top: 34px; padding-bottom: 34px; }
  .nav.open { padding-top: 60px; }
}


/* --------------------------------------------------------------------------
   8. Reduced motion (mobile additions only; site.css handles the rest)
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .nav.open { animation: none; }
  .car-track { transition: none; }
  .hero-bg .slide { transition: none; }
}


/* --------------------------------------------------------------------------
   9. v2.3 components: filmstrip, colour studio, process timeline
   -------------------------------------------------------------------------- */

@media (max-width: 767px) {

  /* --- Filmstrip --------------------------------------------------------- */
  /* Match the mobile gutter and keep the drag inside the strip: without
     overscroll containment an iOS swipe past the last frame triggers the
     browser back gesture. */
  .film {
    gap: 12px;
    padding-left: 18px;
    padding-right: 18px;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
  }
  /* PASS 2: site.css sizes frames by height with `img { width: auto }`, so a
     3:2 photo at the pass-1 floor of 230px came out 345px wide against the
     328px of visible strip a 360px phone has: no single landscape frame ever
     fit. The set also mixes 3:2 and 3:4 originals, so widths jumped between
     345px and 172px. Fix the frame width on phones and let the image cover
     it: every photo fits, the peek of the next one is predictable, and the
     scroll rhythm is even. */
  .film-item {
    height: clamp(216px, 60vw, 300px);
    width: min(78vw, 320px);
  }
  .film-item img { width: 100%; height: 100%; object-fit: cover; }
  /* Captions are always visible on touch (site.css handles that), so shrink
     the gradient so it does not swallow the whole frame. At 12.5px a typical
     caption is two lines and the band covers ~34% of a 216px frame. */
  .film-item figcaption { padding: 30px 13px 11px; font-size: 12.5px; line-height: 1.35; }

  /* --- Colour studio ------------------------------------------------------ */
  .studio-grid { gap: 28px; }
  .studio h2 { font-size: clamp(1.55rem, 6.4vw, 2rem); }
  .studio p { max-width: none; font-size: 15.5px; }

  /* .swatch is display:flex, so the label text node and the <small> line up
     side by side instead of stacking. Force the column direction. */
  .swatch {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-end;
    padding: 11px 12px;
    font-size: 12.5px;
    line-height: 1.25;
  }
  .swatch small { font-size: 11px; line-height: 1.3; margin-top: 2px; }
  .swatch .tag { font-size: 9.5px; padding: 3px 7px; top: 8px; right: 8px; }

  /* --- Process timeline ---------------------------------------------------- */
  .timeline { gap: 22px; }
  .tl-item h3 { font-size: 17.5px; }
  .tl-item p { font-size: 14.5px; }
}

@media (max-width: 480px) {

  .film { padding-left: 16px; padding-right: 16px; }

  /* Three square swatches across 360px leaves ~100px each, which clips the
     "Most requested" tag and crushes the two-line label. Two columns fit. */
  .swatch-grid { grid-template-columns: 1fr 1fr; gap: 12px; }

  /* Line and dot stay aligned: dot is 36px wide at left 0, centre 18px,
     which is where site.css puts the 2px rail. Just tighten the text inset. */
  .tl-item { padding-left: 52px; }
}

@media (hover: none) {
  .film-item:hover img,
  .swatch:hover,
  .tl-item:hover .dot { transform: none; }
  .swatch:hover { box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); }
  .film-btn:hover { transform: translateY(-50%); }
}

/* Fix: the .on state's background shorthand resets background-clip, which
   painted the whole 44px hit area solid. Re-clip active dots to content box. */
@media (max-width: 1099px) {
  .hero-dots button.on, .t-nav button.on { background-clip: content-box; }
}


/* ==========================================================================
   PASS 2
   Second mobile audit, run against the v2.4.x additions in site.css:
   full-bleed filmstrip, colour studio + swatch grid, process timeline,
   .tq-grid testimonial slides, the texture/watermark layers, the slanted
   clip-path transitions, the brush underline on section headings, and the
   larger brand logo. Read together with the in-place PASS 2 notes above.
   Scope is unchanged: nothing here touches layout above 1099px.
   ========================================================================== */


/* --------------------------------------------------------------------------
   P2.1  Slanted section transitions (.studio, .band:not(.light))
   -------------------------------------------------------------------------- */

@media (max-width: 767px) {

  /* site.css cuts both slants at 2.6vw. That is 20px at 767px but only 9px
     at 360px, where a 9px drop across the full width reads as a misaligned
     edge or a rendering seam rather than a deliberate diagonal. Lock it to a
     fixed 16px so the transition looks identical across the phone range. */
  .studio { clip-path: polygon(0 16px, 100% 0, 100% 100%, 0 100%); }
  .band:not(.light) { clip-path: polygon(0 0, 100% 16px, 100% 100%, 0 100%); }

  /* BUG FIX (spacing): `.band:not(.light)` scores 0-2-0, so site.css's
     `padding-top: calc(100px + 2.6vw)` outranked the `.section` padding in
     this file and dark bands shipped with ~109px of top padding against
     46px at the bottom. `.studio` (0-1-0) lost its extra padding entirely.
     Set both explicitly so the slant clears the content either way.
     Neither slant can crop text: 16px is well inside the 46-60px pad. */
  .studio,
  .band:not(.light) { padding-top: 60px; padding-bottom: 56px; }
}

@media (max-width: 480px) {
  .studio,
  .band:not(.light) { padding-top: 50px; padding-bottom: 46px; }
}


/* --------------------------------------------------------------------------
   P2.2  Texture layers
   Rule applied: full-section bitmap layers are off on phones; pure-CSS
   gradient washes and small accents stay; the footer keeps its one layer.
   Each of these costs an image decode plus a blended composite over the whole
   section, and at 360px you only ever see a fraction of the tile, so they
   read as blotches instead of texture.
   -------------------------------------------------------------------------- */

@media (max-width: 767px) {

  .section-alt::before,   /* topo.jpg, multiply, present on 22 of 23 pages */
  .alt-dots::before,      /* same pseudo element as above, listed for clarity */
  .studio::after,         /* hatch at opacity 0.06 behind an invert() pass:
                             invisible on a phone, not free to paint */
  .band.light::before {   /* house.jpg is 655x760 portrait; `contain` inside a
                             ~1000px tall stacked band renders it ~360x418 and
                             anchors it bottom right, which on mobile is
                             entirely behind the opaque band photo. It costs
                             29KB and a full-width multiply to show nothing,
                             and the only part that does escape sits behind the
                             CTA button. */
    display: none;
  }

  /* Kept: the services wash is gradient-only. But the roller bands were 110px
     wide on a 235px cycle, which is one and a half passes on a 360px screen
     and reads as banding. Tighten the cycle so it reads as rhythm. */
  .svc-section::before {
    background:
      repeating-linear-gradient(90deg, rgba(23, 90, 51, 0.05) 0 58px, transparent 58px 126px),
      radial-gradient(420px 320px at 88% 4%, rgba(55, 168, 102, 0.10), transparent 70%);
  }

  /* Kept: the footer contour layer. It is one layer, always below the fold,
     and gated by the content-visibility:auto set in section 3 above.
     Checked for a clash and there is none: generated content is skipped with
     the rest of the skipped subtree, and the paint containment that
     content-visibility applies gives the mix-blend-mode:screen layer a clean
     isolation boundary instead of letting it blend against the page root.
     Only the tile size needs to come down so contours read at phone width. */
  .site-foot::before { background-size: 620px auto; }
}

@media (max-width: 480px) {
  /* The dot grid sits at right 4% / top 30px, which on the home "How a
     project runs" section lands directly behind the centred heading. It is
     the one small accent that collides with text, so it goes at this width. */
  .deco-dots::after { display: none; }
}


/* --------------------------------------------------------------------------
   P2.3  Testimonial slides (.tq-grid)
   -------------------------------------------------------------------------- */

@media (max-width: 767px) {

  /* Verified: no min-height leftovers. site.css resets both `.tq-img` and
     `.tq-grid .quote-featured` to 0 at this width, and `order: -1` puts the
     photo first, so there is no dead space to reclaim. Padding also shrinks
     correctly: site.css only sets min-height and blockquote size at 0-3-0,
     so the 26px/22px and 22px/18px paddings from sections 3 and 4 apply. */
  .tq-grid { gap: 14px; }
  .tq-img { height: clamp(180px, 52vw, 230px); }

  /* `.quote-featured` is a space-between column, so the blockquote's own
     bottom margin stacks with `.quote-person`'s top margin: 20 + 8 left a
     28px hole between the quote and the attribution row. */
  /* Note the selector depth: section 3's `.quote-featured blockquote` is
     0-2-0, so a plain `.tq-grid blockquote` (0-1-1) would lose to it. */
  .tq-grid .quote-featured blockquote { margin-bottom: 10px; }
  .quote-person { gap: 12px; }
}

@media (max-width: 480px) {
  /* 48px avatar + 14px gap ate 62px of a 288px content row, which pushed
     "Business owner, commercial painting" onto a second line. */
  .quote-avatar { width: 42px; height: 42px; font-size: 15px; }
}


/* --------------------------------------------------------------------------
   P2.4  Filmstrip gutter rhythm
   (frame sizing and captions are handled in place in section 9 above)
   -------------------------------------------------------------------------- */

@media (max-width: 360px) {
  /* Section 9 pins the strip to 16px, but `.wrap` drops to 14px at this
     width, so the section heading and the first frame started on different
     lines. Match the page gutter. */
  .film { padding-left: 14px; padding-right: 14px; }
}


/* --------------------------------------------------------------------------
   P2.5  Colour studio swatches
   -------------------------------------------------------------------------- */

@media (max-width: 480px) {

  /* Re-checked against the new `flex-direction: column` swatch in site.css
     (v2.4.3 now sets that itself, so the copy in section 9 is redundant but
     harmless). Two columns is still right: three squares across 360px leave
     ~100px each, which clips the "Most requested" tag. */
  .swatch-grid { grid-template-columns: 1fr 1fr; gap: 12px; }

  /* At 2 columns the tiles are ~158px, and `aspect-ratio: 1` turns nine
     swatches into five rows of squares, ~840px of scrolling. The label plus
     its note only need ~52px of that. A slightly landscape chip reads more
     like a paint sample and takes ~130px off the page. Tag still clears:
     ~80px wide inset 8px from a 158px edge. */
  .swatch { aspect-ratio: 1.25; }
}


/* --------------------------------------------------------------------------
   P2.6  Process timeline (vertical variant, home only)
   -------------------------------------------------------------------------- */

@media (max-width: 767px) {

  /* Rail and dot alignment verified: the 36px dot at left 0 centres on 18px,
     which is exactly where the 2px rail at left:17px sits. That holds at the
     52px text inset set in section 9 too, so nothing conflicts with the
     site.css max-767 block (it only sets padding-top:0 and padding-left).

     VERTICAL alignment was off. The dot keeps its desktop top:8px while
     `padding-top` drops to 0, so the number sat level with the gap between
     the step title and its paragraph instead of next to the title. Lift it
     onto the title's first line; the horizontal centre is untouched. */
  .tl-item .dot { top: -6px; }

  /* The rail runs top:10px to bottom:10px, so it carried on past the last
     dot and dangled beside the final paragraph. Fade the tail out. */
  .timeline::before {
    background: linear-gradient(180deg, var(--leaf), var(--pine) 62%, rgba(23, 90, 51, 0));
  }
}


/* --------------------------------------------------------------------------
   P2.7  Brush underline and heading typography
   -------------------------------------------------------------------------- */

@media (max-width: 767px) {

  /* The 92x8 brush is nearly as wide as a mobile h2 is tall-stacked, and
     16px of padding plus a 0.5em margin left a loose gap before the deck
     copy (or before the content, on the heads that have no deck). */
  .section-head h2 { padding-bottom: 13px; margin-bottom: 0.34em; }
  .section-head h2::after { width: 76px; height: 7px; }
  /* Centred variant keeps working: site.css centres ::after with a transform,
     which the width change does not disturb. */

  /* 1.06 is a display line-height built for one-line desktop headings. On a
     phone the longest h1 ("Cabinet colors South Jersey homeowners are
     choosing", 51 characters) wraps to four lines and the ascenders collide
     with the descenders above. Loosen every heading that wraps. */
  .hero h1 { line-height: 1.1; }
  .page-hero h1 { line-height: 1.12; }
  .section-head h2 { line-height: 1.14; }
  .prose h2 { line-height: 1.2; }
  .cta-panel h2,
  .svc-body h3,
  .link-card h3,
  .tl-item h3,
  .step h3 { line-height: 1.25; }
  /* Summaries are body copy, not headings: 1.65 is loose for a wrapped
     question but 1.25 would be too tight. */
  .faq summary { line-height: 1.35; }
}

@media (max-width: 480px) {
  .section-head h2::after { width: 68px; }
  .page-hero h1 { font-size: clamp(1.6rem, 7vw, 2.05rem); }
  .prose h2 { font-size: 20.5px; margin-top: 28px; }
}


/* --------------------------------------------------------------------------
   P2.8  Remaining checklist items re-verified on every page
   -------------------------------------------------------------------------- */

@media (max-width: 1099px) {
  /* The drawer is fixed to bottom:0, so its last menu row can land under the
     home indicator. It also sits above the callbar (z-index 70 vs 55), so
     nothing else reserves that space. */
  .nav.open { padding-bottom: calc(28px + env(safe-area-inset-bottom)); }
}

@media (max-width: 767px) {
  /* Breadcrumbs are the last sub-44px targets on the inner pages. They are
     inline in a text run so they cannot be boxed out to 44px without
     breaking the line, but 27px is a lot safer than 23px. */
  .crumbs { font-size: 13.5px; }
  .crumbs a { padding: 7px 0; }
}
