/* ==========================================================================
   MyCabin Contact Page Pack — frontend.css
   Clean-room build from source-design/contact-original.zip. Every selector
   is scoped under .pp-contact-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. This
   page's own source styles.css/script.js are confirmed to be the exact
   same shared site-wide files Milla 47's source used (identical :root
   token block) — only the subset of rules this page's own DOM references
   was ported.
   ========================================================================== */

.pp-contact-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-good:         #4F7A44;
  --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-bone-80: color-mix(in oklab, var(--pp-bone) 80%, transparent);
  --pp-bone-60: color-mix(in oklab, var(--pp-bone) 60%, 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-r-pill: 999px;
  --pp-r-card: 11px;
  --pp-r-lg:   10px;
  --pp-r-xs:   7px;

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

  font-family: "Poppins", "Helvetica Neue", Helvetica, sans-serif;
  color: var(--pp-ink);
  background: var(--pp-bone);
  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 omitted this
   rule entirely, which is the exact cause of the flat-background regression
   reported this round. Source declares it as body::after; ported here as
   ::after on this pack's own root (Page Pack Spec scoping — CSS may never
   target bare `body`), which produces the identical visual result because
   position:fixed positions against the viewport regardless of which
   element the pseudo-element is attached to. */
.pp-contact-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, which beats
   an inherited value regardless of specificity. font-family:inherit (not a
   restated literal stack) keeps this root as the single source of truth —
   confirmed necessary on every prior Page Pack in this project. */
.pp-contact-clean h1,
.pp-contact-clean h2,
.pp-contact-clean h3,
.pp-contact-clean h4,
.pp-contact-clean .wp-block-button__link,
.pp-contact-clean .wp-element-button {
  font-family: inherit;
}

/* Page-wide anchor reset — source's own global a{color:ink;text-decoration:
   none} a:hover{color:accent} (styles.css §02), confirmed directly from
   source this round rather than inferred (Milla 47 v1.0.15 found this
   missing after the fact; built in from the start here). text-decoration
   carries !important so it can never depend on load order against theme/
   editor CSS of equal or higher specificity, matching the established
   defensive pattern; color does not, so a future variant can still
   override it normally. */
.pp-contact-clean a { color: var(--pp-ink); text-decoration: none !important; }
.pp-contact-clean a:hover { color: var(--pp-accent); text-decoration: none !important; }
.pp-contact-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 Flow
   margin-block-start injection (Master Workflow §7.1/§17), confirmed as a
   recurring, real mechanism across every prior Page Pack in this project.
   Scoped to exactly the components below; ordinary heading/paragraph
   stacking elsewhere is left to WordPress's own default Flow spacing.
   Top-level sections (.pp-contact-hero, .pp-contact-team, .pp-contact-
   form-section, .pp-contact-visit) also each get their own margin-top:0
   !important below, matching the pattern Milla 47 v1.0.17 found necessary
   at that structural level (every section under one alignfull root wrapper
   is a "later sibling" exposed to the same injection).
   ========================================================================== */
.pp-contact-clean .pp-contact-hero > *,
.pp-contact-clean .pp-contact-hero__text > *,
.pp-contact-clean .pp-contact-hero__btns > *,
.pp-contact-clean .pp-contact-team > *,
.pp-contact-clean .pp-contact-team-grid > *,
.pp-contact-clean .pp-wrap > *,
.pp-contact-clean .pp-contact-card__head-text > *,
.pp-contact-clean .pp-contact-card > *,
.pp-contact-clean .pp-contact-card__lines > *,
.pp-contact-clean .pp-contact-card__line > *,
.pp-contact-clean .pp-contact-form-section > *,
.pp-contact-clean .pp-contact-form-row > *,
.pp-contact-clean .pp-contact-form__copy > *,
.pp-contact-clean .pp-contact-trust > *,
.pp-contact-clean .pp-contact-trust__item > *,
.pp-contact-clean .pp-contact-visit > *,
.pp-contact-clean .pp-contact-visit-grid > *,
.pp-contact-clean .pp-contact-visit-stack > *,
.pp-contact-clean .pp-contact-visit-card > *,
.pp-contact-clean .pp-contact-visit-card__actions > *,
.pp-contact-clean .pp-contact-company-card > *,
.pp-contact-clean .pp-contact-company-card__rows > *,
.pp-contact-clean .pp-contact-company-card__row > * {
  margin-block-start: 0 !important;
  margin-block-end: 0 !important;
}

