/* ==========================================================================
   MyCabin Milla 47 Page Pack — frontend.css
   Clean-room build from source-design/milla-47-original.zip. Every selector
   is scoped under .pp-milla-47-clean (Page Pack Spec §5). Design tokens
   below are the same MyCabin site-wide palette/scale used by every other
   Page Pack in this project — copied here (not shared) because each pack
   owns its own CSS per spec, not because these values are page-specific.
   ========================================================================== */

.pp-milla-47-clean {
  --pp-ink:          #27272C;
  --pp-bone:         #FFFFFF;
  --pp-beige:        #FBF6F3;
  --pp-surface:      var(--pp-beige);
  --pp-accent:       #917EBC;
  --pp-accent-soft:  #CDCBFF;
  --pp-tint:         #E6E6FF;
  --pp-stone:        color-mix(in oklab, var(--pp-ink) 11%, var(--pp-bone));
  --pp-ink-hair:      color-mix(in oklab, var(--pp-ink) 7%,  var(--pp-bone));
  --pp-ink-line:     color-mix(in oklab, var(--pp-ink) 13%, var(--pp-bone));
  --pp-tint-line:        color-mix(in oklab, var(--pp-accent) 18%, var(--pp-tint));
  --pp-tint-line-strong: color-mix(in oklab, var(--pp-accent) 34%, var(--pp-tint));
  --pp-ink-72: color-mix(in oklab, var(--pp-ink) 72%, transparent);
  --pp-ink-56: color-mix(in oklab, var(--pp-ink) 65%, transparent);

  --pp-maxw:    1280px;
  --pp-gutter:  clamp(18px, 4vw, 40px);
  --pp-hdr-h:   clamp(58px, 7vw, 74px);
  --pp-sec-y-p: clamp(48px, 7vw, 104px);
  --pp-rail-pad: max(var(--pp-gutter), calc((100% - var(--pp-maxw)) / 2 + var(--pp-gutter)));

  --pp-r-pill: 999px;
  --pp-r-lg:  10px;
  --pp-r-md:  9px;
  --pp-r-sm:  8px;

  --pp-ease:   cubic-bezier(.22, 1, .36, 1);
  --pp-t-med:  .25s;
  --pp-t-slow: .35s;

  font-family: "Poppins", "Helvetica Neue", Helvetica, sans-serif;
  color: var(--pp-ink);
  overflow-x: clip;
}

/* Fine paper-grain dot texture over the whole page (source styles.css §02:
   "Fine paper grain over the whole page. Very low opacity — it stops large
   flat areas of bone from looking like a screen.") — v1.0.0 through v1.0.22
   omitted this rule entirely (confirmed by grep — no ::after/radial-gradient
   rule existed anywhere in this file), the exact same omission this
   project's Contact Page Pack had at its own v1.0.0 and fixed at v1.0.1
   (same shared source styles.css, same rule, same values). Source declares
   it as body::after; ported here as ::after on this pack's own root
   (Page Pack CSS may never target bare body, Page Pack Spec §5), which
   produces an identical visual result because position:fixed positions
   against the viewport regardless of which element the pseudo-element is
   attached to — a single global overlay layer over the whole viewport, not
   a per-section background, so it is inherently seamless and continuous
   across every section without any section-by-section scoping decision. */
.pp-milla-47-clean::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 200;
  pointer-events: none;
  opacity: .05;
  background-image: radial-gradient(color-mix(in oklab, var(--pp-ink) 55%, transparent) .5px, transparent .5px);
  background-size: 3px 3px;
}

/* Real WordPress typography-cascade fix (Master Workflow §44) — the active
   theme's own generated global-styles block declares a direct font-family
   rule on h1-h6 and .wp-block-button__link/.wp-element-button (confirmed
   live: both rendered Inter despite this root correctly declaring Poppins,
   while plain paragraphs — no competing theme rule — inherited correctly).
   An inherited value never competes in the same cascade contest as an
   explicit rule on the element itself, regardless of that rule's own
   specificity. font-family:inherit (not a restated literal stack) keeps
   this root as the single source of truth. */
.pp-milla-47-clean h1,
.pp-milla-47-clean h2,
.pp-milla-47-clean h3,
.pp-milla-47-clean h4,
.pp-milla-47-clean .wp-block-button__link,
.pp-milla-47-clean .wp-element-button {
  font-family: inherit;
}

/* Page-wide anchor reset — source carries this as a single global rule
   (styles.css line 148-150: a{color:var(--ink);text-decoration:none}
   a:hover{color:var(--accent)}) that every link component on the page
   (buttons included) relies on and never restates itself; this file had no
   equivalent at all. Two concrete, reported symptoms trace back to this
   gap: (1) "pricing & inclusions." (.pp-m47-inline-link) sets no color of
   its own in source OR here, so its hover colour shift was simply missing
   entirely; (2) every .pp-m47-link/.pp-m47-tour-row__link instance sets
   text-decoration:none on its own DEFAULT state but never restates it on
   :hover — leaving hover exposed to the active theme's own default link
   styling (a common WordPress/theme convention is a:hover{text-decoration:
   underline}), which would draw a real browser-native underline at its own
   font-metric position, independent of and misaligned with this file's
   custom border-bottom + background-size wipe underline — i.e. exactly a
   second, differently-positioned line on hover. text-decoration carries
   !important on both states so it can never depend on stylesheet load
   order against theme CSS of equal or higher specificity; color does not,
   so a future on-dark/on-photo variant can still override it normally,
   the same way source's own .link--on-dark:hover{color:var(--paper)}
   overrides this same global rule for that one case. */
.pp-milla-47-clean a { color: var(--pp-ink); text-decoration: none !important; }
.pp-milla-47-clean a:hover { color: var(--pp-accent); text-decoration: none !important; }

/* Source's own keyboard-focus treatment (styles.css line 156-160) — never
   removed, only restyled, per source's own comment there. This file never
   carried an equivalent, so focus indication was falling back entirely to
   the active theme's own default outline. Added, not replacing anything of
   this file's own, so no existing focus behaviour is being removed. */
