/*
 * GL Lookbook.
 *
 * The floor is white and everything on it is black, grey or a photograph.
 * The only motion is scale, blur and opacity, all of it on the compositor,
 * because a row of six cut outs is a lot of pixels to repaint and a runway
 * that stutters is worse than a runway that sits still.
 */

.gl-lb {
	--lb-ease: cubic-bezier(.16, 1, .3, 1);
	--lb-ease-spring: cubic-bezier(.34, 1.56, .64, 1);
	--lb-ease-sheet: cubic-bezier(.32, .72, 0, 1);

	--lb-morph: 900ms;
	--lb-pin-step: 150ms;

	--lb-text: #151413;
	--lb-muted: #66625c;
	--lb-line: #c8c8c8;
	--lb-stage: #fff;

	/* The shape of the runway. Depth is how far the far side of the loop
	   is from the near side, as a share of the near figure's size; sweep is
	   how wide the loop is, as a share of the visible floor. */
	--lb-depth: .87;
	--lb-sweep: .47;
	--lb-blur: 6.5px;
	/* Where round the loop a figure starts leaving and where it has gone,
	   in degrees. Narrow these to put fewer figures on the floor. */
	--lb-arc: 75;
	--lb-arc-out: 105;
	/* How much bigger the open look stands while its panel is out. The
	   figure grows from the soles, so this lifts the head, not the feet. */
	--lb-solo-grow: .08;
	/* How much of the floor the nearest figure stands in. The rest is the
	   air above, which the ones further back rise into. A figure that fills
	   its floor edge to edge has nowhere to walk back to. */
	--lb-figure: 90%;

	--lb-panel-w: 380px;
	--lb-panel-pad: 32px;
	--lb-thumb: 92px;
	--lb-gutter: clamp(20px, 4vw, 64px);
	--lb-sheet: 520ms;
	/* Air under the runway. The track finishes a few pixels off the floor,
	   which was enough when something else followed the section, but as the
	   first thing on a page it has to finish before the next one starts. */
	--lb-tail: clamp(40px, 6vw, 88px);

	position: relative;
	/*
	 * Out of the theme's container and across the whole window. A runway
	 * that stops at a content margin is a picture of a runway. The figures
	 * have to be able to walk in from off the page.
	 */
	width: 100vw;
	max-width: 100vw;
	margin-left: calc(50% - 50vw);
	margin-right: calc(50% - 50vw);
	background: var(--lb-stage);
	color: var(--lb-text);
	font-family: Helvetica, Arial, sans-serif;
	padding-bottom: var(--lb-tail);
	overflow: hidden;
}

/*
 * Standing on the first screen of a page.
 *
 * The script measures the room between the top of the section and the
 * bottom of the window and hands it back as --lb-screen, so the scene is
 * exactly one screen whatever the header above it happens to be. The stage
 * takes the slack rather than the section growing a hole under the track,
 * and the panel, which is as tall as the grid, now reaches the very bottom
 * instead of stopping short and reading as cut off. The tail goes, because
 * the fold is doing that job. Nothing here applies on a phone, or to a
 * lookbook sitting further down a page, where filling the window would
 * only open a hole.
 */
.gl-lb.is-screen {
	display: flex;
	flex-direction: column;
	min-height: var(--lb-screen, auto);
	padding-bottom: 0;
}

.gl-lb.is-screen .gl-lb__grid,
.gl-lb.is-screen .gl-lb__main {
	flex: 1 1 auto;
	display: flex;
	flex-direction: column;
	min-height: 0;
}

.gl-lb.is-screen .gl-lb__stage {
	flex: 1 1 auto;
	height: auto;
	min-height: 0;
}

/*
 * The panel is laid over the runway rather than beside it. A column that
 * appears and disappears would reflow the row every time it did, and a row
 * that reflows cannot be slid smoothly at the same moment. Overlaying keeps
 * the runway's own width fixed and leaves the script one job: shift the row
 * by half the width the panel has covered.
 */
.gl-lb__grid {
	position: relative;
}

/*
 * Every button in here is an invisible hit area, a dot or a word. The theme
 * styles buttons as buttons, which painted a black box over every look, so
 * they are reset once and dressed again below. The tag is in the selector on
 * purpose. The Elementor kit prints .elementor-kit-1912 button after this
 * file, so one class and one tag ties and loses on order. Naming the section
 * tag adds a second tag and wins, while still sitting under every
 * .gl-lb .gl-lb__* rule below, which keeps its own dressing.
 */
section.gl-lb button {
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	background: none;
	box-shadow: none;
	color: inherit;
	font: inherit;
	letter-spacing: inherit;
	text-transform: none;
	min-width: 0;
	min-height: 0;
	-webkit-appearance: none;
	appearance: none;
}

/* ---- heading ---------------------------------------------------------- */

.gl-lb__main {
	position: relative;
	display: flex;
	flex-direction: column;
	min-width: 0;
	padding: 0 0 clamp(14px, 1.6vw, 22px);
}

/*
 * The section brings its own box model. Every theme sets this, which is
 * exactly why it is easy to lean on, and the day one does not a panel with
 * padding and a width of a hundred per cent is wider than the screen.
 */
.gl-lb,
.gl-lb *,
.gl-lb *::before,
.gl-lb *::after {
	box-sizing: border-box;
}

/*
 * Nothing in here is text to be read with a caret. Dragging the runway was
 * selecting the heading and leaving a highlight flickering across it, which
 * is what a browser does for free unless you say otherwise.
 */
.gl-lb,
.gl-lb * {
	-webkit-user-select: none;
	user-select: none;
}

/* The panel is the exception. A shopper copying a product name out of it is
   doing something reasonable, and nothing in there is dragged. */
.gl-lb__panel,
.gl-lb__panel * {
	-webkit-user-select: text;
	user-select: text;
}

/*
 * The words sit above the runway with clear air between. Laying them over it
 * put the sub-line through a model's head, and no amount of nudging fixes
 * that for every look and every window at once. The floor is shortened to pay
 * for the space, which also brings the figures down to the size they are in
 * the reference.
 */
