/* Hand-written overrides for this migration — kept OUTSIDE site/public/styles/ (gotcha 49):
 * tools/port-css.mjs owns that directory and clears it on every run.
 *
 * Population, censused 2026-10-02: pages.txt 32 paths, generated/blog.rss 13 items,
 * 96 post-JS captures (32 x 3 bands). The rules below were copied from the fleet model;
 * any figure in a comment further down that is not restated here is an earlier site's.
 *
 * Keep this file minimal. Anything that can come from the ported cascade should.
 */

/* The honeypot. Positioned off-screen rather than display:none — bots skip obviously
 * hidden fields, and taking it out of flow means it costs no layout, which the pixel
 * gate would otherwise measure. Live has NO honeypot on either of this site's two
 * forms, so this is ours and must cost nothing.
 *
 * /migration phase 8 specifies exactly this and one fleet repo shipped the spec
 * unimplemented — its honeypot rendered as an ordinary 40px text field and read as a
 * 46px layout defect. */
.mg-hp {
  position: absolute !important;
  left: -9999px !important;
  top: auto !important;
  width: 1px !important;
  height: 1px !important;
  overflow: hidden !important;
}

/* SPECIFICITY NOTE — read before editing any rule below.
 *
 * Duda emits a per-widget rule for EVERY widget on the site, shaped
 *
 *     #dm .dmBody div.u_1213107879 { display: block !important }
 *
 * That is (1,2,1) and it is `!important`. A hide written as a plain
 * `.mg-only-t { display:none !important }` is (0,1,0), so with `!important` on both
 * sides SPECIFICITY decides and Duda's rule wins — the element stays visible and
 * nothing in the console says so.
 *
 * So every gate below repeats its class three times behind `#dm`, giving (1,3,0),
 * which outranks (1,2,1) on class count without relying on source order. Do not
 * "tidy" the repetition away.
 */

/* ---------------------------------------------------------------------------
 * BLOG PAGINATION. /blog declares 13 posts and shows 9 behind a numbered pager that
 * REPLACES the card set (measured on live, generated/blog-control-live.json). The build
 * ships every card and pages over them locally, so the withheld ones are hidden here.
 * Repeated class behind #dm: Duda's per-widget display:block!important is (1,2,1)
 * (gotcha 70). */
#dm .mg-blog-hidden.mg-blog-hidden.mg-blog-hidden {
  display: none !important;
}

/* display:none DOES NOT CHANGE CHILD INDICES (gotcha 69): with hidden cards after it,
 * the last VISIBLE card stops being :last-child and gains Duda's
 * `.postArticle:not(:last-child)` bottom padding. This restores live's spacing. */
#dm .postArticle:not(.mg-blog-hidden):has(+ .postArticle.mg-blog-hidden) {
  padding-bottom: 0 !important;
}

/* ---------------------------------------------------------------------------
 * PER-DEVICE WIDGET FORKS. This site serves three different documents (d==t on 0 of 32,
 * d==m on 0 of 32), so widgets that differ per band are emitted once per band and the
 * inactive copies are hidden by Duda's own band edges: phone <= 767, tablet 768-1024,
 * desktop >= 1025. */
@media (max-width: 767px) {
  #dm .mg-only-d.mg-only-d.mg-only-d,
  #dm .mg-only-t.mg-only-t.mg-only-t {
    display: none !important;
  }
}

@media (min-width: 768px) and (max-width: 1024px) {
  #dm .mg-only-d.mg-only-d.mg-only-d,
  #dm .mg-only-m.mg-only-m.mg-only-m {
    display: none !important;
  }
}

@media (min-width: 1025px) {
  #dm .mg-only-t.mg-only-t.mg-only-t,
  #dm .mg-only-m.mg-only-m.mg-only-m {
    display: none !important;
  }
}

/* ---------------------------------------------------------------------------
 * SLIDERS: ssrimageslider and flexslider occur on 0 of 32 pages here, so no rule. */

