/* Ansen — home page sections. */

/* ════════════ Hero ════════════ */
.section-hero {
  padding-block-start: clamp(var(--s-7), 8vw, var(--s-9));
  padding-block-end: 0;
  position: relative;
  overflow: hidden;
}

/* Static blueprint field — the only decorative layer. */
.section-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(var(--line-faint) 1px, transparent 1px),
    linear-gradient(90deg, var(--line-faint) 1px, transparent 1px);
  background-size: 64px 64px;
  background-position: center top;
  mask-image: linear-gradient(to bottom, #000 0%, transparent 78%);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 78%);
  opacity: 0.75;
}

.hero-inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(var(--s-6), 5vw, var(--s-8));
  align-items: center;
  min-block-size: clamp(24rem, 58vh, 34rem);
  padding-block-end: clamp(var(--s-7), 7vw, var(--s-9));
}

.hero-copy { max-width: 36rem; }

.hero-kicker { margin-bottom: var(--s-4); }

.hero-headline {
  font-size: var(--fs-display);
  font-weight: 600;
  line-height: var(--lh-tight);
  letter-spacing: -0.03em;
  margin-bottom: var(--s-4);
  max-width: 15ch;
}

html[dir="rtl"] .hero-headline {
  max-width: 18ch;
  letter-spacing: 0;
  line-height: 1.35;
}

.hero-lead {
  color: var(--text-2);
  font-size: var(--fs-lead);
  line-height: var(--lh-loose);
  max-width: 34rem;
  margin-bottom: var(--s-6);
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
}

/* ════════════ Blueprint hero ════════════
   A set of four product sheets that scribe themselves. Every stroke is a path
   with pathLength="1", so one dasharray drives the whole reveal, and the
   animations are scoped behind .is-active so each sheet replays on demand. */
.hero-blueprint {
  position: relative;
  isolation: isolate;
  margin: 0;
  inline-size: 100%;
  max-inline-size: 34rem;
  justify-self: center;
}

/* Sheet switcher — the same chip language as the catalogue filter bar. */
.bp-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-block-end: var(--s-4);
}

.bp-tab {
  display: inline-flex;
  align-items: baseline;
  gap: 0.45rem;
  border: var(--hair) solid var(--line);
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--text-3);
  padding: 0.4rem 0.85rem;
  min-height: 36px;
  cursor: pointer;
  font-family: var(--font-display);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.02em;
  transition: all var(--dur-2) var(--ease);
}

.bp-tab:hover {
  color: var(--text-1);
  border-color: var(--line-strong);
}

.bp-tab.is-on {
  background: var(--accent-soft);
  border-color: var(--accent-line);
  color: var(--accent-ink);
}

.bp-tab:focus-visible { outline-offset: 2px; }
.bp-tab-num { opacity: 0.6; font-variant-numeric: tabular-nums; }

/* Without the rotator the tabs would be dead controls. */
html:not(.js) .bp-tabs { display: none; }

/* Four sheets share one box, so the hero height never re-resolves. */
.bp-stack {
  display: grid;
  grid-template: "sheet" / 1fr;
  aspect-ratio: 13 / 10;
}

.bp-sheet {
  grid-area: sheet;
  display: block;
  inline-size: 100%;
  block-size: 100%;
  overflow: visible;
}

/* visibility, not opacity: a hidden sheet must not paint half-drawn on either
   edge of a switch, and it must contribute no hit area. */
.bp-sheet:not(.is-active) { visibility: hidden; }

