/* ROUND 6. THE DIRECTION PHOTOGRAPHS, TO TOM'S MEASURED NUMBERS.
 *
 * Every figure here is measured from Tom's mockups at a common scale and is
 * applied as given, not re-derived:
 *
 *   layout        his design          was        now
 *   one photo     1327 x 557 = 2.38   1.50       2.38
 *   two per row    643 x 391 = 1.645  1.50       1.645
 *   three per row  418 x 239 = 1.75   1.49       1.75
 *
 * Everything rendered at 3:2 before, whatever the layout, which is why the
 * banner read 59% too tall.
 *
 * The gutter between photographs in a row is 36-40px in a 1326px container:
 * 2.8% of the container, applied proportionally rather than as a fixed pixel
 * value so it holds at every width.
 *
 * Photographs CROP to fill their frame. Never letterboxed, never distorted.
 */
.ttc-v2 { --pshot-gap: 2.8%; --ratio-1: 2.38; --ratio-2: 1.645; --ratio-3: 1.75;
          /* ROUND 9. THESE THREE ARE MEASURED, NOT DESCRIBED.
           *
           * Read off Tom's two mockup files at 1:1 by tools/mockup_corners.py,
           * which fits each corner from its whole arc and is accurate to 0.3px
           * against rounded rectangles of known radius. The two files are the
           * same design at different zoom -- the second is 1.30x the first --
           * so every value is carried across as a proportion of the PHOTOGRAPH
           * GROUP's width, which is the one thing both files and this page
           * share. The two files agree on those proportions to 2.2% at worst.
           *
           *                       mockup 1   mockup 2   / group    -> ours
           *   group width            1022       1328               1044
           *   photo radius, all 4    35.3       46.0     0.0346     36.1
           *   caption text inset     48.5       63.0     0.0474     49.5
           *   caption box height     34.5       45.0     0.0338     35.2
           *   gap photo -> caption      0          0          0        0
           *
           * Our group is within 2% of mockup 1's, so reading mockup 1 as 1:1
           * and carrying the proportion across give the same answer to within
           * a pixel. That is why the scale ambiguity between the two files
           * does not matter here. */
          --shot-radius: 36px;
          /* ROUND 13, JOB 6. THE RADIUS SCALES WITH THE GROUP, AT EVERY WIDTH.
           *
           * Round 9 measured it off Tom's mockups as 3.4483% of the
           * PHOTOGRAPH GROUP's width -- 36px on a 1044px group -- and then
           * pinned 36px everywhere, because no mockup shows a phone. On a
           * 305px-wide photograph that is a very large corner. Tom's locked
           * rule is the ratio, not the pixel, so the ratio is what is applied.
           *
           * The group's width is a straight line against the viewport below
           * 1245, measured at thirteen widths:
           *   1244 -> 1006.2   1100 -> 876.2   1024 -> 807.6   (slope 0.903)
           *    900 ->  815      768 ->  683     390 ->  305     (slope 1.0)
           * so the radius is that line times 0.034483. It lands within 0.2px
           * of the measured group at every width checked.
           *
           * `--shot-r` and not `--shot-radius`: the shared token keeps the
           * value it has, so nothing else that reads it moves. */
          --shot-r: var(--shot-radius);
          --caption-inset: 49px;
          /* there is NO gap. The photograph's bottom edge is the caption's
             top edge -- measured 0 in both files, at every photograph. */
          --strip-gap: 0px; }

.ttc-v2 .pshots {
  display: grid;
  /* COLUMN gap only as a percentage. A percentage ROW gap on a grid whose
     height comes from its content resolves against a height that does not
     exist yet: Chromium draws the gap between the rows but does not count it
     in the container, so the last photograph hung 12px out of the box and
     landed on the next row's caption. The gutter Tom measured is the one
     between photographs in a row, which is the column gap. */
  column-gap: var(--pshot-gap);
  row-gap: 22px;
  /* PART 3d: one line of space between the step's words and the first
     photograph under them -- the step's own line height, so it is one line
     at every width rather than a number that happens to look like one. */
  margin: var(--step-line) 0 0;
}
.ttc-v2 .pshots + .pshots { margin-top: var(--pshot-gap); }
/* ROUND 38, JOB 39.25 / 39.22 (g). AN UNCAPTIONED PHOTOGRAPH IS NOT STRETCHED
 * TO MATCH A CAPTIONED NEIGHBOUR.
 *
 * A grid's items stretch to the row's height by default, so a photograph with
 * no caption sitting beside one with a two-line caption was pulled down to
 * match it and the difference painted as empty card colour under the picture.
 * MEASURED on Creamy Paprika Chicken, ON rendering, 1280px: 56px, 38px and
 * 94px of dead space below three of the thirty-one boxes.
 *
 * This is NOT the fault 39.25 describes -- that one is space ABOVE the
 * photograph, and measured on the same page it is 0 of 31 boxes, because it
 * was the lazy-load fault round 37 fixed. This is the one that is still there.
 */
