/* JPAccess landing -- #features, the illustrations (v8).
 *
 * v8 over v7 (2026-09-24): a clearly stronger shadow when a card is hovered
 * (the THE REVEAL block below). Nothing else changes.
 *
 * v7 over v6 (2026-09-24): the "Fastest" card is a slow, tilted wall of the
 * dashboard's grid tiles (features-fx.v6.js, kind "wall") on the section's
 * light paper, instead of the warp shader: same vocabulary as every other
 * card here, the same drift as the hero's photo carousel.
 *
 * v6 over v5 (2026-09-24):
 *   - The cards APPEAR like everything else on the page: opacity and an 18px
 *     rise over .7s on the page's own curve. metal-sections.v1.css had set
 *     the cards' transition to box-shadow and transform only, so their
 *     opacity snapped from 0 to 1 in one frame when revealed (measured: fully
 *     opaque 115ms after scrolling) while every other section faded in.
 *   - The "Fastest" card's canvas is the warp shader (features-fx.v5.js),
 *     not the tubes: no drop shadow, a slow fade in once the first frame is
 *     drawn.
 *
 * v5 over v4 (2026-09-24):
 *   - The illustration ground is the light paper again (#EDEFF3, as in v1);
 *     the cards are told apart by SPACE instead: 28px between them, not 16.
 *   - The Fastest card's tubes are no longer an inverted image. They are
 *     drawn black on a transparent canvas (features-fx.v4.js) and get a soft
 *     drop shadow here, so they sit on the white card as objects.
 *
 * v4 == v3 with the Fastest card's static ground made plain white. v3 laid a
 * faint grey radial wash under the canvas; with no GPU (or before the
 * library lands) that read as a smudge on the card rather than as a ground.
 *
 * v3 over v2: the "Fastest" card is white like every other card, with dark
 * type and BLACK tubes (the canvas is inverted: the library draws white on
 * black, so invert(1) gives black on white, its glow a soft grey halo).
 *
 * Paired with features-fx.v3.js (which draws everything below into the
 * .fx-stage divs) and with the bundle from sections54.features2.js on (which
 * renders those divs, the eight cards and the Cross-region span).
 *
 * v2 over v1: a DARKER ground under every illustration (the paper tone read
 * as a smudge of the page rather than as a window, so the cards had no clear
 * edge between picture and text); the "Fastest" card is a dark panel with
 * the tubes effect behind its claim; the Lens card; Proxy's routes alone;
 * a light ground for cut-out product shots; the legal note under the grid.
 *
 * THE LOOK IS THE APP'S, NOT THE LANDING'S. Each stage is a crop of the
 * dashboard on its own paper ground: white surfaces with a hairline and a
 * short lift, the Studio palette from static/jp/theme.css, the Buy pill from
 * static/jp/buybtn-rb.css, the throbber from base.css, the switch from
 * /filters. What went: the gradient rims, inset highlights and heavy casts
 * that made every chip in v5 read as chrome.
 *
 * The CARD FRAMES are untouched and still come from metal-sections.v1.css,
 * so the section keeps the same edge as the pricing cards and the tablet.
 *
 * NO FONT IS NAMED HERE. type-noto.css already paints #root in the product
 * face, and v5's "Arial inside the animations" rule is gone with v5.
 *
 * NOTHING HERE STARTS OR STOPS AN ANIMATION BY ADDING IT. Every keyframe is
 * declared unconditionally and PAUSED while its stage is off screen (the
 * .is-live gate at the bottom), so coming back resumes it instead of
 * replaying it from the first frame.
 */

/* ------------------------------------------------------------------ grid */
@media (min-width: 1024px) {
  #features .fx-grid > .fx-span2-lg { grid-column: span 2; }
}
/* Room between the cards: the bundle's gap-4 (16px) let neighbouring cards
   read as one surface. */
#features .fx-grid { gap: 24px; }

/* THE REVEAL. The bundle's .reveal (opacity 0 + translateY(18px) until
   .is-visible, transitioned .7s cubic-bezier(.22,1,.36,1)) is what every
   section on the page appears with. metal-sections.v1.css replaced the
   cards' transition with `box-shadow .35s, transform .35s` at a higher
   specificity, which dropped opacity from it: the cards popped in. This puts
   the page's own reveal back and keeps the hover shadow's .35s. The per-card
   stagger is the bundle's inline transition-delay (0/90/180ms by column). */
