/* ==========================================================================
   INSAMEVISION — the technical layer

   Visual grammar borrowed selectively from the ERCN / BlackGrid spatial work:
   graphite ground, hairline geometry, mono metadata, coordinate language.
   Used sparingly and never decoratively — every label on screen corresponds
   to something the scene is actually doing.

   The scroll story is a `position: sticky` stage inside a tall track. JS
   writes exactly two things: `--p` (0→1 across the track) and `data-stage`
   (1→6). Everything below is CSS reacting to those.
   ========================================================================== */

.vision {
  --p: 0;
  background: var(--near-black);
  color: var(--ivory);
  position: relative;
}

/* The seam into the dark environment. A hard cut reads as a different
   website; a 60vh gradient wedge reads as descending into another layer. */
.vision__seam {
  height: clamp(18vh, 26vh, 30vh);
  background: linear-gradient(to bottom, var(--ivory), var(--near-black));
}
.vision__seam--up {
  background: linear-gradient(to bottom, var(--near-black), var(--ivory));
}

.vision__intro { padding-block: clamp(3rem, 8vh, 6rem) clamp(4rem, 10vh, 8rem); }
.vision__intro .lead { color: var(--stone-dim); }

.vision__attrib {
  display: inline-flex;
  align-items: center;
  gap: .7rem;
  margin-top: 2.25rem;
  padding: .55rem 1rem;
  border: 1px solid var(--rule-dark);
  border-radius: 999px;
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--stone-dim);
}
.vision__attrib .dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--bronze-light);
  box-shadow: 0 0 0 3px rgba(193, 156, 109, .16);
}

/* --------------------------------------------------------------------------
   Pinned track
   -------------------------------------------------------------------------- */

.vscene { position: relative; }
.vscene__track { height: 600vh; }          /* six stages, one viewport each */
.vscene__pin {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  display: grid;
  place-items: center;
}

/* Faint coordinate field — the environment the captured room sits inside. */
.vscene__pin::before {
  content: "";
  position: absolute;
  inset: -10%;
  background-image:
    linear-gradient(rgba(245, 242, 235, .045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(245, 242, 235, .045) 1px, transparent 1px);
  background-size: 88px 88px;
  -webkit-mask-image: radial-gradient(ellipse 70% 60% at 50% 50%, #000, transparent 78%);
  mask-image: radial-gradient(ellipse 70% 60% at 50% 50%, #000, transparent 78%);
  opacity: calc(.25 + var(--p) * .75);
  transform: translate3d(0, calc(var(--p) * -40px), 0);
  transition: opacity .6s linear;
}

.vscene__inner {
  position: relative;
  width: 100%;
  max-width: 1180px;                 /* narrower than the page shell: the plate
                                        and its reading should sit together, not
                                        at opposite edges of a 1440 grid */
  padding-inline: var(--gutter);
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: clamp(2rem, 5vw, 4.5rem);
}

/* --------------------------------------------------------------------------
   The captured room

   Held at a fixed size so it genuinely stays anchored while the copy and the
   overlays change around it — that stillness is what sells "one room, many
   readings". Source photography caps at 1440px wide, so the plate is capped
   well below full-bleed to stay crisp on retina.
   -------------------------------------------------------------------------- */

.vroom {
  position: relative;
  width: min(46vh, 42vw);
  aspect-ratio: 3 / 4;
  justify-self: start;
  background: #0b0b09;
  overflow: hidden;
  box-shadow: 0 40px 90px -30px rgba(0, 0, 0, .75);
}

.vroom__img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  /* Stage 1 shows the room as photographed. Stages 2–3 pull it toward the
     capture treatment: cooler, flatter, read as data rather than décor. */
  filter: saturate(var(--sat, 1)) contrast(var(--con, 1)) brightness(var(--bri, 1));
  transition: filter 1s var(--e-soft), transform 1.4s var(--e-out);
  transform: scale(var(--scale, 1));
}

/* Graphite wash that arrives with the capture stages. */
.vroom__wash {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(20, 26, 32, .55), rgba(12, 16, 20, .68));
  opacity: var(--wash, 0);
  transition: opacity 1s var(--e-soft);
  pointer-events: none;
}

.vroom__svg {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  pointer-events: none;
  overflow: visible;
}

/* ---- geometry primitives ---- */

.g-trace {
  fill: none;
  stroke: var(--bronze-light);
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
  stroke-dasharray: var(--len, 2000);
  stroke-dashoffset: var(--len, 2000);
  opacity: .9;
}
.g-anchor { stroke: var(--bronze-light); stroke-width: 2; fill: none; vector-effect: non-scaling-stroke; opacity: 0; }
.g-region { fill: rgba(193, 156, 109, .1); stroke: rgba(193, 156, 109, .5); stroke-width: 1; vector-effect: non-scaling-stroke; opacity: 0; }
.g-tag {
  font-family: var(--mono);
  font-size: 26px;
  letter-spacing: .13em;
  fill: var(--ivory);
  opacity: 0;
}
.g-tag--dim { fill: var(--bronze-light); }

/* Stage 2 — traces draw on, anchors pop in sequence. */
[data-stage="2"] .g-trace,
[data-stage="3"] .g-trace,
[data-stage="4"] .g-trace { stroke-dashoffset: 0; transition: stroke-dashoffset 1.5s var(--e-io) var(--d, 0s); }
[data-stage="2"] .g-anchor,
[data-stage="3"] .g-anchor { opacity: 1; transition: opacity .5s var(--e-out) var(--d, 0s); }

/* Stage 3 — planes resolve and label themselves. */
[data-stage="3"] .g-region { opacity: 1; transition: opacity .7s var(--e-out) var(--d, 0s); }
[data-stage="3"] .g-tag { opacity: 1; transition: opacity .6s var(--e-out) calc(var(--d, 0s) + .2s); }

/* Stage 4+ — the readings fall away and the room returns, finished. */
[data-stage="4"] .g-anchor,
[data-stage="4"] .g-region,
[data-stage="4"] .g-tag { opacity: 0; transition: opacity .5s var(--e-out); }
[data-stage="4"] .g-trace { opacity: .25; }
[data-stage="5"] .vroom__svg,
[data-stage="6"] .vroom__svg { opacity: 0; transition: opacity .5s var(--e-out); }

/* Scanning sweep, stage 2 only — one pass, not a looping sci-fi shimmer. */
.vroom__sweep {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg,
    transparent 42%,
    rgba(193, 156, 109, .16) 49%,
    rgba(193, 156, 109, .42) 50%,
    rgba(193, 156, 109, .16) 51%,
    transparent 58%);
  opacity: 0;
  transform: translateY(-100%);
  pointer-events: none;
}
[data-stage="2"] .vroom__sweep { animation: sweep 2.6s var(--e-io) .2s 1 forwards; }
@keyframes sweep {
  0%   { opacity: 0; transform: translateY(-100%); }
  12%  { opacity: 1; }
  88%  { opacity: 1; }
  100% { opacity: 0; transform: translateY(100%); }
}

