/* 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 live: /blog declares data-paginate-total-elements="29" and
 * visible-items="10", and renders exactly 10 distinct data-blog-post-alias values.
 * The control is an APPEND-style <a class="more-posts-text-container"> ("Show
 * More"), not a numbered nav — driving it goes 10 -> 20 -> 29, after which the
 * control removes itself. blog.rss independently declares 29 items.
 *
 * A static build has no Duda backend, so all 26 cards ship 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, so unlike the port it came from it is NOT a no-op here. */
#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.
 *
 * Duda's own rule is `.postArticle:not(:last-child){padding-bottom:Npx}` — this
 * cascade carries it at 100px, 20px and 10px for the three bands. On live the
 * 10th card IS the last child and takes none of it. In our build the 10th card is
 * followed by 19 hidden siblings, so it stops matching :last-child and GAINS that
 * padding, pushing the control and the whole footer down by a constant amount at
 * every width — the signature of one shared element rather than a per-page fault.
 *
 * Keyed on `:has(+ .mg-blog-hidden)` rather than on a stamped 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.
 *
 * Specificity: Duda's rule is (0,2,1) and not !important, so this (0,4,1) plain
 * rule wins on merit without needing one. */
#dm .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 TWICE NOW. The paragraph that stood here described
 * a slider on a client two migrations back, and the retarget before this one
 * replaced it with a claim about cristosgaragedoors' /reviews page — a page this
 * site does not have. Neither was ever a fact about insulationspecialistusa.net.
 * 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, 159 captures, <style>/<script>
 * stripped first): .flexslider is on 24 of 53 pages, identically on all three bands.
 * There is also exactly ONE .bgGallerySlide, on a single page, and photo galleries
 * on 2. Whether any of them auto-advances is measured BEFORE anything is excluded,
 * 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 30 of 53 pages, identically
 * on all three bands.
 *
 * 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).
 * ------------------------------------------------------------------------- */
/* 2000px is the NO-JS FALLBACK ONLY. runtime.js writes the panel's own measured
 * scrollHeight into an inline max-height on open (live writes 57px on a 57px panel),
 * and the inline value overrides this rule. Left here so a panel that somehow gets
 * the class without the runtime still opens rather than staying shut; a fixed value
 * this far above the real panel height (9-35x on this site) finishes the 0.3s
 * transition in ~8ms, which is a snap, not an animation. */
#dm .mg-acc-open.mg-acc-open.mg-acc-open {
  max-height: 2000px;
}

/* ---------------------------------------------------------------------------
   NBC video embed — reproduce the MECHANISM, not the captured number (gotcha 73).

   nbcbayarea's own script sizes this iframe to a fixed 16:9 of its container, and
   it writes the result into the height ATTRIBUTE. Measured on live, all three bands:

       band   height attr   implied container width (h * 16/9)
       d      540           960.00
       t      387           688.00
       m      188.4375      335.00

   all three exact. Our fork is TWO-WAY, so the desktop document also serves the
   768 band — and it carries the DESKTOP capture's 540. Live's runtime re-sizes it
   to 387 at that width; our static markup cannot, so the tablet band rendered the
   video 153px too tall and every element below it moved, scoring 34.975% on
   /about-us/as-seen-on-nbc @768 while 375 and 1440 were 0.199% and 0.005%.

   Hardcoding 387 for the tablet band would be a NEWER frozen value, which is what
   gotcha 73 warns against. The ratio is the actual rule, so it is width-driven and
   correct at every viewport, including between the band edges.
   --------------------------------------------------------------------------- */
iframe[id^="nbcLMP"] {
  aspect-ratio: 16 / 9;
  height: auto !important;
}

/* ---------------------------------------------------------------------------
   TABLET HEADER CTA GROUP — uniform grid instead of a staggered pile.

   REVIEW REQUEST, and a deliberate DEPARTURE FROM LIVE. The port reproduces live
   here exactly — measured button-for-button at 768 and 820, same widths, heights,
   offsets and padding — so this is not a porting defect being corrected; it is the
   original's own tablet layout being tidied because the client asked.

   What live does at 768: five CTAs share a 425px area split into three 142px
   columns holding 1, 2 and 2 buttons. Nothing lines up —

       Pro Shop                   142x96  @(253, 64)
       Book Free Trial            142x96  @(394, 22)
       Basketball Scholars League 142x74  @(394,128)
       Request Info               142x60  @(536, 40)
       Basketball Training        134x74  @(544,110)

   three different heights, five different vertical offsets, and every label wrapped
   because 142px cannot hold it.

   The columns become `display: contents` so the five buttons are grid items in one
   2-column grid: ~207px each, which is wide enough that the long labels wrap to a
   predictable two lines, with a shared min-height so every button is the same size.
   The last one spans the full width rather than leaving a hole in the final row.

   Scoped to the tablet media query the port already uses for this band, so the
   desktop and mobile headers are untouched.
   ------------------------------------------------------------------------- */