.gl-lb__head {
	padding: clamp(20px, 2.4vw, 36px) var(--lb-gutter) 0;
}

.gl-lb__title {
	margin: 0;
	font-size: clamp(28px, 3.4vw, 46px);
	font-weight: 700;
	letter-spacing: -.02em;
	line-height: 1.04;
}

.gl-lb__sub {
	margin: 10px 0 0;
	max-width: 46ch;
	font-size: 12px;
	letter-spacing: .01em;
	color: var(--lb-muted);
}

/* ---- the row ---------------------------------------------------------- */

/*
 * The stage is given a height rather than a minimum one. Everything on it is
 * sized as a percentage of the stage, and a percentage of a minimum is not a
 * number the browser will work out: the row collapses and the figures fall
 * out at their natural size, which for a 2400 pixel cut out is quite a sight.
 */
/*
 * The runway is a closed loop seen in perspective, not a row. Every figure's
 * place on it is one angle: the sine of that angle puts it left or right, the
 * cosine says how near it is, and everything else follows from how near it is.
 * Nearer means larger, sharper, further down the floor and in front of its
 * neighbours. That is the whole model, and the script writes the five
 * resulting values straight onto each figure.
 */
.gl-lb__stage {
	position: relative;
	flex: 0 0 auto;
	height: min(62vh, 560px);
	margin-top: clamp(10px, 1.4vw, 20px);
	/* The runway answers to a horizontal drag, so the browser must not read
	   one as a page scroll and take it away. Vertical is still the page's. */
	touch-action: pan-y;
	/* Figures walk in from beyond both edges and must be cut off there, not
	   allowed to spill across the rest of the page. */
	overflow: hidden;
}

.gl-lb__floor {
	position: absolute;
	inset: 0;
}

.gl-lb__look {
	position: absolute;
	left: 0;
	bottom: 0;
	height: var(--lb-figure);
	/* The width follows the photograph, so a look is as wide as its own
	   figure and never a box with air either side of it. */
	width: auto;
	/* Everything is measured from the soles. A figure grows and shrinks
	   against the floor, never against its own middle. */
	transform-origin: 50% 100%;
	/* Only transform is promised. Promising filter as well asks the browser
	   to keep twelve blurred layers alive at once, which costs more than it
	   saves. */
	will-change: transform;
	backface-visibility: hidden;
}

/*
 * The tag is in these two selectors on purpose. Elementor ships
 * .elementor img { height: auto }, which is one class and one tag, and a
 * lone class loses to it. Inside an Elementor container that rule beat the
 * figure's own height and every look fell back to its natural 2400 pixels,
 * overflowing the floor and being cut off at the knees.
 */
.gl-lb .gl-lb__figure {
	position: relative;
	display: block;
	height: 100%;
}

.gl-lb .gl-lb__img {
	display: block;
	width: auto;
	height: 100%;
	/* The cut outs carry their own alpha. Nothing may paint a box behind
	   them, which is what a stray theme rule on img tends to do. */
	background: none;
	user-select: none;
	-webkit-user-drag: none;
}

/*
 * The pool the reference lays under its figures: wider than the body, barely
 * taller than an ankle, darkest directly under the soles and gone by its own
 * edge. It sits inside the figure, so it takes the same scale and the same
 * blur as the look it belongs to and falls away with it down the runway.
 */
.gl-lb__shadow {
	position: absolute;
	/*
	 * Sat on the bottom of the element, the pool came out a finger's width
	 * below the soles and the figures read as floating: these cut outs carry
	 * about five per cent of their height as clear space under the shoe. It
	 * is lifted to the sole line instead, and narrowed, because the element
	 * is as wide as the file and the body inside it is two thirds of that.
	 */
	left: var(--lb-shadow-x, 50%);
	bottom: var(--lb-shadow-y, 4.9%);
	width: var(--lb-shadow-w, 104%);
	height: 9%;
	max-height: 46px;
	min-height: 14px;
	transform: translate(-50%, 50%);
	background: radial-gradient(closest-side, rgb(20 16 12 / .30), rgb(20 16 12 / .14) 45%, rgb(20 16 12 / .04) 75%, rgb(20 16 12 / 0));
	filter: blur(2px);
	pointer-events: none;
}

.gl-lb .gl-lb__hit {
	position: absolute;
	inset: 0;
	display: block;
	cursor: pointer;
}

.gl-lb .gl-lb__hit:focus-visible {
	outline: 1px solid var(--lb-text);
	outline-offset: 4px;
}

/* ---- the cursor ------------------------------------------------------- */

/*
 * A disc that follows the pointer and says what the runway will do if you
 * use it. It is drawn in the stage rather than set as a CSS cursor image,
 * because a CSS cursor cannot carry a word that changes.
 */
/*
 * The disc is glass over the photograph rather than a black token on top of
 * it. It grows from almost nothing when the pointer arrives and shrinks back
 * when it leaves, so it never appears or vanishes on a frame.
 */
.gl-lb__cursor {
	position: absolute;
	left: 0;
	top: 0;
	z-index: 980;
	width: 0;
	height: 0;
	pointer-events: none;
	will-change: transform;
}

.gl-lb__cursor-in {
	position: absolute;
	left: 0;
	top: 0;
	display: grid;
	place-items: center;
	width: 84px;
	height: 84px;
	margin: -42px 0 0 -42px;
	border: 1px solid rgba(21, 20, 19, .28);
	border-radius: 50%;
	background: rgba(255, 255, 255, .62);
	color: var(--lb-text);
	opacity: 0;
	transform: scale(.3);
	transition:
		transform 600ms var(--lb-ease),
		opacity 350ms linear,
		background-color 350ms linear,
		border-color 350ms linear,
		color 350ms linear;
}

.gl-lb__cursor.is-shown .gl-lb__cursor-in { opacity: 1; transform: scale(1); }
.gl-lb__cursor.is-held .gl-lb__cursor-in { transform: scale(.88); }

