@mixin _oTopperThemeElements($themes) {
	@if index($themes, 'opinion') {
		.o-topper__opinion-genre {
			@include _oTopperOpinionGenre;
		}
	}

	.o-topper__headshot {
		@include _oTopperHeadshot;
	}

	.o-topper__headshot-image {
		@include _oTopperHeadshotImage;
	}

	.o-topper__anchor-link {
		@include _oTopperAnchorLink;
	}
}

@mixin _oTopperThemes($themes, $colors) {
	@include _oTopperThemeElements($themes);

	@if index($themes, 'basic') {
		.o-topper--basic {
			@include _oTopperBasic;
			@if index($themes, 'right-rail') {
				&.o-topper--right-rail {
					@include _oTopperGridRightRail;
				}
			}
		}
	}

	@if index($themes, 'branded') {
		.o-topper--branded {
			@include _oTopperThemeBranded;
			@if index($themes, 'right-rail') {
				&.o-topper--right-rail {
					@include _oTopperGridRightRail;
				}
			}
		}
	}

	@if index($themes, 'opinion') {
		.o-topper--opinion {
			@include _oTopperThemeOpinion;
			@if index($themes, 'right-rail') {
				&.o-topper--right-rail {
					@include _oTopperGridRightRail;
				}
			}
		}
	}

	@if index($themes, 'has-headshot') {
		.o-topper--has-headshot {
			@include _oTopperHasHeadshot;
		}
	}

	@if index($themes, 'full-bleed-offset') {
		.o-topper--full-bleed-offset {
			@include _oTopperThemeFullBleedOffset;
			@if index($themes, 'right-rail') {
				&.o-topper--right-rail {
					@include _oTopperFullBleedGridRightRail;
				}
			}
		}
	}

	@if index($themes, 'split-text-left') or index($themes, 'split-text-center') {
		.o-topper--split-text-left,
		.o-topper--split-text-center {
			@include _oTopperThemeSplitText;
		}
	}

	@if index($themes, 'full-bleed-image-center') or
		index($themes, 'full-bleed-image-left')
	{
		.o-topper--full-bleed-image-center,
		.o-topper--full-bleed-image-left {
			@include _oTopperThemeFullBleedImage;
		}
	}

	@if index($themes, 'package') {
		.o-topper--package {
			@include _oTopperThemePackage;
		}
	}

	@if index($themes, 'package-extra') or index($themes, 'package-extra-wide') {
		.o-topper--package-extra,
		.o-topper--package-extra-wide {
			@include _oTopperThemePackageExtra;
		}
	}

	@if index($themes, 'package-special-report') {
		.o-topper--package-special-report {
			@include _oTopperThemePackageSpecialReport;
		}
	}

	// @deprecated - remove in the next major version,
	// decided not to warm here as users outputting all
	// o-topper themes which includes the news-package
	// by default should not be bothered. This is no longer
	// in use on ft.com / app already:
	// https://financialtimes.atlassian.net/browse/CI-944
	@if index($themes, 'news-package') {
		@error 'The news package topper theme no longer exists. Please speak to Origami if your project depends on this.';
	}

	@if index($themes, 'centered') {
		.o-topper--centered {
			@include _oTopperCentered;
		}
	}

	@if index($themes, 'deep-portrait') {
		.o-topper--deep-portrait {
			@include _oTopperThemeSplitTextPortraitLeft($colors);
		}
	}

	@if index($themes, 'deep-landscape') {
		.o-topper--deep-landscape {
			@include _oTopperThemeDeepLandscape($colors);
		}
	}
}

