/* ──────────────────────────────────────────────────────────────────────
 * Mobile-first full-bleed contract.
 *
 * Every section that hosts cards / carousels / form panels / maps opts
 * into this contract by emitting `data-mobile-full-bleed="true"` on its
 * root <section> (the default — the renderer flips it to `"false"` when
 * the author unchecks the inspector toggle).
 *
 * Bug fix 2026-05-13 — RADIUS-STRIP REMOVED UNIVERSALLY.
 * Previously, this contract did THREE things at ≤768px:
 *   (a) bled the section background to the viewport edges
 *   (b) zero'd `padding-inline` on the section's inner gutter so cards
 *       could reach the edge
 *   (c) stripped `border-radius` (+ left/right borders) from every inner
 *       card / panel container in a long, opt-in selector list
 *
 * (a) and (b) are legitimate — they're what "full-bleed section" means.
 * (c) was an over-reach: feature-cards, cta-band panels, pricing rows,
 * stats cards, intent-router cards, contact-section form-wraps,
 * timeline events, and gallery items ALL lost their visual framing on
 * phones. The whole site read flat-stack-of-rectangles instead of a
 * deliberately framed UI. The radius/border IS the card's identity;
 * stripping it is a parasitic regression.
 *
 * The fix removed:
 *   - `[data-mobile-full-bleed="true"] { border-radius: 0 }` (outer
 *     section — fine if the section had no radius, but parasitic if it
 *     was a framed card itself)
 *   - The fallback radius-zero block on every inner card class
 *     (`.el-feature-cards__card`, `.el-testimonials__card`, etc.)
 *   - The smart-corner runtime CSS that flattened `.is-flat-left/right`
 *     edges. The JS runtime in `MobileFullBleedCorners.tsx` still runs
 *     and toggles those classes, but they're now no-op markers — kept
 *     for forward compatibility / future opt-in card-bleed mode (if a
 *     widget genuinely wants a flush-to-edge card, it can scope its own
 *     CSS to `.is-flat-left` / `.is-flat-right`).
 *
 * What this file DOES at ≤768px:
 *   1. Pulls the section to the viewport edges (margin-inline goes
 *      negative by the page gutter, width grows by 2× gutter) so its
 *      colored / photographic background paints edge to edge.
 *   2. Zeroes `padding-inline` on the inner content wrappers
 *      (`.el-site-container`, `.el-section__inner`,
 *      `.el-compound-section__inner`) so the section's children land
 *      at the viewport edges if they want to.
 *   3. Carousel-specific tweaks: drops slide padding + clip margin +
 *      track gap so 1-per-view carousels snap flush at every stop.
 *   4. Comparison-table containment: keeps the table inside a readable
 *      column while the surrounding section bg still bleeds.
 *   5. Contact-section panel inset: restores a small horizontal pad on
 *      `__body` so the framed form/info/map panels sit visually inside
 *      the bled section (panels themselves keep their desktop chrome).
 *
 * What this file DOES NOT do (intentional, anti-regression):
 *   - Strip `border-radius` from inner cards / panels.
 *   - Strip `border-left/right` from inner cards / panels.
 *   - Touch any class ending in `__card`, `__panel`, `__form-wrap`,
 *     `__info`, `__item`, `__card-container`, `__plan`, etc.
 *
 * If a renderer genuinely needs an inner panel to bleed flush on phones
 * (rare), it should opt-in with its own scoped CSS — NOT add a class to
 * this contract.
 *
 * Mobile breakpoint = 768px (project-wide; never 1024).
 * ────────────────────────────────────────────────────────────────────── */

