/*
 * salsa06.com — the whole stylesheet.
 *
 * Standalone: the page used to load Bootstrap for ten classes and a
 * JavaScript bundle it never called, so the few framework behaviours it
 * genuinely relied on are folded in here — the box-sizing rule, the
 * element margins, and `svg { vertical-align }`, which is what keeps the
 * flag and the star on the text's centre line.
 *
 * The listing is the page. Everything here works towards reading it
 * quickly: the date is the loudest thing, the party name next, the venue
 * line quiet underneath, and a hairline between events instead of
 * bullets and indents.
 */

/* --------------------------------------------------------------- tokens */

:root {
	/* Every secondary tone is WHITE at reduced opacity rather than a
	   fixed grey. The background is a gradient that travels through four
	   colours, so a grey light enough for the navy leg turns invisible on
	   the sky-blue one — the tones have to be made of the text colour, not
	   guessed against one frame of the animation. */
	--text: #fff;
	--muted: rgb(255 255 255 / 78%);
	--dim: rgb(255 255 255 / 68%);
	--rule: rgb(255 255 255 / 28%);

	/* A shade lighter than the site's usual #fdcc52, which the crimson
	   leg of the gradient swallows. */
	--accent: #ffd166;
	--cancelled: #ff8080;

	/* Space Grotesk sets tight and slightly mechanical, which is what
	   gives the masthead and the dates their edge; Geist stays quiet
	   underneath so the listing reads as data. Generic families are
	   UNQUOTED — quoted, they would be read as the name of a font. */
	--font-display: "Space Grotesk", sans-serif;
	--font-body: "Geist", system-ui, sans-serif;

	--gutter: 0.75rem;

	/* The "opens elsewhere" arrow, as a mask rather than an <img> or a
	   glyph: masked, it takes its colour from the text it sits beside,
	   needs no icon font, and never lands in a copied selection. */
	--icon-external: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 17 17 7M9 7h8v8'/%3E%3C/svg%3E");
}

/* ---------------------------------------------------------------- reset */

*,
*::before,
*::after {
	box-sizing: border-box;
}

