/**
 * Progress Bar block styles (shared front-end + editor canvas).
 *
 * The container wrapper drives layout via core's layout support and carries
 * the shared CSS custom properties (Counter pattern: defaults declared once
 * on the wrapper, inline overrides only when a control is set). Every
 * consumer carries its own fallback so an unset variable never collapses
 * the rendering. Number/fill animation is handled by the view.js bundle;
 * the PHP render always emits the final state, so the block stays readable
 * without JavaScript.
 */

.wp-block-wpminty-progress-bar {
	--wpminty-pb-bar-height: 8px;
	--wpminty-pb-bar-radius: 999px;
	--wpminty-pb-circle-size: 120px;
	--wpminty-pb-circle-thickness: 8px;
	--wpminty-pb-track: color-mix(in srgb, currentColor 12%, transparent);
	--wpminty-pb-fallback-fill: currentColor;
	--wpminty-pb-divider-width: 1px;
	--wpminty-pb-divider-style: solid;
	--wpminty-pb-divider-color: currentColor;
	/* Layout/style containment only — `paint` would clip the divider
	 * pseudo-elements and any item shadows. */
	contain: layout style;
}

/* Core layout support owns the container display mode, gap and wrapping.
 * The bar shape always stacks its items into full-width rows regardless of
 * the layout orientation picked in the toolbar: specificity beats the
 * generated .wp-container-* rules without ever needing !important. */
.wp-block-wpminty-progress-bar.is-shape-bar.is-layout-flex {
	flex-direction: column;
	justify-content: flex-start;
	align-items: stretch;
}

/* ---------------------------------------------------------------------------
 * Item (shared by both shapes)
 * ------------------------------------------------------------------------- */

.wpminty-pb-item {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	flex: 1 1 auto;
	min-width: 0;
}

.wp-block-wpminty-progress-bar.is-shape-circle .wpminty-pb-item {
	flex: 0 1 auto;
	align-items: center;
	text-align: center;
}

.wpminty-pb-item__label {
	/* Container typography variables (zero-emission): unset controls fall
	 * back to the element's own defaults / theme inheritance. */
	font-family: var(--wpminty-pb-label-font-family, inherit);
	font-size: var(--wpminty-pb-label-font-size, inherit);
	font-style: var(--wpminty-pb-label-font-style, inherit);
	font-weight: var(--wpminty-pb-label-font-weight, inherit);
	line-height: var(--wpminty-pb-label-line-height, 1.4);
	letter-spacing: var(--wpminty-pb-label-letter-spacing, inherit);
	text-decoration: var(--wpminty-pb-label-text-decoration, inherit);
	text-transform: var(--wpminty-pb-label-text-transform, inherit);
	color: var(--wpminty-pb-label-color, inherit);
}

.wpminty-pb-item__value {
	display: inline-flex;
	align-items: baseline;
	gap: 0.1em;
	font-family: var(--wpminty-pb-value-font-family, inherit);
	font-size: var(--wpminty-pb-value-font-size, inherit);
	font-style: var(--wpminty-pb-value-font-style, inherit);
	font-weight: var(--wpminty-pb-value-font-weight, 600);
	line-height: var(--wpminty-pb-value-line-height, 1);
	letter-spacing: var(--wpminty-pb-value-letter-spacing, inherit);
	text-decoration: var(--wpminty-pb-value-text-decoration, inherit);
	text-transform: var(--wpminty-pb-value-text-transform, inherit);
	color: var(--wpminty-pb-value-color, inherit);
	white-space: nowrap;
	font-variant-numeric: tabular-nums;
}

/* Optional icon ahead of the label (shared by both shapes). Sized in em so
 * it tracks the label/value typography it sits next to. */
.wpminty-pb-item__icon {
	flex-shrink: 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.25em;
	height: 1.25em;
	align-self: center;
	color: var(--wpminty-pb-label-color, inherit);
}

