/* Announcement banner, 56px, all blue, scrolls away on first scroll.
   FREE ESTIMATES left, phone centre, rating right above the mobile split;
   one centred Text Me Now! below it, the rating and Free Estimates having
   moved into the hero.
   Also carries the nav type size and the Contact button treatment.

   The blue is on .anno-inner, never on .anno. Recent iOS Safari tints the
   status bar from the background of whatever fixed element sits at top: 0,
   regardless of theme-color, and stretches that element during a rubber band
   and paints its background through the revealed strip. .anno is the fixed
   element, so a blue .anno put a blue band over the clock and battery at rest
   and a growing blue wedge on pull down. Confirmed on an iPhone in portrait
   2026-09-30 and in landscape 2026-10-01, which is why this is not scoped to
   a breakpoint: a rotated phone is wider than 740px and hit it again.

   .anno-inner is an ordinary child, not fixed, so it neither tints the bar
   nor stretches, and at width/height 100% in a border-box layout it covers
   .anno exactly. Nothing pinned at top: 0 may be blue: that means .anno, the
   body::before strip, and .site-header once .is-scrolled lifts it to top: 0.
   --pale here is what the status bar becomes, so it has to stay in step with
   the theme-color meta in index.html and 404.html. */

.anno {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 56px;
  z-index: 70;
  background: var(--pale);
  color: #FFFFFF;
  display: flex;
  align-items: center;
  transition: transform .3s ease;
}
.wrap:has(.site-header.is-scrolled) .anno { transform: translateY(-100%); }

/* iOS 26 status bar tint: the banner is not pinned on touch devices.

   Two rounds of moving the blue around inside a fixed .anno failed on an
   iPhone 16 and a 12 Pro, portrait and landscape. The sampler does not read
   the fixed element's own background-color; it reads what the fixed subtree
   paints, so a pale .anno wrapping a blue .anno-inner still tinted blue.

   ventureconcreteclt.com, which the owner reports renders an off-white status
   bar on the same phones, was measured at 390px on 2026-10-01: it has NOTHING
   fixed or sticky within 60px of the top at any scroll position, its only
   fixed element is a call button at the bottom, and it carries no theme-color
   at all. Its topmost content is a bright orange bar at position: relative,
   and the status bar still comes out off-white. So ordinary flow content is
   not sampled; with nothing pinned at the top, iOS falls back to the page
   canvas, which for us is --pale on html and body.

   Hence: take the banner out of the fixed layer on touch devices and let it
   scroll away with the page. It already left the screen on first scroll via
   the transform above, so the behaviour barely changes; it now does it by
   scrolling rather than by sliding.

   Keyed on the input type rather than a width. The artifact followed the
   phone into landscape, which is wider than 740px, and a width query would
   have missed it again. Desktop keeps the fixed banner and is untouched.

   .site-header stays fixed and is never blue: transparent at rest, pale and
   translucent once .is-scrolled sets in, so whichever of those the sampler
   reads, it is pale or see-through to the pale canvas. */
@media (hover: none) and (pointer: coarse) {
  .anno {
    position: static;
    transform: none;
  }
  .wrap:has(.site-header.is-scrolled) .anno { transform: none; }

  /* The four parallax layers come out of the fixed layer here too. Below
     740px they are already absolute, for the Safari toolbar strip described
     in the mobile build notes. Above it they are fixed and span the whole
     viewport, so on a phone in landscape they sit at the top edge carrying a
     photograph, which is a second thing the status bar can sample. Making
     them absolute on every touch device closes that and matches what
     portrait already does. The cost is the same one portrait already pays:
     no parallax on these four. */
  .cta-bg,
  .why-bg,
  .rv-bg,
  .ft-bg,
  .bg-fixed .cta-bg,
  .bg-fixed .why-bg,
  .bg-fixed .rv-bg,
  .bg-fixed .ft-bg {
    position: absolute;
    inset: 0;
    height: auto;
    min-height: 100%;
    background-attachment: scroll;
  }
}

.anno-inner {
  /* The visible bar. max-width is lifted to none from 740px up and the
     viewport is narrower than --maxw below that, so this is always the full
     width of the window and the pale .anno behind it never shows. */
  background: #0C56C4;
  width: 100%;
  height: 100%;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 var(--gutter);
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  align-items: center;
}

/* The banner runs full width rather than sitting in the site's 1360px
   container. In that container the inset was margin plus padding, and above
   1360px viewport the margin dominated: 280px each side at 1920, which no
   amount of padding could claw back. Dropping the cap makes the inset a
   single number that holds at every width.

   The cost, accepted deliberately: the banner no longer lines up with the
   logo and nav below it, which do still sit in the container. */
