/* L44 Gallery — the polaroid scatter.
 * -------------------------------------------------------------------------
 * Prints laid out along a line, each turned a little and nudged up or down, so
 * they read as a handful dropped on a table rather than a row. The frames are
 * the Instax outlines, and every figure below comes from measuring them.
 *
 * The script places them; this describes what one is.
 */

.l44g--polaroid {
	position: relative;
	margin: var(--l44g-above, 60px) 0 var(--l44g-below, 60px);
	font-family: "CoFoSans Regular", "CoFo Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
	color: #181617;

	/* A layer of its own. A hovered print is lifted above its neighbours, and
	   without this that lift would be measured against the whole page.
	   
	   It also decides what happens where the spacing is set below nothing and
	   the gallery overlaps what is around it: the row sits above whatever comes
	   before it and below whatever comes after, which is the order they are
	   written in and the one a reader would expect. */
	z-index: 0;
	isolation: isolate;
}

.l44g__scatter {
	position: relative;
	width: 100%;
	/* Height is set by the script, from the tallest print and how far they are
	   allowed to wander vertically. */
	overflow-x: auto;
	overflow-y: visible;
	scrollbar-width: none;
	-ms-overflow-style: none;
	/* Both ways.
	   
	   The row scrolls sideways and the page scrolls down, and a finger has to be
	   able to do either. pan-y alone told the browser to allow only the vertical
	   one — so the sideways scroll this box exists for could not happen by touch
	   at all, which is why the row would not swipe on a phone.
	   
	   The line and the wheel are different: there the sideways movement is the
	   script's own doing, so the browser is right to be told to keep out of it.
	   Here the browser is doing the scrolling. */
	touch-action: pan-x pan-y;
}
.l44g__scatter::-webkit-scrollbar { display: none; }

/* The spread can be wider than the page, so the prints live on a floor of
   their own that the scatter scrolls across. */
.l44g__floor {
	position: relative;
	height: 100%;
}

/* The light's direction, declared so the browser knows it is an angle.
   
   A custom property is text as far as the browser is concerned, so a change
   from 111deg to 106deg is a change from one string to another — nothing to
   move between, and the band jumps while the print turns smoothly under it.
   Saying what kind of value it holds makes it a number the browser can travel
   through, and the two then move together. */
@property --l44g-light {
	syntax: "<angle>";
	inherits: true;
	initial-value: 106deg;
}

.l44g__print {
	position: absolute;
	top: 0;
	left: 0;
	/* The height drives everything: the frame's width follows from its own
	   proportions, and the window and caption from that. */
	height: var(--l44g-print-h, 300px);
	transform-origin: 50% 50%;
	transition:
		transform 0.42s cubic-bezier( .22, .61, .36, 1 ),
		--l44g-light 0.42s cubic-bezier( .22, .61, .36, 1 ),
		filter 0.42s ease;
	will-change: transform;
	cursor: default;
}

/* The three shapes, straight from the files. Only the width differs — every
   frame is the same height and has the same bottom band. */
.l44g__print--mini   { aspect-ratio: 190 / 300; }
.l44g__print--square { aspect-ratio: 250 / 300; }
.l44g__print--wide   { aspect-ratio: 375 / 300; }

/* The picture, behind the frame.
   
   It fills the window and is cut off at the outer edge of the print rather than
   at the window's, so a picture that overflows is hidden by the surround rather
   than by a second, tighter clip. */
.l44g__shot {
	position: absolute;

	/* Under the frame, which is what gives it its edges. */
	z-index: 1;
	overflow: hidden;
	background: #e8e6e3;

	/* Percentages of the print, from the paths: the window starts 23.15 of 300
	   down and is 215 tall in every one of them. */
	top: 7.7167%;
	height: 71.6667%;
}

/* The sides differ, because the frames are different widths. */
.l44g__print--mini   .l44g__shot { left: 7.8947%; right: 7.8947%; }
.l44g__print--square .l44g__shot { left: 7%;      right: 7%; }
.l44g__print--wide   .l44g__shot { left: 4%;      right: 4%; }

/* The look of the print itself, over the whole of it.
   
   Over the frame as well as the picture, because a polaroid is one object: the
   light that falls across the photograph falls across the white surround too,
   and emulsion grain on the picture with a clean white border around it reads
   as a filter applied to a photograph rather than a print of one. They were
   inside the window before, which is exactly what that looked like.
   
   Two layers, because they are two different things. The sheen is a wash of
   light across the surface, as a print catches the room it is held in — it goes
   on in screen, so it lightens without washing the colour out. The grain is the
   emulsion, and goes on in overlay so it darkens as well as lightens and reads
   as texture in the picture rather than dust on top of it.
   
   Drawn rather than fetched. A noise image would be another request, another
   thing to cache and another thing to go missing; this is a filter the browser
   runs once and paints from. */
