/**
 * ThemeFour Shamsi — [shamsi_seasons] widget.
 *
 * The four Jalali seasons as a tabbed stage: a gradient sky per season, a
 * drifting particle layer, and a glass card carrying the season name, its three
 * months and a short line of prose.
 *
 * Two deliberate decisions live in this file.
 *
 * 1. The tabs are hidden radio inputs driven purely by CSS, so switching season
 *    works with JavaScript disabled and needs no re-render. The panels are
 *    siblings of the inputs, which is what makes the ~ combinator possible.
 * 2. The weather is CSS, not a canvas. A canvas particle system holds a
 *    requestAnimationFrame loop open for as long as the page is, which costs
 *    battery on every visit for a purely decorative effect. Tiled gradients
 *    moved by transform are composited, stop the moment a panel is hidden and
 *    disappear entirely under prefers-reduced-motion.
 */

.tfs-seasons {
	--tfs-spring: #4ea862;
	--tfs-summer: #e0952b;
	--tfs-autumn: #b5651d;
	--tfs-winter: #3e7cb1;
	--tfs-gold: #e8a93d;
	--tfs-radius: 26px;
	--tfs-height: 460px;

	box-sizing: border-box;
	inline-size: 100%;
	max-inline-size: 760px;
	margin-inline: auto;
	font-family: inherit;
	line-height: 1.7;
	direction: rtl;

	container-type: inline-size;
	container-name: tfs;
}

.tfs-seasons *,
.tfs-seasons *::before,
.tfs-seasons *::after {
	box-sizing: border-box;
}

/* The radios carry the state. Kept in the accessibility tree (they are a real
   radio group with real labels) but visually replaced by the tab pills. */