/* Pressed on a figure, the disc goes solid so the choice reads as made. */
.gl-lb__cursor.is-held .gl-lb__cursor-in {
	background: rgba(21, 20, 19, .9);
	border-color: rgba(21, 20, 19, .9);
	color: #fff;
}

/*
 * All three words are stacked and only one is lit. Swapping the text instead
 * would reflow the disc on the frame the word changes, which is the snap
 * that makes a cursor feel like a tooltip.
 */
.gl-lb__cursor-word {
	grid-area: 1 / 1;
	font-size: 10px;
	font-weight: 400;
	letter-spacing: .24em;
	text-transform: uppercase;
	line-height: 1;
	opacity: 0;
	transition: opacity 250ms linear, letter-spacing 700ms var(--lb-ease);
}

.gl-lb__cursor-word.is-on { opacity: 1; }
.gl-lb__cursor.is-shown .gl-lb__cursor-word { letter-spacing: .24em; }
.gl-lb__cursor-word { letter-spacing: .5em; }

/* The drawn disc is the pointer here, so the real one is put away over the
   whole stage. Leaving it on would show an arrow and a disc at once. */
@media (hover: hover) {
	.gl-lb__stage,
	.gl-lb__stage * { cursor: none; }
}

/* A pointer that cannot hover has nothing to follow, and a finger does not
   need to be told that it may drag. */
@media (hover: none) {
	.gl-lb__cursor { display: none; }
	.gl-lb__stage { cursor: auto; }
}

/* ---- pins ------------------------------------------------------------- */

.gl-lb__pins {
	position: absolute;
	inset: 0;
	z-index: 2;
	pointer-events: none;
}

.gl-lb .gl-lb__pin {
	position: absolute;
	display: block;
	width: 44px;
	height: 44px;
	margin: -22px 0 0 -22px;
	cursor: pointer;
	pointer-events: none;
	opacity: 0;
	/* Sized down to start with, so a pin arrives rather than blinks on. */
	transform: scale(.4);
	transition:
		opacity 260ms var(--lb-ease),
		transform 420ms var(--lb-ease-spring);
}

/*
 * Pins wait for the figure to finish walking forward before they arrive, then
 * come in one after another. Landing them during the walk reads as clutter,
 * because the thing they are pinned to is still moving.
 */
.gl-lb__look.is-pinned .gl-lb__pin {
	opacity: 1;
	pointer-events: auto;
	transform: scale(1);
	transition-delay: calc(var(--pin-i, 0) * var(--lb-pin-step));
}

.gl-lb__dot {
	position: absolute;
	left: 50%;
	top: 50%;
	display: grid;
	place-items: center;
	width: 24px;
	height: 24px;
	margin: -12px 0 0 -12px;
	border-radius: 50%;
	background: rgba(255, 255, 255, .86);
	-webkit-backdrop-filter: blur(6px) saturate(140%);
	backdrop-filter: blur(6px) saturate(140%);
	box-shadow: 0 1px 6px rgba(21, 20, 19, .22);
	color: var(--lb-text);
	font-size: 11px;
	font-weight: 700;
	line-height: 1;
	transition: transform 220ms var(--lb-ease-spring), background-color 220ms var(--lb-ease);
}

.gl-lb__pin:hover .gl-lb__dot {
	transform: scale(1.18);
	background: #fff;
}

.gl-lb__pin.is-active .gl-lb__dot {
	background: var(--lb-text);
	color: #fff;
}

/* ---- controls --------------------------------------------------------- */

.gl-lb__controls {
	display: flex;
	align-items: center;
	gap: 18px;
	margin-top: clamp(10px, 1.2vw, 16px);
	padding-left: var(--lb-gutter);
	/* The panel covers the right of the section when it is open, so the
	   track steps aside rather than ending up underneath it. */
	padding-right: calc(var(--lb-gutter) + var(--lb-panel-shift, 0px));
	transition: padding-right var(--lb-sheet) var(--lb-ease-sheet);
}

.gl-lb.is-open { --lb-panel-shift: var(--lb-panel-w); }

.gl-lb .gl-lb__nav {
	flex: 0 0 auto;
	display: grid;
	place-items: center;
	width: 34px;
	height: 34px;
	border-radius: 50%;
	color: var(--lb-text);
	cursor: pointer;
	transition: background-color 200ms var(--lb-ease);
}

.gl-lb__nav svg { width: 20px; height: 20px; }
.gl-lb__nav:hover { background: rgba(21, 20, 19, .06); }

.gl-lb .gl-lb__nav:focus-visible {
	outline: 1px solid var(--lb-text);
	outline-offset: 2px;
}

/* One button, two faces. Which one is showing says what pressing it does
   next, which is the only thing a play and pause pair has to get right. */
.gl-lb__play-icon { display: none; }
.gl-lb.is-paused .gl-lb__play-icon { display: block; }
.gl-lb.is-paused .gl-lb__pause-icon { display: none; }

/* With a look open the runway is not going anywhere, so the control that
   stops it has nothing to say. */
.gl-lb.is-open .gl-lb__play { opacity: 0; pointer-events: none; }
.gl-lb__play { transition: opacity 240ms var(--lb-ease); }

/*
 * The track is a short ruler at the left, not a bar across the window. Spread
 * over the full width of a section this wide, four numbers sit so far apart
 * they stop reading as one control.
 */
.gl-lb__ticks {
	display: flex;
	flex: 0 1 auto;
	margin: 0;
	padding: 0;
	list-style: none;
}

/* Everything sits together at the left, next to the track it belongs to,
   and the rest of the row is left empty. */
.gl-lb__spacer { display: none; }
.gl-lb__controls > :last-child { margin-right: auto; }

.gl-lb__ticks {
	gap: 6px;
	/* Six rules, not one. The track used to carry a hairline of its own
	   along its whole length, which bridged every gap between the rules and
	   made the six of them read as a single line with a dark bit in it. The
	   rules are the track; nothing is drawn behind them. */
	/* The open look's rule grows and the one it took over from shrinks. That
	   is a layout change, and without this it is a layout change the browser
	   is free to carry up into the row the figures stand in. */
	contain: layout;
}