.l44g__print::before,
.l44g__print::after {
	content: "";
	position: absolute;
	inset: 0;

	/* Above the frame, which is drawn after the picture and would otherwise
	   cover them. */
	z-index: 5;
	pointer-events: none;
}

.l44g__print::after {
	/* A band of light across the face of the print, brightest along a line and
	   falling away either side of it — a print held under a lamp, rather than a
	   wash over the whole picture.
	   
	   It was a gradient from edge to edge before, which spreads the same light
	   over the whole surface and comes to almost nothing at any strength worth
	   using. The eye reads a highlight by its edge, not by its brightness. */
	/* How far the band reaches either side of its brightest line.
	   
	   One figure, used twice over: a narrow reach makes a hard edge, a wide one
	   a soft wash across most of the print. The stops are worked out from it
	   rather than written down, so there is one number to change rather than
	   four to keep in agreement. */
	--l44g-sheen-far: calc( 26% * var(--l44g-soft, 1) );
	--l44g-sheen-near: calc( 12% * var(--l44g-soft, 1) );

	background:
		/* One band, and nothing else.
		   
		   There was a glow in one corner too, and a corner belongs to the print
		   rather than to the room — so it turned with the print however
		   carefully the band was held still, and one part of the light pivoting
		   gives the whole thing away.
		   
		   The angle arrives worked out, not worked out here.
		   
		   A gradient inside a rotated print rotates with it, so each print
		   caught the light from a different side — a dozen lamps rather than
		   one window. The script takes each print's own turn off the light's
		   direction and sets the answer.
		   
		   Done there rather than with calc() because the turn can be negative,
		   and "calc( 106deg + -5.7deg )" is the plus-then-minus that CSS is
		   strict about — the kind of thing that is dropped in silence, leaving
		   the light doing exactly what it did before. */
		linear-gradient( var(--l44g-light, 106deg),
			rgba( 255, 255, 255, 0 ) calc( 34% - var(--l44g-sheen-far) ),
			rgba( 255, 255, 255, calc( var(--l44g-sheen, 0.3 ) * 0.35 ) ) calc( 34% - var(--l44g-sheen-near) ),
			rgba( 255, 255, 255, var(--l44g-sheen, 0.3 ) ) 34%,
			rgba( 255, 255, 255, calc( var(--l44g-sheen, 0.3 ) * 0.25 ) ) calc( 34% + var(--l44g-sheen-near) ),
			rgba( 255, 255, 255, 0 ) calc( 34% + var(--l44g-sheen-far) ) );
	mix-blend-mode: screen;
}

.l44g__print::before {
	background-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23g)'/%3E%3C/svg%3E" );
	background-size: 160px 160px;
	opacity: var(--l44g-grain, 0.14);

	/* Soft light rather than overlay.
	   
	   Overlay leaves a mid-tone exactly as it found it, so on anything close to
	   middle grey the grain simply is not there — which is most of a
	   photograph, and all of a flat colour. Soft light moves a mid-tone too, so
	   the texture reads across the whole picture instead of only in its
	   highlights and shadows. */
	mix-blend-mode: soft-light;
}

.l44g__shot img,
.l44g__shot video {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;      /* fills the window whichever way round it is */
	pointer-events: none;
	user-select: none;
	-webkit-user-drag: none;
}

/* The white surround, over the picture. An outline with a hole in it, so what
   is behind shows through the window and nowhere else. */
.l44g__frame {
	position: absolute;
	inset: 0;

	/* Below the light and the grain, which are laid over the whole print. */
	z-index: 3;
	pointer-events: none;
	background-repeat: no-repeat;
	background-size: 100% 100%;
	filter: drop-shadow( 0 3px 8px rgba( 24, 22, 23, 0.22 ) );
}

/* The caption, in the band below the window.
   
   Right edge against the window's right edge — which in each frame is the same
   inset as its left — and two lines at most: the band is 61.85 of 300 tall, and
   two lines of ten point sit in it with room to breathe where three fill it to
   the edges. */
