/* Arcadia Homes — foundation tokens + shared components.
   Values from the approved static reference (neutral black/white/grey override in index.html)
   + design-system tokens. Deployed flat to wp-content/uploads/elementor/arc-foundation.css */
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,200;0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500&family=Dancing+Script:wght@500;600;700&display=swap');

:root {
  /* Neutral palette (approved black & white version) */
  --surface-page: #FFFFFF;
  --surface-alt: #F8F9FA;
  --surface-card: #FFFFFF;
  --surface-inverse: #111315;
  --header-solid-bg: rgba(255, 255, 255, 0.72);
  --text-primary: #14161A;
  --text-secondary: #565B62;
  --text-muted: #6F7378; /* was #9AA0A6 (2.64:1) — darkened 2026-09-04 for WCAG AA 4.5:1; see project-state */
  --text-accent: #6B7076;   /* reference eyebrow / meta ink — was missing, do not use --text-muted */
  --text-inverse: #F8F9FA;
  --brand-primary: #14161A;
  --brand-on-primary: #FFFFFF;
  --brand-accent: #14161A;
  --focus-ring: #14161A;
  --border-hair: #EAECEF;
  --border-soft: #E2E5E9;
  --border-strong: #14161A;
  --border-inverse: rgba(255, 255, 255, 0.16);
  --arc-black: #14161A;
  --arc-white: #FFFFFF;
  --arc-linen: #F8F9FA;
  --arc-sand: #EEF0F2;
  --arc-stone-100: #D4D7DB;
  --arc-stone-200: #C2C6CB;   /* testimonial quote glyph */
  --arc-taupe-300: #9AA0A6;

  /* Type */
  --font-sans: 'Montserrat', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-display: var(--font-sans);
  --font-script: 'Dancing Script', cursive;
  --fs-display-xl: clamp(3rem, 6vw, 5.5rem);
  --fs-display-lg: clamp(2.4rem, 4.5vw, 4rem);
  --fs-display-md: clamp(1.9rem, 3vw, 2.75rem);
  --fs-label: 0.8125rem;
  --fs-body-sm: 0.9375rem;
  --ls-wide: 0.08em;
  --ls-wider: 0.18em;
  --ls-widest: 0.28em;

  /* Radius / shadow / motion / layout */
  --radius-xs: 2px;
  --radius-sm: 2px;
  --radius-md: 4px;
  --radius-lg: 8px;
  --radius-pill: 999px;
  --shadow-xs: 0 1px 2px rgba(66, 58, 45, 0.06);
  --shadow-md: 0 8px 24px rgba(66, 58, 45, 0.09);
  --scrim-bottom: linear-gradient(to top, rgba(18,17,16,0.7) 0%, rgba(18,17,16,0.15) 45%, rgba(18,17,16,0) 75%);
  --shadow-lg: 0 20px 48px rgba(66, 58, 45, 0.12);
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --dur-fast: 160ms;
  --dur-med: 320ms;
  --dur-slow: 640ms;
  --container-max: 1280px;
  --container-wide: 1480px;
  --gutter: clamp(1.25rem, 4vw, 4rem);

  /* Star mark — exact path from the reference Stars component (Sections1.js) */
  /* Lucide chevron-right, painted via CSS mask so it follows currentColor and never
     depends on an icon webfont (G7). 24-viewBox path; at a 15px box the glyph is 3.75x7.5,
     which is what the reference renders to the decimal. */
  --arc-chevron: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 24 24%27 fill=%27none%27 stroke=%27black%27 stroke-width=%272%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27%3E%3Cpath d=%27M9 18l6-6-6-6%27/%3E%3C/svg%3E");
  --arc-check: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 24 24%27 fill=%27none%27 stroke=%27black%27 stroke-width=%272%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27%3E%3Cpath d=%27M20 6 9 17l-5-5%27/%3E%3C/svg%3E");
  --arc-star: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2l2.9 6.26L21.8 9.3l-5 4.87L18 21l-6-3.2L6 21l1.2-6.83-5-4.87 6.9-1.04z'/%3E%3C/svg%3E");
}

body {
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
}
/* ⚠️ COLOUR as well as background. These rules set only a background, so selected text kept its
   own colour — and on every dark ground on the site (the design-single spec card's #111315 head,
   the CTA band over its photo, the footer) that is WHITE text on a #D4D7DB highlight: about
   1.5:1, i.e. the user highlights it and it disappears. Pinning the ink takes it to ~12:1 and
   reads correctly on light grounds too, where it was already fine.
   Selection is an interaction-only state: no pixel diff, computed-style pass or axe run sees it,
   so it survives every static gate — it was reported by someone trying to select the text.
   Kept as SEPARATE rules, never comma-joined: a browser that does not know one would invalidate
   both. */