.pp-milla-47-clean :focus-visible {
  outline: 2px solid var(--pp-accent);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ==========================================================================
   WordPress Flow-margin defense — every custom component that owns its own
   direct-child spacing/layout must neutralize WordPress's default
   margin-block-start injection (Master Workflow §7.1/§17). Scoped to exactly
   the components below; ordinary heading/paragraph stacking elsewhere is
   left to WordPress's own default Flow spacing.
   IMPORTANT: this reset carries !important, so it also silently zeroes any
   margin a listed container's own direct child legitimately owns on ITSELF
   (e.g. .pp-m47-specs's own margin-top) unless that rule ALSO carries
   !important — every such component-owned margin/padding-top pairing
   elsewhere in this file already does this (the *__rule separators,
   .pp-m47-faq__more, .pp-m47-cta-split__lead, etc.); v1.0.3 fixed six hero
   rules that had been missed (.pp-m47-gallery__controls, .pp-m47-specs,
   .pp-m47-specs__value, .pp-m47-price__note, .pp-m47-prod-head__lead,
   .pp-m47-prod-head__copy .pp-m47-btn-row), which is why the hero read as
   vertically compressed despite every value already matching source.
   v1.0.12 added .pp-m47-marquee__track and .pp-m47-marquee__group: both are
   real wp:group blocks with no explicit "layout" attribute, so WordPress's
   own default Flow blockGap margin-block-start lands on their direct
   children — including the marquee's own repeated-loop divs, which are
   plain HTML from a core/html block (not Gutenberg-rendered) sitting as
   ordinary DOM siblings of the one real, editable group. WordPress's own
   "* + *" injection targets any element matching that structural position
   regardless of whether it was authored as a real block or raw HTML, so it
   landed on every group *after* the first — pushing each repeated loop down
   by the same margin while the first (real) group stayed at its own
   correctly-zeroed default, exactly the "first loop right, every next loop
   lower" symptom. Neither container needs its own margin restored with
   !important afterward, since both already own their spacing entirely via
   flex `gap`, not margin.
   v1.0.14 found the same mechanism one level up: .pp-m47-cta-split itself
   (a top-level section, not an inner container) had no margin-top and was
   exposed to WordPress's default blockGap margin between it and .pp-m47-faq
   before it, on top of .pp-m47-faq's own bottom padding-block — fixed with
   margin-top:0 !important scoped to that one section.
   v1.0.17 (mobile section-spacing audit) found the identical gap was never
   actually specific to cta-split — EVERY top-level section under the page's
   one alignfull wp:group wrapper (.pp-m47-floorplan, .pp-m47-inside,
   .pp-m47-packages, .pp-m47-visit, .pp-m47-materials, .pp-m47-faq) is an
   equally exposed "later sibling" and was carrying the same unprotected
   margin-top (.pp-m47-prod-head is the sole exception, as the wrapper's
   first child — WordPress's "* + *" injection never targets a first
   child). The fixed WP blockGap value this margin injects does not scale
   with viewport, while --pp-sec-y-p (each section's own top padding) does
   — it clamps down to its 48px floor on mobile but grows past 100px on
   desktop, so the SAME extra margin reads as a large fraction of the
   mobile gap and a comparatively small one on desktop, which is why this
   went unreported through every earlier desktop-focused round and only
   became visually obvious once mobile was audited specifically. Each of
   the six sections gets its own margin-top:0 !important below, matching
   the v1.0.14 precedent exactly — this necessarily also corrects the same
   (previously unnoticed, non-source) extra gap on desktop, since the bug
   was never viewport-specific to begin with.
   ========================================================================== */
.pp-milla-47-clean .pp-m47-prod-head__grid > *,
.pp-milla-47-clean .pp-m47-gallery-col > *,
.pp-milla-47-clean .pp-m47-prod-head__copy > *,
.pp-milla-47-clean .pp-m47-specs > *,
.pp-milla-47-clean .pp-m47-specs__item > *,
.pp-milla-47-clean .pp-m47-price > *,
.pp-milla-47-clean .pp-wrap > *,
.pp-milla-47-clean .pp-m47-plan-grid > *,
.pp-milla-47-clean .pp-m47-plan-img > *,
.pp-milla-47-clean .pp-m47-plan-aside > *,
.pp-milla-47-clean .pp-m47-plan-table > *,
.pp-milla-47-clean .pp-m47-plan-table__row > *,
.pp-milla-47-clean .pp-m47-plan-table__row-inner > *,
.pp-milla-47-clean .pp-m47-marquee > *,
.pp-milla-47-clean .pp-m47-marquee__track > *,
.pp-milla-47-clean .pp-m47-marquee__group > *,
.pp-milla-47-clean .pp-m47-interior > *,
.pp-milla-47-clean .pp-m47-tour-row > *,
.pp-milla-47-clean .pp-m47-tiers > *,
.pp-milla-47-clean .pp-m47-tier > *,
.pp-milla-47-clean .pp-m47-tier__top > *,
.pp-milla-47-clean .pp-m47-tier__name-row > *,
.pp-milla-47-clean .pp-m47-tier-cta > *,
.pp-milla-47-clean .pp-m47-stock-note > *,
.pp-milla-47-clean .pp-m47-stock-note__actions > *,
.pp-milla-47-clean .pp-m47-visit-grid > *,
.pp-milla-47-clean .pp-m47-visit-copy > *,
.pp-milla-47-clean .pp-m47-track > *,
.pp-milla-47-clean .pp-m47-track__step > *,
.pp-milla-47-clean .pp-m47-testimonial > *,
.pp-milla-47-clean .pp-m47-testimonial__body > *,
.pp-milla-47-clean .pp-m47-testimonial__who > *,
.pp-milla-47-clean .pp-m47-cert-grid > *,
.pp-milla-47-clean .pp-m47-cert-copy > *,
.pp-milla-47-clean .pp-m47-faq-cols > *,
.pp-milla-47-clean .pp-m47-faq-col > *,
.pp-milla-47-clean .pp-m47-faq-row > *,
.pp-milla-47-clean .pp-m47-cta-split > *,
.pp-milla-47-clean .pp-m47-cta-split__body > *,
.pp-milla-47-clean .pp-m47-btn-row > * {
  margin-block-start: 0 !important;
  margin-block-end: 0 !important;
}


/* ==========================================================================
   Layout helpers
   ========================================================================== */
.pp-milla-47-clean .pp-wrap {
  max-width: var(--pp-maxw);
  margin: 0 auto;
  padding-inline: var(--pp-gutter);
}
.pp-milla-47-clean .pp-m47-section--p { padding-block: var(--pp-sec-y-p); }
.pp-milla-47-clean .pp-m47-bg-surface { background: var(--pp-surface); }


/* ==========================================================================
   Buttons, pills, links
   ========================================================================== */
.pp-milla-47-clean .wp-block-button__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  height: 40px;
  padding: 0 21px;
  border-radius: var(--pp-r-pill);
  font-size: 15px;
  font-weight: 500;
  white-space: nowrap;
  transition: background var(--pp-t-med), color var(--pp-t-med), border-color var(--pp-t-med);
}
.pp-milla-47-clean .pp-btn-ink .wp-block-button__link { background: var(--pp-ink); color: var(--pp-bone); border: 0; }
.pp-milla-47-clean .pp-btn-ink .wp-block-button__link:hover { background: var(--pp-accent); color: var(--pp-bone); }
.pp-milla-47-clean .pp-btn-accent .wp-block-button__link { background: var(--pp-accent-soft); color: var(--pp-ink); border: 0; }
.pp-milla-47-clean .pp-btn-accent .wp-block-button__link:hover { background: var(--pp-accent); color: var(--pp-ink); }
.pp-milla-47-clean .pp-btn-outline .wp-block-button__link { background: transparent; color: var(--pp-ink); border: 1px solid var(--pp-ink); }
.pp-milla-47-clean .pp-btn-outline .wp-block-button__link:hover { background: var(--pp-surface); color: var(--pp-ink); }
.pp-milla-47-clean .pp-btn-54 .wp-block-button__link { height: 43px; font-size: 15px; }
.pp-milla-47-clean .pp-btn-56 .wp-block-button__link { height: 45px; font-size: 15px; }
.pp-milla-47-clean .pp-btn-block { display: flex; width: 100%; }
.pp-milla-47-clean .pp-btn-block .wp-block-button__link { width: 100%; }

/* Equal-width button rows by default — excludes .pp-m47-btn-row--stack (a
   column, not a row: a flex-basis there would set height, not width — see
   the manifest's own note and the source README). */
.pp-milla-47-clean .pp-m47-btn-row.wp-block-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.pp-milla-47-clean .pp-m47-btn-row:not(.pp-m47-btn-row--stack) > .wp-block-button { flex: 1 1 200px; }
.pp-milla-47-clean .pp-m47-btn-row--stack.wp-block-buttons { flex-direction: column; width: 100%; max-width: 360px; }

/* Text link with the left-to-right underline wipe, plus a decorative arrow
   (source's own inline SVG, aria-hidden, next to the link text) reproduced
   as a background-image on a pseudo-element rather than embedded in the
   paragraph's own RichText content — RichText silently drops nested
   non-text elements from the editor's own live view even though the
   frontend renders them fine (Master Workflow §20); keeping it CSS-owned
   avoids that class of bug entirely, since the arrow carries no independent
   editorial meaning of its own (it's marked aria-hidden in source). */
/* .pp-m47-tour-row__link ("View virtual tour") shares this exact source
   class (link link--sm link--ink) with .pp-m47-link's "See the unit" /
   "Reserve now" instances, but had been given its own, separately-authored
   rule (border-bottom + text-decoration only, no background-image wipe, no
   :hover at all) instead of reusing this one — the tour-row link had no
   hover feedback whatsoever. Merged in here rather than left as a silently
   incomplete duplicate. */
/* Intentional deviation from source (user-requested, v1.0.16): source draws
   this underline as TWO independently-positioned layers — a border-bottom
   (always visible, grey) sitting in the border box, plus a background-image
   wipe (grows on hover) sitting in the padding box, immediately adjacent
   but never pixel-identical to the border. Source itself lets a sliver of
   the grey border remain visible under/beside the hover wipe; this pack now
   intentionally does not. Both lines are now the SAME background-image
   mechanism, stacked as two layers at the identical background-position/
   background-size Y-track (0 100%, height 1.5px) — layer 1 (painted on
   top) is the colour that animates 0%->100% width on hover; layer 2
   (underneath) is a static, always-100%-width grey base line. Because both
   layers use one coordinate system, hover's colour layer covers the grey
   layer with pixel-perfect, guaranteed alignment — no border-vs-background
   box-model discrepancy, no subpixel seam possible. border-bottom is
   removed entirely; padding-bottom absorbs its old 1.5px so total element
   height, text position and arrow position are all unchanged (old
   padding-bottom 3px + border-bottom 1.5px = new padding-bottom 4.5px). */
.pp-milla-47-clean .pp-m47-link a,
.pp-milla-47-clean .pp-m47-tour-row__link a {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 15px;
  font-weight: 500;
  padding-bottom: 4.5px;
  text-decoration: none;
  background-image:
    linear-gradient(var(--pp-ink), var(--pp-ink)),
    linear-gradient(var(--pp-ink-line), var(--pp-ink-line));
  background-repeat: no-repeat, no-repeat;
  background-position: 0 100%, 0 100%;
  background-size: 0% 1.5px, 100% 1.5px;
  transition: background-size .45s var(--pp-ease);
}
.pp-milla-47-clean .pp-m47-link a:hover,
.pp-milla-47-clean .pp-m47-tour-row__link a:hover { background-size: 100% 1.5px, 100% 1.5px; }
/* Source only prefixes an aria-hidden arrow icon on some .link instances
   (Reserve now / Read full story / Quality and materials / More FAQ /
   View virtual tour) — See the unit stays plain text. ::before (not
   ::after) so the icon lands before the text, matching source DOM order.
   mask-image (not background-image): source's inline <svg stroke=
   "currentColor"> recolours the arrow with the link's own text colour, so
   it shifts ink->accent on hover the same as the text does. A background-
   image with a colour baked into the data URI can never do that — masking
   the same shape and painting it with background-color:currentColor
   reproduces source's actual behaviour instead of a static icon. */
.pp-milla-47-clean .pp-m47-link--arrow a::before,
.pp-milla-47-clean .pp-m47-tour-row__link a::before {
  content: "";
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  background-color: currentColor;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2 8h11M9 4l4 4-4 4' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2 8h11M9 4l4 4-4 4' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
/* Source's "Read full story" instance carries its own inline override
   (style="border-bottom:0;padding-bottom:0") — genuinely no underline at
   all, not a bug. The underline mechanism above is now background-image,
   not border-bottom, so background-image:none is required here too or a
   1.5px line would paint flush against the (now zero-padding) text
   baseline instead of disappearing. */
.pp-milla-47-clean .pp-m47-link--noborder a { padding-bottom: 0; background-image: none; }
.pp-milla-47-clean .pp-m47-link--noborder.pp-m47-link--arrow a::before { width: 14px; height: 14px; }
.pp-milla-47-clean .pp-m47-inline-link { border-bottom: 1.5px solid var(--pp-ink); padding-bottom: 1px; text-decoration: none; }
.pp-milla-47-clean .pp-m47-inline-link--soft { border-bottom-color: var(--pp-ink-line); }
/* Quality and materials / More frequently asked questions use the bare
   source .link class (16px/9px gap/4px pad, accent hover-wipe), not
   .link--sm.link--ink like the rest of this page's text links. */
.pp-milla-47-clean .pp-m47-cert-copy .pp-m47-link a,
.pp-milla-47-clean .pp-m47-faq__more a {
  font-size: 16px;
  gap: 9px;
  padding-bottom: 5.5px;
  background-image:
    linear-gradient(var(--pp-accent), var(--pp-accent)),
    linear-gradient(var(--pp-ink-line), var(--pp-ink-line));
}
.pp-milla-47-clean .pp-m47-faq__more a::before {
  content: "";
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  background-color: currentColor;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2 8h11M9 4l4 4-4 4' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2 8h11M9 4l4 4-4 4' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
/* Quality and materials is the one .link instance in source whose arrow
   comes AFTER the text (source markup: text, then svg) — ::after, not
   ::before, unlike every other arrow-link on this page. */
.pp-milla-47-clean .pp-m47-cert-copy .pp-m47-link a::after {
  content: "";
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  background-color: currentColor;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2 8h11M9 4l4 4-4 4' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2 8h11M9 4l4 4-4 4' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

/* --- Round icon button (rail arrows) ------------------------------------ */
.pp-milla-47-clean .pp-m47-iconbtn {
  position: relative;
  width: 35px;
  height: 35px;
  flex: 0 0 auto;
  border-radius: var(--pp-r-pill);
  border: 1px solid var(--pp-ink-line);
  background: transparent;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background var(--pp-t-med), color var(--pp-t-med), border-color var(--pp-t-med);
}
.pp-milla-47-clean .pp-m47-iconbtn:hover { background: var(--pp-ink); color: var(--pp-bone); border-color: var(--pp-ink); }
.pp-milla-47-clean .pp-m47-iconbtn:disabled { opacity: .35; cursor: default; }
.pp-milla-47-clean .pp-m47-iconbtn:disabled:hover { background: transparent; color: inherit; border-color: var(--pp-ink-line); }

/* --- Tab pill (floor plan tabs, interior chips) ------------------------- */
.pp-milla-47-clean .pp-m47-tab {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 30px;
  padding: 0 14px;
  border-radius: var(--pp-r-pill);
  border: 1px solid var(--pp-ink-line);
  background: transparent;
  color: var(--pp-ink);
  font-size: 14px;
  font-weight: 500;
  font-family: inherit;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--pp-t-med), color var(--pp-t-med), border-color var(--pp-t-med);
}
.pp-milla-47-clean .pp-m47-tab[aria-selected="true"],
.pp-milla-47-clean .pp-m47-tab.is-active {
  background: var(--pp-ink);
  border-color: var(--pp-ink);
  color: var(--pp-bone);
}

/* --- Badge / chip -------------------------------------------------------- */
.pp-milla-47-clean .pp-m47-badge {
  display: inline-flex;
  align-items: center;
  height: 26px;
  padding: 0 12px;
  border-radius: var(--pp-r-pill);
  background: var(--pp-ink);
  color: var(--pp-bone);
  font-size: 12px;
  white-space: nowrap;
}
.pp-milla-47-clean .pp-m47-badge--outline {
  height: 28px;
  padding: 0 13px;
  border: 1px solid var(--pp-stone);
  background: var(--pp-bone);
  color: var(--pp-ink-72);
  letter-spacing: .04em;
}
/* Mobile-only, intentional deviation from source (user-requested, v1.0.18):
   source's .badge--outline ("Move in ready") is a single fixed size at
   every viewport (height:28px, padding:0 13px, font-size:12px inherited
   from .badge) — reads as disproportionately large/wide against the
   narrow package card specifically below source's own 900px breakpoint,
   so this pack now makes it more compact there only; desktop keeps the
   unmodified source size above. Scoped through .pp-m47-tier so it can
   never reach the unrelated "Ready now" badge (.pp-m47-stock-note__badge
   also uses .pp-m47-badge, but never --outline). */
@media (max-width: 899px) {
  .pp-milla-47-clean .pp-m47-tier .pp-m47-badge--outline {
    height: 22px;
    padding: 0 9px;
    font-size: 10.5px;
  }
}

/* ==========================================================================
   Product head
   ========================================================================== */
.pp-milla-47-clean .pp-m47-prod-head {
  background: var(--pp-surface);
  padding: calc(var(--pp-hdr-h) + clamp(20px, 3vw, 44px)) 0 clamp(48px, 7vw, 90px);
}
.pp-milla-47-clean .pp-m47-prod-head__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr));
  gap: clamp(28px, 4vw, 64px);
  align-items: start;
}

/* --- Gallery -------------------------------------------------------------- */
.pp-milla-47-clean .pp-m47-gallery {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  border-radius: var(--pp-r-lg);
  scrollbar-width: none;
}
.pp-milla-47-clean .pp-m47-gallery::-webkit-scrollbar { display: none; }
.pp-milla-47-clean .pp-m47-gallery__item.wp-block-image {
  flex: 0 0 100%;
  scroll-snap-align: start;
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: var(--pp-r-lg);
  overflow: hidden;
  background: var(--pp-surface);
  margin: 0;
}
.pp-milla-47-clean .pp-m47-gallery__item img { width: 100%; height: 100%; object-fit: cover; display: block; }

.pp-milla-47-clean .pp-m47-gallery__controls {
  margin-top: 18px !important;
  display: flex;
  align-items: center;
  gap: 16px;
}
.pp-milla-47-clean .pp-m47-dots { display: flex; gap: 6px; }
.pp-milla-47-clean .pp-m47-dot {
  display: block;
  height: 3px;
  width: 14px;
  border-radius: var(--pp-r-pill);
  background: var(--pp-ink-line);
  border: 0;
  padding: 0;
  cursor: pointer;
  transition: width .3s ease, background .3s ease;
}
.pp-milla-47-clean .pp-m47-dot.is-active { width: 26px; background: var(--pp-ink); }
.pp-milla-47-clean .pp-m47-rail__arrows { margin-left: auto; display: flex; gap: 8px; }

/* --- Spec table ------------------------------------------------------------ */
.pp-milla-47-clean .pp-m47-specs {
  margin-top: clamp(26px, 3.5vw, 34px) !important;
  display: grid;
  grid-template-columns: 1fr 1fr;
  border: 1px solid var(--pp-ink-line);
  border-radius: var(--pp-r-sm);
  overflow: hidden;
}
.pp-milla-47-clean .pp-m47-specs__item { padding: 16px 18px; }
.pp-milla-47-clean .pp-m47-specs__item:nth-child(1),
.pp-milla-47-clean .pp-m47-specs__item:nth-child(3) { border-right: 1px solid var(--pp-ink-line); }
.pp-milla-47-clean .pp-m47-specs__item:nth-child(1),
.pp-milla-47-clean .pp-m47-specs__item:nth-child(2) { border-bottom: 1px solid var(--pp-ink-line); }
.pp-milla-47-clean .pp-m47-specs__label { font-size: 12.5px; color: var(--pp-ink-56); }
.pp-milla-47-clean .pp-m47-specs__value { margin-top: 4px !important; font-size: 19px; font-weight: 500; }

/* --- Price block ------------------------------------------------------------ */
.pp-milla-47-clean .pp-m47-price__rule { border-top-width: 1px; border-color: var(--pp-ink-line); margin: clamp(24px, 3vw, 30px) 0 clamp(20px, 2.4vw, 26px) !important; }
.pp-milla-47-clean .pp-m47-price {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 18px;
}
.pp-milla-47-clean .pp-m47-price__label { flex: 1 0 100%; font-size: 12px; letter-spacing: .14em; text-transform: uppercase; color: var(--pp-ink-56); }
.pp-milla-47-clean .pp-m47-price__value { font-size: clamp(30px, 3.6vw, 40px); font-weight: 500; letter-spacing: -.024em; line-height: 1; }
.pp-milla-47-clean .pp-m47-price__vat { font-size: 14px; color: var(--pp-ink-56); font-weight: 300; }
.pp-milla-47-clean .pp-m47-price__note { flex: 1 0 100%; margin-top: 4px !important; font-size: 13.5px; line-height: 1.5; color: var(--pp-ink-56); font-weight: 300; }
.pp-milla-47-clean .pp-m47-prod-head__copy .pp-m47-btn-row { margin-top: clamp(20px, 2.6vw, 26px) !important; }

.pp-milla-47-clean .pp-m47-prod-head__title { font-size: clamp(34px, 5vw, 54px); line-height: 1.04; letter-spacing: -.024em; font-weight: 500; }
.pp-milla-47-clean .pp-m47-prod-head__lead { margin-top: 16px !important; max-width: 48ch; color: var(--pp-ink-72); font-weight: 300; font-size: clamp(16px, 1.9vw, 18px); }

/* ==========================================================================
   Floor plan
   ========================================================================== */
.pp-milla-47-clean .pp-m47-floorplan { margin-top: 0 !important; padding-block: var(--pp-sec-y-p); }
.pp-milla-47-clean .pp-m47-floorplan__h2 { font-size: clamp(28px, 4.4vw, 46px); line-height: 1.06; letter-spacing: -.022em; font-weight: 500; max-width: 18ch; }
.pp-milla-47-clean .pp-m47-floorplan__lead { margin-top: 14px !important; max-width: 44ch; font-size: clamp(15.5px, 1.8vw, 18px); line-height: 1.6; color: var(--pp-ink-72); font-weight: 300; }

.pp-milla-47-clean .pp-m47-plan-tabs { margin-top: clamp(24px, 3vw, 34px) !important; display: flex; gap: 8px; }

.pp-milla-47-clean .pp-m47-plan-grid__rule { border-top-width: 1px; border-color: var(--pp-ink-line); margin: clamp(22px, 3vw, 30px) 0 clamp(24px, 3vw, 36px) !important; }
.pp-milla-47-clean .pp-m47-plan-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(24px, 4vw, 48px);
  align-items: start;
}
/* The plan drawing renders at its own natural size — object-fit:contain,
   not the usual cover-crop every other photo on this page uses — a wide
   technical diagram was being cut off at the sides by a standard crop
   (source styles.css §12.4). */
