/* ===========================================================================
   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; }

/* --- Top announcement bar --------------------------------------------------- */

/* A standing notice above the hero, asked for by the owner: book now, ahead of
   rising material costs. It is the first thing under the header so it is read
   on landing without scrolling.

   Colours are the site's own two: the gold of the CTA buttons
   (rgb(227,182,97), hover rgb(207,167,82)) as the panel, and the dark green of
   the content bands (rgb(31,105,47)) as the text and button. Gold rather than
   green for the panel so the strip reads as a notice instead of looking like
   one more of the page's green sections — the two colours are already paired
   this way on every green band, just inverted.

   Not dismissible and not sticky: the owner wants it seen on arrival, and a
   bar that follows the reader down the page would cover content on phones. */

.tbc-alert {
  background: rgb(227, 182, 97);
  color: rgb(31, 105, 47);
  padding: 14px 20px;
}

.tbc-alert__inner {
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  flex-wrap: wrap;
}

.tbc-alert__icon {
  width: 26px;
  height: 26px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* The ported sheets set paragraph margins globally; zero it here so the strip
   keeps its own padding rather than inheriting a body-copy rhythm. */
.tbc-alert__text {
  margin: 0;
  font-size: 17px;
  line-height: 1.35;
  letter-spacing: 0.01em;
}

.tbc-alert__cta {
  flex: none;
  background: rgb(31, 105, 47);
  color: #ffffff;
  text-decoration: none;
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 11px 22px;
  border-radius: 4px;
  transition: background 0.2s ease;
  white-space: nowrap;
}
.tbc-alert__cta:hover,
.tbc-alert__cta:focus-visible { background: rgb(23, 80, 36); color: #ffffff; }
.tbc-alert__cta:focus-visible { outline: 2px solid rgb(31, 105, 47); outline-offset: 2px; }

/* Phones: the row stacks, so the icon sits with the text rather than above it
   and the button goes full-width for a comfortable tap target. */
@media (max-width: 767px) {
  .tbc-alert { padding: 13px 16px; }
  .tbc-alert__inner { gap: 11px; }
  .tbc-alert__text { font-size: 15.5px; text-align: center; }
  .tbc-alert__icon { display: none; }
  .tbc-alert__cta { width: 100%; text-align: center; padding: 12px 18px; }
}

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