/* =========================================================================
   Velaccio — Formatos

   The shelf of ad styles, sitting under "Qué hacemos": a rail of covers that
   drifts left forever, and opens one card at a time.

   Three things carry the interaction:

     • the rail never ends — the script clones the set until it is wider than
       twice the viewport, so the wrap point is always off-screen
     • an open card rises out of the row and its name unfolds underneath, in
       the gap the lift just made. Nothing below it moves, because the meta
       block is absolutely positioned and the rail already reserves its height
     • everything not open dims and desaturates, so the open one reads as the
       only lit object on the shelf

   Sizes are px/calc rather than rem: main-style.css drives html{font-size}
   off vw, so a rem here would track the viewport twice over — the same reason
   roster.css states for doing it this way.

   Every size below is one number times --fmt-w, so the shelf keeps a single
   set of proportions at any width. Capping each token in px instead froze the
   row at around 1550px while the heading — which is rem, and so never stops
   growing — kept climbing past it: on a 16:9 desktop or an ultrawide the
   covers shrank away under a title too large for its own column. min()
   distributes over multiplication, so moving the one unit moves all of them
   together and nothing drifts out of step.
   ========================================================================= */

.vel-formats {
  /* The unit the section is drawn in. 1vw is the laptop proportion, held at
     every width; the vh term states that same proportion against a 16:10
     screen and takes over once the viewport is wider than it is tall, which
     is the only thing stopping a 21:9 monitor from widening the covers past
     the height left to stand them in. */
  --fmt-w: min(1vw, 1.875vh);

  --fmt-card: max(170px, calc(16 * var(--fmt-w)));
  --fmt-gap: max(12px, calc(1.6 * var(--fmt-w)));
  /* how far an open card climbs out of the row */
  --fmt-lift: max(46px, calc(5 * var(--fmt-w)));
  /* room kept under the row for the name that unfolds there */
  --fmt-meta: max(72px, calc(7.4 * var(--fmt-w)));
  --fmt-e: cubic-bezier(.16, 1, .3, 1);

  position: relative;
  padding: max(56px, calc(8 * var(--fmt-w))) 0 max(56px, calc(8 * var(--fmt-w)));
  background: transparent;
}

/* ---- heading beside the rail --------------------------------------------- */

/* The statement holds the left column and the rail takes the rest, still
   running off the right of the screen. Centred rather than top-aligned: the
   rail's box is taller than its covers (it reserves the lift above and the
   meta below), so aligning to its top would leave the heading floating high
   above the row it belongs to. */
.fmt-layout {
  display: flex;
  align-items: center;
  gap: max(20px, calc(3 * var(--fmt-w)));
}

.fmt-head {
  flex: 0 0 auto;
  /* as wide as the title's longest line. At 27% of the row the heading wrapped
     word by word and left "UN" alone on its own line; the breaks now live in
     the markup and the column follows them */
  width: auto;
  /* centred on the covers, not on the rail's box. The rail reserves --fmt-lift
     above the row and --fmt-meta below it, and the second is taller, so the
     box's middle sits under the covers' middle by half the difference. In a
     centred flex row, a bottom margin of the full difference raises the
     heading by exactly that half — and it moves with the tokens at any width */
  margin-bottom: calc(var(--fmt-meta) - var(--fmt-lift));
}

.fmt-label {
  display: block;
  margin-bottom: max(14px, calc(1.8 * var(--fmt-w)));
  color: rgba(255, 255, 255, .5);
  font-family: "Acid Grotesk", system-ui, sans-serif;
  font-size: max(14px, calc(1.2 * var(--fmt-w)));
  font-weight: 500;
  letter-spacing: .02em;
}

.fmt-title {
  margin: 0;
  font-family: "ABC Gravity Compressed", sans-serif;
  font-weight: 900;
  /* same scale as .wwd-title directly above, so the two statements read as
     one voice rather than a headline and a subhead */
  font-size: clamp(3.2rem, 9.6vw, 11rem);
  line-height: .88;
  letter-spacing: -.01em;
  text-transform: uppercase;
  color: #fff;
  /* each line is set by a <br> in the markup and never re-wraps on its own */
  white-space: nowrap;
}

/* ---- rail ---------------------------------------------------------------- */

/* Bleeds right, not both ways: the heading now closes the left side, so only
   the far edge should run off screen. The negative margin is exactly the
   distance from the centred container's edge to the viewport's — 50% of this
   box is half the content width, and 50vw is half the screen. */
.fmt-rail {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
  margin-right: calc(50% - 50vw);
  overflow: hidden;
  padding-top: var(--fmt-lift);
  padding-bottom: var(--fmt-meta);
  /* covers dissolve as they drift out past the heading, and again as they run
     off the right of the screen — neither edge is a hard cut */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 92%, transparent);
}

