diff --git a/src/App.jsx b/src/App.jsx
index cf2770e..d462330 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -24,7 +24,7 @@ import {
 } from "react-router-dom";
 import * as Sentry from "@sentry/react";
 import { OverlayProvider } from "@react-aria/overlays";
-import { Home } from "./Home";
+import { HomePage } from "./home/HomePage";
 import { LoginPage } from "./LoginPage";
 import { RegisterPage } from "./RegisterPage";
 import { Room } from "./Room";
@@ -45,7 +45,7 @@ export default function App({ history }) {
         <OverlayProvider>
           <Switch>
             <SentryRoute exact path="/">
-              <Home />
+              <HomePage />
             </SentryRoute>
             <SentryRoute exact path="/login">
               <LoginPage />
diff --git a/src/Home.module.css b/src/Home.module.css
deleted file mode 100644
index 15e8534..0000000
--- a/src/Home.module.css
+++ /dev/null
@@ -1,139 +0,0 @@
-.home {
-  display: flex;
-  flex: 1;
-  flex-direction: column;
-  min-height: 100%;
-}
-
-.splitContainer {
-  display: flex;
-  flex: 1;
-  flex-direction: column;
-}
-
-.left,
-.right {
-  display: flex;
-  flex-direction: column;
-  flex: 1;
-}
-
-.fullWidth {
-  background-color: var(--bgColor1);
-}
-
-.fullWidth .header {
-  background-color: var(--bgColor1);
-}
-
-.centered {
-  display: flex;
-  flex-direction: column;
-  flex: 1;
-  width: 100%;
-  max-width: 512px;
-  min-width: 0;
-}
-
-.content {
-  flex: 1;
-}
-
-.left .content {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-}
-
-.left .content form > * {
-  margin-top: 0;
-  margin-bottom: 24px;
-}
-
-.left .content form > :last-child {
-  margin-bottom: 0;
-}
-
-.left .content hr:after {
-  background-color: var(--bgColor1);
-  content: "OR";
-  padding: 0 12px;
-  position: relative;
-  top: -12px;
-}
-
-.left .content form {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  padding: 40px 92px;
-}
-
-.fieldRow {
-  width: 100%;
-}
-
-.button {
-  height: 40px;
-  width: 100%;
-  font-size: 15px;
-  font-weight: 600;
-}
-
-.left .content form:first-child {
-  padding-top: 0;
-}
-
-.left .content form:last-child {
-  padding-bottom: 40px;
-}
-
-.right .content {
-  padding: 0 40px 40px 40px;
-}
-
-.right .content h3:first-child {
-  margin-top: 0;
-}
-
-.authLinks {
-  display: flex;
-  flex-direction: column;
-  justify-content: flex-end;
-  align-items: center;
-}
-
-.authLinks {
-  margin-bottom: 100px;
-  font-size: 15px;
-}
-
-.authLinks a {
-  color: #0dbd8b;
-  font-weight: normal;
-  text-decoration: none;
-}
-
-@media (min-width: 800px) {
-  .left {
-    background-color: var(--bgColor2);
-  }
-
-  .home:not(.fullWidth) .left {
-    max-width: 50%;
-  }
-
-  .home:not(.fullWidth) .leftNav {
-    background-color: var(--bgColor2);
-  }
-
-  .splitContainer {
-    flex-direction: row;
-  }
-
-  .fullWidth .content hr:after,
-  .left .content hr:after,
-  .fullWidth .header {
-    background-color: var(--bgColor2);
-  }
-}
diff --git a/src/CallList.jsx b/src/home/CallList.jsx
similarity index 61%
rename from src/CallList.jsx
rename to src/home/CallList.jsx
index 63cd8e5..8d8fc01 100644
--- a/src/CallList.jsx
+++ b/src/home/CallList.jsx
@@ -1,16 +1,16 @@
-import React, { useMemo } from "react";
+import React from "react";
 import { Link } from "react-router-dom";
-import { CopyButton } from "./button";
-import { Facepile } from "./Facepile";
-import { Avatar } from "./Avatar";
-import { ReactComponent as VideoIcon } from "./icons/Video.svg";
+import { CopyButton } from "../button";
+import { Facepile } from "../Facepile";
+import { Avatar } from "../Avatar";
+import { ReactComponent as VideoIcon } from "../icons/Video.svg";
 import styles from "./CallList.module.css";
-import { getRoomUrl } from "./ConferenceCallManagerHooks";
+import { getRoomUrl } from "../ConferenceCallManagerHooks";
+import { Body, Caption } from "../typography/Typography";
 
-export function CallList({ title, rooms, client }) {
+export function CallList({ rooms, client }) {
   return (
     <>
-      <h3>{title}</h3>
       <div className={styles.callList}>
         {rooms.map(({ roomId, roomName, avatarUrl, participants }) => (
           <CallTile
@@ -32,17 +32,23 @@ function CallTile({ name, avatarUrl, roomId, participants, client }) {
     <div className={styles.callTile}>
       <Link to={`/room/${roomId}`} className={styles.callTileLink}>
         <Avatar
-          size="md"
+          size="lg"
           bgKey={name}
           src={avatarUrl}
           fallback={<VideoIcon width={16} height={16} />}
           className={styles.avatar}
         />
         <div className={styles.callInfo}>
-          <h5>{name}</h5>
-          <p>{getRoomUrl(roomId)}</p>
+          <Body overflowEllipsis fontWeight="semiBold">
+            {name}
+          </Body>
+          <Caption overflowEllipsis>{getRoomUrl(roomId)}</Caption>
           {participants && (
-            <Facepile client={client} participants={participants} />
+            <Facepile
+              className={styles.facePile}
+              client={client}
+              participants={participants}
+            />
           )}
         </div>
         <div className={styles.copyButtonSpacer} />
diff --git a/src/CallList.module.css b/src/home/CallList.module.css
similarity index 61%
rename from src/CallList.module.css
rename to src/home/CallList.module.css
index 1d2b62b..7c658a6 100644
--- a/src/CallList.module.css
+++ b/src/home/CallList.module.css
@@ -1,6 +1,6 @@
 .callTile {
-  min-width: 240px;
-  height: 94px;
+  width: 329px;
+  height: 95px;
   padding: 12px;
   background-color: var(--bgColor2);
   border-radius: 8px;
@@ -31,28 +31,11 @@
 }
 
 .callInfo > * {
-  margin-top: 0;
-  margin-bottom: 8px;
-}
-
-.callInfo > :last-child {
   margin-bottom: 0;
 }
 
-.callInfo h5 {
-  font-size: 15px;
-  font-weight: 600;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-}
-
-.callInfo p {
-  font-weight: 400;
-  font-size: 12px;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
+.facePile {
+  margin-top: 8px;
 }
 
 .copyButtonSpacer,
@@ -69,6 +52,11 @@
 
 .callList {
   display: grid;
-  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
+  grid-template-columns: repeat(auto-fill, 329px);
+  max-width: calc((329px + 24px) * 3);
+  width: calc(100% - 48px);
   gap: 24px;
+  padding: 0 24px;
+  justify-content: center;
+  margin-bottom: 24px;
 }
diff --git a/src/Home.jsx b/src/home/HomePage.jsx
similarity index 78%
rename from src/Home.jsx
rename to src/home/HomePage.jsx
index d26878f..0c5a811 100644
--- a/src/Home.jsx
+++ b/src/home/HomePage.jsx
@@ -15,12 +15,12 @@ limitations under the License.
 */
 
 import React from "react";
-import { useClient } from "./ConferenceCallManagerHooks";
-import { ErrorView, LoadingView } from "./FullScreenView";
-import { UnauthenticatedView } from "./home/UnauthenticatedView";
-import { RegisteredView } from "./home/RegisteredView";
+import { useClient } from "../ConferenceCallManagerHooks";
+import { ErrorView, LoadingView } from "../FullScreenView";
+import { UnauthenticatedView } from "./UnauthenticatedView";
+import { RegisteredView } from "./RegisteredView";
 
-export function Home() {
+export function HomePage() {
   const { isAuthenticated, isPasswordlessUser, loading, error, client } =
     useClient();
 
diff --git a/src/home/RegisteredView.jsx b/src/home/RegisteredView.jsx
index eabec9b..e17ef12 100644
--- a/src/home/RegisteredView.jsx
+++ b/src/home/RegisteredView.jsx
@@ -1,131 +1,117 @@
-import React from "react";
-import { Link } from "react-router-dom";
+import React, { useState, useCallback } from "react";
 import {
+  createRoom,
   useGroupCallRooms,
-  usePublicRooms,
+  roomAliasFromRoomName,
 } from "../ConferenceCallManagerHooks";
 import { Header, HeaderLogo, LeftNav, RightNav } from "../Header";
-import styles from "../Home.module.css";
+import commonStyles from "./common.module.css";
+import styles from "./RegisteredView.module.css";
 import { FieldRow, InputField, ErrorMessage } from "../Input";
 import { Button } from "../button";
-import { CallList } from "../CallList";
-import classNames from "classnames";
+import { CallList } from "./CallList";
 import { UserMenuContainer } from "../UserMenuContainer";
+import { useModalTriggerState } from "../Modal";
+import { JoinExistingCallModal } from "../JoinExistingCallModal";
+import { useHistory } from "react-router-dom";
+import { Headline, Title } from "../typography/Typography";
+import { Form } from "../form/Form";
 
-export function RegisteredView({
-  client,
-  isPasswordlessUser,
-  onCreateRoom,
-  createRoomError,
-  creatingRoom,
-  onJoinRoom,
-}) {
-  const publicRooms = usePublicRooms(
-    client,
-    import.meta.env.VITE_PUBLIC_SPACE_ROOM_ID
+export function RegisteredView({ client }) {
+  const [loading, setLoading] = useState(false);
+  const [error, setError] = useState();
+  const onSubmit = useCallback(
+    (e) => {
+      e.preventDefault();
+      const data = new FormData(e.target);
+      const roomName = data.get("roomName");
+
+      async function submit() {
+        setError(undefined);
+        setLoading(true);
+
+        const roomIdOrAlias = await createRoom(client, roomName);
+
+        if (roomIdOrAlias) {
+          history.push(`/room/${roomIdOrAlias}`);
+        }
+      }
+
+      submit().catch((error) => {
+        if (error.errcode === "M_ROOM_IN_USE") {
+          setExistingRoomId(roomAliasFromRoomName(roomName));
+          setError(undefined);
+          modalState.open();
+        } else {
+          console.error(error);
+          setLoading(false);
+          setError(error);
+          reset();
+        }
+      });
+    },
+    [client]
   );
+
   const recentRooms = useGroupCallRooms(client);
 
-  const hideCallList = publicRooms.length === 0 && recentRooms.length === 0;
+  const { modalState, modalProps } = useModalTriggerState();
+  const [existingRoomId, setExistingRoomId] = useState();
+  const history = useHistory();
+  const onJoinExistingRoom = useCallback(() => {
+    history.push(`/${existingRoomId}`);
+  }, [history, existingRoomId]);
 
   return (
-    <div
-      className={classNames(styles.home, {
-        [styles.fullWidth]: hideCallList,
-      })}
-    >
-      <Header className={styles.header}>
-        <LeftNav className={styles.leftNav}>
+    <>
+      <Header>
+        <LeftNav>
           <HeaderLogo />
         </LeftNav>
         <RightNav>
           <UserMenuContainer />
         </RightNav>
       </Header>
-      <div className={styles.splitContainer}>
-        <div className={styles.left}>
-          <div className={styles.content}>
-            <div className={styles.centered}>
-              <form onSubmit={onJoinRoom}>
-                <h1>Join a call</h1>
-                <FieldRow className={styles.fieldRow}>
-                  <InputField
-                    id="roomId"
-                    name="roomId"
-                    label="Call ID"
-                    type="text"
-                    required
-                    autoComplete="off"
-                    placeholder="Call ID"
-                  />
-                </FieldRow>
-                <FieldRow className={styles.fieldRow}>
-                  <Button className={styles.button} type="submit">
-                    Join call
-                  </Button>
-                </FieldRow>
-              </form>
-              <hr />
-              <form onSubmit={onCreateRoom}>
-                <h1>Create a call</h1>
-                <FieldRow className={styles.fieldRow}>
-                  <InputField
-                    id="roomName"
-                    name="roomName"
-                    label="Room Name"
-                    type="text"
-                    required
-                    autoComplete="off"
-                    placeholder="Room Name"
-                  />
-                </FieldRow>
-                {createRoomError && (
-                  <FieldRow className={styles.fieldRow}>
-                    <ErrorMessage>{createRoomError.message}</ErrorMessage>
-                  </FieldRow>
-                )}
-                <FieldRow className={styles.fieldRow}>
-                  <Button
-                    className={styles.button}
-                    type="submit"
-                    disabled={creatingRoom}
-                  >
-                    {creatingRoom ? "Creating call..." : "Create call"}
-                  </Button>
-                </FieldRow>
-              </form>
-              {isPasswordlessUser && (
-                <div className={styles.authLinks}>
-                  <p>
-                    Not registered yet?{" "}
-                    <Link to="/register">Create an account</Link>
-                  </p>
-                </div>
-              )}
-            </div>
-          </div>
-        </div>
-        {!hideCallList && (
-          <div className={styles.right}>
-            <div className={styles.content}>
-              {publicRooms.length > 0 && (
-                <CallList
-                  title="Public Calls"
-                  rooms={publicRooms}
-                  client={client}
-                />
-              )}
-              {recentRooms.length > 0 && (
-                <CallList
-                  title="Recent Calls"
-                  rooms={recentRooms}
-                  client={client}
-                />
-              )}
-            </div>
-          </div>
-        )}
+      <div className={commonStyles.container}>
+        <main className={commonStyles.main}>
+          <HeaderLogo className={commonStyles.logo} />
+          <Headline className={commonStyles.headline}>
+            Enter a call name
+          </Headline>
+          <Form className={styles.form} onSubmit={onSubmit}>
+            <FieldRow className={styles.fieldRow}>
+              <InputField
+                id="callName"
+                name="callName"
+                label="Call name"
+                placeholder="Call name"
+                type="text"
+                required
+                autoComplete="off"
+              />
+              <Button type="submit" size="lg" disabled={loading}>
+                {loading ? "Loading..." : "Go"}
+              </Button>
+            </FieldRow>
+            {error && (
+              <FieldRow>
+                <ErrorMessage>{error.message}</ErrorMessage>
+              </FieldRow>
+            )}
+          </Form>
+          {recentRooms.length > 0 && (
+            <>
+              <Title className={styles.recentCallsTitle}>
+                Your recent Calls
+              </Title>
+              <CallList rooms={recentRooms} client={client} />
+            </>
+          )}
+        </main>
       </div>
-    </div>
+      {modalState.isOpen && (
+        <JoinExistingCallModal onJoin={onJoinExistingRoom} {...modalProps} />
+      )}
+    </>
   );
 }
diff --git a/src/home/RegisteredView.module.css b/src/home/RegisteredView.module.css
new file mode 100644
index 0000000..03eff0a
--- /dev/null
+++ b/src/home/RegisteredView.module.css
@@ -0,0 +1,14 @@
+.form {
+  padding: 0 24px;
+  justify-content: center;
+  width: 409px;
+  margin-bottom: 72px;
+}
+
+.fieldRow {
+  margin-bottom: 0;
+}
+
+.recentCallsTitle {
+  margin-bottom: 32px;
+}
diff --git a/src/home/UnauthenticatedView.jsx b/src/home/UnauthenticatedView.jsx
index 8c0b684..c779817 100644
--- a/src/home/UnauthenticatedView.jsx
+++ b/src/home/UnauthenticatedView.jsx
@@ -8,13 +8,15 @@ import { randomString } from "matrix-js-sdk/src/randomstring";
 import {
   createRoom,
   useInteractiveRegistration,
+  roomAliasFromRoomName,
 } from "../ConferenceCallManagerHooks";
 import { useModalTriggerState } from "../Modal";
 import { JoinExistingCallModal } from "../JoinExistingCallModal";
 import { useRecaptcha } from "../useRecaptcha";
-import { Body, Caption, Title, Link, Headline } from "../typography/Typography";
+import { Body, Caption, Link, Headline } from "../typography/Typography";
 import { Form } from "../form/Form";
 import styles from "./UnauthenticatedView.module.css";
+import commonStyles from "./common.module.css";
 
 export function UnauthenticatedView() {
   const [loading, setLoading] = useState(false);
@@ -80,10 +82,12 @@ export function UnauthenticatedView() {
           <UserMenuContainer />
         </RightNav>
       </Header>
-      <div className={styles.container}>
-        <main className={styles.main}>
-          <HeaderLogo className={styles.logo} />
-          <Headline className={styles.headline}>Enter a call name</Headline>
+      <div className={commonStyles.container}>
+        <main className={commonStyles.main}>
+          <HeaderLogo className={commonStyles.logo} />
+          <Headline className={commonStyles.headline}>
+            Enter a call name
+          </Headline>
           <Form className={styles.form} onSubmit={onSubmit}>
             <FieldRow>
               <InputField
diff --git a/src/home/UnauthenticatedView.module.css b/src/home/UnauthenticatedView.module.css
index 254ddb6..f336ef1 100644
--- a/src/home/UnauthenticatedView.module.css
+++ b/src/home/UnauthenticatedView.module.css
@@ -1,18 +1,3 @@
-.container {
-  display: flex;
-  min-height: calc(100% - 64px);
-  flex-direction: column;
-  justify-content: space-between;
-}
-
-.main {
-  display: flex;
-  flex: 1;
-  flex-direction: column;
-  align-items: center;
-  justify-content: center;
-}
-
 .footer {
   display: flex;
   flex-direction: column;
@@ -29,15 +14,6 @@
   margin-bottom: 24px;
 }
 
-.logo {
-  display: flex;
-  margin-bottom: 54px;
-}
-
-.headline {
-  margin-bottom: 40px;
-}
-
 .form {
   padding: 0 24px;
   justify-content: center;
@@ -49,15 +25,7 @@
 }
 
 @media (min-width: 800px) {
-  .logo {
-    display: none;
-  }
-
   .mobileLoginLink {
     display: none;
   }
-
-  .container {
-    min-height: calc(100% - 76px);
-  }
 }
diff --git a/src/home/common.module.css b/src/home/common.module.css
new file mode 100644
index 0000000..13eac14
--- /dev/null
+++ b/src/home/common.module.css
@@ -0,0 +1,33 @@
+.container {
+  display: flex;
+  min-height: calc(100% - 64px);
+  flex-direction: column;
+  justify-content: space-between;
+}
+
+.main {
+  display: flex;
+  flex: 1;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+}
+
+.logo {
+  display: flex;
+  margin-bottom: 54px;
+}
+
+.headline {
+  margin-bottom: 40px;
+}
+
+@media (min-width: 800px) {
+  .logo {
+    display: none;
+  }
+
+  .container {
+    min-height: calc(100% - 76px);
+  }
+}
diff --git a/src/icons/Copy.svg b/src/icons/Copy.svg
index 5f977f0..e539711 100644
--- a/src/icons/Copy.svg
+++ b/src/icons/Copy.svg
@@ -1,3 +1,3 @@
-<svg width="21" height="24" viewBox="0 0 21 24" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path fill-rule="evenodd" clip-rule="evenodd" d="M6.03125 3C4.3744 3 3.03125 4.34315 3.03125 6V13C3.03125 14.6569 4.3744 16 6.03125 16H7.07407V18C7.07407 19.6569 8.41722 21 10.0741 21H14.9683C16.6251 21 17.9683 19.6569 17.9683 18V11C17.9683 9.34315 16.6251 8 14.9683 8H13.9255V6C13.9255 4.34315 12.5823 3 10.9255 3H6.03125ZM11.9255 8V6C11.9255 5.44772 11.4777 5 10.9255 5H6.03125C5.47897 5 5.03125 5.44772 5.03125 6V13C5.03125 13.5523 5.47897 14 6.03125 14H7.07407V11C7.07407 9.34315 8.41722 8 10.0741 8H11.9255ZM9.07407 11C9.07407 10.4477 9.52179 10 10.0741 10H14.9683C15.5206 10 15.9683 10.4477 15.9683 11V18C15.9683 18.5523 15.5206 19 14.9683 19H10.0741C9.52179 19 9.07407 18.5523 9.07407 18V11Z" fill="#0DBD8B"/>
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M4 2C2.89543 2 2 2.89543 2 4V8.66667C2 9.77124 2.89543 10.6667 4 10.6667H5.33333V12C5.33333 13.1046 6.22877 14 7.33333 14H12C13.1046 14 14 13.1046 14 12V7.33333C14 6.22876 13.1046 5.33333 12 5.33333H10.6667V4C10.6667 2.89543 9.77123 2 8.66667 2H4ZM9.33333 5.33333V4C9.33333 3.63181 9.03486 3.33333 8.66667 3.33333H4C3.63181 3.33333 3.33333 3.63181 3.33333 4V8.66667C3.33333 9.03486 3.63181 9.33333 4 9.33333H5.33333V7.33333C5.33333 6.22877 6.22876 5.33333 7.33333 5.33333H9.33333ZM6.66667 7.33333C6.66667 6.96514 6.96514 6.66667 7.33333 6.66667H12C12.3682 6.66667 12.6667 6.96514 12.6667 7.33333V12C12.6667 12.3682 12.3682 12.6667 12 12.6667H7.33333C6.96514 12.6667 6.66667 12.3682 6.66667 12V7.33333Z" fill="#8E99A4"/>
 </svg>
diff --git a/src/typography/Typography.jsx b/src/typography/Typography.jsx
index 9193a48..a1f6ec2 100644
--- a/src/typography/Typography.jsx
+++ b/src/typography/Typography.jsx
@@ -4,11 +4,25 @@ import { Link as RouterLink } from "react-router-dom";
 import styles from "./Typography.module.css";
 
 export const Headline = forwardRef(
-  ({ as: Component = "h1", children, className, fontWeight, ...rest }, ref) => {
+  (
+    {
+      as: Component = "h1",
+      children,
+      className,
+      fontWeight,
+      overflowEllipsis,
+      ...rest
+    },
+    ref
+  ) => {
     return (
       <Component
         {...rest}
-        className={classNames(styles[fontWeight], className)}
+        className={classNames(
+          styles[fontWeight],
+          { [styles.overflowEllipsis]: overflowEllipsis },
+          className
+        )}
         ref={ref}
       >
         {children}
@@ -18,11 +32,25 @@ export const Headline = forwardRef(
 );
 
 export const Title = forwardRef(
-  ({ as: Component = "h2", children, className, fontWeight, ...rest }, ref) => {
+  (
+    {
+      as: Component = "h2",
+      children,
+      className,
+      fontWeight,
+      overflowEllipsis,
+      ...rest
+    },
+    ref
+  ) => {
     return (
       <Component
         {...rest}
-        className={classNames(styles[fontWeight], className)}
+        className={classNames(
+          styles[fontWeight],
+          { [styles.overflowEllipsis]: overflowEllipsis },
+          className
+        )}
         ref={ref}
       >
         {children}
@@ -32,11 +60,25 @@ export const Title = forwardRef(
 );
 
 export const Subtitle = forwardRef(
-  ({ as: Component = "h3", children, className, fontWeight, ...rest }, ref) => {
+  (
+    {
+      as: Component = "h3",
+      children,
+      className,
+      fontWeight,
+      overflowEllipsis,
+      ...rest
+    },
+    ref
+  ) => {
     return (
       <Component
         {...rest}
-        className={classNames(styles[fontWeight], className)}
+        className={classNames(
+          styles[fontWeight],
+          { [styles.overflowEllipsis]: overflowEllipsis },
+          className
+        )}
         ref={ref}
       >
         {children}
@@ -46,11 +88,25 @@ export const Subtitle = forwardRef(
 );
 
 export const Body = forwardRef(
-  ({ as: Component = "p", children, className, fontWeight, ...rest }, ref) => {
+  (
+    {
+      as: Component = "p",
+      children,
+      className,
+      fontWeight,
+      overflowEllipsis,
+      ...rest
+    },
+    ref
+  ) => {
     return (
       <Component
         {...rest}
-        className={classNames(styles[fontWeight], className)}
+        className={classNames(
+          styles[fontWeight],
+          { [styles.overflowEllipsis]: overflowEllipsis },
+          className
+        )}
         ref={ref}
       >
         {children}
@@ -60,11 +116,26 @@ export const Body = forwardRef(
 );
 
 export const Caption = forwardRef(
-  ({ as: Component = "p", children, className, fontWeight, ...rest }, ref) => {
+  (
+    {
+      as: Component = "p",
+      children,
+      className,
+      fontWeight,
+      overflowEllipsis,
+      ...rest
+    },
+    ref
+  ) => {
     return (
       <Component
         {...rest}
-        className={classNames(styles.caption, styles[fontWeight], className)}
+        className={classNames(
+          styles.caption,
+          styles[fontWeight],
+          { [styles.overflowEllipsis]: overflowEllipsis },
+          className
+        )}
         ref={ref}
       >
         {children}
@@ -74,11 +145,26 @@ export const Caption = forwardRef(
 );
 
 export const Micro = forwardRef(
-  ({ as: Component = "p", children, className, fontWeight, ...rest }, ref) => {
+  (
+    {
+      as: Component = "p",
+      children,
+      className,
+      fontWeight,
+      overflowEllipsis,
+      ...rest
+    },
+    ref
+  ) => {
     return (
       <Component
         {...rest}
-        className={classNames(styles.micro, styles[fontWeight], className)}
+        className={classNames(
+          styles.micro,
+          styles[fontWeight],
+          { [styles.overflowEllipsis]: overflowEllipsis },
+          className
+        )}
         ref={ref}
       >
         {children}
@@ -96,6 +182,7 @@ export const Link = forwardRef(
       color = "link",
       href,
       fontWeight,
+      overflowEllipsis,
       ...rest
     },
     ref
@@ -113,7 +200,12 @@ export const Link = forwardRef(
       <Component
         {...externalLinkProps}
         {...rest}
-        className={classNames(styles[color], styles[fontWeight], className)}
+        className={classNames(
+          styles[color],
+          styles[fontWeight],
+          { [styles.overflowEllipsis]: overflowEllipsis },
+          className
+        )}
         ref={ref}
       >
         {children}
diff --git a/src/typography/Typography.module.css b/src/typography/Typography.module.css
index ca6e354..0719fbf 100644
--- a/src/typography/Typography.module.css
+++ b/src/typography/Typography.module.css
@@ -27,3 +27,9 @@
 .primary {
   color: var(--primaryColor);
 }
+
+.overflowEllipsis {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}