.ttc-v2 .pshots { align-items: start; }
.ttc-v2 .pshots.n1 { grid-template-columns: 1fr; }
.ttc-v2 .pshots.n2 { grid-template-columns: repeat(2, 1fr); }
.ttc-v2 .pshots.n3 { grid-template-columns: repeat(3, 1fr); }

/* PART 3b: NO WHITE FRAME. The photograph sits on the page with its own
 * rounded corners. A caption -- and only a caption -- puts a white strip
 * under it, the width of the image. */
.ttc-v2 .pshot {
  background: none;
  border-radius: 0;
  padding: 0;
  overflow: visible;
  min-width: 0;
}
/* ROUND 9. WHAT THE MOCKUP ACTUALLY SHOWS.
 *
 * Measured, not described. Every earlier rule here was written from a
 * sentence -- B1's "one card with a square join", its withdrawal's "a
 * separate rounded strip 2px beneath" -- and all of them were wrong, because
 * a sentence cannot carry a corner. The pixels say:
 *
 *   ONE WHITE CARD, rounded 36px on all four corners, holding the photograph
 *   and its caption. At the top of the card the page meets the PHOTOGRAPH
 *   directly -- there is no white margin above it, and the photograph's top
 *   corners are the card's top corners.
 *
 *   THE PHOTOGRAPH is rounded 36px on all four corners, flush to the card's
 *   left, right and top. Its BOTTOM corners show the white card through
 *   them: that is how you can tell it is rounded at the bottom at all.
 *
 *   THE CAPTION is the rest of that same card, immediately below the
 *   photograph. No gap -- measured 0 at every photograph in both files -- no
 *   second box, and no corners of its own except the card's bottom two.
 *
 * So the figure paints the card and the caption paints nothing. A photograph
 * with no caption keeps its four corners and needs no card behind it. */
.ttc-v2 .pshot.has-cap {
  background: #fff;
  border-radius: var(--shot-r);
}
.ttc-v2 .pshot.has-cap figcaption {
  background: none;
  border-radius: 0;
  margin-top: var(--strip-gap);
}
.ttc-v2 .pshot-img { position: relative; display: block; font-size: 0; }
.ttc-v2 .pshot figcaption { font-size: var(--caption-size); }
.ttc-v2 .pshot-img > a:first-child {
  display: block;
  border-radius: var(--shot-r);
  overflow: hidden;
  background: rgba(0, 0, 0, .04);
  cursor: zoom-in;
}
.ttc-v2 .pshots.n1 .pshot-img > a:first-child { aspect-ratio: var(--ratio-1); }
.ttc-v2 .pshots.n2 .pshot-img > a:first-child { aspect-ratio: var(--ratio-2); }
.ttc-v2 .pshots.n3 .pshot-img > a:first-child { aspect-ratio: var(--ratio-3); }
.ttc-v2 .pshot img {
  width: 100%; height: 100%; display: block; object-fit: cover;
  transition: transform .3s ease;
}
.ttc-v2 .pshot:hover img { transform: scale(1.04); }
/* ROUND 7, 2c AND 2e. THE CAPTION'S INSET IS FROM ITS OWN PHOTOGRAPH.
 *
 * Phase B's B2 pinned the standalone caption to the section heading's text
 * column and took the in-box captions' inset away entirely -- 97px on one
 * and 0 on the other, where both had been 14. Tom has withdrawn that rule:
 * a caption is positioned relative to the photograph it belongs to, the
 * same inset in a step box as standing alone, no special cases.
 *
 * 14px is the inset both had before Phase B and is read from the in-box
 * captions, which were correct throughout. */
