diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 380d1e126b399cb3ff3dea1b94161993d6acdba9..a6a5becf63af2205e37415f043b228774979b443 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -204,7 +204,7 @@ lint:
     - >
       df-wiki-cli 
       meilisearch 
-      delete-all-documents system-operon-structure
+      delete-all-documents systemoperonstruct
     - >
       df-wiki-cli 
       content 
diff --git a/components/Nav/Drawer.vue b/components/Nav/Drawer.vue
index 645e512f65f55c2c9248aa653baf8edd2d1353fb..6cdff1f0e09d9075e4e095b3c5c4e768a36c43ac 100644
--- a/components/Nav/Drawer.vue
+++ b/components/Nav/Drawer.vue
@@ -27,7 +27,7 @@ const { navigation, page } = useContent();
 // });
 </script>
 <template>
-    <v-navigation-drawer :model-value="drawer" :border="1" color="background">
+    <v-navigation-drawer name="drawer" :model-value="drawer" :border="1" color="background">
         <v-list nav density="compact" :lines="false">
             <NavNavigation :navigation="navigation" />
         </v-list>
diff --git a/components/OperonStructure.vue b/components/OperonStructure.vue
index 4b5365d635de29e42f0dd98e0c80337f0e1e3dc1..f7ad97e2766e9939f2e178f12dada8000218681a 100644
--- a/components/OperonStructure.vue
+++ b/components/OperonStructure.vue
@@ -2,12 +2,12 @@
 import { useElementSize } from '@vueuse/core'
 import * as d3 from "d3";
 import type { PlotMargin } from "../types/plot";
-import type { StructureOperonGene } from "../types/structure"
+import type { StructureOperonGene, StructureOperonGeneWithCoordinate, StructureOperonGeneWithImg } from "../types/structure"
 import { useStructuresBasket } from '~/stores/structuresBasket';
 
 
 interface Props {
-    genes: StructureOperonGene[] | null
+    genes: StructureOperonGeneWithImg[] | null
 }
 const structureBasket = useStructuresBasket()
 
@@ -15,10 +15,7 @@ const props = withDefaults(defineProps<Props>(), {
     genes: null
 });
 const height = ref<number>(150)
