/* ===========================================================================
   tbc-widgets.css — behaviour styling for Duda widgets whose own CSS and JS
   were never captured by the export.

   The port carries Duda's stylesheets verbatim, but Duda serves its ACCORDION
   and GALLERY LIGHTBOX widgets from separate runtime bundles that the capture
   did not include: for the accordions the ported sheets hold nothing but the
   arrow's width/height, and for the galleries nothing at all. Both widgets
   therefore shipped inert.

   Everything here is structure and motion only. Fonts, colours, borders and
   spacing keep coming from the ported per-widget rules
   (`#dm .dmBody .u_<id> .accordion-…`), which still win on `!important`.
   =========================================================================== */

/* --- Accordions ---------------------------------------------------------- */

/* Duda's accordion is entirely CSS-driven and that CSS *is* ported:
   `.widget-832a29 .section` collapses with `max-height: 0` and
   `transition: max-height .3s ease-out`, and `.widget-832a29 .expanded .section`
   opens it to 30000px, with the layout sheets rotating the chevron. The only
   thing missing from the capture was the script that puts `expanded` on the
   item — see tbc-widgets.js. So nothing here re-implements the open/close or
   its easing; this adds only the affordances Duda's sheet leaves out, because
   its own handler lived in the uncaptured bundle. */

.accordion-title { cursor: pointer; -webkit-tap-highlight-color: transparent; }
.accordion-title:focus-visible { outline: 2px solid currentColor; outline-offset: -2px; }

/* Duda's own open-state rule is `.widget-832a29 .expanded .section`, scoped to
   the widget's build hash. Restating it here anchored on the item itself keeps
   the accordions working regardless of which hash wraps a given instance, and
   this sheet loads after every device sheet so it also settles the cascade.
   Same declaration and same 0.3s ease-out transition as the ported rule — this
   changes no value, only which selector delivers it. */
.accordion-item.expanded > .accordion-description > .section { max-height: 30000px; }

/* The chevron flip, likewise restated. `fullBorder` and `roundedIcon` are the
   two layouts this site uses and both rotate 180deg. */
.accordion-item.expanded .arrow { transform: rotate(180deg); }

@media (prefers-reduced-motion: reduce) {
  .widget-832a29 .section,
  .widget-832a29 .arrow { transition: none !important; }
}

/* --- Gallery lightbox ----------------------------------------------------- */

.tbc-gal-hit { cursor: zoom-in; }

.tbc-lightbox {
  position: fixed;
  inset: 0;
  z-index: 2147483000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.92);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.25s ease, visibility 0.25s ease;
}
.tbc-lightbox[open] { opacity: 1; visibility: visible; }

.tbc-lightbox__img {
  max-width: 92vw;
  max-height: 86vh;
  object-fit: contain;
  display: block;
  box-shadow: 0 10px 50px rgba(0, 0, 0, 0.6);
}

.tbc-lightbox__btn {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
  cursor: pointer;
  transition: background 0.2s ease, transform 0.2s ease;
}
.tbc-lightbox__btn:hover { background: rgba(255, 255, 255, 0.3); }
.tbc-lightbox__btn:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
.tbc-lightbox__btn svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }

.tbc-lightbox__close { top: 18px; right: 18px; }
.tbc-lightbox__prev { left: 18px;  top: 50%; transform: translateY(-50%); }
.tbc-lightbox__next { right: 18px; top: 50%; transform: translateY(-50%); }
.tbc-lightbox__prev:hover,
.tbc-lightbox__next:hover { transform: translateY(-50%) scale(1.06); }

.tbc-lightbox__count {
  position: absolute;
  bottom: 18px;
  left: 50%;
  transform: translateX(-50%);
  color: rgba(255, 255, 255, 0.85);
  font-size: 14px;
  letter-spacing: 0.04em;
}

/* One image: the arrows have nowhere to go. */
.tbc-lightbox[data-single="true"] .tbc-lightbox__prev,
.tbc-lightbox[data-single="true"] .tbc-lightbox__next,
.tbc-lightbox[data-single="true"] .tbc-lightbox__count { display: none; }

@media (max-width: 767px) {
  .tbc-lightbox__btn { width: 44px; height: 44px; }
  .tbc-lightbox__btn svg { width: 20px; height: 20px; }
  .tbc-lightbox__close { top: 10px; right: 10px; }
  .tbc-lightbox__prev { left: 6px; }
  .tbc-lightbox__next { right: 6px; }
}

@media (prefers-reduced-motion: reduce) {
  .tbc-lightbox, .tbc-lightbox__btn { transition: none; }
}

/* --- Service tile links --------------------------------------------------- */

/* The five service names under "Home Remodeling Services We Offer" are now
   links. Colour is inherited so the tiles keep the contrast they already had
   (these sit on a light panel and the label colour is set by the ported
   per-widget rules); the underline appears on hover/focus so the tile reads
   the same at rest but is obviously clickable. */
