/* ═══════════════════════════════════════════════════════════════════════
   ABOUT PREVIEW ("Know me a bit better")
   Sits after Labs and before the CV strip on the homepage.
   Centre column: small heading, one-word facet list, and copy + buttons
   pinned to the bottom. Five flat 3:4 image frames float either side and
   are re-filled with a soft diagonal wipe when the facet changes.
   Behaviour lives in assets/js/modules/about-preview.js.
   ═══════════════════════════════════════════════════════════════════════ */

@property --ap-wipe {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 0%;
}

.about-preview-section {
  --ap-text: #ffffff;
  --ap-text-muted: rgba(255, 255, 255, 0.6);
  --ap-text-dim: rgba(255, 255, 255, 0.4);
  --ap-text-hover: rgba(255, 255, 255, 0.72);
  --ap-pill: rgba(255, 255, 255, 0.16);
  --ap-pill-hover: rgba(255, 255, 255, 0.26);
  --ap-pill-active: rgba(255, 255, 255, 0.32);
  --ap-focus: rgba(255, 255, 255, 0.55);
  --ap-frame-bg: #1e1e1d;
  --ap-stage-bg: transparent;
  --ap-ease: cubic-bezier(0.22, 0.61, 0.36, 1);

  position: relative;
  width: 100%;
  background: transparent;
  /* The stage carries its own bottom spacing; keep only a sliver here so
     the copy and buttons sit close to the section's edge. */
  padding: 0 0 24px 0;
  overflow: hidden;
}

/* Hairline that matches the Case Studies / Labs header bars */
.about-preview__rule {
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}

/* ── Tone ─────────────────────────────────────────────────────────
   data-tone="ink" sets the section on a full-width band in the same
   one step lighter than the page.
   The band has no hard edges: it fades in from the page colour through
   the gap left by Case Studies above, and fades back out before Labs.
   Remove the attribute to sit directly on the page instead. */
.about-preview-section[data-tone='ink'] {
  --ap-band: #161615; /* one step lighter than the page (#111110) */
  --ap-fade: 104px;     /* space above the first image; the fade-in runs across it */
  --ap-fade-out: 80px;  /* shorter, so the buttons stay close to the section's end */
  --ap-frame-bg: #1c1c1b;

  padding: var(--ap-fade) 0 var(--ap-fade-out) 0;
  /* Eased stops, so the colour change has no visible start or end */
  background: linear-gradient(
    to bottom,
    transparent 0,
    color-mix(in srgb, var(--ap-band) 12%, transparent) calc(var(--ap-fade) * 0.25),
    color-mix(in srgb, var(--ap-band) 50%, transparent) calc(var(--ap-fade) * 0.55),
    color-mix(in srgb, var(--ap-band) 88%, transparent) calc(var(--ap-fade) * 0.82),
    var(--ap-band) var(--ap-fade),
    var(--ap-band) calc(100% - var(--ap-fade-out)),
    transparent 100%
  );
}

/* This section owns the gap above it, so the fade starts right under the
   testimonial controls instead of after that section's own padding. */
.testimonials:has(+ .about-preview-section[data-tone='ink']) {
  padding-bottom: 0;
}

.about-preview-section[data-tone] .about-preview__rule {
  display: none;
}

/* ── Stage ────────────────────────────────────────────────────────── */
.about-preview__stage {
  --ap-px: 0;
  --ap-py: 0;
  --ap-scroll: 0;

  position: relative;
  container-type: size;
  width: 100%; /* full window width: this section is not held by the page frame */
  height: clamp(680px, calc(100svh - 8rem), 896px);
  display: flex;
  flex-direction: column;
  align-items: center;
  /* No padding here: cqw / cqh are measured from this box, so the
     top and bottom offsets live on the title and the foot instead. */
}

/* ── Heading ──────────────────────────────────────────────────────── */
.about-preview__title {
  position: relative;
  z-index: 2;
  margin: 18.5cqh 0 10px 0;
  font-family: var(--font-body, 'Switzer', system-ui, sans-serif);
  font-size: 15px;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: 0.01em;
  color: var(--ap-text-muted);
  text-align: center;
}

/* ── Facet list ───────────────────────────────────────────────────── */
.about-preview__list {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.about-preview__tab {
  all: unset;
  box-sizing: border-box;
  cursor: pointer;
  padding: 3px 14px;
  font-family: var(--font-display, 'Switzer', system-ui, sans-serif);
  font-size: 24px;
  font-weight: 400;
  line-height: 32px;
  letter-spacing: normal;
  color: var(--ap-text-dim);
  text-align: center;
  border-radius: 9999px;
  corner-shape: round;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  transition: color 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}

.about-preview__tab:hover {
  color: var(--ap-text-hover);
}

.about-preview__tab.is-active {
  color: var(--ap-text);
}

.about-preview__tab:focus-visible {
  outline: 1.5px solid var(--ap-focus);
  outline-offset: 0;
}

/* ── Foot: copy + buttons, locked to the bottom of the stage ──────── */
.about-preview__foot {
  position: relative;
  z-index: 2;
  margin-top: auto;
  margin-bottom: 7.5cqh;
  width: min(24rem, 100% - 2rem);
  display: grid;
}

.about-preview__panel {
  grid-area: 1 / 1;
  align-self: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  /* The outgoing copy cuts out at once; only the incoming copy fades */
  opacity: 0;
  visibility: hidden;
  transition: none;
}

.about-preview__panel.is-active {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.6s ease 0.1s;
}

.about-preview__desc {
  margin: 0;
  font-family: var(--font-body, 'Switzer', system-ui, sans-serif);
  font-size: 13px;
  line-height: 1.55;
  letter-spacing: 0;
  color: var(--ap-text-muted);
  text-wrap: balance;
}

.about-preview__desc strong {
  color: var(--ap-text);
  font-weight: 500;
}

.about-preview__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-top: 20px;
}

