Add Hebrew translation and RTL support via Docker injection

Injects custom CSS and JS into the Paperclip UI during Docker build:
- RTL layout overrides for Tailwind, Radix UI, and MDXEditor
- Hebrew translation script with MutationObserver for dynamic content
- Patch script to modify index.html with dir="rtl" and lang="he"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Chaim
2026-04-04 20:41:06 +00:00
parent de82ce18f4
commit 5160741248
4 changed files with 1666 additions and 1 deletions

741
assets/rtl-override.css Normal file
View File

@@ -0,0 +1,741 @@
/* ==========================================================================
Paperclip AI - RTL Override for Hebrew (dir="rtl")
Generated from analysis of index-CYurTMty.css (Tailwind v4.1.18 + MDXEditor)
Scoped under html[dir="rtl"] to apply only in RTL mode.
========================================================================== */
/* --------------------------------------------------------------------------
1. GLOBAL DIRECTION
-------------------------------------------------------------------------- */
html[dir="rtl"] {
direction: rtl;
}
html[dir="rtl"] body {
text-align: right;
}
/* --------------------------------------------------------------------------
2. TAILWIND UTILITY CLASSES - Padding Left/Right Swap
.pl-* -> padding-right, .pr-* -> padding-left
-------------------------------------------------------------------------- */
html[dir="rtl"] .pl-1 { padding-left: 0; padding-right: calc(var(--spacing) * 1); }
html[dir="rtl"] .pl-2 { padding-left: 0; padding-right: calc(var(--spacing) * 2); }
html[dir="rtl"] .pl-3 { padding-left: 0; padding-right: calc(var(--spacing) * 3); }
html[dir="rtl"] .pl-4 { padding-left: 0; padding-right: calc(var(--spacing) * 4); }
html[dir="rtl"] .pl-5 { padding-left: 0; padding-right: calc(var(--spacing) * 5); }
html[dir="rtl"] .pl-5\.5 { padding-left: 0; padding-right: calc(var(--spacing) * 5.5); }
html[dir="rtl"] .pl-6 { padding-left: 0; padding-right: calc(var(--spacing) * 6); }
html[dir="rtl"] .pl-7 { padding-left: 0; padding-right: calc(var(--spacing) * 7); }
html[dir="rtl"] .pl-8 { padding-left: 0; padding-right: calc(var(--spacing) * 8); }
html[dir="rtl"] .pr-1 { padding-right: 0; padding-left: calc(var(--spacing) * 1); }
html[dir="rtl"] .pr-2 { padding-right: 0; padding-left: calc(var(--spacing) * 2); }
html[dir="rtl"] .pr-3 { padding-right: 0; padding-left: calc(var(--spacing) * 3); }
html[dir="rtl"] .pr-6 { padding-right: 0; padding-left: calc(var(--spacing) * 6); }
html[dir="rtl"] .pr-8 { padding-right: 0; padding-left: calc(var(--spacing) * 8); }
html[dir="rtl"] .pr-10 { padding-right: 0; padding-left: calc(var(--spacing) * 10); }
/* data-inset padding override */
html[dir="rtl"] .data-\[inset\]\:pl-8[data-inset] {
padding-left: 0;
padding-right: calc(var(--spacing) * 8);
}
/* Responsive padding overrides */
html[dir="rtl"] .sm\:pl-1 { padding-left: 0; padding-right: calc(var(--spacing) * 1); }
html[dir="rtl"] .sm\:pr-3 { padding-right: 0; padding-left: calc(var(--spacing) * 3); }
/* --------------------------------------------------------------------------
3. TAILWIND UTILITY CLASSES - Margin Left/Right Swap
.ml-* -> margin-right, .mr-* -> margin-left
-------------------------------------------------------------------------- */
html[dir="rtl"] .-ml-1\.5 { margin-left: 0; margin-right: calc(var(--spacing) * -1.5); }
html[dir="rtl"] .ml-0\.5 { margin-left: 0; margin-right: calc(var(--spacing) * 0.5); }
html[dir="rtl"] .ml-1 { margin-left: 0; margin-right: calc(var(--spacing) * 1); }
html[dir="rtl"] .ml-1\.5 { margin-left: 0; margin-right: calc(var(--spacing) * 1.5); }
html[dir="rtl"] .ml-2 { margin-left: 0; margin-right: calc(var(--spacing) * 2); }
html[dir="rtl"] .ml-3 { margin-left: 0; margin-right: calc(var(--spacing) * 3); }
html[dir="rtl"] .ml-4 { margin-left: 0; margin-right: calc(var(--spacing) * 4); }
html[dir="rtl"] .ml-5 { margin-left: 0; margin-right: calc(var(--spacing) * 5); }
html[dir="rtl"] .ml-auto { margin-left: 0; margin-right: auto; }
html[dir="rtl"] .mr-1 { margin-right: 0; margin-left: calc(var(--spacing) * 1); }
html[dir="rtl"] .mr-1\.5 { margin-right: 0; margin-left: calc(var(--spacing) * 1.5); }
html[dir="rtl"] .mr-2 { margin-right: 0; margin-left: calc(var(--spacing) * 2); }
html[dir="rtl"] .mr-auto { margin-right: 0; margin-left: auto; }
/* file selector button margin */
html[dir="rtl"] .file\:mr-4::file-selector-button {
margin-right: 0;
margin-left: calc(var(--spacing) * 4);
}
/* Responsive margin overrides */
html[dir="rtl"] .sm\:mr-1 { margin-right: 0; margin-left: calc(var(--spacing) * 1); }
html[dir="rtl"] .md\:ml-auto { margin-left: 0; margin-right: auto; }
/* --------------------------------------------------------------------------
4. TAILWIND UTILITY CLASSES - Left/Right Position Swap
-------------------------------------------------------------------------- */
html[dir="rtl"] .left-0 { left: auto; right: calc(var(--spacing) * 0); }
html[dir="rtl"] .left-1\/2 { left: auto; right: 50%; }
html[dir="rtl"] .left-2 { left: auto; right: calc(var(--spacing) * 2); }
html[dir="rtl"] .left-2\.5 { left: auto; right: calc(var(--spacing) * 2.5); }
html[dir="rtl"] .left-3 { left: auto; right: calc(var(--spacing) * 3); }
html[dir="rtl"] .left-4 { left: auto; right: calc(var(--spacing) * 4); }
html[dir="rtl"] .left-\[-14px\] { left: auto; right: -14px; }
html[dir="rtl"] .left-\[50\%\] { left: auto; right: 50%; }
html[dir="rtl"] .-right-0\.5 { right: auto; left: calc(var(--spacing) * -0.5); }
html[dir="rtl"] .-right-2 { right: auto; left: calc(var(--spacing) * -2); }
html[dir="rtl"] .right-0 { right: auto; left: calc(var(--spacing) * 0); }
html[dir="rtl"] .right-1\.5 { right: auto; left: calc(var(--spacing) * 1.5); }
html[dir="rtl"] .right-2 { right: auto; left: calc(var(--spacing) * 2); }
html[dir="rtl"] .right-3 { right: auto; left: calc(var(--spacing) * 3); }
html[dir="rtl"] .right-4 { right: auto; left: calc(var(--spacing) * 4); }
html[dir="rtl"] .right-6 { right: auto; left: calc(var(--spacing) * 6); }
/* Responsive left positioning */
html[dir="rtl"] .sm\:left-3 { left: auto; right: calc(var(--spacing) * 3); }
/* --------------------------------------------------------------------------
5. TAILWIND UTILITY CLASSES - Text Align Swap
-------------------------------------------------------------------------- */
html[dir="rtl"] .text-left { text-align: right; }
html[dir="rtl"] .text-right { text-align: left; }
html[dir="rtl"] .sm\:text-left { text-align: right; }
html[dir="rtl"] .sm\:text-right { text-align: left; }
/* --------------------------------------------------------------------------
6. TAILWIND UTILITY CLASSES - Float Swap
-------------------------------------------------------------------------- */
html[dir="rtl"] .float-right { float: left; }
/* --------------------------------------------------------------------------
7. TAILWIND UTILITY CLASSES - Border Left/Right Swap
-------------------------------------------------------------------------- */
html[dir="rtl"] .border-l {
border-left-style: none;
border-left-width: 0;
border-right-style: var(--tw-border-style);
border-right-width: 1px;
}
html[dir="rtl"] .border-l-2 {
border-left-style: none;
border-left-width: 0;
border-right-style: var(--tw-border-style);
border-right-width: 2px;
}
html[dir="rtl"] .border-l-transparent {
border-left-color: initial;
border-right-color: #0000;
}
html[dir="rtl"] .border-r {
border-right-style: none;
border-right-width: 0;
border-left-style: var(--tw-border-style);
border-left-width: 1px;
}
/* Responsive border overrides */
html[dir="rtl"] .sm\:border-l {
border-left-style: none;
border-left-width: 0;
border-right-style: var(--tw-border-style);
border-right-width: 1px;
}
html[dir="rtl"] .lg\:border-r {
border-right-style: none;
border-right-width: 0;
border-left-style: var(--tw-border-style);
border-left-width: 1px;
}
/* --------------------------------------------------------------------------
8. TAILWIND UTILITY CLASSES - Rounded Left/Right Swap
-------------------------------------------------------------------------- */
html[dir="rtl"] .rounded-l-md {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-top-right-radius: .5rem;
border-bottom-right-radius: .5rem;
}
html[dir="rtl"] .rounded-r-md {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-top-left-radius: .5rem;
border-bottom-left-radius: .5rem;
}
html[dir="rtl"] .rounded-r-full {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-top-left-radius: 3.40282e38px;
border-bottom-left-radius: 3.40282e38px;
}
/* --------------------------------------------------------------------------
9. TAILWIND UTILITY CLASSES - TranslateX Flip
-------------------------------------------------------------------------- */
html[dir="rtl"] .-translate-x-1\/2 { --tw-translate-x: 50%; }
html[dir="rtl"] .-translate-x-4 { --tw-translate-x: calc(var(--spacing) * 4); }
html[dir="rtl"] .-translate-x-full { --tw-translate-x: 100%; }
html[dir="rtl"] .translate-x-0 { --tw-translate-x: calc(var(--spacing) * 0); }
html[dir="rtl"] .translate-x-0\.5 { --tw-translate-x: calc(var(--spacing) * -0.5); }
html[dir="rtl"] .translate-x-4\.5 { --tw-translate-x: calc(var(--spacing) * -4.5); }
html[dir="rtl"] .translate-x-5 { --tw-translate-x: calc(var(--spacing) * -5); }
html[dir="rtl"] .translate-x-\[-50\%\] { --tw-translate-x: 50%; }
/* --------------------------------------------------------------------------
10. RADIX UI - data-side tooltip/popover offset swap
-------------------------------------------------------------------------- */
html[dir="rtl"] .data-\[side\=left\]\:-translate-x-1[data-side=left] {
--tw-translate-x: calc(var(--spacing) * 1);
}
html[dir="rtl"] .data-\[side\=right\]\:translate-x-1[data-side=right] {
--tw-translate-x: calc(var(--spacing) * -1);
}
/* --------------------------------------------------------------------------
11. MDXEditor - Toolbar Components
-------------------------------------------------------------------------- */
/* Toolbar root - sticky, scrollable row */
html[dir="rtl"] [class*="_toolbarRoot_"] {
flex-direction: row-reverse;
}
/* Toolbar mode switch - push to left in RTL (was margin-left:auto) */
html[dir="rtl"] [class*="_toolbarModeSwitch_"] {
margin-left: 0;
margin-right: auto;
}
/* Toolbar separator - swap border sides */
html[dir="rtl"] [class*="_toolbarRoot_"] div[role="separator"] {
border-left: 1px solid var(--baseBase);
border-right: 1px solid var(--baseBorder);
}
/* Toolbar button adjacency spacing */
html[dir="rtl"] [class*="_toolbarButton_"] + [class*="_toolbarButton_"] {
margin-left: 0;
margin-right: var(--spacing-1);
}
/* Toolbar toggle first/last child border-radius swap */
html[dir="rtl"] [class*="_toolbarToggleSingleGroup_"]:first-of-type [class*="_toolbarToggleItem_"]:only-child,
html[dir="rtl"] [class*="_toolbarToggleSingleGroup_"]:only-child [class*="_toolbarToggleItem_"]:first-child,
html[dir="rtl"] [class*="_toolbarModeSwitch_"] [class*="_toolbarToggleItem_"]:first-child {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-top-right-radius: var(--radius-base);
border-bottom-right-radius: var(--radius-base);
}
html[dir="rtl"] [class*="_toolbarToggleSingleGroup_"]:last-of-type [class*="_toolbarToggleItem_"]:only-child,
html[dir="rtl"] [class*="_toolbarToggleSingleGroup_"]:only-child [class*="_toolbarToggleItem_"]:last-child,
html[dir="rtl"] [class*="_toolbarModeSwitch_"] [class*="_toolbarToggleItem_"]:last-child {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-top-left-radius: var(--radius-base);
border-bottom-left-radius: var(--radius-base);
}
/* Dropdown arrow - push to right in RTL (was margin-left:auto) */
html[dir="rtl"] [class*="_toolbarNodeKindSelectDropdownArrow_"],
html[dir="rtl"] [class*="_selectDropdownArrow_"] {
margin-left: 0;
margin-right: auto;
}
/* Dropdown container - border radius swap */
html[dir="rtl"] [class*="_toolbarNodeKindSelectContainer_"],
html[dir="rtl"] [class*="_toolbarButtonDropdownContainer_"],
html[dir="rtl"] [class*="_toolbarCodeBlockLanguageSelectContent_"],
html[dir="rtl"] [class*="_selectContainer_"] {
border-bottom-left-radius: 0;
border-bottom-right-radius: var(--radius-base);
}
html[dir="rtl"] [class*="_toolbarButtonDropdownContainer_"],
html[dir="rtl"] [class*="_toolbarButtonDropdownContainer_"] [class*="_selectItem_"]:first-child {
border-top-right-radius: 0;
border-top-left-radius: var(--radius-base);
}
/* Select trigger open state - radius swap */
html[dir="rtl"] [class*="_toolbarNodeKindSelectTrigger_"][data-state="open"],
html[dir="rtl"] [class*="_toolbarButtonSelectTrigger_"][data-state="open"],
html[dir="rtl"] [class*="_selectTrigger_"][data-state="open"] {
border-bottom-right-radius: var(--radius-none);
border-bottom-left-radius: var(--radius-none);
}
/* Select item last child - radius swap */
html[dir="rtl"] [class*="_toolbarNodeKindSelectItem_"]:last-child,
html[dir="rtl"] [class*="_selectItem_"]:last-child {
border-bottom-left-radius: 0;
border-bottom-right-radius: var(--radius-base);
}
/* --------------------------------------------------------------------------
12. MDXEditor - CodeMirror & Image Edit Toolbars
Position: was right:0 -> left:0, border-bottom-left -> border-bottom-right
-------------------------------------------------------------------------- */
html[dir="rtl"] [class*="_codeMirrorToolbar_"] {
right: auto;
left: 0;
border-bottom-left-radius: 0;
border-bottom-right-radius: var(--radius-base);
}
html[dir="rtl"] [class*="_editImageToolbar_"] {
right: auto;
left: 0;
border-bottom-left-radius: 0;
border-bottom-right-radius: var(--radius-base);
}
/* --------------------------------------------------------------------------
13. MDXEditor - Property Panel
-------------------------------------------------------------------------- */
html[dir="rtl"] [class*="_propertyPanelTitle_"] {
padding-left: 0;
padding-right: var(--spacing-2);
}
html[dir="rtl"] [class*="_propertyEditorTable_"] th {
text-align: right;
}
html[dir="rtl"] [class*="_propertyEditorTable_"] [class*="_readOnlyColumnCell_"] {
padding-left: initial;
padding-right: 0;
}
html[dir="rtl"] [class*="_readOnlyColumnCell_"] {
padding-left: initial;
padding-right: 0;
}
html[dir="rtl"] [class*="_propertyEditorTable_"] td:last-child [class*="_iconButton_"] {
margin-left: 0;
margin-right: var(--spacing-4);
}
/* --------------------------------------------------------------------------
14. MDXEditor - Dialog
-------------------------------------------------------------------------- */
/* Dialog centered positioning - no swap needed (translate-50% centers) */
html[dir="rtl"] [class*="_dialogTitle_"] {
padding-left: 0;
padding-right: var(--spacing-2);
}
/* Link dialog input button */
html[dir="rtl"] [class*="_linkDialogInputWrapper_"] > button {
padding-right: 0;
padding-left: var(--spacing-2);
}
/* Link dialog input dropdown open state */
html[dir="rtl"] [class*="_linkDialogInputWrapper_"][data-visible-dropdown="true"] {
border-bottom-left-radius: var(--radius-none);
border-bottom-right-radius: var(--radius-none);
}
/* Link dialog preview anchor */
html[dir="rtl"] [class*="_linkDialogPreviewAnchor_"] {
margin-right: 0;
margin-left: var(--spacing-1);
}
/* --------------------------------------------------------------------------
15. MDXEditor - Generic Component Name
-------------------------------------------------------------------------- */
html[dir="rtl"] [class*="_genericComponentName_"] {
padding-right: 0;
padding-left: var(--spacing-2);
}
/* --------------------------------------------------------------------------
16. MDXEditor - Table Editor
-------------------------------------------------------------------------- */
html[dir="rtl"] [class*="_tableEditor_"] thead > tr > th {
text-align: left; /* was right, swap */
}
html[dir="rtl"] [class*="_toolCell_"] {
text-align: left; /* was right, swap */
}
html[dir="rtl"] [class*="_leftAlignedCell_"] {
text-align: right; /* was left, swap */
}
html[dir="rtl"] [class*="_rightAlignedCell_"] {
text-align: left; /* was right, swap */
}
/* Table column editor toolbar separators */
html[dir="rtl"] [class*="_tableColumnEditorToolbar_"] [role="separator"] {
margin-left: 0;
margin-right: var(--spacing-1);
}
/* Add column button - was on right side */
html[dir="rtl"] [class*="_addColumnButton_"] {
margin-left: 0;
margin-right: var(--spacing-px);
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-top-left-radius: var(--radius-medium);
border-bottom-left-radius: var(--radius-medium);
}
/* Toggle group first/last child radius swap */
html[dir="rtl"] [class*="_toggleGroupRoot_"] button:first-child {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-top-right-radius: var(--radius-base);
border-bottom-right-radius: var(--radius-base);
}
html[dir="rtl"] [class*="_toggleGroupRoot_"] button:last-child {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-top-left-radius: var(--radius-base);
border-bottom-left-radius: var(--radius-base);
}
/* --------------------------------------------------------------------------
17. MDXEditor - Diff Source Toggle
-------------------------------------------------------------------------- */
html[dir="rtl"] [class*="_diffSourceToggleWrapper_"] {
margin-left: 0;
margin-right: auto;
right: auto;
left: 0;
}
/* --------------------------------------------------------------------------
18. MDXEditor - Select with Label
-------------------------------------------------------------------------- */
html[dir="rtl"] [class*="_selectWithLabel_"] {
margin-left: 0;
margin-right: var(--spacing-2);
}
html[dir="rtl"] [class*="_toolbarTitleMode_"] {
margin-left: 0;
margin-right: var(--spacing-2);
}
/* --------------------------------------------------------------------------
19. MDXEditor - Downshift Autocomplete
-------------------------------------------------------------------------- */
html[dir="rtl"] [class*="_downshiftInputWrapper_"] > button {
padding-right: 0;
padding-left: var(--spacing-2);
}
html[dir="rtl"] [class*="_downshiftInputWrapper_"][data-visible-dropdown="true"] {
border-bottom-left-radius: var(--radius-none);
border-bottom-right-radius: var(--radius-none);
}
html[dir="rtl"] [class*="_downshiftAutocompleteContainer_"] ul {
border-bottom-left-radius: 0;
border-bottom-right-radius: var(--radius-medium);
}
html[dir="rtl"] [class*="_downshiftAutocompleteContainer_"] ul li:last-of-type {
border-bottom-left-radius: 0;
border-bottom-right-radius: var(--radius-medium);
}
/* --------------------------------------------------------------------------
20. MDXEditor - List Items (Checkbox)
-------------------------------------------------------------------------- */
html[dir="rtl"] [class*="_listItemChecked_"],
html[dir="rtl"] [class*="_listItemUnchecked_"] {
padding-left: 0;
padding-right: var(--spacing-6);
}
html[dir="rtl"] [class*="_listItemChecked_"]:before,
html[dir="rtl"] [class*="_listItemUnchecked_"]:before {
left: auto;
right: 0;
}
html[dir="rtl"] [class*="_listItemChecked_"]:after {
left: auto;
right: var(--spacing-1_5);
}
/* --------------------------------------------------------------------------
21. MDXEditor - Admonitions (Info/Warning/Danger blocks)
-------------------------------------------------------------------------- */
html[dir="rtl"] [class*="_admonitionDanger_"],
html[dir="rtl"] [class*="_admonitionInfo_"],
html[dir="rtl"] [class*="_admonitionNote_"],
html[dir="rtl"] [class*="_admonitionTip_"],
html[dir="rtl"] [class*="_admonitionCaution_"] {
border-left: none;
border-right: 3px solid var(--admonitionBorder);
}
/* --------------------------------------------------------------------------
22. Paperclip Markdown Rendered Content
-------------------------------------------------------------------------- */
html[dir="rtl"] .paperclip-mdxeditor-content ul,
html[dir="rtl"] .paperclip-mdxeditor-content ol {
padding-left: 0;
padding-right: 1.6em;
}
html[dir="rtl"] .paperclip-mdxeditor-content blockquote {
border-left: none;
border-right: 3px solid var(--border);
padding-left: 0;
padding-right: 1em;
}
html[dir="rtl"] .paperclip-markdown :where(ul, ol) {
padding-left: 0;
padding-right: 1.15rem;
}
html[dir="rtl"] .paperclip-markdown li {
padding-left: 0;
padding-right: .2rem;
}
html[dir="rtl"] .paperclip-markdown blockquote {
border-left: none;
border-right: .24rem solid var(--border);
margin-left: initial;
margin-right: 0;
padding-left: 0;
padding-right: .95rem;
}
@supports (color: color-mix(in lab, red, red)) {
html[dir="rtl"] .paperclip-markdown blockquote {
border-right: .24rem solid color-mix(in oklab, var(--border) 84%, var(--muted-foreground) 16%);
}
}
html[dir="rtl"] .paperclip-markdown th {
text-align: right;
}
/* Nested list/ol padding overrides from Tailwind arbitrary selectors */
html[dir="rtl"] .\[\&_ol\]\:pl-5 ol {
padding-left: 0;
padding-right: calc(var(--spacing) * 5);
}
html[dir="rtl"] .\[\&_ul\]\:pl-5 ul {
padding-left: 0;
padding-right: calc(var(--spacing) * 5);
}
/* --------------------------------------------------------------------------
23. CodeMirror (inside MDXEditor) - Cursor & Gutters
-------------------------------------------------------------------------- */
html[dir="rtl"] .paperclip-mdxeditor .cm-cursor,
html[dir="rtl"] .paperclip-mdxeditor .cm-dropCursor {
border-left-color: transparent !important;
border-right-color: #cdd6f4 !important;
}
html[dir="rtl"] .paperclip-mdxeditor .cm-gutters {
border-right: none !important;
border-left: 1px solid #313244 !important;
}
/* --------------------------------------------------------------------------
24. Sidebar Layout (shadcn/ui sidebar pattern)
The sidebar CSS variables are defined but the layout depends on the
app's component structure. These overrides handle common patterns.
-------------------------------------------------------------------------- */
/* If sidebar is positioned with left:0, move to right:0 */
html[dir="rtl"] [data-sidebar="sidebar"] {
left: auto;
right: 0;
}
/* Sidebar rail/resize handle */
html[dir="rtl"] [data-sidebar="rail"] {
left: auto;
right: 0;
}
/* Main content margin adjustment when sidebar present */
html[dir="rtl"] [data-sidebar="content"] {
margin-left: 0;
}
/* --------------------------------------------------------------------------
25. Dialog Overlay - full screen, no directional change needed
But ensure overlay covers correctly
-------------------------------------------------------------------------- */
html[dir="rtl"] [class*="_dialogOverlay_"] {
left: 0;
right: 0;
}
/* --------------------------------------------------------------------------
26. Radix UI Popover/Dropdown Transform Origins
These use CSS variables, so they auto-adapt. No override needed.
-------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
27. Group rotation for collapsible triggers (chevron icons)
In RTL, a right-pointing chevron should point left by default
and rotate when open
-------------------------------------------------------------------------- */
html[dir="rtl"] .group-data-\[state\=open\]\:rotate-90:is(:where(.group)[data-state=open] *) {
rotate: -90deg;
}
/* --------------------------------------------------------------------------
28. General Hebrew typography adjustments
-------------------------------------------------------------------------- */
html[dir="rtl"] input,
html[dir="rtl"] textarea,
html[dir="rtl"] select {
text-align: right;
}
html[dir="rtl"] input[type="email"],
html[dir="rtl"] input[type="url"],
html[dir="rtl"] input[type="number"] {
text-align: left;
direction: ltr;
}
/* Placeholder text alignment */
html[dir="rtl"] input::placeholder,
html[dir="rtl"] textarea::placeholder {
text-align: right;
}
/* --------------------------------------------------------------------------
29. Scrollbar position (WebKit) - move to left side in RTL
-------------------------------------------------------------------------- */
html[dir="rtl"] ::-webkit-scrollbar {
/* Scrollbars auto-flip in RTL for most browsers */
}
/* --------------------------------------------------------------------------
30. Active SVG translate (press feedback) - flip X direction
-------------------------------------------------------------------------- */
html[dir="rtl"] [class*="_toolbarToggleItem_"]:active svg,
html[dir="rtl"] [class*="_toolbarButton_"]:active svg,
html[dir="rtl"] [class*="_actionButton_"]:active svg,
html[dir="rtl"] [class*="_tableColumnEditorTrigger_"]:active svg,
html[dir="rtl"] [class*="_tableColumnEditorToolbar_"] > button:active svg,
html[dir="rtl"] [class*="_toggleGroupRoot_"] button:active svg,
html[dir="rtl"] [class*="_addColumnButton_"]:active svg,
html[dir="rtl"] [class*="_addRowButton_"]:active svg {
transform: translate(-1px, 1px);
}
/* --------------------------------------------------------------------------
31. Responsive breakpoint overrides
-------------------------------------------------------------------------- */
@media (min-width: 640px) {
html[dir="rtl"] .sm\:flex-row {
flex-direction: row-reverse;
}
}
@media (min-width: 768px) {
html[dir="rtl"] .md\:flex-row {
flex-direction: row-reverse;
}
}
@media (min-width: 1024px) {
html[dir="rtl"] .lg\:flex-row {
flex-direction: row-reverse;
}
}
@media (min-width: 1280px) {
html[dir="rtl"] .xl\:flex-row {
flex-direction: row-reverse;
}
}
/* --------------------------------------------------------------------------
32. Fix for centered dialogs using left:50% + translate(-50%, -50%)
These should remain centered, so override left->right and flip translate
-------------------------------------------------------------------------- */
html[dir="rtl"] [class*="_dialogContent_"],
html[dir="rtl"] [class*="_largeDialogContent_"] {
left: auto;
right: 50%;
transform: translate(50%, -50%);
}
@keyframes rtl-contentShow {
0% {
opacity: 0;
transform: translate(50%, -48%) scale(.96);
}
to {
opacity: 1;
transform: translate(50%, -50%) scale(1);
}
}
html[dir="rtl"] [class*="_dialogContent_"],
html[dir="rtl"] [class*="_largeDialogContent_"] {
animation: rtl-contentShow .15s cubic-bezier(.16, 1, .3, 1);
}
/* --------------------------------------------------------------------------
33. Fix Tailwind space-x utilities
These already use margin-inline-start/end, so they should auto-adapt.
No override needed for space-x-* classes (they use logical properties).
-------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
34. Override for the bottom-positioned elements with safe-area-inset
These are vertical-only, no RTL swap needed.
-------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
35. Miscellaneous icon and decorative element adjustments
-------------------------------------------------------------------------- */
/* Ensure icons in buttons don't get mirrored unintentionally */
html[dir="rtl"] svg {
/* Most icons should NOT be mirrored. Only directional icons need it. */
}
/* Mirror directional icons (arrows, chevrons) */
html[dir="rtl"] [class*="chevron-left"] svg,
html[dir="rtl"] [class*="chevron-right"] svg,
html[dir="rtl"] [class*="arrow-left"] svg,
html[dir="rtl"] [class*="arrow-right"] svg {
transform: scaleX(-1);
}