/* ---------------------------------------------------------------------------
 * ACCORDION OPEN STATE. ssraccordion is on 25 of 32 pages, one widget each; the open
 * state is a styled-components class minted at runtime that no shipped sheet carries,
 * so runtime.js marks the open panel with .mg-acc-open (gotcha 75). */
#dm .mg-acc-open.mg-acc-open.mg-acc-open {
  max-height: 2000px;
}

/* ---- Pre-launch review 2026-09-29 ------------------------------------------ */

/* Legal pages (tools/build-legal-pages.mjs). Duda's reset zeroes margin on p, ul
 * and h2, so the template text would otherwise render as one slab with every
 * heading pressed against the paragraph above it. */
#dm .gy-legal-row {
  max-width: 1200px;
  margin: 0 auto;
  padding: 60px 40px 80px;
  box-sizing: border-box;
}
#dm .gy-legal-row h2 {
  margin: 36px 0 12px;
}
#dm .gy-legal-row p {
  margin: 0 0 14px;
}
#dm .gy-legal-row ul {
  margin: 0 0 14px;
  padding-left: 1.4em;
  list-style: disc;
}
#dm .gy-legal-row li {
  margin: 0 0 4px;
}
@media (max-width: 767px) {
  #dm .gy-legal-row {
    padding: 40px 16px 60px;
  }
}

/* ---------------------------------------------------------------- flex popup --
 * THE TWO HOSTS DUDA'S RUNTIME CREATES FOR A CLICK-TRIGGERED FLEX POPUP (gotcha 105),
 * which runtime.js's flexPopup() creates on a click. They exist only after the click, so
 * no capture holds them and port-css has nothing to port; the <dialog> itself is in the
 * popup page's served markup and its rules come through the ported cascade.
 *
 * Read off a live original with a real hit-tested click (2026-10-01), identical at 1440,
 * 768 and 375:
 *   #flex-popup-overlay            position fixed  z-index 200  rgba(0, 0, 0, 0.533), full viewport
 *   #flex-runtime-popup-container  position fixed  z-index 201  display flex, centred, transparent
 * The dialog's place is CENTRING, not a coordinate. Scroll lock is on BODY. No subject on
 * this site (no trigger in the build): these match nothing here.
 */
#flex-popup-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  background-color: rgba(0, 0, 0, 0.533);
}
#flex-runtime-popup-container {
  position: fixed;
  inset: 0;
  z-index: 201;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: transparent;
}

/* ---- Pre-launch review 2026-10-08 ------------------------------------------ */

/* The 404. Live styles its error block from an inline <style> inside the page body,
 * which the port does not carry, so ours rendered as three unstyled lines pressed
 * against the top-left corner. These are live's own rules, scoped to the block. */
#dm #error-container {
  display: block;
  position: relative;
  width: 100%;
  padding-top: 120px;
  background: #fff;
  color: #bababa;
  text-align: center;
  font-family: 'Source Sans Pro';
  overflow: hidden;
}
#dm #error-container .four-o-four {
  font-family: 'Oswald', sans-serif;
  font-size: 130px;
  text-align: center;
  line-height: 130px;
}
#dm #error-container .lean {
  display: inline-block;
  transform: rotate(15deg) translate(-5px, -4px);
}
#dm #error-container .description {
  font-size: 22px;
  margin: 45px 0;
}
#dm #error-container .back-button {
  display: inline-block;
  width: 184px;
  height: 37px;
  margin-bottom: 20px;
  background: #898989;
  color: #fff;
  text-align: center;
  font-size: 16px;
  line-height: 37px;
  border-radius: 2px;
  box-sizing: border-box;
  text-decoration: none;
  cursor: pointer;
}

/* Blog pager: Duda styles only the active page (the dark pill). The other number and
 * the arrow that can be pressed inherit white onto the page's white, 1.00:1, on live
 * too - the visitor sees a lone "1" and no way to page 2. Body ink for the links that
 * can be pressed; the pill and a disabled arrow keep their own treatment. */
