/* LoudMemories — shared design system.
   Loaded only by pages that opted into the new design ($lmNewDesign = true).
   Ladder: 320 / 480 / 768 / 1024 / 1280 / 1536.
   Type in rem so it scales with the reader's browser setting.
   Palette (AAA pairings — do not drift):
     bg #121417 · panel #1B1E22 / #23262B · ink #ECEEE8 · muted #B5B5B5
     green #57B76C / #7BC489 / #1F4A2C · gold #DFAE52 / #4A3A1B · red #F0A49D
     on green tints #C7E8CF · on gold tints #F2D9A0 · on ivory paper #4A4E54 */

/* The palette.

   Declared on the four components that are ivory *by design* as well as on
   :root. The memory card, the front-page sheet, the polaroid mount and the
   white provider button are all written as --lm-ink over --lm-bg — which is
   the very inversion the light theme performs, so on light they would have
   turned into black cards on an ivory page. Holding the palette on the
   elements themselves means the light theme's overrides, which land on
   :root, are not inherited into them: a sheet of paper looks like a sheet
   of paper under either theme, and none of their own rules had to change.

   Shadows are deliberately left out of this block, further down with the
   layout values, so that a card's drop shadow still softens on light. */
:root,
.lm-card,
.ix-paper,
.ix-polaroid,
.lg-provider.is-light {
	--lm-bg: #121417;
	--lm-panel: #1B1E22;
	--lm-panel-2: #23262B;
	--lm-ink: #ECEEE8;
	--lm-muted: #B5B5B5;
	--lm-green: #57B76C;
	--lm-green-lt: #7BC489;
	--lm-green-dk: #1F4A2C;
	/* Was #D9A441, which measured 6.75:1 on --lm-panel-2 and so missed the 7:1
	   this design holds to. That is not a corner case: gold is the link colour,
	   and links sit on panel-2 all over the site. #DFAE52 is the same hue a
	   step lighter and clears the bar on all three dark grounds -- 7.45 on
	   panel-2, 8.22 on panel, 9.06 on the page. Where gold is a fill rather
	   than text the change only lifts it away from the dark ink on top. */
	--lm-gold: #DFAE52;
	--lm-gold-dk: #4A3A1B;
	--lm-red: #F0A49D;
	--lm-on-green: #C7E8CF;
	--lm-on-gold: #F2D9A0;
	--lm-on-red: #F6DAD6;
	--lm-on-paper: #4A4E54;
	/* The placeholder on the front-page sheet: the words the card shows before
	   anything has been typed into it. It was a hex literal over in index.css
	   -- the one thing the palette rule says never to write -- and at #686C72
	   it measured 4.52:1, an AA value on a site that holds text to 7:1.

	   7.05:1 on the sheet. It has to read as waiting rather than written, and
	   it still does: the writing on the card is --lm-bg on the artist line and
	   --lm-panel-2 on the quote, which inside the sheet are #121417 and
	   #23262B, so this is plainly the lighter of the two. Measuring it against
	   --lm-on-paper is what made the first attempt at this look impossible --
	   that token is not what the real text uses.

	   The sheet does not invert, so this is one colour under both themes. */
	--lm-on-paper-soft: #4B4F55;

	/* Text on a filled accent (a green button, a red one). Separate from
	   --lm-bg, which it used to borrow: on the light theme the fill goes dark
	   and this has to go pale, while --lm-bg goes the other way. */
	--lm-on-accent: #121417;
	/* The hover shades of those fills. Were #6BC77F and #F4B8B2, written
	   inline in eleven places. */
	--lm-green-hi: #6BC77F;
	--lm-red-hi: #F4B8B2;

	/* Shades that were hex literals in the area stylesheets. Naming them here
	   is what lets the light theme reach them at all. */
	--lm-green-mid: #3A6E48;   /* the fill of a bar in a chart */
	--lm-red-mid: #ED8981;     /* the heat filter, beside green-lt and gold */
	--lm-red-dk: #4A231F;      /* and its tint, beside green-dk and gold-dk */
	--lm-band: #3A4048;        /* the band the coupons sit on */
	--lm-void: #191C20;        /* a calendar cell outside the month */
	--lm-well: #1F2226;        /* a list row lifting under the cursor */
	--lm-map-outline: #3A4048; /* a country nobody here has played, on the map */

	/* Alpha washes have to be mixed from the theme's own channels, or a
	   hairline written as pale-ink-at-12% survives into the light theme as
	   near-white on near-white and the panel loses its edge. Every border and
	   tint on the site is built from these. */
	--lm-ink-rgb: 236, 238, 232;
	--lm-bg-rgb: 18, 20, 23;
	--lm-panel-rgb: 27, 30, 34;
	--lm-green-rgb: 87, 183, 108;
	--lm-green-lt-rgb: 123, 196, 137;
	--lm-green-dk-rgb: 31, 74, 44;
	--lm-gold-rgb: 223, 174, 82;   /* keeps step with --lm-gold above */
	--lm-gold-dk-rgb: 74, 58, 27;
	--lm-red-rgb: 240, 164, 157;
	--lm-red-mid-rgb: 237, 137, 129;
	--lm-red-dk-rgb: 74, 35, 31;
	--lm-red-deep-rgb: 120, 40, 36;
	--lm-muted-rgb: 181, 181, 181;
	--lm-on-gold-rgb: 242, 217, 160;
	--lm-line: rgba(var(--lm-ink-rgb), .12);
	--lm-line-strong: rgba(var(--lm-ink-rgb), .22);
}

:root {
	/* Not part of the palette above: a shadow is cast onto the page rather
	   than drawn on the component, so it follows the theme even under the
	   paper the palette holds back. */
	--lm-scrim-rgb: 9, 10, 12;
	--lm-shadow-rgb: 0, 0, 0;

	/* What an autofilled field is painted over with, above. Most take their
	   own background; a field that is transparent takes the colour of the box
	   around it, and that box sets this beside the background it sets — which
	   is what stops the list of exceptions this used to be from going stale
	   every time a new search box is drawn. Defined once, in terms of a token
	   that already flips, so it needs no light value of its own. */
	--lm-field-fill: var(--lm-bg);

	--lm-sans: Oswald, "Helvetica Neue", Arial, sans-serif;
	--lm-serif: "Source Serif 4", Georgia, "Times New Roman", serif;
	--lm-mono: "JetBrains Mono", "SFMono-Regular", Consolas, monospace;
	--lm-max: 1040px;

	/* Breakpoint-driven values fluid math cannot express. */
	--lm-gutter: 1rem;
	--lm-sec-gap: 2.5rem;
	--lm-share-cols: 1fr;
}
@media (min-width: 480px)  { :root { --lm-gutter: 1.25rem; } }
@media (min-width: 768px)  { :root { --lm-gutter: 1.5rem; --lm-sec-gap: 3.25rem; --lm-share-cols: 0.85fr 1.15fr; } }
@media (min-width: 1024px) { :root { --lm-gutter: 1.75rem; --lm-sec-gap: 4rem; } }

/* ------------------------------------------------------------ light theme

   The same palette, read from the other end. Nothing here is a new idea about
   what green or gold mean on this site: the pale tint that is a *background*
   on dark becomes the *text* on light, and the deep one that is the text
   becomes the background. That is why the pairs below look like the palette
   above with its two halves exchanged.

   Five values are genuinely new, because the dark palette had nothing to play
   their part: two raised panels (nothing existed lighter than the ink), a red
   dark enough to read on paper, and the two hover shades that go a step
   darker on light where they went a step lighter on dark. Every text pairing
   here was measured at 7:1 or better against the surface it lands on, which
   is the bar the dark palette already meets.

   There are three settings but only two themes: 'system' is resolved to one
   of these by the script in core/headerScripts.php before the first paint, so
   the attribute on <html> is only ever 'dark' or 'light' and this stylesheet
   never has to ask twice. Dark remains the default — an unset preference, or
   no JavaScript at all, gets the theme the site has always had. */

:root[data-theme="light"] {
	--lm-bg: #ECEEE8;          /* was the ink */
	--lm-panel: #F5F6F1;       /* new: nothing in the palette was lighter */
	--lm-panel-2: #FBFBF8;     /* new: and nothing lighter again */
	--lm-ink: #121417;         /* was the background */
	--lm-muted: #44484E;       /* a step darker than the ink on paper: at 7.16:1
	                              that one cleared the page but not the tinted rows
	                              a muted line often sits on. 7.87:1 here, and
	                              still AAA on the gold and green tints. */

	--lm-green: #1F4A2C;       /* was the deep green */
	--lm-green-lt: #1F4A2C;    /* the workhorse accent, 8.66:1 */
	--lm-green-dk: #C7E8CF;    /* was the text on green, now the tint */
	--lm-on-green: #1F4A2C;    /* and the text on that tint, 7.65:1 */
	--lm-gold: #4A3A1B;        /* was the deep gold, 9.39:1 */
	--lm-gold-dk: #F2D9A0;     /* was the text on gold, now the tint */
	--lm-on-gold: #4A3A1B;     /* 7.95:1 on it */
	--lm-red: #6B2620;         /* new: the pale red is unreadable on paper */
	--lm-red-mid: #6B2620;
	--lm-red-dk: #F6DAD6;      /* its tint, beside green-dk and gold-dk */
	--lm-on-red: #6B2620;      /* and the text on that tint */

	--lm-on-accent: #ECEEE8;   /* the fills went dark, so their labels go pale */
	--lm-green-hi: #163A21;    /* new: hover darkens here, where dark lightens */
	--lm-red-hi: #5E231D;      /* new: likewise */
	--lm-green-mid: #2A5F38;
	--lm-band: #E3E5DE;
	--lm-void: #E3E5DE;
	--lm-well: #E9EBE4;
	--lm-map-outline: #C6CAC2;  /* the tiles under it are pale too */

	--lm-ink-rgb: 18, 20, 23;
	--lm-bg-rgb: 236, 238, 232;
	--lm-panel-rgb: 245, 246, 241;
	/* The tint channels go pale, not deep: an accent at 22%% over ivory has to
	   lighten the ground the way it lightens the dark one, or the text on it
	   loses a full step. Red keeps its depth because it also draws borders. */
	--lm-green-rgb: 199, 232, 207;
	--lm-green-lt-rgb: 31, 74, 44;
	--lm-green-dk-rgb: 199, 232, 207;
	--lm-gold-rgb: 74, 58, 27;
	--lm-gold-dk-rgb: 242, 217, 160;
	--lm-red-rgb: 107, 38, 32;
	--lm-red-mid-rgb: 107, 38, 32;
	--lm-red-dk-rgb: 246, 218, 214;
	--lm-red-deep-rgb: 246, 218, 214;
	--lm-muted-rgb: 68, 72, 78;
	--lm-on-gold-rgb: 74, 58, 27;

	/* Black at half opacity is a bruise on paper. The shadows keep their
	   geometry and change only what they are made of. */
	--lm-shadow-rgb: 74, 78, 84;
}

*, *::before, *::after { box-sizing: border-box; }

html {
	background: var(--lm-bg);
	-webkit-text-size-adjust: 100%;
}

body {
	margin: 0;
	padding: 0;
	background: var(--lm-bg);
	color: var(--lm-ink);
	font-family: var(--lm-serif);
	font-size: 1rem;
	line-height: 1.6;
	-webkit-font-smoothing: antialiased;
	overflow-x: hidden;
}

a { color: var(--lm-gold); text-decoration: none; }
a:hover { color: var(--lm-ink); }
img { max-width: 100%; }

::selection { background: var(--lm-green-dk); color: var(--lm-ink); }
:focus-visible { outline: 2px solid var(--lm-green-lt); outline-offset: 2px; }
input::placeholder, textarea::placeholder { color: var(--lm-muted); opacity: 1; }

@keyframes lm-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .2; } }
@keyframes lm-fade { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* Honour a reader who has asked their system for less movement.

   This block was doing the opposite. Shortening a duration to a hundredth of
   a millisecond ends an animation that runs once — but an infinite one just
   restarts, a hundred thousand times a second, and what was a slow fade
   becomes a strobe. The map marker was the visible victim; the live dot on
   the index ticker runs on the same setting.

   Capping the iteration count is the half that was missing: the animation
   runs once, instantly, lands on its final frame and stops. */
@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after {
		transition-duration: .01ms !important;
		animation-duration: .01ms !important;
		animation-iteration-count: 1 !important;
		scroll-behavior: auto !important;
	}
}

