/* Hand-written overrides for this migration.
 *
 * DELIBERATELY OUTSIDE site/public/styles/ (gotcha 49): tools/port-css.mjs owns
 * that directory and clears its own hashed outputs on every run, so a hand-written
 * sheet placed there is deleted by the next port with no error anywhere — on one
 * site that silently removed the sheet that hides the inactive device bands, and
 * all three headers then rendered at every width.
 *
 * 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. */
.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 specificity (1,2,1) and it is `!important`. A hide written as a plain
 * `.mg-only-t { display:none !important }` is (0,1,0), so `!important` on both
 * sides means SPECIFICITY decides and Duda's rule wins — the element stays
 * visible and nothing in the console says so.
 *
 * Measured: with the plain selector, /blog rendered all THREE per-device widget
 * copies at once — 30 cards against live's 10, document height 7640px against
 * live's 3548px, and the gate scored 59.4%.
 *
 * 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 index: THIS SITE DOES HAVE A PAGER, and it withholds most of the posts.
 *
 * MEASURED ON THIS SITE, not carried over — the previous repo's comment described
 * an APPEND-style "Show More" control and a 29-post blog, and BOTH are wrong here.
 * Gotcha 83 warns that the withholding control has at least two shapes and that a
 * tool keyed on one reports a clean run on a site using the other.
 *
 * Live's /blog declares data-paginate-total-elements="16" and visible-items="10",
 * and renders exactly 10 distinct data-blog-post-alias values. The control is a
 * NUMBERED PAGER — nav.pagination-nav with <a data-page="N" data-action="paginate">
 * — which REPLACES the card set on each click rather than appending, so the cards
 * are collected as a UNION across pages. There is no .more-posts-text-container and
 * no .morePosts anywhere on this site.
 *
 * blog.rss independently declares 16 items, and the recovered index matched it
 * exactly: 16 cards, 0 missing, 0 extra, on all three bands.
 *
 * SEVENTEEN pages withhold cards, not one. Each of the 16 blog POSTS carries the
 * same widget declaring 15 (every post except itself) and renders 10. A static
 * build has no Duda backend, so every card ships and the extras are stamped
 * mg-blog-hidden with data-mg-blog-page in live's own batch size; runtime.js
 * reveals them a batch at a time. This rule is what hides them initially. */
#dm .mg-blog-hidden.mg-blog-hidden.mg-blog-hidden {
  display: none !important;
}

/* display:none DOES NOT CHANGE CHILD INDICES, so shipping the withheld cards
 * silently moves which card is :last-child.
 *
 * MEASURED ON THIS SITE at 1440 on /blog: live's 10th card IS :last-child, takes
 * padding-bottom 0 and measures 317px. Ours is followed by the 6 withheld cards, so
 * it stops matching :last-child, KEEPS 30px and measures 347px — a constant +30px at
 * every width with dTop 0, which is gotcha 69's one-shared-element signature. It cost
 * 4.500% / 2.592% / 2.545% at 375 / 768 / 1440.
 *
 * THE RULE THAT HAS TO BE BEATEN, read out of the ported cascade rather than assumed:
 *
 *   #dm [blog-posts-feature-flag=true][list-layout=recent_posts][posts-padding="15"]
 *       .postArticle:not(:last-child) { padding-bottom: 30px }
 *
 * SPECIFICITY IS THE WHOLE PROBLEM AND THE INHERITED COMMENT HAD IT WRONG. That
 * comment asserted Duda's rule was (0,2,1) and this one (0,4,1), so a plain rule
 * would "win on merit". Duda's actual rule here is ONE ID PLUS THREE ATTRIBUTE
 * SELECTORS PLUS A CLASS PLUS A PSEUDO-CLASS = (1,5,0). The first version of the
 * rule below was
 *     #dm .postArticle:not(.mg-blog-hidden):has(+ .postArticle.mg-blog-hidden)
 * which is (1,4,0) and LOSES — measured in the browser, the selector matched the
 * right card (`matches: true`) and the computed padding-bottom was still 30px. An
 * override that matches and does not apply is invisible without reading the computed
 * value, which is why this was found by measuring and not by reading.
 *
 * Three attribute selectors beat any number of repeated classes only up to a point:
 * repeating `.postArticle` three times takes this to (1,6,0), which clears (1,5,0)
 * without needing !important — and Duda's rule is not !important, so winning on
 * specificity is the honest fix rather than escalating.
 *
 * Keyed on `:has(+ .mg-blog-hidden)` rather than on the stamped `lastArticle` class,
 * because that tracks the SEQUENCE as batches are revealed instead of pinning the
 * initial state; runtime.js does not have to re-stamp anything as cards appear.
 */
#dm .postArticle.postArticle.postArticle:not(.mg-blog-hidden):has(+ .postArticle.mg-blog-hidden) {
  padding-bottom: 0;
}