/* ==========================================================================
   Layout helpers
   ========================================================================== */
/* box-sizing:border-box is load-bearing, not decorative (Milla 47 v1.0.14
   lesson) — without it, max-width:1280px + padding-inline would render up
   to 1280px+2×gutter wide (padding content-box-added beyond the cap)
   instead of the source's true border-box-capped 1280px, since source's
   own universal *{box-sizing:border-box} reset has no equivalent here. */
.pp-contact-clean .pp-wrap {
  box-sizing: border-box;
  max-width: var(--pp-maxw);
  margin: 0 auto;
  padding-inline: var(--pp-gutter);
}
.pp-contact-clean .icon { flex: 0 0 auto; }

/* ==========================================================================
   Buttons — same shared .btn system as every other Page Pack in this
   project (base + variant classes ported 1:1 from source's own values).
   ========================================================================== */
.pp-contact-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-contact-clean .pp-btn-ink .wp-block-button__link { background: var(--pp-ink); color: var(--pp-bone); border: 0; }
.pp-contact-clean .pp-btn-ink .wp-block-button__link:hover { background: var(--pp-accent); color: var(--pp-bone); }
.pp-contact-clean .pp-btn-outline .wp-block-button__link { background: transparent; color: var(--pp-ink); border: 1px solid var(--pp-ink); }
.pp-contact-clean .pp-btn-outline .wp-block-button__link:hover { background: var(--pp-surface); color: var(--pp-ink); }
.pp-contact-clean .pp-btn-light .wp-block-button__link { background: var(--pp-bone); color: var(--pp-ink); border: 0; }
.pp-contact-clean .pp-btn-light .wp-block-button__link:hover { background: var(--pp-accent-soft); color: var(--pp-ink); }
.pp-contact-clean .pp-btn-ghost .wp-block-button__link {
  background: color-mix(in oklab, var(--pp-ink) 30%, transparent);
  color: var(--pp-bone);
  border: 1px solid color-mix(in oklab, var(--pp-bone) 60%, transparent);
}
.pp-contact-clean .pp-btn-ghost .wp-block-button__link:hover {
  background: color-mix(in oklab, var(--pp-bone) 14%, transparent);
  border-color: var(--pp-bone);
  color: var(--pp-bone);
}
.pp-contact-clean .pp-btn-block { display: flex; width: 100%; }
.pp-contact-clean .pp-btn-block .wp-block-button__link { width: 100%; }

/* Text link with a leading arrow — same aria-hidden-inline-SVG-before-text
   pattern as Milla 47's .pp-m47-link--arrow, reproduced with mask-image +
   background-color:currentColor (not a static background-image) so the
   arrow recolours with the link's own text colour on hover, matching
   source's stroke="currentColor" behaviour exactly (Milla 47 v1.0.15
   lesson). */
.pp-contact-clean .pp-contact-link-arrow a {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 16px;
  font-weight: 500;
  white-space: nowrap;
}
.pp-contact-clean .pp-contact-link-arrow 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");
}

/* ==========================================================================
   Hero
   ========================================================================== */
