/* ==========================================================================
   site.css — per-site components, built FROM tokens; tokens only, no raw
   literals (house-tech-spec §3). ARCHETYPE poster-hero (brief §5): one
   column, full width, at every width — no rail, nothing overlapping, one
   reading order top to bottom. BREAKPOINTS: 45.5em (ornament step, tokens.css)
   and 48em (layout step) only (brief §5.2's table). ONE GRADIENT, the hero
   atmosphere (brief §4.3).
   ========================================================================== */

/* --- Layout primitives ---------------------------------------------------- */

.container {
  width: 100%;
  max-width: var(--layout-container);
  margin-inline: auto;
  padding-inline: var(--layout-gutter);
}

/* The ONE inter-section value and its two call sites (brief §5.5). No section
   sets its own vertical rhythm. */
.section {
  padding-block: var(--section-gap);
}

.measure {
  max-width: var(--layout-measure);
}

/* Anchor targets need clearance for the sticky 101px stack (brief §5.6:
   expiry 44 + header 56 + 1px border). */
[id] {
  scroll-margin-block-start: calc(var(--expiry-height) + var(--header-height) + var(--border-hairline));
}

/* --- Type roles (brief §2.6). Weight is font-weight and nothing else; no
   variable-axis declaration appears anywhere (brief §2.3). --- */

h2 {
  font-size: var(--text-h2);
}

/* Every caps label on this site — eyebrows, group labels, control labels
   (brief §2.6). Authored in natural case, uppercased here
   (house-tech-spec §8). */
.caps-label {
  font-family: var(--font-body-strong);
  font-weight: var(--font-weight-body-strong);
  letter-spacing: var(--tracking-caps);
  line-height: var(--leading-caps);
  text-transform: uppercase;
}

/* --- Header. 56px + a 1px border-block-end in --color-rule (brief §5.6) =
   the 57px half of the measured 101px sticky stack. The sticky rule and the
   header height both live here; preview.css supplies --expiry-height and the
   matching sticky offset for the bar above it. --- */

.site-header {
  position: sticky;
  inset-block-start: var(--expiry-height);
  z-index: var(--z-header);
  border-block-end: var(--border-hairline) var(--border-style) var(--color-rule);
  background-color: var(--color-bg);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  min-height: var(--header-height);
}

/* Wordmark left, --font-display at 16px, no corner mark — the mark is
   reserved for section poster-heads only (brief §5.6). --text-wordmark is a
   Builder-fill token restating that exact px outcome (tokens.css banner). */
.site-header__brand {
  font-family: var(--font-display);
  font-weight: var(--font-weight-display);
  font-size: var(--text-wordmark);
  color: var(--color-accent);
  text-decoration: none;
}

.site-header__nav {
  display: flex;
  align-items: center;
  gap: var(--space-md);
}

/* The tel: alone at <48rem; #services and #contact join it at ≥48rem
   (brief §5.6). */
.site-header__link {
  display: none;
  font-family: var(--font-body-strong);
  font-weight: var(--font-weight-body-strong);
  font-size: var(--text-small);
  color: var(--color-ink);
  text-decoration: none;
}

.site-header__link:hover,
.site-header__link:focus-visible {
  text-decoration: underline;
  text-underline-offset: var(--space-3xs);
}

@media (min-width: 48rem) {
  .site-header__link {
    display: inline-flex;
    align-items: center;
  }
}

.site-header__tel {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-body-strong);
  font-weight: var(--font-weight-body-strong);
  font-size: var(--text-small);
  color: var(--color-accent);
  text-decoration: none;
  white-space: nowrap;
}

.site-header__tel:hover,
.site-header__tel:focus-visible {
  text-decoration: underline;
  text-underline-offset: var(--space-3xs);
}

