/* Scroll-tilt tablet for the #interface section of the landing page.
   Standalone and additive, same shape as bg-paths.v1.* and liquid-metal.v1.*.

   Why plain CSS and not Tailwind: this page's Tailwind output
   (index-DssA39eN.css) is a frozen build with no source tree, so a utility it
   never emitted does nothing. Every class below is defined here. The colours
   read the page's own :root tokens so the section stays on-palette.

   Geometry follows the ContainerScroll reference, retuned: 64rem scroll runway,
   1000px perspective on the stage, rotateX 20deg -> 0 and scale 1.05 -> 1 as
   the section is scrolled through. The transform values themselves are written
   by the bundle (ScraperShot) on rAF; the values here are the at-rest start
   state, so the card is never flat before JS runs.

   v3 (this file) is v2 with the ORIGINAL device back: 64rem rather than 80rem,
   a 30px radius, the dark #222 bezel, and the six-layer drop shadow. What it
   KEEPS from v2 is the rim — the 1px gradient border lifted from the feature
   cards — plus every responsive decision below 1099px. Only the four colour and
   radius values that assumed a near-white bezel were retuned (the sheen, the
   swipe fade, and the two radii). To go back to the wide light version, point
   index.html at scraper-scroll.v2.css.

   What v2 changed, and which of it still stands, is recorded below:

     1. The card is WIDER — 80rem instead of 64rem. That is deliberately past
        the page's own text column (`.max-w-page`, 1180px, so 1100px of content
        at these paddings): the screenshot is the one thing on the page that
        has to be legible, and at 64rem it rendered NARROWER than the feature
        grid directly below it, which made the page's showpiece read as the
        smallest block on it.

     2. The bezel is quiet. It used to be liquid-metal.v2.js's animated WebGL
        rim over a #222 card with a six-layer drop shadow — an iridescent
        rainbow band around the screenshot that pulled the eye off the UI it
        was framing. It now uses the SAME static brushed edge as the feature
        cards in metal-sections.v1.css: a 1px gradient border, a light card
        face, one diagonal sheen, one soft shadow. Same material, a fraction of
        the volume, and no WebGL context.

        Because of (2), index.html points at liquid-metal.v1.js (buttons only)
        rather than v2 (buttons + .ss-card). The v2 file is still on disk; if
        the animated bezel is ever wanted back, repoint that one tag and
        restore scraper-scroll.v1.css alongside it — the .lm-rim geometry the
        canvas needs lives in v1 of this file and is deliberately absent here.

     3. Below 1100px the screen becomes a horizontally scrollable WINDOW onto
        the screenshot rather than a shrunk-to-fit copy of it. See the
        "narrow screens" block at the bottom for why that is the only option
        that keeps the UI readable. Edited in place rather than forked to a
        v3 because v2 had been live for half an hour, so essentially nobody
        holds a cached copy, and a second session was editing this same file
        at the time — a fork would have silently stranded their next edit. */

.ss-scroll {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 64rem;
  padding: 4rem 1.5rem;
}

.ss-stage {
  position: relative;
  width: 100%;
  perspective: 1000px;
}

/* ---- headline ------------------------------------------------------- */

.ss-head {
  max-width: 64rem;
  margin-left: auto;
  margin-right: auto;
  text-align: center;
  will-change: transform;
}

.ss-kicker {
  margin-top: 0;
  margin-bottom: 0;
  font-size: clamp(1.3rem, 2.4vw, 2.1rem);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.03em;
  color: hsl(var(--deep));
}

.ss-title {
  display: block;
  margin-top: 0.12em;
  font-size: clamp(1.75rem, 4.6vw, 4rem);
  font-weight: 700;
  line-height: 1.04;
  letter-spacing: -0.045em;
  color: hsl(var(--deep));
}

/* The big line is two sentences, and sections6.js renders them as two elements
   (interface.title + interface.title2). Inline while they fit on one line;
   stacked below the mobile breakpoint. Automatic wrapping broke it mid-clause
   there instead -- "In one place. At" / "the same time." -- because the clamp
   floors at 1.75rem under ~465px while the container keeps shrinking. */
.ss-t1,
.ss-t2 { display: inline; }

/* ---- the tablet ----------------------------------------------------- */

