:root {
	/* Base accent — the old Software Updates blue, a little friendlier than the
	   raw Ghost accent. Used where no section hue applies (AI toggle/status dot). */
	--c-accent: #007bff;
	/* Per-section hues. Everything colored per section (card stripe, header dot,
	   tag, Editor's Pick icon) derives from --type-color, which resolves to one
	   of these — swap the hex here to retheme a whole section. */
	--c-update: #007bff;
	--c-launch: #28a745;
	--c-directory: #17a2b8;
	--c-project: var(--c-update);
}

/* Space the whole widget from the newsletter content above it. Applied to the
   mount point, not the first .activity-section, so the sticky bar/<h2> handoff
   (which relies on the bar's negative margin) stays intact. */
#activity-container {
	margin-top: 2rem !important;
}

.activity-card {
	position: relative;
	background: rgba(0, 0, 0, .03);
	box-sizing: border-box;
	border: 1px solid #ededed !important;
	box-shadow: none;
	overflow: hidden;
	transition: transform .15s ease, box-shadow .15s ease, background-color .2s ease, border-color .15s ease;
	margin-top: 0px !important;
	margin-bottom: 15px !important;
	border-radius: 12px !important;

	html[data-color-scheme='dark'] & {
		background: rgba(255, 255, 255, .035);
		border-color: transparent !important;
	}
}

.activity-card { --type-color: var(--c-accent); }
.activity-card--update { --type-color: var(--c-update); }
.activity-card--launch { --type-color: var(--c-launch); }
.activity-card--directory { --type-color: var(--c-directory); }
.activity-card--project { --type-color: var(--c-project); }

@media (min-width: 769px) and (hover: hover) {
	.activity-card:hover {
		transform: translateY(-2px);
		box-shadow: 0 8px 24px rgba(0, 0, 0, .12), 0 2px 6px rgba(0, 0, 0, .06);
		border-color: #dadada !important;
	}

	html[data-color-scheme='dark'] .activity-card:hover {
		border-color: rgba(255, 255, 255, .14) !important;
	}
}

/* Respect reduced-motion: drop the positional hover lift and its transition
   (subtle colour/opacity fades elsewhere are fine to keep). */
@media (prefers-reduced-motion: reduce) {
	.activity-card {
		transition: none;
	}

	.activity-card:hover {
		transform: none;
	}
}