/* ---------------------------------------------------------------- layout */

.lm-wrap {
	max-width: var(--lm-max);
	margin: 0 auto;
	padding-left: var(--lm-gutter);
	padding-right: var(--lm-gutter);
}

.lm-section { padding-top: var(--lm-sec-gap); }

/* Numbered section header: mono eyebrow + "01 Title" rule. */
.lm-sechead {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: 10px 16px;
	margin-bottom: 22px;
	padding-bottom: 14px;
	border-bottom: 1px solid var(--lm-line);
}
.lm-sechead > div { min-width: 0; }
.lm-eyebrow {
	margin: 0 0 7px;
	font-family: var(--lm-mono);
	font-size: 0.6563rem;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--lm-gold);
}
.lm-sechead h2 {
	margin: 0;
	font-family: var(--lm-sans);
	font-size: 0.875rem;
	font-weight: 600;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--lm-ink);
}
.lm-sechead h2 .lm-no { color: var(--lm-green-lt); margin-right: 10px; }
.lm-sechead-meta {
	font-family: var(--lm-mono);
	font-size: 0.6875rem;
	color: var(--lm-muted);
}
.lm-sechead-link {
	font-family: var(--lm-sans);
	font-size: 0.6875rem;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--lm-gold);
	white-space: nowrap;
}

.lm-panel {
	background: var(--lm-panel);
	border: 1px solid var(--lm-line);
	border-radius: 4px;
	padding: clamp(1.125rem, 3.4vw, 1.625rem);
}

/* ---------------------------------------------------------------- buttons */

/* A button is inline-flex, and an author display beats the one the browser
   attaches to [hidden] — so without this a button marked hidden stays on
   screen. The concert page hides its share-sheet button that way when the
   browser has no share sheet. */
.lm-btn[hidden] { display: none; }
.lm-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	white-space: nowrap;
	font-family: var(--lm-sans);
	font-size: 0.75rem;
	letter-spacing: .1em;
	text-transform: uppercase;
	padding: 11px 20px;
	min-height: 2.75rem;
	border-radius: 2px;
	border: 1px solid var(--lm-line-strong);
	background: transparent;
	color: var(--lm-ink);
	cursor: pointer;
	transition: border-color .16s, background .16s, color .16s;
}
.lm-btn:hover { border-color: var(--lm-ink); color: var(--lm-ink); }

.lm-btn-primary {
	font-weight: 600;
	border-color: var(--lm-green);
	background: var(--lm-green);
	color: var(--lm-on-accent);
}
.lm-btn-primary:hover { background: var(--lm-green-hi); border-color: var(--lm-green-hi); color: var(--lm-on-accent); }

.lm-btn-ghost { border-color: rgba(var(--lm-ink-rgb), .3); }

/* State used by concert-js when a toggle is on (my list, favourite). */
.lm-btn.added {
	background: rgba(var(--lm-green-dk-rgb), .5);
	border-color: var(--lm-green-lt);
	color: var(--lm-on-green);
}

/* A button that has been pressed and is waiting for an answer.

   Switching it off was already happening, and on its own it is a state
   nobody can see: .lm-btn declares its own colour, and an author colour
   beats the greying a browser gives a disabled control, so the concert
   page's Share button went dead and identical the moment it was pressed.
   On a fast connection that is invisible; on a slow one it is somebody
   pressing it a second time because nothing appeared to happen.

   Nothing in here changes a colour, so the button reads at the same
   contrast pressed as idle — what changes is the word and the three dots
   after it. Those are the search panel's cycle reused, keyframes and all,
   so that waiting looks the same wherever on the site it happens; they are
   defined further down beside .lm-search-loading.

   The two labels are display:none in turn rather than one span being
   rewritten, because content that is display:none is left out of the
   accessible name — so the name follows the word that is on screen. */
.lm-btn-busy { display: none; }
.lm-btn.is-busy { cursor: progress; }
.lm-btn.is-busy .lm-btn-idle { display: none; }
.lm-btn.is-busy .lm-btn-busy { display: block; }
.lm-btn-busy i { font-style: normal; }
.lm-btn.is-busy .lm-btn-busy i:nth-child(2) { animation: lm-search-dot-2 1.05s steps(1, end) infinite; }
.lm-btn.is-busy .lm-btn-busy i:nth-child(3) { animation: lm-search-dot-3 1.05s steps(1, end) infinite; }
@media (prefers-reduced-motion: reduce) {
	.lm-btn-busy i { animation: none !important; opacity: 1 !important; }
}

/* A face disc holds either a picture of somebody or the letters that stand
   in for one, so the picture is sized to the disc rather than the disc to
   the picture. Its own width is 100% of the content box, which leaves the
   ring the disc already draws showing round it. Shared, because the disc
   is: reviews use it site-wide and the charts use it for concertgoers. */
.lm-face-img {
	display: block;
	width: 100%;
	height: 100%;
	border-radius: 50%;
	object-fit: cover;
}

/* Every avatar image on the site, whatever size and shape its own rule
   gives it — this carries the ground and nothing else, so it composes with
   all nine of them.

   The fifty drawn faces declare no fill anywhere in the file, so they come
   out in the SVG default, which is black. On the dark theme that is black
   line art on --lm-panel-2 at 1.38:1, or 1.14:1 on the artist page's top
   fan, which is present and all but invisible. A pale ground behind the
   drawing takes every one of them to 10.24:1.

   A class the image opts into rather than a list of the nine selectors,
   for the same reason --lm-field-fill is a token: a list is a thing
   somebody has to keep correct, and that one was wrong within a day. A new
   avatar slot names this beside whatever sizes it.

   img rather than the bare class, and that is load-bearing twice over. Six of
   the nine declare their own single-class background, and a page stylesheet
   is served after lm-base.css — so at equal specificity the ground the
   drawing was disappearing into won. Measured with the bare class in place,
   the artist page still read 1.38 and 1.14 to 1. And the element keeps this
   off the letters that stand in where there is no member: .cc-buddy-avatar
   is worn by both an img and a span, and only the img should take a ground.

   A photograph covers the disc and never shows the ground; it appears for
   the moment before one loads, which is a grey circle rather than a hole. */
img.lm-avatar { background-color: var(--lm-muted); }

/* Light needs the opposite of the same reasoning and not the same rule:
   black on that theme's --lm-panel-2 already reads 20.26:1, and its
   --lm-muted is a dark grey that would put the drawing back at 2.28:1. */
:root[data-theme="light"] img.lm-avatar { background-color: transparent; }

/* A label inside a button keeps the button's own type and colour, whatever
   the page around it happens to say about spans — and that is not a
   hypothetical. concert.css carried `.cc-composer-foot span` for the note
   that sits beside the Share button, written when the note was the only
   span in that box; wrapping the label in one brought it into range, and
   the button's own word came out mono grey at 1.22:1 on the green against
   7.38 for the colour it is supposed to have. That rule is a child
   selector now, and this one means the next page to write a descendant
   rule like it cannot reach in here either: two classes beat the
   one-class-one-type selector that is the usual shape of the mistake. */
.lm-btn .lm-btn-idle,
.lm-btn .lm-btn-busy { font: inherit; color: inherit; letter-spacing: inherit; }

.lm-skip {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 60;
	padding: 10px 14px;
	background: var(--lm-green);
	color: var(--lm-on-accent);
	font-family: var(--lm-sans);
	font-size: 0.75rem;
	letter-spacing: .08em;
	text-transform: uppercase;
}
.lm-skip:focus { left: 8px; top: 8px; color: var(--lm-on-accent); }

/* ---------------------------------------------------------------- header */

.lm-header {
	border-bottom: 1px solid var(--lm-line);
	background: var(--lm-bg);
	position: sticky;
	top: 0;
	z-index: 1002;
}
.lm-header-in {
	max-width: var(--lm-max);
	margin: 0 auto;
	padding: 12px var(--lm-gutter);
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	row-gap: 10px;
	column-gap: clamp(0.75rem, 3vw, 2.25rem);
}
.lm-brand { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
/* The LM mark, one file per theme -- see the comment in core/design-header.php
   for which is which, because the names do not say it. Both are in the markup
   and this picks the one that belongs on the ground behind it.

   The width and height attributes carry the intrinsic 185x100, so the browser
   knows the ratio before the file lands and the header does not jump; the
   height here is what it actually draws at. */
.lm-brand-mark { display: block; height: 30px; width: auto; margin-bottom: 1.5px; }
.lm-brand-mark.is-on-light { display: none; }
:root[data-theme="light"] .lm-brand-mark.is-on-dark { display: none; }
:root[data-theme="light"] .lm-brand-mark.is-on-light { display: block; }
.lm-mark {
	width: 30px;
	height: 30px;
	flex: 0 0 30px;
	border: 1.5px solid var(--lm-green-lt);
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--lm-green-lt);
	font-family: var(--lm-sans);
	font-size: 0.75rem;
	font-weight: 700;
}
.lm-brand-name {
	font-family: var(--lm-sans);
	font-weight: 600;
	letter-spacing: .08em;
	font-size: clamp(0.8125rem, 3.4vw, 0.9375rem);
	color: var(--lm-ink);
	margin-bottom: 3px;
}
.lm-brand-name:hover { color: var(--lm-green-lt); }

.lm-nav { flex: 0 1 auto; min-width: min(18.75rem, 44%); overflow-x: auto; scrollbar-width: none; }
.lm-nav::-webkit-scrollbar { display: none; }
.lm-nav ul {
	display: flex;
	flex-wrap: nowrap;
	white-space: nowrap;
	gap: clamp(0.8125rem, 1.6vw, 1.375rem);
	margin: 0;
	padding: 0;
	list-style: none;
	font-family: var(--lm-sans);
	font-size: 0.75rem;
	letter-spacing: .12em;
	text-transform: uppercase;
}
.lm-nav a { color: var(--lm-muted); }
.lm-nav a:hover { color: var(--lm-ink); }
.lm-nav a[aria-current="page"] { color: var(--lm-green-lt); }

/* The row is one line that scrolls sideways with its scrollbar hidden, so
   anything past the edge is gone with nothing to say so. Five items and the
   tracking below fit from 360px up; on the narrowest phones still in use they
   need 28px they have not got, and closing the gaps is the cheapest way to
   find it.

   Tracking comes in too, rather than only the gap, because gap alone lands on
   exactly the width available and leaves nothing spare — and Oswald is a
   condensed face. Where it fails to load, the Arial behind it is wider, and
   the row would go back to being quietly cut off. */
@media (max-width: 359px) {
	.lm-nav ul { gap: 6px; letter-spacing: .06em; }
}

.lm-header-spacer { flex: 1 1 auto; min-width: 0; }
.lm-header-actions {
	display: flex;
	gap: 8px;
	align-items: center;
	flex: 0 0 auto;
	margin-left: auto;
	white-space: nowrap;
}
.lm-header-actions .lm-btn {
	padding: 9px clamp(0.6875rem, 2.6vw, 0.875rem);
	font-size: 0.75rem;
	letter-spacing: .08em;
	color: var(--lm-muted);
}
.lm-header-actions .lm-btn:hover { color: var(--lm-ink); }
.lm-header-actions .lm-btn-primary { color: var(--lm-on-accent); }

/* The unread count on the Profile button.

   Gold with --lm-on-accent on it: the same pairing .lm-btn-primary uses for
   green, and the reason it needs no light value of its own — on dark that is
   near-black on bright gold, on light pale on deep gold, because the two
   tokens swap together. */
.lm-badge-count {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 1.25rem;
	height: 1.25rem;
	margin-left: 7px;
	padding: 0 5px;
	border-radius: 999px;
	background: var(--lm-gold);
	color: var(--lm-on-accent);
	font-family: var(--lm-mono);
	font-size: 0.625rem;
	font-weight: 700;
	letter-spacing: 0;
	line-height: 1;
}
/* The other header buttons are muted until hovered. This one has something to
   say, so it sits at full ink with a gold hairline. */
.lm-header-actions .lm-btn-badged {
	color: var(--lm-ink);
	border-color: rgba(var(--lm-gold-rgb), .5);
}

/* ---------------------------------------------------------------- footer */

