/* ---------------------------------------------------------------
   custom.css
   Hand-written additions on top of the extracted Tailwind build
   (styles.css) and font-face declarations (fonts.css). Covers:
   - scroll/JS driven reveal animation states (headings included --
     each heading is one plain text node, not split per word, for
     clean/SEO-friendly markup)
   - header shrink-on-scroll state
   - mega menu / dropdown menu / mobile nav dialog behaviour
----------------------------------------------------------------- */

/* generic reveal-on-scroll system: any element that shipped from the
   server with an inline opacity:0 (optionally plus a translateX/Y)
   fades/slides into place once it enters the viewport. */
[style*="opacity:0"] {
  transition: opacity .8s cubic-bezier(.16,.84,.44,1), transform .8s cubic-bezier(.16,.84,.44,1);
}
.dw-revealed {
  opacity: 1 !important;
  transform: none !important;
}

/* Hover-reveal card overlays (the "Learn More" panels on the service
   cards) also ship with an inline opacity:0, but that's unrelated to
   scroll position -- their visibility is entirely controlled by
   translate-y-full / group-hover:translate-y-0, clipped by the card's
   overflow-hidden. They must never be picked up by the scroll-reveal
   system above (which would force transform:none via .dw-revealed and
   permanently cancel the translate-y-full that keeps them hidden until
   hover), so their opacity is corrected here, unconditionally, instead. */
[class*="group-hover:translate-y-0"][style*="opacity:0"] {
  opacity: 1 !important;
}

/* header shrink state */
#dw-header-main.dw-scrolled {
  padding-top: .75rem !important;
  padding-bottom: .75rem !important;
  border-bottom-color: #D5D5D5 !important;
}

/* mega menu + simple dropdowns: hidden by default via [hidden], shown by
   removing the attribute and toggling opacity+transform for a combined
   slide-down/fade-in transition. */
.dw-megamenu, .dw-dropdown {
  transform: translateY(-8px);
  transition: opacity .2s ease-out, transform .2s ease-out;
}
.dw-megamenu[hidden], .dw-dropdown[hidden] { display: none; }
.dw-megamenu.dw-open, .dw-dropdown.dw-open { opacity: 1 !important; transform: translateY(0); }

/* mobile nav dialog */
.dw-mobile-overlay {
  position: fixed;
  inset: 0;
  z-index: 40;
  background: rgba(0,0,0,.5);
  opacity: 0;
  transition: opacity .3s ease-in-out;
}
.dw-mobile-overlay.dw-open { opacity: 1; }
#dw-mobile-dialog {
  transform: translateX(100%);
  transition: transform .4s cubic-bezier(.16,.84,.44,1);
}
#dw-mobile-dialog.dw-open { transform: translateX(0); }

.dw-accordion-trigger svg.dw-rotated { transform: rotate(180deg); }
.dw-accordion-trigger svg { transition: transform .2s ease-in-out; }

body.dw-no-scroll { overflow: hidden; }

/* video lightbox (the hero/section "Play Video" buttons) -- matches the
   live site's Radix Dialog: a blurred indigo backdrop behind a centered,
   zoom-in panel holding the video embed. */
.dw-video-overlay {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: rgba(34, 34, 73, .75); /* brand-indigo/75 */
  backdrop-filter: blur(4px);
  opacity: 0;
  transition: opacity .2s ease-out;
}
.dw-video-overlay.dw-open { opacity: 1; }
.dw-video-dialog {
  opacity: 0;
  transform: scale(.95);
  transition: opacity .2s ease-out, transform .2s ease-out;
}
.dw-video-dialog.dw-open { opacity: 1; transform: scale(1); }

/* Close (X) button shared by the video/newsletter dialogs, always pinned
   to the panel's top-right corner. Written as plain CSS rather than
   Tailwind position utilities (e.g. "right-3 top-3") because this
   stylesheet is a real production build that only kept the utility
   classes actually used elsewhere on the live site -- an arbitrary
   combination like "-right-3" or "md:right-2" can be silently absent
   from it, in which case the browser just ignores the unknown class
   with no warning and the button falls back to wherever it sits in
   normal flow (which is how one ended up in the top-LEFT corner instead
   of the right). Positioning it here instead guarantees it actually
   applies regardless of what the purge kept. */
