/*
Portrait row — a row of upright pictures laid out in a checker pattern, optionally with a
glass badge hanging off the bottom corner of each one.

It was written inside About-02 and is a component now because the service pages draw the
same row, to the pixel: same 1128 band, same 265.5x354 tiles, same 24 of radius, same 22 of
gap, same 32 of drop on every second tile, and the same stack on the phone. A second copy of
that would drift the moment either was touched — the argument that took the badge out of the
hero and the ticked list out of the service hero.

    salt_md_portrait_row( $portraits, 'my-block__portraits' );

What belongs to the component and is not to be re-implemented in a block:

    the band and the tiles     width, gap, proportion, radius, shadow
    the checker pattern        which tiles sit lower, and which way they move when stacked
    the entrance               the shared photo reveal, staggered by the row's own step
    the badge                  its rung and where it hangs off the tile

What belongs to the block: how far under its own content the row starts, and — where a block
reorders its card on the phone, as About-02 does — where the row sits in that order.

NOTHING IS PLACED BY ITS INDEX. Which tiles move is :nth-child(even) and the stagger is the
step times an ordinal stamped by the component's own script, so a fifth portrait added in the
admin continues both with nothing to edit. That is the site's standing rule for collections.
*/

/*
The band is narrower than the box it sits in and centred in it, and stated as a maximum so
that below the design frame it gives way rather than pushing the page sideways.

align-items: flex-start is what lets the even tiles hang lower without stretching the odd
ones to match, and it is also what keeps the row's height honest — the drop below is a
margin, so the row grows by it and whatever follows keeps its distance from the lowest tile.

margin-block: 0 rather than nothing at all: this is a <ul> and the user agent gives it an em
of margin top and bottom. The distance above is the block's, set on its own instance.
*/
.portrait-row {
  display: flex;
  width: min(var(--portrait-row-w), 100%);
  align-items: flex-start;
  margin: 0 auto;
  padding: 0;
  gap: var(--portrait-row-gap);
  list-style: none;

  /*
  A badge belongs to the tile it hangs off, so it arrives on the tile's own beat: the badge
  component multiplies this step by the ordinal its script stamps, exactly as the photo
  reveal does below, and hands the same figure down to the counter inside it. Harmless on a
  row without badges — nothing reads it.
  */
  --badge-in-step: var(--portrait-row-step);
}

/*
No width. Four tiles share the row against a fixed gap and come out at the design's 265.5; a
fifth added by the client narrows all five instead of running off the edge.

position: relative is the badge's business — it hangs off this box rather than off the frame,
because the frame clips to the tile's radius and would cut the overhang away.
*/
.portrait-row__item {
  position: relative;
  min-width: 0;
  flex: 1 1 0;
}

/*
The checker pattern, and the whole of it. Which tiles move is their position in the row and
not a number in the markup, so adding, deleting or dragging a portrait renumbers the
alternation by itself.
*/
.portrait-row__item:nth-child(even) {
  margin-top: var(--portrait-row-offset);
}

/*
The frame clips the photograph to the tile's radius and carries the tile's shadow. The shadow
is on the frame rather than on the picture because the frame is what the entrance moves, so
the two stay together for the length of it.
*/
.portrait-row__frame {
  overflow: hidden;
  border-radius: var(--portrait-row-radius);
  box-shadow: var(--portrait-row-shadow);

  /*
  The tiles arrive one after another. The step is the photo reveal component's own knob and
  the ordinal is stamped by its script, so this is one line for any number of tiles.
  */
  --photo-reveal-step: var(--portrait-row-step);
}

/*
height: auto is not decoration. The <img> carries its intrinsic width and height in the markup
so that the tile holds its place before the picture arrives; without height: auto that
attribute beats aspect-ratio and the tile is drawn at the file's own height instead of the
design's. Caught before, on the home page and again on About-01.
*/
.portrait-row__photo {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: var(--portrait-row-ratio);
  object-fit: cover;
}

/*
The badge hangs off a bottom corner of the tile and overhangs it, which is what the frosted
plate is for — it blurs the photograph under most of itself and the page under the rest.

WHICH CORNER IS DATA AND NOT A RULE. The design places the four plates by hand, at four
different offsets with no step between them; read off the render it is one plate pinned to the
bottom left and three to the bottom right, so it is a field on the portrait and a modifier
here. A rule by index would fix the design's own arrangement in code, where the client has to
be able to change it.

The vertical padding is the instance's, and it is zero. In the export the group is 59 tall,
the plate inside it is 42, and the eight above and below are the shadow's overhang rather than
a field: 42 is the two line heights of this rung and nothing else. Taking the group's 59 would
miss the plate by seventeen.
*/
.portrait-row__badge {
  position: absolute;
  bottom: calc(var(--portrait-row-badge-out) * -1);

  --badge-pad-y: var(--portrait-row-badge-pad-y);
}

.portrait-row__badge--bottom-left {
  left: calc(var(--portrait-row-badge-out) * -1);
}

.portrait-row__badge--bottom-right {
  right: calc(var(--portrait-row-badge-out) * -1);
}

/*
The row becomes a stack, and the tiles stand in from its left edge. The inset is the stack's
rather than each tile's, so the alternation below still only has to say which way the even
ones move. --bp-sm
*/
@media (max-width: 700px) {
  .portrait-row {
    flex-direction: column;
    align-items: flex-start;
    padding-inline-start: var(--portrait-row-inset);
  }

  /*
  Stacked, a tile states the design's own width instead of sharing a row — and states it as a
  maximum, less the room the even ones need to move into. Below the design's 390 the card stops
  being wide enough for 265.5 plus that shift, and a fixed width there would put the second,
  fourth and sixth tiles past the edge of the document. Checked at 320.
  */
  .portrait-row__item {
    width: min(var(--portrait-row-item-w), 100% - var(--portrait-row-shift));
    flex: 0 0 auto;
  }

  /*
  The same offset, applied the other way: stacked, every second tile is pulled UP into the one
  above it and pushed right.

  The negative top is paired with a positive bottom because otherwise the tile after it would
  inherit the overlap — the pair is meant to close up, the next pair is not. That pairing is
  also why the last tile gives its bottom margin back: with an even number of portraits the
  positive half would otherwise leave the card padded from where the stack ends rather than
  from where the last picture does, and the design pads from the picture.

  Margins and not a translate, so the stack's own height is the height of what is in it and
  the card closes on the last tile.
  */
  .portrait-row__item:nth-child(even) {
    margin-block: calc(var(--portrait-row-offset) * -1) var(--portrait-row-offset);
    margin-inline-start: var(--portrait-row-shift);
  }

  .portrait-row__item:nth-child(even):last-child {
    margin-bottom: 0;
  }
}
