/*
 * DC-41450 — HyperFollow "Direct Release" page.
 * Served behind the LaunchDarkly flag hyperfollow-release-page-test; see _directRelease.cfm.
 *
 * Ported from the design prototype (direct-release-landing-v4), then revised for DC-42228 to
 * Keith's design: a light page with a permanently dark hero panel. Colour ramps, breakpoints and
 * spacing utilities still come from /css/generic.css, and the page uses the site's Lato face.
 *
 * Every class is hfd- prefixed to stay clear of main.css's global soup.
 */

/* ---- Tokens ---------------------------------------------------------------
 * DC-42228: light only. DC-41450 shipped a dark default with a prefers-color-scheme block, a
 * :root[data-theme="light"] block and a :root[data-theme="dark"] block, driven by ?theme=. Every
 * frame in Keith's design is a light page, so all three collapsed into this one palette and
 * ?theme= is gone. The dark treatment that remains is the hero panel, which is dark by design
 * rather than by theme — see the token re-declaration on .hfd-hero further down.
 */
:root {
	--hfd-font: "Lato", helvetica, arial, sans-serif;
	--hfd-radius: 10px;
	--hfd-radius-sm: 8px;
	--hfd-radius-card: 12px;
	--hfd-ownerbar-h: 56px;
	--hfd-topnav-h: 68px;
	--hfd-page-max: 1040px;
	--hfd-page-gutter: 16px;
	--hfd-ease: 150ms ease;

	/* DC-42228 (Keith's "Spacing adjustments" frames, Figma 9967-1065): the page's vertical rhythm.
	   Every section rule gets --hfd-section-gap of clearance above and below, every section heading
	   sits --hfd-heading-gap above its content, every grid thumbnail sits --hfd-card-gap above its
	   caption. Redefined at 768 alongside --hfd-page-gutter. */
	--hfd-section-gap: 36px;
	--hfd-heading-gap: 18px;
	--hfd-grid-gap: 18px;
	--hfd-card-gap: 12px;
	--hfd-about-gap: 30px;

	/* The hero runs one uniform step: artwork -> title -> player -> store list -> "Show all". */
	--hfd-hero-gap: 24px;
	--hfd-footer-gap: 60px;

	/* Sampled from the reference export's CTA, not Spotify's brand sheet. */
	--hfd-spotify: #00db4d;
	--hfd-bg: #fff;
	--hfd-surface: #f3f4f6;
	--hfd-surface-2: #e5e7eb;
	--hfd-text: #0f0f0f;
	--hfd-muted: #6b7280;
	--hfd-muted-2: #9ca3af;
	--hfd-border: #e5e7eb;
	--hfd-buy: #0f0f0f;
	--hfd-buy-text: #fff;
	--hfd-btn-text: rgb(15 15 15 / 88%);
	--hfd-btn-bg: rgb(15 15 15 / 5%);
	--hfd-btn-border: rgb(15 15 15 / 16%);
	--hfd-btn-hover: rgb(15 15 15 / 10%);
	--hfd-invert-fg: #fff;
	--hfd-chrome-shadow: 0 8px 24px rgb(0 0 0 / 12%);
	--hfd-skel-a: #f3f4f6;
	--hfd-skel-b: #e5e7eb;
	--hfd-cta-bg: #fff;
	--hfd-cta-border: rgb(15 15 15 / 20%);
	--hfd-cta-title: #111;
	--hfd-cta-body: #4b5563;
	--hfd-cta-eyebrow: rgb(15 15 15 / 45%);
	--hfd-cta-btn-bg: #fff;
	--hfd-cta-btn-text: #111;
	--hfd-logo-filter: invert(1) brightness(0.12);

	/* The amber countdown line and the NEW badge on the newest release tile. */
	--hfd-countdown: #e8a33d;
	--hfd-accent: #f6c445;

	/* The dark hero panel: cover art in greyscale under a near-opaque black wash. */
	--hfd-hero-wash: rgb(0 0 0 / 88%);

	/* share-modal brand tiles (ported from BandZoogle's direct.distrokid.com modal).
	   The two black tiles sit on white here, so they need no edge. */
	--hfd-brand-x: #000;
	--hfd-brand-threads: #000;
	--hfd-brand-facebook: #1877f2;
	--hfd-brand-reddit: #ff4500;
	--hfd-brand-email: #4b5563;
	--hfd-brand-edge: transparent;
}

/* ---- Reset (page-scoped) -------------------------------------------------- */
.hfd-body,
.hfd-body *,
.hfd-body *::before,
.hfd-body *::after {
	box-sizing: border-box;
}

.hfd-body {
	margin: 0;
	padding: 0;
	background: var(--hfd-bg);
	color: var(--hfd-text);
	font-family: var(--hfd-font);
	font-size: 14px;
	line-height: 1.5;
	-webkit-font-smoothing: antialiased;
}

.hfd-body h1,
.hfd-body h2,
.hfd-body p,
.hfd-body ol,
.hfd-body ul {
	margin: 0;
	padding: 0;
}

.hfd-body img,
.hfd-body svg {
	display: block;
	max-width: 100%;
}

.hfd-body a {
	color: inherit;
	text-decoration: none;
}

.hfd-body button {
	font-family: inherit;
}

.hfd-body [hidden] {
	display: none;
}

/* ---- Owner utility bar --------------------------------------------------- */

/* DC-42228: the slim dark bar the design puts above the artist bar. Owner-only — it carries
   "Dashboard", which replaced the footer "Manage" button. */
.hfd-ownerbar {
	display: flex;
	align-items: center;
	height: var(--hfd-ownerbar-h);
	background: #1c1c1c;
	color: rgb(255 255 255 / 92%);
}