.wpminty-pb-item__icon svg {
	width: 100%;
	height: 100%;
	fill: currentColor;
}

/* Keyboard focus ring; the hover highlight below treats :focus-visible the
 * same as :hover, so both cues stay in sync. */
.wpminty-pb-item:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 3px;
	border-radius: 4px;
}

/* ---------------------------------------------------------------------------
 * Hover highlight (pure CSS, zero JS)
 *
 * While any item is hovered or keyboard-focused, the siblings fade out.
 * Icon Extra precedent: a single :has() selector, no script involvement.
 * ------------------------------------------------------------------------- */

.wp-block-wpminty-progress-bar.has-hover-highlight .wpminty-pb-item {
	transition: opacity 0.3s ease;
}

.wp-block-wpminty-progress-bar.has-hover-highlight:has(.wpminty-pb-item:hover) .wpminty-pb-item:not(:hover),
.wp-block-wpminty-progress-bar.has-hover-highlight:has(.wpminty-pb-item:focus-visible) .wpminty-pb-item:not(:focus-visible) {
	opacity: 0.45;
}

/* ---------------------------------------------------------------------------
 * Bar shape
 * ------------------------------------------------------------------------- */

.wpminty-pb-item__header {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 0.75rem;
}

/* Value above the bar: the number row leads, the label follows. The DOM
 * order (label first, value second) is kept stable for screen readers, so
 * the visual swap happens through column-reverse. */
.wp-block-wpminty-progress-bar.is-value-above .wpminty-pb-item__header {
	flex-direction: column-reverse;
	align-items: flex-start;
	gap: 0.25rem;
}

/* Label position (bar shape). The DOM order stays label-then-value; the
 * visual arrangement is pure flex direction, so screen readers and the
 * width animation are unaffected. Declared after is-value-above so a
 * combined setup resolves deterministically. */
.wp-block-wpminty-progress-bar.is-label-right .wpminty-pb-item__header {
	flex-direction: row-reverse;
}

.wp-block-wpminty-progress-bar.is-label-above .wpminty-pb-item__header {
	flex-direction: column;
	align-items: flex-start;
	gap: 0.25rem;
}

.wp-block-wpminty-progress-bar.is-value-hidden .wpminty-pb-item__value {
	display: none;
}

.wpminty-pb-item__track {
	height: var(--wpminty-pb-bar-height);
	background: var(--wpminty-pb-track);
	border-radius: var(--wpminty-pb-bar-radius);
	overflow: hidden;
}

/* Animation direction (bar shape). view.js keeps animating `width` in both
 * cases; only the alignment changes — rtl flips the inline start via
 * direction, center flex-centers the fill. */
.wp-block-wpminty-progress-bar.is-dir-rtl .wpminty-pb-item__track {
	direction: rtl;
}

.wp-block-wpminty-progress-bar.is-dir-center .wpminty-pb-item__track {
	display: flex;
	justify-content: center;
}

.wpminty-pb-item__fill {
	position: relative;
	height: 100%;
	border-radius: inherit;
	/* Full fill value lives in a single custom property (solid or complete
	 * gradient string) — never reassembled from parts. */
	background: var(--wpminty-pb-item-fill, var(--wpminty-pb-fallback-fill, currentColor));
}

/* Striped texture: a translucent overlay on top of the fill. The fill
 * contract (`--wpminty-pb-item-fill`) is never touched — the stripes ride
 * on a pseudo-element. */
.wp-block-wpminty-progress-bar.is-texture-striped .wpminty-pb-item__fill::after,
.wp-block-wpminty-progress-bar.is-texture-striped-animated .wpminty-pb-item__fill::after {
	content: "";
	position: absolute;
	inset: 0;
	background-image: repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.18) 0 10px, transparent 10px 20px);
	pointer-events: none;
}

/* One period of the 45-degree stripe pattern along the horizontal axis
 * (20px / cos(45deg)) keeps the loop seamless. */