.tbc-service-link {
  color: inherit;
  text-decoration: none;
  cursor: pointer;
}
.tbc-service-link:hover,
.tbc-service-link:focus-visible { text-decoration: underline; }

/* --- Body-text interlinks -------------------------------------------------- */

/* The business name linked to the homepage inside page copy. Underlined and
   bold, which is the house treatment for an interlink in body text — and it is
   scoped to this class precisely so it never reaches a heading, a button or
   the header/footer. Colour is inherited so the sentence keeps the contrast it
   already had against whatever panel it sits on. */
.tbc-interlink {
  color: inherit;
  font-weight: 700;
  text-decoration: underline;
}
.tbc-interlink:hover,
.tbc-interlink:focus-visible { text-decoration: none; }

/* --- Scroll reveal --------------------------------------------------------- */

/* Duda animates content in as it scrolls into view. Two mechanisms ship in the
   captured markup and neither had anything driving it:

   1. `[data-anim-desktop="fadeIn"]` — Duda's sheet sets
      `.dmDesktopBody [data-anim-desktop]:not([data-anim-desktop="none"])
       { visibility: hidden }` and its runtime reveals the element. With the
      runtime uncaptured the element stayed hidden for good, so one column on
      /basement-finishing-west-boxbury was invisible on desktop.
   2. `style="transition: opacity 1s ease-in-out"` on ~36 paragraph blocks per
      page — Duda's fade, left with nothing to transition from.

   The reveal is driven by tbc-widgets.js. Everything here is gated on the
   `tbc-anim` class the script puts on <html>, so with no JavaScript nothing is
   ever hidden — the page just renders fully, which is what it does today. */

/* Undo Duda's hold-until-revealed, which we now own. */
.dmDesktopBody [data-anim-desktop]:not([data-anim-desktop="none"]),
.dmDesktopBody:not(.editGrid) .dmNewParagraph[data-anim-desktop]:not([data-anim-desktop="none"]) {
  visibility: visible !important;
}

html.tbc-anim [data-tbc-anim] {
  opacity: 0;
  transition: opacity 0.8s ease-in-out, transform 0.8s ease-in-out;
}
html.tbc-anim [data-tbc-anim="up"] { transform: translateY(24px); }
html.tbc-anim [data-tbc-anim].tbc-anim-in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  html.tbc-anim [data-tbc-anim] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

/* --- FAQ accordion (the second, styled-components widget) ------------------ */

/* The blog posts and /accessory-dwelling-units-west-roxbury carry a DIFFERENT
   accordion from the one above: Duda's newer styled-components widget, marked
   up with `data-grab="accordion-…"` and hashed class names (`sc-gEvEer`), not
   `.accordion-wrapper`. Its collapse survives the capture as
   `.dygwmn { max-height: 0; transition: max-height .3s ease-out }` — but the
   open state does not, because styled-components generates that class at
   runtime, so it exists only in the bundle Duda serves separately. The result
   was five pages whose FAQ answers could not be opened at all.
   The `data-grab` hooks are stable, so the state is keyed off those rather
   than off the hashed class names, which change on every Duda build. */

[data-grab="accordion-item-title-wrapper"] {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
[data-grab="accordion-item-title-wrapper"]:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: -2px;
}

[data-grab="accordion-item-arrow"] { transition: transform 0.3s ease; }

[data-grab="accordion-item-container"].tbc-faq-open [data-grab="accordion-item-arrow"] {
  transform: rotate(180deg);
}
/* Same easing as the ported rule; only the open value was missing. 30000px is
   the value Duda uses on its other accordion, and it is deliberately far larger
   than any answer here — max-height only caps, so an over-generous number costs
   nothing, while too small a one would silently clip the end of a long answer. */
[data-grab="accordion-item-container"].tbc-faq-open .dygwmn {
  max-height: 30000px;
}

@media (prefers-reduced-motion: reduce) {
  .dygwmn,
  [data-grab="accordion-item-arrow"] { transition: none !important; }
}

/* --- Contrast ------------------------------------------------------------- */

/* Duda left body copy and body links at rgb(43,43,43) inside the dark green
   panels (rgb(31,105,47)) — 2.1:1 where WCAG AA wants 4.5:1 — and the footer's
   green link colour sits at 2.69:1 on the near-black footer.

   This is NOT fixed with a blanket rule over those panels: the green rows
   contain nested light panels (u_1796428726 on the home page is rgb(250,250,250)),
   and forcing white across the subtree turned that text invisible — a worse
   bug than the one being fixed. The correction is computed per element in
   tbc-widgets.js against each element's ACTUAL painted background, so only
   text that genuinely fails is touched. All this does is mark the result. */

[data-tbc-contrast="light"] { color: #ffffff !important; }
[data-tbc-contrast="dark"]  { color: #1a1a1a !important; }
