/* Features (#explore; heading from shead.css): a horizontal rail of four product cards, each holding
   only the product's app mockup and a small heading. One card fills most of the row, the next peeks in
   from the right; the reader moves sideways with the arrow buttons, the arrow keys, a swipe or a
   trackpad. Under the rail: where you are (01 / 04 and a line) on the left, the arrows on the right.
   The cards are sized from the screen height so the whole section is about one screen tall.
   Without JS it is the same rail, scrolled natively (thin scrollbar, no tools). */

.xp {
  --xp-ease: cubic-bezier(.22, .61, .36, 1);
  --xp-gap: var(--gap-grid);
  --xp-r: 14px;
  --xp-pad: clamp(1.125rem, 2.2vw, 2rem);      /* card head padding */
  --xp-inset: clamp(1.25rem, 3.6vw, 3.5rem);   /* app window inset from the card's sides */
  --xp-line: var(--line-dark);
  --xp-cta-h: 4.25rem; /* the CTA under each card (James, 15 Oct 2026: "add CTAs under the cards") */
  /* everything in the section that is not a card: the heading (eyebrow, one line of heading, one line
     of description under it, its foot, as in shead.css) and the tools row under the rail */
  --xp-chrome: calc(clamp(2rem, 1.3rem + 2.6vw, 3.5rem) * 1.04 + var(--step-0) * 1.55 + 1rem
    + clamp(2.5rem, 5vw, 4.25rem) + 2.25rem + 5rem + var(--xp-cta-h));
  --xp-h: clamp(20rem, calc(100vh - 2 * var(--sec-y, 6rem) - var(--xp-chrome)), 34rem);
}
@supports (height: 100svh) {
  .xp { --xp-h: clamp(20rem, calc(100svh - 2 * var(--sec-y, 6rem) - var(--xp-chrome)), 34rem); }
}
/* phones: a narrow card stays short of a full-height column */
@media (width <= 759px) {
  .xp { --xp-h: clamp(20rem, calc(100vh - 2 * var(--sec-y, 6rem) - var(--xp-chrome)), 30rem); }
  @supports (height: 100svh) {
    .xp { --xp-h: clamp(20rem, calc(100svh - 2 * var(--sec-y, 6rem) - var(--xp-chrome)), 30rem); }
  }
}

/* ---------- rail ---------- */
/* The rail bleeds to the screen edges (so the next card can peek in, also beyond the 1440px page)
   while the first card lines up with the page column; 100% in a card's flex-basis is that column.
   The section is an inline-size container, so 100cqw is the page width without any scrollbar, and the
   bleed is the gap from the page column to the screen edge (.wrap: max 1440px, --gut each side).
   The 8px above and below give the focus ring room inside the scroller. */
