diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d5e97b0e1c375dc0700baacc3bc5f9a84fca0374..29f69dff137571064de8173e9fc0bafabef2764d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -27,7 +27,6 @@ stages:
     BASE_URL: /wiki/
     MEILI_HOST: "http://localhost:7700"
     MEILI_API_KEY: MASTER_KEY
-    CI_DEBUG_TRACE: "true"
   before_script:
     - i=0; while [ "$i" -lt 12 ]; do docker info && break; sleep 5; i=$(( i + 1 )) ; done
     - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
diff --git a/components/Nav/Navbar.vue b/components/Nav/Navbar.vue
index cf7f51d22f26b73235369c51d1179faafe54b310..f580e4c8b290b5f5cb7b42c13076cc062341253c 100644
--- a/components/Nav/Navbar.vue
+++ b/components/Nav/Navbar.vue
@@ -13,8 +13,6 @@ function toggleTheme() {
   theme.global.name.value = theme.global.current.value.dark ? "light" : "dark";
 }
 
-
-
 const sections = ref([
   {
     id: "webservice",
@@ -27,20 +25,6 @@ const sections = ref([
 ]);
 
 
-// const computedSections = computed(() => {
-//   return sections.value.map(section => {
-
-//     if (section?.to) {
-//       const { refinedUrl } = useRefinedUrl(section.to)
-//       return { ...section, to: refinedUrl.value }
-//     }
-//     else {
-//       return section
-//     }
-
-
-//   })
-// })
 
 
 const drawer = ref(true);
diff --git a/components/content/Alert/Danger.vue b/components/content/Alert/Danger.vue
new file mode 100644
index 0000000000000000000000000000000000000000..f66b8e8e6aa59c393fc10bde3c55000fcffca21a
--- /dev/null
+++ b/components/content/Alert/Danger.vue
@@ -0,0 +1,15 @@
+<script setup lang="ts">
+export interface Props {
+    title?: string
+}
+
+const { title } = withDefaults(defineProps<Props>(), {
+    title: 'Danger'
+});
+</script>
+
+<template>
+    <v-alert type="error" border="start" variant="tonal" class="my-2" prominent :title="title">
+        <slot></slot>
+    </v-alert>
+</template>
diff --git a/components/content/Alert/ExpansionDetails.vue b/components/content/Alert/ExpansionDetails.vue
new file mode 100644
index 0000000000000000000000000000000000000000..62823929718b0ffbd8a08ad8f419db08e79b4aea
--- /dev/null
+++ b/components/content/Alert/ExpansionDetails.vue
@@ -0,0 +1,29 @@
+<script setup lang="ts">
+export interface Props {
+    title?: string
+}
+
+const { title } = withDefaults(defineProps<Props>(), {
+    title: 'Details'
+});
+
+
+import { useTheme } from "vuetify";
+const theme = useTheme();
+
+
+</script>
+<template>
+    <div>
+        <v-expansion-panels>
+            <v-expansion-panel>
+                <v-expansion-panel-title class=" text-h6">
+                    {{ title }}
+                </v-expansion-panel-title>
+                <v-expansion-panel-text>
+                    <slot></slot>
+                </v-expansion-panel-text>
+            </v-expansion-panel>
+        </v-expansion-panels>
+    </div>
+</template>
diff --git a/components/content/Alert/Info.vue b/components/content/Alert/Info.vue
new file mode 100644
index 0000000000000000000000000000000000000000..4d804852ccd50256b40ef214455e6911f7ee9bab
--- /dev/null
+++ b/components/content/Alert/Info.vue
@@ -0,0 +1,15 @@
+<script setup lang="ts">
+export interface Props {
+    title?: string
+}
+
+const { title } = withDefaults(defineProps<Props>(), {
+    title: 'Info'
+});
+</script>
+
+<template>
+    <v-alert type="info" border="start" variant="tonal" class="my-2" prominent :title="title">
+        <slot></slot>
+    </v-alert>
+</template>
diff --git a/components/content/Alert/Tip.vue b/components/content/Alert/Tip.vue
new file mode 100644
index 0000000000000000000000000000000000000000..f9e390e280b399f061e2d49c7e374b129d5a41de
--- /dev/null
+++ b/components/content/Alert/Tip.vue
@@ -0,0 +1,15 @@
+<script setup lang="ts">
+export interface Props {
+    title?: string
+}
+
+const { title } = withDefaults(defineProps<Props>(), {
+    title: 'Tip'
+});
+</script>
+<template>
+    <v-alert color="primary" border-color="primary" border="start" variant="tonal" class="my-2" prominent :title="title"
+        icon="md:lightbulb">
+        <slot></slot>
+    </v-alert>
+</template>
diff --git a/components/content/Alert/Warning.vue b/components/content/Alert/Warning.vue
new file mode 100644
index 0000000000000000000000000000000000000000..c5fc34a2bbe45c1f965f230e3ee569bf7dbfb354
--- /dev/null
+++ b/components/content/Alert/Warning.vue
@@ -0,0 +1,14 @@
+<script setup lang="ts">
+export interface Props {
+    title?: string
+}
+
+const { title } = withDefaults(defineProps<Props>(), {
+    title: 'Warning'
+});
+</script>
+<template>
+    <v-alert type="warning" border="start" variant="tonal" class="my-2" prominent :title="title">
+        <slot></slot>
+    </v-alert>
+</template>
diff --git a/components/content/ArticleDoi.vue b/components/content/ArticleDoi.vue
index 3cd6c619dca41bba746e4cbb37bd42647e6ffc70..ea79d24030e5faaeacba3c78f8caf8bafb9c9c40 100644
--- a/components/content/ArticleDoi.vue
+++ b/components/content/ArticleDoi.vue
@@ -28,6 +28,7 @@ const articleAbstract = computed(() => {
 <template>
   <v-list-item
     :href="article?.href"
+    :id="props.doi"
     :target="article?.target"
     density="compact"
     class="px-1"
diff --git a/components/content/ArticleDoiList.vue b/components/content/ArticleDoiList.vue
index fe7727a672fbe67a3741e520b42d97b36550dc03..357e90ee40bc9dc5a3ac068918d372e8a3091926 100644
--- a/components/content/ArticleDoiList.vue
+++ b/components/content/ArticleDoiList.vue
@@ -1,11 +1,25 @@
 <script setup lang="ts">
-const props = defineProps<{
-    items: { doi: string, title?: string, divider: boolean, abstract?: string }[];
-}>();
+import ProseH2 from '~/components/content/ProseH2'
+// const props = defineProps<{
+//   items: { doi: string; title?: string; divider: boolean; abstract?: string }[];
+// }>();
+
+const { page } = useContent();
+const computedDois = computed(() => {
+  if (page.value?.relevantAbstracts) {
+    return page.value.relevantAbstracts;
+  } else {
+    return [];
+  }
+});
 </script>
 <template>
+  <div v-if="computedDois?.length > 0">
+    <ProseH2 id="relevant-abstracts">Relevant abstracts</ProseH2>
+
     <v-list density="compact">
-        <ArticleDoi v-for="item, index in props.items" :key="item.doi" :index="index + 1" :doi="item.doi"
-            :title="item?.title" :divider="item.divider" :abstract="item?.abstract" />
+      <ArticleDoi v-for="(item, index) in computedDois" :key="item.doi" :index="index + 1" :doi="item.doi"
+        :title="item?.title" :divider="item.divider" :abstract="item?.abstract" />
     </v-list>
+  </div>
 </template>
\ No newline at end of file
diff --git a/components/content/Contributors.vue b/components/content/Contributors.vue
index 5c173d624212826b6e80db4755ee37639d1178ae..e79060863111661627017e26de255e35f3a2cc70 100644
--- a/components/content/Contributors.vue
+++ b/components/content/Contributors.vue
@@ -9,6 +9,6 @@ const contributorsString = computed(() => {
 
 </script>
 <template>
-    <div v-if="contributorsString" class="mt-n6 mb-6 text-subtitle-1 text-info">Contributors: {{ contributorsString }}
+    <div v-if="contributorsString" class="mt-n5 mb-6 text-subtitle-1 text-info">Contributors: {{ contributorsString }}
     </div>
 </template>
\ No newline at end of file
diff --git a/components/content/Ref.vue b/components/content/Ref.vue
new file mode 100644
index 0000000000000000000000000000000000000000..006afc08445f05b49419d17bac3dc15f0df40cac
--- /dev/null
+++ b/components/content/Ref.vue
@@ -0,0 +1,17 @@
+<script setup lang="ts">
+export interface Props {
+  doi: string;
+}
+const props = withDefaults(defineProps<Props>(), {});
+const { article } = useFetchArticle(props.doi);
+</script>
+<template>
+  <v-chip
+    v-if="article"
+    variant="text"
+    :href="`#${props.doi}`"
+    class="pa-0 text-caption font-italic"
+    >({{ article?.author[0]?.family ?? "test" }} et al,
+    {{ article?.year }})</v-chip
+  >
+</template>
\ No newline at end of file
diff --git a/composables/useFetchArticle.ts b/composables/useFetchArticle.ts
index 63439bd4e5e1af4ec70de0c0c062955ab7a101b0..a829bc4a2ab8b1ca7e9375119dcf18e0189d73e3 100644
--- a/composables/useFetchArticle.ts
+++ b/composables/useFetchArticle.ts
@@ -25,6 +25,7 @@ export interface Article {
     DOI: string
     title: string
     subtitle: string
+    author: Array<{ family: string; given: string }>
     containerTitle: string
     abstract: string
     year: string
@@ -74,6 +75,7 @@ export function useFetchArticle(doi: string) {
                 DOI,
                 title: sanitizedTitle,
                 subtitle: toAuthorsString(author || []),
+                author,
                 containerTitle: sanitizedContainerTitle,
                 abstract: sanitizedAbstract,
                 year: published?.["date-parts"][0][0] ?? issued?.["date-parts"][0][0] ?? '',
diff --git a/content/3.defense-systems/abi2.md b/content/3.defense-systems/abi2.md
index 808a7367c8c6f20bb252a410e57a5cec2b8d6a54..7e1d4617a877197aec2c7a5405fa0227afffc01d 100644
--- a/content/3.defense-systems/abi2.md
+++ b/content/3.defense-systems/abi2.md
@@ -9,6 +9,8 @@ tableColumns:
     Activator: ''
     Effector: ''
     PFAM: PF07751
+relevantAbstracts:
+  - doi: 10.1016/j.mib.2005.06.006
 ---
 
 # Abi2
@@ -17,7 +19,7 @@ The Abi2 system is composed of one protein: Abi_2.
 
 Here is an example found in the RefSeq database: 
 
-![abi2](/abi2/Abi2.svg){max-width=750px}
+![abi2](/abi2/Abi2.svg)
 
 Abi2 system in the genome of *Clostridium butyricum* (GCF_014131795.1) is composed of 1 protein: Abi_2 (WP_035763709.1).
 
@@ -27,10 +29,7 @@ The Abi2 system is present in a total of 176 different species.
 
 Among the 22k complete genomes of RefSeq, this system is present in 1210 genomes (5.3 %).
 
-![abi2](/abi2/Distribution_Abi2.svg){max-width=750px}
+![abi2](/abi2/Distribution_Abi2.svg)
 
 *Proportion of genome encoding the Abi2 system for the 14 phyla with more than 50 genomes in the RefSeq database.* 
 
-## Relevant abstracts
-
-
diff --git a/content/3.defense-systems/abia.md b/content/3.defense-systems/abia.md
index 3e5d554c5cc9e22ff35d189a3ad04e22809a0dd7..3de86ab7e5ceebfb8521761e72cdbcdba832ccd7 100644
--- a/content/3.defense-systems/abia.md
+++ b/content/3.defense-systems/abia.md
@@ -9,9 +9,14 @@ tableColumns:
     Activator: Unknown
     Effector: Unknown
     PFAM: PF00078, PF18160, PF18732
+relevantAbstracts:
+    - doi: 10.1023/A:1002027321171
+    - doi: 10.1016/j.mib.2005.06.006
+    - doi: 10.1093/nar/gkac467
 ---
 
-# AbiA
+# AbiA 
+
 The AbiA system have been describe in a total of 2 subsystems.
 
 Here is some example found in the RefSeq database:
@@ -24,10 +29,12 @@ AbiA_large subsystem in the genome of *Lactobacillus amylovorus* (GCF_002706375.
 
 AbiA_small subsystem in the genome of *Mesobacillus foraminis* (GCF_003667765.1) is composed of 2 proteins: AbiA_small (WP_121614402.1)and, AbiA_SLATT (WP_121614403.1).
 
-## Distribution of the system among prokaryotes
+## Distribution of the system among prokaryotes 
 
 The AbiA system is present in a total of 35 different species.
 
+
+
 Among the 22k complete genomes of RefSeq, this system is present in 50 genomes (0.2 %).
 
 ![abia](/abia/Distribution_AbiA.svg){max-width=750px}
@@ -67,15 +74,5 @@ AbiA systems were experimentally validated using:
 
 A system from *lactococcal plasmid* in *lactococci* has an anti-phage effect against 936, c2, P335 (Chopin et al., 2005)
 
-## Relevant abstracts
 
-::article-doi-list
----
-items:
-    - doi: 10.1023/A:1002027321171
-    - doi: 10.1016/j.mib.2005.06.006
-    - doi: 10.1093/nar/gkac467
-
----
-::
 
diff --git a/content/3.defense-systems/detocs.md b/content/3.defense-systems/detocs.md
index b715ca6408329a016b39d8cb29c7cd92d0152a84..028de448103f457b1351c16bebf4275d91030af0 100644
--- a/content/3.defense-systems/detocs.md
+++ b/content/3.defense-systems/detocs.md
@@ -6,6 +6,8 @@ tableColumns:
       abstract: |
         During viral infection, cells can deploy immune strategies that deprive viruses of molecules essential for their replication. Here, we report a family of immune effectors in bacteria that, upon phage infection, degrade cellular adenosine triphosphate (ATP) and deoxyadenosine triphosphate (dATP) by cleaving the N-glycosidic bond between the adenine and sugar moieties. These ATP nucleosidase effectors are widely distributed within multiple bacterial defense systems, including cyclic oligonucleotide-based antiviral signaling systems (CBASS), prokaryotic argonautes, and nucleotide-binding leucine-rich repeat (NLR)-like proteins, and we show that ATP and dATP degradation during infection halts phage propagation. By analyzing homologs of the immune ATP nucleosidase domain, we discover and characterize Detocs, a family of bacterial defense systems with a two-component phosphotransfer-signaling architecture. The immune ATP nucleosidase domain is also encoded within diverse eukaryotic proteins with immune-like architectures, and we show biochemically that eukaryotic homologs preserve the ATP nucleosidase activity. Our findings suggest that ATP and dATP degradation is a cell-autonomous innate immune strategy conserved across the tree of life.
     PFAM: PF01048, PF18742
+relevantAbstracts: 
+    - doi: 10.1016/j.cell.2023.07.020
 contributors: 
     - François Rousset
 ---
@@ -83,16 +85,3 @@ dataUrl: /detocs/Detocs_hydrolase__dtcC-plddts_89.47253.pdb
 ---
 ::
 
-## Relevant abstract
-::article-doi-list
----
-items:
-    - doi: 10.1016/j.cell.2023.07.020
-
----
-::
-
-
-## References
-
-Rousset et al., A conserved family of immune effectors cleaves cellular ATP upon viral infection. Cell 186, 1–13 (2023). https://doi.org/10.1016/j.cell.2023.07.020
diff --git a/nuxt.config.ts b/nuxt.config.ts
index 2eac5520d11c49de27cc5e7662abf045e856d437..2a61a770fa262195880939a9c98360e6b615a732 100644
--- a/nuxt.config.ts
+++ b/nuxt.config.ts
@@ -11,6 +11,16 @@ export default defineNuxtConfig({
   content: {
     documentDriven: {
       injectPage: false,
+    },
+    highlight: {
+      theme: {
+        // Default theme (same as single string)        
+        default: 'github-light',
+        // Theme used if `html.dark`        
+        dark: 'github-dark',
+        // Theme used if `html.sepia`        
+        sepia: 'monokai'
+      }
     }
   },
   vuetify: {
diff --git a/server/plugins/content.ts b/server/plugins/content.ts
index 0f843c65913eb850e528d7653738a8deb4ca9e55..19dad94f6b91ee1e41275d3b50c32c772861a4b7 100644
--- a/server/plugins/content.ts
+++ b/server/plugins/content.ts
@@ -4,34 +4,44 @@ export default defineNitroPlugin((nitroApp) => {
     nitroApp.hooks.hook('content:file:beforeParse',
         (file) => {
             if (file?._id?.startsWith('content:3.defense-systems:') && file?._id?.endsWith('.md')) {
-                const regexp = /(?<=---\n).*?(?=\n---)/sg;
-                const match = file.body.match(regexp);
-                const frontMatter = match[0]
-                const parsedFrontMatter = YAML.parse(frontMatter)
-                if (parsedFrontMatter?.contributors?.length > 0) {
-                    file.body = file.body.replace(/(^#[\s+]\w*[\s\S])/gm, "$1:contributors\n\n")
+                const frontMatterRegex = /(?<=---\n).*?(?=\n---)/sg;
+
+                const fontMatterMatch = file.body.match(frontMatterRegex);
+                if (fontMatterMatch?.length > 0) {
+                    const frontMatter = fontMatterMatch[0]
+                    const parsedFrontMatter = YAML.parse(frontMatter)
+                    if (parsedFrontMatter?.contributors?.length > 0) {
+                        file.body = file.body.replace(/(^#[\s+]\w*[\s\S])/gm, "$1\n:contributors\n\n")
+                    }
+                    // try to look at :ref{doi=xxxx}
+                    const matchRef = file.body.match(/(?<=:ref{doi=).*(?=})/gm)
+                    if (matchRef?.length > 0) {
+                        if (parsedFrontMatter?.relevantAbstracts) {
+                            const relevantAbstractsSet = new Set(parsedFrontMatter.relevantAbstracts.map(({ doi }: { doi: string }) => doi))
+                            const filteredMatchRef = matchRef.filter((doi: string) => !relevantAbstractsSet.has(doi))
+                            parsedFrontMatter.relevantAbstracts = [...parsedFrontMatter.relevantAbstracts, ...filteredMatchRef.map((doi: string) => ({ doi }))]
+                        } else {
+                            parsedFrontMatter.relevantAbstracts = matchRef.map((doi: string) => ({ doi }))
+                        }
+                        const newFrontMatterStr = YAML.stringify(parsedFrontMatter)
+                        file.body = file.body.replace(/---\n(.*?)\n---/gs, `---\n${newFrontMatterStr}\n---`)
+                    }
 
                 }
             }
         })
 
 
-    // nitroApp.hooks.hook(
-    //     'content:file:afterParse',
-    //     (file) => {
-    //         if (file._id.endsWith('.md')) {
-
-    //             file.body.children.push({
-    //                 type: "element",
-    //                 tag: 'article-doi-list',
-    //                 props: {
-    //                     items: [
-    //                         { doi: '10.1016/j.mib.2005.06.006' },
-    //                         { doi: '10.1016/j.mib.2005.06.006' }]
-    //                 },
-    //                 children: []
-    //             })
-
-    //         }
-    //     })
+    nitroApp.hooks.hook(
+        'content:file:afterParse',
+        (file) => {
+            if (file?._id?.startsWith('content:3.defense-systems:') && file._id.endsWith('.md')) {
+                file.body.children.push({
+                    type: "element",
+                    tag: 'article-doi-list',
+                    props: {},
+                    children: []
+                })
+            }
+        })
 })
\ No newline at end of file