/*
 * Speaker component layer — portable BEM classes and design tokens.
 *
 * Extracted from the page-scoped <style id="etch-page-styles"> block on
 * the production Patrick Longano profile page. Enqueued conditionally by
 * class-assets.php on singular speaker pages and the directory.
 *
 * Etch's structural scaffolding classes and its companion plugin's
 * component styles intentionally do not live here — that stays with
 * Etch. Only the speaker-* contract is portable.
 */

.speaker-page { position: relative;
	min-height: 100vh;
	/* clip, not hidden. overflow-x: hidden computes to overflow: hidden auto,
	   which makes this element a scroll container -- and a sticky descendant
	   sticks to its nearest scroll container, so the sidebar stuck to a box
	   that scrolls with the page and never stuck at all. clip suppresses the
	   overflow without creating a scroller, which is the whole difference. */
	overflow-x: clip;
	color: var(--speaker-color-text);
	font-family: var(--speaker-font-body);
	background: url('/wp-content/uploads/bg.webp') center / cover fixed no-repeat; }

.speaker-page__overlay { position: fixed;
	inset: 0;
	z-index: 1;
	pointer-events: none;
	background: linear-gradient(160deg, rgba(5, 10, 25, 0.85) 0%, rgba(10, 20, 50, 0.75) 40%, rgba(5, 10, 25, 0.82) 100%); }

.speaker-header { position: fixed;
	inset-block-start: 0;
	inset-inline: 0;
	z-index: 100;
	border-bottom: 1px solid var(--speaker-color-border);
	background: rgba(10, 18, 40, 0.45);
	backdrop-filter: blur(18px);
	-webkit-backdrop-filter: blur(18px); }

.speaker-header__container { inline-size: min(100% - 2rem, 75rem);
	margin-inline: auto;
	position: relative;
	z-index: 10; }

.speaker-header__inner { display: flex;
	align-items: center;
	justify-content: space-between;
	inline-size: min(100%, 75rem);
	min-block-size: 3.625rem;
	margin-inline: auto;
	padding-inline: 0;
	gap: 1rem;

	@media (width <= 1024px) {
		padding-inline: 1rem;
	} }