@mixin _oTopperElements($elements) {
	@if index($elements, 'content') {
		.o-topper__content {
			@include _oTopperContent;
		}
	}

	@if index($elements, 'visual') {
		.o-topper__visual {
			@include _oTopperVisual;
		}
	}

	@if index($elements, 'visual') or index($elements, 'background') {
		.o-topper__visual,
		.o-topper__background {
			@include _oTopperBackground;
		}
	}

	@if index($elements, 'headline') {
		.o-topper__headline {
			margin: 0;
			margin-bottom: oPrivateSpacingByIncrement(5);
			font-family: oPrivateFoundationGet('o3-type-headline-md-font-family');
			font-size: oPrivateFoundationGet('o3-type-headline-md-font-size');
			font-weight: oPrivateFoundationGet('o3-type-headline-md-font-weight');
			line-height: oPrivateFoundationGet('o3-type-headline-md-line-height');

			@include oPrivateGridRespondTo('L') {
				font-family: oPrivateFoundationGet('o3-type-headline-lg-font-family');
				font-size: oPrivateFoundationGet('o3-type-headline-lg-font-size');
				font-weight: oPrivateFoundationGet('o3-type-headline-lg-font-weight');
				line-height: oPrivateFoundationGet('o3-type-headline-lg-line-height');
			}
		}

		.o-topper__headline--large {
			position: relative; //so it appears above the full width background
			margin-bottom: oPrivateSpacingByIncrement(4);
			font-family: oPrivateFoundationGet('o3-type-display-sm-font-family');
			font-size: oPrivateFoundationGet('o3-type-display-sm-font-size');
			font-weight: oPrivateFoundationGet('o3-type-display-sm-font-weight');
			line-height: oPrivateFoundationGet('o3-type-display-sm-line-height');

			@include oPrivateGridRespondTo('S') {
				font-family: oPrivateFoundationGet('o3-type-display-md-font-family');
				font-size: oPrivateFoundationGet('o3-type-display-md-font-size');
				font-weight: oPrivateFoundationGet('o3-type-display-md-font-weight');
				line-height: oPrivateFoundationGet('o3-type-display-md-line-height');
			}

			@include oPrivateGridRespondTo('L') {
				font-family: oPrivateFoundationGet('o3-type-display-lg-font-family');
				font-size: oPrivateFoundationGet('o3-type-display-lg-font-size');
				font-weight: oPrivateFoundationGet('o3-type-display-lg-font-weight');
				line-height: oPrivateFoundationGet('o3-type-display-lg-line-height');
			}

			&:after {
				content: '';
				display: block;
				// 18px Metric = 4px
				// 48px FinancierDisplayWeb = 8px
				border-bottom: calc(0.34ex + 1px) solid;
				// 18px Metric = ~60px
				// 48px FinancierDisplayWeb = ~180px
				width: calc(7ch - 10px);
				max-width: 100%;
				// 20px assuming a 48px font size
				padding-top: 0.416em;
			}
		}
	}

	@if index($elements, 'summary') {
		.o-topper__summary {
			@include _oTopperSummary;
		}
	}

	@if index($elements, 'standfirst') {
		.o-topper__standfirst {
			@include _oTopperStandfirst;
		}
	}

	@if index($elements, 'summary--body') {
		.o-topper__summary--body {
			@include _oTopperSummaryBody;
		}
	}

	@if index($elements, 'tags') {
		.o-topper__tags {
			@include _oTopperTags;
		}
	}

	@if index($elements, 'columnist') {
		.o-topper__columnist {
			margin-top: oPrivateSpacingByName('s4');
			text-transform: uppercase;
		}

		.o-topper--has-headshot .o-topper__columnist {
			margin-right: $_o-topper-headshot-width;
			@include oPrivateGridRespondTo(M) {
				margin-right: $_o-topper-headshot-width-M;
			}
		}
	}

	@if index($elements, 'columnist-name') {
		.o-topper__columnist-name {
			@extend %_o-topper__tag;
			vertical-align: middle;
		}
	}

	@if index($elements, 'brand') {
		.o-topper__brand {
			@include _oTopperBrand;
		}
	}

	@if index($elements, 'topic') {
		.o-topper__topic {
			@include _oTopperTopic;
		}
	}

	@if index($elements, 'read-next') {
		.o-topper__read-next {
			@include _oTopperReadNext;
		}
	}

	@if index($elements, 'image') {
		.o-topper__image {
			@include _oTopperImage;
		}
	}

	@if index($elements, 'image-credit') {
		.o-topper__image-credit {
			@include _oTopperImageCredit;
		}
	}

	@if index($elements, 'image-caption') {
		.o-topper__image-caption {
			@include _oTopperImageCaption;
		}
	}
}