.lm-footer {
	margin-top: clamp(3rem, 8vw, 5rem);
	position: relative;
	overflow: hidden;
	background: var(--lm-panel);
	border-top: 1px solid rgba(var(--lm-green-lt-rgb), .4);
}
.lm-footer-glow {
	position: absolute;
	inset: 0;
	pointer-events: none;
	background:
		radial-gradient(70% 130% at 12% 0%, rgba(var(--lm-green-dk-rgb), .45), transparent 62%),
		radial-gradient(60% 120% at 95% 110%, rgba(var(--lm-gold-dk-rgb), .32), transparent 66%);
}
.lm-footer-grain {
	position: absolute;
	inset: 0;
	pointer-events: none;
	opacity: .45;
	background-image: repeating-linear-gradient(45deg, rgba(var(--lm-ink-rgb), .03) 0 1px, transparent 1px 5px);
}
.lm-footer-in {
	position: relative;
	max-width: var(--lm-max);
	margin: 0 auto;
	padding: clamp(2.25rem, 7vw, 3.25rem) var(--lm-gutter) 20px;
}
.lm-footer-top {
	display: flex;
	flex-wrap: wrap;
	gap: 24px;
	align-items: flex-end;
	justify-content: space-between;
	padding-bottom: 30px;
	border-bottom: 1px solid rgba(var(--lm-ink-rgb), .16);
}
.lm-footer-brand { flex: 1 1 26.25rem; min-width: 0; }
.lm-footer-brand .lm-brand { margin-bottom: 16px; gap: 11px; }
.lm-footer-claim {
	margin: 0;
	font-family: var(--lm-sans);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: .02em;
	font-size: clamp(1.625rem, 7.4vw, 3.25rem);
	line-height: .94;
	color: var(--lm-ink);
}
.lm-footer-claim span { color: var(--lm-green-lt); }
.lm-footer-cta { flex: 1 1 16.25rem; min-width: 0; }
.lm-footer-cta p {
	margin: 0 0 16px;
	font-size: 0.875rem;
	line-height: 1.6;
	color: var(--lm-ink);
	font-style: italic;
	max-width: 300px;
	text-wrap: pretty;
}
.lm-footer-cta div { display: flex; flex-wrap: wrap; gap: 9px; }

.lm-footer-cols {
	display: flex;
	flex-wrap: wrap;
	gap: 24px clamp(1rem, 3vw, 1.875rem);
	justify-content: space-between;
	padding: 28px 0 26px;
}
.lm-footer-col {
	flex: 1 1 8.25rem;
	min-width: 7.25rem;
	font-family: var(--lm-sans);
	font-size: 0.7813rem;
	letter-spacing: .05em;
	text-transform: uppercase;
}
.lm-footer-col.is-wide { flex: 1 1 12.5rem; min-width: 0; }
.lm-footer-col h2 {
	color: var(--lm-gold);
	margin: 0 0 13px;
	font-family: var(--lm-mono);
	font-size: 0.625rem;
	font-weight: 400;
	letter-spacing: .14em;
	text-transform: uppercase;
}
.lm-footer-col ul {
	display: flex;
	flex-direction: column;
	gap: 9px;
	margin: 0;
	padding: 0;
	list-style: none;
}
.lm-footer-col a { color: var(--lm-ink); }
.lm-footer-col a:hover { color: var(--lm-gold); }
.lm-footer-stats {
	display: flex;
	flex-direction: column;
	gap: 7px;
	font-family: var(--lm-mono);
	font-size: 0.7813rem;
	color: var(--lm-ink);
	text-transform: none;
	letter-spacing: normal;
}
.lm-footer-stats b { color: var(--lm-green-lt); font-weight: 700; }

/* The theme switch. Buttons, because they act rather than navigate, but drawn
   as the links they sit among — a control that looked like a control here
   would be the loudest thing in the footer, and it is the least important.

   Hidden until the head script has written data-theme-pref, which is also the
   test for whether any of this can work at all. */
html:not([data-theme-pref]) .lm-theme { display: none; }
.lm-theme button {
	padding: 0;
	border: 0;
	background: none;
	font: inherit;
	color: var(--lm-green-lt);
	text-decoration: underline;
	text-underline-offset: 2px;
	cursor: pointer;
}
.lm-theme button:hover { color: var(--lm-ink); }
/* Lit from the attribute rather than from a class lm.js would have to add,
   so the right one is already lit on the first paint. */
html[data-theme-pref="dark"]   .lm-theme [data-lm-theme="dark"],
html[data-theme-pref="light"]  .lm-theme [data-lm-theme="light"],
html[data-theme-pref="system"] .lm-theme [data-lm-theme="system"] {
	color: var(--lm-ink);
	text-decoration: none;
	font-weight: 700;
}

.lm-footer-base {
	padding: 18px 0 26px;
	border-top: 1px solid rgba(var(--lm-ink-rgb), .16);
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	justify-content: space-between;
	align-items: center;
	color: var(--lm-muted);
	font-size: 0.6875rem;
	font-family: var(--lm-mono);
	letter-spacing: .08em;
}
.lm-footer-base em {
	color: var(--lm-ink);
	font-style: italic;
	font-family: var(--lm-serif);
	font-size: 0.8125rem;
	letter-spacing: normal;
	text-transform: none;
}

/* --------------------------------------------------- shared-component shim

   The new design drops bootstrap_*.css. Bootstrap 3.4.1 *JavaScript* is still
   loaded (core/footer.php) and drives the login / review / upload modals, the
   sidebar and the search overlay, so the handful of classes that markup relies
   on are re-implemented here in the new visual language. Keep in sync with
   core/footer.php if that markup changes. */

/* ------------------------------------------------------------- countdowns

   The jQuery countdown plugin prints each unit as a bare inline <span> with
   nothing between them, so every countdown on the site read "12Days3Hrs44Mins"
   until these rules existed. The concert page's big block overrides the sizes;
   this is only the spacing, which every countdown needs. */

.widget-Countdown { display: inline-flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline; }
.widget-Countdown .countdown-row { display: inline-flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline; }
.widget-Countdown .countdown-section { display: inline-flex; gap: 4px; align-items: baseline; white-space: nowrap; }
.widget-Countdown .countdown-amount { font-variant-numeric: tabular-nums; }
.widget-Countdown .countdown-period { color: var(--lm-muted); }

/* ------------------------------------------------------------ ajax states

   showLoader() in core/script/lm.js drops .lm-loading into whatever container
   is about to be replaced, and every endpoint that can fail answers with
   .lm-ajax-empty or .lm-ajax-error rather than an empty string — a request
   that dies otherwise looks exactly like a section with nothing in it. */

.lm-loading {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 3.75rem;
	padding: 1.25rem 0;
}
.lm-loading img { width: 1.5rem; height: 1.5rem; }

.lm-ajax-empty,
.lm-ajax-error {
	margin: 0;
	padding: 1.25rem 0;
	font-family: var(--lm-mono);
	font-size: 0.75rem;
	letter-spacing: .04em;
	line-height: 1.7;
	color: var(--lm-muted);
}
.lm-ajax-error { color: var(--lm-red); }

/* The panel a "view all" link swaps the page body for. lmAjaxPanel() in
   core/functions.php builds it; every ajax/ endpoint that answers one of those
   links goes through that function, so the panel matches the section it
   replaced instead of each endpoint inventing its own header. */

.lm-ajaxpanel { padding-top: 0; }
.lm-ajaxpanel-close {
	flex: none;
	background: none;
	border: 1px solid var(--lm-line-strong);
	border-radius: 3px;
	color: var(--lm-muted);
	cursor: pointer;
	font-family: var(--lm-mono);
	font-size: 0.6875rem;
	letter-spacing: .08em;
	text-transform: uppercase;
	min-height: 44px;
	padding: 0 14px;
	transition: border-color .16s, color .16s;
}
.lm-ajaxpanel-close:hover { border-color: var(--lm-ink); color: var(--lm-ink); }

/* The forecast strip. The concert page fills it with the three-hourly slots
   for one night, the festival page with the run of the whole edition, both
   from their own ajax/…GetWeatherAjax.php. Scrolls sideways rather than
   wrapping, so the run of hours reads as one line. */

.lm-weather {
	display: flex;
	gap: 10px;
	margin: 0;
	padding: 0 0 6px;
	list-style: none;
	overflow-x: auto;
}
.lm-weather > li {
	flex: 0 0 6.5rem;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 2px;
	padding: 12px 8px;
	background: var(--lm-panel);
	border: 1px solid var(--lm-line);
	border-radius: 4px;
	text-align: center;
}
.lm-weather img { width: 50px; height: 50px; }
.lm-weather b { font-family: var(--lm-mono); font-size: 0.75rem; color: var(--lm-muted); font-weight: 400; }
.lm-weather-temp { font-family: var(--lm-sans); font-size: 1.25rem; color: var(--lm-ink); }
.lm-weather-desc { font-size: 0.75rem; color: var(--lm-muted); line-height: 1.3; }
.lm-weather-src {
	margin: 10px 0 0;
	font-family: var(--lm-mono);
	font-size: 0.6875rem;
	letter-spacing: .04em;
	color: var(--lm-muted);
}
.lm-weather-src a { color: var(--lm-gold); }

/* A filtered list of nights answered inline rather than as a panel — the
   artist page's archive search and the venue page's year chips both do this,
   into a container that is empty until something has been asked for. */
#selectedHistoryConcerts:not(:empty),
#selectedYearConcerts:not(:empty) {
	margin-top: 28px;
	padding-top: 20px;
	border-top: 1px solid var(--lm-line);
}
.lm-found {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	align-items: center;
	justify-content: space-between;
	margin-bottom: 8px;
}
.lm-found-count {
	margin: 0;
	font-family: var(--lm-mono);
	font-size: 0.6875rem;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--lm-muted);
}
.lm-found-off {
	font-family: var(--lm-mono);
	font-size: 0.6875rem;
	text-transform: uppercase;
	color: var(--lm-red);
}

/* ------------------------------------------------------- hero + ticket stub

   Shared by every detail page (concert, artist, festival, venue …). The page
   stylesheet supplies --hero-photo-h and --h1. */

.lm-hero { position: relative; overflow: hidden; }
.lm-hero-bg {
	position: absolute;
	inset: -70px;
	filter: blur(34px) saturate(1.25);
	opacity: .48;
	background-size: cover;
	background-position: center;
}
.lm-hero-tint {
	position: absolute;
	inset: 0;
	pointer-events: none;
	background:
		radial-gradient(120% 95% at 13% 9%, rgba(var(--lm-green-dk-rgb), .58), transparent 58%),
		radial-gradient(90% 85% at 93% 100%, rgba(var(--lm-gold-dk-rgb), .42), transparent 62%),
		linear-gradient(180deg, rgba(var(--lm-bg-rgb), .52), rgba(var(--lm-bg-rgb), .9) 77%, var(--lm-bg));
}
.lm-hero-grain {
	position: absolute;
	inset: 0;
	pointer-events: none;
	opacity: .6;
	background-image:
		repeating-linear-gradient(45deg, rgba(var(--lm-ink-rgb), .035) 0 1px, transparent 1px 4px),
		repeating-linear-gradient(-45deg, rgba(var(--lm-bg-rgb), .3) 0 1px, transparent 1px 5px);
}
.lm-hero-rule {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 1px;
	pointer-events: none;
	background: linear-gradient(90deg, transparent, rgba(var(--lm-green-lt-rgb), .45), transparent);
}
.lm-hero-in {
	position: relative;
	max-width: var(--lm-max);
	margin: 0 auto;
	padding: clamp(1.25rem, 5vw, 2.125rem) var(--lm-gutter) clamp(1.875rem, 6vw, 3.25rem);
}
.lm-kicker {
	margin: 0 0 10px;
	font-family: var(--lm-mono);
	font-size: clamp(0.6875rem, 2.9vw, 0.75rem);
	color: var(--lm-green-lt);
	letter-spacing: .12em;
}
.lm-kicker a { color: var(--lm-green-lt); text-decoration: underline; }
.lm-kicker a:hover { color: var(--lm-ink); }

.lm-ticket {
	border-radius: 6px;
	position: relative;
	overflow: hidden;
	box-shadow: 0 30px 60px rgba(var(--lm-shadow-rgb), .55);
}
/* Concert tickets are green stock; artist tickets are panel stock. */
.lm-ticket.is-green { background: rgba(var(--lm-green-dk-rgb), .94); }
.lm-ticket.is-panel { background: rgba(var(--lm-panel-rgb), .9); border: 1px solid var(--lm-line-strong); }
.lm-ticket-row { display: flex; flex-wrap: wrap; }

