/*
 * Site-wide CTA normalization. Audit (2026-08-17) found the same "Call Us
 * Today" text styled 3 different ways on one page, plus a different red
 * shade on home, plus home's hero pairing both buttons in the identical
 * red (competing primary CTAs, no hierarchy). Elementor writes each
 * button's color as a per-widget ID-scoped rule baked into that page's own
 * data, so normalizing needs !important to override whatever hex that
 * specific page happened to be set to.
 *
 * Only two button intents exist site-wide: a Call action (tel: link) and
 * everything else. tel: is the reliable signal -- present on every Call
 * button audited, absent from every other CTA -- so it drives the split
 * instead of relying on each page's own (inconsistent) color choice.
 */

/* Elementor's default widget wrapper (.elementor-widget) always carries its
   own margin-bottom (20px), regardless of what's inside it. Invisible when
   a section's own background matches the page background, but a real,
   visible white gap wherever a code-first shortcode section (this site's
   whole "Code-First Sections" pattern) sits directly against a
   differently-colored section above/below it -- found live rebuilding
   Lowell (2026-09-07), full-bleed red/dark bands showing a white sliver
   above and below. Every code-first section on this site is a bare
   top-level Elementor widget for exactly this reason (see CLAUDE.md,
   "Code-First Sections"), so this reset is safe and intentional site-wide,
   not scoped to one page. */
.elementor-widget-shortcode {
  margin-bottom: 0 !important;
}

/* Primary: any Call-style button, anywhere on the site. */
a.elementor-button[href^="tel:"] {
  background-color: var(--jr-color-primary) !important;
  border-color: var(--jr-color-primary) !important;
  color: var(--jr-color-text-inverse) !important;
}

/* Secondary: every other button, unconditionally (2026-08-18 -- only two
   CTA intents exist anywhere on the site now: the floating Call button
   handles every call action, so any button that isn't itself a tel: link
   is the form/quote action and gets the same secondary treatment, no
   exceptions, no pairing condition to satisfy first). */
a.elementor-button:not([href^="tel:"]) {
  background-color: rgba(255, 255, 255, 0.29) !important;
  border: 1px solid rgba(255, 255, 255, 0.6) !important;
  color: var(--jr-color-text-inverse) !important;
}

/* Light-surface exception (2026-08-19) -- the address/hours/map section
   was switched to a white background; the translucent-white secondary
   above is invisible there (white-on-white), same root cause the hero's
   .jr-btn-secondary-light was built to fix. This section is still plain
   Elementor (not migrated to code yet), so it needs its own scoped
   override rather than the shared class -- same graphite-fill + red-
   border recipe as .jr-btn-secondary-light for consistency. */
.elementor-element-8be06ae a.elementor-button:not([href^="tel:"]) {
  background-color: var(--jr-color-graphite) !important;
  border: 1px solid var(--jr-color-primary) !important;
  color: var(--jr-color-text-inverse) !important;
}

/* The white background applied to this same section (2026-08-19) only
   covered a ~1250px inner box, not the section edge to edge. Root cause:
   .elementor-element-8be06ae isn't the outer section -- it's one of five
   containers (b541e11, 8850998, 6b6a100, 8be06ae, 47f5c72) that all live
   together inside the REAL outer section (.elementor-element-64b91e8,
   background_color #27252A/graphite), boxed to 1250px by that parent's
   own boxed_width setting. Its own content_width:"full" only controls
   whether ITS children are boxed, not whether IT is boxed inside its
   parent -- that's what made "full" look like a no-op here.
   `width:100%!important` alone (tried first) only filled that same
   1250px box, since 100% of a boxed parent is still boxed.
   Widening the parent (64b91e8) or its shared inner wrapper would also
   widen the other 4 sibling containers, which weren't part of this
   request -- not safe to touch. A box-shadow spread is the standard
   "full-bleed inside a boxed layout" technique: it paints white far past
   this element's own edges without changing its actual box, so the other
   4 siblings' width and layout are untouched. clip-path keeps the spread
   from being clipped oddly by any ancestor. */
.elementor-element-8be06ae {
  position: relative;
  box-shadow: 0 0 0 100vmax var(--jr-color-surface);
  clip-path: inset(0 -100vmax);
}

/* The "Service Areas ends / Roofing - Manchester begins" triangle divider
   (Elementor shape_divider_top on this same 8be06ae node) has the same
   boxed-width problem the background above had: it's a DIRECT child of
   .elementor-element-8be06ae (position:relative, an Elementor default --
   not something added here), so its own position:absolute sizes against
   that same ~1225px boxed box, not the viewport. Unlike the flat white
   background, box-shadow can't fix this -- it's an actual SVG shape that
   has to BE wider, not just color-extended past its box. Standard
   full-bleed break-out instead: 100vw + recenter.
   2026-08-20 correction: the FIRST attempt at this put overflow-x:hidden
   (needed to trim what 100vw over-adds for Chrome's scrollbar gutter) on
   .elementor-element-64b91e8 -- broke the background fix above, since
   that also relies on painting outside 8be06ae's own box, and 64b91e8 is
   a tall flex container whose own layout got disturbed by the overflow
   change too. Scoped to `html` instead: same scrollbar-gutter trim, but
   html has no flex children or height dependencies to disturb, and it's
   already the true full-bleed reference the divider is trying to reach. */
