/*!
 * @be-partner-labs/ds v1.8.0 — components/radio
 * © 2026 Be Partner Labs. MIT License.
 *
 * CDN:  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@be-partner-labs/ds@1.8.0/dist/components/radio.min.css">
 * npm:  @import "@be-partner-labs/ds/components/radio";
 * Docs: https://ds.bepartnerlabs.com/components/radio/
 */
@layer bp-tokens, bp-reset, bp-grid, bp-components, bp-utilities;

@layer bp-components {
	/**
	 * .bp-radio
	 * Single radio control — label wraps input for implicit association.
	 *
	 * .bp-radio-group
	 * Fieldset wrapper for a group of radio buttons.
	 *
	 * Public API:
	 *   --radio-size                Circle diameter
	 *   --radio-dot-size            Inner dot diameter
	 *   --radio-color               Checked ring and dot color
	 *   --radio-border              Unchecked border
	 *   --radio-background                  Unchecked background
	 *   --radio-gap                 Control-to-label gap
	 *   --radio-group-gap           Vertical group gap between items
	 *   --radio-group-gap-horizontal Horizontal group gap between items
	 *   --radio-label-color         Label text color
	 *   --radio-error-color         Error message color
	 */
	.bp-radio {
		--_size: var(--radio-size, 1.125rem);
		--_dot-size: var(--radio-dot-size, 0.5rem);
		--_color: var(--radio-color, var(--bp-primary));
		--_border: var(--radio-border, 1px solid var(--bp-color-border));
		--_background: var(--radio-background, var(--bp-color-bg-elevated));
		--_gap: var(--radio-gap, var(--bp-space-2));
		--_label-color: var(--radio-label-color, var(--bp-color-text));

		display: inline-flex;
		align-items: center;
		gap: var(--_gap);
		cursor: pointer;
	}

	/* Hide the native radio input visually but keep it accessible */
	.bp-radio__input {
		appearance: none;
		-webkit-appearance: none;
		flex-shrink: 0;
		width: var(--_size);
		height: var(--_size);
		border: var(--_border);
		border-radius: var(--bp-radius-full);
		background-color: var(--_background);
		transition:
			border-color var(--bp-duration-fast) var(--bp-ease),
			box-shadow var(--bp-duration-fast) var(--bp-ease);
		cursor: pointer;
	}

	/* The dot is rendered as a ::before pseudo on the label element,
	   positioned relative to itself using a negative margin trick so
	   it overlaps the input circle. We use the sibling combinator. */
	.bp-radio__label {
		position: relative;
		font-size: var(--bp-text-base);
		color: var(--_label-color);
		line-height: var(--bp-leading-normal);
	}

	/* Dot pseudo-element — positioned to float over the input circle */
	.bp-radio__label::before {
		content: '';
		position: absolute;
		/* center dot over the input: input is --_size wide, dot is --_dot-size wide */
		left: calc(-1 * var(--_gap) - var(--_size) / 2 - var(--_dot-size) / 2);
		top: 50%;
		transform: translateY(-50%) scale(0);
		width: var(--_dot-size);
		height: var(--_dot-size);
		border-radius: var(--bp-radius-full);
		background-color: var(--_color);
		transition: transform var(--bp-duration-fast) var(--bp-ease);
		pointer-events: none;
	}

	/* Checked state: show dot and switch border to accent color */
	.bp-radio__input:checked {
		border-color: var(--_color);
	}

	.bp-radio__input:checked + .bp-radio__label::before {
		transform: translateY(-50%) scale(1);
	}

	/* Hover state */
	.bp-radio:hover .bp-radio__input:not(:disabled) {
		border-color: var(--_color);
	}

	/* Focus-visible ring */
	.bp-radio__input:focus-visible {
		outline: none;
		box-shadow: var(--bp-focus-ring);
	}

	/* Disabled state */
	.bp-radio__input:disabled {
		opacity: 0.5;
		cursor: not-allowed;
	}

	.bp-radio:has(.bp-radio__input:disabled) {
		cursor: not-allowed;
		opacity: 0.5;
	}

	/* ── Group ── */
	.bp-radio-group {
		--_group-gap: var(--radio-group-gap, var(--bp-space-3));
		--_error-color: var(--radio-error-color, var(--bp-color-error));

		display: flex;
		flex-direction: column;
		gap: var(--_group-gap);
		border: none;
		padding: 0;
		margin: 0;
	}

	.bp-radio-group__legend {
		font-size: var(--bp-text-sm);
		font-weight: var(--bp-font-weight-medium);
		color: var(--bp-color-text);
		margin-block-end: var(--bp-space-1);
		padding: 0;
		float: left;
		width: 100%;
	}

	/* Horizontal layout modifier */
	.bp-radio-group--horizontal {
		flex-direction: row;
		flex-wrap: wrap;
		align-items: center;
		gap: var(--radio-group-gap-horizontal, var(--bp-space-6));
	}

	/* Error message */
	.bp-radio-group__error {
		font-size: var(--bp-text-xs);
		color: var(--_error-color);
		margin: 0;
	}

	/* Error cascade: invalid fieldset highlights all inputs in the group */
	.bp-radio-group[aria-invalid='true'] .bp-radio__input {
		border-color: var(--_error-color);
	}

	.bp-radio-group[aria-invalid='true'] .bp-radio__input:checked {
		border-color: var(--_error-color);
	}

	.bp-radio-group[aria-invalid='true'] .bp-radio__input:checked + .bp-radio__label::before {
		background-color: var(--_error-color);
	}
}