.hero-blueprint::before {
  content: "";
  position: absolute;
  inset: -14%;
  z-index: -1;
  pointer-events: none;
  background-image:
    linear-gradient(var(--line-faint) 1px, transparent 1px),
    linear-gradient(90deg, var(--line-faint) 1px, transparent 1px);
  background-size: 28px 28px;
  mask-image: radial-gradient(closest-side, #000 45%, transparent 92%);
  -webkit-mask-image: radial-gradient(closest-side, #000 45%, transparent 92%);
  opacity: 0.55;
  animation: bp-drift 30s linear infinite;
}

.hero-blueprint path,
.hero-blueprint circle {
  fill: none;
  stroke: var(--text-3);
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.hero-blueprint .bp-faint {
  stroke: color-mix(in srgb, var(--text-3) 45%, transparent);
  stroke-width: 1.1;
}

.hero-blueprint .bp-rib {
  stroke: color-mix(in srgb, var(--text-3) 65%, transparent);
  stroke-width: 1.2;
}

/* Welded-mesh intersections: zero-length subpaths + round caps read as dots. */
.hero-blueprint .bp-weld {
  stroke: var(--accent);
  stroke-width: 3.4;
}

.hero-blueprint .bp-dim { stroke: var(--accent); stroke-width: 1; }
.hero-blueprint .bp-accent { stroke: var(--accent); stroke-width: 2; }

.hero-blueprint .bp-centreline {
  stroke: color-mix(in srgb, var(--text-3) 55%, transparent);
  stroke-width: 0.9;
}

.hero-blueprint .bp-text {
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.08em;
  fill: var(--text-3);
  direction: ltr;
  unicode-bidi: isolate;
}

.hero-blueprint .bp-text-lg { font-size: 14px; fill: var(--text-2); }
.hero-blueprint .bp-text-strong { fill: var(--accent-ink); font-weight: 600; }

/* Replay by scoping: an animation exists only while its sheet is active, so
   dropping .is-active destroys it and re-adding starts from frame 0 — no forced
   reflow anywhere. The base state below is deliberately *undrawn*; never move an
   `animation` onto bare .bp-draw, or all four sheets play once at load and the
   switcher becomes a no-op. Longhands, not the shorthand, so the .bp-dN / .bp-fN
   delay table below still applies to them. */
.bp-draw {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}

.bp-fade { opacity: 0; }

.bp-sheet.is-active .bp-draw {
  animation-name: bp-scribe;
  animation-duration: 1.1s;
  animation-timing-function: var(--ease);
  animation-fill-mode: forwards;
}

.bp-sheet.is-active .bp-fade {
  animation-name: bp-appear;
  animation-duration: 0.6s;
  animation-timing-function: var(--ease);
  animation-fill-mode: forwards;
}

/* ---- one ambient motion per sheet, each specific to the product ---- */

/* 01 · the rib pattern marches along the bar; each rib carries its own --i. */
.bp-sheet.is-active .bp-march {
  animation: bp-march 2.6s var(--ease) infinite;
  animation-delay: calc(2.3s + var(--i) * 0.13s);
}

/* 02 · a section line scanned across the profile. */
.hero-blueprint .bp-scan {
  stroke: var(--accent);
  stroke-width: 1.2;
  opacity: 0.5;
  transform-box: view-box;
}

.bp-sheet.is-active .bp-scan {
  animation: bp-scan 7s var(--ease) infinite;
  animation-delay: 2.4s;
}

/* 03 · the ERW weld travelling down the pipe. */
.hero-blueprint .bp-seam {
  stroke: var(--accent);
  stroke-width: 1.2;
  stroke-dasharray: 6 14;
  opacity: 0.85;
}

.bp-sheet.is-active .bp-seam {
  animation: bp-seam 5s linear infinite;
  animation-delay: 2.4s;
}

/* 04 · the load path alternating between the two brace directions. */
.hero-blueprint .bp-load {
  stroke: color-mix(in srgb, var(--text-3) 70%, transparent);
  stroke-width: 1.6;
  opacity: 0.55;
}

.bp-sheet.is-active .bp-load { animation: bp-load 8s var(--ease) infinite; }
.bp-sheet.is-active .bp-load-b { animation-delay: 4s; }

@keyframes bp-scribe { to { stroke-dashoffset: 0; } }
@keyframes bp-appear { to { opacity: 1; } }
@keyframes bp-drift { to { background-position: 28px 28px; } }
@keyframes bp-march { 0%, 100% { opacity: 0.3; } 45% { opacity: 1; } }
@keyframes bp-scan { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(110px); } }
@keyframes bp-seam { to { stroke-dashoffset: -40; } }
@keyframes bp-load { 0%, 100% { opacity: 0.18; } 40%, 60% { opacity: 1; } }

/* Stagger: geometry first, then dimensions, then labels. */
.bp-d1 { animation-delay: 0.05s; }
.bp-d2 { animation-delay: 0.35s; }
.bp-d3 { animation-delay: 0.65s; }
.bp-d4 { animation-delay: 0.95s; }
.bp-d5 { animation-delay: 1.15s; }
.bp-d6 { animation-delay: 1.45s; }
.bp-d7 { animation-delay: 1.65s; }
.bp-d8 { animation-delay: 1.85s; }
.bp-d9 { animation-delay: 2.05s; }
.bp-d10 { animation-delay: 2.25s; }

.bp-f1 { animation-delay: 1.25s; }
.bp-f2 { animation-delay: 1.35s; }
.bp-f3 { animation-delay: 1.80s; }
.bp-f4 { animation-delay: 2.30s; }
.bp-f9 { animation-delay: 2.60s; }

/* Stat rail — one band, hairline-divided, not four floating cards. */
.stats-strip {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-block-start: var(--hair) solid var(--line);
}

.stat-item {
  padding: var(--s-6) var(--s-5);
  border-inline-start: var(--hair) solid var(--line-faint);
  text-align: start;
}

.stat-item:first-child {
  border-inline-start: 0;
  padding-inline-start: 0;
}

.stat-item .num {
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 3vw, 2.25rem);
  font-weight: 600;
  line-height: 1.1;
  color: var(--text-1);
  letter-spacing: -0.02em;
  /* The counter repaints this text ~85 times a second; equal-width digits
     keep the "+" from twitching while it rolls. */
  font-variant-numeric: tabular-nums;
}

.stat-item .num-text {
  font-size: clamp(1.05rem, 1.8vw, 1.3rem);
  line-height: 1.3;
  padding-block-start: 0.35rem;
}

/* A "45000+" inside an RTL paragraph is a run of weak characters: the + is a
   bidi neutral, so the algorithm parks it at the other end of the digits and
   the stat reads "20155…+". The block's own base direction keeps it typed. */
.stat-item .num:not(.num-text) { direction: ltr; }

/* …without moving the number: an LTR block resolves text-align:start to the
   left, and this rail is mirrored in Arabic. */
html[dir="rtl"] .stat-item .num:not(.num-text) { text-align: right; }

.stat-item .label {
  margin-top: var(--s-2);
  font-size: var(--fs-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-3);
}

html[dir="rtl"] .stat-item .label { text-transform: none; letter-spacing: 0; }

/* Client proof strip — marks, not a fifth stat. */
.proof {
  /* .section-hero paints an absolute grid field over its content; anything in
     the hero that must stay legible has to opt above it, like .stats-strip. */
  position: relative;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3) var(--s-6);
  padding-block: var(--s-5) var(--s-6);
  border-block-start: var(--hair) solid var(--line-faint);
}

