/**
 * The shared style vocabulary (milestone 23, ruling 3; replaces the Tailwind
 * class constants of milestone 18, ruling 10).
 *
 * Every interactive element must carry `focusRing` or `insetFocusRing`; that
 * is the milestone-9 accessibility floor. Compose at the call site with
 * `stylex.props(styles.button, extra)` instead of re-spelling a variant.
 */

import * as stylex from "@stylexjs/stylex";
import { colors } from "./tokens.stylex";

const FOCUS = ":focus-visible";
const DISABLED = ":disabled";

/** The half-fade loop a placeholder runs while its data is in flight. */
const pulseFrames = stylex.keyframes({
	"50%": { opacity: 0.5 },
});

export const styles = stylex.create({
	/** The ring drawn outside the element. */
	focusRing: {
		outlineWidth: { default: null, [FOCUS]: 2 },
		outlineStyle: { default: null, [FOCUS]: "solid" },
		outlineColor: { default: null, [FOCUS]: colors.focus },
		outlineOffset: { default: null, [FOCUS]: 2 },
	},
	/** The ring drawn inside the element, for controls flush against a panel edge. */
	insetFocusRing: {
		outlineWidth: { default: null, [FOCUS]: 2 },
		outlineStyle: { default: null, [FOCUS]: "solid" },
		outlineColor: { default: null, [FOCUS]: colors.focus },
		outlineOffset: { default: null, [FOCUS]: -2 },
	},

	input: {
		marginTop: "0.25rem",
		width: "100%",
		borderRadius: "0.25rem",
		borderWidth: 1,
		borderStyle: "solid",
		borderColor: colors.borderStrong,
		backgroundColor: colors.surfaceRaised,
		color: colors.text,
		paddingInline: "0.75rem",
		paddingBlock: "0.5rem",
	},
	smallInput: {
		borderRadius: "0.25rem",
		borderWidth: 1,
		borderStyle: "solid",
		borderColor: colors.borderStrong,
		backgroundColor: colors.surfaceRaised,
		color: colors.text,
		paddingInline: "0.5rem",
		paddingBlock: "0.375rem",
		fontSize: "0.875rem",
		lineHeight: "1.25rem",
	},

	button: {
		cursor: { default: "pointer", [DISABLED]: "not-allowed" },
		borderRadius: "0.25rem",
		borderWidth: 1,
		borderStyle: "solid",
		borderColor: colors.borderStrong,
		paddingInline: "0.75rem",
		paddingBlock: "0.375rem",
		fontSize: "0.875rem",
		lineHeight: "1.25rem",
	},
	smallButton: {
		cursor: { default: "pointer", [DISABLED]: "not-allowed" },
		borderRadius: "0.25rem",
		borderWidth: 1,
		borderStyle: "solid",
		borderColor: colors.borderStrong,
		paddingInline: "0.5rem",
		paddingBlock: "0.25rem",
		fontSize: "0.875rem",
		lineHeight: "1.25rem",
	},
	largeButton: {
		cursor: { default: "pointer", [DISABLED]: "not-allowed" },
		borderRadius: "0.25rem",
		borderWidth: 1,
		borderStyle: "solid",
		borderColor: colors.borderStrong,
		paddingInline: "0.75rem",
		paddingBlock: "0.5rem",
		fontWeight: 500,
	},

	primaryButton: {
		cursor: { default: "pointer", [DISABLED]: "not-allowed" },
		borderRadius: "0.25rem",
		borderStyle: "none",
		backgroundColor: colors.primary,
		color: colors.primaryText,
		paddingInline: "0.75rem",
		paddingBlock: "0.375rem",
		fontSize: "0.875rem",
		lineHeight: "1.25rem",
		fontWeight: 500,
		opacity: { default: 1, [DISABLED]: 0.5 },
	},
	largePrimaryButton: {
		cursor: { default: "pointer", [DISABLED]: "not-allowed" },
		borderRadius: "0.25rem",
		borderStyle: "none",
		backgroundColor: colors.primary,
		color: colors.primaryText,
		paddingInline: "0.75rem",
		paddingBlock: "0.5rem",
		fontWeight: 500,
		opacity: { default: 1, [DISABLED]: 0.5 },
	},

	rowButton: {
		cursor: { default: "pointer", [DISABLED]: "not-allowed" },
		borderRadius: "0.25rem",
		borderStyle: "none",
		backgroundColor: "transparent",
		paddingInline: "0.5rem",
		paddingBlock: "0.25rem",
		fontSize: "0.875rem",
		lineHeight: "1.25rem",
		color: colors.primaryOnSurface,
	},
	linkButton: {
		cursor: { default: "pointer", [DISABLED]: "not-allowed" },
		borderStyle: "none",
		backgroundColor: "transparent",
		padding: 0,
		fontSize: "0.875rem",
		lineHeight: "1.25rem",
		fontWeight: 500,
		color: colors.primaryOnSurface,
	},
	dangerLinkButton: {
		cursor: { default: "pointer", [DISABLED]: "not-allowed" },
		borderStyle: "none",
		backgroundColor: "transparent",
		padding: 0,
		fontSize: "0.875rem",
		lineHeight: "1.25rem",
		fontWeight: 500,
		color: colors.danger,
		opacity: { default: 1, [DISABLED]: 0.5 },
	},
	retryButton: {
		cursor: { default: "pointer", [DISABLED]: "not-allowed" },
		marginTop: "0.75rem",
		borderRadius: "0.25rem",
		borderWidth: 1,
		borderStyle: "solid",
		borderColor: colors.dangerBorder,
		backgroundColor: "transparent",
		paddingInline: "0.75rem",
		paddingBlock: "0.375rem",
		fontSize: "0.875rem",
		lineHeight: "1.25rem",
		fontWeight: 500,
		color: colors.dangerText,
	},

	/** Marks an element as waiting on data. Carries no colour of its own. */
	pulse: {
		animationName: pulseFrames,
		animationDuration: "2s",
		animationTimingFunction: "cubic-bezier(0.4, 0, 0.6, 1)",
		animationIterationCount: "infinite",
	},
	/** Digits of equal width, so a column of counts does not jitter as it updates. */
	tabularNums: {
		fontVariantNumeric: "tabular-nums",
	},
	/**
	 * A learned name is runtime state, not something the operator typed, so it
	 * reads muted wherever it appears. The Clients page adds the outlined tag,
	 * where the client is named once; the query tables leave it off rather than
	 * repeat it on every row. The tag is real text — a screen reader announces
	 * it — because colour alone is not an affordance.
	 */
	learnedName: {
		color: colors.textMuted,
	},
	learnedTag: {
		marginLeft: "0.5rem",
		borderWidth: 1,
		borderStyle: "solid",
		borderColor: colors.border,
		borderRadius: "0.25rem",
		paddingInline: "0.375rem",
		paddingBlock: "0.125rem",
		fontSize: "0.75rem",
		lineHeight: "1rem",
		color: colors.textMuted,
	},
	/** For a value the operator reads character by character: a domain, an IP, a URL. */
	mono: {
		fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",
	},
	/**
	 * Visible to a screen reader only; the element keeps its place in the a11y tree.
	 *
	 * Apply it to a block container. `overflow` has no effect on a table box, and
	 * `height` on one is a minimum, so a `<table>` wearing this still lays out at
	 * its full content height and pushes the page's scrollable overflow past the
	 * app shell — invisible, because `clip-path` still hides the paint. Wrap the
	 * table in a hidden `<div>` instead of hiding the table itself.
	 */
	srOnly: {
		position: "absolute",
		width: 1,
		height: 1,
		padding: 0,
		margin: -1,
		overflow: "hidden",
		clipPath: "inset(50%)",
		whiteSpace: "nowrap",
		borderWidth: 0,
	},

	th: {
		borderBottomWidth: 1,
		borderBottomStyle: "solid",
		borderBottomColor: colors.borderStrong,
		paddingInline: "0.75rem",
		paddingBlock: "0.5rem",
		textAlign: "left",
		fontWeight: 500,
	},
	td: {
		borderBottomWidth: 1,
		borderBottomStyle: "solid",
		borderBottomColor: colors.border,
		paddingInline: "0.75rem",
		paddingBlock: "0.5rem",
	},
	tableWrap: {
		marginTop: "1rem",
		overflowX: "auto",
	},
	/**
	 * Not a faithful port: `space-y-3` set sibling margins on a block container,
	 * this is a flex formatting context. StyleX has no way to write the `> * + *`
	 * selector that `space-y` compiles to, so the rhythm can only come from
	 * `gap`. Child sizing and margin behaviour differ from the Tailwind original;
	 * both call sites are plain vertical form stacks, where they do not.
	 */
	formCard: {
		display: "flex",
		flexDirection: "column",
		gap: "0.75rem",
		marginTop: "1rem",
		maxWidth: "32rem",
		borderRadius: "0.25rem",
		borderWidth: 1,
		borderStyle: "solid",
		borderColor: colors.border,
		padding: "1rem",
	},
});
