/* Photo-book project single (JSON "layout": "editorial") — loaded only by
   templates/pages/portfolio-editorial.php. The whole page is black film base with dense,
   calm grain (no flicker of brightness) and a little dust behind still photographs.
   One rule for every frame: at least half the screen high, sized from the screen (14" laptop
   to 27" display). Life comes from placement — rows anchored left, right or centre, frames
   stepped down, some touching the screen edge, full frames edge to edge or as large as the
   screen allows. Text only at the end. Brief: docs/porsche-gt3-brief-art-direction.md */

.ed {
  container-type: inline-size;
  --ed-coal: #0a0a09;
  --ink: #ecebe6;
  --mute: #8d8b85;
  --ed-air: clamp(5rem, 24svh, 17rem);
  --ed-gap: clamp(1rem, 2cqw, 3rem);
  /* text frame in line with the logo; photographs use a stage up to 1920 px wide */
  --ed-frame-w: min(var(--max), calc(100cqw - (2 * var(--page-gutter))));
  --ed-side: max(var(--page-gutter), calc((100cqw - 1920px) / 2));
  --ed-stage: calc(100cqw - 2 * var(--ed-side));
  /* kickass.group noise tile, greyscale */
  --ed-grain: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.7' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  --ed-dust: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='900' height='700'%3E%3Cg fill='white'%3E%3Ccircle cx='412' cy='638' r='1.2'/%3E%3Ccircle cx='119' cy='123' r='1.6'/%3E%3Ccircle cx='676' cy='489' r='1.2'/%3E%3Ccircle cx='615' cy='628' r='1.6'/%3E%3Ccircle cx='338' cy='648' r='2.1'/%3E%3Ccircle cx='120' cy='523' r='1'/%3E%3Ccircle cx='44' cy='281' r='1'/%3E%3Ccircle cx='221' cy='551' r='0.6'/%3E%3Ccircle cx='878' cy='620' r='0.8'/%3E%3Ccircle cx='397' cy='45' r='1'/%3E%3Ccircle cx='422' cy='595' r='1'/%3E%3Ccircle cx='540' cy='282' r='0.6'/%3E%3Ccircle cx='242' cy='591' r='0.8'/%3E%3Ccircle cx='396' cy='104' r='1.2'/%3E%3Ccircle cx='257' cy='371' r='2.1'/%3E%3Ccircle cx='786' cy='433' r='1'/%3E%3Ccircle cx='174' cy='287' r='0.8'/%3E%3Ccircle cx='363' cy='364' r='1'/%3E%3Ccircle cx='64' cy='287' r='1.2'/%3E%3Ccircle cx='435' cy='188' r='0.8'/%3E%3Ccircle cx='23' cy='548' r='1'/%3E%3Ccircle cx='674' cy='382' r='1.6'/%3E%3Ccircle cx='540' cy='306' r='0.6'/%3E%3Ccircle cx='319' cy='125' r='2.1'/%3E%3Ccircle cx='96' cy='216' r='0.6'/%3E%3Ccircle cx='250' cy='293' r='1.6'/%3E%3Cellipse cx='724' cy='373' rx='3.9' ry='0.7'/%3E%3Cellipse cx='634' cy='388' rx='3.0' ry='1.0'/%3E%3Cellipse cx='693' cy='584' rx='2.2' ry='0.7'/%3E%3Cellipse cx='402' cy='441' rx='3.8' ry='0.8'/%3E%3C/g%3E%3Cg stroke='white' stroke-width='0.7' fill='none'%3E%3Cpath d='M295 40 q1.5 46 -1.3 92'/%3E%3Cpath d='M286 494 q1.6 52 -1.0 104'/%3E%3C/g%3E%3C/svg%3E");
  background: var(--ed-coal);
  color: var(--ink);
}

/* Resets at zero specificity, so every component rule below wins */
.ed :where(img, video) { display: block; max-width: none; }
.ed :where(figure, p, h1, h2, dl, dd) { margin: 0; }

.ed-frame {
  width: var(--ed-frame-w);
  margin-inline: auto;
}

