/*
Theme Name: HALCO 2026
Theme URI: https://houseandland.co
Description: Child theme for the House & Land Co rebuild. Carries the design system —
             spacing scale, fluid type, alignment, CTA styles, focus states and motion.
             Elementor handles layout; this file makes the layout consistent.
Author: CentriWeb
Template: hello-elementor
Version: 1.0.0
Text Domain: halco-2026
*/

/* ==========================================================================
   1. DESIGN TOKENS
   Inherited from the live brand (ADR-007: restructure, not rebrand).
   ========================================================================== */

:root {
  /* --- colour ---------------------------------------------------------- */
  --halco-sage:        #707F6A;  /* brand sage. 4.25:1 on white — LARGE TEXT
                                    AND DECORATION ONLY. Fails AA for body. */
  --halco-sage-text:   #5F6D59;  /* 5.50:1 on white — use for body text,
                                    links and button fills. Same character. */
  --halco-sage-dark:   #4F5A4A;  /* 7.25:1 — hover / high-contrast needs */
  --halco-sage-lift:   #96A684;  /* sage on dark backgrounds */
  --halco-sage-wash:   #F2F4F0;  /* section tint */

  --halco-ink:         #15161A;  /* 18.07:1 — primary text */
  --halco-ink-soft:    #4A4D55;
  --halco-muted:       #6B7280;
  --halco-line:        #E3E6E0;
  --halco-canvas:      #FFFFFE;
  --halco-canvas-dark: #1A1A1A;

  /* --- type ------------------------------------------------------------
     Fluid, clamped. The live site's H1 renders 68px and eats the whole first
     viewport on mobile; this caps growth and sets a sane mobile floor. */
  --halco-font-head: 'Manrope', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --halco-font-body: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;

  --halco-h1: clamp(2.25rem, 1.6rem + 2.6vw, 3.75rem);   /* 36 -> 60px */
  --halco-h2: clamp(1.75rem, 1.35rem + 1.7vw, 2.75rem);  /* 28 -> 44px */
  --halco-h3: clamp(1.35rem, 1.15rem + 0.85vw, 1.85rem);
  --halco-h4: clamp(1.15rem, 1.05rem + 0.4vw, 1.35rem);
  --halco-body: clamp(1rem, 0.97rem + 0.14vw, 1.0625rem);
  --halco-small: 0.9375rem;

  --halco-lh-tight: 1.12;
  --halco-lh-head:  1.2;
  --halco-lh-body:  1.65;
  --halco-measure:  64ch;   /* readable line length — the current site runs
                               full-bleed paragraphs at 1300px */

  /* --- spacing ---------------------------------------------------------
     One scale. Every gap comes from here. The single biggest cause of the
     "padding is inconsistent" problem is ad-hoc per-widget values. */
  --halco-s1: 0.25rem;  --halco-s2: 0.5rem;   --halco-s3: 0.75rem;
  --halco-s4: 1rem;     --halco-s5: 1.5rem;   --halco-s6: 2rem;
  --halco-s7: 3rem;     --halco-s8: 4rem;     --halco-s9: 6rem;
  --halco-s10: 8rem;

  --halco-section-y: clamp(3rem, 2rem + 4vw, 6rem);  /* vertical section rhythm */
  --halco-gutter:    clamp(1.25rem, 0.9rem + 1.6vw, 2.5rem);

  /* --- layout ----------------------------------------------------------- */
  --halco-max:        1300px;  /* matches --site-canvas-width today */
  --halco-max-narrow: 780px;   /* prose column */
  --halco-radius:     6px;
  /* SUPERSEDED. Section 20 redefines this as var(--halco-r-pill) = 999px and,
     being later in the cascade, that is the value every button actually gets.
     Both render identically at button heights, so there is no visual
     difference; 320px is kept only so this line is not silently deleted from
     under anyone reading the original token block. Do not trust the number. */
  --halco-radius-pill: 320px;  /* the brand's fully-pill buttons -- see above */

  --halco-shadow-sm: 0 1px 2px rgba(21,22,26,.06), 0 2px 8px rgba(21,22,26,.04);
  --halco-shadow-md: 0 4px 12px rgba(21,22,26,.08), 0 12px 32px rgba(21,22,26,.06);

  --halco-ease: cubic-bezier(.22,.61,.36,1);
  --halco-dur:  .28s;
}

/* ==========================================================================
   2. BASELINE — rhythm and alignment
   ========================================================================== */

body {
  font-family: var(--halco-font-body);
  font-size: var(--halco-body);
  line-height: var(--halco-lh-body);
  color: var(--halco-ink);
  background: var(--halco-canvas);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--halco-font-head);
  color: var(--halco-ink);
  line-height: var(--halco-lh-head);
  margin: 0 0 var(--halco-s4);
  text-wrap: balance;          /* stops orphaned words in headings */
}
h1 { font-size: var(--halco-h1); line-height: var(--halco-lh-tight); letter-spacing: -.02em; }
h2 { font-size: var(--halco-h2); letter-spacing: -.015em; margin-top: var(--halco-s7); }
h3 { font-size: var(--halco-h3); letter-spacing: -.01em; margin-top: var(--halco-s6); }
h4 { font-size: var(--halco-h4); margin-top: var(--halco-s5); }

/* first heading in a region should not push the region open */
h1:first-child, h2:first-child, h3:first-child, h4:first-child { margin-top: 0; }

p, ul, ol, blockquote, table { margin: 0 0 var(--halco-s5); }
p { max-width: var(--halco-measure); text-wrap: pretty; }

ul, ol { padding-left: var(--halco-s5); }
li { margin-bottom: var(--halco-s2); max-width: var(--halco-measure); }

a { color: var(--halco-sage-text); text-underline-offset: .18em; text-decoration-thickness: .06em; }
a:hover { color: var(--halco-sage-dark); }

blockquote {
  border-left: 3px solid var(--halco-sage);
  padding: var(--halco-s2) 0 var(--halco-s2) var(--halco-s5);
  margin-left: 0; color: var(--halco-ink-soft); font-size: 1.0625em;
}

img, video { max-width: 100%; height: auto; }
figure { margin: var(--halco-s6) 0; }
figure img { border-radius: var(--halco-radius); display: block; width: 100%; }

/* Recovered hero backgrounds render as real <img> (ADR-005) rather than CSS
   backgrounds, so they can carry srcset and fetchpriority. */
img.halco-section-bg {
  width: 100%; max-height: 56vh; object-fit: cover;
  border-radius: var(--halco-radius);
}

hr { border: 0; border-top: 1px solid var(--halco-line); margin: var(--halco-s7) 0; }

/* ==========================================================================
   3. LAYOUT + ALIGNMENT
   ========================================================================== */

.halco-wrap  { width: 100%; max-width: var(--halco-max); margin-inline: auto; padding-inline: var(--halco-gutter); }
.halco-prose { max-width: var(--halco-max-narrow); margin-inline: auto; padding-inline: var(--halco-gutter); }
.halco-section { padding-block: var(--halco-section-y); }
.halco-section--tint { background: var(--halco-sage-wash); }
.halco-section--dark { background: var(--halco-canvas-dark); color: var(--halco-canvas); }
.halco-section--dark h1, .halco-section--dark h2, .halco-section--dark h3 { color: var(--halco-canvas); }
.halco-section--dark a { color: var(--halco-sage-lift); }

/* Give imported page content a readable column instead of full-bleed 1300px */
.halco-content > p,
.halco-content > ul,
.halco-content > ol,
.halco-content > blockquote { max-width: var(--halco-measure); }

.halco-grid { display: grid; gap: var(--halco-s6); }
@media (min-width: 700px)  { .halco-grid--2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 980px)  { .halco-grid--3 { grid-template-columns: repeat(3, 1fr); }
                             .halco-grid--4 { grid-template-columns: repeat(4, 1fr); } }

/* ==========================================================================
   4. CALLS TO ACTION
   The live site has six different CTA labels, one with a typo, and one that
   promises a calculation it does not perform. Two variants, one shape.
   ========================================================================== */

.halco-cta,
.halco-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--halco-s2);
  font-family: var(--halco-font-head); font-weight: 600;
  font-size: 1rem; line-height: 1;
  padding: var(--halco-s4) var(--halco-s6);
  min-height: 48px;                     /* comfortable touch target */
  border-radius: var(--halco-radius-pill);
  text-decoration: none; cursor: pointer;
  background: var(--halco-sage-text);   /* 5.50:1 with white — AA compliant */
  color: var(--halco-canvas);
  border: 1.5px solid var(--halco-sage-text);
  transition: background var(--halco-dur) var(--halco-ease),
              border-color var(--halco-dur) var(--halco-ease),
              transform var(--halco-dur) var(--halco-ease),
              box-shadow var(--halco-dur) var(--halco-ease);
}
.halco-cta:hover, .halco-btn:hover {
  background: var(--halco-sage-dark); border-color: var(--halco-sage-dark);
  color: var(--halco-canvas); transform: translateY(-1px); box-shadow: var(--halco-shadow-md);
}
.halco-btn--secondary {
  background: transparent; color: var(--halco-sage-text); border-color: var(--halco-sage-text);
}
.halco-btn--secondary:hover { background: var(--halco-sage-text); color: var(--halco-canvas); }

.halco-cta-row { display: flex; flex-wrap: wrap; gap: var(--halco-s4); margin-block: var(--halco-s6); }

/* ==========================================================================
   5. FOCUS + ACCESSIBILITY
   The live pill buttons have no shadow and no focus style at all.
   ========================================================================== */

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 3px solid var(--halco-sage-dark);
  outline-offset: 3px;
  border-radius: var(--halco-radius);
}
.halco-skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 999;
  background: var(--halco-ink); color: #fff; padding: var(--halco-s3) var(--halco-s5);
}
.halco-skip-link:focus { left: var(--halco-s4); top: var(--halco-s4); }

/* ==========================================================================
   6. MOTION — restrained, and honoured only when the visitor allows it
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {
  a, .halco-card { transition: color var(--halco-dur) var(--halco-ease),
                               transform var(--halco-dur) var(--halco-ease),
                               box-shadow var(--halco-dur) var(--halco-ease); }
  .halco-card:hover { transform: translateY(-2px); box-shadow: var(--halco-shadow-md); }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
}

/* ==========================================================================
   7. COMPONENTS
   ========================================================================== */

.halco-card {
  background: var(--halco-canvas); border: 1px solid var(--halco-line);
  border-radius: var(--halco-radius); padding: var(--halco-s6);
  box-shadow: var(--halco-shadow-sm);
}
.halco-card h3 { margin-top: 0; }

.halco-eyebrow {
  font-family: var(--halco-font-head); font-weight: 600;
  font-size: var(--halco-small); letter-spacing: .08em; text-transform: uppercase;
  color: var(--halco-sage-text); margin-bottom: var(--halco-s3);
}

.halco-stat { text-align: center; }
.halco-stat__n {
  font-family: var(--halco-font-head); font-weight: 800;
  font-size: clamp(2rem, 1.5rem + 2vw, 3rem); color: var(--halco-sage-text); line-height: 1;
}
.halco-stat__l { font-size: var(--halco-small); color: var(--halco-muted); margin-top: var(--halco-s2); }

table { width: 100%; border-collapse: collapse; font-size: var(--halco-small); }
th, td { text-align: left; padding: var(--halco-s3) var(--halco-s4); border-bottom: 1px solid var(--halco-line); }
th { font-family: var(--halco-font-head); font-weight: 700; background: var(--halco-sage-wash); }

/* ==========================================================================
   8. STAGING NOTICE
   ========================================================================== */
.halco-staging-flag {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 99999;
  background: #8A1F1F; color: #fff; text-align: center;
  font: 600 12px/1 var(--halco-font-body); padding: 6px; letter-spacing: .04em;
}

/* ==========================================================================
   9. DESIGN / LISTING RECORDS
   These 97 records hold no post_content — everything is ACF. Styled here so
   the template inherits the design system rather than restyling per record.
   ========================================================================== */

.halco-record__hero img { width: 100%; max-height: 62vh; object-fit: cover; }
.halco-record__tagline {
  font-family: var(--halco-font-head); font-size: var(--halco-h4);
  color: var(--halco-ink-soft); max-width: var(--halco-measure);
}

/* .halco-specs and .halco-spec are defined once, in the Pass 21 block near the
   end of this file. Two earlier definitions lived here and around line 877;
   both were removed because three rules at identical specificity for the same
   component is how `flex-wrap: wrap` survived a rewrite that never mentioned
   it, and left the strip wrapping to two ragged rows. */
.halco-spec__n {
  display: block; font-family: var(--halco-font-head); font-weight: 700;
  font-size: 1.75rem; line-height: 1; color: var(--halco-sage-text);
}
.halco-spec__l {
  display: block; margin-top: var(--halco-s2);
  font-size: var(--halco-small); color: var(--halco-muted);
}

.halco-ticks { list-style: none; padding: 0; }
.halco-ticks li {
  position: relative; padding-left: var(--halco-s6); margin-bottom: var(--halco-s3);
}
.halco-ticks li::before {
  content: ""; position: absolute; left: 0; top: .55em;
  width: 14px; height: 8px; border-left: 2px solid var(--halco-sage-text);
  border-bottom: 2px solid var(--halco-sage-text); transform: rotate(-45deg);
}

.halco-consultant { display: flex; gap: var(--halco-s6); align-items: center; flex-wrap: wrap; }
.halco-consultant__role { color: var(--halco-muted); margin-top: calc(var(--halco-s2) * -1); }
.halco-consultant h2 { margin-top: 0; }

@media (max-width: 560px) {
  .halco-specs { grid-template-columns: repeat(2, 1fr); }
  .halco-consultant { justify-content: center; text-align: center; }
}

/* ---------------------------------------------------------------- Team grid
   Server-rendered by [halco_team] (mu-plugins/halco-team.php). Bios sit inside
   <details> so the full text is in the HTML for crawlers but the card stays
   short for readers, with no JavaScript needed. */

.halco-team { --team-gap: 28px; }

.halco-team__grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--team-gap);
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}