.pp-contact-clean .pp-contact-hero {
  position: relative;
  overflow: hidden;
  height: clamp(420px, 56vw, 520px);
  margin-top: 0 !important;
}
.pp-contact-clean .pp-contact-hero__bg.wp-block-image {
  position: absolute;
  inset: 0;
  z-index: 1;
  margin: 0;
  width: 100%;
  height: 100%;
}
.pp-contact-clean .pp-contact-hero__bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 55%;
  display: block;
}
.pp-contact-clean .pp-contact-hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(180deg, transparent 25%, color-mix(in oklab, var(--pp-ink) 82%, transparent) 90%);
}
.pp-contact-clean .pp-contact-hero__inner {
  box-sizing: border-box;
  position: relative;
  z-index: 3;
  height: 100%;
  max-width: var(--pp-maxw);
  margin: 0 auto;
  display: flex;
  align-items: flex-end;
  padding: clamp(28px, 8vw, 64px) var(--pp-gutter);
  padding-bottom: clamp(48px, 9vw, 88px);
}
.pp-contact-clean .pp-contact-hero__text {
  display: flex;
  flex-direction: column;
  gap: clamp(16px, 4vw, 24px);
  /* Row-flex child in __inner; default min-width:auto sizes it to the
     button row's full content width and overflows the hero, defeating the
     row's own overflow-x:auto (source's own documented fix, README.md —
     "only needed on this variant"). */
  min-width: 0;
}
.pp-contact-clean .pp-contact-hero__h1 {
  font-size: clamp(32px, 9vw, 76px);
  line-height: 1.06;
  letter-spacing: -.04em;
  font-weight: 500;
  max-width: none;
  color: var(--pp-bone);
}
.pp-contact-clean .pp-contact-hero__lead {
  font-size: clamp(14px, 2.4vw, 18px);
  line-height: 1.65;
  font-weight: 300;
  max-width: none;
  color: var(--pp-bone-80);
}
/* Scrolls horizontally rather than wrapping to a second line — same no-bar
   scrollbar-hiding + touch-action:pan-x mechanism as Milla 47's interior
   chips row. */
.pp-contact-clean .pp-contact-hero__btns.wp-block-buttons {
  margin-top: clamp(18px, 2.4vw, 26px) !important;
  display: flex;
  flex-wrap: nowrap;
  gap: 6px;
  overflow-x: auto;
  touch-action: pan-x;
  min-width: 0;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.pp-contact-clean .pp-contact-hero__btns.wp-block-buttons::-webkit-scrollbar { display: none; }
.pp-contact-clean .pp-contact-hero__btns .wp-block-button { flex: none; }
.pp-contact-clean .pp-contact-hero__btns .wp-block-button__link { height: 32px; padding: 0 13px; font-size: 12px; gap: 6px; }

/* ==========================================================================
   Talk to our team
   ========================================================================== */
/* scroll-margin-top (v1.0.6) — reproduces the header-clearance half of
   source's own html{scroll-padding-top:calc(var(--hdr-h) + 12px)} rule
   (styles.css §02) directly on this section root, since that source rule
   lives on the bare <html> element, outside this page pack's own CSS
   scope (Page Pack Spec §5). Applied to the section ROOT specifically
   (this Group block, matching its own "anchor":"team" attribute) rather
   than the heading inside it, so the #team jump lands at the section's
   true top boundary — its own top padding and background visible above
   the heading — not with the heading pinned to the header's bottom edge.
   Works natively with zero JS (a real anchor click, a direct #team page
   load, or browser back/forward all honour it) — frontend.js only adds
   the missing smooth-ANIMATION half on top. */
.pp-contact-clean .pp-contact-team { margin-top: 0 !important; padding-block: var(--pp-sec-y-p); scroll-margin-top: calc(var(--pp-hdr-h) + 12px); }
.pp-contact-clean .pp-contact-team__h2 {
  font-size: clamp(26px, 4.6vw, 40px);
  line-height: 1.08;
  letter-spacing: -.022em;
  font-weight: 500;
  max-width: 16ch;
}
.pp-contact-clean .pp-contact-team-grid {
  margin-top: clamp(24px, 4vw, 32px) !important;
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(14px, 2vw, 18px);
}
.pp-contact-clean .pp-contact-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: clamp(16px, 2.2vw, 20px);
  background: var(--pp-bone);
  border: 1px solid var(--pp-stone);
  border-radius: var(--pp-r-card);
}
.pp-contact-clean .pp-contact-card__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.pp-contact-clean .pp-contact-card__head-text { display: flex; flex-direction: column; }
.pp-contact-clean .pp-contact-card__avatar.wp-block-image {
  width: 72px;
  height: 72px;
  flex: none;
  margin: 0;
  border-radius: var(--pp-r-pill);
  overflow: hidden;
}
.pp-contact-clean .pp-contact-card__avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pp-contact-clean .pp-contact-card__role { font-size: 12.5px; font-weight: 500; color: var(--pp-accent); }
/* line-height:normal — same theme-line-height-inheritance defense as
   Milla 47's .pp-m47-faq__q/.pp-m47-tier__name (Master Workflow §44
   family): a real <h3> with no explicit line-height can inherit the
   active theme's own heading default instead of source's plain "normal"
   (source's own .contact-card__name sets none either). */
