/*
Theme Name: Mistra Vape
Theme URI: https://mistravape.com/
Author: Mistra Vape
Description: Storefront theme for Mistra Vape, a cash-on-delivery vape shop delivering within Amman only. Built as a WordPress block theme, so the design lives in theme.json rather than PHP templates.
Requires at least: 7.1
Tested up to: 7.1
Requires PHP: 8.3
Version: 1.10.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: mistravape
Tags: e-commerce, block-patterns, block-styles, full-site-editing, accessibility-ready, custom-colors, custom-logo
*/

/*
 * This file exists to satisfy WordPress' theme header requirement and to
 * provide the theme-level styles that block markup cannot express.
 *
 * Colours, spacing and typography live in theme.json, which is the single
 * source of truth. Change them there rather than here.
 */

:root {
	/* Placeholder shown while a real product photo is missing. Sits behind
	   the product image so a card never renders as an empty white box. */
	--mistra-placeholder: var(--wp--preset--color--surface-alt);
}

.mistra-placeholder {
	align-items: center;
	background-color: var(--mistra-placeholder);
	color: var(--wp--preset--color--muted);
	display: flex;
	justify-content: center;
	min-height: 12rem;
}

/* ---------------------------------------------------------------------------
 * Header
 *
 * The logo, nav and cart are one flex row. WordPress' own site-logo rules
 * set the image to `height: auto`, which on a 3.3:1 lockup lets it take
 * whatever width it likes and push the nav off the row, so the height is
 * pinned here instead.
 * ------------------------------------------------------------------------- */
.mistra-header {
	/* A hairline under the bar plus a soft shadow, so the header reads as a
	 * distinct surface sitting above the page rather than as content that
	 * happens to be at the top.
	 *
	 * Sticky, because on a shop the cart is the primary action and burying
	 * it under the fold on every scroll is the most common way to lose a
	 * sale. z-index has to beat the navigation block's mobile overlay menu,
	 * which is z-index 100 - hence 20 here for the bar and the media query
	 * below for the overlay. */
	background-color: var(--wp--preset--color--body);
	border-bottom: 1px solid var(--wp--preset--color--border);
	box-shadow: var(--wp--custom--shadow--card);
	position: sticky;
	top: 0;
	z-index: 20;
}

.mistra-site-logo img {
	/* Was 2.75rem. The logo is the only thing identifying the shop, and at
	 * the old size it was visibly smaller than the nav text next to it, so
	 * the brand read as an afterthought. */
	height: 3.5rem;
	width: auto;
	max-width: 100%;
}

.mistra-site-logo {
	display: flex;
	align-items: center;
	line-height: 0;
}

.mistra-site-logo a {
	display: inline-flex;
	align-items: center;
}

.mistra-header-row {
	gap: 1.5rem;
}

.mistra-header-actions {
	gap: 1rem;
}

/* Nav spacing.
 *
 * The Navigation block sets gap on the UL, but its own inline rules win
 * over this declaration, so the gap has to be forced. At the default the
 * six links sat 4px apart and ran together into one unreadable run of
 * words - "Shop Disposable Pod Systems Saltnic Juice Accessories" read as
 * a sentence rather than a menu.
 */
.mistra-nav .wp-block-navigation__container {
	gap: 0.375rem !important;
}

.mistra-nav .wp-block-navigation-item__content {
	/* Pill links rather than bare text. The hover state had to exist before
	 * this: with plain text and a background-only hover the menu looked like
	 * a list that happened to highlight on mouseover, not like navigation. */
	border-radius: var(--wp--custom--radius--pill);
	color: var(--wp--preset--color--ink);
	display: inline-block;
	font-size: 0.9375rem;
	font-weight: 600;
	letter-spacing: 0.01em;
	padding: 0.5rem 0.875rem;
	text-decoration: none;
	transition: background-color var(--wp--custom--transition--base),
		color var(--wp--custom--transition--base);
}

