/* === _base.css (generic) === */

/* ============================================================================
 * _base.css — generic overrides applied to EVERY ported WP page.
 *
 * Loaded by `scripts/port/mirror.ts` BEFORE `<slug>.css` so per-slug files
 * can override anything here. Both files are scoped to `.mirror-root` via
 * `lib/css-scope.ts` and copied to `public/extracted/<slug>/` for the
 * mirror layout's `<link rel="stylesheet">` tags.
 *
 * Keep this file generic. Slug-specific tweaks (BEM ids `XX-YYY`, hero
 * sub-classes pinned to a single page, motion.page floating labels)
 * belong in `<slug>.css`. If you find yourself adding a rule keyed off
 * `--23-` or `--7-`, that's a per-slug rule — move it.
 * ========================================================================= */

/* --- Body restoration ----------------------------------------------------
 * Upstream's `.breakdance { ... }` block applies font-family, color, and
 * line-height to <body class="... breakdance">. Phase B.1 (translate.ts)
 * drops the `.breakdance` class entirely (no project meaning), silently
 * stripping these three declarations. Recreate them on <body> directly. */
body {
  background-color: var(--bde-background-color);
  color: var(--bde-body-text-color);
  font-family: var(--bde-body-font-family);
  font-size: var(--bde-body-font-size);
  font-weight: 200;
  line-height: 1.6;
}

/* --- Long-token safety net (Polish orphan NBSPs) -------------------------
 * strip-chrome.ts / bake-orphans.ts glue single-letter words to the word
 * after them with a NBSP (lib/typography/orphans.ts), which creates
 * unbreakable tokens. `maxGlueLength` caps how long those get; this is the
 * belt to that pair of braces — at 320 px a pathological token can still
 * never push the page into horizontal scroll. */
.mirror-root .text,
.mirror-root .rich-text,
.mirror-root .heading,
.mirror-root p,
.mirror-root li,
.mirror-root h1,
.mirror-root h2,
.mirror-root h3,
.mirror-root h4,
.mirror-root h5,
.mirror-root h6 {
  overflow-wrap: break-word;
}

/* Tailwind v4 Preflight resets margins on p / h1-h6 to 0. Upstream relies
 * on the browser's default UA stylesheet (1em top + bottom on <p>) for
 * paragraph spacing inside rich-text blocks. Restore the UA default ONLY
 * inside `.rich-text` to avoid inflating other widgets that use <p> as a
 * structural element (e.g. counter `<p class="bde-simple-counter__number">`). */
.mirror-root .rich-text p { margin-block-start: 1em; margin-block-end: 1em; }

/* --- Font shadowing ------------------------------------------------------
 * The upstream bundle's @font-face URLs point at
 * `https://imprero.com/.../conthrax_*.woff2` which fail to load from
 * localhost (cross-origin). We have the same fonts locally under
 * /fonts/conthrax/. These rules SHADOW the upstream @font-face by
 * declaring the same family name later in the cascade so the browser
 * picks our URL. */
@font-face {
  font-family: 'Conthrax Bold Italic';
  font-style: italic;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/conthrax/conthrax_bold_italic.woff2') format('woff2');
}
@font-face {
  font-family: 'Conthrax SemiBold Italic';
  font-style: italic;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/conthrax/conthrax_semibold_italic.woff2') format('woff2');
}
@font-face {
  font-family: 'Conthrax UltraThin Italic';
  font-style: italic;
  font-weight: 100;
  font-display: swap;
  src: url('/fonts/conthrax/conthrax_extralight_italic.woff2') format('woff2');
}
@font-face {
  font-family: 'Conthrax Italic';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/conthrax/conthrax_regular_italic.woff2') format('woff2');
}

/* --- Diff equalizer (?no-atmosphere=1) -----------------------------------
 * When the flag is on, hide GradientField and flatten body bg so diff
 * capture compares content-only against the upstream equalizer (which
 * forces flat black via diff.ts EQUALIZER_CSS). Selector targets
 * GradientField's existing DOM signature without modifying the component
 * (see components/brand/GradientField.tsx). */
html[data-no-atmosphere="true"] [aria-hidden="true"].pointer-events-none.absolute.inset-0.-z-10 {
  display: none !important;
}
html[data-no-atmosphere="true"],
html[data-no-atmosphere="true"] body {
  background: #000 !important;
  background-image: none !important;
}

/* --- Animation infrastructure -------------------------------------------
 * The rough-notation library injects this @keyframes at runtime via JS,
 * so Phase A's static stylesheet capture missed it. Hardcoded so SVG
 * underline strokes draw on page load. */
@keyframes rough-notation-dash {
  to { stroke-dashoffset: 0; }
}

/* Clear entrance-state initial transforms once the element reaches its
 * final state. The bundled CSS contains unconditional per-element rules
 * (e.g. `.image--XX-YYY { transform: translateX(-10px) }`) that set the
 * starting frame of the upstream entrance animations. The upstream
 * runtime (and its Custom Code "snap-to-final" snippet) clears these via
 * inline `transform: none`. Mirror the same behavior in CSS scoped to
 * `.is-animated`. */
.mirror-root [data-entrance].is-animated {
  transform: none !important;
}

/* --- Container width sync (annotation #22) -------------------------------
 * Upstream bundle defines `:root { --bde-section-width: 1480px }` but the
 * brand Container uses `--container-max: 1520px`. Vertical edges of the
 * Nav logo + body sections didn't line up. Override scoped to
 * `.mirror-root` so body sections widen to 1520px (matching brand
 * Container). The 40px horizontal padding stays the same on both sides
 * → 1600px total stage width on desktop. */
.mirror-root {
  --bde-section-width: 1520px;
}

/* --- Replacement underline animation (annotations #21 + #43) -------------
 * Upstream's rough-notation lib draws a hand-drawn purple line under
 * `.dual-heading--secondary`. We don't run that JS; strip-chrome.ts
 * removes the captured (mispositioned) SVG. Replace with a CSS-only
 * pseudo-element underline that animates left → right over 2s after a 2s
 * delay, sitting 10px below the text baseline. Class is generic across
 * pages — any heading with `.dual-heading--secondary.js-annotate` gets
 * the underline. */
.mirror-root .dual-heading--secondary.js-annotate {
  position: relative;
  display: inline-block;
}
.mirror-root .dual-heading--secondary.js-annotate::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -10px;
  height: 5px;
  /* Full width from the first frame, revealed by scaleX — NOT animated from
   * `width: 0`.
   *
   * Animating width made this heading the Largest Contentful Paint element at
   * ~2.2s on the live site: the pseudo-element sits outside the text box
   * (bottom: -10px), so when it grew at the 2s mark the heading's painted
   * rectangle grew with it, and Chrome logged a new, larger contentful paint.
   * FCP was already ~200ms — the page just kept re-qualifying its LCP.
   *
   * scaleX is visually identical (still draws left → right) but the element's
   * rect is constant from first paint, so no late LCP candidate. It is also
   * cheaper: transforms composite on the GPU, whereas animating width forced
   * layout on every frame. */
  width: 100%;
  transform: scaleX(0);
  transform-origin: left center;
  background: var(--bde-brand-primary-color, #7c3aed);
  animation: dual-underline-draw 2s ease-out 2s forwards;
}
@keyframes dual-underline-draw {
  to { transform: scaleX(1); }
}

/* --- product-spotlight section padding (annotation #46) ------------------
 * Product-spotlight sections (FotAi, PicBot, Mosaix, PixDron, ChiMind,
 * GraffitX, …) currently inherit `padding-top: 200px` from the bundled
 * section rule. Owner wants 150px on every spotlight. Hero sections have
 * their own override per-page in `<slug>.css` (typical 140px). */
.mirror-root .section.product-spotlight .section-container {
  padding-top: 150px;
}

