diff --git a/src/App.css b/src/App.css
index f20a3b6..a3af7c6 100644
--- a/src/App.css
+++ b/src/App.css
@@ -257,15 +257,15 @@
     --alpha-shadow-color-scroll-shaded-div: 0.3;
 
     --color-very-good: 21, 87, 37;
-        --color-very-good-background: 0, 255, 0, 0.2;
-        --color-good: 66, 77, 30;
-        --color-good-background: 201, 255, 0, 0.2;
-        --color-average: 89, 89, 25;
-        --color-average-background: 255, 217, 0, 0.2;
-        --color-bad: 104, 80, 35;
-        --color-bad-background: 255, 165, 0, 0.2;
-        --color-very-bad: 117, 45, 45;
-        --color-very-bad-background: 153, 1, 1, 0.2;
+    --color-very-good-background: 0, 255, 0, 0.2;
+    --color-good: 66, 77, 30;
+    --color-good-background: 201, 255, 0, 0.2;
+    --color-average: 89, 89, 25;
+    --color-average-background: 255, 217, 0, 0.2;
+    --color-bad: 104, 80, 35;
+    --color-bad-background: 255, 165, 0, 0.2;
+    --color-very-bad: 117, 45, 45;
+    --color-very-bad-background: 153, 1, 1, 0.2;
 }
 
 :root.balanced *,