body {
	margin: 0;
	font-family: var(--font-body);
	font-weight: 400;
	font-size: 1.05em;
	line-height: 1.5;
	color: var(--text);

	/* The site's own background: one gradient four times the size of the
	   page, slid slowly from one corner to the other, so the colour under
	   the listing is never quite the same twice.
	   Darker and purpler than the Django original, which ran crimson →
	   navy → sky blue and spent much of the loop on a bright cyan the
	   white text had to fight. Every stop here is a dark blue-violet, so
	   the whole lap stays in one family instead of one corner being
	   purple and the rest not — a single purple stop is barely ever in
	   frame, since the viewport only ever shows a quarter of the tile. */
	background-color: #16224f;
	background-image: linear-gradient(-45deg, #4a2d7a, #16224f, #245f96, #3b3486);
	background-size: 400% 400%;
	background-position: 0% 50%;
}

/* Opt-in: this repaints for as long as the page is open, and some
   readers ask their system for less motion. They get frame 0, which is
   the position set above. */
@media (prefers-reduced-motion: no-preference) {
	body {
		animation: drift 180s ease-in-out infinite;
	}
}

@keyframes drift {
	0%,
	100% {
		background-position: 0% 50%;
	}
	50% {
		background-position: 100% 50%;
	}
}

/* ----------------------------------------------------- theme B (unwired)
 *
 * Midnight: near-black with a violet and a wine glow drifting across it.
 * Not in use — nothing carries this class. To try it, add
 * class="theme-midnight" to <body> in internal/public/salsa06/page.templ.
 *
 * It is a class rather than a commented-out block so it stays real CSS:
 * it is parsed, it is formatted, and it cannot quietly rot into
 * something that no longer compiles.
 *
 * Note the palette overrides. The tones above are white at reduced
 * opacity because they sit on a bright moving gradient; on near-black
 * that reads as washed-out, so this theme swaps them for solid greys
 * mixed towards the surface. The two are not interchangeable.
 */

body.theme-midnight {
	--text: #ececf1;
	--muted: #9a9ab0;
	--dim: #8b8ba7;
	--rule: rgb(255 255 255 / 7%);
	--accent: #ffb703;
	--cancelled: #ff6b6b;

	/* Each gradient is centred in its own box and the BOX is what moves,
	   which is why the sizes are over 100%: background-position slides the
	   box within the container, so a glow can travel (size − 100%). At
	   150% the centres could only reach a quarter in from each edge and
	   the drift looked pinned to the middle; at 240% they sweep past all
	   four corners. Fixed attachment so they belong to the window rather
	   than scrolling away with the listing. */
	background-color: #0a0a0f;
	background-image:
		radial-gradient(60rem 38rem at 50% 50%, #4a2585 0%, transparent 60%),
		radial-gradient(48rem 30rem at 50% 50%, #a8285a 0%, transparent 58%);
	background-size:
		240% 240%,
		240% 240%;
	background-position:
		5% 10%,
		95% 85%;
	background-repeat: no-repeat;
	background-attachment: fixed;
}

@media (prefers-reduced-motion: no-preference) {
	body.theme-midnight {
		/* linear, not ease-in-out: eased between EVERY keyframe the drift
		   slows to a stop five times a lap and reads as static. */
		animation: glow 40s linear infinite;
	}
}

/* The two glows travel opposite paths, so they cross the page and pass
   each other rather than sliding in formation. */
@keyframes glow {
	0%,
	100% {
		background-position:
			5% 10%,
			95% 85%;
	}
	20% {
		background-position:
			85% 85%,
			10% 15%;
	}
	40% {
		background-position:
			50% 100%,
			95% 20%;
	}
	60% {
		background-position:
			95% 15%,
			5% 90%;
	}
	80% {
		background-position:
			10% 60%,
			60% 5%;
	}
}

h1,
h2,
h3 {
	margin: 0 0 0.5rem;
	font-family: var(--font-display);
	font-weight: 700;
	line-height: 1.2;
	letter-spacing: -0.03em;
}

p {
	margin: 0 0 1rem;
}

ul {
	margin: 0 0 1rem;
	padding-left: 2rem;
}

strong {
	font-weight: bolder;
}

/* Inline icons sit on the text's centre line rather than its baseline.
   The flag and the DJ star both depend on this. */
svg {
	vertical-align: middle;
}

a {
	color: var(--accent);
	text-decoration: underline;
	transition: color 0.2s;
}

a:hover,
a:focus {
	color: var(--text);
}

/* ----------------------------------------------------------- page frame */

/* The reading column: full width with a gutter, widening in steps so a
   line of event text never runs the whole of a large screen. */
.container {
	width: 100%;
	margin-inline: auto;
	padding-inline: var(--gutter);
}

@media (width >= 576px) {
	.container {
		max-width: 540px;
	}
}
@media (width >= 768px) {
	.container {
		max-width: 720px;
	}
}
@media (width >= 992px) {
	.container {
		max-width: 960px;
	}
}
@media (width >= 1200px) {
	.container {
		max-width: 1140px;
	}
}
@media (width >= 1400px) {
	.container {
		max-width: 1320px;
	}
}

header.masthead {
	padding-block: 50px 100px;
}

/* Salsa 06, with its byline beside it.
   Baseline alignment rather than bottom-of-box: the two sit on the same
   line of writing, where aligning the boxes would drop the small text
   into the title's descender space and leave it looking sunk. */
.masthead-title {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: 0 0.9rem;
}

header.masthead > .container:first-child h1 {
	font-size: min(4.5rem, calc(2.2rem + 3.4vw));
}

/* Set like the section labels — same display face, same uppercase, same
   grey — so it reads as a credit rather than as part of the title. */
.byline {
	margin: 0;
	font-family: var(--font-display);
	font-size: 0.85rem;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.16em;
	color: var(--dim);
}

.byline a {
	color: inherit;
	text-decoration: underline;
	text-decoration-color: rgb(255 255 255 / 35%);
	text-underline-offset: 0.25em;
}

.byline a:hover,
.byline a:focus {
	color: var(--text);
}

header.masthead > .container:first-child h1 strong {
	color: var(--accent);
}

/* The page's own line ("Soirées Salsa … sur la Côte d'Azur"). Marked up
   as a heading, but it reads as a standfirst, so it is set as one. */
header.masthead > .container:first-child .fbeventz h1 {
	font-family: var(--font-body);
	font-size: 1rem;
	font-weight: 400;
	letter-spacing: 0;
	color: var(--muted);
}

/* -------------------------------------------------------------- listing */

/* One block per section ("Cette semaine", "Plus tard"). */
.accordionEvent {
	margin-block: 50px;
}

.accordionEvent .card-header {
	padding-block: 1em;
}

/* "Cette semaine", "Plus tard". A quiet label rather than a title: it
   names the section, but the dates below are what the page is read by,
   so it gets out of their way.
   On the h2 now — the markup used to nest an h3 inside it, which is
   invalid, and the styling followed the inner one. */
.accordionEvent .card-header h2 {
	margin: 0;
	font-size: 0.85rem;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.16em;
	color: var(--dim);
}

.fbeventz {
	margin: 0;
	padding: 0;
}

/* The date. Loudest thing in the listing, because it is what the page is
   navigated by — you look for tonight, then read what is on. */
#content .fbeventz h1 {
	margin-bottom: 0.5rem;
	font-size: 1.35em;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--accent);
}

/* No bullets and no indent: a hairline between events separates them
   better than a marker, and buys back the width. */
#content .fbeventz ul {
	margin: 0 0 2.5rem;
	padding-left: 0;
	list-style: none;
}