.hfd-ownerbar-inner {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: 8px;
	width: min(100%, var(--hfd-page-max));
	margin: 0 auto;
	padding: 0 var(--hfd-page-gutter);
}

.hfd-ownerbar-btn {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 6px 10px;
	background: none;
	border: none;
	border-radius: var(--hfd-radius-sm);
	color: inherit;
	font-size: 13px;
	font-weight: 500;
	cursor: pointer;
	transition: background var(--hfd-ease);
}

.hfd-ownerbar-btn:hover {
	background: rgb(255 255 255 / 12%);
}

.hfd-ownerbar-btn.is-primary {
	background: rgb(255 255 255 / 12%);
}

.hfd-ownerbar-btn.is-primary:hover {
	background: rgb(255 255 255 / 20%);
}

.hfd-ownerbar-btn svg {
	width: 15px;
	height: 15px;
	flex-shrink: 0;
}

/* ---- Top nav ------------------------------------------------------------- */

/* DC-42228: in normal flow rather than fixed, so the full-bleed hero abuts it exactly as drawn.
   .hfd-page consequently no longer needs a padding-top to clear it. */
.hfd-topnav {
	display: flex;
	align-items: center;
	min-height: var(--hfd-topnav-h);
	padding: 10px 0;
	background: var(--hfd-bg);
}

.hfd-topnav-inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	width: min(100%, var(--hfd-page-max));
	margin: 0 auto;
	padding: 0 var(--hfd-page-gutter);
}

.hfd-topnav-right {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: 8px;
	margin-left: auto;
	flex-shrink: 0;
}

.hfd-artist-chip {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	min-width: 0;
	color: var(--hfd-text);
}

.hfd-artist-chip img {
	width: 40px;
	height: 40px;
	border-radius: 9999px;
	object-fit: cover;
	background: var(--hfd-surface);
	flex-shrink: 0;
}

/* The mobile frame explicitly demonstrates a name wrapping onto a second line, so clamp at two
   rather than ellipsing at one. */
.hfd-artist-chip span {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	font-size: 16px;
	font-weight: 700;
	letter-spacing: -0.02em;
	line-height: 1.25;
}

/* ---- Buttons ------------------------------------------------------------- */
.hfd-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
	padding: 6px 12px;
	background: var(--hfd-btn-bg);
	border: 1px solid var(--hfd-btn-border);
	border-radius: 6px;
	color: var(--hfd-btn-text);
	font-size: 12px;
	font-weight: 700;
	line-height: 1;
	white-space: nowrap;
	cursor: pointer;
	transition: background var(--hfd-ease), color var(--hfd-ease);
}

.hfd-btn:hover {
	background: var(--hfd-btn-hover);
	color: var(--hfd-text);
}

.hfd-btn svg {
	width: 14px;
	height: 14px;
	flex-shrink: 0;
}

.hfd-topnav-right .hfd-btn {
	height: 32px;
	padding-top: 0;
	padding-bottom: 0;
}

/* ---- Page shell ---------------------------------------------------------- */
.hfd-page {
	display: flex;
	flex-direction: column;
	min-height: 100vh;
}

.hfd-main {
	flex: 1;
	width: 100%;
	max-width: var(--hfd-page-max);
	margin: 0 auto;
	padding: var(--hfd-section-gap) var(--hfd-page-gutter) 0;
}

/* Owner-only banner for a hidden page */
.hfd-hidden-banner {
	padding: 1em;
	background: var(--hfd-text);
	color: var(--hfd-bg);
	font-weight: 700;
	text-align: center;
	text-transform: uppercase;
}

/* ---- Hero ---------------------------------------------------------------- */

/* DC-42228: a full-bleed dark band. The cover art is the backdrop, desaturated to greyscale, with
   #000 at 88% laid over it (the spec frame annotates exactly those two values). Two pseudo-elements
   rather than one, because the wash must not be caught by the greyscale filter — a single element
   cannot filter its background image and hold an unfiltered overlay at the same time.
   The hero re-declares the surface/text tokens for its subtree, so .hfd-audio, .hfd-dsp-row and the
   rest keep working unchanged inside a dark panel on an otherwise light page. */
.hfd-hero {
	--hfd-surface: #1f1f1f;
	--hfd-surface-2: #2a2a2a;
	--hfd-text: #fff;
	--hfd-muted: #9a9a9a;
	--hfd-muted-2: #7c7c7c;
	--hfd-border: rgb(255 255 255 / 10%);
	--hfd-btn-bg: rgb(255 255 255 / 10%);
	--hfd-btn-hover: rgb(255 255 255 / 18%);
	--hfd-invert-fg: #000;

	position: relative;
	isolation: isolate;
	width: 100%;
	background: #000;
	color: var(--hfd-text);
}

.hfd-hero::before,
.hfd-hero::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	pointer-events: none;
}

.hfd-hero::before {
	background-image: var(--hfd-hero-bg);
	background-size: cover;
	background-position: center;
	filter: grayscale(1);
}

.hfd-hero::after {
	background: var(--hfd-hero-wash);
}

/* Content stays on the page grid even though the band is full-bleed. */
.hfd-hero-inner {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--hfd-hero-gap);
	width: min(100%, var(--hfd-page-max));
	margin: 0 auto;

	/* 32 + the 4px tap padding on .hfd-dsp-more = the 36 the small-screen frame leaves below the
	   "Show all" label. */
	padding: 0 0 32px;
}

.hfd-hero-art-wrap {
	position: relative;
	width: 100%;
}

/* Mobile: the artwork is edge-to-edge and square-cornered, per the small-screen frame. */
.hfd-hero-art {
	width: 100%;
	aspect-ratio: 1;
	object-fit: cover;
	background: #111;
	cursor: zoom-in;
}