.halco-team__card {
  display: flex;
  flex-direction: column;
  background: #fff;
  border: 1px solid var(--halco-line, #E3E6E0);
  border-radius: 8px;
  overflow: hidden;
}

.halco-team__photo { aspect-ratio: 4 / 5; overflow: hidden; background: #EDEFEA; }
.halco-team__photo img { width: 100%; height: 100%; object-fit: cover; display: block; }

.halco-team__body { padding: 20px 20px 22px; display: flex; flex-direction: column; gap: 8px; flex: 1; }

.halco-team__name {
  font-family: Manrope, system-ui, sans-serif;
  font-size: 1.15rem; font-weight: 700; line-height: 1.25;
  margin: 0; color: var(--halco-ink, #15161A);
}

.halco-team__role {
  font-size: .82rem; font-weight: 600; letter-spacing: .02em;
  margin: 0; color: var(--halco-sage-text, #5F6D59);
}

.halco-team__lede { font-size: .93rem; line-height: 1.6; margin: 4px 0 0; color: #4A4E54; }

.halco-team__more { margin-top: 2px; }
.halco-team__more summary {
  cursor: pointer; list-style: none;
  font-family: Manrope, system-ui, sans-serif;
  font-size: .85rem; font-weight: 700;
  color: var(--halco-sage-text, #5F6D59);
  padding: 4px 0;
}
.halco-team__more summary::-webkit-details-marker { display: none; }
.halco-team__more summary::after { content: " ↓"; }
.halco-team__more[open] summary::after { content: " ↑"; }
.halco-team__more summary:focus-visible { outline: 2px solid var(--halco-sage, #707F6A); outline-offset: 3px; }
.halco-team__more > div p { font-size: .9rem; line-height: 1.65; color: #4A4E54; margin: 8px 0 0; }

.halco-team__book {
  margin-top: auto;
  align-self: flex-start;
  display: inline-block;
  padding: 10px 20px;
  border-radius: 320px;
  background: var(--halco-sage-text, #5F6D59);
  color: #FFFFFE;
  font-family: Manrope, system-ui, sans-serif;
  font-size: .85rem; font-weight: 700;
  text-decoration: none;
}
.halco-team__book:hover, .halco-team__book:focus-visible { background: var(--halco-ink, #15161A); color: #FFFFFE; }
.halco-team__book:focus-visible { outline: 2px solid var(--halco-sage, #707F6A); outline-offset: 3px; }

@media (prefers-reduced-motion: no-preference) {
  .halco-team__card { transition: transform .18s ease, box-shadow .18s ease; }
  .halco-team__card:hover { transform: translateY(-3px); box-shadow: 0 10px 28px rgba(21,22,26,.08); }
}

/* ------------------------------------------------------------ Comparison table
   Emitted by p_table(). Wrapper scrolls so a wide table never makes the page
   scroll sideways. */

.halco-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 4px 0 8px; }
.halco-table {
  width: 100%;
  min-width: 520px;
  border-collapse: collapse;
  font-size: .95rem;
  background: #fff;
}
.halco-table caption {
  caption-side: top;
  text-align: left;
  font-size: .85rem;
  color: #6B7280;
  padding: 0 0 10px;
}
.halco-table th, .halco-table td {
  text-align: left;
  padding: 13px 16px;
  border-bottom: 1px solid var(--halco-line, #E3E6E0);
  vertical-align: top;
  line-height: 1.55;
}
.halco-table thead th {
  font-family: Manrope, system-ui, sans-serif;
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--halco-sage-text, #5F6D59);
  background: var(--halco-sage-wash, #F2F4F0);
  border-bottom: 1px solid #D6DBD1;
}
.halco-table tbody th {
  font-family: Manrope, system-ui, sans-serif;
  font-weight: 700;
  color: var(--halco-ink, #15161A);
  width: 30%;
}
.halco-table tbody tr:last-child th, .halco-table tbody tr:last-child td { border-bottom: 0; }
.halco-table tbody tr:nth-child(even) { background: #FAFBF9; }

/* --------------------------------------------------------- Package browser
   Rendered by [halco_packages] (mu-plugins/halco-packages.php). Three real
   facets instead of one dropdown that mixed suburbs, lot sizes and inclusions. */

.halco-pk__facets {
  display: flex; flex-wrap: wrap; gap: 14px; align-items: flex-end;
  padding: 18px 20px; margin: 0 0 14px;
  background: var(--halco-sage-wash, #F2F4F0);
  border: 1px solid var(--halco-line, #E3E6E0);
  border-radius: 8px;
}
.halco-pk__facet { display: flex; flex-direction: column; gap: 6px; flex: 1 1 180px; }
.halco-pk__facet > span {
  font-family: Manrope, system-ui, sans-serif;
  font-size: .72rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--halco-sage-text, #5F6D59);
}
.halco-pk__facet select {
  font: inherit; font-size: .95rem;
  padding: 10px 12px;
  border: 1px solid #D3D8CE; border-radius: 6px;
  background: #fff; color: var(--halco-ink, #15161A);
  min-height: 44px;
}
.halco-pk__facet select:focus-visible { outline: 2px solid var(--halco-sage, #707F6A); outline-offset: 2px; }
.halco-pk__reset {
  font-family: Manrope, system-ui, sans-serif; font-size: .85rem; font-weight: 700;
  /* Sits in the same row as the facet selects, which are exactly 44px. At
     12px padding the button's own content came to 46px and overrode the
     shared min-height, so the row read as very slightly broken. 10px lets
     min-height govern and both land on 44. */
  padding: 10px 20px; min-height: 44px; line-height: 1.35;
  border: 1px solid var(--halco-ink, #15161A); border-radius: 320px;
  background: transparent; color: var(--halco-ink, #15161A); cursor: pointer;
}
.halco-pk__reset:hover { background: var(--halco-ink, #15161A); color: #fff; }

.halco-pk__count { font-size: .9rem; color: #6B7280; margin: 0 0 18px; }

.halco-pk__grid {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 22px;
  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
}
.halco-pk__card { display: flex; }
.halco-pk__card[hidden] { display: none; }

.halco-pk__link {
  display: flex; flex-direction: column; width: 100%;
  text-decoration: none; color: inherit;
  background: #fff;
  border: 1px solid var(--halco-line, #E3E6E0);
  border-radius: 8px; overflow: hidden;
}
.halco-pk__link:focus-visible { outline: 2px solid var(--halco-sage, #707F6A); outline-offset: 3px; }

.halco-pk__media { position: relative; aspect-ratio: 3 / 2; background: #EDEFEA; }
.halco-pk__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.halco-pk__band {
  position: absolute; left: 12px; bottom: 12px;
  background: rgba(21,22,26,.88); color: #fff;
  font-family: Manrope, system-ui, sans-serif; font-size: .78rem; font-weight: 700;
  padding: 6px 12px; border-radius: 320px;
}

.halco-pk__body { padding: 16px 18px 20px; display: flex; flex-direction: column; gap: 8px; flex: 1; }
.halco-pk__suburb {
  margin: 0; font-family: Manrope, system-ui, sans-serif;
  font-size: .72rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--halco-sage-text, #5F6D59);
}
.halco-pk__title {
  margin: 0; font-family: Manrope, system-ui, sans-serif;
  font-size: 1.02rem; font-weight: 700; line-height: 1.3;
  color: var(--halco-ink, #15161A);
}
.halco-pk__specs, .halco-pk__tags { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.halco-pk__specs li {
  font-size: .82rem; color: #4A4E54;
  background: var(--halco-sage-wash, #F2F4F0);
  padding: 4px 10px; border-radius: 4px;
}
.halco-pk__tags li { font-size: .78rem; color: #6B7280; }
.halco-pk__tags li:not(:last-child)::after { content: " ·"; }
.halco-pk__cta {
  margin-top: auto; padding-top: 6px;
  font-family: Manrope, system-ui, sans-serif; font-size: .85rem; font-weight: 700;
  color: var(--halco-sage-text, #5F6D59);
}
.halco-pk__link:hover .halco-pk__cta { color: var(--halco-ink, #15161A); }
.halco-pk__cta::after { content: " →"; }

.halco-pk__note {
  margin-top: 18px; padding: 12px 16px; font-size: .85rem;
  background: #FFF8E5; border: 1px solid #E8D9A8; border-radius: 6px; color: #6B5A26;
}

@media (prefers-reduced-motion: no-preference) {
  .halco-pk__link { transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease; }
  .halco-pk__link:hover { transform: translateY(-3px); box-shadow: 0 12px 30px rgba(21,22,26,.09); border-color: #CFD6C8; }
}

/* ------------------------------------------------------------------- Article
   single.php. The guides are the site's real content asset; this gives them a
   measure, a rhythm, a table of contents and — for the first time — a CTA. */

.halco-article { display: block; }

.halco-article__head { background: var(--halco-ink, #15161A); color: #fff; padding: 56px 24px 44px; }
.halco-article__head-inner { max-width: 780px; margin: 0 auto; }

.halco-article__crumbs { font-size: .82rem; color: #9BA396; margin-bottom: 18px; display: flex; flex-wrap: wrap; gap: 8px; }
.halco-article__crumbs a { color: #B9C0B3; text-decoration: none; }
.halco-article__crumbs a:hover { color: #fff; text-decoration: underline; }

.halco-article__title {
  font-family: Manrope, system-ui, sans-serif;
  font-size: clamp(2rem, 1.3rem + 2.6vw, 3rem);
  font-weight: 700; line-height: 1.13; letter-spacing: -.02em;
  color: #FFFFFE; margin: 0;
}
.halco-article__standfirst { font-size: 1.15rem; line-height: 1.6; color: #D3D8CE; margin: 16px 0 0; }
.halco-article__meta { font-size: .85rem; color: #9BA396; margin: 18px 0 0; display: flex; flex-wrap: wrap; gap: 8px; }

.halco-article__hero { margin: 0; max-width: 1100px; padding: 0 24px; margin: -28px auto 0; }
.halco-article__hero img { width: 100%; height: auto; border-radius: 10px; display: block; }

.halco-article__body { max-width: 780px; margin: 0 auto; padding: 48px 24px 72px; }

/* Table of contents */
.halco-toc {
  background: var(--halco-sage-wash, #F2F4F0);
  border: 1px solid var(--halco-line, #E3E6E0);
  border-radius: 8px; padding: 20px 24px; margin: 0 0 36px;
}
.halco-toc__title {
  font-family: Manrope, system-ui, sans-serif;
  font-size: .75rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--halco-sage-text, #5F6D59); margin: 0 0 10px;
}
.halco-toc ol { margin: 0; padding-left: 1.2em; display: grid; gap: 7px; }
.halco-toc a { color: #2A2D31; text-decoration: none; font-size: .95rem; }
.halco-toc a:hover { color: var(--halco-sage-text, #5F6D59); text-decoration: underline; }

/* Prose */
.halco-prose { font-size: 1.06rem; line-height: 1.75; color: #2E3236; }
.halco-prose > * + * { margin-top: 1.1em; }
.halco-prose h2 {
  font-family: Manrope, system-ui, sans-serif;
  font-size: clamp(1.5rem, 1.15rem + 1.1vw, 1.95rem);
  font-weight: 700; line-height: 1.2; letter-spacing: -.015em;
  color: var(--halco-ink, #15161A);
  margin-top: 2.1em; margin-bottom: .5em;
  scroll-margin-top: 96px;
}
.halco-prose h3 {
  font-family: Manrope, system-ui, sans-serif;
  font-size: 1.22rem; font-weight: 700; line-height: 1.3;
  color: var(--halco-ink, #15161A);
  margin-top: 1.7em; margin-bottom: .35em;
  scroll-margin-top: 96px;
}
.halco-prose h4 { font-family: Manrope, system-ui, sans-serif; font-size: 1.05rem; font-weight: 700; margin-top: 1.5em; }
.halco-prose a { color: var(--halco-sage-text, #5F6D59); text-decoration: underline; text-underline-offset: 2px; }
.halco-prose a:hover { color: var(--halco-ink, #15161A); }
.halco-prose ul, .halco-prose ol { padding-left: 1.35em; display: grid; gap: .5em; }
.halco-prose li { line-height: 1.7; }
.halco-prose li::marker { color: var(--halco-sage, #707F6A); }
.halco-prose img { max-width: 100%; height: auto; border-radius: 8px; }
.halco-prose figure { margin: 1.8em 0; }
.halco-prose figcaption { font-size: .85rem; color: #6B7280; margin-top: 8px; }
.halco-prose blockquote {
  margin: 1.8em 0; padding: 4px 0 4px 22px;
  border-left: 3px solid var(--halco-sage, #707F6A);
  font-size: 1.1rem; color: #3A3D42;
}
.halco-prose blockquote p { margin: 0; }
.halco-prose table { width: 100%; border-collapse: collapse; font-size: .95rem; display: block; overflow-x: auto; }
.halco-prose th, .halco-prose td { text-align: left; padding: 12px 14px; border-bottom: 1px solid var(--halco-line, #E3E6E0); vertical-align: top; }
.halco-prose thead th {
  font-family: Manrope, system-ui, sans-serif; font-size: .78rem; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--halco-sage-text, #5F6D59); background: var(--halco-sage-wash, #F2F4F0);
}
.halco-prose hr { border: 0; border-top: 1px solid var(--halco-line, #E3E6E0); margin: 2.4em 0; }
.halco-prose code { background: #F2F4F0; padding: 2px 6px; border-radius: 4px; font-size: .92em; }

/* End-of-article CTA — the guides currently have none */
.halco-article__cta {
  margin-top: 56px; padding: 30px 30px 34px;
  background: var(--halco-ink, #15161A); color: #fff; border-radius: 10px;
}
.halco-article__cta h2 {
  font-family: Manrope, system-ui, sans-serif; font-size: 1.5rem; font-weight: 700;
  color: #FFFFFE; margin: 0 0 10px; line-height: 1.25;
}
.halco-article__cta p { color: #C9CEC4; margin: 0 0 8px; line-height: 1.65; }
.halco-article__cta-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px !important; }

.halco-btn {
  display: inline-block; padding: 13px 26px; border-radius: 320px;
  font-family: Manrope, system-ui, sans-serif; font-size: .95rem; font-weight: 700;
  text-decoration: none; border: 1px solid transparent;
}
.halco-btn--primary { background: #FFFFFE; color: var(--halco-ink, #15161A); }
.halco-btn--primary:hover { background: var(--halco-sage-lift, #96A684); color: var(--halco-ink, #15161A); }
.halco-btn--ghost { border-color: #5A6055; color: #FFFFFE; }
.halco-btn--ghost:hover { background: #FFFFFE; color: var(--halco-ink, #15161A); }
.halco-btn:focus-visible { outline: 2px solid var(--halco-sage-lift, #96A684); outline-offset: 3px; }

/* Related */
.halco-related { margin-top: 56px; }
.halco-related > h2 {
  font-family: Manrope, system-ui, sans-serif; font-size: 1.3rem; font-weight: 700;
  color: var(--halco-ink, #15161A); margin: 0 0 18px;
}
.halco-related ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 18px; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
.halco-related a { text-decoration: none; color: inherit; display: grid; gap: 10px; }
.halco-related__media { display: block; aspect-ratio: 16 / 10; overflow: hidden; border-radius: 8px; background: #EDEFEA; }
.halco-related__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.halco-related__title {
  font-family: Manrope, system-ui, sans-serif; font-size: .98rem; font-weight: 700; line-height: 1.35;
  color: var(--halco-ink, #15161A);
}
.halco-related a:hover .halco-related__title { color: var(--halco-sage-text, #5F6D59); }

.halco-pk__tagline { font-size: .85rem; line-height: 1.55; color: #6B7280; margin: 0; }

/* -------------------------------------------------------------- Mobile CTA
   The reviews say the blocker is hesitation, not price. Keep the ask a thumb
   away on small screens. Hidden on desktop, where the header CTA is visible. */

.halco-mobile-cta { display: none; }

@media (max-width: 767px) {
  .halco-mobile-cta {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 998;
    display: flex; gap: 10px; align-items: stretch;
    padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
    background: rgba(255,255,254,.96);
    backdrop-filter: saturate(150%) blur(8px);
    border-top: 1px solid var(--halco-line, #E3E6E0);
  }
  .halco-mobile-cta a {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    min-height: 48px; border-radius: 320px; text-decoration: none;
    font-family: Manrope, system-ui, sans-serif; font-size: .95rem; font-weight: 700;
  }
  .halco-mobile-cta__call {
    flex: 0 0 auto; padding: 0 18px;
    border: 1px solid var(--halco-ink, #15161A);
    color: var(--halco-ink, #15161A);
  }
  .halco-mobile-cta__book {
    flex: 1 1 auto; padding: 0 18px;
    /* text-safe sage: white on #707F6A is only 4.25:1 */
    background: var(--halco-sage-text, #5F6D59); color: #FFFFFE;
  }
  .halco-mobile-cta a:focus-visible { outline: 2px solid var(--halco-ink, #15161A); outline-offset: 2px; }
  /* Keep the staging flag and page bottom clear of the bar. */
  body { padding-bottom: 74px; }
}

/* ---------------------------------------------------------------- Reveal
   Sections fade and lift very slightly as they enter. Deliberately subtle: the
   audience research names cognitive load as a barrier, so this must not be a
   show. Anyone who asks for reduced motion never sees it — the script does not
   even add the class. */

.halco-motion .halco-reveal { opacity: 0; transform: translateY(18px); }
.halco-motion .halco-reveal.is-in {
  opacity: 1; transform: none;
  transition: opacity .7s cubic-bezier(.16,1,.3,1), transform .7s cubic-bezier(.16,1,.3,1);
}

/* Children of a revealed section follow in sequence, so the block assembles
   rather than arriving as one slab. --halco-stagger is set per child in JS. */
.halco-motion .halco-stagger {
  animation: halco-section-rise .72s cubic-bezier(.16,1,.3,1) both;
  animation-delay: var(--halco-stagger, 0ms);
}
@keyframes halco-section-rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .halco-reveal, .halco-motion .halco-reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
  .halco-stagger, .halco-motion .halco-stagger { animation: none !important; opacity: 1 !important; transform: none !important; }
}

/* Focus visibility across everything Elementor renders — the pill buttons ship
   with no shadow or outline, so focus was invisible. */
a:focus-visible,
button:focus-visible,
select:focus-visible,
summary:focus-visible,
.elementor-button:focus-visible {
  outline: 2px solid var(--halco-sage, #707F6A);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ---------------------------------------------------- "Can I build?" qualifier
   [halco_qualifier]. Answers the exact fear the reviews name: "I thought I
   wouldn't qualify for anything." Deliberately soft — a range and a next step,
   never a yes/no. */

.halco-q {
  background: #fff;
  border: 1px solid var(--halco-line, #E3E6E0);
  border-radius: 10px;
  padding: 28px 28px 24px;
}
.halco-q__stale {
  margin: 0 0 18px; padding: 10px 14px; font-size: .85rem;
  background: #FFF8E5; border: 1px solid #E8D9A8; border-radius: 6px; color: #6B5A26;
}
.halco-q__form { display: grid; gap: 20px; }
.halco-q__step { border: 0; margin: 0; padding: 0; }
.halco-q__step legend {
  font-family: Manrope, system-ui, sans-serif;
  font-size: .78rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--halco-sage-text, #5F6D59); padding: 0 0 10px;
}
.halco-q__opts { display: flex; flex-wrap: wrap; gap: 10px; }
.halco-q__opts label {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 11px 18px; min-height: 44px;
  border: 1px solid #D3D8CE; border-radius: 320px;
  font-size: .95rem; cursor: pointer; background: #fff;
}
.halco-q__opts label:has(input:checked) {
  border-color: var(--halco-sage, #707F6A);
  background: var(--halco-sage-wash, #F2F4F0);
  font-weight: 600;
}
.halco-q__opts input { accent-color: var(--halco-sage, #707F6A); }

.halco-q__row { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.halco-q__field { display: flex; flex-direction: column; gap: 7px; }
.halco-q__field > span {
  font-family: Manrope, system-ui, sans-serif;
  font-size: .78rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--halco-sage-text, #5F6D59);
}
.halco-q__field input {
  font: inherit; font-size: 1rem; padding: 12px 14px; min-height: 46px;
  border: 1px solid #D3D8CE; border-radius: 6px; background: #fff;
}
.halco-q__field input:focus-visible { outline: 2px solid var(--halco-sage, #707F6A); outline-offset: 2px; }

.halco-q__submit {
  justify-self: start;
  font-family: Manrope, system-ui, sans-serif; font-size: 1rem; font-weight: 700;
  padding: 14px 28px; min-height: 48px;
  border: 0; border-radius: 320px; cursor: pointer;
  background: var(--halco-sage-text, #5F6D59); color: #FFFFFE;
}
.halco-q__submit:hover { background: var(--halco-ink, #15161A); }

.halco-q__out { margin-top: 26px; padding-top: 24px; border-top: 1px solid var(--halco-line, #E3E6E0); }
.halco-q__h {
  font-family: Manrope, system-ui, sans-serif; font-size: .78rem; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase;
  color: var(--halco-sage-text, #5F6D59); margin: 0 0 8px;
}
.halco-q__h + .halco-q__h, .halco-q__note + .halco-q__h { margin-top: 24px; }
.halco-q__range {
  font-family: Manrope, system-ui, sans-serif;
  font-size: clamp(1.7rem, 1.1rem + 2vw, 2.5rem); font-weight: 700; letter-spacing: -.02em;
  color: var(--halco-ink, #15161A); margin: 0 0 8px; line-height: 1.1;
}
.halco-q__sub, .halco-q__note, .halco-q__msg { font-size: .95rem; line-height: 1.65; color: #4A4E54; margin: 0 0 10px; }
.halco-q__note {
  background: var(--halco-sage-wash, #F2F4F0);
  border-left: 3px solid var(--halco-sage, #707F6A);
  padding: 12px 16px; border-radius: 0 6px 6px 0;
}
.halco-q__schemes { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.halco-q__schemes li {
  display: grid; gap: 4px;
  padding: 14px 16px; border: 1px solid var(--halco-line, #E3E6E0); border-radius: 8px;
}
.halco-q__schemes strong { font-family: Manrope, system-ui, sans-serif; font-size: .98rem; color: var(--halco-ink, #15161A); }
.halco-q__schemes span { font-size: .9rem; line-height: 1.6; color: #4A4E54; }
.halco-q__cta { display: flex; flex-wrap: wrap; gap: 10px; margin: 22px 0 0; }
.halco-btn--sage { background: var(--halco-sage-text, #5F6D59); color: #FFFFFE; }
.halco-btn--sage:hover { background: var(--halco-ink, #15161A); color: #FFFFFE; }
.halco-btn--outline { border-color: var(--halco-ink, #15161A); color: var(--halco-ink, #15161A); }
.halco-btn--outline:hover { background: var(--halco-ink, #15161A); color: #FFFFFE; }

.halco-q__disclaimer { font-size: .82rem; line-height: 1.6; color: #6B7280; margin: 22px 0 0; }
.halco-q__disclaimer a { color: var(--halco-sage-text, #5F6D59); }

/* ------------------------------------------------- Record body (shortcode)
   [halco_record] renders the ACF-driven part of a Design or Package page. The
   sections around it are Elementor containers, so these styles only cover what
   the shortcode emits. */

.halco-record__hero { margin: 0 0 32px; border-radius: 10px; overflow: hidden; }
.halco-record__hero img { width: 100%; height: auto; display: block; aspect-ratio: 3 / 2; object-fit: cover; }

.halco-record__intro { display: flex; flex-direction: column; gap: 14px; }
.halco-record__intro h1 {
  font-family: Manrope, system-ui, sans-serif;
  font-size: clamp(1.9rem, 1.3rem + 2.2vw, 2.8rem);
  font-weight: 700; line-height: 1.13; letter-spacing: -.02em;
  color: var(--halco-ink, #15161A); margin: 0;
}
.halco-record__tagline { font-size: 1.1rem; line-height: 1.6; color: #4A4E54; margin: 0; max-width: 62ch; }

.halco-record__block { margin-top: 44px; }
.halco-record__block h2 {
  font-family: Manrope, system-ui, sans-serif;
  font-size: clamp(1.4rem, 1.1rem + 1vw, 1.85rem);
  font-weight: 700; line-height: 1.2; letter-spacing: -.015em;
  color: var(--halco-ink, #15161A); margin: 0 0 16px;
}
.halco-record__block--tint {
  background: var(--halco-sage-wash, #F2F4F0);
  border-radius: 10px; padding: 30px 30px 34px;
}
.halco-record__block figure { margin: 0; }
.halco-record__block figure img { width: 100%; height: auto; border-radius: 8px; display: block; }
.halco-record__block .halco-content { font-size: 1.02rem; line-height: 1.75; color: #2E3236; max-width: 68ch; }
.halco-record__block .halco-content p { margin: 0 0 1em; }

.halco-record__gallery {
  display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
}
.halco-record__gallery figure { margin: 0; }
.halco-record__gallery img { aspect-ratio: 4 / 3; object-fit: cover; }

.halco-record__consultant {
  display: flex; gap: 20px; align-items: flex-start; flex-wrap: wrap;
  padding: 24px 26px; border: 1px solid var(--halco-line, #E3E6E0); border-radius: 10px;
}
.halco-record__consultant-photo { width: 88px; height: 88px; border-radius: 50%; object-fit: cover; flex: 0 0 auto; }
.halco-record__consultant h2 { margin: 0 0 4px; font-size: 1.3rem; }
.halco-record__consultant-role { margin: 0 0 12px; font-size: .88rem; color: var(--halco-sage-text, #5F6D59); font-weight: 600; }

/* Two-column inclusions list */
.halco-ticks--2 { columns: 2; column-gap: 32px; }
@media (max-width: 600px) { .halco-ticks--2 { columns: 1; } }

/* Specs row: see the single definition in the Pass 21 block. */

.halco-cta-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 6px; }

/* ------------------------------------------------------- Mobile card rows
   Emitted by p_cardrow(). On a phone, four stacked cards cost ~2,000px of
   scroll; the homepage had four such rows. Scroll-snap collapses each row to
   one card high. No JavaScript, and it degrades to a plain wrap on desktop. */

@media (max-width: 767px) {
  [id^="halco-scroll-"] {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    /* Bleed to the screen edge so the next card peeks — the affordance that
       tells someone there is more to swipe. */
    margin-inline: -20px;
    padding-inline: 20px;
    padding-bottom: 10px;
  }
  [id^="halco-scroll-"]::-webkit-scrollbar { display: none; }

  [id^="halco-scroll-"] > .e-con,
  [id^="halco-scroll-"] > .elementor-element {
    flex: 0 0 78% !important;
    width: 78% !important;
    max-width: 78% !important;
    scroll-snap-align: start;
  }

  /* Card images are the single biggest cost in a card row on mobile. */
  [id^="halco-scroll-"] .elementor-widget-image img { max-height: 150px; object-fit: cover; }
}

/* A quiet hint that the row scrolls, for anyone who would not think to try. */
@media (max-width: 767px) {
  [id^="halco-scroll-"] { position: relative; }
  [id^="halco-scroll-"]::after {
    content: "";
    position: sticky; right: 0; top: 0;
    flex: 0 0 4px; align-self: stretch;
  }
}

/* ------------------------------------------------- Mobile height trimming
   Production's homepage measured 16,223px on a 375px screen — roughly twenty
   screen-heights. These rules attack what is left after the card carousels. */

@media (max-width: 767px) {

  /* Two-up footer columns were tried and rejected: at 150px wide every link
     wrapped to three lines and the footer got TALLER (1,916px -> 2,238px).
     Left as one column deliberately. */

  /* Images inside split copy/image sections are decorative on a phone —
     cap them rather than letting a 3:2 photo eat 250px of scroll. */
  [data-elementor-type] .e-con .elementor-widget-image img { max-height: 230px; object-fit: cover; width: 100%; }
}

/* ==========================================================================
   Sitewide chrome — header and footer polish
   Premium here means restraint: more air, calmer type, one accent, motion you
   feel rather than watch. Not decoration.
   ========================================================================== */

/* ---------------------------------------------------------------- Header
   Sticky, translucent, with a hairline and shadow that only appear once the
   page has moved — so the top of every page starts clean. */

#halco-header {
  position: sticky;
  top: 0;
  z-index: 999;
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color .3s ease, box-shadow .3s ease, background-color .3s ease;
}
#halco-header.is-stuck {
  border-bottom-color: var(--halco-line, #E3E6E0);
  box-shadow: 0 1px 24px rgba(21, 22, 26, .06);
  background-color: rgba(255, 255, 254, .94) !important;
}

/* The underline pointer sits too close to the text by default. */
#halco-header .elementor-nav-menu--main .elementor-item::after,
#halco-header .elementor-nav-menu--main .elementor-item::before { bottom: 2px; }

#halco-header .elementor-nav-menu--main .elementor-item {
  transition: color .2s ease;
}

/* Submenu chevron: smaller, and it turns when the menu opens. */
#halco-header .elementor-nav-menu .sub-arrow svg,
#halco-header .elementor-nav-menu .sub-arrow i {
  font-size: .62em;
  opacity: .55;
  transition: transform .25s ease, opacity .2s ease;
}
#halco-header .elementor-nav-menu li:hover > a .sub-arrow svg,
#halco-header .elementor-nav-menu li:hover > a .sub-arrow i { transform: rotate(180deg); opacity: 1; }

/* Dropdowns arrive rather than appear. */
@media (min-width: 1025px) and (prefers-reduced-motion: no-preference) {
  #halco-header .elementor-nav-menu--dropdown,
  #halco-header .sm-vertical.elementor-nav-menu--dropdown {
    animation: halco-drop .22s cubic-bezier(.22,.61,.36,1) both;
  }
  @keyframes halco-drop {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: none; }
  }
}

/* Header CTA: a quiet lift on hover, no bounce. */
#halco-header .elementor-button {
  transition: background-color .25s ease, color .25s ease, transform .25s cubic-bezier(.22,.61,.36,1);
}
@media (prefers-reduced-motion: no-preference) {
  #halco-header .elementor-button:hover { transform: translateY(-1px); }
}

/* Mobile menu panel */
@media (max-width: 1024px) {
  #halco-header .elementor-nav-menu--dropdown {
    border-radius: 0 0 14px 14px;
    box-shadow: 0 22px 44px rgba(21, 22, 26, .14);
  }
  #halco-header .elementor-nav-menu--dropdown a { padding: 15px 22px !important; font-size: 16px !important; }
}


/* ---------------------------------------------------------------- Footer */

#halco-footer a { text-decoration: none; transition: color .18s ease; }
#halco-footer .elementor-icon-list-item a:hover { color: #FFFFFE; }

/* Link rows get a hairline underline on hover rather than a colour flash. */
#halco-footer .elementor-icon-list-text { position: relative; }
#halco-footer .elementor-icon-list-item a:hover .elementor-icon-list-text::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: -3px;
  height: 1px; background: currentColor; opacity: .45;
}

@media (max-width: 767px) {
  /* Eighteen links in one column is a very long ribbon on a phone. The
     column headings become accordion triggers (see halco-ux.php), and these
     styles dress them. */
  [id^="halco-foot-col-"] > .elementor-widget-heading { cursor: pointer; }
  [id^="halco-foot-col-"].is-collapsible > .elementor-widget-heading .elementor-heading-title {
    display: flex; align-items: center; justify-content: space-between;
    padding: 14px 0;
    border-bottom: 1px solid #2C2F27;
  }
  [id^="halco-foot-col-"].is-collapsible > .elementor-widget-heading .elementor-heading-title::after {
    content: "+";
    font-size: 18px; font-weight: 400; line-height: 1;
    transition: transform .25s ease;
  }
  [id^="halco-foot-col-"].is-open > .elementor-widget-heading .elementor-heading-title::after {
    transform: rotate(45deg);
  }
  [id^="halco-foot-col-"].is-collapsible > .elementor-widget-icon-list {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows .3s cubic-bezier(.22,.61,.36,1);
    overflow: hidden;
  }
  [id^="halco-foot-col-"].is-open > .elementor-widget-icon-list { grid-template-rows: 1fr; }
  [id^="halco-foot-col-"].is-collapsible > .elementor-widget-icon-list > * { min-height: 0; overflow: hidden; }
  [id^="halco-foot-col-"].is-open > .elementor-widget-icon-list .elementor-icon-list-items { padding: 12px 0 16px; }

  #halco-foot-grid { row-gap: 0 !important; }
}

@media (prefers-reduced-motion: reduce) {
  [id^="halco-foot-col-"].is-collapsible > .elementor-widget-icon-list { transition: none; }
}

/* Header items must never wrap — a wrapped nav or CTA silently doubles the
   header height (161px, observed) and pushes the hero below the fold. */
#halco-header .elementor-nav-menu--main > li > a,
#halco-header .elementor-button { white-space: nowrap; }
#halco-header .elementor-nav-menu--main { flex-wrap: nowrap; }

/* ==========================================================================
   Homepage hero — asymmetric bleed
   Copy aligned to the 1340 content grid; photography running off the right
   edge of the viewport. The alignment maths lives here because Elementor
   cannot express "align to the grid, then bleed".
   ========================================================================== */

#hero { min-height: min(88vh, 920px); overflow: hidden; position: relative; }

#halco-hero-copy {
  /* Left edge lines up with the header logo; right edge stops short of the
     photo so the two never touch.

     `padding-left` is NOT set here any more. It moved to PASS 30 near the end
     of this file, where it reads `--halco-canvas-w` instead of hard-coding
     1440px, because the boxed canvas now widens above 1600 and a hard-coded
     offset would have thrown the hero 125px out of line with every section
     below it.

     The declaration used to sit on this line and was left in place when the
     override was added, where it was dead but read as the truth: at 2240 this
     line computes 400px and the live value is 180px. That is the same trap as
     the `--halco-radius-pill` 320-over-999 duplicate, so it is struck rather
     than commented next to a value nobody should believe. */
  padding-right: clamp(32px, 5vw, 76px) !important;
  padding-top: clamp(56px, 7vw, 96px) !important;
  padding-bottom: clamp(56px, 7vw, 96px) !important;
}

#halco-hero-copy .elementor-heading-title { letter-spacing: -.028em; }

/* A hairline above the trust list, so it reads as a footnote to the promise
   rather than a fourth bullet list. */
#halco-hero-copy .elementor-widget-icon-list {
  margin-top: 6px;
  padding-top: 22px;
  border-top: 1px solid rgba(255, 255, 254, .13);
}
#halco-hero-copy .elementor-icon-list-item { font-size: 14.5px; }

#halco-hero-media { position: relative; }
#halco-hero-media .elementor-widget-image,
#halco-hero-media .elementor-widget-image .elementor-widget-container,
#halco-hero-media .elementor-widget-image figure,
#halco-hero-media .elementor-widget-image a { height: 100%; display: block; }
#halco-hero-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 45%;
  display: block;
}

/* A scrim on the photo's left edge so the copy column dissolves into the
   image instead of butting against it. */
#halco-hero-media::before {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(90deg, #15161A 0%, rgba(21,22,26,.55) 18%, rgba(21,22,26,0) 52%);
  z-index: 2; pointer-events: none;
}

/* The original 14s settle lived here and is deliberately gone. It was written
   on the assumption nobody could catch it moving; Jerald caught it on every
   refresh, which is the whole reason the hero motion was reworked. Replaced by
   the load-gated `halco-hero-zoom` in the Pass 11 block near the end of this
   file. Do not reinstate a long ambient animation here: with the kill-rule
   that used to suppress this one now removed, anything declared at this
   selector runs for real.
*/

@media (max-width: 1024px) {
  #hero { min-height: 0; }
  #halco-hero-copy {
    padding-left: 24px !important;
    padding-right: 24px !important;
    padding-top: 52px !important;
    padding-bottom: 44px !important;
  }
  #halco-hero-media { min-height: 320px; }
  #halco-hero-media::before {
    background: linear-gradient(180deg, #15161A 0%, rgba(21,22,26,0) 34%);
  }
}

/* ---------------------------------------------------------------- The grid
   Elementor gives every container a default 10px padding. On a nested column
   that pushes its content 10px off the site's left edge — so headings sat at
   80px while the logo and hero sat at 70px. Near enough to look accidental.

   Overriding the custom properties (not `padding`) means any container with
   padding set deliberately in the builder still wins on specificity: cards,
   tinted blocks and the footer keep theirs. */

.e-con-inner > .e-con {
  --padding-block-start: 0px;
  --padding-block-end: 0px;
  --padding-inline-start: 0px;
  --padding-inline-end: 0px;
}

/* On a phone the header CTA duplicates the sticky bottom bar and costs the nav
   the room it needs. One ask, not two. */
@media (max-width: 767px) {
  #halco-header .elementor-widget-button { display: none; }
}

/* ==========================================================================
   Self-hosted type (ADR-008)
   Variable woff2, latin subset, font-display: swap. Removes the third-party
   connection to fonts.gstatic.com and two render-blocking requests, and
   covers every weight in one file per family.
   ========================================================================== */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('fonts/inter-var.woff2') format('woff2-variations');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('fonts/manrope-var.woff2') format('woff2-variations');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ------------------------------------------------------------------- Logo
   Inline SVG, one file, coloured by context via currentColor. */
.halco-logo { display: block; }
.halco-logo svg { width: 100%; height: auto; display: block; }
.halco-logo__link { display: inline-block; line-height: 0; }
.halco-logo__link:focus-visible { outline: 2px solid var(--halco-sage, #707F6A); outline-offset: 4px; border-radius: 4px; }
.halco-logo--ink   { color: var(--halco-ink, #15161A); }
.halco-logo--light { color: #FFFFFE; }
@media (max-width: 767px) { .halco-logo--ink { width: 124px !important; } }

/* [halco_content] renders the WordPress content field inside an Elementor layout
   (legal pages, and anywhere copy must stay editable outside the builder). Give it
   the same prose treatment as an article. */
.halco-content { font-size: 1.02rem; line-height: 1.75; color: #2E3236; }
.halco-content > * + * { margin-top: 1.05em; }
.halco-content h2 {
  font-family: Manrope, system-ui, sans-serif;
  font-size: clamp(1.3rem, 1.05rem + .9vw, 1.65rem);
  font-weight: 700; line-height: 1.25; color: var(--halco-ink, #15161A);
  margin-top: 2em; margin-bottom: .4em;
}
.halco-content h3 {
  font-family: Manrope, system-ui, sans-serif;
  font-size: 1.12rem; font-weight: 700; color: var(--halco-ink, #15161A);
  margin-top: 1.6em; margin-bottom: .3em;
}
.halco-content a { color: var(--halco-sage-text, #5F6D59); text-decoration: underline; text-underline-offset: 2px; }
.halco-content a:hover { color: var(--halco-ink, #15161A); }
.halco-content ul, .halco-content ol { padding-left: 1.35em; display: grid; gap: .45em; }
.halco-content li::marker { color: var(--halco-sage, #707F6A); }
.halco-content strong { font-weight: 600; }

/* ==========================================================================
   Stat row, testimonials, qualifier — the three blocks that had not had a
   design pass. Same principle throughout: restraint, and let the type do it.
   ========================================================================== */

/* ---------------------------------------------------------------- Stat row
   Hairline rules between figures. It is the cheapest way to make four numbers
   read as one considered set rather than four loose items. */

[id^="halco-stat-"] { position: relative; }

@media (min-width: 768px) {
  [id^="halco-stat-"] + [id^="halco-stat-"]::before {
    content: "";
    position: absolute;
    left: calc(-1 * var(--halco-stat-gap, 12px));
    top: 4px;
    bottom: 4px;
    width: 1px;
    background: currentColor;
    opacity: .16;
  }
}

[id^="halco-stat-"] .elementor-heading-title { font-variant-numeric: tabular-nums lining-nums; }

/* The label sits under the figure, so give it a little air and stop it wrapping
   into a ragged two lines at awkward widths. */
[id^="halco-stat-"] > .elementor-widget-heading:last-child .elementor-heading-title {
  max-width: 22ch;
}

@media (max-width: 767px) {
  [id^="halco-stat-"] { padding-block: 6px; }
}


/* ----------------------------------------------------------- Testimonials
   A quote mark set large and faint, behind the text rather than in front of
   it, and a rule that separates the words from whoever said them. */

[id^="halco-quote-"] { position: relative; overflow: hidden; }

[id^="halco-quote-"]::before {
  content: "\201C";
  position: absolute;
  top: -26px;
  right: 14px;
  font-family: Manrope, Georgia, serif;
  font-size: 150px;
  line-height: 1;
  color: var(--halco-sage, #707F6A);
  opacity: .09;
  pointer-events: none;
  user-select: none;
}

[id^="halco-quote-"] .elementor-widget-text-editor { position: relative; z-index: 1; }
[id^="halco-quote-"] .elementor-widget-text-editor p { margin: 0; }

/* The attribution is the last heading in the card. */
[id^="halco-quote-"] > .elementor-widget-heading:last-child {
  margin-top: auto;
  padding-top: 16px;
  border-top: 1px solid var(--halco-line, #E3E6E0);
  width: 100%;
}
[id^="halco-quote-"] > .elementor-widget-heading:last-child .elementor-heading-title {
  letter-spacing: .04em;
  text-transform: uppercase;
  font-size: 12px;
}

@media (prefers-reduced-motion: no-preference) {
  [id^="halco-quote-"] { transition: transform .22s cubic-bezier(.16,1,.3,1), box-shadow .22s ease, border-color .22s ease; }
  [id^="halco-quote-"]:hover {
    transform: translateY(-3px);
    box-shadow: 0 14px 34px rgba(21, 22, 26, .07);
    border-color: #D3D8CE;
  }
}


/* ------------------------------------------------------------- Qualifier
   The result is the moment the page earns its keep — someone who assumed the
   answer was no is about to see a number. Make it land. */

.halco-q__out {
  border-top: 0;
  margin-top: 28px;
  padding: 26px 26px 24px;
  background: var(--halco-ink, #15161A);
  border-radius: 10px;
}
.halco-q__out .halco-q__h { color: var(--halco-sage-lift, #96A684); }
.halco-q__range {
  color: #FFFFFE;
  font-variant-numeric: tabular-nums lining-nums;
  letter-spacing: -.03em;
}
.halco-q__sub, .halco-q__msg { color: #A9B0A2; }
.halco-q__note {
  background: rgba(150, 166, 132, .12);
  border-left-color: var(--halco-sage-lift, #96A684);
  color: #D3D8CE;
}
.halco-q__schemes li { border-color: #2E322B; background: rgba(255,255,255,.02); }
.halco-q__schemes strong { color: #FFFFFE; }
.halco-q__schemes span { color: #A9B0A2; }

@media (prefers-reduced-motion: no-preference) {
  .halco-q__out[data-shown] { animation: halco-q-in .45s cubic-bezier(.16,1,.3,1) both; }
  @keyframes halco-q-in {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
  }
}

/* The form itself: a little more air between the question groups. */
.halco-q__form { gap: 24px; }
.halco-q__opts label { transition: border-color .18s ease, background-color .18s ease; }

/* Buttons inside the (now dark) qualifier result. */
.halco-q__out .halco-btn--outline { border-color: #5A6055; color: #FFFFFE; }
.halco-q__out .halco-btn--outline:hover { background: #FFFFFE; color: var(--halco-ink, #15161A); }
.halco-q__out .halco-btn--sage { background: var(--halco-sage-lift, #96A684); color: var(--halco-ink, #15161A); }
.halco-q__out .halco-btn--sage:hover { background: #FFFFFE; color: var(--halco-ink, #15161A); }
.halco-q__disclaimer { border-top: 1px solid var(--halco-line, #E3E6E0); padding-top: 18px; }

/* -------------------------------------------------- Team grid on phones
   Twelve stacked cards with 4:5 photos is roughly 7,800px of scroll — most of
   the About page. Turned on its side the same twelve cards cost about a third
   of that, and the photo still does its job at 96px. */

@media (max-width: 767px) {
  .halco-team__grid { grid-template-columns: 1fr; gap: 14px; }

  .halco-team__card {
    display: grid;
    grid-template-columns: 96px 1fr;
    align-items: start;
  }
  /* A square at the top of the column. `height: 100%` stretched it into a
     96x402 strip, which is not a portrait crop anyone would choose. */
  .halco-team__photo {
    aspect-ratio: 1 / 1;
    height: 96px;
    align-self: start;
    border-radius: 8px 0 0 8px;
  }
  .halco-team__body { padding: 14px 16px 16px; gap: 6px; }
  .halco-team__name { font-size: 1rem; }
  .halco-team__role { font-size: .76rem; line-height: 1.35; }
  /* Three lines is enough to place someone; the full bio is one tap away and is
     in the HTML either way. */
  .halco-team__lede {
    font-size: .88rem; line-height: 1.55;
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .halco-team__more[open] ~ * .halco-team__lede,
  .halco-team__card:has(.halco-team__more[open]) .halco-team__lede {
    -webkit-line-clamp: unset; overflow: visible;
  }

  /* The full bio still ships in the HTML for crawlers; it just starts closed. */
  .halco-team__more summary { font-size: .8rem; padding: 2px 0; }
  .halco-team__book { margin-top: 10px; padding: 9px 16px; font-size: .8rem; }

  /* Hover lift is meaningless on touch and costs a repaint. */
  .halco-team__card:hover { transform: none; box-shadow: none; }
}

/* --------------------------------------------------- Widgets fill their section
   Elementor sections are column flex containers. Where align-items is flex-start,
   every child shrinks to its own content width — text looks fine because it wraps
   naturally, but grids collapse. The package browser was rendering 729px wide
   inside a 1300px container, and the same thing was quietly happening to the team
   grid, the footer legal block and every card row.

   `align-self` on the child beats `align-items` on the parent, so this corrects
   pages built before the p_section() default was fixed, without touching their
   stored data. Deliberate centring still works — a centred section centres its
   text, not the widget box. */

[data-elementor-type] .e-con-inner > .elementor-widget,
[data-elementor-type] .e-con-inner > .e-con {
  align-self: stretch;
}

/* -------------------------------------------------------------- Package map
   Leaflet is self-hosted and only fetched when someone opens the map, so the
   page keeps its zero third-party requests until the visitor asks for one. */

.halco-map {
  border: 1px solid var(--halco-line, #E3E6E0);
  border-radius: 10px;
  overflow: hidden;
  background: #fff;
}
.halco-map__intro {
  display: flex; flex-wrap: wrap; gap: 16px;
  align-items: center; justify-content: space-between;
  padding: 20px 24px;
}
.halco-map__title {
  font-family: Manrope, system-ui, sans-serif;
  font-size: 1.15rem; font-weight: 700; margin: 0 0 4px;
  color: var(--halco-ink, #15161A);
}
.halco-map__note { margin: 0; font-size: .9rem; color: #6B7280; }
.halco-map__toggle {
  font-family: Manrope, system-ui, sans-serif; font-size: .9rem; font-weight: 700;
  padding: 12px 24px; min-height: 44px;
  border: 1px solid var(--halco-ink, #15161A); border-radius: 320px;
  background: transparent; color: var(--halco-ink, #15161A); cursor: pointer;
  transition: background-color .18s ease, color .18s ease;
}
.halco-map__toggle:hover:not(:disabled) { background: var(--halco-ink, #15161A); color: #fff; }
.halco-map__toggle:disabled { opacity: .6; cursor: default; }
.halco-map__toggle:focus-visible { outline: 2px solid var(--halco-sage, #707F6A); outline-offset: 3px; }

.halco-map__canvas {
  height: var(--halco-map-h, 520px);
  background: #EDEFEA;
  border-top: 1px solid var(--halco-line, #E3E6E0);
}
.halco-map__canvas[hidden] { display: none; }

.halco-map__editor {
  margin: 0; padding: 12px 24px; font-size: .82rem;
  background: #FFF8E5; border-top: 1px solid #E8D9A8; color: #6B5A26;
}

/* Popups */
.halco-map__pop { min-width: 190px; }
.halco-map__pop img { width: 100%; height: 108px; object-fit: cover; border-radius: 6px; margin-bottom: 8px; display: block; }
.halco-map__pop-sub {
  margin: 0 0 2px !important;
  font-family: Manrope, system-ui, sans-serif;
  font-size: .68rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--halco-sage-text, #5F6D59);
}
.halco-map__pop-title {
  margin: 0 0 4px !important;
  font-family: Manrope, system-ui, sans-serif; font-size: .95rem; font-weight: 700; line-height: 1.3;
  color: var(--halco-ink, #15161A);
}
.halco-map__pop-specs { margin: 0 0 8px !important; font-size: .8rem; color: #6B7280; }
.halco-map__pop a {
  font-family: Manrope, system-ui, sans-serif; font-size: .82rem; font-weight: 700;
  color: var(--halco-sage-text, #5F6D59); text-decoration: none;
}
.halco-map__pop a::after { content: " →"; }

.leaflet-container { font-family: Inter, system-ui, sans-serif; }
.leaflet-popup-content-wrapper { border-radius: 8px; }

@media (max-width: 600px) {
  .halco-map__intro { padding: 16px 18px; }
  .halco-map__toggle { width: 100%; }
  .halco-map__canvas { height: min(var(--halco-map-h, 520px), 62vh); }
}

/* --------------------------------------------------- Measured contrast fixes
   White on the raw brand sage is 4.25:1, under the 4.5 AA needs for text at
   these sizes. The fill moves one step darker to #5F6D59 (5.50:1) — the same
   hue, and the value the Elementor kit already labels "Sage (text safe)".
   The footer fine print was 3.64:1 and is now 4.93:1. */

#halco-header .elementor-button:hover,
.halco-mobile-cta__book,
.halco-team__book,
.halco-q__submit,
.halco-btn--sage { background-color: var(--halco-sage-text, #5F6D59); }

#halco-footer .elementor-widget-text-editor:nth-of-type(2),
#halco-footer .elementor-widget-text-editor:nth-of-type(2) p { color: #7F877A !important; }

/* ==========================================================================
   SESSION E — PASS 1: the header
   Client brief: "the header menu being bigger", and mobile "the way it works".

   Measured before this pass (real Chrome, anonymous):
     1440 header 105px · 1200 header 143px (WRAPPED) · 1024 106px · 375 76px
   The wrap at 1200 was a live defect. Five top-level labels measure 828px at
   16px type; with the logo, gaps and the CTA the header needs ~1218px of inner
   width, and 1200 only offers 1104. Below ~1280 there is no honest way to keep
   a horizontal nav at a readable size, so the burger takes over there and the
   panel is built to be worth using.
   ========================================================================== */

/* ---- Desktop nav: bigger type, padding that scales so it can never wrap ---
   Re-fitted twice. A sixth top-level item ("Estates") pushed six labels to
   978px at 18px, which wrapped the header to two rows and 147px at 1280.
   Session A then shortened three labels ("Home Building" to "Building",
   "Home Finance" to "Finance", "About Us" to "About"), and deliberately kept
   "Designs & Floor Plans" full length because it is the only anchor text on
   the site carrying "floor plans" and it appears on all 31 pages.

   That bought back enough width to keep the full nav at 1280. Verified live at
   1280 / 1366 / 1440 / 1512 / 1600 / 1920 / 2560: one nav row, 105px, zero
   overflow. Below 1280 the burger takes over. */
@media (min-width: 1280px) {
  /* Dialled back after Jerald read the enlarged nav as "a little too large" —
     the widened panel/dropdown were the bigger complaint, but the top-level
     type comes down with it so the whole bar reads calmer. Still above the
     original 16px baseline this replaced, just not by as much. */
  #halco-header .elementor-nav-menu--main .elementor-item {
    font-size: clamp(14.5px, 1.05vw, 16px) !important;
    padding-inline: clamp(6px, 0.8vw, 10px) !important;
  }
  #halco-hdr-right { gap: clamp(12px, 1.5vw, 22px) !important; }
}

/* ---- Burger below 1280, not below 1024 ----------------------------------
   Elementor gates its own burger with (max-width:1024px). These four rules
   move that line without touching the kit's breakpoints, which every other
   session's `_tablet` settings depend on. */
@media (min-width: 1025px) and (max-width: 1279.98px) {
  #halco-header .elementor-nav-menu--main { display: none !important; }
  #halco-header .elementor-menu-toggle { display: flex !important; }
  #halco-header nav.elementor-nav-menu--dropdown.elementor-nav-menu__container {
    display: block !important;
    overflow-y: auto !important;
  }
}

/* ---- The panel ----------------------------------------------------------
   One column, 17px labels, 54px minimum row height (above the 44px AA target
   and comfortable for a thumb), sub-items indented behind a hairline so the
   hierarchy is visible rather than implied. */
@media (max-width: 1279.98px) {
  #halco-header nav.elementor-nav-menu--dropdown.elementor-nav-menu__container {
    border-radius: 0 0 18px 18px;
    box-shadow: 0 26px 60px rgba(21, 22, 26, .18);
    border-top: 1px solid var(--halco-line, #E3E6E0);
    padding-bottom: 8px;
  }
  /* The height cap applies to the OPEN panel only. Applied unconditionally it
     beat Elementor's collapsed `max-height: 0`, leaving a 695px panel sitting
     invisibly over the hero: scaleY(0) flattens it visually but the box still
     takes hit-testing, and at 1280 it swallowed the click on the hero's
     primary CTA. Measured: elementFromPoint over "Book a free consultation"
     returned a menu link, not the button. */
  #halco-header .elementor-menu-toggle.elementor-active + nav.elementor-nav-menu--dropdown {
    max-height: calc(100dvh - var(--halco-header-h, 84px)) !important;
  }
  #halco-header .elementor-menu-toggle:not(.elementor-active) + nav.elementor-nav-menu--dropdown {
    max-height: 0 !important;
    visibility: hidden;
    pointer-events: none;
  }
  #halco-header .elementor-nav-menu--dropdown a.elementor-item {
    font-size: 16px !important;
    font-weight: 600;
    font-family: var(--halco-font-head, 'Manrope', system-ui, sans-serif);
    /* 44px is the AA target-size floor (WCAG 2.2 SC 2.5.8); this was 54px, more
       room than the panel needed. */
    min-height: 46px;
    padding: 12px 22px !important;
    border-inline-start: 0 !important;
    border-bottom: 1px solid rgba(21, 22, 26, .07);
  }
  #halco-header .elementor-nav-menu--dropdown a.elementor-sub-item {
    font-size: 14.5px !important;
    font-weight: 500;
    min-height: 44px;
    padding: 10px 22px 10px 36px !important;
    color: #4A4E54;
    position: relative;
  }
  /* The hairline that makes a sub-item read as a child, not a sibling. */
  #halco-header .elementor-nav-menu--dropdown a.elementor-sub-item::before {
    content: "";
    position: absolute; inset-block: 0; inset-inline-start: 22px;
    width: 1px; background: var(--halco-line, #E3E6E0);
  }
  #halco-header .elementor-nav-menu--dropdown .elementor-item:hover,
  #halco-header .elementor-nav-menu--dropdown .elementor-item:focus,
  #halco-header .elementor-nav-menu--dropdown .elementor-sub-item:hover,
  #halco-header .elementor-nav-menu--dropdown .elementor-sub-item:focus {
    background-color: var(--halco-sage-wash, #F2F4F0) !important;
    color: var(--halco-ink, #15161A) !important;
  }
  /* Sub-menus in the panel are always open. Two taps to reach a page that is
     already only one tap deep is exactly the cognitive load the audience
     research names. */
  #halco-header .elementor-nav-menu--dropdown ul.sub-menu { display: block !important; }
  #halco-header .elementor-nav-menu--dropdown .sub-arrow { display: none !important; }

  /* The actions appended by halco-ux.php, inside the panel. */
  .halco-panel-actions {
    display: flex; flex-direction: column; gap: 10px;
    padding: 18px 22px 6px;
  }
  .halco-panel-actions a {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    min-height: 52px; border-radius: 320px;
    font-family: var(--halco-font-head, 'Manrope', system-ui, sans-serif);
    font-size: 16px; font-weight: 700; text-decoration: none;
  }
  .halco-panel-actions .is-book {
    background: var(--halco-ink, #15161A); color: var(--halco-canvas, #FFFFFE);
  }
  .halco-panel-actions .is-call {
    background: transparent; color: var(--halco-ink, #15161A);
    border: 1px solid var(--halco-line, #E3E6E0);
  }
}

/* The burger itself: a real target, not a 24px glyph. */
#halco-header .elementor-menu-toggle {
  background-color: transparent !important;
  min-width: 48px; min-height: 48px;
  border-radius: 12px;
  transition: background-color .2s ease;
}
#halco-header .elementor-menu-toggle:hover { background-color: var(--halco-sage-wash, #F2F4F0) !important; }

/* Scroll lock while the panel is open, so the page behind does not move. */
html.halco-menu-open, html.halco-menu-open body { overflow: hidden; }

/* ==========================================================================
   SESSION E — PASS 2: the homepage hero
   Client named the hero. Measured before this pass (real Chrome, anonymous):

     1440  hero 832px, header 105 -> 937px, i.e. past the fold on a 900px laptop
     1024  hero 795px, header 106 -> 901px against a 768px viewport
      375  hero 1,175px against an 812px viewport = 1.45 screens

   The mobile number is the one that matters. The hero stacks to copy (835px)
   THEN photo (320px), so on a phone you scroll the entire promise before any
   image appears, and the photo costs 320px to show a crop nobody reads. Making
   the photo the ground the copy sits on removes that 320px outright and gives
   the mobile hero the presence it currently has none of.

   It stays an <img> with srcset and fetchpriority. Only its position changes,
   so the responsive-image rule in DESIGN-SYSTEM.md section 5 still holds.
   ========================================================================== */

/* ---- Phones: one hero, not a stack of two ------------------------------- */
@media (max-width: 767px) {
  #hero { position: relative; isolation: isolate; }

  #halco-hero-media {
    position: absolute !important;
    inset: 0;
    width: 100% !important;
    min-height: 0 !important;
    z-index: 0;
  }
  #halco-hero-media .elementor-widget-image,
  #halco-hero-media .elementor-widget-container,
  #halco-hero-media figure { height: 100%; }
  /* Overrides the sitewide 230px cap on section images, which would otherwise
     letterbox the hero photo against the top of the section. */
  #halco-hero-media img {
    height: 100% !important;
    max-height: none !important;
    object-position: 50% 38%;
  }
  /* Dark enough for AA on the body copy over the busiest part of the photo,
     open enough that the photo still reads. Measured below. */
  #halco-hero-media::before {
    background: linear-gradient(180deg,
      rgba(21,22,26,.94) 0%,
      rgba(21,22,26,.86) 38%,
      rgba(21,22,26,.90) 72%,
      rgba(21,22,26,.96) 100%) !important;
  }

  #halco-hero-copy {
    position: relative;
    z-index: 1;
    padding-top: 40px !important;
    padding-bottom: 38px !important;
    gap: 18px !important;
  }
  #halco-hero-copy .elementor-widget-icon-list { padding-top: 18px; margin-top: 2px; }
}

/* ---- Tablet and small laptop: stop the hero overrunning the fold -------- */
@media (min-width: 768px) and (max-width: 1279.98px) {
  #halco-hero-copy {
    padding-top: clamp(40px, 5vw, 64px) !important;
    padding-bottom: clamp(40px, 5vw, 64px) !important;
  }
  #hero { min-height: 0; }
}

/* ---- Desktop: soften the seam and pull the hero back inside the fold ---- */
@media (min-width: 1280px) {
  #hero { min-height: min(76vh, 720px); }
  #halco-hero-copy {
    padding-top: clamp(48px, 5.4vw, 78px) !important;
    padding-bottom: clamp(48px, 5.4vw, 78px) !important;
  }
  /* The photo met the copy on a hard vertical edge. A longer, softer ramp
     reads as one composition instead of two panels butted together. */
  #halco-hero-media::before {
    background: linear-gradient(90deg,
      #15161A 0%,
      rgba(21,22,26,.82) 12%,
      rgba(21,22,26,.42) 34%,
      rgba(21,22,26,.12) 58%,
      rgba(21,22,26,0) 78%) !important;
  }
}

/* ---- Panel actions stay reachable --------------------------------------
   The menu panel scrolls internally, so appending the two actions put them
   below 735px of list. Pinned to the foot of the panel they are always one
   thumb away, which is the point of having them there at all. */
@media (max-width: 1279.98px) {
  #halco-header nav.elementor-nav-menu--dropdown.elementor-nav-menu__container {
    display: flex !important;
    flex-direction: column;
  }
  #halco-header nav.elementor-nav-menu--dropdown > ul { flex: 1 1 auto; overflow-y: auto; }
  .halco-panel-actions {
    flex: 0 0 auto;
    position: sticky; bottom: 0;
    background: var(--halco-canvas, #FFFFFE);
    border-top: 1px solid var(--halco-line, #E3E6E0);
    padding-bottom: 16px;
  }
}

/* ---- Hero overlay up to the burger breakpoint --------------------------
   Pass 2 first applied this at 767 and below. At 768-1279 the hero was still
   a two-column row, so it measured 802px against a 768px viewport and ran
   139px past the fold. Same treatment, same breakpoint as the nav, so there
   is one line in the design where the layout changes rather than two. */
@media (min-width: 768px) and (max-width: 1279.98px) {
  #hero { position: relative; isolation: isolate; }
  #halco-hero-media {
    position: absolute !important;
    inset: 0;
    width: 100% !important;
    min-height: 0 !important;
    z-index: 0;
  }
  #halco-hero-media .elementor-widget-image,
  #halco-hero-media .elementor-widget-container,
  #halco-hero-media figure { height: 100%; }
  #halco-hero-media img {
    height: 100% !important;
    max-height: none !important;
    object-position: 50% 38%;
  }
  #halco-hero-media::before {
    background: linear-gradient(105deg,
      rgba(21,22,26,.95) 0%,
      rgba(21,22,26,.88) 42%,
      rgba(21,22,26,.72) 70%,
      rgba(21,22,26,.62) 100%) !important;
  }
  #halco-hero-copy {
    position: relative;
    z-index: 1;
    width: 100% !important;
    max-width: 660px;   /* keeps the line length readable at 1279 */
    padding-top: clamp(44px, 5vw, 60px) !important;
    padding-bottom: clamp(44px, 5vw, 60px) !important;
  }
}

/* ==========================================================================
   SESSION E — PASS 3: the footer
   Jerald, twice: "very long, it's not horizontal but vertical", and it still
   reads left-weighted.

   The cause was arithmetic, not styling. The link row was a 26% brand column
   plus four 16% columns, which is 90%, plus four 40px gaps. Against the 1,344px
   inner that totals 101.9%, so it overflowed and "Company" wrapped onto a row
   of its own at the left edge. That lone column under a full row is exactly
   what reads as vertical and left-weighted.

   Widths are now 24% + four 15% with 32px gaps, and the four columns measure
   one even row at x = 414 / 678 / 943 / 1207. Footer 1,323px -> 850px at 1440.
   ========================================================================== */

/* The legal block is a footnote, not a section, so it can carry a longer
   measure than body copy -- but not an unlimited one. Unconstrained it ran the
   full 1392px, which at 11.5px is about 157 characters a line; the
   Acknowledgement of Country in particular deserves to be readable rather than
   merely present. 100ch scales with the type and roughly a third of the line
   length. The wording is untouched and verbatim. */
#halco-foot-legal .elementor-widget-text-editor p {
  line-height: 1.5 !important;
  max-width: 100ch;
}
#halco-foot-legal .elementor-widget-text-editor + .elementor-widget-text-editor { margin-top: 2px; }
}

/* ==========================================================================
   SESSION E — PASS 4: the hero, composed rather than split
   Jerald: it "closes in on the tinge in the background" on every refresh, and
   it should feel premium and luxury on landing.

   Two separate problems.

   1. THE MOVEMENT. The hero image carried a 14s scale(1.06) -> scale(1) settle,
      written on the assumption that nobody would catch it. He caught it on
      every refresh, so the assumption was wrong and the effect is removed
      rather than tuned. Motion the reader notices on a landing screen reads as
      the page still loading, which is the opposite of composed.

   2. THE SEAM. The hero was two rectangles butted together: a flat ink panel
      and a photo starting at 52%. However soft the gradient on the photo, the
      edge is still an edge, and a visible vertical join is the single most
      "template" thing on the page. The photo now spans the whole hero and the
      copy sits on top of it, so there is no join to soften. One photograph,
      one composition.
   ========================================================================== */

/* 1. The old 14s settle is gone (superseded by Pass 11's one-time entrance
      below, not by this rule directly, since the rule that used to sit here
      would have blocked it). object-position stays free for the object-
      position overrides further down to keep winning. */

/* 2. One full-bleed photograph at every width. */
#hero { position: relative; isolation: isolate; }
#halco-hero-media {
  position: absolute !important;
  inset: 0;
  width: 100% !important;
  min-height: 0 !important;
  z-index: 0;
}
#halco-hero-media .elementor-widget-image,
#halco-hero-media .elementor-widget-container,
#halco-hero-media figure,
#halco-hero-media a { height: 100%; display: block; }
#halco-hero-media img {
  width: 100%; height: 100% !important; max-height: none !important;
  object-fit: cover;
  display: block;
}
#halco-hero-copy { position: relative; z-index: 2; }

@media (min-width: 1280px) {
  #hero { min-height: min(78vh, 740px); }

  /* The copy sits on near-solid ink on the left and the photograph is allowed
     to open up on the right. The ramp is long and eased, so there is no point
     at which the reader can see where the panel ends. */
  #halco-hero-media::before {
    background:
      linear-gradient(90deg,
        #14151A 0%,
        #14151A 26%,
        rgba(20,21,26,.94) 38%,
        rgba(20,21,26,.72) 50%,
        rgba(20,21,26,.40) 62%,
        rgba(20,21,26,.14) 76%,
        rgba(20,21,26,0) 92%) !important;
  }
  /* A second, very quiet pass top and bottom. It stops the photograph meeting
     the header and the next section on a hard line, and it is what gives the
     frame depth rather than flatness. */
  #halco-hero-media::after {
    content: "";
    position: absolute; inset: 0; z-index: 3; pointer-events: none;
    background:
      linear-gradient(180deg, rgba(20,21,26,.55) 0%, rgba(20,21,26,0) 22%),
      linear-gradient(0deg,   rgba(20,21,26,.62) 0%, rgba(20,21,26,0) 26%);
  }
  #halco-hero-copy {
    width: 52% !important;
    max-width: 720px;
    padding-right: clamp(40px, 4vw, 64px) !important;
  }
  /* Crop toward the people rather than the shelving. */
  #halco-hero-media img { object-position: 68% 42%; }
}

/* A sage rule ahead of the eyebrow. Small, but it is the detail that makes the
   block read as set rather than typed. */
#halco-hero-copy .elementor-widget-heading:first-child .elementor-heading-title {
  display: inline-flex; align-items: center; gap: 12px;
}
#halco-hero-copy .elementor-widget-heading:first-child .elementor-heading-title::before {
  content: ""; width: 28px; height: 1px; flex: 0 0 28px;
  background: var(--halco-sage-lift, #96A684); opacity: .8;
}

@media (max-width: 1279.98px) {
  #halco-hero-media::after {
    content: "";
    position: absolute; inset: 0; z-index: 3; pointer-events: none;
    background: linear-gradient(180deg, rgba(20,21,26,.5) 0%, rgba(20,21,26,0) 18%);
  }
}

/* ==========================================================================
   SESSION E — PASS 5: the header floats over the hero
   The last thing making the landing screen read as a template was a solid
   white band cutting across the top of the photograph. On the homepage the
   header now sits on the image with no background of its own, and takes its
   white background only once the page has moved, which the sticky state
   already did. Every other page is untouched.

   Nothing depends on JavaScript: the offset uses a CSS custom property with a
   hard fallback, so if halco-ux.php never runs the header still lands in the
   right place. The `is-stuck` rules further up already win once scrolled,
   because they are declared with !important on the background.
   ========================================================================== */

body.home {
  --halco-hdr-h: 105px;
}
@media (max-width: 767px) { body.home { --halco-hdr-h: 77px; } }

body.home #halco-header:not(.is-stuck) {
  background-color: transparent !important;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-bottom-color: transparent;
  box-shadow: none;
}
/* White logo, nav and burger while the header is over the photograph. The mark
   is drawn in currentColor, so this is a colour change and not a second file. */
body.home #halco-header:not(.is-stuck) .halco-logo--ink { color: #FFFFFE; }
body.home #halco-header:not(.is-stuck) .elementor-nav-menu--main .elementor-item,
body.home #halco-header:not(.is-stuck) .elementor-menu-toggle { color: #FFFFFE !important; }
body.home #halco-header:not(.is-stuck) .elementor-menu-toggle svg { fill: #FFFFFE; }
body.home #halco-header:not(.is-stuck) .elementor-nav-menu--main .elementor-item:hover { color: #FFFFFE !important; }
body.home #halco-header:not(.is-stuck) .elementor-menu-toggle:hover { background-color: rgba(255,255,254,.14) !important; }
/* The header CTA was ink-on-white. On the photograph it becomes white-on-ink,
   which keeps it the strongest thing in the bar without introducing a colour. */
body.home #halco-header:not(.is-stuck) #halco-hdr-cta .elementor-button {
  background-color: #FFFFFE !important;
  color: var(--halco-ink, #15161A) !important;
}

/* The hero rises behind the header, and the copy is pushed clear of it. */
body.home #hero { margin-top: calc(-1 * var(--halco-hdr-h)); }
body.home #halco-hero-copy {
  padding-top: calc(var(--halco-hdr-h) + clamp(28px, 3.4vw, 54px)) !important;
}

/* A deeper scrim across the top of the photograph, sized to the header, so the
   nav has guaranteed ground under it whatever the image happens to be doing
   there. Measured after: every header item clears AA. */
body.home #halco-hero-media::after {
  background:
    linear-gradient(180deg, rgba(18,19,23,.82) 0%, rgba(18,19,23,.55) 42%, rgba(18,19,23,0) 100%)
      no-repeat top / 100% calc(var(--halco-hdr-h) * 2.1),
    linear-gradient(0deg, rgba(20,21,26,.62) 0%, rgba(20,21,26,0) 26%) !important;
}

/* ==========================================================================
   SESSION E — PASS 6: the header actually sticks, and returns on scroll up
   Jerald: "having the nav bar somehow pop up even as we scroll down, not
   sticky, but it pops up, because currently it disappears altogether."

   He is describing a real defect, not a preference. `position: sticky` was on
   `#halco-header`, whose containing block is the 105px `.elementor-location-
   header` wrapper. A sticky box cannot leave its containing block, so the
   header slid away at the first scroll on EVERY page and never returned.
   Measured before: at scrollY 600 / 1800 / 4000 the header sat at top -600 /
   -1800 / -4000 on both the homepage and About.

   Sticky now sits on the wrapper, whose containing block is the body, so it
   holds at the top for the whole document. On top of that it steps out of the
   way while you read down and returns as soon as you scroll up.
   ========================================================================== */

header.elementor-location-header {
  position: sticky;
  top: 0;
  z-index: 999;
  transition: transform .34s cubic-bezier(.22,.61,.36,1);
  will-change: transform;
}
header.elementor-location-header.is-away { transform: translateY(-102%); }

/* The inner element keeps its own colour and hairline states, but must not
   compete for stickiness now that the wrapper owns it. */
#halco-header { position: relative; top: auto; }

@media (prefers-reduced-motion: reduce) {
  header.elementor-location-header { transition: none; }
  /* Anyone who has asked for less motion keeps the header where it is rather
     than having it slide in and out of view. */
  header.elementor-location-header.is-away { transform: none; }
}

/* Once it has left the hero the header is always solid, including on the
   homepage, so returning mid-page never lands white type on white content. */
header.elementor-location-header.is-away #halco-header,
body.home #halco-header.is-stuck {
  background-color: rgba(255, 255, 254, .96) !important;
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
}

/* ==========================================================================
   SESSION E — PASS 6b: the hero at large viewports
   Jerald: the words should run further right rather than hugging the left, and
   the photograph should sit a little further right.

   At 2000px wide the copy was capped at 720px against a 280px grid offset, so
   the text finished at the halfway line and left a wide dark gap before the
   photograph. The column now scales with the viewport instead of stopping.
   ========================================================================== */
@media (min-width: 1280px) {
  #halco-hero-copy {
    width: 56% !important;
    max-width: min(56vw, 920px);
    padding-right: clamp(48px, 4.5vw, 88px) !important;
  }
  /* The ramp moves right with the copy, so the text keeps its ground and the
     photograph still opens up rather than being cut off behind a wall. */
  #halco-hero-media::before {
    background:
      linear-gradient(90deg,
        #14151A 0%,
        #14151A 30%,
        rgba(20,21,26,.94) 42%,
        rgba(20,21,26,.70) 55%,
        rgba(20,21,26,.36) 68%,
        rgba(20,21,26,.10) 82%,
        rgba(20,21,26,0) 95%) !important;
  }
  /* A little further right, so more of the far side of the room is in frame. */
  #halco-hero-media img { object-position: 74% 42%; }
}

/* ==========================================================================
   SESSION E — PASS 7: vertical rhythm and line length
   Jerald, third on his list: section padding and vertical rhythm "could be
   further enlightened and improved". Readability was the first word of his
   original brief.

   Measured before this pass:
     - Some paragraphs ran the full 1,392px content width, about 242 characters
       per line, against a 45 to 75 character target. `--halco-measure: 68ch`
       has been a token since the design system was written and was never
       applied to anything.
     - Where two untinted sections sit next to each other their padding doubles
       and the boundary opens to 168px on the homepage, 84px on First Home
       Buyers, 80px on About, against 88px inside a section. A gap twice the
       size of the rhythm reads as a missing section rather than a division.
     - Eyebrow to heading measured 8 to 22px throughout, which is correct
       pairing. Left alone.
   ========================================================================== */

/* ---- Line length --------------------------------------------------------
   Only bites when the container is wider than the measure, so cards, columns
   and the narrow prose blocks are all untouched. Applies to `p` only, so the
   comparison tables emitted by p_table() keep their full width. */
[data-elementor-type] .elementor-widget-text-editor p { max-width: var(--halco-measure, 68ch); }

/* Centred blocks keep their centre. Without this the CTA band copy would sit
   left of its own heading. */
[data-elementor-type] .elementor-widget-text-editor[class*="text-align-center"] p,
[data-elementor-type] [style*="text-align: center"] .elementor-widget-text-editor p,
[data-elementor-type] .e-con[class*="text-align-center"] .elementor-widget-text-editor p {
  margin-inline: auto;
}

/* ---- The doubled boundary ----------------------------------------------
   Two adjacent sections with no background between them were paying full
   padding twice. Elementor writes the tint as `background_background` into
   `data-settings`, so an untinted section is one without it, and this needs no
   change to any build file. Specificity is (0,5,0) against Elementor's
   per-element (0,2,0), so it wins without `!important` and the client can
   still set padding deliberately anywhere it matters. */
[data-elementor-type] > .e-con:not([data-settings*="background_background"])
  + .e-con:not([data-settings*="background_background"]) {
  padding-top: clamp(28px, 3.2vw, 44px);
}

/* The other half of the boundary. Setting only the top padding left the pair
   at 124px, because the section above was still paying a full bottom. `:has()`
   gives the previous-sibling match CSS has never had; where it is unsupported
   the rule is simply ignored and the boundary stays at the old size, which is
   the safe direction to fail in. Together the pair now reads as one 88px
   rhythm step rather than two.

   Deliberately not attempted: two adjacent sections that share the SAME tint.
   `data-settings` records that a section has a background, never which colour,
   so wash-after-wash and wash-after-dark are indistinguishable here and the
   rule would collapse a boundary that is doing real work. Two cases remain,
   on the suburb hubs, and they are a page-composition matter rather than a
   stylesheet one. */
[data-elementor-type] > .e-con:not([data-settings*="background_background"]):has(
    + .e-con:not([data-settings*="background_background"])) {
  padding-bottom: clamp(28px, 3.2vw, 44px);
}

/* ==========================================================================
   SESSION E — PASS 8: the team, as a modal, with a leadership tag
   Jerald prefers the production site's popup to the inline disclosure, and
   asked for the leadership tag back.

   The full bio stays in the HTML inside <details>. With no JavaScript the
   disclosure opens exactly as before. The modal is an enhancement over it, not
   a replacement, because those bios are roughly 4,000 words of real expertise
   and the site's strongest E-E-A-T asset. Nothing is hidden from a crawler to
   get the nicer interaction.
   ========================================================================== */

/* ---- Card ---------------------------------------------------------------- */
.halco-team__tag {
  align-self: flex-start;
  display: inline-block;
  padding: 4px 10px;
  border-radius: 320px;
  background: var(--halco-sage-wash, #F2F4F0);
  border: 1px solid #D8DED3;
  color: var(--halco-sage-dark, #4F5A4A);
  font-family: var(--halco-font-head, Manrope, system-ui, sans-serif);
  font-size: 10.5px; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase;
  margin-bottom: 2px;
}

/* The opening paragraph appears on the card already, so the copy of it that
   the modal reads from must not be shown twice inside the disclosure. */
.halco-team__more .halco-team__lede-copy { display: none; }
.halco-bio .halco-team__lede-copy { display: block; }

/* The disclosure now reads as an action rather than a toggle. */
.halco-team__more summary::after { content: " →"; transition: transform .18s ease; display: inline-block; }
.halco-team__more[open] summary::after { content: " →"; }
.halco-team__more summary:hover::after { transform: translateX(3px); }

/* ---- Modal --------------------------------------------------------------- */
.halco-bio {
  width: min(880px, calc(100vw - 32px));
  max-height: min(86dvh, 820px);
  padding: 0;
  border: 0;
  border-radius: 16px;
  background: var(--halco-canvas, #FFFFFE);
  color: var(--halco-ink, #15161A);
  box-shadow: 0 40px 90px rgba(21, 22, 26, .32);
  overflow: hidden;
}
.halco-bio::backdrop {
  background: rgba(15, 16, 19, .62);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}
.halco-bio__inner {
  display: grid;
  grid-template-columns: 300px 1fr;
  max-height: inherit;
}
.halco-bio__photo { background: #EDEFEA; }
.halco-bio__photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.halco-bio__copy {
  padding: 34px 36px 36px;
  overflow-y: auto;
  display: flex; flex-direction: column; gap: 10px;
}
.halco-bio__tag {
  align-self: flex-start;
  padding: 4px 10px; border-radius: 320px;
  background: var(--halco-sage-wash, #F2F4F0); border: 1px solid #D8DED3;
  color: var(--halco-sage-dark, #4F5A4A);
  font-family: var(--halco-font-head, Manrope, system-ui, sans-serif);
  font-size: 10.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
}
.halco-bio__name {
  font-family: var(--halco-font-head, Manrope, system-ui, sans-serif);
  font-size: clamp(1.5rem, 1.2rem + 1vw, 2rem); font-weight: 700;
  line-height: 1.15; letter-spacing: -.02em; margin: 0;
}
.halco-bio__role {
  margin: 0; color: var(--halco-sage-text, #5F6D59);
  font-family: var(--halco-font-head, Manrope, system-ui, sans-serif);
  font-size: .9rem; font-weight: 600;
}
.halco-bio__text { margin-top: 6px; }
.halco-bio__text p {
  margin: 0 0 .9em; color: #43474D;
  font-size: 1rem; line-height: 1.72; max-width: 62ch;
}
.halco-bio__text p:last-child { margin-bottom: 0; }
.halco-bio__actions { margin-top: 8px; }
.halco-bio__book { display: inline-block; }

.halco-bio__close {
  position: absolute; top: 12px; right: 12px; z-index: 2;
  width: 40px; height: 40px;
  display: grid; place-items: center;
  border: 0; border-radius: 999px;
  background: rgba(255, 255, 254, .92);
  color: var(--halco-ink, #15161A);
  cursor: pointer;
  box-shadow: 0 2px 10px rgba(21, 22, 26, .16);
  transition: background-color .18s ease, transform .18s ease;
}
.halco-bio__close:hover { background: #fff; transform: scale(1.05); }
.halco-bio__close:focus-visible { outline: 2px solid var(--halco-sage, #707F6A); outline-offset: 2px; }

@media (max-width: 767px) {
  .halco-bio { width: calc(100vw - 20px); max-height: 88dvh; border-radius: 14px; }
  .halco-bio__inner { grid-template-columns: 1fr; }
  .halco-bio__photo { max-height: 200px; }
  .halco-bio__copy { padding: 22px 20px 26px; }
}

@media (prefers-reduced-motion: no-preference) {
  .halco-bio[open] { animation: halco-bio-in .26s cubic-bezier(.22,.61,.36,1); }
  .halco-bio[open]::backdrop { animation: halco-bio-fade .26s ease; }
  @keyframes halco-bio-in { from { opacity: 0; transform: translateY(10px) scale(.985); } }
  @keyframes halco-bio-fade { from { opacity: 0; } }
}

/* ==========================================================================
   Bare <button> elements were crimson
   hello-elementor ships `[type="button"], [type="submit"], button { color:#c36 }`
   with a `:hover, :focus` state of `background:#c36; color:#fff`. Any button
   that is not one of Elementor's own widgets inherits it. That is why the
   disclosure control read as a pink pill in Jerald's screenshot, and why the
   bio modal's close button turned magenta the instant it opened: showModal()
   focuses the first control, so `:focus` fires immediately, not on interaction.

   Scoped to our own components rather than reset globally, so Elementor's
   widgets and any WordPress core block keep their own styling.
   ========================================================================== */
/* `:where()` so the reset contributes zero specificity. Written first as a
   plain selector it scored (0,2,1) on `:focus` and beat the component's own
   (0,2,0) rule, which left the close control transparent instead of white. A
   reset should lose every argument with the thing it is resetting. */
:where(button[class^="halco-"], button[class*=" halco-"]),
:where(button[class^="halco-"], button[class*=" halco-"]):hover,
:where(button[class^="halco-"], button[class*=" halco-"]):focus {
  color: inherit;
  border-color: currentColor;
  background-color: transparent;
}

/* The close control, restated after the reset so every state is explicit. */
.halco-bio__close,
.halco-bio__close:hover,
.halco-bio__close:focus,
.halco-bio__close:focus-visible {
  background-color: rgba(255, 255, 254, .94);
  color: var(--halco-ink, #15161A);
  border: 1px solid var(--halco-line, #E3E6E0);
}
.halco-bio__close:hover { background-color: #FFFFFE; }
.halco-bio__close:focus-visible { outline: 2px solid var(--halco-sage, #707F6A); outline-offset: 2px; }

/* ==========================================================================
   In-page anchors must clear the sticky header
   Now that the header genuinely sticks, an anchor jump lands its target flush
   against the viewport top and the header sits on top of it. Measured on
   /about-us/#team: the target's top was 0, entirely behind a 105px header, so
   "Meet Our Team" appeared to land in the middle of a bio. The same applied to
   the homepage hero's "See if you qualify" pointing at #qualify.

   scroll-margin-top only affects scroll-into-view, so it is safe to apply
   broadly and costs nothing anywhere else.
   ========================================================================== */
[id] { scroll-margin-top: 124px; }
@media (max-width: 767px) { [id] { scroll-margin-top: 96px; } }

/* ==========================================================================
   SESSION E — PASS 9: one card treatment, not two
   Session C's finding, and it is a real one. The `pbx-*` decorations live in
   patterns-b.php, so the sixteen pages that require it get a hover lift, an
   image zoom and a focus ring, and the fourteen that do not, including the
   HOMEPAGE and ABOUT, render the same component flat. Two visual dialects
   decided by a PHP include rather than by design.

   Fixed on the base selector every card row already has, rather than by
   promoting the pbx classes, because Elementor containers ignore `_css_classes`
   from raw JSON (the trap in section 17) and `[id^="halco-scroll-"]` is the
   handle that exists on all thirty-three pages. No build file changes, no
   re-runs, and the pbx pages keep working since the rules are equivalent.
   ========================================================================== */

[id^="halco-scroll-"] > .e-con {
  border-radius: 8px;
  overflow: hidden;
}
[id^="halco-scroll-"] > .e-con .elementor-widget-image { overflow: hidden; border-radius: 6px; }

@media (prefers-reduced-motion: no-preference) {
  [id^="halco-scroll-"] > .e-con {
    transition: transform .22s cubic-bezier(.22,.61,.36,1), box-shadow .22s cubic-bezier(.22,.61,.36,1);
  }
  [id^="halco-scroll-"] > .e-con:hover {
    transform: translateY(-3px);
    box-shadow: 0 12px 30px rgba(21, 22, 26, .09);
  }
  [id^="halco-scroll-"] > .e-con .elementor-widget-image img {
    transition: transform .4s cubic-bezier(.22,.61,.36,1);
  }
  [id^="halco-scroll-"] > .e-con:hover .elementor-widget-image img { transform: scale(1.035); }
}

/* A card whose link has focus should look as lifted as one under the pointer,
   so keyboard and mouse get the same feedback. */
[id^="halco-scroll-"] > .e-con:focus-within {
  box-shadow: 0 12px 30px rgba(21, 22, 26, .09);
}

/* ==========================================================================
   SESSION E — PASS 10: inline body links are colour-only
   Found on a visual pass of a page not yet reviewed, not by any automated
   check. Measured: link colour rgb(95,109,89) against surrounding body text
   rgb(58,61,66) is 1.98:1, under the 3:1 WCAG 1.4.1 needs when the only
   distinguishing signal is colour. No underline at rest, on hover, or on
   focus. Passes AA as text against white on its own (5.5:1) so no automated
   text-contrast check catches it, since none of them compare a link to its
   OWN paragraph rather than to the page background.

   73+ inline links across nine pages sampled, all body copy: guides, FAQ
   answers, blog posts. The audience research names cognitive load as a
   barrier, and "which words are clickable" is exactly that kind of ambiguity.
   ========================================================================== */
.elementor-widget-text-editor p a,
.halco-article__body a,
.halco-content a {
  text-decoration: underline;
  text-decoration-color: rgba(95, 109, 89, .45);
  text-underline-offset: 3px;
  transition: text-decoration-color .18s ease, color .18s ease;
}
.elementor-widget-text-editor p a:hover,
.halco-article__body a:hover,
.halco-content a:hover {
  color: var(--halco-ink, #15161A);
  text-decoration-color: currentColor;
}

/* ==========================================================================
   SESSION E — PASS 11: final polish, motion with intent
   Jerald: bring the hero's motion back, done properly, and look for anything
   else that makes the site feel more premium and alive. Four additions, all
   guarded by prefers-reduced-motion, all compositor-only (transform/opacity),
   so none of them cost a layout pass or a request.
   ========================================================================== */

/* ---- 1. Every pill button lifts on hover, not just the header's -----------
   The header CTA has had a considered hover since day one. Everywhere else,
   `.elementor-button` only had Elementor's own colour swap: functional, but
   flat next to the header. Same restrained lift, same easing, applied once,
   sitewide, so the whole button vocabulary reads as one system. */
@media (prefers-reduced-motion: no-preference) {
  .elementor-widget-button .elementor-button,
  .halco-btn, .halco-cta {
    transition: transform .22s cubic-bezier(.22,.61,.36,1),
                box-shadow .22s cubic-bezier(.22,.61,.36,1),
                background-color .22s ease, color .22s ease;
  }
  .elementor-widget-button .elementor-button:hover,
  .halco-btn:hover, .halco-cta:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 20px rgba(21, 22, 26, .12);
  }
  .elementor-widget-button .elementor-button:active,
  .halco-btn:active, .halco-cta:active {
    transform: translateY(-1px);
    transition-duration: .08s;
  }
}
/* The mobile bottom bar is already docked at the screen edge; a shadow there
   would read as a stray line rather than depth, so it keeps the colour swap
   only. */
.halco-mobile-cta .elementor-button,
.halco-mobile-cta a { box-shadow: none !important; }

/* ---- 2. The hero photo, entering once ------------------------------------
   Removed entirely in an earlier pass because the previous version ran for
   14 seconds, so it was still visibly moving whenever anyone looked back at
   it or returned to the tab: a photo that keeps drifting reads as unfinished
   loading, not as a considered detail. This one is different in kind, not
   just degree: it completes in under two seconds, once, on load, then stops
   for good. Nobody can "catch" a motion that is over before they have had
   time to focus on the page. */
@media (prefers-reduced-motion: no-preference) {
  /* Two animations, deliberately separated, because they answer two different
     needs that a single keyframe cannot serve at once.

     The fade is FAST (0.55s): the photograph must be on screen promptly. The
     audience research describes anxious readers on phones, and a hero that
     withholds itself for three seconds is the same failure as a page that
     needs JavaScript to be legible.

     The zoom is SLOW (3.4s) and close to linear, which is the part Jerald
     actually asked for. The previous attempt used a quart-out curve and was
     91% finished within the first 500ms, so lengthening it to 3.2s changed the
     number without changing the feel: still "too quick". An ease-out curve
     spreads the movement across the whole duration so it reads as a slow
     settle you can actually perceive, and it still ends, once, unlike the
     original 14s version that was always caught mid-drift. */
  /* Gated on `.is-ready`, which halco-ux.php adds once the image has actually
     decoded. Without the gate the animation clock starts at CSS parse time,
     long before the photograph is on screen: measured, it was already 55%
     through the zoom by the time the page finished loading, so most of the
     movement happened before there was anything to watch. That is why
     lengthening the duration alone never fixed "too quick".

     Fail-safe by construction: the un-gated state is the finished state. If
     the script never runs, the hero is simply static and fully visible, which
     is the correct thing to degrade to. */
  #halco-hero-media img.is-ready {
    animation:
      halco-hero-fade .55s ease-out both,
      halco-hero-zoom 3.4s cubic-bezier(0, 0, .58, 1) both;
  }
  @keyframes halco-hero-fade {
    from { opacity: .001; }
    to   { opacity: 1; }
  }
  @keyframes halco-hero-zoom {
    from { transform: scale(1.06); }
    to   { transform: scale(1); }
  }
}

/* ---- 3. Smooth scroll for anchor links -------------------------------
   The qualifier, the team section and every footer/nav anchor jump now glide
   rather than cut. Guarded the same as everything else: a hard cut is what
   reduced motion asks for. */
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

/* ==========================================================================
   SESSION E — PASS 12: a divider where two untinted sections meet
   Pass 7 collapsed the doubled padding between same-tone neighbours, which
   fixed the spacing but left nothing to mark the join. On pages that run two
   or three untinted sections back to back that reads as one undifferentiated
   slab: /reviews/ has three consecutive at 1,855px, /new-to-australia/ has a
   1,468px section straight after a 1,542px one, and the audience research
   names cognitive load as the barrier to starting at all.

   A hairline, on the content grid rather than full-bleed, so it reads as
   editorial punctuation rather than a border. Same `:has()` pair the padding
   rule already targets, so the two always agree about where a boundary is.
   ========================================================================== */
@media (min-width: 768px) {
  /* p_section() nests: outer .e-con-full > inner .e-con-boxed > .e-con-inner.
     The rule goes on the boxed child's inner so the hairline sits on the
     content grid rather than running the full bleed of the section. */
  [data-elementor-type] > .e-con:not([data-settings*="background_background"])
    + .e-con:not([data-settings*="background_background"])
    > .e-con-boxed > .e-con-inner {
    border-top: 1px solid var(--halco-line, #E3E6E0);
    padding-top: clamp(28px, 3.2vw, 44px);
  }
}
/* On a phone the sections are already far apart in scroll terms and the rule
   would sit tight against a heading, so the spacing alone does the work. */

/* ==========================================================================
   SESSION E — PASS 13: the 404, the skip link, and a selection colour
   Three details that separate "built" from "cared for". None of them are on a
   page anyone plans, which is exactly why they signal how much attention the
   rest of the site got.
   ========================================================================== */

/* ---- The skip link ------------------------------------------------------
   hello-elementor ships it with `.screen-reader-text`, which hides it, but
   never styles the focused state. So even once it worked it would appear as
   an unstyled browser-default box over the logo. */
.skip-link.screen-reader-text:focus,
.skip-link:focus-visible {
  position: fixed !important;
  top: 12px; left: 12px;
  z-index: 100000;
  width: auto !important; height: auto !important;
  clip: auto !important; clip-path: none !important;
  padding: 12px 20px;
  border-radius: 320px;
  background: var(--halco-ink, #15161A);
  color: var(--halco-canvas, #FFFFFE);
  font-family: var(--halco-font-head, Manrope, system-ui, sans-serif);
  font-size: 15px; font-weight: 700;
  text-decoration: none;
  box-shadow: 0 10px 30px rgba(21, 22, 26, .28);
  outline: 2px solid var(--halco-sage-lift, #96A684);
  outline-offset: 2px;
}
/* The jump target carries no height of its own. */
#content { scroll-margin-top: 124px; }
@media (max-width: 767px) { #content { scroll-margin-top: 96px; } }

/* ---- Selection ----------------------------------------------------------
   The default is the browser's blue, which is the one colour on the page that
   belongs to nobody. Sage wash with ink text keeps it legible on both the
   light and the tinted sections. */
::selection { background: #D5DCCD; color: var(--halco-ink, #15161A); }
::-moz-selection { background: #D5DCCD; color: var(--halco-ink, #15161A); }

/* ---- 404 ---------------------------------------------------------------- */
.halco-404 {
  padding: clamp(64px, 9vw, 128px) var(--halco-gutter, 24px) clamp(72px, 10vw, 140px);
  background: var(--halco-canvas, #FFFFFE);
}
.halco-404__inner { max-width: 1440px; margin-inline: auto; }

.halco-404__eyebrow {
  display: inline-flex; align-items: center; gap: 12px;
  margin: 0 0 18px;
  color: var(--halco-sage-text, #5F6D59);
  font-family: var(--halco-font-head, Manrope, system-ui, sans-serif);
  font-size: 13px; font-weight: 700; letter-spacing: 1.4px; text-transform: uppercase;
}
.halco-404__eyebrow::before {
  content: ""; width: 28px; height: 1px; flex: 0 0 28px;
  background: var(--halco-sage, #707F6A); opacity: .8;
}
.halco-404__title {
  margin: 0 0 18px;
  font-family: var(--halco-font-head, Manrope, system-ui, sans-serif);
  font-size: clamp(2rem, 1.4rem + 2.6vw, 3.5rem);
  font-weight: 700; line-height: 1.1; letter-spacing: -.028em;
  color: var(--halco-ink, #15161A);
  max-width: 20ch; text-wrap: balance;
}
.halco-404__lede {
  margin: 0 0 32px;
  max-width: 56ch;
  font-size: clamp(1rem, .97rem + .2vw, 1.125rem);
  line-height: 1.7; color: #4A4E54;
}

.halco-404__actions { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: clamp(48px, 6vw, 76px); }
.halco-404__btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 50px; padding: 14px 30px;
  border-radius: 320px;
  font-family: var(--halco-font-head, Manrope, system-ui, sans-serif);
  font-size: 16px; font-weight: 700; text-decoration: none;
}
.halco-404__btn--primary { background: var(--halco-sage-text, #5F6D59); color: #FFFFFE; }
.halco-404__btn--primary:hover { background: var(--halco-ink, #15161A); color: #FFFFFE; }
.halco-404__btn--ghost { background: transparent; color: var(--halco-ink, #15161A); border: 1px solid var(--halco-ink, #15161A); }
.halco-404__btn--ghost:hover { background: var(--halco-ink, #15161A); color: #FFFFFE; }

.halco-404__grid {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 20px;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  border-top: 1px solid var(--halco-line, #E3E6E0);
  padding-top: clamp(32px, 4vw, 48px);
}
.halco-404__card a {
  display: flex; flex-direction: column; gap: 8px;
  height: 100%; padding: 22px 22px 24px;
  border: 1px solid var(--halco-line, #E3E6E0);
  border-radius: 8px;
  text-decoration: none;
  background: var(--halco-canvas, #FFFFFE);
}
.halco-404__card-title {
  font-family: var(--halco-font-head, Manrope, system-ui, sans-serif);
  font-size: 1.05rem; font-weight: 700; line-height: 1.3;
  color: var(--halco-ink, #15161A);
}
.halco-404__card-body { font-size: .93rem; line-height: 1.6; color: #4A4E54; }

@media (prefers-reduced-motion: no-preference) {
  .halco-404__card a, .halco-404__btn {
    transition: transform .22s cubic-bezier(.22,.61,.36,1),
                box-shadow .22s cubic-bezier(.22,.61,.36,1),
                background-color .2s ease, color .2s ease, border-color .2s ease;
  }
  .halco-404__card a:hover { transform: translateY(-3px); box-shadow: 0 12px 30px rgba(21,22,26,.09); }
  .halco-404__btn:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(21,22,26,.12); }
}
.halco-404__card a:focus-visible,
.halco-404__btn:focus-visible { outline: 2px solid var(--halco-sage, #707F6A); outline-offset: 3px; }

/* ==========================================================================
   SESSION E — PASS 14: a lede for prose-heavy sections
   The structural audit found pages carrying eight text-only sections with one
   image between them: /new-to-australia/ has a 1,542px section and a 1,468px
   section back to back, /building/first-home-buyers/ and /do-you-charge-fees/
   are similar. Imagery would be the real fix and it is not available, so this
   does the job typographically instead: the opening paragraph of a section
   reads as a standfirst, which gives the eye a step down from heading to body
   and a place to enter. It is the oldest trick in editorial layout and it
   costs nothing.

   Scoped by heading level, which is the clean discriminator here: sections use
   `h2` via p_heading(), cards use `h3` via p_card(). Both have the identical
   "heading widget followed by text widget" shape, so without the `:has(> h2)`
   this would restyle every card on the site.
   ========================================================================== */
.elementor-widget-heading:has(> h2) + .elementor-widget-text-editor > p:first-child {
  font-size: clamp(1.0625rem, 1rem + .35vw, 1.1875rem);
  line-height: 1.72;
  /* No colour here on purpose: Elementor writes the text colour per widget at
     a higher specificity, so a declaration would be dead CSS. The size and
     leading step is what creates the hierarchy anyway. */
}
/* The CTA bands also use an h2 with copy under it, but they are centred, short
   and already sized as a pair, so they keep their own treatment. */
.e-con[style*="text-align"] .elementor-widget-heading:has(> h2) + .elementor-widget-text-editor > p:first-child,
[data-elementor-type] > .e-con[data-settings*="background_background"]
  .elementor-widget-heading:has(> h2) + .elementor-widget-text-editor > p:first-child {
  font-size: inherit;
  line-height: inherit;
}

/* ==========================================================================
   SESSION E — PASS 15: card rows, radius, and slower motion
   ========================================================================== */

/* ---- 1. Card rows sit flush, not left-packed -----------------------------
   Measured at 1440: four cards at 320px with 20px gaps end at x=1364 inside a
   row running to x=1416, leaving 52px of dead space against the right edge.
   The cards were evenly spaced from each other but the SET was not centred in
   its container, which is what reads as "not evenly positioned".

   space-between distributes the leftover into the gaps rather than dumping it
   all on the right, so the row starts on the grid line and finishes on it.
   Deliberately not a fixed 4-column grid: the row's column count is expressed
   through each card's width percentage (23% means four across, 48% means two),
   and forcing a column count here would override that intent on the finance
   page, where a four-card row is meant to sit 2x2. */
@media (min-width: 768px) {
  [id^="halco-scroll-"] { justify-content: space-between; }
}

/* ---- 2. Corner radius, on a scale rather than ad hoc --------------------
   Cards were 8px with 6px media inside them, against 320px pill buttons. Too
   tight to read as deliberate at card size. 12px outer with 8px media keeps
   the nesting correct (inner radius smaller than outer, so the curves stay
   concentric) and is closer to the weight the pill buttons already set. */
[id^="halco-scroll-"] > .e-con { border-radius: 12px; }
[id^="halco-scroll-"] > .e-con .elementor-widget-image,
[id^="halco-scroll-"] > .e-con .elementor-widget-image img { border-radius: 8px; }
.halco-team__card { border-radius: 12px; }
.halco-404__card a { border-radius: 12px; }

/* ---- 3. The hero, slowed until it reads as alive rather than as an effect
   Jerald wants it slow enough to feel like the page is breathing rather than
   playing an animation. 9s, near-linear, so at no point is there a visible
   start or stop. The reason this is safe where the original 14s version was
   not: that one began at CSS parse, so it was always caught mid-drift on a
   refresh and read as the page still loading. This one is gated on the image
   having decoded, so it begins when there is something to watch and ends
   once. The fade stays fast and separate: the photograph still lands
   immediately. */
@media (prefers-reduced-motion: no-preference) {
  #halco-hero-media img.is-ready {
    animation:
      halco-hero-fade .55s ease-out both,
      halco-hero-zoom 9s cubic-bezier(.32,.06,.4,1) both;
  }
  @keyframes halco-hero-zoom {
    from { transform: scale(1.075); }
    to   { transform: scale(1); }
  }
}

/* ==========================================================================
   SESSION E — PASS 16: card links are links, not buttons
   The "Building your first home" style links inherit `.elementor-button`, so
   Pass 11's lift-and-shadow was drawing a pill-shaped shadow around text that
   has no fill and no border. Combined with the inherited 320px radius and
   10px/2px padding, it read as a badly padded button rather than a link.

   They keep the larger tap target, and get a hover that suits a link: the
   underline arrives and a trailing arrow steps forward.
   ========================================================================== */
[id^="halco-scroll-"] .elementor-widget-button .elementor-button {
  border-radius: 0 !important;
  padding: 8px 0 !important;
}
@media (prefers-reduced-motion: no-preference) {
  [id^="halco-scroll-"] .elementor-widget-button .elementor-button:hover {
    transform: none;
    box-shadow: none;
  }
}
[id^="halco-scroll-"] .elementor-widget-button .elementor-button:hover,
[id^="halco-scroll-"] .elementor-widget-button .elementor-button:focus-visible {
  box-shadow: none;
}
/* The arrow is generated, so no build file carries it and it cannot end up in
   the accessible name of the link. */
[id^="halco-scroll-"] .elementor-button .elementor-button-text::after {
  /* Drawn, not typed. A `content: "\2192"` arrow is included in the accessible
     name, so the link announced as "Building your first home right-arrow".
     Empty content with a background image keeps the name clean. */
  content: "";
  display: inline-block;
  width: 14px; height: 10px;
  margin-inline-start: 8px;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 10'%3E%3Cpath d='M9 1l4 4-4 4M13 5H1' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 10'%3E%3Cpath d='M9 1l4 4-4 4M13 5H1' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center / contain;
  transition: transform .22s cubic-bezier(.22,.61,.36,1);
}
[id^="halco-scroll-"] .elementor-button:hover .elementor-button-text::after,
[id^="halco-scroll-"] .e-con:hover .elementor-button .elementor-button-text::after {
  transform: translateX(4px);
}
[id^="halco-scroll-"] .elementor-button:hover .elementor-button-text {
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
}
@media (prefers-reduced-motion: reduce) {
  [id^="halco-scroll-"] .elementor-button .elementor-button-text::after { transition: none; }
}

/* ---- Hero, slower again ------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  #halco-hero-media img.is-ready {
    animation:
      halco-hero-fade .55s ease-out both,
      halco-hero-zoom 12s cubic-bezier(.35,.05,.4,1) both;
  }
}

/* ==========================================================================
   SESSION E — PASS 17: inline links on dark sections
   The packages hero is ink and its inline links were sage-text (#5F6D59),
   3.2:1 against that ground, which fails AA. The hover state resolved to
   #15161A, the background colour itself, so the link disappeared entirely
   when you pointed at it. `halco-on-dark` is added by halco-ux.php after
   measuring the computed background luminance, because CSS has no way to ask.
   ========================================================================== */
/* The footer is dark too, but it has its own deliberate link treatment
   (#A9B0A2 rising to white) that predates this and reads correctly. Excluded
   rather than overridden, so this rule only touches body content that had no
   dark-ground styling of its own. */
.halco-on-dark:not(#halco-footer) a:not(.elementor-button):not(.halco-logo__link) {
  color: var(--halco-sage-lift, #96A684);
  text-decoration-color: rgba(150, 166, 132, .5);
}
.halco-on-dark:not(#halco-footer) a:not(.elementor-button):not(.halco-logo__link):hover,
.halco-on-dark:not(#halco-footer) a:not(.elementor-button):not(.halco-logo__link):focus-visible {
  color: var(--halco-canvas, #FFFFFE);
  text-decoration-color: currentColor;
}

/* ==========================================================================
   SESSION E — PASS 18: the record pages (designs and packages children)
   Measured before: the listing floorplan rendered at 1,100 x 2,204px, the
   facade photographs sat 4,367px down, and the consultant's phone number was
   at 4,846px. One hero image was shown out of a gallery holding six to ten.

   Now: every image in the hero, the summary and the consultant beside it, the
   floor plan in a column with a capped height, and a lightbox on everything.
   ========================================================================== */

.halco-record__top {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(320px, 1fr);
  gap: clamp(28px, 3.4vw, 52px);
  align-items: start;
  margin-bottom: clamp(40px, 5vw, 72px);
}
@media (max-width: 1023px) { .halco-record__top { grid-template-columns: 1fr; } }

/* ---- Gallery ------------------------------------------------------------- */
.halco-gal__stage {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: 12px;
  overflow: hidden;
  background: var(--halco-sage-wash, #F2F4F0);
}
.halco-gal__frame { position: absolute; inset: 0; display: block; opacity: 0; visibility: hidden; }
.halco-gal__frame.is-current { opacity: 1; visibility: visible; }
@media (prefers-reduced-motion: no-preference) {
  .halco-gal__frame { transition: opacity .35s ease; }
}
.halco-gal__img { width: 100%; height: 100%; object-fit: cover; display: block; }
.halco-gal__frame:focus-visible { outline: 3px solid var(--halco-sage, #707F6A); outline-offset: -3px; }

.halco-gal__nav { display: flex; align-items: center; gap: 10px; margin-top: 12px; }
.halco-gal__thumbs {
  list-style: none; margin: 0; padding: 0;
  display: flex; gap: 8px; overflow-x: auto; flex: 1 1 auto;
  scrollbar-width: none;
}
.halco-gal__thumbs::-webkit-scrollbar { display: none; }
.halco-gal__thumb {
  width: 72px; height: 54px; padding: 0;
  border: 1px solid var(--halco-line, #E3E6E0); border-radius: 7px;
  overflow: hidden; cursor: pointer; background: none;
  opacity: .62;
}
.halco-gal__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.halco-gal__thumb.is-current { opacity: 1; border-color: var(--halco-sage-text, #5F6D59); box-shadow: 0 0 0 1px var(--halco-sage-text, #5F6D59); }
.halco-gal__thumb:focus-visible { outline: 2px solid var(--halco-sage, #707F6A); outline-offset: 2px; }
@media (prefers-reduced-motion: no-preference) { .halco-gal__thumb { transition: opacity .18s ease, box-shadow .18s ease; } }

.halco-gal__arrow {
  flex: 0 0 auto; width: 38px; height: 38px;
  border: 1px solid var(--halco-line, #E3E6E0); border-radius: 999px;
  background: var(--halco-canvas, #FFFFFE); cursor: pointer;
  position: relative;
}
.halco-gal__arrow::before {
  content: ""; position: absolute; inset: 0; margin: auto;
  width: 9px; height: 9px;
  border-top: 2px solid var(--halco-ink, #15161A);
  border-right: 2px solid var(--halco-ink, #15161A);
}
.halco-gal__arrow--next::before { transform: rotate(45deg) translate(-2px, 2px); }
.halco-gal__arrow--prev::before { transform: rotate(-135deg) translate(-2px, 2px); }
.halco-gal__arrow:hover { background: var(--halco-sage-wash, #F2F4F0); }
.halco-gal__arrow:focus-visible { outline: 2px solid var(--halco-sage, #707F6A); outline-offset: 2px; }

/* ---- Summary ------------------------------------------------------------- */
.halco-record__summary h1 { margin: 4px 0 6px; }
.halco-record__addr { margin: 0 0 4px; color: var(--halco-muted, #6B7280); font-size: .98rem; }
.halco-record__price {
  margin: 0 0 10px;
  font-family: var(--halco-font-head, Manrope, system-ui, sans-serif);
  font-size: 1.35rem; font-weight: 700; color: var(--halco-sage-text, #5F6D59);
}
.halco-record__tagline { margin: 0 0 16px; color: #4A4E54; line-height: 1.65; }

/* ---- Consultant, in the summary rather than at the foot of the page ------ */
.halco-consultant {
  display: flex; align-items: center; gap: 14px;
  margin-top: 22px; padding: 16px;
  border: 1px solid var(--halco-line, #E3E6E0); border-radius: 12px;
  background: var(--halco-canvas, #FFFFFE);
}
.halco-consultant__body { min-width: 0; }
.halco-consultant__label {
  margin: 0; font-family: var(--halco-font-head, Manrope, system-ui, sans-serif);
  font-size: 10.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--halco-muted, #6B7280);
}
.halco-consultant__name { margin: 2px 0 0; font-family: var(--halco-font-head, Manrope, system-ui, sans-serif); font-weight: 700; }
.halco-consultant__role { margin: 0; font-size: .84rem; color: var(--halco-muted, #6B7280); }
.halco-consultant__phone {
  display: inline-block; margin-top: 4px; font-weight: 700;
  color: var(--halco-sage-text, #5F6D59); text-decoration: none;
}
.halco-consultant__phone:hover { text-decoration: underline; text-underline-offset: 3px; }

/* ---- Floor plan beside the inclusions ------------------------------------ */
.halco-record__plan {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(28px, 3.4vw, 52px);
  align-items: start;
}
@media (max-width: 900px) { .halco-record__plan { grid-template-columns: 1fr; } }
.halco-record__plan-link { display: block; position: relative; border-radius: 12px; overflow: hidden; border: 1px solid var(--halco-line, #E3E6E0); background: #fff; }
.halco-record__plan-img {
  width: 100%;
  /* Was rendering 2,204px tall. Contained, so the whole plan is visible at a
     glance and the full-resolution file is one click away. */
  max-height: 560px; object-fit: contain; display: block;
}
.halco-record__plan-zoom {
  position: absolute; right: 12px; bottom: 12px;
  padding: 7px 14px; border-radius: 320px;
  background: rgba(21, 22, 26, .82); color: #FFFFFE;
  font-family: var(--halco-font-head, Manrope, system-ui, sans-serif);
  font-size: 12.5px; font-weight: 700;
}
.halco-record__plan-link:focus-visible { outline: 2px solid var(--halco-sage, #707F6A); outline-offset: 3px; }

/* ---- Lightbox ------------------------------------------------------------ */
.halco-lb {
  width: min(1180px, calc(100vw - 32px));
  max-height: min(92dvh, 980px);
  padding: 0; border: 0; border-radius: 14px;
  background: transparent; overflow: visible;
}
.halco-lb::backdrop { background: rgba(12, 13, 16, .88); backdrop-filter: blur(2px); }
.halco-lb__img { display: block; width: 100%; max-height: min(88dvh, 900px); object-fit: contain; border-radius: 10px; background: #0E0F12; }
.halco-lb__close, .halco-lb__nav {
  position: absolute; z-index: 2;
  width: 46px; height: 46px; display: grid; place-items: center;
  border: 0; border-radius: 999px; cursor: pointer;
  background: rgba(255, 255, 254, .92); color: var(--halco-ink, #15161A);
}
.halco-lb__close { top: -14px; right: -14px; }
.halco-lb__nav { top: 50%; transform: translateY(-50%); }
.halco-lb__nav--prev { left: -18px; }
.halco-lb__nav--next { right: -18px; }
.halco-lb__nav::before {
  content: ""; width: 11px; height: 11px;
  border-top: 2px solid currentColor; border-right: 2px solid currentColor;
}
.halco-lb__nav--next::before { transform: rotate(45deg) translate(-2px, 2px); }
.halco-lb__nav--prev::before { transform: rotate(-135deg) translate(-2px, 2px); }
.halco-lb__close:hover, .halco-lb__nav:hover { background: #fff; }
.halco-lb__close:focus-visible, .halco-lb__nav:focus-visible { outline: 2px solid var(--halco-sage-lift, #96A684); outline-offset: 2px; }
.halco-lb__count { margin: 10px 0 0; text-align: center; color: #C9CEC4; font-size: .85rem; }
@media (max-width: 767px) {
  .halco-lb__close { top: -10px; right: -6px; }
  .halco-lb__nav--prev { left: -6px; }
  .halco-lb__nav--next { right: -6px; }
}
@media (prefers-reduced-motion: no-preference) {
  .halco-lb[open] { animation: halco-bio-in .24s cubic-bezier(.22,.61,.36,1); }
}

/* ---- Pass 18 corrections, all found by measuring the rendered page --------
   1. The stage image was 584x328 inside a 584x438 frame: `height: 100%` was
      losing to a more specific `img` rule, so the photo sat in the top of a
      grey box. 2. `.halco-btn--outline` was inheriting the sage fill from
      `.halco-btn`, so both buttons in the summary read as primary. 3. The
      thumbnails were picking up a 320px pill radius from the global button
      styling and rendering as ovals. */
.halco-gal__stage .halco-gal__frame { display: block; }
.halco-gal__stage .halco-gal__img {
  width: 100% !important;
  height: 100% !important;
  max-height: none !important;
  object-fit: cover;
}
.halco-record .halco-btn--outline,
.halco-record .halco-btn--outline:link {
  background: transparent;
  color: var(--halco-ink, #15161A);
  border: 1px solid var(--halco-ink, #15161A);
}
.halco-record .halco-btn--outline:hover {
  background: var(--halco-ink, #15161A);
  color: #FFFFFE;
}
.halco-gal__nav .halco-gal__thumb { border-radius: 8px !important; }

/* ==========================================================================
   SESSION E — PASS 19: record page corrections, all measured
   ========================================================================== */

/* 1. The lightbox close button was crimson. Same hello-elementor rule as the
      bio modal: `[type="button"]:focus { background:#c36 }`, and showModal()
      focuses the close control immediately, so it fires on open every time.
      The `:where()` reset cannot win against a `:focus` selector, so every
      state is stated explicitly here, exactly as .halco-bio__close does. */
.halco-lb__close, .halco-lb__close:hover, .halco-lb__close:focus, .halco-lb__close:focus-visible,
.halco-lb__nav,   .halco-lb__nav:hover,   .halco-lb__nav:focus,   .halco-lb__nav:focus-visible {
  background-color: rgba(255, 255, 254, .94);
  color: var(--halco-ink, #15161A);
  border: 1px solid rgba(21, 22, 26, .08);
}
.halco-lb__close:hover, .halco-lb__nav:hover { background-color: #FFFFFE; }
.halco-lb__close:focus-visible, .halco-lb__nav:focus-visible {
  outline: 2px solid var(--halco-sage-lift, #96A684); outline-offset: 2px;
}

/* 2. The dialog was a fixed 1180px, so a portrait floor plan left the close
      and arrow controls floating in empty space beside it rather than on the
      image. Sizing the dialog to its content puts every control back on the
      edge of the picture. */
/* `display` MUST be gated on [open]. A <dialog> is hidden by the user-agent
   `dialog:not([open]) { display: none }` rule; setting `display: flex` on the
   element itself outranks it, so the closed dialog rendered in normal flow at
   the end of the document and its close and arrow controls appeared as loose
   buttons under the footer. That is exactly what Jerald photographed. */
.halco-lb[open] {
  width: auto;
  max-width: min(1180px, calc(100vw - 40px));
  display: flex; flex-direction: column; align-items: center;
}
.halco-lb:not([open]) { display: none; }
.halco-lb__img {
  width: auto; max-width: min(1180px, calc(100vw - 40px));
  max-height: min(84dvh, 860px);
}

/* 3. Pill buttons on the record were `display: block`, so the text sat on the
      padding box rather than being optically centred: 13px padding against a
      15.2px line-height in a 48px control. inline-flex centres it in both
      axes and makes every pill on the page the same height. */
.halco-record .halco-btn,
.halco-record .halco-btn--sage,
.halco-record .halco-btn--outline {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0 26px;
  line-height: 1.1;
  text-align: center;
}

/* 4. Larger imagery. The stage was 4:3 in a 1.25fr column; the photographs are
      the reason someone is on this page, so they get the room. */
@media (min-width: 1024px) {
  .halco-record__top { grid-template-columns: minmax(0, 1.55fr) minmax(340px, 1fr); }
}
.halco-gal__stage { aspect-ratio: 16 / 11; }
.halco-gal__thumb { width: 84px; height: 62px; }

/* ---- Enquiry form modal -------------------------------------------------- */
.halco-formdlg {
  width: min(560px, calc(100vw - 28px));
  max-height: min(88dvh, 860px);
  padding: 0; border: 0; border-radius: 14px; overflow: hidden;
  background: var(--halco-canvas, #FFFFFE);
  box-shadow: 0 40px 90px rgba(21, 22, 26, .34);
}
.halco-formdlg::backdrop { background: rgba(15, 16, 19, .66); backdrop-filter: blur(3px); }
.halco-formdlg__bar {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 14px 16px 14px 20px;
  background: var(--halco-sage-text, #5F6D59); color: #FFFFFE;
}
.halco-formdlg__title {
  margin: 0; font-family: var(--halco-font-head, Manrope, system-ui, sans-serif);
  font-size: 15px; font-weight: 700;
}
.halco-formdlg__close,
.halco-formdlg__close:hover,
.halco-formdlg__close:focus,
.halco-formdlg__close:focus-visible {
  flex: 0 0 auto; width: 34px; height: 34px;
  display: grid; place-items: center;
  border: 0; border-radius: 999px; cursor: pointer;
  background-color: rgba(255, 255, 255, .16); color: #FFFFFE;
}
.halco-formdlg__close:hover { background-color: rgba(255, 255, 255, .3); }
.halco-formdlg__close:focus-visible { outline: 2px solid #FFFFFE; outline-offset: 2px; }
.halco-formdlg__body { height: min(74dvh, 720px); }
.halco-formdlg__body iframe { width: 100%; height: 100%; border: 0; display: block; }

/* ---- Lightbox: controls anchored to the image ---------------------------
   The dialog shrink-wraps to the image's NATURAL width. A portrait floor plan
   is 1,080px wide natively but renders 306px once max-height applies, so
   controls positioned against the dialog sat 405px out in empty space.
   Anchoring them to a wrapper that is sized by the rendered image fixes it
   for every aspect ratio. */
.halco-lb { width: fit-content; max-width: none; background: transparent; }
.halco-lb__stage {
  position: relative;
  display: block;
  margin: 0;
  width: fit-content;
  max-width: calc(100vw - 40px);
}
.halco-lb__img {
  display: block;
  max-width: calc(100vw - 40px);
  max-height: min(84dvh, 860px);
  width: auto; height: auto;
  border-radius: 10px; background: #0E0F12;
}
.halco-lb__close { position: absolute; top: 10px; right: 10px; }
.halco-lb__nav { position: absolute; top: 50%; transform: translateY(-50%); }
.halco-lb__nav--prev { left: 10px; }
.halco-lb__nav--next { right: 10px; }

/* ==========================================================================
   SESSION E — PASS 20: the "Before you commit" panel
   Measured: the panel was 285px tall around 147px of content, so roughly 138px
   of empty space sat below four ticks, and its 26px padding had been zeroed by
   the sitewide container-padding reset because it is a direct child of
   `.e-con-inner`. Four loose ticks in an oversized bordered box is what Jerald
   meant by "could have structured it a little bit more better".

   Now: padding restored, height driven by content, and the four points laid
   out as a two-by-two grid of discrete items so they read as a considered set.
   ========================================================================== */
#halco-why-panel {
  --padding-block-start: 26px;
  --padding-block-end: 28px;
  --padding-inline-start: 26px;
  --padding-inline-end: 26px;
  align-self: start;          /* stop it stretching to the copy column */
}
#halco-why-panel .elementor-icon-list-items {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 18px;
}
#halco-why-panel .elementor-icon-list-item {
  align-items: start;
  padding: 12px 14px;
  border-radius: 10px;
  background: var(--halco-sage-wash, #F2F4F0);
  margin: 0 !important;
}
#halco-why-panel .elementor-icon-list-item .elementor-icon-list-text {
  font-size: .92rem; line-height: 1.5;
}
@media (max-width: 640px) {
  #halco-why-panel .elementor-icon-list-items { grid-template-columns: 1fr; }
}

/* ==========================================================================
   SESSION E — PASS 21: the spec strip, and the crimson button, third time
   ========================================================================== */

/* 1. THE CRIMSON BUTTON, AGAIN. hello-elementor paints every bare <button>
      #c36 on :hover and :focus at (0,2,0) specificity, which no single
      component class can outrank. The bio modal, the lightbox close and the
      form modal were each fixed in turn; the gallery arrow and thumbnail were
      missed and turned pink the moment they took focus. Stated explicitly
      here, and this is now the complete list of bare buttons on the site. */
.halco-gal__arrow, .halco-gal__arrow:hover, .halco-gal__arrow:focus, .halco-gal__arrow:focus-visible {
  background-color: var(--halco-canvas, #FFFFFE);
  color: var(--halco-ink, #15161A);
  border: 1px solid var(--halco-line, #E3E6E0);
}
.halco-gal__arrow:hover { background-color: var(--halco-sage-wash, #F2F4F0); }
.halco-gal__arrow:focus-visible { outline: 2px solid var(--halco-sage, #707F6A); outline-offset: 2px; }
.halco-gal__thumb, .halco-gal__thumb:hover, .halco-gal__thumb:focus, .halco-gal__thumb:focus-visible {
  background-color: transparent;
  color: inherit;
}

/* 2. THE SPEC STRIP. Five tiles in a three-then-two wrap left a ragged gap
      under the last row, which is the "out of pocket" Jerald described: the
      grid was fighting a variable item count (three to five, depending on
      whether total_sqm and lot_width_m are present).

      A single row of figures divided by hairlines has no wrap to go wrong,
      reads as one considered set, and is the treatment the homepage stat row
      already uses. It scrolls rather than wraps on a narrow screen. */
.halco-specs {
  list-style: none;
  display: flex;
  flex-wrap: nowrap;      /* the wrap is what produced the ragged second row */
  margin: 22px 0 24px;
  padding: 18px 0;
  border-top: 1px solid var(--halco-line, #E3E6E0);
  border-bottom: 1px solid var(--halco-line, #E3E6E0);
  gap: 0;
  overflow-x: auto;
  scrollbar-width: none;
}
.halco-specs::-webkit-scrollbar { display: none; }
.halco-specs .halco-spec {
  flex: 1 1 0;
  /* 0, not 84px: a design carries five specs and a listing four, and an
     84px floor pushed five past the summary column and forced a scrollbar
     on desktop. They share the space instead. */
  min-width: 0;
  padding: 0 11px;
  border-inline-start: 1px solid var(--halco-line, #E3E6E0);
  background: none;
  border-radius: 0;
  text-align: left;
}
.halco-specs .halco-spec:first-child { border-inline-start: 0; padding-inline-start: 0; }
.halco-specs .halco-spec__n {
  display: block;
  font-family: var(--halco-font-head, Manrope, system-ui, sans-serif);
  font-size: clamp(1.1rem, .95rem + .45vw, 1.4rem);
  font-weight: 700; line-height: 1.05; letter-spacing: -.02em;
  color: var(--halco-ink, #15161A);
  font-variant-numeric: tabular-nums;
  /* "136 m²" was breaking after the number, which dropped its label a line
     below the other four and undid the alignment the strip exists for. */
  white-space: nowrap;
}
.halco-specs .halco-spec__l {
  display: block; margin-top: 5px;
  font-family: var(--halco-font-head, Manrope, system-ui, sans-serif);
  font-size: 10.5px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: var(--halco-muted, #6B7280);
  white-space: nowrap;
}
@media (max-width: 480px) {
  .halco-specs .halco-spec { min-width: 76px; padding: 0 11px; }
}

/* ---- Packages results bar ------------------------------------------------
   The map sits ~3,000px down, after the entire grid. Anyone who does not
   scroll the whole list never learns it is there. This is the entry point. */
.halco-pk__bar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 12px; margin: 18px 0 22px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--halco-line, #E3E6E0);
}
.halco-pk__bar .halco-pk__count { margin: 0; }
.halco-pk__maplink {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px; padding: 0 18px;
  border-radius: 320px;
  border: 1px solid var(--halco-ink, #15161A);
  background: var(--halco-canvas, #FFFFFE);
  color: var(--halco-ink, #15161A);
  font-family: var(--halco-font-head, Manrope, system-ui, sans-serif);
  font-size: 14.5px; font-weight: 700; text-decoration: none;
}
.halco-pk__maplink:hover { background: var(--halco-ink, #15161A); color: #FFFFFE; }
.halco-pk__maplink:focus-visible { outline: 2px solid var(--halco-sage, #707F6A); outline-offset: 3px; }
@media (prefers-reduced-motion: no-preference) {
  .halco-pk__maplink { transition: background-color .2s ease, color .2s ease, transform .2s ease; }
  .halco-pk__maplink:hover { transform: translateY(-1px); }
}

/* More facets need to wrap gracefully rather than squeeze. */
.halco-pk__facets { flex-wrap: wrap; }
.halco-pk__facet { flex: 1 1 150px; min-width: 130px; }

/* The map itself, given the presence of a destination rather than a footnote. */
#halco-map { scroll-margin-top: 124px; }
@media (max-width: 767px) { #halco-map { scroll-margin-top: 96px; } }

/* ==========================================================================
   SESSION E — PASS 22: icon specs, the contact card, a per-package map
   Jerald referenced a portal listing layout: icons beside each figure, a
   contact card whose photo carries real presence and whose number is revealed
   on demand rather than shown up front, and a map on the record itself.
   ========================================================================== */

/* ---- Specs: icon + figure + label, in a grid with real cadence ----------
   Replaces the single-row strip. The strip solved the ragged wrap but gave
   the figures nothing to hold onto; icons give each row an anchor and let the
   set breathe across two columns. */
.halco-specs {
  display: grid !important;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2px 18px;
  flex-wrap: initial;
  overflow: visible;
}
.halco-specs .halco-spec {
  display: flex; align-items: center; gap: 12px;
  flex: initial;
  padding: 11px 0;
  border-inline-start: 0;
  border-bottom: 1px solid var(--halco-line, #E3E6E0);
}
/* The last row in each column carries no rule, so the block closes cleanly
   whether there are four specs or five. */
.halco-specs .halco-spec:nth-last-child(-n+2):nth-child(odd) { border-bottom: 0; }
.halco-specs .halco-spec:last-child { border-bottom: 0; }
.halco-spec__i { flex: 0 0 22px; color: var(--halco-sage-text, #5F6D59); }
.halco-spec__b { display: flex; align-items: baseline; gap: 7px; min-width: 0; }
.halco-specs .halco-spec__n {
  font-size: 1.05rem; font-weight: 700; line-height: 1.2;
  letter-spacing: 0; white-space: nowrap;
}
.halco-specs .halco-spec__l {
  margin-top: 0; font-size: .88rem; font-weight: 500;
  letter-spacing: 0; text-transform: none;
  color: var(--halco-muted, #6B7280);
}
@media (max-width: 520px) {
  .halco-specs { grid-template-columns: 1fr; }
  .halco-specs .halco-spec:nth-last-child(-n+2):nth-child(odd) { border-bottom: 1px solid var(--halco-line, #E3E6E0); }
  .halco-specs .halco-spec:last-child { border-bottom: 0; }
}

/* ---- Contact card ------------------------------------------------------- */
.halco-consultant {
  display: block;
  margin-top: 24px; padding: 24px 22px;
  border: 1px solid var(--halco-line, #E3E6E0); border-radius: 14px;
  background: var(--halco-canvas, #FFFFFE);
  text-align: center;
}
.halco-consultant__top { display: block; }
/* `.halco-record` prefix is load-bearing: Elementor ships `.elementor img
   { border-radius: 0 }` at (0,1,1), which outranks a lone class and squared
   the portrait off. Two earlier definitions of this rule were removed at the
   same time; three rules for one component is what let the last one lose. */
.halco-record .halco-consultant__photo {
  width: 104px; height: 104px; flex: none;
  border-radius: 999px; object-fit: cover;
  margin: 0 auto 12px; display: block;
  background: var(--halco-sage-wash, #F2F4F0);
}
.halco-consultant__name {
  margin: 0; font-family: var(--halco-font-head, Manrope, system-ui, sans-serif);
  font-size: 1.12rem; font-weight: 700; color: var(--halco-ink, #15161A);
}
.halco-consultant__role { margin: 2px 0 0; font-size: .86rem; color: var(--halco-muted, #6B7280); }

.halco-consultant__actions { display: grid; gap: 10px; margin-top: 18px; }
.halco-consultant__reveal { text-align: center; }
.halco-consultant__reveal summary,
.halco-consultant__email {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  min-height: 48px; padding: 0 18px;
  border-radius: 10px;
  font-family: var(--halco-font-head, Manrope, system-ui, sans-serif);
  font-size: 15px; font-weight: 700; text-decoration: none;
  cursor: pointer; list-style: none;
}
.halco-consultant__reveal summary::-webkit-details-marker { display: none; }
.halco-consultant__reveal summary {
  background: var(--halco-sage-wash, #F2F4F0);
  color: var(--halco-ink, #15161A);
  border: 1px solid transparent;
}
.halco-consultant__reveal summary:hover { background: #E8ECE4; border-color: #D8DED3; }
.halco-consultant__reveal[open] summary { border-radius: 10px 10px 0 0; background: #E8ECE4; }
.halco-consultant__email {
  background: var(--halco-ink, #15161A); color: #FFFFFE;
}
.halco-consultant__email:hover { background: var(--halco-sage-text, #5F6D59); color: #FFFFFE; }
.halco-consultant__reveal summary:focus-visible,
.halco-consultant__email:focus-visible { outline: 2px solid var(--halco-sage, #707F6A); outline-offset: 2px; }
.halco-consultant__phone {
  display: block; padding: 12px;
  border: 1px solid #D8DED3; border-top: 0; border-radius: 0 0 10px 10px;
  background: var(--halco-canvas, #FFFFFE);
  font-family: var(--halco-font-head, Manrope, system-ui, sans-serif);
  font-size: 1.16rem; font-weight: 700; letter-spacing: .01em;
  color: var(--halco-sage-text, #5F6D59); text-decoration: none;
}
.halco-consultant__phone:hover { color: var(--halco-ink, #15161A); background: var(--halco-sage-wash, #F2F4F0); }

/* ---- Larger gallery ----------------------------------------------------- */
@media (min-width: 1024px) {
  .halco-record__top { grid-template-columns: minmax(0, 1.75fr) minmax(330px, 1fr); }
}
.halco-gal__stage { aspect-ratio: 3 / 2; }

/* ---- The single-record map ---------------------------------------------- */
.halco-map--single { margin: 34px 0 8px; }
.halco-map--single .halco-map__title { font-size: 1.15rem; }

/* ==========================================================================
   20. DEPTH LAYER — spatial rhythm, tonal planes, elevation, layering
   Added 2026-08-25. Specified in docs/DESIGN-LANGUAGE.md.

   Why this exists: the tokens above were correct and then bypassed. The
   section-rhythm token was referenced twice against 88 hardcoded px paddings
   and seven competing clamp formulas; there were fourteen corner radii; and
   there were exactly two negative margins in 3,330 lines, which is why nothing
   on the site ever overlaps anything and every page reads as flat stacked
   bands.

   Everything here is compositor-only and adds no network bytes. That is a hard
   constraint: the homepage sits at 615 KB against a 900 KB ceiling.
   ========================================================================== */

:root {
  /* --- spatial rhythm — ONE scale, four steps -------------------------
     A section uses --halco-rhythm-md unless it has a stated reason. Bottom
     padding runs ~12% heavier than top: a heading above its content needs less
     air than the gap before the next idea. Optical, not mathematical. */
  --halco-rhythm-xs: clamp(2rem,   1.4rem + 2.4vw,  3.25rem);
  --halco-rhythm-sm: clamp(3rem,   2.2rem + 3.4vw,  5rem);
  --halco-rhythm-md: clamp(4.5rem, 3.2rem + 5.2vw,  7.5rem);
  --halco-rhythm-lg: clamp(6rem,   4rem   + 8vw,   10.5rem);

  /* --- tonal ladder — four planes -------------------------------------
     The move that buys the most depth: white stops being the ground and
     becomes the card. A faintly warm off-white becomes the page. Depth is
     impossible with two tones, and the site had two. */
  --halco-plane-sunk:   #EDF0EA;  /* 0 — recessed: filter bars, quiet bands  */
  --halco-plane-base:   #F7F8F5;  /* 1 — the page ground                     */
  --halco-plane-raised: #FFFFFE;  /* 2 — cards and panels, lifted            */
  --halco-plane-ink:    #15161A;  /* 3 — feature. Max 2 per page, never adjacent */

  /* --- elevation — ambient + direct, tinted sage ----------------------
     Two layers each, per the Vercel Design rule. Tinted toward sage rather
     than neutral grey so a shadow on a sage-wash section reads as the same
     light as the brand instead of as grime. One light source: always down. */
  --halco-elev-1: 0 1px 2px rgba(58,68,52,.05),  0 2px 6px  rgba(58,68,52,.04);
  --halco-elev-2: 0 2px 4px rgba(58,68,52,.06),  0 8px 20px rgba(58,68,52,.05);
  --halco-elev-3: 0 4px 8px rgba(58,68,52,.07),  0 18px 44px rgba(58,68,52,.07);
  --halco-elev-4: 0 8px 16px rgba(58,68,52,.08), 0 36px 84px rgba(58,68,52,.10);

  /* Semi-transparent, hue-matched. A solid grey hairline reads as dirt on a
     tinted plane; a tinted one reads as an edge. */
  --halco-hairline: 1px solid rgba(58,68,52,.10);
  --halco-hairline-strong: 1px solid rgba(58,68,52,.16);

  /* --- radius — four values, concentric -------------------------------
     The law: child radius <= parent radius, and child = parent - padding, so
     nested curves stay parallel. This is most of the "machined" feeling. */
  --halco-r-xs:   6px;
  --halco-r-sm:  10px;
  --halco-r-md:  16px;
  --halco-r-lg:  24px;
  --halco-r-pill: 999px;

  /* 320px and 999px were both in use for the same pill. Unified. The old
     names stay as aliases so nothing breaks mid-migration. */
  --halco-radius-pill: var(--halco-r-pill);

  /* --- motion curve ---------------------------------------------------
     Fast start, long settle. The asymmetry is what reads as weight. */
  --halco-ease-settle: cubic-bezier(.16,1,.3,1);
}

/* --------------------------------------------------------------------------
   20.1 Rhythm utilities
   Sections pull from the scale. No page authors its own padding.
   -------------------------------------------------------------------------- */

.halco-rhythm-xs { padding-block: var(--halco-rhythm-xs) calc(var(--halco-rhythm-xs) * 1.12); }
.halco-rhythm-sm { padding-block: var(--halco-rhythm-sm) calc(var(--halco-rhythm-sm) * 1.12); }
.halco-rhythm-md { padding-block: var(--halco-rhythm-md) calc(var(--halco-rhythm-md) * 1.12); }
.halco-rhythm-lg { padding-block: var(--halco-rhythm-lg) calc(var(--halco-rhythm-lg) * 1.12); }

/* --------------------------------------------------------------------------
   20.2 Tonal planes
   A raised element must sit on a lower plane than itself. A white card on a
   white section is not a card, it is a rectangle with a border.
   -------------------------------------------------------------------------- */

.halco-plane--sunk   { background: var(--halco-plane-sunk); }
.halco-plane--base   { background: var(--halco-plane-base); }
.halco-plane--raised { background: var(--halco-plane-raised); }
.halco-plane--ink    { background: var(--halco-plane-ink); color: var(--halco-canvas); }
.halco-plane--ink :where(h1,h2,h3,h4,h5,h6) { color: var(--halco-canvas); }
.halco-plane--ink :where(a):not(.halco-btn):not(.halco-cta) { color: var(--halco-sage-lift); }

/* Seam. Where two planes meet, state the join rather than leaving a raw colour
   change, so the page stops reading as stacked rectangles. */
.halco-seam { border-top: 1px solid rgba(58,68,52,.08); }

/* --------------------------------------------------------------------------
   20.3 Elevation + enclosure
   The flattened double-bezel: high-end-visual-design wants an outer shell
   wrapper around every card, which is DOM we cannot afford. We take the optics
   and skip the wrapper. The `inset 0 1px 0` white line along the top edge is
   the whole trick — it reads as light catching a bevel, from one element.
   -------------------------------------------------------------------------- */

.halco-elev-1 { box-shadow: var(--halco-elev-1); }
.halco-elev-2 { box-shadow: var(--halco-elev-2); }
.halco-elev-3 { box-shadow: var(--halco-elev-3); }
.halco-elev-4 { box-shadow: var(--halco-elev-4); }

.halco-enclose {
  background: var(--halco-plane-raised);
  border: var(--halco-hairline);
  border-radius: var(--halco-r-md);
  box-shadow: var(--halco-elev-2), inset 0 1px 0 rgba(255,255,255,.9);
}

/* Concentric children. A 16px parent with 6px padding holds a 10px child. */
.halco-enclose > .halco-enclose__inner {
  border-radius: var(--halco-r-sm);
  overflow: hidden;
}

/* Hover raises exactly one step. Never two. No scale on cards: scaling text
   resamples the glyph anti-aliasing and looks cheap. */
@media (prefers-reduced-motion: no-preference) {
  .halco-enclose {
    transition: box-shadow .22s var(--halco-ease-settle),
                transform  .22s var(--halco-ease-settle),
                border-color .22s var(--halco-ease-settle);
  }
  a:hover > .halco-enclose,
  .halco-enclose--interactive:hover,
  .halco-enclose--interactive:focus-within {
    box-shadow: var(--halco-elev-3), inset 0 1px 0 rgba(255,255,255,.9);
    border-color: rgba(58,68,52,.16);
    transform: translateY(-2px);
  }
}

/* --------------------------------------------------------------------------
   20.4 Layering
   The actual luxury lever, and the one thing wholly absent before now.
   Budget: two overlaps per page maximum. Overlap is punctuation.
   -------------------------------------------------------------------------- */

/* Pull a leading element up into the section above so the planes interlock
   instead of butting. */
.halco-overlap {
  position: relative;
  z-index: 1;
  margin-block-start: clamp(-5rem, -4vw, -2.5rem);
}

/* Overlap is a desktop composition. On mobile it collides with touch targets
   and steals the vertical space the reader needs, so it collapses. */
@media (max-width: 767px) {
  .halco-overlap { margin-block-start: 0; }
}

/* Asymmetric bleed: a feature panel runs past the canvas on ONE side only.
   Asymmetry is what makes it read as composed rather than centred. */
.halco-bleed-r { margin-inline-end: calc(var(--halco-gutter) * -1); }
.halco-bleed-l { margin-inline-start: calc(var(--halco-gutter) * -1); }
@media (min-width: 1024px) {
  .halco-bleed-r { margin-inline-end: clamp(-6rem, -5vw, -2rem); }
  .halco-bleed-l { margin-inline-start: clamp(-6rem, -5vw, -2rem); }
}
@media (max-width: 767px) {
  .halco-bleed-r, .halco-bleed-l { margin-inline: 0; }
}

/* --------------------------------------------------------------------------
   20.5 Motion choreography
   The delivery mechanism in halco-ux.php is good and stays exactly as built:
   IntersectionObserver, unobserve after firing, failsafe timer, scroll +
   watchdog second release, and a reduced-motion bail-out that never adds the
   class at all, so there is no flash of hidden content.

   What changes is the choreography. Every section previously got an identical
   18px/0.7s/70ms treatment, so a stats row, a testimonial and a CTA band all
   arrived the same way. That uniformity is why the scroll felt flat: it read
   as a page-wide effect rather than as content arriving.

   Four profiles, assigned by what the section does. Distance and duration are
   tied to the section's weight.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {

  /* quiet — prose, supporting copy, legal, FAQ. Barely there by design. */
  .halco-motion .halco-reveal--quiet { opacity: 0; transform: translateY(10px); }
  .halco-motion .halco-reveal--quiet.is-in {
    opacity: 1; transform: none;
    transition: opacity .55s var(--halco-ease-settle), transform .55s var(--halco-ease-settle);
  }

  /* sequence — ORDERED content only: the five steps, the problem list.
     Slower stagger, because order is the message. Using this on an unordered
     grid is a lie about the content. */
  .halco-motion .halco-reveal--sequence { opacity: 0; transform: translateY(22px); }
  .halco-motion .halco-reveal--sequence.is-in {
    opacity: 1; transform: none;
    transition: opacity .75s var(--halco-ease-settle), transform .75s var(--halco-ease-settle);
  }
  .halco-motion .halco-reveal--sequence.is-in > * > .halco-stagger,
  .halco-motion .halco-reveal--sequence.is-in > .halco-stagger {
    animation-duration: .75s;
    animation-delay: calc(var(--halco-stagger, 0ms) * 1.57);  /* 70ms -> 110ms */
  }

  /* arrive — ONE section per page maximum. Two makes both ordinary.
     Hero-adjacent, or the finale CTA. Carries a whisper of scale because this
     is the one moment allowed to feel like an entrance. */
  .halco-motion .halco-reveal--arrive { opacity: 0; transform: translateY(28px) scale(.985); }
  .halco-motion .halco-reveal--arrive.is-in {
    opacity: 1; transform: none;
    transition: opacity .85s var(--halco-ease-settle), transform .85s var(--halco-ease-settle);
  }
  .halco-motion .halco-reveal--arrive.is-in > * > .halco-stagger,
  .halco-motion .halco-reveal--arrive.is-in > .halco-stagger {
    animation-duration: .85s;
    animation-delay: calc(var(--halco-stagger, 0ms) * 1.28);  /* 70ms -> 90ms */
  }

  /* `settle` is the existing .halco-reveal default and needs no override. */
}

/* --------------------------------------------------------------------------
   20.6 Interaction feedback
   Physical press response was missing entirely. It is the highest-value
   micro-interaction available and costs nothing.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  .halco-cta:active,
  .halco-btn:active,
  .elementor-button:active {
    transform: translateY(0) scale(.98);
    transition-duration: .09s;   /* press is immediate; release settles */
  }
}

/* Focus rings are already instant: nothing in this stylesheet transitions
   `outline`, so there is no rule to write here. Do not add one - a blanket
   `transition: none` on :focus-visible would also kill the hover animation of
   an already-focused button, which is a regression, not a fix. */

/* ============================================================================
   SESSION E — PASS 23  ·  Filterable grids: empty state, length cap, density
   ----------------------------------------------------------------------------
   Three gaps the Web Interface Guidelines audit found in the package and design
   grids. All three are governed by JS in halco-ux.php, so all three degrade to
   "everything is visible", which is the correct no-JS result for a catalogue.
   ========================================================================== */

/* Filtering to nothing used to render an empty grid under the words
   "Showing 0", with the only way out a Clear button above a fold the user had
   already scrolled past. */
.halco-pk__empty {
  margin: 8px 0 0;
  padding: 34px 26px;
  text-align: center;
  font-size: 1.02rem;
  color: #4B5563;
  background: var(--halco-mist, #F5F6F3);
  border: 1px dashed var(--halco-line, #E3E6E0);
  border-radius: 10px;
}
.halco-pk__empty[hidden] { display: none; }

.halco-pk__clear,
.halco-pk__more {
  font: inherit;
  cursor: pointer;
  border-radius: 320px;
  transition: background-color .2s ease, color .2s ease, border-color .2s ease;
}

/* Inline inside the empty-state sentence, so it reads as part of the sentence
   rather than as a second competing control. */
.halco-pk__clear {
  border: 0;
  background: none;
  padding: 0;
  color: var(--halco-sage, #707F6A);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.halco-pk__clear:hover { color: var(--halco-ink, #15161A); }
.halco-pk__clear:focus-visible {
  outline: 2px solid var(--halco-sage, #707F6A);
  outline-offset: 3px;
}

/* The reveal control. The designs archive is 46 cards, which is 27,286px on a
   375px viewport. All 46 stay in the DOM for crawlers and for filtering; this
   button governs how many are painted. */
.halco-pk__more {
  display: block;
  margin: 26px auto 0;
  padding: 13px 30px;
  background: #fff;
  color: var(--halco-ink, #15161A);
  border: 1px solid var(--halco-ink, #15161A);
}
.halco-pk__more:hover {
  background: var(--halco-ink, #15161A);
  color: #fff;
}
.halco-pk__more:focus-visible {
  outline: 2px solid var(--halco-sage, #707F6A);
  outline-offset: 3px;
}
.halco-pk__more[hidden] { display: none; }

/* Phone density. The supporting tagline is the one line on the card that is
   not load-bearing: the title, the lot band and the bed/bath/car specs all
   answer a question the browser is asking, and the tagline elaborates. Below
   600px it costs about 70px of every card and it is the first thing to go. */
@media (max-width: 599.98px) {
  .halco-pk__grid { gap: 16px; }
  .halco-pk__tagline { display: none; }
}

/* ============================================================================
   SESSION E — PASS 24  ·  Design records vs package records
   ----------------------------------------------------------------------------
   The two record types rendered as the same page with one word changed in the
   eyebrow. They are not the same thing, and the brief asked for the difference
   to be visible: a design is a repeatable plan chosen on size and lot width, a
   package is one block at one address with a price attached.

   The differentiators are functional, not decorative:
     design   -> the floor plan leads, as a labelled frame in the gallery
     package  -> the address, the price and the map lead
   The badge colour is the label on top of that, not the substance of it.
   ========================================================================== */

.halco-record__kind {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin: 0 0 12px;
  padding: 5px 13px 5px 11px;
  border-radius: 320px;
  font-size: .74rem;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  line-height: 1.4;
}
/* A dot rather than an icon: at this size an icon is a smudge, and the badge
   already carries the word. */
.halco-record__kind::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}
.halco-record--design  .halco-record__kind {
  background: #EDF1EA;
  color: #4A5744;
}
.halco-record--package .halco-record__kind {
  background: #ECEEF1;
  color: #33383F;
}

/* --- The floor plan as a gallery frame ----------------------------------
   A plan is line art on white. `cover`, which is right for a photograph,
   crops the very edges of a plan where the dimensions are printed, so the
   plan frame contains instead and sits on a tinted ground so the white of
   the drawing still reads as a drawing. */
.halco-gal__frame--plan .halco-gal__img {
  object-fit: contain;
  background: #F7F8F6;
  padding: 12px;
}
.halco-gal__thumb--plan { position: relative; }
.halco-gal__thumb--plan img { object-fit: contain; background: #F7F8F6; }
.halco-gal__plantag {
  position: absolute;
  left: 50%;
  bottom: 4px;
  transform: translateX(-50%);
  padding: 2px 7px;
  border-radius: 320px;
  background: rgba(21, 22, 26, .82);
  color: #fff;
  font-size: .58rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  pointer-events: none;
  white-space: nowrap;
}

/* The price is the package page's headline fact and was set at body weight,
   the same as the tagline underneath it. Number columns and money get tabular
   figures so a row of prices lines up on the decimal. */
.halco-record__price {
  font-variant-numeric: tabular-nums;
}
.halco-record--package .halco-record__price {
  font-size: 1.42rem;
  font-weight: 700;
  color: var(--halco-ink, #15161A);
  margin: 2px 0 10px;
}
.halco-record--package .halco-record__addr {
  font-size: 1rem;
  color: #5A6169;
}

/* ============================================================================
   SESSION E — PASS 25  ·  Button geometry and card padding
   ----------------------------------------------------------------------------
   From Jerald's review, all three reproduced by measurement at 1512px before
   being touched.
   ========================================================================== */

/* --- Team booking buttons ------------------------------------------------
   At 1512px and above the team grid goes to five columns and the cards drop
   to 266px. "Book a session with Spencer" needs 227px, so it wrapped to two
   lines: 65px against every other button's 42px, dragging that row's baseline
   23px out of line. Jerald caught it on the live staging page.

   Sizing each pill to its own label was the mistake. Twelve buttons in a grid
   reading "Book a consultation", "Book a session with Jess", "Book a session
   with Spencer" produce twelve different widths whatever the viewport, which
   looks accidental even when nothing wraps. Stretched to the card, they are
   one width, the longest label has the full card to sit in, and the wrap
   cannot happen. `margin-top: auto` already pinned them to the card bottom;
   that stays and now actually holds a straight line. */
.halco-team__book {
  align-self: stretch;
  text-align: center;
  padding: 11px 14px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Five columns is where the labels get tight. One notch down on the type and
   the padding buys back the 20px the longest name needs, without touching the
   sizes that are comfortable at three and four columns. */
@media (min-width: 1500px) {
  .halco-team__book { font-size: .8rem; padding: 11px 10px; }
}

/* --- The booking modal ---------------------------------------------------
   A GHL booking calendar is a month grid plus a time-slot column plus a form.
   In the enquiry form's dialog height it opened scrolled and cramped. */
.halco-formdlg--tall { width: min(680px, 94vw); }
.halco-formdlg--tall .halco-formdlg__body { height: min(78vh, 760px); }
.halco-formdlg--tall .halco-formdlg__body iframe { width: 100%; height: 100%; border: 0; }

/* --- Cards that carry a radius must carry padding -------------------------
   NOT FIXED HERE, DELIBERATELY.

   `p_card()`'s flat variant unsets the background and the border but leaves
   `border-radius` set and zeroes the padding. At rest that is invisible; the
   moment a hover state paints a background or a shadow, the box renders hard
   against the text on all four sides. That is what Jerald described on the
   homepage process row as "very sharp", and it also affects the four numbered
   cards on the packages page, `/contact-us/` af536a0 and `/areas/` 3bffefb.

   Overriding it here would need `!important` against Elementor's generated
   per-element rule, and the Elementor sidebar would then show `padding: 0`
   while the page rendered 22px. Jerald's standing requirement is that the
   sidebar stays truthful and hand-editable, so a stylesheet override is the
   wrong instrument no matter how small.

   The fix is one line in `p_card()` and has been handed, with measurements, to
   the session that owns patterns.php. If you are reading this because the
   cards still look tight, chase that, do not add a rule here. */

/* ============================================================================
   SESSION E — PASS 26  ·  The nested-container padding reset ate real padding
   ----------------------------------------------------------------------------
   The reset above at "The grid" carries a comment claiming that "any container
   with padding set deliberately in the builder still wins on specificity".
   That comment is wrong, and it has been wrong since it was written.

   Elementor writes author padding through the same `--padding-*` custom
   properties the reset overrides, so the reset always wins. Whether a card
   keeps its padding therefore depends on nothing but where it happens to sit
   in the container tree:

     parent is `e-con-full`   -> no `.e-con-inner` wrapper, reset misses it,
                                 padding survives
     parent is `e-con-inner`  -> reset applies, padding is zeroed

   Measured on /reviews/, six quote cards built by the same `p_quote()` call
   with the same `el_dim(30, 30, 28, 30)`:

     halco-quote-855979  e-con-full   30px 30px 28px
     halco-quote-e4a36a  e-con-full   30px 30px 28px
     halco-quote-90c3be  e-con-full   30px 30px 28px
     halco-quote-0b393d  e-con-full   30px 30px 28px
     halco-quote-0fdc51  e-con-inner  0px          <- text flush to a tinted box
     halco-quote-72aa26  e-con-inner  0px          <- same

   Four look right and two look broken, from one pattern, for a reason no one
   editing the page could see. This is the same fault that zeroed the "Before
   you commit" panel's deliberate 26px.

   Restoring the derived properties at higher specificity than the reset gives
   the padding back to things that paint themselves, while bare nested layout
   columns, which is what the reset exists for, stay at zero. Verified in the
   browser before shipping: six quotes restored to 30/30/28, five sampled
   layout columns still 0.

   `.halco-padded` is the general hook. Put it on any container that sets its
   own padding and must keep it, via `css_classes` (containers) rather than
   `_css_classes` (widgets) -- the two are different keys and the underscored
   one is silently dropped on a container.

   ONLY SAFE ON A CONTAINER THAT ACTUALLY SETS PADDING. The rule re-derives the
   block/inline properties from `--padding-top` and friends. On a container that
   never defines them, `var(--padding-top)` is guaranteed-invalid, the
   declaration dies at computed-value time, and the padding resolves to zero --
   so tagging a container "just in case" does the exact damage the hook exists
   to prevent. The `0px` fallbacks below make that failure explicit and equal to
   the reset rather than undefined, but they do not make the tag correct: do not
   put this class on `p_section()` or `pb_hero()`. Both are top-level sections
   whose parent is the document root, never `.e-con-inner`, so the reset cannot
   reach them and the hook has nothing to undo.

   The `[id^="halco-quote-"]` selector that used to lead this rule is gone.
   It was a transitional fallback from when the class could not be applied from
   a pattern; `p_quote()`, `p_card()`, `pb_callout()` and the bespoke page
   panels now all carry `.halco-padded` at creation. 197 nested painted and
   padded containers tagged across 33 pages, 0 untagged. */
.e-con-inner > .e-con.halco-padded {
  --padding-block-start: var(--padding-top, 0px);
  --padding-block-end: var(--padding-bottom, 0px);
  --padding-inline-start: var(--padding-left, 0px);
  --padding-inline-end: var(--padding-right, 0px);
}

/* ============================================================================
   SESSION E — PASS 27  ·  Record pages: the hero image gets the room
   ----------------------------------------------------------------------------
   Jerald, twice: "I thought we're gonna make the overall image bigger... Can we
   not make the actual images a lot larger, where it fills up more" and then,
   more precisely, "I want it to feel like how we currently have in our main
   house and land co website. How all the images are embedded through the hero
   section and made a lot larger. Right now, all the images within the child
   page, post page, are very small."

   He is right and the numbers are stark. At 1512px the hero rendered 667x445
   inside a `.e-con-inner` capped at 1100px, so the photograph that is the whole
   reason for the page occupied 44% of the viewport width, in a container
   narrower than the rest of the site.

   HOW BIG, THOUGH: the source images will not carry a true full-bleed hero.
   Measured across every published record:

       property            231 images  min 843   median 1264  max 2560
                           96% are under 1400px wide
       exclusive_property  170 images  min 269   median 1024  max 2000
                           87% are under 1400px wide

   Stretching a 1264px median across a 1512px viewport, let alone 2560, upscales
   almost the entire library and returns a soft hero. That is not "nicer", it is
   the same complaint with more pixels. So the hero goes as large as the assets
   genuinely support and no larger: the record breaks out of the 1100px cap to
   the site canvas, and the stage spans the full width of it rather than sitting
   in a 1.75fr column.

   1,300px wide against a 1,264px median is close to native for most of the
   library, and it is roughly double the 667px it had.
   ========================================================================== */

@media (min-width: 1024px) {
  /* Break out of the Elementor container's 1100px cap up to the site canvas.
     The container is centred, so 50% + translate is stable regardless of what
     the parent's padding happens to be. */
  .halco-record {
    width: min(1300px, calc(100vw - 56px));
    margin-left: 50%;
    transform: translateX(-50%);
  }

  /* The hero stops being a column and becomes the page's opening image. */
  .halco-record__top {
    grid-template-columns: 1fr;
    gap: 0;
  }

  .halco-record__media { width: 100%; }

  /* 16:9 at 1300px is 731px tall, which pushes the specs and the consultant
     off the fold on a 900px viewport. Capped so the hero stays large without
     re-creating the problem the two-column layout was solving. */
  .halco-gal__stage {
    aspect-ratio: 16 / 9;
    max-height: min(58vh, 560px);
    border-radius: 14px;
  }

  /* The summary lifts over the bottom of the hero rather than following it,
     which is the production treatment Jerald referred to and keeps the price,
     the specs and the enquiry button at the top of the page. The card is
     inset from the hero's edges so the photograph still reads as full width. */
  .halco-record__summary {
    position: relative;
    z-index: 2;
    margin: -72px auto 0;
    width: min(1180px, calc(100% - 64px));
    background: #fff;
    border: 1px solid var(--halco-line, #E3E6E0);
    border-radius: 14px;
    padding: 30px 34px 32px;
    box-shadow: 0 18px 44px rgba(21, 22, 26, .09);
  }

  /* The thumbnail strip belongs to the hero, so it sits above the lifted card
     rather than being covered by it. */
  .halco-gal__nav {
    position: relative;
    z-index: 3;
    margin-top: 14px;
    padding-bottom: 58px;
  }

  /* Specs read as a row across the wider card instead of a narrow stack. */
  .halco-record__summary .halco-specs {
    display: flex;
    flex-wrap: wrap;
    gap: 14px 30px;
  }
}

/* Wider still: the canvas is the limit, not the viewport. */
@media (min-width: 1440px) {
  .halco-gal__stage { max-height: min(60vh, 600px); }
}

/* Phones keep the scroll-snap gallery and the stacked card; the breakout and
   the overlap are desktop-only. Nothing above this point applies under 1024. */

/* ============================================================================
   SESSION E — PASS 28  ·  Mobile record pages were scrolling sideways
   ----------------------------------------------------------------------------
   Found while measuring the hero, and it is the more serious of the two.

   `.halco-record__top` computed `grid-template-columns: 916px` on a 375px
   viewport. The document scrolled horizontally by 565px on every listing
   record, and the hero image rendered 916px wide from a 345px source, a 2.66x
   upscale, which is a large part of why the phone images looked poor.

   The cause is the standard CSS Grid blowout: `1fr` is shorthand for
   `minmax(auto, 1fr)`, and `auto` as a minimum resolves to the item's
   max-content size. `.halco-record__media` carried `min-width: auto`, so the
   thumbnail strip, nine thumbs at 84px plus gaps, set the floor for the whole
   track. The track could not shrink below its widest descendant, so it did not.

   `minmax(0, 1fr)` plus an explicit `min-width: 0` is the fix. The strip scrolls
   inside its own container instead of setting the width of the page.
   ========================================================================== */

@media (max-width: 1023px) {
  .halco-record__top { grid-template-columns: minmax(0, 1fr); }
  .halco-record__media,
  .halco-record__summary { min-width: 0; }
  .halco-gal,
  .halco-gal__stage { width: 100%; max-width: 100%; }

  /* The strip is the thing that was doing the pushing; let it scroll. */
  .halco-gal__thumbs {
    overflow-x: auto;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
  }
  .halco-gal__thumbs > li { scroll-snap-align: start; flex: none; }
}

/* --------------------------------------------------------------------------
   And the desktop card: the enquiry CTA had fallen to y=1234 once the hero
   went full width, which is below the fold on a 900px viewport and undoes the
   earlier work that pulled the consultant and the ask up the page.

   Splitting the lifted card into two columns puts the ask beside the specs
   rather than under them, so the hero keeps its full width and the button
   comes back above the fold. */
@media (min-width: 1024px) {
  .halco-record__summary {
    display: grid;
    grid-template-columns: minmax(0, 1.35fr) minmax(280px, 1fr);
    gap: 12px 40px;
    align-items: start;
  }
  .halco-record__summary > .halco-record__kind,
  .halco-record__summary > h1,
  .halco-record__summary > .halco-record__addr,
  .halco-record__summary > .halco-record__price,
  .halco-record__summary > .halco-record__tagline,
  .halco-record__summary > .halco-specs { grid-column: 1; }
  .halco-record__summary > .halco-cta-row,
  .halco-record__summary > .halco-consultant {
    grid-column: 2;
    align-self: start;
  }
  .halco-record__summary > .halco-cta-row {
    grid-row: 1 / span 3;
    flex-direction: column;
    align-items: stretch;
    margin-top: 4px;
  }
  .halco-record__summary > .halco-cta-row .halco-btn { text-align: center; }
}

/* --------------------------------------------------------------------------
   PASS 28b · The phone hero.

   Fixing the grid blowout above correctly sized the mobile stage to its
   container, 327x218, but that is a thumbnail, not a hero, and "the images
   are very small" was the original complaint. On a phone the hero should own
   the top of the screen the way it does on the production site.

   Full-bleed to the viewport edge and 4:3 gives 375x281: 48% more image than
   the corrected size and 72% more than the container-width version, with the
   photograph running edge to edge as it does on production. The images are
   landscape and `object-fit: cover` crops to the frame, so 4:3 is about as
   tall as it can go before the crop starts removing roof and driveway, which
   is the part of a facade shot that carries the information.

   The bleed is on the stage only. The thumbnail strip and the card keep the
   page gutter, so the layout does not lose its left edge. */
@media (max-width: 1023px) {
  .halco-gal__stage {
    width: 100vw;
    max-width: 100vw;
    margin-left: 50%;
    transform: translateX(-50%);
    aspect-ratio: 4 / 3;
    border-radius: 0;
  }
  .halco-gal__nav { margin-top: 14px; }
}

/* The bleed uses 100vw, which on a page with a vertical scrollbar is wider
   than the content box. Desktop keeps its own scrollbar, phones overlay it,
   so this is scoped to the range where the bleed applies and paired with the
   overflow guard below. */
@media (max-width: 1023px) {
  .halco-record,
  .halco-record__top { overflow-x: clip; }
}

/* ==========================================================================
   CAREERS — expression of interest form  ([halco_careers_form])
   The brief's core direction: "starting a conversation, not applying for a
   mortgage." So: one column, generous targets, no boxed-in form chrome, and
   nothing that reads as corporate HR.
   ========================================================================== */

.halco-cf { max-width: 720px; }
.halco-cf__form { display: grid; gap: var(--halco-s5); }
.halco-cf__form.is-hidden { display: none; }

/* Two up on a wide screen, one on a phone. The four short fields only —
   everything that needs thinking room stays full width. */
.halco-cf__grid {
  display: grid; gap: var(--halco-s5);
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

.halco-cf__field { display: flex; flex-direction: column; gap: var(--halco-s2); margin: 0; }
.halco-cf__field > label,
.halco-cf__set > legend {
  font-family: var(--halco-font-head); font-weight: 700;
  font-size: 0.9375rem; color: var(--halco-ink); line-height: 1.35;
}
.halco-cf__req {
  font-weight: 600; font-size: 0.75rem; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--halco-muted); margin-left: 0.35em;
}
.halco-cf__hint { font-size: 0.875rem; color: var(--halco-muted); line-height: 1.5; }
.halco-cf__set > legend + .halco-cf__hint { display: block; margin-bottom: var(--halco-s3); }

.halco-cf input[type="text"],
.halco-cf input[type="tel"],
.halco-cf input[type="email"],
.halco-cf input[type="url"],
.halco-cf textarea {
  width: 100%;
  font-family: var(--halco-font-body); font-size: 1rem; line-height: 1.5;
  color: var(--halco-ink); background: var(--halco-canvas);
  border: 1.5px solid var(--halco-line); border-radius: var(--halco-radius, 8px);
  padding: 0.8rem 0.95rem;
  min-height: 48px;                     /* the tap target from the brief */
  transition: border-color var(--halco-dur) var(--halco-ease);
}
.halco-cf textarea { min-height: auto; resize: vertical; line-height: 1.6; }
.halco-cf input::placeholder, .halco-cf textarea::placeholder { color: #9AA0A8; }
.halco-cf input:hover, .halco-cf textarea:hover { border-color: #C9CEC4; }
.halco-cf input:focus, .halco-cf textarea:focus { border-color: var(--halco-sage-text); }

.halco-cf__count { font-size: 0.8125rem; color: var(--halco-muted); text-align: right; }
.halco-cf__count.is-over { color: var(--halco-sage-dark); }

/* ---- The interest chips ------------------------------------------------
   Checkboxes, not a <select multiple>. A multi-select on a phone is a native
   picker most people never realise takes more than one answer. */
.halco-cf__set { border: 0; margin: 0; padding: 0; }
.halco-cf__chips { display: flex; flex-wrap: wrap; gap: var(--halco-s2); }
.halco-cf__chip {
  display: inline-flex; align-items: center; gap: 0.55rem;
  padding: 0.7rem 1rem; min-height: 48px;
  border: 1.5px solid var(--halco-line); border-radius: var(--halco-radius-pill, 320px);
  font-size: 0.9375rem; line-height: 1.25; color: var(--halco-ink-soft);
  background: var(--halco-canvas); cursor: pointer;
  transition: border-color var(--halco-dur) var(--halco-ease),
              background var(--halco-dur) var(--halco-ease),
              color var(--halco-dur) var(--halco-ease);
}
.halco-cf__chip:hover { border-color: var(--halco-sage); }
.halco-cf__chip input { accent-color: var(--halco-sage-text); width: 1.05rem; height: 1.05rem; margin: 0; }
/* Two selectors for one state.
   :has(input:checked) is the real rule and works on its own in every browser
   that supports :has(). `.is-picked` is toggled in JS alongside it so that the
   chip still FILLS on a browser without :has() — older Safari would otherwise
   fall through to the outline in the @supports block below, which is a much
   weaker signal on the one question where several answers are expected.
   (An earlier version of this comment claimed a Chromium :has() invalidation
   bug. There is no such bug here — that reading came from measuring computed
   styles in a backgrounded automation tab, which does not recalculate style.) */
.halco-cf__chip:has(input:checked),
.halco-cf__chip.is-picked {
  border-color: var(--halco-sage-text); background: var(--halco-sage-wash); color: var(--halco-ink);
  font-weight: 600;
}
/* No :has and no JS: the native checkbox is still the state, so make it loud. */
@supports not selector(:has(*)) { .halco-cf__chip input:checked { outline: 2px solid var(--halco-sage-text); } }

/* ---- The optional block ------------------------------------------------
   Visibly set apart, because the brief is emphatic that a CV is encouraged and
   never a gate. Making it look like the required fields undoes that. */
.halco-cf__optional {
  display: grid; gap: var(--halco-s4);
  padding: var(--halco-s5);
  background: var(--halco-sage-wash);
  border-radius: var(--halco-radius, 8px);
}
.halco-cf__opt-h {
  font-family: var(--halco-font-head); font-size: 1.0625rem; font-weight: 700;
  color: var(--halco-ink); margin: 0;
}
.halco-cf__opt-t { font-size: 0.9375rem; color: var(--halco-ink-soft); margin: 0; line-height: 1.6; }
.halco-cf__optional input[type="url"] { background: var(--halco-canvas); }

.halco-cf__drop {
  position: relative;
  display: flex; align-items: center; justify-content: center; text-align: center;
  min-height: 96px; padding: var(--halco-s4);
  border: 1.5px dashed #B9C2B2; border-radius: var(--halco-radius, 8px);
  background: var(--halco-canvas); color: var(--halco-ink-soft); font-size: 0.9375rem;
  transition: border-color var(--halco-dur) var(--halco-ease), background var(--halco-dur) var(--halco-ease);
}
/* The real input covers the whole zone, so the click target is the zone and the
   keyboard still reaches a genuine file input rather than a faked button. */
.halco-cf__drop input[type="file"] {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0; cursor: pointer;
}
.halco-cf__drop-link { color: var(--halco-sage-text); text-decoration: underline; text-underline-offset: 2px; }
.halco-cf__drop.is-over { border-color: var(--halco-sage-text); background: var(--halco-sage-wash); }
.halco-cf__drop.has-file { border-style: solid; border-color: var(--halco-sage-text); background: var(--halco-sage-wash); }
.halco-cf__drop.has-error { border-color: #A8442F; }
.halco-cf__drop:focus-within { outline: 3px solid var(--halco-sage-dark); outline-offset: 3px; }

/* ---- Consent ----------------------------------------------------------- */
.halco-cf__consent { margin: 0; }
.halco-cf__consent > label {
  display: flex; gap: 0.75rem; align-items: flex-start;
  font-size: 0.9375rem; line-height: 1.6; color: var(--halco-ink-soft); cursor: pointer;
}
.halco-cf__consent input {
  accent-color: var(--halco-sage-text);
  width: 1.25rem; height: 1.25rem; margin: 0.15rem 0 0; flex: 0 0 auto;
}
.halco-cf__consent a { color: var(--halco-sage-text); }

/* ---- Submit ------------------------------------------------------------ */
.halco-cf__submit { display: flex; flex-wrap: wrap; align-items: center; gap: var(--halco-s4); }
.halco-cf__go { text-transform: uppercase; letter-spacing: 0.04em; }
.halco-cf__go[disabled] { opacity: 0.7; cursor: progress; }
.halco-cf__time { font-size: 0.875rem; color: var(--halco-muted); }

/* ---- Errors ------------------------------------------------------------ */
.halco-cf__err { display: block; font-size: 0.875rem; line-height: 1.5; color: #A8442F; }
.halco-cf .has-error input,
.halco-cf .has-error textarea { border-color: #A8442F; }
.halco-cf__alert {
  padding: var(--halco-s4) var(--halco-s5);
  border-left: 4px solid #A8442F; background: #FBF1EE;
  border-radius: 0 var(--halco-radius, 8px) var(--halco-radius, 8px) 0;
  color: #6E2C1E; font-size: 0.9375rem; line-height: 1.6;
}
.halco-cf__alert ul { margin: var(--halco-s2) 0 0; padding-left: 1.15rem; }
.halco-cf__alert a { color: inherit; }

/* ---- Success ----------------------------------------------------------- */
.halco-cf__done {
  padding: var(--halco-s6);
  background: var(--halco-ink); color: #E7EAE3;
  border-radius: var(--halco-radius, 8px);
  line-height: 1.65;
}
.halco-cf__done-h {
  font-family: var(--halco-font-head); font-size: var(--halco-h3); font-weight: 700;
  color: var(--halco-canvas); margin: 0 0 var(--halco-s3);
}
.halco-cf__done p { margin: 0 0 var(--halco-s3); }
.halco-cf__done p:last-child { margin-bottom: 0; }
.halco-cf__done-sub { font-size: 0.9375rem; color: #AFB6A8; }
.halco-cf__done strong { color: var(--halco-canvas); }

/* The honeypot: out of sight, out of the a11y tree, and never focusable. */
.halco-cf__hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

@media (max-width: 600px) {
  .halco-cf__optional { padding: var(--halco-s4); }
  .halco-cf__done { padding: var(--halco-s5); }
  .halco-cf__submit { gap: var(--halco-s3); }
  .halco-cf__go { width: 100%; }
  .halco-cf__time { width: 100%; text-align: center; }
}

/* ==========================================================================
   21. WIDE-DISPLAY CANVAS  (design-system session, 2026-08-26)

   Jerald: "as the screen size goes bigger the side space tends to be larger."

   Correct, and measurable. p_section boxes content at 1440px, so a 2560px
   display renders a 1440px column with 560px of dead margin each side. The
   page stops reading as a composition and starts reading as a narrow strip
   stranded in the middle of a large screen.

   Only sections using the DEFAULT canvas are widened. p_section tags those
   `halco-canvas`; sections that asked for 900, 940 or 960 are deliberately
   narrow reading columns and are left exactly as they are. Widening a prose
   column past its measure would be a regression dressed up as a fix.

   SPECIFICITY. Elementor writes `--content-width` at
   `.elementor-42 .elementor-element.elementor-element-XXX`, which is (0,3,0),
   and its per-post stylesheet loads AFTER this file. A plain `.halco-canvas`
   rule at (0,1,0) loses, silently, and the fix would look applied while doing
   nothing. Adding the `body` element selector takes this to (0,3,1), which
   wins on specificity rather than on order. No `!important`: a section given an
   explicit width in the Elementor sidebar still needs to be able to win.

   Paragraph measure is unaffected: `p { max-width: var(--halco-measure) }`
   caps body text at 64ch regardless of how wide its container becomes, so this
   gives card rows and media the room and leaves reading alone.

   HELD AT 1440 FOR NOW, DELIBERATELY. The widening is written and disabled.

   Session E measured that the hero copy column is offset by
   `padding-left: max(24px, calc((100vw - 1440px) / 2))` so its left edge lines
   up with the header logo. That 1440 is hard-coded. If the boxed width grows
   and the offset does not, the hero text stops aligning with every section
   below it: at 1920 the hero would start 125px right of the section content.
   That trade is worse than the dead margin it fixes, so the responsive values
   below stay commented until the offset consumes the same number.

   THE CONTRACT: `--halco-canvas-w` is the single source of truth for the boxed
   content width. Session E consumes it as
   `calc((100vw - var(--halco-canvas-w)) / 2)` in the offset rule; this file
   consumes it as `--content-width`. Once both sides read it, uncomment the two
   media queries and the whole grid moves together.
   ========================================================================== */

:root {
  --halco-canvas-w: 1440px;
}

body .elementor .elementor-element.halco-canvas {
  --content-width: var(--halco-canvas-w);
}

/* ENABLED 2026-08-26. Session E's offset now reads --halco-canvas-w (style.css
   PASS 30), so the boxed width and the hero's left edge move together and the
   125px misalignment this was held back for cannot happen.

   Checked against the wrap Session E measured before enabling. The hero button
   row needs 506.3px; the copy column's content box holds at 844px from 1920
   all the way to 2560, because their max-width now carries the offset rather
   than being eaten by it. No wrap is re-introduced at any width. */

@media (min-width: 1600px) { :root { --halco-canvas-w: min(88vw, 1760px); } }

/* Past ~2200px the proportion matters more than the width. A 1880px measure at
   default display sizes reads thin against that much glass, so the two display
   steps go up with it. Body text is untouched: `p { max-width: 64ch }` caps the
   reading measure regardless of how wide the container gets. */
@media (min-width: 2200px) {
  :root {
    --halco-canvas-w: min(84vw, 1880px);
    --halco-h1: clamp(2.25rem, 1.6rem + 2.6vw, 4.25rem);
    --halco-h2: clamp(1.75rem, 1.35rem + 1.7vw, 3.1rem);
  }
}

/* ============================================================================
   SESSION E — PASS 29  ·  Record hero: fill the screen, and stop shrinking
   ----------------------------------------------------------------------------
   PASS 27 was wrong and Jerald rejected it on sight: "The hero section image is
   way too large now. But keep in mind, I wanted it to be filling the whole
   screen. If you can't do that, put it back to what it was. Because now it's
   leaving so much screen real estate on the open."

   Both halves of that are correct and they are the same fault. Screenshot and
   measurement at 1512:

       record   1300px
       stage    1013px      <- 287px of dead white to the right of the photo
       height    570px      <- tall AND short of the edge, so it reads as broken

   The cause was mine and it is a classic: `aspect-ratio: 16 / 9` together with
   `max-height: min(58vh, 560px)` and no `width`. The height cap won, and the
   width was then DERIVED from it as 570 x 16/9 = 1013. Constraining the height
   of an aspect-ratio box silently shrinks its width. The image did not fill the
   screen because it was never asked to; it was asked to be 570px tall.

   Fixed by making width authoritative and height explicit, with no aspect ratio
   to mediate between them. The photograph now runs the full width of the
   viewport, which is what "filling the whole screen" means, and is shorter, so
   it stops eating the fold.
   ========================================================================== */

@media (min-width: 1024px) {
  .halco-gal__stage {
    /* Full-bleed out of the 1300px record, edge to edge. */
    width: 100vw;
    max-width: 100vw;
    margin-left: 50%;
    transform: translateX(-50%);
    /* Explicit height, no aspect-ratio: nothing left to derive a width from. */
    aspect-ratio: auto;
    height: clamp(380px, 46vh, 520px);
    max-height: none;
    border-radius: 0;
  }

  /* The thumbnail strip and arrows belong to the photograph, so they sit back
     inside the canvas and hug the strip instead of being flung to the page
     edges by a 1300px flex row. */
  .halco-gal__nav {
    justify-content: flex-start;
    padding-bottom: 0;
    margin-top: 14px;
  }
  .halco-gal__thumbs { flex: 0 1 auto; }

  /* The lifted card is the full canvas width so its left edge agrees with the
     rest of the page, rather than being inset by an arbitrary 60px. */
  .halco-record__summary {
    width: 100%;
    margin-top: 26px;
    padding: 28px 32px 30px;
  }

  /* The kind badge is a pill, not a bar. As a grid item it was stretching to
     the full 500px column, which is what put a sage-tinted strip across the
     top of the card. */
  .halco-record__summary > .halco-record__kind {
    justify-self: start;
    width: max-content;
    max-width: 100%;
  }

  /* PASS 28 spanned the CTA across three grid rows to pull it up. On a long
     title that forced the h1 into a shorter row than it needed and clipped it,
     which is visible on "19 Thanander St, Southern River". Let the rows size
     to their content and keep the CTA at the top of the second column. */
  .halco-record__summary > .halco-cta-row {
    grid-row: auto;
    grid-column: 2;
  }
  .halco-record__summary { align-items: start; }
}

/* Ultra-wide: the sources cannot carry a 2560px hero (median original is
   1264px across 231 design images), so the bleed stops growing and the photo
   centres rather than turning to mush. */
@media (min-width: 1900px) {
  .halco-gal__stage {
    width: min(100vw, 1900px);
    max-width: min(100vw, 1900px);
    height: clamp(420px, 44vh, 560px);
  }
}

/* --------------------------------------------------------------------------
   PASS 29b · The bleed was compounding.

   `.halco-record` is already centred with `margin-left: 50%` +
   `translateX(-50%)` to break out of Elementor's 1100px cap. Applying the same
   pair again to the stage inside it shifted the photograph right by half the
   difference a second time: measured gapLeft 106px, gapRight -106px, and 106px
   of horizontal page overflow at 1512.

   `margin-left: calc(50% - 50vw)` does the same job arithmetically without a
   second transform, and it cancels the parent's offset exactly because the 50%
   resolves against the record's own width. No transform, nothing to compound.
   ========================================================================== */
@media (min-width: 1024px) {
  .halco-gal__stage {
    margin-left: calc(50% - 50vw);
    transform: none;
  }
}
@media (min-width: 1900px) {
  .halco-gal__stage {
    margin-left: calc(50% - min(50vw, 950px));
  }
}

/* The h1 sat in a grid row sized by its siblings and clipped its own
   descenders on the two-line addresses. Let it own its height. */
.halco-record__summary h1 {
  overflow: visible;
  min-width: 0;
  padding-bottom: 2px;
}

/* ============================================================================
   SESSION E — PASS 30  ·  Hero CTAs wrapped as the viewport got WIDER
   ----------------------------------------------------------------------------
   Jerald: "as I make the screen size larger the both the call to action aren't
   side by side one goes below the other."

   Backwards, and it was two rules of mine that are each defensible alone:

     line ~1083  padding-left: max(24px, calc((100vw - 1440px) / 2))
     line ~2033  max-width: min(56vw, 920px)

   The first is the content-grid offset, so the hero copy's left edge lines up
   with the header logo. It GROWS with the viewport: 24px at 1440, 560px at
   2560. The second caps the text measure. With `box-sizing: border-box` the
   padding lives inside the max-width, so the usable content box is
   920 - padLeft - padRight and it SHRINKS as the screen grows.

   Measured on / across twelve widths. The two buttons are 279.2px and 215.1px
   at every single one of them, constant, so button width is not the variable:

       vw     padLeft   actions row   need
       1440    24px       717.6       506.3   ok
       1600    80px       744.0       506.3   ok
       1920   240px       593.6       506.3   ok
       2048   304px       528.0       506.3   ok, barely
       2240   400px       432.0       506.3   WRAPS
       2560   560px       272.0       506.3   WRAPS

   920 - 560 - 88 = 272 at 2560, exactly the measured row. Predicted threshold
   is 100vw > 2091; observed first wrap 2240, none at 2048. Both agree.

   Fix: let the cap carry the offset, so the CONTENT measure stays ~830px
   instead of collapsing. Nothing changes at or below 1440.

   Also adopts `--halco-canvas-w` from the design-system session, so the offset
   tracks the boxed width instead of hard-coding 1440. That hard-code was about
   to misalign the hero by 125px at 1920 the moment the canvas widened.
   ========================================================================== */

#halco-hero-copy {
  --hero-offset: max(24px, calc((100vw - var(--halco-canvas-w, 1440px)) / 2));
  padding-left: var(--hero-offset) !important;
}

@media (min-width: 1280px) {
  #halco-hero-copy {
    max-width: min(56vw, calc(920px + var(--hero-offset)));
  }
}

/* ============================================================================
   SESSION E — PASS 31  ·  The hero was cutting the house in half
   ----------------------------------------------------------------------------
   Jerald: "the actual image itself... it's very cut up. It doesn't make sense.
   It cuts the whole house into half."

   Correct, and it is arithmetic rather than taste. `object-fit: cover` keeps
   the frame's aspect and throws away the rest, so the loss is:

       cropped = 1 - (source aspect / frame aspect)

   The sources are about 1.6:1 (1240x776 on the Thanander listing, 1240x697 on
   The Ascent). PASS 29 framed them at 1512x437, which is 3.46:1:

       1 - (1.6 / 3.46) = 54% of the image height discarded

   Just over half, taken equally from the top and the bottom, which is exactly
   where the roofline and the ground are. The house was being reduced to a
   horizontal band through its middle.

   Two levers, and only two: make the frame taller, or accept the crop. Full
   bleed on a wide desktop with a 1.6:1 source cannot show the whole house at
   440px tall; those constraints are simply incompatible.

   So the frame gets taller, and the crop that remains is taken from the sky
   rather than shared with the roof:

       1512 x 620  ->  2.44:1  ->  34% cropped, versus 54%
       object-position centre 38%  ->  biases the keep-window upward, so the
       roofline survives and the loss falls on foreground lawn and driveway,
       which carry nothing.

   Still a crop. A facade shot cannot fill a 2.4:1 frame without one. But it is
   a crop of the sky and the lawn instead of a cut through the building.
   ========================================================================== */

@media (min-width: 1024px) {
  .halco-gal__stage {
    height: clamp(500px, 65vh, 700px);
    max-height: none;
  }
  .halco-gal__stage .halco-gal__img {
    object-position: center 38%;
  }
}

@media (min-width: 1900px) {
  .halco-gal__stage { height: clamp(560px, 62vh, 760px); }
}

/* Phones were never the problem: 375x281 is 1.33:1 against a 1.6:1 source, so
   only 17% is lost and it comes off the sides, not the roof. Left alone. */

/* --------------------------------------------------------------------------
   And the column that held the removed enquiry button. With one control gone
   the card's second column is the floor plan and then the consultant, both
   sitting higher up the page, which is what was asked for. */
@media (min-width: 1024px) {
  .halco-record__summary > .halco-cta-row { margin-top: 0; }
  .halco-record__summary > .halco-consultant { margin-top: 14px; }
}

/* ============================================================================
   SESSION E — PASS 32  ·  The contact card sits at the top of its column
   ----------------------------------------------------------------------------
   Two parts to "bring the contact section higher", and the ordering fix in
   halco-record.php only addressed one of them.

   The card is now above "See the floor plan", which is what was asked for
   literally. But it still began level with the SPECS, roughly 480px down,
   because the summary is a two-column grid with auto row placement: every item
   in column 1 claims a row, and the consultant, being later in source order,
   landed in whatever row was next. The whole top of the right-hand column,
   beside the badge, the title, the price and the tagline, was empty.

   Pinning the card to row 1 of column 2 puts it beside the title where it
   belongs. The floor plan follows it in row 2. The left column keeps flowing
   through rows 1..n underneath, which is what auto-placement already does.

   Net effect on the package record: the consultant's name, photo, phone and
   the enquiry button all move roughly 480px up the page, and the dead space
   in the right column goes.
   ========================================================================== */

@media (min-width: 1024px) {
  .halco-record__summary > .halco-consultant {
    grid-column: 2;
    grid-row: 1;
    margin-top: 0;
  }
  .halco-record__summary > .halco-cta-row {
    grid-column: 2;
    grid-row: 2;
    margin-top: 12px;
  }
  /* Auto-placed left-column items must not spill into column 2 and collide
     with the pinned card. */
  .halco-record__summary > .halco-record__kind,
  .halco-record__summary > h1,
  .halco-record__summary > .halco-record__addr,
  .halco-record__summary > .halco-record__price,
  .halco-record__summary > .halco-record__tagline,
  .halco-record__summary > .halco-specs {
    grid-column: 1;
  }
  /* Rows 1 and 2 are the card and the plan button; everything below is the
     left column continuing, so the row track must not stretch them. */
  .halco-record__summary { align-content: start; }
}

/* --------------------------------------------------------------------------
   PASS 32b · The aside is one cell.

   PASS 32 pinned the consultant to grid row 1, which put it at the top but
   also made row 1 as tall as the card, stranding the badge 350px above the
   title. A grid item always sets its row's height; the only ways out are to
   span the rows, which hard-wires a count that breaks the moment a line is
   added to the left column, or to make the column a single cell.

   halco-record.php now wraps the card and the plan button in
   `.halco-record__aside`, so this is one item spanning the full height and the
   left column keeps its own rhythm. */
@media (min-width: 1024px) {
  .halco-record__aside {
    grid-column: 2;
    grid-row: 1 / -1;
    align-self: start;
    display: flex;
    flex-direction: column;
    gap: 12px;
  }
  /* Superseded by the wrapper: these no longer place themselves. */
  .halco-record__summary > .halco-consultant,
  .halco-record__summary > .halco-cta-row { grid-column: auto; grid-row: auto; }
  .halco-record__aside .halco-consultant,
  .halco-record__aside .halco-cta-row { margin-top: 0; }
}

/* --------------------------------------------------------------------------
   PASS 32c · `grid-row: 1 / -1` does nothing on an implicit grid.

   The aside was still stranding the badge 426px above the title. `-1` names
   the last line of the EXPLICIT grid, and `grid-template-rows` was never
   declared here, so there is no explicit row line to count back from: the
   aside resolved to row 1 alone, and a 412px card then set row 1's height.
   Exactly the fault the wrapper was meant to cure, surviving the cure.

   `span 100` covers every implicit row that auto-placement creates, without
   needing to know how many there are. Measured after: badge-to-title gap
   426px -> 8px on the package record, and the design record, which has no
   aside, is unchanged. */
@media (min-width: 1024px) {
  .halco-record__aside { grid-row: 1 / span 100; }
}

/* PASS 32d · The plan button matches the card it sits under. Sized to its own
   label it was 185px against the card's 486px, which reads as an offcut rather
   than the column's second action. Same reasoning as the team cards. */
@media (min-width: 1024px) {
  .halco-record__aside .halco-cta-row { display: flex; flex-direction: column; }
  .halco-record__aside .halco-cta-row .halco-btn {
    display: block;
    width: 100%;
    text-align: center;
  }
}

/* ============================================================================
   SESSION E — PASS 33  ·  Kill the grid, and rehome the floor plan link
   ----------------------------------------------------------------------------
   Two faults in one screenshot, and the first was mine three passes running.

   THE EXPANSE. The summary card ran roughly 800px past its own content. Cause:
   PASS 32c gave the aside `grid-row: 1 / span 100` so it would reach the top
   of the column. That works, and it also instantiates 100 implicit rows, and
   `gap: 12px 40px` applies a 12px row-gap to every one of them. 99 empty rows
   x 12px is about 1,190px of nothing, drawn inside the card's border.

   I kept reaching for a bigger grid hammer: pin to row 1 (stranded the badge),
   span to -1 (does nothing on an implicit grid), span 100 (this). The problem
   was never the spanning rule, it was that the summary had six flat children
   and wanted two. With a wrapper on each side it is a flex row with two items
   and no rows to gap at all.

   THE ORPHAN BUTTON. "See the floor plan" sat alone under the contact card, a
   lone pill in a column whose only other content is a person. It has moved to
   sit under the specifications, where it answers the same question they do.
   ========================================================================== */

.halco-record__summary { display: block; }

@media (min-width: 1024px) {
  .halco-record__summary {
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    gap: 44px;
    /* Grid leftovers from passes 28 to 32. */
    grid-template-columns: none;
    align-content: initial;
  }
  .halco-record__main  { flex: 1 1 auto; min-width: 0; }
  .halco-record__aside {
    flex: 0 0 clamp(280px, 26%, 340px);
    display: flex;
    flex-direction: column;
    gap: 12px;
    /* No longer a grid item. */
    grid-column: auto;
    grid-row: auto;
  }
}

/* --- The floor plan link --------------------------------------------------
   Not a pill. The two pills on this page are the enquiry actions, and giving
   a reference link the same shape made it compete with them for the same
   attention while doing something entirely different. This is a bordered,
   square-cornered control with a plan glyph: clearly interactive, clearly not
   the ask. */
.halco-planlink {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-top: 20px;
  padding: 11px 18px;
  border: 1px solid var(--halco-line, #E3E6E0);
  border-radius: 8px;
  background: #fff;
  color: var(--halco-ink, #15161A);
  font-family: var(--halco-font-head, Manrope, system-ui, sans-serif);
  font-size: .9rem;
  font-weight: 700;
  text-decoration: none;
  transition: background-color .18s ease, border-color .18s ease;
}
.halco-planlink svg { color: var(--halco-sage-text, #5F6D59); flex: none; }
.halco-planlink:hover {
  background: var(--halco-sage-wash, #F2F4F0);
  border-color: var(--halco-sage, #707F6A);
}
.halco-planlink:focus-visible {
  outline: 2px solid var(--halco-sage, #707F6A);
  outline-offset: 2px;
}

/* ---- Careers: hero face grid -------------------------------------------
   The twelve staff portraits the site already owns, six of them, on the ink
   hero. Not stock: a careers page that shows no one is asking people to join
   something it will not show them, and CLAUDE.md §4 is explicit that the stock
   photography is the weakest thing on this site. These are real, consistent
   (620px square, branded polo, same wall) and already paid for. */
.halco-facegrid .elementor-widget-image {
  width: calc(33.333% - 8px);
  flex: 0 0 calc(33.333% - 8px);
}
.halco-facegrid .elementor-widget-image img {
  width: 100%; height: auto; aspect-ratio: 1 / 1; object-fit: cover;
  display: block;
  /* A hairline in the sage, so six squares on near-black read as a considered
     grid rather than six photos that happen to be next to each other. */
  border: 1px solid rgba(150, 166, 132, 0.28);
}
.halco-facegrid .elementor-widget-text-editor { width: 100%; flex: 0 0 100%; }
.halco-facegrid a { color: var(--halco-sage-lift, #96A684); }

@media (max-width: 1024px) {
  /* Tablet and phone: the faces sit UNDER the copy, so six squares would push
     the form a whole screen further away. Six across in one band keeps the
     proof visible and costs almost no height. */
  .halco-facegrid .elementor-widget-image {
    width: calc(16.666% - 7px); flex: 0 0 calc(16.666% - 7px);
  }
}
@media (max-width: 480px) {
  .halco-facegrid .elementor-widget-image {
    width: calc(33.333% - 6px); flex: 0 0 calc(33.333% - 6px);
  }
}

/* ---- Careers: the form as an object, not a column of inputs ------------- */
.halco-cf__form {
  background: var(--halco-canvas, #FFFFFE);
  border: 1px solid var(--halco-line, #E3E6E0);
  border-radius: 12px;
  padding: var(--halco-s6);
}
.halco-cf__form.is-hidden { display: none; }

/* Three named stretches instead of one undifferentiated column of seven.
   Purely visual — the brief rules out a multi-step wizard and this is not one,
   nothing is hidden and nothing gates anything else. */
.halco-cf__group { display: grid; gap: var(--halco-s5); }
.halco-cf__group + .halco-cf__group {
  padding-top: var(--halco-s5);
  border-top: 1px solid var(--halco-line, #E3E6E0);
}
.halco-cf__group-h {
  display: flex; align-items: center; gap: 0.65rem;
  font-family: var(--halco-font-head); font-size: 1.0625rem; font-weight: 700;
  color: var(--halco-ink); margin: 0;
}
.halco-cf__group-n {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.65rem; height: 1.65rem; flex: 0 0 auto;
  border-radius: 999px;
  background: var(--halco-sage-wash, #F2F4F0);
  color: var(--halco-sage-text, #5F6D59);
  font-size: 0.8125rem; font-weight: 700;
}

@media (max-width: 600px) {
  .halco-cf__form { padding: var(--halco-s4); border-radius: 10px; }
}

/* ============================================================================
   SESSION E — PASS 34  ·  The whole photograph, and no letterbox
   ----------------------------------------------------------------------------
   Jerald: "the bigger hero section image for each of the property image, it
   seems to be a little cut. Can we not have the whole image without it feeling
   cut?"

   The constraint is real and I have said it twice, so here is the way round it
   rather than a third restatement. `object-fit: cover` fills the frame and
   discards the overflow; the loss is 1 - (source aspect / frame aspect), and
   with ~1.6:1 sources in a full-bleed frame that is a third of the picture.
   Showing all of it at 1512 wide would need a hero about 945px tall.

   So: `contain`, which crops nothing, and fill what would otherwise be bars
   with a blurred enlargement of the same photograph. The frame stays full
   width, the house is complete including its roof and its driveway, and the
   surround reads as depth rather than as a broken image.

   `contain` also fixes something `cover` was hiding: the floor plan frame.
   A plan is line art with dimensions printed at its edges, and cover was
   cropping exactly those.
   ========================================================================== */

.halco-gal__bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Scaled past the frame so the blur's soft edge never reaches a border. */
  transform: scale(1.18);
  filter: blur(26px) saturate(1.1) brightness(.7);
  z-index: 0;
  pointer-events: none;
}

/* Supersedes the `cover` rule set when the stage was a small column. */
.halco-gal__stage .halco-gal__img,
.halco-gal__frame .halco-gal__img {
  position: relative;
  z-index: 1;
  object-fit: contain !important;
  object-position: center !important;
}

/* The plan frame already had its own tinted ground; it does not want a blurred
   photograph behind line art. */
.halco-gal__frame--plan .halco-gal__bg { display: none; }
.halco-gal__frame--plan { background: #F7F8F6; }
.halco-gal__frame--plan .halco-gal__img { padding: 14px; }

/* A blurred backdrop is a large composited layer. Static, never animated, and
   one per record, so it paints once. Honour reduced-motion anyway by dropping
   the scale, which is the only part that could read as movement mid-transition. */
@media (prefers-reduced-motion: reduce) {
  .halco-gal__bg { transform: none; filter: blur(22px) brightness(.72); }
}

/* ---- Careers: the team strip ([halco_team_strip]) -----------------------
   All twelve, scrolling, on the ink hero. It replaced a hand-picked grid of
   six: choosing six of twelve publishes a pecking order nobody agreed to, and
   the six were not the leadership. Rendering everyone removes the decision.

   Native scroll-snap. No carousel library, no autoplay — a swipe, a trackpad,
   shift-wheel, the arrows and the keyboard all work because it is a list that
   scrolls rather than a widget pretending to be one. */
.halco-strip { position: relative; }

.halco-strip__track {
  display: flex; gap: 14px;
  list-style: none; margin: 0; padding: 2px 0 6px;
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: none;                 /* the arrows and the fade are the affordance */
}
.halco-strip__track::-webkit-scrollbar { display: none; }
.halco-strip__track:focus-visible { outline: 3px solid var(--halco-sage-lift, #96A684); outline-offset: 4px; }

.halco-strip__item { flex: 0 0 auto; scroll-snap-align: start; width: 132px; }
.halco-strip__link {
  display: flex; flex-direction: column; gap: 8px;
  text-decoration: none; color: inherit;
}
.halco-strip__img {
  width: 132px; height: 132px; display: block;
  object-fit: cover; border-radius: 10px;
  border: 1px solid rgba(150, 166, 132, 0.28);
  transition: border-color var(--halco-dur) var(--halco-ease),
              transform var(--halco-dur) var(--halco-ease);
}
.halco-strip__link:hover .halco-strip__img,
.halco-strip__link:focus-visible .halco-strip__img {
  border-color: var(--halco-sage-lift, #96A684);
  transform: translateY(-2px);
}
.halco-strip__name {
  font-family: var(--halco-font-head); font-weight: 700; font-size: 0.875rem;
  color: var(--halco-canvas, #FFFFFE); line-height: 1.25;
}
/* No role line. It was clamped to two lines and ten of the twelve still cut
   mid-title, and a row reading "Co-Founder & Managing Director" next to "Virtual
   Assistant" puts back the hierarchy this strip exists to avoid showing. The
   role stays in the image alt text and on the page each face links to. */

/* The arrows are for pointers only; the list itself is the keyboard route. */
.halco-strip__nav {
  position: absolute; top: 58px; transform: translateY(-50%);
  display: none; align-items: center; justify-content: center;
  width: 36px; height: 36px; padding: 0;
  border-radius: 999px; cursor: pointer;
  background: rgba(21, 22, 26, 0.82);
  border: 1px solid rgba(150, 166, 132, 0.4);
  color: var(--halco-canvas, #FFFFFE);
  transition: background var(--halco-dur) var(--halco-ease);
}
.halco-strip__nav:hover { background: var(--halco-sage-text, #5F6D59); }
.halco-strip__nav--prev { left: -8px; }
.halco-strip__nav--next { right: -8px; }
@media (hover: hover) and (min-width: 900px) {
  .halco-strip__nav { display: flex; }
  .halco-strip.at-start .halco-strip__nav--prev,
  .halco-strip.at-end .halco-strip__nav--next { display: none; }
}

/* A fade on the trailing edge, so it is visible that the row continues. */
.halco-strip::after {
  content: ""; position: absolute; top: 0; right: 0; bottom: 6px; width: 56px;
  pointer-events: none;
  background: linear-gradient(to right, rgba(21,22,26,0), rgba(21,22,26,0.92));
  opacity: 1; transition: opacity var(--halco-dur) var(--halco-ease);
}
.halco-strip.at-end::after { opacity: 0; }

@media (max-width: 600px) {
  .halco-strip__item, .halco-strip__img { width: 112px; }
  .halco-strip__img { height: 112px; }
  .halco-strip__track { gap: 11px; }
}

/* ============================================================================
   SESSION E — PASS 35  ·  "On this page" for the long-form pages
   ----------------------------------------------------------------------------
   Behaviour is in halco-ux.php; the reasoning is recorded there. In short: the
   three newest, highest-intent pages are the least navigable on the site, and
   they are written for the readers least able to cope with that. The migrant
   page runs 14,864px on a phone with a 2,076px stretch containing no heading,
   image or button.

   Deliberately quiet. This is an orientation aid, not a feature: it should
   read as part of the page's furniture, not compete with the content or the
   calls to action. No card shadow, no accent fill, one hairline.

   Open by default on desktop where there is room, collapsed on phones where
   eleven links would push the article down by most of a screen. `<details>`
   does that with no JavaScript beyond the list's own construction.
   ========================================================================== */

.halco-toc {
  max-width: var(--halco-canvas-w, 1440px);
  margin: 4px auto 30px;
  padding: 0 24px;
}

.halco-toc__d {
  border-top: 1px solid var(--halco-line, #E3E6E0);
  border-bottom: 1px solid var(--halco-line, #E3E6E0);
  padding: 6px 0 10px;
}

.halco-toc__d > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 0;
  font-family: var(--halco-font-head, Manrope, system-ui, sans-serif);
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--halco-sage-text, #5F6D59);
}
.halco-toc__d > summary::-webkit-details-marker { display: none; }
.halco-toc__d > summary::after {
  content: "";
  width: 7px; height: 7px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translateY(-2px);
  transition: transform .2s ease;
}
.halco-toc__d[open] > summary::after { transform: rotate(-135deg) translateY(-1px); }
.halco-toc__d > summary:focus-visible {
  outline: 2px solid var(--halco-sage, #707F6A);
  outline-offset: 3px;
}

.halco-toc ol {
  list-style: none;
  margin: 2px 0 0;
  padding: 0;
  /* Eleven items down one column is its own wall. Columns keep the whole
     shape of the page visible at a glance, which is the entire point. */
  columns: 2;
  column-gap: 40px;
}
.halco-toc li { break-inside: avoid; margin: 0 0 2px; }

.halco-toc a {
  display: block;
  padding: 7px 0 7px 16px;
  position: relative;
  font-size: .95rem;
  line-height: 1.45;
  color: #4A4E54;
  text-decoration: none;
  border-radius: 4px;
  transition: color .16s ease;
}
.halco-toc a::before {
  content: "";
  position: absolute;
  left: 0; top: 50%;
  width: 6px; height: 1px;
  background: var(--halco-line, #C9D0C4);
  transform: translateY(-50%);
  transition: width .18s ease, background-color .18s ease;
}
.halco-toc a:hover { color: var(--halco-ink, #15161A); }
.halco-toc a:hover::before { width: 11px; background: var(--halco-sage, #707F6A); }
.halco-toc a:focus-visible {
  outline: 2px solid var(--halco-sage, #707F6A);
  outline-offset: 2px;
}

/* Where the reader currently is. */
.halco-toc a[aria-current="true"] {
  color: var(--halco-ink, #15161A);
  font-weight: 700;
}
.halco-toc a[aria-current="true"]::before {
  width: 11px;
  background: var(--halco-sage, #707F6A);
}

@media (max-width: 767.98px) {
  .halco-toc { padding: 0 20px; margin-bottom: 22px; }
  .halco-toc ol { columns: 1; }
  .halco-toc a { font-size: .92rem; padding-left: 14px; }
}

/* ==========================================================================
   22. THE MONEY FLOW  (design-system session, 2026-08-26)

   /do-you-charge-fees/ carries the single strongest argument on this site --
   the builder pays us, you pay nothing, and there is no markup on your
   contract -- and it makes it entirely in prose. CLAUDE.md records that an AI
   Overview about House & Land Co's own pricing is currently answered using
   CommBank, LJ Hooker and Mozo content, because nothing here answers it
   memorably. Prose is answerable. A diagram is quotable.

   The argument is spatial, so it should be drawn: money moves from the builder
   to us, service moves from us to the client, and the client is never in the
   money row. Three nodes and two arrows says that in two seconds. Six
   paragraphs do not.

   No photography, no icon font, no library. Roughly 1 KB of CSS and some
   markup, which is the whole point: the premium signal here is the clarity,
   not the decoration.
   ========================================================================== */

.halco-flow {
  margin: var(--halco-s6) 0 var(--halco-s5);
  padding: 0;
}

.halco-flow__track {
  display: grid;
  grid-template-columns: 1fr auto 1fr auto 1fr;
  align-items: stretch;
  gap: 0;
}

.halco-flow__node {
  background: var(--halco-plane-raised);
  border: var(--halco-hairline);
  border-radius: var(--halco-r-md);
  box-shadow: var(--halco-elev-1), inset 0 1px 0 rgba(255,255,255,.9);
  padding: var(--halco-s5) var(--halco-s5) calc(var(--halco-s5) * 1.1);
  text-align: center;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
}

/* The middle node is the one doing the work, so it sits one step higher. */
.halco-flow__node--us {
  background: var(--halco-plane-ink);
  border-color: transparent;
  box-shadow: var(--halco-elev-3);
}
.halco-flow__node--us .halco-flow__who  { color: var(--halco-canvas); }
.halco-flow__node--us .halco-flow__what { color: #C9CFC2; }

.halco-flow__who {
  font-family: var(--halco-font-head);
  font-weight: 700;
  font-size: 1.0625rem;
  line-height: 1.25;
  color: var(--halco-ink);
  letter-spacing: -.01em;
}
.halco-flow__what {
  font-size: .9375rem;
  line-height: 1.5;
  color: var(--halco-ink-soft);
  max-width: none;      /* overrides the 64ch prose measure inside a card */
  margin: 0;
}

/* The number is the payload of the whole page. It gets to be large. */
.halco-flow__zero {
  font-family: var(--halco-font-head);
  font-weight: 700;
  font-size: clamp(2.25rem, 1.6rem + 2.4vw, 3.25rem);
  line-height: 1;
  color: var(--halco-sage-text);
  letter-spacing: -.03em;
}

.halco-flow__arrow {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 0 var(--halco-s3);
  min-width: 108px;
}
.halco-flow__arrow span {
  font-size: .75rem;
  text-transform: uppercase;
  letter-spacing: .09em;
  font-weight: 700;
  color: var(--halco-sage-text);
  text-align: center;
  line-height: 1.3;
}
/* Drawn with a border, not an icon font and not an SVG file. */
.halco-flow__arrow::after {
  content: "";
  width: 100%;
  height: 1px;
  background: rgba(58,68,52,.28);
  position: relative;
}
.halco-flow__arrow i {
  display: block;
  width: 7px; height: 7px;
  border-top: 1px solid rgba(58,68,52,.45);
  border-right: 1px solid rgba(58,68,52,.45);
  transform: rotate(45deg);
  margin-top: -4px;
  margin-left: auto;
}

.halco-flow__note {
  margin: var(--halco-s4) 0 0;
  font-size: .9375rem;
  color: var(--halco-muted);
  text-align: center;
  max-width: none;
}

/* Stacks below 860. The arrows turn to point down rather than disappearing,
   because the direction of travel IS the argument. */
@media (max-width: 860px) {
  .halco-flow__track { grid-template-columns: 1fr; }
  .halco-flow__arrow { min-width: 0; padding: var(--halco-s3) 0; flex-direction: row; gap: 10px; }
  .halco-flow__arrow::after { width: 1px; height: 26px; }
  .halco-flow__arrow i { transform: rotate(135deg); margin: 0 0 0 -4px; }
}

/* PASS 35b · Two columns via grid, not `columns`.
   `columns: 2` did not take: the list rendered ten items in a single full-width
   stack, which is the wall the contents exists to break. Grid is explicit
   about the track count and does not depend on fragmentation behaviour. */
@media (min-width: 768px) {
  .halco-toc ol {
    columns: auto;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 44px;
    row-gap: 0;
  }
}


/* ==========================================================================
   Reclaimed from Elementor HTML widgets, 2026-08-31.
   These three blocks were stored as page content on 27 pages. Moving them
   here removes an uneditable widget from the top of each page and the two
   empty 44px sections that wrapped them.
   ========================================================================== */

.pbx-eb .elementor-heading-title::before{content:"";display:inline-block;width:24px;height:2px;background:currentColor;opacity:.55;vertical-align:middle;margin-right:10px;transform:translateY(-3px)}.pbx-hero{position:relative;background-image:radial-gradient(115% 85% at 78% 12%,rgba(150,166,132,.20),rgba(150,166,132,0) 62%)}.pbx-hero::after{content:"";position:absolute;inset:16px;border:1px solid rgba(150,166,132,.26);border-radius:12px;pointer-events:none}@media(max-width:767px){.pbx-hero::after{inset:9px;border-radius:9px}}.pbx-num .elementor-heading-title{display:inline-block;padding-bottom:5px;border-bottom:2px solid rgba(112,127,106,.30)}.pbx-l{list-style:none;margin:0;padding:0;display:grid;gap:14px}.pbx-l li{display:grid;grid-template-columns:20px 1fr;gap:12px;align-items:start;font-family:var(--halco-font-body,Inter,system-ui,sans-serif);font-size:17px;line-height:1.55}.pbx-l svg{width:19px;height:19px;margin-top:2px}.pbx-l li>span{min-width:0}.pbx a.elementor-button:focus-visible,.pbx a:focus-visible{outline:3px solid var(--halco-sage-lift,#96A684);outline-offset:3px;border-radius:6px}.pb-tw:focus-visible{outline:3px solid var(--halco-sage-dark,#4F5A4A);outline-offset:2px}.pb-t tbody tr{transition:background .15s ease}.pb-t tbody tr:hover th,.pb-t tbody tr:hover td{background:#F7F9F5}@media (prefers-reduced-motion: no-preference){.pbx-card{transition:transform .22s cubic-bezier(.22,.61,.36,1),box-shadow .22s ease,border-color .22s ease}.pbx-card:hover{transform:translateY(-3px);box-shadow:0 12px 30px rgba(21,22,26,.09);border-color:#CFD6C8}.pbx a.elementor-button{transition:background-color .18s ease,color .18s ease,transform .18s ease,box-shadow .18s ease}.pbx a.elementor-button:hover{transform:translateY(-1px);box-shadow:0 8px 20px rgba(21,22,26,.16)}.pbx-card .elementor-widget-image{overflow:hidden;border-radius:6px}.pbx-card .elementor-widget-image img{transition:transform .4s cubic-bezier(.22,.61,.36,1)}.pbx-card:hover .elementor-widget-image img{transform:scale(1.035)}}@media print{.pbx-hero::after{display:none}}

[id^="pc-"]{scroll-margin-top:110px}@media(max-width:767px){[id^="pc-"]{scroll-margin-top:98px}}ul.pcx-toc{list-style:none;padding:0;margin:0;display:flex;flex-wrap:wrap;gap:8px 10px}ul.pcx-toc li{margin:0}ul.pcx-toc a{display:inline-block;padding:7px 14px;border:1px solid #E3E6E0;border-radius:320px;background:#FFFFFE;color:#5F6D59;font-family:Manrope,system-ui,sans-serif;font-size:14px;font-weight:700;text-decoration:none;line-height:1.3}ul.pcx-toc a:hover{background:#15161A;border-color:#15161A;color:#FFFFFE}ul.pcx-toc a:focus-visible{outline:2px solid #96A684;outline-offset:3px}

.pb-tw{width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;border:1px solid #E3E6E0;border-radius:8px}.pb-tw:focus-visible{outline:3px solid #5F6D59;outline-offset:2px}.pb-t{width:100%;border-collapse:collapse;font-family:Inter,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;font-size:15.5px;line-height:1.6;color:#3A3D42;min-width:520px;background:#FFFFFE}.pb-t caption{caption-side:top;text-align:left;padding:16px 18px 0;font-size:14px;color:#6B7280}.pb-t th,.pb-t td{padding:14px 18px;text-align:left;vertical-align:top;border-bottom:1px solid #E3E6E0}.pb-t thead th{background:#F2F4F0;font-family:Manrope,sans-serif;font-weight:700;font-size:14px;letter-spacing:.02em;color:#15161A;text-transform:none}.pb-t tbody th{font-family:Manrope,sans-serif;font-weight:700;color:#15161A;width:26%}.pb-t tbody tr:last-child th,.pb-t tbody tr:last-child td{border-bottom:0}@media(max-width:782px){.pb-t{font-size:15px}.pb-t th,.pb-t td{padding:12px 14px}.pb-t tbody th{width:auto}}


/* ==========================================================================
   Tick / cross / pin lists, as editable widgets.

   These were hand-written <ul> blocks inside Elementor HTML widgets: the client
   could not add a point, reword one or reorder them without editing raw markup.
   They are now native Icon List widgets carrying no icon, with the marker drawn
   here from a CSS mask. The text lives in the repeater where anyone can edit it,
   and the marker cannot be knocked out of alignment by a stray keystroke.

   Colour comes from --pbx-mark, so a variant is one custom-property override
   rather than a second copy of the shape.
   ========================================================================== */
.pbx-l .elementor-icon-list-items {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 14px;
}

.pbx-l .elementor-icon-list-item {
  --pbx-mark: #707F6A;
  display: grid;
  grid-template-columns: 20px 1fr;
  gap: 12px;
  align-items: start;
  margin: 0;
  font-family: var(--halco-font-body, Inter, system-ui, sans-serif);
  font-size: 17px;
  line-height: 1.55;
  color: #2A2D31;
}

.pbx-l .elementor-icon-list-item::before {
  content: "";
  width: 19px;
  height: 19px;
  margin-top: 2px;
  background-color: var(--pbx-mark);
  -webkit-mask: var(--pbx-shape) no-repeat center / contain;
          mask: var(--pbx-shape) no-repeat center / contain;
}

/* Elementor draws its own icon slot and separator on icon lists. Neither applies
   here: the marker is the ::before, and these always read as a stacked list. */
.pbx-l .elementor-icon-list-item > .elementor-icon-list-text { padding: 0; min-width: 0; }
.pbx-l .elementor-icon-list-item > .elementor-icon-list-icon { display: none; }
.pbx-l .elementor-icon-list-item:not(:last-child)::after { display: none; }

.pbx-l--tick .elementor-icon-list-item {
  --pbx-mark: #707F6A;
  --pbx-shape: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M4 10.6l4 3.9 8-8.1" fill="none" stroke="black" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/></svg>');
}

.pbx-l--cross .elementor-icon-list-item {
  --pbx-mark: #B4483C;
  --pbx-shape: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M5.6 5.6l8.8 8.8M14.4 5.6l-8.8 8.8" fill="none" stroke="black" stroke-width="2.2" stroke-linecap="round"/></svg>');
}

/* The muted cross is the "what you are up against today" list. Deliberately
   quieter than the red one, so it reads as context rather than alarm. */
.pbx-l--cross-muted .elementor-icon-list-item {
  --pbx-mark: #9AA093;
  --pbx-shape: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M5.6 5.6l8.8 8.8M14.4 5.6l-8.8 8.8" fill="none" stroke="black" stroke-width="2.2" stroke-linecap="round"/></svg>');
  color: #4A4E54;
}

.pbx-l--pin .elementor-icon-list-item {
  --pbx-mark: #707F6A;
  --pbx-shape: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 2.5c-3 0-5.5 2.4-5.5 5.4 0 4 5.5 9.6 5.5 9.6s5.5-5.6 5.5-9.6c0-3-2.5-5.4-5.5-5.4zm0 7.5a2.1 2.1 0 110-4.2 2.1 2.1 0 010 4.2z" fill="black"/></svg>');
}


/* ==========================================================================
   Stat rows wrap instead of overflowing.

   Three and four-up stat rows ("3,500+ homes delivered", "$960M+ contract value
   managed & delivered") were laid out as a single flex row at every width. At
   768 the four-up version needed 749px inside a 720px column, so the page
   carried a 5px horizontal scrollbar -- small enough to look like a rendering
   fault rather than a layout one, which is worse. "$960M+" alone wanted 185px
   in a 146px column.

   Two per row at tablet, one at phone. The figures keep their weight and nothing
   is truncated. Measured on /building/first-home-buyers/, 2026-08-31.
   ========================================================================== */
@media (max-width: 1024px) {
  .halco-stats {
    flex-wrap: wrap;
  }
  .halco-stats > .e-con,
  .halco-stats > .elementor-element {
    flex: 1 1 calc(50% - var(--gap-x, 20px));
    min-width: 0;
  }
}

@media (max-width: 479px) {
  .halco-stats > .e-con,
  .halco-stats > .elementor-element {
    flex-basis: 100%;
  }
}


/* ==========================================================================
   Blog cards without a featured image.

   Three posts ship without one. Elementor simply omits the thumbnail block, so
   those cards came out 613px tall against 952px for every card that has a photo
   -- and because they are the three NEWEST posts they sat first in the grid, so
   the index opened on a ragged shelf of short text cards above rows of tall
   photographed ones.

   Rather than pin a stock house photo to a grants article -- the site already
   leans on stock more than it should -- a card with no image gets a brand panel
   at exactly the thumbnail's height, captioned with its own category. The grid
   stays even, and the card still says what it is.

   Replacing this with real photography is a straight improvement; nothing here
   needs removing first. The panel simply stops applying once a post gets one.
   ========================================================================== */
.elementor-posts--skin-cards .elementor-post:not(:has(.elementor-post__thumbnail__link)) .elementor-post__card::before {
  content: "House & Land Co";
  display: flex;
  align-items: flex-end;
  aspect-ratio: 444 / 293;
  width: 100%;
  padding: 22px 24px;
  box-sizing: border-box;
  font-family: var(--halco-font-head, Manrope, system-ui, sans-serif);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: .01em;
  color: #FFFFFE;
  background:
    radial-gradient(120% 90% at 82% 8%, rgba(150, 166, 132, .38), rgba(150, 166, 132, 0) 60%),
    linear-gradient(160deg, #5F6D59 0%, #3F4A3B 100%);
}

/* The category is the honest caption: it is the one thing we know about the
   post without an editor choosing anything. */
.elementor-posts--skin-cards .elementor-post.category-grants-incentives:not(:has(.elementor-post__thumbnail__link)) .elementor-post__card::before { content: "Grants & incentives"; }
.elementor-posts--skin-cards .elementor-post.category-home-finance:not(:has(.elementor-post__thumbnail__link)) .elementor-post__card::before { content: "Home finance"; }
.elementor-posts--skin-cards .elementor-post.category-first-homes:not(:has(.elementor-post__thumbnail__link)) .elementor-post__card::before { content: "First homes"; }
.elementor-posts--skin-cards .elementor-post.category-builder-brokers:not(:has(.elementor-post__thumbnail__link)) .elementor-post__card::before { content: "Choosing who builds"; }
.elementor-posts--skin-cards .elementor-post.category-construction:not(:has(.elementor-post__thumbnail__link)) .elementor-post__card::before { content: "Construction"; }
.elementor-posts--skin-cards .elementor-post.category-investment-properties:not(:has(.elementor-post__thumbnail__link)) .elementor-post__card::before { content: "Investment"; }
.elementor-posts--skin-cards .elementor-post.category-knockdown-rebuild:not(:has(.elementor-post__thumbnail__link)) .elementor-post__card::before { content: "Knock down & rebuild"; }
.elementor-posts--skin-cards .elementor-post.category-land:not(:has(.elementor-post__thumbnail__link)) .elementor-post__card::before { content: "Land"; }


/* ==========================================================================
   Article hero: a consistent band, not whatever shape the photo happens to be.

   The hero was rendered at its natural aspect ratio with no height limit, so it
   swung from 592px to 1577px across the twelve articles purely on whether the
   source upload was landscape or portrait. On a portrait photo that is nearly
   two full screens of image before the first sentence -- and the reader has no
   way to know the article has begun.

   Cropping to a fixed band is the right trade here: these are stock and library
   photographs used as mastheads, not diagrams where the full frame carries
   meaning. object-position sits above centre because the subject in a portrait
   crop is almost always in the upper half.
   ========================================================================== */
.halco-article__hero {
  margin: 0 0 28px;
}

.halco-article__hero img {
  display: block;
  width: 100%;
  height: clamp(260px, 38vw, 560px);
  object-fit: cover;
  object-position: center 35%;
  border-radius: 6px;
}


/* ==========================================================================
   Calculator text buttons were crimson too.

   Same root cause as the bare-button note above: hello-elementor's reset ships
   `[type="button"], [type="submit"], button { color:#c36 }`. The `:where()`
   reset written for that carries zero specificity by design, so it loses to the
   reset's own (0,0,1) `button` selector -- fine for our components, which
   restate their colours afterwards, but halco-calculators does not, and its
   stylesheet is enqueued BEFORE reset.css rather than after.

   The result: "< Back", "Edit" and "Year-by-year schedule" render
   rgb(204, 51, 102) -- a colour in no part of this brand -- and they appear from
   step two of the qualification wizard onward, on all eight pages carrying a
   calculator. Not visible on first paint, which is why it survived review.

   Restated here, in the child theme, which loads last.
   ========================================================================== */
.halco-calc button,
.halco-calc button:hover,
.halco-calc button:focus,
.halco-calc-suite button,
.halco-calc-suite button:hover,
.halco-calc-suite button:focus {
  border-color: transparent;
}

.halco-calc__back,
.halco-calc__back:hover,
.halco-calc__back:focus,
.halco-calc__running-summary-edit,
.halco-calc__running-summary-edit:hover,
.halco-calc__running-summary-edit:focus,
.halco-calc__schedule-toggle,
.halco-calc__schedule-toggle:hover,
.halco-calc__schedule-toggle:focus {
  color: var(--halco-mid, #6B6B6B);
  background-color: transparent;
}

.halco-calc__back:hover,
.halco-calc__running-summary-edit:hover,
.halco-calc__schedule-toggle:hover {
  color: var(--halco-ink, #1A1A1A);
}

/* The primary action keeps its sage fill through every state; the reset would
   otherwise repaint it crimson on hover and on focus. */
.halco-calc__submit,
.halco-calc__submit:hover,
.halco-calc__submit:focus,
.halco-calc__segment-btn[aria-pressed="true"],
.halco-calc__segment-btn[aria-pressed="true"]:hover {
  background-color: var(--halco-green, #707F6A);
  color: #FFFFFE;
}


/* ==========================================================================
   THE TYPE SYSTEM — one place, and the way to build new sections.

   Elementor's own global typography cannot be used here. Its Global Classes
   feature binds only to V4 atomic elements and every widget on this site is a
   classic one; its four system typography styles are sitewide defaults that
   restyle the page when touched; and custom typography globals defined in the
   Kit are simply never emitted onto widgets by the 4.2.3 renderer. All three
   were tried and measured on 2026-09-01.

   What DOES work on classic widgets is the CSS Classes field, which sits on
   every widget under Advanced. So the type scale lives here as classes.

   TO BUILD A NEW SECTION: leave the widget's Typography panel alone and put one
   of these class names in Advanced -> CSS Classes. It will match the rest of the
   site and it will follow any future change made here.

   TO CHANGE THE FONTS FOR THE WHOLE SITE: edit the two variables directly below.
   That is the entire job.
   ========================================================================== */

:root {
  --halco-font-head: "Manrope";
  --halco-font-body: "Inter";
  --halco-font-head-stack: var(--halco-font-head), ui-sans-serif, system-ui, sans-serif;
  --halco-font-body-stack: var(--halco-font-body), ui-sans-serif, system-ui, sans-serif;
}

/* Specificity note: these are written at (0,2,0) so they beat the theme and
   Elementor's widget defaults, and still LOSE to Elementor's own per-element
   rules at (0,3,0). That ordering is deliberate -- setting Typography on a single
   widget in the editor must still win, so a one-off override keeps working. */

.elementor-element.halco-t-display .elementor-heading-title,
.elementor-element.halco-t-h1 .elementor-heading-title,
.elementor-element.halco-t-h2 .elementor-heading-title,
.elementor-element.halco-t-h2s .elementor-heading-title,
.elementor-element.halco-t-h3 .elementor-heading-title,
.elementor-element.halco-t-h3s .elementor-heading-title,
.elementor-element.halco-t-stat .elementor-heading-title,
.elementor-element.halco-t-eyebrow .elementor-heading-title,
.elementor-element.halco-t-micro .elementor-heading-title {
  font-family: var(--halco-font-head-stack);
  font-weight: 700;
}

.elementor-element.halco-t-display .elementor-heading-title { font-size: 50px;   line-height: 1em;    letter-spacing: -1.8px; }
.elementor-element.halco-t-h1 .elementor-heading-title      { font-size: 44px;   line-height: 1.14em; letter-spacing: -0.8px; }
.elementor-element.halco-t-h2 .elementor-heading-title      { font-size: 40px;   line-height: 1.14em; letter-spacing: -0.8px; }
.elementor-element.halco-t-h2s .elementor-heading-title     { font-size: 38px;   line-height: 1.14em; letter-spacing: -0.8px; }
.elementor-element.halco-t-h3 .elementor-heading-title      { font-size: 21px;   line-height: 1.25em; }
.elementor-element.halco-t-h3s .elementor-heading-title     { font-size: 19px;   line-height: 1.25em; }
.elementor-element.halco-t-stat .elementor-heading-title    { font-size: 34px;   line-height: 1em; }
.elementor-element.halco-t-eyebrow .elementor-heading-title { font-size: 13px;   letter-spacing: 1.4px; text-transform: uppercase; }
.elementor-element.halco-t-micro .elementor-heading-title   { font-size: 12.5px; line-height: 1.5em; letter-spacing: 0.6px; font-weight: 600; }

/* Target the widget element itself, NOT .elementor-widget-container.
   The e_optimized_markup experiment is active on this site and it removes that
   wrapper entirely, so a rule hung on it matches nothing at all. Measured after
   the first attempt shipped 241 body paragraphs at the wrong size. */
.elementor-element.halco-t-body,
.elementor-element.halco-t-body-s,
.elementor-element.halco-t-body-l,
.elementor-element.halco-t-body-xl {
  font-family: var(--halco-font-body-stack);
  line-height: 1.7em;
}

.elementor-element.halco-t-body    { font-size: 17px; }
.elementor-element.halco-t-body-s  { font-size: 16px; }
.elementor-element.halco-t-body-l  { font-size: 18px; }
.elementor-element.halco-t-body-xl { font-size: 19px; }

.elementor-element.halco-t-btn .elementor-button,
.elementor-element.halco-t-btn-s .elementor-button {
  font-family: var(--halco-font-head-stack);
  font-weight: 700;
}
.elementor-element.halco-t-btn .elementor-button   { font-size: 16px; }
.elementor-element.halco-t-btn-s .elementor-button { font-size: 15px; }


/* ==========================================================================
   MODERNISATION PASS — 1 September 2026

   Subtle only. No layout moves, no colour changes, no type changes. Every rule
   here is about surface: how edges, depth, materials and controls read. The
   brand stays exactly as it is.

   Three things dated the page more than anything else, in order:
     1. the filter dropdowns were raw browser controls
     2. cards used a 5px radius and a hard 1px border
     3. the sticky header went translucent without blurring what is behind it

   Radius is the through-line. The site had eight different values in use
   (320, 14, 12, 10, 8, 6, 5, 4). These tokens give it three, plus the pill.
   ========================================================================== */

:root {
  --halco-r-sm: 10px;   /* controls, chips, small media */
  --halco-r-md: 14px;   /* cards, panels, images        */
  --halco-r-lg: 20px;   /* full-bleed media, hero frames */
}

/* --------------------------------------------------------------------------
   The header, once it sticks.

   It already went to 94% white on scroll. Without a blur behind it, content
   scrolling underneath stays legible through the gap and the bar reads as
   half-broken rather than as a material. saturate() before blur is what keeps
   photography underneath from going grey.
   -------------------------------------------------------------------------- */
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  #halco-header.is-stuck {
    background-color: rgba(255, 255, 254, .72) !important;
    -webkit-backdrop-filter: saturate(180%) blur(20px);
            backdrop-filter: saturate(180%) blur(20px);
  }
}

/* --------------------------------------------------------------------------
   Form controls.

   The package filters were native <select> elements: system chrome, system
   chevron, square corners, sitting next to a fully-pill "Clear" button. On the
   highest-intent page on the site. This is the single most dated thing here.

   appearance:none removes the platform styling; the chevron is an inline SVG in
   the background so it inherits nothing and cannot go missing.
   -------------------------------------------------------------------------- */
.halco-pk__facet select,
.halco-pk select,
select.halco-select {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  width: 100%;
  padding: 11px 38px 11px 14px;
  font-family: var(--halco-font-body-stack);
  font-size: 15px;
  line-height: 1.3;
  color: var(--halco-ink, #15161A);
  background-color: #FFFFFE;
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="none" stroke="%235F6D59" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M5 8l5 5 5-5"/></svg>');
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 16px 16px;
  border: var(--halco-hairline, 1px solid rgba(58,68,52,.10));
  border-radius: var(--halco-r-sm);
  box-shadow: var(--halco-elev-1);
  cursor: pointer;
  transition: border-color var(--halco-dur, .28s) var(--halco-ease),
              box-shadow var(--halco-dur, .28s) var(--halco-ease);
}

.halco-pk__facet select:hover,
.halco-pk select:hover { border-color: rgba(58,68,52,.22); }

.halco-pk__facet select:focus-visible,
.halco-pk select:focus-visible {
  outline: 2px solid var(--halco-sage, #707F6A);
  outline-offset: 2px;
  border-color: var(--halco-sage, #707F6A);
  box-shadow: var(--halco-elev-2);
}

/* --------------------------------------------------------------------------
   Cards.

   5px is the radius of a 2012 card. 14px reads as current without becoming
   a bubble. The hard border goes: a hairline plus a real shadow gives the same
   separation with far less visual noise, and gives the hover somewhere to go.
   -------------------------------------------------------------------------- */
.halco-pk__card,
.pbx-card {
  border-radius: var(--halco-r-md);
  border: var(--halco-hairline, 1px solid rgba(58,68,52,.10));
  box-shadow: var(--halco-elev-1);
  overflow: hidden;                 /* so the image corners follow the card */
  transition: transform var(--halco-dur, .28s) var(--halco-ease-settle),
              box-shadow var(--halco-dur, .28s) var(--halco-ease),
              border-color var(--halco-dur, .28s) var(--halco-ease);
}

@media (prefers-reduced-motion: no-preference) {
  .halco-pk__card:hover,
  .pbx-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--halco-elev-3);
    border-color: rgba(58,68,52,.16);
  }
}

/* The media sat square-cornered inside a rounded card. overflow:hidden above
   fixes the top corners; this keeps the ratio honest while it does so. */
.halco-pk__media {
  border-radius: 0;
  overflow: hidden;
}
.halco-pk__media img {
  display: block;
  width: 100%;
  transition: transform .5s var(--halco-ease-settle);
}
@media (prefers-reduced-motion: no-preference) {
  .halco-pk__card:hover .halco-pk__media img { transform: scale(1.03); }
}

/* --------------------------------------------------------------------------
   Spec chips.

   "4 bed / 2 bath / 2 car" were grey rectangles. Softer corners and a tinted
   fill make them read as data rather than as buttons you cannot press.
   -------------------------------------------------------------------------- */
.halco-pk__specs li {
  border-radius: 8px;
  background: var(--halco-sage-wash, #F2F4F0);
  border: 1px solid rgba(58,68,52,.07);
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   Content images.

   Editorial images sat at 5px, which at 1100px wide is almost a sharp corner --
   it reads as unstyled rather than deliberate.
   -------------------------------------------------------------------------- */
.elementor-widget-image img { border-radius: var(--halco-r-md); }
.halco-article__hero img    { border-radius: var(--halco-r-md); }

/* Full-bleed and framed hero media carries the larger radius. */
.pbx-hero img,
.halco-media--lg img { border-radius: var(--halco-r-lg); }

/* --------------------------------------------------------------------------
   Focus, everywhere.

   A single visible ring, on the brand sage, at an offset that clears the shape.
   Keyboard users get one consistent signal instead of whatever each component
   happened to define.
   -------------------------------------------------------------------------- */
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible,
input:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--halco-sage, #707F6A);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Numerals in figures should not shuffle width as they change. */
.halco-pk__band,
.pbx-num .elementor-heading-title { font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------------------------
   Card tags: separators do not survive wrapping.

   Tags were joined with " ·" on every item but the last. With three tags in a
   card that wraps to two lines, the separator lands at the END of the first
   line and reads as a typo -- "Family home · Close to schools ·". Seen on the
   Southern River four-bedroom card.

   A flex gap does the same job and cannot dangle. Quiet outline rather than a
   fill, so tags stay visually below the spec chips above them.
   -------------------------------------------------------------------------- */
.halco-pk__tags { gap: 6px 8px; }
/* Must match the specificity of the rule it overrides.
   The original is `.halco-pk__tags li:not(:last-child)::after`, and :not()
   counts toward specificity, so a plain `li::after` lost and the dangling
   separator came back the moment anything else re-rendered. */
.halco-pk__tags li::after,
.halco-pk__tags li:not(:last-child)::after { content: none !important; }
.halco-pk__tags li {
  padding: 3px 9px;
  border: 1px solid rgba(58, 68, 52, .13);
  border-radius: 999px;
  line-height: 1.5;
}

/* --------------------------------------------------------------------------
   Qualifier fields: inputs align even when a label wraps.

   "Other loan and card repayments, per month" runs to two lines while its two
   neighbours run to one, so its input sat 13px lower than theirs and the row
   read as broken. Measured on the homepage.

   Pushing the input to the bottom of its own cell keeps the three aligned
   whatever the labels do, which also means nobody has to keep field labels
   artificially short to protect the layout.
   -------------------------------------------------------------------------- */
.halco-q__row { align-items: end; }

.halco-q__field {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.halco-q__field > input,
.halco-q__field > select {
  margin-top: auto;
}

/* ============================================================================
   SESSION E — PASS 36  ·  List markers, card baselines
   ----------------------------------------------------------------------------
   Jerald: "I don't like the dashes or the ticks... it could have more luxurious
   feel to it."

   THE MARKERS. A tick and a dash are clip-art: they carry no meaning the
   sentence does not already carry, and they date a page faster than almost
   anything else on it. They were also misaligned. `align-items: center` centres
   the marker against the WHOLE item, so a two-line entry put it 26px down,
   level with nothing. Measured: one-line items 13px from the text top,
   two-line items 26px.

   Replaced with a single hairline rule, aligned to the first line's optical
   centre, in sage. One mark for both list kinds, because the difference between
   a problem list and a benefit list is carried by the words, not by the
   punctuation in front of them. It cannot fall out of alignment again, because
   it is positioned against the first line rather than the block.
   ========================================================================== */

.elementor-icon-list-item { align-items: flex-start !important; }

/* The glyph goes. Elementor renders it inline, so there is no request saved,
   but there is a lot of visual noise removed. */
.elementor-icon-list-icon svg,
.elementor-icon-list-icon i { display: none !important; }

.elementor-icon-list-icon {
  position: relative;
  display: block !important;
  width: 15px;
  flex: none;
  align-self: flex-start !important;
  margin-top: .62em;   /* optical centre of the first line, not the box top */
}
.elementor-icon-list-icon::before {
  content: "";
  display: block;
  width: 13px;
  height: 1.5px;
  border-radius: 2px;
  background: var(--halco-sage, #707F6A);
  opacity: .85;
  transition: width .3s cubic-bezier(.22, .61, .36, 1), opacity .3s ease;
}

/* On ink grounds the rule has to lift rather than recede. */
.halco-on-dark .elementor-icon-list-icon::before {
  background: var(--halco-sage-lift, #96A684);
  opacity: 1;
}

/* A list is one object, so it answers as one: hovering anywhere in it extends
   every rule. Quiet, and it gives a static block a pulse without animating
   anything that moves layout. */
@media (prefers-reduced-motion: no-preference) {
  .elementor-widget-icon-list:hover .elementor-icon-list-icon::before {
    width: 18px;
    opacity: 1;
  }
}

/* --------------------------------------------------------------------------
   CARD LINK BASELINES. In the "Whoever you are" row the four cards hold
   different amounts of copy, so their links sat at four heights: measured
   spread 27px. Jerald raised the same row earlier. `margin-top: auto` pins the
   link to the card's bottom so the row reads as one line whatever sits above
   it. Scoped to cards, which are columns with a background, so it cannot reach
   a button sitting in a plain layout row. */
.e-con[class*="elementor-element"] > .elementor-widget-button:last-child {
  margin-top: auto;
}

/* --------------------------------------------------------------------------
   The mid-article call to action.

   Deliberately quiet. It sits inside the reading column, so anything with a
   heavy fill or a hard border would read as an ad break and get scrolled past
   -- which is the failure mode of every inline CTA on the internet. A sage rule
   down the left edge and a wash background is enough to mark it as an aside
   without breaking the read.
   -------------------------------------------------------------------------- */
.halco-inline-cta {
  margin: 34px 0;
  padding: 22px 24px;
  background: var(--halco-sage-wash, #F2F4F0);
  border-left: 3px solid var(--halco-sage, #707F6A);
  border-radius: 0 var(--halco-r-sm, 10px) var(--halco-r-sm, 10px) 0;
}

.halco-inline-cta__lead {
  margin: 0 0 14px;
  font-family: var(--halco-font-head-stack);
  font-size: 19px;
  font-weight: 700;
  line-height: 1.35;
  color: var(--halco-ink, #15161A);
}

.halco-inline-cta__actions {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

@media (max-width: 479px) {
  .halco-inline-cta { padding: 18px 18px; }
  .halco-inline-cta__actions > .halco-btn { width: 100%; text-align: center; }
}

/* The inline CTA sits on a LIGHT wash, so it cannot inherit the button colours.
   .halco-btn--ghost was written for the dark end-of-article panel, where it
   takes its text colour from the parent. Dropped onto a light background it
   resolved to sage text on a sage fill -- the same colour, so the label was
   invisible. Both buttons are stated explicitly here rather than inherited. */
.halco-inline-cta .halco-btn--primary,
.halco-inline-cta .halco-btn--primary:hover,
.halco-inline-cta .halco-btn--primary:focus {
  background-color: var(--halco-sage-dark, #4F5A4A);
  border: 1px solid var(--halco-sage-dark, #4F5A4A);
  color: #FFFFFE;
  text-decoration: none;
}

.halco-inline-cta .halco-btn--ghost,
.halco-inline-cta .halco-btn--ghost:hover,
.halco-inline-cta .halco-btn--ghost:focus {
  background-color: #FFFFFE;
  border: 1px solid rgba(58, 68, 52, .22);
  color: var(--halco-ink, #15161A);
  text-decoration: none;
}

.halco-inline-cta .halco-btn--primary:hover { background-color: var(--halco-ink, #15161A); border-color: var(--halco-ink, #15161A); }
.halco-inline-cta .halco-btn--ghost:hover   { border-color: var(--halco-sage, #707F6A); }

/* --------------------------------------------------------------------------
   Listing context: where this is, and who you would be dealing with.

   Two cards rather than a list of links, because both are a decision rather
   than a reference — "read about this suburb" and "this is the person" are the
   two questions someone has after they like a house.
   -------------------------------------------------------------------------- */
.halco-lctx {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px;
  margin: 0;
}

.halco-lctx__item {
  display: block;
  padding: 22px 24px;
  background: #FFFFFE;
  border: var(--halco-hairline, 1px solid rgba(58,68,52,.10));
  border-radius: var(--halco-r-md, 14px);
  box-shadow: var(--halco-elev-1);
  text-decoration: none;
  transition: transform var(--halco-dur, .28s) var(--halco-ease-settle),
              box-shadow var(--halco-dur, .28s) var(--halco-ease),
              border-color var(--halco-dur, .28s) var(--halco-ease);
}

@media (prefers-reduced-motion: no-preference) {
  .halco-lctx__item:hover {
    transform: translateY(-3px);
    box-shadow: var(--halco-elev-3);
    border-color: rgba(58,68,52,.16);
  }
}

.halco-lctx__label {
  display: block;
  font-family: var(--halco-font-head-stack);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--halco-sage, #707F6A);
  margin-bottom: 8px;
}

.halco-lctx__title {
  display: block;
  font-family: var(--halco-font-head-stack);
  font-size: 21px;
  font-weight: 700;
  line-height: 1.25;
  color: var(--halco-ink, #15161A);
  margin-bottom: 6px;
}

.halco-lctx__note {
  display: block;
  font-family: var(--halco-font-body-stack);
  font-size: 15.5px;
  line-height: 1.55;
  color: var(--halco-ink-soft, #4A4E54);
}

/* ============================================================================
   SESSION E — PASS 37  ·  Wide lists use the width they are given
   ----------------------------------------------------------------------------
   The "Why House & Land Co exists" section is 1,512px wide and its list is
   900px, so roughly 540px of the canvas sat empty to the right of five short
   lines. That is what reads as heaviness in a dark section: not too much
   content, too little of the space used, so the block is taller than it needs
   to be and the eye has nowhere to go.

   Column-WIDTH rather than column-count, which makes the rule self-regulating
   and safe everywhere. `columns: 380px` asks for as many 380px columns as fit:
   a 900px list gets two, a 300px list inside a card gets one and is untouched.
   No need to guess which lists are wide, and a list that becomes narrow later
   fixes itself.
   ========================================================================== */

@media (min-width: 1024px) {
  .elementor-widget-icon-list .elementor-icon-list-items {
    columns: 380px;
    column-gap: 54px;
  }
  .elementor-widget-icon-list .elementor-icon-list-item {
    break-inside: avoid;
    /* Flex items do not fragment predictably across columns; inline-flex keeps
       each row intact inside its column. */
    display: flex;
  }
}

/* Footer and nav link lists are navigation, not prose, and already sit in
   their own columns. */
.elementor-location-footer .elementor-icon-list-items,
#halco-header .elementor-icon-list-items { columns: auto !important; }

/* ============================================================================
   SESSION E — PASS 38  ·  Touch targets in the footer
   ----------------------------------------------------------------------------
   A responsive sweep at 320, 375, 414, 768, 1024, 1512 and 2560 across thirteen
   pages found no horizontal overflow anywhere, which is the thing that usually
   breaks. It did find the same 28 undersized tap targets on every page, and
   "identical on every page" means a shared template, not a page fault: the
   footer link lists.

   Measured at 375px: 21px tall, zero vertical padding, in 27px rows. WCAG 2.5.5
   asks for 44px and Material for 48px. On a phone these are links you aim at
   and miss, and the miss lands on the neighbouring link rather than on nothing,
   which is the worse kind of miss.

   Padding rather than font-size: the type is fine, the hit area is not. This
   also spaces the columns out, which they needed anyway.
   ========================================================================== */

@media (max-width: 767.98px) {
  .elementor-location-footer .elementor-icon-list-item > a,
  .elementor-location-footer .elementor-icon-list-item {
    min-height: 44px;
    display: flex;
    align-items: center;
  }
  /* The row itself must grow with the link, or the padding overlaps rather
     than separating. */
  .elementor-location-footer .elementor-icon-list-items > li { margin-bottom: 0; }

  /* Contact links in the footer are on their own lines and want the same
     floor, without the flex changing how the address wraps. */
  .elementor-location-footer a[href^="tel:"],
  .elementor-location-footer a[href^="mailto:"] {
    display: inline-block;
    padding: 11px 0;
  }
}

/* ============================================================================
   SESSION E — PASS 39  ·  Undoing two thirds of PASS 36 and 37
   ----------------------------------------------------------------------------
   Jerald: "This looks worse than before. The dash technically looked better."
   He is right on both counts and both were my errors, not taste differences.

   1. THE MARKER HAD NO GAP. The icon slot was set to 15px holding a 13px rule,
   leaving two pixels before the text. So it rendered as an em-dash welded to
   the first word: "—Worried the builder's". The old tick and dash looked
   better simply because Elementor's own icon spacing gave them room. The
   alignment fix in PASS 36 was right; the spacing that came with it was not.

   2. THE COLUMNS HURT THIS SECTION. PASS 37 split wide lists into columns to
   use the empty right-hand space. On this list it halved the measure to about
   400px and the questions, which are long, started breaking mid-phrase:
   "what they want / to sell". I was solving for the space and made the reading
   worse, which is the wrong trade.

   And the premise was shaky. 900px at 17px is roughly 90 characters, already
   past the 65 to 75 that reads comfortably. That "unused" 540px was not waste,
   it was the measure being held. Columns are kept only where a list is wide
   AND its items are short enough to survive the narrower column.
   ========================================================================== */

/* Marker: shorter, lighter, and with room to breathe. */
.elementor-icon-list-icon {
  width: 26px;
}
.elementor-icon-list-icon::before {
  width: 11px;
  height: 1px;
  opacity: .55;
}
.halco-on-dark .elementor-icon-list-icon::before { opacity: .7; }

@media (prefers-reduced-motion: no-preference) {
  .elementor-widget-icon-list:hover .elementor-icon-list-icon::before {
    width: 15px;
    opacity: .9;
  }
}

/* Columns: only for lists whose items are short. A list of one-line benefits
   ("Realistic prices", "Faster build times") columnises well; a list of
   full-sentence questions does not. There is no CSS test for "short", so the
   threshold is the column width itself, raised so that a 900px list stays
   whole and only a genuinely wide one splits. */
@media (min-width: 1024px) {
  .elementor-widget-icon-list .elementor-icon-list-items {
    columns: 460px;
    column-gap: 60px;
  }
}

/* PASS 39b · The marker was reading as grey, not sage.
   At .55 on the ink ground the rule lost its colour entirely and looked like a
   smudge rather than a deliberate mark. Sage is the brand's only accent and
   this is one of the few places it appears in body content, so it should be
   legible as sage. Light grounds stay restrained; ink grounds carry it. */
.elementor-icon-list-icon::before { opacity: .7; }
.halco-on-dark .elementor-icon-list-icon::before {
  background: var(--halco-sage-lift, #96A684);
  opacity: .95;
  height: 1.5px;
}

/* ============================================================================
   SESSION E — PASS 40  ·  No marker at all
   ----------------------------------------------------------------------------
   Third attempt, and the first two were the wrong question. A tick was clip-art,
   a dash was clip-art with better spacing, and a hairline rule was a dash that
   had been to design school. Jerald has now said twice that he does not like
   it, which is the answer: the mark itself is the problem, not its shape.

   The expensive-looking sites do not bullet a five-item list. They give it room
   and let the rhythm do the work, because a marker in front of every line is a
   nineteenth-century convention for dense print, and these are five short
   questions with air around them.

   So: no per-item mark. One hairline for the whole group instead, which says
   "these belong together" once rather than five times, and the items separate
   on spacing. This is a structural move rather than another glyph, which is why
   it is the last one.
   ========================================================================== */

.elementor-icon-list-icon { display: none !important; }

.elementor-widget-icon-list .elementor-icon-list-items {
  position: relative;
  padding-left: 26px;
  border-left: 1px solid var(--halco-line, #E3E6E0);
}
.halco-on-dark .elementor-widget-icon-list .elementor-icon-list-items {
  border-left-color: rgba(150, 166, 132, .42);
}

/* Rhythm carries the separation now, so it has to be real. */
.elementor-widget-icon-list .elementor-icon-list-item {
  padding: 0 0 2px;
  margin-bottom: 15px;
}
.elementor-widget-icon-list .elementor-icon-list-item:last-child { margin-bottom: 0; }

/* Navigation lists are a different object: a column of links wants neither the
   rule nor the rhythm, it wants to be compact and scannable. */
.elementor-location-footer .elementor-icon-list-items,
#halco-header .elementor-icon-list-items,
.halco-toc ol {
  padding-left: 0 !important;
  border-left: 0 !important;
}
.elementor-location-footer .elementor-icon-list-item,
#halco-header .elementor-icon-list-item { margin-bottom: 0; }

/* PASS 41 · The team member's name is a link to their page.
   Styled as the heading it already was, not as a link, so the card gains a
   destination without gaining visual noise. The underline appears on hover and
   focus, which is where it is useful. */
.halco-team__namelink {
  color: inherit;
  text-decoration: none;
  background-image: linear-gradient(var(--halco-sage, #707F6A), var(--halco-sage, #707F6A));
  background-size: 0 1.5px;
  background-position: 0 100%;
  background-repeat: no-repeat;
  transition: background-size .26s cubic-bezier(.22, .61, .36, 1), color .2s ease;
}
.halco-team__namelink:hover,
.halco-team__namelink:focus-visible {
  color: var(--halco-sage-text, #5F6D59);
  background-size: 100% 1.5px;
}
.halco-team__namelink:focus-visible {
  outline: 2px solid var(--halco-sage, #707F6A);
  outline-offset: 3px;
  border-radius: 2px;
}
@media (prefers-reduced-motion: reduce) {
  .halco-team__namelink { transition: none; }
}


/* ==========================================================================
   The dash comes back -- Jerald, 2 September 2026.

   Overrides the "no per-item mark" decision recorded around line 6140. That pass
   removed the marker entirely and left one hairline rule for the whole group.
   Asked directly, Jerald said he preferred the dash. So the dash returns and the
   rule stays: the dash marks each line, the rule holds the group.

   The dash is drawn in CSS, NOT with Elementor's icon. Its minus glyph carries a
   448x512 viewBox, so asking for a 14x2 rule renders a 6x2 fragment -- the
   aspect ratio is preserved and the shape collapses. A border is a rule at
   exactly the length asked for, at any zoom, with no glyph to distort.
   ========================================================================== */

.elementor-widget-icon-list .elementor-icon-list-icon,
.elementor-widget-icon-list .elementor-icon-list-icon svg { display: none !important; }

.elementor-widget-icon-list .elementor-icon-list-item { position: relative; }

/* The indent belongs on the ITEM, not the list.
   Hung off the <ul> the dash sat 19px outside the widget's own box and was
   clipped away -- and the earlier padding-left on .elementor-icon-list-items was
   being overridden anyway. Padding the item means the dash is always inside the
   element it marks, at any width. */
.elementor-widget-icon-list .elementor-icon-list-item {
  padding-left: 32px;
}

.elementor-widget-icon-list .elementor-icon-list-item::before {
  content: "";
  position: absolute;
  left: 0;
  top: .72em;                 /* optical centre of the first line, not the box */
  width: 18px;
  height: 0;
  border-top: 2px solid var(--halco-sage, #707F6A);
  opacity: .9;
}

.halco-on-dark .elementor-widget-icon-list .elementor-icon-list-item::before {
  border-top-color: rgba(150, 166, 132, .85);
}

/* The group rule GOES.
   Keeping both was the mistake: a vertical rule down the group and a dash on
   every item are two marks doing one job, and because the dash starts where the
   rule sits, each dash appeared to cut through it. It read as a ladder.
   One mark. The dash is the mark, so the rule is removed here -- overriding the
   earlier `border-left` on .elementor-icon-list-items. */
.elementor-widget-icon-list .elementor-icon-list-items,
.halco-on-dark .elementor-widget-icon-list .elementor-icon-list-items {
  border-left: 0 !important;
  padding-left: 0 !important;
}

/* Navigation and footer lists are a different object: no rule, no dash. */
.elementor-nav-menu .elementor-icon-list-item::before,
.halco-footer .elementor-icon-list-item::before { content: none; }


/* ==========================================================================
   DIRECTION B — "Warm", applied properly. 2 September 2026.

   Chosen by Jerald from the three mock-ups. The version he first saw was too
   timid to read as a change at all: measured against live it was a 5-unit
   warmer background, 14px to 22px corners, 17px to 18px body, and a button
   radius shift from 320px to 999px that renders identically on a pill. He said
   it looked like the current site, and he was right.

   This is the same direction with the timidity taken out. It is still SUBTLE in
   the sense that nothing moves position -- no layout changes, no type scale
   changes, no copy changes -- but the surface genuinely differs.

   Why warm, for this client: the reviews describe anxious first-home buyers,
   recent migrants, and at least one neurodivergent reader who found the whole
   process overwhelming. A cool white clinical ground is the wrong room for that
   conversation. Warm paper, soft edges and generous shadow read as reassuring.
   ========================================================================== */

:root {
  --halco-r-sm: 12px;
  --halco-r-md: 20px;
  --halco-r-lg: 28px;

  /* Warm paper, not clinical white. Roughly 6% warmer than #FFFFFE. */
  --halco-paper:      #FAF7F2;
  --halco-paper-card: #FFFDFA;
  --halco-warm-line:  rgba(74, 62, 48, .10);
}

body,
.elementor-kit-4 { background-color: var(--halco-paper) !important; }

/* Sections that were painted the old near-white take the warm ground too,
   otherwise they read as pale rectangles floating on it. */
.e-con[style*="rgb(255, 255, 254)"],
.e-con[style*="rgb(247, 248, 245)"] { background-color: var(--halco-paper) !important; }

/* Cards: no border at all. On a warm ground a hairline reads as a cut edge;
   shadow alone is what makes something look placed rather than drawn. */
.halco-pk__card,
.pbx-card,
.halco-lctx__item {
  background: var(--halco-paper-card) !important;
  border: none !important;
  border-radius: var(--halco-r-md) !important;
  box-shadow: 0 1px 2px rgba(74, 62, 48, .04),
              0 10px 28px rgba(74, 62, 48, .07) !important;
}

@media (prefers-reduced-motion: no-preference) {
  .halco-pk__card:hover,
  .pbx-card:hover,
  .halco-lctx__item:hover {
    box-shadow: 0 2px 6px rgba(74, 62, 48, .06),
                0 22px 52px rgba(74, 62, 48, .12) !important;
  }
}

/* Imagery carries the same corner as the cards, so nothing looks cropped in. */
.elementor-widget-image img,
.halco-article__hero img { border-radius: var(--halco-r-md) !important; }

/* Body copy: one step up, a warmer ink, and more line height. This is the part
   that does the most for a nervous reader and the least to the layout. */
/* Body ink is NOT changed by this direction.
   Two attempts to warm it failed the same way: the dark sections on this site do
   not all carry a marker class, so a global rule (and then a :not() guard)
   repainted light-on-dark copy to dark-on-dark. Measured contrast fell to 1.8:1
   on the homepage hero and the "Fixing what's broken" block -- unreadable.

   The warmth in this direction comes from the ground and the cards, which is
   where it belongs. Line height still opens up; colour is left exactly as the
   sections define it. */
.elementor-element.halco-t-body,
.elementor-element.halco-t-body-s,
.elementor-element.halco-t-body-l,
.elementor-element.halco-t-body-xl { line-height: 1.78 !important; }
.elementor-element.halco-t-body    { font-size: 17.5px !important; }
.elementor-element.halco-t-body-s  { font-size: 16.5px !important; }

/* Form controls and quiet surfaces pick up the warmth rather than staying grey. */
.halco-pk__facet select,
.halco-pk select { background-color: var(--halco-paper-card) !important; border-color: var(--halco-warm-line) !important; }
.halco-pk__specs li { background: #F4F1EA !important; border-color: var(--halco-warm-line) !important; }
.halco-inline-cta   { background: #F1EFE7 !important; }

/* The stuck header matches the paper it floats over. */
#halco-header.is-stuck { background-color: rgba(250, 247, 242, .78) !important; }


/* ==========================================================================
   Footer corrections — 2 September 2026.

   Two faults, both introduced by the dash work earlier today.
   ========================================================================== */

/* 1. NO DASH IN THE HEADER OR FOOTER.

   The dash was written for editorial lists -- five short statements with air
   around them, where a marker helps. The footer link columns are navigation:
   four tight columns of destinations. A dash in front of every one adds 40-odd
   marks to the page and turns a clean sitemap into a bulleted wall.

   The earlier exclusions named `.elementor-nav-menu` and `.halco-footer`, and
   the footer carries neither -- Elementor marks its templates with
   `.elementor-location-footer`. That is why it leaked. */
.elementor-location-footer .elementor-icon-list-item::before,
.elementor-location-header .elementor-icon-list-item::before { content: none !important; }

.elementor-location-footer .elementor-icon-list-item,
.elementor-location-header .elementor-icon-list-item { padding-left: 0 !important; }

/* 2. THE TWO CTA BUTTONS SIT ON ONE LINE.

   "Book a free chat" and the phone number were 37px apart vertically inside a
   flex row set to align-items: normal, so each button sat wherever its own
   wrapper put it and the pair read as staggered. Centring the row lines them up
   on their shared axis regardless of what either wrapper does. */
/* NO blanket align-items here.
   Centring every flex container in the footer to line up two buttons also
   centred the column headings over their left-aligned links, the "Have a
   question" block, and the address stack. The stray margin below was the actual
   cause; removing it aligns the buttons on its own and leaves everything else
   exactly where the layout put it. */

/* Elementor ships `.e-con[class*="elementor-element"] > .elementor-widget-button
   :last-child { margin-top: auto }` to pin a card's CTA to the bottom of its
   box. In a flex ROW that rule spends the leftover height as a top margin, which
   is why the phone button hung 36.875px below "Book a free chat". A plain
   `.elementor-widget-button` reset loses to it on specificity, so the override
   has to name the same shape. */
.elementor-location-footer .e-con > .elementor-widget-button,
.elementor-location-footer .e-con > .elementor-widget-button:last-child {
  margin-top: 0;
  margin-bottom: 0;
}


/* ==========================================================================
   URGENT FIX — .pbx-l lists collapsed below 1024px. 2 September 2026.

   Reported by the design-audit session and confirmed by measurement: on
   /building/first-home-buyers/, knock-down-rebuild, rural-builders-wa,
   property-investment-builder-perth and plan-review-compliance the list text
   rendered as a 20x168px column -- one word per line, six lines deep -- at both
   768 and 375. At 1440 it was fine, which is why it survived every check.

   Cause: two marker systems fighting. The icon-list conversion laid these items
   out as `display: grid; grid-template-columns: 20px 1fr` with the marker in
   column one. The later "dash comes back" work drew markers from an absolutely
   positioned ::before instead and hid the icon slot -- so column one emptied,
   and at narrow widths the text fell into the 20px track.

   Resolved by using ONE mechanism: padding on the item, marker absolutely
   positioned into that padding. No grid, no track to fall into, and it cannot
   break at a width because there is no column to collapse. The tick/cross/pin
   colours are kept, because on these pages the cross genuinely means "this is
   the problem" and the tick means "this is what we do".
   ========================================================================== */

.pbx-l .elementor-icon-list-item {
  display: block !important;
  grid-template-columns: none !important;
  position: relative;
  padding-left: 32px !important;
  margin-bottom: 14px;
}

.pbx-l .elementor-icon-list-item > .elementor-icon-list-text { display: inline; }

/* The marker: same absolute dash the rest of the site now uses, coloured by
   variant so the meaning survives. */
.pbx-l .elementor-icon-list-item::before {
  content: "";
  position: absolute;
  left: 0;
  top: .72em;
  width: 18px;
  height: 0;
  border-top: 2px solid var(--pbx-mark, #707F6A);
  background: none;
  -webkit-mask: none;
          mask: none;
  opacity: .9;
}

.pbx-l--tick        .elementor-icon-list-item { --pbx-mark: #707F6A; }
.pbx-l--cross       .elementor-icon-list-item { --pbx-mark: #B4483C; }
.pbx-l--cross-muted .elementor-icon-list-item { --pbx-mark: #9AA093; }
.pbx-l--pin         .elementor-icon-list-item { --pbx-mark: #707F6A; }


/* ==========================================================================
   Refinement pass, 3 September 2026. Part 1: two regressions Jerald flagged.
   Both decorative or layout-only. No content, no structure, no new bytes on
   the wire beyond this block. Appended, never edited in place.
   ========================================================================== */

/* 1. Record-page aside button: label pinned to the top of the pill.
   `.halco-record__aside .halco-cta-row .halco-btn { display:block }` (around
   line 4694) is there so the button fills the aside width. It also discards
   the inline-flex + align-items:center from the shared .halco-btn rule, so
   with padding 0 26px and min-height 48px the text sat at the top edge.
   flex is block-level too, so the full-width intent survives. */
.halco-record__aside .halco-cta-row .halco-btn {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 2. Step numerals in pb_card grids ("01" .. "06"): the 2px sage underline
   under each numeral dates from 25 August, when cards carried a hairline
   border and it read as a card detail. On the borderless warm cards it reads
   as a stray hyphen. Jerald asked for it to go. The tabular-nums rule stays. */
.pbx-num .elementor-heading-title {
  border-bottom: 0;
  padding-bottom: 0;
}


/* ==========================================================================
   Refinement pass, 3 September 2026. Part 2: finishing Direction B, plus four
   measured fixes. All keyed on classes that refine-2026-09-03.php adds to the
   stored Elementor data, so nothing here depends on inline styles or ids.
   ========================================================================== */

/* A. THE WARM GROUND, REACHING THE SECTIONS THIS TIME.
   Direction B's `.e-con[style*="rgb(255, 255, 254)"]` matched no section on
   any page measured, because Elementor writes container colours into
   post-N.css rather than a style attribute. So the paper ground existed only
   as the body colour, behind sections that covered it edge to edge, and showed
   nowhere. These two classes are on every container that was painted the old
   raised or base plane. Sage tint and ink sections are untouched on purpose:
   they are the punctuation, and the ladder keeps them. */
.e-con.halco-plane-raised,
.e-con.halco-plane-base { background-color: var(--halco-paper, #FAF7F2) !important; }

/* B. ONE CARD, NOT SIX.
   Package cards and pbx cards took the warm treatment on 2 September. Team
   cards, p_card() cards, design cards and blog cards did not, and the site was
   carrying six card treatments at once. Same rule, same shadow, same corner,
   for all of them. p_card() had no class of its own until today. */
.halco-card,
.halco-team__card,
.halco-pk__link,
.elementor-post__card {
  background: var(--halco-paper-card, #FFFDFA) !important;
  border: none !important;
  border-radius: var(--halco-r-md, 20px) !important;
  box-shadow: 0 1px 2px rgba(74, 62, 48, .04),
              0 10px 28px rgba(74, 62, 48, .07) !important;
}
@media (prefers-reduced-motion: no-preference) {
  .halco-card:hover,
  .halco-team__card:hover,
  .halco-pk__link:hover,
  .elementor-post__card:hover {
    box-shadow: 0 2px 6px rgba(74, 62, 48, .06),
                0 22px 52px rgba(74, 62, 48, .12) !important;
  }
}
/* The team photo and the post thumbnail sit flush inside the card; the card's
   corner has to clip them or the image shows square corners over a round card. */
.halco-team__card, .elementor-post__card, .halco-pk__link { overflow: hidden; }

/* C. CARD LINK TAP TARGET.
   p_card()'s "Learn more" link is a text-only button with 8px vertical padding
   and a 15px face: about 37px tall, under the 44px floor the rest of the site
   holds (WCAG 2.2, 2.5.8). Height only; the underline-and-arrow hover in
   style.css is unchanged. */
.halco-card .elementor-widget-button a.elementor-button {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}

/* D. TEAM GRID: TWELVE PEOPLE, FOUR ACROSS.
   auto-fill at minmax(260px) resolves to five columns at 1440, so twelve cards
   fill 5 / 5 / 2 and the last row is 60% empty. At minmax(300px) the same rule
   resolves to four, 4 / 4 / 4, and each portrait gains 40px. Below 1024 the
   existing responsive rules still apply. */
@media (min-width: 1025px) {
  .halco-team__grid { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }
}

/* E. FOOTER LINKS ON THE DARK PLANE.
   hello@houseandland.co inherited the site's light-ground link colour,
   #5F6D59, on #141512: 3.33:1, under AA. The on-dark link rule at ~2765
   excludes the footer citing a treatment that does not exist. This is that
   treatment: the same #C4CABD as the address text beside it, rising to white
   on hover, matching the column links' existing behaviour. */
#halco-footer a:not(.elementor-button):not(.halco-logo__link) { color: #C4CABD; }
#halco-footer a:not(.elementor-button):not(.halco-logo__link):hover,
#halco-footer a:not(.elementor-button):not(.halco-logo__link):focus-visible { color: #FFFFFE; }


/* ==========================================================================
   Refinement pass, 3 September 2026. Part 3: two small layout rules.
   ========================================================================== */

/* F. HOMEPAGE "ONE TEAM" SECTION, PHONE ORDER.
   The section is a two-column row: copy and buttons on the left, photo on the
   right. p_section() stacks rows into a column below 768 in source order, so
   on a phone the reader was asked to act and then shown the picture, 250px
   below the buttons. No pattern option exists for a mobile reorder, and a
   rebuild of the homepage would discard UI edits, so the order is set here on
   the section's own ids: 8ac4abb is the section, 0cd1666 the photo column.
   Only this section; the other split rows on the site read correctly. */
@media (max-width: 767px) {
  .elementor-element-8ac4abb .elementor-element-0cd1666 { order: -1; }
}

/* G. PACKAGES MAP "SHOW ALL" CONTROL.
   Added by halco-map.php when the map opens on the Perth cluster and there are
   listings outside it. Styled like the zoom bar it sits beside, in the site's
   own face and sage, so it reads as part of the map rather than a stray link. */
.halco-map__all a {
  width: auto;
  padding: 0 12px;
  font: 600 13px/30px "Manrope", -apple-system, sans-serif;
  color: var(--halco-sage-text, #5F6D59);
  white-space: nowrap;
}
.halco-map__all a:hover,
.halco-map__all a:focus-visible { color: var(--halco-ink, #15161A); }

/* Part 3, correction. Leaflet marks the container `.leaflet-touch` on every
   pointer type it considers touch-capable, and its `.leaflet-touch .leaflet-bar a`
   (0,2,1) pins width to 30px, beating the (0,1,1) rule above, so "Show all 15"
   overflowed its own bar and clipped at the map edge. Matched specificity. */
.leaflet-touch .halco-map__all a,
.halco-map__all a {
  width: auto;
  height: 30px;
  line-height: 30px;
  padding: 0 12px;
}
/* leaflet.css is enqueued by halco-map.php and lands AFTER this sheet, so at
   equal specificity Leaflet's `.leaflet-touch .leaflet-bar a` (0,2,1) still
   won. One more class on the bar takes it to (0,3,1). */
.leaflet-touch .leaflet-bar.halco-map__all a,
.leaflet-bar.halco-map__all a { width: auto; height: 30px; line-height: 30px; padding: 0 12px; }

/* SESSION E — PASS 42 was removed here on 3 September 2026.
   It set `content: none !important` on every icon-list ::before and ::after and
   `padding-left: 0 !important` on the item, which switched off the sage dash added
   on 2 September at Jerald's request AND the hanging indent with it. The list under
   "We work across WA's top builders" rendered as five phrases with nothing joining
   them. PASS 42 was written without knowledge of the 2 September decision: its own
   header cites three earlier requests to remove markers, all of which predate it.

   Removed rather than overridden, on PASS 42's own instruction: "If a marker is
   wanted again, delete this block rather than adding a fourth mechanism somewhere
   else in the file." The dash now comes from one place, the 2 September block above,
   which already excludes the header and footer via .elementor-location-*.

   Verified before applying, by serving the edited sheet to a real browser: dash 18px
   at 2px in brand sage, 32px hanging indent, header and footer still unmarked, the
   .pbx-l tick/cross/pin colour variants intact, and 91 list items across the five
   building pages at 375 and 768 with zero squeezed and no overflow. */

/* ============================================================================
   SESSION E — PASS 43  ·  Painted sections lift, they do not fade
   ----------------------------------------------------------------------------
   The white band Jerald saw on first load between the dark call-to-action and
   the dark footer. A section carrying its own background colour was a reveal
   target at `opacity: 0`, which makes a dark band show the cream page through
   it and then darken as it animates. Measured: 8 of 8 painted sections on the
   homepage were fading up from fully transparent.

   `halco-reveal--solid` is the same movement with the opacity left alone.
   halco-ux.php decides which class a section gets by reading its computed
   background at the moment it is marked, so nothing has to be maintained by
   hand as sections change colour.
   ========================================================================== */

.halco-motion .halco-reveal--solid {
  transform: translateY(18px);
  will-change: transform;
}
.halco-motion .halco-reveal--solid.is-in {
  transform: none;
  transition: transform .7s cubic-bezier(.16, 1, .3, 1);
}
@media (prefers-reduced-motion: reduce) {
  .halco-reveal--solid,
  .halco-motion .halco-reveal--solid {
    transform: none !important;
    transition: none !important;
  }
}

/* PASS 43b · Unconditional. A painted section is never see-through.
   PASS 43 gave these sections a class with no opacity rule, and they were
   STILL measuring 0.2 mid-transition with no matching rule and no animation
   found by selector. Rather than keep hunting the source, this states the
   requirement directly: a section that paints its own background does not fade,
   from any source, at any point. The lift is the whole animation. */
.halco-motion .halco-reveal--solid,
.halco-motion .halco-reveal--solid.is-in,
.halco-reveal--solid { opacity: 1 !important; }

/* ============================================================================
   SESSION E — PASS 44  ·  The last section before the footer
   ----------------------------------------------------------------------------
   Jerald: "in both child pages the padding seems to be off before the footer."

   Measured on the listing record, last three sections:

       Common questions          padding  44 / 72
       Independent advice        padding  76 / 76
       The area + Your consultant padding  0 / 0     <-- this one

   The closing card pair had no padding at all, so it sat pressed between the
   dark call-to-action above it and the dark footer below, while every other
   section on the page breathes at 44 to 76px. The page's rhythm simply stopped
   at the last block.

   Matched to the section above it rather than picked: 76px is what the
   call-to-action band uses, so the closing pair now sits in the same measure as
   the rest of the page instead of being the one exception.

   Scoped to a section that has NO padding of its own, so a section someone has
   deliberately set flush stays flush, and this cannot fight a value set in the
   Elementor sidebar. */

@media (min-width: 768px) {
  [data-elementor-type="single-post"] > .e-con:last-of-type:not([style*="padding"]) {
    padding-top: 60px;
    padding-bottom: 76px;
  }
}
@media (max-width: 767.98px) {
  [data-elementor-type="single-post"] > .e-con:last-of-type:not([style*="padding"]) {
    padding-top: 40px;
    padding-bottom: 52px;
  }
}

/* ============================================================================
   SESSION E — PASS 45  ·  Painted CHILDREN lift too
   ----------------------------------------------------------------------------
   PASS 43 stopped top-level sections fading. The same fault was one level down
   and far more common: the stagger fades a section's children, and most of them
   are painted, so every tinted card and panel on the site showed the page
   through itself on the way in.

   Audited across 14 pages before this: 38 painted containers caught mid-fade,
   on every page including the homepage, finance, reviews, careers and areas.
   That is the same flicker Jerald reported at the footer, happening quietly
   everywhere else as well.

   Nothing here changes the movement or its timing. Only the opacity is left
   alone, and only where a surface would otherwise turn see-through.
   ========================================================================== */

.halco-motion .halco-stagger--solid {
  animation: halco-section-lift .72s cubic-bezier(.16, 1, .3, 1) both;
  animation-delay: var(--halco-stagger, 0ms);
}
@keyframes halco-section-lift {
  from { transform: translateY(14px); }
  to   { transform: none; }
}

/* Belt to that brace, and the reason PASS 43b needed one: opacity on a painted
   surface has come from more than one place tonight. State it once. */
.halco-stagger--solid,
.halco-motion .halco-stagger--solid { opacity: 1 !important; }

@media (prefers-reduced-motion: reduce) {
  .halco-stagger--solid,
  .halco-motion .halco-stagger--solid {
    animation: none !important;
    transform: none !important;
  }
}

/* ============================================================================
   SESSION E — PASS 46  ·  halco-nofade: the one rule about painted surfaces
   ----------------------------------------------------------------------------
   halco-ux.php tags any element that paints a background AND carries one of
   the reveal or stagger classes, from any session's mechanism. This is what the
   tag does, and it is deliberately the only rule in the file that touches
   opacity on an animated element.

   Transform is untouched on purpose: every lift, rise and stagger still plays
   exactly as its author wrote it. The only thing forbidden is a surface going
   see-through, because that is never the intended effect, it is a side effect
   of animating a container instead of its contents.
   ========================================================================== */

.halco-nofade,
.halco-motion .halco-nofade,
.halco-nofade.is-in,
.halco-nofade.is-done { opacity: 1 !important; }