/* ============================================================================
 * RESPONSIVE OVERRIDES — generic patterns
 *
 * Upstream WP pages were never optimized for narrow viewports. The bundle
 * ships 48 media queries but most target legacy widget-specific concerns;
 * the actual page-level layout (flex rows that don't wrap, fixed pixel
 * widths on cards, hard-coded inner paddings, sections pinned at 200px
 * vertical padding) stays desktop-shaped at every viewport. This block
 * fixes the recurring patterns.
 *
 * Constraints (owner-set):
 *  • No `!important` — match bundle specificity via `.mirror-root` ancestor.
 *
 * Breakpoints align to brand Tailwind defaults (lg=1024, md=768, sm=480).
 * ========================================================================= */

/* --- Section padding scales fluidly ------------------------------------- */
@media (max-width: 1023px) {
  .mirror-root {
    --bde-section-vertical-padding: 80px;
    --bde-section-horizontal-padding: 24px;
  }
  .mirror-root .section.section--hero .section-container { padding-top: 110px; }
  .mirror-root .section.product-spotlight .section-container { padding-top: 110px; }
}
@media (max-width: 767px) {
  .mirror-root {
    --bde-section-vertical-padding: 60px;
    --bde-section-horizontal-padding: 30px;
  }
  .mirror-root .section.section--hero .section-container { padding-top: 90px; padding-bottom: 60px; }
  .mirror-root .section.product-spotlight .section-container { padding-top: 70px; padding-bottom: 60px; }
}
@media (max-width: 479px) {
  .mirror-root {
    --bde-section-horizontal-padding: 30px;
  }
}

/* --- Headings scale fluidly (no media query — clamp handles all widths) -
 * Bundle: h3=3.4rem, h4=1.56rem flat across all viewports. Replace with
 * fluid clamps anchored to the bundled values at desktop end. */
.mirror-root .heading--h3,
.mirror-root h3 { font-size: clamp(1.8rem, 4.5vw, 3.4rem); }
.mirror-root .heading--h4,
.mirror-root h4 { font-size: clamp(1.1rem, 2.5vw, 1.56rem); }
.mirror-root .heading--h1,
.mirror-root h1 { font-size: clamp(1.6rem, 4vw, var(--bde-h1-font-size, 2.5rem)); }

/* --- Generic block stacking at <md --------------------------------------
 * Breakdance composes layouts as nested `.block` flex containers (rows of
 * text+image columns, image grids, counter strips, all using
 * `flex-direction: row; flex-wrap: nowrap`). At narrow viewports each
 * child compresses to ~100px, forcing one-word-per-line text and tiny
 * thumbnails. Convert every `.block` inside a section to flex-column so
 * children stack at full container width.
 *
 * Heavy-handed by design: targeting individual blocks per slug would mean
 * 30+ rules. Stacking all `.block` instead is one rule that also self-
 * heals as new content lands. Children that should stay inline
 * (.icon-box, .container-link's own flex layout) are unaffected — they're
 * not `.block`. */
@media (max-width: 767px) {
  .mirror-root .section .block {
    flex-direction: column;
    align-items: stretch;
    flex-wrap: wrap;
  }
}

/* --- Reset large pixel paddings on spotlight inner blocks ---------------
 * Bundle puts `padding-left: 100px` on outer spotlight rows and
 * `padding-right: 100px` on text columns to create the desktop margin
 * that frames the image grid. At 375 viewport the math is brutal: 343px
 * container minus 200px combined padding = 143px usable, then split
 * 50/50 = ~70px per child column. Rich text inside collapses to one word
 * per line. Force every `.block` inside `.product-spotlight` to
 * width:100% + zero horizontal padding at <md. The section-container
 * already supplies the gutter via `--bde-section-horizontal-padding`. */
@media (max-width: 767px) {
  .mirror-root .section.product-spotlight .block {
    width: 100%;
    padding-left: 0;
    padding-right: 0;
  }
}

/* --- Counter cards (generic) -------------------------------------------
 * Bundle pins fixed pixel widths on counter widgets (typically 400px).
 * At <1280 we let them go fluid; at <md they stack one-per-row. Per-slug
 * counters with non-standard typography or layout can override with
 * higher-specificity rules in `<slug>.css`. */
@media (max-width: 1279px) {
  .mirror-root .counter {
    width: 100%;
    max-width: 360px;
  }
}
@media (max-width: 767px) {
  .mirror-root .counter {
    max-width: 100%;
  }
}

/* --- Images respect intrinsic max-width inside narrow columns ---------- */
@media (max-width: 767px) {
  .mirror-root .image img,
  .mirror-root .image picture {
    max-width: 100%;
    height: auto;
  }
}

/* ============================================================================
 * Ported content stacking containment.
 *
 * The brand <Nav> (sticky, z-50) and <main class="mirror-root"> are siblings
 * inside the layout's `relative min-h-screen` wrapper. `mirror-root` was
 * static (not a stacking context), so the ported body's positioned
 * descendants — Breakdance assigns z-index into the 1000s — competed directly
 * in the wrapper's stacking context and could paint OVER the nav and over the
 * sticky `.page-submenu`. Make `mirror-root` its own stacking context at z-0
 * so ALL ported content is contained below the nav (z-50). The submenu, being
 * inside mirror-root, then sits above its sibling content (via its own high
 * z-index) yet still below the nav (the whole context is z-0 < 50).
 *
 * GradientField is `-z-10` inside the same wrapper, so it stays behind this
 * z-0 layer. This selector starts with the scope class so lib/css-scope.ts
 * leaves it unprefixed (targets the <main> element itself, not a descendant).
 * ========================================================================= */
.mirror-root {
  position: relative;
  z-index: 0;
}

/* ============================================================================
 * In-page section sub-menu (.page-submenu) — shared chrome across every
 * attraction page (fotai / picbot / mosaix / future ports).
 *
 * The sub-menu is the in-page jump-nav strip ("Co to jest / Jak działa / …").
 * fotai's upstream HTML carries the `page-submenu` class natively; picbot &
 * mosaix get it injected by their `<slug>.strip.ts` (addClasses) so all three
 * share one generic style here instead of per-slug BEM-id rules.
 *
 * Every page's processed bundle ships the global Breakdance rule
 * `@media (min-width:1023px){ .page-submenu { position:sticky; top:0;
 * z-index:1000; transition: top .2s ease } }`. We layer on top of it:
 *
 *   Desktop (≥1023px) — sticky dock-below-nav:
 *     • header visible → top = nav height (120px = pt-10 40 + h-20 80)
 *     • header hidden  → top = 0 (Nav writes html[data-nav-hidden="true"])
 *     • z-index stays high (above ported content) — the nav can't be covered
 *       because `.mirror-root` is a contained stacking context below it (see
 *       the rule above). The bundle's `transition: top .2s ease` animates the
 *       dock/undock. Sticky only applies ≥1023px, where the Nav is always
 *       desktop-height, so 120px is a constant.
 *
 *   Mobile (<1023px) — dropped entirely (owner: hide the 12-anchor strip on
 *     mobile). The bundle leaves it static below 1023px; we display:none it.
 *
 *   Background band — #1B0048 + GradientField-matched dot pattern. A
 *     deliberate exception to "sections stay transparent": this is fixed-style
 *     navigation chrome, not a content section (owner annotations #94/#113).
 *     Promoted here from per-slug fotai.css / picbot.css so mosaix matches too.
 *
 * NOTE: the `html[...]` rule is NOT scoped to .mirror-root by lib/css-scope.ts
 * (it skips selectors starting with html/body/:root), so it carries
 * `.mirror-root` inline. */
