@use 'sass:math';
@use '../tokens/index.scss' as tokens;
@use '../mixins/index.scss' as mixins;

$quarter-widescreen: math.div(tokens.$breakpoint-widescreen, 4);
$half-widescreen: math.div(tokens.$breakpoint-widescreen, 2);
$three-quarters-widescreen: math.div(tokens.$breakpoint-widescreen, 4) * 3;
$default-flyout-width-desktop: 320px;
$default-flyout-width-widescreen: 480px;
$default-aside-min-width: 300px;
$eighth-widescreen: math.div(tokens.$breakpoint-widescreen, 8); // 225px
$five-eighths-widescreen: math.div(tokens.$breakpoint-widescreen, 8) * 5; // 1125px
$layout-menu-collapsed-width: 96px !default;

:root {
	--window-inner-height: 100vh; // to be overwritten by JS
	--atlas-header-height: 0px; // to be overwritten by JS
	--atlas-footer-height: 0px; // to be overwritten by JS
	--atlas-contained-height: 1fr; // default value, does not contain the height
}

.layout {
	display: flex;
	flex-direction: column;
	max-inline-size: 100vw;

	// --layout-gutter by default, see tokens/layout.scss
	#{tokens.$layout-gap-custom-property-name}: tokens.$layout-gap-narrow;
	#{tokens.$layout-gap-scalable-custom-property-name}: tokens.$layout-gap-narrow;

	#{tokens.$layout-flyout-width-desktop-custom-property-name}: $default-flyout-width-desktop;
	#{tokens.$layout-flyout-width-widescreen-custom-property-name}: $default-flyout-width-widescreen;
	#{tokens.$layout-flyout-width-name}: var(
		#{tokens.$layout-flyout-width-desktop-custom-property-name}
	);
	#{tokens.$layout-menu-collapsed-width-name}: $layout-menu-collapsed-width;
	#{tokens.$layout-menu-collapsed-width-widescreen-spacer-width-name}: calc(
		$quarter-widescreen - var(#{tokens.$layout-menu-collapsed-width-name})
	);

	@include mixins.desktop {
		#{tokens.$layout-gap-custom-property-name}: tokens.$layout-gap;
		#{tokens.$layout-gap-scalable-custom-property-name}: tokens.$layout-gap;
	}

	@include mixins.widescreen {
		#{tokens.$layout-gap-scalable-custom-property-name}: tokens.$layout-widescreen-gap;
		// sets widescreen custom prop
		#{tokens.$layout-flyout-width-name}: var(
			#{tokens.$layout-flyout-width-widescreen-custom-property-name}
		);
	}
}

