Preliminary step for RTL

This commit is contained in:
Lim Chee Aun 2024-08-04 13:32:30 +08:00
parent 2aff1dc1fd
commit f05e3012e3
44 changed files with 654 additions and 383 deletions

View file

@ -162,7 +162,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
white-space: nowrap; white-space: nowrap;
} }
.deck > header .header-grid > .header-side:last-of-type { .deck > header .header-grid > .header-side:last-of-type {
text-align: right; text-align: end;
grid-column: 3; grid-column: 3;
} }
.deck > header .header-grid :is(button, .button).plain { .deck > header .header-grid :is(button, .button).plain {
@ -181,8 +181,8 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
grid-template-columns: 1fr max-content; grid-template-columns: 1fr max-content;
} }
.deck > header .header-grid-2 h1 { .deck > header .header-grid-2 h1 {
text-align: left; text-align: start;
padding-left: 8px; padding-inline-start: 8px;
} }
.deck > header .header-grid h1:has(.ancestors-indicator) { .deck > header .header-grid h1:has(.ancestors-indicator) {
display: flex; display: flex;
@ -217,6 +217,19 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
opacity: 0.25; opacity: 0.25;
} }
} }
@keyframes indeterminate-bar-rtl {
0% {
transform: translateX(50%);
opacity: 0.25;
}
50% {
opacity: 1;
}
100% {
transform: translateX(-50%);
opacity: 0.25;
}
}
.deck > header.loading:after { .deck > header.loading:after {
pointer-events: none; pointer-events: none;
content: ''; content: '';
@ -232,6 +245,9 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
transparent transparent
); );
animation: indeterminate-bar 1s ease-in-out infinite alternate; animation: indeterminate-bar 1s ease-in-out infinite alternate;
&:dir(rtl) {
animation-name: indeterminate-bar-rtl;
}
} }
@media (min-width: 40em) { @media (min-width: 40em) {
.deck > header.loading:after { .deck > header.loading:after {
@ -268,6 +284,9 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
width: 95vw; width: 95vw;
max-width: calc(320px * 3.3); max-width: calc(320px * 3.3);
transform: translateX(calc(-50% + var(--main-width) / 2)); transform: translateX(calc(-50% + var(--main-width) / 2));
&:dir(rtl) {
transform: translateX(calc(50% - var(--main-width) / 2));
}
} }
} }
@ -346,6 +365,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
margin: 0; margin: 0;
padding: 0; padding: 0;
border-bottom: var(--hairline-width) solid var(--divider-color); border-bottom: var(--hairline-width) solid var(--divider-color);
--line-dir: var(--to-forward);
} }
.timeline.flat > li { .timeline.flat > li {
border-bottom: none; border-bottom: none;
@ -362,10 +382,14 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
--avatar-size: 50px; --avatar-size: 50px;
--avatar-margin-start: 16px; --avatar-margin-start: 16px;
--avatar-margin-end: 12px; --avatar-margin-end: 12px;
--line-curve: 45deg;
:dir(rtl) & {
--line-curve: -45deg;
}
} }
.timeline.contextual > li { .timeline.contextual > li {
background-image: linear-gradient( background-image: linear-gradient(
to right, var(--line-dir),
transparent, transparent,
transparent var(--line-start), transparent var(--line-start),
var(--comment-line-color) var(--line-start), var(--comment-line-color) var(--line-start),
@ -394,7 +418,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
.timeline.contextual .timeline.contextual
> li.descendant:not(.thread) > li.descendant:not(.thread)
> :is(.status-link, .status-focus) { > :is(.status-link, .status-focus) {
padding-left: 40px; padding-inline-start: 40px;
} }
.timeline.contextual .replies[data-scroll-left]:not([data-scroll-left='0']) { .timeline.contextual .replies[data-scroll-left]:not([data-scroll-left='0']) {
background-color: var(--bg-color); background-color: var(--bg-color);
@ -408,7 +432,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
} }
.timeline.contextual .replies[data-comments-level='4']:has(.replies) { .timeline.contextual .replies[data-comments-level='4']:has(.replies) {
overflow-x: auto; overflow-x: auto;
mask-image: linear-gradient(to left, transparent, black 32px); mask-image: linear-gradient(var(--to-backward), transparent, black 32px);
} }
.timeline.contextual .timeline.contextual
.replies[data-comments-level='4']:has(.replies) .replies[data-comments-level='4']:has(.replies)
@ -426,145 +450,61 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
> :is(.status-link, .status-focus) > :is(.status-link, .status-focus)
+ .replies + .replies
.replies-summary { .replies-summary {
margin-left: calc( margin-inline-start: calc(
var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) + var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) +
(var(--line-margin-end) * (var(--comments-level) - 1)) (var(--line-margin-end) * (var(--comments-level) - 1))
); );
} }
/* .timeline.contextual
> li.descendant.thread
> .status-link
+ .replies
.replies
> .replies-summary {
margin-left: calc(
var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) +
var(--line-margin-end)
);
}
.timeline.contextual
> li.descendant.thread
> .status-link
+ .replies
.replies
.replies
> .replies-summary {
margin-left: calc(
var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) +
(var(--line-margin-end) * 2)
);
} */
.timeline.contextual .timeline.contextual
> li.descendant.thread > li.descendant.thread
> :is(.status-link, .status-focus) > :is(.status-link, .status-focus)
+ .replies + .replies
:is(.status-link, .status-focus) { :is(.status-link, .status-focus) {
padding-left: calc( padding-inline-start: calc(
var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) + var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) +
(var(--line-margin-end) * (var(--comments-level) - 1)) (var(--line-margin-end) * (var(--comments-level) - 1))
); );
} }
/* .timeline.contextual
> li.descendant.thread
> .status-link
+ .replies
.replies
.status-link {
padding-left: calc(
var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) +
var(--line-margin-end)
);
}
.timeline.contextual
> li.descendant.thread
> .status-link
+ .replies
.replies
.replies
.status-link {
padding-left: calc(
var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) +
(var(--line-margin-end) * 2)
);
} */
.timeline.contextual .timeline.contextual
> li.descendant:not(.thread) > li.descendant:not(.thread)
> :is(.status-link, .status-focus) > :is(.status-link, .status-focus)
+ .replies + .replies
.replies-summary { .replies-summary {
margin-left: calc( margin-inline-start: calc(
var(--thread-start) + var(--line-margin-end) * var(--comments-level) var(--thread-start) + var(--line-margin-end) * var(--comments-level)
); );
} }
/* .timeline.contextual
> li.descendant:not(.thread)
> .status-link
+ .replies
.replies
> .replies-summary {
margin-left: calc(
var(--thread-start) + var(--line-margin-end) + var(--line-margin-end)
);
}
.timeline.contextual
> li.descendant:not(.thread)
> .status-link
+ .replies
.replies
.replies
> .replies-summary {
margin-left: calc(
var(--thread-start) + var(--line-margin-end) + (var(--line-margin-end) * 2)
);
} */
.timeline.contextual .timeline.contextual
> li.descendant:not(.thread) > li.descendant:not(.thread)
> :is(.status-link, .status-focus) > :is(.status-link, .status-focus)
+ .replies + .replies
:is(.status-link, .status-focus) { :is(.status-link, .status-focus) {
padding-left: calc( padding-inline-start: calc(
var(--thread-start) + var(--line-margin-end) * var(--comments-level) var(--thread-start) + var(--line-margin-end) * var(--comments-level)
); );
} }
/* .timeline.contextual
> li.descendant:not(.thread)
> .status-link
+ .replies
.replies
.status-link {
padding-left: calc(var(--thread-start) + (var(--line-margin-end) * 2));
}
.timeline.contextual
> li.descendant:not(.thread)
> .status-link
+ .replies
.replies
.replies
.status-link {
padding-left: calc(var(--thread-start) + (var(--line-margin-end) * 3));
} */
.timeline.contextual > li.descendant:not(.thread):before { .timeline.contextual > li.descendant:not(.thread):before {
content: ''; content: '';
position: absolute; position: absolute;
top: 10px; top: 10px;
left: var(--line-start); inset-inline-start: var(--line-start);
width: var(--line-diameter); width: var(--line-diameter);
height: var(--line-diameter); height: var(--line-diameter);
border-radius: var(--line-radius); border-radius: var(--line-radius);
border-style: solid; border-style: solid;
border-width: var(--line-width); border-width: var(--line-width);
border-color: transparent transparent var(--comment-line-color) transparent; border-color: transparent transparent var(--comment-line-color) transparent;
transform: rotate(45deg); transform: rotate(var(--line-curve));
} }
.timeline.contextual > li .replies-link { .timeline.contextual > li .replies-link {
color: var(--text-insignificant-color); color: var(--text-insignificant-color);
margin-left: 16px; margin-inline-start: 16px;
margin-top: -12px; margin-top: -12px;
padding-bottom: 12px; padding-bottom: 12px;
font-size: 90%; font-size: 90%;
} }
.timeline.contextual > li.ancestor .replies-link { .timeline.contextual > li.ancestor .replies-link {
margin-left: calc( margin-inline-start: calc(
var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end)
); );
} }
@ -572,7 +512,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
> li.thread > li.thread
> :is(.status-link, .status-focus) > :is(.status-link, .status-focus)
.replies-link { .replies-link {
margin-left: calc( margin-inline-start: calc(
var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end)
); );
} }
@ -603,7 +543,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
list-style: none; list-style: none;
gap: 8px; gap: 8px;
align-items: center; align-items: center;
margin-right: calc(44px + 8px); margin-inline-end: calc(44px + 8px);
b { b {
font-weight: 500; font-weight: 500;
@ -618,7 +558,9 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
transition: transform 0.3s ease; transition: transform 0.3s ease;
&:not(:first-child) { &:not(:first-child) {
margin: 0 0 0 -4px; transform: rotate(0deg);
margin: 0;
margin-inline-start: -4px;
} }
} }
} }
@ -637,7 +579,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
.replies-parent-link { .replies-parent-link {
position: absolute; position: absolute;
right: 4px; inset-inline-end: 4px;
height: 100%; height: 100%;
z-index: 2; z-index: 2;
font-size: 16px; font-size: 16px;
@ -648,8 +590,11 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
align-items: center; align-items: center;
padding: var(--summary-padding) calc(var(--summary-padding) * 2); padding: var(--summary-padding) calc(var(--summary-padding) * 2);
transform: translateX(100%); transform: translateX(100%);
margin: calc(-1 * var(--summary-padding)) calc(-1 * var(--summary-padding)) &:dir(rtl) {
calc(-1 * var(--summary-padding)) 0; transform: translateX(-100%);
}
margin: calc(-1 * var(--summary-padding)) 0;
margin-inline-end: calc(-1 * var(--summary-padding));
border-radius: 8px; border-radius: 8px;
background-color: var(--link-bg-color); background-color: var(--link-bg-color);
@ -681,7 +626,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
color: var(--text-color); color: var(--text-color);
background-color: var(--comment-line-color); background-color: var(--comment-line-color);
background-image: linear-gradient( background-image: linear-gradient(
to top right, to top var(--forward),
var(--comment-line-color), var(--comment-line-color),
var(--bg-faded-color) var(--bg-faded-color)
); );
@ -697,7 +642,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
} }
} }
.timeline.contextual > li .replies[open] > .replies-summary { .timeline.contextual > li .replies[open] > .replies-summary {
border-bottom-left-radius: 0; border-end-start-radius: 0;
.avatars { .avatars {
opacity: 0.5; opacity: 0.5;
@ -727,7 +672,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
); );
--line-end: calc(var(--line-start) + var(--line-width)); --line-end: calc(var(--line-start) + var(--line-width));
background-image: linear-gradient( background-image: linear-gradient(
to right, var(--line-dir),
transparent, transparent,
transparent var(--line-start), transparent var(--line-start),
var(--comment-line-color) var(--line-start), var(--comment-line-color) var(--line-start),
@ -768,14 +713,14 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
content: ''; content: '';
position: absolute; position: absolute;
top: 10px; top: 10px;
left: var(--line-start); inset-inline-start: var(--line-start);
width: var(--line-diameter); width: var(--line-diameter);
height: var(--line-diameter); height: var(--line-diameter);
border-radius: var(--line-radius); border-radius: var(--line-radius);
border-style: solid; border-style: solid;
border-width: var(--line-width); border-width: var(--line-width);
border-color: transparent transparent var(--comment-line-color) transparent; border-color: transparent transparent var(--comment-line-color) transparent;
transform: rotate(45deg); transform: rotate(var(--line-curve));
} }
/* .timeline.contextual > li .replies .replies li:before { /* .timeline.contextual > li .replies .replies li:before {
--line-start: calc( --line-start: calc(
@ -814,8 +759,11 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
> ul > li:only-child { > ul > li:only-child {
> .replies { > .replies {
> ul > li:only-child { > ul > li:only-child {
margin-left: calc(-1 * var(--line-margin-end)); margin-inline-start: calc(-1 * var(--line-margin-end));
background-position: calc(16px) 0; background-position: 16px 0;
&:dir(rtl) {
background-position: -16px 0;
}
background-size: 100% calc(20px + 8px); background-size: 100% calc(20px + 8px);
&:before { &:before {
@ -856,7 +804,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
--line-width: 3px; --line-width: 3px;
--line-end: calc(var(--line-start) + var(--line-width)); --line-end: calc(var(--line-start) + var(--line-width));
background-image: linear-gradient( background-image: linear-gradient(
to right, var(--line-dir),
transparent, transparent,
transparent var(--line-start), transparent var(--line-start),
var(--comment-line-color) var(--line-start), var(--comment-line-color) var(--line-start),
@ -868,8 +816,8 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
} }
.timeline:not(.flat) > li.timeline-item-container-start { .timeline:not(.flat) > li.timeline-item-container-start {
margin-bottom: 0; margin-bottom: 0;
border-bottom-left-radius: 0; border-end-start-radius: 0;
border-bottom-right-radius: 0; border-end-end-radius: 0;
border-bottom: 0; border-bottom: 0;
background-position: 0 calc(16px + var(--avatar-size)); background-position: 0 calc(16px + var(--avatar-size));
} }
@ -882,8 +830,8 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
} }
.timeline:not(.flat) > li.timeline-item-container-end { .timeline:not(.flat) > li.timeline-item-container-end {
margin-top: 0; margin-top: 0;
border-top-left-radius: 0; border-start-start-radius: 0;
border-top-right-radius: 0; border-start-end-radius: 0;
border-top: 0; border-top: 0;
background-size: 100% 16px; background-size: 100% 16px;
@ -909,8 +857,10 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
} }
.timeline .show-more { .timeline .show-more {
padding-left: calc(var(--line-end) + var(--line-margin-end)) !important; padding-inline-start: calc(
text-align: left; var(--line-end) + var(--line-margin-end)
) !important;
text-align: start;
background-color: transparent !important; background-color: transparent !important;
backdrop-filter: none !important; backdrop-filter: none !important;
position: relative; position: relative;
@ -918,7 +868,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
padding-block: 16px !important; padding-block: 16px !important;
.avatars-bunch > .avatar:not(:first-child) { .avatars-bunch > .avatar:not(:first-child) {
margin-left: -4px; margin-inline-start: -4px;
} }
} }
.timeline .show-more:hover { .timeline .show-more:hover {
@ -930,14 +880,14 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
content: ''; content: '';
position: absolute; position: absolute;
top: 10px; top: 10px;
left: var(--line-start); inset-inline-start: var(--line-start);
width: var(--line-diameter); width: var(--line-diameter);
height: var(--line-diameter); height: var(--line-diameter);
border-radius: var(--line-radius); border-radius: var(--line-radius);
border-style: solid; border-style: solid;
border-width: var(--line-width); border-width: var(--line-width);
border-color: transparent transparent var(--comment-line-color) transparent; border-color: transparent transparent var(--comment-line-color) transparent;
transform: rotate(45deg); transform: rotate(var(--line-curve));
} }
.status-loading { .status-loading {
@ -988,7 +938,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
.status-carousel { .status-carousel {
--carousel-faded-color: var(--bg-faded-color); --carousel-faded-color: var(--bg-faded-color);
background: linear-gradient( background: linear-gradient(
to bottom right, to bottom var(--forward),
var(--carousel-faded-color), var(--carousel-faded-color),
transparent transparent
); );
@ -1058,12 +1008,12 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
display: none; display: none;
} }
.status-carousel .status-carousel-beacon { .status-carousel .status-carousel-beacon {
margin-right: calc(-1 * var(--carousel-gap)); margin-inline-end: calc(-1 * var(--carousel-gap));
pointer-events: none; pointer-events: none;
opacity: 0; opacity: 0;
~ .status-carousel-beacon { ~ .status-carousel-beacon {
margin-left: calc(-1 * var(--carousel-gap)); margin-inline-start: calc(-1 * var(--carousel-gap));
} }
} }
/* /*
@ -1107,7 +1057,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
.status-carousel.boosts-carousel > ul > li:before { .status-carousel.boosts-carousel > ul > li:before {
content: counter(index); content: counter(index);
position: absolute; position: absolute;
left: 0; inset-inline-start: 0;
font-size: 10px; font-size: 10px;
color: var(--text-insignificant-color); color: var(--text-insignificant-color);
padding: 6px; padding: 6px;
@ -1147,11 +1097,11 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
box-shadow: 0 1px var(--bg-color); box-shadow: 0 1px var(--bg-color);
&:has(.status-badge:not(:empty)) { &:has(.status-badge:not(:empty)) {
border-top-right-radius: 8px; border-start-end-radius: 8px;
} }
.status-carousel.boosts-carousel & { .status-carousel.boosts-carousel &:not(.timeline-item-carousel-group &) {
border-top-left-radius: 8px; border-start-start-radius: 8px;
} }
} }
.status-carousel-link::focus { .status-carousel-link::focus {
@ -1189,14 +1139,29 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0);
} }
} }
@keyframes slide-in-rtl {
0% {
transform: translate3d(-100%, 0, 0);
}
100% {
transform: translate3d(0, 0, 0);
}
}
.deck-backdrop .deck { .deck-backdrop .deck {
width: var(--main-width); width: var(--main-width);
max-width: 100vw; max-width: 100vw;
background-color: var(--bg-color); background-color: var(--bg-color);
box-shadow: -1px 0 var(--bg-color); box-shadow: -1px 0 var(--bg-color);
&:dir(rtl) {
box-shadow: 1px 0 var(--bg-color);
}
} }
.deck-backdrop .deck.slide-in:not(.deck-view-full) { .deck-backdrop .deck.slide-in:not(.deck-view-full) {
animation: slide-in 0.5s var(--timing-function); animation: slide-in 0.5s var(--timing-function);
&:dir(rtl) {
animation-name: slide-in-rtl;
}
} }
.deck-backdrop .deck .status { .deck-backdrop .deck .status {
max-width: var(--main-width); max-width: var(--main-width);
@ -1240,7 +1205,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
content: ''; content: '';
display: inline-block; display: inline-block;
position: absolute; position: absolute;
right: 10px; inset-inline-end: 10px;
width: 4px; width: 4px;
height: 4px; height: 4px;
border-radius: 50%; border-radius: 50%;
@ -1519,7 +1484,7 @@ body:has(.media-modal-container + .status-deck) .media-post-link {
.media-modal-container + .status-deck { .media-modal-container + .status-deck {
/* display: none; */ /* display: none; */
position: absolute; position: absolute;
right: 0; inset-inline-end: 0;
z-index: -1; z-index: -1;
pointer-events: none; pointer-events: none;
user-select: none; user-select: none;
@ -1547,8 +1512,8 @@ body:has(.media-modal-container + .status-deck) .media-post-link {
) )
#modal-container #modal-container
> div { > div {
left: 0; inset-inline-start: 0;
right: 350px; inset-inline-end: 350px;
width: auto; width: auto;
} }
/* ✨ New */ /* ✨ New */
@ -1579,8 +1544,8 @@ body:has(.media-modal-container + .status-deck) .media-post-link {
position: fixed; position: fixed;
bottom: 16px; bottom: 16px;
bottom: max(16px, env(safe-area-inset-bottom)); bottom: max(16px, env(safe-area-inset-bottom));
right: 16px; inset-inline-end: 16px;
right: max(16px, env(safe-area-inset-right)); inset-inline-end: max(16px, env(safe-area-inset-right));
padding: 16px; padding: 16px;
background-color: var(--button-bg-blur-color); background-color: var(--button-bg-blur-color);
/* backdrop-filter: blur(16px); */ /* backdrop-filter: blur(16px); */
@ -1629,7 +1594,7 @@ body:has(.media-modal-container + .status-deck) .media-post-link {
display: block; display: block;
position: absolute; position: absolute;
top: 0; top: 0;
right: 0; inset-inline-end: 0;
width: 14px; width: 14px;
height: 14px; height: 14px;
border-radius: 50%; border-radius: 50%;
@ -1696,6 +1661,10 @@ body:has(.media-modal-container + .status-deck) .media-post-link {
border-radius: 0; border-radius: 0;
padding: 0; padding: 0;
right: env(safe-area-inset-right); right: env(safe-area-inset-right);
&:dir(rtl) {
right: auto;
left: env(safe-area-inset-left);
}
width: 44px; width: 44px;
height: 44px; height: 44px;
display: inline-flex; display: inline-flex;
@ -1737,6 +1706,11 @@ body:has(.media-modal-container + .status-deck) .media-post-link {
} }
.sheet .sheet-close:not(.outer) + header { .sheet .sheet-close:not(.outer) + header {
padding-right: max(44px, env(safe-area-inset-right)); padding-right: max(44px, env(safe-area-inset-right));
&:dir(rtl) {
padding-right: max(16px, env(safe-area-inset-right));
padding-left: max(44px, env(safe-area-inset-left));
}
} }
.sheet header :is(h1, h2, h3) { .sheet header :is(h1, h2, h3) {
margin: 0; margin: 0;
@ -1774,6 +1748,10 @@ body:has(.media-modal-container + .status-deck) .media-post-link {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
:dir(rtl) &.rtl-flip {
transform: scaleX(-1);
}
} }
/* TAG */ /* TAG */
@ -1839,7 +1817,7 @@ body > .szh-menu-container {
border: 1px solid var(--outline-color); border: 1px solid var(--outline-color);
border-radius: 8px; border-radius: 8px;
box-shadow: 0 3px 16px -3px var(--drop-shadow-color); box-shadow: 0 3px 16px -3px var(--drop-shadow-color);
text-align: left; text-align: start;
/* animation: appear-smooth 0.15s ease-in-out; */ /* animation: appear-smooth 0.15s ease-in-out; */
width: 16em; width: 16em;
max-width: 90vw; max-width: 90vw;
@ -1975,7 +1953,7 @@ body > .szh-menu-container {
} }
.szh-menu .menu-horizontal > .szh-menu__item:not(:only-child):first-child, .szh-menu .menu-horizontal > .szh-menu__item:not(:only-child):first-child,
.szh-menu .menu-horizontal > *:not(:only-child):first-child .szh-menu__item { .szh-menu .menu-horizontal > *:not(:only-child):first-child .szh-menu__item {
padding-right: 4px !important; padding-inline-end: 4px !important;
} }
.szh-menu .szh-menu
.menu-horizontal .menu-horizontal
@ -1984,12 +1962,12 @@ body > .szh-menu-container {
.menu-horizontal .menu-horizontal
> *:not(:only-child):not(:first-child):not(:last-child) > *:not(:only-child):not(:first-child):not(:last-child)
.szh-menu__item { .szh-menu__item {
padding-left: 8px !important; padding-inline-start: 8px !important;
padding-right: 4px !important; padding-inline-end: 4px !important;
} }
.szh-menu .menu-horizontal > .szh-menu__item:not(:only-child):last-child, .szh-menu .menu-horizontal > .szh-menu__item:not(:only-child):last-child,
.szh-menu .menu-horizontal > *:not(:only-child):last-child .szh-menu__item { .szh-menu .menu-horizontal > *:not(:only-child):last-child .szh-menu__item {
padding-left: 8px !important; padding-inline-start: 8px !important;
} }
.szh-menu .szh-menu__item .menu-shortcut { .szh-menu .szh-menu__item .menu-shortcut {
opacity: 0.5; opacity: 0.5;
@ -2053,7 +2031,11 @@ body > .szh-menu-container {
text-align: center; text-align: center;
opacity: 0.5; opacity: 0.5;
text-overflow: clip; text-overflow: clip;
mask-image: linear-gradient(to left, transparent, black 16px); mask-image: linear-gradient(
var(--to-backward),
transparent,
black 16px
);
} }
} }
} }
@ -2069,10 +2051,10 @@ body > .szh-menu-container {
} }
> [class^='szh-menu']:first-child { > [class^='szh-menu']:first-child {
border-top-left-radius: 8px; border-start-start-radius: 8px;
} }
> [class^='szh-menu']:last-child { > [class^='szh-menu']:last-child {
border-top-right-radius: 8px; border-start-end-radius: 8px;
} }
} }
} }
@ -2153,6 +2135,9 @@ body > .szh-menu-container {
background-image: var(--middle-circle), background-image: var(--middle-circle),
conic-gradient(var(--color) var(--fill), var(--outline-color) 0); conic-gradient(var(--color) var(--fill), var(--outline-color) 0);
transform: scale(0.7); transform: scale(0.7);
&:dir(rtl) {
transform: scale(-0.7, 0.7);
}
transition: transform 0.2s ease-in-out; transition: transform 0.2s ease-in-out;
&::-webkit-meter-inner-element, &::-webkit-meter-inner-element,
@ -2362,12 +2347,12 @@ ul.link-list li a {
} }
} }
ul.link-list li:first-child a { ul.link-list li:first-child a {
border-top-left-radius: var(--radius); border-start-start-radius: var(--radius);
border-top-right-radius: var(--radius); border-start-end-radius: var(--radius);
} }
ul.link-list li:last-child a { ul.link-list li:last-child a {
border-bottom-left-radius: var(--radius); border-end-start-radius: var(--radius);
border-bottom-right-radius: var(--radius); border-end-end-radius: var(--radius);
} }
ul.link-list li a:is(:hover, :focus) { ul.link-list li a:is(:hover, :focus) {
color: var(--text-color); color: var(--text-color);
@ -2404,8 +2389,8 @@ ul.link-list li a .icon {
} }
.nav-menu-button.with-avatar .icon { .nav-menu-button.with-avatar .icon {
position: absolute; position: absolute;
bottom: 4px; inset-block-end: 4px;
right: 8px; inset-inline-end: 8px;
background-color: var(--bg-color); background-color: var(--bg-color);
border-radius: 2px; border-radius: 2px;
} }
@ -2433,13 +2418,17 @@ ul.link-list li a .icon {
} */ } */
#columns > * { #columns > * {
overscroll-behavior: auto; overscroll-behavior: auto;
scroll-snap-align: left; scroll-snap-align: start;
scroll-snap-stop: always; scroll-snap-stop: always;
overscroll-behavior: auto; overscroll-behavior: auto;
flex-basis: min(100vw, 360px); flex-basis: min(100vw, 360px);
flex-shrink: 0; flex-shrink: 0;
box-shadow: -1px 0 var(--bg-color), -2px 0 var(--drop-shadow-color), box-shadow: -1px 0 var(--bg-color), -2px 0 var(--drop-shadow-color),
-3px 0 var(--bg-color); -3px 0 var(--bg-color);
&:dir(rtl) {
box-shadow: 1px 0 var(--bg-color), 2px 0 var(--drop-shadow-color),
3px 0 var(--bg-color);
}
} }
#columns:has(> :nth-child(3)) > *:nth-child(even), #columns:has(> :nth-child(3)) > *:nth-child(even),
#columns:has(> :nth-child(3)) #columns:has(> :nth-child(3))
@ -2572,7 +2561,7 @@ ul.link-list li a .icon {
gap: 8px; gap: 8px;
overflow-x: auto; overflow-x: auto;
mask-image: linear-gradient( mask-image: linear-gradient(
to right, var(--to-forward),
transparent, transparent,
black 16px, black 16px,
black calc(100% - 16px), black calc(100% - 16px),
@ -2586,6 +2575,9 @@ ul.link-list li a .icon {
width: 95vw; width: 95vw;
max-width: calc(320px * 3.3); max-width: calc(320px * 3.3);
transform: translateX(calc(-50% + var(--main-width) / 2)); transform: translateX(calc(-50% + var(--main-width) / 2));
&:dir(rtl) {
transform: translateX(calc(50% - var(--main-width) / 2));
}
} }
} }
@ -2704,7 +2696,8 @@ ul.link-list li a .icon {
min-width: 16px; min-width: 16px;
min-height: 16px; min-height: 16px;
padding: 4px; padding: 4px;
margin: -4px -8px -4px 0; margin: -4px 0;
margin-inline-end: -8px;
background-color: var(--bg-faded-color); background-color: var(--bg-faded-color);
border-radius: 999px; border-radius: 999px;
} }
@ -2734,11 +2727,14 @@ ul.link-list li a .icon {
.deck-container:has(~ .deck-backdrop .deck) { .deck-container:has(~ .deck-backdrop .deck) {
transition: transform 0.4s ease-out; transition: transform 0.4s ease-out;
transform: translate3d(-5vw, 0, 0); transform: translate3d(-5vw, 0, 0);
&:dir(rtl) {
transform: translate3d(5vw, 0, 0);
}
} }
.deck-backdrop .deck { .deck-backdrop .deck {
/* width: 50%; /* width: 50%;
min-width: var(--main-width); */ min-width: var(--main-width); */
border-left: 1px solid var(--divider-color); border-inline-start: 1px solid var(--divider-color);
} }
.timeline-deck { .timeline-deck {
border: 0; border: 0;
@ -2799,16 +2795,19 @@ ul.link-list li a .icon {
> li:not(.timeline-item-container-end, .timeline-item-container-middle):has( > li:not(.timeline-item-container-end, .timeline-item-container-middle):has(
.status-badge:not(:empty) .status-badge:not(:empty)
) { ) {
border-top-right-radius: 8px; border-start-end-radius: 8px;
} }
.timeline:not(.flat) > li:has(.status-link.is-active) { .timeline:not(.flat) > li:has(.status-link.is-active) {
transition: var(--back-transition); transition: var(--back-transition);
transform: translate3d(-2.5vw, 0, 0); transform: translate3d(-2.5vw, 0, 0);
&:dir(rtl) {
transform: translate3d(2.5vw, 0, 0);
}
} }
.timeline:not(.flat) .timeline:not(.flat)
> li.timeline-item-container:has(.status-link.is-active) { > li.timeline-item-container:has(.status-link.is-active) {
border-top-left-radius: var(--item-radius); border-start-start-radius: var(--item-radius);
border-bottom-left-radius: var(--item-radius); border-end-start-radius: var(--item-radius);
} }
.timeline:not(.flat) .timeline:not(.flat)
> li:not(:has(.status-carousel)):has(+ li .status-link.is-active), > li:not(:has(.status-carousel)):has(+ li .status-link.is-active),
@ -2817,19 +2816,22 @@ ul.link-list li a .icon {
+ li { + li {
transition: var(--back-transition); transition: var(--back-transition);
transform: translate3d(-1.25vw, 0, 0); transform: translate3d(-1.25vw, 0, 0);
&:dir(rtl) {
transform: translate3d(1.25vw, 0, 0);
}
} }
.timeline:not(.flat) .timeline:not(.flat)
> li.timeline-item-container:not(:has(.status-carousel)):has( > li.timeline-item-container:not(:has(.status-carousel)):has(
+ li .status-link.is-active + li .status-link.is-active
) { ) {
border-top-left-radius: var(--item-radius); border-start-start-radius: var(--item-radius);
} }
.timeline:not(.flat) .timeline:not(.flat)
> li.timeline-item-container:not(:has(.status-carousel)):has( > li.timeline-item-container:not(:has(.status-carousel)):has(
.status-link.is-active .status-link.is-active
) )
+ li.timeline-item-container { + li.timeline-item-container {
border-bottom-left-radius: var(--item-radius); border-end-start-radius: var(--item-radius);
} }
.box { .box {
padding: 32px; padding: 32px;
@ -2841,5 +2843,8 @@ ul.link-list li a .icon {
width: 95vw; width: 95vw;
max-width: calc(320px * 3.3); max-width: calc(320px * 3.3);
transform: translateX(calc(-50% + var(--main-width) / 2)); transform: translateX(calc(-50% + var(--main-width) / 2));
&:dir(rtl) {
transform: translateX(calc(50% - var(--main-width) / 2));
}
} }
} }

View file

@ -132,6 +132,8 @@ setTimeout(() => {
setTimeout(() => { setTimeout(() => {
if (Array.isArray(ICONS[icon])) { if (Array.isArray(ICONS[icon])) {
ICONS[icon][0]?.(); ICONS[icon][0]?.();
} else if (typeof ICONS[icon] === 'object') {
ICONS[icon].module?.();
} else { } else {
ICONS[icon]?.(); ICONS[icon]?.();
} }

View file

@ -6,8 +6,14 @@ export const ICONS = {
'x-circle': () => import('@iconify-icons/mingcute/close-circle-line'), 'x-circle': () => import('@iconify-icons/mingcute/close-circle-line'),
transfer: () => import('@iconify-icons/mingcute/transfer-4-line'), transfer: () => import('@iconify-icons/mingcute/transfer-4-line'),
rocket: () => import('@iconify-icons/mingcute/rocket-line'), rocket: () => import('@iconify-icons/mingcute/rocket-line'),
'arrow-left': () => import('@iconify-icons/mingcute/arrow-left-line'), 'arrow-left': {
'arrow-right': () => import('@iconify-icons/mingcute/arrow-right-line'), module: () => import('@iconify-icons/mingcute/arrow-left-line'),
rtl: true,
},
'arrow-right': {
module: () => import('@iconify-icons/mingcute/arrow-right-line'),
rtl: true,
},
'arrow-up': () => import('@iconify-icons/mingcute/arrow-up-line'), 'arrow-up': () => import('@iconify-icons/mingcute/arrow-up-line'),
'arrow-down': () => import('@iconify-icons/mingcute/arrow-down-line'), 'arrow-down': () => import('@iconify-icons/mingcute/arrow-down-line'),
earth: () => import('@iconify-icons/mingcute/earth-line'), earth: () => import('@iconify-icons/mingcute/earth-line'),
@ -16,8 +22,14 @@ export const ICONS = {
'eye-close': () => import('@iconify-icons/mingcute/eye-close-line'), 'eye-close': () => import('@iconify-icons/mingcute/eye-close-line'),
'eye-open': () => import('@iconify-icons/mingcute/eye-2-line'), 'eye-open': () => import('@iconify-icons/mingcute/eye-2-line'),
message: () => import('@iconify-icons/mingcute/mail-line'), message: () => import('@iconify-icons/mingcute/mail-line'),
comment: () => import('@iconify-icons/mingcute/chat-3-line'), comment: {
comment2: () => import('@iconify-icons/mingcute/comment-2-line'), module: () => import('@iconify-icons/mingcute/chat-3-line'),
rtl: true,
},
comment2: {
module: () => import('@iconify-icons/mingcute/comment-2-line'),
rtl: true,
},
home: () => import('@iconify-icons/mingcute/home-3-line'), home: () => import('@iconify-icons/mingcute/home-3-line'),
notification: () => import('@iconify-icons/mingcute/notification-line'), notification: () => import('@iconify-icons/mingcute/notification-line'),
follow: () => import('@iconify-icons/mingcute/user-follow-line'), follow: () => import('@iconify-icons/mingcute/user-follow-line'),
@ -31,23 +43,46 @@ export const ICONS = {
gear: () => import('@iconify-icons/mingcute/settings-3-line'), gear: () => import('@iconify-icons/mingcute/settings-3-line'),
more: () => import('@iconify-icons/mingcute/more-3-line'), more: () => import('@iconify-icons/mingcute/more-3-line'),
more2: () => import('@iconify-icons/mingcute/more-1-fill'), more2: () => import('@iconify-icons/mingcute/more-1-fill'),
external: () => import('@iconify-icons/mingcute/external-link-line'), external: {
popout: () => import('@iconify-icons/mingcute/external-link-line'), module: () => import('@iconify-icons/mingcute/external-link-line'),
popin: [() => import('@iconify-icons/mingcute/external-link-line'), '180deg'], rtl: true,
},
popout: {
module: () => import('@iconify-icons/mingcute/external-link-line'),
rtl: true,
},
popin: {
module: () => import('@iconify-icons/mingcute/external-link-line'),
rotate: '180deg',
rtl: true,
},
plus: () => import('@iconify-icons/mingcute/add-circle-line'), plus: () => import('@iconify-icons/mingcute/add-circle-line'),
'chevron-left': () => import('@iconify-icons/mingcute/left-line'), 'chevron-left': {
'chevron-right': () => import('@iconify-icons/mingcute/right-line'), module: () => import('@iconify-icons/mingcute/left-line'),
rtl: true,
},
'chevron-right': {
module: () => import('@iconify-icons/mingcute/right-line'),
rtl: true,
},
'chevron-down': () => import('@iconify-icons/mingcute/down-line'), 'chevron-down': () => import('@iconify-icons/mingcute/down-line'),
reply: [ reply: {
() => import('@iconify-icons/mingcute/share-forward-line'), module: () => import('@iconify-icons/mingcute/share-forward-line'),
'180deg', rotate: '180deg',
'horizontal', flip: 'horizontal',
], rtl: true,
},
thread: () => import('@iconify-icons/mingcute/route-line'), thread: () => import('@iconify-icons/mingcute/route-line'),
group: () => import('@iconify-icons/mingcute/group-line'), group: {
module: () => import('@iconify-icons/mingcute/group-line'),
rtl: true,
},
bot: () => import('@iconify-icons/mingcute/android-2-line'), bot: () => import('@iconify-icons/mingcute/android-2-line'),
menu: () => import('@iconify-icons/mingcute/rows-4-line'), menu: () => import('@iconify-icons/mingcute/rows-4-line'),
list: () => import('@iconify-icons/mingcute/list-check-line'), list: {
module: () => import('@iconify-icons/mingcute/list-check-line'),
rtl: true,
},
search: () => import('@iconify-icons/mingcute/search-2-line'), search: () => import('@iconify-icons/mingcute/search-2-line'),
hashtag: () => import('@iconify-icons/mingcute/hashtag-line'), hashtag: () => import('@iconify-icons/mingcute/hashtag-line'),
info: () => import('@iconify-icons/mingcute/information-line'), info: () => import('@iconify-icons/mingcute/information-line'),
@ -62,12 +97,21 @@ export const ICONS = {
share: () => import('@iconify-icons/mingcute/share-2-line'), share: () => import('@iconify-icons/mingcute/share-2-line'),
sparkles: () => import('@iconify-icons/mingcute/sparkles-line'), sparkles: () => import('@iconify-icons/mingcute/sparkles-line'),
sparkles2: () => import('@iconify-icons/mingcute/sparkles-2-line'), sparkles2: () => import('@iconify-icons/mingcute/sparkles-2-line'),
exit: () => import('@iconify-icons/mingcute/exit-line'), exit: {
module: () => import('@iconify-icons/mingcute/exit-line'),
rtl: true,
},
translate: () => import('@iconify-icons/mingcute/translate-line'), translate: () => import('@iconify-icons/mingcute/translate-line'),
play: () => import('@iconify-icons/mingcute/play-fill'), play: () => import('@iconify-icons/mingcute/play-fill'),
trash: () => import('@iconify-icons/mingcute/delete-2-line'), trash: () => import('@iconify-icons/mingcute/delete-2-line'),
mute: () => import('@iconify-icons/mingcute/volume-mute-line'), mute: {
unmute: () => import('@iconify-icons/mingcute/volume-line'), module: () => import('@iconify-icons/mingcute/volume-mute-line'),
rtl: true,
},
unmute: {
module: () => import('@iconify-icons/mingcute/volume-line'),
rtl: true,
},
block: () => import('@iconify-icons/mingcute/forbid-circle-line'), block: () => import('@iconify-icons/mingcute/forbid-circle-line'),
unblock: [ unblock: [
() => import('@iconify-icons/mingcute/forbid-circle-line'), () => import('@iconify-icons/mingcute/forbid-circle-line'),
@ -81,30 +125,51 @@ export const ICONS = {
filters: () => import('@iconify-icons/mingcute/filter-line'), filters: () => import('@iconify-icons/mingcute/filter-line'),
chart: () => import('@iconify-icons/mingcute/chart-line-line'), chart: () => import('@iconify-icons/mingcute/chart-line-line'),
react: () => import('@iconify-icons/mingcute/react-line'), react: () => import('@iconify-icons/mingcute/react-line'),
layout4: () => import('@iconify-icons/mingcute/layout-4-line'), layout4: {
module: () => import('@iconify-icons/mingcute/layout-4-line'),
rtl: true,
},
layout5: () => import('@iconify-icons/mingcute/layout-5-line'), layout5: () => import('@iconify-icons/mingcute/layout-5-line'),
announce: () => import('@iconify-icons/mingcute/announcement-line'), announce: {
module: () => import('@iconify-icons/mingcute/announcement-line'),
rtl: true,
},
alert: () => import('@iconify-icons/mingcute/alert-line'), alert: () => import('@iconify-icons/mingcute/alert-line'),
round: () => import('@iconify-icons/mingcute/round-fill'), round: () => import('@iconify-icons/mingcute/round-fill'),
'arrow-up-circle': () => 'arrow-up-circle': () =>
import('@iconify-icons/mingcute/arrow-up-circle-line'), import('@iconify-icons/mingcute/arrow-up-circle-line'),
'arrow-down-circle': () => 'arrow-down-circle': () =>
import('@iconify-icons/mingcute/arrow-down-circle-line'), import('@iconify-icons/mingcute/arrow-down-circle-line'),
clipboard: () => import('@iconify-icons/mingcute/clipboard-line'), clipboard: {
module: () => import('@iconify-icons/mingcute/clipboard-line'),
rtl: true,
},
'account-edit': () => import('@iconify-icons/mingcute/user-edit-line'), 'account-edit': () => import('@iconify-icons/mingcute/user-edit-line'),
'account-warning': () => import('@iconify-icons/mingcute/user-warning-line'), 'account-warning': () => import('@iconify-icons/mingcute/user-warning-line'),
keyboard: () => import('@iconify-icons/mingcute/keyboard-line'), keyboard: () => import('@iconify-icons/mingcute/keyboard-line'),
cloud: () => import('@iconify-icons/mingcute/cloud-line'), cloud: () => import('@iconify-icons/mingcute/cloud-line'),
month: () => import('@iconify-icons/mingcute/calendar-month-line'), month: {
module: () => import('@iconify-icons/mingcute/calendar-month-line'),
rtl: true,
},
media: () => import('@iconify-icons/mingcute/photo-album-line'), media: () => import('@iconify-icons/mingcute/photo-album-line'),
speak: () => import('@iconify-icons/mingcute/radar-line'), speak: () => import('@iconify-icons/mingcute/radar-line'),
building: () => import('@iconify-icons/mingcute/building-5-line'), building: () => import('@iconify-icons/mingcute/building-5-line'),
history2: () => import('@iconify-icons/mingcute/history-2-line'), history2: {
module: () => import('@iconify-icons/mingcute/history-2-line'),
rtl: true,
},
document: () => import('@iconify-icons/mingcute/document-line'), document: () => import('@iconify-icons/mingcute/document-line'),
'arrows-right': () => import('@iconify-icons/mingcute/arrows-right-line'), 'arrows-right': {
module: () => import('@iconify-icons/mingcute/arrows-right-line'),
rtl: true,
},
code: () => import('@iconify-icons/mingcute/code-line'), code: () => import('@iconify-icons/mingcute/code-line'),
copy: () => import('@iconify-icons/mingcute/copy-2-line'), copy: () => import('@iconify-icons/mingcute/copy-2-line'),
quote: () => import('@iconify-icons/mingcute/quote-left-line'), quote: {
module: () => import('@iconify-icons/mingcute/quote-left-line'),
rtl: true,
},
settings: () => import('@iconify-icons/mingcute/settings-6-line'), settings: () => import('@iconify-icons/mingcute/settings-6-line'),
'heart-break': () => import('@iconify-icons/mingcute/heart-crack-line'), 'heart-break': () => import('@iconify-icons/mingcute/heart-crack-line'),
'user-x': () => import('@iconify-icons/mingcute/user-x-line'), 'user-x': () => import('@iconify-icons/mingcute/user-x-line'),

View file

@ -29,6 +29,8 @@
line-clamp: 1; line-clamp: 1;
text-overflow: ellipsis; text-overflow: ellipsis;
overflow: hidden; overflow: hidden;
unicode-bidi: isolate;
direction: initial;
} }
a { a {

View file

@ -120,7 +120,7 @@ function AccountBlock({
)} )}
</> </>
)}{' '} )}{' '}
<span class="account-block-acct"> <span class="account-block-acct bidi-isolate">
{acct2 ? '' : '@'} {acct2 ? '' : '@'}
{acct1} {acct1}
<wbr /> <wbr />

View file

@ -57,7 +57,7 @@
background-repeat: no-repeat; background-repeat: no-repeat;
animation: swoosh-bg-image 0.3s ease-in-out 0.3s both; animation: swoosh-bg-image 0.3s ease-in-out 0.3s both;
background-image: linear-gradient( background-image: linear-gradient(
to right, var(--to-forward),
var(--original-color) 0%, var(--original-color) 0%,
var(--original-color) calc(var(--originals-percentage) - var(--gap)), var(--original-color) calc(var(--originals-percentage) - var(--gap)),
var(--gap-color) calc(var(--originals-percentage) - var(--gap)), var(--gap-color) calc(var(--originals-percentage) - var(--gap)),
@ -181,8 +181,8 @@
opacity: 1; opacity: 1;
} }
.sheet .account-container .header-banner { .sheet .account-container .header-banner {
border-top-left-radius: 16px; border-start-start-radius: 16px;
border-top-right-radius: 16px; border-start-end-radius: 16px;
} }
.account-container .header-banner.header-is-avatar { .account-container .header-banner.header-is-avatar {
mask-image: linear-gradient( mask-image: linear-gradient(
@ -288,10 +288,17 @@
align-self: center !important; align-self: center !important;
/* clip a dog ear on top right */ /* clip a dog ear on top right */
clip-path: polygon(0 0, calc(100% - 4px) 0, 100% 4px, 100% 100%, 0 100%); clip-path: polygon(0 0, calc(100% - 4px) 0, 100% 4px, 100% 100%, 0 100%);
&:dir(rtl) {
/* top left */
clip-path: polygon(4px 0, 100% 0, 100% 100%, 0 100%, 0 4px);
}
/* 4x4px square on top right */ /* 4x4px square on top right */
background-size: 4px 4px; background-size: 4px 4px;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: top right; background-position: top right;
&:dir(rtl) {
background-position: top left;
}
background-image: linear-gradient( background-image: linear-gradient(
to bottom, to bottom,
var(--private-note-border-color), var(--private-note-border-color),
@ -311,7 +318,7 @@
box-orient: vertical; box-orient: vertical;
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
line-clamp: 2; line-clamp: 2;
text-align: left; text-align: start;
} }
&:hover:not(:active) { &:hover:not(:active) {
@ -370,7 +377,8 @@
animation: appear 1s both ease-in-out; animation: appear 1s both ease-in-out;
> *:not(:first-child) { > *:not(:first-child) {
margin: 0 0 0 -4px; margin: 0;
margin-inline-start: -4px;
} }
} }
} }
@ -422,15 +430,15 @@
} }
&:has(+ .account-metadata-box) { &:has(+ .account-metadata-box) {
border-bottom-left-radius: 4px; border-end-start-radius: 4px;
border-bottom-right-radius: 4px; border-end-end-radius: 4px;
} }
+ .account-metadata-box { + .account-metadata-box {
border-top-left-radius: 4px; border-start-start-radius: 4px;
border-top-right-radius: 4px; border-start-end-radius: 4px;
border-bottom-left-radius: 16px; border-end-start-radius: 16px;
border-bottom-right-radius: 16px; border-end-end-radius: 16px;
} }
} }
@ -805,7 +813,7 @@
width: 100%; width: 100%;
th { th {
text-align: left; text-align: start;
color: var(--text-insignificant-color); color: var(--text-insignificant-color);
font-weight: normal; font-weight: normal;
font-size: 0.8em; font-size: 0.8em;

View file

@ -568,7 +568,9 @@ function AccountInfo({
</div> </div>
<MenuItem <MenuItem
onClick={() => { onClick={() => {
const handleWithInstance = acct.includes('@') ? `@${acct}` : `@${acct}@${instance}`; const handleWithInstance = acct.includes('@')
? `@${acct}`
: `@${acct}@${instance}`;
try { try {
navigator.clipboard.writeText(handleWithInstance); navigator.clipboard.writeText(handleWithInstance);
showToast('Handle copied'); showToast('Handle copied');
@ -1221,7 +1223,7 @@ function RelatedActions({
<small> <small>
Copy handle Copy handle
<br /> <br />
<span class="more-insignificant"> <span class="more-insignificant bidi-isolate">
@{currentInfo?.acct || acctWithInstance} @{currentInfo?.acct || acctWithInstance}
</span> </span>
</small> </small>
@ -1895,6 +1897,7 @@ function PrivateNoteSheet({
ref={textareaRef} ref={textareaRef}
name="note" name="note"
disabled={uiState === 'loading'} disabled={uiState === 'loading'}
dir="auto"
> >
{initialNote} {initialNote}
</textarea> </textarea>
@ -2017,6 +2020,7 @@ function EditProfileSheet({ onClose = () => {} }) {
defaultValue={displayName} defaultValue={displayName}
maxLength={30} maxLength={30}
disabled={uiState === 'loading'} disabled={uiState === 'loading'}
dir="auto"
/> />
</label> </label>
</p> </p>
@ -2029,6 +2033,7 @@ function EditProfileSheet({ onClose = () => {} }) {
maxLength={500} maxLength={500}
rows="5" rows="5"
disabled={uiState === 'loading'} disabled={uiState === 'loading'}
dir="auto"
/> />
</label> </label>
</p> </p>
@ -2092,6 +2097,7 @@ function FieldsAttributesRow({ name, value, disabled, index: i }) {
disabled={disabled} disabled={disabled}
maxLength={255} maxLength={255}
required={hasValue} required={hasValue}
dir="auto"
/> />
</td> </td>
<td> <td>
@ -2102,6 +2108,7 @@ function FieldsAttributesRow({ name, value, disabled, index: i }) {
disabled={disabled} disabled={disabled}
maxLength={255} maxLength={255}
onChange={(e) => setHasValue(!!e.currentTarget.value)} onChange={(e) => setHasValue(!!e.currentTarget.value)}
dir="auto"
/> />
</td> </td>
</tr> </tr>

View file

@ -16,7 +16,6 @@
} }
#compose-container .compose-top { #compose-container .compose-top {
text-align: right;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
gap: 8px; gap: 8px;
@ -62,7 +61,7 @@
box-shadow: 0 -3px 12px -3px var(--drop-shadow-color); box-shadow: 0 -3px 12px -3px var(--drop-shadow-color);
} }
#compose-container .status-preview:has(.status-badge:not(:empty)) { #compose-container .status-preview:has(.status-badge:not(:empty)) {
border-top-right-radius: 8px; border-start-end-radius: 8px;
} }
#compose-container .status-preview :is(.content-container, .time) { #compose-container .status-preview :is(.content-container, .time) {
pointer-events: none; pointer-events: none;
@ -216,8 +215,8 @@
line-height: 1em; line-height: 1em;
} }
#compose-container .toolbar-button:not(.show-field) select { #compose-container .toolbar-button:not(.show-field) select {
right: 0; inset-inline-end: 0;
left: auto !important; inset-inline-start: auto !important;
} }
#compose-container #compose-container
.toolbar-button:not(:disabled):is( .toolbar-button:not(:disabled):is(
@ -303,6 +302,9 @@
} }
#compose-container .text-expander-menu li[aria-selected] { #compose-container .text-expander-menu li[aria-selected] {
box-shadow: inset 4px 0 0 0 var(--button-bg-color); box-shadow: inset 4px 0 0 0 var(--button-bg-color);
:dir(rtl) & {
box-shadow: inset -4px 0 0 0 var(--button-bg-color);
}
} }
#compose-container .text-expander-menu li[data-more] { #compose-container .text-expander-menu li[data-more] {
&:not(:hover, :focus, [aria-selected]) { &:not(:hover, :focus, [aria-selected]) {
@ -494,14 +496,14 @@
display: flex; display: flex;
gap: 4px; gap: 4px;
align-items: center; align-items: center;
border-left: 1px solid var(--outline-color); border-inline-start: 1px solid var(--outline-color);
padding-left: 8px; padding-inline-start: 8px;
} }
#compose-container .expires-in { #compose-container .expires-in {
flex-grow: 1; flex-grow: 1;
border-left: 1px solid var(--outline-color); border-inline-start: 1px solid var(--outline-color);
padding-left: 8px; padding-inline-start: 8px;
display: flex; display: flex;
gap: 4px; gap: 4px;
flex-wrap: wrap; flex-wrap: wrap;
@ -646,7 +648,7 @@
&:hover { &:hover {
background-image: linear-gradient( background-image: linear-gradient(
to right, var(--to-forward),
transparent 75%, transparent 75%,
var(--link-bg-color) var(--link-bg-color)
); );
@ -654,7 +656,7 @@
&.selected { &.selected {
background-image: linear-gradient( background-image: linear-gradient(
to right, var(--to-forward),
var(--bg-faded-color) 75%, var(--bg-faded-color) 75%,
var(--link-bg-color) var(--link-bg-color)
); );
@ -666,8 +668,8 @@
border-top: var(--hairline-width) solid var(--divider-color); border-top: var(--hairline-width) solid var(--divider-color);
position: absolute; position: absolute;
bottom: 0; bottom: 0;
left: 58px; inset-inline-start: 58px;
right: 0; inset-inline-end: 0;
} }
&:has(+ li:is(.selected, :hover)):before, &:has(+ li:is(.selected, :hover)):before,
@ -951,7 +953,7 @@
overflow-x: auto; overflow-x: auto;
overflow-y: hidden; overflow-y: hidden;
mask-image: linear-gradient( mask-image: linear-gradient(
to right, var(--to-forward),
transparent 2px, transparent 2px,
black 16px, black 16px,
black calc(100% - 16px), black calc(100% - 16px),

View file

@ -27,6 +27,7 @@ import urlRegex from '../data/url-regex';
import { api } from '../utils/api'; import { api } from '../utils/api';
import db from '../utils/db'; import db from '../utils/db';
import emojifyText from '../utils/emojify-text'; import emojifyText from '../utils/emojify-text';
import isRTL from '../utils/is-rtl';
import localeMatch from '../utils/locale-match'; import localeMatch from '../utils/locale-match';
import localeCode2Text from '../utils/localeCode2Text'; import localeCode2Text from '../utils/localeCode2Text';
import openCompose from '../utils/open-compose'; import openCompose from '../utils/open-compose';
@ -103,7 +104,8 @@ const observer = new IntersectionObserver((entries) => {
const { left, width } = entry.boundingClientRect; const { left, width } = entry.boundingClientRect;
const { innerWidth } = window; const { innerWidth } = window;
if (left + width > innerWidth) { if (left + width > innerWidth) {
menu.style.left = innerWidth - width - windowMargin + 'px'; const insetInlineStart = isRTL() ? 'right' : 'left';
menu.style[insetInlineStart] = innerWidth - width - windowMargin + 'px';
} }
} }
}); });
@ -1127,6 +1129,7 @@ function Compose({
setVisibility(e.target.value); setVisibility(e.target.value);
}} }}
disabled={uiState === 'loading' || !!editStatus} disabled={uiState === 'loading' || !!editStatus}
dir="auto"
> >
<option value="public"> <option value="public">
Public <Icon icon="earth" /> Public <Icon icon="earth" />
@ -1383,6 +1386,7 @@ function Compose({
store.session.set('currentLanguage', value || DEFAULT_LANG); store.session.set('currentLanguage', value || DEFAULT_LANG);
}} }}
disabled={uiState === 'loading'} disabled={uiState === 'loading'}
dir="auto"
> >
{topSupportedLanguages.map(([code, common, native]) => ( {topSupportedLanguages.map(([code, common, native]) => (
<option value={code} key={code}> <option value={code} key={code}>
@ -1716,7 +1720,9 @@ const Textarea = forwardRef((props, ref) => {
</span> </span>
<span> <span>
<b>${displayNameWithEmoji || username}</b> <b>${displayNameWithEmoji || username}</b>
<br>@${encodeHTML(acct)} <br><span class="bidi-isolate">@${encodeHTML(
acct,
)}</span>
</span> </span>
</li> </li>
`; `;

View file

@ -27,7 +27,7 @@ button.draft-item {
background-color: var(--bg-color); background-color: var(--bg-color);
color: var(--text-color); color: var(--text-color);
border: 1px solid var(--link-faded-color); border: 1px solid var(--link-faded-color);
text-align: left; text-align: start;
padding: 0; padding: 0;
} }
button.draft-item:is(:hover, :focus) { button.draft-item:is(:hover, :focus) {

View file

@ -62,13 +62,13 @@
border-top: var(--hairline-width) solid var(--divider-color); border-top: var(--hairline-width) solid var(--divider-color);
position: absolute; position: absolute;
bottom: calc(-1 * var(--list-gap) / 2); bottom: calc(-1 * var(--list-gap) / 2);
left: 40px; inset-inline-start: 40px;
right: 0; inset-inline-end: 0;
} }
&:has(.reactions-block):before { &:has(.reactions-block):before {
/* avatar + reactions + gap */ /* avatar + reactions + gap */
left: calc(40px + 16px + 8px); inset-inline-start: calc(40px + 16px + 8px);
} }
} }

View file

@ -53,9 +53,14 @@ function Icon({
return null; return null;
} }
let rotate, flip; let rotate,
flip,
rtl = false;
if (Array.isArray(iconBlock)) { if (Array.isArray(iconBlock)) {
[iconBlock, rotate, flip] = iconBlock; [iconBlock, rotate, flip] = iconBlock;
} else if (typeof iconBlock === 'object') {
({ rotate, flip, rtl } = iconBlock);
iconBlock = iconBlock.module;
} }
const [iconData, setIconData] = useState(ICONDATA[icon]); const [iconData, setIconData] = useState(ICONDATA[icon]);
@ -72,13 +77,14 @@ function Icon({
return ( return (
<span <span
class={`icon ${className}`} class={`icon ${className} ${rtl ? 'rtl-flip' : ''}`}
title={title || alt} title={title || alt}
style={{ style={{
width: `${iconSize}px`, width: `${iconSize}px`,
height: `${iconSize}px`, height: `${iconSize}px`,
...style, ...style,
}} }}
data-icon={icon}
> >
{iconData && ( {iconData && (
// <svg // <svg

View file

@ -6,7 +6,7 @@
overflow-x: auto; overflow-x: auto;
background-color: var(--bg-faded-color); background-color: var(--bg-faded-color);
mask-image: linear-gradient( mask-image: linear-gradient(
to right, var(--to-forward),
transparent, transparent,
black 16px, black 16px,
black calc(100% - 16px), black calc(100% - 16px),
@ -20,6 +20,9 @@
width: 95vw; width: 95vw;
max-width: calc(320px * 3.3); max-width: calc(320px * 3.3);
transform: translateX(calc(-50% + var(--main-width) / 2)); transform: translateX(calc(-50% + var(--main-width) / 2));
&:dir(rtl) {
transform: translateX(calc(50% - var(--main-width) / 2));
}
} }
} }
@ -38,12 +41,16 @@
color: var(--text-insignificant-color); color: var(--text-insignificant-color);
position: absolute; position: absolute;
top: 8px; top: 8px;
left: 0; inset-inline-start: 0;
transform-origin: top left; transform-origin: top left;
transform: rotate(-90deg) translateX(-100%); transform: rotate(-90deg) translateX(-100%);
&:dir(rtl) {
transform-origin: top right;
transform: rotate(90deg) translateX(100%);
}
user-select: none; user-select: none;
background-image: linear-gradient( background-image: linear-gradient(
to left, var(--to-backward),
var(--text-color), var(--text-color),
var(--link-color) var(--link-color)
); );

View file

@ -10,6 +10,7 @@ import {
import { useHotkeys } from 'react-hotkeys-hook'; import { useHotkeys } from 'react-hotkeys-hook';
import { oklab2rgb, rgb2oklab } from '../utils/color-utils'; import { oklab2rgb, rgb2oklab } from '../utils/color-utils';
import isRTL from '../utils/is-rtl';
import showToast from '../utils/show-toast'; import showToast from '../utils/show-toast';
import states from '../utils/states'; import states from '../utils/states';
@ -54,7 +55,7 @@ function MediaModal({
const differentStatusID = prevStatusID.current !== statusID; const differentStatusID = prevStatusID.current !== statusID;
if (differentStatusID) prevStatusID.current = statusID; if (differentStatusID) prevStatusID.current = statusID;
carouselRef.current.scrollTo({ carouselRef.current.scrollTo({
left: scrollLeft, left: scrollLeft * (isRTL() ? -1 : 1),
behavior: differentStatusID ? 'auto' : 'smooth', behavior: differentStatusID ? 'auto' : 'smooth',
}); });
carouselRef.current.focus(); carouselRef.current.focus();
@ -91,7 +92,7 @@ function MediaModal({
useEffect(() => { useEffect(() => {
let handleScroll = () => { let handleScroll = () => {
const { clientWidth, scrollLeft } = carouselRef.current; const { clientWidth, scrollLeft } = carouselRef.current;
const index = Math.round(scrollLeft / clientWidth); const index = Math.round(Math.abs(scrollLeft) / clientWidth);
setCurrentIndex(index); setCurrentIndex(index);
}; };
if (carouselRef.current) { if (carouselRef.current) {
@ -178,7 +179,7 @@ function MediaModal({
? { ? {
backgroundAttachment: 'local', backgroundAttachment: 'local',
backgroundImage: `linear-gradient( backgroundImage: `linear-gradient(
to right, ${mediaAccentGradient})`, to ${isRTL() ? 'left' : 'right'}, ${mediaAccentGradient})`,
} }
: {} : {}
} }
@ -257,7 +258,8 @@ function MediaModal({
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
carouselRef.current.scrollTo({ carouselRef.current.scrollTo({
left: carouselRef.current.clientWidth * i, left:
carouselRef.current.clientWidth * i * (isRTL() ? -1 : 1),
behavior: 'smooth', behavior: 'smooth',
}); });
carouselRef.current.focus(); carouselRef.current.focus();
@ -368,7 +370,10 @@ function MediaModal({
e.stopPropagation(); e.stopPropagation();
carouselRef.current.focus(); carouselRef.current.focus();
carouselRef.current.scrollTo({ carouselRef.current.scrollTo({
left: carouselRef.current.clientWidth * (currentIndex - 1), left:
carouselRef.current.clientWidth *
(currentIndex - 1) *
(isRTL() ? -1 : 1),
behavior: 'smooth', behavior: 'smooth',
}); });
}} }}
@ -384,7 +389,10 @@ function MediaModal({
e.stopPropagation(); e.stopPropagation();
carouselRef.current.focus(); carouselRef.current.focus();
carouselRef.current.scrollTo({ carouselRef.current.scrollTo({
left: carouselRef.current.clientWidth * (currentIndex + 1), left:
carouselRef.current.clientWidth *
(currentIndex + 1) *
(isRTL() ? -1 : 1),
behavior: 'smooth', behavior: 'smooth',
}); });
}} }}

View file

@ -23,7 +23,7 @@
pointer-events: none; pointer-events: none;
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; inset-inline-start: 0;
z-index: 1; z-index: 1;
background-color: var(--bg-blur-color); background-color: var(--bg-blur-color);
margin: 8px; margin: 8px;

View file

@ -1,21 +1,33 @@
import { Menu } from '@szhsin/react-menu'; import { Menu } from '@szhsin/react-menu';
import { useRef } from 'preact/hooks'; import { useRef } from 'preact/hooks';
import isRTL from '../utils/is-rtl';
import safeBoundingBoxPadding from '../utils/safe-bounding-box-padding'; import safeBoundingBoxPadding from '../utils/safe-bounding-box-padding';
import useWindowSize from '../utils/useWindowSize'; import useWindowSize from '../utils/useWindowSize';
// It's like Menu but with sensible defaults, bug fixes and improvements. // It's like Menu but with sensible defaults, bug fixes and improvements.
function Menu2(props) { function Menu2(props) {
const { containerProps, instanceRef: _instanceRef } = props; const { containerProps, instanceRef: _instanceRef, align } = props;
const size = useWindowSize(); const size = useWindowSize();
const instanceRef = _instanceRef?.current ? _instanceRef : useRef(); const instanceRef = _instanceRef?.current ? _instanceRef : useRef();
// Values: start, end, center
// Note: don't mess with 'center'
const rtlAlign = isRTL()
? align === 'end'
? 'start'
: align === 'start'
? 'end'
: align
: align;
return ( return (
<Menu <Menu
boundingBoxPadding={safeBoundingBoxPadding()} boundingBoxPadding={safeBoundingBoxPadding()}
repositionFlag={`${size.width}x${size.height}`} repositionFlag={`${size.width}x${size.height}`}
unmountOnClose unmountOnClose
{...props} {...props}
align={rtlAlign}
instanceRef={instanceRef} instanceRef={instanceRef}
containerProps={{ containerProps={{
onClick: (e) => { onClick: (e) => {

View file

@ -1,7 +1,7 @@
#modal-container > div { #modal-container > div {
position: fixed; position: fixed;
top: 0; top: 0;
right: 0; inset-inline-end: 0;
height: 100%; height: 100%;
width: 100%; width: 100%;
z-index: 1000; z-index: 1000;
@ -26,21 +26,30 @@
user-select: none; user-select: none;
overflow: hidden; overflow: hidden;
transform: scale(0); transform: scale(0);
--right: max( --end: max(
var(--compose-button-dimension-margin), var(--compose-button-dimension-margin),
env(safe-area-inset-right) env(safe-area-inset-right)
); );
:dir(rtl) & {
--end: max(
var(--compose-button-dimension-margin),
env(safe-area-inset-left)
);
}
--bottom: max( --bottom: max(
var(--compose-button-dimension-margin), var(--compose-button-dimension-margin),
env(safe-area-inset-bottom) env(safe-area-inset-bottom)
); );
--origin-right: calc( --origin-end: calc(
100% - var(--compose-button-dimension-half) - var(--right) 100% - var(--compose-button-dimension-half) - var(--end)
); );
:dir(rtl) & {
--origin-end: calc(var(--compose-button-dimension-half) + var(--end));
}
--origin-bottom: calc( --origin-bottom: calc(
100% - var(--compose-button-dimension-half) - var(--bottom) 100% - var(--compose-button-dimension-half) - var(--bottom)
); );
transform-origin: var(--origin-right) var(--origin-bottom); transform-origin: var(--origin-end) var(--origin-bottom);
} }
.sheet { .sheet {

View file

@ -88,13 +88,13 @@ function NameText({
)} )}
{displayName && !short ? ( {displayName && !short ? (
<> <>
<b> <b dir="auto">
<EmojiText text={displayName} emojis={emojis} /> <EmojiText text={displayName} emojis={emojis} />
</b> </b>
{!showAcct && !hideUsername && ( {!showAcct && !hideUsername && (
<> <>
{' '} {' '}
<i>@{username}</i> <i class="bidi-isolate">@{username}</i>
</> </>
)} )}
</> </>
@ -106,7 +106,7 @@ function NameText({
{showAcct && ( {showAcct && (
<> <>
<br /> <br />
<i> <i class="bidi-isolate">
{acct2 ? '' : '@'} {acct2 ? '' : '@'}
{acct1} {acct1}
{!!acct2 && <span class="ib">{acct2}</span>} {!!acct2 && <span class="ib">{acct2}</span>}

View file

@ -35,11 +35,15 @@
} }
.nav-menu section:last-child { .nav-menu section:last-child {
background-image: linear-gradient( background-image: linear-gradient(
to right, var(--to-forward),
var(--divider-color) 1px, var(--divider-color) 1px,
transparent 1px transparent 1px
), ),
linear-gradient(to bottom left, var(--bg-blur-color), transparent), linear-gradient(
to bottom var(--backward),
var(--bg-blur-color),
transparent
),
url(../assets/phanpy-bg.svg); url(../assets/phanpy-bg.svg);
background-repeat: no-repeat; background-repeat: no-repeat;
/* background-size: auto, auto, 200%; */ /* background-size: auto, auto, 200%; */
@ -49,8 +53,8 @@
position: sticky; position: sticky;
top: 0; top: 0;
animation: phanpying 0.2s ease-in-out both; animation: phanpying 0.2s ease-in-out both;
border-top-right-radius: inherit; border-start-end-radius: inherit;
border-bottom-right-radius: inherit; border-end-end-radius: inherit;
margin-bottom: 0; margin-bottom: 0;
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View file

@ -187,9 +187,6 @@ export default function Poll({
type="button" type="button"
class="plain small" class="plain small"
disabled={uiState === 'loading'} disabled={uiState === 'loading'}
style={{
marginLeft: -8,
}}
onClick={(e) => { onClick={(e) => {
e.preventDefault(); e.preventDefault();
setUIState('loading'); setUIState('loading');

View file

@ -92,7 +92,7 @@
pointer-events: none; pointer-events: none;
user-select: none; user-select: none;
position: absolute; position: absolute;
right: 32px; inset-inline-end: 32px;
margin-top: -48px; margin-top: -48px;
animation: rubber-stamp 0.3s ease-in both; animation: rubber-stamp 0.3s ease-in both;
position: absolute; position: absolute;
@ -148,7 +148,7 @@
} }
.report-rules { .report-rules {
margin-left: 1.75em; margin-inline-start: 1.75em;
} }
} }

View file

@ -273,6 +273,7 @@ const SearchForm = forwardRef((props, ref) => {
class={`search-popover-item ${i === 0 ? 'focus' : ''}`} class={`search-popover-item ${i === 0 ? 'focus' : ''}`}
// hidden={hidden} // hidden={hidden}
onClick={(e) => { onClick={(e) => {
console.log('onClick', e);
props?.onSubmit?.(e); props?.onSubmit?.(e);
}} }}
> >

View file

@ -18,8 +18,8 @@
counter-increment: index; counter-increment: index;
display: inline-block; display: inline-block;
width: 1.2em; width: 1.2em;
text-align: right; text-align: end;
margin-right: 8px; margin-inline-end: 8px;
color: var(--text-insignificant-color); color: var(--text-insignificant-color);
font-size: 90%; font-size: 90%;
flex-shrink: 0; flex-shrink: 0;
@ -55,12 +55,12 @@
justify-content: center; justify-content: center;
} }
#shortcuts-settings-container .shortcuts-view-mode label:first-child { #shortcuts-settings-container .shortcuts-view-mode label:first-child {
border-top-left-radius: 16px; border-start-start-radius: 16px;
border-bottom-left-radius: 16px; border-end-start-radius: 16px;
} }
#shortcuts-settings-container .shortcuts-view-mode label:last-child { #shortcuts-settings-container .shortcuts-view-mode label:last-child {
border-top-right-radius: 16px; border-start-end-radius: 16px;
border-bottom-right-radius: 16px; border-end-end-radius: 16px;
} }
#shortcuts-settings-container .shortcuts-view-mode label img { #shortcuts-settings-container .shortcuts-view-mode label img {
max-height: 64px; max-height: 64px;
@ -114,7 +114,7 @@
} }
#shortcut-settings-form label > span:first-child { #shortcut-settings-form label > span:first-child {
flex-basis: 5em; flex-basis: 5em;
text-align: right; text-align: end;
} }
#shortcut-settings-form :is(input[type='text'], select) { #shortcut-settings-form :is(input[type='text'], select) {
flex-grow: 1; flex-grow: 1;
@ -185,8 +185,8 @@
counter-increment: index; counter-increment: index;
display: inline-block; display: inline-block;
width: 1.2em; width: 1.2em;
text-align: right; text-align: end;
margin-right: 8px; margin-inline-end: 8px;
color: var(--text-insignificant-color); color: var(--text-insignificant-color);
font-size: 90%; font-size: 90%;
flex-shrink: 0; flex-shrink: 0;

View file

@ -612,6 +612,7 @@ function ShortcutForm({
}} }}
defaultValue={editMode ? shortcut.type : undefined} defaultValue={editMode ? shortcut.type : undefined}
name="type" name="type"
dir="auto"
> >
<option></option> <option></option>
{TYPES.map((type) => ( {TYPES.map((type) => (
@ -632,6 +633,7 @@ function ShortcutForm({
required={!notRequired} required={!notRequired}
disabled={disabled || uiState === 'loading'} disabled={disabled || uiState === 'loading'}
defaultValue={editMode ? shortcut.id : undefined} defaultValue={editMode ? shortcut.id : undefined}
dir="auto"
> >
<option value=""></option> <option value=""></option>
{lists.map((list) => ( {lists.map((list) => (
@ -663,6 +665,7 @@ function ShortcutForm({
autocapitalize="off" autocapitalize="off"
spellCheck={false} spellCheck={false}
pattern={pattern} pattern={pattern}
dir="auto"
/> />
{currentType === 'hashtag' && {currentType === 'hashtag' &&
followedHashtags.length > 0 && ( followedHashtags.length > 0 && (
@ -780,6 +783,7 @@ function ImportExport({ shortcuts, onClose }) {
onInput={(e) => { onInput={(e) => {
setImportShortcutStr(e.target.value); setImportShortcutStr(e.target.value);
}} }}
dir="auto"
/> />
{states.settings.shortcutSettingsCloudImportExport && ( {states.settings.shortcutSettingsCloudImportExport && (
<button <button
@ -996,6 +1000,7 @@ function ImportExport({ shortcuts, onClose }) {
showToast('Unable to copy shortcuts'); showToast('Unable to copy shortcuts');
} }
}} }}
dir="auto"
/> />
</p> </p>
<p> <p>

View file

@ -2,8 +2,8 @@
position: fixed; position: fixed;
bottom: 16px; bottom: 16px;
bottom: max(16px, env(safe-area-inset-bottom)); bottom: max(16px, env(safe-area-inset-bottom));
left: 16px; inset-inline-start: 16px;
left: max(16px, env(safe-area-inset-left)); inset-inline-start: max(16px, env(safe-area-inset-left));
padding: 16px; padding: 16px;
background-color: var(--bg-faded-blur-color); background-color: var(--bg-faded-blur-color);
z-index: 101; z-index: 101;
@ -34,9 +34,9 @@
@media (min-width: calc(40em + 56px + 8px)) { @media (min-width: calc(40em + 56px + 8px)) {
#shortcuts-button { #shortcuts-button {
right: 16px; inset-inline-end: 16px;
right: max(16px, env(safe-area-inset-right)); inset-inline-end: max(16px, env(safe-area-inset-right));
left: auto; inset-inline-start: auto;
top: 16px; top: 16px;
top: max(16px, env(safe-area-inset-top)); top: max(16px, env(safe-area-inset-top));
bottom: auto; bottom: auto;

View file

@ -1,22 +1,31 @@
/* REBLOG + REPLY-TO */ /* REBLOG + REPLY-TO */
:root {
--post-gradient-angle: 160deg;
--post-gradient-chip-angle: -20deg;
&:dir(rtl) {
--post-gradient-angle: -160deg;
--post-gradient-chip-angle: 20deg;
}
}
.status-reblog { .status-reblog {
background: linear-gradient( background: linear-gradient(
160deg, var(--post-gradient-angle),
var(--reblog-faded-color), var(--reblog-faded-color),
transparent min(160px, 50%) transparent min(160px, 50%)
); );
} }
.status-group { .status-group {
background: linear-gradient( background: linear-gradient(
160deg, var(--post-gradient-angle),
var(--group-faded-color), var(--group-faded-color),
transparent min(160px, 50%) transparent min(160px, 50%)
); );
} }
.status-followed-tags { .status-followed-tags {
background: linear-gradient( background: linear-gradient(
160deg, var(--post-gradient-angle),
var(--hashtag-faded-color), var(--hashtag-faded-color),
transparent min(160px, 50%) transparent min(160px, 50%)
); );
@ -33,14 +42,14 @@
} }
.status-reply-to { .status-reply-to {
background: linear-gradient( background: linear-gradient(
160deg, var(--post-gradient-angle),
var(--reply-to-faded-color), var(--reply-to-faded-color),
transparent min(160px, 50%) transparent min(160px, 50%)
); );
} }
:is(.status-reblog, .status-group, .status-followed-tags) .status-reply-to { :is(.status-reblog, .status-group, .status-followed-tags) .status-reply-to {
background: linear-gradient( background: linear-gradient(
-20deg, var(--post-gradient-chip-angle),
var(--reply-to-faded-color), var(--reply-to-faded-color),
transparent min(160px, 50%) transparent min(160px, 50%)
); );
@ -72,12 +81,12 @@
} }
.status-reblog .status-pre-meta .icon { .status-reblog .status-pre-meta .icon {
color: var(--reblog-color); color: var(--reblog-color);
margin-right: 4px; margin-inline-end: 4px;
vertical-align: text-bottom; vertical-align: text-bottom;
} }
.status-group .status-pre-meta .icon { .status-group .status-pre-meta .icon {
color: var(--group-color); color: var(--group-color);
margin-right: 4px; margin-inline-end: 4px;
vertical-align: text-bottom; vertical-align: text-bottom;
} }
.status-followed-tags { .status-followed-tags {
@ -91,7 +100,7 @@
.icon { .icon {
color: var(--hashtag-color); color: var(--hashtag-color);
margin-right: 4px; margin-inline-end: 4px;
vertical-align: text-bottom; vertical-align: text-bottom;
} }
a { a {
@ -208,7 +217,7 @@
/* filter: drop-shadow(0 2px 4px var(--bg-faded-color)); */ /* filter: drop-shadow(0 2px 4px var(--bg-faded-color)); */
} }
.status-card:has(.status-badge:not(:empty)) { .status-card:has(.status-badge:not(:empty)) {
border-top-right-radius: 8px; border-start-end-radius: 8px;
} }
.status-card > * { .status-card > * {
pointer-events: none; pointer-events: none;
@ -276,7 +285,8 @@
align-items: center; align-items: center;
.status-carousel & { .status-carousel & {
padding: 16px 16px 16px 24px; padding: 16px;
padding-inline-start: 24px;
} }
} }
.status.filtered .status-filtered-info { .status.filtered .status-filtered-info {
@ -286,7 +296,7 @@
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
mask-image: linear-gradient(to right, black 90%, transparent); mask-image: linear-gradient(var(--to-forward), black 90%, transparent);
position: relative; position: relative;
} }
.status.filtered .avatar { .status.filtered .avatar {
@ -312,7 +322,7 @@
opacity: 0; opacity: 0;
transform: translateX(8px); transform: translateX(8px);
position: absolute; position: absolute;
left: 0; inset-inline-start: 0;
} }
.status.filtered:is(:hover, :focus, :active) .status-filtered-info-2 { .status.filtered:is(:hover, :focus, :active) .status-filtered-info-2 {
opacity: 0.75; opacity: 0.75;
@ -353,7 +363,7 @@
padding-bottom: 0; padding-bottom: 0;
margin-bottom: calc(-1 * var(--top-padding) / 2); margin-bottom: calc(-1 * var(--top-padding) / 2);
background-image: linear-gradient( background-image: linear-gradient(
160deg, var(--post-gradient-angle),
transparent 2.5%, transparent 2.5%,
var(--reply-to-faded-color) 10%, var(--reply-to-faded-color) 10%,
transparent transparent
@ -381,7 +391,7 @@
content: ''; content: '';
position: absolute; position: absolute;
top: calc(var(--top-padding) + var(--avatar-size)); top: calc(var(--top-padding) + var(--avatar-size));
left: var(--line-start); inset-inline-start: var(--line-start);
width: var(--line-width); width: var(--line-width);
height: calc( height: calc(
100% - var(--top-padding) - var(--avatar-size) + (var(--top-padding) / 2) 100% - var(--top-padding) - var(--avatar-size) + (var(--top-padding) / 2)
@ -392,7 +402,7 @@
} }
.avatar { .avatar {
margin-left: calc((50px - var(--avatar-size)) / 2); margin-inline-start: calc((50px - var(--avatar-size)) / 2);
justify-self: center; justify-self: center;
z-index: 1; z-index: 1;
} }
@ -433,7 +443,7 @@
min-width: 0; min-width: 0;
} }
.status:not(.small) > .container { .status:not(.small) > .container {
padding-left: 12px; padding-inline-start: 12px;
} }
.status > .container > .meta { .status > .container > .meta {
@ -451,7 +461,7 @@
/* text-overflow: ellipsis; */ /* text-overflow: ellipsis; */
} }
.status > .container > .meta .meta-name { .status > .container > .meta .meta-name {
mask-image: linear-gradient(to left, transparent, black 16px); mask-image: linear-gradient(var(--to-backward), transparent, black 16px);
flex-grow: 1; flex-grow: 1;
.name-text b { .name-text b {
@ -470,7 +480,7 @@
text-align: end; text-align: end;
text-decoration: none; text-decoration: none;
flex-shrink: 0; flex-shrink: 0;
margin-left: 4px; margin-inline-start: 4px;
white-space: nowrap; white-space: nowrap;
} }
.status > .container > .meta a.time { .status > .container > .meta a.time {
@ -482,7 +492,7 @@
font-size: 90%; font-size: 90%;
.more { .more {
margin-left: 4px; margin-inline-start: 4px;
transition: transform 0.2s ease-out; transition: transform 0.2s ease-out;
} }
} }
@ -509,7 +519,8 @@
.status-reply-badge { .status-reply-badge {
display: inline-flex; display: inline-flex;
margin: 2px 0 2px 4px; margin: 2px 0;
margin-inline-start: 4px;
gap: 4px; gap: 4px;
align-items: center; align-items: center;
vertical-align: middle; vertical-align: middle;
@ -609,7 +620,7 @@
position: absolute; position: absolute;
width: 100%; width: 100%;
top: calc(100% + 2px); top: calc(100% + 2px);
left: 0; inset-inline-start: 0;
text-align: center; text-align: center;
} }
.status-filtered-badge.horizontal.badge-meta > span + span { .status-filtered-badge.horizontal.badge-meta > span + span {
@ -618,7 +629,7 @@
} }
.status.large > .container > .content-container { .status.large > .container > .content-container {
margin-left: calc(-50px - 16px); margin-inline-start: calc(-50px - 16px);
padding-top: 10px; padding-top: 10px;
padding-bottom: 10px; padding-bottom: 10px;
} }
@ -1005,13 +1016,13 @@
.media-gt2 .media-gt2
) { ) {
/* 50px = avatar size */ /* 50px = avatar size */
margin-left: calc(-1 * ((50px / 2))); margin-inline-start: calc(-1 * ((50px / 2)));
/* /*
outer padding = 16px outer padding = 16px
gap = 12px gap = 12px
so... 16 - 12 = 4 so... 16 - 12 = 4
*/ */
margin-right: -4px; margin-inline-end: -4px;
} }
.status.large :is(.media-container, .media-container.media-gt2) { .status.large :is(.media-container, .media-container.media-gt2) {
height: auto; height: auto;
@ -1121,40 +1132,46 @@
} }
/* Special media borders */ /* Special media borders */
.status .media-container.media-eq2 .media:first-of-type { .status .media-container.media-eq2 .media:first-of-type {
border-radius: var(--media-radius) var(--media-radius-inner) border-start-end-radius: var(--media-radius-inner);
var(--media-radius-inner) var(--media-radius); border-end-end-radius: var(--media-radius-inner);
} }
.status .media-container.media-eq2 .media:last-of-type { .status .media-container.media-eq2 .media:last-of-type {
border-radius: var(--media-radius-inner) var(--media-radius) border-start-start-radius: var(--media-radius-inner);
var(--media-radius) var(--media-radius-inner); border-end-start-radius: var(--media-radius-inner);
} }
.status .media-container.media-eq3 .media:first-of-type { .status .media-container.media-eq3 .media:first-of-type {
border-radius: var(--media-radius) var(--media-radius-inner) border-start-end-radius: var(--media-radius-inner);
var(--media-radius-inner) var(--media-radius); border-end-end-radius: var(--media-radius-inner);
} }
.status .media-container.media-eq3 .media:nth-of-type(2) { .status .media-container.media-eq3 .media:nth-of-type(2) {
border-radius: var(--media-radius-inner) var(--media-radius) border-start-start-radius: var(--media-radius-inner);
var(--media-radius-inner) var(--media-radius-inner); border-end-end-radius: var(--media-radius-inner);
border-end-start-radius: var(--media-radius-inner);
} }
.status .media-container.media-eq3 .media:last-of-type { .status .media-container.media-eq3 .media:last-of-type {
border-radius: var(--media-radius-inner) var(--media-radius-inner) border-start-start-radius: var(--media-radius-inner);
var(--media-radius) var(--media-radius-inner); border-start-end-radius: var(--media-radius-inner);
border-end-start-radius: var(--media-radius-inner);
} }
.status .media-container.media-eq4 .media:first-of-type { .status .media-container.media-eq4 .media:first-of-type {
border-radius: var(--media-radius) var(--media-radius-inner) border-start-end-radius: var(--media-radius-inner);
var(--media-radius-inner) var(--media-radius-inner); border-end-end-radius: var(--media-radius-inner);
border-end-start-radius: var(--media-radius-inner);
} }
.status .media-container.media-eq4 .media:nth-of-type(2) { .status .media-container.media-eq4 .media:nth-of-type(2) {
border-radius: var(--media-radius-inner) var(--media-radius) border-start-start-radius: var(--media-radius-inner);
var(--media-radius-inner) var(--media-radius-inner); border-end-end-radius: var(--media-radius-inner);
border-end-start-radius: var(--media-radius-inner);
} }
.status .media-container.media-eq4 .media:nth-of-type(3) { .status .media-container.media-eq4 .media:nth-of-type(3) {
border-radius: var(--media-radius-inner) var(--media-radius-inner) border-start-start-radius: var(--media-radius-inner);
var(--media-radius-inner) var(--media-radius); border-start-end-radius: var(--media-radius-inner);
border-end-end-radius: var(--media-radius-inner);
} }
.status .media-container.media-eq4 .media:last-of-type { .status .media-container.media-eq4 .media:last-of-type {
border-radius: var(--media-radius-inner) var(--media-radius-inner) border-start-start-radius: var(--media-radius-inner);
var(--media-radius) var(--media-radius-inner); border-start-end-radius: var(--media-radius-inner);
border-end-start-radius: var(--media-radius-inner);
} }
.status .media:only-child { .status .media:only-child {
grid-area: span 2 / span 2; grid-area: span 2 / span 2;
@ -1207,7 +1224,7 @@
.alt-badge { .alt-badge {
position: absolute; position: absolute;
bottom: 8px; bottom: 8px;
left: 8px; inset-inline-start: 8px;
&:before { &:before {
content: ''; content: '';
@ -1266,7 +1283,7 @@ body:has(#modal-container .carousel) .status .media img:hover {
content: attr(data-formatted-duration); content: attr(data-formatted-duration);
position: absolute; position: absolute;
bottom: 8px; bottom: 8px;
right: 8px; inset-inline-end: 8px;
color: var(--media-fg-color); color: var(--media-fg-color);
background-color: var(--media-bg-color); background-color: var(--media-bg-color);
border: var(--hairline-width) solid var(--media-outline-color); border: var(--hairline-width) solid var(--media-outline-color);
@ -1283,7 +1300,7 @@ body:has(#modal-container .carousel) .status .media img:hover {
content: attr(data-label); content: attr(data-label);
position: absolute; position: absolute;
bottom: 8px; bottom: 8px;
right: 8px; inset-inline-end: 8px;
color: var(--media-fg-color); color: var(--media-fg-color);
background-color: var(--media-bg-color); background-color: var(--media-bg-color);
border: var(--hairline-width) solid var(--media-outline-color); border: var(--hairline-width) solid var(--media-outline-color);
@ -1456,7 +1473,7 @@ body:has(#modal-container .carousel) .status .media img:hover {
z-index: 1; z-index: 1;
position: absolute; position: absolute;
top: 8px; top: 8px;
right: 8px; inset-inline-end: 8px;
color: var(--media-fg-color); color: var(--media-fg-color);
background-color: var(--media-bg-color); background-color: var(--media-bg-color);
padding: 2px 8px; padding: 2px 8px;
@ -1484,8 +1501,8 @@ body:has(#modal-container .carousel) .status .media img:hover {
} }
+ .carousel-button { + .carousel-button {
left: auto; inset-inline-start: auto;
right: 8px; inset-inline-end: 8px;
} }
} }
@ -1655,7 +1672,7 @@ body:has(#modal-container .carousel) .status .media img:hover {
display: none; display: none;
+ * { + * {
margin-left: 1ex; margin-inline-start: 1ex;
} }
} }
} }
@ -1746,9 +1763,9 @@ body:has(#modal-container .carousel) .status .media img:hover {
--bottom: 16px; --bottom: 16px;
bottom: var(--bottom); bottom: var(--bottom);
bottom: calc(var(--bottom) + env(safe-area-inset-bottom)); bottom: calc(var(--bottom) + env(safe-area-inset-bottom));
left: 16px; inset-inline-start: 16px;
left: calc(16px + env(safe-area-inset-left)); inset-inline-start: calc(16px + env(safe-area-inset-left));
text-align: left; text-align: start;
border-radius: 8px; border-radius: 8px;
color: var(--text-color); color: var(--text-color);
padding: 4px 8px; padding: 4px 8px;
@ -2023,8 +2040,8 @@ a.card:is(:hover, :focus):visited {
z-index: 0; z-index: 0;
} }
.poll-option:first-child:after { .poll-option:first-child:after {
border-top-left-radius: 12px; border-start-start-radius: 12px;
border-top-right-radius: 12px; border-start-end-radius: 12px;
} }
.poll-option:hover:after { .poll-option:hover:after {
opacity: 1; opacity: 1;
@ -2057,7 +2074,9 @@ a.card:is(:hover, :focus):visited {
opacity: 1; opacity: 1;
} }
.poll-vote-button { .poll-vote-button {
margin: 8px 8px 0 12px; margin: 8px 0 0;
margin-inline-start: 12px;
margin-inline-end: 8px;
/* padding-inline: 24px; */ /* padding-inline: 24px; */
min-width: 160px; min-width: 160px;
} }
@ -2066,6 +2085,10 @@ a.card:is(:hover, :focus):visited {
margin: 8px 16px; margin: 8px 16px;
font-size: 90%; font-size: 90%;
user-select: none; user-select: none;
> button:first-child {
margin-inline-start: -8px;
}
} }
.poll-option-title { .poll-option-title {
text-shadow: 0 1px var(--bg-color); text-shadow: 0 1px var(--bg-color);
@ -2101,14 +2124,14 @@ a.card:is(:hover, :focus):visited {
} }
.status.large .extra-meta { .status.large .extra-meta {
padding-top: 0; padding-top: 0;
margin-left: calc(-50px - 16px); margin-inline-start: calc(-50px - 16px);
} }
/* EMOJI REACTIONS */ /* EMOJI REACTIONS */
.status.large .emoji-reactions { .status.large .emoji-reactions {
cursor: default; cursor: default;
margin-left: calc(-50px - 16px); margin-inline-start: calc(-50px - 16px);
} }
/* ACTIONS */ /* ACTIONS */
@ -2120,7 +2143,7 @@ a.card:is(:hover, :focus):visited {
.status.large .actions { .status.large .actions {
padding-top: 4px; padding-top: 4px;
padding-bottom: 16px; padding-bottom: 16px;
margin-left: calc(-50px - 16px); margin-inline-start: calc(-50px - 16px);
color: var(--text-insignificant-color); color: var(--text-insignificant-color);
border-top: var(--hairline-width) solid var(--outline-color); border-top: var(--hairline-width) solid var(--outline-color);
margin-top: 8px; margin-top: 8px;
@ -2279,7 +2302,7 @@ a.card:is(:hover, :focus):visited {
width: 100%; width: 100%;
border: 1px solid var(--outline-color); border: 1px solid var(--outline-color);
background: linear-gradient( background: linear-gradient(
to bottom right, to bottom var(--forward),
var(--bg-faded-color), var(--bg-faded-color),
transparent 160px transparent 160px
); );
@ -2297,7 +2320,7 @@ a.card:is(:hover, :focus):visited {
display: flex; display: flex;
position: absolute; position: absolute;
top: -6px; top: -6px;
right: 8px; inset-inline-end: 8px;
background-color: var(--bg-color); background-color: var(--bg-color);
border-radius: 8px; border-radius: 8px;
z-index: 1; z-index: 1;
@ -2307,7 +2330,7 @@ a.card:is(:hover, :focus):visited {
opacity: 0; opacity: 0;
pointer-events: none; pointer-events: none;
transform: translate3d(0, 6px, 0); transform: translate3d(0, 6px, 0);
transform-origin: right center; transform-origin: var(--forward) center;
transition: all 0.15s ease-out 0.3s, border-color 0.3s ease-out; transition: all 0.15s ease-out 0.3s, border-color 0.3s ease-out;
.timeline.contextual .replies[data-comments-level='4'] & { .timeline.contextual .replies[data-comments-level='4'] & {
@ -2386,8 +2409,13 @@ a.card:is(:hover, :focus):visited {
} }
} }
.timeline.contextual .descendant .status { .timeline.contextual .descendant .status {
--bg-gradient-rotation: -140deg;
:dir(rtl) & {
--bg-gradient-rotation: 140deg;
}
--bg-gradient: linear-gradient( --bg-gradient: linear-gradient(
-140deg, var(--bg-gradient-rotation),
var(--bg-faded-color), var(--bg-faded-color),
transparent 75% transparent 75%
); );
@ -2414,7 +2442,7 @@ a.card:is(:hover, :focus):visited {
.status-badge { .status-badge {
position: absolute; position: absolute;
top: 4px; top: 4px;
right: 4px; inset-inline-end: 4px;
line-height: 0; line-height: 0;
pointer-events: none; pointer-events: none;
opacity: 0.75; opacity: 0.75;
@ -2441,8 +2469,21 @@ a.card:is(:hover, :focus):visited {
transform: translateX(0); transform: translateX(0);
} }
} }
@keyframes swoosh-from-left {
0% {
opacity: 0;
transform: translateX(-300%);
}
100% {
opacity: 1;
transform: translateX(0);
}
}
.status-badge > * { .status-badge > * {
animation: swoosh-from-right 1s cubic-bezier(0.51, 0.28, 0.16, 1.26) both; animation: swoosh-from-right 1s cubic-bezier(0.51, 0.28, 0.16, 1.26) both;
:dir(rtl) & {
animation-name: swoosh-from-left;
}
} }
.status-badge > *:nth-child(2) { .status-badge > *:nth-child(2) {
animation-delay: 0.1s; animation-delay: 0.1s;
@ -2457,7 +2498,8 @@ a.card:is(:hover, :focus):visited {
/* MISC */ /* MISC */
.status-aside { .status-aside {
padding: 0 16px 16px 80px; padding: 0 16px 16px;
padding-inline-start: 80px;
color: var(--text-insignificant-color); color: var(--text-insignificant-color);
} }
@ -2740,7 +2782,7 @@ a.card:is(:hover, :focus):visited {
vertical-align: super; vertical-align: super;
font-weight: normal; font-weight: normal;
line-height: 0; line-height: 0;
padding-left: 2px; padding-inline-start: 2px;
} }
&.clickable { &.clickable {

View file

@ -46,6 +46,7 @@ import getTranslateTargetLanguage from '../utils/get-translate-target-language';
import getHTMLText from '../utils/getHTMLText'; import getHTMLText from '../utils/getHTMLText';
import handleContentLinks from '../utils/handle-content-links'; import handleContentLinks from '../utils/handle-content-links';
import htmlContentLength from '../utils/html-content-length'; import htmlContentLength from '../utils/html-content-length';
import isRTL from '../utils/is-rtl';
import isMastodonLinkMaybe from '../utils/isMastodonLinkMaybe'; import isMastodonLinkMaybe from '../utils/isMastodonLinkMaybe';
import localeMatch from '../utils/locale-match'; import localeMatch from '../utils/locale-match';
import mem from '../utils/mem'; import mem from '../utils/mem';
@ -2363,7 +2364,7 @@ function MediaFirstContainer(props) {
useEffect(() => { useEffect(() => {
let handleScroll = () => { let handleScroll = () => {
const { clientWidth, scrollLeft } = carouselRef.current; const { clientWidth, scrollLeft } = carouselRef.current;
const index = Math.round(scrollLeft / clientWidth); const index = Math.round(Math.abs(scrollLeft) / clientWidth);
setCurrentIndex(index); setCurrentIndex(index);
}; };
if (carouselRef.current) { if (carouselRef.current) {
@ -2407,7 +2408,10 @@ function MediaFirstContainer(props) {
e.stopPropagation(); e.stopPropagation();
carouselRef.current.focus(); carouselRef.current.focus();
carouselRef.current.scrollTo({ carouselRef.current.scrollTo({
left: carouselRef.current.clientWidth * (currentIndex - 1), left:
carouselRef.current.clientWidth *
(currentIndex - 1) *
(isRTL() ? -1 : 1),
behavior: 'smooth', behavior: 'smooth',
}); });
}} }}
@ -2425,7 +2429,10 @@ function MediaFirstContainer(props) {
e.stopPropagation(); e.stopPropagation();
carouselRef.current.focus(); carouselRef.current.focus();
carouselRef.current.scrollTo({ carouselRef.current.scrollTo({
left: carouselRef.current.clientWidth * (currentIndex + 1), left:
carouselRef.current.clientWidth *
(currentIndex + 1) *
(isRTL() ? -1 : 1),
behavior: 'smooth', behavior: 'smooth',
}); });
}} }}
@ -2580,8 +2587,6 @@ function Card({ card, selfReferential, instance }) {
class={`card link ${isPost ? 'card-post' : ''} ${ class={`card link ${isPost ? 'card-post' : ''} ${
blurhashImage ? '' : size blurhashImage ? '' : size
}`} }`}
lang={language}
dir="auto"
style={{ style={{
'--average-color': '--average-color':
rgbAverageColor && `rgb(${rgbAverageColor.join(',')})`, rgbAverageColor && `rgb(${rgbAverageColor.join(',')})`,
@ -2608,7 +2613,7 @@ function Card({ card, selfReferential, instance }) {
}} }}
/> />
</div> </div>
<div class="meta-container"> <div class="meta-container" lang={language}>
<p class="meta domain"> <p class="meta domain">
<span class="domain">{domain}</span>{' '} <span class="domain">{domain}</span>{' '}
{!!publishedAt && <>&middot; </>} {!!publishedAt && <>&middot; </>}
@ -2685,6 +2690,7 @@ function Card({ card, selfReferential, instance }) {
rel="nofollow noopener noreferrer" rel="nofollow noopener noreferrer"
class={`card link ${isPost ? 'card-post' : ''} no-image`} class={`card link ${isPost ? 'card-post' : ''} no-image`}
lang={language} lang={language}
dir="auto"
onClick={handleClick} onClick={handleClick}
> >
<div class="meta-container"> <div class="meta-container">
@ -2987,6 +2993,7 @@ function EmbedModal({ post, instance, onClose }) {
onClick={(e) => { onClick={(e) => {
e.target.select(); e.target.select();
}} }}
dir="auto"
> >
{htmlCode} {htmlCode}
</textarea> </textarea>
@ -3133,6 +3140,7 @@ function EmbedModal({ post, instance, onClose }) {
<output <output
class="embed-preview" class="embed-preview"
dangerouslySetInnerHTML={{ __html: htmlCode }} dangerouslySetInnerHTML={{ __html: htmlCode }}
dir="auto"
/> />
<p> <p>
<small>Note: This preview is lightly styled.</small> <small>Note: This preview is lightly styled.</small>

View file

@ -13,6 +13,7 @@ import { useSnapshot } from 'valtio';
import FilterContext from '../utils/filter-context'; import FilterContext from '../utils/filter-context';
import { filteredItems, isFiltered } from '../utils/filters'; import { filteredItems, isFiltered } from '../utils/filters';
import isRTL from '../utils/is-rtl';
import states, { statusKey } from '../utils/states'; import states, { statusKey } from '../utils/states';
import statusPeek from '../utils/status-peek'; import statusPeek from '../utils/status-peek';
import { isMediaFirstInstance } from '../utils/store-utils'; import { isMediaFirstInstance } from '../utils/store-utils';
@ -864,8 +865,11 @@ function StatusCarousel({ title, class: className, children }) {
class="small plain2" class="small plain2"
// disabled={reachStart} // disabled={reachStart}
onClick={() => { onClick={() => {
const left =
Math.min(320, carouselRef.current?.offsetWidth) *
(isRTL() ? 1 : -1);
carouselRef.current?.scrollBy({ carouselRef.current?.scrollBy({
left: -Math.min(320, carouselRef.current?.offsetWidth), left,
behavior: 'smooth', behavior: 'smooth',
}); });
}} }}
@ -878,8 +882,11 @@ function StatusCarousel({ title, class: className, children }) {
class="small plain2" class="small plain2"
// disabled={reachEnd} // disabled={reachEnd}
onClick={() => { onClick={() => {
const left =
Math.min(320, carouselRef.current?.offsetWidth) *
(isRTL() ? -1 : 1);
carouselRef.current?.scrollBy({ carouselRef.current?.scrollBy({
left: Math.min(320, carouselRef.current?.offsetWidth), left,
behavior: 'smooth', behavior: 'smooth',
}); });
}} }}

View file

@ -35,7 +35,7 @@
border-bottom: 0; border-bottom: 0;
margin-bottom: -1px; margin-bottom: -1px;
background-image: linear-gradient( background-image: linear-gradient(
to top left, to top var(--backward),
var(--bg-color) 50%, var(--bg-color) 50%,
var(--bg-faded-blur-color) var(--bg-faded-blur-color)
); );
@ -44,12 +44,13 @@
.status-translation-block .translated-block { .status-translation-block .translated-block {
border: 1px solid var(--outline-color); border: 1px solid var(--outline-color);
line-height: 1.3; line-height: 1.3;
border-radius: 0 8px 8px 8px; border-radius: 8px;
border-start-start-radius: 0;
margin: 0; margin: 0;
padding: 8px; padding: 8px;
background-color: var(--bg-color); background-color: var(--bg-color);
background-image: linear-gradient( background-image: linear-gradient(
to bottom right, to bottom var(--forward),
var(--bg-color), var(--bg-color),
var(--bg-faded-blur-color) var(--bg-faded-blur-color)
); );

View file

@ -110,6 +110,17 @@
--spring-timing-funtion: cubic-bezier(0.175, 0.885, 0.32, 1.275); --spring-timing-funtion: cubic-bezier(0.175, 0.885, 0.32, 1.275);
--min-dimension: 88px; --min-dimension: 88px;
--forward: right;
--backward: left;
--to-forward: to right;
--to-backward: to left;
&:dir(rtl) {
--forward: left;
--backward: right;
--to-forward: to left;
--to-backward: to right;
}
} }
@media (min-resolution: 2dppx) { @media (min-resolution: 2dppx) {
@ -442,6 +453,11 @@ kbd {
display: initial; display: initial;
} }
.bidi-isolate {
direction: initial;
unicode-bidi: isolate;
}
/* KEYFRAMES */ /* KEYFRAMES */
@keyframes appear { @keyframes appear {

View file

@ -28,7 +28,7 @@
} }
#accounts-container section > ul > li .current { #accounts-container section > ul > li .current {
margin-right: 8px; margin-inline-end: 8px;
color: var(--green-color); color: var(--green-color);
opacity: 0.1; opacity: 0.1;
} }
@ -47,7 +47,7 @@
} }
#accounts-container .avatar { #accounts-container .avatar {
margin-right: 8px; margin-inline-end: 8px;
} }
#accounts-container .accounts-list li div { #accounts-container .accounts-list li div {

View file

@ -111,7 +111,7 @@
margin-bottom: 8px; margin-bottom: 8px;
align-items: center; align-items: center;
gap: 8px; gap: 8px;
text-align: left; text-align: start;
justify-content: space-between; justify-content: space-between;
a { a {
@ -146,6 +146,9 @@
input[type='range'] { input[type='range'] {
accent-color: var(--link-color); accent-color: var(--link-color);
direction: rtl; direction: rtl;
&:dir(rtl) {
direction: ltr;
}
} }
} }
@ -251,7 +254,7 @@
overflow-y: hidden; overflow-y: hidden;
max-width: 100%; max-width: 100%;
mask-image: linear-gradient( mask-image: linear-gradient(
to right, var(--to-forward),
transparent, transparent,
black 16px calc(100% - 16px), black 16px calc(100% - 16px),
transparent transparent
@ -315,7 +318,7 @@
.count { .count {
font-size: 70%; font-size: 70%;
margin-left: 4px; margin-inline-start: 4px;
background-color: var(--bg-color); background-color: var(--bg-color);
padding: 4px 6px; padding: 4px 6px;
border-radius: 12px; border-radius: 12px;
@ -386,7 +389,7 @@
.count { .count {
position: absolute; position: absolute;
right: -4px; inset-inline-end: -4px;
top: -4px; top: -4px;
font-size: 10px; font-size: 10px;
background-color: var(--bg-color); background-color: var(--bg-color);
@ -406,7 +409,7 @@
overflow: hidden; overflow: hidden;
text-align: center; text-align: center;
mask-image: linear-gradient( mask-image: linear-gradient(
to right, var(--to-forward),
black calc(100% - 0.5em), black calc(100% - 0.5em),
transparent 100% transparent 100%
); );
@ -478,13 +481,13 @@
> li { > li {
&:first-child > a { &:first-child > a {
border-top-left-radius: var(--corner-radius); border-start-start-radius: var(--corner-radius);
border-top-right-radius: var(--corner-radius); border-start-end-radius: var(--corner-radius);
} }
&:last-child > a { &:last-child > a {
border-bottom-left-radius: var(--corner-radius); border-end-start-radius: var(--corner-radius);
border-bottom-right-radius: var(--corner-radius); border-end-end-radius: var(--corner-radius);
} }
} }
} }
@ -502,13 +505,13 @@
@media (min-width: 40em) { @media (min-width: 40em) {
&.separator + li a { &.separator + li a {
border-top-left-radius: var(--corner-radius); border-start-start-radius: var(--corner-radius);
border-top-right-radius: var(--corner-radius); border-start-end-radius: var(--corner-radius);
} }
&:has(+ .separator) a { &:has(+ .separator) a {
border-bottom-left-radius: var(--corner-radius); border-end-start-radius: var(--corner-radius);
border-bottom-right-radius: var(--corner-radius); border-end-end-radius: var(--corner-radius);
} }
} }
@ -572,8 +575,12 @@
'author meta' 'author meta'
'content content'; 'content content';
/* align-items: center; */ /* align-items: center; */
--bg-gradient-angle: 140deg;
&:dir(rtl) {
--bg-gradient-angle: -140deg;
}
background-image: linear-gradient( background-image: linear-gradient(
140deg, var(--bg-gradient-angle),
var(--post-bg-color), var(--post-bg-color),
transparent min(160px, 50%) transparent min(160px, 50%)
); );
@ -636,7 +643,7 @@
} }
> .avatar ~ .avatar { > .avatar ~ .avatar {
margin-left: -8px; margin-inline-start: -8px;
} }
> .icon { > .icon {
@ -655,7 +662,7 @@
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
mask-image: linear-gradient( mask-image: linear-gradient(
to right, var(--to-forward),
black calc(100% - 1em), black calc(100% - 1em),
transparent 100% transparent 100%
); );
@ -887,12 +894,15 @@
&:has(.post-peek-media), &:has(.post-peek-media),
.post-peek-media:first-child img { .post-peek-media:first-child img {
transform-origin: left center; transform-origin: left center;
:dir(rtl) & {
transform-origin: right center;
}
} }
} }
@media (max-width: 480px) { @media (max-width: 480px) {
.post-peek-media:not(:last-child) { .post-peek-media:not(:last-child) {
margin-right: -24px; margin-inline-end: -24px;
box-shadow: 0 0 0 2px var(--bg-blur-color); box-shadow: 0 0 0 2px var(--bg-blur-color);
} }
/* Max 10, I'm not going to code more than this */ /* Max 10, I'm not going to code more than this */

View file

@ -365,6 +365,7 @@ function FiltersAddEdit({ filter, onClose }) {
defaultValue={keyword} defaultValue={keyword}
disabled={uiState === 'loading'} disabled={uiState === 'loading'}
required required
dir="auto"
/> />
<div class="filter-keyword-actions"> <div class="filter-keyword-actions">
<label> <label>

View file

@ -166,7 +166,7 @@ function Hashtags({ media: mediaView, columnMode, ...props }) {
titleComponent={ titleComponent={
!!instance && ( !!instance && (
<h1 class="header-double-lines"> <h1 class="header-double-lines">
<b>{hashtagTitle}</b> <b dir="auto">{hashtagTitle}</b>
<div>{instance}</div> <div>{instance}</div>
</h1> </h1>
) )
@ -379,6 +379,7 @@ function Hashtags({ media: mediaView, columnMode, ...props }) {
// no spaces, no hashtags // no spaces, no hashtags
pattern="[^#][^\s#]+[^#]" pattern="[^#][^\s#]+[^#]"
disabled={reachLimit} disabled={reachLimit}
dir="auto"
/> />
</form> </form>
)} )}
@ -402,7 +403,7 @@ function Hashtags({ media: mediaView, columnMode, ...props }) {
}} }}
> >
<Icon icon="x" alt="Remove hashtag" class="danger-icon" /> <Icon icon="x" alt="Remove hashtag" class="danger-icon" />
<span> <span class="bidi-isolate">
<span class="more-insignificant">#</span> <span class="more-insignificant">#</span>
{t} {t}
</span> </span>

View file

@ -30,14 +30,15 @@
#instances-suggestions { #instances-suggestions {
margin: 0.2em 0 0; margin: 0.2em 0 0;
padding: 0 0 0 1.2em; padding: 0;
padding-inline-start: 1.2em;
list-style: none; list-style: none;
width: 90vw; width: 90vw;
max-width: 40em; max-width: 40em;
overflow: auto; overflow: auto;
white-space: nowrap; white-space: nowrap;
mask-image: linear-gradient( mask-image: linear-gradient(
to right, var(--to-forward),
transparent, transparent,
black 1.2em, black 1.2em,
black calc(100% - 5em), black calc(100% - 5em),

View file

@ -158,6 +158,7 @@ function Login() {
onInput={(e) => { onInput={(e) => {
setInstanceText(e.target.value); setInstanceText(e.target.value);
}} }}
dir="auto"
/> />
{instancesSuggestions?.length > 0 ? ( {instancesSuggestions?.length > 0 ? (
<ul id="instances-suggestions"> <ul id="instances-suggestions">

View file

@ -185,7 +185,7 @@
.notification-group-statuses > li:before { .notification-group-statuses > li:before {
content: counter(index); content: counter(index);
position: absolute; position: absolute;
left: 0; inset-inline-start: 0;
font-size: 10px; font-size: 10px;
padding: 8px; padding: 8px;
font-weight: bold; font-weight: bold;
@ -194,16 +194,19 @@
margin-top: -1px; margin-top: -1px;
} }
.notification-group-statuses > li:not(:last-child) .status-link { .notification-group-statuses > li:not(:last-child) .status-link {
border-bottom-left-radius: 0; border-end-start-radius: 0;
border-bottom-right-radius: 0; border-end-end-radius: 0;
} }
.notification-group-statuses > li:not(:first-child) .status-link { .notification-group-statuses > li:not(:first-child) .status-link {
border-top-left-radius: 0; border-start-start-radius: 0;
border-top-right-radius: 0; border-start-end-radius: 0;
} }
#mentions-option { #mentions-option {
float: right; float: right;
&:dir(rtl) {
float: left;
}
margin-top: 0.5em; margin-top: 0.5em;
} }
#mentions-option label { #mentions-option label {
@ -388,7 +391,7 @@
width: calc(100% - 16px); width: calc(100% - 16px);
} }
.announcements > ul > li:last-child { .announcements > ul > li:last-child {
border-right: none; border-inline-end: none;
} }
.announcements .announcement-block { .announcements .announcement-block {
padding: 16px; padding: 16px;

View file

@ -48,10 +48,10 @@
a { a {
.icon { .icon {
vertical-align: middle; vertical-align: middle;
transition: transform 0.2s; transition: margin 0.2s;
} }
&:hover .icon { &:hover .icon {
transform: translateX(4px); margin-inline-start: 4px;
} }
} }
} }
@ -101,9 +101,8 @@ ul.link-list.hashtag-list li a {
} }
.search-popover { .search-popover {
position: absolute; position: absolute;
left: 8px; inset-inline-start: 8px;
max-width: calc(100% - 16px); max-width: calc(100% - 16px);
/* right: 8px; */
background-color: var(--bg-color); background-color: var(--bg-color);
border: 1px solid var(--outline-color); border: 1px solid var(--outline-color);
box-shadow: 0 4px 24px var(--drop-shadow-color); box-shadow: 0 4px 24px var(--drop-shadow-color);
@ -118,7 +117,8 @@ ul.link-list.hashtag-list li a {
} }
.search-popover-item { .search-popover-item {
text-decoration: none; text-decoration: none;
padding: 8px 16px 8px 8px; padding: 8px;
padding-inline-end: 16px;
display: flex; display: flex;
gap: 8px; gap: 8px;
align-items: center; align-items: center;
@ -132,10 +132,15 @@ ul.link-list.hashtag-list li a {
} }
.search-popover-item:is(:focus, .focus) { .search-popover-item:is(:focus, .focus) {
box-shadow: inset 4px 0 0 0 var(--button-bg-color); box-shadow: inset 4px 0 0 0 var(--button-bg-color);
:dir(rtl) & {
box-shadow: inset -4px 0 0 0 var(--button-bg-color);
}
} }
.search-popover-item :is(mark, q) { .search-popover-item :is(mark, q) {
color: var(--text-color); color: var(--text-color);
background-color: var(--link-bg-color); background-color: var(--link-bg-color);
unicode-bidi: isolate;
direction: initial;
} }
.search-popover-item:is(:hover, :focus, .focus) :is(mark, q) { .search-popover-item:is(:hover, :focus, .focus) :is(mark, q) {
background-color: var(--link-bg-color); background-color: var(--link-bg-color);

View file

@ -36,12 +36,12 @@
border-bottom: var(--hairline-width) solid var(--outline-color); border-bottom: var(--hairline-width) solid var(--outline-color);
} }
#settings-container section > ul > li > div:last-child { #settings-container section > ul > li > div:last-child {
text-align: right; text-align: end;
} }
#settings-container section > ul > li .sub-section { #settings-container section > ul > li .sub-section {
text-align: left !important; text-align: start !important;
margin-top: 8px; margin-top: 8px;
margin-left: 24px; margin-inline-start: 24px;
} }
#settings-container section > ul > li .sub-section p { #settings-container section > ul > li .sub-section p {
margin-block: 0.5em; margin-block: 0.5em;
@ -121,11 +121,11 @@
grid-template-rows: 1fr 1fr; grid-template-rows: 1fr 1fr;
> span:first-child { > span:first-child {
text-align: left; text-align: start;
} }
> span:last-child { > span:last-child {
text-align: right; text-align: end;
} }
} }
} }

View file

@ -11,7 +11,7 @@
align-self: stretch; align-self: stretch;
} }
header h1 .deck-back { header h1 .deck-back {
margin-left: -16px; margin-inline-start: -16px;
} }
.button-refresh .icon { .button-refresh .icon {
@ -39,7 +39,7 @@
font-size: 70% !important; font-size: 70% !important;
& > .avatar ~ .avatar { & > .avatar ~ .avatar {
margin-left: -4px; margin-inline-start: -4px;
} }
} }
.ancestors-indicator:not([hidden]) { .ancestors-indicator:not([hidden]) {

View file

@ -1370,6 +1370,8 @@ function SubComments({
const detailsRef = useRef(); const detailsRef = useRef();
useLayoutEffect(() => { useLayoutEffect(() => {
function handleScroll(e) { function handleScroll(e) {
// NOTE: this scrollLeft works for RTL too
// Browsers do the magic for us
e.target.dataset.scrollLeft = e.target.scrollLeft; e.target.dataset.scrollLeft = e.target.scrollLeft;
} }
detailsRef.current?.addEventListener('scroll', handleScroll, { detailsRef.current?.addEventListener('scroll', handleScroll, {

View file

@ -209,7 +209,7 @@ function Trending({ columnMode, ...props }) {
const total = history.reduce((acc, cur) => acc + +cur.uses, 0); const total = history.reduce((acc, cur) => acc + +cur.uses, 0);
return ( return (
<Link to={`/${instance}/t/${name}`} key={name}> <Link to={`/${instance}/t/${name}`} key={name}>
<span> <span dir="auto">
<span class="more-insignificant">#</span> <span class="more-insignificant">#</span>
{name} {name}
</span> </span>

View file

@ -140,7 +140,7 @@
height: auto; height: auto;
max-height: none; max-height: none;
position: fixed; position: fixed;
left: 0; inset-inline-start: 0;
top: 0; top: 0;
bottom: 0; bottom: 0;
width: 50%; width: 50%;
@ -153,8 +153,9 @@
} }
#why-container { #why-container {
padding: 32px 32px 32px 8px; padding: 32px;
margin-left: 50%; padding-inline-start: 8px;
margin-inline-start: 50%;
/* overflow: auto; /* overflow: auto;
mask-image: linear-gradient(to top, transparent 16px, black 64px); */ mask-image: linear-gradient(to top, transparent 16px, black 64px); */

26
src/utils/is-rtl.js Normal file
View file

@ -0,0 +1,26 @@
let IS_RTL = false;
// Use MutationObserver to detect RTL
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'attributes') {
const { value } = mutation.target;
if (value === 'rtl') {
IS_RTL = true;
} else {
IS_RTL = false;
}
// Fire custom event 'dirchange' on document
// document.dispatchEvent(new Event('dirchange'));
}
});
});
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['dir'],
});
export default function isRTL() {
return IS_RTL;
// return document.documentElement.dir === 'rtl';
}