.pp-contact-clean .pp-contact-card__name {
  margin-top: 3px !important;
  font-size: 21px;
  font-weight: 500;
  line-height: normal;
  letter-spacing: -.02em;
  color: var(--pp-ink);
}
.pp-contact-clean .pp-contact-card__desc { margin-top: 6px !important; font-size: 13px; line-height: 1.5; font-weight: 300; color: var(--pp-ink-72); }
.pp-contact-clean .pp-contact-card__lines { display: flex; flex-direction: column; gap: 5px; margin-top: 1px !important; }
.pp-contact-clean .pp-contact-card__line { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--pp-ink-72); }
.pp-contact-clean .pp-contact-card__line a { color: var(--pp-ink); }
/* v1.0.7 — phone/email icons are now real core/image blocks (independently
   selectable/replaceable/duplicatable in Gutenberg), replacing the CSS
   mask-image ::before pseudo-element this class used through v1.0.6, which
   could never be selected or edited as its own element. Rasterized 1:1
   from the exact same SVG path data the mask-image used (assets/icon-
   phone.png, assets/icon-email.png — 200x200, transparent background,
   colour #737376 baked in: the real composited value of var(--pp-ink-56)
   over the card's white background, read via real canvas pixel sampling
   rather than guessed, since color-mix(in oklab, ...) has no simple
   linear-RGB equivalent to hand-compute). Sized identically to the old
   pseudo-element's own box (14x14, no margin) so the row's visual gap/
   alignment is unchanged. */
.pp-contact-clean .pp-contact-card__line-icon {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  margin: 0;
}
.pp-contact-clean .pp-contact-card__line-icon img { width: 100%; height: 100%; object-fit: contain; display: block; }
.pp-contact-clean .pp-contact-card__btn.wp-block-buttons { margin-top: 2px !important; }

/* ==========================================================================
   Ask us anything (contact form)
   ========================================================================== */
.pp-contact-clean .pp-contact-form__rule { border-top-width: 1px; border-color: var(--pp-tint-line); margin: 0 !important; }
/* scroll-margin-top (v1.0.6) — same header-clearance mechanism as
   .pp-contact-team above, for the #contact-form anchor. */
.pp-contact-clean .pp-contact-form-section { margin-top: 0 !important; padding-block: var(--pp-sec-y-p); background: var(--pp-tint); scroll-margin-top: calc(var(--pp-hdr-h) + 12px); }
.pp-contact-clean .pp-contact-form-row { display: flex; flex-wrap: wrap; gap: clamp(28px, 4vw, 44px); }
.pp-contact-clean .pp-contact-form__copy { flex: 1 1 300px; min-width: 0; }
.pp-contact-clean .pp-contact-form__h2 {
  font-size: clamp(26px, 4.6vw, 40px);
  line-height: 1.08;
  letter-spacing: -.022em;
  font-weight: 500;
  max-width: 16ch;
}
.pp-contact-clean .pp-contact-form__intro { margin-top: 14px !important; font-size: 14px; line-height: 1.65; font-weight: 300; color: var(--pp-ink-72); max-width: 44ch; }
.pp-contact-clean .pp-contact-trust { margin-top: 18px !important; display: flex; flex-direction: column; gap: 8px; }
.pp-contact-clean .pp-contact-trust__item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  font-weight: 400;
  color: var(--pp-ink-72);
}
/* v1.0.7 — shield icon is now a real core/image block, same reasoning as
   the phone/email icons above (see that comment). Rasterized from the
   exact same SVG path data (assets/icon-shield.png, 200x200, transparent),
   colour #4F7A44 baked in — var(--pp-good) is a plain hex value here, no
   color-mix, so no compositing/sampling was needed for this one. Sized
   identically to the old pseudo-element's own box (15x15, no margin). */
.pp-contact-clean .pp-contact-trust__item-icon {
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  margin: 0;
}
.pp-contact-clean .pp-contact-trust__item-icon img { width: 100%; height: 100%; object-fit: contain; display: block; }