.gl-lb__tick { flex: 0 0 auto; min-width: 0; }

/*
 * Each look gets a two pixel rule of its own. The one whose turn it is fills
 * left to right as the timer runs, the ones behind it stay filled, and the
 * ones ahead are empty. It is a progress bar split into chapters, which says
 * both where you are and how long until the next one without a word.
 */
.gl-lb .gl-lb__tick-btn {
	display: block;
	width: 56px;
	padding: 0;
	color: var(--lb-muted);
	cursor: pointer;
	text-align: left;
	transition: width 420ms var(--lb-ease);
}

/*
 * The open look takes the long rule. The track then says where you are
 * twice over, by ink and by length, and the name has something to sit on
 * instead of running off the end of a stub.
 */
.gl-lb__tick.is-on .gl-lb__tick-btn,
.gl-lb__tick.is-run .gl-lb__tick-btn { width: 196px; }

.gl-lb__tick-bar {
	position: relative;
	display: block;
	height: 2px;
	overflow: hidden;
	background: rgba(21, 20, 19, .14);
}

.gl-lb__tick-bar::before {
	content: "";
	position: absolute;
	inset: 0;
	background: var(--lb-text);
	transform: scaleX(var(--tick-fill, 0));
	transform-origin: 0 50%;
}

/*
 * No transition on the ink at all. The bar that is going dark is also getting
 * shorter, and two curves of different lengths pulling on the same edge is
 * what made the handover stutter: the ink eased left while the rule under it
 * ran right. The rule's own travel now carries the change, and the ink is
 * either being written every frame or it is not there.
 */
.gl-lb__tick-bar::before { transition: none; }

.gl-lb__tick-label {
	display: flex;
	align-items: baseline;
	gap: 7px;
	padding-top: 10px;
	font-size: 10px;
	letter-spacing: .12em;
}

.gl-lb__tick-num {
	font-variant-numeric: tabular-nums;
	transition: color 220ms var(--lb-ease);
}

/*
 * Only the open look is named. Six names along the track turns a control into
 * a menu, and the eye has to read all of them to find out where it is.
 */
.gl-lb__tick-name {
	max-width: 0;
	text-transform: uppercase;
	white-space: nowrap;
	overflow: hidden;
	opacity: 0;
	transition:
		max-width 420ms var(--lb-ease),
		opacity 240ms var(--lb-ease),
		color 220ms var(--lb-ease);
}

.gl-lb__tick.is-on .gl-lb__tick-name,
.gl-lb__tick.is-run .gl-lb__tick-name {
	max-width: 180px;
	opacity: 1;
}

.gl-lb__tick.is-on .gl-lb__tick-num,
.gl-lb__tick.is-on .gl-lb__tick-name,
.gl-lb__tick.is-run .gl-lb__tick-num,
.gl-lb__tick.is-run .gl-lb__tick-name { color: var(--lb-text); }

.gl-lb .gl-lb__tick-btn:focus-visible {
	outline: 1px solid var(--lb-text);
	outline-offset: 3px;
}

/* ---- the panel -------------------------------------------------------- */

/*
 * Closed until a look is opened. It is moved out by its own width rather
 * than hidden, so it slides instead of appearing, and visibility is switched
 * at the far end of the journey so nothing inside it can be tabbed to while
 * it is off screen.
 */
.gl-lb__panel {
	position: absolute;
	top: 0;
	right: 0;
	/* Over everything. Figures near the front of the loop are handed a
	   z-index of up to nine hundred, so a panel at three went under them
	   the moment it stopped being beside the runway and started
	   overlapping it. */
	z-index: 1100;
	display: flex;
	flex-direction: column;
	width: var(--lb-panel-w);
	height: 100%;
	padding: clamp(26px, 3.6vw, 44px) var(--lb-panel-pad) var(--lb-panel-pad);
	border-left: 1px solid var(--lb-line);
	background: var(--lb-stage);
	/* The sheet is over the runway, so it casts. Without it the panel reads
	   as a block of the same white page rather than a thing in front. */
	box-shadow: -24px 0 48px -24px rgba(21, 20, 19, .18);
	transform: translateX(100%);
	visibility: hidden;
	will-change: transform;
	transition:
		transform var(--lb-sheet) var(--lb-ease-sheet),
		visibility 0s linear var(--lb-sheet);
}

.gl-lb.is-open .gl-lb__panel {
	transform: none;
	visibility: visible;
	transition:
		transform var(--lb-sheet) var(--lb-ease-sheet),
		visibility 0s linear 0s;
}

/*
 * One line: what this is on the left, how many pieces on the right, a hairline
 * under both. The look's own name is already on the track below the runway,
 * and printing it twice made the panel shout.
 */
.gl-lb__panel-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding-bottom: 18px;
	border-bottom: 1px solid var(--lb-line);
}

/* What this is and how much of it, as one phrase, so the close has the whole
   right hand end of the line to itself. */
.gl-lb__panel-lead {
	display: flex;
	align-items: baseline;
	gap: 10px;
	min-width: 0;
}

.gl-lb__panel-title {
	margin: 0;
	font-size: 13px;
	font-weight: 700;
	letter-spacing: .01em;
}

.gl-lb__count {
	font-size: 10px;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--lb-muted);
}

/*
 * The reference has no close, because its panel never leaves. Ours does, so
 * it needs one. Floated in the corner above the heading it read as a mark on
 * the paper and sat on top of the piece count; on the heading line, ringed,
 * it is plainly the button that shuts this.
 */
.gl-lb .gl-lb__close {
	position: relative;
	flex: 0 0 auto;
	display: grid;
	place-items: center;
	width: 34px;
	height: 34px;
	margin: -5px -3px -5px 0;
	border: 1px solid var(--lb-line);
	border-radius: 50%;
	color: var(--lb-text);
	cursor: pointer;
	transition:
		background-color 200ms var(--lb-ease),
		border-color 200ms var(--lb-ease),
		color 200ms var(--lb-ease);
}