.hfd-hero-info {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--hfd-hero-gap);
	width: 100%;
	padding: 0 var(--hfd-page-gutter);
	text-align: center;
}

/* Sizes measured off the reference exports rather than guessed: at 1440 the design's title sets
   at ~26px and the countdown/date lines at ~15px; at 402 the title drops to ~22px. */
.hfd-hero-title {
	font-size: 22px;
	font-weight: 500;
	letter-spacing: -0.01em;
	line-height: 1.2;
	color: var(--hfd-text);
}

.hfd-hero-date {
	font-size: 15px;
	color: var(--hfd-text);
}

/* Sits above the "Available <date>" line — the order DC-42228 reversed. */
.hfd-countdown {
	font-size: 15px;
	font-weight: 400;
	letter-spacing: 0.01em;
	color: var(--hfd-countdown);
	font-variant-numeric: tabular-nums;
}

.hfd-hero-state {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--hfd-hero-gap);
	width: 100%;
}

/* ---- Pre-save CTA -------------------------------------------------------- */
.hfd-cta-presave {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 10px;
	width: 100%;
	margin-top: 0;
	padding: 11px 18px;
	background: var(--hfd-spotify);
	color: #000;
	border: none;
	border-radius: var(--hfd-radius-sm);
	font-size: 15px;
	font-weight: 700;
	cursor: pointer;
	transition: filter var(--hfd-ease), transform var(--hfd-ease);
}

.hfd-cta-presave:hover {
	filter: brightness(1.06);
}

.hfd-cta-presave:active {
	transform: scale(0.99);
}

.hfd-cta-presave svg {
	width: 20px;
	height: 20px;
	flex-shrink: 0;
}

.hfd-cta-presave.is-done {
	background: var(--hfd-surface);
	color: var(--hfd-text);
	cursor: default;
}

/* DC-42228: white 15px label with a blue checkbox, directly under the green CTA. */
.hfd-presave-email {
	display: flex;
	align-items: center;
	gap: 8px;
	margin-top: 4px;
	font-size: 16px;
	color: var(--hfd-text);
	cursor: pointer;
}

.hfd-presave-email input {
	width: 17px;
	height: 17px;
	margin: 0;
	accent-color: #1a73e8;
	cursor: pointer;
}

.hfd-presave-error {
	width: 100%;
	padding: 14px 18px;
	background: var(--hfd-surface);
	border-radius: var(--hfd-radius-sm);
	color: var(--hfd-muted);
	font-size: 13px;
	text-align: center;
}

/* ---- Audio preview player ------------------------------------------------ */
.hfd-audio {
	display: flex;
	align-items: center;
	gap: 12px;
	width: 100%;
	margin: 0;
	padding: 14px;
	background: var(--hfd-surface);
	border: 1px solid var(--hfd-border);
	border-radius: var(--hfd-radius-card);
}

.hfd-audio-play {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 56px;
	height: 56px;
	flex-shrink: 0;
	border: 0;
	border-radius: 50%;
	background: rgb(255 255 255 / 14%);
	color: #fff;
	cursor: pointer;
}

.hfd-audio-play:hover {
	filter: brightness(0.92);
}

.hfd-audio-play svg {
	width: 16px;
	height: 16px;
}

/* Scoped to .hfd-audio-play so this outweighs the ".hfd-body svg { display: block }" reset. */
.hfd-audio-play .hfd-audio-icon-pause {
	display: none;
}

.hfd-audio[data-playing="true"] .hfd-audio-icon-play {
	display: none;
}

.hfd-audio[data-playing="true"] .hfd-audio-icon-pause {
	display: block;
}