@container site style(--site-bp: mobile) {
  /* ── Outer section: bleed background to viewport edges ─────────────── */
  /* Pull the section past the page gutter so any background colour /
     photographic band paints all the way to 0px / 100vw. Pages set
     `--site-page-gutter` in `:root` (er-layout.css); falls back to 0
     so pages without a gutter remain a no-op.
     Both contracts opt in here:
       - `data-mobile-full-bleed="true"`   — bg bleeds + inner cards bleed
       - `data-mobile-bleed-bg-only="true"` — bg bleeds but inner cards
         stay inset at the page gutter (see MOBILE_BLEED_BG_ONLY_FIELD).
     The bg-only contract DELIBERATELY does not appear in any of the
     inner-zero-pad selectors below — that is what keeps cards inset. */
  [data-mobile-full-bleed="true"],
  [data-mobile-bleed-bg-only="true"] {
    margin-inline: calc(var(--site-page-gutter, 0px) * -1) !important;
    width: calc(100% + var(--site-page-gutter, 0px) * 2) !important;
    max-width: none !important;
  }

  /* Universal top-level edge-to-edge: any top-level .el wrapper (hero,
     cta-with-image, page-header, etc.) collapses its inline-axis
     `--el-padding` on phones so the visual band spans viewport edge to
     edge. Block-axis padding is preserved (vertical rhythm intact).
     Authors keep their desktop gutter by setting
     data-mobile-full-bleed="false" on the element. Excluded: navbar,
     footer, loading screen — they ship their own mobile shells.
     NOTE: this kills inline padding only — it does NOT touch
     border-radius. The wrapper's radius (if any) is preserved.
     The `:has(> [data-mobile-full-bleed="false"])` clause is the
     anti-regression fix: most renderers emit the opt-out attribute on
     the INNER section (their JSX root), not on the `.el` wrapper that
     `ElementWrapper` adds. Without :has(), the wrapper-level :not()
     never sees the opt-out and this rule fires anyway, dropping the
     section's padding-inline to 0 — exactly the bug that left HUD-income
     cards bleeding to the viewport edge under 768px viewport widths. */
  .el--top-level:not([data-mobile-full-bleed="false"]):not(:has(> [data-mobile-full-bleed="false"])):not(.el--navbar):not(.el--footer):not(.el--loading) > :not(style) {
    padding-inline: 0 !important;
  }

  /* The compound-section inner wrapper carries `.el-site-container`,
     which clamps width + adds responsive horizontal padding. On mobile
     full-bleed sections we need to drop both so cards can reach the
     edges. The first selector covers the case where the section ITSELF
     is the `.el-site-container` (e.g. ContactSectionRenderer's <section>
     root) — the descendant selector below misses that case.
     `.el-section` and `.el-section__inner` cover the standard
     SectionRenderer path: critical CSS (CriticalCss.tsx) sets
     `.el-section { padding-inline: var(--site-content-gutter, 24px) }`
     and the renderer applies `paddingLeft/Right` inline on `__inner` —
     both must zero out on phones for the section's own children to
     reach the viewport edge. */
  [data-mobile-full-bleed="true"].el-site-container,
  [data-mobile-full-bleed="true"] .el-site-container,
  [data-mobile-full-bleed="true"].el-section,
  [data-mobile-full-bleed="true"] > .el-section__inner,
  [data-mobile-full-bleed="true"] > .el-compound-section__inner,
  [data-mobile-full-bleed="true"] > .el-contact-section__body {
    padding-inline: 0 !important;
    max-width: 100% !important;
  }

  /* Contact-section panels (form-wrap / info / map) are FRAMED CARDS —
     their border + radius IS their visual identity. The outer section
     background still bleeds to viewport edges, but the inner panels
     stay visually inset with a small horizontal pad so they don't
     touch the edge. Authors who want true flush panels can flip
     `mobileFullBleed: false` to drop the entire contract. */
  [data-mobile-full-bleed="true"].el-contact-section > .el-contact-section__body {
    padding-inline: clamp(0.75rem, 4vw, 1.25rem) !important;
  }

  /* ── Carousel: edge-to-edge slide + flush snap ─────────────────────── */
  /* When the section is full-bleed on mobile, the compound-section
     carousel track must:
       · drop the inner-slide padding so the active card's left edge
         sits at viewport-left (no internal gutter peek);
       · drop the frame's clip-margin so adjacent slides don't bleed
         visibly past the active one;
       · keep `flex-basis: 100cqw` from er-compound-section.css so each
         slide IS the frame width (already in place at ≤768px).
     Net: the existing `stepSize = first.offsetWidth + gap` math in
     `useInfiniteCarousel` lands the next card flush at every snap stop.
     NOTE: slide-level `border-radius` is preserved — the inner card
     keeps its rounded corners. */
  [data-mobile-full-bleed="true"] .el-compound-section__carousel-frame {
    overflow-clip-margin-left: 0 !important; overflow-clip-margin-right: 0 !important;
  }
  [data-mobile-full-bleed="true"] .el-compound-section__carousel-slide {
    padding-inline: 0 !important;
  }
  [data-mobile-full-bleed="true"] .el-compound-section__carousel-track {
    /* Eliminate the inter-card gap on full-bleed mobile so a 1-per-view
       carousel snaps card-flush-to-card. */
    gap: 0 !important;
  }

  /* ── Gallery, image-carousel, content-slider list/grid padding ─────── */
  /* When these run in non-carousel modes (gallery grid, image-carousel
     "stack"), zero the list/grid's inline padding so tiles reach the
     edge. Tile `border-radius` is preserved. */
  [data-mobile-full-bleed="true"] .el-gallery__grid,
  [data-mobile-full-bleed="true"] .el-image-carousel__list,
  [data-mobile-full-bleed="true"] .el-content-slider__list {
    padding-inline: 0 !important;
  }

  /* REMOVED 2026-05-13 — `margin-inline: 0` on inner cards caused
     feature-cards, testimonials, timeline-events, and gallery items to
     visually bleed to viewport edges while pricing-cards / intent-cards /
     stats__items (NOT in the list) stayed inset. User reports this as
     an inconsistency: cards should all share the same gutter pattern.
     Removing the rule lets every inner card inherit the grid track
     gutter from its parent compound-section — same as pricing already
     does. The SECTION bg still bleeds (outer wrapper rule above).
     If a tenant genuinely wants cards to touch viewport edges, opt in
     via `[data-mobile-bleed-card="true"]` on the specific card. */

  /* ── Comparison-table mobile containment ───────────────────────────── */
  /* Comparison tables reflow into row cards on mobile, but the
     comparison root is also an `.el-site-container`. The generic
     full-bleed rule above is correct for compound card grids, but it
     makes comparison sections wider than neighboring content cards.
     Keep comparison-table contained inside a readable mobile column
     while the parent section can still paint its background
     edge-to-edge. */
  [data-mobile-full-bleed="true"] .el-comparison.el-site-container {
    width: min(
      var(--el-comparison-mobile-width, calc(100% - clamp(3rem, 12vw, 6rem))),
      var(--el-comparison-max-width, 100%)
    ) !important;
    max-width: var(--el-comparison-max-width, 100%) !important;
    margin-inline: auto !important;
    padding-inline: 0 !important;
  }

  [data-mobile-full-bleed="true"] .el-comparison__heading-wrap,
  [data-mobile-full-bleed="true"] .el-comparison__body-wrap {
    box-sizing: border-box;
    width: 100%;
    padding-inline: clamp(0.75rem, 4vw, 1.25rem);
  }

  [data-mobile-full-bleed="true"] .el-comparison__scroll-wrapper {
    box-sizing: border-box;
    width: min(
      var(--el-comparison-scroll-mobile-width, calc(100% - clamp(1.5rem, 8vw, 2.5rem))),
      100%
    ) !important;
    margin-inline: auto !important;
    padding-inline: 0 !important;
    background: transparent !important;
    border-color: transparent !important;
    box-shadow: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }

  /* ── Smart-corner classes — INTENTIONALLY NO RULES ─────────────────── */
  /* MobileFullBleedCorners.tsx still toggles `is-flat-left` /
     `is-flat-right` / `data-mfb-corners="active"` on cards whose edges
     touch the viewport. We deliberately ship no CSS for those classes
     anymore: the global rule used to flatten the touching corners, but
     that turned out to be the source of the regression — even an
     "outer corner only" flatten makes a glass card with hairline
     borders read as broken at ≤768px. If a future opt-in card-bleed
     mode is needed, scope it inside that widget's own CSS, NOT here.
     Leaving the runtime in place means we can re-enable selective
     behavior later without re-wiring the JS pass. */
}