@mixin _oTopperColors($colors) {
	@each $color in $colors {
		$o3-color-name: if(
			$color == 'matisse',
			'o3-color-palette-#{$color}-blue',
			'o3-color-palette-#{$color}'
		);
		.o-topper--color-#{$color} {
			@include _oTopperColor($o3-color-name);
		}
	}
}

// uses topper background colour to set background and pick contrasting text color
@mixin _oTopperColor($color-name) {
	$background: oPrivateFoundationGet($color-name);
	$foreground: oPrivateColorsGetTextColor($background, $opacity: 100);
	$link-text-color: oPrivateFoundationGet('o3-color-use-case-link-text');
	$link-contrasts-with-background: oPrivateColorsGetContrastRatio(
			$background,
			$link-text-color
		)
		> 4.5;
	// include oTopperColor on a parent then extend this placeholder on a
	// descendent to lend that descendent the color you specified in the mixin
	.o-topper__background,
	.o-topper__content {
		background-color: $background;
	}

	.o-topper__standfirst,
	.o-topper__summary {
		@if $link-contrasts-with-background {
			a {
				@include oPrivateTypographyLink();
			}
		} @else {
			a {
				$hover-color: darken($foreground, 20%);
				color: $foreground;
				border-bottom-color: $foreground;
				text-decoration-color: $foreground;

				&:hover {
					color: $hover-color;
					border-bottom-color: $hover-color;
					text-decoration-color: $hover-color;
				}
			}
		}
	}

	.o-topper__headline {
		&::after {
			border-bottom: 6px solid $foreground;
			@include oPrivateGridRespondTo($from: L) {
				border-bottom-width: 8px;
			}
		}
	}

	.o-topper__tags,
	.o-topper__columnist-name,
	.o-topper__headline,
	.o-topper__standfirst,
	.o-topper__summary,
	.o-topper__read-next {
		color: $foreground;
	}

	.o-topper__topic,
	.o-topper__brand {
		color: $foreground;

		&:hover {
			color: oPrivateColorsMix($foreground, $color-name, 73);
		}
	}

	.o-topper__image-caption {
		color: oPrivateColorsMix($foreground, $color-name, 73);
	}

	@if $color-name ==
		'o3-color-palette-paper' or
		$color-name ==
		'o3-color-palette-wheat'
	{
		.o-topper__opinion-genre,
		.o-topper__topic,
		.o-topper__columnist-name {
			$color: oPrivateFoundationGet('_o3-editorial-typography-topic-tag-color');
			color: oPrivateFoundationGet('_o3-editorial-typography-topic-tag-color');

			&:hover {
				color: oPrivateFoundationGet(
					'_o3-editorial-typography-topic-tag-hover-color'
				);
			}
		}
	}

	@if $color-name == 'o3-color-palette-sky' {
		.o-topper__tags,
		.o-topper__topic,
		.o-topper__columnist-name {
			color: oPrivateFoundationGet('o3-color-palette-oxford');

			&:hover {
				color: oPrivateFoundationGet('o3-color-palette-black-80');
			}
		}
	}

	@if $color-name == 'o3-color-palette-matisse-blue' {
		.o-topper__columnist-name {
			&:hover {
				color: oPrivateColorsMix($foreground, $color-name, 73);
			}
		}
		:focus-visible {
			outline-color: oPrivateFoundationGet('o3-color-palette-white');
		}
	}
}

@mixin _oTopperAlignText($position) {
	$mleft: (
		'left': 0,
		'center': auto,
		'right': auto,
	);
	$mright: (
		'left': auto,
		'center': auto,
		'right': 0,
	);
	$value: (
		'left': flex-start,
		'center': center,
		'right': flex-end,
	);

	.o-topper__headline--large {
		&:after {
			margin-left: map-get($mleft, #{$position});
			margin-right: map-get($mright, #{$position});
		}
	}

	.o-topper__content {
		text-align: $position;
		align-self: map-get($value, #{$position});
	}

	.o-topper__tags {
		justify-content: map-get($value, #{$position});
	}
}

@mixin _oTopperDefineOnce($label) {
	@if not map-has-key($_o-topper-defined, $label) {
		@content;
		$_o-topper-defined: map-merge(
			$_o-topper-defined,
			(
				$label: true,
			)
		) !global;
	}
}