#features .fx-grid > .reveal {
  transition:
    opacity .7s cubic-bezier(.22, 1, .36, 1),
    transform .7s cubic-bezier(.22, 1, .36, 1),
    box-shadow .35s ease;
}
/* That inline delay also applies to the hover shadow; on hover it should
   answer at once. (A transition takes the delay of the state it goes TO, so
   this does not touch the reveal's stagger.) */
#features .fx-grid > .reveal.is-visible:hover { transition-delay: 0s !important; }

/* HOVER. A clearly deeper lift than metal-sections.v1.css gives a hovered
   card (0 18px 46px at .16): a tight contact shadow, a mid shadow and a wide
   soft one, eased in over the .35s box-shadow transition above. One class
   more specific than that rule, and later, so it wins without !important. */
#features .fx-grid > .fx-card:hover {
  box-shadow:
    0 2px 4px hsl(var(--deep) / .08),
    0 14px 30px hsl(var(--deep) / .14),
    0 32px 72px hsl(var(--deep) / .22),
    inset 0 1px hsl(0 0% 100% / 1);
}
@media (min-width: 1024px) {
  #features .fx-grid { gap: 28px; }
}

/* ----------------------------------------------------------------- stage */
#features .fx-stage {
  /* The ground: the app's light paper. The cards are separated by the
     wider grid gap below, not by a heavy tint. */
  --fx-paper: #EDEFF3;
  --fx-paper2: #F6F7FA;
  --fx-paper3: #E3E5EA;
  --fx-ink: #161513;
  --fx-ink2: #35332E;
  --fx-ink3: #656259;
  --fx-rule: #D5D8DE;
  --fx-rule2: #E3E5EA;
  --fx-danger: #8C2F22;
  --fx-positive: #2C6446;
  --fx-scrim: rgba(22, 21, 19, .62);
  --fx-lift: 0 1px 2px rgba(22, 21, 19, .05), 0 4px 14px -6px rgba(22, 21, 19, .14);
  --fx-ease: cubic-bezier(.22, 1, .36, 1);
  position: relative;
  height: 224px;
  overflow: hidden;
  isolation: isolate;
  container-type: inline-size;
  background: var(--fx-paper);
  color: var(--fx-ink);
  font-size: 12px;
  line-height: 1.3;
  -webkit-user-select: none;
  user-select: none;
}
#features .fx-stage img { max-width: none; }
#features .fx-stage .num { font-variant-numeric: tabular-nums; }

/* A surface: white, hairline, short lift. The whole material vocabulary. */
#features .fx-sf {
  background: #fff;
  border: 1px solid var(--fx-rule2);
  box-shadow: var(--fx-lift);
}
#features .fx-ph {
  display: block;
  object-fit: cover;
  background: var(--fx-paper3);
}
/* Cut-out shots (transparent webp) sit on a studio-white ground, contained
   rather than cropped, like the product photo they are. */
#features .fx-ph.is-cut { background: #F4F4F6; object-fit: contain; }
#features .fx-tile > .fx-ph.is-cut { padding: 10% 8% 26%; }
#features .fx-mk { display: block; flex: none; }
#features .fx-flag {
  display: block;
  flex: none;
  width: 15px;
  height: 10px;
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(22, 21, 19, .14);
}

/* Lane slots (features-fx.v1.js, Lane): the wrapper around each item.
   Position is the transform, and a move between slots is this transition.
   The item inside animates its own arrival. */
#features .fx-li {
  position: absolute;
  left: 0;
  top: 0;
  transition: transform .62s var(--fx-ease), opacity .45s ease;
  will-change: transform;
}
#features .fx-lane-y > .fx-li { right: 0; }
#features .fx-li.fx-leave,
#features .fx-li.fx-out { opacity: 0; }

/* ------------------------------------------------------------------ tile
   The grid tile: photo to the edge, marketplace and age on scrim pills,
   brand and price on a gradient at the foot. */
#features .fx-tile {
  position: relative;
  width: var(--tw, 96px);
  height: var(--th, 128px);
  border-radius: 10px;
  overflow: hidden;
  background: var(--fx-paper3);
  box-shadow: 0 1px 2px rgba(22, 21, 19, .08), 0 6px 14px -8px rgba(22, 21, 19, .32);
}
#features .fx-tile > .fx-ph {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
#features .fx-tile::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 58%;
  background: linear-gradient(to top, rgba(22, 21, 19, .74) 0%, rgba(22, 21, 19, .32) 48%, rgba(22, 21, 19, 0) 100%);
  pointer-events: none;
}
#features .fx-pill {
  position: absolute;
  left: 6px;
  top: 6px;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  max-width: calc(100% - 12px);
  height: 16px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--fx-scrim);
  color: #fff;
  font-size: 8.5px;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  overflow: hidden;
}
#features .fx-pill-mk { padding-left: 2.5px; }
#features .fx-pill .fx-mk { width: 11px; height: 11px; border-radius: 3px; }
#features .fx-pill-age { top: 25px; font-variant-numeric: tabular-nums; }
#features .fx-pill-age.is-first { top: 6px; }
#features .fx-cap {
  position: absolute;
  left: 7px;
  right: 7px;
  bottom: 6px;
  z-index: 1;
  display: flex;
  flex-direction: column;
  color: #fff;
  line-height: 1.2;
}
#features .fx-cap-b {
  font-size: 8.5px;
  opacity: .9;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#features .fx-cap b { font-size: 11.5px; font-weight: 700; letter-spacing: -.01em; }