.hfd-audio-body {
	flex: 1;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.hfd-audio-meta {
	display: flex;
	flex-direction: column;
	gap: 1px;
	min-width: 0;
	text-align: left;
}

.hfd-audio-title {
	font-size: 16px;
	font-weight: 400;
	color: var(--hfd-text);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.hfd-audio-sub {
	font-size: 13px;
	color: var(--hfd-muted);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.hfd-audio-track {
	position: relative;
	height: 4px;
	border-radius: 9999px;
	background: var(--hfd-border);
	cursor: pointer;
}

.hfd-audio-fill {
	position: absolute;
	left: 0;
	top: 0;
	bottom: 0;
	width: 0;
	border-radius: inherit;
	background: var(--hfd-text);
	pointer-events: none;
}

.hfd-audio-times {
	display: flex;
	justify-content: space-between;
	font-size: 14px;
	color: var(--hfd-muted-2);
	font-variant-numeric: tabular-nums;
}

.hfd-audio-skip {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	flex-shrink: 0;
	border: 0;
	border-radius: 50%;
	background: transparent;
	color: var(--hfd-muted);
	cursor: pointer;
}

.hfd-audio-skip:hover {
	color: var(--hfd-text);
	background: var(--hfd-surface-2);
}

.hfd-audio-skip svg {
	width: 14px;
	height: 14px;
}

/* ---- DSP list (out-now state) -------------------------------------------- */

/* DC-42228: the rows now live inside one rounded card divided by hairlines, rather than being
   separate pills. Radius is clipped by overflow so the first and last rows round with the card. */
.hfd-dsp-list {
	display: flex;
	flex-direction: column;
	gap: 0;
	width: 100%;
	overflow: hidden;
	background: var(--hfd-surface);
	border-radius: var(--hfd-radius-card);
}

.hfd-dsp-primary,
.hfd-dsp-extra {
	display: flex;
	flex-direction: column;
	gap: 0;
	width: 100%;
}

.hfd-dsp-extra {
	display: none;
}

.hfd-dsp-list.is-expanded .hfd-dsp-extra {
	display: flex;
}

.hfd-dsp-row {
	display: flex;
	align-items: center;
	gap: 14px;
	width: 100%;
	padding: 14px 16px;
	background: none;
	border: none;
	border-top: 1px solid var(--hfd-border);
	border-radius: 0;
	color: var(--hfd-text);
	font-size: 16px;
	font-weight: 400;
	text-align: left;
	cursor: pointer;
	transition: background var(--hfd-ease);
}

/* The card's own top edge needs no rule. .hfd-dsp-extra is hidden until expanded, so its first
   row keeps its border and reads as a continuation of the list. */
.hfd-dsp-primary .hfd-dsp-row:first-child {
	border-top: none;
}

.hfd-dsp-row:hover {
	background: var(--hfd-surface-2);
}

.hfd-dsp-icon {
	width: 30px;
	height: 30px;
	flex-shrink: 0;
	object-fit: contain;
	border-radius: 7px;
}

.hfd-dsp-name {
	flex: 1;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.hfd-dsp-chevron {
	width: 16px;
	height: 16px;
	flex-shrink: 0;
	color: var(--hfd-muted);
}

.hfd-dsp-divider {
	width: 100%;
	margin-top: 8px;
	font-size: 16px;
	font-weight: 700;
	text-align: left;
	color: var(--hfd-text);
}

/* DC-42228: a small centred text link, not the full-width button the prototype used. */
.hfd-dsp-more {
	margin: -4px auto 0;
	padding: 4px 0;
	background: none;
	border: none;
	color: var(--hfd-muted);
	font-size: 14px;
	font-weight: 400;
	text-decoration: underline;
	text-underline-offset: 4px;
	cursor: pointer;
}

.hfd-dsp-more:hover {
	color: var(--hfd-text);
}

.hfd-cta-buy {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	margin-top: 8px;
	padding: 14px 18px;
	background: var(--hfd-buy);
	color: var(--hfd-buy-text);
	border: none;
	border-radius: var(--hfd-radius-sm);
	font-size: 15px;
	font-weight: 700;
	cursor: pointer;
	transition: filter var(--hfd-ease);
}

.hfd-cta-buy:hover {
	filter: brightness(0.95);
}

/* ---- Sections and grids -------------------------------------------------- */

/* DC-42228: a hairline rule closes every section, which is how the design separates Related merch
   / Releases / About from each other and from the footer. */
.hfd-section {
	padding-bottom: var(--hfd-section-gap);
	margin-bottom: var(--hfd-section-gap);
	border-bottom: 1px solid var(--hfd-border);
}

/* Regular weight and no icon — none of the section headings in the design carries either.

   DC-42228: no margin-bottom here. `.hfd-body h2 { margin: 0 }` in the page reset is 0-1-1 and beats
   any single class, so a margin-bottom on this rule is silently dropped — it is why the heading sat
   flush against its grid. The heading gap is applied to the content below instead (see .hfd-grid). */
.hfd-section-heading {
	font-size: 16px;
	font-weight: 400;
	color: var(--hfd-text);
}

.hfd-grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--hfd-grid-gap);
	margin-top: var(--hfd-heading-gap);
}

.hfd-card {
	display: flex;
	flex-direction: column;
	gap: var(--hfd-card-gap);
	min-width: 0;
	color: inherit;
	transition: opacity var(--hfd-ease);
}

.hfd-card:hover {
	opacity: 0.92;
}

/* Square corners: every tile in the design is a hard-edged square. */
.hfd-card-img-wrap {
	position: relative;
	overflow: hidden;
	background: var(--hfd-surface);
}

.hfd-card-img {
	width: 100%;
	aspect-ratio: 1;
	object-fit: cover;
	background: var(--hfd-surface);
}

/* Merch mockups are rendered on a pale ground and must not be cropped. */
.hfd-card-merch .hfd-card-img {
	object-fit: contain;
	padding: 6%;
}

.hfd-card-meta {
	display: flex;
	flex-direction: column;
	gap: 2px;
}

/* Release tiles: title only, semibold. */
.hfd-card-title {
	font-size: 14px;
	font-weight: 700;
	line-height: 1.3;
	color: var(--hfd-text);
}

/* Merch tiles: price above name, both regular weight, per the design. */
.hfd-card-price,
.hfd-card-name {
	font-size: 14px;
	font-weight: 400;
	line-height: 1.35;
	color: var(--hfd-text);
}

.hfd-card-sub {
	font-size: 12px;
	font-weight: 500;
	line-height: 1.35;
	color: var(--hfd-muted);
}

.hfd-badge-new {
	position: absolute;
	top: 8px;
	left: 8px;
	z-index: 1;
	padding: 4px 7px;
	border-radius: 4px;
	background: var(--hfd-accent);
	color: #111;
	font-size: 10px;
	font-weight: 700;
	letter-spacing: 0.04em;
}

.hfd-tile-play {
	position: absolute;
	left: 8px;
	bottom: 8px;
	display: inline-flex;
	align-items: center;
	gap: 5px;
	padding: 5px 9px;
	border-radius: 9999px;
	background: rgb(0 0 0 / 72%);
	color: #fff;
	font-size: 10px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	pointer-events: none;
}

.hfd-tile-play svg {
	width: 12px;
	height: 12px;
}

/* Tiles past the first row stay hidden until "View all" */
.hfd-release-extra {
	display: none;
}

.hfd-releases-section.is-expanded .hfd-release-extra {
	display: flex;
}

/* DC-42228: the outline that marked the release currently being viewed is off at Keith's request
   ("remove the is-current css from the Releases section for now"). The template still puts
   .is-current on that tile, so restoring this is a matter of putting the rule back:

       .hfd-card.is-current .hfd-card-img-wrap {
           outline: 2px solid var(--hfd-text);
           outline-offset: 2px;
       }
*/

.hfd-btn-viewall {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	margin-top: 24px;
	padding: 14px 16px;
	background: var(--hfd-surface);
	color: var(--hfd-text);
	border: none;
	border-radius: var(--hfd-radius-sm);
	font-size: 14px;
	font-weight: 700;
	cursor: pointer;
	transition: background var(--hfd-ease);
}

.hfd-btn-viewall:hover {
	background: var(--hfd-surface-2);
}

/* ---- Owner merch prompt (get store / add products) ----------------------- */
.hfd-merch-cta {
	position: relative;
	display: flex;
	align-items: center;
	gap: 32px;
	padding: 34px 32px;
	overflow: hidden;
	border: 1.5px dashed var(--hfd-cta-border);
	border-radius: 16px;
	background: var(--hfd-cta-bg);
}

.hfd-merch-cta-copy {
	flex: 1 1 auto;
	min-width: 0;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 8px;
}

.hfd-merch-cta-eyebrow {
	font-size: 12px;
	font-weight: 500;
	color: var(--hfd-cta-eyebrow);
}

/* 16px, measured off the reference frame — the prototype's 22px reads as a headline next to it. */
.hfd-merch-cta-title {
	font-size: 16px;
	font-weight: 700;
	line-height: 1.3;
	color: var(--hfd-cta-title);
}

/* No width cap: in the design the copy runs the full width of the card beside the mockup and wraps
   onto two lines. Capping it at 28em forced a third line. */
.hfd-merch-cta-body {
	margin-bottom: 8px;
	font-size: 14px;
	font-weight: 500;
	line-height: 1.45;
	color: var(--hfd-cta-body);
}

/* Scoped to .hfd-merch-cta so the colour beats the ".hfd-body a { color: inherit }" reset — this
   button is an <a> for the owner CTAs, and inheriting would render white-on-white. */

/* DC-42228: an outlined button, as drawn. It needs a real border — the fill is white and it sits on
   a white card, so `border: none` made it invisible. The gap is load-bearing too: the element is a
   flex container, which discards the whitespace-only text node before the arrow. */
.hfd-merch-cta .hfd-merch-cta-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
	margin-top: 4px;
	padding: 9px 16px;
	background: var(--hfd-cta-btn-bg);
	color: var(--hfd-cta-btn-text);
	border: 1px solid rgb(15 15 15 / 22%);
	border-radius: 6px;
	font-size: 13px;
	font-weight: 700;
	cursor: pointer;
	transition: background var(--hfd-ease), border-color var(--hfd-ease);
}

.hfd-merch-cta .hfd-merch-cta-btn:hover {
	background: var(--hfd-surface);
	border-color: rgb(15 15 15 / 38%);
}

.hfd-merch-cta-visual {
	flex: 0 0 200px;
	width: 200px;
	align-self: center;
	position: relative;
	aspect-ratio: 1;
	border-radius: 8px;
	overflow: hidden;
	background: #e8e8e8;
}

.hfd-merch-cta-visual .hfd-merch-blank {
	width: 100%;
	height: 100%;
	object-fit: contain;

	/* tshirt5.svg ships as a light garment; the prototype renders it as a black tee. Filtering the
	   blank only — the artwork overlaid on it must keep its own colours. */
	filter: brightness(0.12);
}

.hfd-merch-cta-visual .hfd-merch-art {
	position: absolute;
	top: 44%;
	left: 50%;
	width: 34%;
	height: auto;
	transform: translate(-50%, -50%);
}

.hfd-dismiss {
	position: absolute;
	top: 10px;
	right: 10px;
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 30px;
	height: 30px;
	padding: 0;
	border: none;
	border-radius: 50%;
	background: var(--hfd-btn-bg);
	color: var(--hfd-muted);
	cursor: pointer;
	transition: background var(--hfd-ease);
}

.hfd-dismiss:hover {
	background: var(--hfd-btn-hover);
	color: var(--hfd-text);
}

.hfd-dismiss svg {
	width: 14px;
	height: 14px;
}

/* ---- About --------------------------------------------------------------- */

/* DC-42228: the small-screen frame reads heading -> artwork -> bio -> socials, but the heading lives
   inside .hfd-about-copy, which follows the image slot in source order. display:contents promotes
   the copy column's children to grid items of .hfd-about at this width so `order` can lift the
   heading above the image; the 768 block below restores the real two-column box. The grid gap also
   sidesteps the reset problem noted on .hfd-section-heading — none of these children can carry a
   working margin. */
.hfd-about {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--hfd-about-gap);
}