/* The <form> itself is a core/html block (Page Pack Spec — no native
   Gutenberg primitive covers a topic <select> + <textarea> + checkbox
   consent this faithfully without real fidelity loss; source's own
   action="#" method="post" is preserved verbatim, no backend wired up).
   All surrounding editorial content (heading, intro, trust list) is real,
   native, independently editable content — see the handoff's form-
   architecture note. */
.pp-contact-clean .pp-contact-form {
  flex: 1 1 380px;
  min-width: 0;
  box-sizing: border-box;
  background: var(--pp-bone);
  border-radius: var(--pp-r-lg);
  box-shadow: 0 12px 40px color-mix(in oklab, var(--pp-ink) 8%, transparent);
  padding: clamp(24px, 3.2vw, 32px);
  margin: 0;
}
.pp-contact-clean .pp-contact-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
/* min-width:0 is load-bearing, not decorative (the same recurring "1fr
   grid/flex item defaults to min-width:auto, sized to its own content's
   min-content contribution" lesson this project has hit repeatedly —
   Milla 47's .pp-m47-cta-split__media/__body, .pp-contact-hero__text).
   v1.0.1 root-caused this round's "other fields move on focus" report to
   exactly this: without it, if any WordPress/theme :focus rule (still
   possible despite this file's own !important geometry lock immediately
   below) nudges a focused input's own intrinsic/min-content width even
   fractionally, the 1fr column carrying it can regrow to accommodate that
   larger min-content size, visibly shifting the OTHER column's field —
   min-width:0 removes the column's ability to grow for that reason at
   all, independent of whatever a theme rule does to the input itself. */
/* v1.0.5 — gap removed deliberately (was `gap: 6px`), replaced by an
   explicit margin-top on the control itself (see the input/select/textarea
   rule below). Root-caused this round: a real password-manager browser
   extension (confirmed via NordPass on real WordPress) injects its own
   custom element (e.g. <nordpass-icon>) as an extra DOM child of this
   flex-column wrapper the moment its <input> is focused. With `gap` on the
   flex container, EVERY additional flex child adds one more gap-worth of
   space between it and the previous child — even a zero-height injected
   element — which is exactly what pushed every field/row below downward
   on focus. `gap` counts children; `margin-top` on a specific, known
   element does not, so this removes the entire class of third-party-DOM-
   injection risk regardless of which extension injects what, or how many
   extra elements appear. */
.pp-contact-clean .pp-contact-field { display: flex; flex-direction: column; min-width: 0; }
/* v1.0.3 — :focus-within defensive lock, all three wrapper levels. v1.0.2
   locked geometry on the <input>/<select>/<textarea> elements themselves,
   but a WordPress theme's own focus treatment is not guaranteed to target
   the control — a very common alternative pattern styles the WRAPPING
   element via :focus-within instead (e.g. a rule shaped like
   ".field:focus-within { border: 2px solid <colour> }" or a padding/
   box-shadow change on the wrapper), which nothing in this file defended
   against before this round. Each wrapper level below explicitly restates
   its own actual box-model properties (verbatim, matching its own base
   rule) plus forces border/box-shadow/padding/margin/outline to their
   base-state values (0, or the real declared value for .pp-contact-form,
   which does own a real padding/box-shadow normally) — so no theme rule
   reaching .pp-contact-field, .pp-contact-fields, or .pp-contact-form
   itself via :focus-within can add/change ANY box-model property,
   regardless of its own specificity or load order. */