/* ------------------------------------------------------------ Buy pill
   buybtn-rb.css at rest, and base.css's two answers: the Chromium throbber
   while the order runs, then the panel that rises with a green wash. */
#features .fx-buy {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 28px;
  min-width: 78px;
  padding: 0 14px;
  border-radius: 999px;
  border: 1px solid transparent;
  background:
    linear-gradient(180deg, #FFFFFF, #F2F2F4) padding-box,
    linear-gradient(180deg, rgba(0, 0, 0, .10), rgba(0, 0, 0, .17)) border-box;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .08), 0 6px 16px -6px rgba(0, 0, 0, .22), inset 0 1px 0 #fff;
  color: #111;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: -.005em;
  overflow: hidden;
  transition: transform .16s ease;
}
#features .fx-buy.is-press { transform: scale(.93); }
#features .fx-buy-t { transition: opacity .18s ease; }
#features .fx-buy .fx-spin {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 14px;
  height: 14px;
  margin: -7px 0 0 -7px;
  opacity: 0;
  transition: opacity .18s ease;
}
#features .fx-buy.is-working .fx-buy-t,
#features .fx-buy.is-done .fx-buy-t { opacity: 0; }
#features .fx-buy.is-working .fx-spin { opacity: 1; }
#features .fx-buy-p {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  border-radius: inherit;
  background: linear-gradient(180deg, rgba(44, 100, 70, .10), rgba(44, 100, 70, .17)), #fff;
  color: var(--fx-ink);
  transform: translateY(105%);
  transition: transform .42s var(--fx-ease);
}
#features .fx-buy-p svg { width: 11px; height: 11px; color: var(--fx-positive); flex: none; }
#features .fx-buy.is-done .fx-buy-p { transform: none; }

#features .fx-spin svg { display: block; width: 100%; height: 100%; }
#features .fx-spin circle {
  fill: none;
  stroke: #4285F4;
  stroke-width: 3.4;
  stroke-linecap: round;
  stroke-dasharray: 60.3;
  stroke-dashoffset: 18;
  transform-origin: 50% 50%;
}
#features .fx-buy.is-working .fx-spin svg { animation: fx-spin-rot 1.5s linear infinite; }
#features .fx-buy.is-working .fx-spin circle {
  animation: fx-spin-arc 1.5s ease-in-out infinite, fx-spin-hue 6s steps(1) infinite;
}
@keyframes fx-spin-rot { to { transform: rotate(360deg); } }
@keyframes fx-spin-arc {
  0% { stroke-dashoffset: 57; transform: rotate(0); }
  50% { stroke-dashoffset: 15; transform: rotate(60deg); }
  100% { stroke-dashoffset: 57; transform: rotate(360deg); }
}
@keyframes fx-spin-hue {
  0% { stroke: #4285F4; } 25% { stroke: #EA4335; } 50% { stroke: #FBBC05; } 75% { stroke: #34A853; }
}

/* ============================================================ FASTEST ===
   Built like every other card here: the illustration on the section's light
   paper at the top, a hairline, and the text below -- except that the text
   is the section's lead claim. The illustration is a slow wall of fresh
   finds (features-fx.v6.js, kind "wall"): the dashboard's grid tiles in two
   tilted rows, Europe above Japan in the order the claim names them,
   drifting in opposite directions like the hero's photo carousel. The card
   keeps the frame and fill every card here has (metal-sections.v1.css). */
#features .fx-hero {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 340px;
}
/* The stage takes whatever height the claim leaves (the row's height is set
   by Cross-region beside it). Nothing in here takes the pointer. The bundle
   before sections56 named this stage "tubes". */