.dw-dialog-close {
  position: absolute;
  top: .75rem;
  right: .75rem;
}

/* header search dialog */
.dw-search-overlay {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: rgba(0, 0, 0, .5);
  opacity: 0;
  transition: opacity .2s ease-out;
}
.dw-search-overlay.dw-open { opacity: 1; }
.dw-search-dialog {
  opacity: 0;
  transform: scale(.95);
  transition: opacity .2s ease-out, transform .2s ease-out;
}
.dw-search-dialog.dw-open { opacity: 1; transform: scale(1); }
.dw-search-result {
  display: block;
  padding: .75rem 1.5rem;
  font-size: .9rem;
  color: #222249;
  text-decoration: none;
  border-bottom: 1px solid #F0F0F0;
}
.dw-search-result:hover { background: #F5F5F5; }
.dw-search-empty {
  padding: 1.5rem;
  font-size: .9rem;
  color: #6b7280;
  text-align: center;
}

/* Footer vertical padding, trimmed down from the site's original values
   (pt-24/lg:pt-40, lg:pb-32 -- 96px/160px top, 128px bottom at desktop).
   Written as an explicit override here rather than swapping Tailwind
   utility classes in the markup: this CSS bundle is a real production
   build that only kept the utility classes actually used elsewhere on
   the site, so an arbitrary class like "lg:pt-20" can silently not exist
   in it at all -- the browser just ignores the unknown class name with
   no warning, so the padding quietly falls back to whatever the base
   (mobile) class resolves to, which can be a much bigger cut than
   intended. Setting the exact value directly here avoids that trap. */
#footer-inner {
  padding-top: 4rem; /* was 6rem (pt-24) */
}
@media (min-width: 1024px) {
  #footer-inner {
    padding-top: 6rem;   /* was 10rem (lg:pt-40) */
    padding-bottom: 3rem; /* was 8rem (lg:pb-32) -- mobile had no bottom padding here originally, so it's left alone below 1024px */
  }
}

/* Header "nearest store" button + its Info/Hours location dialog */
#dw-nearest-store-name {
  text-decoration: none;
  cursor: pointer;
}
#dw-nearest-store-name:hover { text-decoration: underline; }

#dw-location-badge.dw-open-badge { background: #DCFCE7; color: #15803D; }
#dw-location-badge.dw-closed-badge { background: #FEE2E2; color: #B91C1C; }

.dw-location-tab {
  padding: .5rem 1rem;
  font-size: .8rem;
  font-weight: 600;
  color: #9CA3AF;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.dw-location-tab-active {
  color: #222249; /* brand-indigo */
  border-bottom-color: #00AF9D; /* brand-green */
}

.dw-location-hours-list { font-size: .875rem; }
.dw-location-hours-row {
  display: flex;
  justify-content: space-between;
  padding: .5rem 0;
  border-bottom: 1px solid #F0F0F0;
  color: #222249;
}
.dw-location-hours-row.dw-today { font-weight: 700; }

/* Inventory detail pages (inventory-<slug>.html): the product photo box
   and the sticky "Back" link both need arbitrary-value Tailwind utility
   classes ("aspect-[4/3]" and "md:top-[10rem]") that happen not to be
   used anywhere else on the already-cloned pages, so the purged
   styles.css build never picked them up -- same silent-no-op trap noted
   above for "-right-3"/"md:right-2". Defined here instead of an inline
   style attribute, matching this file's established pattern. */
.aspect-\[4\/3\] {
  aspect-ratio: 4 / 3;
}
@media (min-width: 768px) {
  .md\:top-\[10rem\] {
    top: 10rem;
  }
}

/* Segment pages (segments-agriculture-*.html): the indigo image-overlay
   tint used on the "Brand Spotlight" and "Get a Quote / Find a Location"
   blocks needs arbitrary-value background-color utilities
   ("bg-[#222249]/75" and "bg-[#222249]/80") that aren't used anywhere
   else in the already-cloned pages, so the purged styles.css build never
   picked them up -- same silent-no-op trap noted above. Defined here
   instead, matching this file's established pattern. */