.speaker-header__name { font-family: var(--speaker-font-display);
	font-size: 1.95rem;
	font-weight: 400;
	line-height: 1;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	background: linear-gradient(135deg, #ffffff 0%, #a5c8f0 40%, #c4a8f5 75%, #ffffff 100%);
	background-clip: text;
	-webkit-background-clip: text;
	-webkit-text-fill-color: transparent;
	filter: drop-shadow(0 1px 8px rgba(100, 160, 230, 0.35));

	@media (width <= 1024px) {
		font-size: 1.5625rem;
	}

	@media (width <= 700px) {
		font-size: 1.3rem;
	} }

.speaker-header__actions { display: flex;
	gap: 0.625rem;
	flex-wrap: wrap; }

.speaker-button { display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	text-decoration: none;
	transition: background 0.22s ease, border-color 0.22s ease, transform 0.22s ease, box-shadow 0.22s ease, filter 0.22s ease;

	&:hover {
		transform: translateY(-2px);
	} }

.speaker-button--glass { padding: 0.4375rem 1.125rem;
	border: 1px solid var(--speaker-color-border);
	border-radius: var(--speaker-radius-pill);
	background: var(--speaker-color-glass);
	color: #fff;
	box-shadow: 0 2px 12px var(--speaker-color-shadow), inset 0 1px 0 rgba(255, 255, 255, 0.18);
	font-size: 0.85rem;
	font-weight: 600;
	letter-spacing: 0.02em;
	backdrop-filter: blur(18px);
	-webkit-backdrop-filter: blur(18px);

	&:hover {
		background: rgba(255, 255, 255, 0.18);
		border-color: var(--speaker-color-border-strong);
	}

	@media (width <= 1024px) {
		padding: 0.375rem 0.8125rem;
		font-size: 0.78rem;
	} }

.speaker-button--primary { background: linear-gradient(135deg, color-mix(in oklab, var(--speaker-color-accent) 55%, transparent), color-mix(in oklab, var(--speaker-color-accent-2) 45%, transparent));
	border-color: color-mix(in oklab, var(--speaker-color-accent) 50%, transparent);

	&:hover {
		background: linear-gradient(135deg, color-mix(in oklab, var(--speaker-color-accent) 75%, transparent), color-mix(in oklab, var(--speaker-color-accent-2) 65%, transparent));
	} }

/* Not a layout tier. Below ~410px the header buttons drop their labels and
   become icons; the two real breakpoints are 700 and 1024. */
.speaker-header__actions .speaker-button { @media (width <= 410px) {
    gap: 0;
    padding-inline: 0.75rem;
    min-inline-size: 2.5rem;
    font-size: 0;
  } }

.speaker-header__actions .speaker-button::before { @media (width <= 410px) {
		color: #fff;
		font-size: 1rem;
	} }

.speaker-button[class^="icon-"]::before,
.speaker-button[class*=" icon-"]::before { @media (width <= 1024px) {
		font-size: 1rem;
		line-height: 1;
		color: #fff;
	} }

.speaker-main { position: relative;
	z-index: 10;
	padding-block: calc(3.625rem + 0.25rem) 3.75rem;
	padding-inline: 2.5rem;

	@media (width <= 1024px) {
		padding-inline: 1.25rem;
		padding-block: calc(3.625rem + 0.25rem) 3.125rem;
	} }

.speaker-section { position: relative;
	z-index: 10;
	margin-block-start: 0;
	padding-block-start: 0; }

.speaker-layout { display: grid;
	grid-template-columns: 240px minmax(0, 1fr);
	gap: 3rem;
	align-items: start;
	inline-size: min(100%, 68.75rem);
	margin-inline: auto;

	@media (width <= 1024px) {
		grid-template-columns: 1fr;
		gap: 2rem;
	} }

/* A speaker with no headshot, no credentials and no topics renders no
   sidebar, and .speaker-content then auto-places into the 240px track --
   174px of bio beside 812px of empty background. Only reachable on a sparse
   profile, which is why it survived until a second speaker existed. */
.speaker-layout:not(:has(.speaker-sidebar)) {
	grid-template-columns: minmax(0, 1fr);
}

.speaker-sidebar { position: sticky;
	inset-block-start: 5rem;
	display: flex;
	flex-direction: column;
	gap: 1.25rem;
	align-items: center;

	/* Tablet: headshot and topics menu side by side, per the design. */
	@media (width <= 1024px) {
		position: static;
		flex-direction: row;
		align-items: flex-start;
		gap: 1rem;
	}

	/* Phone: stacked again, headshot centred, menu full width. Side by side
	   at this width leaves the menu about 396px and wraps the titles. */
	@media (width <= 700px) {
		flex-direction: column;
		align-items: center;
	} }

.speaker-sidebar__image-wrap { inline-size: 100%;

	@media (width <= 1024px) {
		inline-size: 210px;
		flex-shrink: 0;
	}

	/* Full width inside the 16px page padding -- the 180px portrait floating
	   in a full-width column read as an afterthought. The 260px cap the
	   sidebar carries is dropped at this breakpoint only; tablet keeps 210px
	   and its side-by-side row. */
	@media (width <= 700px) {
		inline-size: 100%;
		max-inline-size: none;
		margin-inline: 0;
	}

	/* Full-bleed is right on a phone and wrong on a small tablet: at 700 the
	   3/4 portrait came out 700x930 and pushed the headline off the fold
	   entirely. Capped and centred from 560 up, still edge to edge below. */
	@media (560px <= width <= 700px) {
		max-inline-size: 420px;
		margin-inline: auto;
	} }

.speaker-sidebar__image-frame { inline-size: 100%;
	aspect-ratio: 3 / 4;
	padding: 0.25rem;
	border-radius: var(--speaker-radius-m);
	background: linear-gradient(135deg, var(--speaker-color-accent), var(--speaker-color-accent-2));
	box-shadow: 0 0 40px var(--speaker-color-accent-glow), 0 8px 32px var(--speaker-color-shadow-strong); }

.speaker-sidebar__image { display: block;
	inline-size: 100%;
	block-size: 100%;
	border-radius: var(--speaker-radius-s);
	object-fit: cover;
	object-position: center top; }

.speaker-sidebar__credentials { display: flex;
	flex-direction: column;
	gap: 0.625rem;
	inline-size: 100%;
	list-style: none;
	padding: 0;
	margin: 0;

	@media (width <= 1024px) {
		flex: 1;
	} }

.speaker-sidebar__credential { display: flex;
	align-items: flex-start;
	gap: 0.625rem;
	color: rgba(210, 228, 255, 0.82);
	font-size: 0.78rem;
	font-weight: 500;
	line-height: 1.4;
	letter-spacing: 0.02em;

	&::before {
		content: '';
		display: block;
		inline-size: 0.3125rem;
		block-size: 0.3125rem;
		flex-shrink: 0;
		margin-block-start: 0.3125rem;
		border-radius: 50%;
		background: var(--speaker-color-accent);
	} }

.speaker-content { min-inline-size: 0; }

/* ------------------------------------------------------------------
   Content column order — set explicitly, at every width.

   The handset reading order is headline, subhead, topics, bio, quote,
   posts, track record, CTAs. Source order used to carry it and produced
   two bugs, so every child names its own place. Anything unlisted keeps
   the default 0 and stays where the markup puts it -- which is the
   headline and subhead, and is correct.
   ------------------------------------------------------------------ */
.speaker-content > .speaker-accordion   { order: 1; }
.speaker-content > .speaker-card        { order: 2; }
.speaker-content > .speaker-pullquote   { order: 3; }
.speaker-content > .speaker-posts-block { order: 4; }
.speaker-content > .speaker-record      { order: 5; }
.speaker-content > .speaker-actions     { order: 6; }

.speaker-content { display: flex; flex-direction: column; }

/* ------------------------------------------------------------------
   Speaking Topics accordion — handset only
   Rendered at every width, shown only here. Above 700 the sidebar menu
   is the one that exists.
   ------------------------------------------------------------------ */

.speaker-accordion { display: none; }

@media (width <= 700px) {
	.speaker-accordion { display: block;
		margin-block-end: 1.5rem;
		border: 1px solid var(--speaker-color-border);
		border-radius: 20px;
		background: var(--speaker-color-glass-soft);
		box-shadow: 0 4px 32px var(--speaker-color-shadow);
		backdrop-filter: blur(18px);
		-webkit-backdrop-filter: blur(18px);
		overflow: hidden; }

	/* The sidebar's own menu is the desktop and tablet one; only one of the
	   two is ever visible, so they cannot both answer the same tap. */
	.speaker-sidebar .sb-topics { display: none; }
}

.speaker-accordion__header { inline-size: 100%;
	min-block-size: 56px;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding: 16px 18px;
	border: 0;
	background: none;
	color: color-mix(in oklab, var(--mmp-ice-solid) 90%, transparent);
	font-family: var(--text-font-family);
	font-size: 0.72rem;
	font-weight: 700;
	letter-spacing: 0.22em;
	text-align: start;
	text-transform: uppercase;
	cursor: pointer; }

.speaker-accordion__chevron { flex: none;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	inline-size: 26px;
	block-size: 26px;
	border: 1px solid color-mix(in oklab, var(--speaker-color-accent) 35%, transparent);
	border-radius: 50%;
	background: color-mix(in oklab, var(--speaker-color-accent) 18%, transparent);
	color: var(--mmp-ice-solid);
	font-size: 0.7rem;
	transition: transform 0.22s ease; }

.speaker-accordion__header[aria-expanded="true"] .speaker-accordion__chevron {
	transform: rotate(180deg); }

.speaker-accordion__panel { display: flex;
	flex-direction: column;
	border-block-start: 1px solid rgba(255, 255, 255, 0.10); }

.speaker-accordion__panel[hidden] { display: none; }

.speaker-accordion__row { display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	min-block-size: 56px;
	padding: 14px 18px;
	border: 0;
	border-block-end: 1px solid rgba(255, 255, 255, 0.10);
	background: none;
	color: var(--mmp-text-menu);
	font-family: var(--heading-font-family);
	font-size: 1.12rem;
	letter-spacing: 0.045em;
	text-align: start;
	cursor: pointer; }

.speaker-accordion__row:last-child { border-block-end: 0; }

.speaker-accordion__row:active,
.speaker-accordion__row:focus-visible {
	background: color-mix(in oklab, var(--speaker-color-accent) 12%, transparent); }

.speaker-accordion__cue { flex: none;
	color: color-mix(in oklab, var(--mmp-ice-solid) 60%, transparent);
	font-size: 0.85rem; }

/* ------------------------------------------------------------------
   Sticky action bar — handset only
   ------------------------------------------------------------------ */

.speaker-actionbar { display: none; }

@media (width <= 700px) {
	.speaker-actionbar { position: fixed;
		inset-inline: 0;
		inset-block-end: 0;
		z-index: 150;
		display: grid;
		grid-template-columns: repeat(3, 1fr);
		gap: 8px;
		padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
		background: var(--mmp-actionbar-bg);
		border-block-start: 1px solid var(--speaker-color-border);
		backdrop-filter: blur(18px);
		-webkit-backdrop-filter: blur(18px); }

	/* Room for the bar. Without it the last CTA sits under the glass.
	   The gutter is 16px and it is applied ONCE: .speaker-section inherits a
	   fluid inline padding from ACSS, so main's own padding was landing on
	   top of it and the headshot came out 64px narrower than the column it
	   is supposed to fill. */
	.speaker-main { padding-block-end: 108px; padding-inline: 16px; }
	.speaker-section { padding-inline: 0; }

	/* The in-page pair is redundant once the bar is always on screen. Both
	   stay at tablet and up, where there is no bar. */
	.speaker-content > .speaker-actions { display: none; }
}

.speaker-actionbar__item { display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 7px;
	min-block-size: 48px;
	border-radius: var(--speaker-radius-pill);
	font-family: var(--text-font-family);
	font-size: 0.85rem;
	font-weight: 700;
	text-decoration: none;
	cursor: pointer; }

.speaker-actionbar__item--glass { border: 1px solid var(--speaker-color-border);
	background: var(--mmp-glass-bg);
	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18);
	color: var(--mmp-text-menu); }