.mistra-nav .wp-block-navigation-item__content:hover,
.mistra-nav .wp-block-navigation-item__content:focus-visible {
	background-color: var(--wp--preset--color--surface-alt);
	color: var(--wp--preset--color--accent-strong);
}

/* The current page has no page context in a block theme's nav, so the
 * first item is not highlighted. Leave that to the site editor rather than
 * guessing. */

/* Under ~860px the logo plus six nav links plus a cart no longer fit on one
 * line. Rather than let the nav wrap under the logo at an arbitrary width,
 * hand over to the navigation block's mobile overlay menu earlier. */
@media (max-width: 860px) {
	.mistra-site-logo img {
		height: 2.75rem;
	}

	.mistra-header-row,
	.mistra-header-actions {
		gap: 0.75rem;
	}
}

/* WordPress hides the desktop nav behind a toggle using this class; make
 * sure the toggle inherits the brand colour rather than the UA default. */
.wp-block-navigation__responsive-container-open,
.wp-block-navigation__responsive-container-close {
	color: var(--wp--preset--color--ink);
}

/* Cart link: a filled pill, not a bordered outline.
 *
 * The block puts its own class on the wrapper div and the anchor inside it
 * carries wc-block-cart-link, so the styling has to be applied to the
 * anchor rather than to .mistra-cart-link itself - targeting the wrapper
 * produced a visible empty pill, because the wrapper is a full-width div.
 *
 * Filled rather than outlined so the cart reads as the one action in the
 * bar worth pressing; an outline put it at the same weight as the nav and
 * it disappeared against it. */
.mistra-cart-link {
	display: inline-flex;
}

.mistra-cart-link a {
	align-items: center;
	background-color: var(--wp--preset--color--accent);
	border-radius: var(--wp--custom--radius--pill);
	color: var(--wp--preset--color--body);
	display: inline-flex;
	font-size: 0.875rem;
	font-weight: 600;
	gap: 0.375rem;
	line-height: 1;
	padding: 0.625rem 1rem;
	text-decoration: none;
	white-space: nowrap;
	transition: background-color var(--wp--custom--transition--base);
}

.mistra-cart-link a:hover,
.mistra-cart-link a:focus-visible {
	background-color: var(--wp--preset--color--accent-strong);
	color: var(--wp--preset--color--body);
}

/* The custom logo falls back to the site title when none is set, so this
 * has to look deliberate in that case too. */
.mistra-site-title {
	color: var(--wp--preset--color--ink);
	font-weight: 700;
	letter-spacing: -0.01em;
}

/* Age-restricted product notice.
 *
 * Vape products are age-restricted, and a purchase age gate is the main
 * safeguard on a store with no payment step to act as a control point.
 * Stated plainly rather than buried in the footer. */
.mistra-age-gate {
	background-color: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--surface);
	padding: 0.75rem 1.25rem;
	text-align: center;
}

.mistra-age-gate strong {
	color: var(--wp--preset--color--body);
}

/* Trust strip directly under the header. Surface is a very light blue, so
 * the text needs the ink colour rather than a muted grey to stay legible. */
.mistra-strip {
	background-color: var(--wp--preset--color--surface);
	color: var(--wp--preset--color--ink);
	font-size: 0.875rem;
}

/* Footer rule, previously a separator carrying a preset colour class. */
.mistra-footer-rule {
	border-color: var(--wp--preset--color--border);
	border-width: 1px;
}

.mistra-strip-text strong {
	color: var(--wp--preset--color--accent-strong);
}

/* Delivery information, repeated where the 3.00 JOD fee would otherwise
   be a surprise at checkout. */
.mistra-delivery-note {
	color: var(--wp--preset--color--muted);
	font-size: 0.875rem;
	margin: 0.5rem 0 1rem;
}

/* Out-of-area notice from the store config mu-plugin. */
.woocommerce-error,
.woocommerce-notices-wrapper .woocommerce-error {
	border-top-color: var(--wp--preset--color--danger);
}