/* PER-DEVICE WIDGET FORKS.
 *
 * Duda builds .dmPhotoGallery and .mainBlog client-side and the three device
 * documents genuinely differ, so build-pages.py emits each widget three times and
 * stamps the copies mg-only-d / mg-only-t / mg-only-m. Without these rules ALL
 * THREE render at every width — which is exactly what the first gate run showed:
 * / came back at 77% with a +10458px height delta and /blog at 62% with +10150,
 * both of them simply the same widget painted three times over.
 *
 * The band boundaries are Duda's own, read out of the ported cascade: mobile
 * <=767, tablet 768-1024, desktop >=1025.
 *
 * These hide rather than remove, deliberately — the elements stay in the document
 * so the runtime can still address them, and display:none costs no layout.
 *
 * Only the INACTIVE bands are hidden, inside the media queries. The active band is
 * never touched, so it keeps whatever `display` the ported cascade gives it — an
 * earlier version hid all three and restored one with `display: revert`, which
 * reverts past the author cascade to the UA default and would have replaced the
 * widget's real display value with a plain `block`. */
@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;
  }
}

/* MEDIA-SLIDER FILM ROLE — NO OVERRIDE, and that is the measured answer.
 *
 * An earlier revision added a filmstrip rule here, reasoning from the SERVED html
 * where the film role carries `.gDtRCy` with position:absolute, right:-200%,
 * flex-direction:row and translateX(-0%). That was WRONG, and it is recorded
 * rather than quietly deleted because the reasoning is seductive.
 *
 * The served html is the authority for what the RUNTIME WRITES, but this rule is
 * not something the runtime writes — it belongs to the pre-hydration render. Once
 * the component hydrates it re-renders under a different generated class and the
 * filmstrip rule is simply not applied.
 *
 * MEASURED on live, settled, at 1440:
 *     class="sc-gEvEer jKjUdt"  position:relative  display:block
 *     left:0px  right:0px  transform:none  children:2
 *
 * which is precisely what this build already produced WITHOUT any override. So
 * the correct action here is to add nothing.
 *
 * INHERITED CONTEXT, RETARGETED AGAIN. The paragraph that stood here has now been
 * rewritten on each of several migrations and named pages that did not exist on the
 * site it was describing. None of it was ever a fact about
 * prescottspasandbilliards.com.
 * The general lesson both recorded still holds and is why the block above adds
 * nothing: a slider showing a different photograph than live is usually the CAPTURE
 * landing on a different slide, not a CSS defect, and the remedy is to exclude it
 * from the pixel gate and verify it per element.
 *
 * CENSUSED ON THIS SITE (tools/census-structure.mjs, 123 captures, <style>/<script>
 * stripped first): .flexslider is on 1 of 41 pages — the home page — identically on
 * all three bands. There are ZERO .bgGallerySlide elements on any band, and FOUR
 * photo galleries across 4 pages. That one slider WAS measured before anything was
 * excluded, by watching live for 30s at 1440 with no scrolling: it holds 2 real
 * slides and cross-fades between them every 5s, matching its declared
 * slideshowSpeed:5000. So it IS excluded, and tools/check-slider-motion.mjs is the
 * per-element check that covers what the exclusion removes,
 * and each exclusion is recorded in visual-diff.config.json's hiddenRegions with the
 * measurement behind it — a hidden region gets no pixel coverage at all, so the
 * per-element check is the only coverage it has.
 */

/* ---------------------------------------------------------------------------
 * ACCORDION OPEN STATE — recovering a rule the live CSS read could not see.
 *
 * Duda's FAQ accordion is a styled-component driven by Duda's runtime, which is
 * correctly not ported. The markup and the ported cascade both arrive intact, so
 * the widget PAINTS in its settled state and the pixel gate scores the page
 * 0.000% — while every click is inert. CENSUSED HERE: an accordion (matched on
 * data-grab, not on a class token — styled-components generate their class names,
 * so a class regex finds nothing on these) is present on 26 of 41 pages, identically
 * on all three bands. NOTE a raw count of the data-grab ATTRIBUTE reports 36 per
 * page and 44 on /platinum-spas — gotcha 65 exactly: one widget carries eight
 * different data-grab tokens. The widget count is 1 per page, and 2 on
 * /platinum-spas.
 *
 * The state is a generated class on the panel host, and the two names are NOT
 * hardcoded here for the reason gotcha 75 gives: styled-components mint a fresh
 * instance name per render. What IS measured is the mechanism —
 *
 *     closed: .dygwmn { overflow:hidden; transition:max-height .3s ease-out;
 *                       height:auto; max-height:0px; }
 *
 * — so the transition runs on MAX-HEIGHT, and opening means raising it.
 *
 * THE OPEN RULE IS ABSENT FROM THE PORTED CASCADE, and that is not a porting
 * mistake. styled-components insert their rules through the CSSOM, so a class
 * only exists in a document's sheet if that component actually RENDERED with it.
 * No panel is ever open on a freshly loaded page, so `.gnWefg` — the open class
 * live uses — appears in ZERO of the ported sheets while `.dygwmn` appears in 4.
 * Restoring it is recovering a sheet the live read could not reach, which is the
 * same situation gotcha 46 describes for a slider's resting state, arrived at
 * from the opposite direction.
 *
 * Keyed on our own class rather than Duda's generated one so nothing here depends
 * on a name that changes per render. Repeated behind #dm to clear Duda's own
 * per-widget `!important` display rules (gotcha 70).
 *
 * Lives in gm/, NOT in styles/: port-css cleans its own hashed output from that
 * directory on every run and would take this file with it (gotcha 49).
 * ------------------------------------------------------------------------- */
#dm .mg-acc-open.mg-acc-open.mg-acc-open {
  max-height: 2000px;
}