/* --- Buttons. One control shape, three instances (hero, §II foot, §VI
   submit — brief §6.6): accent fill, accent-ink label, --radius-sm. The
   label is set in the DISPLAY face at 400, not the body-strong caps
   treatment used elsewhere (brief §5 §I slot ③ — "Tile C's own
   construction"). Full width below 48rem; inline-block, min 260px, at
   ≥48rem; 52px tall at every width. --- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  padding-inline: var(--space-md);
  border: var(--border-hairline) var(--border-style) transparent;
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-none);
  font-family: var(--font-display);
  font-weight: var(--font-weight-display);
  font-size: var(--text-body);
  line-height: var(--leading-snug);
  letter-spacing: var(--tracking-normal);
  text-align: center;
  text-decoration: none;
  transition: background-color var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out);
}

.btn--primary {
  width: 100%;
  min-height: var(--control-height);
  background-color: var(--color-accent);
  color: var(--color-accent-ink);
}

@media (min-width: 48rem) {
  .btn--primary {
    width: auto;
    min-width: var(--control-min-width);
  }
}

/* The secondary CTA — a text link, never a second button shape
   (brief §5 §I "Secondary CTA"). */
.btn--text {
  color: var(--color-accent);
  font-family: var(--font-body);
  font-weight: var(--font-weight-body);
  font-size: var(--text-small);
  text-decoration: underline;
  text-underline-offset: var(--space-3xs);
}

/* --- §I hero-quote, house DOM order (brief §5.3): eyebrow → h1 → primary
   CTA → secondary CTA → field → lead → facts. The field sits BELOW the ask:
   a photographic sibling block, never a backdrop for type (brief §4.3,
   §5.1 rule 3). The atmosphere gradient is the ONE gradient on the site. --- */

.hero {
  padding-block-start: var(--space-sm);
  padding-block-end: var(--section-gap);
  background: radial-gradient(120% 95% at 30% -15%,
    var(--color-atmos-hi) 0%, var(--color-atmos-mid) 60%, var(--color-atmos-lo) 100%);
}

@media (min-width: 48rem) {
  .hero {
    padding-block-start: var(--space-xl);
  }
}

/* Slot ① — trade + place, max 2 lines at 375 (brief §6 §I). */
.hero__eyebrow {
  margin-block-end: var(--space-xs);
  color: var(--color-ink-muted);
  font-size: var(--text-eyebrow);
}

/* Slot ② — the poster h1. --text-h1 runs 35.2px at 320 to 67.2px at 1440;
   one word ("escape") carries --color-accent (brief §6 §I). Capped at
   --h1-max so the poster stacks rather than running the full measure. */
.poster {
  max-width: var(--h1-max);
  margin-block-end: var(--space-sm);
  font-size: var(--text-h1);
  color: var(--color-ink);
}

.poster .accent {
  color: var(--color-accent);
}

.hero__ask {
  margin-block-end: var(--space-xs);
}

.hero__secondary {
  margin-block-end: var(--space-sm);
}

/* The living field — a photographic sibling block, 2px ink border, radius-sm
   (brief §6 §I slot ④). Aspect 3/2 below 48rem, 12/5 at ≥48rem. Named
   .hero__field (not .field) to keep this distinct from the contact form's
   .field row wrapper below — same word, two different house components. */
.hero__field {
  position: relative;
  overflow: hidden;
  aspect-ratio: var(--hero-field-ratio);
  border: var(--border-frame) var(--border-style) var(--color-ink);
  border-radius: var(--radius-sm);
  background-color: var(--color-surface);
}