-const svgRef = ref(null)
-
-
-
+const svgRef = ref<SVGElement | null>(null)
 const margin = ref<PlotMargin>({
     marginTop: 10,
     marginRight: 7,
@@ -26,34 +23,41 @@ const margin = ref<PlotMargin>({
     marginLeft: 7,
 })
 
+
+
 const plotHeight = computed(() => {
     const { marginTop, marginBottom } = toValue(margin)
     return toValue(height) + marginTop + marginBottom
 })
 
-const xScale = ref(
-    d3.scaleBand().paddingInner(0.1)
-);
+const domain = computed(() => {
+    const genes = toValue(computedGenes)
+    return genes?.map(d => { return d.gene })
+})
+
+const xScale = computed(() => {
+    return d3.scaleBand()
+        .paddingInner(0.1)
+        .domain(toValue(domain))
+        .range([0, computedPlotWidth.value])
+})
+
+
 const yScale = ref(d3.scaleBand()
     .domain(['1'])
     .range([toValue(margin).marginTop, toValue(height)]));
 const gbContainer = ref(null)
-const gbContainerWidth = ref(useElementSize(gbContainer, { width: 500, height: 0 }, { box: 'border-box' }).width)
-
 const computedContainerWidth = computed(() => {
-    return gbContainerWidth.value
+    return useElementSize(gbContainer, { width: 500, height: 0 }, { box: 'border-box' }).width.value
 })
-
 const computedPlotWidth = computed(() => {
     const { marginLeft, marginRight } = toValue(margin)
     return computedContainerWidth.value - marginLeft - marginRight
 })
 
-onMounted(() => {
-    draw()
-})
 
-const computedGenes = computed(() => {
+
+const computedGenes = computed<StructureOperonGene[]>(() => {
     const genes = toValue(props.genes)
     if (genes !== null) {
         return genes.map(d => {
@@ -67,7 +71,6 @@ const computedGenes = computed(() => {
 
 
 const structureVersion = computed(() => {
-
     const genesVal = toValue(computedGenes)
     if (genesVal?.length > 0) {
         return genesVal[0].version
@@ -77,16 +80,8 @@ const structureVersion = computed(() => {
     }
 })
 
-watch(computedGenes, () => {
-    const genes = toValue(computedGenes)
-    const domain = genes?.map(d => { return d.gene })
-    xScale.value.domain(domain)
-        .range([0, computedPlotWidth.value])
-})
-
-
 
-const genesWithCoord = computed(() => {
+const genesWithCoord = computed<StructureOperonGeneWithCoordinate[]>(() => {
     const genes = toValue(computedGenes)
     const xScaleVal = toValue(xScale)
     const yScaleVal = toValue(yScale)
@@ -103,12 +98,15 @@ const genesWithCoord = computed(() => {
     }
     else { return [] }
 })
+onMounted(() => {
+    draw()
+})
 
 watch(genesWithCoord, () => {
     draw()
 })
 
-function createOrSelect(container, tag, selectionClass) {
+function createOrSelect(container: d3.Selection<SVGElement, any, HTMLElement | null, any>, tag: string, selectionClass: string) {
     let selection = container.select(`${tag}.${selectionClass}`)
     if (selection.empty()) {
         selection = container.append(tag).classed(selectionClass, true)
@@ -117,39 +115,41 @@ function createOrSelect(container, tag, selectionClass) {
 }
 
 function draw() {
-    const svg = d3.select(svgRef.value);
-    const { marginLeft } = toValue(margin)
-    const xAxis = d3.axisBottom(xScale.value)
-    const gx = createOrSelect(svg, 'g', 'x-axis')
-
-    gx
-        .attr("transform", `translate(${marginLeft},${toValue(height)})`)
-        .call(xAxis)
-        .selectAll("text")
-        .attr("transform", 'rotate(45)')
-        .attr("text-anchor", "start")
-
-    const gxTitle = createOrSelect(gx, "text", "x-axis-title")
-    gxTitle
-        .attr("text-anchor", "end")
-        .attr("fill", "currentColor")
-
-    gxTitle
-        .attr("x", toValue(computedPlotWidth))
-        .attr("y", - 10)
-
-
-    let gGenes = createOrSelect(svg, "g", "genes")
-    gGenes
-        .attr("transform", `translate(${marginLeft},0)`)
-        .call(drawGenes, xScale, yScale)
+
+    if (svgRef.value !== null) {
+        const svg = d3.select<SVGElement, undefined>(svgRef.value);
+        const { marginLeft } = toValue(margin)
+        const xAxis = d3.axisBottom(xScale.value)
+        const gx = createOrSelect(svg, 'g', 'x-axis')
+        gx
+            .attr("transform", `translate(${marginLeft},${toValue(height)})`)
+            .call(xAxis)
+            .selectAll("text")
+            .attr("transform", 'rotate(45)')
+            .attr("text-anchor", "start")
+
+        const gxTitle = createOrSelect(gx, "text", "x-axis-title")
+        gxTitle
+            .attr("text-anchor", "end")
+            .attr("fill", "currentColor")
+
+        gxTitle
+            .attr("x", toValue(computedPlotWidth))
+            .attr("y", - 10)
+
+
+        let gGenes = createOrSelect(svg, "g", "genes")
+        gGenes
+            .attr("transform", `translate(${marginLeft},0)`)
+            .call(drawGenes, xScale, yScale)
+    }
 }
 
-function drawGenes(genesGroup) {
-    console.log(toValue(genesWithCoord))
+function drawGenes(genesGroup: d3.Selection<SVGElement, any, SVGElement, any>) {
+    const data = toValue(genesWithCoord)
     const genesSelection = genesGroup
         .selectAll("g.gene") // get all "existing" lines in svg
-        .data(toValue(genesWithCoord)) // sync them with our data
+        .data<StructureOperonGeneWithCoordinate>(data) // sync them with our data
         .join(
             enter => {
                 const g = enter.append("g")
@@ -159,7 +159,6 @@ function drawGenes(genesGroup) {
 
                 g.append("image")
                     .on("mouseover", function (event) {
-                        console.log(event.srcElement)
                         d3.select(event.srcElement.previousSibling)
                             .attr("stroke-width", 4)
                             .attr("stroke", "darkred")
@@ -184,12 +183,12 @@ function drawGenes(genesGroup) {
         )
     genesSelection.attr("transform", d => `translate(${d.x},${d.y})`)
     genesSelection.select("image")
-        .attr("href", d => d?.structImg)
+        .attr("href", d => d?.structImg ?? null)
         .attr("width", d => d.width)
         .attr("height", d => d.height)
         .on("click", function (event) {
-            const data = d3.select(this).data()
-            structureBasket.set(data.map(s => s.structPath))
+            const data = d3.select<SVGElement, StructureOperonGeneWithCoordinate>(this).data()
+            structureBasket.set(data.map(s => s?.structPath ?? ''))
 
         })
     genesSelection.select("path.gene")
@@ -212,7 +211,6 @@ function drawGene({ width, height }) {
     <div ref="gbContainer">
         <v-card flat color="transparent">
             <v-card-subtitle>model version : {{ structureVersion }}</v-card-subtitle>
-            <!-- <v-img :href=""></v-img> -->
             <svg ref="svgRef" :width="computedContainerWidth" :height="plotHeight">
                 <g class="x-axis" />
             </svg>
diff --git a/components/content/ArticleStructure.vue b/components/content/ArticleStructure.vue
index 29b36c314e3d3f2c41a9986e09eb96df74263cd1..8333dc672f2bcb521a4b1f699e761d375b2d2495 100644
--- a/components/content/ArticleStructure.vue
+++ b/components/content/ArticleStructure.vue
@@ -11,7 +11,6 @@ import { useStructuresBasket } from '~/stores/structuresBasket';
 const { page } = useContent();
 const client = useMeiliSearchRef()
 const structureBasket = useStructuresBasket()
-
 // get the structures
 const structures = ref<SearchResponse<StructureItem, SearchParams> | undefined>()
 const structureTitle = ref("Structure")
@@ -67,9 +66,7 @@ function displayStructure(item) {
 const sanitizedStructures = computed(() => {
     const toValStructures = toValue(structures)
     if (toValStructures?.hits && toValStructures?.hits?.length > 0) {
-
         return toValStructures.hits.map(item => {
-            console.log(item)
             return {
                 ...item, structuresUrls: [`/${item.system.toLowerCase()}/${pdbNameToCif(item.pdb)}`, `/${item.system.toLowerCase()}/${item.pdb}`]
                     .map(url => {
@@ -111,16 +108,8 @@ async function fetchStructures() {
     <v-card flat>
         <template v-for="[subsystem, structures] in perSubsystemStructures" :key="subsystem[0]">
             <ProseH3>{{ subsystem }}</ProseH3>
-            <v-row align="end">
-                <v-col cols="6" class="ml-0 ">
-                    <SystemOperonStructure :system="computedSystem" :subsystem="subsystem" :structures="structures" />
-                </v-col>
-                <v-col cols="6">
-                    <PdockqMatrix :subsystem="subsystem" />
-                </v-col>
-            </v-row>
+            <SystemOperonStructure :system="computedSystem" :subsystem="subsystem" :structures="structures" />
         </template>
-
         <ProseH3>Summary</ProseH3>
         <v-data-table :headers="headers" :items="sanitizedStructures" :group-by="groupBy">
             <template #[`item.proteins_in_the_prediction`]="{ item }">
diff --git a/components/content/PdockqMatrix.vue b/components/content/PdockqMatrix.vue
index 289b7739fb5e5bf0ad0834cfe772daaf8e1aba4a..cd5735135e4e7afc19572c4465b323382113b139 100644
--- a/components/content/PdockqMatrix.vue
+++ b/components/content/PdockqMatrix.vue
@@ -152,8 +152,6 @@ function on(mark) {
         // but in simple cases it works
 
         const data = this.data;
-        console.log(data)
-        const key = data[0].key
         // 🌶 since a point or band scale doesn't have an inverse, create one from its domain and range
         const g = render.apply(this, arguments);
         const r = d3.select(g).selectChildren();
diff --git a/components/content/SystemOperonStructure.vue b/components/content/SystemOperonStructure.vue
index c1a69d2fb02a414cf2c14d4c2e79218cfd34ec2e..6809308484eb8ecec2b74d34f1b3d303a41623b1 100644
--- a/components/content/SystemOperonStructure.vue
+++ b/components/content/SystemOperonStructure.vue
@@ -1,7 +1,8 @@
 <script setup lang="ts">
-import type { StructureItem, StructureOperonGene } from "../../types/structure";
+import type { StructureItem, StructureOperonGene, StructureOperonGeneWithImg } from "../../types/structure";
 import type { SearchResponse } from "meilisearch";
-import { withTrailingSlash, withLeadingSlash, joinURL } from 'ufo'
+import { joinURL } from 'ufo'
+import { useColumnLayout } from '~/composables/useColumnLayout';
 
 
 interface Props {
@@ -17,6 +18,8 @@ const { system, subsystem, structures } = withDefaults(defineProps<Props>(), {
 const client = useMeiliSearchRef()
 
 const pending = ref<boolean>(false)
+const sizeGene = ref<number>(100)
+
 const msIndexName = ref<'systemoperonstruct'>("systemoperonstruct")
 const msResponse = ref<SearchResponse<StructureOperonGene> | undefined>(undefined)
 
@@ -38,7 +41,7 @@ const monomerStructures = computed(() => {
     }
 })
 
-const sanitizedHits = computed(() => {
+const sanitizedHits = computed<StructureOperonGeneWithImg[]>(() => {
     const toValMsResponse = toValue(msResponse)
     if (toValMsResponse && toValMsResponse?.hits?.length > 0) {
         return toValMsResponse.hits.map(hit => {
@@ -52,7 +55,7 @@ const sanitizedHits = computed(() => {
                 const rawImgUrl = joinURL(`/${system.toLowerCase()}`, struct?.structImg ?? '')
                 const rawStructUrl = joinURL(`/${system.toLowerCase()}`, struct?.structPath ?? '')
                 const { refinedUrl: structImgHref } = useRefinedUrl(rawImgUrl)
-                return { ...hit, gene: sanitizedGene, structImg: toValue(structImgHref), structPath: rawStructUrl}
+                return { ...hit, gene: sanitizedGene, structImg: toValue(structImgHref), structPath: rawStructUrl }
             }
             else {
                 return { ...hit, gene: sanitizedGene }
@@ -80,6 +83,13 @@ const sanitizedSubsystem = computed(() => {
     }
 })
 
+const contentWidth = computed(() => {
+    return sanitizedHits.value.length * sizeGene.value
+})
+
+const { wholeRow } = useColumnLayout({ contentWidth, widthThreshold: 600 })
+
+
 onMounted(() => {
     fetchOperonStructure()
 })
@@ -105,9 +115,12 @@ async function fetchOperonStructure() {
 </script>
 
 <template>
-
-    <v-card variant="flat">
-        <OperonStructure :genes="sanitizedHits" :system :subsystem />
-    </v-card>
-
+    <v-row align="center">
+        <v-col :cols="wholeRow ? 12 : 6" class="pa-0">
+            <OperonStructure :genes="sanitizedHits" :system :subsystem />
+        </v-col>
+        <v-col :cols="wholeRow ? 12 : 6" class="pa-0">
+            <PdockqMatrix :subsystem="subsystem" />
+        </v-col>
+    </v-row>
 </template>
\ No newline at end of file
diff --git a/composables/useColumnLayout.ts b/composables/useColumnLayout.ts
new file mode 100644
index 0000000000000000000000000000000000000000..dca16406be60da91b9c12b77c04e259360599dd1
--- /dev/null
+++ b/composables/useColumnLayout.ts
@@ -0,0 +1,33 @@
+
+import { useDisplay, useLayout } from "vuetify";
+
+interface ParametersColumnLayout {
+    contentWidth: MaybeRef<number>,
+    widthThreshold: MaybeRef<number> | ((width: Ref<number>) => number)
+}
+
+export function useColumnLayout({ contentWidth, widthThreshold }: ParametersColumnLayout) {
+    const { getLayoutItem } = useLayout()
+    const { width } = useDisplay()
+    const widthTresholdRef = computed(() => {
+        if (typeof widthThreshold === "function") {
+            return widthThreshold(width)
+        }
+        else {
+            return toValue(widthThreshold)
+        }
+    })
+
+    const computedWidth = computed(() => {
+        const drawerLayout = getLayoutItem("drawer")
+        if (drawerLayout && drawerLayout.size > 0) {
+            return toValue(width) - drawerLayout.size
+        }
+        return toValue(width)
+    })
+
+    const wholeRow = computed(() => {
+        return toValue(contentWidth) > toValue(computedWidth) / 2
+    })
+    return { widthTresholdRef, wholeRow }
+}
\ No newline at end of file
diff --git a/packages/df-wiki-cli/df_wiki_cli/content/main.py b/packages/df-wiki-cli/df_wiki_cli/content/main.py
index 48a89a26ed9f91b7fb893e758d6c924eb3691821..a71043813f3fd9b097cfa10ae42c9210eb70a4d3 100644
--- a/packages/df-wiki-cli/df_wiki_cli/content/main.py
+++ b/packages/df-wiki-cli/df_wiki_cli/content/main.py
@@ -8,7 +8,7 @@ import matplotlib.pyplot as plt
 from operator import itemgetter
 from pandas.errors import ParserError
 from typing_extensions import Annotated
-from typing import Optional, List, Tuple
+from typing import Optional, List
 from pathlib import Path
 from pydantic import BaseModel, ValidationError
 import frontmatter
@@ -286,10 +286,17 @@ def system_operon_structure(
         for row in tsvreader:
             systems.append({"system": row["system"], "subsystem": row["subsystem"]})
     system_genes = []
+    system_genes_got = set()
     for system_def in systems:
         system, subsystem = itemgetter("system", "subsystem")(system_def)
+        system_id = f"{system}-{subsystem}"
         list_paths = list(gen_model_path(model_dirs))
-        if system != "#N/A" and subsystem != "#N/A":
+        if (
+            system != "#N/A"
+            and subsystem != "#N/A"
+            and system_id not in system_genes_got
+        ):
+            system_genes_got.add(system_id)
             def_path = find_model_definition(system, subsystem, list_paths)
             in_exchangeables = False
             current_gene = {}
diff --git a/types/structure.ts b/types/structure.ts
index ef0f6badfcad03fc85798db79e427ac5169e857c..7e90fde5ee523e1295ddb46499e325fefdb3471a 100644
--- a/types/structure.ts
+++ b/types/structure.ts
@@ -6,6 +6,17 @@ export interface StructureOperonGene {
     system: string
 }
 
+export interface StructureOperonGeneWithImg extends StructureOperonGene {
+    structImg?: string
+    structPath?: string
+}
+
+export interface StructureOperonGeneWithCoordinate extends StructureOperonGeneWithImg {
+    width: number
+    height: number
+    x: number | undefined
+    y: number | undefined
+}
 export type StructurePredictionType = "monomer" | "multimer" | "multimer(dimer)" | "multimer(homodimer)"
 export type StructureType = "Validated" | "DF" | "na"