.about-preview__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 36px;
  padding: 0 16px;
  /* !important: the site's .js-trigger-cv-modal rule forces a 6px radius */
  border-radius: 9999px !important;
  corner-shape: round; /* the site-wide superellipse corners stop pills from being fully round */
  background: var(--ap-pill);
  color: var(--ap-text);
  font-family: var(--font-body, 'Switzer', system-ui, sans-serif);
  font-size: 15px;
  font-weight: 500; /* same weight as every other pill button on the site */
  line-height: 1;
  letter-spacing: 0;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.2s ease;
}

.about-preview__btn:hover {
  background: var(--ap-pill-hover);
  color: var(--ap-text);
}

.about-preview__btn:active {
  background: var(--ap-pill-active);
}

.about-preview__btn:focus-visible {
  outline: 1.5px solid var(--ap-focus);
  outline-offset: 2px;
}

/* ── Entrance: heading, then each word, then the copy ─────────────
   Plays once, when the script adds .is-inview. Only armed after the
   script has run (data-ready), so the text is never hidden without it. */
.about-preview-section[data-ready] .about-preview__title,
.about-preview-section[data-ready] .about-preview__tab,
.about-preview-section[data-ready] .about-preview__foot {
  --ap-in: 0s;
  opacity: 0;
  transform: translateY(10px);
  transition: none; /* hide instantly on load; only the reveal animates */
}

.about-preview-section[data-ready].is-inview .about-preview__title,
.about-preview-section[data-ready].is-inview .about-preview__tab,
.about-preview-section[data-ready].is-inview .about-preview__foot {
  opacity: 1;
  transform: none;
  transition:
    color 0.2s cubic-bezier(0.4, 0, 0.2, 1),
    opacity 0.6s ease var(--ap-in),
    transform 0.8s var(--ap-ease) var(--ap-in);
}

.about-preview-section[data-ready] .about-preview__tab:nth-child(1) { --ap-in: 0.12s; }
.about-preview-section[data-ready] .about-preview__tab:nth-child(2) { --ap-in: 0.18s; }
.about-preview-section[data-ready] .about-preview__tab:nth-child(3) { --ap-in: 0.24s; }
.about-preview-section[data-ready] .about-preview__tab:nth-child(4) { --ap-in: 0.30s; }
.about-preview-section[data-ready] .about-preview__tab:nth-child(5) { --ap-in: 0.36s; }
.about-preview-section[data-ready] .about-preview__tab:nth-child(6) { --ap-in: 0.42s; }
.about-preview-section[data-ready] .about-preview__tab:nth-child(7) { --ap-in: 0.48s; }
.about-preview-section[data-ready] .about-preview__tab:nth-child(8) { --ap-in: 0.54s; }
.about-preview-section[data-ready] .about-preview__foot { --ap-in: 0.7s; }

/* ── Image frames ─────────────────────────────────────────────────── */
.about-preview__media {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.about-frame {
  --ap-depth: 12;

  pointer-events: auto;
  position: absolute;
  aspect-ratio: 3 / 4;
  border-radius: 6px;
  overflow: hidden;
  background: var(--ap-frame-bg);
  translate: calc(var(--ap-px) * var(--ap-depth) * 1px) calc(var(--ap-py) * var(--ap-depth) * 1px);
  transition: opacity 0.9s ease, transform 1.1s var(--ap-ease);
  will-change: translate;
}

/* Hidden until scrolled in, but only once the script is running, so the
   frames still show if JavaScript fails to load. */
.about-preview-section[data-ready]:not(.is-inview) .about-frame {
  opacity: 0;
  transform: translateY(28px);
}

/* Cursor-following sheen, matching the Labs marquee tiles
   (.archive-tile__sheen) but without their rim outline.
   --sheen-x / --sheen-y are set by the script. */
.about-frame::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(
    360px circle at var(--sheen-x, 50%) var(--sheen-y, 50%),
    rgba(255, 255, 255, 0.44) 0%,
    rgba(255, 255, 255, 0.2) 28%,
    rgba(255, 255, 255, 0) 70%
  );
  mix-blend-mode: overlay;
  transition: opacity 0.3s ease;
  z-index: 5;
}

@media (hover: hover) {
  .about-frame:hover::before {
    opacity: 1;
  }
}

/* Slot geometry, measured from the reference on a 1512 × 790 stage.
   Left: one large, one medium, one small. Right: one medium, one large. */
