/* 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'S INDEX IS /news, not /blog (/blog 404s on live). It
 * serves 10 of 35 posts (data-paginate-total-elements="35", visible-items="10")
 * and pages the rest from Duda's backend, which we do not have. All 35 ship;
 * runtime.js shows one page of 10 at a time. The 35 is asserted against
 * blog.rss, an INDEPENDENT source, so a short capture fails rather than
 * silently shipping a truncated index. */
#dm .mg-blog-hidden.mg-blog-hidden.mg-blog-hidden {
  display: none !important;
}

/* THE LAST VISIBLE CARD MUST LOSE ITS BOTTOM PADDING, as live's last card does.
 *
 * Duda zeroes it with :not(:last-child). Shipping all 35 posts means the 25 not
 * yet revealed sit AFTER the visible ten, so the tenth card is no longer the
 * last child and keeps its 30px -- display:none does not change child indices.
 *
 * Measured on /news at 1440: cards 0-8 matched live to the pixel and card 9 was
 * 311.59px against live's 281.59px. Exactly 30px, on one card, which was the
 * whole of that page's +30 height delta and 2.4-2.8% of its pixels.
 *
 * The override REUSES DUDA'S OWN SELECTOR PREFIX, found with
 * tools/probe-padding-rule.mjs:
 *
 *   #dm [blog-posts-feature-flag="true"][list-layout="recent_posts"][posts-padding="15"]
 *       .postArticle:not(:last-child) { padding-bottom: 30px }
 *
 * A generic "#dm .postArticle.postArticle.postArticle..." was tried first and
 * lost -- three attribute selectors outrank repeated classes -- and the gate came
 * back BIT-IDENTICAL, which was the only sign the rule had done nothing.
 *
 * :has(+ ...) picks the visible card immediately followed by a hidden one, i.e.
 * the last visible card at any point in the reveal sequence. Once everything is
 * revealed nothing matches and Duda's own :last-child rule takes over again, so
 * this tracks live through the whole Show More sequence rather than pinning the
 * initial state. */
#dm [blog-posts-feature-flag="true"][list-layout="recent_posts"][posts-padding="15"] .postArticle:not(.mg-blog-hidden):has(+ .postArticle.mg-blog-hidden) {
  padding-bottom: 0 !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, and on THIS site they were confirmed
 * against live rather than inherited: tools/probe-header-bands.mjs measured the
 * hamburger header painting at 768/1023/1024 and .dmHeaderContainer taking over
 * at exactly 1025, so mobile <=767, tablet 768-1024, desktop >=1025.
 *
 * NOTE this site serves only TWO documents — the desktop document covers the
 * desktop AND tablet bands, the phone gets its own. So the d and t copies of a
 * forked widget are usually identical; they are still emitted separately because
 * the band gating is what decides which paints, and collapsing them would couple
 * this file to an equality that holds today and need not hold tomorrow.
 *
 * 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;
  }
}

/* PRE-DRIVER HERO: SHOW ONE FINISHED SLIDE, NOT A COLUMN OF FIVE.
 *
 * tools/flexslider_state.py strips FlexSlider's frozen runtime state and seeds
 * `flex-active-slide` + `.slide-inner.animated` on the first slide, so the hero
 * reads as a finished static hero before site/public/scripts/runtime.js runs.
 * That leaves ONE thing the markup cannot express without shipping geometry:
 * the other four slides must not paint.
 *
 * WITHOUT THIS RULE ALL FIVE PAINT STACKED. The strip's own docstring used to
 * claim `.flexslider .slides > li{display:none}` in the ported cascade kept them
 * hidden. It does not — Duda's
 *   .flexslider.ed-version:not([layout]) .slides > li[layout="center"]
 * overrides it with `display:flex !important` at (0,5,2). Measured on the
 * deployed site with only runtime.js blocked: 5 slides, 1440x720 each, a 3600px
 * column pushing the rest of the page down.
 *
 * SPECIFICITY (read the note at the top of this file first): beating an
 * !important (0,5,2) needs an id, so this is anchored on #dm rather than on
 * repeated classes. Repetition alone would not have been enough here.
 *
 * THE HANDOFF NEEDS NO COOPERATION FROM THE DRIVER. init() sets data-mg-flex="1"
 * as its very first statement, before it reads or writes anything else, so
 * :not([data-mg-flex]) stops matching the instant the driver engages and every
 * slide is governed by the driver's own inline layout from then on. The two
 * never both apply, and neither has to know about the other.
 *
 * :has() IS LOAD-BEARING AND ITS FAILURE MODE IS THE SAFE ONE. It restricts the
 * rule to sliders that were actually seeded. A root the builder did not seed has
 * no .flex-active-slide, so :not(.flex-active-slide) would match EVERY slide and
 * hide the hero completely — strictly worse than the stacking it replaces. In a
 * browser with no :has() support the whole rule is dropped and the pre-driver
 * state falls back to that stacking, which is today's behaviour, not a new one.
 * The .postArticle rule above already depends on :has(), so this adds no new
 * requirement. */
#dm .flexslider:not([data-mg-flex]) .slides:has(> li.flex-active-slide) > li:not(.flex-active-slide) {
  display: none !important;
}