.bg-\[\#222249\]\/75 {
  background-color: rgba(34, 34, 73, .75);
}
.bg-\[\#222249\]\/80 {
  background-color: rgba(34, 34, 73, .8);
}

/* Jobs listing page (jobs.html): the job-card border/shadow hover state
   and the "Hired" ribbon's tint need opacity-modified color utilities
   ("border-gray-200/80", "hover:border-gray-300/80", "bg-brand-green/10")
   that aren't used anywhere else in the already-cloned pages, so the
   purged styles.css build never picked them up -- same silent-no-op trap
   noted above. Defined here instead, matching this file's established
   pattern. (gray-200/gray-300/brand-green base colors taken from their
   already-present non-opacity utilities in styles.css.) */
.border-gray-200\/80 {
  border-color: rgb(229 231 235 / .8);
}
.hover\:border-gray-300\/80:hover {
  border-color: rgb(209 213 219 / .8);
}
.bg-brand-green\/10 {
  background-color: rgb(0 175 157 / .1);
}

/* Project detail page image gallery lightbox (dw-gallery-dialog, e.g. on
   projects-turbine-build-shop.html): unlike this project's other dialogs
   (search/video/newsletter/location), this one needs a bare "flex" utility
   class on itself to center the viewed image, and that silently broke its
   "hidden" attribute -- the browser's default [hidden]{display:none} and
   Tailwind's .flex{display:flex} are equal-specificity single-class/
   attribute selectors, so whichever rule comes later in the cascade wins,
   and .flex came later. Real-world effect: while "closed", the dialog was
   still computed as display:flex -- an invisible, full-viewport,
   z-50 layer sitting on top of the whole page, silently swallowing every
   real mouse click (a JS-triggered .click() on a button underneath still
   fired, since that bypasses hit-testing, which is why this only showed up
   under genuine mouse interaction, not automated checks). Fixed here with
   an ID-selector override, which beats the class selector regardless of
   cascade order, instead of removing "flex" from the dialog's class list
   and fighting Tailwind's own centering utilities in JS. */
#dw-gallery-dialog[hidden] {
  display: none;
}

/* Same equal-specificity [hidden] vs .flex problem as above, on the three
   client-side-filtered card grids (inventory.js/projects.js/news.js each
   set li.hidden on non-matching cards, but every card carries "flex w-full"
   -- the "hidden" attribute is set correctly, but every card kept rendering
   at display:flex regardless of the filter, so selecting a filter appeared
   to do nothing). */
#dw-inv-grid li[hidden],
#dw-projects-grid li[hidden],
#dw-news-grid li[hidden],
#dw-jobs-grid li[hidden] {
  display: none;
}

/* Locations pages (locations.html, locations-<slug>.html): the live site's
   Tailwind config defines a custom "regular" font-weight utility
   (font-regular, weight 400) used throughout the address/hours info panel
   and location cards. It isn't used anywhere else in the already-cloned
   pages, so the purged styles.css build never picked it up -- same
   silent-no-op trap noted above for "-right-3"/"md:right-2". Defined here
   instead, matching this file's established pattern. */
.font-regular {
  font-weight: 400;
}

/* Sitemap page (sitemap.html): the link-list hover-color utility
   ("hover:text-brand-green") isn't used anywhere else in the already-cloned
   pages, so the purged styles.css build never picked it up -- same
   silent-no-op trap noted above. Defined here instead, matching this
   file's established pattern (brand-green hex taken from its already-
   present non-hover utilities in styles.css). */
.hover\:text-brand-green:hover {
  color: #00af9d;
}

/* ---------------------------------------------------------------
   Merged from assets/css/about.css (about.html no longer links it
   separately -- kept as its own section here so it stays easy to find).
----------------------------------------------------------------- */

/* Timeline carousel: cross-fade + slight rise/dip when the slide changes,
   and a smooth active-tab indicator transition underneath the year row. */
#dw-timeline-image,
#dw-timeline-year,
#dw-timeline-caption {
  transition: opacity .35s ease, transform .35s ease;
}
.dw-timeline-fade-out {
  opacity: 0 !important;
}
#dw-timeline-image.dw-timeline-fade-out { transform: scale(1.03); }
#dw-timeline-year.dw-timeline-fade-out,
#dw-timeline-caption.dw-timeline-fade-out { transform: translateY(8px); }