.speaker-actionbar__item--book { border: 0;
	background: var(--mmp-grad-cta);
	box-shadow: var(--mmp-shadow-cta);
	color: var(--mmp-cta-ink); }

/* ------------------------------------------------------------------
   Track Record
   ------------------------------------------------------------------ */

.speaker-record { margin-block-end: 1.375rem;
	padding: 22px 26px;
	border: 1px solid var(--speaker-color-border);
	border-radius: 20px;
	background: var(--speaker-color-glass-soft);
	box-shadow: 0 4px 32px var(--speaker-color-shadow);
	backdrop-filter: blur(18px);
	-webkit-backdrop-filter: blur(18px); }

.speaker-record__label { margin: 0 0 14px;
	color: color-mix(in oklab, var(--mmp-ice-solid) 75%, transparent);
	font-family: var(--text-font-family);
	font-size: 0.72rem;
	font-weight: 700;
	letter-spacing: 0.22em;
	line-height: 1;
	text-transform: uppercase; }

.speaker-record__list { display: flex;
	flex-direction: column;
	margin: 0;
	padding: 0;
	list-style: none; }

/* One credential per row. A grid made a long credential shove its
   neighbour out of line; this lets it wrap into its own space. */
.speaker-record__row { display: flex;
	align-items: center;
	gap: 14px;
	padding-block: 12px;
	border-block-end: 1px solid rgba(255, 255, 255, 0.10); }

.speaker-record__row:last-child { border-block-end: 0; }

.speaker-record__icon { flex: none;
	display: inline-flex;
	inline-size: 24px;
	block-size: 24px;
	align-items: center;
	justify-content: center;
	color: var(--mmp-ice-solid); }

.speaker-record__icon svg { inline-size: 16px; block-size: 16px; display: block; }

/* The design system's fallback for a credential with no icon chosen. */
.speaker-record__bullet { flex: none;
	inline-size: 5px;
	block-size: 5px;
	border-radius: 50%;
	background: var(--speaker-color-accent); }

.speaker-record__text { flex: 1;
	color: var(--mmp-body);
	font-size: 0.92rem;
	line-height: 1.5;
	text-wrap: pretty; }

/* nowrap is load-bearing: "2023 – 26" breaks at the en dash without it and
   drags the hairline below out of alignment. */
.speaker-record__year { flex: none;
	min-inline-size: 62px;
	color: var(--mmp-ice-solid);
	font-size: 0.78rem;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-align: end;
	white-space: nowrap;

	@media (width <= 700px) { min-inline-size: 56px; } }



/* Manrope, not the heading face. Bebas Neue ships uppercase glyphs only, so
   the headline rendered as caps no matter what text-transform said -- the
   approved design sets this line in Manrope 700, mixed case. The 0.05em
   tracking was there to open Bebas up and reads as damage on Manrope. */