.lm-ticket-photo {
	position: relative;
	flex: 1 1 15rem;
	min-width: 0;
	max-width: 18.75rem;
	height: var(--hero-photo-h, 14.5rem);
	background: var(--lm-panel-2);
}
.lm-ticket-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.lm-photo-shade {
	position: absolute;
	inset: 0;
	pointer-events: none;
	background:
		linear-gradient(205deg, rgba(var(--lm-green-dk-rgb), .38), transparent 43%, rgba(var(--lm-gold-rgb), .14)),
		radial-gradient(110% 85% at 50% 5%, transparent 45%, rgba(var(--lm-bg-rgb), .5));
	box-shadow: inset 0 0 0 1px rgba(var(--lm-ink-rgb), .12), inset 0 -80px 66px -46px rgba(var(--lm-bg-rgb), .95);
}
.lm-photo-corner {
	position: absolute;
	top: 11px;
	width: 14px;
	height: 14px;
	pointer-events: none;
	border-top: 1px solid rgba(var(--lm-ink-rgb), .45);
}
.lm-photo-corner.is-left { left: 11px; border-left: 1px solid rgba(var(--lm-ink-rgb), .45); }
.lm-photo-corner.is-right { right: 11px; border-right: 1px solid rgba(var(--lm-ink-rgb), .45); }
.lm-photo-meta {
	position: absolute;
	bottom: 0;
	left: 0;
	right: 0;
	pointer-events: none;
	padding: 10px 12px;
	display: flex;
	justify-content: space-between;
	align-items: flex-end;
	gap: 8px;
	font-family: var(--lm-mono);
	font-size: 0.5938rem;
	letter-spacing: .08em;
	color: var(--lm-muted);
}
.lm-photo-meta .is-accent { color: var(--lm-green-lt); }

.lm-perf { flex: 0 0 0; width: 0; border-left: 2px dashed rgba(var(--lm-ink-rgb), .28); position: relative; }
.lm-perf-hole {
	position: absolute;
	left: -11px;
	width: 22px;
	height: 22px;
	border-radius: 50%;
	background: var(--lm-bg);
}
.lm-perf-hole.is-top { top: -11px; }
.lm-perf-hole.is-bottom { bottom: -11px; }

.lm-tear { position: relative; height: 0; border-top: 2px dashed rgba(var(--lm-ink-rgb), .28); }
.lm-tear-hole {
	position: absolute;
	top: -11px;
	width: 22px;
	height: 22px;
	border-radius: 50%;
	background: var(--lm-bg);
}
.lm-tear-hole.is-left { left: -11px; }
.lm-tear-hole.is-right { right: -11px; }

.lm-stub {
	flex: 0 0 9.375rem;
	padding: 20px 14px;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: space-between;
	gap: 14px;
}
.lm-stub-vert {
	writing-mode: vertical-rl;
	transform: rotate(180deg);
	font-family: var(--lm-sans);
	font-size: 0.6875rem;
	letter-spacing: .18em;
	text-transform: uppercase;
	color: var(--lm-ink);
}
.lm-stub-code {
	width: 100%;
	height: 38px;
	opacity: .85;
	background: repeating-linear-gradient(90deg, var(--lm-ink) 0 2px, transparent 2px 5px);
}
.lm-stub-no { font-family: var(--lm-mono); font-size: 0.625rem; color: var(--lm-ink); }

.lm-coupons { display: flex; flex-wrap: wrap; background: var(--lm-band); }
.lm-coupon {
	flex: 1 1 20%;
	min-width: 5.25rem;
	padding: 16px 10px;
	text-align: center;
	border-left: 1px dashed rgba(var(--lm-ink-rgb), .22);
}
.lm-coupon b {
	display: block;
	font-family: var(--lm-mono);
	font-size: clamp(1.125rem, 4.4vw, 1.5rem);
	font-weight: 700;
	color: var(--lm-ink);
}
.lm-coupon span {
	display: block;
	margin-top: 3px;
	font-family: var(--lm-sans);
	font-size: 0.625rem;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--lm-ink);
}

/* -------------------------------------------------------------- section nav */

.lm-submenu {
	position: sticky;
	top: 3.5rem;
	z-index: 1001;
	background: var(--lm-bg);
	border-bottom: 1px solid var(--lm-line);
}
.lm-submenu ul {
	max-width: var(--lm-max);
	margin: 0 auto;
	padding: 0 var(--lm-gutter);
	display: flex;
	gap: clamp(0.75rem, 2.4vw, 1.5rem);
	list-style: none;
	overflow-x: auto;
	white-space: nowrap;
	scrollbar-width: none;
	-webkit-overflow-scrolling: touch;
}
.lm-submenu ul::-webkit-scrollbar { display: none; }
.lm-submenu a {
	display: block;
	padding: 14px 0;
	font-family: var(--lm-sans);
	font-size: 0.6875rem;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--lm-muted);
	border-bottom: 2px solid transparent;
}
.lm-submenu a:hover { color: var(--lm-ink); border-bottom-color: var(--lm-green); }
.lm-submenu a.disabled { pointer-events: none; opacity: .35; }

/* ------------------------------------------------------------------ reviews

   commentsOutput() in core/functions.php is shared across the concert, artist,
   venue and festival pages, so its markup is left alone and restyled here. */

.lm-reviews ul { margin: 0; padding: 0; list-style: none; }
.lm-reviews > ul > li { border-bottom: 1px solid var(--lm-line); }
.lm-reviews > ul > li:last-child { border-bottom: 0; }
.lm-reviews .commentListDiv {
	display: flex;
	gap: clamp(0.75rem, 3vw, 1rem);
	padding: 20px 12px;
	margin: 0 -12px;
	border-radius: 3px;
	transition: background .16s;
}
.lm-reviews .commentListDiv:hover { background: rgba(var(--lm-panel-rgb), .75); }

/* The disc in front of a review carries two letters, not a photograph. Nearly
   nine reviews in ten were written by somebody without an account, so a photo
   was a fallback avatar in almost every row — and twenty of them cost twenty
   file lookups a page. */
.lm-reviews .rv-face {
	flex: 0 0 2.5rem;
	width: 2.5rem;
	height: 2.5rem;
	border-radius: 50%;
	background: var(--lm-panel-2);
	border: 1px solid var(--lm-line-strong);
	display: flex;
	align-items: center;
	justify-content: center;
	font-family: var(--lm-sans);
	font-size: 0.8125rem;
	letter-spacing: .04em;
	color: var(--lm-green-lt);
}

.lm-reviews .wm-text { flex: 1 1 auto; min-width: 0; }
.lm-reviews .rv-head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 4px 10px;
	margin: 0 0 2px;
	font-size: 0.8125rem;
	color: var(--lm-muted);
}
.lm-reviews .rv-who {
	font-family: var(--lm-sans);
	font-size: 0.875rem;
	letter-spacing: .02em;
	color: var(--lm-ink);
}
.lm-reviews a.rv-who:hover { color: var(--lm-green-lt); }
.lm-reviews .rv-who.is-guest { color: var(--lm-muted); }
.lm-reviews .rv-on { font-family: var(--lm-mono); font-size: 0.6875rem; letter-spacing: .06em; text-transform: uppercase; opacity: .8; }
/* A review whose night the catalogue holds no row for. The reviews index and
   the artist page's "read all" panel both raise it. */
.rv-lost {
	display: inline-block;
	font-family: var(--lm-mono);
	font-size: 0.5625rem;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--lm-muted);
	border: 1px dashed var(--lm-line-strong);
	border-radius: 2px;
	padding: 2px 6px;
	cursor: help;
}
/* The author has this night in their own journal. Same pill as .rv-lost above,
   in green and solid rather than muted and dashed — one is a thing the
   catalogue is missing, the other a thing it can vouch for. */
.rv-verified {
	display: inline-block;
	font-family: var(--lm-mono);
	font-size: 0.6875rem;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--lm-green-lt);
	/* --lm-green-lt-rgb, not --lm-green-rgb: the plain green channel is only
	   ever a tint and goes pale on the light theme (199,232,207), where a
	   border mixed from it would disappear against the page. The -lt channel
	   keeps its depth both ways, and matches the text sitting on it. */
	border: 1px solid rgba(var(--lm-green-lt-rgb), .7);
	border-radius: 2px;
	padding: 2px 6px;
	cursor: help;
}

.lm-reviews .rv-head a:not(.rv-who) { color: var(--lm-gold); }
.lm-reviews .rv-head a:not(.rv-who):hover { color: var(--lm-ink); }

.lm-reviews .more {
	margin: 8px 0 10px;
	font-size: clamp(0.875rem, 3.6vw, 0.9375rem);
	line-height: 1.65;
	color: var(--lm-muted);
	text-wrap: pretty;
	/* showMoreLessOpinion() in lm.js collapses a long review by setting a
	   height on this element and appending the link below. Without this the
	   text simply carried on past the box it had been folded into. */
	overflow: hidden;
}
/* All that is left of a review whose writer closed their account and took
   their words with them. The card stays because the replies under it do. */
.lm-reviews .more.is-gone { font-style: italic; opacity: .6; }
/* The opening quote mark the design puts in front of a review. Drawn here
   rather than written into the markup so it cannot end up inside the text that
   read-more truncates, or inside what the edit box loads. */
.lm-reviews .more::before {
	content: "\201C";
	font-family: var(--lm-serif);
	font-size: 1.375rem;
	line-height: 0;
	color: var(--lm-gold);
	margin-right: 4px;
	vertical-align: -3px;
}
.lm-reviews .morelink {
	display: inline-block;
	margin: 0 0 10px;
	font-family: var(--lm-mono);
	font-size: 0.6875rem;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--lm-green-lt);
}
.lm-reviews .morelink:hover { color: var(--lm-ink); }
.lm-reviews .wm-replay-button {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	align-items: center;
	margin: 0;
	font-family: var(--lm-sans);
	font-size: 0.6875rem;
	letter-spacing: .05em;
	text-transform: uppercase;
	color: var(--lm-muted);
}

/* The two vote chips. They were font-awesome thumbs before, which meant the
   controls only appeared once a print-media stylesheet had finished loading. */
.lm-reviews .rv-vote {
	min-width: 2.25rem;
	padding: 8px 9px;
	border: 1px solid var(--lm-line-strong);
	border-radius: 3px;
	background: transparent;
	cursor: pointer;
	font-family: var(--lm-mono);
	font-size: 0.6875rem;
	line-height: 1;
	color: var(--lm-muted);
	transition: border-color .16s, color .16s;
}
.lm-reviews .rv-vote:hover { border-color: var(--lm-green-lt); color: var(--lm-green-lt); }
.lm-reviews .rv-vote.is-down:hover { border-color: var(--lm-red); color: var(--lm-red); }
/* check_commentUserLike_db() marks how you voted with these two class names.

   Both were short of the 7:1 the palette holds to, and for opposite reasons.

   Red drew its fill from --lm-red-rgb, the same channel as its text, so the
   wash lifted the ground towards the ink — the mistake .li-flash.is-bad also
   made. Green's fill was already a -dk tint, but its text was --lm-green-lt,
   a mid green rather than a shade meant to sit on that tint.

   Neither failed where these buttons actually are. Every review list on the
   site sits on --lm-bg, and there they measured 7.46 and 7.09 — passing, with
   nothing to spare. Move one onto a panel and both drop through the floor,
   silently, because a contrast failure looks like nothing at all:

                          --lm-bg   --lm-panel   --lm-panel-2
       selectRed  before    7.46       6.63          5.97
                  after     8.25       7.74          7.31
       selectGreen before    7.09       6.59          6.19
                  after    11.14      10.35          9.72

   So each takes what its own palette already had: red keeps --lm-red, whose
   pale salmon is legible as it is, and only its ground moves to the -dk tint.
   Green keeps its ground and takes --lm-on-green, which exists for exactly
   this — text on the green tint, the pairing .li-flash.is-good has always
   used. On the light theme --lm-on-green and --lm-green-lt are the same
   value, so nothing there changes at all. */
.lm-reviews .rv-vote.selectGreen { border-color: var(--lm-green-lt); color: var(--lm-on-green); background: rgba(var(--lm-green-dk-rgb), .45); }
.lm-reviews .rv-vote.selectRed { border-color: var(--lm-red); color: var(--lm-red); background: rgba(var(--lm-red-dk-rgb), .45); }

