/* ==========================================================================
   PDF VIEWER

   Two trees to style, and the split matters:

     1. The LIGHT DOM - the slotted heading and the slotted link row, both
        written by instance.mvt. Styled by plain class selectors, because this
        stylesheet is in the real page head. Nothing here uses ::slotted(): for
        a slotted element the outer document's rules beat the shadow tree's
        ::slotted rules at equal specificity, so geometry declared in both
        places silently loses.

     2. The SHADOW ROOT - the panel, stage, canvas, arrows, dots and counter,
        all rendered by the component. Styled by :host and part selectors.

   Every layout choice arrives as a literal attribute on the host, resolved
   once in instance.mvt: alignment, placement, direction, distribution and both
   arrow glyphs. A rule here maps one literal to one declaration. The CSS never
   works out a combination, which is what keeps it from disagreeing with the
   template or the JS.
   ========================================================================== */

:host {
	display: block;
}

.pdf-viewer {
	margin-inline: auto;
	max-width: var(--pdf-viewer__max-width, none);
	padding: var(--pdf-viewer__padding, 0);
}

/* Full Browser Width.

   Removing the max-width is not enough, and that is why the setting appeared to do
   nothing: the component sits inside the theme's centred content column, so with no
   cap of its own it simply fills that column instead of the viewport.

   calc(50% - 50vw) is the escape. Each side gets a negative margin equal to the
   distance from the column's edge to the viewport's edge, so the box grows to the
   full width of the window from wherever it happens to sit. No width declaration and
   no wrapper to reach for - which matters, because a component cannot restyle its
   own ancestors.

   One caveat that belongs to the technique rather than to this component: vw includes
   the scrollbar, so on a page that has no vertical scrollbar this can overshoot by a
   few pixels. If that shows, overflow-x: hidden on the page wrapper settles it. */

:host([data-full-width="1"]) .pdf-viewer {
	margin-inline: calc( 50% - 50vw );
	max-width: none;
}


/* The panel
   ========================================================================== */

