diff --git a/external/lang b/external/lang
index dad00381aaaafc1ab829816dffc31f0f37ee56a9..5cad406a2fb09d90803c5604d6f27701c3bf140b 160000
--- a/external/lang
+++ b/external/lang
@@ -1 +1 @@
-Subproject commit dad00381aaaafc1ab829816dffc31f0f37ee56a9
+Subproject commit 5cad406a2fb09d90803c5604d6f27701c3bf140b
diff --git a/src/components/common/user/UserIcon.tsx b/src/components/common/user/UserIcon.tsx
index 9d7bb8017b35a240c007f022b223813eae35ad36..724f042ee7eb13688cfd98d470b67e51b2b4e2cf 100644
--- a/src/components/common/user/UserIcon.tsx
+++ b/src/components/common/user/UserIcon.tsx
@@ -9,6 +9,7 @@ import { AppContext } from "../../../context/revoltjs/RevoltClient";
 
 type VoiceStatus = "muted";
 interface Props extends IconBaseProps<User> {
+    mask?: string;
     status?: boolean;
     voice?: VoiceStatus;
 }
@@ -52,7 +53,7 @@ import fallback from '../assets/user.png';
 export default function UserIcon(props: Props & Omit<JSX.SVGAttributes<SVGSVGElement>, keyof Props>) {
     const client = useContext(AppContext);
 
-    const { target, attachment, size, voice, status, animate, children, as, ...svgProps } = props;
+    const { target, attachment, size, voice, status, animate, mask, children, as, ...svgProps } = props;
     const iconURL = client.generateFileURL(target?.avatar ?? attachment, { max_side: 256 }, animate)
         ?? (target ? client.users.getDefaultAvatarURL(target._id) : fallback);
 
@@ -62,7 +63,7 @@ export default function UserIcon(props: Props & Omit<JSX.SVGAttributes<SVGSVGEle
             height={size}
             aria-hidden="true"
             viewBox="0 0 32 32">
-            <foreignObject x="0" y="0" width="32" height="32" mask={props.status ? "url(#user)" : undefined}>
+            <foreignObject x="0" y="0" width="32" height="32" mask={mask ?? (status ? "url(#user)" : undefined)}>
                 {
                     <img src={iconURL}
                         draggable={false} />
diff --git a/src/components/ui/Masks.tsx b/src/components/ui/Masks.tsx
index 3a1513f13abab8b58dc11769ae965be8b629d6be..eba85108a99bd53b8845392b888f1a9132579150 100644
--- a/src/components/ui/Masks.tsx
+++ b/src/components/ui/Masks.tsx
@@ -12,6 +12,10 @@ export default function Masks() {
                     <rect x="0" y="0" width="32" height="32" fill="white" />
                     <circle cx="27" cy="27" r="7" fill={"black"} />
                 </mask>
+                <mask id="overlap">
+                    <rect x="0" y="0" width="32" height="32" fill="white" />
+                    <circle cx="32" cy="16" r="18" fill={"black"} />
+                </mask>
             </defs>
         </svg>
     )
diff --git a/src/context/intermediate/popovers/PendingRequests.tsx b/src/context/intermediate/popovers/PendingRequests.tsx
index 710cb6b2f250a588a66a9588a2e68e8fc55376ae..5b6a68b843d45a4fd03feb65e552e219808301b8 100644
--- a/src/context/intermediate/popovers/PendingRequests.tsx
+++ b/src/context/intermediate/popovers/PendingRequests.tsx
@@ -1,3 +1,4 @@
+import { Text } from "preact-i18n";
 import styles from "./UserPicker.module.scss";
 import { useUsers } from "../../revoltjs/hooks";
 import Modal from "../../../components/ui/Modal";
@@ -14,7 +15,7 @@ export function PendingRequests({ users: ids, onClose }: Props) {
     return (
         <Modal
             visible={true}
-            title={"Pending requests"}
+            title={<Text id="app.special.friends.pending" />}
             onClose={onClose}>
             <div className={styles.list}>
                 { users
diff --git a/src/pages/friends/Friend.module.scss b/src/pages/friends/Friend.module.scss
index 2fd1da5b8bdebaa695149f5d99ff0345ba0dda5f..5d1b5aec8288a1ef160aac929b0acafbfba9cb58 100644
--- a/src/pages/friends/Friend.module.scss
+++ b/src/pages/friends/Friend.module.scss
@@ -150,6 +150,11 @@
         display: flex;
         flex-shrink: 0;
         margin-inline-end: 15px;
+
+        svg:not(:first-child) {
+            position: relative;
+            margin-left: -32px;
+        }
     }
 
     .details {
diff --git a/src/pages/friends/Friends.tsx b/src/pages/friends/Friends.tsx
index 7e11fe682631a59460cf5ee7b8ded8d95aa51972..b713eddc70ab6c543fbba882341a6dc8f6410100 100644
--- a/src/pages/friends/Friends.tsx
+++ b/src/pages/friends/Friends.tsx
@@ -12,6 +12,8 @@ import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice";
 import { useIntermediate } from "../../context/intermediate/Intermediate";
 import { ChevronDown, ChevronRight } from "@styled-icons/boxicons-regular";
 import { UserDetail, Conversation, UserPlus } from "@styled-icons/boxicons-solid";
+import { TextReact } from "../../lib/i18n";
+import { Children } from "../../types/Preact";
 
 export default function Friends() {
     const { openScreen } = useIntermediate();
@@ -22,10 +24,10 @@ export default function Friends() {
     const friends = users.filter(x => x.relationship === Users.Relationship.Friend);
 
     const lists = [
-        [ 'app.special.friends.pending', users.filter(x =>
+        [ '', users.filter(x =>
             x.relationship === Users.Relationship.Incoming
         ) ],
-        [ 'app.special.friends.pending', users.filter(x =>
+        [ 'app.special.friends.sent', users.filter(x =>
             x.relationship === Users.Relationship.Outgoing
         ) ],
         [ 'app.status.online', friends.filter(x =>
@@ -39,6 +41,10 @@ export default function Friends() {
         ) ]
     ] as [ string, User[] ][];
 
+    const incoming = lists[0][1];
+    const userlist: Children[] = incoming.map(x => <b>{ x.username }</b>);
+    for (let i=incoming.length-1;i>0;i--) userlist.splice(i, 0, ', ');
+
     const isEmpty = lists.reduce((p: number, n) => p + n.length, 0) === 0;
     return (
         <>
@@ -74,15 +80,20 @@ export default function Friends() {
                     </>
                 )}
 
-                { lists[0][1].length > 0 && <div className={styles.pending}
-                    onClick={() => openScreen({ id: 'pending_requests', users: lists[0][1].map(x => x._id) })}>
+                { incoming.length > 0 && <div className={styles.pending}
+                    onClick={() => openScreen({ id: 'pending_requests', users: incoming.map(x => x._id) })}>
                     <div className={styles.avatars}>
-                        { lists[0][1].map((x, i) => i < 3 && <UserIcon target={x} size={54} />) }
+                        { incoming.map((x, i) => i < 3 && <UserIcon target={x} size={64} mask={ i < Math.min(incoming.length - 1, 2) ? "url(#overlap)" : undefined } />) }
                     </div>
                     <div className={styles.details}>
-                        {/* ! FIXME: i18n */}
-                        <div className={styles.title}>Pending requests<span>{ lists[0][1].length }</span></div>
-                        <span className={styles.from}>From <span className={styles.user}>{ lists[0][1].map(x => x.username).join(', ') }</span></span>
+                        <div><Text id="app.special.friends.pending" /> <span>{ incoming.length }</span></div>
+                        <span>
+                            {
+                                  incoming.length > 3 ? <TextReact id="app.special.friends.from.several" fields={{ userlist: userlist.slice(0, 6), count: incoming.length - 3 }} />
+                                : incoming.length > 1 ? <TextReact id="app.special.friends.from.multiple" fields={{ user: userlist.shift()!, userlist: userlist.slice(1) }} />
+                                : <TextReact id="app.special.friends.from.single" fields={{ user: userlist[0] }} />
+                            }
+                        </span>
                     </div>
                     <ChevronRight size={28} />
                 </div> }