/*
Theme Name:   Playpoi
Theme URI:    https://playpoi.com
Description:  Playpoi's own theme layer, built as a child of GeneratePress. Holds the site's custom post type templates (learn, inspiration, gear, courses, premium_courses, testimonials) and the Playpoi visual identity. The parent theme supplies the maintained foundation — clean markup, responsiveness, accessibility — so the only code maintained here is what is genuinely Playpoi-specific.
Author:       Playpoi
Template:     generatepress
Version:      0.30.0
License:      GNU General Public License v2 or later
License URI:  http://www.gnu.org/licenses/gpl-2.0.html
Text Domain:  playpoi
*/

/* ------------------------------------------------------------------
   Brand tokens — taken from the live site's computed styles and the
   old theme's active red.css, recorded in playpoi_theme_archaeology.
   These are the identity: red accent on clean white, squared buttons.
   ------------------------------------------------------------------ */

:root {
	--pp-red:        #df1d25; /* links */
	--pp-red-button: #e42d3f; /* buttons */
	--pp-orange:     #f59017; /* secondary accent, used sparingly */
	--pp-text:       #656565;
	--pp-text-dark:  #555555;

	/* Type: Montserrat for body copy and navigation, Raleway for headings —
	   what playpoi.com serves, measured 2026-08-14. The webfonts are loaded in
	   functions.php with display=swap; the system faces below stay as the
	   fallback for the moment before they arrive. */
	--pp-font-body: Montserrat, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

body {
	font-family: var(--pp-font-body);
	color: var(--pp-text);
}

a {
	color: var(--pp-red);
}

a:hover,
a:focus {
	color: var(--pp-red-button);
}

/* Squared, confident buttons — an era tell worth keeping through the facelift.
   Spacing and type scale get modernized in the design pass; the shape stays. */
.button,
button,
input[type="button"],
input[type="submit"],
.wp-block-button__link {
	background-color: var(--pp-red-button);
	color: #ffffff;
	border-radius: 0;
}

.button:hover,
button:hover,
input[type="button"]:hover,
input[type="submit"]:hover,
.wp-block-button__link:hover {
	background-color: var(--pp-red);
	color: #ffffff;
}

/* ------------------------------------------------------------------
   Footer menu — scaffold styling only.
   ------------------------------------------------------------------ */

.playpoi-footer-menu ul {
	display: flex;
	flex-wrap: wrap;
	gap: 1rem 1.5rem;
	justify-content: center;
	margin: 0;
	padding: 0;
	list-style: none;
}

.playpoi-footer-menu a {
	text-decoration: none;
}


/* ------------------------------------------------------------------
   Tutorial videos (Phase 3).
   The stored embeds carry fixed pixel dimensions, so the ratio box is
   what makes them responsive. Rendered as iframes rather than as CSS
   backgrounds, per the rebuild's image-delivery constraint.
   ------------------------------------------------------------------ */

.playpoi-video {
	position: relative;
	aspect-ratio: 16 / 9;
	margin: 0 0 1.5rem;
	background-color: #000;
}

.playpoi-video iframe {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
}

/* ------------------------------------------------------------------
   Archive grids (Phase 3b).
   ------------------------------------------------------------------ */

.playpoi-video-thumb img {
	width: 100%;
	height: auto;
	display: block;
}

.playpoi-term-filter {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin: 0 0 2rem;
}

.playpoi-term-filter .playpoi-term {
	display: inline-block;
	padding: 0.35em 0.9em;
	border: 1px solid var(--pp-red);
	border-radius: 2em;
	color: var(--pp-red);
	font-size: 0.875rem;
	line-height: 1.4;
	text-decoration: none;
}

.playpoi-term-filter .playpoi-term:hover,
.playpoi-term-filter .playpoi-term:focus,
.playpoi-term-filter .playpoi-term.is-current {
	background-color: var(--pp-red);
	color: #ffffff;
}

/* ------------------------------------------------------------------
   Archive grid (Phase 3c).

   The old theme laid tutorials out in a multi-column grid; GeneratePress
   defaults to a single-column list, which stretched a 320px video still
   across 740px. Restoring the grid restores the layout AND resolves the
   blur, since each cell is now close to the thumbnail's native width.

   Scoped by the body classes WordPress already sets, so no PHP is needed.
   The image is ordered above the title, as it was in the old grid.
   ------------------------------------------------------------------ */

body.post-type-archive-learn .site-main,
body.post-type-archive-inspiration .site-main,
body.post-type-archive-gear .site-main,
body.tax-learn-categories .site-main,
body.tax-inspiration-categories .site-main,
body.tax-gear-categories .site-main {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
	gap: 2.5rem 2rem;
	align-items: start;
}

/* Full-width rows inside the grid: page title, category filter, pagination. */
body.post-type-archive-learn .site-main > .page-header,
body.post-type-archive-inspiration .site-main > .page-header,
body.post-type-archive-gear .site-main > .page-header,
body.tax-learn-categories .site-main > .page-header,
body.tax-inspiration-categories .site-main > .page-header,
body.tax-gear-categories .site-main > .page-header,
body.post-type-archive-learn .site-main > .playpoi-term-filter,
body.post-type-archive-inspiration .site-main > .playpoi-term-filter,
body.post-type-archive-gear .site-main > .playpoi-term-filter,
body.tax-learn-categories .site-main > .playpoi-term-filter,
body.tax-inspiration-categories .site-main > .playpoi-term-filter,
body.tax-gear-categories .site-main > .playpoi-term-filter,
body.post-type-archive-learn .site-main > .paging-navigation,
body.post-type-archive-inspiration .site-main > .paging-navigation,
body.post-type-archive-gear .site-main > .paging-navigation,
body.tax-learn-categories .site-main > .paging-navigation,
body.tax-inspiration-categories .site-main > .paging-navigation,
body.tax-gear-categories .site-main > .paging-navigation {
	grid-column: 1 / -1;
}

/* Image above title, as the old grid had it. */
body.post-type-archive-learn .site-main > article > .inside-article,
body.post-type-archive-inspiration .site-main > article > .inside-article,
body.post-type-archive-gear .site-main > article > .inside-article,
body.tax-learn-categories .site-main > article > .inside-article,
body.tax-inspiration-categories .site-main > article > .inside-article,
body.tax-gear-categories .site-main > article > .inside-article {
	display: flex;
	flex-direction: column;
	height: 100%;
	margin: 0;
}

body.post-type-archive-learn .site-main > article .post-image,
body.post-type-archive-inspiration .site-main > article .post-image,
body.post-type-archive-gear .site-main > article .post-image,
body.tax-learn-categories .site-main > article .post-image,
body.tax-inspiration-categories .site-main > article .post-image,
body.tax-gear-categories .site-main > article .post-image {
	order: -1;
	margin: 0 0 0.75rem;
}

body.post-type-archive-learn .site-main > article .entry-title,
body.post-type-archive-inspiration .site-main > article .entry-title,
body.post-type-archive-gear .site-main > article .entry-title,
body.tax-learn-categories .site-main > article .entry-title,
body.tax-inspiration-categories .site-main > article .entry-title,
body.tax-gear-categories .site-main > article .entry-title {
	font-size: 1.25rem;
	line-height: 1.3;
	margin-bottom: 0.5rem;
}

/* Archive images fill their cell; the featured-image path needs this too. */
body.post-type-archive-learn .site-main > article .post-image img,
body.post-type-archive-inspiration .site-main > article .post-image img,
body.post-type-archive-gear .site-main > article .post-image img,
body.tax-learn-categories .site-main > article .post-image img,
body.tax-inspiration-categories .site-main > article .post-image img,
body.tax-gear-categories .site-main > article .post-image img {
	width: 100%;
	height: auto;
	aspect-ratio: 16 / 9;
	object-fit: cover;
	display: block;
}

/* ------------------------------------------------------------------
   Gallery and related content (Phase 3d).
   ------------------------------------------------------------------ */

.playpoi-gallery {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
	gap: 1rem;
	margin: 2rem 0;
}

.playpoi-gallery-item {
	margin: 0;
}

.playpoi-gallery-item img {
	width: 100%;
	height: auto;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	display: block;
}

.playpoi-gallery-item figcaption {
	font-size: 0.85rem;
	margin-top: 0.4rem;
}

.playpoi-related {
	margin: 2.5rem 0 0;
}

.playpoi-related ul {
	list-style: none;
	margin: 0;
	padding: 0;
}

.playpoi-related li {
	margin-bottom: 0.4rem;
}

.playpoi-related-type {
	font-size: 0.8rem;
	color: var(--pp-text);
	text-transform: lowercase;
}

/* ------------------------------------------------------------------
   Homepage (Phase 4).
   ------------------------------------------------------------------ */

.playpoi-welcome {
	text-align: center;
	margin: 0 0 3rem;
}

.playpoi-home-section {
	margin: 0 0 3rem;
	padding: 2rem 0;
}

.playpoi-home-section.is-alt {
	background-color: #f5f5f5;
}

/* The header rule threads between the title and "View more" — live's hr-title
   treatment: one line at mid-height with both texts sitting on it, knocked out
   over the section's own background so the line reads as connecting them. */
.playpoi-home-section-head {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 0.5rem 1rem;
	position: relative;
	margin-bottom: 1.5rem;
}

.playpoi-home-section-head::before {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	top: 50%;
	border-top: 1px solid #bbb;
}

.playpoi-home-section-head h2 {
	margin: 0;
	font-size: 1.5rem;
	position: relative;
	background: #fff;
	padding-right: 12px;
}

.playpoi-home-section-head h2 a {
	color: inherit;
	text-decoration: none;
}

.playpoi-view-more {
	color: var(--pp-red);
	font-size: 0.9rem;
	text-decoration: none;
	position: relative;
	background: #fff;
	padding-left: 12px;
}

/* Knockouts match the alternating band. */
.playpoi-home-section.is-alt .playpoi-home-section-head h2,
.playpoi-home-section.is-alt .playpoi-view-more {
	background: #f5f5f5;
}

.playpoi-card-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
	gap: 1.5rem;
}