@media (min-width: 740px) {
  .anno-inner {
    max-width: none;
    /* 80px is the target and it lands from about 1212px up. Below that it
       scales with the viewport: at a flat 95px the three items collapse into
       one run-on line around 740 to 800px, where 190px of padding leaves the
       columns narrower than the phone number inside them. */
    /* Align the A of FREE ESTIMATES with the L logo mark over the hero.
       The logo lives in the site's 1360px container, so its x position is
       (viewport - 1360) / 2 + gutter. The A sits 124px into the string at
       19px with .10em tracking, so the banner inset has to be that much less.
       Falls back to the previous inset below roughly 1650px, where the logo
       is too close to the edge for the A to reach it at all. */
    padding: 0 max(
      min(80px, 6.6vw),
      calc(max(0px, (100vw - 1360px) / 2) + var(--gutter) - 124px)
    );
  }
}

/* 700 is the heaviest Figtree weight the site loads. Going past it would mean
   adding a weight to the Google Fonts request, which costs a second file.
   Sizes are fluid because at a fixed 18px the items collided between roughly
   740 and 850px. */
.anno-item {
  color: #FFFFFF;
  font-size: clamp(15px, 2.1vw, 19px);
  font-weight: 700;
  letter-spacing: .02em;
  line-height: 1.2;
  white-space: nowrap;
}
a.anno-item:hover { color: #FFFFFF; text-decoration: underline; }

.anno-left   { justify-self: start;  text-align: left; letter-spacing: .10em; }
.anno-center { justify-self: center; text-align: center; }
.anno-right  { justify-self: end;    text-align: right; }

.site-header {
  top: 56px;
  transition: top .3s ease, background .3s ease, border-color .3s ease, backdrop-filter .3s ease;
}
.site-header.is-scrolled { top: 0; }

/* Both are mobile only: above the split the three original columns stand as
   they always did. */
.anno-textme { display: none; }

/* Two columns on mobile: the Google rating left, Call and Text right.
   FREE ESTIMATES and the centre phone line both drop, the rating taking the
   left slot and the two buttons the right.

   The banner grows from 56px to 64px here to seat two 44px targets with room
   around them. .site-header's top offset follows it, or the header would
   overlap the buttons. */
@media (max-width: 739.98px) {
  /* One item, so the three column grid collapses to a single centred cell and
     the bar goes back to its 56px desktop height. .site-header's offset does
     not need a mobile value any more. */
  .anno-inner { grid-template-columns: 1fr; }
  .anno-left,
  .anno-center,
  .anno-right { display: none; }

  /* Still 44px tall. It is the only thing to tap in the bar, and the bar is
     56px, so the target fills it top to bottom with room to spare. */
  .anno-textme {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    justify-self: center;
    min-height: 44px;
    padding: 0 16px;
    font-size: clamp(15px, 4.4vw, 19px);
    letter-spacing: .03em;
    text-align: center;
  }
  a.anno-textme:hover,
  a.anno-textme:active { color: #FFFFFF; text-decoration: underline; }
}

/* Nav bar type up from the fluid clamp(15px, 11.78px + 0.43vw, 17px) to a
   flat 18px. Both selectors, so the Contact button stays the same size as the
   four links beside it. Only .nav-desktop uses these classes and it is hidden
   below 740px, so the mobile menu is untouched.

   Kept here rather than edited into styles.css, so the variant still shows
   exactly what would have to change in the repo. */
.nav-link,
.nav-cta { font-size: 18px; }

/* Contact button filled blue, inverting to white on hover.

   The border stays accent blue in both states on purpose. The scrolled header
   is rgba(250, 249, 247, .86), so a white fill with a white border would have
   nothing to sit against and the button would dissolve into the bar. Blue on
   blue is invisible in the resting state anyway, so keeping it costs nothing
   there and saves the hover.

   Both states are written twice, once plain and once under .is-scrolled,
   because styles.css sets the scrolled colour separately and that selector
   outranks a bare .nav-cta. */
.nav-cta,
.is-scrolled .nav-cta {
  background: var(--accent);
  border-color: var(--accent);
  color: #FFFFFF;
}
.nav-cta:hover,
.is-scrolled .nav-cta:hover {
  background: #FFFFFF;
  color: var(--accent);
}

/* Keep the original desktop banner spans and spacing. */
.anno-m { display: none; }

@media (max-width: 349.98px) {
  .anno { display: none; }
}

@media (max-width: 939.98px) {
  .anno-center { display: none; }
}

/* With the centre phone line hidden, keep the rating anchored in the third
   column instead of letting grid auto-placement pull it into the middle. */
@media (min-width: 740px) and (max-width: 939.98px) {
  .anno-right { grid-column: 3; }
}