.mirror-root .page-submenu {
  background-color: #1b0048;
  background-image: radial-gradient(
    circle,
    rgba(255, 255, 255, 0.06) 1px,
    transparent 1px
  );
  background-size: 15px 15px;
  background-position: 0 0;
}
@media (min-width: 1023px) {
  .mirror-root .page-submenu {
    top: 120px;
    /* Above ported content (Breakdance z-index runs into the 1000s);
     * stays below the Nav (z-50) because .mirror-root is a contained
     * stacking context — see the mirror-root rule below. */
    z-index: 1000;
  }
  html[data-nav-hidden='true'] .mirror-root .page-submenu {
    top: 0;
  }
}
@media (max-width: 1022px) {
  .mirror-root .page-submenu {
    display: none;
  }
}

/* --- Self-hosted streamed video with centered play overlay -----------------
 * Shared by any ported page that swaps a captured/embedded video for a
 * self-hosted <video> (home #wideo intro, /picbot "AI widzi"). The frame,
 * pulsing play button, and native-control trimming are identical across pages;
 * only the row layout (columns / gaps / margins) lives in each <slug>.css.
 * Wired by components/brand/VideoPlayOverlayMount.tsx — it pairs every
 * .video-play-overlay with the <video> in its own .ee-video-container. */

/* Vertical 9:16 frame with the bundle's spinning `.animated-border` ring.
 * `border: 0` kills any static bundle border on the frame's BEM class so only
 * the animated ring shows. Compounded with `.video` (both frames carry it) so
 * the specificity beats bundle rules that compound `.video.<bem-id>`
 * (e.g. picbot's `.video.video--634-138 .ee-video-container`, 0,0,4,0). */
.mirror-root .video.video-selfhost {
  width: 360px;
  max-width: 100%;
  border: 0;
  --border-thickness: 4px; /* thicker ring than the bundle default 2px */
  border-radius: 14px; /* outer = 4px ring + 10px inner (.animated-border *) */
  box-shadow: 5px 20px 35px 5px #000000db;
  overflow: hidden;
}
.mirror-root .video.video-selfhost .ee-video-container {
  padding-top: 177.77777777778%; /* 9:16 vertical */
}

/* Centered violet play-circle SVG — shown over the poster while paused, faded
 * out during playback (toggled by VideoPlayOverlayMount). The SVG *is* the
 * circle, so the button itself is a transparent positioning wrapper. Native
 * controls stay for in-playback control once revealed on first play. */