.lm-reviews .badge {
	font-family: var(--lm-mono);
	font-size: 0.6875rem;
	font-variant-numeric: tabular-nums;
	padding: 5px 9px;
	border-radius: 3px;
	border: 1px solid var(--lm-line-strong);
	color: var(--lm-muted);
}
.lm-reviews .badge.up { color: var(--lm-green-lt); }
.lm-reviews .badge.down { color: var(--lm-red); }

.lm-reviews .rv-when { font-family: var(--lm-mono); font-size: 0.6875rem; text-transform: none; letter-spacing: 0; opacity: .8; }
.lm-reviews .rv-mine { font-family: var(--lm-mono); font-size: 0.625rem; letter-spacing: .1em; color: var(--lm-gold); }
.lm-reviews .rv-act {
	padding: 5px 2px;
	border: 0;
	background: none;
	cursor: pointer;
	font-family: var(--lm-sans);
	font-size: 0.6875rem;
	letter-spacing: .05em;
	text-transform: uppercase;
	color: var(--lm-gold);
}
.lm-reviews .rv-act:hover { color: var(--lm-ink); }
.lm-reviews .children { margin: 10px 0 10px clamp(1rem, 5vw, 3.25rem); padding: 0; border-left: 2px dashed var(--lm-line-strong); }
/* A reply is wrapped in <ul class="children commentListDiv"><li>, where the
   top-level review is a plain <div>. The flex row that puts the initials disc
   beside the words is on .commentListDiv, so on a reply it landed on the <ul>
   — whose only flex item is the <li>. The disc and the text sit inside that
   <li>, which is a list-item, so they stacked and every reply began with an
   avatar on a line of its own. The row has to be the <li>. */
.lm-reviews .children > li {
	display: flex;
	gap: clamp(0.75rem, 3vw, 1rem);
	padding-left: 14px;
}

/* The box the reply button opens.

   It was built out of the purchased theme's classes — wm-contact-form around
   it, wm-bgcolor on the button — and both of those stylesheets went with the
   old design. What was left was a browser default: a white monospace textarea
   and a grey outset button, on a dark page. It was also inserted *after*
   .wm-text, which is a flex item of the review row, so it arrived as a third
   column against the right edge instead of under the review it answers. It
   goes inside .wm-text now, where the column it belongs to already is. */
.lm-reviews .rv-reply { margin: 14px 0 2px; }
.lm-reviews .rv-reply textarea {
	display: block;
	width: 100%;
	min-height: 5.5rem;
	padding: 12px 14px;
	background: var(--lm-panel-2);
	border: 1px solid var(--lm-line-strong);
	border-radius: 3px;
	color: var(--lm-ink);
	font-family: var(--lm-serif);
	font-size: 0.9375rem;
	line-height: 1.6;
	resize: vertical;
}
.lm-reviews .rv-reply textarea::placeholder { color: var(--lm-muted); opacity: 1; }
.lm-reviews .rv-reply textarea:focus { outline: none; border-color: var(--lm-green-lt); }
.lm-reviews .rv-reply.has-error textarea { border-color: var(--lm-red); }
.lm-reviews .rv-reply-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 10px; }
.lm-reviews .rv-reply-error {
	margin: 0;
	font-family: var(--lm-mono);
	font-size: 0.75rem;
	line-height: 1.5;
	color: var(--lm-red);
}
.lm-reviews-empty { color: var(--lm-muted); font-size: 0.9375rem; }
.lm-reviews-empty ul { margin: 8px 0 0 1.25rem; list-style: disc; }
.lm-reviews-empty li { margin: 4px 0; }

/* What replaces the review form once a review has been written. The green used
   to be a hex literal inside the language string itself — #22b14c, from the old
   theme, which is not a colour this design has anywhere. */
.lm-thanks {
	margin: 0;
	font-family: var(--lm-sans);
	font-size: clamp(1rem, 3.6vw, 1.125rem);
	font-weight: 600;
	letter-spacing: .02em;
	color: var(--lm-green-lt);
}
.lm-thanks i { margin-left: 6px; }

/* --------------------------------------------------------------- link rows */

.lm-rows { margin: 0; padding: 0; list-style: none; }
.lm-row {
	color: inherit;
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	justify-content: space-between;
	align-items: center;
	padding: 14px 12px;
	margin: 0 -12px;
	border-radius: 3px;
	border-bottom: 1px solid var(--lm-line);
	transition: background .16s;
}
.lm-row:hover { background: rgba(var(--lm-panel-rgb), .8); color: inherit; }
.lm-row-title { font-family: var(--lm-sans); font-size: 0.9063rem; color: var(--lm-ink); min-width: 0; }
.lm-row-meta {
	display: flex;
	align-items: center;
	gap: 10px;
	font-family: var(--lm-mono);
	font-size: 0.75rem;
	color: var(--lm-muted);
}
.lm-row-meta i { color: var(--lm-gold); font-style: normal; }
.lm-row-title .fi { margin-right: 6px; vertical-align: baseline; }

/* The "were you there / are you going" toggle, wherever a list of nights
   offers one. lm.js swaps .add for .added on it in place, so both states are
   styled here rather than by whichever list happens to contain it.

   It used to be called .lm-mark, which is also the LM badge in the header —
   and being declared second, this rule was winning, so the badge came out a
   30px-wide 44px-tall pill instead of a circle.

   Gold is the default because gold is the colour of a date still to come, and
   a night still to come is the one where pressing this changes anything. */
.lm-going {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	min-height: 2.75rem;
	padding: 8px 14px;
	border-radius: 2px;
	cursor: pointer;
	white-space: nowrap;
	font-family: var(--lm-sans);
	font-size: 0.6563rem;
	font-weight: 600;
	letter-spacing: .1em;
	text-transform: uppercase;
	background: transparent;
	border: 1px solid rgba(var(--lm-gold-rgb), .35);
	color: var(--lm-gold);
	transition: background .16s, border-color .16s, color .16s;
}
.lm-going:hover { background: rgba(var(--lm-gold-dk-rgb), .4); border-color: var(--lm-gold); color: var(--lm-on-gold); }
.lm-going.added { background: rgba(var(--lm-gold-dk-rgb), .4); border-color: rgba(var(--lm-gold-rgb), .55); color: var(--lm-on-gold); }

/* A night that has already happened is green — the same green the rest of the
   site uses for something that is on the record. */
.lm-going.is-past { border-color: rgba(var(--lm-green-lt-rgb), .35); color: var(--lm-green-lt); }
.lm-going.is-past:hover { background: rgba(var(--lm-green-dk-rgb), .5); border-color: var(--lm-green-lt); color: var(--lm-on-green); }
.lm-going.is-past.added { background: rgba(var(--lm-green-dk-rgb), .35); border-color: rgba(var(--lm-green-lt-rgb), .55); color: var(--lm-on-green); }

/* -------------------------------------------------------------------- tags */

.lm-tags { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; list-style: none; align-items: center; }
/* A tag is a chip whether or not it leads anywhere. Genres are plain text now,
   so the same shape has to work on a span. */
.lm-tags a,
.lm-tags > li > span {
	display: inline-block;
	border: 1px solid var(--lm-line-strong);
	color: var(--lm-muted);
	font-family: var(--lm-mono);
	font-size: 0.6875rem;
	letter-spacing: .05em;
	text-transform: uppercase;
	padding: 5px 10px;
	border-radius: 20px;
	transition: border-color .16s, color .16s;
}
.lm-tags a:hover { border-color: var(--lm-green-lt); color: var(--lm-green-lt); }
.lm-tags .lm-tags-src { font-family: var(--lm-mono); font-size: 0.625rem; color: var(--lm-muted); font-style: italic; }

/* ------------------------------------------------------------- photo grid */

.lm-photos { position: relative; }
.lm-photos-empty { color: var(--lm-muted); font-size: 0.9375rem; }
#galleryTiles { min-height: 1px; }
#galleryTiles .ug-thumb-wrapper { border-radius: 2px; overflow: hidden; }

/* ------------------------------------------------------ expandable panels */

/* The expanded "view all" panels are injected here. They carry .lm-reviews so
   commentsOutput() markup picks up the same styling it gets inline. */
#selectedContent {
	display: none;
	max-width: var(--lm-max);
	margin: 0 auto;
	padding: var(--lm-sec-gap) var(--lm-gutter) 0;
}
#selectedContent .wm-blog-heading h2,
#selectedContent h2 {
	font-family: var(--lm-sans);
	font-size: 0.875rem;
	font-weight: 600;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--lm-ink);
	margin: 0 0 18px;
	padding-bottom: 14px;
	border-bottom: 1px solid var(--lm-line);
}
#selectedContent .closeSelectedContent,
#selectedContent .closeTourConcerts {
	cursor: pointer;
	font-family: var(--lm-sans);
	font-size: 0.6875rem;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--lm-gold);
}
.lm-source { margin-top: var(--lm-sec-gap); text-align: right; }
.lm-source p { font-family: var(--lm-mono); font-size: 0.6875rem; color: var(--lm-muted); }
.lm-source img { opacity: .55; }
.lm-source img:hover { opacity: 1; }

/* getStarRating() emits this next to a reviewer's name, on every page that
   prints comments. */
.lm-rating-badge {
	display: inline-block;
	margin-left: 6px;
	padding: 2px 7px;
	border-radius: 3px;
	border: 1px solid var(--lm-line-strong);
	font-family: var(--lm-mono);
	font-size: 0.6875rem;
	color: var(--lm-muted);
}
.lm-rating-badge.colorBest { color: var(--lm-green-lt); border-color: rgba(var(--lm-green-lt-rgb), .5); }
.lm-rating-badge.badgeBad { color: var(--lm-red); border-color: rgba(var(--lm-red-rgb), .5); }

.lm-hidden, .hide { display: none !important; }
.clearfix::after { content: ""; display: table; clear: both; }
.pull-right { float: right; }
.pull-left { float: left; }
.text-center { text-align: center; }
.text-right { text-align: right; }
.sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

.modal {
	position: fixed;
	inset: 0;
	z-index: 1050;
	display: none;
	overflow: hidden auto;
	outline: 0;
	-webkit-overflow-scrolling: touch;
}
.modal.in { display: block; }
.modal.fade .modal-dialog { transform: translateY(-16px); transition: transform .2s ease-out; }
.modal.in .modal-dialog { transform: none; }
.modal-open { overflow: hidden; }
.modal-backdrop {
	position: fixed;
	inset: 0;
	z-index: 1040;
	background: #000;
}
.modal-backdrop.fade { opacity: 0; transition: opacity .15s linear; }
.modal-backdrop.in { opacity: .7; }
.modal-dialog {
	position: relative;
	width: auto;
	max-width: 34rem;
	margin: 2rem auto;
	padding: 0 var(--lm-gutter);
}
.bs-example-modal-lg .modal-dialog { max-width: 52rem; }
.modal-content {
	position: relative;
	background: var(--lm-panel);
	border: 1px solid var(--lm-line);
	border-radius: 4px;
	box-shadow: 0 30px 60px rgba(var(--lm-shadow-rgb), .6);
}
.modal-header {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 12px;
	padding: 18px clamp(1.125rem, 3.4vw, 1.625rem);
	border-bottom: 1px dashed var(--lm-line-strong);
}
.modal-title {
	font-family: var(--lm-sans);
	font-size: 1rem;
	letter-spacing: .06em;
	color: var(--lm-ink);
}
.modal-title small { display: block; font-family: var(--lm-mono); font-size: 0.6875rem; color: var(--lm-muted); }
.modal-header .close {
	order: 2;
	background: none;
	border: 0;
	color: var(--lm-muted);
	font-size: 1.5rem;
	line-height: 1;
	min-width: 2.75rem;
	min-height: 2.75rem;
	cursor: pointer;
}
.modal-header .close:hover { color: var(--lm-ink); }
.modal-body { padding: clamp(1.125rem, 3.4vw, 1.625rem); }