.pp-contact-clean.pp-contact-clean .pp-contact-field:focus-within {
  display: flex !important;
  flex-direction: column !important;
  min-width: 0 !important;
  width: auto !important;
  height: auto !important;
  border: 0 !important;
  box-shadow: none !important;
  padding: 0 !important;
  margin: 0 !important;
  outline: none !important;
}
.pp-contact-clean.pp-contact-clean .pp-contact-fields:focus-within {
  display: grid !important;
  grid-template-columns: 1fr 1fr !important;
  gap: 12px !important;
  border: 0 !important;
  box-shadow: none !important;
  padding: 0 !important;
  margin: 0 !important;
  outline: none !important;
}
.pp-contact-clean.pp-contact-clean .pp-contact-form:focus-within {
  flex: 1 1 380px !important;
  min-width: 0 !important;
  box-sizing: border-box !important;
  background: var(--pp-bone) !important;
  border: 0 !important;
  border-radius: var(--pp-r-lg) !important;
  box-shadow: 0 12px 40px color-mix(in oklab, var(--pp-ink) 8%, transparent) !important;
  padding: clamp(24px, 3.2vw, 32px) !important;
  margin: 0 !important;
  outline: none !important;
}
.pp-contact-clean .pp-contact-field--wide { grid-column: 1 / -1; }
.pp-contact-clean .pp-contact-field label { font-size: 11.5px; color: var(--pp-ink-56); }
/* v1.0.1: the "Message topic"/"Your message" controls (select/textarea)
   already rendered correctly, but First/Last name/Phone/Email (all plain
   <input> elements) came back from real WordPress with a white background,
   a strong dark border, taller boxes and off-centre placeholder text — the
   active theme evidently carries its own default styling specifically
   keyed to <input> (a very common pattern: a global-styles/classic-theme
   rule scoped by element type or input[type=...], which selects only
   <input>, never <select>/<textarea>, exactly matching the reported
   split). This file's own selector already had valid, correct, source-
   matched values — the problem was never the values, only that a same-
   or-higher-specificity theme rule could still win the cascade contest on
   <input> specifically. !important removes any dependency on winning that
   contest by specificity or load order (Master Workflow §44 family — the
   same defensive pattern already used throughout this project for exactly
   this class of real-WordPress-only interference). line-height:normal is
   added defensively too, for the same reason as every prior "unexpectedly
   tall themed control" bug this project has hit (Bug Pattern C) — source
   itself sets none either, landing on plain browser "normal". */
.pp-contact-clean.pp-contact-clean .pp-contact-field input,
.pp-contact-clean.pp-contact-clean .pp-contact-field select,
.pp-contact-clean.pp-contact-clean .pp-contact-field textarea {
  box-sizing: border-box !important;
  width: 100% !important;
  height: auto !important;
  margin-top: 6px !important;
  font: 400 14px "Poppins", "Helvetica Neue", Helvetica, sans-serif !important;
  line-height: normal !important;
  color: var(--pp-ink) !important;
  background: var(--pp-surface) !important;
  border: 1px solid var(--pp-ink-hair) !important;
  border-radius: var(--pp-r-xs) !important;
  padding: 12px 14px !important;
  outline: none;
}
/* v1.0.4 — explicit border-box height pin, <input> only (First/Last/Phone/
   Email — this round's exact 4 reported fields; Message topic/Your message
   are select/textarea and were never reported broken, so they keep auto/
   min-height sizing and are untouched here). Root-caused this round via a
   hostile-stylesheet test: a same-specificity !important rule loaded AFTER
   this file (e.g. a real theme's own input:focus rule, or WordPress's
   global-styles-inline-css block, which is not guaranteed to print before
   a page pack's own enqueued stylesheet) wins the cascade purely on source
   order, regardless of !important on both sides — the exact mechanism the
   v1.0.2/v1.0.3 "restate every property with !important" defense could not
   close, since restating a property doesn't help once a same-specificity,
   later rule is the one actually applied. Boosting this selector's own
   specificity (.pp-contact-clean.pp-contact-clean — repeating the root
   class matches the identical elements but raises the selector's own
   weight) raises the bar an external rule must clear, and this explicit
   47px height (the field's real measured border-box height: 12px+12px
   padding + 1px+1px border + ~21px "normal" line-height content, box-
   sizing:border-box already set above) is the structural backstop — even
   in the residual case where an external rule still wins on border-width/
   padding/line-height, the outer border-box height itself is pinned, so
   the field's box — and therefore every row/field/button below it — still
   cannot grow or move. */
