/* ==========================================================================
   Before / after compare
   --------------------------------------------------------------------------
   Two screenshots of the same screen, one revealed over the other.

   The control is a real <input type="range">. It is not decoration over a
   div with a drag listener: it is the actual input, so it is keyboard
   operable, announced by assistive technology, and focusable, for free.
   Pointer dragging on the image writes to the same input, so both routes
   drive one source of truth.

   Both images are always in the DOM with real alt text. A screen reader
   user gets both descriptions regardless of where the handle sits.

   Without JavaScript the two images stack, each under its own label, and
   the range is not shown. Enhanced styling is scoped to .compare--enhanced,
   which script adds. Nothing here needs JavaScript to be readable.

   Semantic tokens only.
   ========================================================================== */

.compare {
  margin-block: var(--space-stack-xl);
}

/* --------------------------------------------------------------------------
   Baseline: no JavaScript. Two labelled images, stacked.
   -------------------------------------------------------------------------- */

.compare__viewport {
  display: grid;
  gap: var(--space-stack-lg);
}

.compare__pane {
  margin: var(--space-none);
  min-width: 0;
}

.compare__label {
  display: block;
  margin-block-end: var(--space-stack-2xs);
  font-family: var(--type-label-font);
  font-size: var(--type-label-size);
  font-weight: var(--type-label-weight);
  line-height: var(--type-label-leading);
  letter-spacing: var(--type-label-tracking);
  text-transform: var(--type-label-transform);
  color: var(--text-muted);
}

.compare__img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-media);
  border: var(--border-width-default) solid var(--border-container);
  background-color: var(--surface-subtle);
}

.compare__control {
  display: none;
}

.compare__caption {
  margin-block-start: var(--space-stack-md);
  max-width: var(--measure-narrow);
  font-family: var(--type-caption-font);
  font-size: var(--type-caption-size);
  font-weight: var(--type-caption-weight);
  line-height: var(--type-caption-leading);
  letter-spacing: var(--type-caption-tracking);
  color: var(--text-muted);
}

/* --------------------------------------------------------------------------
   Enhanced: the panes overlay, the after pane is clipped, the range drives it.
   -------------------------------------------------------------------------- */

.compare--enhanced .compare__viewport {
  position: relative;
  display: block;
  aspect-ratio: var(--compare-ratio);
  overflow: hidden;
  border-radius: var(--radius-media);
  border: var(--border-width-default) solid var(--border-container);
  background-color: var(--surface-subtle);
  cursor: ew-resize;
  /* Vertical scrolling still belongs to the page; horizontal drag is ours. */
  touch-action: pan-y;
}

.compare--enhanced .compare__pane {
  position: absolute;
  inset: 0;
}

/* The two panes tile rather than overlap: before owns 0 to the handle, after
   owns the handle to 100. They have to be clipped as a pair.

   Clipping only the after pane looks correct on the image, because the before
   pane is simply covered up. It is not correct for anything drawn on top of
   the before pane: its label is still painted over an image it no longer
   describes, and at position 0 the page shows a fully revealed after image
   still wearing a "Before" chip. Clipping both makes each label disappear
   with the pane it belongs to, which is the behaviour that was already
   correct on the after side by accident.

   The panes are absolutely positioned to the same box, so the two insets
   resolve against identical geometry and meet exactly. The divider sits on
   the seam and is wider than a pixel, so any sub-pixel rounding is covered. */
.compare--enhanced .compare__pane--before {
  clip-path: inset(0 calc(100% - var(--compare-pos) * 1%) 0 0);
}

.compare--enhanced .compare__pane--after {
  clip-path: inset(0 0 0 calc(var(--compare-pos) * 1%));
}

.compare--enhanced .compare__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top left;
  border: var(--border-width-none);
  border-radius: var(--radius-media);
}

/* The labels become chips pinned to the outer corners, so each one sits over
   the pane it names no matter where the handle is. */
.compare--enhanced .compare__label {
  position: absolute;
  z-index: var(--layer-raised);
  inset-block-start: var(--space-inset-sm);
  margin-block-end: var(--space-none);
  padding: var(--space-inset-2xs) var(--space-inset-xs);
  border-radius: var(--radius-pill);
  background-color: var(--surface-inverse);
  color: var(--text-on-inverse);
}

