# ivyforms/1.1.1/frontend/src/utils/formStyleGenerator.ts

The Innovative Form Builder – IvyForms, version 1.1.1. 966 lines.

- Page: https://pluginprobe.com/plugins/ivyforms/1.1.1/code/frontend/src/utils/formStyleGenerator.ts
- Raw: https://pluginprobe.com/plugins/ivyforms/1.1.1/raw/frontend/src/utils/formStyleGenerator.ts
- Modified: 2026-06-08T12:18:46+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/ivyforms/1.1.1/code/frontend/src/utils/formStyleGenerator.ts#L10-L20`.

```typescript
import type { FormStyleSettings } from '@/types/form-style'

import { formatDimensionToCss, resolveBorderStyle } from '@/utils/styleUtils'
import { applyAlpha } from '@/utils/colorUtils'
import { parseCssClassList } from '@/utils/form-styles/classParser'
import { buildFormPopperScopeClass, buildFormStyleSelectors } from '@/utils/form-styles/selectors'
import { resolveActiveColors, resolveCornerRadiusValue } from '@/utils/form-styles/styleSettings'
import { applyFormContainerStyles } from '@/utils/form-styles/sections/formContainer'
import { applyFormHeaderStyles } from '@/utils/form-styles/sections/formHeader'
import { applyFieldLabelStyles } from '@/utils/form-styles/sections/fieldLabels'
import { applyFieldStateVariantStyles } from '@/utils/form-styles/sections/fieldStateVariants'

export { parseCssClassList }

export function generateFormCSS(
  formId: string | number,
  styleSettings: FormStyleSettings | null,
): string {
  if (!styleSettings || styleSettings.stylesEnabled === false) {
    return ''
  }

  const { formSelector, baseSelector } = buildFormStyleSelectors(
    formId,
    styleSettings.customCssClass,
  )
  const formPopperScopeClass = buildFormPopperScopeClass(formId)

  const css: string[] = []
  const activeColors = resolveActiveColors(styleSettings)

  const formBackground =
    styleSettings.advancedMode?.general?.formBackground ||
    styleSettings.quickMode?.formBackground ||
    'transparent'
  const formBorderColor =
    styleSettings.advancedMode?.general?.formBorderColor || styleSettings.quickMode?.formBorderColor
  const formBorderWidth =
    styleSettings.advancedMode?.general?.formBorderWidth || styleSettings.quickMode?.formBorderWidth
  const formBorderStyle = resolveBorderStyle(styleSettings.advancedMode?.general?.formBorderStyle)
  const formPaddingLeftRight = styleSettings.advancedMode?.general?.formPaddingLeftRight || '24px'
  const formPaddingTopBottom = styleSettings.advancedMode?.general?.formPaddingTopBottom || '24px'
  const verticalSpacing =
    styleSettings.advancedMode?.general?.verticalSpacing ||
    styleSettings.quickMode?.verticalSpacing ||
    '16px'
  const horizontalSpacing =
    styleSettings.advancedMode?.general?.horizontalSpacing ||
    styleSettings.quickMode?.horizontalSpacing ||
    '12px'
  const formAlignment = styleSettings.advancedMode?.general?.alignment || 'left'
  const formCornerRadius = resolveCornerRadiusValue(
    styleSettings.advancedMode?.general?.formCorner || styleSettings.quickMode?.formCorner,
    '8px',
  )

  const fieldBackground =
    styleSettings.advancedMode?.fieldStates?.default?.background ||
    styleSettings.quickMode?.fieldBackground ||
    'transparent'
  const fieldBorderColor =
    styleSettings.advancedMode?.fieldStates?.default?.borderColor ||
    styleSettings.quickMode?.fieldBorderColor ||
    '#6B737D'
  const fieldTextColor =
    styleSettings.advancedMode?.fieldStates?.default?.textColor || activeColors.fieldText
  const fieldFontWeight = styleSettings.advancedMode?.fieldStates?.default?.fontWeight
  const fieldFontStyle = styleSettings.advancedMode?.fieldStates?.default?.fontStyle
  const fieldFontSize = formatDimensionToCss(
    styleSettings.advancedMode?.fieldStates?.default?.fontSize,
  )
  const fieldCornerRadius = resolveCornerRadiusValue(
    styleSettings.advancedMode?.fieldStates?.default?.corner ||
      styleSettings.quickMode?.fieldCorner,
    '6px',
  )
  const fieldPaddingX =
    styleSettings.advancedMode?.fieldStates?.default?.paddingLeftRight ||
    styleSettings.quickMode?.fieldPaddingLeftRight ||
    '8px'
  const fieldPaddingY =
    styleSettings.advancedMode?.fieldStates?.default?.paddingTopBottom ||
    styleSettings.quickMode?.fieldPaddingTopBottom ||
    '0px'
  const fieldBorderWidth =
    styleSettings.advancedMode?.fieldStates?.default?.borderWidth ||
    styleSettings.quickMode?.fieldBorderWidth ||
    '1px'
  const fieldBorderStyle = resolveBorderStyle(
    styleSettings.advancedMode?.fieldStates?.default?.borderStyle,
  )
  const fieldDescriptionColor =
    styleSettings.advancedMode?.fieldStates?.default?.descriptionColor || '#212832'

  const buttonCornerRadius = resolveCornerRadiusValue(
    styleSettings.advancedMode?.buttonStates?.normal?.corner ||
      styleSettings.corners?.buttonCornerRadius ||
      styleSettings.button?.borderRadius,
  )
  const buttonBackground =
    styleSettings.advancedMode?.buttonStates?.normal?.background ||
    styleSettings.quickMode?.buttonBackground ||
    '#FFFFFF'
  const buttonBorderColor =
    styleSettings.advancedMode?.buttonStates?.normal?.borderColor ||
    styleSettings.quickMode?.buttonBorderColor ||
    styleSettings.quickMode?.buttonBackground ||
    '#707883'
  const buttonBorderWidth =
    styleSettings.advancedMode?.buttonStates?.normal?.borderWidth ||
    styleSettings.quickMode?.buttonBorderWidth ||
    '1px'
  const buttonTextColor =
    styleSettings.advancedMode?.buttonStates?.normal?.textColor || activeColors.buttonText

  applyFormContainerStyles(css, {
    formId,
    baseSelector,
    formSelector,
    formBackground,
    formBorderColor,
    formBorderWidth,
    formBorderStyle,
    formCornerRadius,
    formPaddingTopBottom,
    formPaddingLeftRight,
    formAlignment,
    verticalSpacing,
    horizontalSpacing,
  })

  applyFormHeaderStyles(css, formId, styleSettings, activeColors)
  applyFieldLabelStyles(css, baseSelector, styleSettings, activeColors)

  // Text inputs and textareas (Element Plus wrappers) + phone/select/date/time variants - high specificity to override component styles
  const textAndPhoneWrappers = [
    `${baseSelector} .ivyforms-input.el-input .el-input__wrapper`,
    `${baseSelector} .ivyforms-field .el-input__wrapper`,
    `${baseSelector} .ivyforms-phone-input .el-input__wrapper`,
    `${baseSelector} .ivyforms-field__phone .el-input__wrapper`,
    `${baseSelector} .ivyforms-field .vue-tel-input`,
    `${baseSelector} .ivyforms-field__select .el-input__wrapper`,
    `${baseSelector} .ivyforms-field__select .el-select__wrapper`,
    `${baseSelector} .el-select .el-select__wrapper`,
    `${baseSelector} .ivyforms-field__address .el-input__wrapper`,
    `${baseSelector} .ivyforms-field__date .el-input__wrapper`,
    `${baseSelector} .ivyforms-field__time .el-input__wrapper`,
  ]

  css.push(textAndPhoneWrappers.join(',') + ' {')
  if (fieldBackground) {
    css.push(`  background-color: ${fieldBackground} !important;`)
  }
  if (fieldBorderColor) {
    css.push(`  border: ${fieldBorderWidth} ${fieldBorderStyle} ${fieldBorderColor} !important;`)
    css.push(`  box-shadow: none !important;`)
  }
  if (fieldCornerRadius) {
    css.push(`  border-radius: ${fieldCornerRadius} !important;`)
  }
  css.push(`  padding: ${fieldPaddingY} ${fieldPaddingX} !important;`)
  css.push('  box-sizing: border-box !important;')
  css.push('}')

  if (fieldBackground || fieldBorderColor || fieldCornerRadius) {
    css.push(`${baseSelector} .ivyforms-field__textarea .el-textarea__inner {`)
    if (fieldBackground) {
      css.push(`  background-color: ${fieldBackground} !important;`)
    }
    if (fieldBorderColor) {
      css.push(`  border: ${fieldBorderWidth} ${fieldBorderStyle} ${fieldBorderColor} !important;`)
      css.push(`  box-shadow: none !important;`)
    }
    if (fieldCornerRadius) {
      css.push(`  border-radius: ${fieldCornerRadius} !important;`)
    }
    css.push(`  padding: ${fieldPaddingY} ${fieldPaddingX} !important;`)
    css.push('  box-sizing: border-box !important;')
    css.push('}')
  }
  // Ensure custom number-field wrappers match the same border-radius and clip inner backgrounds
  css.push(
    `${baseSelector} .ivyforms-text-number, ${baseSelector} .ivyforms-text-number__input, ${baseSelector} .el-input-number {`,
  )
  if (fieldCornerRadius) {
    css.push(`  border-radius: ${fieldCornerRadius} !important;`)
  }
  css.push('  overflow: hidden !important;')
  css.push('}')

  // Override fixed height on .ivyforms-input.el-input to allow padding to control size
  css.push(`${baseSelector} .ivyforms-input.el-input,`)
  css.push(`${baseSelector} .ivyforms-phone-input,`)
  css.push(`${baseSelector} .ivyforms-field__phone,`)
  css.push(`${baseSelector} .ivyforms-field__select,`)
  css.push(`${baseSelector} .ivyforms-field__address,`)
  css.push(`${baseSelector} .ivyforms-field__date,`)
  css.push(`${baseSelector} .ivyforms-field__time,`)
  css.push(`${baseSelector} .ivyforms-form-item-select .el-select__wrapper,`)
  css.push(`${baseSelector} .ivyforms-phone-input .vue-tel-input {`)
  css.push('  height: auto !important;')
  css.push('  min-height: 40px !important;')
  css.push('}')

  // Also override height on nested select/date picker elements
  css.push(`${baseSelector} .el-select,`)
  css.push(`${baseSelector} .el-date-picker,`)
  css.push(`${baseSelector} .el-time-picker {`)
  css.push('  height: auto !important;')
  css.push('}')

  // Override el-input height constraints
  css.push(`${baseSelector} .el-input {`)
  css.push('  height: auto !important;')
  css.push('}')

  // Ensure select and date picker inputs have consistent sizing
  css.push(`${baseSelector} .el-select .el-input,`)
  css.push(`${baseSelector} .ivyforms-field__select .el-input,`)
  css.push(`${baseSelector} .ivyforms-field__date .el-input,`)
  css.push(`${baseSelector} .ivyforms-field__time .el-input {`)
  css.push('  height: auto !important;')
  css.push('}')

  // Override date picker specific height constraint
  css.push(`${baseSelector} .ivyforms-date-picker .ivyforms-input .el-input__wrapper,`)
  css.push(`${baseSelector} .ivyforms-date-picker .ivyforms-input.el-input__wrapper {`)
  css.push('  height: auto !important;')
  css.push('  min-height: 40px !important;')
  css.push(`  padding: ${fieldPaddingY} ${fieldPaddingX} !important;`)
  css.push('}')

  // Phone inner input (vue-tel-input) - remove inner borders to avoid double outline
  css.push(`${baseSelector} .vti__input {`)
  if (fieldTextColor) {
    css.push(`  color: ${fieldTextColor} !important;`)
  }
  css.push('  border: none !important;')
  css.push('  box-shadow: none !important;')
  css.push('  background: transparent !important;')
  css.push('  padding: 0 !important;')
  css.push('}')

  // Ensure dropdowns display content vertically centered with flex
  css.push(`${baseSelector} .el-select__wrapper,`)
  css.push(`${baseSelector} .ivyforms-form-item-select .el-select__wrapper {`)
  css.push('  display: flex !important;')
  css.push('  align-items: center !important;')
  css.push('}')

  // Set select selection min-height to match text input inner height (30px)
  css.push(`${baseSelector} .el-select__selection {`)
  css.push('  min-height: 30px !important;')
  css.push('}')

  const selectWrappers = [
    `${baseSelector} .el-select .el-input__wrapper`,
    `${baseSelector} .el-select__wrapper`,
    `${baseSelector} .ivyforms-field__select-input .el-select__wrapper`,
  ]

  css.push(selectWrappers.join(',') + ' {')
  if (fieldBackground) {
    css.push(`  background-color: ${fieldBackground} !important;`)
  }
  if (fieldBorderColor) {
    css.push(`  border: ${fieldBorderWidth} ${fieldBorderStyle} ${fieldBorderColor} !important;`)
    css.push(`  box-shadow: none !important;`)
  }
  if (fieldCornerRadius) {
    css.push(`  border-radius: ${fieldCornerRadius} !important;`)
  }
  css.push('}')

  // Select inner input - make transparent to avoid double borders
  css.push(`${baseSelector} .el-select .el-input__inner,`)
  css.push(`${baseSelector} .ivyforms-field__select .el-input__inner,`)
  css.push(`${baseSelector} .el-select__selected-item {`)
  if (fieldTextColor) {
    css.push(`  color: ${fieldTextColor} !important;`)
  }
  css.push('  border: none !important;')
  css.push('  background: transparent !important;')
  css.push('}')

  // Reset select inner input padding to avoid covering borders
  css.push(`${baseSelector} .el-select__input {`)
  css.push('  padding: 0 !important;')
  css.push('  background: transparent !important;')
  css.push('  border: none !important;')
  css.push('}')

  // Country field in address - top/bottom borders only to match address row styling
  if (fieldBorderColor) {
    // Target using field class applied to country-address wrapper
    css.push(`${baseSelector} .country-address .el-select__wrapper {`)
    css.push(
      `  border-top: ${fieldBorderWidth} ${fieldBorderStyle} ${fieldBorderColor} !important;`,
    )
    css.push(
      `  border-bottom: ${fieldBorderWidth} ${fieldBorderStyle} ${fieldBorderColor} !important;`,
    )
    css.push(`  border-left: none !important;`)
    css.push(`  border-right: none !important;`)
    css.push('}')
  }

  if (fieldDescriptionColor) {
    css.push(`${baseSelector} .ivyforms-form-item__info-text {`)
    css.push(`  color: ${fieldDescriptionColor} !important;`)
    css.push(`  --ivyforms-info-color: ${fieldDescriptionColor} !important;`)
    css.push('}')
  }
  // Input text color
  if (fieldTextColor || fieldFontWeight || fieldFontStyle || fieldFontSize) {
    css.push(`${baseSelector} .el-input__inner,`)
    css.push(`${baseSelector} .el-textarea__inner,`)
    css.push(`${baseSelector} .ivyforms-field__phone .vti__input,`)
    css.push(`${baseSelector} .ivyforms-field__phone .vue-tel-input input,`)
    css.push(`${baseSelector} .ivyforms-field__select .el-select__selected-item,`)
    css.push(`${baseSelector} .el-select .el-select__selected-item {`)
    if (fieldTextColor) {
      css.push(`  color: ${fieldTextColor} !important;`)
    }
    if (fieldFontWeight) {
      css.push(`  font-weight: ${fieldFontWeight} !important;`)
    }
    if (fieldFontStyle) {
      css.push(`  font-style: ${fieldFontStyle} !important;`)
    }
    if (fieldFontSize) {
      css.push(`  font-size: ${fieldFontSize} !important;`)
    }
    css.push('}')
  }

  // Phone input (intl-tel-input) fallback
  css.push(`${baseSelector} .iti input,`)
  css.push(`${baseSelector} .iti__selected-flag,`)
  css.push(`${baseSelector} .iti__country-list,`)
  css.push(`${baseSelector} .vue-tel-input,`)
  css.push(`${baseSelector} .vti__input {`)
  if (fieldBackground) {
    css.push(`  background-color: ${fieldBackground} !important;`)
  }
  if (fieldBorderColor) {
    css.push(`  border-color: ${fieldBorderColor} !important;`)
  }
  if (fieldCornerRadius) {
    css.push(`  border-radius: ${fieldCornerRadius} !important;`)
  }
  css.push('}')

  // Phone field text color (needs to be separate to avoid being overridden)
  if (fieldTextColor || fieldFontWeight || fieldFontStyle || fieldFontSize) {
    css.push(`${baseSelector} .vti__input {`)
    if (fieldTextColor) {
      css.push(`  color: ${fieldTextColor} !important;`)
    }
    if (fieldFontWeight) {
      css.push(`  font-weight: ${fieldFontWeight} !important;`)
    }
    if (fieldFontStyle) {
      css.push(`  font-style: ${fieldFontStyle} !important;`)
    }
    if (fieldFontSize) {
      css.push(`  font-size: ${fieldFontSize} !important;`)
    }
    css.push('}')
  }

  css.push(`${baseSelector} .choices__inner {`)
  if (fieldBackground) {
    css.push(`  background-color: ${fieldBackground};`)
  }
  if (fieldBorderColor) {
    css.push(`  border: ${fieldBorderWidth} ${fieldBorderStyle} ${fieldBorderColor};`)
  }
  if (fieldCornerRadius) {
    css.push(`  border-radius: ${fieldCornerRadius};`)
  }
  css.push(`  padding: ${fieldPaddingY} ${fieldPaddingX};`)
  css.push('  min-height: auto;')
  css.push('}')

  // Field placeholder
  const fieldPlaceholderPaddingLR = formatDimensionToCss(
    styleSettings.advancedMode?.fieldPlaceholder?.paddingLeftRight,
  )
  const fieldPlaceholderAlignment =
    styleSettings.advancedMode?.fieldPlaceholder?.alignment || 'left'
  const fieldPlaceholderFontWeight = styleSettings.advancedMode?.fieldPlaceholder?.fontWeight
  const fieldPlaceholderFontStyle = styleSettings.advancedMode?.fieldPlaceholder?.fontStyle
  const fieldPlaceholderFontSize = formatDimensionToCss(
    styleSettings.advancedMode?.fieldPlaceholder?.fontSize,
  )

  if (
    activeColors.fieldPlaceholder ||
    fieldPlaceholderAlignment !== 'left' ||
    fieldPlaceholderFontWeight ||
    fieldPlaceholderFontStyle ||
    fieldPlaceholderFontSize
  ) {
    const placeholderColor = activeColors.fieldPlaceholder

    css.push(`${baseSelector} .el-input__inner::placeholder,`)
    css.push(`${baseSelector} .el-textarea__inner::placeholder,`)
    css.push(`${baseSelector} .el-select__placeholder,`)
    css.push(`${baseSelector} input::placeholder,`)
    css.push(`${baseSelector} textarea::placeholder {`)

    if (placeholderColor) {
      css.push(`  color: ${placeholderColor} !important;`)
    }
    if (fieldPlaceholderPaddingLR) {
      css.push(`  padding-left: ${fieldPlaceholderPaddingLR} !important;`)
      css.push(`  padding-right: ${fieldPlaceholderPaddingLR} !important;`)
    }
    if (fieldPlaceholderAlignment !== 'left') {
      css.push(`  text-align: ${fieldPlaceholderAlignment} !important;`)
    }
    if (fieldPlaceholderFontWeight) {
      css.push(`  font-weight: ${fieldPlaceholderFontWeight} !important;`)
    }
    if (fieldPlaceholderFontStyle) {
      css.push(`  font-style: ${fieldPlaceholderFontStyle} !important;`)
    }
    if (fieldPlaceholderFontSize) {
      css.push(`  font-size: ${fieldPlaceholderFontSize} !important;`)
    }
    css.push('}')

    if (placeholderColor) {
      css.push(`${baseSelector} .el-select__placeholder {`)
      css.push(`  color: ${placeholderColor} !important;`)
      css.push('}')
    }
  }

  if (fieldTextColor) {
    css.push(`${baseSelector} .ivyforms-field__textarea .el-textarea,`)
    css.push(`${baseSelector} .ivyforms-field__textarea .ivyforms-textarea {`)
    css.push(`  --el-input-text-color: ${fieldTextColor};`)
    css.push('}')
    css.push(`${baseSelector} .ivyforms-field__textarea .el-textarea__inner,`)
    css.push(`${baseSelector} .ivyforms-field__phone .vti__input,`)
    css.push(`${baseSelector} .ivyforms-field__phone .vue-tel-input input {`)
    css.push(`  color: ${fieldTextColor} !important;`)
    css.push('}')
  }

  applyFieldStateVariantStyles(css, {
    baseSelector,
    styleSettings,
    fieldBorderWidth,
    fieldTextColor,
    fieldFontSize,
    fieldFontWeight,
    fieldFontStyle,
  })

  // Checkbox and Radio Selection (Element Plus components)
  const selectionColor =
    styleSettings.advancedMode?.checkboxRadio?.selectionColor ||
    activeColors.checkboxRadioSelection ||
    activeColors.checkboxRadioBorder

  // Border color for unchecked state - use activeColors which includes both quick and advanced
  const checkboxRadioBorderColor = activeColors.checkboxRadioBorder || selectionColor

  // Label color for unchecked state
  const checkboxRadioLabelColor = activeColors.checkboxRadioLabel
  const checkboxRadioFontWeight = styleSettings.advancedMode?.checkboxRadio?.fontWeight
  const checkboxRadioFontStyle = styleSettings.advancedMode?.checkboxRadio?.fontStyle
  const checkboxRadioFontSize = formatDimensionToCss(
    styleSettings.advancedMode?.checkboxRadio?.fontSize,
  )

  if (selectionColor) {
    // Base border and radius for unchecked
    css.push(`${baseSelector} .ivyforms-checkbox .el-checkbox__input .el-checkbox__inner,`)
    css.push(`${baseSelector} .el-checkbox__input .el-checkbox__inner {`)
    css.push(`  border-color: ${checkboxRadioBorderColor} !important;`)
    css.push('  border-width: 2px !important;')
    css.push('  border-radius: 4px !important;')
    css.push('  background-color: transparent !important;')
    css.push('  box-shadow: none !important;')
    css.push('}')

    css.push(`${baseSelector} .ivyforms-radio .el-radio__input .el-radio__inner,`)
    css.push(`${baseSelector} .el-radio__input .el-radio__inner {`)
    css.push(`  border-color: ${checkboxRadioBorderColor} !important;`)
    css.push('  border-width: 2px !important;')
    css.push('  border-radius: 50% !important;')
    css.push('  background-color: transparent !important;')
    css.push('  box-shadow: none !important;')
    css.push('}')

    // Checkbox checked state - use selectionColor for FILL
    css.push(
      `${baseSelector} .ivyforms-checkbox.priority-primary .el-checkbox__input.is-checked .el-checkbox__inner,`,
    )
    css.push(
      `${baseSelector} .ivyforms-checkbox .el-checkbox__input.is-checked .el-checkbox__inner,`,
    )
    css.push(`${baseSelector} .el-checkbox__input.is-checked .el-checkbox__inner {`)
    css.push(`  background-color: ${selectionColor} !important;`)
    css.push(`  border-color: ${selectionColor} !important;`)
    css.push('  box-shadow: none !important;')
    css.push('}')

    // Checkbox checked inner marker - override priority colors
    css.push(
      `${baseSelector} .ivyforms-checkbox.priority-primary .el-checkbox__input.is-checked .el-checkbox__inner::after,`,
    )
    css.push(
      `${baseSelector} .ivyforms-checkbox .el-checkbox__input.is-checked .el-checkbox__inner::after {`,
    )
    css.push(`  background-color: ${selectionColor} !important;`)
    css.push(`  border-color: ${selectionColor} !important;`)
    css.push('}')

    // Radio checked state - use selectionColor for outer ring and inner dot
    css.push(`${baseSelector} .ivyforms-radio .el-radio__input.is-checked .el-radio__inner,`)
    css.push(`${baseSelector} .el-radio__input.is-checked .el-radio__inner {`)
    css.push(`  border-color: ${selectionColor} !important;`)
    css.push('  background-color: transparent !important;')
    css.push('  box-shadow: none !important;')
    css.push('}')
    css.push(`${baseSelector} .ivyforms-radio .el-radio__input.is-checked .el-radio__inner::after,`)
    css.push(`${baseSelector} .el-radio__input.is-checked .el-radio__inner::after {`)
    css.push(`  background-color: ${selectionColor} !important;`)
    css.push('  width: 8px !important;')
    css.push('  height: 8px !important;')
    css.push('}')
  }

  // Apply checkbox and radio label color
  if (
    checkboxRadioLabelColor ||
    checkboxRadioFontWeight ||
    checkboxRadioFontStyle ||
    checkboxRadioFontSize
  ) {
    css.push(`${baseSelector} .ivyforms-checkbox .el-checkbox__label,`)
    css.push(`${baseSelector} .el-checkbox__label {`)
    if (checkboxRadioLabelColor) {
      css.push(`  color: ${checkboxRadioLabelColor} !important;`)
    }
    if (checkboxRadioFontWeight) {
      css.push(`  font-weight: ${checkboxRadioFontWeight} !important;`)
    }
    if (checkboxRadioFontStyle) {
      css.push(`  font-style: ${checkboxRadioFontStyle} !important;`)
    }
    if (checkboxRadioFontSize) {
      css.push(`  font-size: ${checkboxRadioFontSize} !important;`)
    }
    css.push('}')

    css.push(`${baseSelector} .ivyforms-radio .el-radio__label,`)
    css.push(`${baseSelector} .el-radio__label {`)
    if (checkboxRadioLabelColor) {
      css.push(`  color: ${checkboxRadioLabelColor} !important;`)
    }
    if (checkboxRadioFontWeight) {
      css.push(`  font-weight: ${checkboxRadioFontWeight} !important;`)
    }
    if (checkboxRadioFontStyle) {
      css.push(`  font-style: ${checkboxRadioFontStyle} !important;`)
    }
    if (checkboxRadioFontSize) {
      css.push(`  font-size: ${checkboxRadioFontSize} !important;`)
    }
    css.push('}')
  }

  // Form action buttons: standalone submit + multipage navigation (Prev/Next/Submit in page nav)
  const buttonPaddingLR = formatDimensionToCss(
    styleSettings.advancedMode?.buttonStates?.normal?.paddingLeftRight,
  )
  const buttonPaddingTB = formatDimensionToCss(
    styleSettings.advancedMode?.buttonStates?.normal?.paddingTopBottom,
  )
  const hasButtonPaddingLR = buttonPaddingLR !== undefined && buttonPaddingLR !== ''
  const hasButtonPaddingTB = buttonPaddingTB !== undefined && buttonPaddingTB !== ''
  const buttonPaddingValue =
    (hasButtonPaddingTB ? buttonPaddingTB : '8px') +
    ' ' +
    (hasButtonPaddingLR ? buttonPaddingLR : '16px')

  const buttonWidthValue = formatDimensionToCss(
    styleSettings.advancedMode?.buttonStates?.normal?.width,
  )
  const buttonHeightValue = formatDimensionToCss(
    styleSettings.advancedMode?.buttonStates?.normal?.height,
  )
  const buttonFontWeight = styleSettings.advancedMode?.buttonStates?.normal?.fontWeight
  const buttonFontStyle = styleSettings.advancedMode?.buttonStates?.normal?.fontStyle
  const buttonFontSize = formatDimensionToCss(
    styleSettings.advancedMode?.buttonStates?.normal?.fontSize,
  )

  css.push(`${baseSelector} .ivyforms-form-submit .ivyforms-button-action,`)
  css.push(`${baseSelector} .ivyforms-form-submit button.ivyforms-button-action,`)
  css.push(`${baseSelector} .ivyforms-form-page-navigation .ivyforms-button-action,`)
  css.push(`${baseSelector} .ivyforms-form-page-navigation button.ivyforms-button-action {`)
  if (buttonBackground) {
    css.push(`  background-color: ${buttonBackground} !important;`)
  }
  if (buttonTextColor) {
    css.push(`  color: ${buttonTextColor} !important;`)
  }
  if (buttonFontWeight) {
    css.push(`  font-weight: ${buttonFontWeight} !important;`)
  }
  if (buttonFontStyle) {
    css.push(`  font-style: ${buttonFontStyle} !important;`)
  }
  if (buttonFontSize) {
    css.push(`  font-size: ${buttonFontSize} !important;`)
  }
  css.push(`  padding: ${buttonPaddingValue} !important;`)
  if (buttonWidthValue) {
    css.push(`  width: ${buttonWidthValue} !important;`)
  }
  if (buttonHeightValue) {
    css.push(`  height: ${buttonHeightValue} !important;`)
  }
  if (buttonBorderWidth && buttonBorderWidth !== '0px') {
    css.push(
      `  border: ${buttonBorderWidth} solid ${buttonBorderColor || buttonBackground} !important;`,
    )
  } else {
    css.push(`  border: none !important;`)
  }
  if (buttonCornerRadius) {
    css.push(`  border-radius: ${buttonCornerRadius} !important;`)
  }
  css.push('}')

  // Button hover state - simple opacity effect
  css.push(`${baseSelector} .ivyforms-form-submit .ivyforms-button-action:hover,`)
  css.push(`${baseSelector} .ivyforms-form-submit button.ivyforms-button-action:hover,`)
  css.push(`${baseSelector} .ivyforms-form-page-navigation .ivyforms-button-action:hover,`)
  css.push(`${baseSelector} .ivyforms-form-page-navigation button.ivyforms-button-action:hover {`)
  css.push('  opacity: 0.9 !important;')
  css.push('  transform: translateY(-1px) !important;')
  css.push('}')

  // Success/Confirmation message
  const conf = styleSettings.advancedMode?.confirmationMessage || {}

  const successBgColor = conf.backgroundColor || '#F3F4F5'
  const confirmBorderColor =
    conf.borderColor ||
    styleSettings.advancedMode?.general?.formBorderColor ||
    styleSettings.quickMode?.formBorderColor ||
    '#8B929C'
  const confirmBorderWidth =
    conf.borderWidth ||
    styleSettings.advancedMode?.general?.formBorderWidth ||
    styleSettings.quickMode?.formBorderWidth ||
    '1px'
  const confirmBorderStyle = resolveBorderStyle(
    conf.borderStyle || styleSettings.advancedMode?.general?.formBorderStyle,
  )
  const confirmCorner = resolveCornerRadiusValue(
    conf.corner ||
      styleSettings.advancedMode?.general?.formCorner ||
      styleSettings.quickMode?.formCorner,
    '12px',
  )
  const successColor = conf.textColor

  css.push(`.ivyforms-form-wrapper-${formId} .ivyforms-success-message,`)
  css.push(`.ivyforms-form-wrapper-${formId} .ivyforms-confirmation-message {`)
  if (successBgColor) {
    css.push(`  background-color: ${successBgColor} !important;`)
  }
  if (successColor) {
    css.push(`  color: ${successColor} !important;`)
  }
  if (confirmBorderColor && confirmBorderWidth) {
    css.push(
      `  border: ${confirmBorderWidth} ${confirmBorderStyle} ${confirmBorderColor} !important;`,
    )
  } else if (confirmBorderColor || confirmBorderWidth) {
    // Partial config
    if (confirmBorderColor) {
      css.push(`  border-color: ${confirmBorderColor} !important;`)
    }
    if (confirmBorderWidth) {
      css.push(`  border-width: ${confirmBorderWidth} !important;`)
    }
    css.push(`  border-style: ${confirmBorderStyle} !important;`)
  } else {
    // No border configured
    css.push('  border: none !important;')
  }
  if (confirmCorner) {
    css.push(`  border-radius: ${confirmCorner} !important;`)
  }
  css.push('  padding: 12px 16px !important;')
  css.push('  margin-bottom: 16px !important;')
  css.push('}')

  // Hide form wrapper border/background when confirmation is shown - but NOT for sample preview
  if (formId !== 'sample-preview') {
    css.push(`${baseSelector}:has(.ivyforms-success-message) {`)
    css.push('  background: transparent !important;')
    css.push('  border: none !important;')
    css.push('  padding: 0 !important;')
    css.push('}')
  }

  // Error message
  const errorMessageColor = styleSettings.advancedMode?.fieldStates?.error?.textColor

  if (errorMessageColor) {
    css.push(`${baseSelector} .el-form-item__error {`)
    css.push(`  color: ${errorMessageColor} !important;`)
    css.push('}')
  }

  // Rating
  const ratingIconSize = styleSettings.advancedMode?.rating?.iconSize
  const ratingIconColor = styleSettings.advancedMode?.rating?.iconColor

  if (ratingIconSize) {
    css.push(`${baseSelector} .ivyforms-field__rating .ivyforms-rating__star .ivyforms-icon {`)
    css.push(`  width: ${ratingIconSize} !important;`)
    css.push(`  height: ${ratingIconSize} !important;`)
    css.push('}')
    css.push(`${baseSelector} .ivyforms-field__rating .ivyforms-rating__star .ivyforms-icon svg {`)
    css.push(`  width: ${ratingIconSize} !important;`)
    css.push(`  height: ${ratingIconSize} !important;`)
    css.push('}')
  }

  if (ratingIconColor) {
    css.push(
      `${baseSelector} .ivyforms-field__rating .ivyforms-rating__star.is-filled .ivyforms-icon,`,
    )
    css.push(
      `${baseSelector} .ivyforms-field__rating .ivyforms-rating__star.is-hovered .ivyforms-icon {`,
    )
    css.push(`  color: ${ratingIconColor} !important;`)
    css.push('}')
    css.push(
      `${baseSelector} .ivyforms-field__rating .ivyforms-rating__star.is-filled .ivyforms-icon svg path,`,
    )
    css.push(
      `${baseSelector} .ivyforms-field__rating .ivyforms-rating__star.is-hovered .ivyforms-icon svg path {`,
    )
    css.push(`  fill: ${ratingIconColor} !important;`)
    css.push(`  stroke: ${ratingIconColor} !important;`)
    css.push('}')
  }

  // Date & Time Picker
  const dtCalendarBg = styleSettings.advancedMode?.dateTimePicker?.calendarBackground
  const dtNumberTextColor = styleSettings.advancedMode?.dateTimePicker?.numberTextColor
  const dtSelectionColor = styleSettings.advancedMode?.dateTimePicker?.selectionColor

  if (dtCalendarBg) {
    css.push(`.${formPopperScopeClass}.ivyforms-date-picker-popper.el-popper,`)
    css.push(`.${formPopperScopeClass}.ivyforms-date-picker-popper .el-picker-panel,`)
    css.push(`.${formPopperScopeClass}.ivyforms-time-popper.el-popper,`)
    css.push(`.${formPopperScopeClass}.ivyforms-time-popper .el-time-panel {`)
    css.push(`  background-color: ${dtCalendarBg} !important;`)
    css.push('}')
    // Popper caret (Element Plus: .el-popper__arrow ::before draws the triangle)
    css.push(
      `.${formPopperScopeClass}.ivyforms-date-picker-popper.el-popper .el-popper__arrow::before,`,
    )
    css.push(
      `.${formPopperScopeClass}.ivyforms-date-picker-popper.el-popper .el-popper__arrow:before,`,
    )
    css.push(`.${formPopperScopeClass}.ivyforms-time-popper.el-popper .el-popper__arrow::before,`)
    css.push(`.${formPopperScopeClass}.ivyforms-time-popper.el-popper .el-popper__arrow:before {`)
    css.push(`  background: ${dtCalendarBg} !important;`)
    css.push(`  background-color: ${dtCalendarBg} !important;`)
    css.push(`  border-color: ${dtCalendarBg} !important;`)
    css.push('}')
  }
  if (dtNumberTextColor) {
    css.push(
      `.${formPopperScopeClass}.ivyforms-date-picker-popper .el-date-table td .el-date-table-cell__text,`,
    )
    css.push(`.${formPopperScopeClass}.ivyforms-date-picker-popper .el-date-picker__header-label,`)
    css.push(`.${formPopperScopeClass}.ivyforms-date-picker-popper .el-month-table td .cell,`)
    css.push(`.${formPopperScopeClass}.ivyforms-date-picker-popper .el-year-table td .cell,`)
    css.push(`.${formPopperScopeClass}.ivyforms-time-popper .el-time-spinner__item {`)
    css.push(`  color: ${dtNumberTextColor} !important;`)
    css.push('}')
  }
  if (dtSelectionColor) {
    css.push(
      `.${formPopperScopeClass}.ivyforms-date-picker-popper .el-date-table td.current:not(.disabled) .el-date-table-cell__text,`,
    )
    css.push(
      `.${formPopperScopeClass}.ivyforms-date-picker-popper .el-date-table td.available:hover .el-date-table-cell__text {`,
    )
    css.push(`  background-color: ${dtSelectionColor} !important;`)
    css.push(`  border-color: ${dtSelectionColor} !important;`)
    css.push('}')
    css.push(`.${formPopperScopeClass}.ivyforms-time-popper .el-time-spinner__item.active,`)
    css.push(`.${formPopperScopeClass}.ivyforms-time-popper .el-time-spinner__item:hover {`)
    css.push(`  color: ${dtSelectionColor} !important;`)
    css.push('}')
    css.push(
      `.${formPopperScopeClass}.ivyforms-date-picker-popper .el-date-table td.start-date .el-date-table-cell__text,`,
    )
    css.push(
      `.${formPopperScopeClass}.ivyforms-date-picker-popper .el-date-table td.end-date .el-date-table-cell__text {`,
    )
    css.push(`  background-color: ${dtSelectionColor} !important;`)
    css.push('}')
    css.push(
      `.${formPopperScopeClass}.ivyforms-date-picker-popper .el-date-table td.in-range .el-date-table-cell {`,
    )
    css.push(`  background-color: ${applyAlpha(dtSelectionColor, '26')} !important;`)
    css.push('}')
  }

  // Select (Dropdown)
  const selectTagColor = styleSettings.advancedMode?.select?.tagColor
  const selectTagTextColor = styleSettings.advancedMode?.select?.tagTextColor
  const selectOptionHoverColor = styleSettings.advancedMode?.select?.optionHoverColor
  const selectSelectionTextColor = styleSettings.advancedMode?.select?.selectionTextColor
  const selectSelectionBackgroundColor =
    styleSettings.advancedMode?.select?.selectionBackgroundColor

  if (selectTagColor) {
    css.push(`${baseSelector} .ivyforms-field__select .ivyforms-form-item-select {`)
    css.push(`  --ivyforms-select-tag-bg: ${selectTagColor} !important;`)
    css.push('}')
    css.push(`${baseSelector} .ivyforms-field__select .el-select .el-tag,`)
    css.push(
      `${baseSelector} .ivyforms-field__select .ivyforms-form-item-select .el-select__wrapper.is-focused .el-tag,`,
    )
    css.push(
      `${baseSelector} .ivyforms-field__select .ivyforms-form-item-select .el-select__wrapper.is-active .el-tag,`,
    )
    css.push(
      `${baseSelector} .ivyforms-field__select .ivyforms-form-item-select.is-secondary .el-select__wrapper.is-focused .el-tag,`,
    )
    css.push(
      `${baseSelector} .ivyforms-field__select .ivyforms-form-item-select.is-secondary .el-select__wrapper.is-active .el-tag {`,
    )
    css.push(`  background: ${selectTagColor} !important;`)
    css.push(`  background-color: ${selectTagColor} !important;`)
    css.push(`  border-color: ${selectTagColor} !important;`)
    css.push('}')
  }
  if (selectTagTextColor) {
    css.push(`${baseSelector} .ivyforms-field__select .ivyforms-form-item-select {`)
    css.push(`  --ivyforms-select-tag-text: ${selectTagTextColor} !important;`)
    css.push('}')
    css.push(`${baseSelector} .ivyforms-field__select .el-select .el-tag,`)
    css.push(`${baseSelector} .ivyforms-field__select .el-select .el-tag .el-tag__content,`)
    css.push(`${baseSelector} .ivyforms-field__select .el-select .el-select__tags-text,`)
    css.push(`${baseSelector} .ivyforms-field__select .el-select .el-select__selected-item,`)
    css.push(`${baseSelector} .ivyforms-field__select .el-select .el-tag .el-tag__close svg {`)
    css.push(`  color: ${selectTagTextColor} !important;`)
    css.push('}')
  }
  if (selectOptionHoverColor) {
    css.push(
      `.${formPopperScopeClass}.ivyforms-select-popper .ivyforms-select-option.el-select-dropdown__item:hover,`,
    )
    css.push(
      `.${formPopperScopeClass}.ivyforms-select-popper .ivyforms-select-option.el-select-dropdown__item.hover,`,
    )
    css.push(
      `.${formPopperScopeClass}.ivyforms-select-popper .ivyforms-select-option.el-select-dropdown__item.is-hovering {`,
    )
    css.push(`  background-color: ${selectOptionHoverColor} !important;`)
    css.push('}')
  }
  if (selectSelectionTextColor) {
    css.push(`${baseSelector} .ivyforms-field__select .ivyforms-form-item-select {`)
    css.push(`  --ivyforms-select-option-selected-text: ${selectSelectionTextColor} !important;`)
    css.push('}')
    css.push(
      `.${formPopperScopeClass}.ivyforms-select-popper .ivyforms-select-option.el-select-dropdown__item.is-selected,`,
    )
    css.push(
      `.${formPopperScopeClass}.ivyforms-select-popper .ivyforms-select-option.el-select-dropdown__item.selected,`,
    )
    css.push(
      `.${formPopperScopeClass}.ivyforms-select-popper .ivyforms-select-option.el-select-dropdown__item.is-selected.is-hovering,`,
    )
    css.push(
      `.${formPopperScopeClass}.ivyforms-select-popper .ivyforms-select-option.el-select-dropdown__item.is-selected.is-secondary,`,
    )
    css.push(
      `.${formPopperScopeClass}.ivyforms-select-popper.ivyforms-select-popper--secondary .ivyforms-select-option.el-select-dropdown__item.is-selected {`,
    )
    css.push(`  color: ${selectSelectionTextColor} !important;`)
    css.push('}')
  }
  if (selectSelectionBackgroundColor) {
    css.push(`${baseSelector} .ivyforms-field__select .ivyforms-form-item-select {`)
    css.push(
      `  --ivyforms-select-option-selected-bg: ${selectSelectionBackgroundColor} !important;`,
    )
    css.push('}')
    css.push(
      `.${formPopperScopeClass}.ivyforms-select-popper .ivyforms-select-option.el-select-dropdown__item.is-selected,`,
    )
    css.push(
      `.${formPopperScopeClass}.ivyforms-select-popper .ivyforms-select-option.el-select-dropdown__item.selected,`,
    )
    css.push(
      `.${formPopperScopeClass}.ivyforms-select-popper .ivyforms-select-option.el-select-dropdown__item.is-selected.is-hovering,`,
    )
    css.push(
      `.${formPopperScopeClass}.ivyforms-select-popper .ivyforms-select-option.el-select-dropdown__item.is-selected.is-secondary,`,
    )
    css.push(
      `.${formPopperScopeClass}.ivyforms-select-popper.ivyforms-select-popper--secondary .ivyforms-select-option.el-select-dropdown__item.is-selected {`,
    )
    css.push(`  background-color: ${selectSelectionBackgroundColor} !important;`)
    css.push('}')
  }

  return css.join('\n')
}

/**
 * Inject CSS into the document
 *
 * @param formId - The form ID
 * @param css - The CSS string
 */
export function injectFormCSS(formId: string | number, css: string): void {
  const styleId = `ivyforms-style-${formId}`

  const existingStyle = document.getElementById(styleId)
  if (existingStyle) {
    existingStyle.remove()
  }

  const styleTag = document.createElement('style')
  styleTag.id = styleId
  styleTag.textContent = css
  document.head.appendChild(styleTag)
}

/**
 * Generate and inject form CSS
 *
 * @param formId - The form ID
 * @param styleSettings - The style settings
 */
export function applyFormStyles(
  formId: string | number,
  styleSettings: FormStyleSettings | null,
): void {
  const css = generateFormCSS(formId, styleSettings)
  injectFormCSS(formId, css)
}

```