.mirror-root .video-play-overlay {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 2;
  display: inline-flex;
  width: 80px;
  height: 80px;
  padding: 0;
  border: 0;
  border-radius: 50%; /* round base so the pulsing box-shadow ring stays round */
  background: transparent;
  cursor: pointer;
  --pulse-color: 107, 27, 197; /* brand violet #6B1BC5 */
  transform: translate(-50%, -50%);
  animation: video-play-pulse 2s infinite;
  transition: opacity 0.2s ease;
}
.mirror-root .video-play-overlay.is-hidden {
  opacity: 0;
  pointer-events: none;
  animation: none; /* stop pulsing while the video plays */
}
.mirror-root .video-play-overlay__icon {
  width: 100%;
  height: 100%;
  fill: var(--bde-brand-primary-color, #6b1bc5);
  filter: drop-shadow(0 6px 16px rgba(0, 0, 0, 0.5));
  transition: fill 0.2s ease;
}
.mirror-root .video-play-overlay:hover .video-play-overlay__icon {
  fill: #7d28dc;
}
/* Pulsing ring — the centering translate is folded into the keyframes so the
 * animation keeps the -50%/-50% offset. */
@keyframes video-play-pulse {
  0% {
    transform: translate(-50%, -50%) scale(0.95);
    box-shadow: 0 0 0 0 rgba(var(--pulse-color), 0.7);
  }
  70% {
    transform: translate(-50%, -50%) scale(1);
    box-shadow: 0 0 0 18px rgba(var(--pulse-color), 0);
  }
  100% {
    transform: translate(-50%, -50%) scale(0.95);
    box-shadow: 0 0 0 0 rgba(var(--pulse-color), 0);
  }
}
/* Trim native controls: hide the scrubber timeline. Blink/WebKit only
 * (Chrome/Edge/Safari); Firefox keeps full controls. The three-dots overflow
 * menu is removed via `controlslist` + `disablepictureinpicture` on <video>. */
.mirror-root .ee-video-container video::-webkit-media-controls-timeline,
.mirror-root .ee-video-container video::-webkit-media-controls-timeline-container {
  display: none !important;
}


/* === home.css (slug-specific) === */

/* ============================================================================
 * home.css — slug-specific overrides for the home page port.
 *
 * Layered AFTER `_base.css` by `scripts/port/mirror.ts`, both scoped to
 * `.mirror-root` via `lib/css-scope.ts`. Generic cross-cutting rules
 * (body restoration, @font-face, generic block stacking, section-padding
 * scaling, generic h3/h4 clamps, etc.) live in `_base.css` — DO NOT
 * duplicate them here.
 *
 * What belongs here:
 *  • BEM-id-specific tweaks (`block--23-114`, `heading--23-127`,
 *    `dual-heading--23-284`, `multi-header--23-106`, etc.)
 *  • Hero-section specific values (e.g. hero padding-top: 140px — the
 *    home hero's preferred value, may differ on other pages)
 *  • Page-unique layouts (`attraction-hub`, `home-atrakcje-grid`)
 *  • Page-unique animation hooks (motion.page floating labels
 *    `.hero-video-text-1..4`)
 * ========================================================================= */

/* Owner annotation #17 — hero section top padding. Upstream bundle sets
 * `.section--hero .section-container { padding-top: 200px }` but the
 * intended desktop value is 140px on the home page. Other pages may want
 * different hero padding — keep this slug-specific.
 *
 * Raised 50px → 100px for desktop. This rule is unscoped, so it lands on
 * everything ≥768 (the <768 override at the bottom of this file pins
 * mobile at 40px and still wins). 768 is also where the brand header
 * switches to its taller desktop padding, so the two move together. */
.mirror-root .section.section--hero .section-container {
  padding-top: 100px;
}

/* Owner annotation #42 — drop italic on the entire `dual-heading--23-284`
 * line ("Goście wychodzą z czymś więcej niż wspomnieniem: z historiami,
 * które chcą opowiadać!"). Rule scopes to the heading and all its
 * children so neither the primary nor secondary span renders italic. */
.mirror-root .dual-heading--23-284,.mirror-root 
.dual-heading--23-284 * {
  font-style: normal;
}

/* Owner annotation #44 — lift the FotAi / PicBot badge row inside
 * block--23-114 by 20px so the badges sit higher in the hero column. */
.mirror-root .block--23-114 {
  margin-top: -20px;
}

/* Owner annotation #45 — heading--23-127 ("atrakcje" stencil) needs
 * its top offset changed to -10px. Add `position: relative` so the
 * `top` value actually applies (the bundle doesn't position it by
 * default). */
.mirror-root .heading--23-127 {
  position: relative;
  top: -10px;
}

/* ============================================================================
 * RESPONSIVE OVERRIDES — home-specific
 *
 * Generic mobile patterns (block stacking, section padding scaling, image
 * fluid sizing, counter sizing, h3/h4/h1 clamps) live in `_base.css`. The
 * rules below address layouts and elements unique to the home page.
 *
 * Constraints (owner-set):
 *  • No `!important` — match bundle specificity via `.mirror-root` ancestor.
 *  • Hero floating labels: scale via `font-size` only (animations
 *    untouched — keyframes use % translate so footprint scales with
 *    font-size naturally).
 * ========================================================================= */

/* --- attraction-hub mobile padding (home-only section class) ----------- */
@media (max-width: 1023px) {
  .mirror-root .section.attraction-hub .section-container { padding-top: 110px; padding-bottom: 40px; }
}
@media (max-width: 767px) {
  .mirror-root .section.attraction-hub .section-container { padding-top: 70px; padding-bottom: 30px; }
}

/* --- Hero floating labels (.hero-video-text-1..4) — scale via font-size --
 * Bundle defaults: 3rem / 2.5rem / 2.3rem / 2rem with negative-px right/left
 * offsets calibrated for desktop. We keep the offsets but shrink font-size;
 * keyframes use % translates so the animation footprint shrinks with the
 * type. The motion.page floating labels are a home-page-only widget. */
@media (max-width: 1023px) {
  .mirror-root .hero-video-text-1 { font-size: 2.2rem; right: -20px; }
  .mirror-root .hero-video-text-2 { font-size: 1.9rem; right: -10px; }
  .mirror-root .hero-video-text-3 { font-size: 1.7rem; right: -50px; }
  .mirror-root .hero-video-text-4 { font-size: 1.5rem; }
}
@media (max-width: 767px) {
  .mirror-root .hero-video-text-1 { font-size: 1.6rem; right: 0; }
  .mirror-root .hero-video-text-2 { font-size: 1.4rem; right: 0; }
  .mirror-root .hero-video-text-3 { font-size: 1.3rem; right: -20px; }
  .mirror-root .hero-video-text-4 { font-size: 1.2rem; left: 0; }
}
@media (max-width: 479px) {
  .mirror-root .hero-video-text-1 { font-size: 1.25rem; }
  .mirror-root .hero-video-text-2 { font-size: 1.1rem; }
  .mirror-root .hero-video-text-3 { font-size: 1rem; }
  .mirror-root .hero-video-text-4 { font-size: 0.95rem; }
}

/* --- Hero h1 styled-word spans (multi-header--23-106) —
 * bundle pins:
 *   styling-1 ("Eventowe", outlined) 5.5rem desktop / 3.5rem at <768
 *   styling-2 ("atrakcje premium")    3.125rem / 2rem
 *   styling-3 ("w erze")              3.125rem / 2rem
 *   styling-4 ("Ai")                  3.825rem / 2.5rem
 * The <768 fallback still overflows at 375. Replace with fluid clamps so
 * "Eventowe" never exceeds the viewport, anchored to bundled desktop values
 * at the upper end. Specificity matches bundle so no !important needed. */
.mirror-root .multi-header.multi-header--23-106 span.multi-header__styling-1 {
  font-size: clamp(2rem, 8vw, 5.5rem);
}
.mirror-root .multi-header.multi-header--23-106 span.multi-header__styling-2 {
  font-size: clamp(1.4rem, 4.5vw, 3.125rem);
}
.mirror-root .multi-header.multi-header--23-106 span.multi-header__styling-3 {
  font-size: clamp(1.4rem, 4.5vw, 3.125rem);
}
.mirror-root .multi-header.multi-header--23-106 span.multi-header__styling-4 {
  font-size: clamp(1.7rem, 5.5vw, 3.825rem);
}

/* --- attraction-hub: bundle defines `.home-atrakcje-grid` as a 10-column
 * CSS grid with `grid-template-columns: repeat(10, 1fr) !important` and
 * per-child `grid-column: 2/5; grid-row: 1` placements that keep 6 mini
 * product cards in a 3×2 layout on desktop. At narrow viewports the 10
 * columns squish to ~33px and the cards overflow.
 *
 * `!important` on `grid-template-columns` blocks any non-`!important` grid
 * tweak. Workaround: switch `display: grid → flex` at <lg, which voids
 * every grid-track / grid-area rule (they don't apply to flex containers).
 * Then standard flex-wrap controls the layout. */
@media (max-width: 1023px) {
  .mirror-root .section.attraction-hub .home-atrakcje-grid {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 24px;
  }
  .mirror-root .section.attraction-hub .home-atrakcje-grid > * {
    flex: 1 1 calc(33.333% - 24px);
    min-width: 220px;
  }
}
@media (max-width: 767px) {
  .mirror-root .section.attraction-hub .home-atrakcje-grid > * {
    flex: 1 1 calc(50% - 24px);
    min-width: 0;
  }
}
@media (max-width: 479px) {
  .mirror-root .section.attraction-hub .home-atrakcje-grid > * {
    flex: 1 1 100%;
  }
}

/* --- Counter cards (home BEM ids 23-278..23-281) ------------------------
 * `_base.css` provides generic `.mirror-root .counter` width/max-width
 * rules at <1280 + <md. Home counters get extra typography tightening at
 * <md (numbers shrink to 2rem so the strip stays readable when stacked). */
@media (max-width: 767px) {
  .mirror-root .counter[class*="counter--23-"] .counter__number,
  .mirror-root .counter[class*="counter--23-"] .counter__digit,
  .mirror-root .counter[class*="counter--23-"] .counter__prefix,
  .mirror-root .counter[class*="counter--23-"] .counter__suffix {
    font-size: 2rem;
  }
}

/* --- Suppress the rotated "atrakcje" stencil heading at narrow viewports;
 * bundle absolute-positions `.heading--23-127` against the section's left
 * edge with `position:relative;top:-10px` (per annotation #45). On mobile
 * it overlaps body content. */
@media (max-width: 767px) {
  .mirror-root .heading--23-127 { display: none; }
}

/* ==========================================================================
 * Mobile annotation round 2 (#52..#60)
 * ======================================================================= */

/* --- #52 hero h1 lines overlap on mobile ---------------------------------
 * Bundle pins `margin-bottom: -37px` on styling-2 ("atrakcje premium") so
 * the next inline-rendered words ("w erze Ai") tuck up against it on
 * desktop. At mobile font-sizes (clamp-driven, 1.4rem..) -37px overshoots
 * the line height and lands styling-3/4 ON TOP of styling-2's text.
 * Zero out the negatives at <md and let normal line-height do the work. */
@media (max-width: 767px) {
  .mirror-root .multi-header.multi-header--23-106 span.multi-header__styling-1,
  .mirror-root .multi-header.multi-header--23-106 span.multi-header__styling-2,
  .mirror-root .multi-header.multi-header--23-106 span.multi-header__styling-3,
  .mirror-root .multi-header.multi-header--23-106 span.multi-header__styling-4 {
    margin-top: 0;
    margin-bottom: 0;
    line-height: 1.3;
  }
}

/* --- #53 hero round video over-zoom -------------------------------------
 * Bundle sets `object-fit: none` on the inner <video>, which renders the
 * source at intrinsic resolution centered in the round frame — at 338px
 * frame size the camera face gets cropped (forehead off the top). Switch
 * to `object-fit: cover` so the video scales to fit the frame while
 * preserving aspect — the full face stays visible. Universal — applies
 * at every viewport, not just mobile. */
.mirror-root .video--23-259 video {
  object-fit: cover;
}

/* --- #53 hero AI logo + tagline alignment -------------------------------
 * On desktop the AI logo + "Emocje gwarantowane!" sit absolute-positioned
 * to the bottom-left of the round video. On mobile my generic `.block`
 * stack rule pushed them below the video, centered. Pull them back to
 * left-aligned so they sit under-left of the circle, matching the desktop
 * intent. */
@media (max-width: 767px) {
  .mirror-root .block--23-109 {
    align-items: flex-start;
  }
}

/* --- #54 reduce vertical gap between product spotlights -----------------
 * The `_base.css` baseline is 60px. Owner wants tighter on mobile — the
 * 6 stacked spotlights add up. Drop to 30px top + 30px bottom. */
@media (max-width: 767px) {
  .mirror-root .section.product-spotlight .section-container {
    padding-top: 30px;
    padding-bottom: 30px;
  }
}

/* --- #55 counter cards: 2-per-row at mobile -----------------------------
 * Stacked one-per-row eats vertical space. Owner wants 2-up at mobile
 * with smaller fonts. The strip is `block--23-277` (4 counter children).
 * Override the generic `.block { flex-direction: column }` from `_base`
 * back to row + wrap for this specific block. Each counter takes ~50%.
 *
 * Specificity note: `_base.css` uses `.mirror-root .section .block`
 * (0,0,3,0). Match it by chaining `.section .block--23-277` (also
 * 0,0,3,0) so source order (home loads after _base) decides. */
@media (max-width: 767px) {
  .mirror-root .section .block--23-277 {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: center;
  }
  .mirror-root .section .block--23-277 > .counter[class*="counter--23-"] {
    flex: 1 1 calc(50% - 10px);
    width: auto;
    max-width: calc(50% - 10px);
    padding: 16px 10px;
    margin: 0;
  }
  .mirror-root .section .block--23-277 .counter[class*="counter--23-"] .counter__number,
  .mirror-root .section .block--23-277 .counter[class*="counter--23-"] .counter__digit,
  .mirror-root .section .block--23-277 .counter[class*="counter--23-"] .counter__prefix,
  .mirror-root .section .block--23-277 .counter[class*="counter--23-"] .counter__suffix {
    font-size: 1.6rem;
  }
  .mirror-root .section .block--23-277 .counter[class*="counter--23-"] .counter__title {
    font-size: 0.85rem;
  }
}

/* --- #56 atrakcje hub center area --------------------------------------
 * `block--23-121` holds 5 floating stencil text labels (text--23-264..269,
 * "eventy/targi/sport/integ/konferer") plus `block--23-265` (the AI logo
 * + "atrakcje imprero" wordmark). On desktop the stencils are absolutely
 * positioned around the central logo. On mobile they collapse into the
 * flow and overlap. Hide stencils + center the logo block. */
@media (max-width: 767px) {
  .mirror-root .text--23-264,
  .mirror-root .text--23-266,
  .mirror-root .text--23-267,
  .mirror-root .text--23-268,
  .mirror-root .text--23-269 {
    display: none;
  }
  .mirror-root .block--23-121 {
    align-items: center;
    justify-content: center;
  }
  .mirror-root .block--23-265 {
    margin-left: auto;
    margin-right: auto;
  }
}

/* --- #57 + #60 stretched marquee/badge images --------------------------
 * Bundle pins `width: 350px; height: 97px; object-fit: fill` on
 * `.image--23-155` (FotAi badge image) and `.image--23-161` (PicBot
 * badge). At mobile width 350px the images get squashed to 97px tall,
 * with `object-fit: fill` distorting the aspect. Remove the height
 * constraint and let aspect drive height. */
@media (max-width: 767px) {
  .mirror-root .image--23-155,
  .mirror-root .image--23-161 {
    width: 100%;
    max-width: 180px;
    height: auto;
    object-fit: contain;
    margin-left: -10px;
  }
  .mirror-root .image--23-155 img,
  .mirror-root .image--23-161 img {
    width: 100%;
    height: auto;
    object-fit: contain;
  }
}

/* --- #58 FotAi 4-image collage grid ------------------------------------
 * Bundle composes the FotAi avatar grid as two `.block` rows
 * (block--23-152 with 2 images, block--23-153 with 3 images including
 * an arrow). The generic `.block { flex-direction: column }` stacks
 * them vertically — owner wants the desktop 2x2-ish pattern preserved.
 * Override back to row + wrap for these two blocks. Specificity matched
 * to `_base` via `.section` ancestor. */
@media (max-width: 767px) {
  .mirror-root .section .block--23-152,
  .mirror-root .section .block--23-153 {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px;
  }
  .mirror-root .section .block--23-152 > .image,
  .mirror-root .section .block--23-153 > .image {
    flex: 0 1 auto;
    width: auto;
    max-width: 48%;
  }
  .mirror-root .section .block--23-152 > .image img,
  .mirror-root .section .block--23-153 > .image img {
    width: 100%;
    height: auto;
  }
}

/* --- #59 reverse flex order so text comes before images on mobile ------
 * Owner directive: every product section on mobile needs text first, then
 * images. Per runtime DOM-order analysis the actual outer-row blocks (the
 * ones that have BOTH a heading-bearing child AND an image-bearing child
 * as direct siblings) are:
 *   fotai    block--23-141  text-first   ✓ no reverse needed
 *   picbot   block--23-157  image-first  → reverse
 *   mosaix   block--23-173  text-first   ✓ no reverse
 *   pixdron  block--23-191  text last (3 children, text idx 2) → reverse
 *   chimind  block--23-220  text-first   ✓ no reverse
 *   graffitx block--23-235  image-first  → reverse */
@media (max-width: 767px) {
  .mirror-root .product-spotlight--picbot .block--23-157,
  .mirror-root .product-spotlight--pixdron .block--23-191,
  .mirror-root .product-spotlight--graffitx .block--23-235 {
    flex-direction: column-reverse;
  }
}

/* ==========================================================================
 * Mobile annotation round 3 (#61..#68)
 * ======================================================================= */

/* --- #61 hero FotAi + PicBot badge row (block--23-114) ------------------
 * Two badge images stacked vertically by the generic `.block` column rule.
 * Owner wants them side-by-side at 45% width each on mobile so they read
 * as a paired award row (like desktop). Override back to row-wrap. */
@media (max-width: 767px) {
  .mirror-root .section .block.block--23-114 {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 4%;
  }
  .mirror-root .block.block--23-114 > .image {
    width: 45%;
    max-width: 45%;
    flex: 0 0 45%;
  }
  .mirror-root .block.block--23-114 > .image img {
    width: 100%;
    height: auto;
  }
}

/* --- #62 dual-heading--secondary block wrap — SUPERSEDED by #101.
 * Round 6 (#101) switched the secondary span to `display: inline`, which
 * makes the block-vs-inline tug-of-war moot. Rule kept here as a stub so
 * the round-3 numbering stays intact in commit history; the actual
 * `display: inline` override lives in the round-6 section below. */

/* --- #63 hero AI logo (image--23-270) — mobile placement -----------------
 * Bundle desktop position is bottom-left of the round video. Owner-tuned
 * mobile values: nudge in by 5px from the left, drop 20px below the
 * baseline, scale to 90%. Image is `position: absolute` so left/bottom
 * apply directly. Uses the `scale` CSS property (separate from
 * `transform`) so it doesn't collide with `_base.css`'s
 * `[data-entrance].is-animated { transform: none !important }` rule
 * that clears upstream entrance translates. */
@media (max-width: 767px) {
  .mirror-root .image.image--23-270 {
    left: -5px;
    bottom: -20px;
    scale: 0.9;
    transform-origin: bottom left;
  }
}

/* --- #64 "Emocje gwarantowane!" badge (heading--23-283) — mobile bottom 0
 * Bundle desktop has a positive offset that on mobile lifts the badge
 * above the video bottom edge. Owner wants it pinned to the bottom. */
@media (max-width: 767px) {
  .mirror-root .heading.heading--23-283 {
    bottom: 0;
  }
}

/* --- #65 block--23-119 mobile margin-top --------------------------------
 * Bundle pins margin-top:200px so on desktop the achievement-counter
 * block clears the hero column. On mobile that's wasted space. Owner
 * wants 80px. */
@media (max-width: 767px) {
  .mirror-root .block.block--23-119 {
    margin-top: 80px;
  }
}

/* --- #66 block--23-121 mobile alignment + offset ------------------------
 * The atrakcje-hub center block needs to self-center horizontally on
 * mobile + drop 40px below the previous block. */
@media (max-width: 767px) {
  .mirror-root .block.block--23-121 {
    align-self: center;
    margin-top: 40px;
  }
}

/* --- #67 block--23-272 mobile margin-top --------------------------------
 * Bundle pins ~80-100px. Owner wants 20px on mobile. */
@media (max-width: 767px) {
  .mirror-root .block.block--23-272 {
    margin-top: 20px;
  }
}

/* --- #68 product-spotlight content horizontal gutter on mobile ----------
 * `_base.css` zeroed the bundle's 100px spotlight inner padding to keep
 * narrow viewports readable. Owner wants 40px back so content isn't edge
 * to edge. Apply via section-container padding-inline (works for both
 * the text col and the image col since both inherit the container's
 * available width). */
@media (max-width: 767px) {
  .mirror-root .section.product-spotlight .section-container {
    padding-inline: 40px;
  }
}

/* ==========================================================================
 * Mobile annotation round 4 (#69..#84)
 * ======================================================================= */

/* --- #69..#72 hero h1 spans — explicit mobile sizes (replace clamps) ---
 * Owner-set: Eventowe 2.5rem, atrakcje premium 1.6rem, w erze 1.6rem,
 * Ai 2rem. Same selectors as the desktop clamp rules above; source order
 * (these come later) wins on equal specificity. */
@media (max-width: 767px) {
  .mirror-root .multi-header.multi-header--23-106 span.multi-header__styling-1 {
    font-size: 2.5rem;
  }
  .mirror-root .multi-header.multi-header--23-106 span.multi-header__styling-2 {
    font-size: 1.6rem;
  }
  .mirror-root .multi-header.multi-header--23-106 span.multi-header__styling-3 {
    font-size: 1.6rem;
  }
  .mirror-root .multi-header.multi-header--23-106 span.multi-header__styling-4 {
    font-size: 2rem;
  }
}

/* --- #74 dual-heading--23-285 leading — SUPERSEDED by #101 / round 7.
 * The block-layout leading hacks (margin-top:0 + line-height:1.2/1.3)
 * are obsolete now that the secondary span flows inline. Round 7
 * sets the final font-size + line-height + margin-bottom values. */

/* --- #75 hero round video object-fit -----------------------------------
 * Round 2 set `object-fit: cover` (universal) to replace bundle's
 * `object-fit: none`. Owner reports video is still scaled-up + cropped
 * and wants `contain` instead. Switch on mobile only — desktop stays at
 * `cover` (looks correct at 350x350). */
@media (max-width: 767px) {
  .mirror-root .video--23-259 video {
    object-fit: contain;
  }
}

/* --- #76 product-spotlight H4 mobile size ------------------------------
 * Owner wants 1.8rem at mobile. Bundle has `.heading--h4, h4 { font-size:
 * 1.56rem }` (color brand-primary). Override via `.section .heading--h4`
 * to match bundle specificity. */
@media (max-width: 767px) {
  .mirror-root .section .heading--h4,
  .mirror-root .section h4 {
    font-size: 1.8rem;
  }
}

/* --- #77 infobox-subtitle mobile size ----------------------------------
 * Currently 1.25rem (20px). Owner wants 1.15rem on mobile. */
@media (max-width: 767px) {
  .mirror-root .infobox-subtitle {
    font-size: 1.15rem;
  }
}

/* --- #78 attraction-hub grid row-gap on mobile -------------------------
 * Earlier round set `gap: 24px` on the flex-converted grid. Owner wants
 * a much larger row-gap (80px) so the 2-up cards breathe. */
@media (max-width: 767px) {
  .mirror-root .section.attraction-hub .home-atrakcje-grid {
    row-gap: 80px;
  }
}

/* --- #79 .outline-hash-heading::before — mobile placement --------------
 * The `#` mark drawn via ::before pseudo-element next to spotlight
 * headings. Owner-tuned mobile values: left:0, top:-80px, font-size 3.5rem
 * (currently smaller + offset for desktop). */
@media (max-width: 767px) {
  .mirror-root .outline-hash-heading::before {
    left: 0;
    top: -80px;
    font-size: 3.5rem;
  }
}

/* --- #80..#84 spotlight image grids: 2-col grid + natural proportions ---
 * Owner wants every spotlight image block on mobile to be a 2-column
 * grid with images at their native aspect ratio (no crop, no stretch).
 * Replaces the row-wrap rule from round 2 (#58) which only covered FotAi
 * and produced stretched images.
 *
 * Targeted blocks (each is a direct IMG-children container):
 *   FotAi:    block--23-152 (2 imgs), block--23-153 (3 imgs incl arrow)
 *   PicBot:   block--23-166 (2 imgs)
 *   Mosaix:   block--23-179 (2 imgs), block--23-182 (2 imgs)
 *   PixDron:  block--23-193 (2 imgs), block--23-195 (1 img)
 *   ChiMind:  block--23-227 (2 imgs), block--23-230 (1 img)
 *   GraffitX: block--23-242 (2 imgs), block--23-245 (1 img)
 *
 * 2-col grid means 2 imgs → 1 row × 2; 3 imgs → 2 rows (2 + 1); single
 * img → 1 row × 1 (centered). */
@media (max-width: 767px) {
  .mirror-root .section .block.block--23-152,
  .mirror-root .section .block.block--23-153,
  .mirror-root .section .block.block--23-166,
  .mirror-root .section .block.block--23-179,
  .mirror-root .section .block.block--23-182,
  .mirror-root .section .block.block--23-193,
  .mirror-root .section .block.block--23-195,
  .mirror-root .section .block.block--23-227,
  .mirror-root .section .block.block--23-230,
  .mirror-root .section .block.block--23-242,
  .mirror-root .section .block.block--23-245 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    align-items: start;
    justify-items: center;
  }
  .mirror-root .section .block.block--23-152 > img,
  .mirror-root .section .block.block--23-153 > img,
  .mirror-root .section .block.block--23-166 > img,
  .mirror-root .section .block.block--23-179 > img,
  .mirror-root .section .block.block--23-182 > img,
  .mirror-root .section .block.block--23-193 > img,
  .mirror-root .section .block.block--23-195 > img,
  .mirror-root .section .block.block--23-227 > img,
  .mirror-root .section .block.block--23-230 > img,
  .mirror-root .section .block.block--23-242 > img,
  .mirror-root .section .block.block--23-245 > img {
    width: 100%;
    height: auto;
    max-width: 100%;
    object-fit: contain;
  }
}