html {
  overflow-x: hidden;
}

.elementor-element-8be06ae > .elementor-shape-top {
  left: 50% !important;
  width: 100vw !important;
  /* margin-left, not transform -- Elementor already puts its own
     rotate/flip transform on this element (that's what makes the shape
     point the direction it does); a transform here would fight that
     same property and one of the two silently loses. margin-left does
     the identical "shift back to center after left:50%" job without
     touching a property Elementor is already using. */
  margin-left: -50vw !important;
  /* Owner also flagged it rendering behind other elements -- raise it
     above the section's own content stacking. */
  z-index: 3;
}

/*
 * Canonical button system -- exactly 3 types, per the brand doc
 * (Colores_y_Tipografia_2026-09-08.html): Primary (strong CTA),
 * Secondary (secondary CTA), Tertiary (internal navigation). For any
 * section built in plain code (not Elementor) -- the .elementor-button
 * overrides above exist only because Elementor bakes per-widget inline
 * styles into each page's own data that have to be overridden with
 * !important; a hand-coded section has no such baggage, so it reaches
 * for these classes directly instead of reinventing button styling
 * locally. Every color value here is one of the 3 brand colors (or the
 * white/black text colors) -- no hardcoded hex.
 */
.jr-btn {
  display: inline-block;
  padding: 20px 40px;
  border-radius: 4px;
  font-family: var(--jr-font-action);
  font-size: 15px;
  font-weight: 700;
  line-height: 1;
  text-transform: uppercase;
  text-decoration: none;
  text-align: center;
  transition: background-color 0.2s ease, border-color 0.2s ease;
}

.jr-btn-primary {
  border: 1px solid var(--jr-color-primary);
  background: var(--jr-color-primary);
  color: var(--jr-color-text-inverse);
}

.jr-btn-primary:hover,
.jr-btn-primary:focus-visible {
  background: var(--jr-color-primary-hover);
  border-color: var(--jr-color-primary-hover);
  color: var(--jr-color-text-inverse);
}

/* Secondary has two surface-adapted looks -- same button TYPE, not two
   types: translucent white only reads against a dark/photo surface; on a
   light surface it's white-on-white and disappears. No single flat color
   solves both directions (a solid fill has the identical problem in
   reverse: graphite-on-graphite would vanish on the hero, which IS
   graphite-toned). Pick the variant that matches the surface behind the
   button, not one universal color.
   -dark: on graphite, photo overlays, anything dark-toned.
   -light: on white sections. Solid fill (not translucent) since a light
   surface needs real contrast, not transparency. */
.jr-btn-secondary-dark {
  border: 1px solid rgba(255, 255, 255, 0.6);
  background: rgba(255, 255, 255, 0.29);
  color: var(--jr-color-text-inverse);
}

.jr-btn-secondary-dark:hover,
.jr-btn-secondary-dark:focus-visible {
  background: rgba(255, 255, 255, 0.42);
  border-color: var(--jr-color-text-inverse);
  color: var(--jr-color-text-inverse);
}

.jr-btn-secondary-light {
  /* Thin brand-red border -- the graphite fill alone still read as
     low-contrast against a busy photo (as opposed to a flat white
     section, where graphite pops fine on its own). Red edge gives it a
     second, color-based signal that doesn't depend on whatever's
     directly behind the button. */
  border: 1px solid var(--jr-color-primary);
  background: var(--jr-color-graphite);
  color: var(--jr-color-text-inverse);
}

.jr-btn-secondary-light:hover,
.jr-btn-secondary-light:focus-visible {
  /* Derived darker graphite, not a second stored dark background color
     -- same reasoning as --jr-color-primary-hover in tokens-joes-roofing.css. */
  background: color-mix(in srgb, var(--jr-color-graphite) 80%, black);
  border-color: color-mix(in srgb, var(--jr-color-graphite) 80%, black);
  color: var(--jr-color-text-inverse);
}

