/* ALHST — minimal front-end styles.
   theme.json owns the design system (colour, type, spacing, layout).
   This file holds only what theme.json cannot express. */

/* --- Breadcrumbs (alhst-core) ------------------------------------------ */
.alhst-breadcrumbs { margin-block: var(--wp--preset--spacing--20); font-size: var(--wp--preset--font-size--xs); }
.alhst-breadcrumbs ol { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .35rem .5rem; }
.alhst-breadcrumbs li + li::before { content: "›"; margin-right: .5rem; color: var(--wp--preset--color--muted); }
.alhst-breadcrumbs a { color: var(--wp--preset--color--muted); text-decoration: none; }
.alhst-breadcrumbs a:hover { color: var(--wp--preset--color--navy); text-decoration: underline; }
.alhst-breadcrumbs [aria-current="page"] { color: var(--wp--preset--color--ink); }

/* --- Related content: the contextual internal-linking module ------------ */
.alhst-related {
  margin-block: var(--wp--preset--spacing--40);
  padding: var(--wp--preset--spacing--30);
  background: var(--wp--preset--color--surface);
  border-left: 3px solid var(--wp--preset--color--accent);
  border-radius: 4px;
}
.alhst-related__title { font-size: var(--wp--preset--font-size--lg); margin: 0 0 var(--wp--preset--spacing--20); }
.alhst-related ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .6rem; }
@media (min-width: 640px) { .alhst-related ul { grid-template-columns: 1fr 1fr; } }
.alhst-related a { text-decoration: none; font-weight: 500; }
.alhst-related a:hover { text-decoration: underline; }

/* --- Accessibility ------------------------------------------------------ */
.skip-link { position: absolute; left: -9999px; }
.skip-link:focus {
  left: var(--wp--preset--spacing--20); top: var(--wp--preset--spacing--20);
  z-index: 999; padding: .75rem 1rem; background: var(--wp--preset--color--navy);
  color: #fff; border-radius: 4px;
}
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--wp--preset--color--accent); outline-offset: 2px;
}

