/* Före och efter — the draggable comparison sliders.
   ==================================================================
   Its OWN file rather than a block in home.css, because the CMS row at
   /admin/cms/fore-efter renders the SAME markup as the public card and has to
   look identical to it. A preview that is a re-implementation is a preview you
   cannot trust: the editor aligns two roofs against admin CSS and ships
   something else. Both pages link this file; nothing else may restyle .ba-*.

   The whole animation is one custom property: JS sets --ba-pos and CSS does
   the rest through clip-path. Nothing here reads layout per frame, so dragging
   costs a style recalc on one element rather than a reflow of the card. */

.ba-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-5);
}

.ba-card {
  background: var(--surface-card);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-card);
}

.ba-frame {
  position: relative;
  /* 16:9, matching the subject rather than the camera. A roof photographed
     from the ground is a wide, shallow subject, and a 4:3 frame spent the
     extra height on driveway and sky. The wide frame also gives the wipe more
     horizontal travel per pixel of card, which is the gesture the section
     exists for. */
  aspect-ratio: 16 / 9;
  overflow: hidden;
  cursor: ew-resize;
  /* Horizontal drags belong to the slider, vertical scrolling still belongs to
     the page. Without this the section is a scroll trap on a phone: every
     attempt to scroll past it moves the handle instead. */
  touch-action: pan-y;
  -webkit-user-select: none;
  user-select: none;
  /* The starting position, and the value the no-JS state keeps. */
  --ba-pos: 50%;
}

.ba-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  /* The images are decorative to the pointer: only the range input should ever
     receive the drag, and a native image drag would cancel it mid-gesture. */
  -webkit-user-drag: none;
  pointer-events: none;
}

/* The "before" half, clipped from the right edge inward. */
.ba-clip {
  position: absolute;
  inset: 0;
  clip-path: inset(0 calc(100% - var(--ba-pos)) 0 0);
}

.ba-tag {
  position: absolute;
  top: var(--sp-4);
  font: 600 12px/1 var(--font-body);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 7px 11px;
  border-radius: var(--radius-pill);
  pointer-events: none;
}

.ba-tag--before {
  left: var(--sp-4);
  background: rgba(16, 24, 32, 0.82);
  color: #fff;
}

.ba-tag--after {
  right: var(--sp-4);
  background: rgba(255, 255, 255, 0.92);
  color: var(--ink-900);
}

.ba-divider {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--ba-pos);
  width: 2px;
  background: rgba(255, 255, 255, 0.9);
  transform: translateX(-1px);
  pointer-events: none;
}

.ba-handle {
  position: absolute;
  top: 50%;
  left: var(--ba-pos);
  width: 44px;
  height: 44px;
  margin: -22px 0 0 -22px;
  border-radius: 50%;
  background: var(--paper-0);
  box-shadow: 0 2px 10px rgba(16, 24, 32, 0.28);
  display: grid;
  place-items: center;
  color: var(--ink-900);
  pointer-events: none;
}

/* The real control, stretched over the whole frame and made invisible.
   It stays in the accessibility tree and the tab order — this is what carries
   keyboard support, and what makes the component work with JS disabled. */
.ba-range {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: ew-resize;
}

/* Focus has to be visible on the chrome, since the input itself is
   transparent. Keyboard users get the same ring as every other control. */
.ba-range:focus-visible ~ .ba-handle {
  box-shadow: var(--focus-ring), 0 2px 10px rgba(16, 24, 32, 0.28);
}

.ba-cap {
  margin: 0;
  padding: var(--sp-4) var(--sp-5) var(--sp-5);
  font: var(--body-md);
  color: var(--text-body);
}

.ba-cap b {
  color: var(--ink-900);
}

/* The one-time hint: the handle drifts a few percent and settles back when the
   card first scrolls into view, so it reads as draggable without a label
   saying so. Driven by a class the script adds, and the transition below is
   the only thing that makes it a movement rather than a jump. */
.ba-frame--hinting .ba-clip,
.ba-frame--hinting .ba-divider,
.ba-frame--hinting .ba-handle {
  transition: clip-path 620ms var(--ease), left 620ms var(--ease);
}

@media (prefers-reduced-motion: reduce) {
  /* Not just "no transition" — before-after.js skips the hint entirely. This
     is the belt to that braces, in case the class is ever applied elsewhere. */
  .ba-frame--hinting .ba-clip,
  .ba-frame--hinting .ba-divider,
  .ba-frame--hinting .ba-handle {
    transition: none;
  }
}

@media (max-width: 860px) {
  .ba-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}