::selection { background: #D4D7DB; color: #14161A; }
::-moz-selection { background: #D4D7DB; color: #14161A; }
:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) {
  .arc-nav__panel, .arc-fgroup__wrap, .arc-macc__wrap, .arc-chev { transition: none !important; }
}

/* Shared chevron rotation */
.arc-chev { transition: transform var(--dur-med) var(--ease-out); flex: 0 0 auto; }
.is-open > .arc-nav__link .arc-chev,
.is-open > .arc-fgroup__btn .arc-chev,
.is-open > .arc-macc__btn .arc-chev,
.arc-has-dd.is-open > .arc-nav__link .arc-chev { transform: rotate(180deg); }

/* Hand-built button (design-system Button parity) — used where a native widget can't be (mobile panel) */
body .arc-btn-el,
body a.arc-btn-el {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.6em;
  font-family: var(--font-sans) !important; font-weight: 600 !important;
  text-transform: uppercase; letter-spacing: var(--ls-wide);
  text-decoration: none !important; border-radius: var(--radius-sm);
  cursor: pointer; border: 1px solid transparent; white-space: nowrap;
  transition: transform var(--dur-med) var(--ease-out), box-shadow var(--dur-med) var(--ease-out),
    background-color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out);
  will-change: transform;
}
body .arc-btn-el:hover { transform: translateY(-2px); box-shadow: 0 10px 26px rgba(20, 22, 26, 0.16); }
body .arc-btn-el:active { transform: translateY(0); transition-duration: 60ms; }
body .arc-btn-el--sm { font-size: 0.6875rem; padding: 0.6rem 1.1rem; }
body .arc-btn-el--lg { font-size: 0.875rem; padding: 1.15rem 2.5rem; }
body .arc-btn-el--primary,
body a.arc-btn-el--primary,
body a.arc-btn-el--primary:hover { background: var(--brand-primary); color: #FFFFFF !important; border-color: var(--brand-primary); }
body .arc-btn-el--inverse,
body a.arc-btn-el--inverse,
body a.arc-btn-el--inverse:hover { background: var(--arc-white); color: var(--arc-black) !important; border-color: var(--arc-white); }
body .arc-btn-el--secondary,
body a.arc-btn-el--secondary,
body a.arc-btn-el--secondary:hover { background: transparent; color: var(--text-primary) !important; border-color: var(--border-strong); }
@media (prefers-reduced-motion: reduce) {
  body .arc-btn-el { transition: background-color var(--dur-fast) var(--ease-out) !important; }
  body .arc-btn-el:hover { transform: none; box-shadow: none; }
}

/* Elementor Button widget — Arcadia design-system parity (scoped by our helper classes) */
.arc-btn-primary .elementor-button, .arc-btn-inverse .elementor-button, .arc-btn-secondary .elementor-button {
  font-family: var(--font-sans) !important; font-weight: 600 !important;
  white-space: nowrap !important; display: inline-flex !important; align-items: center; justify-content: center;
  line-height: normal !important;
  text-transform: uppercase !important; letter-spacing: var(--ls-wide) !important;
  border-radius: var(--radius-sm) !important; border: 1px solid transparent !important;
  transition: transform var(--dur-med) var(--ease-out), box-shadow var(--dur-med) var(--ease-out),
    background-color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out) !important;
  will-change: transform;
}
.arc-btn-primary .elementor-button:hover, .arc-btn-inverse .elementor-button:hover, .arc-btn-secondary .elementor-button:hover {
  transform: translateY(-2px); box-shadow: 0 10px 26px rgba(20, 22, 26, 0.16);
}
.arc-btn-primary .elementor-button:active, .arc-btn-inverse .elementor-button:active, .arc-btn-secondary .elementor-button:active {
  transform: translateY(0); transition-duration: 60ms;
}
.arc-btn-sm .elementor-button { font-size: 0.6875rem !important; padding: 0.6rem 1.1rem !important; }
.arc-btn-lg .elementor-button { font-size: 0.875rem !important; padding: 1.15rem 2.5rem !important; }
.arc-btn-primary .elementor-button { background: var(--brand-primary) !important; color: #FFFFFF !important; border-color: var(--brand-primary) !important; }
.arc-btn-inverse .elementor-button { background: var(--arc-white) !important; color: var(--arc-black) !important; border-color: var(--arc-white) !important; }
.arc-btn-secondary .elementor-button { background: transparent !important; color: var(--text-primary) !important; border-color: var(--border-strong) !important; }
@media (prefers-reduced-motion: reduce) {
  .arc-btn-primary .elementor-button:hover, .arc-btn-inverse .elementor-button:hover, .arc-btn-secondary .elementor-button:hover { transform: none; box-shadow: none; }
}

/* Stars */
.arc-stars { display: inline-flex; align-items: center; gap: 2px; line-height: 0; }

/* Google rating row (reference GoogleRating component) */
.arc-grating { display: inline-flex; align-items: center; gap: 12px; line-height: 1.4; }
.arc-grating__score { font-family: var(--font-sans); font-weight: 600; font-size: 1.15rem; }
.arc-grating__meta { font-family: var(--font-sans); font-size: 0.8rem; letter-spacing: 0.02em; }
.arc-grating__meta strong { font-weight: 600; }
.arc-grating--dark .arc-grating__score { color: #fff; }
.arc-grating--dark .arc-stars { color: #fff; }
.arc-grating--dark .arc-grating__meta { color: rgba(255, 255, 255, 0.85); }
.arc-grating--light .arc-grating__score { color: var(--text-primary); }
.arc-grating--light .arc-stars { color: var(--text-primary); }
.arc-grating--light .arc-grating__meta { color: var(--text-secondary); }


/* Site-wide trailing-arrow layer -----------------------------------------------
   The reference renders a literal "\2192" glyph after certain button/link labels
   (TextLink, primary buttons). ONE layer keyed on .arc-arrow — never hand-author a
   per-section arrow override (G17). The label itself stays clean for copy + SEO. */
.arc-arrow .elementor-button-content-wrapper {
  display: inline-flex; align-items: center;
  gap: 0 !important;   /* Elementor's Button ships gap:5px here (its icon_indent default) and it
                          stacks on the arrow's own margin — measured +5px on every arrow button. */
}
.arc-arrow .elementor-button-content-wrapper::after {
  content: "\2192"; font-family: var(--font-sans); font-size: inherit; font-weight: inherit;
  line-height: inherit; letter-spacing: inherit;   /* the reference arrow span inherits the
                          label's 0.08em tracking — zeroing it made the glyph 1px narrow */
  margin-left: var(--arc-arrow-gap, 0.55em);
}
/* Variant: the reference's primary Buttons carry the arrow INSIDE the label after a normal
   space ("More about us \2192"), where TextLink uses a real flex gap. Reproduce the space
   itself rather than guessing a pixel gap — an nbsp picks up the label's tracking for free. */
.arc-arrow--space .elementor-button-content-wrapper::after {
  content: "\00a0\2192"; margin-left: 0;
}
/* ⚠️ The layer above keys on .elementor-button-content-wrapper, which only exists inside the
   Elementor Button WIDGET. A hand-built <a class="arc-btn-el arc-arrow"> — used where a native
   widget cannot go, e.g. inside a shortcode — matches nothing and silently loses its arrow.
   Extending the same layer is the fix; writing a second arrow into that section's CSS is
   exactly the per-section override G17 exists to prevent. Same glyph, same gap variable, so
   the two shapes cannot drift. */
.arc-arrow.arc-btn-el::after,
a.arc-arrow.arc-btn-el::after {
  content: "\2192"; font-family: var(--font-sans); font-size: inherit; font-weight: inherit;
  line-height: inherit; letter-spacing: inherit;
  margin-left: var(--arc-arrow-gap, 0.55em);
}
/* the base .arc-btn-el sets gap:0.6em for an icon slot; with the arrow supplied as ::after that
   gap doubles up with the arrow's own margin */
.arc-arrow.arc-btn-el { gap: 0; }
/* Third shape on the same layer: a plain text LINK inside a shortcode (no Elementor Button, no
   .arc-btn-el). Same glyph, same gap variable — the reference separates label and arrow with a
   7px flex gap, and 0.55em at this link's 12.8px is 7.04, so the default already lands.
   Written here rather than in the section's own CSS: a per-section arrow is exactly what G17
   exists to prevent, and this site now has four call-site shapes sharing one glyph. */
.arc-arrow-txt::after,
a.arc-arrow-txt::after {
  content: "\2192"; font-family: var(--font-sans); font-size: inherit; font-weight: inherit;
  line-height: inherit; letter-spacing: inherit;
  margin-left: var(--arc-arrow-gap, 0.55em);
}

/* Visually-hidden text for screen readers. Added 2026-08-27 for the Display Homes cards,
   whose spec row is three aria-hidden icons plus a bare number — "4 3 2" with no units — and
   whose three action buttons repeat identical labels once per card. The clip-path form, not
   the old 1px-clip hack: it does not affect layout and does not break text selection. */
.arc-sr-only {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  border: 0;
}

/* ---- Scroll reveal ----------------------------------------------------------
   Ported 2026-09-04 from the approved static reference (index.html lines 63-66
   plus its inline observer at 106-133). This build had never implemented it.

   Text rises 26px and fades in ONCE as it enters the viewport. It never fades
   back OUT — the observer unobserves on first intersection, so this is a
   one-shot reveal, not an in/out effect.

   QA note: _qa-lib.js settle() force-reveals .arc-reveal and freezes
   transitions, so every geometry harness is unaffected by this change. That
   same neutralising rule, applied to both sides, is why 2000+ green parity
   checks never registered that the animation was missing here. */
.arc-reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out);
  will-change: opacity, transform;
}
.arc-reveal.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .arc-reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
}