/* The border/background pair is lifted verbatim from `#features .grid > *` in
   metal-sections.v1.css so the two surfaces are the same material: a 1px
   gradient border is not expressible directly, so the element paints the
   gradient and masks it to its own 1px frame with padding-box/border-box.
   That keeps the radius exact, which border-image cannot do.

   `isolation: isolate` is what keeps the negative-z sheen below contained. The
   3D transform already creates a stacking context, so this is belt and braces,
   but it is also what stops the sheen escaping if the transform is ever
   dropped (it is, under prefers-reduced-motion). */
.ss-card {
  position: relative;
  isolation: isolate;
  width: 100%;
  max-width: 64rem;
  margin: -3rem auto 0;
  padding: 0.75rem;
  border: 1px solid transparent;
  border-radius: 30px;
  background:
    linear-gradient(#222, #222) padding-box,
    linear-gradient(145deg,
        hsl(0 0% 100% / .95) 0%,
        hsl(var(--line-strong)) 22%,
        hsl(0 0% 100% / .9) 38%,
        hsl(var(--warm)) 58%,
        hsl(0 0% 100% / .85) 74%,
        hsl(var(--line-strong)) 100%) border-box;
  /* v3: the original device's drop shadow is back — six layers out to a 233px
     blur, which is what made it read as a physical object floating over the
     page rather than a card lying on it. The inset white top edge stays from
     v2; it is what makes the 1px gradient border read as metal. */
  box-shadow:
    0 0 #0000004d, 0 9px 20px #0000004a, 0 37px 37px #00000042,
    0 84px 50px #00000026, 0 149px 60px #0000000a, 0 233px 65px #00000003,
    inset 0 1px hsl(0 0% 100% / .5);
  transform: rotateX(20deg) scale(1.05);
  will-change: transform;
}

/* The single diagonal highlight that makes a flat gradient read as METAL
   rather than as a coloured border — the feature cards' ::before, same angle
   and same stops. At z-index -1 it paints after the card's own background but
   before .ss-screen, so it shows on the bezel ring only and can never sit over
   the screenshot. Pointer-transparent so it cannot eat a click. */
.ss-card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(122deg,
      hsl(0 0% 100% / 0) 34%,
      hsl(0 0% 100% / .30) 47%,
      hsl(0 0% 100% / 0) 60%);
}

.ss-screen {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  width: 100%;
  overflow: hidden;
  border-radius: 1rem;
  background: hsl(var(--surface-2));
  /* The screen takes the screenshot's own aspect ratio, so the tablet is built
     around the image instead of the image being cropped to fit the tablet.
     ScraperShot overwrites --shot-ar from the file's real naturalWidth/Height
     once it loads; the fallback is the current screenshot, so there is no
     layout shift on a cold load. */
  aspect-ratio: var(--shot-ar, 1600 / 749);
}

.ss-screen img {
  display: block;
  height: 100%;
  width: 100%;
  object-fit: cover;
  object-position: left top;
}

/* ---- empty state, shown until the screenshot exists ------------------ */

.ss-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  height: 100%;
  width: 100%;
  color: hsl(var(--fg-subtle));
}

.ss-empty span { font-size: 12px; }

.ss-empty .ss-empty-kicker {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.16em;
}

/* ---- if liquid-metal is ever repointed at v2 while this file is live --- */

/* v2 of the script mounts .lm-rim / .lm-face / .lm-ripples inside .ss-card.
   None of them have geometry here, so an unstyled canvas would sit at its
   intrinsic 300x150 in the middle of the bezel. Hide the lot: this file and
   the animated bezel are mutually exclusive by design, and a mismatched pair
   should degrade to the static edge rather than to a stray grey box. */
.ss-card .lm-rim,
.ss-card .lm-face,
.ss-card .lm-ripples {
  display: none;
}

/* ---- narrow screens: the screen becomes a scrollable window ------------ */

/* THE PROBLEM. img/scraper-ui.jpeg is a 1600x749 capture of a dense desktop
   layout -- left rail, three marketplace feed columns of cards, right stats and
   chat rail. Fitting all 1600px into a phone renders it at about 0.22x, where
   no price, brand or column header is readable: the section costs a full screen
   of scroll and communicates nothing but "there is a grey UI". Measured against
   the desktop render, the shrink-to-fit is legible down to roughly 0.64x and
   falls apart below it. Solving `(vw - 74) / 1600 = 0.64` for the card's own
   geometry puts that at a 1100px viewport, which is where the breakpoint below
   sits -- not the usual 768px. A 900px tablet has the same problem as a 390px
   phone, just less of it.

   WHY SCROLL AND NOT A CROP. At a legible scale a phone fits about 1.5 of the
   three feed columns, so no fixed crop can show "all marketplaces at the same
   time" -- which is the literal headline above it. Panning is the only
   treatment that keeps both the legibility and the claim. The tilt goes flat
   here too: a 3D-rotated horizontal scroller is unpleasant to swipe, and the
   old rotateX(20deg) scale(0.8) shrank the screenshot further to buy an effect
   nobody can see at that size.

   The bundle writes rotateX/scale and translateY to these two nodes inline on
   rAF, so overriding them needs !important -- an important author declaration
   beats a normal inline one. The rAF work itself keeps running and is thrown
   away; stopping it would need a bundle change and it is one transform write
   per scroll event. */