.gl-lb .gl-lb__close:hover {
	border-color: var(--lb-text);
	background: var(--lb-text);
	color: #fff;
}

.gl-lb .gl-lb__close:focus-visible {
	outline: 1px solid var(--lb-text);
	outline-offset: 2px;
}

.gl-lb .gl-lb__close svg { width: 15px; height: 15px; }

.gl-lb__panel-body {
	flex: 1 1 auto;
	min-height: 0;
	overflow-y: auto;
	overscroll-behavior: contain;
}

.gl-lb__items {
	margin: 0;
	padding: 0;
	list-style: none;
}

/*
 * The row is a link to the piece and, beside it, a button that opens the
 * sheet where a size is chosen. Two jobs, so two controls: a button inside
 * a link is not something a browser or a screen reader can make sense of.
 */
.gl-lb__item {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 42px;
	align-items: center;
	border-bottom: 1px solid var(--lb-line);
	/* Rows arrive with the panel rather than all at once, in the same order
	   as the pins they belong to. */
	opacity: 0;
	transform: translateY(6px);
	animation: gl-lb-row 300ms var(--lb-ease-sheet) forwards;
	animation-delay: calc(var(--row-i, 0) * 34ms);
}

@keyframes gl-lb-row {
	to { opacity: 1; transform: none; }
}

/*
 * The whole row is one link, so the theme underlines every word in it: the
 * category, the name and the price all at once. Only the name should carry
 * the underline, and only when the row is being pointed at.
 */
.gl-lb .gl-lb__piece,
.gl-lb .gl-lb__piece * {
	text-decoration: none;
}

.gl-lb .gl-lb__piece {
	display: grid;
	grid-template-columns: var(--lb-thumb) minmax(0, 1fr);
	align-items: center;
	gap: 15px;
	padding: 13px 0;
	color: inherit;
}

.gl-lb .gl-lb__plus {
	justify-self: end;
	display: grid;
	place-items: center;
	width: 38px;
	height: 38px;
	border-radius: 50%;
	color: var(--lb-text);
	cursor: pointer;
	transition: background-color 200ms var(--lb-ease);
}

.gl-lb .gl-lb__plus:hover { background: rgba(21, 20, 19, .07); }

.gl-lb .gl-lb__plus:focus-visible {
	outline: 1px solid var(--lb-text);
	outline-offset: 2px;
}

.gl-lb .gl-lb__plus svg { width: 17px; height: 17px; }

/* One button, two faces, like the pause. While its piece is open it is the
   way to shut it again, so it shows a cross. */
.gl-lb__plus-x { display: none; }
.gl-lb__plus.is-open .gl-lb__plus-x { display: block; }
.gl-lb__plus.is-open .gl-lb__plus-add { display: none; }

.gl-lb__plus.is-open {
	border: 1px solid var(--lb-line);
	border-radius: 50%;
}

.gl-lb .gl-lb__piece:hover .gl-lb__piece-name,
.gl-lb .gl-lb__piece:focus-visible .gl-lb__piece-name { text-decoration: underline; }

.gl-lb__piece:focus-visible {
	outline: 1px solid var(--lb-text);
	outline-offset: 2px;
}

/*
 * A square of room with the product floating inside it, not filling it. These
 * are cut-out pack shots of very different shapes, and cropping a long shoe
 * to a portrait box takes the toe off. No tile behind them: the cut outs
 * carry their own alpha, so a wash only draws a grey box around a piece that
 * was photographed to stand on nothing.
 */
.gl-lb__media {
	position: relative;
	width: var(--lb-thumb);
	aspect-ratio: 1 / 1;
	padding: 6px;
	overflow: hidden;
}

.gl-lb__media img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: contain;
}

/* The number belongs to the pin on the photograph, so it rides on the
   picture of the piece rather than sitting out in the type. */
.gl-lb__num {
	position: absolute;
	right: 5px;
	top: 5px;
	display: grid;
	place-items: center;
	width: 17px;
	height: 17px;
	border-radius: 50%;
	background: rgba(255, 255, 255, .92);
	color: var(--lb-text);
	font-size: 9px;
	font-weight: 700;
	line-height: 1;
}

.gl-lb__piece-eyebrow {
	display: block;
	font-size: 9px;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--lb-muted);
}

.gl-lb__piece-name {
	display: block;
	margin-top: 6px;
	font-size: 13px;
	line-height: 1.32;
}

.gl-lb__piece-price {
	display: block;
	margin-top: 5px;
	font-size: 12px;
	color: var(--lb-text);
}

/* A price that has come down shows both figures, the old one stepped back. */
.gl-lb .gl-lb__piece-price del { opacity: .55; text-decoration: line-through; }
.gl-lb .gl-lb__piece-price ins { color: var(--lb-text); }

.gl-lb .gl-lb__item.is-active .gl-lb__piece-name { text-decoration: underline; }

.gl-lb__note {
	padding: 24px 0;
	font-size: 12px;
	color: var(--lb-muted);
}

/* ---- narrow ----------------------------------------------------------- */

@media (max-width: 900px) {
	.gl-lb {
		--lb-depth: .62;
		--lb-sweep: .62;
		--lb-blur: 4.5px;
		--lb-figure: 88%;
		--lb-arc: 58;
		--lb-arc-out: 84;
		--lb-thumb: 66px;
		--lb-panel-pad: 22px;
	}

	.gl-lb__stage { height: min(56vh, 460px); }

	.gl-lb .gl-lb__tick-btn { width: 46px; }
	.gl-lb__tick.is-on .gl-lb__tick-btn,
	.gl-lb__tick.is-run .gl-lb__tick-btn { width: 92px; }

	.gl-lb__grid {
		grid-template-columns: minmax(0, 1fr);
		min-height: 0;
	}

	.gl-lb {
		--lb-panel-w: min(380px, 56vw);
		--lb-gutter: 24px;
	}

	.gl-lb__panel { padding-top: 24px; }

	/* The track has nowhere to step aside to on a screen this narrow. */
	.gl-lb.is-open { --lb-panel-shift: 0px; }

	.gl-lb__tick-name { display: none; }
}