#dm .pagination-nav .pagination-link:not(.active):not(.disabled),
#dm .pagination-nav .pagination-link:not(.active):not(.disabled) span {
  color: rgb(19, 51, 72);
}

/* /blog-search: "Search Results" is the page's <h1> now (it was an <h2> on a page
 * with no <h1>). Pinned to the <h2>'s measured box so the retag moves nothing. */
#dm#dm [id="1523391464"] h1 {
  font-size: 32px !important;
  line-height: normal;
  font-weight: bold;
  margin: 0;
}
@media (min-width: 768px) and (max-width: 1024px) {
  #dm#dm [id="1523391464"] h1,
  #dm#dm [id="1523391464"] h1 span {
    font-size: 40px !important;
  }
}
@media (max-width: 767px) {
  #dm#dm [id="1523391464"] h1 {
    font-size: 26px !important;
  }
}

/* Home page: the McKinney photo slides in from the right as it is scrolled to
 * (runtime.js flexAnimations). While it travels it reaches past the page edge and the
 * whole page gains a sideways scroll - 54px at 1440, 163px at 1100, on live too.
 * Clipped at its own section, which is the full width of the page. */
#dm section[id="5ebd18cb"] {
  overflow-x: clip;
}

/* Blog posts' "Recent Posts" slider: at rest its two arrows sit 50px outside the card
 * (they slide in on hover), and at 1025-1060px wide the right one reaches 2px past the
 * page edge, giving every post a sideways scroll there - on live too. Clipped at the
 * slider's own section; the arrows themselves are untouched. */
#dm section:has(.mainBlog.list_slider) {
  overflow-x: clip;
}

/* The thank-you message that replaces a sent form. */
#dm .dmform-success {
  padding: 12px 0;
}

/* Footer menu drop-downs open UPWARD. They hung below the last line of the footer:
 * hidden, but still part of the page, so every page ended in a 131px blank white strip
 * under the footer, and on hover the list dropped off the bottom of the screen (on live
 * too). The doubled selectors are needed to outrank the cascade's own `top`. */
#dm#dm #flex-footer .unifiednav__item-wrap > .unifiednav__container_sub-nav.unifiednav__container_sub-nav[data-depth="0"] {
  top: auto !important;
  bottom: 100% !important;
}

/* Footer menu sub-menus on touch screens (runtime.js footerSubnav()): closed until the
 * caret is tapped. It has to outrank the cascade's :hover opener, which a tap leaves
 * stuck; an open group shows, whatever :hover currently says. */
#flex-footer#flex-footer li.gy-fsub > .unifiednav__container_sub-nav {
  overflow: hidden;
  transition: max-height .3s ease, opacity .2s ease;
}
#flex-footer#flex-footer li.gy-fsub.gy-sub-closed > .unifiednav__container_sub-nav {
  max-height: 0 !important;
  padding-top: 0 !important;
  padding-bottom: 0 !important;
  margin-top: 0 !important;
  margin-bottom: 0 !important;
  border-width: 0 !important;
  opacity: 0 !important;
  pointer-events: none !important;
  visibility: hidden;
}
#flex-footer#flex-footer li.gy-fsub:not(.gy-sub-closed) > .unifiednav__container_sub-nav {
  max-height: 200em;
  opacity: 1 !important;
  pointer-events: auto !important;
}

/* Menu panel: the close (X) row stays at the top while the panel scrolls. On a phone
 * the panel is taller than the screen once a group is open, and the X scrolled away
 * with the logo. The row takes the panel's own white so the menu passes under it. */
#hamburger-drawer > div:has(.hamburgerButton) {
  position: sticky;
  top: 0;
  z-index: 5;
  background-color: #fff;
}

/* "Recent Posts" slider: the card change cross-fades, as on live (measured ~0.6s). The
 * desktop copy had no transition of its own and snapped from one post to the next. */
#dm .mainBlog.list_slider .postArticle {
  transition: opacity 0.6s ease;
}