/* ==========================================================================
 * Mobile annotation round 5 (#85..#91)
 * ======================================================================= */

/* --- #86 dual-heading--23-285 secondary leading — SUPERSEDED by #101.
 * The line-height:1 !important on the parent (used to defeat bundle
 * leading when secondary was display:block) is what was overriding
 * Round 7's line-height:1.6 — removing it lets Round 7 win cleanly. */

/* --- #87 / #103 hero round video — bundle has object-fit:none !important
 * Bundle uses `.mirror-root .video.video--23-259 video` (compound
 * `.video.video--23-259` raises spec to 0,0,3,1) with !important. Match
 * the compound here so our `contain !important` wins via source order. */
.mirror-root .video.video--23-259 video {
  object-fit: contain !important;
}

/* --- #88 block--23-152 (FotAi top two-image row) → align END ------------
 * Round 4 set `align-items: start` for every spotlight image grid; owner
 * wants the FotAi top row aligned to the bottom edge so the shorter image
 * sits flush with the taller one's baseline. */
@media (max-width: 767px) {
  .mirror-root .section .block.block--23-152 {
    align-items: end;
  }
}

/* --- #89 / #91 block--23-153 + block--23-182 → keep aligned START --------
 * Reaffirm explicit start alignment so per-page tweaks don't drift later.
 * Already set in the round-4 unified rule; isolating here makes the intent
 * permanent and overrides the #88 sibling rule by source order. */
