/* ==========================================================================
   Insights (after Mondragon's insights)
   The head: [06], INSIGHTS and [All posts] on one line. Then one row per
   post, each row a single link: a card with a 2px white frame holding the
   cover and the words (the cover swaps sides row to row), and beside it a
   white tab reading [READ MORE] up its length.
   The motion, in order:
   - In view (insights.js): the head's words rise and [All posts] scrambles
     in; each row, as it arrives, rises into place, its cover unveils from
     its outer edge while the picture settles from a lean-in, the words
     follow, the tab grows up from its foot and its label scrambles in.
   - Hover: the tab fills with ink (the label scrambles back into place and
     an arrow rises in under it), the title greys, and the cover leans in
     and drifts against the pointer, as if seen through a window.
   - Press: the row gives a touch.
   ========================================================================== */

.insights {
  position: relative;
  z-index: 1;
  padding: clamp(56px, 9vh, 110px) var(--gutter) clamp(96px, 16vh, 180px);
  background: var(--bone);
}

/* Paper grain, as on the rest of the page. */
.insights::before {
  content: "";
  position: absolute;
  inset: 0;
  background: url("../assets/textures/grain.webp") repeat;
  background-size: 160px 160px;
  opacity: 0.55;
  pointer-events: none;
}

.insights > * {
  position: relative;
}

/* ------------------------------------------------------------------ head */

.insights__top {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: baseline;
  column-gap: clamp(28px, 4.9vw, 96px);
}

.insights__index,
.insights__title {
  display: inline-block;
  overflow: clip;
  padding-bottom: 0.08em;
  margin: 0 0 -0.08em;
  font-size: clamp(1.375rem, 1.55vw, 1.875rem);
  font-weight: 400;
  line-height: 1.05;
  letter-spacing: 0.02em;
  color: var(--text);
}

.insights__index > span,
.insights__title > span {
  display: inline-block;
}

.insights__all {
  position: relative;
  padding: 6px 0;
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  white-space: nowrap;
  -webkit-tap-highlight-color: transparent;
}

/* An ink line that draws under it on hover. */
.insights__all::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0.22em;
  bottom: 1px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: 100% 50%;
  transition: transform 500ms var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .insights__all:hover::after {
    transform: scaleX(1);
    transform-origin: 0% 50%;
  }
}

/* ------------------------------------------------------------------ rows */

.insights__list {
  display: grid;
  gap: clamp(14px, 1.5vw, 28px);
  margin: clamp(48px, 10vh, 106px) 0 0;
  padding: 0;
  list-style: none;
}

.ins__link {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(64px, 7.4vw, 150px);
  gap: 4px;
  border-radius: 10px;
  transition: scale 260ms var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}

.ins__link:active {
  scale: 0.994;
}

.ins__link:focus-visible {
  outline-offset: 5px;
}

/* The card: the cover and the words in a thin white frame. Mondragon's
   proportions (637 : 757); the cover takes the other side on flipped rows. */
.ins__card {
  display: grid;
  grid-template-columns: minmax(0, 637fr) minmax(0, 757fr);
  min-height: clamp(200px, 15.2vw, 300px);
  border: 2px solid var(--white);
  border-radius: 8px;
}

.ins--flip .ins__card {
  grid-template-columns: minmax(0, 757fr) minmax(0, 637fr);
}

.ins--flip .ins__media {
  order: 2;
}

.ins__media {
  position: relative;
  overflow: hidden;
  border-radius: 6px;
  background: var(--bone-deep);
}

/* Hover leans the cover in and drifts it against the pointer (--dx, --dy in
   -1..1, from insights.js). One transform, so the drift and the scale ease
   together and the edge of the picture never shows. */
.ins__zoom {
  position: absolute;
  inset: 0;
  transform: translate3d(calc(var(--dx, 0) * -12px), calc(var(--dy, 0) * -5px), 0) scale(var(--z, 1));
  transition: transform 1100ms var(--ease-out);
}

.ins__zoom img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.ins__body {
  display: grid;
  align-content: center;
  gap: clamp(14px, 1.5vw, 24px);
  padding: clamp(24px, 3.15vw, 64px);
}

.ins__title {
  margin: 0;
  font-family: var(--font-mono);
  font-size: clamp(1.25rem, 1.95vw, 2.5rem);
  font-weight: 400;
  line-height: 1.12;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  text-wrap: balance;
  transition: color 300ms ease;
}

.ins__sum {
  max-width: 60ch;
  margin: 0;
  font-size: clamp(0.9375rem, 0.9rem + 0.12vw, 1.0625rem);
  line-height: 1.55;
  color: rgb(17 17 17 / 0.64);
  text-wrap: pretty;
}

/* The tab: white, [READ MORE] reading up it. Hover fills it with ink. */
.ins__tab {
  position: relative;
  display: grid;
  place-items: center;
  border-radius: 8px;
  color: var(--ink);
  background: var(--white);
  transition:
    background-color 300ms ease,
    color 300ms ease;
}

.ins__more {
  writing-mode: vertical-rl;
  rotate: 180deg;
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.24em;
  white-space: nowrap;
}