.pp-milla-47-clean .pp-m47-plan-img { position: relative; }
.pp-milla-47-clean .pp-m47-plan-img__photo.wp-block-image { margin: 0; display: none; }
.pp-milla-47-clean .pp-m47-plan-img__photo.is-active.wp-block-image { display: block; }
.pp-milla-47-clean .pp-m47-plan-img__photo img { width: 100%; height: auto; object-fit: contain; display: block; }

.pp-milla-47-clean .pp-m47-plan-table {
  border: 1px solid var(--pp-ink-line);
  border-radius: var(--pp-r-sm);
  overflow: hidden;
  background: var(--pp-bone);
}
.pp-milla-47-clean .pp-m47-plan-table__row-rule { border-top-width: 1px; border-color: var(--pp-ink-line); margin: 0 !important; }
.pp-milla-47-clean .pp-m47-plan-table__row-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 18px;
}
.pp-milla-47-clean .pp-m47-plan-table__label { font-size: 14.5px; color: var(--pp-ink-56); }
.pp-milla-47-clean .pp-m47-plan-table__value { font-size: 14.5px; font-weight: 500; text-align: right; }
.pp-milla-47-clean .pp-m47-plan-dl.wp-block-buttons { margin-top: clamp(20px, 2.5vw, 26px) !important; max-width: 460px; }
/* Source's download icon (script-free inline svg, before the button text) —
   reproduced the same way as the arrow-link icons elsewhere in this file
   (Master Workflow §20: RichText silently drops nested non-text elements
   from the editor's own live view, even though the frontend renders them
   fine, so a real <svg> inside this wp:button's RichText content is not a
   safe option). The button link is already display:inline-flex with its
   own gap:10px (matching source .btn's gap exactly), so the icon needs no
   extra spacing/alignment rules of its own — it lands before the text,
   vertically centered, 10px from it, for free. White stroke because this
   specific button is always the pp-btn-ink (dark-background) variant. */