/* ---------------------------------------------------------------------------
 * Home page sections
 *
 * The hero and the section patterns below carry these class names, and the
 * theme shipped with no rules for any of them, so the whole front page was
 * rendering as unstyled block defaults: no card treatment, no section
 * rhythm, no hero hierarchy.
 * ------------------------------------------------------------------------- */

/* Hero: deep ink panel with an azure glow bleeding in from the top right,
   which echoes the swirl in the logo without adding an image.
 *
 * The backgroundColor/textColor attributes on the group block were removed
   from the pattern. They emit .has-primary-background-color, a bare
 * background-color declaration, which this rule cannot outrank without
 * !important - and a gradient cannot be expressed as a preset colour at
 * all. Colour now comes from CSS alone. */
.mistra-hero {
	background-color: var(--wp--preset--color--ink);
	background-image: radial-gradient(
		120% 140% at 100% 0%,
		var(--wp--preset--color--accent) 0%,
		transparent 55%
	);
	color: var(--wp--preset--color--body);
	position: relative;
}

/* Headings inside the hero have to be forced light.
 *
 * theme.json sets the heading element colour to ink globally, and that
 * declaration targets the bare element, so it wins against an inherited
 * colour from the parent. Without this the h1 paints ink-on-ink and the
 * title is invisible. The earlier version of this rule was scoped to
 * .has-body-color, which stopped matching once the textColor attribute was
 * removed from the pattern - and an invisible headline is exactly the kind
 * of breakage that still looks "fine" in markup. */
.mistra-hero :where(h1, h2, h3, h4, h5, h6),
.mistra-hero .wp-block-heading {
	color: var(--wp--preset--color--body);
}

.mistra-eyebrow {
	color: var(--wp--preset--color--sky);
	font-size: 0.875rem;
	font-weight: 600;
	letter-spacing: 0.14em;
	margin-bottom: 0.5rem;
	text-transform: uppercase;
}

.mistra-hero-title {
	font-size: clamp(2rem, 5vw, 3.25rem);
	letter-spacing: -0.02em;
	line-height: 1.1;
	margin-bottom: 1rem;
}

.mistra-hero-text {
	color: var(--wp--preset--color--surface-alt);
	font-size: 1.125rem;
	margin-bottom: 2rem;
	max-width: 34rem;
}

.mistra-hero-actions {
	gap: 0.75rem;
}

/* Hero layout: copy on the left, brand artwork on the right.
 *
 * Previously the hero was a single left-aligned column of text with a CSS
 * gradient behind it. The artwork is a tall portrait crop (758x809), so it
 * needs its own column or it would push the headline down the page.
 *
 * The artwork is decorative - the brand name is already in the eyebrow and
 * the logo sits in the header - so it carries an empty alt attribute and is
 * skipped by screen readers rather than announced as a second "Mistra Vape".
 */
.mistra-hero-layout {
	align-items: center;
	display: grid;
	gap: 2.5rem;
	grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
}

.mistra-hero-image {
	border-radius: var(--wp--custom--radius--lg);
	display: block;
	height: auto;
	margin: 0 auto;
	max-height: 26rem;
	object-fit: cover;
	width: 100%;
}

/* Below 860px the artwork is dropped rather than stacked: on a phone it
 * pushed the headline below the fold, and the copy is what sells the page. */
@media (max-width: 860px) {
	.mistra-hero-layout {
		gap: 1.5rem;
		grid-template-columns: 1fr;
	}

	.mistra-hero-art {
		display: none;
	}
}

/* The second button is the outline variant on a dark panel, so its border
   and text have to be light. The default outline style uses the accent,
   which is invisible against the ink. */
.mistra-hero .wp-block-button.is-style-outline .wp-block-button__link {
	border-color: rgb(255 255 255 / 0.55);
	color: var(--wp--preset--color--body);
}

