/* ============================================================
   PHOTOGRAPHS — the client's own, on the home page (and on About,
   where about.css lays the same frames out).
   Three places, each beside the sentence it is evidence for: the
   record beside How We Work's table, a block of ours on the floor
   after the credentials strip, and Schiphol under Who We Are.
   Nothing in the hero, nothing in Core Services.

   They are phone pictures from forty different rooms — a warehouse
   lit sodium, a data hall lit blue, a truck in the sun, a hi-vis vest
   in half of them — so they are graded as one set: most of the colour
   out, the accent laid back over it as hue, and grain over the lot.
   The values are tokens (--ph-*, in tokens.css).
   ============================================================ */

:root { --ph-gap: clamp(12px, 1.6vw, 24px); }

/* ---- the frame: picture, tint, grain — in that order ---- */
.ph { margin: 0; display: grid; gap: 14px; align-content: start; min-width: 0; }
.ph__frame {
  position: relative; overflow: hidden;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius);
  background: var(--ground-2);
  isolation: isolate;
  /* the edge a pale sky or ceiling cannot hold by itself — outside the
     frame, so the grain above the picture never touches it */
  box-shadow: 0 0 0 1px rgba(14, 21, 19, .07);
}
.ph__frame--tall { aspect-ratio: 4 / 5; }
.ph__frame img {
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  filter: var(--ph-grade);
}
/* the accent, as hue and nothing else */
.ph__frame::before {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: var(--accent);
  mix-blend-mode: color;
  opacity: var(--ph-tint);
  pointer-events: none;
}
/* the grain: a 180px noise tile, grey and centred on mid-grey so that
   overlay moves the picture both ways and keeps its average. Filtered in
   sRGB, or the noise comes out a stop light and only ever brightens. */
.ph__frame::after {
  content: ""; position: absolute; inset: 0; z-index: 2;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='.33 .33 .33 0 0 .33 .33 .33 0 0 .33 .33 .33 0 0 0 0 0 0 1'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='linear' slope='3.5' intercept='-1.25'/%3E%3CfeFuncG type='linear' slope='3.5' intercept='-1.25'/%3E%3CfeFuncB type='linear' slope='3.5' intercept='-1.25'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E") 0 0 / 180px 180px;
  mix-blend-mode: overlay;
  opacity: var(--ph-grain);
  pointer-events: none;
}

/* ---- the caption: a record line, then one sentence ---- */
.ph__cap { display: grid; gap: 8px; }
.ph__k {
  font-family: var(--mono); font-size: .75rem; font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.ph__t { font-size: var(--fs-body); line-height: 1.5; color: var(--ink-2); max-width: 44ch; text-wrap: pretty; }

/* ============================================================
   HOW WE WORK — the record beside his table. The table keeps its
   measure; the picture takes the width it used to leave empty, and on
   a wide screen exactly the height of the two runs: it starts on their
   headings and ends where CFL's run fades out, its caption below.
   ============================================================ */
.ph-cmp { margin-top: clamp(48px, 5vw, 80px); }
.ph-cmp > .cmp { margin-top: 0; }
.ph--record { margin-top: clamp(32px, 4vw, 48px); max-width: 560px; }
.ph--record .ph__frame--tall { aspect-ratio: 4 / 3; }
.ph--record .ph__frame img { object-position: 50% 62%; }
@media (min-width: 1100px) {
  /* rows: the table's caption, the runs, the picture's caption. The table
     and the picture each take two of them as a subgrid, so the frame —
     which has no height of its own — is as tall as the runs. */
  .ph-cmp {
    display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); grid-template-rows: auto auto auto;
    column-gap: clamp(40px, 5vw, 96px); row-gap: 22px; align-items: start;
  }
  .ph-cmp > .cmp { grid-row: 1 / span 2; grid-template-rows: subgrid; }
  .ph--record { grid-column: 2; grid-row: 2 / span 2; grid-template-rows: subgrid; row-gap: normal; margin-top: 0; max-width: none; }
  /* the subgrid keeps the table's 22px gap, so the caption comes back up
     to the 14px it has everywhere else — .ph's own gap would grow the
     frame by half the difference */
  .ph--record .ph__cap { margin-top: -8px; }
  .ph--record .ph__frame--tall { aspect-ratio: auto; align-self: stretch; }
  .ph--record .ph__frame img { object-position: 72% 58%; }
}

/* ============================================================
   ON THE FLOOR — six frames in the order a consignment goes
   through them. One size, one grid: a sequence, not a collage.
   ============================================================ */
.ph-grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(32px, 3.4vw, 52px) var(--ph-gap);
}
@media (max-width: 999px) { .ph-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* A phone stacked the six at full width, 4:5 each — five screens of
   photographs. They become a row the thumb swipes through instead, in
   the same order, the next one showing at the edge; the row bleeds to
   the screen's edges and snaps each frame to the gutter. A frame in it
   is uncovered as it comes in, without waiting on its place in the row. */
@media (max-width: 559px) {
  .ph-grid {
    grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: 78%;
    gap: 14px;
    margin-inline: calc(var(--gutter) * -1); padding: 0 var(--gutter) 6px;
    overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory; scroll-padding-inline: var(--gutter);
    scrollbar-width: none;
  }
  .ph-grid::-webkit-scrollbar { display: none; }
  .ph-grid > .ph { scroll-snap-align: start; }
  .ph-grid > .ph[data-reveal], .ph-grid > .ph[data-reveal] .ph__frame { transition-delay: 0ms; }
  .ph-grid > .ph[data-reveal] .ph__frame img { transition-delay: 0ms; }
}
.ph-grid .ph__cap { padding-top: 14px; border-top: 1px solid var(--rule); }
.ph-note {
  margin-top: clamp(36px, 4vw, 56px); padding-top: 22px; border-top: 1px solid var(--rule);
  font-family: var(--mono); font-size: .6875rem; letter-spacing: .04em; color: var(--ink-3);
}

/* ============================================================
   WHO WE ARE — Schiphol, under the headline it names. The body
   keeps the right-hand column the whole height.
   ============================================================ */
.who__in--ph > .who__ph { margin-top: clamp(28px, 3vw, 44px); }
@media (min-width: 881px) {
  .who__in--ph > .sec-head { grid-column: 1; grid-row: 1; }
  .who__in--ph > .who__ph  { grid-column: 1; grid-row: 2; margin-top: 0; }
  .who__in--ph > .who__body { grid-column: 2; grid-row: 1 / span 2; align-self: start; }
  .who__in--ph { row-gap: clamp(28px, 3vw, 44px); }
}
@media (max-width: 880px) {
  /* the picture closes the block rather than splitting the headline
     from the sentence that answers it */
  .who__in--ph > .who__ph { order: 3; }
}
