From harness-claude
Guides UI design for internationalization: text expansion (up to 200%), RTL layouts with logical CSS properties, icon cultural sensitivity, locale formatting for dates/numbers/currency, pseudolocalization testing.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Designing for internationalization — text expansion, RTL layout, icon cultural sensitivity, date/number/currency formatting, pseudolocalization testing
Guides writing source strings for internationalization: avoid concatenation, use ICU MessageFormat for pluralization, externalize UI text to resource files, handle dynamic values like dates and numbers.
Adapts product experiences for new markets via cultural reconception: info density, navigation, colors, icons, dates, trust signals, payments, compliance. For intl expansion, i18n audits, RTL, cultural reviews.
Share bugs, ideas, or general feedback.
Designing for internationalization — text expansion, RTL layout, icon cultural sensitivity, date/number/currency formatting, pseudolocalization testing
Design for text expansion from the start. English is one of the most compact major languages. When translated, text expands significantly:
German averages 30% longer
Finnish 30-40% longer
French 15-20% longer
Some languages double the length
A button labeled "Submit" (6 characters) becomes "Absenden" in German (8 characters) or "Envoyer la demande" in French (18 characters).
Design every text-containing element with expansion in mind: buttons should size to content rather than fixed widths, navigation items should accommodate 40% growth, and headlines should tolerate 30% expansion without breaking layout.
IBM globalization expansion table:
| Source length (characters) | Expected expansion |
|---|---|
| 1-10 | Up to 200% |
| 11-20 | Up to 80% |
| 21-30 | Up to 60% |
| 31-50 | Up to 40% |
| 51-70 | Up to 31% |
| 70+ | Up to 30% |
Short strings expand the most — disproportionately affecting buttons, labels, tab names, and navigation items.
Build layouts with logical properties, not physical directions. Replace all directional CSS with logical equivalents:
margin-left becomes margin-inline-startpadding-right becomes padding-inline-endtext-align: left becomes text-align: startfloat: left becomes float: inline-startstart and end instead of left and right.dir="rtl" attribute on the <html> element then flips the entire layout correctly. Test by toggling dir in dev tools — if elements jump or overlap, you have physical properties that need migration.Mirror the entire interface for RTL, not just the text. RTL is not text-align: right. It is a complete interface mirror:
Audit every icon and image for cultural sensitivity. Icons that seem universal often carry culture-specific meanings:
Never concatenate strings or embed text in images. String concatenation breaks in every language with different word order:
"You have " + count + " items in your cart" fails in Japanese, where the count goes before "items" and both before "cart" with particles between them.{count, plural, one {You have # item in your cart} other {You have # items in your cart}}Format dates, numbers, and currencies using locale-aware APIs. Never hardcode formats:
Intl.DateTimeFormat or equivalent.Intl.NumberFormat with style: 'currency' and the correct ISO 4217 code.Design forms that accept international input. Common assumptions that break internationally:
Implement pseudolocalization as a development practice. Pseudolocalization transforms English strings into accented variants that test i18n readiness without real translations. Three levels:
Chinese, Japanese, and Korean (CJK) text introduces unique design challenges:
writing-mode: vertical-rl) in traditional contexts — common in Japanese print, rare in web interfacesword-break: break-all is needed for CJK to prevent overflow, but must not be applied to Latin text where it breaks words mid-syllableWhen implementing RTL support, verify each item:
left/right replaced with inline-start/inline-end. All top/bottom replaced with block-start/block-end where applicable.dir attribute. flex-direction: row respects dir correctly. But flex-direction: row-reverse does not flip and must be audited.translateX(100px) does not automatically mirror. Use translateX(100%) with logical properties or JavaScript-based direction detection.border-top-left-radius is physical. Use border-start-start-radius (logical) or apply all four radii symmetrically.box-shadow: 5px 0 10px casts a shadow on the physical right. In RTL, it should appear on the left. Use CSS custom properties that flip based on dir.<bdi> or <span dir="ltr"> to prevent reordering errors.Beyond basic number formatting, consider:
Intl.NumberFormat('en-IN') handles this correctly.The "We'll Localize Later" Assumption. Building an entire product in English with hardcoded strings, fixed-width layouts, and concatenated text, then expecting localization to be a translation pass. By the time localization begins, hundreds of layout assumptions make expansion impossible without a rewrite. The fix: internationalize from day one. Use logical CSS properties, externalize all strings into resource files, and run pseudolocalization in CI from the first sprint.
The Google Translate Test. Using machine translation to validate i18n readiness. Machine translation produces text that fits in the same space as English (word-for-word translation), missing real expansion. It also masks concatenation issues because it follows English word order. The fix: use pseudolocalization for layout testing and professional translators for final localization. Machine translation is not a substitute for either.
The Flag-for-Language Dropdown. Using country flags to represent language choices. Flags represent countries, not languages. The Spanish flag does not represent 400 million Latin American Spanish speakers. Some countries have multiple official languages (Switzerland has 4, India has 22). The fix: use language names written in their own script — "Deutsch" not "German," "Espanol" not "Spanish" — in a text-based selector.
The Right-to-Left Afterthought. Adding RTL support by applying direction: rtl and text-align: right and calling it done. This misses icon mirroring, shadow direction, animation direction, progress bars, form alignment, navigation hierarchy, and dozens of other spatial elements. The fix: implement RTL using logical properties from the start, test with real Arabic/Hebrew content, and use a native RTL speaker for QA.
Hardcoded Pluralization. Using count === 1 ? "item" : "items". This breaks in Arabic (6 plural forms), Polish (3 forms with complex rules), and even French (zero is singular). The fix: use ICU MessageFormat or Intl.PluralRules, which implements CLDR plural rules for all locales.
Airbnb's i18n Design System. Airbnb operates in 220+ countries and 62 languages. Their design system enforces i18n at the component level:
maxLines prop with ellipsis behaviorSlack's RTL Support. When Slack added Arabic and Hebrew, they discovered mirroring broke threaded messages: the reply indicator line used hardcoded border-left and margin-left. In RTL, the line appeared on the wrong side, disconnecting replies from parents. They migrated 2,400+ CSS declarations from physical to logical properties over 6 months. The hardest part was custom canvas-rendered elements (emoji picker positioning, rich text cursor behavior) where CSS logical properties do not apply and direction-aware JavaScript was needed.
Mozilla's Pontoon Localization Platform. Mozilla localizes Firefox into 90+ languages. Pontoon enforces i18n best practices at the string level:
WhatsApp's Bidirectional Text Handling. WhatsApp supports mixed-direction text in messages (Arabic user sending a message with an English URL). They use the Unicode Bidirectional Algorithm with explicit directional marks: when the app detects a message starting with an RTL character, it wraps the message in a Right-to-Left Mark (U+200F). Embedded LTR segments (URLs, numbers, brand names) are isolated using First Strong Isolate (U+2068). Without these marks, a message containing "Visit www.example.com" in Arabic reorders URL segments, breaking the link.