#features .fx-stage.fx-wall,
#features .fx-stage.fx-tubes {
  position: relative;
  flex: 1 1 auto;
  min-height: 150px;
  height: auto;
  pointer-events: none;
}
#features .fx-wl {
  --tw: 70px;
  --th: 93px;
  position: absolute;
  inset: 0;
  overflow: hidden;
}
/* Two rows, tilted as one. Wider than the card and pulled left so the
   rotated rows reach both edges; centred vertically in the stage. */
#features .fx-wl-tilt {
  position: absolute;
  left: -30%;
  top: 50%;
  width: 170%;
  display: flex;
  flex-direction: column;
  gap: 10px;
  transform: translateY(-50%) rotate(-7deg);
  transform-origin: 50% 50%;
}
/* Each track is two identical copies of its row; it slides by exactly one
   copy and starts again. The spacing is every tile's own right margin (not a
   flex gap), so one copy is exactly half the track and the loop has no seam.
   Durations are set per row by the script: 10-14 px/s. */
#features .fx-wl-track {
  display: flex;
  width: max-content;
  animation: fx-wl-slide 74s linear infinite;
  will-change: transform;
}
#features .fx-wl-track.is-rev { animation-direction: reverse; }
#features .fx-wl-track > .fx-tile { flex: none; margin-right: 10px; }
/* At this size the marketplace pill is its logo alone, as on a narrow lane. */
#features .fx-wl .fx-pill-mk { padding: 0 2.5px; }
#features .fx-wl .fx-pill-mk > span { display: none; }
@keyframes fx-wl-slide {
  from { transform: translate3d(0, 0, 0); }
  to { transform: translate3d(-50%, 0, 0); }
}
#features .fx-hero-copy {
  position: relative;
  flex: none;
  padding: 22px 24px 26px;
  border-top: 1px solid hsl(var(--line));
  container-type: inline-size;
}
/* Each sentence on ONE line, in every language: the size is the column's
   width over the longest line's measured width in Noto Sans 750 (en 8.28em,
   de 10.10em, fr 11.70em), less 4%. The first declaration is the fallback
   for an engine without container units. */
#features .fx-hero-h {
  white-space: pre-line;
  font-size: clamp(22px, 2.1vw, 30px);
  font-size: max(20px, min(30px, 11.6cqi));
  line-height: 1.1;
  letter-spacing: -.032em;
  color: hsl(var(--fg));
}
html[lang="de"] #features .fx-hero-h { font-size: max(19px, min(30px, 9.5cqi)); }
html[lang="fr"] #features .fx-hero-h { font-size: max(18px, min(30px, 8.2cqi)); }
#features .fx-hero-p {
  margin-top: 10px;
  font-size: 14px;
  line-height: 1.6;
  color: hsl(var(--fg-muted));
}

/* ================================================================ SPAM == */
#features .fx-sp {
  position: absolute;
  left: 18px;
  right: 18px;
  top: 37px;
  height: 150px;
}
#features .fx-sp-list { position: relative; height: 100%; }
#features .fx-srow {
  position: relative;
  height: 46px;
  border-radius: 12px;
  background: #fff;
  border: 1px solid var(--fx-rule2);
  box-shadow: var(--fx-lift);
  transition: background-color .3s ease, border-color .3s ease;
}
#features .fx-srow-main {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 0 9px 0 6px;
  transition: opacity .28s ease;
}
#features .fx-srow-ph { width: 27px; height: 36px; border-radius: 5px; flex: none; }
#features .fx-srow-tx {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
  line-height: 1.2;
}
#features .fx-srow-tx > b {
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#features .fx-srow-tx > span {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 9.5px;
  color: var(--fx-ink3);
  white-space: nowrap;
  overflow: hidden;
}
#features .fx-av {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--fx-paper3);
  color: var(--fx-ink2);
  font-size: 7.5px;
  font-style: normal;
  font-weight: 700;
}
#features .fx-star { font-style: normal; color: #B98A12; }
#features .fx-srow.is-fake .fx-star { color: var(--fx-ink3); }
#features .fx-srow-p { flex: none; font-size: 11.5px; font-weight: 700; }

/* The report control, as it sits on a stream card: a round button, a
   danger-ink flag on white, that fills with the danger brick when pressed. */
#features .fx-flagbtn {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 1px solid rgba(140, 47, 34, .5);
  background: #fff;
  color: var(--fx-danger);
  transition: transform .14s ease, color .2s ease;
}
#features .fx-flagbtn::before {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: 50%;
  background: var(--fx-danger);
  opacity: 0;
  transition: opacity .2s ease;
}
#features .fx-flagbtn svg { position: relative; width: 12px; height: 12px; }
#features .fx-flagbtn.is-press { transform: scale(.84); }
#features .fx-flagbtn.is-on { color: #fff; }
#features .fx-flagbtn.is-on::before { opacity: 1; }