.hfd-about-copy {
	display: contents;
}

.hfd-about-copy > * {
	order: 3;
}

.hfd-about-img-slot {
	order: 2;
	width: 100%;
	flex-shrink: 0;
}

.hfd-about-img {
	width: 100%;
	aspect-ratio: 1;
	object-fit: cover;
	background: var(--hfd-surface);
}

.hfd-about-title {
	order: 1;
	font-size: 16px;
	font-weight: 700;
}

.hfd-about-bio {
	font-size: 14px;
	line-height: 1.55;
	color: var(--hfd-muted);
	white-space: pre-wrap;
}

.hfd-about-location {
	display: flex;
	align-items: center;
	gap: 6px;
	font-size: 13px;
	color: var(--hfd-muted);
}

.hfd-about-location svg {
	width: 14px;
	height: 14px;
	flex-shrink: 0;
}

.hfd-socials {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 12px;
}

/* Bare icons on the white ground, as drawn — no grey pill behind them. */
.hfd-socials a {
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--hfd-text);
	transition: opacity var(--hfd-ease);
}

.hfd-socials a:hover {
	opacity: 0.65;
}

.hfd-socials img {
	width: 19px;
	height: 19px;
}

/* #ArtistsForChange */
.hfd-afc {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	margin: 0 0 32px;
	font-size: 13px;
	color: var(--hfd-muted);
}