@media (max-width: 767px) {
  .mirror-root .section .block.block--23-153,
  .mirror-root .section .block.block--23-182 {
    align-items: start;
  }
}

/* --- #90 PicBot and following spotlights → 80px mobile padding-top ------
 * Round 2 (#54) set padding-top:30px universally on every product
 * spotlight section. Owner now wants 80px from PicBot onwards so each
 * product gets vertical breathing room above the outline `#` heading.
 * FotAi (the first spotlight) keeps the round-2 30px since it sits right
 * below the hero. */
@media (max-width: 767px) {
  .mirror-root .section.product-spotlight--picbot .section-container,
  .mirror-root .section.product-spotlight--mosaix .section-container,
  .mirror-root .section.product-spotlight--pixdron .section-container,
  .mirror-root .section.product-spotlight--chimind .section-container,
  .mirror-root .section.product-spotlight--graffitx .section-container {
    padding-top: 80px;
  }
}

/* ==========================================================================
 * Mobile annotation round 6 (#100..#103)
 * ======================================================================= */

/* --- #100 / #101 dual-heading--23-285 — drop italic + inline secondary
 * Owner wants the entire dual-heading not italic, and the secondary
 * span to flow inline with the primary (replaces the round 3 / 4 / 5
 * block-with-zero-leading approach — once it's inline, the leading
 * issue is moot). */