.layout-padding {
	padding-inline: var(#{tokens.$layout-gap-custom-property-name}) !important;
}

.layout-margin {
	margin-inline: var(#{tokens.$layout-gap-scalable-custom-property-name}) !important;
}

@include mixins.tablet {
	.layout-padding-tablet {
		padding-inline: var(#{tokens.$layout-gap-custom-property-name}) !important;
	}

	.layout-margin-tablet {
		margin-inline: var(#{tokens.$layout-gap-scalable-custom-property-name}) !important;
	}
}

.layout-body {
	display: grid;
	width: 100%;
	max-width: 100%;
}

// grid-area values

.layout-body-header {
	grid-area: header;
}

.layout-body-hero {
	grid-area: hero;
}

.layout-body-menu {
	grid-area: menu;
}

.layout-body-main {
	grid-area: main;
}

.layout-body-aside {
	grid-area: aside;
}

.layout-body-footer {
	grid-area: footer;
}

.layout-body-flyout {
	display: none;
	grid-area: flyout;
}

.layout-body-hero,
.layout-body-main,
.layout-body-footer,
.layout-body-aside,
.layout-body-menu {
	&:empty {
		display: none;
	}
}

/* It is quite hard to keep the layout rules organized / group while satisfying the no-descrending specificity lint rule. Disabling it here. */

/* stylelint-disable */

.layout,
.layout.layout-single {
	.layout-body {
		grid-template: minmax(auto, max-content) auto auto 1fr auto auto / minmax(0, 1fr);
		grid-template-areas: 'header' 'hero' 'menu' 'main' 'aside' 'footer';
	}

	&.layout-flyout-active .layout-body {
		@include mixins.desktop {
			grid-template: minmax(auto, max-content) auto auto 1fr auto auto / minmax(0, 1fr) var(
					#{tokens.$layout-flyout-width-name}
				);
			grid-template-areas: 'header header' 'hero flyout' 'menu flyout' 'main flyout' 'aside flyout' 'footer footer';
		}
	}
}

.layout.layout-holy-grail {
	.layout-body {
		grid-template: minmax(auto, max-content) auto auto 1fr auto auto / minmax(0, 1fr);
		grid-template-areas: 'header' 'hero' 'menu' 'main' 'aside' 'footer';

		@include mixins.tablet {
			grid-template:
				minmax(auto, max-content) auto var(--atlas-contained-height) auto auto / minmax(0, 1fr)
				minmax(0, 2fr);
			grid-template-areas:
				'header header'
				'hero hero'
				'menu main'
				'menu aside'
				'footer footer';
		}

		@include mixins.desktop {
			grid-template:
				minmax(auto, max-content) auto var(--atlas-contained-height) auto / minmax(0, 1fr) minmax(
					0,
					2fr
				)
				minmax(0, 1fr);
			grid-template-areas:
				'header header header'
				'hero hero hero'
				'menu main aside'
				'footer footer footer';
		}

		@include mixins.widescreen {
			grid-template: minmax(auto, max-content) auto var(--atlas-contained-height) auto / auto #{$quarter-widescreen} #{$half-widescreen} #{$quarter-widescreen} auto;
			grid-template-areas:
				'header header header header header'
				'hero hero hero hero hero'
				'. menu main aside .'
				'footer footer footer footer footer';
		}
	}

	&.layout-menu-collapsed .layout-body {
		@include mixins.tablet {
			grid-template:
				minmax(auto, max-content) auto var(--atlas-contained-height) auto auto / var(
					#{tokens.$layout-menu-collapsed-width-name}
				)
				minmax(0, 1fr);
			grid-template-areas:
				'header header'
				'hero hero'
				'menu main'
				'menu aside'
				'footer footer';
		}

		@include mixins.desktop {
			grid-template:
				minmax(auto, max-content) auto var(--atlas-contained-height) auto / var(
					#{tokens.$layout-menu-collapsed-width-name}
				)
				minmax(0, 4fr)
				minmax(0, 23fr) minmax(0, 10fr);
			grid-template-areas:
				'header header header header'
				'hero hero hero hero'
				'menu . main aside'
				'footer footer footer footer';
		}

		@include mixins.widescreen {
			grid-template:
				minmax(auto, max-content) auto var(--atlas-contained-height) auto / minmax(0, auto) var(
					#{tokens.$layout-menu-collapsed-width-name}
				)
				minmax(0, var(#{tokens.$layout-menu-collapsed-width-widescreen-spacer-width-name}))
				$half-widescreen minmax(0, #{$quarter-widescreen}) minmax(0, auto);
			grid-template-areas:
				'header header header header header header'
				'hero hero hero hero hero hero'
				'. menu . main aside .'
				'footer footer footer footer footer footer';
		}
	}

	&.layout-flyout-active .layout-body {
		@include mixins.desktop {
			grid-template:
				auto auto var(--atlas-contained-height) auto / minmax(0, 1fr) minmax(0, 2fr) minmax(0, 1fr)
				var(#{tokens.$layout-flyout-width-name});
			grid-template-areas:
				'header header header header'
				'hero hero hero flyout'
				'menu main aside flyout'
				'footer footer footer footer';
		}

		@include mixins.widescreen {
			grid-template:
				auto auto var(--atlas-contained-height) auto / minmax(0, 1fr) minmax(0, 2fr) minmax(0, 1fr)
				var(#{tokens.$layout-flyout-width-name});
			grid-template-areas:
				'header header header header'
				'hero hero hero flyout'
				'menu main aside flyout'
				'footer footer footer footer';
		}
	}

	&.layout-flyout-active.layout-menu-collapsed .layout-body {
		@include mixins.desktop {
			grid-template:
				auto auto var(--atlas-contained-height) auto / var(
					#{tokens.$layout-menu-collapsed-width-name}
				)
				minmax(0, 2fr) minmax(0, 1fr)
				var(#{tokens.$layout-flyout-width-name});
			grid-template-areas:
				'header header header header'
				'hero hero hero flyout'
				'menu main aside flyout'
				'footer footer footer footer';
		}

		@include mixins.widescreen {
			grid-template:
				auto auto var(--atlas-contained-height) auto / var(
					#{tokens.$layout-menu-collapsed-width-name}
				)
				minmax(0, 2fr) minmax(0, 1fr)
				var(#{tokens.$layout-flyout-width-name});
			grid-template-areas:
				'header header header header'
				'hero hero hero flyout'
				'menu main aside flyout'
				'footer footer footer footer';
		}
	}
}

.layout.layout-sidecar-left {
	.layout-body-aside {
		display: none;
	}

	.layout-body {
		grid-template: minmax(auto, max-content) auto auto 1fr auto / minmax(0, 1fr);
		grid-template-areas: 'header' 'hero' 'menu' 'main' 'footer';

		@include mixins.tablet {
			grid-template:
				minmax(auto, max-content) auto var(--atlas-contained-height) auto / minmax(0, 1fr)
				minmax(0, 2fr);
			grid-template-areas:
				'header header'
				'hero hero'
				'menu main'
				'footer footer';
		}

		@include mixins.desktop {
			grid-template:
				minmax(auto, max-content) auto var(--atlas-contained-height) auto / minmax(0, 1fr)
				minmax(0, 3fr);
			grid-template-areas:
				'header header'
				'hero hero'
				'menu main'
				'footer footer';
		}

		@include mixins.widescreen {
			grid-template: minmax(auto, max-content) auto var(--atlas-contained-height) auto / auto #{$quarter-widescreen} #{$three-quarters-widescreen} auto;
			grid-template-areas:
				'header header header header'
				'hero hero hero hero'
				'. menu main .'
				'footer footer footer footer';
		}
	}

	&.layout-menu-collapsed .layout-body {
		@include mixins.tablet {
			grid-template:
				minmax(auto, max-content) auto var(--atlas-contained-height) auto / var(
					#{tokens.$layout-menu-collapsed-width-name}
				)
				minmax(0, 1fr);
			grid-template-areas:
				'header header'
				'hero hero'
				'menu main'
				'footer footer';
		}

		@include mixins.desktop {
			grid-template:
				minmax(auto, max-content) auto var(--atlas-contained-height) auto / var(
					#{tokens.$layout-menu-collapsed-width-name}
				)
				minmax(0, 4fr)
				minmax(0, 23fr) minmax(0, 10fr);
			grid-template-areas:
				'header header header header'
				'hero hero hero hero'
				'menu . main main'
				'footer footer footer footer';
		}

		@include mixins.widescreen {
			grid-template:
				minmax(auto, max-content) auto var(--atlas-contained-height) auto / minmax(0, auto) var(
					#{tokens.$layout-menu-collapsed-width-name}
				)
				minmax(0, var(#{tokens.$layout-menu-collapsed-width-widescreen-spacer-width-name}))
				#{$three-quarters-widescreen} minmax(0, auto);
			grid-template-areas:
				'header header header header header'
				'hero hero hero hero hero'
				'. menu . main .'
				'footer footer footer footer footer';
		}
	}

	&.layout-flyout-active .layout-body {
		@include mixins.desktop {
			grid-template:
				minmax(auto, max-content) auto var(--atlas-contained-height) auto / minmax(0, 1fr) minmax(
					0,
					3fr
				)
				var(#{tokens.$layout-flyout-width-name});
			grid-template-areas:
				'header header header'
				'hero hero flyout'
				'menu main flyout'
				'footer footer footer';
		}

		@include mixins.widescreen {
			grid-template:
				minmax(auto, max-content) auto var(--atlas-contained-height) auto / minmax(0, 1fr) minmax(
					0,
					3fr
				)
				var(#{tokens.$layout-flyout-width-name});
			grid-template-areas:
				'header header header'
				'hero hero flyout'
				'menu main flyout'
				'footer footer footer';
		}
	}

	&.layout-flyout-active.layout-menu-collapsed .layout-body {
		@include mixins.desktop {
			grid-template:
				auto auto var(--atlas-contained-height) auto / var(
					#{tokens.$layout-menu-collapsed-width-name}
				)
				minmax(0, 1fr)
				var(#{tokens.$layout-flyout-width-name});
			grid-template-areas:
				'header header header'
				'hero hero flyout'
				'menu main flyout'
				'footer footer footer';
		}

		@include mixins.widescreen {
			grid-template:
				auto auto var(--atlas-contained-height) auto / var(
					#{tokens.$layout-menu-collapsed-width-name}
				)
				minmax(0, var(#{tokens.$layout-menu-collapsed-width-widescreen-spacer-width-name}))
				minmax(0, 1fr)
				var(#{tokens.$layout-flyout-width-name});
			grid-template-areas:
				'header header header header'
				'hero hero hero flyout'
				'menu . main flyout'
				'footer footer footer footer';
		}
	}
}

.layout.layout-sidecar-right {
	.layout-body-menu {
		display: none;
	}

	.layout-body {
		grid-template: minmax(auto, max-content) auto auto 1fr auto / minmax(0, 1fr);
		grid-template-areas: 'header' 'hero' 'main' 'aside' 'footer';

		@include mixins.tablet {
			grid-template:
				minmax(auto, max-content) auto var(--atlas-contained-height) auto / minmax(0, 2fr)
				minmax(0, 1fr);
			grid-template-areas:
				'header header'
				'hero hero'
				'main aside '
				'footer footer';
		}

		@include mixins.desktop {
			grid-template:
				minmax(auto, max-content) auto var(--atlas-contained-height) auto / minmax(0, 3fr)
				minmax(0, 1fr);
			grid-template-areas:
				'header header'
				'hero hero'
				'main aside'
				'footer footer';
		}

		@include mixins.widescreen {
			grid-template: minmax(auto, max-content) auto var(--atlas-contained-height) auto / auto #{$three-quarters-widescreen} #{$quarter-widescreen} auto;
			grid-template-areas:
				'header header header header'
				'hero hero hero hero'
				'. main aside .'
				'footer footer footer footer';
		}
	}

	&.layout-flyout-active .layout-body {
		@include mixins.desktop {
			grid-template:
				minmax(auto, max-content) auto var(--atlas-contained-height) auto / minmax(0, 3fr) minmax(
					0,
					1fr
				)
				var(#{tokens.$layout-flyout-width-name});
			grid-template-areas:
				'header header header'
				'hero hero flyout'
				'main aside flyout'
				'footer footer footer';
		}

		@include mixins.widescreen {
			grid-template:
				minmax(auto, max-content) auto var(--atlas-contained-height) auto / minmax(0, 3fr) minmax(
					0,
					1fr
				)
				var(#{tokens.$layout-flyout-width-name});
			grid-template-areas:
				'header header header'
				'hero hero flyout'
				'main aside flyout'
				'footer footer footer';
		}
	}
}

.layout.layout-twin {
	.layout-body-menu {
		display: none;
	}

	.layout-body {
		grid-template: minmax(auto, max-content) auto auto 1fr auto / minmax(0, 1fr);
		grid-template-areas: 'header' 'hero' 'main' 'aside' 'footer';

		// note that to make some extra room this layout is not constrained by the widescreen breakpoint like others
		@include mixins.tablet {
			grid-template:
				minmax(auto, max-content) auto var(--atlas-contained-height) auto / minmax(0, 1fr)
				minmax(0, 1fr);
			grid-template-areas:
				'header header'
				'hero hero'
				'main aside'
				'footer footer';
		}
	}

	&.layout-flyout-active .layout-body {
		@include mixins.desktop {
			grid-template:
				minmax(auto, max-content) auto var(--atlas-contained-height) auto / minmax(0, 1fr) minmax(
					0,
					1fr
				)
				var(#{tokens.$layout-flyout-width-name});
			grid-template-areas:
				'header header header'
				'hero hero flyout'
				'main aside flyout'
				'footer footer footer';
		}
	}
}

@mixin constrained-layout-child {
	position: sticky;
	inset-block-start: 0;
	overflow: hidden auto;
	-webkit-overflow-scrolling: touch;
}

// hide flyout when it's inactive

@include mixins.desktop {
	.layout.layout-flyout-active {
		.layout-body-flyout {
			display: block;
		}
	}
}

@include mixins.tablet {
	.layout.layout-constrained {
		&.layout-twin,
		&.layout-sidecar-left,
		&.layout-sidecar-right {
			--atlas-contained-height: calc(
				var(--window-inner-height) - var(--atlas-header-height) - var(--atlas-footer-height) - 1px
			);
		}

		&.layout-twin,
		&.layout-sidecar-right {
			.layout-body-main,
			.layout-body-aside {
				@include constrained-layout-child;
			}
		}

		&.layout-sidecar-left {
			.layout-body-menu,
			.layout-body-main {
				@include constrained-layout-child;
			}
		}
	}
}

// Because the holy grail has two rows (containing menu main, menu aside) on tablet, we cannot apply height constraints at that size
@include mixins.desktop {
	.layout.layout-constrained.layout-holy-grail {
		--atlas-contained-height: calc(
			var(--window-inner-height) - var(--atlas-header-height) - var(--atlas-footer-height) - 1px
		);

		.layout-body-main,
		.layout-body-menu,
		.layout-body-aside {
			@include constrained-layout-child;
		}
	}

	.layout.layout-constrained {
		.layout-body-flyout {
			@include constrained-layout-child;
		}
	}
}

/* stylelint-enable */