.pp-milla-47-clean .pp-m47-plan-dl .wp-block-button__link::before {
  content: "";
  flex: 0 0 auto;
  width: 17px;
  height: 17px;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M10 3v10m0 0 4-4m-4 4-4-4M4 16h12' fill='none' stroke='%23FFFFFF' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}


/* ==========================================================================
   Inside Milla 47 (interior chips + rail)
   ========================================================================== */
.pp-milla-47-clean .pp-m47-inside { margin-top: 0 !important; padding-block: var(--pp-sec-y-p); }
.pp-milla-47-clean .pp-m47-inside__h2 { font-size: clamp(28px, 4.4vw, 46px); line-height: 1.06; letter-spacing: -.022em; font-weight: 500; }

.pp-milla-47-clean .pp-m47-chips {
  margin-top: clamp(20px, 2.6vw, 28px) !important;
  display: flex;
  gap: 8px;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  touch-action: pan-x;
}
.pp-milla-47-clean .pp-m47-chips::-webkit-scrollbar { display: none; }

.pp-milla-47-clean .pp-m47-interior {
  margin-top: clamp(20px, 2.6vw, 28px);
  display: flex;
  gap: 12px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  padding: 0 var(--pp-rail-pad) 6px;
  scroll-padding-left: var(--pp-rail-pad);
  scrollbar-width: none;
}
.pp-milla-47-clean .pp-m47-interior::-webkit-scrollbar { display: none; }
.pp-milla-47-clean .pp-m47-interior__item.wp-block-image {
  flex: 0 0 min(84%, 720px);
  scroll-snap-align: start;
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: var(--pp-r-md);
  overflow: hidden;
  background: var(--pp-surface);
  margin: 0;
}
.pp-milla-47-clean .pp-m47-interior__item img { width: 100%; height: 100%; object-fit: cover; display: block; }

.pp-milla-47-clean .pp-m47-tour-row {
  margin-top: clamp(20px, 2.6vw, 28px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
}
.pp-milla-47-clean .pp-m47-tour-row__label { font-size: 16px; font-weight: 500; }
/* .pp-m47-tour-row__link a's styling now lives with .pp-m47-link above —
   same source class (link link--sm link--ink), merged so it gets the
   background-image hover-wipe and :hover rule it was missing here. */

/* ==========================================================================
   Packages (tiers)
   ========================================================================== */
.pp-milla-47-clean .pp-m47-packages { margin-top: 0 !important; background: var(--pp-surface); padding-block: var(--pp-sec-y-p); }
.pp-milla-47-clean .pp-m47-packages__h2 { font-size: clamp(28px, 4.4vw, 46px); line-height: 1.06; letter-spacing: -.022em; font-weight: 500; }
.pp-milla-47-clean .pp-m47-packages__lead { margin-top: 14px !important; max-width: 46ch; font-size: clamp(15.5px, 1.8vw, 18px); line-height: 1.6; color: var(--pp-ink-72); font-weight: 300; }

.pp-milla-47-clean .pp-m47-tiers {
  margin-top: clamp(26px, 3.5vw, 40px) !important;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
  gap: clamp(14px, 1.8vw, 20px);
  align-items: stretch;
}
.pp-milla-47-clean .pp-m47-tier {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: clamp(22px, 2.4vw, 28px);
  border-radius: var(--pp-r-md);
  background: var(--pp-bone);
  border: 1px solid var(--pp-ink-line);
}
.pp-milla-47-clean .pp-m47-tier--1 { background: color-mix(in oklab, var(--pp-bone) 35%, transparent); }
.pp-milla-47-clean .pp-m47-tier--2 { background: color-mix(in oklab, var(--pp-bone) 50%, transparent); }
.pp-milla-47-clean .pp-m47-tier--3 { background: var(--pp-bone); }
.pp-milla-47-clean .pp-m47-tier--rec { border-color: var(--pp-ink); }
.pp-milla-47-clean .pp-m47-tier__top { display: flex; flex-direction: column; gap: 6px; }
.pp-milla-47-clean .pp-m47-tier__name-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
/* line-height:normal — same theme-interference fix as .pp-m47-faq__q
   (v1.0.13) and .pp-m47-track__step-title: a real <h3> with no explicit
   line-height inherits the active theme's own heading default instead of
   source's plain browser "normal" (source's .tier h3 also sets none). */
.pp-milla-47-clean .pp-m47-tier__name { font-size: 19px; font-weight: 500; line-height: normal; letter-spacing: normal; }
/* Higher specificity than the generic body-paragraph rule below on purpose
   — a bare .pp-m47-tier__price class alone loses that fight and silently
   renders at the muted paragraph weight/colour (source styles.css §12.6). */
.pp-milla-47-clean .pp-m47-tier__top .pp-m47-tier__price { color: var(--pp-ink); font-size: 17px; font-weight: 700; letter-spacing: -.01em; }
.pp-milla-47-clean .pp-m47-tier__adds { margin-top: 14px !important; font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--pp-ink-56); }
/* Mobile-only, intentional deviation from source (user-requested, v1.0.18):
   source's .tier__adds ("Adds") is 12px at every viewport; this pack now
   bumps it slightly below source's 900px breakpoint only, where it reads
   too small next to the rest of the card. Letter-spacing/uppercase/colour
   unchanged, per instruction. Desktop keeps the unmodified source size. */
@media (max-width: 899px) {
  .pp-milla-47-clean .pp-m47-tier__adds { font-size: 13px; }
}
.pp-milla-47-clean .pp-m47-tier__adds + .pp-m47-tier__body { margin-top: 6px !important; }
.pp-milla-47-clean .pp-m47-tier p:not(.pp-m47-tier__price):not(.pp-m47-tier__adds) { font-size: 14.5px; line-height: 1.55; color: var(--pp-ink-72); font-weight: 300; }
.pp-milla-47-clean .pp-m47-tier__body { margin-top: 14px !important; }

.pp-milla-47-clean .pp-m47-tier-cta__rule { border-top-width: 1px; border-color: var(--pp-ink-line); margin: clamp(24px, 3vw, 32px) 0 clamp(22px, 2.6vw, 28px) !important; }
.pp-milla-47-clean .pp-m47-tier-cta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  gap: 14px;
}
.pp-milla-47-clean .pp-m47-tier-cta__h3 { font-size: clamp(28px, 4.4vw, 46px); line-height: 1.06; letter-spacing: -.022em; font-weight: 500; }
.pp-milla-47-clean .pp-m47-tier-cta__body { margin: 0; max-width: 34ch; font-size: 14.5px; line-height: 1.55; color: var(--pp-ink-72); font-weight: 300; }
.pp-milla-47-clean .pp-m47-tier-cta__btn.wp-block-buttons { align-self: stretch; }