.mistra-hero .wp-block-button.is-style-outline .wp-block-button__link:hover,
.mistra-hero .wp-block-button.is-style-outline .wp-block-button__link:focus {
	background-color: rgb(255 255 255 / 0.12);
	border-color: var(--wp--preset--color--body);
	color: var(--wp--preset--color--body);
}

.mistra-hero .wp-block-button.is-style-fill .wp-block-button__link {
	background-color: var(--wp--preset--color--body);
	color: var(--wp--preset--color--ink);
}

.mistra-hero .wp-block-button.is-style-fill .wp-block-button__link:hover,
.mistra-hero .wp-block-button.is-style-fill .wp-block-button__link:focus {
	background-color: var(--wp--preset--color--surface-alt);
	color: var(--wp--preset--color--ink);
}

/* Shared section headings. */
.mistra-section-title {
	letter-spacing: -0.015em;
	margin-bottom: 0.5rem;
}

.mistra-section-text {
	color: var(--wp--preset--color--muted);
	margin-bottom: 2rem;
	max-width: 44rem;
}

/* Category grid: cards rather than bare text columns. */
.mistra-categories {
	padding-bottom: 4rem;
	padding-top: 4rem;
}

/* Category grid: three across on desktop, two on tablet, one on phones.
 *
 * The columns block defaults to laying out as many columns as fit on one
 * row with flex-wrap: nowrap, which squeezed all five into 173px at a
 * 1000px viewport - too narrow for a photograph and three lines of text, and
 * the card titles wrapped onto two lines ("Pods and / Accessories").
 *
 * The column count is set explicitly rather than left to the intrinsic
 * width, so the layout is deliberate. 3+2 also reads better than five: the
 * descriptions have room to breathe.
 */
.mistra-category-columns {
	--wp--style--columns: 3;
	gap: 1.5rem;
}

@media (max-width: 900px) {
	.mistra-category-columns {
		--wp--style--columns: 2;
	}
}

@media (max-width: 560px) {
	.mistra-category-columns {
		--wp--style--columns: 1;
	}
}

.mistra-category-card {
	background-color: var(--wp--preset--color--body);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--lg);
	box-shadow: var(--wp--custom--shadow--card);
	color: inherit;
	display: flex;
	flex-direction: column;
	height: 100%;
	padding: 1.5rem;
	text-decoration: none;
	transition: border-color var(--wp--custom--transition--base),
		box-shadow var(--wp--custom--transition--base),
		transform var(--wp--custom--transition--base);
}

.mistra-category-card:hover,
.mistra-category-card:focus-within {
	border-color: var(--wp--preset--color--accent);
	box-shadow: var(--wp--custom--shadow--brand);
	transform: translateY(-2px);
}

/* Category photograph.
 *
 * object-fit: cover is what makes five different aspect ratios line up on
 * one row. The supplied images are between 1.33:1 and 1.8:1, so without it
 * the cards would be a ragged edge of mismatched heights and the text below
 * each would not align.
 *
 * The image is decorative - the category name follows it as text - so it is
 * rendered with an empty alt attribute and is not announced twice.
 */
.mistra-category-image {
	aspect-ratio: 1 / 1;
	border-radius: var(--wp--custom--radius--md);
	display: block;
	height: auto;
	margin-bottom: 1rem;
	object-fit: cover;
	overflow: hidden;
	width: 100%;
}

.mistra-category-card:hover .mistra-category-image {
	filter: saturate(1.08);
}

/* Card without a photograph: the text needs to sit at the top rather than
 * being pushed down by the margin the image would have occupied. */
.mistra-category-card:not(:has(.mistra-category-image)) .mistra-category-title {
	margin-top: 0;
}

.mistra-category-title {
	font-size: 1.125rem;
	margin-bottom: 0.5rem;
}

.mistra-category-card a.mistra-category-title {
	color: var(--wp--preset--color--ink);
	text-decoration: none;
}

.mistra-category-card a.mistra-category-title:hover {
	color: var(--wp--preset--color--accent-strong);
}

