Border Radius

Consistent rounded corner styles from sharp edges to fully rounded elements. All values use rem units for scalability.

Radius Scale

none
Sharp corners
xs
Extra small radius
sm
Small radius
md
Medium radius
lg
Large radius
xl
Extra large
2xl
Double XL
3xl
Triple XL
4xl
Quadruple XL
5xl
Quintuple XL
full
Fully rounded
---
import { css } from "@pindoba/styled-system/css";

// Common styles
const containerStyle = css({
  display: "flex",
  flexDirection: "column",
  gap: "lg",
  width: "full",
});

// Scale example styles
const scaleGridStyle = css({
  display: "grid",
  gridTemplateColumns: "repeat(auto-fill, minmax(120px, 1fr))",
  gap: "md",
});

const scaleItemStyle = css({
  backgroundColor: "neutral.surface",
  border: "1px solid",
  borderColor: "neutral.border.muted",
  borderRadius: "md",
  padding: "md",
  display: "flex",
  flexDirection: "column",
  alignItems: "center",
  gap: "sm",
});

const scaleBoxStyle = css.raw({
  width: "100px",
  height: "100px",
  backgroundColor: "primary",
  border: "2px solid",
  borderColor: { _light: "contrast.darkest", _dark: "contrast.lightest" },
});

const scaleLabelTextStyle = css({
  textStyle: "code",
  textAlign: "center",
  colorPalette: "neutral",
  pindobaTextColor: "md",
});

const scaleLabelDescriptionStyle = css({
  textStyle: "label.sm",
  textAlign: "center",
  colorPalette: "neutral",
  pindobaTextColor: "sm",
});

// Border radius styles using css.raw()
const borderRadiusStyles = {
  none: css.raw({ borderRadius: "none" }),
  xs: css.raw({ borderRadius: "xs" }),
  sm: css.raw({ borderRadius: "sm" }),
  md: css.raw({ borderRadius: "md" }),
  lg: css.raw({ borderRadius: "lg" }),
  xl: css.raw({ borderRadius: "xl" }),
  "2xl": css.raw({ borderRadius: "2xl" }),
  "3xl": css.raw({ borderRadius: "3xl" }),
  "4xl": css.raw({ borderRadius: "4xl" }),
  "5xl": css.raw({ borderRadius: "5xl" }),
  full: css.raw({ borderRadius: "full" }),
} as const;

type BorderRadiusKey = keyof typeof borderRadiusStyles;

// Data for scale
const borderRadiusScale = [
  {
    value: "none" as BorderRadiusKey,
    label: "none",
    description: "Sharp corners",
  },
  {
    value: "xs" as BorderRadiusKey,
    label: "xs",
    description: "Extra small radius",
  },
  { value: "sm" as BorderRadiusKey, label: "sm", description: "Small radius" },
  { value: "md" as BorderRadiusKey, label: "md", description: "Medium radius" },
  { value: "lg" as BorderRadiusKey, label: "lg", description: "Large radius" },
  { value: "xl" as BorderRadiusKey, label: "xl", description: "Extra large" },
  { value: "2xl" as BorderRadiusKey, label: "2xl", description: "Double XL" },
  { value: "3xl" as BorderRadiusKey, label: "3xl", description: "Triple XL" },
  {
    value: "4xl" as BorderRadiusKey,
    label: "4xl",
    description: "Quadruple XL",
  },
  {
    value: "5xl" as BorderRadiusKey,
    label: "5xl",
    description: "Quintuple XL",
  },
  {
    value: "full" as BorderRadiusKey,
    label: "full",
    description: "Fully rounded",
  },
];
---

<div class={containerStyle}>
  <!-- Border Radius Scale -->
  <div class={scaleGridStyle}>
    {
      borderRadiusScale.map(({ value, label, description }) => (
        <div class={scaleItemStyle}>
          <div class={css(scaleBoxStyle, borderRadiusStyles[value])} />
          <div>
            <div class={scaleLabelTextStyle}>{label}</div>
            <div class={scaleLabelDescriptionStyle}>{description}</div>
          </div>
        </div>
      ))
    }
  </div>
</div>
{
  none: "0",
  xs:    "0.4rem",  //  4px
  sm:    "0.6rem",  //  6px
  md:    "0.8rem",  //  8px
  lg:    "1.2rem",  // 12px
  xl:    "1.6rem",  // 16px
  "2xl": "2.4rem",  // 24px
  "3xl": "3.2rem",  // 32px
  "4xl": "4.0rem",  // 40px
  "5xl": "4.8rem",  // 48px
  "6xl": "6.4rem",  // 64px
  full:  "9999px",
}

