/* prove-it.css — the prove-it slider's two panes + gold divider handle.
   Site-local clip-path slider (see prove-it.js for why, not createBeforeAfter).
   Instant, no transition on the clip/handle position — direct-manipulation
   drags that lag read as broken, not smooth (same principle the engine's own
   pointer-drive comment makes for createBeforeAfter).

   REDESIGN (2026-07-20, owner-ratified): the liquid feTurbulence/feDisplacement
   seam ribbon was "doing too much" — removed entirely. Restraint on the
   mechanism (a thin straight bar, idle-pulsing when not touched, still when
   it is); drama moved into the revealed content instead — see
   .prove-pane-handbuilt below for the motion ramp / tonal contrast / edge
   glow that replace it. */

.prove-slider {
  position: relative;
  width: 100%;
  aspect-ratio: 2.4 / 1;
  border: 1px solid var(--line);
  border-radius: 4px;
  overflow: hidden;
  margin-top: 26px;
  cursor: ew-resize;
  touch-action: pan-y;
  outline-offset: 3px;
}
.prove-slider:focus-visible { outline: 2px solid var(--gold-text); }
@media (max-width: 700px) {
  .prove-slider { aspect-ratio: 4 / 3; }
  /* Narrow phones: the pane's flex layout doesn't shrink this single-line,
     right-anchored label below its natural width (flex items default to
     min-width:auto), so at the default 50% cut the label's own left edge
     runs past the clip line and reads as truncated ("ELIER · PASADENA")
     instead of wrapping. Cap it to less than the visible half so it wraps
     onto two lines and stays clear of the clip at rest. */
  .prove-lab { max-width: 42%; }
}

.prove-pane { position: absolute; inset: 0; padding: clamp(20px, 3.5vw, 40px); overflow: hidden; }

/* Template pane — a tasteful parody of a generic template site. No real
   brand's design or copy reused. Sits as the base layer (unclipped); the
   hand-built pane is clipped over it, revealing this underneath on the left.
   Slightly desaturated/flattened (constant, not reveal-dependent) — the
   tonal half of this redesign's "drama in the content, not the mechanism"
   direction: the template side reads a shade duller next to the handbuilt
   side's full color, even before anyone touches the slider. */