/* --- Images: never shift layout ---------------------------------------- */
img, iframe, video { max-width: 100%; height: auto; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* =======================================================================
   BRAND LAYER — added with the evidence-based palette, 18 Aug 2026.
   theme.json owns colour, type and spacing. Everything below is something
   theme.json genuinely cannot express.
   ===================================================================== */

/* --- Numerals ----------------------------------------------------------
   Alegreya Sans ships OLD-STYLE figures by default: 1912 and 2,410 render
   with descenders, at lowercase height. That is correct for running prose
   and wrong for every price, bed/bath count and square-footage figure on
   this site. `lnum` gives lining figures; `tnum` gives fixed-width ones so
   price columns align. Source Sans 3 has neither, which is part of why the
   body face changed.                                                     */
body { font-variant-numeric: lining-nums; }
.alhst-stats, .alhst-price, table, .wp-block-table,
.alhst-related time, .wp-block-post-date {
  font-variant-numeric: lining-nums tabular-nums;
}

/* --- Section eyebrow ---------------------------------------------------
   h6 is styled as the small-caps oxblood label above a section heading.
   Kept as a real heading element so the document outline stays honest,
   but visually it is a label, not a rank-6 heading.                      */
/* The eyebrow was authored as an <h6>. That was wrong twice over: it put a
   level-6 heading directly after the H1 (a two-level jump in the outline, which
   the SEO audit caught on 26 August), and it leaned on the heading element for
   its appearance instead of saying what it wanted. It is a <p> now, so the
   appearance has to be stated here — including the family, which was never set,
   meaning the "already small caps" comment below described a face the eyebrow
   was not actually using. */
.alhst-eyebrow {
  margin-block: 0 var(--wp--preset--spacing--10);
  font-family: var(--wp--preset--font-family--display);  /* Alegreya Sans SC — real small caps */
  font-weight: 700;
  font-size: var(--wp--preset--font-size--xs);
  letter-spacing: .06em;
  line-height: 1.3;
  color: var(--wp--preset--color--muted);
  text-transform: none;   /* the face is already small caps — do not double up */
}
/* On a navy panel the muted grey fails contrast, so the eyebrow follows the
   panel's own text colour instead of insisting on its own. */
.has-navy-background-color .alhst-eyebrow,
.has-navy-deep-background-color .alhst-eyebrow {
  color: var(--wp--preset--color--navy-tint);
}

/* --- Header ------------------------------------------------------------ */
.wp-block-site-logo img { display: block; height: auto; }
/* The site title is a fallback for when no site logo is set. Once the logo
   is uploaded, WordPress renders both — hide the text and let the logo,
   which carries the same words, do the work. The title stays in the DOM
   for screen readers.                                                     */
.wp-block-site-logo:not(:empty) + .alhst-title-fallback {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
@media (max-width: 599px) { .alhst-header-cta { display: none; } }

/* --- Buttons on a navy panel ------------------------------------------
   Navy and oxblood sit at 1.22:1 against each other, so the accent colour
   cannot be used for anything on a navy background. On navy, the filled
   button inverts to white-on-navy and the outline button goes white.     */
.alhst-btn-invert .wp-block-button__link {
  background-color: var(--wp--preset--color--base);
  color: var(--wp--preset--color--navy);
}
.alhst-btn-invert .wp-block-button__link:hover,
.alhst-btn-invert .wp-block-button__link:focus {
  background-color: var(--wp--preset--color--navy-tint);
  color: var(--wp--preset--color--navy-deep);
}
.alhst-btn-invert-outline .wp-block-button__link {
  border-color: var(--wp--preset--color--base);
  color: var(--wp--preset--color--base);
}
.alhst-btn-invert-outline .wp-block-button__link:hover,
.alhst-btn-invert-outline .wp-block-button__link:focus {
  background-color: var(--wp--preset--color--base);
  color: var(--wp--preset--color--navy);
}
/* Focus rings must not use the oxblood accent on navy — 1.22:1. */
.has-navy-background-color :where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline-color: var(--wp--preset--color--base);
}

/* --- Query-loop grids -------------------------------------------------- */
.wp-block-post-template.is-layout-grid { gap: var(--wp--preset--spacing--30); }
.wp-block-post-featured-image img { width: 100%; object-fit: cover; }

/* --- Long-form measure -------------------------------------------------
   contentSize is 720px. Alegreya Sans has a small x-height (0.458em), so a
   720px line at 19px lands near 68 characters, which is inside the 45–75
   band. Do not widen this without re-checking the character count.       */
.wp-block-post-content > p { text-wrap: pretty; }
h1, h2, h3, .wp-block-post-title { text-wrap: balance; }

/* --- Brokerage attribution (alhst/brokerage) ---------------------------
   The NAME carries the regulatory weight, so it is never hidden and never
   replaced by the logo. If the logo image fails to load, the attribution is
   still complete.                                                         */
.alhst-brokerage { margin-block: var(--wp--preset--spacing--20); }
.alhst-brokerage__logo { display: block; margin-bottom: .5rem; }
.alhst-brokerage__name {
  margin: 0;
  font-family: var(--wp--preset--font-family--display);
  font-size: var(--wp--preset--font-size--xs);
  letter-spacing: .05em;
}
/* On the navy footer the Stonehaus mark is navy-on-transparent, so it needs a
   light plate behind it rather than a filter — inverting or brightening a
   two-colour logo misrepresents the brand mark. */
.alhst-brokerage--inverted .alhst-brokerage__logo {
  background: var(--wp--preset--color--base);
  padding: .5rem .65rem;
  border-radius: 3px;
}

/* --- Property facts (alhst/property-facts) ----------------------------- */
.alhst-facts {
  display: grid; gap: 0 var(--wp--preset--spacing--20); margin: 0;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
/* The rule goes on the TOP of each cell, not the bottom. A property with nine
   facts in a seven-column grid leaves a two-cell final row — a bottom border
   there renders as a dangling half-underline. Topping every cell instead means
   a partial row still reads as deliberate, and it matches the neighbourhood
   cards on the homepage, which use the same 2px line-strong rule. */
.alhst-facts__row {
  padding: var(--wp--preset--spacing--20) 0;
  border-top: 2px solid var(--wp--preset--color--line-strong);
}
.alhst-facts dt {
  font-family: var(--wp--preset--font-family--display);
  font-size: var(--wp--preset--font-size--xs);
  letter-spacing: .06em;
  color: var(--wp--preset--color--muted);
  margin-bottom: .15rem;
}
.alhst-facts dd {
  margin: 0;
  font-size: var(--wp--preset--font-size--lg);
  font-weight: 500;
  color: var(--wp--preset--color--navy);
  font-variant-numeric: lining-nums tabular-nums;
}
.alhst-facts__note {
  margin-top: var(--wp--preset--spacing--20);
  font-size: var(--wp--preset--font-size--xs);
  color: var(--wp--preset--color--muted);
}

/* --- Property parents (alhst/property-parents) ------------------------- */
.alhst-parents ul {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: .55rem;
}
@media (min-width: 640px) { .alhst-parents ul { grid-template-columns: 1fr 1fr; } }
.alhst-parents a { font-weight: 500; }

/* --- Query pagination --------------------------------------------------
   Pagination is INDEXED on this site — /property/page/13/ holds 471
   impressions — so these links are crawl paths, not decoration. They must
   remain real anchors with visible focus states.                          */
.wp-block-query-pagination {
  padding-top: var(--wp--preset--spacing--30);
  border-top: 1px solid var(--wp--preset--color--line);
  gap: var(--wp--preset--spacing--20);
}
.wp-block-query-pagination a,
.wp-block-query-pagination .current {
  font-family: var(--wp--preset--font-family--display);
  font-weight: 700;
  letter-spacing: .03em;
  text-decoration: none;
  padding: .35em .7em;
  border-radius: 3px;
}
.wp-block-query-pagination a:hover { background: var(--wp--preset--color--navy-tint); }
.wp-block-query-pagination-numbers .current {
  background: var(--wp--preset--color--navy);
  color: var(--wp--preset--color--base);
}

/* --- Search form ------------------------------------------------------- */
.wp-block-search__inside-wrapper { display: flex; max-width: 460px; }
.wp-block-search__input {
  border: 1px solid var(--wp--preset--color--line-strong);
  border-radius: 3px 0 0 3px;
  flex: 1;
  padding: .6em .8em;
  font-family: var(--wp--preset--font-family--sans);
  font-size: var(--wp--preset--font-size--md);
}
.wp-block-search__button {
  font-family: var(--wp--preset--font-family--display);
  font-weight: 700;
  letter-spacing: .03em;
  background: var(--wp--preset--color--navy);
  color: var(--wp--preset--color--base);
  border: 0;
  border-radius: 0 3px 3px 0;
  padding: .6em 1.2em;
}

/* --- Archive header ---------------------------------------------------- */
.wp-block-term-description { color: var(--wp--preset--color--muted); }
.wp-block-term-description p:last-child { margin-bottom: 0; }

/* --- Post date --------------------------------------------------------- */
.wp-block-post-date {
  font-family: var(--wp--preset--font-family--display);
  letter-spacing: .05em;
  font-variant-numeric: lining-nums;
}

/* --- Video facade (alhst/video) ----------------------------------------
   The poster and a play button stand in for the player until someone clicks.
   The whole facade is a real anchor to the watch page, so crawlers and
   no-JavaScript visitors get a working route rather than a dead box.        */
.alhst-video { margin: 0; }
.alhst-video__link {
  position: relative;
  display: block;
  border-radius: 6px;
  overflow: hidden;
  background: var(--wp--preset--color--navy-tint);
  text-decoration: none;
}
.alhst-video__poster {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}
/* Play button drawn in CSS — no icon font, no SVG request, and it inherits
   the brand rather than YouTube's red. */
.alhst-video__play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 68px; height: 68px;
  border-radius: 50%;
  background: var(--wp--preset--color--accent);
  box-shadow: 0 2px 14px rgba(0,37,88,.35);
}
.alhst-video__play::after {
  content: "";
  position: absolute;
  top: 50%; left: 54%;
  transform: translate(-50%, -50%);
  border-style: solid;
  border-width: 11px 0 11px 18px;
  border-color: transparent transparent transparent #fff;
}
.alhst-video__link:hover .alhst-video__play,
.alhst-video__link:focus-visible .alhst-video__play {
  background: var(--wp--preset--color--navy);
}
.alhst-video__caption {
  margin-top: var(--wp--preset--spacing--10);
  font-size: var(--wp--preset--font-size--sm);
  font-weight: 500;
  color: var(--wp--preset--color--navy);
}
.alhst-video__frame {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  height: auto;
  border: 0;
  border-radius: 6px;
}

/* --- Hero portrait ----------------------------------------------------- */
.alhst-hero-portrait img {
  border-radius: 6px;
  display: block;
  width: 100%;
  height: auto;
}
