/*!
 * Hard Piston Toolkit - Piston Meter
 * 高級スポーツカーのタコメーターを模したスコアメーター用スタイル。
 * BEM命名規則に準拠。全セレクタを .hpt- 名前空間配下に限定し、
 * テーマ（Cocoon等）とのCSS競合を防止する。
 */

.hpt-meter {
	--hpt-bg: #111111;
	--hpt-text: #ececec;
	--hpt-primary: #ff4fa3;
	--hpt-primary-rgb: 255, 79, 163;
	--hpt-max: #ff1493;
	--hpt-max-rgb: 255, 20, 147;
	--hpt-gray: #6f6f6f;
	--hpt-white: #ececec;
	--hpt-track: #2a2a2a;
	--hpt-accent-color: var(--hpt-gray);

	/* size属性によるスケール係数。カード・文字・数字・針(SVG)すべてが
	 * この一つの係数を軸に比率を保ったまま拡大縮小する。
	 * （SVG内の針・目盛り・弧はviewBoxベースのベクターのため、
	 * 　カード幅がスケールすれば自動的に比率を保って追従する。）
	 */
	--hpt-scale: 1;

	position: relative;
	box-sizing: border-box;
	max-width: calc(320px * var(--hpt-scale));
	width: 100%;
	margin: 0 auto;
	padding: calc(22px * var(--hpt-scale)) calc(18px * var(--hpt-scale)) calc(18px * var(--hpt-scale));
	overflow: hidden;
	isolation: isolate;

	/* マットブラック：微細なムラ・ヴィネットを重ねたブラッシュドメタル調の下地 */
	background:
		radial-gradient(120% 90% at 50% -20%, rgba(255, 255, 255, 0.05) 0%, rgba(255, 255, 255, 0) 55%),
		radial-gradient(140% 100% at 50% 115%, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0) 60%),
		linear-gradient(155deg, #1a1a1a 0%, #101010 45%, #0a0a0a 75%, #050505 100%);

	border: 1px solid rgba(255, 255, 255, 0.07);
	border-radius: calc(18px * var(--hpt-scale));

	/* 外側の落ち影＋上端のハイライト＋下端の深い内側シャドウでガラス/金属パネルの厚みを表現 */
	box-shadow:
		0 24px 48px rgba(0, 0, 0, 0.55),
		0 2px 6px rgba(0, 0, 0, 0.5),
		inset 0 1px 0 rgba(255, 255, 255, 0.08),
		inset 0 -18px 30px rgba(0, 0, 0, 0.55),
		inset 0 0 0 1px rgba(255, 255, 255, 0.02);

	color: var(--hpt-text);
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Hiragino Sans", "Noto Sans JP", Meiryo, sans-serif;
	line-height: 1.4;
}

.hpt-meter *,
.hpt-meter *::before,
.hpt-meter *::after {
	box-sizing: border-box;
}

/* ---- ガラス風の反射（斜めのグロス光沢） ----
 * カード左上から右へ抜ける薄い光の帯。pointer-eventsを切り、
 * クリック・タップ操作を阻害しないようにする。
 */
.hpt-meter::before {
	content: "";
	position: absolute;
	inset: -40% -20%;
	background: linear-gradient(
		115deg,
		rgba(255, 255, 255, 0) 30%,
		rgba(255, 255, 255, 0.06) 45%,
		rgba(255, 255, 255, 0.1) 50%,
		rgba(255, 255, 255, 0.02) 58%,
		rgba(255, 255, 255, 0) 70%
	);
	pointer-events: none;
	z-index: 1;
}

/* ---- 微細なマット粒状ノイズ（艶消し質感） ----
 * SVGのfeTurbulenceで生成したノイズをoverlay合成し、
 * のっぺりしがちなグラデーションに素材感を足す。
 */
.hpt-meter::after {
	content: "";
	position: absolute;
	inset: 0;
	background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
	background-size: 180px 180px;
	opacity: 0.035;
	mix-blend-mode: overlay;
	pointer-events: none;
	z-index: 1;
}

/* ---- テーマ質感用テクスチャ層 ----
 * theme="carbon" の時のみカーボン柄を表示するための専用要素。
 * ::before/::after は既にガラス反射・ノイズで使用しているため、
 * 干渉を避けて別要素として用意している（常にDOMには存在し、CSSで出し分ける）。
 */
.hpt-meter__texture {
	display: none;
	position: absolute;
	inset: 0;
	pointer-events: none;
	z-index: 1;
}

.hpt-meter__title,
.hpt-meter__body {
	position: relative;
	z-index: 2;
}