.pp-contact-clean.pp-contact-clean .pp-contact-field input { height: 47px !important; }
.pp-contact-clean.pp-contact-clean .pp-contact-field select { appearance: none; }
.pp-contact-clean.pp-contact-clean .pp-contact-field select option { color: var(--pp-ink); }
.pp-contact-clean.pp-contact-clean .pp-contact-field textarea { min-height: 92px !important; resize: vertical; }
/* v1.0.2 — layout-stability fix. Reported bug: focusing any field shifted
   the whole form (other fields moved). Root cause: the base rule above
   only carries forward automatically while no other rule targets the
   :focus/:focus-visible state with equal-or-higher precedence for a
   geometry property — an active WordPress theme very commonly ships its
   own input:focus (or textarea:focus/select:focus) rule (a heavier
   border, extra padding, or a different line-height/font-size, the exact
   candidates this round's task named), and this file previously had
   nothing of its own targeting the focus state except outline (which
   never affects layout on its own). Rather than guess which specific
   property a live theme changes, this rule explicitly RESTATES every
   layout-relevant property to the identical base-state value, on both
   :focus (fires for every focus method, including a plain mouse click)
   and :focus-visible (the source's own original trigger), so no external
   rule targeting either pseudo-class can win on any geometry property
   regardless of its own specificity or load order — only outline (which
   is explicitly excluded from the box model and can never cause reflow)
   changes. Paired with the min-width:0 fix above (the other structural
   half of this bug — see that comment). */
.pp-contact-clean.pp-contact-clean .pp-contact-field input:focus,
.pp-contact-clean.pp-contact-clean .pp-contact-field select:focus,
.pp-contact-clean.pp-contact-clean .pp-contact-field textarea:focus,
.pp-contact-clean.pp-contact-clean .pp-contact-field input:focus-visible,
.pp-contact-clean.pp-contact-clean .pp-contact-field select:focus-visible,
.pp-contact-clean.pp-contact-clean .pp-contact-field textarea:focus-visible {
  box-sizing: border-box !important;
  width: 100% !important;
  min-width: 0 !important;
  height: auto !important;
  margin: 6px 0 0 !important;
  font: 400 14px "Poppins", "Helvetica Neue", Helvetica, sans-serif !important;
  line-height: normal !important;
  color: var(--pp-ink) !important;
  background: var(--pp-surface) !important;
  border: 1px solid var(--pp-ink-hair) !important;
  border-radius: var(--pp-r-xs) !important;
  padding: 12px 14px !important;
  box-shadow: none !important;
  transform: none !important;
  outline: 2px solid var(--pp-accent-soft) !important;
  outline-offset: 2px;
}
/* Same explicit-height backstop as the base rule above, restated for the
   focus/focus-visible state specifically — this is the state the reported
   bug actually fires in, so the pin must hold here independently (a rule
   winning the cascade specifically on :focus/:focus-visible, as reproduced
   in this round's hostile-stylesheet test, only ever applies while
   focused). */
.pp-contact-clean.pp-contact-clean .pp-contact-field input:focus,
.pp-contact-clean.pp-contact-clean .pp-contact-field input:focus-visible {
  height: 47px !important;
}
.pp-contact-clean.pp-contact-clean .pp-contact-field textarea:focus,
.pp-contact-clean.pp-contact-clean .pp-contact-field textarea:focus-visible { min-height: 92px !important; }
.pp-contact-clean .pp-contact-field input::placeholder,
.pp-contact-clean .pp-contact-field textarea::placeholder { color: var(--pp-ink-56) !important; opacity: 1; }
.pp-contact-clean .pp-contact-consent {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  margin: 14px 0 18px;
  font-size: 11.5px;
  line-height: 1.6;
  font-weight: 300;
  color: var(--pp-ink-72);
  cursor: pointer;
}
.pp-contact-clean .pp-contact-consent input { margin-top: 2px; flex: none; accent-color: var(--pp-accent); }
.pp-contact-clean .pp-contact-consent a { color: var(--pp-ink); text-decoration: underline !important; }
.pp-contact-clean .pp-contact-submit {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 40px;
  padding: 0 21px;
  border: 0;
  border-radius: var(--pp-r-pill);
  font: 500 15px "Poppins", "Helvetica Neue", Helvetica, sans-serif;
  white-space: nowrap;
  cursor: pointer;
  background: var(--pp-ink);
  color: var(--pp-bone);
  transition: background var(--pp-t-med), color var(--pp-t-med);
}
.pp-contact-clean .pp-contact-submit:hover { background: var(--pp-accent); color: var(--pp-bone); }

/* ==========================================================================
   Visit us
   ========================================================================== */
/* scroll-margin-top (v1.0.6) — same header-clearance mechanism as
   .pp-contact-team above, for the #visit anchor. */