.speaker-content__title { max-inline-size: 62ch;
	margin-block-end: 0.875rem;
	font-family: var(--text-font-family);
	font-size: clamp(1.7rem, 3.5vw, 2.8rem);
	font-weight: 700;
	line-height: 1.18;
	letter-spacing: -0.01em;
	background: linear-gradient(135deg, #fff 30%, #a5c8f0 100%);
	background-clip: text;
	-webkit-background-clip: text;
	-webkit-text-fill-color: transparent;
	text-wrap: balance; }

.speaker-content__intro { max-inline-size: 70ch;
	margin-block-end: 1.75rem;
	color: var(--speaker-color-text-muted);
	font-size: clamp(0.95rem, 1.8vw, 1.15rem);
	line-height: 1.55;
	text-wrap: pretty; }

.speaker-card { margin-block-end: 1.5rem;
	padding: 1.75rem 2rem;
	border: 1px solid var(--speaker-color-border);
	border-radius: var(--speaker-radius-l);
	background: var(--speaker-color-glass-soft);
	box-shadow: 0 4px 32px var(--speaker-color-shadow);
	backdrop-filter: blur(18px);
	-webkit-backdrop-filter: blur(18px);

	@media (width <= 1024px) {
		padding: 1.25rem 1.125rem;
	} }

.speaker-bio { color: rgba(230, 240, 255, 0.88);
	font-size: 0.95rem;
	line-height: 1.72; }

.speaker-bio__paragraph { max-inline-size: 70ch;
	margin-block-end: 0.875rem; }

.speaker-bio__quote-inline { max-inline-size: 70ch;
  margin-block: 1.125rem;
  padding-inline-start: 2rem;
  border-inline-start: 3px solid var(--speaker-color-accent);
  color: #c5deff;
  font-family: var(--speaker-font-serif);
  font-size: 1.08rem;
  font-style: italic;
  font-weight: 500;
  text-wrap: pretty;
  line-height: 1.5rem;
    @media (width <= 1024px) {
    padding-inline-start: .8rem;
  } }

.speaker-bio__quote-cite { font-size: 0.78rem;
  font-style: normal;
  font-weight: 500;
  font-family: var(--speaker-font-body);
  text-transform: uppercase;
  color: rgba(165, 212, 245, 0.7); }

.speaker-badges { display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin-block: 0.75rem 1rem;
	padding: 0;
	list-style: none; }

.speaker-badge { display: inline-flex;
	align-items: center;
	padding: 0.25rem 0.875rem;
	border: 1px solid var(--speaker-color-accent-border);
	border-radius: var(--speaker-radius-pill);
	/* Scrim first, translucent accent layered over it, so the pill does not
	   track the background photo and contrast stays deterministic at any
	   scroll position. See docs/design/accent-palette.md. */
	background:
		linear-gradient(var(--speaker-color-accent-soft), var(--speaker-color-accent-soft)),
		var(--speaker-color-accent-scrim);
	color: var(--speaker-color-accent-text);
	font-size: 0.78rem;
	font-weight: 600; }

.speaker-bio__paragraph--muted { color: var(--speaker-color-text-soft);
	font-size: 0.88rem;
	margin-block-end: 0; }

.speaker-pullquote { margin-block-end: 1.75rem;
	padding: 1.5rem 2rem;
	border: 1px solid color-mix(in oklab, var(--speaker-color-accent) 25%, transparent);
	border-radius: var(--speaker-radius-l);
	background: color-mix(in oklab, var(--speaker-color-accent) 8%, transparent);
	box-shadow: 0 4px 32px color-mix(in oklab, var(--speaker-color-accent) 10%, transparent);
	text-align: center;
	backdrop-filter: blur(18px);
	-webkit-backdrop-filter: blur(18px);

	@media (width <= 1024px) {
		padding: 1.125rem;
	} }

.speaker-pullquote__text { max-inline-size: 70ch;
  margin-inline: auto;
  color: #d6eaff;
  font-family: var(--speaker-font-serif);
  font-size: clamp(1.08rem, 2vw, 1.45rem);
  font-style: italic;
  font-weight: 500;
  line-height: 1.5;
  text-wrap: balance;
  display: block;
  
  &::before {
    content: '\201C';
  }

  &::after {
    content: '\201D';
  } }

/* The em dash is presentational -- the design shows "\2014 PATRICK LONGANO" --
   so it belongs here rather than concatenated into the field value, where it
   would end up stored in the database and duplicated by any other consumer. */
.speaker-pullquote__cite::before { content: "\2014\00a0"; }

.speaker-pullquote__cite { display: block;
  margin-block-start: 0.625rem;
  color: rgba(165, 212, 245, 0.7);
  font-size: 0.82rem;
  font-style: normal;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase; }

/* ------------------------------------------------------------------
   Latest Posts — the 1a card grid
   Three columns desktop, two tablet, one handset.
   ------------------------------------------------------------------ */

.speaker-posts-block { margin-block-end: 2.25rem; }

.speaker-posts__head { display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
	margin-block-end: 1rem; }

.speaker-posts__eyebrow { margin: 0;
	color: var(--mmp-ice);
	font-family: var(--text-font-family);
	font-size: 0.72rem;
	font-weight: 700;
	letter-spacing: 0.22em;
	line-height: 1;
	text-transform: uppercase; }

.speaker-posts__all { display: inline-flex;
	align-items: center;
	gap: 0.35rem;
	color: var(--mmp-ice-solid);
	font-size: 0.88rem;
	font-weight: 600;
	text-decoration: none;
	transition: color 0.2s ease; }

.speaker-posts__all:hover,
.speaker-posts__all:focus-visible { color: var(--mmp-text); }

.speaker-posts__grid { display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 20px;

	@media (width <= 1024px) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	@media (width <= 700px)  { grid-template-columns: minmax(0, 1fr); } }

.speaker-post-card { display: flex;
	flex-direction: column;
	border: 1px solid var(--speaker-color-border);
	border-radius: 20px;
	background: var(--speaker-color-glass-soft);
	box-shadow: 0 4px 32px var(--speaker-color-shadow);
	backdrop-filter: blur(18px);
	-webkit-backdrop-filter: blur(18px);
	overflow: hidden;
	text-decoration: none;
	transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s ease; }

.speaker-post-card:hover,
.speaker-post-card:focus-visible { background: var(--mmp-glass-bg);
	border-color: var(--mmp-glass-border-hi);
	transform: translateY(-1px); }

.speaker-post-card__media { position: relative; display: block; }

.speaker-post-card__image { display: block;
	inline-size: 100%;
	aspect-ratio: 16 / 9;
	object-fit: cover; }

/*
 * The typographic fallback when a post has no image.
 *
 * border-box is not optional here: this band carries aspect-ratio AND 22px of
 * inline padding, and under content-box the ratio resolves against the content
 * box only -- the band lands short of the image cards beside it and steps the
 * whole row out of alignment.
 */
.speaker-post-card__band { box-sizing: border-box;
	display: flex;
	align-items: center;
	justify-content: center;
	inline-size: 100%;
	aspect-ratio: 16 / 9;
	padding-inline: 22px;
	border-block-end: 1px solid color-mix(in oklab, var(--speaker-color-accent) 25%, transparent);
	background: color-mix(in oklab, var(--speaker-color-accent) 8%, transparent);
	color: var(--mmp-ice-solid);
	font-family: var(--heading-font-family);
	font-size: 1.5rem;
	letter-spacing: 0.045em;
	line-height: 1.1;
	text-align: center;
	text-wrap: balance; }

.speaker-post-card__badge { position: absolute;
	inset-inline-start: 14px;
	inset-block-end: 14px;
	display: inline-flex;
	align-items: center;
	gap: 7px;
	padding: 5px 12px;
	border: 1px solid var(--speaker-color-border);
	border-radius: var(--speaker-radius-pill);
	background: var(--mmp-bubble-bg);
	color: var(--mmp-ice-solid);
	font-family: var(--text-font-family);
	font-size: 0.68rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase; }

.speaker-post-card__body { display: flex;
	flex-direction: column;
	gap: 10px;
	padding: 18px 20px 20px; }

.speaker-post-card__meta { display: flex;
	align-items: center;
	gap: 10px;
	color: var(--mmp-muted);
	font-size: 0.88rem; }

.speaker-post-card__topic { color: var(--mmp-ice-solid);
	font-size: 0.68rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase; }

.speaker-post-card__title { color: var(--mmp-text);
	font-size: 1.08rem;
	font-weight: 700;
	line-height: 1.32;
	text-wrap: pretty; }

.speaker-post-card__excerpt { color: var(--mmp-body);
	font-size: 0.9rem;
	line-height: 1.6;
	text-wrap: pretty; }

.speaker-actions { display: flex;
	flex-wrap: wrap;
	gap: 0.875rem;
	justify-content: center; }

.speaker-button--cta { padding: 0.875rem 1.875rem;
	border: 1px solid transparent;
	border-radius: var(--speaker-radius-pill);
	font-size: 1rem;
	font-weight: 700;
	letter-spacing: 0.01em;

	@media (width <= 1024px) {
		padding: 0.75rem 1.25rem;
		font-size: 0.93rem;
	} }

.speaker-button--book { border-color: rgba(255, 255, 255, 0.15);
	background: linear-gradient(135deg, var(--speaker-color-accent), var(--speaker-color-accent-2));
	/* White on the accent fill measures 2.75:1 — well below AA — and fails
	   for every palette hue. Dark ink gives 5.94:1 at worst. */
	color: var(--speaker-color-accent-ink);
	box-shadow: 0 4px 24px color-mix(in oklab, var(--speaker-color-accent) 45%, transparent);

	&:hover {
		box-shadow: 0 8px 36px color-mix(in oklab, var(--speaker-color-accent) 60%, transparent);
		filter: brightness(1.08);
	} }

.speaker-button--contact { border-color: var(--speaker-color-border);
	background: var(--speaker-color-glass);
	color: #fff;
	box-shadow: 0 2px 12px var(--speaker-color-shadow), inset 0 1px 0 rgba(255, 255, 255, 0.18);
	backdrop-filter: blur(18px);
	-webkit-backdrop-filter: blur(18px);

	&:hover {
		background: rgba(255, 255, 255, 0.18);
		border-color: var(--speaker-color-border-strong);
	} }

.speaker-footer { position: relative;
	z-index: 10;
	padding: 1.125rem 1.5rem 1.75rem;
	text-align: center;
	padding-block: 1.125rem 1.75rem;
	padding-inline: 0; }

/* The Etch theme prints a fallback banner -- site title, tagline, a rule --
   before the template's own markup. It is not in the approved design and was
   bleeding out from under the fixed header. Scoped with :has() so it only
   disappears on pages this plugin renders. */
body:has(.speaker-page) #header,
body:has(.speaker-page) #page > hr,
body:has(.speaker-page) #footer { display: none; }

/* ------------------------------------------------------------------
   Social buttons
   Header: a 36px pill that is a circle until you hover it, then the
   label unrolls. Footer: static 38px circles above the copyright.
   One partial renders both; the variant class picks the presentation.
   ------------------------------------------------------------------ */

.speaker-social { display: flex;
	align-items: center;
	gap: 0.375rem;
	margin: 0;
	padding: 0;
	list-style: none; }

.speaker-social__link { display: inline-flex;
	align-items: center;
	justify-content: center;
	color: var(--speaker-color-text-muted);
	text-decoration: none;
	background: rgba(255, 255, 255, 0.07);
	border: 1px solid rgba(255, 255, 255, 0.22);
	backdrop-filter: blur(18px);
	transition: color 0.28s ease, background 0.28s ease,
		border-color 0.28s ease, box-shadow 0.28s ease, transform 0.28s ease; }

.speaker-social__icon { flex: none; }

/* The label is the animated part: width from 0, so the collapsed button is a
   true circle rather than a pill with empty space in it. */
.speaker-social__label { display: block;
	max-inline-size: 0;
	overflow: hidden;
	white-space: nowrap;
	font-size: 0.78rem;
	font-weight: 600;
	line-height: 1;
	opacity: 0;
	transition: max-inline-size 0.28s ease, opacity 0.28s ease,
		padding-inline-start 0.28s ease; }

/* --- header ------------------------------------------------------- */

.speaker-social--header .speaker-social__link { block-size: 36px;
	min-inline-size: 36px;
	padding-inline: 9px;
	border-radius: 980px; }

.speaker-social--header .speaker-social__link:hover,
.speaker-social--header .speaker-social__link:focus-visible {
	color: var(--mmp-text, #f0f4ff);
	background: color-mix(in oklab, var(--speaker-color-accent) 28%, transparent);
	border-color: color-mix(in oklab, var(--speaker-color-accent) 65%, transparent); }

.speaker-social--header .speaker-social__link:hover .speaker-social__label,
.speaker-social--header .speaker-social__link:focus-visible .speaker-social__label {
	max-inline-size: 120px;
	padding-inline-start: 7px;
	opacity: 1; }

/* Drawn here rather than printed in the template: a speaker with no social
   URLs renders no list at all, and a divider with nothing on one side of it
   is worse than no divider. */
.speaker-header__actions:has(.speaker-social)::before { content: "";
	align-self: center;
	inline-size: 1px;
	block-size: 20px;
	background: rgba(255, 255, 255, 0.22);
	order: 1; }

.speaker-header__actions .speaker-social { order: 0; }
.speaker-header__actions .speaker-button { order: 2; }

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

.speaker-social--footer { justify-content: center;
	gap: 0.5rem;
	margin-block-end: 0.875rem; }

.speaker-social--footer .speaker-social__link { inline-size: 38px;
	block-size: 38px;
	border-radius: 50%; }

.speaker-social--footer .speaker-social__label { display: none; }

.speaker-social--footer .speaker-social__link:hover,
.speaker-social--footer .speaker-social__link:focus-visible {
	color: var(--mmp-text, #f0f4ff);
	background: color-mix(in oklab, var(--speaker-color-accent) 28%, transparent);
	border-color: color-mix(in oklab, var(--speaker-color-accent) 65%, transparent);
	box-shadow: 0 0 16px color-mix(in oklab, var(--speaker-color-accent) 30%, transparent);
	transform: translateY(-2px); }

/* A "#" placeholder still renders -- the design ships them -- but it must not
   behave like a live destination. */
.speaker-social__link[aria-disabled="true"] { cursor: default; }

/* Phone: the header set goes, the footer keeps them. Per the handoff. */
@media (width <= 700px) {
	.speaker-social--header { display: none; }
	.speaker-header__actions:has(.speaker-social)::before { display: none; }
}

@media (prefers-reduced-motion: reduce) {
	.speaker-social__link,
	.speaker-social__label { transition: none; }
}

.speaker-footer__text { color: rgba(200, 220, 255, 0.4);
	font-size: 0.78rem;
	letter-spacing: 0.04em;
	text-align: center; }

:root {
	--speaker-color-accent:         #4fa3e0;
	--speaker-color-accent-2:       #a78bfa;

	/* Derived accents. Each has a plain fallback first so a browser without
	   color-mix keeps a usable colour rather than an unset one. */
	--speaker-color-accent-soft:    rgba(79, 163, 224, 0.18);
	--speaker-color-accent-soft:    color-mix(in oklab, var(--speaker-color-accent) 18%, transparent);
	--speaker-color-accent-border:  rgba(79, 163, 224, 0.35);
	--speaker-color-accent-border:  color-mix(in oklab, var(--speaker-color-accent) 35%, transparent);
	--speaker-color-accent-glow:    rgba(79, 163, 224, 0.30);
	--speaker-color-accent-glow:    color-mix(in oklab, var(--speaker-color-accent) 30%, transparent);
	--speaker-color-accent-text:    #9eccee;
	--speaker-color-accent-text:    color-mix(in oklab, var(--speaker-color-accent) 55%, #ffffff);

	/* Dark ink for text sitting on a bright accent fill, and the scrim that
	   sits under translucent accent surfaces. */
	--speaker-color-accent-ink:     #0a0e1a;
	--speaker-color-accent-scrim:   rgba(10, 14, 26, 0.55);

	--speaker-color-text:           #f0f4ff;
	--speaker-color-text-muted:     rgba(240, 244, 255, 0.72);
	--speaker-color-text-soft:      rgba(200, 220, 255, 0.60);

	--speaker-color-glass:          rgba(255, 255, 255, 0.10);
	--speaker-color-glass-soft:     rgba(255, 255, 255, 0.07);
	--speaker-color-border:         rgba(255, 255, 255, 0.22);
	--speaker-color-border-strong:  rgba(255, 255, 255, 0.38);

	--speaker-color-shadow:         rgba(0, 0, 0, 0.18);
	--speaker-color-shadow-strong:  rgba(0, 0, 0, 0.45);

	--speaker-font-display: 'Bebas Neue', 'Impact', 'Arial Narrow', sans-serif;
	--speaker-font-serif:   'Cormorant Garamond', 'Times New Roman', serif;
	--speaker-font-body:    'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

	--speaker-radius-s:    0.8125rem;
	--speaker-radius-m:    1rem;
	--speaker-radius-l:    1.25rem;
	--speaker-radius-pill: 999rem;
}

/* ------------------------------------------------------------------
   Speaker accent palette. Eight options, each a single override; the
   text colour, soft fill, border, and glow all derive from it.
   Contrast-verified against the real background photo — worst case
   5.70:1 on badges and 5.94:1 on the primary CTA, against a 4.5:1
   requirement. Analysis: docs/design/accent-palette.md
   ------------------------------------------------------------------ */
[data-speaker-accent="teal"]    { --speaker-color-accent: #3fb8ac; }
[data-speaker-accent="emerald"] { --speaker-color-accent: #46b06a; }
[data-speaker-accent="amber"]   { --speaker-color-accent: #d99a3c; }
[data-speaker-accent="coral"]   { --speaker-color-accent: #e2705f; }
[data-speaker-accent="violet"]  { --speaker-color-accent: #a78bfa; }
[data-speaker-accent="rose"]    { --speaker-color-accent: #dd6a9b; }
[data-speaker-accent="steel"]   { --speaker-color-accent: #7f8fb3; }

/* ------------------------------------------------------------------
   Accessibility utilities and focus states.

   AA requires a visible focus indicator on every interactive element
   (spec §10). The glass surfaces are low-contrast by design, so the
   ring is white with an accent halo rather than the accent alone.
   ------------------------------------------------------------------ */

.speaker-visually-hidden { position: absolute;
	inline-size: 1px;
	block-size: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0; }

.speaker-skip-link { position: absolute;
	inset-block-start: -100%;
	inset-inline-start: 1rem;
	z-index: 200;
	padding: 0.6rem 1.1rem;
	border-radius: var(--speaker-radius-pill);
	background: var(--speaker-color-accent);
	color: var(--speaker-color-accent-ink);
	font-family: var(--speaker-font-body);
	font-size: 0.85rem;
	font-weight: 700;
	text-decoration: none;

	&:focus-visible {
		inset-block-start: 0.75rem;
	} }

/* [tabindex="-1"] is excluded on purpose. A dialog carries it so the panel can
   be focused programmatically on open -- it is a container, not a control, and
   it was picking up a control's ring AND a control's 13px radius, which
   overrode the sheet's own 24px 24px 0 0 corners. */
:is(.speaker-page, .speaker-directory) :is(a, button, summary, [tabindex]):not([tabindex="-1"]):focus-visible { outline: 2px solid #ffffff;
	outline-offset: 3px;
	border-radius: var(--speaker-radius-s);
	box-shadow: 0 0 0 6px color-mix(in oklab, var(--speaker-color-accent) 45%, transparent); }

/* ------------------------------------------------------------------
   Header anchor navigation. Generated from the sections that actually
   rendered, so it is never a link to nothing. Hidden below the tablet
   breakpoint, where the name and the two buttons already fill the bar.
   ------------------------------------------------------------------ */

.speaker-header__nav { display: flex;
	gap: 1.25rem;
	align-items: center;
	margin-inline: auto;

	@media (width <= 1024px) {
		display: none;
	} }

.speaker-header__link { color: var(--speaker-color-text-muted);
	font-size: 0.82rem;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	text-decoration: none;
	transition: color 0.22s ease;

	&:hover {
		color: var(--speaker-color-text);
	} }

/* ------------------------------------------------------------------
   Bio paragraphs.

   The bio is a WYSIWYG field, so its paragraphs cannot carry
   .speaker-bio__paragraph the way the hand-built production markup did.
   These element rules reproduce it, and the first paragraph gets the
   lead treatment that page 65 applied with .speaker-bio__lead.
   ------------------------------------------------------------------ */

.speaker-bio p { max-inline-size: 70ch;
	margin-block-end: 0.875rem; }

.speaker-bio p:last-child { margin-block-end: 0; }

.speaker-bio blockquote { max-inline-size: 70ch;
	margin-block: 1.125rem;
	padding-inline-start: 2rem;
	border-inline-start: 3px solid var(--speaker-color-accent);
	color: #c5deff;
	font-family: var(--speaker-font-serif);
	font-size: 1.08rem;
	font-style: italic;
	font-weight: 500;
	line-height: 1.5rem;
	text-wrap: pretty;

	@media (width <= 1024px) {
		padding-inline-start: 0.8rem;
	} }

.speaker-bio__lead,
.speaker-bio > p:first-child { color: #dce9ff;
	font-size: 1.03rem;
	line-height: 1.62; }

/* ------------------------------------------------------------------
   Shared section heading. Production had no section headings — the page
   was a single unlabelled column — so this is new, pitched between the
   h1 and the body copy.
   ------------------------------------------------------------------ */

.speaker-heading { margin-block: 2.25rem 1.125rem;
	color: var(--speaker-color-text);
	font-family: var(--speaker-font-display);
	font-size: clamp(1.35rem, 2.4vw, 1.85rem);
	font-weight: 400;
	letter-spacing: 0.07em;
	line-height: 1.1;
	text-transform: uppercase; }

/* ------------------------------------------------------------------
   Speaking topics. Synopsis always visible, full detail in a <details>
   accordion (spec §5.6).
   ------------------------------------------------------------------ */

/* The header is fixed, so every anchor target needs to clear it. */
.speaker-card[id],
.sb-topics,
.speaker-testimonials { scroll-margin-block-start: 5rem; }

/* ------------------------------------------------------------------
   Testimonials. Three across on desktop, stacking down to one. Every
   field but the quote is optional, so the attribution block may be
   absent entirely.
   ------------------------------------------------------------------ */

.speaker-testimonials__grid { display: grid;
	grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
	gap: 1rem;
	margin: 0 0 1.75rem;
	padding: 0;
	list-style: none; }

.speaker-testimonial { display: flex;
	padding: 1.25rem 1.375rem;
	border: 1px solid var(--speaker-color-border);
	border-radius: var(--speaker-radius-m);
	background: var(--speaker-color-glass-soft);
	box-shadow: 0 4px 32px var(--speaker-color-shadow);
	backdrop-filter: blur(18px);
	-webkit-backdrop-filter: blur(18px); }

.speaker-testimonial__figure { display: flex;
	flex-direction: column;
	gap: 0.875rem;
	margin: 0;
	inline-size: 100%; }

.speaker-testimonial__quote { margin: 0;
	color: #d6eaff;
	font-family: var(--speaker-font-serif);
	font-size: 1.02rem;
	font-style: italic;
	line-height: 1.5;
	text-wrap: pretty;

	&::before {
		content: '\201C';
	}

	&::after {
		content: '\201D';
	} }

.speaker-testimonial__attribution { display: flex;
	gap: 0.75rem;
	align-items: center;
	margin-block-start: auto; }

.speaker-testimonial__photo { inline-size: 2.5rem;
	block-size: 2.5rem;
	flex-shrink: 0;
	border-radius: 50%;
	object-fit: cover;
	border: 1px solid var(--speaker-color-accent-border); }

.speaker-testimonial__who { display: flex;
	flex-direction: column;
	gap: 0.125rem;
	min-inline-size: 0; }

.speaker-testimonial__name { color: var(--speaker-color-text);
	font-size: 0.85rem;
	font-weight: 700; }

.speaker-testimonial__role { color: var(--speaker-color-text-soft);
	font-size: 0.76rem;
	line-height: 1.35; }

/* Footer directory link. */
.speaker-footer__link { color: rgba(200, 220, 255, 0.62);
	text-decoration: underline;
	text-underline-offset: 0.2em;

	&:hover {
		color: var(--speaker-color-text);
	} }

/* ------------------------------------------------------------------
   Directory hub.

   Rendered by the [mmpsb_directory] shortcode into an ordinary page, so
   it carries its own typography rather than inheriting the profile
   wrapper's. It assumes the dark ground the rest of the design uses;
   the host page supplies the background.
   ------------------------------------------------------------------ */

.speaker-directory { font-family: var(--speaker-font-body);
	color: var(--speaker-color-text);
	inline-size: min(100%, 68.75rem);
	margin-inline: auto; }

.speaker-directory__filters { display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin-block-end: 1.75rem; }

.speaker-directory__filter { padding: 0.3125rem 0.9375rem;
	border: 1px solid var(--speaker-color-border);
	border-radius: var(--speaker-radius-pill);
	background: var(--speaker-color-glass-soft);
	color: var(--speaker-color-text-muted);
	font-size: 0.8rem;
	font-weight: 600;
	letter-spacing: 0.02em;
	text-decoration: none;
	transition: background 0.22s ease, border-color 0.22s ease, color 0.22s ease;

	&:hover {
		border-color: var(--speaker-color-border-strong);
		color: var(--speaker-color-text);
	}

	&.is-active {
		border-color: var(--speaker-color-accent-border);
		background:
			linear-gradient(var(--speaker-color-accent-soft), var(--speaker-color-accent-soft)),
			var(--speaker-color-accent-scrim);
		color: var(--speaker-color-accent-text);
	} }

.speaker-directory__empty { padding: 2rem 0;
	color: var(--speaker-color-text-muted);
	font-size: 0.95rem;

	& a {
		color: var(--speaker-color-accent-text);
		font-weight: 600;
	} }

.speaker-directory__grid { display: grid;
	grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
	gap: 1.25rem;
	margin: 0;
	padding: 0;
	list-style: none; }

.speaker-directory__card { display: flex;
	flex-direction: column;
	overflow: hidden;
	border: 1px solid var(--speaker-color-border);
	border-radius: var(--speaker-radius-l);
	background: var(--speaker-color-glass-soft);
	box-shadow: 0 4px 32px var(--speaker-color-shadow);
	backdrop-filter: blur(18px);
	-webkit-backdrop-filter: blur(18px);
	transition: border-color 0.22s ease, transform 0.22s ease, box-shadow 0.22s ease;

	&:hover {
		border-color: var(--speaker-color-accent-border);
		transform: translateY(-3px);
		box-shadow: 0 8px 40px var(--speaker-color-shadow-strong);
	} }

.speaker-directory__card--featured { border-color: var(--speaker-color-accent-border);
	box-shadow: 0 4px 32px color-mix(in oklab, var(--speaker-color-accent) 18%, transparent); }

.speaker-directory__thumb { aspect-ratio: 3 / 4;
	overflow: hidden;
	background: var(--speaker-color-glass); }

.speaker-directory__image { display: block;
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover;
	object-position: center top; }

.speaker-directory__body { display: flex;
	flex-direction: column;
	gap: 0.4375rem;
	padding: 1.125rem 1.25rem 1.375rem; }

.speaker-directory__flag { margin: 0;
	color: var(--speaker-color-accent-text);
	font-size: 0.68rem;
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase; }

.speaker-directory__name { margin: 0;
	font-size: 1.05rem;
	font-weight: 700;
	line-height: 1.25; }

.speaker-directory__link { color: var(--speaker-color-text);
	text-decoration: none;

	/* The whole card is the target; the link keeps the accessible name. */
	&::after {
		content: '';
		position: absolute;
		inset: 0;
	} }

.speaker-directory__card { position: relative; }

.speaker-directory__headline { margin: 0;
	color: var(--speaker-color-accent-text);
	font-size: 0.83rem;
	font-weight: 600;
	line-height: 1.4;
	text-wrap: pretty; }

.speaker-directory__location { margin: 0;
	color: var(--speaker-color-text-soft);
	font-size: 0.76rem;
	letter-spacing: 0.02em; }

.speaker-directory__excerpt { margin: 0;
	color: rgba(230, 240, 255, 0.82);
	font-size: 0.85rem;
	line-height: 1.55;
	text-wrap: pretty; }

.speaker-directory__pills { display: flex;
	flex-wrap: wrap;
	gap: 0.3125rem;
	margin: 0.3125rem 0 0;
	padding: 0;
	list-style: none; }

.speaker-directory__pill { padding: 0.125rem 0.5625rem;
	border: 1px solid var(--speaker-color-accent-border);
	border-radius: var(--speaker-radius-pill);
	background:
		linear-gradient(var(--speaker-color-accent-soft), var(--speaker-color-accent-soft)),
		var(--speaker-color-accent-scrim);
	color: var(--speaker-color-accent-text);
	font-size: 0.68rem;
	font-weight: 600; }

/* Directory search. */
.speaker-directory__search { display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	align-items: center;
	margin-block-end: 1rem; }

.speaker-directory__input { flex: 1 1 16rem;
	min-inline-size: 0;
	padding: 0.5rem 1rem;
	border: 1px solid var(--speaker-color-border);
	border-radius: var(--speaker-radius-pill);
	background: var(--speaker-color-glass-soft);
	color: var(--speaker-color-text);
	font-family: var(--speaker-font-body);
	font-size: 0.9rem;
	backdrop-filter: blur(18px);
	-webkit-backdrop-filter: blur(18px);

	&::placeholder {
		color: var(--speaker-color-text-soft);
	}

	&:focus {
		border-color: var(--speaker-color-accent-border);
		outline: none;
	} }

.speaker-directory__clear { color: var(--speaker-color-text-soft);
	font-size: 0.8rem;
	text-decoration: underline;
	text-underline-offset: 0.2em;

	&:hover {
		color: var(--speaker-color-text);
	} }

.speaker-directory__empty strong { color: var(--speaker-color-text); }