#content .fbeventz li {
	border-top: 1px solid var(--rule);
}

/* The padding lives on the row, not the li, so that when the row IS a
   link the whole padded band is the tap target — two lines tall on a
   phone instead of the width of a party name. */
/* Square, and flush with the hairlines above and below: the highlight
   is the row, so it ends exactly where the row's rules do.
   The 8px on the left holds the text off that edge, so the hover
   highlight has a margin rather than butting straight against the party
   name. It is on .row and not only on the anchor: applied to the links
   alone, linked and unlinked events would start at different places and
   the column of titles would go ragged. */
.fbeventz .row {
	position: relative;
	display: block;
	padding: 0.85rem 2.2rem 0.85rem 8px;
	color: inherit;
	text-decoration: none;
}

/* An arrow at the right edge, in a column down the page: it marks the
   rows that go somewhere without putting an icon inside the sentence,
   which is where it read as a second separator. */
a.row::after {
	content: "";
	position: absolute;
	right: 0.6rem;
	top: 50%;
	translate: 0 -50%;
	width: 0.85rem;
	height: 0.85rem;
	opacity: 0.45;
	background-color: currentColor;
	mask: var(--icon-external) center / contain no-repeat;
	transition:
		opacity 0.2s,
		translate 0.2s;
}

a.row:hover,
a.row:focus-visible {
	background: rgb(255 255 255 / 8%);
}

a.row:hover::after,
a.row:focus-visible::after {
	opacity: 1;
	translate: 2px -50%;
}

.fbeventz .row > div:first-child {
	font-weight: 500;
}

/* The subtitle after the party name: lighter and in the muted tone, so
   the title is what the eye lands on and the qualifier follows it. */
.fbeventz .subname {
	color: var(--muted);
	font-weight: 400;
}

/* the second line: city, venue, address, repeat day */
.fbeventz .sub_event {
	margin-top: 0.15rem;
	font-size: 0.86em;
	color: var(--muted);
}

.fbeventz .sub_event strong {
	color: var(--accent);
	font-weight: 500;
}

/* The venue is the second thing looked for after the city, so it stays
   at full contrast — the address after it is reference material and
   stays quiet. Never a link (see eventBody). */
.fbeventz .venue {
	color: var(--text);
}

.fbeventz .cancelled {
	color: var(--cancelled);
	text-decoration: line-through;
}

.fbeventz .cancelled a,
.fbeventz .cancelled strong {
	color: var(--cancelled);
}

/* Nudged off the centre line: a flag is a solid rectangle, and centring
   it by its box leaves it reading slightly low against the city name. */
.country-flag {
	vertical-align: 0.06em;
}

/* The badge marking a night DJ Anael plays: a solid accent disc with the
   headphones knocked out of it. A filled disc is what makes it findable
   while scanning a long list — the outline alone disappeared into the
   text.
   The drawing is inline SVG (see djAnaelMark); all this does is colour
   and place it. It was a CSS mask over a data URI, which rasterised the
   disc and left its edge visibly soft. */
.dj-mark {
	color: var(--accent);
	margin-left: 0.25em;
	vertical-align: -0.3em;
}

/* --------------------------------------------------------------- footer */

footer {
	padding-block: 25px 40px;
	text-align: center;
	color: var(--dim);
}

footer p {
	margin: 0;
	font-size: 12px;
}

footer ul {
	margin-bottom: 0;
}

footer a {
	font-size: 12px;
	color: var(--dim);
	text-decoration: none;
}

footer a:hover,
footer a:focus {
	color: var(--text);
}

.list-inline {
	padding-left: 0;
	list-style: none;
}

.list-inline-item {
	display: inline-block;
}

.list-inline-item:not(:last-child) {
	margin-right: 0.75rem;
}