.modal-body input[type="text"],
.modal-body input[type="email"],
.modal-body input[type="search"],
.modal-body input[type="password"],
.modal-body textarea {
	width: 100%;
	background: var(--lm-bg);
	border: 1px solid var(--lm-line-strong);
	border-radius: 2px;
	color: var(--lm-ink);
	font-family: var(--lm-serif);
	font-size: 1rem;
	line-height: 1.6;
	padding: 12px 13px;
}
.modal-body textarea { resize: vertical; min-height: 8rem; }
.modal-body label, .modal-body .control-label,
.modal-body .input-group-addon {
	display: block;
	margin-bottom: 6px;
	font-family: var(--lm-sans);
	font-size: 0.75rem;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--lm-muted);
}
.modal-body .input-group { margin-bottom: 14px; }

.btn, .modal-body input[type="submit"] {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-family: var(--lm-sans);
	font-size: 0.75rem;
	letter-spacing: .1em;
	text-transform: uppercase;
	padding: 12px 20px;
	min-height: 2.75rem;
	border-radius: 2px;
	border: 1px solid var(--lm-line-strong);
	background: transparent;
	color: var(--lm-ink);
	cursor: pointer;
}
.btn:hover, .modal-body input[type="submit"]:hover { border-color: var(--lm-ink); }
.btn-success, .modal-body input[type="submit"] {
	font-weight: 600;
	border-color: var(--lm-green);
	background: var(--lm-green);
	color: var(--lm-on-accent);
}
.btn-success:hover, .modal-body input[type="submit"]:hover { background: var(--lm-green-hi); border-color: var(--lm-green-hi); }
.btn-social-logins { margin: 0 6px 6px 0; }
.w-100 { width: 100%; }

.has-error input, .has-error textarea { border-color: var(--lm-red); }
.help-block {
	margin-top: 6px;
	font-family: var(--lm-mono);
	font-size: 0.6875rem;
	color: var(--lm-red);
}

.collapse { display: none; }
.collapse.in { display: block; }

/* The legacy slide-out sidebar and search overlay stay reachable but are not
   part of the new chrome; keep them off-canvas and unstyled-but-legible. */
#sidebar {
	position: fixed;
	top: 0;
	left: -100%;
	width: min(20rem, 85vw);
	height: 100%;
	z-index: 1060;
	overflow-y: auto;
	background: var(--lm-panel-2);
	border-right: 1px solid var(--lm-line);
	transition: left .25s ease;
}
#sidebar.active { left: 0; }
#sidebar ul { margin: 0; padding: 0 1rem 2rem; list-style: none; }
#sidebar a { display: block; padding: 8px 0; color: var(--lm-ink); font-family: var(--lm-sans); font-size: 0.8125rem; }
#sidebar a:hover { color: var(--lm-green-lt); }
#sidebar hr { border: 0; border-top: 1px solid var(--lm-line); margin: 12px 0; }
.overlay { display: none; }
.overlay.active {
	display: block;
	position: fixed;
	inset: 0;
	z-index: 1055;
	background: rgba(var(--lm-shadow-rgb), .6);
}

#scrollToTop {
	position: fixed;
	right: 16px;
	bottom: 16px;
	z-index: 30;
	display: none;
	width: 2.75rem;
	border-radius: 2px;
	border: 1px solid var(--lm-line-strong);
	background: var(--lm-panel);
	color: var(--lm-muted);
	text-align: center;
}
#scrollToTop:hover { color: var(--lm-ink); border-color: var(--lm-ink); }

/* ==================================================== the login modal
   core/design-login-modal.php, included from core/footer.php on every page
   that has moved to the new design — so it lives here rather than with the
   register page the design drew it on. The shell (.modal / .modal-dialog /
   .modal-content) is the bootstrap shim above; everything below is the
   dialog itself. */

.lg-modal .modal-dialog { max-width: 26.5rem; }
.lg-modal .modal-content { border-color: rgba(var(--lm-green-lt-rgb), .45); }

.lg-head {
	display: flex;
	align-items: flex-start;
	gap: 12px;
	padding: clamp(1rem, 3vw, 1.375rem) clamp(1rem, 3vw, 1.375rem) 0;
}
.lg-head > div { flex: 1 1 auto; min-width: 0; }
.lg-eyebrow {
	margin: 0 0 4px;
	font-family: var(--lm-mono);
	font-size: 0.625rem;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--lm-gold);
}
.lg-title {
	margin: 0;
	font-family: var(--lm-sans);
	font-weight: 600;
	font-size: 1.25rem;
	line-height: 1.1;
	letter-spacing: .04em;
	text-transform: uppercase;
	color: var(--lm-ink);
}
.lg-close {
	flex: 0 0 auto;
	width: 2.75rem;
	height: 2.75rem;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: 2px;
	border: 1px solid rgba(var(--lm-ink-rgb), .24);
	background: transparent;
	color: var(--lm-muted);
	font-family: var(--lm-mono);
	font-size: 0.9375rem;
	cursor: pointer;
}
.lg-close:hover { color: var(--lm-ink); border-color: var(--lm-ink); }