/* ---- Target size, WCAG 2.5.8 AA (2026-09-04) --------------------------------
   The carousel dots painted 9x9 (26x9 active) against a 24x24 minimum. The earlier attempt
   (BugHerd #20) stretched an invisible ::after over them, which does widen the POINTER
   target but cannot satisfy the checkers: axe and Lighthouse both measure the element's own
   getBoundingClientRect(), and a pseudo-element is not part of it.

   This grows the element's border box to 24x24 while keeping the PAINTED dot at 9x9:
   box-sizing:border-box + 7.5px padding + background-clip:content-box. Because it never
   touches `background`, every dot variant keeps its own colour without being restated here —
   the one property that differs between the six of them.

   ⚠️ THE [class] IS LOad-BEARING. The per-section rules are two classes deep
   (`.arc-usps-section .arc-usps__dot`, 0-2-0) and use !important, so a `body .arc-usps__dot`
   override (0-1-1) LOSES on specificity no matter what order the files load in — measured:
   the dots stayed 26x9. Adding [class] lifts each selector to 0-2-1 (and 0-3-1 for the
   is-active pair, which must beat a three-class rule) without needing to know each section's
   wrapper class.

   ⚠️ Not visually free: the dots' pitch goes 17px -> 24px, so the painted gap widens 8px ->
   15px and each dot row gets wider. `gap: 0` keeps that to the minimum that still clears
   24px. This IS a deviation from the approved design; reverse by deleting this block. */