.hpt-meter__title {
	margin: 0 0 calc(10px * var(--hpt-scale));
	font-size: calc(17px * var(--hpt-scale));
	font-weight: 800;
	letter-spacing: 0.16em;
	text-align: center;
	text-transform: uppercase;
	color: var(--hpt-meter-title-color, var(--hpt-text));
}

.hpt-meter__body {
	position: relative;
	width: 100%;
	padding: calc(10px * var(--hpt-scale)) calc(6px * var(--hpt-scale)) calc(4px * var(--hpt-scale));
	border-radius: calc(14px * var(--hpt-scale));

	/* ダイヤルがパネルに一段沈み込んでいるような内側シャドウ */
	background: linear-gradient(180deg, rgba(0, 0, 0, 0.35) 0%, rgba(0, 0, 0, 0) 40%);
	box-shadow:
		inset 0 6px 14px rgba(0, 0, 0, 0.5),
		inset 0 -1px 0 rgba(255, 255, 255, 0.04);
}

.hpt-meter__svg {
	display: block;
	width: 100%;
	height: auto;
	overflow: visible;
}

/* ---- 目盛りトラック（背景の弧） ---- */
.hpt-meter__track {
	fill: none;
	stroke: var(--hpt-track);
	stroke-width: 6;
	stroke-linecap: round;
}

/* ---- スコアに応じて伸びるプログレスの弧 ---- */
.hpt-meter__progress {
	fill: none;
	stroke: var(--hpt-accent-color);
	stroke-width: 6;
	stroke-linecap: round;
	transition: stroke 0.6s ease-out;
}

/* ---- 目盛り線 ---- */
.hpt-meter__tick {
	stroke: #4a4a4a;
	stroke-width: 1.4;
}

.hpt-meter__tick--major {
	stroke: #7a7a7a;
	stroke-width: 2;
}

.hpt-meter__tick-label {
	fill: #b6b6b6;
	font-size: 8.4px;
	font-weight: 700;
	font-family: inherit;
}

/* ---- 針 ----
 * 回転は必ずJS側でSVGの transform="rotate(angle 100 100)" 属性として付与する。
 * viewBox座標(100,100)＝メーター中心と完全に一致させるため、
 * CSSの transform / transform-origin は意図的に一切使用しない。
 * （CSSのtransform-originはレスポンシブでスケールされた表示px基準になり、
 * 　viewBoxのuser unit基準とズレて針が中心からずれる原因になるため。）
 */
.hpt-meter__needle {
	stroke: var(--hpt-accent-color);
	stroke-width: 3;
	stroke-linecap: round;
	transition: stroke 0.6s ease-out;
}

.hpt-meter__needle-tail {
	stroke: var(--hpt-accent-color);
	stroke-width: 3;
	stroke-linecap: round;
	opacity: 0.5;
	transition: stroke 0.6s ease-out;
}

.hpt-meter__hub {
	fill: #1a1a1a;
	stroke: var(--hpt-accent-color);
	stroke-width: 2;
	transition: stroke 0.6s ease-out;
}

.hpt-meter__hub-inner {
	fill: var(--hpt-accent-color);
	transition: fill 0.6s ease-out;
}

/* ---- スコア表示（カード内で最も視認性を優先する主役要素） ---- */
.hpt-meter__score {
	margin-top: -2px;
	display: flex;
	align-items: flex-end;
	justify-content: center;
	gap: calc(3px * var(--hpt-scale));
}

.hpt-meter__score-number {
	font-size: calc(56px * var(--hpt-scale));
	font-weight: 900;
	font-variant-numeric: tabular-nums;
	color: var(--hpt-accent-color);
	letter-spacing: -0.015em;
	line-height: 1;
	transition: color 0.6s ease-out;

	/* 数字そのものを太く・くっきり見せるための輪郭補強 */
	-webkit-text-stroke: 0.6px currentColor;
}

/* ---- 満点表示（"score / max" の "/ max" 部分）
 * max属性が既定値(100)以外のときのみ出力される。数字本体より小さく、
 * 控えめな色にしてスコア数字を主役として引き立てる。
 */
.hpt-meter__score-max {
	font-size: calc(22px * var(--hpt-scale));
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	line-height: 1;
	padding-bottom: calc(6px * var(--hpt-scale));
	color: #b0b0b0;
}

.hpt-meter__score-suffix {
	font-size: calc(12px * var(--hpt-scale));
	font-weight: 600;
	line-height: 1;
	padding-bottom: calc(5px * var(--hpt-scale));
	color: #a6a6a6;
}