/* Fallback shown when the activity feed can't load or has nothing this week. */
.activity-empty {
	margin: 0 !important;
	padding: 28px 16px;
	text-align: center;
	color: var(--color-typography-tone, #888);
	font-size: 15px;
}

.activity-card-container {
	align-items: flex-start;
	display: flex;
	flex-basis: 67%;
	flex-direction: column;
	justify-content: space-between;
	padding: 10px 14px;
	line-height: var(--line-height-extra);
}

.activity-title-container {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	font-size: 15px;
	font-weight: 700 !important;
	margin-bottom: 3px;
	line-height: 1.5;

	a {
		padding-bottom: 0px !important;
		font-weight: 700 !important;
		text-decoration: none !important;
	}
}

.activity-title-text {
	margin-right: 6px;
}

/* In dark mode lift the project name a touch above the description/icon tone. */
html[data-color-scheme='dark'] .activity-title-text-name {
	color: color-mix(in srgb, var(--color-main, #ddd) 80%, #fff);
}

.activity-text-container {
	display: -webkit-box;
	font-family: var(--font-family-post-body);
	font-size: 13.5px;
	line-height: 1.45;
	font-weight: var(--font-weight-post-body);
	letter-spacing: var(--letter-spacing-post-body);
	margin-bottom: 0;
	overflow-y: hidden;
}

/* Mute the description toward the page background so the (bold) project name reads
   a step above it. Scoped under #activity-container (ID) so it outranks the Ghost
   theme's desktop-only content-colour rule — that rule beat the plain class on wide
   screens (muted showed on mobile only). The *:not(a) arm catches text the raw
   description HTML wraps in its own elements; links keep their colour. Dark keeps
   full --color-main — muted tones wash out there, and the name is already lifted. */
#activity-container .activity-text-container,
#activity-container .activity-text-container *:not(a) {
	color: color-mix(in srgb, var(--color-main) 70%, var(--color-background, #fff)) !important;
}

html[data-color-scheme='dark'] #activity-container .activity-text-container,
html[data-color-scheme='dark'] #activity-container .activity-text-container *:not(a) {
	color: var(--color-main) !important;
}

.activity-tag {
	display: inline-flex !important;
	align-items: center !important;
	gap: 1px !important;
	font-size: 14px !important;
	font-weight: 500 !important;
	padding: 0 !important;
	margin: 0 10px 0 2px !important;
	line-height: 1 !important;
	text-decoration: none !important;
	background: transparent !important;
	color: color-mix(in srgb, var(--type-color, #888) 80%, #000) !important;
	position: relative !important;
	z-index: 2 !important;

	&::before {
		content: "#";
		font-weight: 600;
		opacity: 0.6;
	}

	html[data-color-scheme='dark'] & {
		color: color-mix(in srgb, var(--type-color, #888) 62%, #fff) !important;
	}

	&:hover {
		text-decoration: underline !important;
	}

	&:hover::before {
		opacity: 1;
	}
}

.activity-card-link {
	position: absolute;
	inset: 0;
	z-index: 1;
	border-radius: inherit;
}

.activity-version-text {
	font-weight: 400 !important;
	font-size: 13.5px;
	color: #6b7280;
	opacity: 1;
}

/* Keep any links inside the description clickable above the card overlay */
.activity-text-container a {
	position: relative;
	z-index: 2;
}

.activity-project-update-element {
	font-weight: bold;
	opacity: 0.95;
}

.activity-project-update-element-value {
	font-weight: 400;
	opacity: 0.95;
}

/* Icons shared across activity cards */
.activity-icon,
.activity-editors-pick-icon,
.activity-trending-icon {
	margin: 2px 4.5px 2px 0;
	vertical-align: middle;
	position: relative;
	z-index: 2;
}

.activity-icon {
	width: 16px;
	height: 16px;
}

.activity-icon {
	opacity: 0.4;

	html[data-color-scheme='dark'] & {
		filter: contrast(0%) brightness(350%);
		opacity: 0.70 !important;
	}
}

.activity-editors-pick-icon {
	display: inline-flex;
	align-items: center;
	color: color-mix(in srgb, var(--type-color, var(--ghost-accent-color)) 80%, #000);

	html[data-color-scheme='dark'] & {
		color: color-mix(in srgb, var(--type-color, var(--ghost-accent-color)) 62%, #fff);
	}

	svg {
		width: 16px;
		height: 16px;
		display: block;
	}
}

.activity-trending-icon {
	display: inline-flex;
	align-items: center;
	color: orange;
	/* The flame glyph sits inset within its viewBox; pull the box in so its
	   visible edges align with the other icons' spacing. */
	margin: 2px 2.5px 2px -2px;

	svg {
		width: 16px;
		height: 16px;
		display: block;
	}
}

.activity-bar {
	position: sticky;
	top: 0;
	z-index: 5;
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 4px 14px;
	min-height: 60px;
	box-sizing: border-box;
	background: var(--color-background, #fff);
	/* Negative margin (== min-height) collapses the bar's own row so the first
	   section <h2> flows up beside the legend instead of below it. */
	margin-bottom: -60px;
}

.activity-bar.is-past {
	visibility: hidden;
}

/* Edge fade: a short gradient pinned just below the sticky header so cards
   dissolve into the page as they scroll under it instead of cutting off at a
   hard line. It lives in the bar's stacking context (z-index 5) so it paints
   over card content (cards are z-index auto; their raised children top out at
   z-index 2) but never over the section <h2> (z-index 6): the heading owns the
   0-60px band and the strip sits in 60-76px, so they don't overlap. Uses the
   theme background token so it flips with light/dark automatically. */
.activity-bar::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	top: 100%;
	height: 16px;
	background: linear-gradient(to bottom, var(--color-background, #fff), transparent);
	pointer-events: none;
	/* Hidden at rest so the first card isn't feathered; JS adds is-stuck once
	   the bar pins to the top and content actually scrolls under it. */
	opacity: 0;
	transition: opacity .15s ease;
}

.activity-bar.is-stuck::after {
	opacity: 1;
}

/* The AI-Assisted chip uses a single fixed accent (--h3-dot) — it no longer
   shifts color per section, so the control doesn't read as changing state. */
.activity-bar { --h3-dot: var(--c-accent); }

#activity-toggles {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px 14px;
	margin-left: auto;
	position: relative;
	/* Sits above the section <h2> (z-index 6), which the negative-margin overlap
	   pulls into this same row; its own opaque fill keeps the legend readable even
	   if the theme renders the heading full-width. */
	z-index: 7;
	background: var(--color-background, #fff);
	padding-left: 10px;
}

#activity-lock-indicator {
	display: flex;
	align-items: center;
	flex-shrink: 0;
	color: #888;

	svg {
		width: 15px;
		height: 15px;
		display: block;
	}
}

.activity-legend-item {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	user-select: none;
	font-size: 13px;
	position: relative;

	&.locked {
		.activity-toggle-icon,
		.activity-legend-label {
			opacity: 0.75;
		}

		.activity-toggle-icon {
			color: #888;
		}
	}
}

.activity-key {
	display: inline-flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 6px 14px;
}

.activity-legend-label {
	font-size: 14px;
	color: var(--color-typography-tone);
	letter-spacing: -0.02em;
	opacity: 0.9;
	font-weight: normal;

	html[data-color-scheme='dark'] & {
		letter-spacing: 0em;
		/* The muted typography tone reads as washed out on the dark background;
		   match the card description colour (full --color-main) instead. */
		color: var(--color-main);
		opacity: 1;
	}
}

#ec-legend:not(.locked) .activity-toggle-icon {
	color: color-mix(in srgb, var(--h3-dot, var(--ghost-accent-color)) 80%, #000);
	transition: color .2s ease;
}

html[data-color-scheme='dark'] #ec-legend:not(.locked) .activity-toggle-icon {
	color: color-mix(in srgb, var(--h3-dot, var(--ghost-accent-color)) 62%, #fff);
}

#trending-legend:not(.locked) .activity-toggle-icon {
	color: orange;
}

/* Legend spacing refinements — DESKTOP ONLY. On mobile the labels are hidden
   (the legend collapses to an icon-only cluster), so icon-to-label gaps and the
   AI-vs-key separation are irrelevant there. */
@media (min-width: 641px) {
	/* Tighten each marker's icon-to-label gap. */
	.activity-legend-item {
		gap: 3px;
	}

	/* The flame glyph is inset within its viewBox, so its span leaves whitespace
	   on the right that reads as a wider gap before the label than the Editor's
	   Pick star. Pull the label in to match (paid + locked). */
	#trending-legend .activity-toggle-icon {
		margin-right: -2px;
	}

	/* Give the interactive AI-Assisted toggle a little more breathing room from
	   the display-only marker key (Editor's Pick / Trending). Adds to the
	   #activity-toggles column gap. */
	.activity-key {
		margin-left: 5px;
	}
}

#activity-container h2 {
	position: sticky;
	top: 0;
	z-index: 6;
	width: fit-content;
	max-width: 100%;
	min-height: 60px;
	box-sizing: border-box;
	display: flex;
	align-items: center;
	background: var(--color-background, #fff);
	margin-top: 0 !important;
	margin-bottom: 0 !important;
	padding-top: 6px;
	padding-bottom: 6px;
}

/* Header marker: a small dot in the section's hue, trailing the title.
   The h2 is already display:flex/align-items:center, so it centers natively. */
#activity-container h2#software-updates { --type-color: var(--c-update); }
#activity-container h2#new-software { --type-color: var(--c-launch); }
#activity-container h2#directory-additions { --type-color: var(--c-directory); }
#activity-container h2#project-updates { --type-color: var(--c-project); }

#activity-container h2::after {
	content: "";
	flex: 0 0 auto;
	width: 9px;
	height: 9px;
	border-radius: 50%;
	margin-left: 9px;
	background: var(--type-color, var(--c-accent));
}

html[data-color-scheme='dark'] #activity-container h2::after {
	background: color-mix(in srgb, var(--type-color, var(--c-accent)) 62%, #fff);
}

#activity-container h2 + .activity-card {
	margin-top: 4px !important;
}


/* AI-Assisted reads like the Editor's Pick / Trending markers (icon + label, no
   chip). The robot stays the SAME muted gray it is on a card (AI apps are flagged,
   not highlighted). A small trailing status dot carries the show/hide state: it
   glows the accent when AI-assisted apps are shown (default) and goes gray when
   they're hidden — a live-indicator metaphor, not a UI widget. */
.activity-toggle {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	cursor: pointer;
	user-select: none;
	position: relative;
	font-size: 13px;

	&:empty {
		display: none;
	}

	.activity-dot {
		width: 8px;
		height: 8px;
		border-radius: 50%;
		margin-left: -1px;
		flex: 0 0 auto;
		/* Hidden state: a quiet gray dot, no glow. */
		background: #9b9b9b;
		transition: background-color .15s ease, box-shadow .15s ease;
	}

	/* Shown (default): the dot is solid accent, no glow at rest. */
	&.active .activity-dot {
		background: color-mix(in srgb, var(--c-accent) 80%, #000);
	}

	/* Hovering the shown entry adds a soft glow to hint the apps can be hidden.
	   Gated on hover:hover so it doesn't trigger on touch. */
	@media (hover: hover) {
		&.active:not(.locked):hover .activity-dot {
			box-shadow: 0 0 5px color-mix(in srgb, var(--c-accent) 65%, transparent);
		}
	}

	/* Unpaid view: the robot matches the Editor's Pick / Trending locked icons
	   (gray, 0.75), and the dot stays blue but faded (no glow) to read as locked. */
	&.locked {
		cursor: not-allowed;

		.activity-toggle-icon { color: #888; opacity: 0.75; }
		.activity-legend-label { opacity: 0.75; }

		.activity-dot {
			background: var(--c-accent);
			opacity: 0.4;
			box-shadow: none;
		}
	}
}

html[data-color-scheme='dark'] .activity-toggle .activity-dot {
	background: #6a6a6a;
}

html[data-color-scheme='dark'] .activity-toggle.active .activity-dot {
	background: color-mix(in srgb, var(--c-accent) 62%, #fff);
}

/* Locked overrides the active dot (the unpaid control still carries .active by
   default); placed after so it wins the equal-specificity dark active rule. */
html[data-color-scheme='dark'] .activity-toggle.locked .activity-dot {
	background: color-mix(in srgb, var(--c-accent) 75%, #fff 25%);
	opacity: 0.45;
	box-shadow: none;
}

.activity-toggle-message {
	position: absolute;
	top: calc(100% + 8px);
	left: 0;
	background: #1a1a1a;
	color: #fff;
	font-size: 14px;
	font-weight: normal;
	letter-spacing: 0.03em;
	line-height: 1.5;
	padding: 8px 14px;
	border-radius: 4px;
	width: max-content;
	max-width: min(300px, 85vw);
	pointer-events: none;
	opacity: 0;
	transition: opacity 0.2s;
	z-index: 100;
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);

	html[data-color-scheme='dark'] & {
		border: 1px solid rgba(255, 255, 255, 0.25);
	}
}

.activity-toggle-message.visible {
	opacity: 1;
}

/* Hover reveal only on hover-capable devices — on touch, :hover sticks after a
   tap and would pin the tooltip open; there the JS-timed .visible class drives it. */
@media (hover: hover) {
	.activity-toggle.locked:hover .activity-toggle-message,
	.activity-legend-item.locked:hover .activity-toggle-message,
	#activity-toggles.is-locked:hover .activity-toggle-message {
		opacity: 1;
	}
}

@media (max-width: 640px) {
	/* The legend is right-aligned and stuck to the top on mobile, so anchor the
	   message to the right edge (grows leftward) and drop it BELOW the bar. Popping
	   it above ran it off the top of the screen and behind the sticky <h2> — the
	   message lives in the bar's lower stacking context (z-index 5) so it can't
	   paint over the heading (z-index 6); below the bar there's nothing to cover it. */
	.activity-toggle-message {
		top: calc(100% + 8px);
		bottom: auto;
		left: auto;
		right: 0;
	}

	/* Icon-only legend on mobile — drop ALL labels, including AI-Assisted. That
	   shrinks the legend to a compact icon cluster that fits beside the section
	   <h2> and sticks/hands off with it (the desktop beside layout), instead of
	   taking its own line above the content. Meaning stays available via the tap
	   tooltip; the status dot still shows the AI show/hide state. */
	.activity-bar .activity-legend-label {
		display: none;
	}

	/* Unpaid members can't toggle, so the (locked) dot is just noise on the
	   cramped mobile legend — hide it there, leaving the robot marker alone. */
	.activity-toggle.locked .activity-dot {
		display: none;
	}

	/* Unpaid: pull the three legend icons closer together... */
	#activity-toggles.is-locked {
		gap: 8px;
	}

	#activity-toggles.is-locked .activity-key {
		gap: 6px 8px;
	}

	/* ...and divide the lock icon off from them so it doesn't read as a legend
	   icon itself. The padding sits between the lock and the rule; the flex gap
	   provides the matching space on the legend side. */
	#activity-toggles.is-locked #activity-lock-indicator {
		padding-right: 8px;
		border-right: 1px solid color-mix(in srgb, var(--color-main, #888) 22%, transparent);
	}
}

.activity-toggle-icon {
	display: flex;
	align-items: center;
	color: #888;
	transition: color 0.2s;

	svg {
		width: 17px;
		height: 17px;
		display: block;
	}
}

/* Hover tooltip for card icons — mirrors the app directory's #app-tooltip:
   a frosted, semi-transparent dark chip positioned via JS. Kept dark in both
   color schemes (conventional for tooltips) rather than flipping with the theme. */
#activity-tooltip {
	position: fixed;
	z-index: 99999;
	pointer-events: none;
	padding: 4px 10px;
	background: rgba(28, 28, 30, .82);
	-webkit-backdrop-filter: blur(3px);
	backdrop-filter: blur(3px);
	color: #f5f5f5;
	font-size: 0.75rem;
	font-weight: 500;
	border-radius: 6px;
	white-space: pre-line;
	max-width: 260px;
	text-align: left;
	line-height: 1.5;
	opacity: 0;
	transition: opacity .08s ease;
	border: 1px solid rgba(255, 255, 255, .1);
	box-shadow: 0 2px 8px rgba(0, 0, 0, .2);
}

#activity-tooltip.visible {
	opacity: 1;
}
