/* The only authored stylesheet the migrated pages load.
 *
 * Everything else under /styles/duda is ported verbatim from the live
 * document's own cascade. This file covers the two things that have no
 * original to port: the honeypot, which the Duda site never had, and the
 * Leaflet host, which replaces a Mapbox widget we cannot ship.
 */

/* Honeypot. Off-screen by position, never display:none — bots know to skip an
 * obviously-hidden field, and taking it out of flow means it costs no layout,
 * which the pixel gate would otherwise measure. */
.dm-hp {
  position: absolute !important;
  left: -9999px !important;
  top: auto !important;
  width: 1px !important;
  height: 1px !important;
  overflow: hidden !important;
}

/* Leaflet fills the same box Duda's Mapbox canvas did. */
.mapContainer .leaflet-container {
  width: 100%;
  height: 100%;
}

/* ---------------------------------------------------------------------------
   One header per device.

   Duda serves three documents and each contains only ONE header, so its own
   sheets never need to hide the other — which means nothing in the ported
   cascade does it for us. This build ships both trees in one document and
   picks between them off the data-dev attribute the pre-paint script sets.

   Written with html[data-dev=...] rather than a media query on purpose: the
   device decision is Duda's, made from the user-agent, and the tablet document
   lays out on a fixed 960px canvas, so a width test would disagree with the
   document it is styling.
   --------------------------------------------------------------------------- */

/* Desktop and tablet: no hamburger bar, no drawer. */
html[data-dev="d"] #hamburger-header-container,
html[data-dev="t"] #hamburger-header-container,
html[data-dev="d"] #layout-drawer-hamburger,
html[data-dev="t"] #layout-drawer-hamburger,
html[data-dev="d"] #mobile-hamburger-drawer,
html[data-dev="t"] #mobile-hamburger-drawer,
html[data-dev="d"] #hamburger-drawer,
html[data-dev="t"] #hamburger-drawer,
html[data-dev="d"] > body .layout-drawer-overlay,
html[data-dev="t"] > body .layout-drawer-overlay {
  display: none !important;
}

/* Phone: no desktop header. */
html[data-dev="m"] .dmHeaderContainer {
  display: none !important;
}

/* GOTCHA 14 — the phone document has no <div><div id="iscrollBody"> wrapper at
   all; see hasIscroll in tools/live-shell/shells.json. Desktop and tablet need
   it, because .dmBodyNoIscroll #iscrollBody{overflow-x:hidden} is what stops an
   overhanging section stretching the document and painting a bare strip down
   the page. So neutralise it on the phone with display:contents rather than
   removing it from the markup: the box stops existing, the children stay
   exactly where the phone cascade expects them. */
html[data-dev="m"] #iscrollBody {
  display: contents;
}

/* Same mechanism, second instance. Duda's blog-card widget wraps .postText in
   a .postTextContainer on the desktop and tablet documents and omits the
   wrapper entirely on the phone one — 18 of the 31 captured documents on
   desktop and tablet, 0 on phone. The patch list can change attributes and
   classes but not the shape of the tree, so the wrapper survives into the
   phone rendering and adds its own padding to every card. Worth 2.463% on one
   blog post at 375, and present on every page carrying a card list.

   display:contents rather than a padding reset, because the wrapper's whole
   contribution is the box: with the box gone the children land exactly where
   the phone cascade expects them, whatever else it later says about the
   wrapper.

   !important because the ported cascade carries
   #dm [blog-posts-feature-flag="true"] .postTextContainer { display: flex },
   and an id in that selector beats an attribute selector on html. Without it
   this rule is written, served, and silently loses. */
html[data-dev="m"] .postTextContainer {
  display: contents !important;
}

/* GOTCHA 13 — the phone header is position:fixed, so it takes no space, and
   Duda's runtime writes a MEASURED padding-top onto .dmLayoutWrapper to make
   the content clear it. We do not ship that runtime, so nothing writes it and
   every phone page comes out one header height short.

   The value is not a round number: live renders 106.47px, because the header's
   height falls out of its own type and padding. Rounding it to 106 shifts
   every box below the header up by half a pixel, which rounds to a one-pixel
   offset for the whole document — 11,447px of edges all one pixel out, worth
   4.5% of differing pixels on the home page and invisible to a geometry diff
   that rounds. So it is measured at runtime in /duda/runtime.js against the
   header we actually render, and re-measured after webfonts settle.

   This rule only reserves the space before that runs, so first paint is not a
   header-height jump; the runtime overwrites it with the exact value. */