.ed-hero__back,
.ed-hero__kicker,
.ed-intro__facts dt {
  font-family: var(--font-sans);
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

/* —— Opening: one photograph, full screen, the title kept small —— */
.ed-hero {
  position: relative;
  height: 100svh;
  min-height: 30rem;
  overflow: hidden;
  background: var(--ed-coal);
}
.ed-hero__media,
.ed-hero__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.ed-hero__img {
  object-fit: cover;
  object-position: var(--focus, 50% 50%);
}
.ed-hero::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: 45%;
  background: linear-gradient(to top, rgba(10, 10, 9, 0.65), rgba(10, 10, 9, 0));
  pointer-events: none;
}
.ed-hero__meta {
  position: absolute;
  inset: auto 0 clamp(2rem, 7vh, 4.5rem);
  z-index: 1;
}
.ed-hero__back {
  color: rgba(236, 235, 230, 0.72);
  text-decoration: none;
  transition: color var(--motion-fast) var(--ease-soft);
}
.ed-hero__back:hover,
.ed-hero__back:focus-visible { color: var(--ink); }
.ed-hero__title {
  margin-top: 1.1rem;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(2.25rem, 4vw, 3.75rem);
  line-height: 1;
  letter-spacing: 0.01em;
}
.ed-hero__kicker {
  margin-top: 0.9rem;
  color: rgba(236, 235, 230, 0.72);
}

/* —— Board: film base → grain and dust → still photographs —— */
.ed-board {
  position: relative;
  isolation: isolate;
  overflow: clip;
  padding-block: var(--ed-air);
}
.ed-board::before,
.ed-board::after {
  content: "";
  position: absolute;
  z-index: 1;
  pointer-events: none;
}
/* Analogue film grain: a new grain pattern every frame (~12 fps), like a projected print —
   the density and brightness never change, only the grains move */
.ed-board::before {
  inset: -240px;
  background-image: var(--ed-grain);
  background-size: 170px 170px;
  /* darken first, then stretch: the mid-grey of the noise drops to black and only the grains
     light up — dense grain on a page that stays black */
  opacity: 0.42;
  filter: brightness(60%) contrast(400%);
  animation: ed-grain 0.66s steps(1, end) infinite;
  will-change: transform;
}
/* A little dust and a hairline scratch, landing somewhere else about once a second */
.ed-board::after {
  inset: -240px;
  background-image: var(--ed-dust);
  background-size: 900px 700px;
  opacity: 0.12;
  animation: ed-dust 5s steps(1, end) infinite;
  will-change: transform;
}
.ed-board > * {
  position: relative;
  z-index: 2;
}
.ed-board > * + * { margin-top: var(--air, var(--ed-air)); }