.hfd-afc svg {
	width: 15px;
	height: 15px;
	flex-shrink: 0;
	color: #dc2626;
}

.hfd-afc a {
	color: var(--hfd-text);
	text-decoration: underline;
	text-underline-offset: 2px;
}

/* ---- Footer + free-trial bar --------------------------------------------- */

/* DC-42228: two centred lines of small grey type, then a separate pale bar carrying the CTA. The
   DistroKid logo and the HyperFollow promo link the prototype had are gone, replaced by the
   "powered by DistroKid" sentence; the owner "Manage" button moved to .hfd-ownerbar. */
.hfd-footer {
	width: 100%;
	max-width: var(--hfd-page-max);
	margin: 0 auto;
	padding: calc(var(--hfd-footer-gap) - var(--hfd-section-gap)) var(--hfd-page-gutter) 32px;
	color: var(--hfd-muted-2);
	font-size: 12px;
	line-height: 1.6;
	text-align: center;
}

.hfd-footer-copy {
	display: flex;
	flex-direction: column;
	gap: 4px;
}

.hfd-footer-link {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 2px;
}

.hfd-footer-link:hover {
	color: var(--hfd-muted);
}

.hfd-trialbar {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 4px;
	padding: 22px var(--hfd-page-gutter);
	background: var(--hfd-surface);
	color: var(--hfd-muted);
	font-size: 12px;
	text-align: center;
}

.hfd-trialbar-cta {
	color: var(--hfd-text);
	font-weight: 500;
	text-decoration: underline;
	text-underline-offset: 3px;
}

.hfd-trialbar-cta:hover {
	color: var(--hfd-muted);
}

/* ---- Dialogs (owner menu, follow mockup, artwork lightbox) --------------- */
.hfd-dialog {
	width: 100%;
	max-width: 360px;
	padding: 24px;
	border: 1px solid var(--hfd-border);
	border-radius: 12px;
	background: var(--hfd-bg);
	color: var(--hfd-text);
	box-shadow: var(--hfd-chrome-shadow);
	font-family: var(--hfd-font);
}

.hfd-dialog::backdrop {
	background: rgb(0 0 0 / 55%);
}

.hfd-dialog-title {
	margin-bottom: 10px;
	font-size: 16px;
	font-weight: 700;
	letter-spacing: -0.01em;
}

/* Escape closes a <dialog> for free, but that is not discoverable — every dialog gets a visible X.
   The dialog itself is position: fixed while modal, so it is the containing block here. */
.hfd-dialog-close {
	position: absolute;
	top: 14px;
	right: 14px;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 30px;
	height: 30px;
	padding: 0;
	border: none;
	border-radius: 50%;
	background: var(--hfd-btn-bg);
	color: var(--hfd-muted);
	cursor: pointer;
	transition: background var(--hfd-ease), color var(--hfd-ease);
}

.hfd-dialog-close:hover {
	background: var(--hfd-btn-hover);
	color: var(--hfd-text);
}

.hfd-dialog-close svg {
	width: 14px;
	height: 14px;
}

/* Keep the title clear of the close button. */
.hfd-dialog-close + .hfd-dialog-title {
	padding-right: 34px;
}

.hfd-dialog-body {
	margin-bottom: 20px;
	font-size: 13px;
	line-height: 1.55;
	color: var(--hfd-muted);
}

.hfd-dialog-form {
	display: flex;
	align-items: stretch;
	gap: 8px;
}

.hfd-dialog-input {
	flex: 1;
	min-width: 0;
	padding: 11px 12px;
	background: var(--hfd-surface);
	border: 1px solid var(--hfd-border);
	border-radius: 6px;
	color: var(--hfd-text);
	font-family: inherit;
	font-size: 13px;
}

.hfd-dialog-input:focus {
	border-color: var(--hfd-text);
	outline: none;
}

.hfd-dialog-confirm {
	flex-shrink: 0;
	padding: 11px 14px;
	background: var(--hfd-buy);
	color: var(--hfd-buy-text);
	border: none;
	border-radius: 6px;
	font-family: inherit;
	font-size: 13px;
	font-weight: 700;
	white-space: nowrap;
	cursor: pointer;
}

/* Owner menu */
.hfd-menu-label {
	padding: 12px 10px 4px;
	font-size: 10px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--hfd-muted-2);
}

.hfd-menu-item {
	display: flex;
	align-items: center;
	gap: 8px;
	width: 100%;
	padding: 10px 12px;
	background: none;
	border: none;
	border-radius: 6px;
	color: var(--hfd-text);
	font-family: inherit;
	font-size: 13px;
	font-weight: 700;
	text-align: left;
	cursor: pointer;
}

.hfd-menu-item:hover {
	background: var(--hfd-surface-2);
}

.hfd-menu-select {
	width: 100%;
	margin-top: 4px;
	padding: 10px 12px;
	background: var(--hfd-surface);
	border: 1px solid var(--hfd-border);
	border-radius: 6px;
	color: var(--hfd-text);
	font-family: inherit;
	font-size: 13px;
}

/* Artwork lightbox */
.hfd-lightbox {
	width: 100%;
	max-width: 92vw;
	max-height: 92vh;
	padding: 0;
	border: none;
	background: transparent;
	box-shadow: none;
}

.hfd-lightbox::backdrop {
	background: rgb(0 0 0 / 85%);
}

.hfd-lightbox img {
	width: 100%;
	height: auto;
	max-height: 92vh;
	object-fit: contain;
	border-radius: var(--hfd-radius);
}

.hfd-lightbox-close {
	position: absolute;
	top: 12px;
	right: 12px;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	border: none;
	border-radius: 50%;
	background: rgb(0 0 0 / 60%);
	color: #fff;
	cursor: pointer;
}