@keyframes wpminty-pb-stripes {
	from {
		background-position: 0 0;
	}
	to {
		background-position: 28.284px 0;
	}
}

.wp-block-wpminty-progress-bar.is-texture-striped-animated .wpminty-pb-item__fill::after {
	animation: wpminty-pb-stripes 1s linear infinite;
}

/* ---------------------------------------------------------------------------
 * Tooltip value style (bar shape)
 *
 * The value element is moved inside the fill (item/render.php) and rides
 * its width: while view.js animates `width`, the bubble tracks the fill's
 * leading edge automatically, and the static / no-JS state parks it at the
 * final position with zero scripting. view.js only contributes an edge
 * clamp (--wpminty-pb-tooltip-shift) so the bubble never hangs outside the
 * track at 0% / 100%.
 * ------------------------------------------------------------------------- */

/* The bubble escapes the track vertically, so the radius clipping is
 * dropped in this mode; the fill carries its own border-radius. */
.wp-block-wpminty-progress-bar.is-value-tooltip .wpminty-pb-item__track {
	overflow: visible;
}

/* `inset-inline-end: 0` pins the bubble's trailing edge to the fill's
 * leading edge, so centering the bubble on that point needs a shift of
 * +50% of its own width (LTR) — a negative shift would park the center
 * a full bubble width away. The view.js clamp adds a physical pixel
 * offset on top; the arrow below subtracts the same offset so the tip
 * keeps pointing at the fill edge even while the bubble is clamped. */
.wpminty-pb-item__value--tooltip {
	position: absolute;
	inset-inline-end: 0;
	bottom: calc(100% + 8px);
	z-index: 2;
	display: inline-flex;
	padding: 0.2em 0.55em;
	background: var(--wpminty-pb-tooltip-bg, var(--wp--preset--color--contrast));
	color: var(--wpminty-pb-tooltip-text, var(--wp--preset--color--base));
	border-radius: 6px;
	pointer-events: none;
	transform: translateX(calc(50% + var(--wpminty-pb-tooltip-shift, 0px)));
}

/* RTL fills grow from the inline end, so the leading edge is the fill's
 * left edge — flip the centering shift. The view.js clamp variable stays
 * a physical pixel offset in both directions. */
.wp-block-wpminty-progress-bar.is-dir-rtl .wpminty-pb-item__value--tooltip {
	transform: translateX(calc(-50% + var(--wpminty-pb-tooltip-shift, 0px)));
}

/* Bubble arrow, pointing down at the fill's leading edge. The horizontal
 * position subtracts the clamp shift the bubble itself received, so the
 * tip always sits on the fill edge: bubble center + shift - shift. */
.wpminty-pb-item__value--tooltip::after {
	content: "";
	position: absolute;
	top: 100%;
	left: calc(50% - var(--wpminty-pb-tooltip-shift, 0px));
	transform: translateX(-50%);
	border: 5px solid transparent;
	border-top-color: var(--wpminty-pb-tooltip-bg, var(--wp--preset--color--contrast));
}

/* ---------------------------------------------------------------------------
 * Circle shape
 * ------------------------------------------------------------------------- */

.wpminty-pb-item__circle {
	position: relative;
	width: var(--wpminty-pb-circle-size);
	height: var(--wpminty-pb-circle-size);
}

.wpminty-pb-item__svg {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
}

.wpminty-pb-item__track-ring {
	stroke: var(--wpminty-pb-track);
}

.wpminty-pb-item__fill-ring {
	stroke-dasharray: var(--wpminty-pb-item-dash, none);
	stroke-dashoffset: var(--wpminty-pb-item-dash-offset, 0);
}

/* The value sits in the middle of the ring as real HTML text (selectable,
 * translatable, countable by view.js) instead of SVG <text>. */
.wpminty-pb-item--circle .wpminty-pb-item__value {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
}