/* Tertiary -- internal navigation (e.g. "See all reviews"). No fill, no
   border: text-only with an underline, the lightest-weight of the 3
   types, for a lower-emphasis in-page link rather than a CTA competing
   with Primary/Secondary. Same pattern already proven in
   google-reviews-band.css's .lib-reviews-band__cta (a vendored
   hhds-web-library component, left as-is); this is the canonical
   project-owned equivalent for any new section.
   Real bug found live, 2026-09-08: every one of these lives inside an
   Elementor Shortcode widget (every code-first section on this site is
   embedded that way), and Elementor's own frontend.min.css ships
   ".elementor a { text-decoration:none; box-shadow:none; }" -- a class
   + element selector (specificity 0,1,1) that beats a single-class
   ".jr-btn-tertiary" (0,1,0) regardless of load order. Result: every
   <a class="jr-btn jr-btn-tertiary"> on the page silently lost its
   underline (owner: "porque carajos se ve asi todo sin diseno").
   Selector requires both classes together (0,2,0) so it always wins --
   matches how every real usage already writes the markup (jr-btn
   jr-btn-tertiary, never tertiary alone). Same fix already proven on
   .jr-lowell-faq__toggle's button-only padding/color fight. */
.jr-btn.jr-btn-tertiary {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0;
  border: 0;
  background: none;
  font-family: var(--jr-font-action);
  font-size: 15px;
  font-weight: 700;
  color: var(--jr-color-primary);
  text-decoration: underline;
  text-underline-offset: 0.2em;
  text-transform: none;
}

.jr-btn.jr-btn-tertiary:hover,
.jr-btn.jr-btn-tertiary:focus-visible {
  color: var(--jr-color-primary-hover);
}

@media (max-width: 767px) {
  .jr-btn {
    padding: 15px 25px;
  }
}

/*
 * Floating "Call Us" button -- the site's single primary conversion path,
 * present on every page (see jr_floating_call_button() in functions.php).
 * Bottom-right, above everything (z-index higher than the sticky header's
 * 1200), pill shape so it reads as an action, not a form field.
 */
.jr-floating-call {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 9999;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.85rem 1.25rem;
  border-radius: 999px;
  background: var(--jr-color-primary);
  color: var(--jr-color-text-inverse);
  font-weight: 700;
  font-size: 0.95rem;
  text-decoration: none;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.jr-floating-call:hover,
.jr-floating-call:focus-visible {
  color: var(--jr-color-text-inverse);
  transform: translateY(-2px);
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.3);
}

.jr-floating-call__icon {
  width: 1.25rem;
  height: 1.25rem;
  flex-shrink: 0;
}

@media (max-width: 480px) {
  /* Label stays visible on phones too -- a bare icon reads as decoration,
     not a call-to-action. Just a smaller pill/gap than desktop. */
  .jr-floating-call {
    padding: 0.7rem 1rem;
    gap: 0.4rem;
    font-size: 0.85rem;
  }
  .jr-floating-call__icon {
    width: 1.1rem;
    height: 1.1rem;
  }
}

/* Mobile: this button is red, and on a phone it can end up floating
   directly over other red elements behind it (the ticker band, another
   CTA) where the plain dark drop-shadow alone doesn't read as separated
   -- a shadow only shows where the background is lighter than it, so it
   can get visually lost against a similarly dark/red backdrop (owner,
   2026-09-09: "debe tener sombra o borde... para que sobreponga sobre
   cualquier otro elemento de color rojo"). A thin light ring works
   regardless of what's behind it, layered with the existing elevation
   shadow rather than replacing it -- still reads as "floating", not a
   hard outline. */
@media (max-width: 767px) {
  .jr-floating-call {
    box-shadow:
      0 0 0 2px color-mix(in srgb, var(--jr-color-text-inverse) 85%, transparent),
      0 8px 20px rgba(0, 0, 0, 0.35);
  }
}

/* Eyebrow badge -- turns the plain "Roofing Services" / "Service Areas"
   style intro line above each section title into a small lit pill
   (owner reference: a "LANDSCAPING SPECIALISTS" badge with a dot before
   the text, elegant/sophisticated, not a plain uppercase label sitting
   loose). A second class alongside each section's own existing eyebrow
   class (.jr-services__eyebrow etc, which still owns font/size/weight/
   letter-spacing/color/margin) -- this only adds the pill shape + dot,
   so nothing sitewide needs restyling twice. Red-tinted, not solid, so
   it reads correctly on both this page's dark sections (services) and
   white ones (about/final-cta/area) with the same one class. */
/* Doubled selector (.jr-eyebrow-badge.jr-eyebrow-badge, specificity 0,2,0)
   -- same real-bug pattern as .jr-btn.jr-btn-tertiary above: Kadence's own
   theme CSS ships a broad ".single-content p" rule (content.min.css,
   margin-bottom: var(--global-md-spacing), ~32px) that's more specific
   (0,1,1) than a single class alone (0,1,0) and was winning regardless of
   file load order, so every eyebrow's real spacing to its title was
   Kadence's generic paragraph rhythm, not this component's own value
   (owner, 2026-09-09: "los eyebrow sing estan muy lejos de titulo").
   The doubled class is the established, safe way to clear a specific
   third-party selector without an !important or restructuring the DOM. */