.playpoi-card {
	display: flex;
	flex-direction: column;
}

.playpoi-card-image img {
	width: 100%;
	height: auto;
	aspect-ratio: 16 / 9;
	object-fit: cover;
	display: block;
}

.playpoi-card-title {
	font-size: 1.05rem;
	line-height: 1.3;
	margin: 0.6rem 0 0.4rem;
}

.playpoi-card-title a {
	color: inherit;
	text-decoration: none;
}

.playpoi-card-excerpt {
	font-size: 0.9rem;
	margin: 0;
}

/* ------------------------------------------------------------------
   Featured tiles (Phase 4b) — replaces the old hero carousel.
   Every enabled slide is visible at once, so no link waits its turn.
   ------------------------------------------------------------------ */

.playpoi-tiles {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( 240px, 1fr ) );
	gap: 1.25rem;
	margin: 0 0 3rem;
}

.playpoi-tile {
	display: flex;
	flex-direction: column;
	background-color: #ffffff;
	border: 1px solid #e6e6e6;
	border-radius: 4px;
	overflow: hidden;
	text-decoration: none;
	color: var( --pp-text-dark );
	transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.playpoi-tile:hover,
.playpoi-tile:focus-visible {
	transform: translateY( -2px );
	box-shadow: 0 6px 18px rgba( 0, 0, 0, 0.12 );
}

/* Imagify wraps images in <picture> and carries the class onto the wrapper, so
   the sizing has to be stated for both the wrapper and the inner <img>. */
.playpoi-tile-image {
	display: block;
	width: 100%;
}

.playpoi-tile-image img,
img.playpoi-tile-image {
	width: 100%;
	height: auto;
	aspect-ratio: 16 / 9;
	object-fit: cover;
	display: block;
}

.playpoi-tile-body {
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
	flex: 1;
	padding: 1rem;
}

.playpoi-tile-title {
	font-size: 1.1rem;
	font-weight: 700;
	line-height: 1.25;
	color: var( --pp-text-dark );
}

.playpoi-tile-text {
	font-size: 0.9rem;
	color: var( --pp-text );
	flex: 1;
}

.playpoi-tile-cta {
	align-self: flex-start;
	margin-top: 0.5rem;
	padding: 0.45em 1.1em;
	border-radius: 2em;
	background-color: var( --pp-red-button );
	color: #ffffff;
	font-size: 0.875rem;
	font-weight: 600;
}

.playpoi-tile-cta.is-orange {
	background-color: var( --pp-orange );
}

.playpoi-tile:hover .playpoi-tile-cta,
.playpoi-tile:focus-visible .playpoi-tile-cta {
	background-color: var( --pp-red );
}

/* The front page carries the site's identity in the header and tiles, not in a
   heading that reads 'Homepage'. Hidden visually rather than removed, so the page
   keeps one h1 for document structure and screen readers. */

body.home .page-header .entry-title,
body.home .entry-header .entry-title {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect( 0, 0, 0, 0 );
	white-space: nowrap;
	border: 0;
}

/* ------------------------------------------------------------------
   Typography (Phase 5).

   Measured on playpoi.com 2026-08-14: Montserrat carries body copy and
   navigation, Raleway carries headings at weight 700 — the homepage welcome
   heading being the one live exception, set light at 300. The webfonts are
   loaded in functions.php; this section only assigns them.

   Body size stays at the parent theme's 17px rather than the live site's 14px.
   Reproducing 14px would carry over a readability problem the rebuild's
   accessibility criterion asks us to improve on, and size is not what makes
   the site recognizable — the faces and the red are.
   ------------------------------------------------------------------ */

:root {
	--pp-font-heading: Raleway, Montserrat, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

h1,
h2,
h3,
h4,
h5,
h6,
.entry-title {
	font-family: var(--pp-font-heading);
	font-weight: 700;
}

.playpoi-welcome h2 {
	font-weight: 300;
}

/* playpoi.com lowercases its navigation in CSS. The menu items themselves are
   typed with mixed capitals, so without the transform the menu reads
   "About Learn Inspiration gear reviews blog" — capitalized wherever someone
   happened to type a capital. */

.main-navigation a,
.main-navigation .menu-toggle {
	font-family: var(--pp-font-body);
	font-weight: 700;
	text-transform: lowercase;
}


/* ------------------------------------------------------------------
   Type scale and reading measure (Phase 5, design pass).

   Two changes, both about reading rather than appearance.

   1. Measure. Removing the empty sidebar gave article text the full 1200px
      container, which put tutorial copy at roughly 132 characters a line at
      17px. Comfortable reading sits between 45 and 85. Capping the text at
      62ch fixes that (Montserrat's zero is wide, so 62ch measures out near 80
      characters); video, gallery and related-content blocks opt back out,
      since those are not read line by line.

   2. Scale. GeneratePress ships larger headings than this site had (h1 42px
      against live's 32px). Live's scale was built around 14px body text and
      reads tight against 17px, so this sits between the two rather than
      matching either. Set in rem so the whole scale moves together.

   Elementor pages are excluded: their layouts set their own widths, and
   constraining them here would fight the builder.
   ------------------------------------------------------------------ */

body.single:not(.elementor-page) .entry-content > * {
	max-width: 62ch;
}

body.single:not(.elementor-page) .entry-content > .playpoi-video,
body.single:not(.elementor-page) .entry-content > .playpoi-gallery,
body.single:not(.elementor-page) .entry-content > .playpoi-related,
body.single:not(.elementor-page) .entry-content > figure,
body.single:not(.elementor-page) .entry-content > .wp-block-image {
	/* Wider than the text column, but not the whole container: at full width a
	   16:9 embed stands over 600px tall and swallows the page. 900px is what the
	   live site gives a tutorial video. */
	max-width: 900px;
}

h1,
.entry-title {
	font-size: 2.125rem;
	line-height: 1.2;
}

h2 {
	font-size: 1.75rem;
	line-height: 1.25;
}

h3 {
	font-size: 1.5rem;
	line-height: 1.3;
}

h4 {
	font-size: 1.25rem;
	line-height: 1.35;
}


/* ------------------------------------------------------------------
   Vertical rhythm (Phase 5).

   Measured on the homepage before this block: 94px of stacked space between
   the header and the first tile, from three unrelated sources — a 20px
   container margin, 40px of article padding, and a 34px margin GeneratePress
   adds to separate the content from an entry header that is hidden here.
   Then 48px under the tiles and 16px of padding inside every card.

   None of it was chosen; it is the sum of defaults. Tightened so the page
   opens on content rather than on empty space.
   ------------------------------------------------------------------ */

/* The entry header is hidden on the front page, so this margin separates the
   content from nothing. */
body.home .entry-content {
	margin-top: 0;
}

body.home .inside-article {
	padding-top: 1.5rem;
	padding-bottom: 1.5rem;
}

.playpoi-tiles {
	gap: 1rem;
	margin-bottom: 2rem;
}

.playpoi-tile-body {
	gap: 0.3rem;
	padding: 0.85rem 1rem 1rem;
}

.playpoi-home-section {
	margin-bottom: 2rem;
	padding: 1.25rem 0;
}

.playpoi-home-section-head {
	margin-bottom: 1rem;
}

.playpoi-welcome {
	margin-bottom: 2rem;
}


/* ------------------------------------------------------------------
   Archive header (Phase 5).

   The category description is prose and wants the same measure article text
   gets; at the full 1120px it ran past 130 characters a line. The gap between
   the filter row and the first card was 72px — the filter's own 32px margin
   plus the grid's 40px row gap stacking — which read as a break in the page
   rather than as one view.
   ------------------------------------------------------------------ */

.taxonomy-description {
	max-width: 62ch;
}

.playpoi-term-filter {
	margin-bottom: 1.25rem;
}

body.post-type-archive-learn .site-main,
body.post-type-archive-inspiration .site-main,
body.post-type-archive-gear .site-main,
body.tax-learn-categories .site-main,
body.tax-inspiration-categories .site-main,
body.tax-gear-categories .site-main {
	gap: 2rem;
}


/* ------------------------------------------------------------------
   Hero (Phase 5) — full-bleed photography, all destinations visible.

   Replaces the tile grid. The tiles met the "every link visible" requirement
   but rendered each photograph at about 263px, which turned the images into
   decoration on a site whose subject is light in motion. This shows one image
   at full width and carries the remaining destinations as a link row beneath,
   so nothing waits its turn in a rotation.

   Rendered on generate_after_header, outside the content container, so the
   image is genuinely full-bleed rather than escaping the container with a
   negative-margin trick. Still an <img> with srcset — a CSS background could
   not be optimized, which is the defect the old hero carried.
   ------------------------------------------------------------------ */

.playpoi-hero {
	background-color: #000;
}

.playpoi-hero-viewport {
	position: relative;
	width: 100%;
	/* Height stated directly rather than as aspect-ratio + max-height: with both,
	   a short window makes the browser narrow the box to hold the ratio, which
	   left an 88px gap beside a hero that is supposed to be full-bleed.
	   42.86vw is the 21:9 height; 72vh caps it on short screens. */
	height: clamp( 320px, 42.86vw, 72vh );
	overflow: hidden;
}

/* Slides stack; only the active one is opaque. Cross-fade rather than slide,
   because a horizontal transition moves the copy across the reader's eye and a
   fade does not. */
.playpoi-hero-slide {
	position: absolute;
	inset: 0;
	display: block;
	color: #fff;
	text-decoration: none;
	opacity: 0;
	visibility: hidden;
	transition: opacity 0.9s ease;
}

.playpoi-hero-slide.is-active {
	opacity: 1;
	visibility: visible;
}

@media (prefers-reduced-motion: reduce) {
	.playpoi-hero-slide {
		transition: none;
	}
}

.playpoi-hero-image,
img.playpoi-hero-image,
.playpoi-hero-image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

/* A scrim only where the copy sits, so the photograph stays a photograph. */
.playpoi-hero-slide::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient( 90deg, rgba( 0, 0, 0, 0.65 ) 0%, rgba( 0, 0, 0, 0.35 ) 38%, rgba( 0, 0, 0, 0 ) 65% );
}

.playpoi-hero-copy {
	position: absolute;
	z-index: 1;
	top: 50%;
	left: max( 1.5rem, calc( 50% - 560px ) );
	transform: translateY( -50% );
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 0.75rem;
	max-width: min( 30rem, 70% );
}

.playpoi-hero-title {
	font-family: var(--pp-font-heading);
	font-size: clamp( 1.6rem, 3.2vw, 2.6rem );
	font-weight: 700;
	line-height: 1.15;
	color: #fff;
}

.playpoi-hero-text {
	font-size: clamp( 0.95rem, 1.4vw, 1.1rem );
	color: rgba( 255, 255, 255, 0.9 );
}

.playpoi-hero-cta {
	margin-top: 0.4rem;
	padding: 0.6em 1.5em;
	border-radius: 2em;
	background-color: var( --pp-red-button );
	color: #fff;
	font-weight: 700;
	font-size: 0.95rem;
}

.playpoi-hero-cta.is-orange {
	background-color: var( --pp-orange );
}

.playpoi-hero-slide:hover .playpoi-hero-cta,
.playpoi-hero-slide:focus-visible .playpoi-hero-cta {
	background-color: var( --pp-red );
}


@media (max-width: 768px) {
	.playpoi-hero-image,
	img.playpoi-hero-image {
		aspect-ratio: 4 / 3;
	}

	.playpoi-hero-copy {
		left: 1.25rem;
		right: 1.25rem;
		max-width: none;
	}
}


/* ------------------------------------------------------------------
   Hero controls and floating header (Phase 5).

   playpoi.com floats the navigation over the slider rather than sitting it in
   a black bar above — one image running edge to edge and top to bottom, with
   the identity on top of it. That is the look, and it only needs the header
   taken out of the flow on the front page.
   ------------------------------------------------------------------ */

body.home .site-header,
body.playpoi-has-page-header .site-header {
	position: absolute;
	z-index: 5;
	width: 100%;
	background-color: transparent;
}

/* The navigation carries its own black, set in the Customizer, so clearing the
   header alone left a bar floating over the photograph. The dropdown keeps a
   solid background — it opens over the image and has to stay readable. */
body.home .main-navigation,
body.home .main-navigation .inside-navigation,
body.playpoi-has-page-header .main-navigation,
body.playpoi-has-page-header .main-navigation .inside-navigation {
	background-color: transparent;
}

body.home .main-navigation .sub-menu,
body.playpoi-has-page-header .main-navigation .sub-menu {
	background-color: rgba( 0, 0, 0, 0.9 );
}

/* The transparency above is written for the desktop navigation floating over
   the hero and the page-header photographs. On mobile the panel that opens
   IS that navigation, so the same rule left red links sitting over the
   photograph and the page text (Nick, 2026-08-20). While the menu is open the
   header is opaque, matching how it already looks on pages with no header
   image. .toggled exists only while the mobile menu is open, so no media
   query is needed. :has() carries the logo row; where it is unsupported the
   menu still gets its own background. */
.site-header:has( .main-navigation.toggled ),
body .main-navigation.toggled {
	background-color: #000;
}

/* A soft gradient under the header so red-on-bright-sky stays legible whatever
   the slide behind it happens to be. */
body.home .site-header::before {
	content: "";
	position: absolute;
	inset: 0 0 auto 0;
	height: 180%;
	background: linear-gradient( 180deg, rgba( 0, 0, 0, 0.55 ) 0%, rgba( 0, 0, 0, 0 ) 100% );
	pointer-events: none;
	z-index: -1;
}

/* The hero starts at the very top; the header sits over its first slice. */
body.home .playpoi-hero {
	margin-top: 0;
}

/* Enough room under the header that the copy never collides with the menu. */
body.home .playpoi-hero-copy {
	margin-top: 2rem;
}

.playpoi-hero-arrow {
	position: absolute;
	z-index: 2;
	top: 50%;
	transform: translateY( -50% );
	display: flex;
	align-items: center;
	justify-content: center;
	width: 3rem;
	height: 3rem;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background-color: rgba( 0, 0, 0, 0.35 );
	color: #fff;
	font-size: 2rem;
	line-height: 1;
	cursor: pointer;
	transition: background-color 0.2s ease;
}

.playpoi-hero-arrow:hover,
.playpoi-hero-arrow:focus-visible {
	background-color: var( --pp-red );
}

.playpoi-hero-arrow.is-prev {
	left: 1rem;
}

.playpoi-hero-arrow.is-next {
	right: 1rem;
}

.playpoi-hero-dots {
	position: absolute;
	z-index: 2;
	left: 0;
	right: 0;
	bottom: 1.25rem;
	display: flex;
	justify-content: center;
	gap: 0.6rem;
}

/* Bars rather than circles, matching the live site. */
.playpoi-hero-dot {
	width: 2.75rem;
	height: 4px;
	padding: 0;
	border: 0;
	border-radius: 2px;
	background-color: rgba( 255, 255, 255, 0.4 );
	cursor: pointer;
	transition: background-color 0.2s ease;
}

.playpoi-hero-dot.is-current,
.playpoi-hero-dot:hover,
.playpoi-hero-dot:focus-visible {
	background-color: #fff;
}

@media (max-width: 768px) {
	.playpoi-hero-arrow {
		width: 2.5rem;
		height: 2.5rem;
		font-size: 1.6rem;
	}
}

/* Elementor pages carry their own headline: keep the page title in the
   markup for screen readers and search engines without showing it twice.
   Added 2026-08-17 with the Elementor asset guards in functions.php. */
body.elementor-page .entry-header .entry-title {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}


/* ---- Footer ------------------------------------------------------------
   Course call-to-action band above the footer, then menu, social links and
   copyright inside GeneratePress's .site-info. Band and button colours echo
   the live footer; the red is the theme token rather than live's #f43030 so
   the whole site draws from one palette. */

.playpoi-footer-cta {
	background: var(--pp-red);
	padding: 28px 20px;
}

.playpoi-footer-cta-inner {
	max-width: 1200px;
	margin: 0 auto;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px 24px;
	flex-wrap: wrap;
}

.playpoi-footer-cta-heading {
	color: #fff;
	font-family: Raleway, var(--pp-font-body);
	font-size: 1.5rem;
	font-weight: 700;
	margin: 0;
}

.playpoi-footer-cta-action {
	margin: 0;
}

a.playpoi-footer-cta-button {
	display: inline-block;
	background: #fff;
	color: #111;
	font-weight: 700;
	font-size: 0.75rem;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	padding: 16px 34px;
}

a.playpoi-footer-cta-button:hover,
a.playpoi-footer-cta-button:focus {
	background: #111;
	color: #fff;
}

.site-info {
	text-align: center;
	padding: 28px 20px 24px;
}

/* The parent lays .inside-site-info out as a flex row; stack our three footer
   rows (menu, social, copyright) vertically instead. */
.site-info .inside-site-info {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 14px;
}

.playpoi-footer-menu ul {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 6px 22px;
}

.playpoi-footer-menu a {
	font-size: 0.8rem;
	color: var(--pp-text);
}

.playpoi-footer-menu a:hover,
.playpoi-footer-menu a:focus {
	color: var(--pp-red);
}

.playpoi-footer-social {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	justify-content: center;
	gap: 12px;
}

.playpoi-footer-social li {
	margin: 0;
}

.playpoi-footer-social a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	border-radius: 50%;
	background: var(--pp-red);
	color: #fff;
}