.wpminty-pb-item--circle .wpminty-pb-item__number {
	font-size: 1.5em;
}

/* ---------------------------------------------------------------------------
 * Line dividers between items (Counter precedent)
 *
 * The line is painted by the item pseudo-elements in the middle of the
 * layout gap, so it works for both directions: vertical lines between
 * side-by-side circles, horizontal lines between stacked bars, switching
 * automatically when the flex layout wraps. Lines that would hang outside
 * the first column or row are cut off by clipping the container at its
 * content box.
 * ------------------------------------------------------------------------- */

.wp-block-wpminty-progress-bar.has-dividers {
	/* Mirrors core's own gap fallbacks; overridden inline when blockGap is set. */
	--wpminty-pb-divider-gap-x: var(--wp--style--block-gap, 0.5em);
	--wpminty-pb-divider-gap-y: var(--wp--style--block-gap, 0.5em);
	overflow: clip;
	overflow-clip-margin: content-box;
}

.wp-block-wpminty-progress-bar.has-dividers .wpminty-pb-item::before,
.wp-block-wpminty-progress-bar.has-dividers .wpminty-pb-item::after {
	content: "";
	position: absolute;
	pointer-events: none;
	border: 0 var(--wpminty-pb-divider-style) var(--wpminty-pb-divider-color);
}

/* Column divider, extended into the row gaps so wrapped lines meet cleanly.
 * No line may precede the first item (N items = N - 1 lines). On the
 * front-end the item itself is the container child; in the editor every
 * item sits alone inside its block-list wrapper, so both DOM shapes are
 * covered. Full-width bars rely on the container clip for the outer edges
 * of wrapped rows, where this line lands outside the content box anyway;
 * content-sized items (circles) are centered, so the exclusion is what
 * keeps their leading space clean. */
.wp-block-wpminty-progress-bar.has-dividers .wpminty-pb-item:not(:first-child)::before,
.wp-block-wpminty-progress-bar.has-dividers > :not(:first-child) .wpminty-pb-item:first-child::before {
	inset-block: calc(-1 * var(--wpminty-pb-divider-gap-y) / 2);
	inset-inline-start: calc(-1 * var(--wpminty-pb-divider-gap-x) / 2);
	border-inline-start-width: var(--wpminty-pb-divider-width);
}

/* Row divider. */
.wp-block-wpminty-progress-bar.has-dividers .wpminty-pb-item::after {
	inset-inline: calc(-1 * var(--wpminty-pb-divider-gap-x) / 2);
	inset-block-start: calc(-1 * var(--wpminty-pb-divider-gap-y) / 2);
	border-block-start-width: var(--wpminty-pb-divider-width);
}

/* Editor compensation: on the front end every item IS the flex child and
 * stretches with its row, so the item-anchored divider lines span the full
 * row height. In the editor each item sits inside a block-list wrapper that
 * takes the flex slot while the item keeps its content height, leaving the
 * lines shorter than the row. Only the height is compensated — the wrapper
 * keeps its plain block formatting context, because reformatting it (grid or
 * flex) breaks the circle item's centered column layout. When the stretched
 * wrapper height does not resolve for a percentage, the item simply keeps
 * its content height (the pre-compensation state). The front end has no
 * wrapper, so this never matches there. */
.wp-block-wpminty-progress-bar.has-dividers .block-editor-block-list__block .wpminty-pb-item {
	height: 100%;
}

/* ---------------------------------------------------------------------------
 * Screen reader announcement (maintained by view.js after the animation)
 * ------------------------------------------------------------------------- */

.wpminty-pb__live {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* ---------------------------------------------------------------------------
 * Reduced motion
 * ------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	.wpminty-pb-item__fill,
	.wpminty-pb-item__fill::after,
	.wpminty-pb-item__fill-ring,
	.wpminty-pb-item__number {
		transition: none;
		animation: none;
	}
}