.tfs-radio {
	position: absolute;
	inline-size: 1px;
	block-size: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* ---------- Tabs ---------- */
.tfs-tabs {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 8px;
	margin-block-end: 18px;
}

/* Each tab carries its own season colour as an opaque tint with dark ink, so
   the contrast is fixed by the widget rather than inherited from whatever it
   was dropped onto. The dot repeats the colour for anyone who cannot rely on
   the tint alone. */
.tfs-tab {
	--tfs-c: #7a8a92;
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 9px 18px;
	border-radius: 999px;
	border: 1px solid color-mix(in srgb, var(--tfs-c) 42%, transparent);
	/*
	 * The pill is always a pale tint of the season colour and its ink is
	 * always a near-black carrying only a trace of that colour. Both anchors
	 * are fixed, so the pair stays legible whatever hue is chosen: mixing the
	 * ink mostly *from* the colour, as this rule used to, produced mid-grey
	 * text on a near-white pill as soon as someone picked a pale or a very
	 * bright season colour.
	 */
	background: color-mix(in srgb, var(--tfs-c) 14%, #ffffff);
	color: color-mix(in srgb, var(--tfs-c) 34%, #10151a);
	font-size: 0.86em;
	font-weight: 700;
	cursor: pointer;
	transition: background 0.22s ease, color 0.22s ease, transform 0.22s ease;
}

.tfs-tab-spring { --tfs-c: var(--tfs-spring); }
.tfs-tab-summer { --tfs-c: var(--tfs-summer); }
.tfs-tab-autumn { --tfs-c: var(--tfs-autumn); }
.tfs-tab-winter { --tfs-c: var(--tfs-winter); }

.tfs-dot {
	inline-size: 9px;
	block-size: 9px;
	flex: none;
	border-radius: 50%;
	background: var(--tfs-c);
	box-shadow: 0 0 0 2px color-mix(in srgb, var(--tfs-c) 22%, transparent);
}

.tfs-tab:hover {
	background: color-mix(in srgb, var(--tfs-c) 24%, #ffffff);
	border-color: color-mix(in srgb, var(--tfs-c) 62%, transparent);
}

/* Keyboard focus lands on the hidden radio, so the visible pill has to show
   it — otherwise the tab strip is unusable without a mouse. */
.tfs-radio:focus-visible + .tfs-tab {
	outline: 2px solid var(--tfs-gold);
	outline-offset: 2px;
}

/* ---------- Stage ---------- */
/* White ink belongs to the stage, not to the whole widget. The tabs live above
   it on the page's own background, which may be light, so inheriting white
   there left the unselected tabs nearly invisible. */
.tfs-stage {
	color: #fff;
	position: relative;
	overflow: hidden;
	min-block-size: var(--tfs-height);
	border-radius: var(--tfs-radius);
	border: 1px solid rgba(255, 255, 255, 0.1);
	box-shadow: 0 40px 80px -34px rgba(0, 0, 0, 0.6);
}

.tfs-panel {
	display: none;
	position: relative;
	min-block-size: var(--tfs-height);
	padding: 26px 20px;
}

/* Panels stack their own layers: sky, weather, then the card on top. */
.tfs-sky {
	position: absolute;
	inset: 0;
}

.tfs-fx {
	position: absolute;
	inset: 0;
	pointer-events: none;
	overflow: hidden;
}

.tfs-fx i {
	position: absolute;
	inset: 0;
	display: block;
	background-repeat: repeat;
	animation: tfs-drift var(--tfs-speed, 96s) linear infinite;
}

/* The pattern scrolls; the layer itself never moves.
 *
 * It used to be the other way round: the layer was made 12% larger than the
 * panel and slid with `transform`. Two things were wrong with that. It slid
 * further than it overhung, so a bare band opened along the top edge and grew
 * until the cycle restarted, and it slid sideways by a flat 18px, which is not
 * a whole number of tiles, so at the restart the entire field snapped
 * sideways. Both were measurable: freezing the layer at 0% and at 100% of one
 * cycle produced two visibly different frames.
 *
 * Moving the background instead removes the question of coverage entirely,
 * since a repeating pattern has no edges to run out of, and the loop closes
 * exactly whenever the travel is a whole number of tiles. Falling six tiles for
 * every one tile of sideways drift keeps the shallow angle the layer always had
 * while making both components whole tiles. Each season's duration is scaled by
 * the same six, so nothing changed speed.
 *
 * `--tfs-ox` and `--tfs-oy` are the starting corner, which is how the second
 * copy is offset now that it can no longer carry a static
 * `background-position` of its own.
 */
@keyframes tfs-drift {
	from {
		background-position: var(--tfs-ox, 0px) var(--tfs-oy, 0px);
		-webkit-mask-position: var(--tfs-ox, 0px) var(--tfs-oy, 0px);
		mask-position: var(--tfs-ox, 0px) var(--tfs-oy, 0px);
	}

	to {
		background-position:
			calc(var(--tfs-ox, 0px) - var(--tfs-tile, 96px))
			calc(var(--tfs-oy, 0px) + 6 * var(--tfs-tile, 96px));
		-webkit-mask-position:
			calc(var(--tfs-ox, 0px) - var(--tfs-tile, 96px))
			calc(var(--tfs-oy, 0px) + 6 * var(--tfs-tile, 96px));
		mask-position:
			calc(var(--tfs-ox, 0px) - var(--tfs-tile, 96px))
			calc(var(--tfs-oy, 0px) + 6 * var(--tfs-tile, 96px));
	}
}

.tfs-card-wrap {
	position: relative;
	z-index: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	min-block-size: calc(var(--tfs-height) - 52px);
}

.tfs-card {
	max-inline-size: 420px;
	padding: 32px 28px;
	border-radius: 22px;
	border: 1px solid rgba(255, 255, 255, 0.26);
	background: rgba(18, 20, 26, 0.34);
	backdrop-filter: blur(10px);
	box-shadow: 0 20px 50px -22px rgba(0, 0, 0, 0.55);
	text-align: center;
}

.tfs-name {
	font-size: 1.85em;
	font-weight: 800;
	line-height: 1.25;
}

.tfs-tag {
	margin-block-start: 2px;
	font-size: 0.72em;
	letter-spacing: 0.24em;
	text-transform: uppercase;
	opacity: 0.72;
	direction: ltr;
}

.tfs-months {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 8px;
	margin-block-start: 18px;
}

.tfs-months span {
	padding: 5px 14px;
	border-radius: 999px;
	border: 1px solid rgba(255, 255, 255, 0.3);
	background: rgba(255, 255, 255, 0.16);
	font-size: 0.8em;
	font-weight: 600;
}

.tfs-poem {
	margin-block-start: 18px;
	font-size: 0.88em;
	opacity: 0.92;
}

/* Every panel carries the badge; only the panel matching data-current shows
   it. That way crossing a season boundary on a cached page is a single
   attribute rewrite instead of a re-render. */
.tfs-badge {
	display: none;
	margin-block-start: 18px;
	padding: 6px 15px;
	border-radius: 999px;
	background: rgba(255, 255, 255, 0.92);
	color: #23303a;
	font-size: 0.74em;
	font-weight: 700;
}

.tfs-seasons[data-current="spring"] .tfs-panel-spring .tfs-badge,
.tfs-seasons[data-current="summer"] .tfs-panel-summer .tfs-badge,
.tfs-seasons[data-current="autumn"] .tfs-panel-autumn .tfs-badge,
.tfs-seasons[data-current="winter"] .tfs-panel-winter .tfs-badge {
	display: inline-block;
}

/* ---------- CSS-only tab switching ---------- */
.tfs-radio:nth-of-type(1):checked ~ .tfs-stage .tfs-panel-spring,
.tfs-radio:nth-of-type(2):checked ~ .tfs-stage .tfs-panel-summer,
.tfs-radio:nth-of-type(3):checked ~ .tfs-stage .tfs-panel-autumn,
.tfs-radio:nth-of-type(4):checked ~ .tfs-stage .tfs-panel-winter {
	display: block;
	animation: tfs-fade 0.42s ease;
}

@keyframes tfs-fade {
	from { opacity: 0; transform: translateY(8px); }
	to { opacity: 1; transform: none; }
}

/*
 * Selected: a deeper tint of the same colour, a ring, a lift and a shadow.
 *
 * It used to fill the pill with the raw season colour and then hardcode the
 * ink: dark for spring and summer, white for autumn and winter. That only
 * worked while nobody changed the colours. A dark green spring left dark ink
 * on a dark pill at a contrast of 1.2 to 1, which is invisible. Selection is
 * now signalled by weight rather than by inverting the ink, so the same safe
 * ink serves both states and no hue can break it.
 */
.tfs-radio:nth-of-type(1):checked ~ .tfs-tabs .tfs-tab-spring,
.tfs-radio:nth-of-type(2):checked ~ .tfs-tabs .tfs-tab-summer,
.tfs-radio:nth-of-type(3):checked ~ .tfs-tabs .tfs-tab-autumn,
.tfs-radio:nth-of-type(4):checked ~ .tfs-tabs .tfs-tab-winter {
	background: color-mix(in srgb, var(--tfs-c) 30%, #ffffff);
	border-color: color-mix(in srgb, var(--tfs-c) 85%, transparent);
	box-shadow:
		inset 0 0 0 1px color-mix(in srgb, var(--tfs-c) 55%, transparent),
		0 6px 14px -8px color-mix(in srgb, var(--tfs-c) 70%, transparent);
	transform: translateY(-1px);
}

.tfs-radio:nth-of-type(1):checked ~ .tfs-tabs .tfs-tab-spring .tfs-dot,
.tfs-radio:nth-of-type(2):checked ~ .tfs-tabs .tfs-tab-summer .tfs-dot,
.tfs-radio:nth-of-type(3):checked ~ .tfs-tabs .tfs-tab-autumn .tfs-dot,
.tfs-radio:nth-of-type(4):checked ~ .tfs-tabs .tfs-tab-winter .tfs-dot {
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--tfs-c) 30%, transparent);
}

/* Without color-mix() the tint and the ink both fail open to a plain readable
   pill rather than to white-on-white. */
@supports not (background: color-mix(in srgb, red 10%, white)) {
	.tfs-tab {
		background: #f2f4f5;
		border-color: rgba(0, 0, 0, 0.16);
		color: #2b3a42;
	}

	.tfs-tab:hover {
		background: #e6eaec;
	}
}

/* Hiding the strip removes only the controls: the chosen radio stays checked,
   so its panel keeps showing through the same rules above. */
.tfs-seasons.tfs-no-tabs .tfs-tabs {
	display: none;
}

/* ---------- Season skies ----------
 *
 * Every stop is derived from the one colour the season owns, so changing that
 * colour repaints the whole panel. Until 3.13.0 only the final stop read the
 * variable and the rest were literal hex, which is why picking a colour used to
 * appear to change nothing but the bottom edge of the box.
 *
 * `--tfs-c` is set per panel so the four ramps below can be written once
 * against a single name. Each season keeps its own ramp shape, which is what
 * carries its character: spring and summer open pale and settle into the
 * colour, autumn deepens past it into soil, winter starts as a night sky and
 * lightens toward the horizon. Shape is the season; hue is the setting.
 *
 * `background-color` is declared separately and first on purpose. A browser
 * without `color-mix()` drops the whole `background-image` declaration as
 * invalid, and a separate longhand survives that, so the panel degrades to a
 * flat block of the chosen colour rather than to nothing at all.
 */
.tfs-panel-spring { --tfs-c: var(--tfs-spring); }
.tfs-panel-summer { --tfs-c: var(--tfs-summer); }
.tfs-panel-autumn { --tfs-c: var(--tfs-autumn); }
.tfs-panel-winter { --tfs-c: var(--tfs-winter); }

.tfs-sky {
	background-color: var(--tfs-c, #7a8a92);
}

.tfs-panel-spring .tfs-sky {
	background-image: linear-gradient(
		180deg,
		color-mix(in srgb, var(--tfs-c) 10%, #ffffff) 0%,
		color-mix(in srgb, var(--tfs-c) 34%, #ffffff) 35%,
		color-mix(in srgb, var(--tfs-c) 72%, #ffffff) 70%,
		var(--tfs-c) 100%
	);
}

.tfs-panel-summer .tfs-sky {
	background-image:
		radial-gradient(
			circle at 50% 4%,
			color-mix(in srgb, var(--tfs-c) 8%, #ffffff) 0%,
			color-mix(in srgb, var(--tfs-c) 34%, transparent) 16%,
			transparent 40%
		),
		linear-gradient(
			180deg,
			color-mix(in srgb, var(--tfs-c) 12%, #ffffff) 0%,
			color-mix(in srgb, var(--tfs-c) 44%, #ffffff) 40%,
			color-mix(in srgb, var(--tfs-c) 82%, #ffffff) 75%,
			var(--tfs-c) 100%
		);
}

.tfs-panel-autumn .tfs-sky {
	background-image: linear-gradient(
		180deg,
		color-mix(in srgb, var(--tfs-c) 18%, #ffffff) 0%,
		color-mix(in srgb, var(--tfs-c) 62%, #ffffff) 40%,
		var(--tfs-c) 75%,
		color-mix(in srgb, var(--tfs-c) 66%, #1a0d04) 100%
	);
}

.tfs-panel-winter .tfs-sky {
	background-image:
		radial-gradient(circle at 80% 12%, rgba(255, 255, 255, 0.24), transparent 42%),
		linear-gradient(
			180deg,
			color-mix(in srgb, var(--tfs-c) 42%, #05121e) 0%,
			color-mix(in srgb, var(--tfs-c) 68%, #06182a) 45%,
			color-mix(in srgb, var(--tfs-c) 88%, #0a2338) 78%,
			var(--tfs-c) 100%
		);
}

/* The card no longer flips its ink per season.
 *
 * It used to: spring and summer were known to be pale, so those two panels got
 * dark text on a white pane. That only held while the colours were fixed. The
 * moment a site owner picked a dark spring or a pale winter, the card was ink
 * on ink or white on white, with nothing in the CSS able to notice. The card
 * now carries its own dark pane on every season, so its contrast comes from the
 * card itself and no longer depends on the colour behind it. */
.tfs-card {
	background: rgba(13, 16, 22, 0.58);
	border-color: rgba(255, 255, 255, 0.28);
}

/* ---------- Weather layers ---------- */
.tfs-panel-spring .tfs-fx i {
	--tfs-tile: 104px;
	--tfs-speed: 102s;
	background-image: radial-gradient(ellipse 5px 3px, rgba(255, 255, 255, 0.9) 0 100%, transparent 101%);
	background-size: 104px 104px;
}

/* Summer motes rise rather than fall; the sign of the translation is the only
   difference, so it swaps the animation name instead of adding a layer. */
.tfs-panel-summer .tfs-fx i {
	--tfs-tile: 120px;
	--tfs-speed: 192s;
	background-image: radial-gradient(circle 2px, rgba(255, 255, 255, 0.55) 0 100%, transparent 101%);
	background-size: 120px 120px;
	animation-name: tfs-rise;
}

@keyframes tfs-rise {
	from {
		background-position: var(--tfs-ox, 0px) var(--tfs-oy, 0px);
	}

	to {
		background-position:
			calc(var(--tfs-ox, 0px) + var(--tfs-tile, 120px))
			calc(var(--tfs-oy, 0px) - 8 * var(--tfs-tile, 120px));
	}
}

.tfs-panel-autumn .tfs-fx i {
	--tfs-tile: 180px;
	--tfs-speed: 144s;
	/* Kept for browsers with no mask support, where the specks are still
	   better than an empty sky. Overridden below wherever masks work. */
	background-image: radial-gradient(ellipse 6px 3px, color-mix(in srgb, color-mix(in srgb, var(--tfs-c) 62%, #241205) 75%, transparent) 0 100%, transparent 101%);
	background-size: var(--tfs-tile) var(--tfs-tile);
}

@supports (mask-image: url("#a")) or (-webkit-mask-image: url("#a")) {
	.tfs-panel-autumn .tfs-fx i {
		background-image: none;
		background-color: color-mix(in srgb, color-mix(in srgb, var(--tfs-c) 62%, #241205) 82%, transparent);
		-webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20180%20180'%20fill='%23fff'%3E%3Cdefs%3E%3Cg%20id='l'%3E%3Cpath%20d='M0-9C5-5.4%206.2.9%200%207.2%20-6.2.9-5-5.4%200-9Z'/%3E%3Cpath%20d='M-.55%206.6H.55L.45%2011h-.9Z'/%3E%3C/g%3E%3C/defs%3E%3Cuse%20href='%23l'%20transform='translate(28%2030)rotate(-26)scale(1.55)'%20opacity='0.95'/%3E%3Cuse%20href='%23l'%20transform='translate(108%2016)rotate(41)scale(1.10)'%20opacity='0.72'/%3E%3Cuse%20href='%23l'%20transform='translate(108%20196)rotate(41)scale(1.10)'%20opacity='0.72'/%3E%3Cuse%20href='%23l'%20transform='translate(150%2078)rotate(-14)scale(1.35)'%20opacity='0.86'/%3E%3Cuse%20href='%23l'%20transform='translate(62%2096)rotate(64)scale(0.95)'%20opacity='0.62'/%3E%3Cuse%20href='%23l'%20transform='translate(16%20146)rotate(30)scale(1.25)'%20opacity='0.80'/%3E%3Cuse%20href='%23l'%20transform='translate(196%20146)rotate(30)scale(1.25)'%20opacity='0.80'/%3E%3Cuse%20href='%23l'%20transform='translate(112%20156)rotate(-49)scale(1.45)'%20opacity='0.90'/%3E%3C/svg%3E");
		mask-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20180%20180'%20fill='%23fff'%3E%3Cdefs%3E%3Cg%20id='l'%3E%3Cpath%20d='M0-9C5-5.4%206.2.9%200%207.2%20-6.2.9-5-5.4%200-9Z'/%3E%3Cpath%20d='M-.55%206.6H.55L.45%2011h-.9Z'/%3E%3C/g%3E%3C/defs%3E%3Cuse%20href='%23l'%20transform='translate(28%2030)rotate(-26)scale(1.55)'%20opacity='0.95'/%3E%3Cuse%20href='%23l'%20transform='translate(108%2016)rotate(41)scale(1.10)'%20opacity='0.72'/%3E%3Cuse%20href='%23l'%20transform='translate(108%20196)rotate(41)scale(1.10)'%20opacity='0.72'/%3E%3Cuse%20href='%23l'%20transform='translate(150%2078)rotate(-14)scale(1.35)'%20opacity='0.86'/%3E%3Cuse%20href='%23l'%20transform='translate(62%2096)rotate(64)scale(0.95)'%20opacity='0.62'/%3E%3Cuse%20href='%23l'%20transform='translate(16%20146)rotate(30)scale(1.25)'%20opacity='0.80'/%3E%3Cuse%20href='%23l'%20transform='translate(196%20146)rotate(30)scale(1.25)'%20opacity='0.80'/%3E%3Cuse%20href='%23l'%20transform='translate(112%20156)rotate(-49)scale(1.45)'%20opacity='0.90'/%3E%3C/svg%3E");
		-webkit-mask-size: var(--tfs-tile) var(--tfs-tile);
		mask-size: var(--tfs-tile) var(--tfs-tile);
		-webkit-mask-repeat: repeat;
		mask-repeat: repeat;
	}

}

.tfs-panel-winter .tfs-fx i {
	--tfs-tile: 88px;
	--tfs-speed: 114s;
	background-image: radial-gradient(circle 2.4px, rgba(255, 255, 255, 0.92) 0 100%, transparent 101%);
	background-size: 88px 88px;
}

/* A second, offset copy gives the field depth. It must not set `transform`:
   the drift keyframes own that property, and a static transform here would be
   silently overridden for the whole animation. Offset and pace only. */
.tfs-fx i + i {
	--tfs-ox: 41px;
	--tfs-oy: 27px;
	animation-duration: calc(var(--tfs-speed, 96s) * 1.7);
	animation-direction: reverse;
	opacity: 0.5;
}

/* ---------- Motion ---------- */
@media (prefers-reduced-motion: reduce) {
	.tfs-fx {
		display: none;
	}

	.tfs-radio:checked ~ .tfs-stage .tfs-panel {
		animation: none;
	}

	.tfs-tab {
		transition: none;
	}
}

/* ---------- Narrow containers ---------- */
@container tfs (max-width: 480px) {
	.tfs-seasons { --tfs-height: 500px; }
	.tfs-card { padding: 24px 18px; }
	.tfs-name { font-size: 1.5em; }
	.tfs-tab { padding: 8px 15px; font-size: 0.8em; }
}

/* Fallback for browsers without container queries. */
@supports not (container-type: inline-size) {
	@media (max-width: 480px) {
		.tfs-seasons { --tfs-height: 500px; }
		.tfs-card { padding: 24px 18px; }
		.tfs-name { font-size: 1.5em; }
		.tfs-tab { padding: 8px 15px; font-size: 0.8em; }
	}
}