#dw-timeline-tabs button {
  transition: color .2s ease, border-color .25s ease;
}

/* Year-tab strip: signal it's manually draggable with the mouse, not just
   auto-advanced by the Prev/Next buttons. The drag state class is applied
   to the scrollable container (the [role="tablist"] wrapper), not the
   #dw-timeline-tabs row it wraps. */
.timeline-block [role="tablist"] {
  cursor: grab;
}
.timeline-block [role="tablist"].dw-dragging {
  cursor: grabbing;
}
.timeline-block [role="tablist"].dw-dragging #dw-timeline-tabs button {
  transition: none;
}

/* ---------------------------------------------------------------
   Merged from assets/css/contact.css (contact.html no longer links it
   separately -- kept as its own section here so it stays easy to find).
----------------------------------------------------------------- */

/* Hero paragraph copy: live site sets prose-p:xl:text-lg and
   prose-p:xl:leading-[1.8] on this block, neither of which exists in
   the purged styles.css (arbitrary/xl-prefixed prose modifiers aren't
   used anywhere else on the already-cloned homepage), so set the exact
   values directly. */
@media (min-width: 1280px) {
  .dw-contact-hero-copy p {
    font-size: 1.125rem;
    line-height: 1.8;
  }
}

/* Request a Quote / General Inquiry intro paragraph: live site adds
   prose-p:xl:text-sm on top of the base prose-p:text-xs; same "class
   not in the purge" situation as above. */
@media (min-width: 1280px) {
  .dw-contact-form-copy p {
    font-size: .875rem;
  }
}

/* Pill tab switcher ("Request a Quote" / "General Inquiry"). The
   sliding indicator div is positioned/animated via inline left/width
   styles set by contact.js (transition-all already covers the
   animation); this just handles the two label states, matching the
   live site's hover:text-gray-900 on the inactive tab which also isn't
   in the purge. */
.dw-contact-tab {
  color: #374151; /* text-gray-700, already proven present, used as the base state */
  background: transparent;
  border: 0;
  cursor: pointer;
}
.dw-contact-tab:hover {
  color: #111827; /* text-gray-900 */
}
.dw-contact-tab-active,
.dw-contact-tab-active:hover {
  color: #fff;
}

/* Two more purged arbitrary-value classes on this same tab switcher (see
   the .min-w-\[120px\] precedent above for why these are hand-written
   instead of relying on the Tailwind build). */
.border-gray-200\/40 {
  border-color: rgb(229 231 235 / 0.4);
}
.mt-1\.5 {
  margin-top: 0.375rem;
}

/* Form panel crossfade between the two tabs (mirrors the live site's
   "animate-in fade-in slide-in-from-right-4" on tab switch). */
.dw-contact-form-panel {
  animation: dw-contact-fade-in .3s ease-out;
}
@keyframes dw-contact-fade-in {
  from { opacity: 0; transform: translateX(8px); }
  to { opacity: 1; transform: none; }
}

/* Location cards ("Our Locations" grid): live site's hover state is
   hover:bg-brand-green/10, an opacity-modified brand color not in the
   purge (only the solid bg-brand-green exists there). */
.dw-location-card {
  cursor: pointer;
}
.dw-location-card:hover {
  background-color: rgba(0, 175, 157, .1);
}

/* "Show All" reveal: extra location cards ship hidden and fade in when
   the button is clicked, rather than being absent from the DOM. */
.dw-location-card[hidden] {
  display: none;
}

/* Locations map embed: a plain Google Maps iframe embed (same
   maps.google.com/maps?...output=embed technique already used by the
   header's per-store location dialog) standing in for the live site's
   interactive Google Maps JS API multi-marker map, which needs a
   billed Maps JavaScript API key this static clone doesn't have. */
.dw-locations-map-wrap {
  width: 100%;
  height: 600px;
  border-radius: 8px;
  overflow: hidden;
}

/* ---------------------------------------------------------------
   Merged from assets/css/inventory.css (inventory.html no longer links
   it separately -- kept as its own section here so it stays easy to find).
----------------------------------------------------------------- */

/* brand-indigo = rgb(34 34 73), brand-green = rgb(0 175 157),
   brand-green-darker = rgb(0 159 143) */