.fmt-track {
  display: flex;
  gap: var(--fmt-gap);
  margin: 0;
  padding: 0;
  list-style: none;
  width: max-content;
  will-change: transform;
}

.fmt-card {
  flex: none;
  width: var(--fmt-card);
}

/* ---- card ---------------------------------------------------------------- */

.fmt-card__btn {
  position: relative;
  display: block;
  width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .8s var(--fmt-e);
}

.fmt-card__media {
  position: relative;
  display: block;
  aspect-ratio: 5 / 7;
  border-radius: max(12px, calc(1.1 * var(--fmt-w)));
  overflow: hidden;
  background: #141414;
  /* the shadow only exists while lifted, so it is animated from nothing */
  box-shadow: 0 0 0 rgba(0, 0, 0, 0);
  transition:
    filter .8s var(--fmt-e),
    opacity .8s var(--fmt-e),
    box-shadow .8s var(--fmt-e);
}

.fmt-card__media img,
.fmt-card__media video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* the video sits over its own poster and only fades up once it can play, so
   the swap from still to motion is never a black flash */
.fmt-card__media video {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity .5s ease;
}

.fmt-card.is-playing .fmt-card__media video {
  opacity: 1;
}

/* ---- meta, under the card ------------------------------------------------ */

.fmt-card__meta {
  position: absolute;
  top: 100%;
  left: 0;
  width: 100%;
  padding-top: max(10px, calc(1.1 * var(--fmt-w)));
  opacity: 0;
  transform: translateY(6px);
  pointer-events: none;
  transition:
    opacity .5s ease,
    transform .8s var(--fmt-e);
}

.fmt-card__name {
  display: block;
  color: #fff;
  font-family: "Acid Grotesk", system-ui, sans-serif;
  font-size: max(14px, calc(1.25 * var(--fmt-w)));
  font-weight: 500;
  letter-spacing: -.01em;
  line-height: 1.15;
}

.fmt-card__desc {
  /* two lines is the reserve the rail is built around; clamp rather than let
     a longer line push the text out of its own gap */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  /* The three lines above are the -webkit-box idiom every browser still
     implements. `line-clamp` is the standardised property that replaces it;
     stating both means this keeps working if the prefixed form is ever
     dropped, and browsers that already support the standard use that. */
  line-clamp: 2;
  overflow: hidden;
  margin-top: .35em;
  color: rgba(255, 255, 255, .5);
  font-family: "Acid Grotesk", system-ui, sans-serif;
  font-size: max(12px, calc(1.05 * var(--fmt-w)));
  font-weight: 400;
  line-height: 1.3;
}

/* ---- open (hovered or focused) / resting states -------------------------- */

.fmt-card.is-open .fmt-card__btn {
  transform: translateY(calc(-1 * var(--fmt-lift)));
}

.fmt-card.is-open .fmt-card__media {
  box-shadow: 0 calc(.35 * var(--fmt-lift)) calc(.68 * var(--fmt-lift)) calc(-.24 * var(--fmt-lift)) rgba(0, 0, 0, .85);
}

.fmt-card.is-open .fmt-card__meta {
  opacity: 1;
  transform: translateY(0);
}

/* everything else steps back while one is open */
.vel-formats.has-open .fmt-card:not(.is-open) .fmt-card__media {
  filter: saturate(.5) brightness(.62);
  opacity: .75;
}

.fmt-card__btn:focus-visible {
  outline: none;
}

.fmt-card__btn:focus-visible .fmt-card__media {
  box-shadow: 0 0 0 2px #000, 0 0 0 4px rgba(255, 255, 255, .85);
}

/* Under the theme's breakpoint the two columns stop paying for themselves —
   the heading gets too narrow long before the covers do — so it goes back to
   sitting above a rail that bleeds both ways. */
@media (max-width: 1099px) {
  .fmt-layout {
    display: block;
  }

  .fmt-head {
    width: auto;
    margin-bottom: clamp(26px, 4vw, 52px);
  }

  .fmt-rail {
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
  }
}

/* ---- no script / reduced motion ------------------------------------------ */

/* Without the script there is no clone set to drift, so the rail becomes an
   ordinary swipeable row rather than a dead strip showing six covers. */
.fmt-rail.is-static {
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-mask-image: none;
  mask-image: none;
}

.fmt-rail.is-static::-webkit-scrollbar {
  display: none;
}

.fmt-rail.is-static .fmt-track {
  padding: 0 max(16px, calc(5 * var(--fmt-w)));
}

@media (prefers-reduced-motion: reduce) {

  .fmt-card__btn,
  .fmt-card__media,
  .fmt-card__meta {
    transition-duration: .01ms;
  }
}