diff --git a/src/App.jsx b/src/App.jsx
index 9b614b0..9d84a35 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -874,9 +874,6 @@ export default function App() {
                 newGrade.subjectName = grade.libelleMatiere;
                 newGrade.isSignificant = !grade.nonSignificatif;
                 newGrade.examSubjectSRC = grade.uncSujet;
-                if (grade.id == 6291688) {
-                    console.log(grade)
-                }
                 newGrade.examSubjectSRC = grade.uncSujet === "" ? undefined : new File(grade.uncSujet, "NODEVOIR", grade.uncSujet, `sujet-${grade.devoir}-${grade.subjectCode}`, { idDevoir: grade.id });
                 newGrade.examCorrectionSRC = grade.uncCorrige === "" ? undefined : new File(grade.uncCorrige, "NODEVOIR", grade.uncCorrige, `correction-${grade.devoir}-${grade.subjectCode}`, { idDevoir: grade.id });
                 newGrade.isReal = true;
@@ -1141,7 +1138,7 @@ export default function App() {
 
 
     function sortMessages(messages) {
-        const sortedMessages = messages.messages.received.map((message) => { console.log("files:", message.files); return {
+        const sortedMessages = messages.messages.received.map((message) => { return {
             date: message.date,
             files: structuredClone(message.files)?.map((file) => new File(file.id, file.type, file.libelle)),
             from: message.from,
@@ -1316,7 +1313,6 @@ export default function App() {
                 })
             })
             .then((response) => {
-                console.log(".then ~ response:", response)
                 // GESTION DATA
                 let statusCode = response.code;
                 if (statusCode === 200) {
@@ -1696,7 +1692,6 @@ export default function App() {
         )
             .then((response) => response.json())
             .then((response) => {
-                console.log(".then ~ response:", response)
                 let code;
                 if (accountsListState[activeAccount].firstName === "Guest") {
                     code = 49969;
@@ -1723,7 +1718,7 @@ export default function App() {
 
     async function fetchMessageContent(id, controller) {
         const oldSortedMessages = useUserData("sortedMessages").get();
-        if (oldSortedMessages) {
+        if (oldSortedMessages && oldSortedMessages?.length > 0) {
             const targetMessageIdx = oldSortedMessages.findIndex((item) => item.id === id);
             if (oldSortedMessages[targetMessageIdx].content !== null) {
                 return;
diff --git a/src/components/app/Messaging/Inbox.css b/src/components/app/Messaging/Inbox.css
index b5d3328..e8e4337 100644
--- a/src/components/app/Messaging/Inbox.css
+++ b/src/components/app/Messaging/Inbox.css
@@ -43,9 +43,24 @@
     padding: 10px;    
     border-left: 4px solid rgb(var(--text-color-alt), .5);
     border-bottom: 1px solid rgb(var(--text-color-alt), .5);
-    opacity: .6;
+    opacity: 0;
+    --opacity: .6;
     outline: none;
     cursor: pointer;
+    animation: jump-in 0.5s var(--timing-function-spring-effect) forwards;
+    animation-delay: calc(var(--order) * 60ms);
+}
+
+@keyframes jump-in {
+    from {
+        opacity: 0;
+        transform: translateY(-20px);
+    }
+    
+    to {
+        opacity: var(--opacity);
+        transform: translateY(0);
+    }
 }
 
 #inbox .message-container:last-child {
@@ -55,14 +70,14 @@
 #inbox .message-container[data-read=false] {
     border-left: 4px solid rgb(var(--text-color-alt));
     padding-left: 6px;
-    opacity: 1;
+    --opacity: 1;
 }
 
 #inbox .message-container:is(:hover, :focus-visible) {
     background-color: rgba(var(--background-color-0), .2);
 }
 #inbox .message-container.selected {
-    opacity: .8;
+    --opacity: .8;
     background-color: rgba(var(--background-color-focus));
 }
 
@@ -128,3 +143,14 @@
 :fullscreen #inbox .message-container:last-child {
     border-bottom: none;
 }
+
+
+#inbox .no-message-received {
+    color: rgb(var(--text-color-alt));
+    display: flex;
+    height: 100%;
+    padding: 75px 20px;
+    align-items: center;
+    justify-content: center;
+    text-align: center;
+}
diff --git a/src/components/app/Messaging/Inbox.jsx b/src/components/app/Messaging/Inbox.jsx
index f064bd7..342676b 100644
--- a/src/components/app/Messaging/Inbox.jsx
+++ b/src/components/app/Messaging/Inbox.jsx
@@ -1,5 +1,5 @@
-import { useState, useEffect, useContext } from "react";
-
+import { useState, useEffect, useRef, useContext } from "react";
+import ContentLoader from "react-content-loader";
 import { AppContext } from "../../../App";
 
 import "./Inbox.css";
@@ -12,31 +12,34 @@ import MarkAsUnread from "../../graphics/MarkAsUnread";
 
 export default function Inbox({ selectedMessage, setSelectedMessage, fetchMessageMarkAsUnread }) {
     // States
-    const { useUserData } = useContext(AppContext);
+    const { useUserData, actualDisplayTheme, useUserSettings } = useContext(AppContext);
+    const settings = useUserSettings();
     const [search, setSearch] = useState("");
     const messages = useUserData("sortedMessages");
 
+    const contentLoadersRandomValues = useRef({ authorWidth: Array.from({ length: 13 }, (_) => Math.round(Math.random() * 100) + 100), subjectWidth: Array.from({ length: 13 }, (_) => Math.floor(Math.random() * 150) + 150), dateWidth: Array.from({ length: 13 }, (_) => Math.floor(Math.random() * 50) + 50), containsFiles: Array.from({ length: 13 }, (_) => (Math.random() > .6)) })
+
     // behavior
     const handleClick = (message) => {
         setSelectedMessage(message.id);
     }
-    
+
     const handleKeyDown = (event, msg) => {
         if (event.key === "Enter" || event.key === " ") {
             handleClick(msg);
         }
     }
-    
+
     const handleMarkAsUnread = (event, msg) => {
         event.preventDefault();
         event.stopPropagation();
         const controller = new AbortController();
         fetchMessageMarkAsUnread([msg.id], controller);
-        
+
         if (msg.id === selectedMessage) {
             setSelectedMessage(null);
         }
-        
+
         // mark as unread locally and kick the content so as to trigger a refetch the next reading (as the "mark as read" feature is trigger when fetching the message)
         const oldMsg = messages.get();
         const msgIdx = oldMsg.findIndex((item) => item.id === msg.id);
@@ -54,7 +57,7 @@ export default function Inbox({ selectedMessage, setSelectedMessage, fetchMessag
         let regexp;
         try {
             regexp = new RegExp(removeAccents(search.toLowerCase()));
-        } catch {return -1}
+        } catch { return -1 }
         const filterBy = [message.subject, message.from.name, message.content?.content, message.files?.map((file) => file.name)].flat();
         for (let filter of filterBy) {
             if (filter) {
@@ -75,8 +78,8 @@ export default function Inbox({ selectedMessage, setSelectedMessage, fetchMessag
                 ? (messages.get().length > 0
                     ? <ScrollShadedDiv className="messages-container">
                         <ul>
-                            {messages.get().filter(filterResearch).map((message) => <li className={"message-container" + (selectedMessage === message.id ? " selected" : "")} data-read={message.read} onClick={() => handleClick(message)} onKeyDown={(event) => handleKeyDown(event, message)} key={message.id} role="button" tabIndex={0}>
-                                <h4 className="message-subject"><span className="author-name">{message.from.name}</span> <span className="actions"><button disabled={!message.read} onClick={(event) => handleMarkAsUnread(event, message)} className="mark-as-unread" title="Marquer comme non lu"><MarkAsUnread className="mark-as-unread-icon"/></button> {message.files?.length > 0 && <AttachmentIcon className="attachment-icon" />}</span></h4>
+                            {messages.get().filter(filterResearch).map((message, index) => <li style={{ "--order": index }} className={"message-container" + (selectedMessage === message.id ? " selected" : "")} data-read={message.read} onClick={() => handleClick(message)} onKeyDown={(event) => handleKeyDown(event, message)} key={message.id} role="button" tabIndex={0}>
+                                <h4 className="message-subject"><span className="author-name">{message.from.name}</span> <span className="actions"><button disabled={!message.read} onClick={(event) => handleMarkAsUnread(event, message)} className="mark-as-unread" title="Marquer comme non lu"><MarkAsUnread className="mark-as-unread-icon" /></button> {message.files?.length > 0 && <AttachmentIcon className="attachment-icon" />}</span></h4>
                                 <p className="message-author">{message.subject}</p>
                                 <p className="message-date">{(new Date(message.date)).toLocaleDateString("fr-FR", {
                                     month: "long",
@@ -87,9 +90,41 @@ export default function Inbox({ selectedMessage, setSelectedMessage, fetchMessag
                             </li>)}
                         </ul>
                     </ScrollShadedDiv>
-                    : <p>Vous n'avez reçu aucun message. Profitez bien de votre isolement social ^^</p>
+                    : <p className="no-message-received">Vous n'avez reçu aucun message. Profitez bien de votre isolement social ^^</p>
                 )
-                : <p>content-loader</p>
+                : <ScrollShadedDiv className="messages-container">
+                    <ul>
+                        {Array.from({ length: 13 }, (_, index) => <li key={index} style={{ "--order": -69 /* skip the animation */ }} className={"message-container"}>
+                            <h4 className="message-subject"><span className="author-name"><ContentLoader
+                                animate={settings.get("displayMode") === "quality"}
+                                speed={1}
+                                backgroundColor={actualDisplayTheme === "dark" ? "#7878ae" : "#75759a"}
+                                foregroundColor={actualDisplayTheme === "dark" ? "#9292d4" : "#9292c0"}
+                                style={{ width: `min(${contentLoadersRandomValues.current.authorWidth[index]}px, 100%)`, maxHeight: "20px" }}
+                            >
+                                <rect x="0" y="0" rx="5" ry="5" width="100%" height="100%" />
+                            </ContentLoader></span><span className="actions">{contentLoadersRandomValues.current.containsFiles[index] && <AttachmentIcon className="attachment-icon" />}</span></h4>
+                            <p className="message-author"><ContentLoader
+                                animate={settings.get("displayMode") === "quality"}
+                                speed={1}
+                                backgroundColor={actualDisplayTheme === "dark" ? "#63638c" : "#9d9dbd"}
+                                foregroundColor={actualDisplayTheme === "dark" ? "#7e7eb2" : "#bcbce3"}
+                                style={{ width: `min(${contentLoadersRandomValues.current.subjectWidth[index]}px, 60%)`, maxHeight: "16px" }}
+                            >
+                                <rect x="0" y="0" rx="5" ry="5" width="100%" height="100%" />
+                            </ContentLoader></p>
+                            <p className="message-date"><ContentLoader
+                                animate={settings.get("displayMode") === "quality"}
+                                speed={1}
+                                backgroundColor={actualDisplayTheme === "dark" ? "#63638c" : "#9d9dbd"}
+                                foregroundColor={actualDisplayTheme === "dark" ? "#7e7eb2" : "#bcbce3"}
+                                style={{ width: `min(${contentLoadersRandomValues.current.dateWidth[index]}px, 30%)`, maxHeight: "16px" }}
+                            >
+                                <rect x="0" y="0" rx="5" ry="5" width="100%" height="100%" />
+                            </ContentLoader></p>
+                        </li>)}
+                    </ul>
+                </ScrollShadedDiv>
             }
         </div>
     )
diff --git a/src/components/app/Messaging/MessageReader.css b/src/components/app/Messaging/MessageReader.css
index aa5cdab..1ebf66f 100644
--- a/src/components/app/Messaging/MessageReader.css
+++ b/src/components/app/Messaging/MessageReader.css
@@ -101,3 +101,14 @@
 #message-reader .attachments-container .attachment .download-icon {
     height: 20px;
 }
+
+#message-reader .no-selected-message-placeholder {
+    color: rgb(var(--text-color-alt));
+    width: 100%;
+    padding: 75px 20px;
+    position: relative;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+    text-align: center;
+}
diff --git a/src/components/app/Messaging/MessageReader.jsx b/src/components/app/Messaging/MessageReader.jsx
index 5da9e06..764f945 100644
--- a/src/components/app/Messaging/MessageReader.jsx
+++ b/src/components/app/Messaging/MessageReader.jsx
@@ -1,5 +1,5 @@
 import { useState, useEffect, useContext } from "react";
-
+import ContentLoader from "react-content-loader";
 import { AppContext } from "../../../App";
 
 import "./MessageReader.css";
@@ -12,7 +12,8 @@ import DownloadIcon from "../../graphics/DownloadIcon";
 
 export default function MessageReader({ selectedMessage }) {
     // States
-    const { useUserData, actualDisplayTheme } = useContext(AppContext);
+    const { useUserData, actualDisplayTheme, useUserSettings } = useContext(AppContext);
+    const settings = useUserSettings();
     const messages = useUserData("sortedMessages").get();
     const message = messages ? messages.find((item) => item.id === selectedMessage) : null;
 
@@ -21,8 +22,7 @@ export default function MessageReader({ selectedMessage }) {
     // JSX
     return (
         <div id="message-reader">
-            {selectedMessage !== null
-                ? message?.content
+            {selectedMessage !== null && messages && messages.length > 0
                     ? <div className="message-container">
                         <div className="email-header">
                             <p className="author">{message && message?.from?.name}</p>
@@ -35,9 +35,37 @@ export default function MessageReader({ selectedMessage }) {
                             }))}</p>
                         </div>
                         <hr />
-                        <ScrollShadedDiv className="message-content-container" key={selectedMessage}>
+                        <ScrollShadedDiv className="message-content-container" key={message?.content ? selectedMessage + "-content" /* trigger a rerender so that the ScrollShadedDiv detect overflow and display shadows */ : selectedMessage}>
+                            {message?.content
+                                ? <EncodedHTMLDiv className="message-content" backgroundColor={actualDisplayTheme === "dark" ? "#303047" : "#d6d6f8"}>{message?.content && message?.content?.content}</EncodedHTMLDiv>
+                                : <ContentLoader
+                                    className="message-content"
+                                    animate={settings.get("displayMode") === "quality"}
+                                    speed={1}
+                                    backgroundColor={actualDisplayTheme === "dark" ? "#63638c" : "#9d9dbd"}
+                                    foregroundColor={actualDisplayTheme === "dark" ? "#7e7eb2" : "#bcbce3"}
+                                    style={{ display: "block", width: "min(800px, 100%)", margin: "0 auto", height: "575px" }}
+                                >
+                                    <rect x="0" y="0" rx="8" ry="8" width="30%" height="20px" />
+
+                                    <rect x="0" y="60" rx="8" ry="8" width="100%" height="20px" />
+                                    <rect x="0" y="90" rx="8" ry="8" width="70%" height="20px" />
+
+                                    <rect x="0" y="150" rx="8" ry="8" width="100%" height="20px" />
+                                    <rect x="0" y="180" rx="8" ry="8" width="100%" height="20px" />
+                                    <rect x="0" y="210" rx="8" ry="8" width="100%" height="20px" />
+                                    <rect x="0" y="240" rx="8" ry="8" width="50%" height="20px" />
+
+                                    <rect x="0" y="300" rx="8" ry="8" width="100%" height="20px" />
+                                    <rect x="0" y="330" rx="8" ry="8" width="40%" height="20px" />
+
+                                    <rect x="0" y="390" rx="8" ry="8" width="40%" height="20px" />
+                                    <rect x="0" y="420" rx="8" ry="8" width="60%" height="20px" />
+                                    <rect x="0" y="450" rx="8" ry="8" width="30%" height="20px" />
 
-                            <EncodedHTMLDiv className="message-content" backgroundColor={actualDisplayTheme === "dark" ? "#303047" : "#d6d6f8"}>{message?.content && message?.content?.content}</EncodedHTMLDiv>
+                                    <rect x="0" y="510" rx="8" ry="8" width="20%" height="20px" />
+                                </ContentLoader>
+                            }
                         </ScrollShadedDiv>
                         {message && (message?.files?.length > 0
                             ? <>
@@ -51,8 +79,7 @@ export default function MessageReader({ selectedMessage }) {
                             : null)}
 
                     </div>
-                    : <p>content-loader</p>
-                : <p>Sélectionnez un message dans votre boîte de réception pour le visualiser ici !</p>
+                : <p className="no-selected-message-placeholder">Sélectionnez un message dans votre boîte de réception pour le visualiser ici</p>
             }
         </div>
     )
diff --git a/src/components/app/Messaging/Messaging.jsx b/src/components/app/Messaging/Messaging.jsx
index 452ac20..aceeabe 100644
--- a/src/components/app/Messaging/Messaging.jsx
+++ b/src/components/app/Messaging/Messaging.jsx
@@ -38,7 +38,6 @@ export default function Messaging({ isLoggedIn, activeAccount, fetchMessages, fe
         if (isLoggedIn) {
             if (messages.get() === undefined) {
                 fetchMessages(controller);
-                setSelectedMessage(null);
             }
         }
 
@@ -48,6 +47,9 @@ export default function Messaging({ isLoggedIn, activeAccount, fetchMessages, fe
     }, [isLoggedIn, activeAccount, messages.get()]);
 
     useEffect(() => {
+        if (messages.get() === undefined) {
+            return;
+        }
         const controller = new AbortController();
         if (selectedMessage !== null) {
             fetchMessageContent(selectedMessage, controller);
@@ -65,7 +67,7 @@ export default function Messaging({ isLoggedIn, activeAccount, fetchMessages, fe
         return () => {
             controller.abort();
         }
-    }, [location, selectedMessage]);
+    }, [location, selectedMessage, messages.get()]);
 
     useEffect(() => {
         if (oldSelectedMessage.current !== selectedMessage) {
diff --git a/src/components/graphics/Arrow.jsx b/src/components/graphics/Arrow.jsx
index 39e4848..4fecfab 100644
--- a/src/components/graphics/Arrow.jsx
+++ b/src/components/graphics/Arrow.jsx
@@ -2,6 +2,6 @@
 import "./graphics.css"
 export default function Arrow({ className = "", id = "", alt, ...props }) {
     return (
-        <svg aria-label={alt} className={className} id={id} height="20px" width="20px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-62.7 -62.7 455.40 455.40" xml:space="preserve" strokeWidth="33"><g id="SVGRepo_bgCarrier" strokeWidth="0"></g><g id="SVGRepo_tracerCarrier" strokeLinecap="round" strokeLinejoin="round"></g><g id="SVGRepo_iconCarrier"> <path id="XMLID_337_" d="M253.858,234.26c-2.322-5.605-7.792-9.26-13.858-9.26h-60V15c0-8.284-6.716-15-15-15 c-8.284,0-15,6.716-15,15v210H90c-6.067,0-11.537,3.655-13.858,9.26c-2.321,5.605-1.038,12.057,3.252,16.347l75,75 C157.322,328.536,161.161,330,165,330s7.678-1.464,10.607-4.394l75-75C254.896,246.316,256.18,239.865,253.858,234.26z M165,293.787 L126.213,255h77.573L165,293.787z"></path> </g></svg>
+        <svg aria-label={alt} className={className} id={id} height="20px" width="20px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" viewBox="-62.7 -62.7 455.40 455.40" xmlSpace="preserve" strokeWidth="33"><g id="SVGRepo_bgCarrier" strokeWidth="0"></g><g id="SVGRepo_tracerCarrier" strokeLinecap="round" strokeLinejoin="round"></g><g id="SVGRepo_iconCarrier"> <path id="XMLID_337_" d="M253.858,234.26c-2.322-5.605-7.792-9.26-13.858-9.26h-60V15c0-8.284-6.716-15-15-15 c-8.284,0-15,6.716-15,15v210H90c-6.067,0-11.537,3.655-13.858,9.26c-2.321,5.605-1.038,12.057,3.252,16.347l75,75 C157.322,328.536,161.161,330,165,330s7.678-1.464,10.607-4.394l75-75C254.896,246.316,256.18,239.865,253.858,234.26z M165,293.787 L126.213,255h77.573L165,293.787z"></path> </g></svg>
     )
 }
\ No newline at end of file