.ins__arrow {
  position: absolute;
  left: 50%;
  bottom: clamp(16px, 1.6vw, 26px);
  width: 18px;
  height: 18px;
  margin-left: -9px;
  opacity: 0;
  translate: 0 12px;
  rotate: -45deg;
  transition:
    opacity 300ms ease,
    translate 600ms var(--ease-out),
    rotate 600ms var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .ins__link:hover .ins__tab {
    color: var(--white);
    background: var(--ink);
  }

  .ins__link:hover .ins__title {
    color: var(--text-mute);
  }

  .ins__link:hover .ins__zoom {
    --z: 1.06;
  }

  .ins__link:hover .ins__arrow {
    opacity: 1;
    translate: 0 0;
    rotate: 0deg;
    transition-delay: 80ms;
  }
}

/* The keyboard gets the same tell as the pointer. */
.ins__link:focus-visible .ins__tab {
  color: var(--white);
  background: var(--ink);
}

.ins__link:focus-visible .ins__arrow {
  opacity: 1;
  translate: 0 0;
  rotate: 0deg;
}

/* Tablets: the words get a little more of the row. */
@media (max-width: 1099px) {
  .ins__card,
  .ins--flip .ins__card {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  }

  .ins--flip .ins__card {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  }
}

/* Phones: the cover on top, the words under it, and the tab kept as on
   desktop: the white strip up the side, [READ MORE] reading up it, its
   arrow showing at the foot (there's no hover to bring it in). */
@media (max-width: 719px) {
  .insights__top {
    grid-template-columns: auto minmax(0, 1fr);
    row-gap: 18px;
  }

  .insights__all {
    grid-column: 1 / -1;
    justify-self: start;
  }

  .ins__link {
    grid-template-columns: minmax(0, 1fr) 48px;
  }

  .ins__card,
  .ins--flip .ins__card {
    grid-template-columns: minmax(0, 1fr);
    min-height: 0;
  }

  .ins--flip .ins__media {
    order: 0;
  }

  .ins__media {
    aspect-ratio: 16 / 10;
  }

  .ins__body {
    padding: 22px 18px 26px;
  }

  .ins__more {
    font-size: 0.75rem;
    letter-spacing: 0.2em;
  }

  .ins__arrow {
    bottom: 16px;
    opacity: 1;
    translate: none;
    rotate: 0deg;
  }
}

/* ------------------------------------------------------------------ reveal
   Armed by insights.js only when there's motion to play; without it (or
   without JS) everything simply shows. */

.insights.is-armed .insights__index > span,
.insights.is-armed .insights__title > span {
  translate: 0 110%;
}

.insights.is-armed .insights__all {
  opacity: 0;
}

.insights.is-armed .insights__top.is-in .insights__index > span,
.insights.is-armed .insights__top.is-in .insights__title > span {
  translate: none;
  transition: translate 1150ms var(--ease-out);
}

.insights.is-armed .insights__top.is-in .insights__title > span {
  transition-delay: 70ms;
}

.insights.is-armed .insights__top.is-in .insights__all {
  opacity: 1;
  transition: opacity 400ms ease 200ms;
}

.insights.is-armed .ins {
  opacity: 0;
  translate: 0 56px;
}

.insights.is-armed .ins .ins__media {
  clip-path: inset(0 100% 0 0 round 6px);
}

.insights.is-armed .ins--flip .ins__media {
  clip-path: inset(0 0 0 100% round 6px);
}

.insights.is-armed .ins img {
  transform: scale(1.18);
}

.insights.is-armed .ins .ins__title,
.insights.is-armed .ins .ins__sum {
  opacity: 0;
  translate: 0 18px;
}

.insights.is-armed .ins .ins__tab {
  clip-path: inset(100% 0 0 0 round 8px);
}

.insights.is-armed .ins.is-in {
  opacity: 1;
  translate: none;
  transition:
    opacity 700ms ease,
    translate 1100ms var(--ease-out);
}

.insights.is-armed .ins.is-in .ins__media {
  clip-path: inset(0 0 0 0 round 6px);
  transition: clip-path 1300ms var(--ease-out) 120ms;
}

.insights.is-armed .ins.is-in img {
  transform: none;
  transition: transform 1700ms var(--ease-out) 120ms;
}

.insights.is-armed .ins.is-in .ins__title,
.insights.is-armed .ins.is-in .ins__sum {
  opacity: 1;
  translate: none;
  transition:
    color 300ms ease,
    opacity 700ms ease 260ms,
    translate 1000ms var(--ease-out) 260ms;
}

.insights.is-armed .ins.is-in .ins__sum {
  transition-delay: 0ms, 340ms, 340ms;
}

.insights.is-armed .ins.is-in .ins__tab {
  clip-path: inset(0 0 0 0 round 8px);
  transition:
    background-color 300ms ease,
    color 300ms ease,
    clip-path 900ms var(--ease-out) 380ms;
}

@media (prefers-reduced-motion: reduce) {
  .insights *,
  .insights *::before,
  .insights *::after {
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
  }

  .ins__zoom {
    transform: none !important;
  }
}

/* Phones: the site's section rhythm (--sec-top / --sec-bot / --sec-end, tokens.css),
   so every gap between two sections reads the same. */
@media (max-width: 719px) {
  .insights {
    padding-top: var(--sec-top);
    padding-bottom: var(--sec-bot);
  }
}