/* ---- reduced motion --------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	/*
	 * The step forward stays, because without it there is no way to tell
	 * which look is open. What goes is the travel: the scale and the row
	 * slide land immediately, and the pins stop staggering and springing.
	 */
	.gl-lb__look,
	.gl-lb__panel,
	.gl-lb__pin,
	.gl-lb__dot {
		transition-duration: 1ms !important;
		transition-delay: 0ms !important;
	}

	.gl-lb__item {
		animation: none;
		opacity: 1;
		transform: none;
	}
}

/* ---- bits the theme may not provide ----------------------------------- */

.gl-lb .screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/*
 * When the script is driving, transform belongs to it alone. Leaving the CSS
 * transition on transform as well means two things easing the same property
 * with two different curves, which reads as a stutter at the handover.
 */
/*
 * Transform is written every frame, because it is cheap and the runway has to
 * follow a hand. Blur and fade are not: a filter is re-rasterised every time
 * its value changes, and twelve photographs re-rasterising sixty times a
 * second is most of what a stuttering carousel actually is. Those two are
 * written only when they have really changed and handed to the browser to
 * interpolate, which it can do on its own schedule.
 */
.gl-lb.is-js .gl-lb__look {
	/*
	 * Blur only. Opacity is now written every frame, which costs the
	 * compositor nothing, and easing it as well left the fade a third of a
	 * second behind the figure it belonged to: the look arrived, then
	 * caught up with its own brightness.
	 */
	transition: filter 320ms linear;
}

/* ---- phones ----------------------------------------------------------- */

/*
 * A phone gets one look, not a crowd. The arc is narrowed so only the chosen
 * figure and the shoulders of its neighbours are on the floor, and the sweep
 * is widened so those neighbours sit at the very edges rather than crowding
 * the middle. Everything else on this screen follows from there.
 */
@media (max-width: 600px) {
	.gl-lb {
		--lb-depth: .5;
		--lb-sweep: 1;
		--lb-blur: 4px;
		--lb-figure: 94%;
		--lb-arc: 46;
		--lb-arc-out: 72;
		--lb-gutter: 18px;
		--lb-thumb: 60px;
		--lb-panel-pad: 18px;
		/* The panel rises from the bottom here, so the runway does not move
		   sideways to make room for it. */
	}

	/*
	 * The whole screen, near enough. A runway is the one thing on a phone
	 * worth giving all of it to, and at half the height the figures were
	 * small enough to be a thumbnail of a runway rather than the thing.
	 */
	.gl-lb__stage { height: min(74vh, 700px); }

	.gl-lb__title { font-size: 30px; }
	.gl-lb__sub { font-size: 11px; }

	/*
	 * The arrows go. A phone changes look by pushing the runway with a
	 * thumb, which is the gesture the whole thing is built on, and two
	 * 34px targets either side of the track would take the room the track
	 * needs without adding a way of doing anything.
	 */
	.gl-lb__controls [data-gl-lb-prev],
	.gl-lb__controls [data-gl-lb-next] { display: none; }

	.gl-lb__controls { gap: 14px; }
	.gl-lb .gl-lb__tick-btn { width: 38px; }
	.gl-lb__tick.is-on .gl-lb__tick-btn,
	.gl-lb__tick.is-run .gl-lb__tick-btn { width: 76px; }

	/*
	 * The panel becomes a bottom sheet. A 380px drawer arriving from the
	 * side of a 390px screen is not a drawer, it is a new page, and it
	 * takes the look you were just reading away with it.
	 */
	.gl-lb__panel {
		left: 0;
		right: 0;
		top: auto;
		bottom: 0;
		width: 100%;
		height: auto;
		max-height: 68%;
		padding: 18px var(--lb-panel-pad) calc(var(--lb-panel-pad) + env(safe-area-inset-bottom, 0px));
		border-left: 0;
		border-top: 1px solid var(--lb-line);
		border-radius: 14px 14px 0 0;
		transform: translateY(100%);
		box-shadow: 0 -18px 40px -24px rgba(21, 20, 19, .28);
	}

	/* The grab handle says which way this thing goes. */
	.gl-lb__panel::before {
		content: "";
		position: absolute;
		left: 50%;
		top: 7px;
		width: 36px;
		height: 4px;
		margin-left: -18px;
		border-radius: 2px;
		background: var(--lb-line);
	}

	.gl-lb.is-open .gl-lb__panel { transform: none; }

	.gl-lb .gl-lb__close {
		width: 32px;
		height: 32px;
		margin: -4px 0;
	}

	.gl-lb__panel-head { padding: 6px 0 14px; }
	.gl-lb__panel-body { -webkit-overflow-scrolling: touch; }

	.gl-lb .gl-lb__piece { padding: 11px 0; gap: 13px; }
	.gl-lb__piece-name { font-size: 12.5px; }
}

/*
 * The sheet rises into room made for it, rather than over the look it is
 * describing. Shortening the runway instead left the figure behind the
 * sheet, which answers a question nobody can see the subject of. The room
 * is made over the same half second the sheet takes to arrive, so the
 * section grows with it instead of jumping.
 */
@media (max-width: 600px) {
	.gl-lb { --lb-sheet: min(42vh, 340px); }

	.gl-lb__main { transition: padding-bottom var(--lb-sheet-dur, 520ms) var(--lb-ease-sheet); }
	.gl-lb.is-open .gl-lb__main { padding-bottom: var(--lb-sheet); }

	.gl-lb__panel { height: var(--lb-sheet); max-height: none; }
}

/* ---- the pick sheet --------------------------------------------------- */

/*
 * Where a size is chosen and a piece goes in the bag. It is the only part of
 * this section that changes anything, so it is the only part that darkens the
 * page behind it and takes the keyboard.
 */