/* What the dashboard writes where the card was. */
#features .fx-note {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 14px;
  font-size: 11px;
  color: var(--fx-ink2);
  white-space: nowrap;
  opacity: 0;
  transition: opacity .3s ease .12s;
}
#features .fx-note i {
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--fx-danger);
}
#features .fx-srow.is-flagged { background: #FBF6F5; border-color: #E4CBC5; }
#features .fx-srow.is-flagged .fx-srow-main { opacity: 0; }
#features .fx-srow.is-flagged .fx-note { opacity: 1; }

#features .fx-cursor {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 5;
  width: 16px;
  height: 18px;
  opacity: 0;
  pointer-events: none;
  transition: transform .74s cubic-bezier(.45, 0, .2, 1), opacity .35s ease;
}
#features .fx-cursor.is-on { opacity: 1; }
#features .fx-cursor svg {
  display: block;
  width: 100%;
  height: 100%;
  transform-origin: 1px 1px;
  filter: drop-shadow(0 1px 1.5px rgba(22, 21, 19, .3));
  transition: transform .12s ease;
}
#features .fx-cursor.is-press svg { transform: scale(.84); }

/* =============================================================== PROXY ==
   The routes alone: three proxy routes to one listing, the cheapest ticked
   and labelled. Row 26px + gap 18px = the 44px step features-fx.v2.js moves
   the label by (PX_STEP); change them together. */
#features .fx-px {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 0 22px;
}
#features .fx-px-routes {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 16px 14px;
  padding-right: 128px;
  border-radius: 14px;
  background: #fff;
  border: 1px solid var(--fx-rule2);
  box-shadow: var(--fx-lift);
}
#features .fx-px-r { display: flex; align-items: center; gap: 10px; height: 26px; }
#features .fx-radio {
  position: relative;
  flex: none;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 1.5px solid var(--fx-rule);
  background: #fff;
  transition: border-color .3s ease;
}
#features .fx-radio::after {
  content: "";
  position: absolute;
  inset: 2.5px;
  border-radius: 50%;
  background: var(--fx-ink);
  transform: scale(0);
  transition: transform .3s var(--fx-ease);
}
#features .fx-px-r.is-win .fx-radio { border-color: var(--fx-ink); }
#features .fx-px-r.is-win .fx-radio::after { transform: scale(1); }
#features .fx-px-bar {
  position: relative;
  flex: 1;
  min-width: 30px;
  height: 9px;
  border-radius: 999px;
  background: #E6E8EC;
  overflow: hidden;
}
#features .fx-px-bar i {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: #A9AEB7;
  transform: scaleX(.4);
  transform-origin: left center;
  transition: transform .8s var(--fx-ease), background-color .3s ease;
}
#features .fx-px-r.is-win .fx-px-bar i { background: var(--fx-ink); }
#features .fx-px-v {
  flex: none;
  width: 60px;
  text-align: right;
  font-size: 11.5px;
  font-weight: 500;
  color: var(--fx-ink3);
  transition: color .3s ease;
}
#features .fx-px-r.is-win .fx-px-v { color: var(--fx-ink); font-weight: 700; }
#features .fx-px-pill {
  position: absolute;
  right: 12px;
  top: 16px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 26px;
  padding: 0 11px 0 9px;
  border-radius: 999px;
  background: var(--fx-ink);
  color: #fff;
  font-size: 10.5px;
  font-weight: 600;
  white-space: nowrap;
  box-shadow: 0 4px 12px -6px rgba(22, 21, 19, .5);
  transition: transform .55s var(--fx-ease);
}
#features .fx-px-pill svg { width: 11px; height: 11px; flex: none; }

/* ================================================================ LENS ==
   A grid tile with the dashboard's Lens button (base.css .jcc-lens, at tile
   scale), and the docked Lens window beside it. */
