ui/optionspanel.razor.scss
// Shared options block (jump toggle + volume + gamepad). Designed in 1080-reference space (matches
// TitleScreen).
@import "Theme.scss";

OptionsPanel {
	flex-direction: column;
	align-items: center;
	font-family: $font;
	font-smooth: never;

	.rows {
		position: relative;
		flex-direction: column;
		gap: 16px;
		// Left lane the smiling-cube selector slides in. Keep in sync with ROW_PITCH and the
		// .selector width.
		padding-left: 72px;

		// The smiling-cube selector. Absolutely positioned so it slides smoothly between rows;
		// `top` and the frame (background-position) are set inline from the controller.
		// Row pitch = .row height (56) + gap (16) = 72px (ROW_PITCH in the razor). The sheet is
		// 7 frames wide, so background-size:700% makes one frame exactly fill the box.
		.selector {
			position: absolute;
			left: 0;
			top: 0;
			width: 56px;
			height: 56px;
			background-image: url( "sprites/menu_selector.png" );
			background-repeat: no-repeat;
			background-size: 700% 100%;
			image-rendering: pixelated;
		}

		// In-list section divider (GAMEPAD), styled like the top VOLUME heading. Explicit height
		// keeps the selector math deterministic — see GAMEPAD_GAP in the razor (margin-top 24 +
		// height 56 + one extra .rows gap 16 = 96). The negative margin-left cancels the selector
		// lane so the word centres over the whole block like VOLUME rather than over the row lane.
		.section {
			height: 56px;
			margin-top: 24px;
			margin-left: -72px;
			align-items: center;
			justify-content: center;
			font-size: 48px;
			// Pixel font reserves a tall line box (see .label); hug the glyphs so the word centres
			// in the 56px band rather than riding high.
			line-height: 0.8;
			color: $white;
			text-shadow: 4px 4px 0 $black;
		}

		.row {
			flex-direction: row;
			align-items: center;
			height: 56px;
			width: 620px;
			pointer-events: all;
			cursor: blank-hand;

			.label {
				font-size: 32px;
				// The pixel font reserves a tall line box with empty space below the glyphs; unhugged
				// it pushes the text above the row centre (leaving the centred selector cube low) and
				// inflates the row past its 56px height, drifting ROW_PITCH off further each row down.
				line-height: 0.8;
				color: $black;
				width: 200px;
				flex-shrink: 0;
			}

			.value {
				font-size: 32px;
				line-height: 0.8;
				color: $black;
				width: 64px;
				flex-shrink: 0;
				text-align: right;
			}

			// The slider itself is a self-styled PixelSlider component (its own stylesheet owns the
			// pixel/cube look — s&box stylesheets don't cascade into child components).
			.slider-wrap {
				flex-grow: 1;
				align-items: stretch;
				margin: 0 16px;
			}

			// Highlight the focused row (cube parity with the title menu).
			&.selected {
				.label,
				.value,
				.text {
					color: $white;
				}
			}
		}

		// The toggle row: label on the left (free to grow past the 200px slider-label lane, since
		// "DISABLE ↑ JUMP" is wider), checkbox pushed to the right where the slider value sits. The
		// PixelCheckbox is a self-styled child component (owns its own pixel look).
		.row.toggle {
			.label {
				width: auto;
				flex-grow: 1;
			}

			.checkbox-wrap {
				flex-shrink: 0;
				align-items: center;
				justify-content: center;
			}
		}

		.row.restart-delay .label {
			font-size: 24px;
			line-height: 1;
		}

		.row.back {
			justify-content: flex-start;
			// Extra gap above BACK (mirrored by BACK_GAP in the razor so the selector stays aligned).
			margin-top: 24px;

			.text {
				align-self: flex-start;
				width: auto;
				text-align: center;
				font-size: 40px;
				line-height: 0.8;   // hug the pixel-font glyphs (see .label) so the box padding is even
				color: $black;
				background-color: #c98a8a;   // desaturated red box, matching the score/replay BACK buttons
				padding: 6px 36px;
			}

			// .row.back .text ties specificity with the generic &.selected rule above and wins by
			// source order, so re-apply the focused colour explicitly for the BACK button.
			&.selected .text {
				color: $black;
				background-color: #d99a9a;
			}
		}
	}

	// The in-game overlay now uses the same bright teal checkerboard field as the main menu, so the
	// hosted panel styles identically whether or not it's `.dimmed` (the flag now only switches the
	// BACK/CLOSE wording in the razor). The near-black default labels read fine over the teal field.
}