.jr-eyebrow-badge.jr-eyebrow-badge {
  display: inline-flex;
  /* Real bug, caught on the footer form's own "Free quote" kicker: its
     parent (.jr-quiz-form-wrap) is a flex column, whose default
     align-items:stretch overrides inline-flex's own shrink-to-content
     width regardless of this element's own display value -- the badge
     rendered stretched edge-to-edge instead of hugging its text. A
     badge should never stretch to fill whatever flex container it
     lands in, so this is set unconditionally, not just patched for
     this one instance. */
  align-self: flex-start;
  align-items: center;
  gap: 0.55rem;
  padding: 0.4rem 0.9rem 0.4rem 0.7rem;
  border: 1px solid color-mix(in srgb, var(--jr-color-primary) 35%, transparent);
  border-radius: var(--jr-radius-pill);
  background: color-mix(in srgb, var(--jr-color-primary) 10%, transparent);
  /* 2026-09-09: real bug, not a style preference -- every section's own
     eyebrow class (.jr-services__eyebrow etc) only set a small
     margin-bottom (~0.6rem/8px), but each also inherits this site's
     body line-height (1.6) on its text, and 1.6x a ~13px label reads as
     a much taller line-box than the glyphs alone -- padding + that
     inflated line-box + the margin together read as a badge sitting
     "muy lejos" of its title (owner, 2026-09-09), even though the
     margin value itself was already small. Tightening line-height here
     (a one-line pill label needs none of body copy's paragraph leading)
     is the real fix; margin-bottom is set ONLY here now (removed from
     every per-section eyebrow class below) so this single value governs
     the eyebrow-to-title gap sitewide, on every device -- exactly the
     "un solo ajuste modifica cada seccion" the owner asked for. */
  line-height: 1;
  margin: 0 0 0.35rem;
}

/* 2026-09-09, second pass: the badge's own margin-bottom above was only
   HALF the real bug. The section titles that follow (.jr-services__title,
   .jr-lowell-about__title, .jr-lowell-final-cta__title,
   .jr-lowell-area__title) each already declare their own margin:0 --
   but Kadence's theme CSS also ships a broad rule for every heading
   inside its content wrapper (content.min.css: ".single-content h1,
   h2, h3, h4, h5, h6 { margin-top: 1.5em }"), specificity 0,1,1, which
   beats a lone 0,1,0 title class regardless of file load order and was
   silently adding a real ~1.5x-the-font-size gap ON TOP OF the eyebrow's
   own margin -- the actual majority of the visible "muy lejos" distance
   (owner, 2026-09-09, second report with the same complaint: "deja solo
   la mitad de ese espacio"). Grouped here (0,2,0 specificity, same
   doubled-selector trick as above) instead of duplicating an override
   into all four section files -- one rule, every title, every page. */
.jr-eyebrow-badge + .jr-services__title,
.jr-eyebrow-badge + .jr-lowell-about__title,
.jr-eyebrow-badge + .jr-lowell-final-cta__title,
.jr-eyebrow-badge + .jr-lowell-area__title {
  margin-top: 0;
}

.jr-eyebrow-badge::before {
  content: '';
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--jr-color-primary);
  /* The "lit" read -- a soft halo around the dot, like a small light
     turned on, rather than a flat colored circle. */
  box-shadow:
    0 0 0 3px color-mix(in srgb, var(--jr-color-primary) 18%, transparent),
    0 0 8px 1px color-mix(in srgb, var(--jr-color-primary) 55%, transparent);
}

/* Real bug, found 2026-09-09 on the Final CTA card list going noticeably
   off-center on mobile ("todavia queda espacio a la izquierda"): six
   different <ul>s across this theme (final-cta list, service-area
   address list, ticker band, projects/reviews carousel tracks) all carry
   a "lib-no-list" class that was never actually defined anywhere in this
   project -- it assumes hhds-web-library's core/foundation/utilities.css
   reset, which this standalone child theme never loads. With the class a
   complete no-op, Kadence's own theme CSS fills the gap instead
   (content.min.css: ".single-content ul, .single-content ol { margin: 0
   0 var(--global-md-spacing); padding-left: 2em }", specificity 0,1,1),
   giving every one of those lists a real ~34px LEFT-ONLY padding (plus a
   visible disc bullet from global.min.css's own "ul { list-style: disc
   }") that nothing in this theme was actually asking for or aware of.
   Doubled selector for the same reliable 0,2,0 specificity used
   elsewhere in this file -- defines the reset for real instead of
   patching each of the six call sites separately. */
.lib-no-list.lib-no-list {
  margin: 0;
  padding: 0;
  list-style: none;
}