#features .fx-ln {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 16px;
}
#features .fx-ln-src {
  position: relative;
  flex: none;
  width: 126px;
  height: 168px;
  overflow: hidden;
  border-radius: 10px;
}
#features .fx-ln-src .fx-tile { --tw: 126px; --th: 168px; }
#features .fx-ln-btn {
  position: absolute;
  right: 6px;
  top: 6px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, .26);
  background: rgba(22, 21, 15, .62);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .2), 0 1px 3px rgba(0, 0, 0, .28);
  transition: transform .14s ease, background-color .14s ease;
}
#features .fx-ln-btn .fx-lens-ico { width: 15px; height: 15px; display: block; }
#features .fx-ln-btn.is-press { transform: scale(.88); background: rgba(22, 21, 15, .86); }
/* Lens's viewfinder: four corners closing on the piece once it is sent. */
#features .fx-ln-vf {
  position: absolute;
  inset: 22% 16% 30%;
  z-index: 1;
  opacity: 0;
  transform: scale(1.14);
  transition: opacity .35s ease, transform .45s var(--fx-ease);
  pointer-events: none;
}
#features .fx-ln-vf i {
  position: absolute;
  width: 16px;
  height: 16px;
  border: 0 solid #fff;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .35));
}
#features .fx-ln-vf i:nth-child(1) { left: 0; top: 0; border-width: 3px 0 0 3px; border-top-left-radius: 8px; }
#features .fx-ln-vf i:nth-child(2) { right: 0; top: 0; border-width: 3px 3px 0 0; border-top-right-radius: 8px; }
#features .fx-ln-vf i:nth-child(3) { left: 0; bottom: 0; border-width: 0 0 3px 3px; border-bottom-left-radius: 8px; }
#features .fx-ln-vf i:nth-child(4) { right: 0; bottom: 0; border-width: 0 3px 3px 0; border-bottom-right-radius: 8px; }
#features .fx-ln-tile.is-scan .fx-ln-vf { opacity: 1; transform: none; }
#features .fx-ln-win {
  flex: 1;
  min-width: 0;
  height: 188px;
  display: flex;
  flex-direction: column;
  padding: 10px;
  border-radius: 14px;
}
#features .fx-ln-h {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 18px;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--fx-ink2);
  white-space: nowrap;
  overflow: hidden;
}
#features .fx-ln-h .fx-lens-ico { flex: none; width: 14px; height: 14px; display: block; }
#features .fx-ln-grid {
  flex: 1;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  gap: 7px;
  margin-top: 8px;
}
#features .fx-ln-m {
  position: relative;
  overflow: hidden;
  border-radius: 8px;
  background: var(--fx-paper3);
  transition: opacity .35s ease;
}
#features .fx-ln-grid.is-stale .fx-ln-m { opacity: .28; }
#features .fx-ln-mi { position: absolute; inset: 0; }
#features .fx-ln-mi .fx-ph { width: 100%; height: 100%; }
#features .fx-ln-m b {
  position: absolute;
  left: 5px;
  bottom: 5px;
  z-index: 1;
  padding: 2px 6px;
  border-radius: 999px;
  background: #fff;
  color: var(--fx-ink);
  font-size: 9.5px;
  font-weight: 700;
  line-height: 1.2;
  box-shadow: 0 1px 3px rgba(22, 21, 19, .22);
}
/* A source line, drawn rather than named: the matches are the point, not
   whose shop they are in. */
#features .fx-ln-site {
  position: absolute;
  right: 6px;
  bottom: 9px;
  z-index: 1;
  width: 22px;
  height: 4px;
  border-radius: 2px;
  background: rgba(255, 255, 255, .85);
}

/* ============================================================== REGION ==
   Marketplaces on the left, one rail each into the feed's inlet, the feed
   as a row of grid tiles that moves along as each catch lands. */
#features .fx-rg {
  --tw: 98px;
  --th: 131px;
  --chip-w: 142px;
  --rail-w: 66px;
  position: absolute;
  inset: 0;
}
#features .fx-rg-chips {
  position: absolute;
  left: 18px;
  top: 50%;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: 8px;
  transform: translateY(-50%);
}
#features .fx-rg-chip {
  position: relative;
  display: flex;
  align-items: center;
  gap: 7px;
  width: var(--chip-w);
  height: 26px;
  padding: 0 9px 0 5px;
  border-radius: 999px;
  font-size: 10.5px;
  font-weight: 600;
  white-space: nowrap;
}
#features .fx-rg-chip .fx-mk { width: 16px; height: 16px; border-radius: 4px; }
#features .fx-rg-chip .fx-flag { width: 14px; height: 9.5px; }
#features .fx-rg-n { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* The ring a chip sends out when one of its listings leaves for the feed. */
#features .fx-rg-ring {
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  border: 1.5px solid var(--fx-ink);
  opacity: 0;
  pointer-events: none;
}
#features .fx-rg-rails {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}
#features .fx-rg-rails path { fill: none; stroke: #C6CAD1; stroke-width: 1.2; }
#features .fx-rg-inlet { fill: #fff; stroke: #9DA2AB; stroke-width: 1.2; }
#features .fx-rg-box {
  position: absolute;
  top: 50%;
  right: 18px;
  left: calc(18px + var(--chip-w) + var(--rail-w));
  z-index: 2;
  height: calc(var(--th) + 22px);
  padding: 10px;
  border-radius: 14px;
  background: var(--fx-paper2);
  border: 1px solid var(--fx-rule2);
  transform: translateY(-50%);
  overflow: hidden;
}
#features .fx-rg-track {
  position: relative;
  height: var(--th);
  -webkit-mask-image: linear-gradient(to right, #000 0, #000 82%, transparent 100%);
  mask-image: linear-gradient(to right, #000 0, #000 82%, transparent 100%);
}
#features .fx-rg-fly { position: absolute; inset: 0; z-index: 3; pointer-events: none; }
#features .fx-rg-dot {
  position: absolute;
  left: 0;
  top: 0;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--fx-paper3);
  box-shadow: 0 0 0 1.5px #fff, 0 2px 6px rgba(22, 21, 19, .32);
  will-change: transform;
}
#features .fx-rg-dot .fx-ph { width: 100%; height: 100%; }