Inner Radii

Semantic inner radius tokens are auto-generated for nested elements. They ensure an inner element’s radius looks proportional to its parent by computing max(4px, calc(outerRadius - spacing)):

// Example: a card with lg radius and md padding
// The inner element uses the inner radius token
<div className={css({ borderRadius: "lg", padding: "md" })}>
  <div className={css({ borderRadius: "inner.lg.md" })}>
    Inner content with proportional rounding
  </div>
</div>

Basic Usage

Card (lg)

Card content with large border radius

Button (md)

Badge/Pill (full)

Badge
---
import { css } from "@pindoba/styled-system/css";

// Common styles using css.raw()
const containerStyle = css({
  display: "flex",
  flexDirection: "column",
  gap: "lg",
  width: "full",
});

const subsectionTitleStyle = css.raw({
  fontSize: "sm",
  fontWeight: "bold",
  color: "neutral.text.bold",
});

const sectionStyle = css.raw({
  display: "flex",
  flexDirection: "column",
  gap: "md",
});

const sectionContentStyle = css.raw({
  display: "flex",
  flexDirection: "column",
  alignItems: "flex-start",
  gap: "2xs",
  backgroundColor: "neutral.surface",
  borderRadius: "lg",
  padding: "lg",
  border: "1px solid",
  borderColor: "neutral.border.muted",
});

// Static border radius styles
const borderRadiusStyles = {
  lg: css.raw({ borderRadius: "lg" }),
  md: css.raw({ borderRadius: "md" }),
  full: css.raw({ borderRadius: "full" }),
} as const;

// Base component styles
const baseCardStyle = css.raw({
  backgroundColor: "neutral.surface.hover",
  padding: "md",
  border: "1px solid",
  borderColor: "neutral.border.muted",
});

const baseButtonStyle = css.raw({
  backgroundColor: "primary.sunken",
  color: "primary.text.contrast",
  padding: "sm md",
  border: "none",
  cursor: "pointer",
  px: "sm",
  py: "xs",
});

const baseBadgeStyle = css.raw({
  display: "inline-flex",
  backgroundColor: "success.sunken",
  color: "success.text.contrast",
  px: "xs",
  py: "2xs",
  fontSize: "xs",
  fontWeight: "bold",
  borderRadius: "full",
});

// Component examples data
const examples = [
  {
    title: "Card (lg)",
    content: "Card content with large border radius",
    style: baseCardStyle,
    borderRadius: "lg" as const,
  },
  {
    title: "Button (md)",
    content: "Button",
    style: baseButtonStyle,
    borderRadius: "md" as const,
  },
  {
    title: "Badge/Pill (full)",
    content: "Badge",
    style: baseBadgeStyle,
    borderRadius: "full" as const,
  },
];
---

<div class={containerStyle}>
  <!-- Basic Border Radius -->
  <div class={css(sectionStyle)}>
    {
      examples.map((example) => (
        <div class={css(sectionContentStyle)}>
          <h4 class={css(subsectionTitleStyle)}>{example.title}</h4>
          {example.title.includes("Button") ? (
            <button
              class={css(
                example.style,
                borderRadiusStyles[example.borderRadius],
              )}
            >
              {example.content}
            </button>
          ) : (
            <div
              class={css(
                example.style,
                borderRadiusStyles[example.borderRadius],
              )}
            >
              {example.content}
            </div>
          )}
        </div>
      ))
    }
  </div>
</div>

Directional Border Radius

Directional Border Radius

Top rounded
borderTopRadius: "lg"
Bottom rounded
borderBottomRadius: "lg"
Left rounded
borderLeftRadius: "lg"
Right rounded
borderRightRadius: "lg"
Asymmetric rounding
TL: xl, TR: sm, BR: xl, BL: sm
---
import { css } from "@pindoba/styled-system/css";

// Common styles using css.raw()
const containerStyle = css({
  display: "flex",
  flexDirection: "column",
  gap: "lg",
});

const sectionStyle = css.raw({
  backgroundColor: "neutral.surface",
  borderRadius: "lg",
  padding: "lg",
  border: "1px solid",
  borderColor: "neutral.border.muted",
});