@media (max-width: 768px) {
  /* Identical contract for browsers without `@container style()`
     support. Keep in sync with the block above. */

  [data-mobile-full-bleed="true"],
  [data-mobile-bleed-bg-only="true"] {
    margin-inline: calc(var(--site-page-gutter, 0px) * -1) !important;
    width: calc(100% + var(--site-page-gutter, 0px) * 2) !important;
    max-width: none !important;
  }

  /* `:not(:has(> [data-mobile-full-bleed="false"]))` mirrors the
     container-query block above — see line 102 for the full reasoning. */
  .el--top-level:not([data-mobile-full-bleed="false"]):not(:has(> [data-mobile-full-bleed="false"])):not(.el--navbar):not(.el--footer):not(.el--loading) > :not(style) {
    padding-inline: 0 !important;
  }

  [data-mobile-full-bleed="true"].el-site-container,
  [data-mobile-full-bleed="true"] .el-site-container,
  [data-mobile-full-bleed="true"].el-section,
  [data-mobile-full-bleed="true"] > .el-section__inner,
  [data-mobile-full-bleed="true"] > .el-compound-section__inner,
  [data-mobile-full-bleed="true"] > .el-contact-section__body {
    padding-inline: 0 !important;
    max-width: 100% !important;
  }

  [data-mobile-full-bleed="true"].el-contact-section > .el-contact-section__body {
    padding-inline: clamp(0.75rem, 4vw, 1.25rem) !important;
  }

  [data-mobile-full-bleed="true"] .el-compound-section__carousel-frame {
    overflow-clip-margin-left: 0 !important; overflow-clip-margin-right: 0 !important;
  }
  [data-mobile-full-bleed="true"] .el-compound-section__carousel-slide {
    padding-inline: 0 !important;
  }
  [data-mobile-full-bleed="true"] .el-compound-section__carousel-track {
    gap: 0 !important;
  }

  [data-mobile-full-bleed="true"] .el-gallery__grid,
  [data-mobile-full-bleed="true"] .el-image-carousel__list,
  [data-mobile-full-bleed="true"] .el-content-slider__list {
    padding-inline: 0 !important;
  }

  [data-mobile-full-bleed="true"] .el-region-portfolio__card-container,
  [data-mobile-full-bleed="true"] .el-feature-cards__card,
  [data-mobile-full-bleed="true"] .el-testimonials__card,
  [data-mobile-full-bleed="true"] .el-timeline-event,
  [data-mobile-full-bleed="true"] .el-gallery__item {
    margin-inline: 0 !important;
  }

  [data-mobile-full-bleed="true"] .el-comparison.el-site-container {
    width: min(
      var(--el-comparison-mobile-width, calc(100% - clamp(3rem, 12vw, 6rem))),
      var(--el-comparison-max-width, 100%)
    ) !important;
    max-width: var(--el-comparison-max-width, 100%) !important;
    margin-inline: auto !important;
    padding-inline: 0 !important;
  }

  [data-mobile-full-bleed="true"] .el-comparison__heading-wrap,
  [data-mobile-full-bleed="true"] .el-comparison__body-wrap {
    box-sizing: border-box;
    width: 100%;
    padding-inline: clamp(0.75rem, 4vw, 1.25rem);
  }

  [data-mobile-full-bleed="true"] .el-comparison__scroll-wrapper {
    box-sizing: border-box;
    width: min(
      var(--el-comparison-scroll-mobile-width, calc(100% - clamp(1.5rem, 8vw, 2.5rem))),
      100%
    ) !important;
    margin-inline: auto !important;
    padding-inline: 0 !important;
    background: transparent !important;
    border-color: transparent !important;
    box-shadow: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }
}