/* =========================================================
 * スコア帯（バンド）別のアクセントカラー
 * low: グレー / mid: 白 / high: ピンク / max: ネオンピンク
 * ========================================================= */

.hpt-meter[data-band="low"] {
	--hpt-accent-color: var(--hpt-gray);
}

.hpt-meter[data-band="mid"] {
	--hpt-accent-color: var(--hpt-white);
}

.hpt-meter[data-band="high"] {
	--hpt-accent-color: var(--hpt-primary);
}

.hpt-meter[data-band="max"] {
	--hpt-accent-color: var(--hpt-max);
}

/* =========================================================
 * color属性：カラーバリエーション
 * 針・メーター（進捗弧/目盛り）・数字・ネオン発光すべてに反映される。
 * low(グレー) / mid(白) はスコア帯として中立色を維持し、
 * high(80〜89) / max(90〜100・ネオン) のみブランドカラーに追従する。
 * ========================================================= */

.hpt-meter[data-color="pink"] {
	--hpt-primary: #ff4fa3;
	--hpt-primary-rgb: 255, 79, 163;
	--hpt-max: #ff1493;
	--hpt-max-rgb: 255, 20, 147;
}

.hpt-meter[data-color="red"] {
	--hpt-primary: #ff4f4f;
	--hpt-primary-rgb: 255, 79, 79;
	--hpt-max: #ff1a1a;
	--hpt-max-rgb: 255, 26, 26;
}

.hpt-meter[data-color="blue"] {
	--hpt-primary: #4f9dff;
	--hpt-primary-rgb: 79, 157, 255;
	--hpt-max: #0066ff;
	--hpt-max-rgb: 0, 102, 255;
}

.hpt-meter[data-color="green"] {
	--hpt-primary: #4fe38a;
	--hpt-primary-rgb: 79, 227, 138;
	--hpt-max: #00d26a;
	--hpt-max-rgb: 0, 210, 106;
}

.hpt-meter[data-color="orange"] {
	--hpt-primary: #ff9d4f;
	--hpt-primary-rgb: 255, 157, 79;
	--hpt-max: #ff7a00;
	--hpt-max-rgb: 255, 122, 0;
}

.hpt-meter[data-color="purple"] {
	--hpt-primary: #b34fff;
	--hpt-primary-rgb: 179, 79, 255;
	--hpt-max: #9000ff;
	--hpt-max-rgb: 144, 0, 255;
}

/* =========================================================
 * theme属性：カードの質感バリエーション
 * dark   : 既定のマットブラック（1.0 Alphaのデザインをそのまま維持）
 * carbon : マットブラック＋控えめなカーボン柄
 * glass  : ガラス風の半透明カード
 * ========================================================= */

/* dark（既定）: ベースの .hpt-meter で定義済みのため上書き不要。
 * 明示のため空セレクタは置かず、コメントのみとする。 */

.hpt-meter[data-theme="carbon"] .hpt-meter__texture {
	display: block;

	/* 45度/-135度の細い縞を重ねてカーボン繊維の綾織り風パターンを再現。
	 * 画像アセットを使わずCSSのみで軽量に表現し、あくまで控えめな柄に留める。 */
	background-image:
		repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.05) 0 1.5px, rgba(255, 255, 255, 0) 1.5px 5px),
		repeating-linear-gradient(-45deg, rgba(0, 0, 0, 0.45) 0 1.5px, rgba(0, 0, 0, 0) 1.5px 5px);
	background-size: 7px 7px;
	opacity: 0.55;
	mix-blend-mode: overlay;
}

.hpt-meter[data-theme="glass"] {
	/* ガラス風カード：半透明＋背景ぼかしで、光を透過する質感を表現 */
	background:
		linear-gradient(160deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.03) 45%, rgba(10, 10, 10, 0.4) 100%);
	border: 1px solid rgba(255, 255, 255, 0.16);
	backdrop-filter: blur(18px) saturate(140%);
	-webkit-backdrop-filter: blur(18px) saturate(140%);
	box-shadow:
		0 20px 44px rgba(0, 0, 0, 0.4),
		inset 0 1px 0 rgba(255, 255, 255, 0.22),
		inset 0 -14px 26px rgba(0, 0, 0, 0.3);
}

.hpt-meter[data-theme="glass"] .hpt-meter__body {
	background: linear-gradient(180deg, rgba(0, 0, 0, 0.22) 0%, rgba(0, 0, 0, 0) 40%);
	box-shadow:
		inset 0 6px 14px rgba(0, 0, 0, 0.3),
		inset 0 -1px 0 rgba(255, 255, 255, 0.08);
}