.playpoi-footer-social a:hover,
.playpoi-footer-social a:focus {
	background: #111;
	color: #fff;
}

.copyright-bar {
	margin-top: 0;
	font-size: 0.75rem;
	color: var(--pp-text);
}

/* Elementor's testimonial swiper measures itself wider than the viewport on
   small screens (388px at a 375px viewport). The same protrusion exists on
   live, where the old theme's site-wide overflow-x:hidden masks it. Clip at
   the Elementor content root only, so the theme's own templates keep
   surfacing their overflow bugs instead of having them silently hidden. */
.elementor {
	overflow-x: clip;
}

/* --------------------------------------------------------------------------
   Page header — full-bleed featured image with the page title over it.
   Rendered by playpoi_render_page_header() on pages that have a featured
   image. The scrim sits in its own layer so the photograph keeps its contrast
   where there is no text over it.
   -------------------------------------------------------------------------- */

.playpoi-page-header {
	position: relative;
	width: 100%;
	margin: 0;
	background-color: #000;
	overflow: hidden;
}

/* Imagify wraps the image in <picture> and moves the class onto the wrapper,
   so both the wrapper and the inner <img> need the sizing rules. */
.playpoi-page-header__image,
.playpoi-page-header__image img {
	display: block;
	width: 100%;
	height: clamp(320px, 30vw, 420px);
	object-fit: cover;
	object-position: center;
}