.dw-inv-card:hover {
  box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
  border-color: rgba(34, 34, 73, 0.25);
}

.dw-inv-card .dw-inv-card-img {
  transition: transform 0.3s ease;
}
.dw-inv-card:hover .dw-inv-card-img {
  transform: scale(1.05);
}

/* dl rows inside cards: border between rows, none on the last row */
.dw-inv-dl > div {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid rgb(243 244 246);
}
.dw-inv-dl > div:last-child {
  border-bottom: 0;
}

/* filter select text/chevron should stay white against the pill's own
   green fill (from the "bg-brand-green" utility class already on these
   selects) -- this must only touch text color, never background-color:
   an ID selector like this beats a class selector regardless of source
   order, so a background-color here would silently strip the green fill
   the Tailwind class sets, leaving an invisible white-on-white pill. */
#dw-inv-filters select {
  color: #fff;
}
#dw-inv-filters select option {
  color: #222249;
  background-color: #fff;
}

/* price inputs: focus ring using the real brand-green value, since
   focus:ring-1 / focus:ring-brand-green / focus:border-brand-green
   aren't present in the purged build */
#dw-inv-filters input[type="number"]:focus {
  border-color: rgb(0 175 157);
  box-shadow: 0 0 0 1px rgb(0 175 157);
  outline: none;
}

.dw-inv-reset-btn {
  background: none;
  border: none;
  cursor: pointer;
}

/* quote dialog form inputs: match the site's rounded bordered fields
   and give them a visible focus state (hover:/focus: ring utilities
   for this exact combination aren't in the purged build either) */
.dw-inv-quote-form input,
.dw-inv-quote-form textarea {
  font: inherit;
}
.dw-inv-quote-form input:focus,
.dw-inv-quote-form textarea:focus {
  border-color: rgb(0 175 157);
  box-shadow: 0 0 0 1px rgb(0 175 157);
  outline: none;
}

@media (max-width: 767px) {
  .dw-inv-quote-form {
    grid-template-columns: 1fr;
  }
  .dw-inv-quote-form .col-span-2,
  .dw-inv-quote-form .col-span-1 {
    grid-column: span 1 / span 1;
  }
}

/* ---------------------------------------------------------------
   Merged from assets/css/legal.css (privacy-policy.html,
   terms-of-service.html and forced-labour-and-child-labour-report.html
   no longer link it separately -- kept as its own section here so it
   stays easy to find).
----------------------------------------------------------------- */

/* Smooth-scroll for the in-page "View Policy" hero button and the
   copy-link icons on each section heading -- both jump to an #id further
   down the same page. */
html {
  scroll-behavior: smooth;
}

/* The header is fixed (h-[60px] on mobile, h-[120px] from lg: up), so an
   in-page anchor jump needs matching scroll offset or the target heading
   lands underneath it. */
main#main-content [id] {
  scroll-margin-top: 90px;
}

@media (min-width: 1024px) {
  main#main-content [id] {
    scroll-margin-top: 140px;
  }
}

/* Active nav-link highlighting (site.js's setupActiveNav): the current
   page's own link in the header's mega-menus/dropdowns/mobile accordion,
   plus the trigger it lives under, get the brand-green color regardless
   of their own text-brand-navy/text-brand-indigo class -- !important
   beats those since a link's own color class always wins over a merely
   inherited one otherwise. */
.dw-nav-active {
  color: #00af9d !important;
}

/* Inventory cards (inventory.html): the "More info" / "Request a quote"
   button pair's min-width floor was only ever authored as "sm:min-w-
   [120px]" (mobile always got "w-full" instead, stacking the two buttons
   full-width on top of each other) -- neither the sm: nor a plain
   unprefixed variant of this arbitrary value is in the purged styles.css
   build, so it's defined here instead, matching this file's established
   pattern, now applied unprefixed since both buttons sit side by side
   (each flex-1) at every width, not just sm: and up. */
.min-w-\[120px\] {
  min-width: 120px;
}

/* Header search dialog's categorized results (site.js setupSearchDialog):
   a new component with no precedent in source, so — same purge-gap
   reasoning as above — hand-written here rather than via Tailwind
   utility combinations that were never compiled into styles.css. */