const sectionTitleStyle = css.raw({
  fontSize: "md",
  fontWeight: "bold",
  marginBottom: "md",
  color: "neutral.text.bold",
});

const gridStyle = css.raw({
  display: "grid",
  gridTemplateColumns: "repeat(auto-fit, minmax(200px, 1fr))",
  gap: "md",
});

const itemContainerStyle = css.raw({
  display: "flex",
  flexDirection: "column",
  alignItems: "center",
  gap: "sm",
});

const baseBoxStyle = css.raw({
  padding: "md",
  width: "full",
  textAlign: "center",
  border: "1px solid",
});

const labelStyle = css.raw({
  fontSize: "xs",
  color: "neutral.text",
  fontFamily: "mono",
});

const specialItemStyle = css.raw({
  display: "flex",
  flexDirection: "column",
  alignItems: "center",
  gap: "sm",
  gridColumn: "1 / -1",
});

const specialBoxStyle = css.raw({
  padding: "md",
  textAlign: "center",
  border: "1px solid",
  borderColor: "info.border.muted",
  maxWidth: "sm",
  width: "full",
});

// Directional border radius styles
const directionalBorderRadiusStyles = {
  top: css.raw({
    borderTopLeftRadius: "lg",
    borderTopRightRadius: "lg",
  }),
  bottom: css.raw({
    borderBottomLeftRadius: "lg",
    borderBottomRightRadius: "lg",
  }),
  left: css.raw({
    borderTopLeftRadius: "lg",
    borderBottomLeftRadius: "lg",
  }),
  right: css.raw({
    borderTopRightRadius: "lg",
    borderBottomRightRadius: "lg",
  }),
  mixed: css.raw({
    borderTopLeftRadius: "xl",
    borderTopRightRadius: "sm",
    borderBottomRightRadius: "xl",
    borderBottomLeftRadius: "sm",
  }),
} as const;

// Component data
const directionalExamples = [
  {
    direction: "top" as const,
    text: "Top rounded",
    bgColor: "primary.surface",
    borderColor: "primary.border.muted",
    label: 'borderTopRadius: "lg"',
  },
  {
    direction: "bottom" as const,
    text: "Bottom rounded",
    bgColor: "success.surface",
    borderColor: "success.border.muted",
    label: 'borderBottomRadius: "lg"',
  },
  {
    direction: "left" as const,
    text: "Left rounded",
    bgColor: "warning.surface",
    borderColor: "warning.border.muted",
    label: 'borderLeftRadius: "lg"',
  },
  {
    direction: "right" as const,
    text: "Right rounded",
    bgColor: "danger.surface",
    borderColor: "danger.border.muted",
    label: 'borderRightRadius: "lg"',
  },
];
---

<div class={containerStyle}>
  <!-- Directional Border Radius -->
  <div class={css(sectionStyle)}>
    <h3 class={css(sectionTitleStyle)}>Directional Border Radius</h3>
    <div class={css(gridStyle)}>
      {
        directionalExamples.map((example) => (
          <div class={css(itemContainerStyle)}>
            <div
              class={css(
                baseBoxStyle,
                directionalBorderRadiusStyles[example.direction],
                {
                  backgroundColor: example.bgColor,
                  borderColor: example.borderColor,
                },
              )}
            >
              {example.text}
            </div>
            <span class={css(labelStyle)}>{example.label}</span>
          </div>
        ))
      }

      <!-- Mixed Radius Values -->
      <div class={css(specialItemStyle)}>
        <div
          class={css(specialBoxStyle, directionalBorderRadiusStyles.mixed, {
            backgroundColor: "info.surface",
          })}
        >
          Asymmetric rounding
        </div>
        <span
          class={css(labelStyle, {
            textAlign: "center",
          })}
        >
          TL: xl, TR: sm, BR: xl, BL: sm
        </span>
      </div>
    </div>
  </div>
</div>

Responsive & Interactive

Responsive Border Radius

Responsive Radius

Radius changes with screen size

Mobile: sm → Tablet: md → Desktop: lg

Interactive Radius (Hover)

Hover to change radius

Default: md → Hover: xl

Focus State Radius

Focus changes radius from sm to lg

Active State Radius

Active state reduces radius from lg to sm

---
import { css } from "@pindoba/styled-system/css";

// Common styles using css()
const containerStyle = css({
  display: "flex",
  flexDirection: "column",
  gap: "lg",
});

const sectionStyle = css({
  backgroundColor: "neutral.surface",
  borderRadius: "lg",
  padding: "lg",
  border: "1px solid",
  borderColor: "neutral.border.muted",
});