.gl-lb__pick {
	position: fixed;
	inset: 0;
	z-index: 2000;
	display: grid;
	place-items: center;
}

/*
 * Weighted above the inline rule below, which also sets a display and comes
 * later in the file. Equal weight and later position meant that once the
 * picker had been moved into a row, hidden stopped hiding it: the script
 * dutifully set the property, every check agreed the thing was gone, and it
 * sat on the screen. A toggle that cannot put a thing away is how this
 * looked from the outside.
 */
.gl-lb .gl-lb__pick[hidden] { display: none; }

.gl-lb__pick-scrim {
	position: absolute;
	inset: 0;
	background: rgba(21, 20, 19, .34);
	opacity: 0;
	transition: opacity 320ms var(--lb-ease);
}

.gl-lb__pick.is-up .gl-lb__pick-scrim { opacity: 1; }

.gl-lb__pick-sheet {
	position: relative;
	width: min(420px, calc(100vw - 32px));
	padding: 26px 26px 24px;
	background: var(--lb-stage);
	box-shadow: 0 28px 70px -30px rgba(21, 20, 19, .5);
	transform: translateY(14px) scale(.98);
	opacity: 0;
	transition:
		transform 380ms var(--lb-ease-sheet),
		opacity 260ms linear;
}

.gl-lb__pick.is-up .gl-lb__pick-sheet { transform: none; opacity: 1; }

.gl-lb .gl-lb__pick-x {
	position: absolute;
	right: 10px;
	top: 10px;
	display: grid;
	place-items: center;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	color: var(--lb-text);
	cursor: pointer;
	transition: background-color 200ms var(--lb-ease);
}

.gl-lb .gl-lb__pick-x:hover { background: rgba(21, 20, 19, .07); }

.gl-lb .gl-lb__pick-x:focus-visible {
	outline: 1px solid var(--lb-text);
	outline-offset: 2px;
}

.gl-lb .gl-lb__pick-x svg { width: 19px; height: 19px; }

.gl-lb__pick-head {
	display: grid;
	grid-template-columns: 64px minmax(0, 1fr);
	align-items: center;
	gap: 14px;
	padding: 0 44px 20px 0;
	border-bottom: 1px solid var(--lb-line);
}

.gl-lb__pick-media {
	width: 64px;
	aspect-ratio: 1 / 1;
	padding: 5px;
	overflow: hidden;
}

.gl-lb__pick-media img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: contain;
}

.gl-lb__pick-name {
	display: block;
	font-size: 14px;
	line-height: 1.3;
}

.gl-lb__pick-price {
	display: block;
	margin-top: 5px;
	font-size: 12px;
	color: var(--lb-muted);
}

.gl-lb__pick-choose { padding: 20px 0 22px; }
.gl-lb__pick-choose[hidden] { display: none; }

/* A piece can ask more than one question. The rows need air between them or
   the second reads as part of the first. */
.gl-lb__pick-group + .gl-lb__pick-group { margin-top: 18px; }

.gl-lb__pick-label {
	display: block;
	margin-bottom: 12px;
	font-size: 12px;
	font-weight: 700;
}

.gl-lb__pick-options {
	display: flex;
	flex-wrap: wrap;
	gap: 9px;
}

/*
 * A chip per choice. Round, hairline, and filled black when it is the one.
 * A size with nothing left is struck through rather than hidden, because a
 * shopper looking for their size wants to know it exists and has gone.
 */
.gl-lb .gl-lb__chip {
	min-width: 46px;
	height: 46px;
	padding: 0 14px;
	border: 1px solid var(--lb-line);
	border-radius: 999px;
	background: none;
	color: var(--lb-text);
	font-size: 12px;
	cursor: pointer;
	transition:
		background-color 180ms var(--lb-ease),
		border-color 180ms var(--lb-ease),
		color 180ms var(--lb-ease);
}

.gl-lb .gl-lb__chip:hover { border-color: var(--lb-text); }

.gl-lb .gl-lb__chip.is-picked {
	background: var(--lb-text);
	border-color: var(--lb-text);
	color: #fff;
}

.gl-lb .gl-lb__chip[disabled] {
	color: var(--lb-muted);
	border-color: var(--lb-line);
	cursor: not-allowed;
	text-decoration: line-through;
	opacity: .55;
}

.gl-lb .gl-lb__chip:focus-visible {
	outline: 1px solid var(--lb-text);
	outline-offset: 3px;
}

.gl-lb .gl-lb__pick-add {
	display: block;
	width: 100%;
	height: 52px;
	background: var(--lb-text);
	color: #fff;
	font-size: 13px;
	letter-spacing: .04em;
	cursor: pointer;
	transition: opacity 200ms var(--lb-ease);
}

.gl-lb .gl-lb__pick-add:hover { opacity: .86; }

.gl-lb .gl-lb__pick-add[disabled] {
	opacity: .34;
	cursor: not-allowed;
}

.gl-lb .gl-lb__pick-add:focus-visible {
	outline: 1px solid var(--lb-text);
	outline-offset: 3px;
}

.gl-lb__pick-note {
	margin: 12px 0 0;
	min-height: 16px;
	font-size: 11px;
	line-height: 1.4;
	color: var(--lb-muted);
}