@keyframes ed-grain {
  0% { transform: translate3d(0, 0, 0); }
  12.5% { transform: translate3d(-63px, 41px, 0); }
  25% { transform: translate3d(48px, -87px, 0); }
  37.5% { transform: translate3d(-112px, -29px, 0); }
  50% { transform: translate3d(91px, 66px, 0); }
  62.5% { transform: translate3d(-37px, 104px, 0); }
  75% { transform: translate3d(127px, -52px, 0); }
  87.5% { transform: translate3d(-84px, -118px, 0); }
  100% { transform: translate3d(0, 0, 0); }
}
@keyframes ed-grain-shift {
  0% { background-position: 0 0; }
  12.5% { background-position: -63px 41px; }
  25% { background-position: 48px -87px; }
  37.5% { background-position: -112px -29px; }
  50% { background-position: 91px 66px; }
  62.5% { background-position: -37px 104px; }
  75% { background-position: 127px -52px; }
  87.5% { background-position: -84px -118px; }
  100% { background-position: 0 0; }
}
@keyframes ed-dust {
  0% { transform: translate3d(0, 0, 0); }
  20% { transform: translate3d(-170px, 90px, 0); }
  40% { transform: translate3d(130px, -160px, 0); }
  60% { transform: translate3d(-60px, -210px, 0); }
  80% { transform: translate3d(200px, 120px, 0); }
  100% { transform: translate3d(0, 0, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .ed-board::before,
  .ed-board::after,
  .ed-row__item.is-video::after,
  body:has(.ed) .site-footer::before { animation: none; }
}

/* —— The site footer stays on the same black film base on this page —— */
body:has(.ed) { background: var(--ed-coal, #0a0a09); }
body:has(.ed) .site-footer {
  --bg: #0a0a09;
  --text: #ecebe6;
  --muted: #8d8b85;
  --border: rgba(236, 235, 230, 0.12);
  position: relative;
  isolation: isolate;
  overflow: clip;
  background: #0a0a09;
  color: var(--text);
}
body:has(.ed) .site-footer::before {
  content: "";
  position: absolute;
  inset: -240px;
  z-index: -1;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.7' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 170px 170px;
  opacity: 0.42;
  filter: brightness(60%) contrast(400%);
  animation: ed-grain 0.66s steps(1, end) infinite;
}
body:has(.ed) .site-footer a { color: var(--text); }
/* the site's back-to-top arrow, on the same black */
body:has(.ed) .to-top {
  --bg: #0a0a09;
  --text: #ecebe6;
}
body:has(.ed) .site-footer .logo__img--on-dark { opacity: 1; }
body:has(.ed) .site-footer .logo__img--on-light { opacity: 0; }

/* —— Full: edge to edge (bleed), or as large as the screen allows and never cropped (frame) —— */
.ed-full--bleed .ed-full__img {
  width: 100cqw;
  height: auto;
  max-height: 100svh;
  object-fit: cover;
  object-position: var(--focus, 50% 50%);
}
.ed-full--frame {
  display: flex;
  justify-content: center;
}
.ed-full--frame .ed-full__img {
  width: min(var(--ed-stage), calc(90svh * var(--ratio)));
  height: auto;
}

/* —— Row: one to three frames, each at least half the screen high —— */
.ed-row {
  display: flex;
  align-items: flex-start;
  gap: var(--ed-gap);
  padding-inline: var(--ed-side);
}
.ed-row--left { justify-content: flex-start; }
.ed-row--right { justify-content: flex-end; }
.ed-row--center { justify-content: center; }
.ed-row--between { justify-content: space-between; }
/* Frames meeting on one bottom line */
.ed-row.is-bottom { align-items: flex-end; }
.ed-row__item {
  flex: none;
  margin-top: var(--dy, 0);
}
.ed-row__item--square .ed-row__img {
  width: min(calc(var(--h) * 1svh), calc(var(--ed-stage) * var(--wmax) / 100));
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  object-position: var(--focus, 50% 50%);
}
.ed-row__item--natural .ed-row__img {
  width: min(calc(var(--h) * 1svh * var(--ratio)), calc(var(--ed-stage) * var(--wmax) / 100));
  height: auto;
}
/* 16:9, cropped around the focus point */
.ed-row__item--wide .ed-row__img {
  width: min(calc(var(--h) * 1svh * 16 / 9), calc(var(--ed-stage) * var(--wmax) / 100));
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  object-position: var(--focus, 50% 50%);
}
/* Touching the screen edge */
.ed-row__item.is-edge-left { margin-left: calc(var(--ed-side) * -1); }
.ed-row__item.is-edge-right { margin-right: calc(var(--ed-side) * -1); }
/* Laid over the frame before it, like two prints on a table — no frame, photo on photo */
.ed-row__item.is-over {
  position: relative;
  z-index: 1;
  margin-left: calc(var(--ed-stage) * var(--ov) / -100 - var(--ed-gap));
}
/* A silent loop in place of a photograph: same size rules, its own moving film grain on top */
.ed-row__item.is-video { position: relative; }
.ed-row__item.is-video .ed-row__img {
  aspect-ratio: var(--ratio);
  object-fit: cover;
}
.ed-row__item.is-video::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image: var(--ed-grain);
  background-size: 210px 210px;
  /* stretched around mid-grey, so overlay leaves the picture's tones and adds only grain */
  filter: contrast(320%);
  mix-blend-mode: overlay;
  opacity: 0.5;
  /* moves the pattern, not the layer, so the frame needs no clipping and can rise into place */
  animation: ed-grain-shift 0.66s steps(1, end) infinite;
}
/* Joined: frames side by side on one height, a hairline of black between — a diptych */
.ed-row.is-join {
  --ed-join: clamp(6px, 0.6cqw, 12px);
  gap: var(--ed-join);
  align-items: flex-end;
}
.ed-row.is-join .ed-row__item { margin-top: 0; }
.ed-row.is-join .ed-row__img {
  width: calc(min(var(--h) * 1svh, (var(--ed-stage) - var(--ed-join) * (var(--n) - 1)) / var(--sumr)) * var(--jr));
}

/* —— Layer: a print laid on a photograph edge to edge — the place behind, the detail on top —— */
.ed-layer {
  /* height of the photograph behind: its own proportion, never taller than the screen */
  --bgh: min(100svh, 100cqw * var(--bgk, 0.6667));
  display: grid;
  align-items: center;
}
.ed-layer > * { grid-area: 1 / 1; }
.ed-layer__bgimg {
  width: 100cqw;
  height: var(--bgh);
  object-fit: cover;
  object-position: var(--focus, 50% 50%);
}
.ed-layer__print { justify-self: center; }
.ed-layer--left .ed-layer__print { justify-self: start; margin-left: calc(var(--ed-side) + var(--ed-stage) * 0.08); }
.ed-layer--right .ed-layer__print { justify-self: end; margin-right: calc(var(--ed-side) + var(--ed-stage) * 0.08); }
.ed-layer__img {
  width: min(calc(var(--h) * 1svh * var(--ratio)), calc(var(--bgh) * 0.76 * var(--ratio)), calc(var(--ed-stage) * 0.6));
  height: auto;
}

/* —— Outro: the last frame against the left edge, facts and text in the black beside it —— */
.ed-outro {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  column-gap: clamp(3rem, 7cqw, 8rem);
  padding-right: var(--ed-side);
}
.ed-outro__img {
  width: min(calc(92svh * var(--ratio)), 46cqw);
  height: auto;
}
.ed-outro__copy {
  display: grid;
  gap: clamp(2rem, 5svh, 3.5rem);
  max-width: 31rem;
}
.ed-outro .ed-intro__facts,
.ed-outro .ed-intro__text { grid-column: auto; }
/* With a second frame: it meets the top of the tall frame, the text meets its bottom */
.ed-outro.has-second { align-items: stretch; }
.ed-outro.has-second .ed-outro__copy {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: clamp(2rem, 5svh, 3.5rem);
  max-width: none;
}
.ed-outro__img2 {
  width: min(100%, calc(52svh * var(--ratio)));
  height: auto;
}
.ed-outro.has-second .ed-intro__facts,
.ed-outro.has-second .ed-intro__text { max-width: 31rem; }
.ed-outro .ed-intro__facts {
  grid-template-columns: repeat(3, auto);
  justify-content: start;
  column-gap: clamp(1.5rem, 3cqw, 3rem);
}

/* —— Facts and two short paragraphs, at the end —— */
.ed-intro {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--ed-gap);
  row-gap: 2rem;
}
.ed-intro__facts {
  grid-column: 1 / span 3;
  display: grid;
  align-content: start;
  gap: 1.1rem;
}
.ed-intro__facts dt { color: var(--mute); }
.ed-intro__facts dd {
  margin-top: 0.35rem;
  font-family: var(--font-display);
  font-size: 1.15rem;
  letter-spacing: 0.02em;
}
.ed-intro__text {
  grid-column: 7 / span 5;
  max-width: 34rem;
  font-size: 0.9rem;
  line-height: 1.8;
  color: color-mix(in srgb, var(--ink) 82%, var(--mute));
}
.ed-intro__text p + p { margin-top: 1.1em; }

/* —— Close —— */
.ed-close {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--ed-gap);
  row-gap: 2rem;
  align-items: end;
  padding-top: clamp(2rem, 4vw, 3rem);
  border-top: 1px solid color-mix(in srgb, var(--ink) 18%, transparent);
}
.ed-close__title {
  grid-column: 1 / span 7;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(2rem, 3.6vw, 3.5rem);
  line-height: 1;
}
.ed-close__aside { grid-column: 9 / -1; }
.ed-close__body {
  margin-bottom: 1.5rem;
  font-size: 0.9rem;
  line-height: 1.75;
  color: var(--mute);
}
.ed .btn--primary {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--ed-coal);
}