.pp-milla-47-clean .pp-m47-stock-note__rule { border-top-width: 1px; border-color: var(--pp-ink-line); margin: clamp(18px, 2.4vw, 24px) 0 !important; }
.pp-milla-47-clean .pp-m47-stock-note {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  gap: 12px;
}
.pp-milla-47-clean .pp-m47-stock-note__badge { flex: 0 0 auto; }
.pp-milla-47-clean .pp-m47-stock-note__body { margin: 0; max-width: 34ch; font-size: 14.5px; line-height: 1.55; color: var(--pp-ink-72); font-weight: 300; }
.pp-milla-47-clean .pp-m47-stock-note__actions { display: flex; align-items: center; justify-content: flex-start; gap: 10px; flex-wrap: wrap; }
.pp-milla-47-clean .pp-m47-stock-note__dot { color: var(--pp-ink-56); }

/* ==========================================================================
   Visit
   ========================================================================== */
.pp-milla-47-clean .pp-m47-visit { margin-top: 0 !important; padding-block: var(--pp-sec-y-p); }
.pp-milla-47-clean .pp-m47-visit-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(28px, 4vw, 56px);
  align-items: stretch;
}
.pp-milla-47-clean .pp-m47-visit-img.wp-block-image {
  position: relative;
  min-height: 260px;
  border-radius: var(--pp-r-lg);
  overflow: hidden;
  background: var(--pp-surface);
  margin: 0;
}
.pp-milla-47-clean .pp-m47-visit-img img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }

.pp-milla-47-clean .pp-m47-visit__h2 { font-size: clamp(28px, 4vw, 44px); line-height: 1.06; letter-spacing: -.022em; font-weight: 500; max-width: 16ch; }
.pp-milla-47-clean .pp-m47-visit__lead { margin-top: 12px !important; max-width: 42ch; font-size: clamp(15.5px, 1.8vw, 17px); line-height: 1.55; color: var(--pp-ink-72); font-weight: 300; }

/* --- Four-step vertical tracker ------------------------------------------- */
.pp-milla-47-clean .pp-m47-track { margin-top: clamp(22px, 2.8vw, 30px) !important; display: flex; flex-direction: column; }
.pp-milla-47-clean .pp-m47-track__step {
  position: relative;
  padding: 0 0 16px 24px;
}
.pp-milla-47-clean .pp-m47-track__step--last { padding-bottom: 0; }
/* Dot + connecting line, drawn per-step so no extra non-editable markup is
   needed for the rail itself (source has separate .track__rail elements;
   here each step draws its own dot via ::before and its own line via
   ::after, which is purely decorative rail chrome). Dot top:5px / line
   top:15px match source's rail exactly: a flex column (dot margin-top:5px,
   10px dot height, then the line) — not the 6px/16px this pack had before.
   The dot needs its own explicit box-sizing:border-box — this file has no
   global *, *::before, *::after border-box reset the way source's own
   styles.css does, so without it the browser default (content-box) adds
   the 1px border OUTSIDE the declared 10px width/height, rendering a true
   12px-diameter circle whose real center sits 1px right of x=5 — 1px off
   from .track__line's left:4.5px (itself already centered under a TRUE
   10px-wide box). border-box makes width/height include the border, so
   the rendered circle is genuinely 10px across and both centerlines land
   on the same x=5. */
.pp-milla-47-clean .pp-m47-track__step::before {
  content: "";
  position: absolute;
  box-sizing: border-box;
  left: 0; top: 5px;
  width: 10px; height: 10px;
  border-radius: var(--pp-r-pill);
  border: 1px solid var(--pp-ink-line);
  background: var(--pp-bone);
}
.pp-milla-47-clean .pp-m47-track__step--on::before { background: var(--pp-ink); border-color: var(--pp-ink); }
.pp-milla-47-clean .pp-m47-track__step::after {
  content: "";
  position: absolute;
  left: 4.5px; top: 15px; bottom: 0;
  width: 1px;
  background: var(--pp-ink-line);
}
.pp-milla-47-clean .pp-m47-track__step--last::after { display: none; }
/* line-height:normal is required, not decorative — without it this element
   inherits the active WordPress theme's own default paragraph line-height
   (measured live: 25.57px rendered height) instead of the plain browser
   default source's own unstyled <p> renders with (measured on source:
   23.5px). The dot itself is anchored to a fixed 5px-below-row-top offset
   (unaffected either way), but the ~2px-per-row line-height difference
   inflates every .track__step's own height, so it accumulates down all 4
   rows — each dot drifting further from its source position by the time
   the tracker reaches "Manufacture and install" (~6px of accumulated drift
   measured live before this fix). Master Workflow §44-pattern: a real
   WordPress theme default, not a Page Pack CSS value. */
.pp-milla-47-clean .pp-m47-track__step-title { font-size: 15.5px; font-weight: 500; line-height: normal; color: var(--pp-ink-72); }
.pp-milla-47-clean .pp-m47-track__step--on .pp-m47-track__step-title { color: var(--pp-ink); }
.pp-milla-47-clean .pp-m47-track__step-note { display: block; margin-top: 3px !important; font-size: 13.5px; line-height: 1.5; color: var(--pp-ink-56); font-weight: 300; }

.pp-milla-47-clean .pp-m47-visit-copy .pp-m47-btn-row { margin-top: clamp(24px, 3vw, 32px) !important; }
.pp-milla-47-clean .pp-m47-visit-note { margin-top: 12px !important; font-size: 13.5px; color: var(--pp-ink-56); font-weight: 300; }

.pp-milla-47-clean .pp-m47-testimonial__rule { border-top-width: 1px; border-color: var(--pp-ink-line); margin: clamp(24px, 3vw, 32px) 0 clamp(20px, 2.4vw, 26px) !important; }
.pp-milla-47-clean .pp-m47-testimonial {
  display: flex;
  gap: 16px;
  align-items: flex-start;
}
.pp-milla-47-clean .pp-m47-testimonial__portrait.wp-block-image {
  flex: 0 0 62px;
  width: 62px; height: 62px;
  border-radius: var(--pp-r-pill);
  overflow: hidden;
  background: var(--pp-surface);
  margin: 0;
}
.pp-milla-47-clean .pp-m47-testimonial__portrait img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pp-milla-47-clean .pp-m47-testimonial__quote { font-size: 15px; line-height: 1.5; max-width: 38ch; font-style: normal; }
.pp-milla-47-clean .pp-m47-testimonial__who {
  margin-top: 10px !important;
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  font-size: 13.5px;
  color: var(--pp-ink-56);
}
.pp-milla-47-clean .pp-m47-testimonial__name { font-size: 13.5px; color: var(--pp-ink-56); }