.hero__field-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* --- The signature — "the sign swings" (brief §8.2/§8.3). A decorative SVG
   overlay sitting over the field image, aria-hidden, carrying no text: a
   two-sided roadside sign, a wind chime and a swan silhouette, each on its
   own independent, non-synchronised loop. Flat ink linework only — no
   gradient fill, no cross-hatching (ref-010's hand-drawn register). --- */

.hero__field-overlay {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.sign-elem,
.chime-elem,
.swan-elem,
.overlay-post {
  opacity: var(--rm-haze-opacity);
}

.swan-elem {
  fill: var(--color-accent-2);
  stroke: var(--color-ink);
  stroke-width: 2;
  stroke-linejoin: round;
}

.sign-elem,
.chime-elem,
.overlay-post {
  fill: none;
  stroke: var(--color-ink);
  stroke-width: 6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.sign-elem__board {
  fill: var(--color-bg);
}

@media (prefers-reduced-motion: no-preference) {
  .sign-elem {
    animation: sign-swing var(--duration-sign) ease-in-out infinite;
    transform-origin: 50% 0%;
  }

  .chime-elem {
    animation: chime-sway var(--duration-chime) ease-in-out infinite;
    animation-delay: var(--delay-chime);
    transform-origin: 50% 0%;
  }

  .swan-elem {
    animation: swan-bob var(--duration-swan) ease-in-out infinite;
    animation-delay: var(--delay-swan);
  }
}

@keyframes sign-swing {
  0%, 100% { transform: rotate(-3deg); }
  50%      { transform: rotate(3deg); }
}

@keyframes chime-sway {
  0%, 100% { transform: rotate(4deg); }
  50%      { transform: rotate(-4deg); }
}

@keyframes swan-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(calc(-1 * var(--space-3xs))); }
}

.hero__lead {
  margin-block-start: var(--space-sm);
  font-size: var(--text-lead);
  line-height: var(--leading-snug);
}

/* Facts line — the free estimate offer and the phone number. No
   numeral-as-ornament, no stat-counter row (brief §6 §I). The rule is
   DECORATIVE, per brief §5.4/§6.6 — it separates the line, it is not a
   functional edge. */
.hero__facts {
  margin-block-start: var(--space-md);
  padding-block-start: var(--space-xs);
  border-block-start: var(--border-hairline) var(--border-style) var(--color-rule);
  color: var(--color-ink-muted);
  font-size: var(--text-small);
}

/* --- The poster-head object, repeated at every section below the hero
   (brief §5.4/§6.6): a 3px --color-ink rule, a caps eyebrow in
   --color-accent-2, an h2 in --font-display, and the settled sign-silhouette
   corner mark at the rule's top-right corner. --- */

.poster-head {
  position: relative;
  margin-block-end: var(--space-md);
  padding-block-start: var(--space-xs);
  padding-inline-end: calc(var(--mark-size) + var(--space-sm));
  border-block-start: var(--rule-section) var(--border-style) var(--color-ink);
}

.poster-head__eyebrow {
  margin-block-end: var(--space-xs);
  color: var(--color-accent-2);
  font-size: var(--text-eyebrow);
}

.poster-head__title {
  margin: 0;
}

/* The settled sign-silhouette — a single flat ink shape, the two-sided sign
   at rest, no chime, no swan (brief §5.4 point 3). It never animates: the
   hero's own live moment is the site's one spectacular moment (brief §8.2). */
.poster-head__mark {
  position: absolute;
  inset-block-start: 0;
  inset-inline-end: 0;
  inline-size: var(--mark-size);
  block-size: var(--mark-size);
  transform: translateY(-50%);
  fill: none;
  stroke: var(--color-ink);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.poster-head__mark rect {
  fill: var(--color-bg);
}

/* --- §II services-specific — an index list, not cards, not chips, not
   icons (brief §6 §II). Largest intra-section gap on the site: 40px between
   the four groups (brief §5.5). --- */

.group-label {
  margin-block-start: var(--space-lg);
  margin-block-end: 0;
  color: var(--color-accent-2);
  font-size: var(--text-eyebrow);
}

.group-label:first-of-type {
  margin-block-start: 0;
}

.index {
  border-block-start: var(--border-hairline) var(--border-style) var(--color-rule);
}

.index__row {
  padding-block: var(--space-sm);
  border-block-end: var(--border-hairline) var(--border-style) var(--color-rule);
}

.index__name {
  font-family: var(--font-body);
  font-weight: var(--font-weight-body);
  font-size: var(--text-body);
  color: var(--color-ink);
}

/* Inline plates — type sits beneath, never over (brief §4.3). */
.section-figure {
  margin-block-start: var(--space-lg);
}

.section-figure img {
  width: 100%;
  height: auto;
  border-radius: var(--radius-sm);
}

.section__ask {
  margin-block-start: var(--space-lg);
}

/* --- §III trust-and-place — one block, --color-surface ground
   (brief §6 §III). --- */

.trust-and-place {
  background-color: var(--color-surface);
}

.trust-and-place__fact {
  margin-block-end: var(--space-md);
  font-size: var(--text-lead);
  line-height: var(--leading-snug);
}

.trust-and-place__aside,
.trust-and-place__voice {
  max-width: var(--layout-measure);
  margin-block-end: var(--space-md);
  line-height: var(--leading-body);
}

.trust-and-place__voice {
  margin-block-end: 0;
  color: var(--color-ink-muted);
}

/* --- §IV / §V — the reserved frames: rendered, never filled, never deleted
   (brief §6 §IV/§V). No shape mimics content that does not exist. --- */

.reserved {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-2xs);
  min-block-size: var(--reserved-height);
  padding: var(--space-md);
  border: var(--border-hairline) dashed var(--color-border);
  border-radius: var(--radius-sm);
}

.reserved__label {
  margin: 0;
  color: var(--color-ink-muted);
  font-size: var(--text-eyebrow);
}

.reserved__line {
  margin: 0;
  max-width: var(--layout-measure);
  color: var(--color-ink-muted);
  font-size: var(--text-small);
  line-height: var(--leading-body);
}

/* --- §VI contact — the estimate/call block (house-tech-spec §6). --- */

.contact__lead {
  margin-block-end: var(--space-md);
  max-width: var(--layout-measure);
  font-size: var(--text-lead);
  line-height: var(--leading-snug);
}

.contact__phone {
  margin-block-start: var(--space-md);
  max-width: var(--layout-measure);
  line-height: var(--leading-body);
}

.contact__phone a {
  text-underline-offset: var(--space-3xs);
}

.form {
  display: grid;
  gap: var(--space-md);
  max-width: var(--layout-measure);
}

.field {
  display: grid;
  gap: var(--space-3xs);
}

.field__label {
  font-family: var(--font-body-strong);
  font-weight: var(--font-weight-body-strong);
  font-size: var(--text-small);
}

.field__control {
  width: 100%;
  min-height: var(--layout-tap-min);
  padding: var(--space-2xs) var(--space-xs);
  background-color: var(--color-surface);
  color: var(--color-ink);
  border: var(--border-hairline) var(--border-style) var(--color-border);
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
}

textarea.field__control {
  resize: vertical;
}

.field__hint {
  font-size: var(--text-small);
  color: var(--color-ink-muted);
}

/* Honeypot: in the DOM for bots, unreachable otherwise. Not display:none. */
.form__trap {
  position: absolute;
  /* @allow-literal: off-canvas parking position, not a design value */
  left: -9999px;
  opacity: 0;
  pointer-events: none;
}

.form__status {
  font-size: var(--text-small);
  color: var(--color-ink-muted);
}

.form__status[data-state='error'] {
  color: var(--color-ink);
  font-family: var(--font-body-strong);
  font-weight: var(--font-weight-body-strong);
}

/* --- Footer — NAP, the call-ahead line, no copyright, no social links
   (copy.md's own Footer note). No hours markup ships: no V-tier hours exist
   (house-tech-spec §4's condition 1 fails), so no [data-hours] element and no
   openingHoursSpecification. --- */

.site-footer {
  padding-block: var(--section-gap);
  font-size: var(--text-small);
}

.site-footer > .container > * + * {
  margin-block-start: var(--space-sm);
}

.site-footer__nap {
  font-style: normal;
  line-height: var(--leading-body);
}

.site-footer__nap a {
  text-underline-offset: var(--space-3xs);
}

.site-footer__nap a[href^='tel'] {
  display: inline-flex;
  align-items: center;
  min-height: var(--layout-tap-min);
}

.site-footer__call-ahead {
  color: var(--color-ink-muted);
}

/* --- thanks.html: no field, no atmosphere, flat --color-bg. The h2 stands
   in as the page's display headline; the primary action is the phone
   (brief §5.6). --- */

.thanks__eyebrow {
  margin-block-end: var(--space-xs);
  color: var(--color-ink-muted);
  font-size: var(--text-eyebrow);
}

.thanks__title {
  margin-block-end: var(--space-sm);
  font-size: var(--text-h2);
}

.thanks__lead {
  margin-block-end: var(--space-md);
  font-size: var(--text-lead);
  line-height: var(--leading-body);
}

.thanks__ask {
  margin-block-end: var(--space-md);
}

/* --- Reveals (brief §8.1). base.css owns the states; --duration-slow and
   --reveal-shift/--reveal-stagger already carry the timing. --- */

@media (prefers-reduced-motion: reduce) {
  .sign-elem,
  .chime-elem,
  .swan-elem {
    animation: none;
  }
}