.xp { container-type: inline-size; }
.xp__list {
  --xp-bleed: var(--gut);
  display: flex;
  gap: var(--xp-gap);
  margin: -8px calc(var(--xp-bleed) * -1);
  padding: 8px var(--xp-bleed);
  scroll-padding-inline: var(--xp-bleed);
  list-style: none;
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}
@supports (width: 1cqw) {
  .xp__list { --xp-bleed: calc((100cqw - min(100cqw, 1440px)) / 2 + var(--gut)); }
}
.xp__list::-webkit-scrollbar { display: none; }
html:not(.js) .xp__list { padding-bottom: 14px; scrollbar-width: thin; scrollbar-color: #ffffff2e transparent; }

.xp__item {
  flex: 0 0 calc(100% - 2.75rem);
  min-width: 0;
  list-style: none;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}
@media (min-width: 760px) {
  .xp__item { flex-basis: min(27rem, 64%); }
}
@media (min-width: 1024px) {
  .xp__item { flex-basis: 88%; }
}
@media (min-width: 1200px) {
  .xp__item { flex-basis: 84%; }
}

/* ---------- card: a small heading over the app window, the whole card one link ---------- */
.xp__card {
  position: relative;
  display: flex;
  flex-direction: column;
  height: var(--xp-h);
  overflow: hidden;
  border: 1px solid #262a31;
  border-radius: var(--xp-r);
  background:
    radial-gradient(90% 60% at 50% 115%, #0062fe26, #0062fe00 62%),
    linear-gradient(180deg, #15181d 0%, #0f1115 60%, #0d0f12 100%);
  box-shadow: inset 0 1px 0 #ffffff0f;
  color: var(--paper);
  transition: border-color .35s;
}
.xp__card:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; }

.xp__head {
  flex: none;
  padding: var(--xp-pad) var(--xp-pad) clamp(1rem, 2vw, 1.5rem);
}
/* the heading sits a step back at rest and comes up to full white when the card is reached for */
#main .xp .xp__name {
  margin: 0;
  font-family: var(--mono);
  font-size: var(--step--1);
  font-weight: 400;
  letter-spacing: .14em;
  line-height: 1.2;
  text-transform: uppercase;
  color: #ffffffbf;
  transition: color .35s;
}

/* the app window rises from the card's bottom edge and is cropped by it (the card's overflow, so the
   window's glow fades out above it instead of stopping at a line) */
.xp__media {
  position: relative;
  flex: 1 1 0;
  min-height: 0;
  padding: 0 var(--xp-inset);
}
/* at least a little taller than the space it sits in, so it is always cut by the card's edge
   (the window's own background continues the mockup's below its last row) */
.xp__win {
  position: relative;
  min-height: calc(100% + 1.5rem);
  overflow: hidden;
  border: 1px solid #ffffff1c;
  border-bottom: 0;
  border-radius: 10px 10px 0 0;
  background: #111214;
  box-shadow: 0 -24px 70px -40px #0062fe8c;
  transition: transform .6s var(--xp-ease);
}
.xp__bar {
  display: flex;
  align-items: center;
  height: 28px;
  padding: 0 12px;
  border-bottom: 1px solid #ffffff10;
  background: #17191d;
}
.xp__lights { display: flex; gap: 6px; }
.xp__lights i { width: 8px; height: 8px; border-radius: 50%; background: #ffffff21; }
.xp__win .shot__box { pointer-events: none; }

/* hover and keyboard focus share one state: a lighter edge, the heading up to white, the window lifts */
.xp__card:hover, .xp__card:focus-visible { border-color: #3a414c; }
#main .xp .xp__card:hover .xp__name, #main .xp .xp__card:focus-visible .xp__name { color: var(--paper); }
.xp__card:hover .xp__win, .xp__card:focus-visible .xp__win { transform: translateY(-6px); }

/* between 1024px and about 1400px the window is too narrow for a readable desktop screen (0.39 scale
   at 1024): the screen keeps a width of at least 980px (scale 0.51 and up) and the window crops its
   right side, so the left of the screen and its title stay in view. Wider pages are not affected. */
.xp__win .shot__box--wide { width: max(100%, 61.25rem); }

/* tablets and phones: the phone mockup, in a phone frame rising from the card's edge
   (a 1920px window shrunk below about 0.4 scale reads as noise) */
@media (width <= 1023px) {
  .xp .shot__box--wide { display: none; }
  .xp .shot__box--tall { display: block; }
  /* the phone is sized from the space it sits in: wide enough that its screen always runs past the
     card's edge (a phone is about 2.16 times as tall as it is wide), never wider than the space */
  .xp__media { container-type: size; }
  .xp__win {
    width: min(15rem, 78%);
    width: min(max(min(15rem, 78cqw), 54cqh), 100cqw);
    min-height: 0;
    margin: 0 auto;
    /* a current iPhone: thin black bezel inside a titanium band (as on the product pages) */
    padding: 6px 6px 0;
    border: 0;
    border-radius: 2.6rem 2.6rem 0 0;
    background: #030304;
    box-shadow: 0 0 0 1.5px #4a4e56, 0 0 0 2.5px #1c1e22, 0 -24px 70px -40px #0062fe8c;
  }
  .xp__win .shot__box--tall { border-radius: 2.2rem 2.2rem 0 0; }
  .xp__bar { display: none; }
  /* the phone fades out into the card's bottom edge, so the edge never slices a button into a sliver */
  .xp__media {
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 3rem), #0000);
    mask-image: linear-gradient(to bottom, #000 calc(100% - 3rem), #0000);
  }
}

.xp__sr {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* no JS: let each mockup's viewBox scale it (the base fallback scale() is not valid CSS) */
html:not(.js) .xp .shot__box svg { width: 100%; height: 100%; transform: none; }

/* ---------- tools: progress on the left, arrows on the right ---------- */
.xp__tools {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: clamp(1.25rem, 2.4vw, 1.75rem);
}
.xp__tools[hidden] { display: none; }
#main .xp .xp__prog {
  display: flex;
  flex: 0 1 auto;
  align-items: center;
  gap: 1rem;
  min-width: 0;
  margin: 0;
  font-family: var(--mono);
  font-size: var(--step--1);
  letter-spacing: .14em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.xp__count { flex: none; white-space: nowrap; }
.xp__now { color: var(--paper); }
.xp__of { color: var(--mute-dark); }
.xp__track {
  position: relative;
  flex: 1 1 auto;
  width: 11rem;
  min-width: 4rem;
  height: 1px;
  background: #ffffff24;
}
.xp__fill {
  position: absolute;
  inset: 0;
  background: var(--blue);
  transform: scaleX(var(--xp-p, .25));
  transform-origin: 0 50%;
  transition: transform .2s linear;
}
.xp__ctl { display: flex; gap: .5rem; }
.xp__btn {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--xp-line);
  border-radius: 50%;
  background: transparent;
  color: var(--paper);
  cursor: pointer;
  transition: border-color .25s, background-color .25s, opacity .25s;
}
.xp__btn:hover:not(:disabled) { border-color: #ffffff42; background: #ffffff0a; }
.xp__btn:disabled { opacity: .3; cursor: default; }
.xp__btn:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; }

/* touch screens have no hover: the heading shows at full strength */
@media (hover: none) {
  #main .xp .xp__name { color: var(--paper); }
}

/* reduced motion: nothing moves on hover, the rail jumps instead of gliding (explore.js) */
@media (prefers-reduced-motion: reduce) {
  .xp *, .xp *::before, .xp *::after { transition: none !important; animation: none !important; }
  .xp__card:hover .xp__win, .xp__card:focus-visible .xp__win { transform: none; }
}

/* ---------- CTA under each card ---------- */
.xp__cta { margin: 1.25rem 0 0; }
.xp__cta .btn { white-space: nowrap; }