.mistra-category-text {
	color: var(--wp--preset--color--muted);
	font-size: 0.9375rem;
	margin-bottom: 1rem;
}

.mistra-category-cta {
	color: var(--wp--preset--color--accent-strong);
	font-weight: 600;
	margin-top: auto;
	text-decoration: none;
}

/* Delivery promise: three cards on a tinted panel.
 * Same reasoning as the hero: the backgroundColor attribute would emit a
 * flat preset background, so the tint lives here instead. */
.mistra-delivery-promise {
	background-color: var(--wp--preset--color--surface-alt);
	color: var(--wp--preset--color--ink);
	padding-bottom: 4rem;
	padding-top: 4rem;
}

.mistra-delivery-columns {
	gap: 1.25rem;
}

.mistra-delivery-card {
	background-color: var(--wp--preset--color--body);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--lg);
	height: 100%;
	padding: 1.5rem;
}

.mistra-delivery-card-title {
	font-size: 1.0625rem;
	margin-bottom: 0.375rem;
}

.mistra-delivery-card-text {
	color: var(--wp--preset--color--muted);
	font-size: 0.9375rem;
}

/* Featured collection. */
.mistra-featured {
	padding-bottom: 4rem;
	padding-top: 4rem;
}

/* Pre-order reassurance, closing the page before the footer.
 * Buttons reuse .mistra-hero-actions, which is scoped to the dark hero, so
 * the light-surface variants are restated here rather than relying on it. */
.mistra-reassure {
	padding-bottom: 4rem;
	padding-top: 0.5rem;
}

.mistra-reassure-columns {
	gap: 3rem;
}

.mistra-reassure-col {
	flex-basis: 0;
	flex-grow: 1;
}

.mistra-reassure .mistra-hero-actions {
	margin-top: 1.5rem;
}

.mistra-reassure .wp-block-button.is-style-fill .wp-block-button__link {
	background-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--body);
}

.mistra-reassure .wp-block-button.is-style-fill .wp-block-button__link:hover,
.mistra-reassure .wp-block-button.is-style-fill .wp-block-button__link:focus {
	background-color: var(--wp--preset--color--accent-strong);
	color: var(--wp--preset--color--body);
}

.mistra-reassure .wp-block-button.is-style-outline .wp-block-button__link {
	border-color: var(--wp--preset--color--accent-strong);
	color: var(--wp--preset--color--accent-strong);
}

.mistra-reassure .wp-block-button.is-style-outline .wp-block-button__link:hover,
.mistra-reassure .wp-block-button.is-style-outline .wp-block-button__link:focus {
	background-color: var(--wp--preset--color--surface);
	color: var(--wp--preset--color--accent-strong);
}

/* Checklist: a tick before each item, no list markers. */
.mistra-check-list {
	list-style: none;
	margin: 1rem 0 0;
	padding: 0;
}

.mistra-check-list li {
	color: var(--wp--preset--color--muted);
	padding-left: 1.75rem;
	position: relative;
}

.mistra-check-list li + li {
	margin-top: 0.625rem;
}

.mistra-check-list li::before {
	color: var(--wp--preset--color--success);
	content: "\2713";
	font-weight: 700;
	left: 0;
	position: absolute;
}

/* Product cards in the featured grid and on archives.
 * The featured section reuses .mistra-product-card from archive.html, so the
 * treatment is defined once and both benefit. */
.mistra-product-grid {
	margin-top: 2rem;
}

/* The card class sits on the post-template UL, which is the grid container.
 * Styling it as a card drew one border around the whole grid; the card
 * treatment has to go on the LI, which is what :where() reaches from the
 * template without needing a class on every item. */
.mistra-product-grid .wp-block-post-template > li {
	background-color: var(--wp--preset--color--body);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--lg);
	display: flex;
	flex-direction: column;
	padding: 1rem;
	transition: border-color var(--wp--custom--transition--base),
		box-shadow var(--wp--custom--transition--base);
}