/* ---- corner reticles: the plate reads as a capture frame ----
   Indexed with :nth-of-type, not :nth-child — the reticles are preceded by the
   image, the wash and the sweep, so :nth-child(1..4) matched only one of them
   and left the other three stacked in the corner at their static position. */
.vroom__reticle { position: absolute; width: 22px; height: 22px; border: 1px solid var(--bronze-light); opacity: 0; transition: opacity .6s var(--e-out); }
.vroom__reticle:nth-of-type(1) { top: 10px; left: 10px; border-right: 0; border-bottom: 0; }
.vroom__reticle:nth-of-type(2) { top: 10px; right: 10px; border-left: 0; border-bottom: 0; }
.vroom__reticle:nth-of-type(3) { bottom: 10px; left: 10px; border-right: 0; border-top: 0; }
.vroom__reticle:nth-of-type(4) { bottom: 10px; right: 10px; border-left: 0; border-top: 0; }
[data-stage="2"] .vroom__reticle,
[data-stage="3"] .vroom__reticle { opacity: .85; }

/* --------------------------------------------------------------------------
   Stage copy
   -------------------------------------------------------------------------- */

.vcopy { position: relative; min-height: 15.5rem; }
.vstep {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1.1rem;
  opacity: 0;
  transform: translate3d(0, 18px, 0);
  transition: opacity .5s var(--e-out), transform .6s var(--e-out);
  pointer-events: none;
}
.vstep.is-on { opacity: 1; transform: none; pointer-events: auto; }

.vstep__k {
  display: flex;
  align-items: center;
  gap: .85rem;
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--bronze-light);
}
.vstep__k .bar { width: 30px; height: 1px; background: currentColor; }

.vstep h3 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(2rem, 4.4vw, 3.6rem);
  line-height: 1.02;
  letter-spacing: -.02em;
}
.vstep p { color: var(--stone-dim); max-width: 38ch; }

/* --------------------------------------------------------------------------
   Progress rail
   -------------------------------------------------------------------------- */

.vrail {
  position: absolute;
  left: var(--gutter);
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: .85rem;
  z-index: 3;
}
.vrail__i { display: flex; align-items: center; gap: .7rem; }
.vrail__dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: rgba(245, 242, 235, .22);
  transition: background .4s var(--e-out), transform .4s var(--e-out);
}
.vrail__i.is-on .vrail__dot { background: var(--bronze-light); transform: scale(1.6); }
.vrail__n {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .14em;
  color: rgba(245, 242, 235, .45);
  transition: color .4s var(--e-out);
}
.vrail__i.is-on .vrail__n { color: var(--ivory); }

/* Metadata readout — reports the scene's real state, nothing invented. */
.vmeta {
  position: absolute;
  right: var(--gutter);
  bottom: clamp(1.5rem, 4vh, 3rem);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: rgba(245, 242, 235, .52);
  text-align: right;
  line-height: 1.9;
  z-index: 3;
}
.vmeta b { color: var(--bronze-light); font-weight: 400; }