.mirror-root .dual-heading--23-285,
.mirror-root .dual-heading--23-285 * {
  font-style: normal;
}
@media (max-width: 767px) {
  .mirror-root .dual-heading--23-285 .dual-heading--secondary {
    display: inline;
  }
}

/* --- #102 hero section-container — 40px padding-top on mobile -----------
 * Universal value at line 24-26 is 50px (owner annotation #17). Mobile
 * override drops it to 40px so the hero opening line sits closer to
 * the brand chrome. */
@media (max-width: 767px) {
  .mirror-root .section.section--hero .section-container {
    padding-top: 40px;
  }
}

/* --- Round 7 dual-heading--23-285 sizing on mobile ---------------------
 * Owner spec: 0.9rem font-size + 1.6 line-height so the inline-flowing
 * primary + secondary spans (#101) wrap with comfy vertical rhythm.
 * 40px bottom margin gives air below before the next block. No
 * margin-top — the previous block's own bottom spacing handles the
 * gap above. */
@media (max-width: 767px) {
  .mirror-root .dual-heading.dual-heading--23-285 {
    font-size: 0.9rem;
    line-height: 1.6;
    margin-bottom: 40px;
  }
}

/* --- Reya (standing) — decorative presenter on the right of the atrakcje grid */
.mirror-root .section.attraction-hub .section-container {
  position: relative;
}
.mirror-root .home-reya-standing {
  position: absolute;
  right: -120px;
  bottom: -40px;
  width: 400px;
  height: auto;
  z-index: 3;
  pointer-events: none;
}
@media (max-width: 1023px) {
  .mirror-root .home-reya-standing {
    display: none;
  }
}

/* --- Reya — decorative sitting cutout on the counters row -------------------
 * Perched on the right edge of the counter cards (block--23-277), rising into
 * the space above with heels hanging in front. Absolute within the cards row;
 * pointer-events:none so it never blocks the cards. Hidden on tablet/mobile. */
.mirror-root .block.block--23-277 {
  position: relative;
}
.mirror-root .home-reya {
  position: absolute;
  right: -135px;
  bottom: 37px;
  width: 300px;
  height: auto;
  z-index: 3;
  pointer-events: none;
}
@media (max-width: 1023px) {
  .mirror-root .home-reya {
    display: none;
  }
}

/* --- Round 7 .button--23-113 margin-bottom on mobile -------------------
 * Owner spec: 60px gap below the hero CTA so the next block doesn't
 * hug it. */
@media (max-width: 767px) {
  .mirror-root .button.button--23-113 {
    margin-bottom: 60px;
  }
}

/* --- Homepage intro video row (block--23-271) -------------------------------
 * Owner replaced the "Atrakcje imprero" floating-words graphic in the second
 * hero row with a YouTube embed: [video (left) | text (right, left-aligned)].
 * Size + border mirror the /fotai `.video--239-334` reference — a vertical
 * 9:16 frame (the clip is a YouTube Short), #24015D border, soft drop shadow.
 * Owner desktop spec: 360px video right-aligned in its half, 100px gap to a
 * narrower text column, 140px top margin on the section.
 * NOTE: the markup is a hand edit inside the auto-generated home-body.ts;
 * a future `strip-chrome --slug=home` run would drop it. */
.mirror-root .block.block--23-271.home-intro-row {
  flex-direction: row;
  flex-wrap: nowrap;
  align-items: center;
}
.mirror-root .home-intro-row__media {
  width: 100%;
  display: flex;
  flex-direction: row; /* override generic .block column stacking from _base.css */
  justify-content: center; /* centered on mobile; right-aligned on desktop */
}
.mirror-root .home-intro-row__text {
  width: 100%;
  padding: 0;
  text-align: left;
}
.mirror-root .home-intro-row__text .text.text--23-122 {
  text-align: left;
}
/* Video frame + play overlay + pulse + control-trim are shared across ported
 * pages and now live in _base.css (.video-selfhost / .video-play-overlay).
 * Home's frame div carries `video-selfhost`, so it inherits the 360px 9:16
 * vertical frame, the spinning `.animated-border`, and the centered play
 * button. Only the row layout below is home-specific. */
/* Desktop: video right-aligned in left half, 100px gap, narrower text. */
@media (min-width: 768px) {
  .mirror-root .block.block--23-119 {
    margin-top: 140px;
  }
  .mirror-root .block.block--23-271.home-intro-row {
    gap: 100px;
  }
  .mirror-root .home-intro-row__media {
    flex: 0 0 calc(50% - 50px);
    justify-content: flex-end;
  }
  .mirror-root .home-intro-row__text {
    flex: 1 1 auto;
    padding-right: 100px; /* narrows the text column */
  }
}
/* Mobile: text first, then full-width video below. */
@media (max-width: 767px) {
  .mirror-root .block.block--23-271.home-intro-row {
    flex-direction: column-reverse; /* text (2nd child) on top, video below */
    gap: 40px;
  }
  .mirror-root .video.video--home-intro {
    width: 100%;
  }
}

/* --- Hero CTA row: primary "Sprawdź atrakcje" + secondary "Zobacz wideo" ----
 * Lay the two buttons side by side (wrap on narrow screens). The secondary
 * uses the built-in `button-atom--secondary` outline variant; `home-cta-video`
 * just adds the gap between its play icon and label. */
.mirror-root .button.button--23-113 {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 40px;
}
/* Secondary "Zobacz wideo": its 2px border (vs the primary's 1px) makes it
 * taller, so trim vertical padding by 2x the border (14px -> 12px/side) to
 * match the primary's 46px outer height. The play triangle sits in a
 * currentColor ring with spacing to the label. */
.mirror-root .button-atom.home-cta-video {
  gap: 10px;
  padding-top: 12px;
  padding-bottom: 12px;
}
.mirror-root .button-atom.home-cta-video .button-atom__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  width: 18px;
  height: 18px;
  border: 1.5px solid currentColor;
  border-radius: 50%;
}
.mirror-root .button-atom.home-cta-video .button-atom__icon svg {
  width: 8px;
  height: 8px;
  margin-left: 1px; /* optical-center the triangle inside the ring */
}

/* ==========================================================================
 * Frontpage annotations #12 / #13 — FotAi + PicBot scattered image collages
 * --------------------------------------------------------------------------
 * Owner replaced the FotAi example set with 8 AI-transformation shots and
 * expanded the PicBot set with 4 real event photos. Both are laid out as a
 * staggered (deliberately non-grid) masonry with rounded corners: a
 * flex-wrap row of `.home-collage__col` columns (2–3 images each) where even
 * columns drop down for the scatter. The HTML lives in home-body.ts
 * (block--23-143 = FotAi, block--23-162 = PicBot). The `.block.home-collage`
 * compound raises specificity above the bundle's `.block.block--23-143/-162`
 * flex rules so wrap/gap/alignment win. Responsive: columns shrink and wrap;
 * images are width:100% of their column so nothing overflows.
 * ======================================================================= */
.mirror-root .block.home-collage {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 16px;
}
.mirror-root .home-collage--fotai {
  justify-content: flex-start;
}
.mirror-root .home-collage--picbot {
  justify-content: flex-end;
}