.gl-lb__pick-note.is-bad { color: #b32d2e; }

@media (prefers-reduced-motion: reduce) {
	.gl-lb__pick-scrim,
	.gl-lb__pick-sheet,
	.gl-lb .gl-lb__tick-btn { transition-duration: 1ms; }
}

/*
 * On a wide screen the picker is not a dialog at all. It opens inside the
 * panel, under the row it belongs to, so the piece stays in front of you
 * while you choose: the thumbnail, the name and the price are already up
 * there and a floating copy of them over a dimmed page is a second place to
 * read the same thing.
 */
.gl-lb__pick.is-inline {
	position: static;
	display: block;
	z-index: auto;
	grid-column: 1 / -1;
	/*
	 * The dialog centres its sheet. Left on, a piece with no size to pick
	 * has nothing wide inside it, so the sheet shrinks to the width of the
	 * words on the button and the button lands adrift in the middle of the
	 * row instead of sitting under it.
	 */
	place-items: stretch;
}

.gl-lb__pick.is-inline .gl-lb__pick-scrim,
.gl-lb__pick.is-inline .gl-lb__pick-x,
.gl-lb__pick.is-inline .gl-lb__pick-head { display: none; }

.gl-lb__pick.is-inline .gl-lb__pick-sheet {
	width: 100%;
	padding: 0 0 18px;
	background: none;
	box-shadow: none;
	transform: none;
	opacity: 1;
}

.gl-lb__pick.is-inline .gl-lb__pick-choose { padding: 4px 0 18px; }

/* ---- the pick sheet, and the panel, on a phone ------------------------ */

@media (max-width: 600px) {
	/*
	 * Anchored to the window rather than to the section. The section is
	 * taller than a phone, so a sheet pinned to the bottom of it rises from
	 * somewhere below the fold and appears to come in from the wrong place
	 * entirely, or not to come in at all.
	 */
	.gl-lb__panel {
		position: fixed;
		max-height: 46vh;
		height: auto;
	}

	.gl-lb.is-open .gl-lb__main { padding-bottom: 0; }

	/* The look gives up the bottom of the screen when the sheet needs it,
	   and takes it all back on close. */
	.gl-lb.is-open .gl-lb__stage { height: min(46vh, 400px); }

	/*
	 * The pieces lie down and run sideways, one card at a time with the next
	 * one showing at the edge. Stacked, three rows of a piece each need more
	 * height than a phone has left once the look is still on screen.
	 */
	.gl-lb__items {
		display: flex;
		gap: 12px;
		margin: 0 calc(var(--lb-panel-pad) * -1);
		padding: 2px var(--lb-panel-pad) 8px;
		overflow-x: auto;
		overscroll-behavior-x: contain;
		scroll-snap-type: x mandatory;
		-webkit-overflow-scrolling: touch;
		scrollbar-width: none;
	}

	.gl-lb__items::-webkit-scrollbar { display: none; }

	.gl-lb__item {
		flex: 0 0 76%;
		border-bottom: 0;
		border-right: 1px solid var(--lb-line);
		padding-right: 12px;
		scroll-snap-align: start;
		/* Already in view the moment the sheet arrives, so they do not need
		   to be announced one after another as well. */
		animation: none;
		opacity: 1;
		transform: none;
	}

	.gl-lb__item:last-child { border-right: 0; }

	.gl-lb .gl-lb__piece { padding: 0; gap: 11px; }
	.gl-lb__panel-body { overflow: hidden; }

	/* The sheet rises from the bottom here too, rather than growing from
	   the middle of the screen. */
	.gl-lb__pick { place-items: end stretch; }

	.gl-lb__pick-sheet {
		width: 100%;
		padding: 18px 20px calc(20px + env(safe-area-inset-bottom, 0px));
		border-radius: 14px 14px 0 0;
		transform: translateY(100%);
	}

	.gl-lb__pick-sheet::before {
		content: "";
		position: absolute;
		left: 50%;
		top: 7px;
		width: 36px;
		height: 4px;
		margin-left: -18px;
		border-radius: 2px;
		background: var(--lb-line);
	}

	.gl-lb__pick-head { padding-top: 8px; }
	.gl-lb .gl-lb__pick-x { top: 14px; }
}

/* ---- the phone layout ------------------------------------------------- */

/*
 * The reference does not give a phone a drawer. The runway takes the top of
 * the screen, a short rule under it says where you are, and the pieces are
 * the next thing down the page: a line of cards you push sideways, with the
 * one after the one you are reading showing at the edge. Nothing slides over
 * anything, so there is nothing to open and nothing to close.
 */
@media (max-width: 600px) {
	/* Room for the heading and the top of the first card under the runway,
	   which is what says there is more down there. */
	.gl-lb__stage,
	.gl-lb.is-open .gl-lb__stage { height: min(66vh, 620px); }

	.gl-lb__main,
	.gl-lb.is-open .gl-lb__main {
		padding-bottom: 0;
		transition: none;
	}

	.gl-lb__panel,
	.gl-lb.is-open .gl-lb__panel {
		position: static;
		width: auto;
		height: auto;
		max-height: none;
		padding: 16px var(--lb-gutter) calc(10px + env(safe-area-inset-bottom, 0px));
		border: 0;
		border-radius: 0;
		box-shadow: none;
		transform: none;
		visibility: visible;
		transition: none;
	}

	/* No handle and no close: it is not a sheet and it does not leave. */
	.gl-lb__panel::before { display: none; }
	.gl-lb .gl-lb__close { display: none; }

	.gl-lb__panel-head {
		padding: 0 0 15px;
		border-bottom: 0;
	}

	.gl-lb__panel-title { font-size: 15px; }
	.gl-lb__panel-lead { gap: 9px; }

	/* The cards run to both edges of the screen while the heading above them
	   keeps the section's gutter. */
	.gl-lb__items {
		margin: 0 calc(var(--lb-gutter) * -1);
		padding: 2px var(--lb-gutter) 6px;
	}

	/*
	 * One rule, centred, six segments long, with ink in the segment whose
	 * turn it is. Numbers under it would be six more things to read on the
	 * one screen where there is least room to read them.
	 */
	.gl-lb__controls {
		justify-content: center;
		gap: 0;
	}

	.gl-lb__controls > :last-child { margin-right: 0; }
	.gl-lb .gl-lb__play { display: none; }

	.gl-lb__ticks { gap: 0; }

	.gl-lb .gl-lb__tick-btn,
	.gl-lb__tick.is-on .gl-lb__tick-btn,
	.gl-lb__tick.is-run .gl-lb__tick-btn {
		width: 15px;
		transition: none;
	}

	.gl-lb__tick-label { display: none; }
}