@container (max-width: 560px) {
  #features .fx-rg { --tw: 84px; --th: 112px; --chip-w: 30px; --rail-w: 38px; }
  #features .fx-rg-chips { left: 14px; }
  #features .fx-rg-chip { padding: 0; justify-content: center; }
  #features .fx-rg-n,
  #features .fx-rg-chip .fx-flag { display: none; }
  #features .fx-rg-box { right: 14px; left: calc(14px + var(--chip-w) + var(--rail-w)); }
}

/* ============================================================= AUTOBUY == */
#features .fx-ab { position: absolute; inset: 0; padding: 18px; }
#features .fx-ab-f {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 50px;
  padding: 0 12px 0 10px;
  border-radius: 12px;
}
#features .fx-ab-f > .fx-mk { width: 20px; height: 20px; border-radius: 5px; }
#features .fx-ab-tx {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  line-height: 1.2;
}
#features .fx-ab-tx b {
  font-size: 11.5px;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#features .fx-ab-tx span {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 10px;
  color: var(--fx-ink3);
  white-space: nowrap;
  overflow: hidden;
}
#features .fx-hair { flex: none; width: 1px; height: 9px; background: var(--fx-rule); }
#features .fx-ab-sw {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}
#features .fx-ab-sw > span:first-child {
  font-size: 8.5px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--fx-ink3);
}
/* The switch from /filters: grey and off, ink and on, the knob carrying a
   dot in the track's colour. */
#features .fx-sw {
  position: relative;
  width: 34px;
  height: 20px;
  border-radius: 999px;
  background: #D9DBE0;
  transition: background-color .35s ease;
}
#features .fx-sw i {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 2px rgba(22, 21, 19, .25);
  transition: transform .35s var(--fx-ease);
}
#features .fx-sw i::after {
  content: "";
  position: absolute;
  inset: 5px;
  border-radius: 50%;
  background: #C6C9CF;
  transition: background-color .35s ease;
}
#features .fx-sw.is-on { background: var(--fx-ink); }
#features .fx-sw.is-on i { transform: translateX(14px); }
#features .fx-sw.is-on i::after { background: var(--fx-ink); }
#features .fx-ab-list {
  position: relative;
  height: 134px;
  margin-top: 12px;
  overflow: hidden;
}
#features .fx-arow {
  height: 62px;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 10px 0 7px;
  border-radius: 12px;
}
#features .fx-arow-ph { width: 36px; height: 48px; border-radius: 6px; flex: none; }
#features .fx-arow-tx {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  line-height: 1.25;
}
#features .fx-arow-tx > b:first-child { font-size: 11px; font-weight: 600; }
#features .fx-arow-tx > span {
  font-size: 10px;
  color: var(--fx-ink3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#features .fx-arow-tx > b.num { margin-top: 2px; font-size: 12px; font-weight: 700; }

/* ============================================================= COLUMNS == */
#features .fx-cols {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  padding: 14px 14px 0;
}
#features .fx-col { position: relative; min-width: 0; display: flex; flex-direction: column; }
#features .fx-col-h { display: flex; align-items: center; gap: 4px; height: 26px; }
#features .fx-col-p {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  height: 26px;
  padding: 0 8px 0 5px;
  border-radius: 999px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
}
#features .fx-col-p .fx-mk { width: 13px; height: 13px; border-radius: 3.5px; }
#features .fx-col-p b { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#features .fx-col-p svg { flex: none; width: 10px; height: 10px; color: var(--fx-ink3); }
#features .fx-col-pause {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  color: var(--fx-ink2);
}
#features .fx-col-pause svg { width: 10px; height: 10px; }
#features .fx-col-b { position: relative; flex: 1; margin-top: 8px; overflow: hidden; }
#features .fx-col-b .fx-tile { width: 100%; height: 84px; }
@container (max-width: 420px) {
  #features .fx-col-pause,
  #features .fx-col-p svg { display: none; }
}

