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


/* ------------------------------------------- why the mg-only rules still exist --
 * band_prune() now REMOVES the non-matching .mg-only-* widget variants rather
 * than leaving them hidden, because HIDING THEM IS NOT ENOUGH: a display:none
 * element is still a sibling for structural selectors, and the ported cascade
 * carries
 *
 *     .dmRespCol > [dmle_extension]:not(:first-child) { margin-top: 10px }
 *
 * Live has ONE widget in that column, so it is :first-child and gets no margin.
 * We emitted three variants, so whichever one was visible at a given band was
 * usually NOT first and picked up a 10px top margin live never has — the exact
 * +10px every blog post was out by at 375.
 *
 * The rules below are kept as the PRE-PAINT state: they hide the wrong variants
 * for the instant between parse and band_prune(), so nothing flashes. Removal is
 * what makes the DOM structurally match live; hiding is only the stopgap.
 */

/* 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: /blog serves 10 of 65 posts and pages the rest from Duda's backend,
 * which we do not have. All 65 ship; runtime.js shows one page of 10 at a time. */
#dm .mg-blog-hidden.mg-blog-hidden.mg-blog-hidden {
  display: none !important;
}

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

/* ---------------------------------------------------- parallax attachment --
 * Duda freezes parallax on touch from its RUNTIME, not from CSS (gotcha 22), so
 * the ported cascade — which carries `background-attachment: fixed !important`
 * at `#dm .dmBody div.u_<id>` specificity — keeps it fixed at every width while
 * the live tablet and phone documents compute `scroll`. Left uncorrected, a
 * full-page capture sizes a fixed background to the whole DOCUMENT instead of
 * the section, rendering a completely different crop of the same photograph.
 *
 * MEASURED per element per width off live (tools/probe-attachment.mjs, 18
 * section observations across /, /furniture-for-rent, /furniture-for-sale,
 * /rent-to-own, /blog):
 *
 *     @1440  fixed   (5 sections)
 *     @768   scroll  (5 sections)
 *     @375   scroll  (5 sections)
 *
 * Not one section computes `fixed` below 1025, so the correct override is a
 * BLANKET rule below the desktop band — gotcha 44's point that a selector scoped
 * to `[class*="dmSectionParall"]` would miss a plain dmRespCol carrying a fixed
 * background. This is keyed on nothing but the media query for that reason.
 *
 * The repeated class raises specificity above `#dm .dmBody div.u_<id>`; a plain
 * `[class*=...]` selector loses to it.
 */
@media (max-width: 1024px) {
  #dm .dmBody div[class],
  #dm .dmBody div[class][class],
  #dm .dmBody div[class][class][class] {
    background-attachment: scroll !important;
  }
}

/* ------------------------------------ the per-device variant sibling margin --
 * THE PROBLEM. build-pages emits three band variants of each forked widget
 * (.dmPhotoGallery, .mainBlog, .imageWidget) stamped mg-only-d/t/m, and hides the
 * two that do not apply. Hiding is correct — REMOVING them at runtime was tried
 * and regressed badly, blanking the related-posts grid entirely — but a
 * display:none element is STILL A SIBLING for structural selectors, and the
 * ported cascade carries
 *
 *     .dmRespCol > [dmle_extension]:not(:first-child) { margin-top: 10px }
 *
 * Live has ONE widget in that column; we have three. Every one of the 29 blog
 * posts was exactly +10px tall at 375 because of this.
 *
 * THE FIX, AND WHY IT IS THIS NARROW. A first attempt zeroed the margin on ANY
 * variant preceded by a variant. That is wrong in the other direction: on /blog
 * the widget genuinely IS a non-first child and live DOES give it 10px, so the
 * blanket rule made /blog 25.690% with a -22px height delta.
 *
 * The group of variants stands in for live's single element, so:
 *   - variant 1 sits exactly where live's element sits and needs NO correction —
 *     :not(:first-child) already evaluates identically for it;
 *   - variants 2 and 3 must simply match variant 1.
 * When variant 1 IS :first-child (margin 0), the later variants must be 0 too.
 * When it is not, they must keep the 10px — so the rule is anchored on
 * `:first-child` and expressed with `+` chains rather than `~`, so it cannot
 * reach a genuinely different widget that follows the group.
 */
#dm .dmRespCol > [dmle_extension][class*="mg-only-"]:first-child + [dmle_extension][class*="mg-only-"],
#dm .dmRespCol > [dmle_extension][class*="mg-only-"]:first-child + [dmle_extension][class*="mg-only-"] + [dmle_extension][class*="mg-only-"] {
  margin-top: 0 !important;
}