.lg-providers { padding: clamp(1rem, 3vw, 1.375rem) clamp(1rem, 3vw, 1.375rem) 0; display: flex; flex-direction: column; gap: 9px; }
.lg-provider {
	display: flex;
	align-items: center;
	gap: 11px;
	width: 100%;
	font-family: var(--lm-sans);
	font-weight: 600;
	font-size: 0.8125rem;
	letter-spacing: .08em;
	text-transform: uppercase;
	padding: 13px 16px;
	min-height: 2.75rem;
	border-radius: 2px;
	border: 1px solid rgba(var(--lm-ink-rgb), .4);
	background: transparent;
	color: var(--lm-ink);
}
.lg-provider:hover { border-color: var(--lm-ink); background: rgba(var(--lm-ink-rgb), .06); color: var(--lm-ink); }
.lg-provider.is-light { border-color: var(--lm-ink); background: var(--lm-ink); color: var(--lm-bg); }
.lg-provider.is-light:hover { background: #FFFFFF; color: var(--lm-bg); }
.lg-provider.is-green { border-color: var(--lm-green); background: var(--lm-green); color: var(--lm-on-accent); }
.lg-provider.is-green:hover { background: var(--lm-green-hi); color: var(--lm-on-accent); }
.lg-provider-mark {
	width: 20px;
	height: 20px;
	flex: 0 0 20px;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	font-family: var(--lm-mono);
	font-size: 0.6875rem;
	font-weight: 700;
	background: var(--lm-ink);
	color: var(--lm-bg);
}
.lg-provider.is-light .lg-provider-mark,
.lg-provider.is-green .lg-provider-mark { background: var(--lm-bg); color: var(--lm-ink); }
.lg-provider.is-green .lg-provider-mark { color: var(--lm-green-lt); }

.lg-or { display: flex; align-items: center; gap: 12px; padding: clamp(1rem, 3vw, 1.375rem) clamp(1rem, 3vw, 1.375rem) 0; }
.lg-or span { flex: 1 1 auto; height: 1px; background: rgba(var(--lm-ink-rgb), .16); }
.lg-or { font-family: var(--lm-mono); font-size: 0.625rem; letter-spacing: .14em; text-transform: uppercase; color: var(--lm-muted); }

.lg-form,
.lg-reset { padding: clamp(1rem, 3vw, 1.375rem); display: flex; flex-direction: column; gap: 14px; }
.lg-reset { padding-top: 0; }
.lg-reset[hidden] { display: none; }

.lg-field { min-width: 0; }
.lg-field label,
.lg-field-top label {
	display: block;
	margin-bottom: 7px;
	font-family: var(--lm-mono);
	font-size: 0.625rem;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--lm-muted);
}
.lg-field-top { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.lg-field-top label { margin-bottom: 0; }
.lg-field input[type="email"],
.lg-field input[type="password"],
.lg-field input[type="text"] {
	width: 100%;
	background: var(--lm-bg);
	border: 1px solid var(--lm-line-strong);
	border-radius: 2px;
	padding: 12px 13px;
	min-height: 2.75rem;
	color: var(--lm-ink);
	font-family: var(--lm-serif);
	font-size: 1rem;
}
.lg-field input::placeholder { color: rgba(var(--lm-muted-rgb), .6); }
.lg-field input:focus { outline: none; border-color: var(--lm-green-lt); }
.lg-field-top + input { margin-top: 7px; }

/* What the browser does to a field it has filled in for you.

   Chromium paints an autofilled input with its own pale blue and its own dark
   text, from a UA rule that sets background-color !important — which is why
   `background: var(--lm-bg)` and `color: var(--lm-ink)`, which every field here
   sets, both lose. On a dark page that is a white box with black text sitting
   inside a black one. Firefox does not do it, which is why this only ever
   showed up in Chrome and Edge.

   An author declaration cannot win against that !important, so the fill is
   painted over rather than replaced:

   - an inset box-shadow a thousand pixels deep covers the whole field, and
     shadows are drawn above the background and below the text. This is the one
     that actually does the work.
   - -webkit-text-fill-color beats `color`, which the UA rule also sets.
   - the never-finishing transition is kept behind them: on the versions that
     animate the fill in, it never arrives.

   The shadow needs a real colour, so it is the only part of this that has to
   know where the field sits. Most take their own --lm-bg; the two that are
   transparent on a panel are named below. Tokens throughout, so it still
   follows the theme.

   A previous attempt used background-clip:text, which hides the fill by
   clipping it to the glyphs — but it clips the field's *own* background the
   same way, hollowing out every input that has one. It is not here for that
   reason.

   :autofill is the standard name and :-webkit-autofill the one shipping
   browsers still answer to. They are written as separate rules on purpose: a
   selector list is dropped whole by any browser that does not know one of its
   parts, so pairing them would lose the fix in the browser that needs it. */
input:-webkit-autofill,
textarea:-webkit-autofill,
select:-webkit-autofill {
	-webkit-text-fill-color: var(--lm-ink);
	caret-color: var(--lm-ink);
	-webkit-box-shadow: 0 0 0 1000px var(--lm-field-fill) inset;
	box-shadow: 0 0 0 1000px var(--lm-field-fill) inset;
	transition: background-color 600000s 0s, color 600000s 0s;
}
input:autofill,
textarea:autofill,
select:autofill {
	-webkit-text-fill-color: var(--lm-ink);
	caret-color: var(--lm-ink);
	-webkit-box-shadow: 0 0 0 1000px var(--lm-field-fill) inset;
	box-shadow: 0 0 0 1000px var(--lm-field-fill) inset;
	transition: background-color 600000s 0s, color 600000s 0s;
}

/* Ten-pixel type on its own is a 26x13 target. The padding grows it past 44px
   and the matching negative margin puts the text back exactly where the design
   drew it, so nothing moves. */
.lg-forgot {
	font-family: var(--lm-mono);
	font-size: 0.625rem;
	letter-spacing: .06em;
	background: transparent;
	border: 0;
	padding: 16px 10px;
	margin: -16px -10px;
	color: var(--lm-gold);
	cursor: pointer;
}
.lg-forgot:hover { color: var(--lm-ink); }

/* The sentence under a field, and the banner above the button. They started in
   content/account/css/account.css; /add-concert wants the same parts and does
   not load that file, so they live here with the rest of the form system. */
.li-hint {
	margin: 7px 0 0;
	font-family: var(--lm-mono);
	font-size: 0.6875rem;
	line-height: 1.5;
	letter-spacing: .04em;
	color: var(--lm-muted);
}
/* The field states are set on .lg-field, so the border and the hint move
   together — one answer per box rather than a colour and a sentence that can
   disagree. */
.lg-field.is-good input { border-color: var(--lm-green); }
.lg-field.is-good .li-hint { color: var(--lm-green-lt); }
.lg-field.is-bad input { border-color: var(--lm-red); }
.lg-field.is-bad .li-hint { color: var(--lm-red); }

.li-flash {
	margin-top: 16px;
	margin-bottom: 0;
	padding: 11px 13px;
	font-family: var(--lm-mono);
	font-size: 0.75rem;
	line-height: 1.5;
}
.li-flash.is-good { border-left: 3px solid var(--lm-green); background: rgba(var(--lm-green-dk-rgb), .35); color: var(--lm-on-green); }
/* Three tokens, not one used three times.

   is-bad drew its border, its wash and its text all out of --lm-red, so the
   wash lifted the panel towards the very colour the text was written in:
   6.92:1 on dark, under the 7:1 the rest of the palette holds to. is-good
   never had the problem because it was built properly — the strong colour on
   the border, the -dk tint behind it, and an --lm-on- shade made for that
   tint. Red is built the same way now. */
.li-flash.is-bad { border-left: 3px solid var(--lm-red); background: rgba(var(--lm-red-dk-rgb), .35); color: var(--lm-on-red); }
.li-flash[hidden] { display: none; }
.li-flash a { color: inherit; border-bottom: 1px solid currentColor; }

.lg-check { display: flex; gap: 11px; align-items: center; min-height: 2.75rem; font-size: 0.875rem; color: var(--lm-ink); cursor: pointer; }
.lg-check input { width: 20px; height: 20px; flex: 0 0 20px; accent-color: var(--lm-green); cursor: pointer; }

/* ------------------------------------------------ the type-ahead panel */

/* Drawn by core/script/lm-suggest.js, which replaced jQuery UI's
   autocomplete. The colours are the ones add-concert had already given that
   menu in its own stylesheet, promoted here because they were only ever
   applied on that one page — the concert page and the profile were getting
   jquery-ui.css's own pale theme instead, on the same interaction. */
.lm-suggest { position: relative; }
.lm-suggest-list {
	position: absolute;
	left: 0;
	top: 100%;
	z-index: 1200;
	max-height: 20rem;
	margin: 2px 0 0;
	padding: 4px;
	overflow-y: auto;
	overflow-x: hidden;
	list-style: none;
	border: 1px solid var(--lm-green-lt);
	border-radius: 3px;
	background: var(--lm-panel-2);
	box-shadow: 0 18px 40px rgba(var(--lm-shadow-rgb), .45);
}
.lm-suggest-list[hidden] { display: none; }
.lm-suggest-hit {
	padding: 9px 11px;
	border-radius: 2px;
	font-family: var(--lm-mono);
	font-size: 0.8125rem;
	line-height: 1.45;
	color: var(--lm-muted);
	cursor: pointer;
}
.lm-suggest-hit.is-on {
	background: rgba(var(--lm-green-dk-rgb), .65);
	color: var(--lm-on-green);
}

.lg-submit {
	width: 100%;
	display: flex;
	align-items: center;
	justify-content: center;
	font-family: var(--lm-sans);
	font-weight: 600;
	font-size: 0.875rem;
	letter-spacing: .12em;
	text-transform: uppercase;
	padding: 15px 20px;
	min-height: 3rem;
	border-radius: 2px;
	border: 1px solid var(--lm-green);
	background: var(--lm-green);
	color: var(--lm-on-accent);
	cursor: pointer;
	transition: background .16s;
}
.lg-submit:hover { background: var(--lm-green-hi); }
.lg-submit.is-ghost { background: transparent; border-color: var(--lm-line-strong); color: var(--lm-ink); }
.lg-submit.is-ghost:hover { background: rgba(var(--lm-ink-rgb), .06); border-color: var(--lm-ink); }

.lg-foot {
	margin: 0;
	font-family: var(--lm-mono);
	font-size: 0.6875rem;
	letter-spacing: .04em;
	line-height: 1.6;
	color: var(--lm-muted);
	text-align: center;
}
.lg-foot a { color: var(--lm-gold); border-bottom: 1px solid rgba(var(--lm-gold-rgb), .5); }
.lg-foot a:hover { color: var(--lm-ink); border-bottom-color: var(--lm-ink); }

/* ------------------------------------------------------ the search overlay */

/* The button lives with log in and add concert, so it is sized like them. Below
   the widest phones the word goes and the glyph carries it — three words of
   chrome in a row is what pushes the header onto two lines. */
.lm-searchbtn { display: inline-flex; align-items: center; gap: 7px; }
.lm-searchbtn-icon { font-size: 1.0625rem; line-height: 1; margin-bottom: 6px;}
@media (max-width: 600px) {
	.lm-searchbtn-word { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
	.lm-searchbtn { padding-left: 11px; padding-right: 11px; }
}

.lm-search[hidden] { display: none; }
.lm-search {
	position: fixed;
	inset: 0;
	z-index: 1060;
	display: flex;
	justify-content: center;
	padding: clamp(0.75rem, 5vh, 5rem) var(--lm-gutter) var(--lm-gutter);
}
.lm-search-scrim {
	position: absolute;
	inset: 0;
	background: rgba(var(--lm-scrim-rgb), .78);
}
.lm-search-box {
	position: relative;
	width: 100%;
	max-width: 34rem;
	max-height: 100%;
	display: flex;
	flex-direction: column;
	background: var(--lm-panel);
	--lm-field-fill: var(--lm-panel);
	border: 1px solid var(--lm-line-strong);
	box-shadow: 0 24px 60px rgba(var(--lm-shadow-rgb), .55);
}

.lm-search-form {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 12px 14px;
	border-bottom: 1px solid var(--lm-line);
	flex: 0 0 auto;
}
.lm-search-icon { color: var(--lm-green-lt); font-size: 1.25rem; line-height: 1; }
.lm-search-input {
	flex: 1 1 auto;
	min-width: 0;
	background: none;
	border: 0;
	color: var(--lm-ink);
	font-family: var(--lm-serif);
	font-size: 1.0625rem;
	padding: 6px 0;
}
.lm-search-input:focus { outline: none; }
.lm-search-input::-webkit-search-cancel-button { display: none; }
.lm-search-x {
	flex: 0 0 auto;
	width: 44px;
	height: 44px;
	background: none;
	border: 0;
	color: var(--lm-muted);
	font-size: 1.5rem;
	line-height: 1;
	cursor: pointer;
}
.lm-search-x:hover { color: var(--lm-ink); }

.lm-search-results { overflow-y: auto; flex: 1 1 auto; }
.lm-search-group { border-bottom: 1px solid var(--lm-line); padding: 8px 0; }
.lm-search-group:last-child { border-bottom: 0; }
.lm-search-group h3 {
	margin: 0;
	padding: 4px 14px 6px;
	font-family: var(--lm-mono);
	font-size: 0.625rem;
	letter-spacing: .18em;
	text-transform: uppercase;
	color: var(--lm-gold);
	font-weight: 400;
}
.lm-search-hit {
	display: flex;
	align-items: baseline;
	gap: 10px;
	padding: 9px 14px;
	min-height: 44px;
	color: var(--lm-ink);
}
.lm-search-hit:hover,
.lm-search-hit.is-on {
	background: var(--lm-panel-2);
	color: var(--lm-ink);
}
.lm-search-hit.is-on { box-shadow: inset 3px 0 0 var(--lm-green); }
.lm-search-hit-name {
	font-family: var(--lm-sans);
	font-size: 0.9375rem;
	font-weight: 500;
	letter-spacing: .01em;
	flex: 1 1 auto;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
/* The run that matched what was typed. lm-base sets no <mark> style, and the
   browser default is black on yellow. */
.lm-search-hit-name mark {
	background: none;
	color: var(--lm-green-lt);
	font-weight: 700;
}
.lm-search-hit-meta {
	flex: 0 0 auto;
	font-family: var(--lm-mono);
	font-size: 0.6875rem;
	color: var(--lm-muted);
	white-space: nowrap;
	max-width: 45%;
	overflow: hidden;
	text-overflow: ellipsis;
}

.lm-search-note {
	margin: 0;
	padding: 18px 14px;
	font-size: 0.875rem;
	color: var(--lm-muted);
}
.lm-search-note b { color: var(--lm-ink); font-weight: 400; }

/* "Searching", with the dots arriving one at a time and starting over: . then
   .. then ... and round again.

   The first dot is always lit, so it has no animation at all; the other two
   are switched on a third and two thirds of the way through the cycle. Only
   their opacity changes, never their space, so the word cannot shuffle
   sideways as they come and go. steps(1) because a dot should appear rather
   than fade up.

   A reader who has asked for less movement gets the word standing still with
   all three dots lit. That needs saying here rather than being left to the
   blanket rule at the top of this file: capping the duration and the iteration
   count ends the animation, but steps(1) holds each step's *opening* value for
   its whole length, so what it ends on is the opening frame — one dot, which
   reads as a full stop rather than as waiting. Measured in a browser with the
   setting on: dots two and three both computed to opacity 0. */
.lm-search-loading i { font-style: normal; }
.lm-search-loading i:nth-child(2) { animation: lm-search-dot-2 1.05s steps(1, end) infinite; }
.lm-search-loading i:nth-child(3) { animation: lm-search-dot-3 1.05s steps(1, end) infinite; }
@keyframes lm-search-dot-2 { 0%, 33.3% { opacity: 0; } 33.4%, 100% { opacity: 1; } }
@keyframes lm-search-dot-3 { 0%, 66.6% { opacity: 0; } 66.7%, 100% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
	.lm-search-loading i { animation: none !important; opacity: 1 !important; }
}

.lm-search-foot {
	margin: 0;
	padding: 10px 14px;
	border-top: 1px solid var(--lm-line);
	display: flex;
	flex-wrap: wrap;
	gap: 8px 14px;
	align-items: center;
	justify-content: space-between;
	flex: 0 0 auto;
}
.lm-search-hint {
	font-family: var(--lm-mono);
	font-size: 0.625rem;
	letter-spacing: .06em;
	color: var(--lm-muted);
}
.lm-search-hint kbd {
	display: inline-block;
	min-width: 18px;
	padding: 1px 4px;
	margin-right: 3px;
	border: 1px solid var(--lm-line-strong);
	border-radius: 3px;
	font-family: inherit;
	font-size: inherit;
	color: var(--lm-ink);
	text-align: center;
}
/* The pointer has no keys to press, and the hint is the widest thing in the
   footer. */
@media (max-width: 520px) { .lm-search-hint { display: none; } }
.lm-search-all {
	font-family: var(--lm-sans);
	font-size: 0.75rem;
	letter-spacing: .08em;
	text-transform: uppercase;
	margin-left: auto;
}

/* ----------------------------------------------- the dot on a leaflet map

   Four page stylesheets carried a copy of this, three of them identical, and
   all four blinked: they animated lm-pulse, which swings opacity from 1 down
   to .2, and over two seconds on a dark map that reads as an alarm going off
   rather than as "the concert was here".

   The dot holds still now and a ring breathes out of it over four seconds,
   with a pause before the next one — the pause is most of what makes a pulse
   read as slow. A page that wants another colour sets the three variables;
   the artist map is gold, because green already means something else there. */

.concert-marker { position: relative; }
.concert-marker .pulse {
	--lm-pin: var(--lm-green);
	--lm-pin-halo: rgba(var(--lm-green-rgb), .22);
	--lm-pin-ring: rgba(var(--lm-green-lt-rgb), .85);
	position: relative;
	width: 18px;
	height: 18px;
	border-radius: 50%;
	background: var(--lm-pin);
	box-shadow: 0 0 0 5px var(--lm-pin-halo);
}
/* Transform and opacity only, so the ring costs a composite rather than a
   repaint of the map tiles underneath it. */
.concert-marker .pulse::after {
	content: "";
	position: absolute;
	inset: -5px;
	border-radius: 50%;
	border: 2.5px solid var(--lm-pin-ring);
	animation: lm-map-pulse 3.6s cubic-bezier(.22, .61, .36, 1) infinite;
}
/* Starts on the outside of the halo rather than under the dot, so the ring is
   already visible on the frame it appears. */
@keyframes lm-map-pulse {
	0%   { transform: scale(1); opacity: .9; }
	78%  { transform: scale(2.6); opacity: 0; }
	100% { transform: scale(2.6); opacity: 0; }
}
/* A reader who asked for less movement still gets a pulse — it just does not
   move. The ring holds one size and breathes its opacity instead, slower than
   the travelling one. That is the substitution the guidance asks for: what
   the preference is about is things crossing the screen, not a light going up
   and down.

   It has to say !important to get past the blanket rule at the top of this
   file, which caps duration and iteration count on everything and cannot be
   told about exceptions any other way. */
@media (prefers-reduced-motion: reduce) {
	.concert-marker .pulse::after {
		transform: scale(1.35);
		animation: lm-map-breathe 5s ease-in-out infinite !important;
	}
}
@keyframes lm-map-breathe {
	0%, 100% { opacity: .85; }
	50%      { opacity: .12; }
}

/* ============================================ the memory card =========

   Section 02 of a concert and of a festival. Both pages carry the same
   card, so it lives here rather than in either of them — a copy in each
   would be two cards inside a month.

   The festival card has no cover to show, so it sets --lm-card-head to
   something shorter and leaves the picture out; everything else is the
   same object.
 */

/* ------------------------------------------------------------------ share

   This card is the file. html2canvas photographs #shareCard exactly as it
   stands and scales the render to 1080 wide, so what is on screen and what
   lands in the camera roll are the same object. Two rules follow.

   One: every measurement inside the card is a percentage of the card, in cqw
   off the stage — never rem, never vw. That is what makes the preview honest
   at any width, and it is what fixes the old bug. The card used to be a box
   with a fixed aspect-ratio and overflow:hidden holding type sized in rem and
   vw, so whether the contents fitted was luck. They did not fit at 16:9, and
   because .lm-card-body carries margin-top:auto the overflow went off the
   top: the first thing to disappear was the line naming the site. A few of
   the type sizes carry a rem value in front of the cqw one, so a browser
   without container queries still gets a readable card rather than a heap of
   default-sized text.

   Two: it can only use what html2canvas 1.4.1 actually paints — solid fills,
   gradients, borders, radii, shadows, loaded webfonts, and images with given
   dimensions. filter, backdrop-filter, masks and blend modes are dropped in
   silence. The card this replaces leaned on two of them, which is why the
   glow behind the artwork is missing from every PNG it ever made. */

.lm-share-grid {
	display: grid;
	grid-template-columns: var(--lm-share-cols);
	gap: clamp(1rem, 3vw, 1.75rem);
	align-items: start;
}
.lm-card-stage {
	container-type: inline-size;
	width: 100%;
	max-width: 28rem;
	margin: 0 auto;
}
/* A festival has no cover of its own, and the one stock picture every
   edition shares would say nothing about this particular weekend. Without
   the square to hold, the header only needs the room its type takes. */
.lm-card.is-flat { --lm-card-head: 34cqw; }

.lm-card {
	--lm-card-head: 48cqw;
	width: 100%;
	aspect-ratio: 4 / 5;
	margin: 0;
	background: var(--lm-ink);
	border-radius: 4px;
	box-shadow: 0 22px 44px rgba(var(--lm-shadow-rgb), .5);
	overflow: hidden;
	display: flex;
	flex-direction: column;
}
/* the header: cover, billing, stamp

   The artist cover is 300x300 and there is no larger one anywhere — the hero
   on this page asks for it at exactly 300, and the meta-tag helper points at
   the same file. It used to fill a band 1080 wide, which is a three and a
   half times enlargement, and that is the whole of why the picture on a
   downloaded card was soft. Here it is a square at very close to its own
   size, on a dark header, and it is sharp.

   A square source in a square box also settles the framing: object-fit is one
   of the properties html2canvas does not implement, so the browser cropped
   the old band and the PNG stretched it. With both sides equal there is
   nothing left for the two to disagree about. */

.lm-card-head {
	flex: 0 0 auto;
	height: 13rem;
	height: var(--lm-card-head);
	display: flex;
	align-items: center;
	gap: 4.5cqw;
	padding: 5cqw;
	background: var(--lm-bg);
}
.lm-card-cover {
	flex: 0 0 auto;
	display: block;
	width: 7.25rem;
	width: 27cqw;
	height: 7.25rem;
	height: 27cqw;
	object-fit: cover;
	border: 0.2cqw solid rgba(var(--lm-ink-rgb), .14);
	border-radius: 2px;
	background: var(--lm-panel-2);
}
.lm-card-headtext {
	min-width: 0;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 2.2cqw;
}
.lm-card-brand {
	font-family: var(--lm-mono);
	font-size: 0.625rem;
	font-size: 1.85cqw;
	line-height: 1.4;
	letter-spacing: .18em;
	text-transform: uppercase;
	color: var(--lm-muted);
}
.lm-card-billing {
	font-family: var(--lm-sans);
	font-size: 0.9375rem;
	font-size: 2.9cqw;
	line-height: 1.25;
	font-weight: 600;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--lm-gold);
}
/* The tour, under the act it belonged to. Quiet on purpose: the moment this
   is set as loudly as the name above it, the card starts announcing the tour
   as the thing that was attended. */
.lm-card-tour {
	font-family: var(--lm-mono);
	font-size: 0.6875rem;
	font-size: 2.05cqw;
	line-height: 1.35;
	letter-spacing: .04em;
	color: var(--lm-muted);
}
.lm-card-stamp {
	padding: 1.2cqw 2.4cqw;
	border: 0.26cqw solid var(--lm-green-lt);
	border-radius: 2px;
	background: rgba(var(--lm-green-dk-rgb), .62);
	font-family: var(--lm-sans);
	font-size: 0.6875rem;
	font-size: 1.95cqw;
	line-height: 1.4;
	font-weight: 700;
	letter-spacing: .2em;
	text-transform: uppercase;
	color: var(--lm-green-lt);
}

/* the stub */

.lm-card-face {
	position: relative;
	flex: 1 1 auto;
	min-height: 0;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	padding: 4.4cqw 5cqw 4.8cqw;
	border-top: 0.26cqw dashed rgba(var(--lm-bg-rgb), .28);
}
.lm-card-grain {
	position: absolute;
	inset: 0;
	pointer-events: none;
	opacity: .5;
	background-image: repeating-linear-gradient(45deg, rgba(var(--lm-bg-rgb), .05) 0 1px, transparent 1px 5px);
}
/* Every line on the stub carries a line-height of its own. Left to "normal",
   the box a browser gives a line of text can be shorter than the glyphs in
   it, and html2canvas paints to the box — which is how half of a tour name
   came to be missing from the picture while the page looked right. */
.lm-card-top {
	position: relative;
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 2cqw;
	font-family: var(--lm-mono);
	font-size: 0.625rem;
	font-size: 1.85cqw;
	line-height: 1.5;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--lm-on-paper);
}
.lm-card-top span { flex: 0 0 auto; }
.lm-card-body { position: relative; min-width: 0; }
.lm-card-body h3 {
	margin: 0;
	font-family: var(--lm-sans);
	font-size: 2.375rem;
	font-size: 8.6cqw;
	line-height: .94;
	text-transform: uppercase;
	font-weight: 700;
	color: var(--lm-bg);
	overflow-wrap: anywhere;
}
/* Long names step down rather than crowd the stub. Which step a name gets is
   decided in PHP, where the length is known, instead of by a clamp that can
   only see the viewport. */
.lm-card-body h3.is-long { font-size: 1.875rem; font-size: 6.8cqw; }
.lm-card-body h3.is-longer { font-size: 1.4375rem; font-size: 5.2cqw; }
.lm-card-body p {
	margin: 2.4cqw 0 0;
	font-family: var(--lm-mono);
	font-size: 0.8125rem;
	font-size: 2.5cqw;
	line-height: 1.4;
	letter-spacing: .04em;
	color: var(--lm-panel-2);
}
/* A festival edition and a long venue name land on the same line, and it is
   the one line on the card whose length nothing else bounds. */
.lm-card-body p.is-long { font-size: 0.6875rem; font-size: 2.1cqw; }
.lm-card-body p + p { margin-top: 1.2cqw; letter-spacing: .06em; color: var(--lm-on-paper); }
.lm-card-foot {
	position: relative;
	padding-top: 3.4cqw;
	border-top: 0.26cqw dashed rgba(var(--lm-bg-rgb), .3);
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 3cqw;
}
.lm-card-verdict { min-width: 0; }
.lm-card-verdict span {
	display: block;
	font-family: var(--lm-mono);
	font-size: 0.625rem;
	font-size: 1.85cqw;
	line-height: 1.5;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--lm-on-paper);
}
.lm-card-verdict b {
	display: block;
	margin-top: 0.6cqw;
	font-family: var(--lm-sans);
	font-size: 2rem;
	font-size: 7.4cqw;
	font-weight: 700;
	line-height: 1;
	color: var(--lm-green-dk);
}
.lm-card-verdict em {
	display: block;
	margin-top: 1cqw;
	font-style: normal;
	font-family: var(--lm-mono);
	font-size: 0.75rem;
	font-size: 2.4cqw;
	line-height: 1.4;
	letter-spacing: .06em;
	color: var(--lm-panel-2);
}
.lm-card-who { flex: 0 0 auto; display: flex; align-items: center; gap: 2.4cqw; }
/* Both follow the "I was there" button, and both carry a display of their
   own, which would otherwise win against the one [hidden] brings. */