.mistra-product-grid .wp-block-post-template > li:hover {
	border-color: var(--wp--preset--color--accent);
	box-shadow: var(--wp--custom--shadow--raised);
}

.mistra-product-media {
	background-color: var(--wp--preset--color--surface-alt);
	border-radius: var(--wp--custom--radius--md);
	margin-bottom: 0.875rem;
	overflow: hidden;
}

.mistra-product-title {
	font-size: 1rem;
	line-height: 1.35;
	margin-bottom: 0.375rem;
}

.mistra-product-price {
	color: var(--wp--preset--color--ink);
	font-weight: 700;
	margin-bottom: 0.875rem;
}

.mistra-product-button {
	margin-top: auto;
}

.mistra-product-cat {
	font-size: 0.75rem;
	letter-spacing: 0.06em;
	margin-bottom: 0.375rem;
	text-transform: uppercase;
}

.mistra-no-results,
.mistra-no-posts {
	color: var(--wp--preset--color--muted);
	padding: 2rem 0;
}

/* Footer sits on the light blue surface, so links and headings take the
   ink and accent colours rather than inheriting body text.
 *
   The backgroundColor attribute was stripped from the footer template along
   with the others, which left the footer transparent: it read as an
   unstyled white block rather than the closing band it is meant to be. */
.mistra-footer {
	background-color: var(--wp--preset--color--surface);
	color: var(--wp--preset--color--ink);
	position: relative;
}

/* The band is separated from the page by an accent rule rather than a
 * border, so the footer closes the page instead of looking like another
 * section of it. A gradient is used because a flat rule read as a divider
 * between two white areas and the footer lost its role as the end of the
 * page. */
.mistra-footer::before {
	background: linear-gradient(
		90deg,
		var(--wp--preset--color--accent) 0%,
		var(--wp--preset--color--sky) 45%,
		var(--wp--preset--color--violet) 100%
	);
	content: "";
	height: 4px;
	left: 0;
	position: absolute;
	top: 0;
	width: 100%;
}

.mistra-footer a {
	color: var(--wp--preset--color--accent-strong);
}

.mistra-footer-heading {
	/* Was the same size as body text, so the footer had no hierarchy at all:
	 * three headings and three link lists rendered as one undifferentiated
	 * wall of short lines. Small caps and letterspacing mark the columns
	 * without shouting over the logo. */
	color: var(--wp--preset--color--ink);
	font-size: 0.8125rem;
	font-weight: 700;
	letter-spacing: 0.09em;
	margin-bottom: 1rem;
	text-transform: uppercase;
}

/* The brand column sits above its own baseline: the logo is 3rem tall and
 * the columns beside it are top-aligned text, so without this the logo
 * floats and the whole first column reads as misaligned. */
.mistra-footer-logo img {
	height: 3rem;
	width: auto;
	max-width: 100%;
}

.mistra-footer-logo {
	display: flex;
	align-items: center;
	line-height: 0;
	margin-bottom: 0.875rem;
}

.mistra-footer-logo a {
	display: inline-flex;
	align-items: center;
}

.mistra-footer-small {
	color: var(--wp--preset--color--muted);
}

.mistra-footer-links {
	line-height: 2;
}

/* is-style-wide, not a width declaration here.
 *
 * Core ships `.wp-block-separator:not(.is-style-wide) { width: 100px }`, and
 * that `:not()` selector matches at the same specificity as a plain class, so
 * a `width: 100%` on .mistra-footer-rule either lost or only won by source
 * order. The separator was rendering as a 100px stub inside a 1068px footer.
 * The block's own wide style is the supported way to ask for a full-width
 * rule, so the class is used rather than the override. */
.mistra-footer-rule {
	border-color: var(--wp--preset--color--border);
	border-width: 1px;
}

@media (max-width: 860px) {
	.mistra-footer-logo img {
		height: 2.5rem;
	}
}

@media (prefers-reduced-motion: reduce) {
	.mistra-marquee {
		animation: none;
	}
}