/* --------------------------------------------------------------------------
   Stage 5 — before / after

   Both halves are the SAME photograph. The left is the captured reading, the
   right the finished room. Nothing here implies two different photographs of
   two different moments, because no such matched pair exists in the library —
   and the product story is genuinely "one space, two readings" anyway.
   -------------------------------------------------------------------------- */

.vba {
  --x: 50%;
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity .6s var(--e-out), visibility .6s;
}
[data-stage="5"] .vba { opacity: 1; visibility: visible; }

.vba__layer { position: absolute; inset: 0; }
.vba__layer img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Captured reading sits on top and is clipped to the handle position. */
.vba__layer--before {
  clip-path: inset(0 calc(100% - var(--x)) 0 0);
  filter: saturate(.12) contrast(1.16) brightness(.82);
}
.vba__layer--before::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(18, 26, 34, .5), rgba(10, 14, 18, .62));
}

.vba__handle {
  position: absolute;
  top: 0; bottom: 0;
  left: var(--x);
  width: 1px;
  background: var(--ivory);
  transform: translateX(-.5px);
  pointer-events: none;
}
.vba__grip {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 46px; height: 46px;
  border-radius: 50%;
  background: var(--ivory);
  color: var(--near-black);
  display: grid;
  place-items: center;
  box-shadow: 0 8px 26px rgba(0, 0, 0, .45);
}
.vba__grip svg { width: 17px; height: 17px; }

/* A real range input is the control: pointer drag, touch and keyboard all
   come free, and it is announced to assistive tech. It is transparent and
   stretched over the plate; the visible handle is the div above. */
.vba__range {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  margin: 0;
  opacity: 0;
  cursor: ew-resize;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;

  /* Critical on touch. This control is not a 4px track — it covers the whole
     plate, in the middle of a PINNED section. Left at `auto`, an ambiguous
     drag can be claimed by the slider, and a visitor who cannot scroll past
     stage 5 is simply stuck on the page. `pan-y` gives vertical panning back
     to the document and keeps horizontal drags for the comparison. */
  touch-action: pan-y;
}
.vba__range::-webkit-slider-thumb { -webkit-appearance: none; width: 56px; height: 100%; cursor: ew-resize; }
.vba__range::-moz-range-thumb { width: 56px; height: 999px; border: 0; background: transparent; cursor: ew-resize; }
.vba__range:focus-visible ~ .vba__handle .vba__grip { outline: 2px solid var(--bronze); outline-offset: 3px; }

.vba__tag {
  position: absolute;
  bottom: 14px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ivory);
  background: rgba(19, 18, 16, .55);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  padding: .35rem .6rem;
  pointer-events: none;
}
.vba__tag--l { left: 14px; }
.vba__tag--r { right: 14px; }

/* --------------------------------------------------------------------------
   Stage 6 — the closing statement takes the whole stage
   -------------------------------------------------------------------------- */

.vfinal {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  text-align: center;
  padding-inline: var(--gutter);
  opacity: 0;
  visibility: hidden;
  background: var(--near-black);
  transition: opacity .7s var(--e-out), visibility .7s;
  z-index: 4;
}
[data-stage="6"] .vfinal { opacity: 1; visibility: visible; }

.vfinal h3 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(2.4rem, 7vw, 6rem);
  line-height: .98;
  letter-spacing: -.025em;
}
.vfinal h3 span { display: block; }
.vfinal h3 span:nth-child(2) { color: var(--stone); }
.vfinal h3 span:nth-child(3) { color: var(--bronze-light); font-style: italic; }
.vfinal .btn { margin-top: 2.75rem; }

/* --------------------------------------------------------------------------
   Responsive

   The pinned story is kept on phones — it is the point of the page — but it
   is recomposed rather than squashed: copy sits under the plate, the rail
   goes horizontal along the top, and the track shortens so the section does
   not swallow the scroll.
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
  .vscene__track { height: 480vh; }
  .vscene__inner {
    grid-template-columns: 1fr;
    gap: clamp(1.5rem, 4vh, 2.5rem);
    align-content: center;
  }
  .vroom { width: min(58vw, 34vh); justify-self: center; }
  .vcopy { min-height: 12rem; text-align: center; }
  .vstep { align-items: center; }
  .vstep__k { justify-content: center; }
  .vstep p { max-width: 32ch; }

  .vrail {
    left: 50%;
    top: calc(var(--nav-h) + 1.25rem);
    transform: translateX(-50%);
    flex-direction: row;
    gap: 1rem;
  }
  .vrail__n { display: none; }
  .vmeta { display: none; }
}

@media (max-width: 560px) {
  .vroom { width: min(72vw, 32vh); }
  .vba__grip { width: 40px; height: 40px; }
  .vba__tag { font-size: 9px; }
}

/* On very short viewports the pinned stage has nowhere to put both the plate
   and the copy; drop the plate rather than crushing the type. */
@media (max-height: 620px) and (max-width: 900px) {
  .vroom { width: 30vh; }
  .vstep p { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .vroom__sweep { animation: none !important; opacity: 0 !important; }
  .g-trace { stroke-dashoffset: 0 !important; }
}