body [class*="__dots"][class] {
  gap: 0 !important;
  /* The 24px buttons would add 15px to every carousel section (measured: USPs and Building
     Process +15, News +10 vs the reference). Pinning the row to the painted dot height and
     centring lets the transparent padding overflow symmetrically, so the hit box is 24x24
     and the section geometry is byte-identical to before. */
  height: 9px !important; align-items: center !important;
}
/* .arc-news__dot is deliberately NOT in this list. The News carousel has no dots row, but it
   still renders 12 .arc-news__dot elements outside any __dots container, and sizing them to
   24x24 added exactly 10px to the News section (measured against the reference). axe never
   flagged them, so they need no fix. */
body .arc-usps__dot[class], body .arc-bp__dot[class], body .arc-cta__dot[class],
body .arc-dhg__dot[class], body .arc-chg__dot[class] {
  box-sizing: border-box !important;
  width: 24px !important; height: 24px !important;
  padding: 7.5px !important;
  background-clip: content-box !important;
}
/* Active pills stay 26px / 28px painted: 26 + 15 = 41, 28 + 15 = 43. */
/* The is-active rules must ALSO restate background-clip. Their per-section rules use the
   background SHORTHAND, which resets background-clip to border-box, and at 0-3-0 they outrank
   the 0-2-1 base rule above — so the active pill painted its whole 41x24 box as one large
   blob instead of a 26x9 pill. Caught by screenshotting it; every automated check passed
   either way. [class] here lifts these to 0-3-1. */
body .arc-usps__dot.is-active[class], body .arc-bp__dot.is-active[class],
body .arc-cta__dot.is-active[class] { width: 41px !important; background-clip: content-box !important; }
body .arc-dhg__dot.is-active[class], body .arc-chg__dot.is-active[class] { width: 43px !important; background-clip: content-box !important; }
/* The old pseudo hit area is redundant now, and at inset -8px on a 24px box it would overlap
   its neighbours. */
.arc-usps__dot::after, .arc-bp__dot::after, .arc-cta__dot::after,
.arc-dhg__dot::after, .arc-chg__dot::after, .arc-news__dot::after { content: none !important; }