/* ==========================================================================
   Materials — marquee + certifications
   ========================================================================== */
.pp-milla-47-clean .pp-m47-materials { margin-top: 0 !important; padding-block: var(--pp-sec-y-p); overflow: hidden; }
.pp-milla-47-clean .pp-m47-materials__h2 { font-size: clamp(28px, 4.4vw, 46px); line-height: 1.06; letter-spacing: -.022em; font-weight: 500; max-width: 16ch; }
.pp-milla-47-clean .pp-m47-materials__lead { margin-top: 14px !important; max-width: 46ch; font-size: clamp(15.5px, 1.8vw, 18px); line-height: 1.6; color: var(--pp-ink-72); font-weight: 300; }

.pp-milla-47-clean .pp-m47-marquee {
  position: relative;
  margin-top: clamp(28px, 4vw, 44px) !important;
}
.pp-milla-47-clean .pp-m47-marquee__rule { border-top-width: 1px; border-color: var(--pp-ink-line); margin: 0 !important; }
.pp-milla-47-clean .pp-m47-marquee__rule--top { margin-bottom: clamp(10px, 2vw, 16px) !important; }
.pp-milla-47-clean .pp-m47-marquee__rule--bottom { margin-top: clamp(10px, 2vw, 16px) !important; }
.pp-milla-47-clean .pp-m47-marquee__track {
  display: flex;
  width: max-content;
  animation: pp-m47-marquee 32s linear infinite;
}
.pp-milla-47-clean .pp-m47-marquee:hover .pp-m47-marquee__track { animation-play-state: paused; }
.pp-milla-47-clean .pp-m47-marquee__group {
  display: flex;
  align-items: center;
  gap: clamp(46px, 8vw, 100px);
  padding-right: clamp(46px, 8vw, 100px);
}
.pp-milla-47-clean .pp-m47-marquee__group img,
.pp-milla-47-clean .pp-m47-logo.wp-block-image { width: auto; display: block; flex: 0 0 auto; margin: 0; opacity: .72; }
.pp-milla-47-clean .pp-m47-marquee__group img { opacity: .72; }
.pp-milla-47-clean .pp-m47-logo--velux img, .pp-milla-47-clean img.pp-m47-logo--velux { height: clamp(22px, 3vw, 30px); width: auto; }
.pp-milla-47-clean .pp-m47-logo--ruukki img, .pp-milla-47-clean img.pp-m47-logo--ruukki { height: clamp(20px, 2.7vw, 28px); width: auto; }
.pp-milla-47-clean .pp-m47-logo--hansgrohe img, .pp-milla-47-clean img.pp-m47-logo--hansgrohe { height: clamp(18px, 2.4vw, 25px); width: auto; }
.pp-milla-47-clean .pp-m47-logo--tikkurila img, .pp-milla-47-clean img.pp-m47-logo--tikkurila { height: clamp(20px, 2.7vw, 28px); width: auto; }

@keyframes pp-m47-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }

.pp-milla-47-clean .pp-m47-cert-grid {
  margin-top: clamp(34px, 4.5vw, 56px) !important;
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(24px, 4vw, 56px);
  align-items: center;
}
/* No font-size/line-height/font-weight here on purpose: source's own
   typography rule for this copy is ".cert-copy p + p" (a SECOND paragraph
   adjacent to a first one) — Milla 47's cert-copy has only ONE <p>, so that
   rule never actually matches it in source, and the paragraph renders at
   plain unstyled default text (no other rule in source's styles.css touches
   a bare <p>). This pack was previously restating the p+p sizing here
   unconditionally, which doesn't match what source actually renders —
   removed so this paragraph inherits the same way source's does. */
.pp-milla-47-clean .pp-m47-cert-copy__body { max-width: 24ch; }
.pp-milla-47-clean .pp-m47-cert-copy .pp-m47-link { margin-top: 20px !important; }
.pp-milla-47-clean .pp-m47-cert-marks {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(22px, 3.2vw, 44px);
  align-items: center;
  justify-items: center;
}
.pp-milla-47-clean .pp-m47-cert-mark.wp-block-image { margin: 0; }
.pp-milla-47-clean .pp-m47-cert-mark img {
  max-width: 100%;
  max-height: clamp(72px, 9vw, 118px);
  width: auto; height: auto;
  display: block;
}

/* ==========================================================================
   FAQ — non-exclusive accordion (source script.js §09: exclusivity is
   opt-in via a [data-faq-exclusive] wrapper this page's FAQ does not carry
   — multiple answers may be open at once here, unlike an exclusive FAQ on
   a different page. Do not add that attribute to this section.)
   ========================================================================== */
.pp-milla-47-clean .pp-m47-faq { margin-top: 0 !important; background: var(--pp-surface); padding-block: var(--pp-sec-y-p); }
.pp-milla-47-clean .pp-m47-faq__h2 { font-size: clamp(28px, 4.4vw, 46px); line-height: 1.06; letter-spacing: -.022em; font-weight: 500; max-width: 16ch; }

/* margin-top matches source's own inline override on this specific
   .faq-cols instance (style="margin-top:clamp(26px,3.5vw,40px)"), not the
   larger clamp(28px,4vw,52px) the bare .faq-cols class defaults to
   elsewhere on the shared site. Needs !important: direct child of .pp-wrap,
   on this file's Flow-margin-defense reset list. */
.pp-milla-47-clean .pp-m47-faq-cols {
  margin-top: clamp(26px, 3.5vw, 40px) !important;
  max-width: 1100px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr));
  gap: 0 clamp(28px, 5vw, 64px);
  align-items: start;
}
.pp-milla-47-clean .pp-m47-faq-cols__rule { border-top-width: 1px; border-color: var(--pp-ink-line); margin: 0 !important; }
.pp-milla-47-clean .pp-m47-faq-col { display: flex; flex-direction: column; }
.pp-milla-47-clean .pp-m47-faq-row__rule { border-top-width: 1px; border-color: var(--pp-ink-line); margin: 0 !important; }

/* line-height:normal is required, not decorative — this is a real <h3>
   heading (Master Workflow §44 territory: the active theme's own global
   styles bundle a line-height with every heading level's font-family
   preset), while source's equivalent element reaches the same "no line-
   height set anywhere" state differently (.faq h3{font:inherit} strips the
   browser's own h3 default back to inherit, then the source .faq__q button
   inside it never sets line-height either, landing on plain browser
   "normal"). Without this, every FAQ question - and therefore every row's
   own height, expanded or collapsed - inflates uniformly, which is why the
   whole grid, every divider after row 1, and the final "More FAQ" gap all
   drift progressively lower despite their own spacing values already
   matching source exactly. */