@media (max-width: 1099px) {
  /* The fixed 64rem runway existed to give the tilt something to animate over.
     With the tilt gone it is just a column of dead space, so the section sizes
     to its content instead. */
  .ss-scroll { height: auto; padding: 3.25rem 1.5rem 4rem; }
  .ss-head { transform: none !important; }

  .ss-card {
    transform: none !important;
    margin: 2.25rem auto 0;
    max-width: none;
  }

  .ss-screen {
    /* flex-start, not center: when a flex container's content overflows, the
       centred overflow on the START side is unreachable by scrolling. */
    justify-content: flex-start;
    /* The image's fixed width below drives everything and the screen takes its
       height from it, so --shot-ar has nothing left to do here. Sizing from the
       WIDTH rather than from a vh height is what keeps the scale identical on
       every narrow device: a 64vh height looked tidy but rendered 0.57x on a
       667px-tall phone against 0.69x on an 844px one, i.e. it was worst exactly
       where legibility was already tightest. min-height is only for the
       .ss-empty fallback, which has no intrinsic size of its own. */
    aspect-ratio: auto;
    height: auto;
    min-height: 16rem;
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
  }

  .ss-screen img {
    /* .ss-screen is a flex container, so without flex:0 0 auto the image is
       compressed back to the container width and there is nothing to scroll --
       min-width:auto does not save it here because the default is to shrink.
       1100px of a 1600px source is 0.69x, a shade sharper than the 1024px
       desktop render this was read against, and it guarantees something to
       swipe at every viewport the block covers. */
    flex: 0 0 auto;
    width: 1100px;
    max-width: none;
    height: auto;
  }

  .ss-screen::-webkit-scrollbar { height: 4px; }
  .ss-screen::-webkit-scrollbar-track { background: transparent; }
  .ss-screen::-webkit-scrollbar-thumb {
    border-radius: 2px;
    background: hsl(var(--line-strong));
  }

  /* The swipe affordance. A fade over the right edge is the one signal that
     needs no words -- which matters on a page that runs in en/de/fr and whose
     i18n dictionaries fall back to English silently, so a text hint would have
     meant three dictionary entries and a bundle fork. It sits inside the bezel
     (inset by the card's padding) at z-index 1, above .ss-screen, which is in
     normal flow; .ss-card's `isolation: isolate` keeps it out of the page's
     stacking context. It stays visible at the far right of the scroll, where
     it washes near-white over the app's own near-white chrome and disappears
     on its own. */
  .ss-card::after {
    content: "";
    position: absolute;
    z-index: 1;
    top: 0.75rem;
    right: 0.75rem;
    bottom: 0.75rem;
    width: 3rem;
    pointer-events: none;
    border-radius: 0 1rem 1rem 0;
    /* v3: fades to the bezel, which is #222 again — against the light bezel of
       v2 this was hsl(var(--bg)) and would now paint a white smear inside a
       dark frame. */
    background: linear-gradient(to left,
        #222 10%,
        #22222200 100%);
  }
}

/* ---- small screens ---------------------------------------------------- */

@media (max-width: 768px) {
  .ss-scroll { padding: 2.5rem 1rem 3rem; }
  .ss-card {
    margin-top: 1.75rem;
    padding: 0.4rem;
    border-radius: 22px;
  }
  .ss-screen { border-radius: 0.75rem; }
  .ss-card::after {
    top: 0.4rem;
    right: 0.4rem;
    bottom: 0.4rem;
    width: 2.5rem;
    border-radius: 0 0.75rem 0.75rem 0;
  }
  .ss-t1,
  .ss-t2 { display: block; }
}

/* ---- no motion ------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .ss-head { transform: none !important; }
  .ss-card { transform: rotateX(0deg) scale(1) !important; }
}