.playpoi-page-header__inner {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: flex-end;
	padding: 2rem 1.25rem;
	/* Two scrims: one under the floating navigation at the top, one under the
	   title at the bottom. The middle of the photograph keeps full contrast. */
	background:
		linear-gradient( to bottom, rgba( 0, 0, 0, 0.6 ) 0%, rgba( 0, 0, 0, 0.25 ) 22%, rgba( 0, 0, 0, 0 ) 40% ),
		linear-gradient( to top, rgba( 0, 0, 0, 0.72 ) 0%, rgba( 0, 0, 0, 0.35 ) 38%, rgba( 0, 0, 0, 0 ) 72% );
}

.playpoi-page-header__title {
	width: 100%;
	max-width: 1200px;
	margin: 0 auto;
	color: #fff;
	font-size: clamp( 1.75rem, 4.5vw, 3rem );
	line-height: 1.15;
	text-shadow: 0 1px 3px rgba( 0, 0, 0, 0.5 );
}

/* --- Elementor mobile layout (v0.29.0, 2026-08-20) --------------------
   Elementor sections on the course pages were authored against a
   full-width container. GeneratePress puts 30px of side padding on
   .site-content, which costs 60px of a 393px phone: non-stretched
   sections rendered 333px wide and their type filled the box edge to
   edge. Give Elementor pages the full width back on phones; each
   section's own padding supplies the breathing room.

   The testimonial carousels overflowed for a separate reason — a fixed
   px width set per page in Elementor (428px on /learn-and-master/,
   460px on /advanced-poi/, against a 393px phone). That was fixed at
   source in the widget settings, not here: a CSS override loses to
   Elementor's per-page generated rule on specificity, and masking it
   is what produced the cut-off text in the first place. */

@media (max-width: 767px) {

	body.elementor-page .site-content {
		padding-left: 0;
		padding-right: 0;
	}

}