.pp-contact-clean .pp-contact-visit { margin-top: 0 !important; padding-block: var(--pp-sec-y-p); scroll-margin-top: calc(var(--pp-hdr-h) + 12px); }
.pp-contact-clean .pp-contact-visit__h2 {
  font-size: clamp(26px, 4.6vw, 40px);
  line-height: 1.08;
  letter-spacing: -.022em;
  font-weight: 500;
  max-width: 16ch;
}
.pp-contact-clean .pp-contact-visit-grid {
  margin-top: clamp(24px, 4vw, 32px) !important;
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(16px, 2.4vw, 22px);
}
.pp-contact-clean .pp-contact-visit-photo {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: var(--pp-r-card);
  overflow: hidden;
}
.pp-contact-clean .pp-contact-visit-photo__img.wp-block-image { margin: 0; width: 100%; height: 100%; }
.pp-contact-clean .pp-contact-visit-photo__img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pp-contact-clean .pp-contact-visit-stack { display: flex; flex-direction: column; gap: clamp(16px, 2.4vw, 22px); }
.pp-contact-clean .pp-contact-visit-card {
  background: var(--pp-bone);
  border: 1px solid var(--pp-stone);
  border-radius: var(--pp-r-card);
  padding: clamp(18px, 2.6vw, 24px);
}
.pp-contact-clean .pp-contact-visit-card__h3 { font-size: 16px; font-weight: 500; line-height: normal; letter-spacing: -.015em; color: var(--pp-ink); }
.pp-contact-clean .pp-contact-visit-card__p { margin-top: 4px !important; font-size: 13px; font-weight: 300; color: var(--pp-ink-72); }
.pp-contact-clean .pp-contact-visit-card__actions {
  margin-top: 16px !important;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 12px;
}
.pp-contact-clean .pp-contact-visit-card__actions .pp-contact-link-arrow { font-size: 13px; }
.pp-contact-clean .pp-contact-visit-card__actions .pp-contact-link-arrow a { font-size: 13px; }

.pp-contact-clean .pp-contact-company-card {
  padding: clamp(20px, 2.6vw, 26px);
  background: var(--pp-tint);
  border-radius: var(--pp-r-card);
}
.pp-contact-clean .pp-contact-company-card__eyebrow {
  font-size: 11px;
  font-weight: 400;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--pp-accent);
}
.pp-contact-clean .pp-contact-company-card__name { margin-top: 6px !important; font-size: 18px; font-weight: 500; line-height: normal; letter-spacing: -.02em; color: var(--pp-ink); }
.pp-contact-clean .pp-contact-company-card__rows { margin-top: 18px !important; display: flex; flex-direction: column; gap: 12px; }
.pp-contact-clean .pp-contact-company-card__label { font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--pp-ink-56); }
.pp-contact-clean .pp-contact-company-card__value { margin-top: 3px !important; font-size: 13.5px; font-weight: 400; color: var(--pp-ink); }

/* ==========================================================================
   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) — must be tested at 901/899.
   ========================================================================== */
@media (min-width: 900px) {
  .pp-contact-clean .pp-contact-team-grid { grid-template-columns: repeat(3, 1fr); }

  .pp-contact-clean .pp-contact-hero__btns.wp-block-buttons { flex-wrap: nowrap; gap: 8px; }
  .pp-contact-clean .pp-contact-hero__btns .wp-block-button__link { height: 34px; padding: 0 15px; font-size: 13px; }

  .pp-contact-clean .pp-contact-visit-grid { grid-template-columns: 1fr 1fr; align-items: stretch; }
  .pp-contact-clean .pp-contact-visit-photo { aspect-ratio: auto; height: 100%; }
  .pp-contact-clean .pp-contact-visit-card__actions { flex-direction: row; align-items: center; gap: 18px; }
  .pp-contact-clean .pp-contact-visit-card__actions .wp-block-buttons.pp-contact-visit-card__btn,
  .pp-contact-clean .pp-contact-visit-card__actions .wp-block-button__link { width: auto; }
}

/* ==========================================================================
   Scroll reveal (frontend.js) + reduced motion
   ========================================================================== */
.pp-contact-clean .pp-io-fade {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity .8s var(--pp-ease), transform .8s var(--pp-ease);
}
.pp-contact-clean .pp-io-fade.in-view { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .pp-contact-clean .pp-io-fade { transition: none; }
}