.prove-pane-template { background: #ffffff; color: #333; font-family: Arial, Helvetica, sans-serif; filter: saturate(0.55) contrast(0.94); }
.prove-pane-template .prove-nav { display: flex; gap: 18px; font-size: 12px; color: #888; border-bottom: 1px solid #eee; padding-bottom: 10px; }
.prove-pane-template h4 { font-size: clamp(18px, 3vw, 28px); color: #2a6fd6; margin: 18px 0 8px; font-weight: 700; }
.prove-pane-template p { font-size: 13px; color: #777; max-width: 30ch; line-height: 1.5; }
.prove-btn-template {
  display: inline-block; margin-top: 14px; background: #2a6fd6; color: #fff;
  padding: 8px 16px; border-radius: 4px; font-size: 12px; font-family: Arial, Helvetica, sans-serif;
}
.prove-stock {
  margin-top: 18px; width: 120px; height: 70px;
  background: repeating-linear-gradient(45deg, #e8e8e8, #e8e8e8 8px, #f4f4f4 8px, #f4f4f4 16px);
  border-radius: 4px; display: grid; place-items: center; color: #aaa;
  font-size: 9px; letter-spacing: 0.1em; font-family: Arial, sans-serif;
}

/* Hand-built pane — the SITE'S OWN real tokens (Rule 11), not the mockup's
   Georgia/hardcoded hex. Clipped from the left; template shows through on
   the left of the handle, this shows on the right, per the caption
   ("made by hand →"), regardless of where the handle currently sits.

   Content is RIGHT-anchored (flex, align-items:flex-end, text-align:right)
   — not left-padded like the template pane. A left-anchored block sits
   exactly where inset(0 0 0 50%) clips it away at the default 50% position
   (found this the hard way: the pane rendered as a solid dark rectangle,
   no visible text, at first cut). Right-anchoring keeps the copy in the
   sliver that survives clipping across the 25/50/75% range this was
   verified at.

   --reveal-ramp (0–1, set by fx/prove-it.js's existing setCut() — no new
   per-frame loop) is 0 until the reveal fraction crosses ~0.6, then eases to
   1 at full reveal. It drives a small extra brightness/saturation lift on
   top of the constant baseline lift below, plus the sheen sweep further
   down — "our side comes alive as it's unveiled." Filter transition is
   short and only smooths the 4%-per-keystroke keyboard steps; pointer drags
   already fire setCut() many times a second, so this never reads as lag on
   the thing that actually matters (the clip/handle position itself, which
   stays untransitioned per the file-level rule above). */
.prove-pane-handbuilt {
  --reveal-ramp: 0;
  background: linear-gradient(160deg, #1c1712, #242019 55%, #2A2218);
  color: #EDE7D9;
  clip-path: inset(0 0 0 50%);
  display: flex; flex-direction: column; justify-content: center; align-items: flex-end;
  text-align: right;
  filter: saturate(calc(1.05 + var(--reveal-ramp) * 0.3)) brightness(calc(1.04 + var(--reveal-ramp) * 0.14));
  transition: filter 0.15s linear;
}
.prove-lab { font-family: var(--sans); font-size: 11px; letter-spacing: 0.24em; color: #B89968; text-transform: uppercase; }
.prove-pane-handbuilt h4 { font-family: var(--serif); font-weight: 500; font-size: clamp(20px, 3.6vw, 36px); line-height: 1.08; margin: 12px 0 8px; }
.prove-pane-handbuilt h4 em { font-style: italic; color: #B89968; }
.prove-pane-handbuilt p { font-family: var(--serif); color: #cdc3ac; max-width: 24ch; font-size: clamp(12px, 1.5vw, 15px); line-height: 1.5; }
.prove-btn-handbuilt {
  display: inline-block; margin-top: 16px; background: #B89968; color: #2A2218;
  padding: 10px 20px; border-radius: 4px; font-family: var(--sans); font-size: 11px;
  font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase;
}

/* World cycle (2026-07-20) — recorded loops of real engine scenes cycling
   behind the constant content above. Stacking (back to front, all explicit
   z-index so this never depends on DOM-order stacking quirks): base
   gradient (.prove-pane-handbuilt's own background, always there as an
   instant "poster" before/without video) -> video (0) -> scrim (1) ->
   comes-alive sheen (2, unchanged from before) -> content (3). */
.prove-world-video {
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transition: opacity 0.3s ease;
}
.prove-world-video.is-visible { opacity: 1; }

/* Constant dark scrim so the existing cream/gold text stays legible over
   EVERY world — including the bright Letterpress one, which would nearly
   white out this pane's light text without it. Same tone as the pane's own
   base gradient, so a world showing through reads as "seen through this
   pane's own glass," not a jarring foreign background. Never changes with
   --reveal-ramp or which world is playing — a constant, not a drama beat. */
.prove-world-scrim {
  position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(160deg, rgba(28, 23, 18, 0.82), rgba(36, 32, 25, 0.78) 55%, rgba(42, 34, 24, 0.85));
  pointer-events: none;
}

/* Small-cell dither texture for the world-to-world transition (fx/prove-it.js
   toggles .is-transitioning for ~600ms around a source swap) — a tileable,
   tiny (6x6px) black/gold speckle, opacity-animated so the swap reads as a
   grainy dissolve rather than a flat opacity crossfade. Purely decorative;
   skipped under reduced-motion (which never cycles worlds anyway). */
.prove-world-dither {
  position: absolute; inset: 0; z-index: 2;
  background-image:
    radial-gradient(circle at 1px 1px, rgba(247, 236, 216, 0.5) 0.6px, transparent 0.6px),
    radial-gradient(circle at 4px 3px, rgba(184, 153, 104, 0.45) 0.6px, transparent 0.6px);
  background-size: 6px 6px;
  opacity: 0;
  pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
  .prove-world-video.is-transitioning ~ .prove-world-dither { animation: proveDither 0.6s ease-in-out; }
}
@keyframes proveDither {
  0%, 100% { opacity: 0; }
  50% { opacity: 0.9; }
}

.prove-content { position: relative; z-index: 3; }

/* The "comes alive" sheen — a soft diagonal gold sweep, invisible until
   --reveal-ramp rises past 0 (i.e. reveal fraction > ~0.6), fading in as it
   climbs to 1. Purely decorative/ambient, so it's the one piece gated
   behind prefers-reduced-motion; the brightness/saturation lift above is a
   static color value tied to slider position (not autonomous motion) and
   stays for reduced-motion users. z-index 4 — above the world/scrim/dither
   layers (0-2) and the content (3), same as it swept over the text before
   the world-cycle feature existed. */
.prove-pane-handbuilt::before {
  content: '';
  position: absolute; inset: 0; z-index: 4;
  background: linear-gradient(115deg, transparent 30%, rgba(247, 236, 216, 0.16) 48%, transparent 66%);
  background-size: 220% 100%;
  background-position: 0 0;
  opacity: var(--reveal-ramp, 0);
  pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
  .prove-pane-handbuilt::before { animation: proveSheen 2.6s ease-in-out infinite; }
}
@keyframes proveSheen {
  0%, 100% { background-position: 100% 0; }
  50% { background-position: -20% 0; }
}

/* The gold divider + drag pill at the seam — a thin straight bar, full
   height, small grabbable handle. Idle pulse: a slow ~2s opacity breathe
   inviting the drag, paused (and forced solid) while actually being
   dragged or during the auto-preview sweep, since a moving pulse fighting a
   moving handle reads as noise, not feedback. Base opacity is 1 (solid) so
   reduced-motion users — who never get the animation — see a plain, fully
   legible bar, never stuck at the pulse's dim trough. */
.prove-handle {
  position: absolute; top: 0; bottom: 0; left: 50%; width: 2px;
  background: #B89968; z-index: 4; pointer-events: none;
  opacity: 1;
}
@media (prefers-reduced-motion: no-preference) {
  .prove-handle { animation: proveHandlePulse 2s ease-in-out infinite; }
}
@keyframes proveHandlePulse {
  0%, 100% { opacity: 0.6; }
  50% { opacity: 1; }
}
.prove-slider.is-dragging .prove-handle,
.prove-slider.is-sweeping .prove-handle {
  /* animation: none (not animation-play-state: paused) — a paused CSS
     animation freezes at whatever value the keyframe happened to be mid-
     breath, and an animated property always wins over a plain opacity
     declaration in the same rule regardless of specificity, so opacity:1
     below would otherwise lose to e.g. opacity:0.74 frozen mid-pulse.
     Removing the animation outright lets the static opacity apply cleanly
     — also a more deliberate "solid" feedback state than an arbitrary
     paused mid-tone, and resuming after (animation re-added) restarts the
     breathe fresh rather than resuming an odd phase. */
  animation: none;
  opacity: 1;
}
.prove-handle-pill {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  background: #B89968; color: #2A2218;
  font-family: var(--sans); font-size: 10px; font-weight: 700; letter-spacing: 0.08em;
  padding: 7px 10px; border-radius: 999px; white-space: nowrap;
}

/* Faint gold edge-glow trailing the divider onto the handbuilt side only —
   a soft, low-alpha gradient starting right at the bar's own right edge and
   fading out within ~46px. Always present at this same low intensity
   (not reveal-ramp-gated) — a constant, subtle marker of "this side is
   ours," not a dynamic effect competing with the sheen above. */
.prove-handle::after {
  content: '';
  position: absolute; top: 0; bottom: 0; left: 2px; width: 46px;
  background: linear-gradient(to right, rgba(184, 153, 104, 0.22), transparent);
  pointer-events: none;
}

/* Release-settle: applied only briefly (by fx/prove-it.js, on pointerup,
   only when released past ~85% reveal) so the clip/handle glide the rest of
   the way to full reveal instead of snapping. Everywhere else — including
   mid-drag — the file-level "no transition on position" rule stands. */
.prove-slider.is-settling .prove-pane-handbuilt { transition: clip-path 0.4s cubic-bezier(.2,.7,.3,1), filter 0.15s linear; }
.prove-slider.is-settling .prove-handle { transition: left 0.4s cubic-bezier(.2,.7,.3,1); }

/* Stat ticker + footnote beneath the slider. */
.prove-ticker {
  display: flex; flex-wrap: wrap; gap: 10px 20px; justify-content: center;
  margin-top: 22px; font-family: var(--sans);
}
.stat {
  border: 1px solid var(--line); background: var(--surface); border-radius: 6px;
  padding: 10px 18px; min-width: 10.5rem; text-align: center;
  transition: background-color 0.5s var(--ease), border-color 0.5s var(--ease);
}
.stat-k { display: block; font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.stat-v {
  display: block; font-size: 18px; font-weight: 700; color: var(--text);
  font-variant-numeric: tabular-nums; margin-top: 3px;
}
@media (prefers-reduced-motion: no-preference) { .stat-v { transition: color 0.2s var(--ease); } }
.stat-v.flip { color: var(--gold-text); }
.prove-footnote {
  margin-top: 14px; text-align: center; font-family: var(--serif); font-style: italic;
  font-size: 13px; color: var(--muted);
}