.about-frame--1 {
  --ap-depth: 26;
  left: 6.9cqw;
  top: 4.5cqh;
  width: min(21.25rem, 16.9cqw, 33cqh);
}

.about-frame--2 {
  --ap-depth: 21;
  left: 18cqw;
  bottom: 4.5cqh;
  width: min(17.5rem, 13.7cqw, 27cqh);
  transition-delay: 0.08s;
}

.about-frame--3 {
  --ap-depth: 19;
  right: 18.8cqw;
  top: 6.8cqh;
  width: min(15.6rem, 12.3cqw, 24.5cqh);
  transition-delay: 0.16s;
}

.about-frame--4 {
  --ap-depth: 26;
  right: 8.1cqw;
  bottom: 7cqh;
  width: min(21.25rem, 16.7cqw, 33cqh);
  transition-delay: 0.24s;
}

.about-frame--5 {
  --ap-depth: 13;
  left: 6.5cqw;
  bottom: 19.5cqh;
  width: min(10.6rem, 8.5cqw, 17cqh);
  transition-delay: 0.32s;
}

/* ── Layers: each selection stacks a new layer and wipes it in ────── */
.about-frame__layer {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: var(--ap-frame-bg);
}

/* The picture is taller than its frame so it can slide vertically as
   the page scrolls (up when scrolling down), without moving the frame. */
.about-frame__img {
  position: absolute;
  left: 0;
  top: -9%;
  width: 100%;
  height: 118%;
  object-fit: cover;
  display: block;
  translate: 0 calc(var(--ap-scroll) * -7.6%);
  will-change: translate;
}

.about-frame__layer.is-entering {
  -webkit-mask-image: linear-gradient(8deg, #000 calc(var(--ap-wipe) - 45%), transparent var(--ap-wipe));
  mask-image: linear-gradient(8deg, #000 calc(var(--ap-wipe) - 45%), transparent var(--ap-wipe));
  animation: ap-wipe 0.55s cubic-bezier(0.4, 0, 0.2, 1) var(--ap-delay, 0ms) both;
}

.about-frame__layer.is-entering > * {
  animation: ap-settle 0.9s var(--ap-ease) var(--ap-delay, 0ms) both;
}

@keyframes ap-wipe {
  from { --ap-wipe: 0%; }
  to   { --ap-wipe: 145%; }
}

@keyframes ap-settle {
  from { transform: scale(1.04); }
  to   { transform: scale(1); }
}

/* Gradient tile for slots that have no image yet.
   Colours (--g1…--g4) and shape (--gx, --gy, --ga) are set per facet
   and per slot by the script. */
.about-frame__img--empty {
  background:
    radial-gradient(120% 75% at var(--gx, 12%) var(--gy, 0%), var(--g1, #6a4cff) 0%, transparent 60%),
    radial-gradient(110% 85% at calc(100% - var(--gx, 12%)) calc(100% - var(--gy, 0%)), var(--g2, #ff8fb1) 0%, transparent 65%),
    linear-gradient(var(--ga, 165deg), var(--g3, #1c1147), var(--g4, #ffd9b8));
}

/* ── Tablet & mobile: stack, and turn the frames into a swipe rail ── */
@media screen and (max-width: 1099px) {
  .about-preview-section {
    padding-bottom: 56px;
  }

  .about-preview-section[data-tone='ink'] {
    --ap-fade: 96px;
  }

  .about-preview__stage {
    container-type: normal;
    height: auto;
    padding: 0 0 8px;
  }

  .about-preview__title {
    margin-top: 0;
  }

  .about-preview__tab {
    font-size: 21px;
    line-height: 30px;
  }

  .about-preview__media {
    position: relative;
    inset: auto;
    width: 100%;
    margin: 28px 0 28px;
    padding-inline: var(--container-pad, 1rem);
    box-sizing: border-box;
    display: flex;
    gap: 10px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--container-pad, 1rem);
    scrollbar-width: none;
    pointer-events: auto;
  }

  .about-preview__media::-webkit-scrollbar {
    display: none;
  }

  .about-frame,
  .about-frame--5 {
    position: relative;
    display: block;
    inset: auto;
    flex: 0 0 auto;
    width: clamp(150px, 42vw, 240px);
    translate: none;
    scroll-snap-align: start;
  }

  .about-preview__foot {
    margin-top: 0;
    margin-bottom: 0;
    width: min(24rem, 100% - 2 * var(--container-pad, 1rem));
  }
}

@media (prefers-reduced-motion: reduce) {
  .about-frame,
  .about-preview__panel,
  .about-preview__panel.is-active,
  .about-preview-section[data-ready] .about-preview__title,
  .about-preview-section[data-ready] .about-preview__tab,
  .about-preview-section[data-ready] .about-preview__foot {
    transition: none;
    transform: none;
  }

  .about-frame,
  .about-frame__img {
    translate: none;
  }
}

/* Touch screens: words and buttons are at least 44px tall */
@media (pointer: coarse) {
  .about-preview__tab {
    padding-block: 7px;
  }

  .about-preview__btn {
    height: 44px;
  }
}