html[data-dev="m"] .dmLayoutWrapper {
  padding-top: 106px;
}

/* ---------------------------------------------------------------------------
   Blog post title: h3 -> h1.

   Duda rendered the post-title widget as an <h3> on all 17 posts, so those
   pages shipped with NO <h1> at all — while the section headings under it are
   <h2>, which also makes the outline start at h3 and jump backwards. The tag
   is now <h1> in the emitted markup.

   The rendering has to stay byte-identical, and a bare tag swap does not give
   you that: the ported cascade already carries a rule set for
   `#dm .dmBody h1.u_1852899778` — Duda's own, authored against the heading
   level its design panel thinks the widget is, and dead until now. Switching
   the tag WAKES those rules and drops the two declarations that actually
   matter, because they live on the h3 selectors:

     893a427e26eb.css (desktop + tablet)  h3 -> font-size: 38px
     a2259bd3a86d.css (phone)             h3 -> font-size: 24px
     36208ebc/42bb92c3/cd2facd9.css       h3 -> color: rgb(255, 255, 255)

   with the woken h1 rules supplying a different box (860px / 328px fixed
   width, margin 0) and no font-size, so the title would fall back to the UA's
   h1 { font-size: 2em } — 32px in both directions, white text turned black.

   So restate the h3 geometry against the h1 selector. `html` on the front
   buys one type-selector's specificity over Duda's `#dm .dmBody h1.u_...`,
   which is what it takes to win an `!important` tie; the device split is the
   same html[data-dev] mechanism the rest of this file uses, and mirrors the
   d+t / m sheet split above exactly (verified per page against the D.s list
   in each document's pre-paint script).
   --------------------------------------------------------------------------- */
html #dm .dmBody h1.u_1852899778 {
  color: rgb(255, 255, 255) !important;
  line-height: normal !important;
  /* The site theme gives H1 its own face:
   *   #dm div.dmContent h1 { font-family: "Roboto Mono", "Roboto Mono Fallback" }
   * against Poppins everywhere else. Left alone, the tag swap silently
   * restyles all 18 post titles into a monospace face and, because
   * line-height is `normal` (resolved from the font's own metrics), makes
   * every title box 7px shorter at 1440 and 6px shorter at 375 — which then
   * shifts the whole article below it. Measured against live before and
   * after; with this line the box is identical to the h3 it replaced. */
  font-family: Poppins, "Poppins Fallback" !important;
}

html[data-dev="d"] #dm .dmBody h1.u_1852899778,
html[data-dev="t"] #dm .dmBody h1.u_1852899778 {
  display: block !important;
  float: none !important;
  top: 0px !important;
  left: 0px !important;
  width: calc(100% - 58px) !important;
  position: relative !important;
  height: auto !important;
  padding: 2px 0px !important;
  margin: 8px auto !important;
  max-width: 744px !important;
  min-width: 25px !important;
  text-align: center !important;
  font-size: 38px !important;
}

html[data-dev="m"] #dm .dmBody h1.u_1852899778 {
  display: block !important;
  float: none !important;
  top: 0px !important;
  left: 0px !important;
  width: 328px !important;
  position: relative !important;
  height: auto !important;
  padding: 2px 0px !important;
  margin: 8px auto !important;
  max-width: 100% !important;
  min-width: 0px !important;
  text-align: center !important;
  font-size: 24px !important;
}