[part~="panel"] {
	background-color: var(--pdf-viewer__panel-background, #f5f5f5);
	border-radius: var(--pdf-viewer__panel-radius, 0);
	padding: var(--pdf-viewer__panel-padding, 0);
}


/* The heading
   ==========================================================================
   The heading area exists in the shadow tree in one of two positions - inside
   the panel or above it - and render() emits only the one the placement asks
   for. Two positions rather than one moved by CSS, because "inside the panel"
   means inside its background and its padding, which no amount of ordering can
   fake from outside.

   text-align rather than a flex alignment: the heading is a single block, and
   text-align inherits across the shadow boundary into mmx-text's own shadow
   root, which is where the words are. */

[part~="heading-area"] {
	margin-bottom: var(--pdf-viewer__heading-gap, 0px);
}

:host([data-heading-align="left"]) [part~="heading-area"] { text-align: left; }
:host([data-heading-align="center"]) [part~="heading-area"] { text-align: center; }
:host([data-heading-align="right"]) [part~="heading-area"] { text-align: right; }

/* The background belongs to the heading itself, not to its area, or a centred
   heading would sit on a full-width band instead of a fitted one. inline-block
   so the box is the width of the words and still follows the text-align above. */

.pdf-viewer__heading {
	background-color: var(--pdf-viewer__heading-background, transparent);
	border-radius: var(--pdf-viewer__heading-radius, 0);
	display: inline-block;
	margin: 0;
	padding: var(--pdf-viewer__heading-padding, 0);
}


/* The stage: page plus arrows
   ==========================================================================
   Three placements, and each is a different axis, so each gets its own rule
   rather than one rule with overrides. */

[part~="stage"] {
	align-items: center;
	display: flex;
	gap: var(--pdf-viewer__arrow-gap, 16px);
	justify-content: center;
}

[part~="stage"]:focus-visible {
	outline: 2px solid var(--pdf-viewer__arrow-color, #999999);
	outline-offset: 4px;
}

:host([data-arrow-placement="sides"]) [part~="stage"] {
	flex-direction: row;
}

/* Below and above put the arrows in a row UNDER or OVER the page.

   WRAPPING, not a column. A column direction gives every child its own line, so the
   two arrows ended up stacked one above the other with the page above them - which is
   what made this look wrong in those modes and on phones.

   Instead the row keeps its direction and the PAGE is given a full-width basis. That
   forces a break after it, and the two arrows, which are auto-width, land together on
   the next line and can be centred as a pair. */

:host([data-arrow-placement="below"]) [part~="stage"],
:host([data-arrow-placement="above"]) [part~="stage"] {
	flex-direction: row;
	flex-wrap: wrap;
}

:host([data-arrow-placement="below"]) [part~="page"],
:host([data-arrow-placement="above"]) [part~="page"] {
	flex: 0 0 100%;
}

:host([data-arrow-placement="below"]) [part~="page"] { order: 1; }
:host([data-arrow-placement="below"]) [part~="arrow--previous"] { order: 2; }
:host([data-arrow-placement="below"]) [part~="arrow--next"] { order: 3; }

:host([data-arrow-placement="above"]) [part~="arrow--previous"] { order: 1; }
:host([data-arrow-placement="above"]) [part~="arrow--next"] { order: 2; }
:host([data-arrow-placement="above"]) [part~="page"] { order: 3; }

/* The arrows are the ones that must NOT take a full basis, or they would each claim a
   line of their own again. */

:host([data-arrow-placement="below"]) [part~="arrow"],
:host([data-arrow-placement="above"]) [part~="arrow"] {
	flex: 0 0 auto;
}


/* The page and canvas
   ==========================================================================
   The canvas is sized in the JS: its width and height attributes are the
   device-pixel size for sharpness, and its CSS width is the layout size. Only
   the height is declared here, and only as a maximum, so a tall page scales
   down to fit rather than overflowing the panel. */

[part~="page"] {
	background-color: var(--pdf-viewer__page-background, #ffffff);
	box-shadow: var(--pdf-viewer__page-shadow, none);
	line-height: 0;
	max-width: 100%;
	position: relative;
}

[part~="canvas"] {
	display: block;
	height: auto;
	max-height: var(--pdf-viewer__page-height, 720px);
	max-width: 100%;
}

:host([data-fit="width"]) [part~="page"] {
	width: 100%;
}

:host([data-fit="width"]) [part~="canvas"] {
	max-height: none;
	width: 100%;
}

/* The status line sits over the page rather than in the flow, so a message
   appearing or clearing cannot change the layout - which would otherwise shift
   the whole component every time a page loads. */

[part~="status"] {
	align-items: center;
	display: flex;
	inset: 0;
	justify-content: center;
	line-height: 1.4;
	padding: 2rem;
	position: absolute;
	text-align: center;
}

[part~="status"]:empty {
	display: none;
}


/* Arrows
   ========================================================================== */

[part~="arrow"] {
	align-items: center;
	background: none;
	border: 0;
	color: var(--pdf-viewer__arrow-color, #999999);
	cursor: pointer;
	display: flex;
	flex: 0 0 auto;
	font-size: var(--pdf-viewer__arrow-size, 40px);
	justify-content: center;
	line-height: 1;
	padding: 0;
}

[part~="arrow"]:disabled {
	cursor: default;
	opacity: 0.3;
}

[part~="arrow"]:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 4px;
}


/* Counter and dots
   ========================================================================== */

[part~="counter"] {
	color: var(--pdf-viewer__arrow-color, #999999);
	font-size: 0.875rem;
	margin-top: 0.75rem;
	text-align: center;
}

[part~="dots"] {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	justify-content: center;
	margin-top: 1rem;
}

[part~="dot"] {
	background: var(--pdf-viewer__arrow-color, #999999);
	border: 0;
	border-radius: 50%;
	cursor: pointer;
	height: 0.5rem;
	opacity: 0.35;
	padding: 0;
	width: 0.5rem;
}

[part~="dot"][aria-current="true"] {
	opacity: 1;
}


/* The link row
   ==========================================================================
   Light DOM, so plain classes reach it.

   Two independent controls, on two different axes, which is why they cannot
   share a rule: Layout picks the axis, Distribution picks how the items sit
   along it. Distribution arrives already resolved - "Follow the Alignment"
   became left, center or right in the template, and the space-* keywords pass
   through untouched. */

.pdf-viewer__links {
	display: flex;
	flex-wrap: wrap;
	gap: var(--pdf-viewer__links-gap, 24px);
	margin-top: var(--pdf-viewer__links-top-gap, 16px);
}

[data-links-direction="row"] .pdf-viewer__links { flex-direction: row; }
[data-links-direction="stacked"] .pdf-viewer__links { flex-direction: column; }

/* Side by side: the items sit along the main axis, so this is justify-content.
   left / center / right are real keywords for justify-content, unlike
   align-items, so the resolved value maps straight through. */

[data-links-direction="row"][data-links-justify="left"] .pdf-viewer__links { justify-content: flex-start; }
[data-links-direction="row"][data-links-justify="center"] .pdf-viewer__links { justify-content: center; }
[data-links-direction="row"][data-links-justify="right"] .pdf-viewer__links { justify-content: flex-end; }
[data-links-direction="row"][data-links-justify="space-between"] .pdf-viewer__links { justify-content: space-between; }
[data-links-direction="row"][data-links-justify="space-around"] .pdf-viewer__links { justify-content: space-around; }
[data-links-direction="row"][data-links-justify="space-evenly"] .pdf-viewer__links { justify-content: space-evenly; }

/* Stacked: the items sit across the cross axis, so this is align-items - and
   align-items has no left or right keyword, which is the whole reason the
   template resolves alignment to a literal for the CSS to translate here. */

[data-links-direction="stacked"][data-links-align="left"] .pdf-viewer__links { align-items: flex-start; }
[data-links-direction="stacked"][data-links-align="center"] .pdf-viewer__links { align-items: center; }
[data-links-direction="stacked"][data-links-align="right"] .pdf-viewer__links { align-items: flex-end; }

.pdf-viewer__link {
	align-items: baseline;
	color: var(--pdf-viewer__link-color, inherit);
	display: inline-flex;
	gap: 0.4em;
	text-decoration: var(--pdf-viewer__link-decoration, none);
}

/* Bold steps aside for a theme. A typography carries its own weight, and the Bold toggle defaults
   to on for the first link, so without this guard every themed link would be forced to 700 - the
   same half-applied-guard mistake that stopped the carousel flag from ever taking a typography. */

.pdf-viewer__link[data-emphasis]:not([data-theme]) {
	font-weight: 700;
}

/* An arrow before the label rather than after it, for a left-pointing one. The
   glyph is a separate element so the gap is a real gap and not a space that a
   text transform or a font could swallow. */

.pdf-viewer__link[data-arrow-first] {
	flex-direction: row;
}

.pdf-viewer__link-arrow {
	flex: 0 0 auto;
	text-decoration: none;
}

a.pdf-viewer__link:hover,
a.pdf-viewer__link:focus-visible {
	text-decoration: underline;
}


/* Phones
   ==========================================================================
   Arrows either side of the page stop working on a narrow screen: two 40px
   controls plus the page cannot share the width, so the page shrinks to
   nothing. Below the page instead, which is the same arrangement the Below
   setting produces - and the link row stacks, because two labels this long do
   not sit side by side at this width whatever the distribution says. */

@media ( max-width: 47.9375em ) {

	/* Arrows either side of the page cannot work here: two controls plus the page
	   cannot share a phone's width, and the page ends up squeezed to nothing. They
	   move under it - by wrapping, for the reason given above, so the pair sits on one
	   line rather than one each. */

	:host([data-arrow-placement="sides"]) [part~="stage"] {
		flex-wrap: wrap;
	}

	:host([data-arrow-placement="sides"]) [part~="page"] {
		flex: 0 0 100%;
		order: 1;
	}

	:host([data-arrow-placement="sides"]) [part~="arrow--previous"] { order: 2; }
	:host([data-arrow-placement="sides"]) [part~="arrow--next"] { order: 3; }

	:host([data-arrow-placement="sides"]) [part~="arrow"] {
		flex: 0 0 auto;
	}

	/* Everything scales back. A 40px arrow and 24px of panel padding are proportionate
	   on a desktop and take a quarter of the width on a phone. */

	[part~="stage"] {
		gap: 0.75rem;
	}

	[part~="arrow"] {
		font-size: clamp( 1.5rem, 8vw, var(--pdf-viewer__arrow-size, 40px) );
	}

	[part~="panel"] {
		padding: clamp( 0.75rem, 4vw, 2.5rem );
	}

	[part~="status"] {
		padding: 1rem;
	}

	/* The link row stacks whatever the Distribution says - two labels this long do not
	   sit side by side at this width - and the gap comes down with it, because 24px
	   between two stacked lines reads as a paragraph break rather than a list. */

	[data-links-direction="row"] .pdf-viewer__links {
		flex-direction: column;
		gap: 0.75rem;
	}

	[data-links-direction="row"][data-links-align="left"] .pdf-viewer__links { align-items: flex-start; }
	[data-links-direction="row"][data-links-align="center"] .pdf-viewer__links { align-items: center; }
	[data-links-direction="row"][data-links-align="right"] .pdf-viewer__links { align-items: flex-end; }

	.pdf-viewer__links {
		margin-top: 0.75rem;
	}

}