.dw-search-body {
  display: flex;
  flex-direction: column;
}
@media (min-width: 768px) {
  .dw-search-body {
    flex-direction: row;
  }
}
.dw-search-categories {
  width: 100%;
  flex-shrink: 0;
  border-bottom: 1px solid #e5e7eb;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
@media (min-width: 768px) {
  .dw-search-categories {
    width: 14rem;
    border-bottom: 0;
    border-right: 1px solid #e5e7eb;
  }
}
.dw-search-cat {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.5rem 0.75rem;
  border-radius: 0.5rem;
  text-align: left;
  background: transparent;
  border: 0;
  cursor: pointer;
  transition: background-color 0.2s ease;
}
.dw-search-cat:hover,
.dw-search-cat-active {
  background-color: #e0f5f3;
}
.dw-search-cat-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  flex-shrink: 0;
  border-radius: 9999px;
  background-color: #e0f5f3;
  color: #222249;
}
.dw-search-cat-label {
  flex: 1;
  font-size: 0.875rem;
  font-weight: 500;
  color: #222249;
}
.dw-search-cat-count {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 1.5rem;
  height: 1.5rem;
  padding: 0 0.375rem;
  border-radius: 9999px;
  background-color: #00af9d;
  color: #fff;
  font-size: 0.75rem;
  font-weight: 700;
}
.dw-search-results-col {
  flex: 1;
  min-width: 0;
  padding: 1rem;
}
.dw-search-summary {
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #9ca3af;
  margin-bottom: 0.75rem;
}
.dw-search-results {
  max-height: 45vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.dw-search-empty {
  font-size: 0.875rem;
  color: #6b7280;
  padding: 1.5rem 0;
}
.dw-search-result {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem;
  border-radius: 0.5rem;
  border: 1px solid #f3f4f6;
  transition: background-color 0.2s ease, border-color 0.2s ease;
}
.dw-search-result:hover {
  background-color: #f9fafb;
  border-color: #e5e7eb;
}
.dw-search-result-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  flex-shrink: 0;
  border-radius: 0.375rem;
  background-color: #f3f4f6;
  color: #222249;
}
.dw-search-result-text {
  flex: 1;
  min-width: 0;
}
.dw-search-result-title {
  display: block;
  font-size: 0.875rem;
  font-weight: 600;
  color: #222249;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dw-search-result-cat {
  display: block;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #9ca3af;
  margin-top: 0.125rem;
}
.dw-search-result-chevron {
  color: #d1d5db;
  flex-shrink: 0;
}

/* Newsletter signup dialog (and any other dialog reusing these same
   classes): md:h-fit / lg:max-h-[90vh] / md:inset-10 were never compiled
   into styles.css (not used anywhere else in the original site), so the
   dialog stayed locked at h-full (100% of the viewport) on every screen
   size instead of shrinking to fit its real content -- the HubSpot embed
   (which can be taller than the viewport) was clipped with no visible way
   to reach the Submit button below the fold. */
@media (min-width: 768px) {
  .md\:h-fit {
    height: fit-content;
  }
  .md\:inset-10 {
    inset: 2.5rem;
  }
}
@media (min-width: 1024px) {
  .lg\:max-h-\[90vh\] {
    max-height: 90vh;
  }
}

/* Back link (project/job/inventory/news single detail pages, via
   delta_back_link() in inc/template-functions.php). Source renders this as
   an inline lucide chevron-left icon + "Back" label with an underline-grow
   hover effect on the label; written as plain CSS here (rather than the
   Tailwind utilities the source used, e.g. group-hover:max-w-full and
   underline-offset-4) because those specific combinations were never
   compiled into styles.css -- same purge-gap situation as elsewhere in this
   file. This is a bespoke .delta-back-link class (not a Tailwind utility),
   so it's simplest to give it its own small rule block entirely. */
.delta-back-link {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.875rem;
  font-weight: 500;
  color: #222249; /* brand-indigo */
}
.delta-back-link__icon {
  flex-shrink: 0;
}
.delta-back-link__label {
  position: relative;
}
.delta-back-link__label::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -4px;
  display: block;
  width: 100%;
  max-width: 0;
  height: 1.5px;
  border-radius: 9999px;
  background-color: #000;
  transition: max-width 0.3s ease-in-out;
}
.delta-back-link:hover .delta-back-link__label::after {
  max-width: 100%;
}