.hfd-lightbox-close svg {
	width: 18px;
	height: 18px;
}

/* ---- Share modal --------------------------------------------------------
 * Layout follows BandZoogle's direct.distrokid.com "Share this" modal; the parts are this page's
 * own — .hfd-dialog for the shell, --hfd-* tokens for every colour.
 */
.hfd-share-dialog {
	max-width: 456px;
	padding: 0;
}

.hfd-share-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding: 16px 20px;
	border-bottom: 1px solid var(--hfd-border);
}

/* .hfd-dialog-title carries a bottom margin for the other dialogs; the flex row handles it here. */
.hfd-share-head .hfd-dialog-title {
	margin-bottom: 0;
}

.hfd-share-close {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 30px;
	height: 30px;
	flex-shrink: 0;
	padding: 0;
	border: none;
	border-radius: 50%;
	background: var(--hfd-btn-bg);
	color: var(--hfd-muted);
	cursor: pointer;
	transition: background var(--hfd-ease), color var(--hfd-ease);
}

.hfd-share-close:hover {
	background: var(--hfd-btn-hover);
	color: var(--hfd-text);
}

.hfd-share-close svg {
	width: 14px;
	height: 14px;
}

/* Preview card — a facsimile of a link unfurl */
.hfd-share-preview {
	margin: 16px 20px;
	overflow: hidden;
	border: 1px solid var(--hfd-border);
	border-radius: var(--hfd-radius-sm);
}

/* The OG ratio, not the artwork's. Letterboxing a square cover is what makes this read as an
   unfurl rather than as another copy of the hero image. */
.hfd-share-preview-art {
	position: relative;
	aspect-ratio: 1200 / 630;
	background: var(--hfd-surface);
}

.hfd-share-preview-art img {
	position: absolute;
	inset: 14px;
	width: calc(100% - 28px);
	height: calc(100% - 28px);
	object-fit: contain;
}

.hfd-share-preview-meta {
	padding: 8px 10px;
	border-top: 1px solid var(--hfd-border);
	background: var(--hfd-bg);
}

.hfd-share-preview-domain {
	margin-bottom: 2px;
	font-size: 11px;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--hfd-muted);
}

.hfd-share-preview-title {
	display: -webkit-box;
	overflow: hidden;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	font-size: 15px;
	font-weight: 700;
	line-height: 1.3;
	color: var(--hfd-text);
}

/* Copy-link row — one bordered pill holding both controls */
.hfd-share-copy {
	display: flex;
	align-items: stretch;
	margin: 0 20px 16px;
	overflow: hidden;
	background: var(--hfd-surface);
	border: 1px solid var(--hfd-border);
	border-radius: var(--hfd-radius-sm);
}

.hfd-share-copy-input {
	flex: 1;
	min-width: 0;
	padding: 10px 12px;
	border: none;
	background: transparent;
	color: var(--hfd-text);
	font-family: ui-monospace, "SF Mono", menlo, monospace;
	font-size: 13px;
	text-overflow: ellipsis;
}

.hfd-share-copy-input:focus {
	outline: none;
}

.hfd-share-copy-btn {
	flex-shrink: 0;
	padding: 0 16px;
	border: none;
	background: transparent;
	color: var(--hfd-text);
	font-family: inherit;
	font-size: 13px;
	font-weight: 700;
	white-space: nowrap;
	cursor: pointer;
}

.hfd-share-copy-btn:hover {
	color: var(--hfd-muted);
}

/* Social row */
.hfd-share-socials {
	display: flex;
	justify-content: space-between;
	gap: 4px;
	margin: 0 20px 20px;
}

/* The tiles are a mix of <a> and <button>, so the button chrome has to be zeroed for the two to
   render identically. */
.hfd-share-social {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 6px;
	padding: 0;
	border: none;
	background: none;
	color: var(--hfd-muted);
	font-family: inherit;
	cursor: pointer;
}

.hfd-share-social:hover {
	color: var(--hfd-text);
}

.hfd-share-social-icon {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	flex-shrink: 0;
	border-radius: 9999px;
	color: #fff;
}

.hfd-share-social-icon svg {
	width: 20px;
	height: 20px;
}

.hfd-share-social-label {
	font-size: 13px;
	text-align: center;
}

/* The two black tiles would disappear against the dark theme's #000 page; --hfd-brand-edge is the
   visible border in dark and transparent in light. */
.hfd-share-x,
.hfd-share-threads {
	border: 1px solid var(--hfd-brand-edge);
}

.hfd-share-x {
	background: var(--hfd-brand-x);
}

/* The X mark reads optically larger than the other glyphs at the same box size. */
.hfd-share-x svg {
	width: 16px;
	height: 16px;
}

.hfd-share-threads {
	background: var(--hfd-brand-threads);
}

.hfd-share-facebook {
	background: var(--hfd-brand-facebook);
}

.hfd-share-reddit {
	background: var(--hfd-brand-reddit);
}

.hfd-share-email {
	background: var(--hfd-brand-email);
}

/* "More" is not a brand, so it inverts with the theme — same trick as .hfd-audio-play. */
.hfd-share-more {
	background: var(--hfd-text);
	color: var(--hfd-invert-fg);
}

/* ---- 404 ----------------------------------------------------------------- */
.hfd-notfound {
	max-width: 420px;
	margin: 3em auto;
	padding: 0 20px;
	text-align: center;
	color: var(--hfd-muted);
}

.hfd-notfound-logo {
	width: 100%;
	max-width: 300px;
	margin: 0 auto 3em;
	filter: var(--hfd-logo-filter);
}

.hfd-notfound-art {
	margin: 0 auto 1.5em;
}

.hfd-notfound-text {
	font-size: 14px;
}