.compare--enhanced .compare__pane--before .compare__label {
  inset-inline-start: var(--space-inset-sm);
}

.compare--enhanced .compare__pane--after .compare__label {
  inset-inline-end: var(--space-inset-sm);
}

/* --------------------------------------------------------------------------
   The divider. Decorative: the range is the control, so this is aria-hidden
   and never receives pointer events.
   -------------------------------------------------------------------------- */

.compare__divider {
  display: none;
}

.compare--enhanced .compare__divider {
  display: block;
  position: absolute;
  z-index: var(--compare-divider-layer);
  inset-block: 0;
  inset-inline-start: calc(var(--compare-pos) * 1%);
  width: var(--border-width-accent);
  transform: translateX(-50%);
  background-color: var(--surface-accent);
  pointer-events: none;
}

.compare__divider::after {
  content: "";
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  translate: -50% -50%;
  inline-size: var(--control-handle-size);
  block-size: var(--control-handle-size);
  border-radius: var(--radius-pill);
  background-color: var(--surface-accent);
  box-shadow: var(--elevation-raised);
}

/* Focus lives on the range, but the divider is what the eye is on, so mirror
   the ring there too. Both are visible; neither replaces the other. */
.compare--enhanced:has(.compare__range:focus-visible) .compare__divider::after {
  outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
  outline-offset: var(--focus-ring-offset);
}

/* --------------------------------------------------------------------------
   The control itself.
   -------------------------------------------------------------------------- */

.compare--enhanced .compare__control {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-inline-sm);
  margin-block-start: var(--space-stack-md);
}

.compare__control-label {
  font-family: var(--type-label-font);
  font-size: var(--type-label-size);
  font-weight: var(--type-label-weight);
  line-height: var(--type-label-leading);
  letter-spacing: var(--type-label-tracking);
  text-transform: var(--type-label-transform);
  color: var(--text-secondary);
}

.compare__range {
  flex: 1 1 var(--layout-content-max);
  min-inline-size: 0;
  /* Give the input a real height rather than letting it collapse onto a track
     that is 2px tall in Direction B. The track stays thin; the hit area does
     not. WCAG 2.5.8 wants 24px minimum and every direction's handle token
     clears that. */
  block-size: var(--control-handle-size);
  margin: var(--space-none);
  background: none;
  -webkit-appearance: none;
  appearance: none;
}

.compare__range:focus-visible {
  outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
  outline-offset: var(--focus-ring-offset);
  border-radius: var(--radius-focus);
}

/* Track and thumb need vendor pseudo-elements. There is no shorthand that
   covers both engines, so the declarations are duplicated rather than
   grouped: one invalid selector in a list would drop the whole rule.

   These use physical width and height rather than the logical inline-size and
   block-size used everywhere else in this file. Logical property support on
   vendor-prefixed slider pseudo-elements is inconsistent, and where it is not
   supported the thumb collapses to nothing with no other symptom. The page has
   no writing-mode variation, so nothing is lost by being literal here. */

.compare__range::-webkit-slider-runnable-track {
  height: var(--control-track-height);
  border-radius: var(--radius-pill);
  background-color: var(--border-subtle);
}

.compare__range::-moz-range-track {
  height: var(--control-track-height);
  border-radius: var(--radius-pill);
  background-color: var(--border-subtle);
}

.compare__range::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: var(--control-handle-size);
  height: var(--control-handle-size);
  /* Centre the thumb on the track rather than hanging it below. */
  margin-top: calc((var(--control-track-height) - var(--control-handle-size)) / 2);
  border: var(--border-width-none);
  border-radius: var(--radius-pill);
  background-color: var(--surface-accent);
  box-shadow: var(--elevation-raised);
  cursor: ew-resize;
}

.compare__range::-moz-range-thumb {
  width: var(--control-handle-size);
  height: var(--control-handle-size);
  border: var(--border-width-none);
  border-radius: var(--radius-pill);
  background-color: var(--surface-accent);
  box-shadow: var(--elevation-raised);
  cursor: ew-resize;
}