/* Segment pages' Call to Action block ("Technology Spotlight" / "Brand
   Spotlight" eyebrow above the CTA heading, template-parts/sections/
   layout_call_to_action.php's new cta_eyebrow field): needs "md:mb-7",
   which isn't used anywhere else in the already-cloned pages, so the
   purged styles.css build never picked it up -- same silent-no-op trap
   noted elsewhere in this file. Defined here instead, matching this
   file's established pattern. */
@media (min-width: 768px) {
  .md\:mb-7 {
    margin-bottom: 1.75rem;
  }
}

/* Newsletter CTA bar heading (footer.php, "Sign up for our Newsletter"):
   centered on mobile/tablet to match the centered Subscribe button below
   it (QA item: heading was left-aligned while button was centered), but
   needs to revert to left-aligned once the bar switches to a side-by-side
   row at `lg:` (lg:flex-row). "lg:text-left" isn't used anywhere else in
   the already-cloned pages, so the purged styles.css build never picked
   it up -- same purge-gap situation as elsewhere in this file. */
@media (min-width: 1024px) {
  .lg\:text-left {
    text-align: left;
  }
}

/* Our Team page's "Our Regional Team" province filter
   (template-parts/sections/layout_team_block.php's #dw-team-filter):
   live wraps the native <select> (appearance-none, so the browser's own
   arrow is suppressed) in a `.group` with an absolutely-positioned custom
   chevron SVG, which turns brand-green on hover/focus along with the
   select's own text/border. Our markup had the select but no replacement
   chevron at all, so the control showed no dropdown indicator (QA:
   "Filters dropdown icon should display as per live site"). The chevron's
   hover-color swap is a plain custom selector here, not a Tailwind
   arbitrary-value utility, so there's no purge-gap risk -- just added
   directly. */
.group:hover .dw-team-filter-chevron {
  stroke: #00af9d;
}

/* Cookie consent banner + "Cookie Settings" preferences dialog
   (template-parts/cookie-consent.php, assets/js/cookie-consent.js). Not a
   Tailwind component -- live runs this off the c15t consent-manager
   package (a Next.js/React library with no WordPress equivalent), so this
   is a plain hand-written component matching its copy, button colors and
   layout (confirmed from live's own embedded c15t config), reusing the
   existing .dw-video-overlay/.dw-video-dialog dialog convention for the
   preferences panel. */
.dw-cookie-banner {
  position: fixed;
  left: 1rem;
  right: 1rem;
  bottom: 1rem;
  z-index: 60;
  max-width: 640px;
  background: #fff;
  border-radius: 0.75rem;
  box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
  padding: 1.25rem;
  opacity: 0;
  transform: translateY(1rem);
  transition: opacity 0.2s ease-out, transform 0.2s ease-out;
}
.dw-cookie-banner.dw-open {
  opacity: 1;
  transform: translateY(0);
}
.dw-cookie-banner-text h2 {
  font-weight: 700;
  font-size: 1rem;
  color: #222249;
  margin-bottom: 0.375rem;
}
.dw-cookie-banner-text p {
  font-size: 0.8125rem;
  line-height: 1.4;
  color: #4b5563;
}
.dw-cookie-banner-text p a {
  text-decoration: underline;
  color: #115e59;
}
.dw-cookie-banner-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 1rem;
}

.dw-cookie-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.5rem 1rem;
  border-radius: 0.5rem;
  font-size: 0.8125rem;
  font-weight: 600;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.dw-cookie-btn-solid {
  background: #00af9d;
  border-color: #009f8f;
  color: #fff;
}
.dw-cookie-btn-solid:hover {
  background: #115e59;
}
.dw-cookie-btn-outline {
  background: transparent;
  border-color: #115e59;
  color: #115e59;
}
.dw-cookie-btn-outline:hover {
  background: #fff;
  border-color: #00af9d;
}

.dw-cookie-type {
  padding: 0.875rem 0;
  border-bottom: 1px solid #e5e7eb;
}
.dw-cookie-type-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}
.dw-cookie-type-title {
  font-weight: 600;
  font-size: 0.875rem;
  color: #222249;
}
.dw-cookie-type-desc {
  margin-top: 0.375rem;
  font-size: 0.8125rem;
  color: #6b7280;
  line-height: 1.4;
}
.dw-cookie-dialog-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 1.5rem;
}