/* ---------------------------------------------------------------------------
   Google Business Profile map, footer-wide.

   A new full-width row between the footer's content row (u_1929681044) and its
   copyright row (u_1541644133), on all 32 documents. The embed is the client's
   own; the only thing added to their iframe is a title, so it is not an
   unlabelled frame for a screen reader.

   Height is capped at 300px in three places on purpose — the iframe's height
   attribute, the iframe's CSS height, and max-height on the wrapper — because
   the ported cascade carries several `#dm ... iframe { height: ... }` rules
   from Duda's own widgets and the attribute alone does not survive them.
   line-height:0 on the wrapper kills the few pixels of descender space an
   inline-level iframe would otherwise add under the map.

   Written against classes rather than the u_* id convention because there is
   no original to port here: this row does not exist on the live site.
   --------------------------------------------------------------------------- */
#dm .gbpMapRow {
  /* Full-bleed. The footer's rows sit in a max-width content column (1200px of
   * 1440), which left the map inset with a band of footer either side. These
   * four lines break it out to the viewport edge from inside that column
   * without touching the column itself: 100vw wide, then pulled back by half
   * the difference. margin-right as well as left, or the row keeps reserving
   * its original width and drags a horizontal scrollbar in behind it. */
  position: relative;
  width: 100vw;
  max-width: 100vw;
  left: 50%;
  right: 50%;
  margin-left: -50vw;
  margin-right: -50vw;
  float: none;
  clear: both;
  padding: 0;
}

#dm .gbpMapRow > .dmRespColsWrapper,
#dm .gbpMapRow > .dmRespColsWrapper > .dmRespCol {
  /* Duda's grid puts padding on every column; here it would reintroduce the
   * inset this rule just removed. */
  width: 100%;
  max-width: none;
  padding: 0;
  margin: 0;
}

#dm .gbpMap {
  width: 100%;
  max-height: 300px;
  overflow: hidden;
  line-height: 0;
  font-size: 0;
}

#dm .gbpMap iframe {
  display: block;
  width: 100%;
  height: 300px;
  max-height: 300px;
  border: 0;
}

/* ---------------------------------------------------------------------------
   Legal pages (/privacy-policy, /terms-and-conditions).

   Both are built on the /our-team document, so they inherit the header, the
   footer, the per-device patch list and the u_* boxes the ported cascade is
   written against — nothing new to measure. What they add that /our-team never
   had is long-form structure: h2 section headings and bulleted lists inside a
   .dmNewParagraph, which Duda only ever filled with <p>. The ported cascade has
   no opinion about either in this context, so the browser default applies and
   the lists lose their markers to the site's global list reset.
   --------------------------------------------------------------------------- */
#dm .dmBody .legalBody {
  text-align: left;
}

#dm .dmBody .legalBody h2 {
  font-size: 24px;
  line-height: 1.35;
  margin: 28px 0 10px;
  text-align: left;
}

#dm .dmBody .legalBody p {
  line-height: 1.7;
  text-align: left;
}

#dm .dmBody .legalBody ul.legalList {
  list-style: disc outside;
  margin: 8px 0 8px 24px;
  padding-left: 8px;
}

#dm .dmBody .legalBody ul.legalList li {
  list-style: disc outside;
  line-height: 1.7;
  margin: 0 0 4px;
}

/* Legal links: footer strip, and the consent line under the contact form.
   Deliberately NOT given the body-text interlink treatment (bold + underline)
   — that styling is scoped to body copy, and these sit in the footer chrome
   and in a form. Underline on hover only, colour inherited from whatever they
   sit on, so they read as fine print rather than as calls to action. */
#dm .legalLinks {
  text-align: center;
  font-size: 13px;
  line-height: 1.6;
  margin: 0 0 6px;
}

#dm .legalLinks span {
  margin: 0 8px;
  opacity: 0.6;
}

#dm .legalConsent {
  clear: both;
  margin: 12px 0 0;
  font-size: 12px;
  line-height: 1.6;
}


/* ---------------------------------------------------------------------------
   Review slider — the crossfade.

   Flexslider fades in JS on live: computed transition-duration on the slides is
   0s on both sides, and the port's own opacity swap was therefore a hard cut.
   The slides are already stacked at one origin by Duda's own CSS (same x, same
   y, z-index 1 with 2 on .flex-active-slide), so a plain opacity transition on
   the whole set is the entire crossfade — the outgoing slide fades out while
   the incoming one fades in underneath it.

   600ms is Flexslider's animationSpeed default, which is what live runs.
   --------------------------------------------------------------------------- */