/* =========================================================
 * size属性：スケール係数
 * カード・タイトル・数字・pt・SVG（針/目盛り/弧）すべてが
 * --hpt-scale 一つの値を軸に比率を保ったまま拡大縮小する。
 * ========================================================= */

.hpt-meter[data-size="small"] {
	--hpt-scale: 0.8;
}

.hpt-meter[data-size="medium"] {
	--hpt-scale: 1;
}

.hpt-meter[data-size="large"] {
	--hpt-scale: 1.2;
}

.hpt-meter[data-size="xlarge"] {
	--hpt-scale: 1.45;
}

/* ---- ネオン発光エフェクト（針・数字・目盛り）
 * 派手さより高級感を優先し、発光量を控えめ（従来の目安75%程度）に調整。
 * ぼんやりと上質に光る程度に留める。
 * 色はcolor属性で選択された --hpt-max-rgb に自動で追従する。
 *
 * 発光させるかどうかは data-glow-active（true/false）で判定する。
 * この値はPHP側（Meter::resolve_glow_active()）で
 * glow属性（auto/on/off）とスコア帯を踏まえて一元的に決定済みのため、
 * CSS側はスコア帯を意識せず data-glow-active のみを見ればよい。
 *   glow="auto"（既定）: 従来仕様どおり達成率90%以上のみ true
 *   glow="on"          : スコアに関わらず常に true
 *   glow="off"         : スコアに関わらず常に false
 */
.hpt-meter[data-glow-active="true"] .hpt-meter__needle,
.hpt-meter[data-glow-active="true"] .hpt-meter__needle-tail,
.hpt-meter[data-glow-active="true"] .hpt-meter__hub {
	filter: drop-shadow(0 0 2.2px var(--hpt-max)) drop-shadow(0 0 5.3px rgba(var(--hpt-max-rgb), 0.45));
}

.hpt-meter[data-glow-active="true"] .hpt-meter__progress {
	filter: drop-shadow(0 0 3px var(--hpt-max));
}

.hpt-meter[data-glow-active="true"] .hpt-meter__tick--major,
.hpt-meter[data-glow-active="true"] .hpt-meter__tick {
	stroke: var(--hpt-max);
	filter: drop-shadow(0 0 1.5px rgba(var(--hpt-max-rgb), 0.53));
}

.hpt-meter[data-glow-active="true"] .hpt-meter__score-number {
	text-shadow: 0 0 4.5px rgba(var(--hpt-max-rgb), 0.56), 0 0 12px rgba(var(--hpt-max-rgb), 0.26);
}

/* ゆっくり呼吸するようなネオンの明滅
 * 高級オーディオのLEDやアンビエントライトのように、
 * ゆっくり・弱く・上品に光る速度感へ調整（3.2s→5.5sへ延長）。
 */
.hpt-meter[data-glow-active="true"].is-animated .hpt-meter__score-number,
.hpt-meter[data-glow-active="true"].is-animated .hpt-meter__needle,
.hpt-meter[data-glow-active="true"].is-animated .hpt-meter__hub {
	animation: hpt-neon-breathe 5.5s ease-in-out infinite;
}

@keyframes hpt-neon-breathe {
	0%,
	100% {
		filter: drop-shadow(0 0 1.5px var(--hpt-max)) drop-shadow(0 0 3.8px rgba(var(--hpt-max-rgb), 0.34));
	}
	50% {
		filter: drop-shadow(0 0 3.8px var(--hpt-max)) drop-shadow(0 0 9px rgba(var(--hpt-max-rgb), 0.6));
	}
}

.hpt-meter[data-glow-active="true"].is-animated .hpt-meter__score-number {
	animation-name: hpt-neon-breathe-text;
}

@keyframes hpt-neon-breathe-text {
	0%,
	100% {
		text-shadow: 0 0 3px rgba(var(--hpt-max-rgb), 0.41), 0 0 7.5px rgba(var(--hpt-max-rgb), 0.19);
	}
	50% {
		text-shadow: 0 0 6px rgba(var(--hpt-max-rgb), 0.68), 0 0 15px rgba(var(--hpt-max-rgb), 0.38);
	}
}

/* =========================================================
 * アクセシビリティ
 * ========================================================= */

.hpt-meter .screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

@media (prefers-reduced-motion: reduce) {
	.hpt-meter[data-glow-active="true"].is-animated .hpt-meter__score-number,
	.hpt-meter[data-glow-active="true"].is-animated .hpt-meter__needle,
	.hpt-meter[data-glow-active="true"].is-animated .hpt-meter__hub {
		animation: none;
	}

	.hpt-meter__needle-group,
	.hpt-meter__progress,
	.hpt-meter__score-number {
		transition: none !important;
	}
}