.mirror-root .home-collage__col {
  display: flex;
  flex-direction: column;
  gap: 16px;
  flex: 1 1 130px;
  max-width: 175px;
  min-width: 0;
}
/* Stagger: nudge every 2nd column down so the set reads as a scatter, not
 * aligned rows. `nth-of-type` counts the column <div>s only (the FotAi
 * circuit <img> is a different element type, so it doesn't shift the count). */
.mirror-root .home-collage__col:nth-of-type(even) {
  margin-top: 40px;
}

.mirror-root .home-collage__img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 14px;
  box-shadow: 0 0 35px 10px #000c;
  object-fit: cover;
}

/* Mid widths: trim the max column so 4 FotAi columns keep breathing room
 * before the flex-wrap kicks them onto a second line. */
@media (max-width: 1100px) {
  .mirror-root .home-collage__col {
    max-width: 155px;
  }
}

/* Mobile: collage spans the full width of its (stacked) section column and
 * keeps two staggered columns, tighter gaps. `!important` beats the bundle's
 * desktop width:50%/45% on block--23-143/-162. */
@media (max-width: 767px) {
  .mirror-root .block.home-collage {
    width: 100% !important;
    padding-left: 0;
    gap: 10px;
    justify-content: center;
  }
  .mirror-root .home-collage__col {
    flex: 1 1 42%;
    max-width: 46%;
    gap: 10px;
  }
  .mirror-root .home-collage__col:nth-of-type(even) {
    margin-top: 24px;
  }
}

/* --- PicBot spotlight row (block--23-157) — desktop proportions ----------
 * Owner-tuned split for the #picbot section: even 50/50 columns instead of
 * the bundle's 55/45, the text column pushed a further 100px off the
 * collage (padding-left 100px → 200px), and the row's own right padding
 * dropped so the collage can breathe out to the container edge.
 *
 * Bundle values being overridden (all unscoped, so they'd otherwise apply
 * at every width):
 *   .block--23-157 { width: 100%; padding-right: 100px }
 *   .block--23-158 { width: 55%;  padding-left: 100px }
 *   .block--23-162 { width: 45%;  padding-top: 80px }
 *
 * Scoped ≥1024, not ≥768. A 200px inset on a half-width column needs the
 * width to pay for it: at 768 the container is 688px, so the text column
 * would be 344 − 200 = 144px and the copy would wrap two words per line.
 * Below 1024 the bundle's 55/45 + 100px split stays, and below 768
 * _base.css stacks the whole row. Compound `.block.block--23-*` matches
 * bundle specificity; the override bundle loads later, so equal
 * specificity is enough (no !important). */
@media (min-width: 1024px) {
  .mirror-root .block.block--23-157 {
    width: 100%;
    padding-right: 0;
  }
  .mirror-root .block.block--23-158 {
    width: 50%;
    padding-left: 200px;
  }
  .mirror-root .block.block--23-162 {
    width: 50%;
    padding-top: 80px;
  }
}

/* ==========================================================================
 * Mobile annotation round 8 (#104..#110)
 * ======================================================================= */

/* --- #104 spotlight collages → two independent columns ------------------
 * Round 4 (#80..#84) turned every image container into its own 2-col grid.
 * That makes each container a ROW, so the two containers of a section
 * cannot interleave: the lower-left image can only start below the TALLEST
 * image of the row above, leaving a hole under the shorter one. Owner saw
 * this as "bottom-left image floating too low" on Mosaix / ChiMind.
 *
 * Fix: promote the shared parent to the 2-col grid and let each original
 * container be one column (flex column). Left images stack directly under
 * each other, right images likewise — the desktop intent at mobile width.
 *
 * Nesting (parent > columns > images):
 *   Mosaix    23-178 > 23-179 [180,181] | 23-182 [184,185]
 *   PixDron   23-192 > 23-193 [204,196] | 23-195 [197]
 *   ChiMind   23-226 > 23-227 [228,229] | 23-230 [231]
 *   Graffit.X 23-241 > 23-242 [243,244] | 23-245 [246]
 *
 * Declared after the round-4 block so it wins on source order at equal
 * specificity. */
@media (max-width: 767px) {
  .mirror-root .section .block.block--23-178,
  .mirror-root .section .block.block--23-192,
  .mirror-root .section .block.block--23-226,
  .mirror-root .section .block.block--23-241 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: start;
    gap: 12px;
  }
  .mirror-root .section .block.block--23-179,
  .mirror-root .section .block.block--23-182,
  .mirror-root .section .block.block--23-193,
  .mirror-root .section .block.block--23-195,
  .mirror-root .section .block.block--23-227,
  .mirror-root .section .block.block--23-230,
  .mirror-root .section .block.block--23-242,
  .mirror-root .section .block.block--23-245 {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
    width: 100%;
    margin-bottom: 0;
    padding-left: 0;
    padding-right: 0;
  }
}

/* --- #105 FotAi → PicBot gap ---------------------------------------------
 * Every spotlight after FotAi carries a bundle rule with FIVE classes —
 * `.mirror-root .section.product-spotlight--picbot.product-spotlight
 * .section-container { padding-top: 70px; padding-bottom: 100px }` — so
 * those sections sit 100 + 70 = 170px apart. FotAi has no such bundle rule,
 * so it falls back to #54's 30px and the FotAi→PicBot seam is only
 * 30 + 70 = 100px: visibly tighter than every other seam. Match it.
 *
 * NB the compound `.product-spotlight--x.product-spotlight` in the bundle
 * outranks the 4-class selectors used above (which is why #90's 80px
 * padding-top never actually applied — measured value is still 70px).
 * Anything that needs to beat the bundle here has to repeat the compound. */
@media (max-width: 767px) {
  .mirror-root .section.product-spotlight--fotai .section-container {
    padding-bottom: 100px;
  }
}

/* --- #106 PicBot collage → balanced 2-column masonry --------------------
 * `.home-collage` is a flex-wrap row of `__col` columns. FotAi has 4 of
 * them (wraps 2 + 2, even, fine); PicBot has 3, so the third wraps onto a
 * row of its own and `justify-content: center` parks it in the middle —
 * the misalignment the owner flagged. Three columns side by side would
 * put each image at ~110px on a 375 screen, too small to read.
 *
 * Instead flow all 7 images through a 2-column multicol: `display:
 * contents` dissolves the `__col` wrappers so the images become the
 * multicol content, and the browser balances the two columns by height.
 * `break-inside: avoid` keeps an image from splitting across the columns.
 * Scoped to PicBot — FotAi's even wrap is not broken and stays as it is. */
@media (max-width: 767px) {
  .mirror-root .block.home-collage--picbot {
    display: block;
    columns: 2;
    column-gap: 12px;
  }
  .mirror-root .home-collage--picbot .home-collage__col {
    display: contents;
  }
  .mirror-root .home-collage--picbot .home-collage__img {
    display: block;
    width: 100%;
    margin: 0 0 12px;
    break-inside: avoid;
  }
}

/* --- #107 PixDron right column drops to mid-height ----------------------
 * The right column holds a single image; flush with the top of the left
 * column it reads as a failed 2×2 grid. Owner wants it "between the two
 * left ones", so offset it by half a column width — percentage margins
 * resolve against the containing block's inline size, so this scales with
 * the viewport instead of drifting at 375 vs 767. */
@media (max-width: 767px) {
  .mirror-root .section .block.block--23-195 {
    margin-top: 90%;
  }
}

/* --- #108 ChiMind left column starts above the right -------------------
 * Same single-image right column as PixDron, but the owner wants only a
 * slight stagger here — enough to break the flush top edge, not enough to
 * push the right image past the left column's first image. Graffit.X has
 * the identical 2-left/1-right shape, so it takes the same offset — its
 * images were the ones the owner called unevenly spaced, and matching the
 * ChiMind rhythm is what makes the pair read as deliberate. */
@media (max-width: 767px) {
  .mirror-root .section .block.block--23-230,
  .mirror-root .section .block.block--23-245 {
    margin-top: 12%;
  }
}