.proof-label {
  font-size: var(--fs-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-3);
}

html[dir="rtl"] .proof-label { text-transform: none; letter-spacing: 0; }

/* Wraps rather than scrolls: a horizontal rail would meet the RTL overflow
   landmine and hide the spill from layout checks. */
.proof-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-4) var(--s-6);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* A fit derivative of a square logo lands square, so height alone drives the
   box — at 34px an emblem reads as a smudge. The paper plate is what
   .client-logo img does for the same reason: a transparent logo is dark art. */
.proof-mark {
  display: block;
  inline-size: auto;
  block-size: 44px;
  max-inline-size: 132px;
  object-fit: contain;
  background: var(--paper);
  border: var(--hair) solid var(--line);
  border-radius: var(--r-xs);
}

.proof-name {
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--text-2);
}

/* ════════════ About ════════════ */
.section-about { padding-block-end: var(--section-pad-sm); }

.about-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: clamp(var(--s-6), 6vw, var(--s-9));
  align-items: start;
}

.about-text p {
  color: var(--text-2);
  line-height: var(--lh-loose);
}

.about-text p + p { margin-top: var(--s-4); }

.about-facts {
  display: flex;
  flex-direction: column;
  border: var(--hair) solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface-1);
  overflow: hidden;
}

.about-fact {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr);
  gap: var(--s-3);
  align-items: start;
  padding: var(--s-4) var(--s-5);
  border-bottom: var(--hair) solid var(--line-faint);
}

.about-fact:last-child { border-bottom: 0; }

.about-fact .ui-icon {
  inline-size: 18px;
  block-size: 18px;
  margin-top: 0.15rem;
  color: var(--accent-ink);
}

.about-fact dt {
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text-1);
}

.about-fact dd {
  font-size: var(--fs-sm);
  color: var(--text-3);
  margin-top: 0.1rem;
}