/* =========================================================== WAREHOUSE ==
   Two routes from Japan to Europe. The parcel on the public-proxy route
   waits at the $$$ stop; the one through our warehouse does not. */
#features .fx-wh {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 46px;
  padding: 0 22px;
}
#features .fx-wh-l {
  position: relative;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: center;
  height: 34px;
}
#features .fx-wh-end,
#features .fx-wh-mid { position: relative; z-index: 2; justify-self: center; }
#features .fx-wh-end .fx-flag { width: 30px; height: 20px; border-radius: 3px; }
#features .fx-wh-mid {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 50px;
  height: 34px;
  padding: 0 12px;
  border-radius: 10px;
}
#features .fx-wh-cap {
  position: absolute;
  left: 50%;
  top: calc(100% + 7px);
  transform: translateX(-50%);
  font-size: 9.5px;
  font-weight: 500;
  color: var(--fx-ink3);
  white-space: nowrap;
}
#features .fx-wh-cost { font-size: 15px; font-weight: 700; letter-spacing: -.04em; color: var(--fx-ink3); }
#features .fx-wh-ico { display: block; width: 20px; height: 20px; color: var(--fx-ink); }
#features .fx-wh-ico svg { display: block; width: 100%; height: 100%; }
#features .fx-wh-rail {
  position: absolute;
  left: 16.667%;
  right: 16.667%;
  top: 50%;
  z-index: 0;
  height: 1px;
  background: repeating-linear-gradient(90deg, #BFC3CA 0 4px, transparent 4px 8px);
}
#features .fx-wh-run {
  position: absolute;
  left: 16.667%;
  top: 50%;
  z-index: 1;
  width: 66.667%;
  height: 0;
}
#features .fx-wh-pkg {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 0;
  opacity: 0;
  will-change: transform;
}
#features .fx-wh-pkg svg {
  position: absolute;
  left: -9px;
  top: -9px;
  width: 18px;
  height: 18px;
  filter: drop-shadow(0 1px 1.5px rgba(22, 21, 19, .25));
}
#features .fx-wh-slow .fx-wh-pkg { animation: fx-wh-slow 6s linear infinite; }
#features .fx-wh-fast .fx-wh-pkg { animation: fx-wh-fast 2.6s cubic-bezier(.45, .05, .55, .95) infinite; }
#features .fx-wh-fast .fx-wh-pkg2 { animation-delay: -1.3s; }
@keyframes fx-wh-slow {
  0% { transform: translate3d(0, 0, 0); opacity: 0; }
  6% { opacity: 1; }
  34% { transform: translate3d(50%, 0, 0); }
  70% { transform: translate3d(50%, 0, 0); }
  94% { opacity: 1; }
  100% { transform: translate3d(100%, 0, 0); opacity: 0; }
}
@keyframes fx-wh-fast {
  0% { transform: translate3d(0, 0, 0); opacity: 0; }
  10% { opacity: 1; }
  90% { opacity: 1; }
  100% { transform: translate3d(100%, 0, 0); opacity: 0; }
}

/* ========================================================== legal note ==
   Under the grid, where the illustrations it qualifies are: they show
   example items, prices and sellers, not real listings. */
#features .fx-legal {
  max-width: 760px;
  margin: 36px auto 0;
  text-align: center;
  font-size: 12px;
  line-height: 1.6;
  color: hsl(var(--fg-subtle));
}

/* ================================================================ gate ==
   Off screen, in a background tab, or before the card has ever been seen:
   every running keyframe in the stage holds its frame. */
#features .fx-stage:not(.is-live) *,
#features .fx-stage:not(.is-live) *::before,
#features .fx-stage:not(.is-live) *::after { animation-play-state: paused !important; }

@media (prefers-reduced-motion: reduce) {
  #features .fx-stage *,
  #features .fx-stage *::before,
  #features .fx-stage *::after { animation: none !important; transition: none !important; }
  #features .fx-wh-pkg { opacity: 1; transform: translate3d(22%, 0, 0); }
  #features .fx-grid > .reveal { transition: none !important; }
}