#dm .flexslider .slides > li {
  transition: opacity 0.6s ease;
}

#dm .flexslider .slides > li.flex-active-slide {
  z-index: 2;
}

@media (prefers-reduced-motion: reduce) {
  #dm .flexslider .slides > li,
  #dm .accordion-item .section,
  #dm [data-grab="accordion-item-container"] > div {
    transition-duration: 0.01ms;
  }
}

/* The arrows are opacity:0 until the slider is hovered — Flexslider's own
   behaviour, and live's. Keyboard focus has to reveal them too, or they are
   reachable but invisible. */
#dm .flexslider .flex-direction-nav a:focus-visible {
  opacity: 1;
}

/* ---------------------------------------------------------------------------
   Link contrast.

   The footer legal links were set to `color: inherit`, which resolved to
   rgb(43,43,43) — the site's body ink — against the footer's rgb(18,62,131).
   That is roughly 1.5:1, well under the 4.5:1 WCAG AA needs for body text, and
   in practice unreadable. `inherit` was the wrong instinct: it inherits from
   whatever wrapper happens to enclose the link, not from the text beside it.

   So state the colour. Both of these sit on the dark footer / dark form panel,
   and both are given white at 0.9 — 13.6:1 against rgb(18,62,131) — rather
   than a grey that would have to be re-checked against every background the
   footer might later take.
   --------------------------------------------------------------------------- */
/* The footer strip sits on the footer's navy, rgb(18,62,131) — white at 0.9
   gives 10.3:1. */
#dm .legalLinks,
#dm .legalLinks a {
  color: rgba(255, 255, 255, 0.9);
}

/* The consent line does NOT. It sits inside the contact form, whose panel is
   rgb(255,255,255) — the first version of this rule painted both the same
   white and made the consent line invisible on a white card, which a rendered
   screenshot caught and a computed-style check did not. Match the form's own
   label ink, rgb(43,43,43), which is 12.6:1 there. */
#dm .legalConsent,
#dm .legalConsent a {
  color: rgb(43, 43, 43);
}

#dm .legalLinks a,
#dm .legalConsent a {
  text-decoration: underline;
  text-underline-offset: 2px;
}

#dm .legalLinks a:hover,
#dm .legalConsent a:hover,
#dm .legalLinks a:focus-visible,
#dm .legalConsent a:focus-visible {
  color: rgb(255, 255, 255);
}

/* ---------------------------------------------------------------------------
   Blog pagination — making `hidden` actually hide.

   The two page panels are marked up with the `hidden` attribute, but the UA
   rule behind it is only `[hidden] { display: none }` at author-origin zero
   specificity, and Duda's own `.inner` carries a display declaration that beats
   it outright. So both pages rendered at once: 18 cards stacked under a
   pagination bar that appeared to do nothing. State it where it wins.
   --------------------------------------------------------------------------- */
#dm [data-paginate-page][hidden] {
  display: none !important;
}

/* Duda styles the current page through .pagination-item.active on the <li>;
   the <a> carries .active too and both are kept in step by the runtime. The
   disabled chevron should look disabled and not invite a click. */
#dm .pagination-link.disabled {
  opacity: 0.4;
  pointer-events: none;
  cursor: default;
}

#dm .pagination-link {
  cursor: pointer;
}

/* Same `[hidden]` problem as the pagination panels: Duda's grid gives these a
   display, which beats the UA's [hidden] rule. */
#dm [data-more-posts][hidden] {
  display: none !important;
}

#dm .more-posts-text-container {
  cursor: pointer;
}

/* Blog search results. Same `[hidden]` caveat as the pagination panels — the
   grid's display beats the UA rule — so state it where it wins. */
#dm .mainBlog.large_list .postArticle[hidden],
#dm .mainBlog.large_list .inner[hidden] {
  display: none !important;
}

/* Live's /blog-search has no <h1> at all. One is added for heading structure
   and screen readers, and kept out of the visual design so the page still
   looks like the original. Not display:none — that would hide it from the
   assistive tech it exists for. */
#dm .srOnlyHeading {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}