/* ════════════ Process ════════════ */
.process-steps {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s-5);
  border-block-start: var(--hair) solid var(--line);
}

.process-step {
  padding-block-start: var(--s-5);
  position: relative;
}

.step-num {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 3vw, 2.25rem);
  font-weight: 600;
  line-height: 1;
  color: var(--text-1);
  letter-spacing: -0.02em;
  margin-bottom: var(--s-4);
  position: relative;
  padding-bottom: var(--s-3);
}

.step-num::after {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  inset-block-end: 0;
  inline-size: 28px;
  block-size: 2px;
  background: var(--accent);
}

.process-step h3 {
  font-size: var(--fs-body);
  font-weight: 600;
  margin-bottom: var(--s-2);
}

.process-step p {
  font-size: var(--fs-sm);
  color: var(--text-3);
  line-height: var(--lh-body);
}

/* ════════════ Booking ════════════ */
.section-booking {
  background: var(--ink-2);
  border-block: var(--hair) solid var(--line);
}

/* Home CTA band — the form itself lives on /booking/. */
.booking-teaser {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: clamp(var(--s-6), 5vw, var(--s-8));
  align-items: center;
  background: var(--surface-1);
  border: var(--hair) solid var(--line-strong);
  border-inline-start: 3px solid var(--accent);
  border-radius: var(--r-md);
  padding: clamp(var(--s-6), 4vw, var(--s-8));
}

.booking-teaser .section-title { margin-bottom: var(--s-3); }

.booking-teaser .section-sub {
  color: var(--text-2);
  margin: 0;
  max-inline-size: 56ch;
}

.booking-teaser-actions {
  display: grid;
  gap: var(--s-3);
  justify-items: stretch;
  max-inline-size: 19rem;
  margin-inline-start: auto;
}

@media (max-width: 860px) {
  .booking-teaser { grid-template-columns: minmax(0, 1fr); }
  .booking-teaser-actions { max-inline-size: none; margin-inline-start: 0; }
}

.booking-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: clamp(var(--s-6), 5vw, var(--s-8));
  align-items: start;
}

.booking-aside h2 {
  font-size: var(--fs-h3);
  margin-bottom: var(--s-4);
}

.booking-steps {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  margin-bottom: var(--s-6);
}

.booking-step {
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr);
  gap: var(--s-3);
  align-items: start;
  padding-bottom: var(--s-4);
  border-bottom: var(--hair) solid var(--line-faint);
}

.booking-step:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}

.booking-step-idx {
  font-family: var(--font-display);
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--accent-ink);
  padding-top: 0.15rem;
}

.booking-step strong {
  display: block;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text-1);
  margin-bottom: 0.15rem;
}

.booking-step span {
  font-size: var(--fs-sm);
  color: var(--text-3);
  line-height: var(--lh-body);
}

.booking-direct {
  font-size: var(--fs-sm);
  color: var(--text-3);
  padding-top: var(--s-4);
  border-top: var(--hair) solid var(--line-faint);
}

.booking-direct a {
  color: var(--accent-ink);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--accent-line);
}

/* ════════════ Contact ════════════ */
.contact-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: clamp(var(--s-5), 4vw, var(--s-7));
  align-items: start;
}

.contact-intro {
  color: var(--text-3);
  font-size: var(--fs-sm);
  margin-bottom: var(--s-5);
}

.contact-channels {
  display: flex;
  flex-direction: column;
  gap: 0;
  border-block: var(--hair) solid var(--line);
}

.channel-btn {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-4) var(--s-2);
  border-bottom: var(--hair) solid var(--line-faint);
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--text-1);
  transition: color var(--dur-2) var(--ease), padding-inline-start var(--dur-2) var(--ease);
}

.channel-btn:last-child { border-bottom: 0; }

.channel-btn:hover {
  color: var(--accent-ink);
  padding-inline-start: var(--s-4);
}

.channel-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 30px;
  block-size: 30px;
  flex-shrink: 0;
  border-radius: var(--r-xs);
  background: var(--surface-1);
  border: var(--hair) solid var(--line);
  color: var(--text-2);
}

.channel-btn:hover .channel-icon {
  border-color: var(--accent-line);
  color: var(--accent-ink);
}

.channel-btn.wa { color: var(--success-ink); }