.dw-cookie-toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  width: 2.5rem;
  height: 1.375rem;
  border-radius: 9999px;
  background: #d1d5db;
  border: none;
  padding: 0;
  cursor: pointer;
  flex-shrink: 0;
  transition: background-color 0.2s ease;
}
.dw-cookie-toggle[aria-checked="true"] {
  background: #00af9d;
}
.dw-cookie-toggle-locked {
  background: #00af9d;
  cursor: not-allowed;
}
.dw-cookie-toggle-knob {
  position: absolute;
  top: 0.1875rem;
  left: 0.1875rem;
  width: 1rem;
  height: 1rem;
  border-radius: 9999px;
  background: #fff;
  transition: transform 0.2s ease;
}
.dw-cookie-toggle[aria-checked="true"] .dw-cookie-toggle-knob,
.dw-cookie-toggle-locked .dw-cookie-toggle-knob {
  transform: translateX(1.125rem);
}

@media (max-width: 640px) {
  .dw-cookie-banner {
    left: 0.5rem;
    right: 0.5rem;
    bottom: 0.5rem;
    padding: 1rem;
  }
  .dw-cookie-banner-actions {
    flex-direction: column;
  }
  .dw-cookie-banner-actions .dw-cookie-btn {
    width: 100%;
  }
}

/* Partner dialog (header.php's #dw-partner-dialog): rebuilt to match
   live's actual rendered sizing (confirmed via a real click on live's own
   popup, not just guessed from source), which needs a couple of arbitrary
   values this purged build never picked up. */
.max-h-full {
  max-height: 100%;
}
@media (min-width: 768px) {
  .md\:w-\[90vw\] {
    width: 90vw;
  }
  .dw-partner-dialog-maxh {
    max-height: min(90vh, 700px);
  }
}

/* #dw-partner-dialog is centered via left:50%/top:50% + a translate(-50%,-50%)
   transform (so its own center, not its top-left corner, lands on the
   viewport's center) -- but .dw-video-dialog's shared open/close animation
   also sets `transform` (scale(.95) -> scale(1)), and since that's a single
   CSS property, whichever rule wins controls the WHOLE value, not just the
   part each author cared about. custom.css loads after the Tailwind build,
   so .dw-video-dialog's scale-only transform silently clobbered the
   centering translate entirely, leaving the dialog's top-left corner (not
   its center) pinned to the viewport's center -- it rendered real, correctly
   sized, and even at the right 1024px width (confirmed earlier), just
   anchored from the wrong point, so it overflowed off the right/bottom edge
   instead of actually centering. Combine both concerns into one
   ID-scoped rule (specific enough to always win) instead of two rules
   fighting over the same property. */
#dw-partner-dialog.dw-video-dialog {
  transform: translate(-50%, -50%) scale(0.95);
}
#dw-partner-dialog.dw-video-dialog.dw-open {
  transform: translate(-50%, -50%) scale(1);
}
/* Same root cause as the #dw-gallery-dialog/archive-grid [hidden] bugs
   elsewhere in this file: the dialog's own `flex` class (needed for its
   live-matching flex-col layout) beats the browser's [hidden]{display:none}
   UA rule at equal-or-higher author-stylesheet specificity, so closing the
   dialog (which only toggles the `hidden` attribute + dw-open class, after
   the fade-out) left it still rendered as display:flex -- invisible
   (opacity 0) but still occupying its full centered, ~1024px-wide layout
   box and intercepting clicks on whatever partner tile happened to sit
   underneath it. */
#dw-partner-dialog[hidden] {
  display: none;
}

/* Resources page (page-templates/page-resources.php) -- a couple of
   arbitrary values this purged build never picked up. */
.min-w-\[220px\] {
  min-width: 220px;
}
.space-y-1\.5 > * + * {
  margin-top: 0.375rem;
}

/* Project pages: photo grids inside the article body keep equal 4:3 tiles,
   matching the live site (the images are cropped to fill, not stretched). */
.prose .not-prose.grid img {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}