const sectionTitleStyle = css({
  fontSize: "md",
  fontWeight: "bold",
  marginBottom: "md",
  color: "neutral.text.bold",
});

const sectionContentStyle = css({
  display: "flex",
  flexDirection: "column",
  gap: "lg",
});

const subsectionTitleStyle = css({
  fontSize: "sm",
  fontWeight: "medium",
  marginBottom: "sm",
  color: "neutral.text.bold",
});

const baseBoxStyle = css.raw({
  padding: "md",
  border: "1px solid",
  textAlign: "center",
});

const baseDescriptionStyle = css({
  margin: "0",
  fontSize: "sm",
});

const primarySubDescriptionStyle = css({
  margin: "0",
  fontSize: "xs",
  marginTop: "xs",
  color: "primary.text",
});

const successSubDescriptionStyle = css({
  margin: "0",
  fontSize: "xs",
  marginTop: "xs",
  color: "success.text",
});

const baseButtonStyle = css.raw({
  border: "2px solid",
  fontSize: "sm",
  cursor: "pointer",
  py: "md",
  px: "lg",
});

const buttonDescriptionStyle = css({
  margin: "0",
  fontSize: "xs",
  color: "neutral.text",
  marginTop: "xs",
});

const responsiveRadiusBoxStyle = css.raw({
  borderRadius: {
    base: "sm",
    md: "md",
    lg: "lg",
  },
  backgroundColor: "primary.surface",
  borderColor: "primary.border.muted",
});

const interactiveRadiusBoxStyle = css.raw({
  borderRadius: "md",
  backgroundColor: "success.surface",
  borderColor: "success.border.muted",
  transition: "all 0.3s ease",
  cursor: "pointer",
  "&:hover": {
    borderRadius: "xl",
  },
});

const focusButtonStyle = css.raw({
  borderRadius: "sm",
  backgroundColor: "warning.surface",
  borderColor: "warning.border.muted",
  transition: "all 0.2s ease",
  "&:focus": {
    borderRadius: "lg",
    borderColor: "warning.border",
    outline: "none",
  },
});

const activeButtonStyle = css.raw({
  borderRadius: "lg",
  backgroundColor: "info.surface",
  borderColor: "info.border.muted",
  transition: "all 0.1s ease",
  "&:active": {
    borderRadius: "sm",
    transform: "scale(0.98)",
  },
});
---

<div class={containerStyle}>
  <!-- Responsive Border Radius -->
  <div class={sectionStyle}>
    <h3 class={sectionTitleStyle}>Responsive Border Radius</h3>
    <div class={sectionContentStyle}>
      <div>
        <h4 class={subsectionTitleStyle}>Responsive Radius</h4>
        <div class={css(baseBoxStyle, responsiveRadiusBoxStyle)}>
          <p class={baseDescriptionStyle}>Radius changes with screen size</p>
          <p class={primarySubDescriptionStyle}>
            Mobile: sm → Tablet: md → Desktop: lg
          </p>
        </div>
      </div>

      <div>
        <h4 class={subsectionTitleStyle}>Interactive Radius (Hover)</h4>
        <div class={css(baseBoxStyle, interactiveRadiusBoxStyle)}>
          <p class={baseDescriptionStyle}>Hover to change radius</p>
          <p class={successSubDescriptionStyle}>Default: md → Hover: xl</p>
        </div>
      </div>

      <div>
        <h4 class={subsectionTitleStyle}>Focus State Radius</h4>
        <button class={css(baseButtonStyle, focusButtonStyle)}>
          Click to focus
        </button>
        <p class={buttonDescriptionStyle}>Focus changes radius from sm to lg</p>
      </div>

      <div>
        <h4 class={subsectionTitleStyle}>Active State Radius</h4>
        <button class={css(baseButtonStyle, activeButtonStyle)}>
          Press me
        </button>
        <p class={buttonDescriptionStyle}>
          Active state reduces radius from lg to sm
        </p>
      </div>
    </div>
  </div>
</div>

Best Practices

  • none — sharp edges for technical designs
  • xssm — subtle rounding for small elements, form inputs
  • md — standard buttons, inputs, small cards
  • lgxl — cards, panels, content containers
  • 2xl6xl — large components, hero sections
  • full — pills, circular buttons, badges
  • Use inner.* tokens for nested elements to maintain proportional rounding