@media (max-width: 1023px) {
  .ed { --ed-air: clamp(4rem, 14svh, 7rem); }
  .ed-intro__facts,
  .ed-intro__text,
  .ed-close__title,
  .ed-close__aside { grid-column: 1 / -1; }
  .ed-intro__facts { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
/* Phones: not a shrunken desktop. Frames pinned to one screen edge or the other — tall ones
   (portrait or square) large on the left, the second one of a pair smaller on the right; flat
   ones nearly full width; some pairs stacked, the second laid over the first. Edge-to-edge
   photographs become a taller 4:5 window around their own phone focus. Tablets held upright
   get the same placement — the desktop rows would leave them small frames. */
@media (max-width: 767px), (max-width: 1100px) and (orientation: portrait) {
  .ed { --ed-gap: 0.75rem; --ed-mgap: clamp(4rem, 12svh, 7rem); --ed-air: 36svh; }
  /* plenty of black between sections: each photograph gets most of a screen to itself */
  .ed-board > * + * { margin-top: max(var(--air, 0px), 40svh); }
  .ed-full--bleed .ed-full__img,
  .ed-layer__bgimg {
    height: auto;
    max-height: none;
    aspect-ratio: var(--mar, 4 / 5);
    object-fit: cover;
    object-position: var(--mfocus, var(--focus, 50% 50%));
  }
  .ed-layer { --bgh: 125cqw; }
  .ed-layer--left .ed-layer__print { margin-left: calc(var(--ed-side) + 3cqw); }
  .ed-layer--right .ed-layer__print { margin-right: calc(var(--ed-side) + 3cqw); }
  .ed-layer__img { width: min(calc(var(--bgh) * 0.7 * var(--ratio)), 62cqw); }
  .ed-full--frame .ed-full__img { width: 100cqw; }

  .ed-row {
    flex-direction: column;
    gap: var(--ed-mgap);
    padding-inline: 0;
  }
  .ed-row__item { margin: 0; align-self: flex-start; }
  .ed-row__item:nth-child(even) { align-self: flex-end; }
  .ed-row--right > .ed-row__item:only-child { align-self: flex-end; }
  .ed-row--center > .ed-row__item:only-child { align-self: center; }
  .ed-row__item.is-edge-left { margin: 0; align-self: flex-start; }
  .ed-row__item.is-edge-right { margin: 0; align-self: flex-end; }
  .ed-row__item.is-over { margin: 0; }
  /* never taller than the screen (upright tablets) */
  .ed-row .ed-row__item--natural.is-tall .ed-row__img { width: min(84cqw, calc(86svh * var(--ratio))); }
  .ed-row .ed-row__item--natural.is-tall:nth-child(even) .ed-row__img { width: min(64cqw, calc(70svh * var(--ratio))); }
  .ed-row .ed-row__item--square.is-tall .ed-row__img { width: min(84cqw, 80svh); }
  .ed-row .ed-row__item--square.is-tall:nth-child(even) .ed-row__img { width: min(64cqw, 64svh); }
  .ed-row .ed-row__item.is-flat .ed-row__img { width: 92cqw; }
  .ed-row .ed-row__item--wide.is-flat .ed-row__img { width: 100cqw; }
  /* Stacked: the second frame pulled up over the corner of the first */
  /* Joined: one under the other, a hairline apart, as wide as the screen allows */
  .ed-row.is-join { gap: var(--ed-join); }
  .ed-row.is-join > .ed-row__item { align-self: center; }
  .ed-board .ed-row.is-join .ed-row__item:is(.is-tall, .is-flat) .ed-row__img { width: min(100cqw, calc(86svh * var(--jr))); }
  /* finer, lighter grain on the loops — on a phone the desktop grain reads too coarse */
  .ed-row__item.is-video::after {
    background-size: 120px 120px;
    opacity: 0.3;
  }
  .ed-row.is-mstack > .ed-row__item + .ed-row__item {
    position: relative;
    z-index: 1;
    margin-top: calc(var(--ed-mgap) * -1 - 16cqw);
  }

  .ed-intro__facts { grid-template-columns: minmax(0, 1fr); }
  .ed-outro {
    grid-template-columns: minmax(0, 1fr);
    row-gap: clamp(2.5rem, 8svh, 4rem);
    padding-right: 0;
  }
  .ed-outro__img { width: calc(var(--ed-stage) + var(--ed-side)); }
  .ed-outro__copy { padding-inline: var(--ed-side); }
  .ed-outro__img2 { width: 100%; }
  .ed-outro .ed-intro__facts { grid-template-columns: minmax(0, 1fr); }
}