.pp-milla-47-clean .pp-m47-faq__q {
  position: relative;
  margin: 0;
  padding: 20px 28px 20px 0;
  font: inherit;
  font-size: 16px;
  font-weight: 500;
  line-height: normal;
  letter-spacing: normal;
  cursor: pointer;
  transition: color .2s;
}
.pp-milla-47-clean .pp-m47-faq__q:hover { color: var(--pp-accent); }
.pp-milla-47-clean .pp-m47-faq__q::after {
  content: "+";
  position: absolute;
  right: 0;
  top: 20px;
  width: 20px;
  font-size: 20px;
  line-height: 1;
  font-weight: 300;
  color: var(--pp-ink-56);
  text-align: right;
}
.pp-milla-47-clean .pp-m47-faq-row--open .pp-m47-faq__q::after { content: "\2212"; }

.pp-milla-47-clean .pp-m47-faq__a {
  margin: 0 !important;
  padding: 0 0 22px;
  font-size: 15.5px;
  line-height: 1.6;
  color: var(--pp-ink-72);
  font-weight: 300;
  max-width: 52ch;
  display: none;
}
.pp-milla-47-clean .pp-m47-faq-row--open .pp-m47-faq__a { display: block; }

.pp-milla-47-clean .pp-m47-faq__more { margin-top: clamp(40px, 5vw, 52px) !important; }


/* ==========================================================================
   Closing split CTA
   ========================================================================== */
/* Source's .cta-split carries no top spacing of its own — the visible gap
   after FAQ is entirely FAQ's own bottom padding-block. This section is a
   direct child of the page's single alignfull wp:group wrapper alongside
   every other top-level section, none of which neutralize WordPress's
   default Flow margin-block-start injection on "* + *" — margin-top:0
   !important reproduces source's actual (implicit) zero rather than
   whatever blockGap the active theme injects between sections here. */
.pp-milla-47-clean .pp-m47-cta-split {
  display: flex;
  flex-direction: column;
  margin-top: 0 !important;
  --pp-split-h: clamp(300px, 68vw, 400px);
}
.pp-milla-47-clean .pp-m47-cta-split__media {
  position: relative;
  height: var(--pp-split-h);
  background: var(--pp-tint);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.pp-milla-47-clean .pp-m47-cta-split__render.wp-block-image { margin: 0; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; }
.pp-milla-47-clean .pp-m47-cta-split__render img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: clamp(24px, 5vw, 56px);
  box-sizing: border-box;
}
/* box-sizing:border-box is load-bearing here, not decorative — source's
   universal *{box-sizing:border-box} reset (styles.css line 116) has no
   equivalent in this file (Master Workflow §7.1: added per-element only
   where proven necessary, not as a global reset). Without it, this panel's
   desktop flex:1 1 50% (below) targets the CONTENT box, so its own padding
   (clamp(36,6vw,72) block + clamp(56,6vw,112) left at desktop) is added on
   top of that 50% instead of living inside it — the resulting overflow
   forces flexbox to shrink BOTH this panel and its sibling .cta-split__media
   to fit, taking the padding-free media panel down with it even though
   nothing about the media panel itself is wrong. That is the actual
   mechanism behind "the house render is too small with excess lavender
   space above it": the render's own container was never the full 50% share
   source gives it. */
.pp-milla-47-clean .pp-m47-cta-split__body {
  min-height: var(--pp-split-h);
  padding: clamp(36px, 6vw, 72px) var(--pp-gutter);
  background: var(--pp-bone);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  box-sizing: border-box;
}
.pp-milla-47-clean .pp-m47-cta-split__h2 { font-size: clamp(28px, 5vw, 48px); line-height: 1.06; letter-spacing: -.022em; font-weight: 400; }
.pp-milla-47-clean .pp-m47-cta-split__lead { margin-top: 14px !important; max-width: 46ch; color: var(--pp-ink-72); font-size: clamp(15.5px, 1.9vw, 18px); line-height: 1.55; font-weight: 300; }
/* Needs !important: .pp-m47-cta-split__body is on this file's Flow-margin-
   defense reset list (its own direct children's margin-block-start is
   zeroed !important), so this button row's own legitimate margin-top was
   being silently zeroed the same way .pp-m47-specs and five other rules
   were in v1.0.3 — the exact "subtitle sits too close to the first CTA"
   symptom reported for this section. */
.pp-milla-47-clean .pp-m47-cta-split__body .pp-m47-btn-row { margin-top: clamp(24px, 3vw, 32px) !important; }

/* ==========================================================================
   Desktop layer — the design's single breakpoint (min-width: 900px)
   Preserved exactly at the source's own 900px cut, not Gutenberg's built-in
   782px default (Master Workflow §7.6/§46) — tested at 901/899.
   ========================================================================== */
@media (min-width: 900px) {
  .pp-milla-47-clean .pp-m47-plan-grid { grid-template-columns: 2fr 1fr; align-items: center; }

  .pp-milla-47-clean .pp-m47-visit-grid { grid-template-columns: 1fr 1fr; }
  .pp-milla-47-clean .pp-m47-visit-img.wp-block-image { min-height: 100%; }

  .pp-milla-47-clean .pp-m47-cert-grid { grid-template-columns: .85fr 1.3fr; align-items: end; }

  .pp-milla-47-clean .pp-m47-faq-cols { grid-template-columns: repeat(auto-fit, minmax(min(100%, 440px), 1fr)); gap: 0 clamp(30px, 5vw, 72px); }

  .pp-milla-47-clean .pp-m47-cta-split { flex-direction: row; }
  .pp-milla-47-clean .pp-m47-cta-split__media,
  .pp-milla-47-clean .pp-m47-cta-split__body { flex: 1 1 50%; min-width: 0; }
  .pp-milla-47-clean .pp-m47-cta-split__media { height: auto; }
  .pp-milla-47-clean .pp-m47-cta-split__body {
    min-height: 0;
    align-items: flex-start;
    text-align: left;
    padding-left: clamp(56px, 6vw, 112px);
  }

  /* flex-wrap is the overflow safety valve here — the nowrap sentence below
     has a fixed minimum width it never shrinks under, so on narrower
     desktop widths (~900–1150px) there isn't room for badge + sentence +
     actions on one line without it (source styles.css §12.6 + README). */
  .pp-milla-47-clean .pp-m47-stock-note { flex-direction: row; flex-wrap: wrap; align-items: center; text-align: left; gap: 12px 24px; }
  .pp-milla-47-clean .pp-m47-stock-note__body { flex: 1 1 auto; max-width: none; white-space: nowrap; }
  .pp-milla-47-clean .pp-m47-stock-note__actions { justify-content: flex-start; flex: 0 0 auto; gap: 10px; }

  /* Same grid as .pp-m47-tiers above it — not just three items in a row,
     but headline/subtext/button sharing the tier cards' own column lines
     (source styles.css §12.6 + README's "Make it yours" note). */
  .pp-milla-47-clean .pp-m47-tier-cta {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
    align-items: center;
    text-align: left;
    gap: clamp(14px, 1.8vw, 20px);
  }
  .pp-milla-47-clean .pp-m47-tier-cta__body { max-width: none; }
  .pp-milla-47-clean .pp-m47-tier-cta__btn.wp-block-buttons { align-self: center; width: 100%; justify-content: center; }
}


/* ==========================================================================
   Reduced motion
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .pp-milla-47-clean .pp-m47-marquee__track { animation-duration: .001ms !important; animation-iteration-count: 1 !important; }
  .pp-milla-47-clean .pp-m47-gallery,
  .pp-milla-47-clean .pp-m47-interior,
  .pp-milla-47-clean .pp-m47-chips { scroll-behavior: auto; }
}