.l44g__caption {
	position: absolute;

	/* Above the frame, below the light.
	   
	   The caption is written on the white band, and the frame is the white
	   band — so once the frame was given a layer of its own the caption went
	   behind it and the writing simply vanished. It takes the light and the
	   grain like everything else printed on a polaroid, so it sits under
	   those. */
	z-index: 4;
	bottom: 6.5%;
	text-align: right;
	line-height: 1.16;
	color: #181617;

	/* Ten point at the size the frames were drawn, and in proportion to the
	   print at any other, so it never outgrows its band. */
	font-size: calc( var(--l44g-print-h, 300px) * 0.0444 );

	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	pointer-events: none;
}

.l44g__print--mini   .l44g__caption { right: 7.8947%; left: 20%; }
.l44g__print--square .l44g__caption { right: 7%;      left: 20%; }
.l44g__print--wide   .l44g__caption { right: 4%;      left: 30%; }

/* A print that can be opened or followed says so. */
.l44g__print.has-link { cursor: pointer; }

@media (max-width: 700px) {
	/* The phone's own spacing, which the section carries alongside the
	   desktop's — a scatter wants less air around it on a narrow screen, where
	   there is less of everything. */
	.l44g--polaroid { margin: var(--l44g-above-m, 24px) 0 var(--l44g-below-m, 24px); }
}

/* The light does not change when a print is picked out.
   
   It brightened on hover, which meant the light followed the pointer around the
   row — a lamp that moves is not a lamp. Standing the print up and straightening
   it is enough to say which one is being looked at. */

@media (prefers-reduced-motion: reduce) {
	.l44g__print { transition: none; }
}


/* Hidden until the script has laid them out, so the left-edge resting place
   the stylesheet gives them is never seen — they appear already gathered in the
   middle and spread from there. If the script never runs, they are shown
   anyway after three seconds rather than kept hidden for good. */
.l44g--polaroid .l44g__floor:not(.is-placed) .l44g__print {
	visibility: hidden;
	animation: l44g-print-fallback 0s 3s forwards;
}

@keyframes l44g-print-fallback {
	to { visibility: visible; }
}

/* ---- a caption that was worked out rather than typed ----
 *
 * The band above is built for a few words set against the right edge of the
 * print — a fifth of the width is given back to the picture, and two lines is
 * all it holds. That is right for a caption somebody wrote.
 *
 * A show's prints carry the show's own title and the artist beneath it, and a
 * title is as long as it is. So here the band runs the full width of the
 * print and holds three lines: two for a long title, balanced so neither is a
 * stub, and one for the artist. Only where the caller asked for it.
 * ------------------------------------------------------------------------- */

/* Centred in the band rather than hung from its foot.

   A caption is anchored to the bottom of the print and grows upward, which is
   right while it is one line or two: it sits where a caption sits and the band
   is deep enough to hold it. A third line grows past the band and over the
   photograph — measured on a 300px print, the writing reached three pixels
   into the picture.

   So where three lines are expected the caption is given the band itself and
   centres inside it. The figures are the window's own: it starts 7.7167% down
   and is 71.6667% tall, so everything below 79.3834% is white paper and that
   is what the writing gets. One line or three, it now sits in the middle of
   the space rather than against one edge of it. */
.l44g--polaroid.is-capwide .l44g__caption {
	top: 79.3834%;
	bottom: 0;

	display: flex;
	flex-direction: column;
	justify-content: center;

	/* The clamp above is a -webkit-box trick and does not survive flex. It is
	   not needed here either: the band's own height is the limit, and anything
	   that will not fit in it is cut off by the overflow already set. */
	-webkit-line-clamp: none;

	/* A little tighter than a typed caption, so three lines sit comfortably in
	   a band that was drawn with two in mind. */
	line-height: 1.12;
}

/* The same air at the left as at the right, rather than a fifth of the print. */
.l44g--polaroid.is-capwide .l44g__print--mini   .l44g__caption { left: 7.8947%; }
.l44g--polaroid.is-capwide .l44g__print--square .l44g__caption { left: 7%; }
.l44g--polaroid.is-capwide .l44g__print--wide   .l44g__caption { left: 4%; }

/* The title takes the width it needs and breaks itself evenly.
   
   text-wrap: balance is the browser doing what you would do by hand — trying
   the break points and choosing the one that leaves the two lines closest in
   length, rather than filling the first line and leaving three words on the
   second. Where it is not understood the title simply wraps as it always
   would, which is the old behaviour and not a fault. */
.l44g--polaroid.is-capwide .l44g__cap-title {
	display: block;
	text-wrap: balance;
}

.l44g--polaroid.is-capwide .l44g__cap-by {
	display: block;
}