.ttc-v2 .pshot figcaption {
  /* 8px above and below puts a one-line caption box at 35px, which is what
     both mockups measure once carried to this width. The horizontal value is
     the measured text inset. */
  padding: 8px var(--caption-inset);
  font-size: var(--caption-size);
  font-weight: var(--caption-weight);
  line-height: var(--caption-line);
  color: var(--body);
}

/* the two round buttons over the photograph's top-right corner */
.ttc-v2 .pbtn {
  position: absolute; top: 12px; width: 40px; height: 40px;
  border-radius: 50%; background-color: rgba(255, 255, 255, .82);
  background-repeat: no-repeat; background-position: center;
  background-size: 18px auto;
  transition: background-color .2s ease;
}
.ttc-v2 .pbtn:hover { background-color: #fff; }
.ttc-v2 .pbtn.pin {
  right: 60px;
  background-image: url("/ttc-media/icons/pinterest.svg");
}
.ttc-v2 .pbtn.sh {
  right: 12px;
  background-image: url("/ttc-media/icons/share-black.svg");
}

/* ROUND 6, PART 1. A PHOTOGRAPH STANDING ON ITS OWN, OUTSIDE A BOX.
 *
 * Round 5 read the mockup as "align to the content edge". Tom has overruled
 * that: the edges are the CONTENT BOX's edges, flush, not inset to the text
 * column. Measured on the pizza page it was 1386 of 1534 -- 90.4% -- and it
 * must be 100%.
 *
 * Its HEIGHT is the same as an in-box single photograph: the step's content
 * width divided by 2.38. The `::before` is what makes that exact at every
 * width without a magic number -- it is as wide as the content column
 * (the box less its two paddings) and 2.38 times shorter, and it sets the
 * height of the block. The photograph then fills the FULL width at that
 * height, cropping.
 */
.ttc-v2 .pshot.solo {
  display: block;
  /* the 22px is on `.pshot-box.solo` now -- see the note there. Zero here
     rather than deleted, because `<figure>` has a UA margin and leaving this
     line out would let `1em 40px` back in. */
  margin: 0;
  padding: 0;
}
/* ROUND 9: a captioned standalone photograph is the same white card as any
   other captioned photograph. This block used to force `background: none`
   and `border-radius: 0` on the figure, and because it comes after the
   has-cap rule at the same specificity it silently cancelled it -- the
   standalone would have been the one photograph in the design without its
   card. An uncaptioned standalone still paints nothing: there is no caption
   for a card to hold. */
.ttc-v2 .pshot.solo:not(.has-cap) { background: none; border-radius: 0; }
.ttc-v2 .pshot.solo .pshot-img::before {
  content: '';
  display: block;
  margin: 0 var(--pad-r) 0 var(--pad-l);
  aspect-ratio: var(--ratio-1);
}
.ttc-v2 .pshot.solo .pshot-img > a:first-child {
  position: absolute; inset: 0;
  aspect-ratio: auto;
  /* the token, not a number written out again -- this line said 14px while
     the token said something else, which is how the standalone photograph
     drifted away from every other one */
  border-radius: var(--shot-r);
}

@media (max-width: 1023px) {
  /* every layout becomes one photograph per row, and each keeps the banner's
     shape so a phone does not get three different heights */
  .ttc-v2 .pshots.n1,
  .ttc-v2 .pshots.n2,
  .ttc-v2 .pshots.n3 { grid-template-columns: 1fr; }
  .ttc-v2 .pshots.n2 .pshot-img > a:first-child,
  .ttc-v2 .pshots.n3 .pshot-img > a:first-child { aspect-ratio: var(--ratio-1); }
  .ttc-v2 .pbtn { width: 34px; height: 34px; background-size: 15px auto; }
  .ttc-v2 .pbtn.pin { right: 52px; }
}

/* PART 1. The article's photographs -- the ones `stepphotos.place` puts
 * beside the paragraph that talks about that step.
 *
 * The live site's own rule, from `static/embeds/embeds.css`, which the
 * recipe pages load whenever a photograph was placed. Same 3:2 crop, same
 * reserved space (the aspect-ratio is on the figure, not the image, so the
 * box exists before the file arrives and the page does not shift), same
 * rounded corner. rem to px at the theme's 10px base, as above. */
.ttc-v2 .ttc-stepshot {
  margin: 24px 0;
  aspect-ratio: 3 / 2;
  background: rgba(0, 0, 0, .04);
  border-radius: 12px;
  overflow: hidden;
}
.ttc-v2 .ttc-stepshot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* PART 1. A photograph or a callout BETWEEN two runs of steps.
 * The recipe stores these in the directions and v3 was drawing neither.
 * Both take the recipe card's own measurements rather than the theme's, so
 * they sit in the v3 page instead of looking imported into it. */
.ttc-v2 .dirshot {
  margin: 22px var(--pad-r) 22px var(--pad-l);
  aspect-ratio: 3 / 2;
  background: rgba(0, 0, 0, .04);
  border-radius: 16px;
  overflow: hidden;
}
.ttc-v2 .dirshot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ttc-v2 .dirshot figcaption {
  padding: 10px 4px 0;
  font-size: var(--caption-size);
  line-height: var(--caption-block-line);
  color: var(--body);
}

.ttc-v2 .card.note.recipe-important { border-left: 4px solid var(--red); }
.ttc-v2 .card.note.recipe-tip { border-left: 4px solid var(--orange); }
@media (max-width: 1023px) {
  .ttc-v2 .dirshot { margin-left: var(--pad-l); margin-right: var(--pad-r); }
}

/* THE CAPTION UNDER A STANDALONE PHOTOGRAPH gets the grey the content boxes
 * use -- var(--card), read from the stylesheet rather than picked -- the full
 * width of the photograph, the same rounded bottom and the same padding the
 * caption strips elsewhere already have. The photograph is unchanged. */
/* ROUND 8, B1. THE PHOTOGRAPH AND ITS CAPTION STRIP ARE ONE CARD.
 *
 * Measured at the bottom-left of the pizza's standalone photograph: the
 * photograph's left edge moved from x=29 to x=40 across fifteen rows -- a
 * rounded bottom corner -- while the grey strip under it started square at
 * x=29, and the page showed through as a white wedge.
 *
 * Only the OUTER four corners are round now: the photograph's top two and
 * the strip's bottom two. The two edges that meet are square, and there is
 * nothing between them.
 */
/* ROUND 11, ITEM 2. GREY BEHIND THE STANDALONE PHOTOGRAPH'S CAPTION.
 *
 * This one strip and nothing else: the caption under a photograph that stands
 * outside a step box -- the ingredients photograph above "1. Dough:" is the
 * example. A captioned photograph inside a step box already sits on the box's
 * own grey and is left alone, as are the photograph, the page, the content
 * boxes and the Variations rows.
 *
 * The grey is `--card`, read from the stylesheet rather than picked, so it is
 * the same grey the content boxes use and cannot drift from them.
 *
 * The bottom two corners follow the card's, because the strip sits at the
 * bottom of the white card the photograph and caption share: a square-cornered
 * grey rectangle would spill past the card's curve. Rounding the strip itself
 * keeps the change on this one element -- putting `overflow: hidden` on the
 * card would have been a change to the card. */
.ttc-v2 .pshot.solo.has-cap figcaption {
  background: var(--card);
  /* SQUARE, all four. Round 11 put the card's 36px on the strip's own bottom
     corners and that was wrong: the strip is 35px tall, so two 36px arcs meet
     in the middle and eat it from both sides -- the grey came in 4px at the
     top of the curve and 33px at the bottom, which is the "ten pixels short
     on each side, narrowing further going down" Tom measured. The strip is
     square and the CARD clips it, so the top tucks under the photograph with
     no step and the bottom carries the card's radius exactly. */
  border-radius: 0;
}
/* and this is what gives the strip its bottom corners: the card's own curve,
   clipping the square grey rectangle inside it. Scoped to the standalone, so
   captions inside a step box are untouched. The photograph is unaffected --
   it already carries the same radius the card clips to. */
.ttc-v2 .pshot.solo.has-cap { overflow: hidden; }


/* ROUND 13, JOB 6: the two bands where the group is narrower than 1044.
   Above 1245 the group is a fixed 1044 and the radius stays the measured
   36px. See the token block at the top for the measurements these come
   from. */
@media (max-width: 1244px) {
  .ttc-v2 { --shot-r: calc(3.114vw - 4.03px); }
}
@media (max-width: 1023px) {
  .ttc-v2 { --shot-r: calc(3.4483vw - 2.93px); }
}


/* ==================================================================
 * ROUND 25, JOB 25.4. THE PHOTOGRAPH AND ITS GREY STRIP.
 *
 * MEASURED FIRST, in painted pixels, before any of this was written. On
 * /preview-v3/60-min-pan-pizza/, at ten widths from 1440 down to 390:
 *
 *   white pixels in the photograph's two bottom corners:
 *     1440 -> 329    1245 -> 336   1024 -> 253   390 -> 34
 *   and every one of the ten widths had them.
 *
 * Round 8's comment says the two edges that meet are square. THE CODE DOES
 * NOT DO THAT. `.pshot-img > a:first-child` carries `border-radius:
 * var(--shot-r)` on ALL FOUR corners, and `.pshot.has-cap` behind it is
 * `#fff`, so the card's white shows through the curve at each bottom corner
 * -- a wedge, exactly where the photograph is supposed to meet the grey.
 *
 * (a)(b) THE TWO EDGES THAT MEET ARE SQUARE, in the code and not only in the
 * comment. The photograph keeps --shot-r on its TOP two corners; its bottom
 * two are 0. The strip's bottom two come from the card's own curve clipping
 * it, which is already how it works, and its top two are 0. So there is no
 * curve at the join for anything to show through.
 * ================================================================== */
.ttc-v2 .pshot.has-cap .pshot-img > a:first-child,
.ttc-v2 .pshot.solo.has-cap .pshot-img > a:first-child {
  border-radius: var(--shot-r) var(--shot-r) 0 0;
}

/* (d) --shot-r IS CONTINUOUS.
 *
 * It was three hand-fitted formulas handing over at two breakpoints, and they
 * did not meet: 27.86px at 1024 against 32.35px at 1023, a 4.49px jump, and
 * 34.71 against 36 at the 1244/1245 handover. Both are artefacts of fitting a
 * line to the VIEWPORT when the rule Tom locked is a proportion of the
 * PHOTOGRAPH GROUP -- 3.4483% of it.
 *
 * So the radius is taken from the group itself. `.pshot` is a query container
 * and `cqw` is one percent of its own inline size, which makes the radius
 * exactly 3.4483% of the photograph at every width, continuously, with no
 * formula to hand over and no width to re-fit. The three media queries below
 * stay as the fallback for a browser without container queries, where the old
 * behaviour is no worse than it was.
 */
/*
 * THE CONSTANT IS 2.8916%, NOT 3.4483%. Round 9 measured the radius as
 * 3.4483% of the photograph GROUP, and on the mockup the group was 1044px
 * wide -- 36px. `cqw` measures the PHOTOGRAPH, which on this page is 1245px
 * at the design width, so the same 36px is 2.8916% of it. The pixel the
 * mockups were measured at is unchanged at the top end and every other width
 * follows it in a straight line; only the two hand-fitted formulas are gone.
 *
 * WHAT REMAINS, AND IT IS NOT A FORMULA FAULT. The photograph itself jumps
 * width where the page's layout changes -- 1245px at 1245 against 1204 at
 * 1244, and 984 at 1024 against 1023 at 1023, because the page's side padding
 * goes away. A radius that is a fixed proportion of the photograph must step
 * with it: 1.19px at the first and 1.13px at the second, against the 4.49px
 * the old handover produced. Removing the last of it means changing the
 * page's padding, which is not this round's to change.
 */
/* 19 SEPTEMBER, ITEM 3. THE CARD MEASURES ITSELF NOW.
   `.pshot-box` is the wrapper app/recipe_v3.py puts round every figure, and
   it is the container. The FIGURE is a descendant of it, so `2.8916cqw` on
   the figure finally means 2.8916% of the figure's own width instead of the
   page's -- which is the whole of this item. `.pshot` stays a container as
   well, so everything already inside it keeps resolving exactly as it did.
   The wrapper carries `min-width: 0` for the same reason `.pshot` does: a
   grid item's default minimum is its content, and a wide photograph would
   otherwise refuse to shrink. */
.ttc-v2 .pshot-box { display: block; min-width: 0; }
/* AND THE STANDALONE'S MARGINS MOVE OUT WITH IT.
   MEASURED, the first time the wrapper went in: every figure on the page --
   265 of them across two recipes and five widths -- moved DOWN BY EXACTLY
   22px, and nothing else changed at all: the same sizes, the same internal
   boxes, to three decimals. `container-type` applies layout containment, so
   the wrapper is a block formatting context, and a margin does not collapse
   out of one. `.pshot.solo`'s `margin: 22px 0` used to collapse with the flow
   around it; inside the box it was added to it instead, twice, and everything
   below shifted.
   So the margin lives on the OUTSIDE of the box, where it collapses exactly
   as it did before, and the figure has none of its own. The wrapper carries
   the same modifier class as the figure -- app/recipe_v3.py puts it there --
   rather than `:has()`, so this does not depend on a selector an older
   browser may not have. Re-measured after: 265 of 265 figures identical,
   absolute y included. */
.ttc-v2 .pshot-box.solo { margin: 22px 0; }
@supports (container-type: inline-size) {
  .ttc-v2 .pshot-box { container-type: inline-size; }
  .ttc-v2 .pshot { container-type: inline-size; }
  .ttc-v2 .pshot .pshot-img > a:first-child,
  .ttc-v2 .pshot.has-cap { --shot-r: 2.8916cqw; }
}


/* ==================================================================
 * PHASE A, 19 September. THE STANDALONE PHOTOGRAPH'S TOP CORNERS.
 *
 * THE FAULT, measured before anything was changed. On a standalone
 * photograph the top-left and top-right corners painted the CARD'S GREY
 * inside the photograph's own rounded corner -- at 1440 the grey reached
 * 11px along the diagonal before the picture began, at 1024 8px, at 390 3px.
 * `document.elementsFromPoint` at the corner returned SPAN.pshot-img with
 * `background-color: rgb(247,247,247)` and `border-radius: 0px`, and nothing
 * above it.
 *
 * WHAT PUT IT THERE, and it was put there on purpose for the other end.
 * recipe-v3.css line 1484:
 *
 *     .ttc-v2 .pshot .pshot-img,
 *     .ttc-v2 .pshot .pshot-img > a:first-child { background-color: #f7f7f7 }
 *
 * Its own comment says why: "the photograph carries the strip's own colour
 * behind it, so a rounded BOTTOM corner can only ever reveal #f7f7f7,
 * whatever the theme paints underneath at any width". That is right, and it
 * is still right. The trouble is that `.pshot-img` is a SQUARE box, so the
 * same grey also sits inside the photograph's TOP corners, where there is no
 * strip for it to belong to and where the page is what should show.
 *
 * SO THE GREY IS SHAPED, NOT REMOVED. The top two corners take the
 * photograph's own radius; the bottom two stay square, so the strip, the
 * bottom join and the figcaption are untouched -- this rule sets no bottom
 * radius at all. `overflow` is not touched either: a background is clipped to
 * its own border box by default, so the corner is shaped without clipping the
 * buttons or anything else inside.
 *
 * --shot-r HAS TO BE RE-DECLARED HERE, and this is the part that is easy to
 * get wrong. `cqw` is one percent of the nearest ANCESTOR container, and
 * `.pshot` is the container -- so `--shot-r: 2.8916cqw` set on `.pshot.has-cap`
 * computes against the page, not against itself: 41.639px at 1440 where the
 * photograph's own is 36.000px. That value then INHERITS down. Taking
 * `var(--shot-r)` here without re-declaring it would have rounded this box
 * 5.6px more than the photograph it is meant to hug, which is the same fault
 * again with a different number. Declared on `.pshot-img`, which is inside
 * the container, it resolves against the photograph and comes out at 36.000.
 * ================================================================== */
@supports (container-type: inline-size) {
  .ttc-v2 .pshot.solo .pshot-img { --shot-r: 2.8916cqw; }
}
.ttc-v2 .pshot.solo .pshot-img {
  border-top-left-radius: var(--shot-r);
  border-top-right-radius: var(--shot-r);
}