.channel-btn.wa .channel-icon {
  color: var(--success-ink);
  border-color: var(--success-line);
  background: var(--success-soft);
}

.contact-place {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  block-size: 100%;
}

.contact-place .map-frame {
  flex: 1;
  display: grid;
}

.contact-place .map-frame iframe {
  inline-size: 100%;
  block-size: 100%;
  min-block-size: 300px;
  border: 0;
  display: block;
}

.contact-place .location-card {
  flex: 1;
  align-items: center;
}

.map-frame {
  position: relative;
  border: var(--hair) solid var(--line);
  border-radius: var(--r-sm);
  overflow: hidden;
  background-color: var(--surface-2);
  /* The iframe paints late (or never, offline). A grid underneath keeps the
     slot reading as a map rather than as a broken embed. */
  background-image:
    linear-gradient(var(--line-faint) 1px, transparent 1px),
    linear-gradient(90deg, var(--line-faint) 1px, transparent 1px);
  background-size: 24px 24px;
}

.map-frame::after {
  content: "";
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  translate: -50% -50%;
  inline-size: 14px;
  block-size: 14px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 6px var(--accent-soft);
  z-index: 0;
}

.map-frame iframe {
  position: relative;
  z-index: 1;
  inline-size: 100%;
  block-size: 320px;
  border: 0;
  display: block;
}

.location-card {
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr);
  gap: var(--s-4);
  align-items: start;
  padding: var(--s-5);
  border: var(--hair) solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface-1);
}

.location-card-icon {
  display: inline-grid;
  place-items: center;
  inline-size: 32px;
  block-size: 32px;
  color: var(--accent-ink);
}

.location-card-label {
  font-family: var(--font-display);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: var(--tr-kicker);
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: var(--s-2);
}

html[dir="rtl"] .location-card-label { text-transform: none; letter-spacing: 0; }

.location-card-body p {
  color: var(--text-2);
  margin-bottom: var(--s-4);
  line-height: var(--lh-body);
}

/* ════════════ Responsive ════════════ */
@media (max-width: 1040px) {
  .hero-inner { grid-template-columns: minmax(0, 1fr); }
  .hero-blueprint { max-inline-size: 30rem; margin-block-start: var(--s-5); }
  .booking-grid { grid-template-columns: minmax(0, 1fr); }
  .contact-grid { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 860px) {
  .about-grid { grid-template-columns: minmax(0, 1fr); }
  .process-steps { grid-template-columns: repeat(2, 1fr); }
  .stats-strip { grid-template-columns: repeat(2, 1fr); }

  .stat-item {
    padding-inline: var(--s-4);
    border-block-start: var(--hair) solid var(--line-faint);
  }

  .stat-item:nth-child(odd) { border-inline-start: 0; padding-inline-start: 0; }
  .stat-item:nth-child(-n+2) { border-block-start: 0; }
}

@media (max-width: 620px) {
  .hero-headline { font-size: clamp(2rem, 9vw, 2.5rem); }
  .hero-actions .btn { inline-size: 100%; }
  .hero-blueprint { max-inline-size: 24rem; }
  .process-steps { grid-template-columns: minmax(0, 1fr); gap: var(--s-4); }
  .section-head { grid-template-columns: minmax(0, 1fr); }
  .section-sub { justify-self: start; }
  .card-actions { flex-direction: column; align-items: stretch; }
  .card-actions .quote-btn { margin-inline-start: 0; }
  .proof { padding-block-end: var(--s-5); }
  .proof-strip { gap: var(--s-4) var(--s-5); }
  .proof-mark { block-size: 40px; max-inline-size: 112px; }
}

/* Reduced motion: the drawing is shown complete, never mid-stroke. */
@media (prefers-reduced-motion: reduce) {
  .hero-blueprint::before { animation: none; }

  /* The drawing is shown complete and stays complete; the ambient motions
     simply do not run. These must carry the .is-active prefix to win — the rules
     that install the animations use the same specificity and come earlier. */
  .bp-sheet.is-active .bp-draw,
  .bp-sheet.is-active .bp-fade {
    animation: none;
    stroke-dashoffset: 0;
    opacity: 1;
  }

  .bp-sheet.is-active .bp-march,
  .bp-sheet.is-active .bp-seam,
  .bp-sheet.is-active .bp-load { animation: none; }

  .hero-blueprint .bp-scan { display: none; }
}