/* ---- Captcha -------------------------------------------------------------
   The captcha widgets come from /_includes/captchaProcessorScripts.cfm, whose usual host pages
   pull in main.css. This page deliberately does not (see the note at the top of _directRelease.cfm),
   so the two rules those widgets depend on are restated here rather than left to inherit nothing.
   Both containers render empty until a flow actually challenges — Turnstile is loaded with
   render=explicit and reCAPTCHA is invisible — so today these only keep the badges out of the
   layout. */

/* reCAPTCHA injects its own floating badge as soon as api.js loads. */
.grecaptcha-badge {
	visibility: hidden;
}

/* Values copied from main.css: the page-level container floats centred over the page rather than
   sitting in flow at the foot of the document. The z-index clears .hfd-topnav (100); it does not
   clear an open <dialog>, which the browser puts in the top layer — a challenge raised from inside
   a dialog has to render into that dialog's own host container, which is what turnstile.js already
   does when it is handed a host. */
.turnstile-badge {
	position: fixed;
	top: 50%;
	left: 50%;
	margin-top: -32px;
	margin-left: -150px;
	z-index: 1000;
}

.turnstile-badge.visible.with-background::before {
	content: "";
	position: fixed;
	top: 0;
	left: 0;
	z-index: -1;
	width: 100vw;
	height: 100vh;
	background-color: #000;
	opacity: 0.5;
}

/* ---- Desktop ------------------------------------------------------------- */
@media (width >= 768px) {
	:root {
		--hfd-page-gutter: 24px;

		/* The design gives the artist bar a lot of air: a 48px avatar with ~48px above and below. */
		--hfd-topnav-h: 144px;

		/* DC-42228: the 1440 frames breathe more than the 402 ones. */
		--hfd-section-gap: 42px;
		--hfd-heading-gap: 30px;
	}

	.hfd-artist-chip img {
		width: 48px;
		height: 48px;
	}

	.hfd-artist-chip span {
		font-size: 17px;
	}

	/* The band keeps its full-bleed background; only the content is constrained. Art on the left at
	   roughly 57% of the content column, info on the right — the proportions in the 1440 frames. */

	/* The info column is top-aligned with the artwork — in the design the title sits level with the
	   top of the cover, it is not centred against it. */
	.hfd-hero-inner {
		flex-direction: row;
		align-items: flex-start;
		gap: 48px;
		padding: 40px var(--hfd-page-gutter);
	}

	.hfd-hero-art-wrap {
		flex: 0 0 57%;
	}

	/* Rounded on desktop, where the artwork sits inside the band rather than bleeding off it. */
	.hfd-hero-art {
		border-radius: var(--hfd-radius);
	}

	.hfd-hero-info {
		flex: 1;
		align-items: flex-start;
		padding: 0;
		text-align: left;
	}

	.hfd-hero-title {
		font-size: 24px;
	}

	.hfd-hero-state {
		align-items: flex-start;
	}

	.hfd-grid-merch {
		grid-template-columns: repeat(3, 1fr);
		gap: 42px;
	}

	.hfd-grid-releases {
		grid-template-columns: repeat(4, 1fr);
		gap: 24px;
	}

	/* The frame gives the button a full section-gap of air above it here, not the 24px it gets on
	   small screens. */
	.hfd-btn-viewall {
		margin-top: var(--hfd-section-gap);
	}

	/* Back to a real two-column box: the image slot beside a copy column that owns its own rhythm. */
	.hfd-about {
		display: flex;
		flex-direction: row;
		align-items: flex-start;
		gap: 32px;
	}

	/* order:2 above is only meaningful while .hfd-about-copy is display:contents. Here the copy is a
	   real flex child again (order 0), so the image has to be reset or it lands to the right of it. */
	.hfd-about-img-slot {
		order: 0;
		flex: 0 0 200px;
		width: 200px;
	}

	.hfd-about-copy {
		display: flex;
		flex-direction: column;
		gap: var(--hfd-about-gap);
		flex: 1;
		padding-top: 4px;
	}

	.hfd-footer {
		padding: calc(var(--hfd-footer-gap) - var(--hfd-section-gap)) var(--hfd-page-gutter) 40px;
	}
}

/* ---- Wide desktop -------------------------------------------------------- */

/* 1024 is welcome-mat.css's desktop step and Tailwind's `lg`; the 1440 frames give the hero more
   air than the 768 layout does. */
@media (width >= 1024px) {
	.hfd-hero-inner {
		padding: 48px var(--hfd-page-gutter);
	}
}

@media (width <= 767px) {
	.hfd-btn-label {
		display: none;
	}

	/* Icon-only pills, as in the small-screen frame. */
	.hfd-topnav-right .hfd-btn {
		width: 40px;
		height: 40px;
		padding: 0;
	}

	.hfd-merch-cta {
		flex-direction: column;
		align-items: stretch;
		gap: 20px;
		padding: 24px;
	}

	.hfd-merch-cta-visual {
		flex: 0 0 auto;
		width: 140px;
		align-self: center;
	}

	/* Full-width centred card. .hfd-dialog is already width:100% with a max-width cap, so this is
	   the only override needed. */
	.hfd-share-dialog {
		max-width: calc(100% - 24px);
	}

	/* Six tiles across a 360px viewport is the binding constraint: 336px card - 32px gutters = 304px
	   over six, so ~50px each. The 40px circle clears that; "Facebook" is the label that decides it. */
	.hfd-share-head,
	.hfd-share-preview,
	.hfd-share-copy,
	.hfd-share-socials {
		margin-left: 16px;
		margin-right: 16px;
	}

	.hfd-share-head {
		margin: 0;
		padding-left: 16px;
		padding-right: 16px;
	}

	.hfd-share-socials {
		gap: 2px;
	}

	.hfd-share-social-label {
		font-size: 11px;
	}
}