.lm-card-stamp[hidden], .lm-card-who[hidden], .lm-card-verdict[hidden] { display: none; }
/* The foot rules a dashed line above whatever it holds. With the verdict
   hidden and the signature not shown there is nothing under that line, and a
   rule hanging over blank card reads as something that failed to load rather
   than as a ticket with room left on it. */
.lm-card-foot.is-bare { border-top: 0; padding-top: 0; }
/* Keeps the signature over on the right when the verdict beside it is hidden.
   The foot is space-between, and a lone child in one of those goes to the
   start — so without this the avatar slid under the date. */
.lm-card-who { margin-left: auto; }
.lm-card-who img,
.lm-card-initial {
	flex: 0 0 auto;
	display: block;
	width: 2.5rem;
	width: 9cqw;
	height: 2.5rem;
	height: 9cqw;
	border-radius: 50%;
	object-fit: cover;
	border: 0.26cqw solid rgba(var(--lm-bg-rgb), .25);
	background: var(--lm-panel-2);
}
/* Centred by line-height and text-align rather than by flex: the picture is
   painted from the text's own box, and a glyph centred by the flexbox is not
   in the box a painter would look in. Selector has to out-rank .lm-card-who
   span below, which is why it names both. */
.lm-card-who .lm-card-initial {
	background: var(--lm-green-dk);
	border-color: rgba(var(--lm-bg-rgb), .2);
	display: flex;
	align-items: center;
	justify-content: center;
	font-family: var(--lm-sans);
	font-size: 1.375rem;
	font-size: 4.9cqw;
	font-weight: 700;
	line-height: 1;
	padding-top: 0.45cqw;
	color: var(--lm-ink);
}
.lm-card-who strong {
	display: block;
	font-family: var(--lm-sans);
	font-size: 0.9375rem;
	font-size: 2.9cqw;
	font-weight: 600;
	line-height: 1.2;
	color: var(--lm-bg);
}
.lm-card-who div span {
	display: block;
	margin-top: 0.4cqw;
	font-family: var(--lm-mono);
	font-size: 0.625rem;
	font-size: 1.85cqw;
	line-height: 1.4;
	color: var(--lm-on-paper);
}

/* what you can do with it */

.lm-share-actions { display: flex; flex-wrap: wrap; gap: 9px; }
.lm-share-status {
	margin: 12px 0 0;
	font-family: var(--lm-mono);
	font-size: 0.6875rem;
	line-height: 1.5;
	color: var(--lm-muted);
	min-height: 1.0625rem;
}
.lm-share-status.is-bad { color: var(--lm-gold); }
.lm-share-copy { margin: 15px 0 0; font-size: 0.9375rem; line-height: 1.6; color: var(--lm-muted); text-wrap: pretty; }
.lm-share-links { margin: 17px 0 0; padding: 0; list-style: none; display: flex; flex-wrap: wrap; gap: 8px; }
.lm-share-links a {
	display: flex;
	align-items: center;
	font-family: var(--lm-sans);
	font-size: 0.75rem;
	letter-spacing: .1em;
	text-transform: uppercase;
	padding: 12px 18px;
	min-height: 2.75rem;
	border-radius: 2px;
	border: 1px solid rgba(var(--lm-ink-rgb), .3);
	color: var(--lm-ink);
}
.lm-share-links a:hover { border-color: var(--lm-green-lt); color: var(--lm-green-lt); }
.lm-copy-row { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 14px; }
.lm-copy-url {
	flex: 1 1 12rem;
	min-width: 0;
	display: flex;
	align-items: center;
	padding: 12px 13px;
	min-height: 2.75rem;
	background: var(--lm-bg);
	border: 1px solid rgba(var(--lm-ink-rgb), .18);
	border-radius: 2px;
	font-family: var(--lm-mono);
	font-size: 0.6875rem;
	color: var(--lm-muted);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.dc-tag {
	font-family: var(--lm-mono);
	font-size: 0.5938rem;
	letter-spacing: .08em;
	text-transform: uppercase;
	padding: 4px 8px;
	border-radius: 2px;
	border: 1px solid var(--lm-line-strong);
	color: var(--lm-muted);
}
.dc-tag.is-fest { border-color: rgba(var(--lm-gold-rgb), .45); color: var(--lm-gold); }