@media (min-width: 768px) and (max-width: 1024px) {
  /* Every button carries its own captured size at (1,2,1):
   *   #dm .p_hfcontainer a.u_1187869429 { width: 187.07px !important; ... }
   * so a rule at #dm [id=...] .dmButtonLink (1,2,0) loses even with !important, and
   * the first attempt at this left the widths exactly as they were. These selectors
   * sit at (1,3,1) to clear that, and `grid-auto-rows: 1fr` equalises the rows so
   * the captured per-button min-heights cannot reintroduce three different heights. */
  #dm .p_hfcontainer [id="1069986610"] {
    display: grid !important;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-auto-rows: 1fr;
    gap: 10px;
    align-items: stretch;
    padding: 6px 0;
  }

  #dm .p_hfcontainer [id="1069986610"] > .dmRespCol {
    display: contents !important;
  }

  #dm .p_hfcontainer [id="1069986610"] a.dmButtonLink {
    width: 100% !important;
    min-width: 0 !important;
    max-width: none !important;
    height: auto !important;
    min-height: 60px !important;
    margin: 0 !important;
    padding: 8px 10px !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    text-align: center !important;
    line-height: 1.2 !important;
    box-sizing: border-box !important;
    float: none !important;
    position: relative !important;
  }

  /* Odd count: let the final CTA run the full width instead of stranding it. */
  #dm .p_hfcontainer [id="1069986610"] > .dmRespCol:last-child a.dmButtonLink:last-child {
    grid-column: 1 / -1;
  }

  /* Captured type is 20px on three buttons and 14px on the two long ones, which is
     the other half of why the group looked unrelated. One size for all five. */
  #dm .p_hfcontainer [id="1069986610"] a.dmButtonLink .text,
  #dm .p_hfcontainer [id="1069986610"] a.dmButtonLink .text * {
    white-space: normal !important;
    font-size: 16px !important;
    line-height: 1.2 !important;
  }

  /* Pro Shop's cart glyph is absolutely placed with a 50px left inset to suit the
     original's narrow column; that inset is wrong once the box is 207px wide. */
  #dm .p_hfcontainer [id="1069986610"] a.dmButtonLink .iconBg {
    position: static !important;
    margin-right: 8px !important;
  }
}

/* ---------------------------------------------------------------------------
   MOBILE HEADER CTA GROUP — centre on any width, and align the odd one out.

   All four CTAs live in one full-width column (#1644505790) but carry HARD-CODED
   side margins baked in at the 375px capture width, and the fourth's differs from
   the other three:

       Book Free Trial                 margin: 0    67px
       Request Info                    margin: 3px  67px 0
       Basketball Scholars League      margin: 3px  67px 0
       Basketball Training Membership  margin: 3px  46.5625px 0     <- 20px adrift

   At exactly 375px those numbers happen to centre the first three, which is why
   this reads as fine on one device and crooked on every other. Measured left edges:

       viewport   first three    fourth
       360        40             47
       375        48             47
       414        67             47

   `auto` margins centre all four at any width and cost nothing at 375, and the
   width cap keeps them inside the screen below 320px.
   ------------------------------------------------------------------------- */
@media (max-width: 767px) {
  /* Scoped through .dmBody, not .p_hfcontainer: the captured rule that has to be
   * cleared is `#dm .dmBody a.u_1894553101 { margin: 3px 46.5625px 0 !important }`
   * at (1,2,1), and .p_hfcontainer is not an ancestor of these buttons in the mobile
   * band — a selector built on it matched nothing and the fourth button stayed put. */
  #dm .dmBody [id="1644505790"] a.dmButtonLink {
    margin-left: auto !important;
    margin-right: auto !important;
    width: 280px !important;
    max-width: calc(100% - 40px) !important;
    box-sizing: border-box !important;
    float: none !important;
  }
}

/* ---------------------------------------------------------------------------
   HOME PAGE FAQ — 20px of breathing room above the section.

   Requested. The FAQ row (u_1321286526, the "Frequently Asked Questions" heading
   plus its accordion) sat flush against what precedes it: the ported cascade zeroes
   it out with

       #dm .dmBody div.u_1321286526 { margin: 0 !important; padding: 0 !important }

   at (1,2,1), so this selector adds .u_dmStyle_template_home to reach (1,3,1) and
   clear it. That class is on the home page's own body wrapper, which also keeps the
   rule from reaching anything else — though the row id is unique to index.html in
   any case. All three bands, since the gap is missing in all three.
   ------------------------------------------------------------------------- */
#dm .dmBody.u_dmStyle_template_home div.u_1321286526 {
  padding-top: 20px !important;
}