/* ---- animate="off": 最初から完成状態で出力されるため、
 * 万一プロパティが変化してもトランジションが走らないようにしておく
 * （実行コストの無駄な発生を防ぐ念のためのガード）。
 */
.hpt-meter[data-animate="off"] .hpt-meter__needle-group,
.hpt-meter[data-animate="off"] .hpt-meter__progress,
.hpt-meter[data-animate="off"] .hpt-meter__needle,
.hpt-meter[data-animate="off"] .hpt-meter__needle-tail,
.hpt-meter[data-animate="off"] .hpt-meter__hub,
.hpt-meter[data-animate="off"] .hpt-meter__hub-inner,
.hpt-meter[data-animate="off"] .hpt-meter__score-number {
	transition: none;
}

/* =========================================================
 * variant="compact"：汎用コンパクトメーター
 *
 * タイムライン・ランキング・比較表・関連記事・作品一覧など、
 * 他のカードの中に埋め込んで使うための軽量表示モード。
 * カード自体の装飾（背景/枠/シャドウ/ガラス反射/ノイズ）だけをCSSで
 * 打ち消し、--hpt-scale をさらに縮小することで、他のすべてのプロパティ
 * （タイトル・数字・SVG＝針/目盛り/弧のサイズ）は既存の calc(Xpx * var(--hpt-scale))
 * 計算式がそのまま連動して縮小される。render_meter() 側の描画ロジック・
 * 針/目盛り/アニメーション/Glow等の機能は default と100%共通。
 * ========================================================= */

.hpt-meter[data-variant="compact"] {
	/* size属性（small/medium/large/xlarge）による --hpt-scale の値を
	 * さらに約45%へ縮小する（従来は55%）。cascade順の都合で、このルールは
	 * data-size系ルールより後方に置くこと。
	 *
	 * 0.55→0.45への変更は、タイムライン内での標準的な組み合わせ
	 * （size="small" = 0.8）を基準に「現在より約15〜20%小さく」という
	 * 要件を満たすよう校正した値（0.8×0.55=0.44 → 0.8×0.45=0.36、約18%減）。
	 * transform:scale() は一切使わず、この係数によって
	 * calc(Xpx * var(--hpt-scale)) を参照する全プロパティ
	 * （メーター直径＝SVGのwidth、針・目盛りのSVG内座標、タイトル・数値の
	 * font-size、余白のpadding/gap）が比率を保ったまま再計算される。
	 * compactはタイムライン専用ではなく、ランキング・比較表・関連記事・
	 * 作品一覧など他のカードでも共通利用する前提の値としている。 */
	--hpt-scale: calc(var(--hpt-scale) * 0.45);

	background: none;
	border: none;
	border-radius: 0;
	box-shadow: none;
	backdrop-filter: none;
	-webkit-backdrop-filter: none;
	padding: calc(4px * var(--hpt-scale)) 0 0;
	max-width: 100%;
	width: 100%;
}

.hpt-meter[data-variant="compact"]::before,
.hpt-meter[data-variant="compact"]::after,
.hpt-meter[data-variant="compact"] .hpt-meter__texture {
	display: none;
}

.hpt-meter[data-variant="compact"] .hpt-meter__body {
	background: none;
	box-shadow: none;
	padding: 0;
}

/* =========================================================
 * レスポンシブ
 * ========================================================= */

@media (max-width: 782px) {
	.hpt-meter {
		max-width: calc(280px * var(--hpt-scale));
		padding: calc(16px * var(--hpt-scale)) calc(12px * var(--hpt-scale)) calc(12px * var(--hpt-scale));
	}

	.hpt-meter__title {
		font-size: calc(16px * var(--hpt-scale));
	}

	.hpt-meter__score-number {
		font-size: calc(48px * var(--hpt-scale));
	}

	.hpt-meter__score-suffix {
		font-size: calc(11px * var(--hpt-scale));
	}
}

@media (max-width: 480px) {
	.hpt-meter {
		max-width: 100%;
		padding: calc(14px * var(--hpt-scale)) calc(10px * var(--hpt-scale)) calc(10px * var(--hpt-scale));
	}

	.hpt-meter__title {
		font-size: calc(15px * var(--hpt-scale));
		letter-spacing: 0.12em;
	}

	.hpt-meter__score-number {
		font-size: calc(42px * var(--hpt-scale));
	}

	.hpt-meter__score-suffix {
		font-size: calc(11px * var(--hpt-scale));
	}
}
