diff --git a/app/comp/res_common.py b/app/comp/res_common.py
index 0fa9fcd7dd1d5fb20e13a6e5660602c82ffa81f9..839f631540fe3159a42bb09ee16f7cba7f96764c 100644
--- a/app/comp/res_common.py
+++ b/app/comp/res_common.py
@@ -541,7 +541,9 @@ class ResultatsSemestre(ResultatsCache):
             row["_moy_gen_class"] = "col_moy_gen"
             # titre de la ligne:
             row["prenom"] = row["nom_short"] = bottom_line.capitalize()
-            row["_tr_class"] = bottom_line.lower()
+            row["_tr_class"] = bottom_line.lower() + (
+                (" " + row["_tr_class"]) if "_tr_class" in row else ""
+            )
             footer_rows.append(row)
         titles_bot.update(titles)
         footer_rows.append(titles_bot)
@@ -554,30 +556,29 @@ class ResultatsSemestre(ResultatsCache):
 
     def _recap_bottom_infos(self, ues, modimpl_ids: set, fmt_note) -> dict:
         """Les informations à mettre en bas de la table: min, max, moy, ECTS"""
-        bottom_infos = {  # { key : row } avec key = min, max, moy, coef
-            "min": {},
-            "max": {},
-            "moy": {},
-            "coef": {},
-        }
+        row_min, row_max, row_moy, row_coef, row_ects = (
+            {"_tr_class": "bottom_info"},
+            {"_tr_class": "bottom_info"},
+            {"_tr_class": "bottom_info"},
+            {"_tr_class": "bottom_info"},
+            {"_tr_class": "bottom_info"},
+        )
         # --- ECTS
-        row = {}
         for ue in ues:
-            row[f"moy_ue_{ue.id}"] = ue.ects
-            row[f"_moy_ue_{ue.id}_class"] = "col_ue"
+            row_ects[f"moy_ue_{ue.id}"] = ue.ects
+            row_ects[f"_moy_ue_{ue.id}_class"] = "col_ue"
             # style cases vides pour borders verticales
-            bottom_infos["coef"][f"moy_ue_{ue.id}"] = ""
-            bottom_infos["coef"][f"_moy_ue_{ue.id}_class"] = "col_ue"
-        row["moy_gen"] = sum([ue.ects or 0 for ue in ues if ue.type != UE_SPORT])
-        row["_moy_gen_class"] = "col_moy_gen"
-        bottom_infos["ects"] = row
+            row_coef[f"moy_ue_{ue.id}"] = ""
+            row_coef[f"_moy_ue_{ue.id}_class"] = "col_ue"
+        row_ects["moy_gen"] = sum([ue.ects or 0 for ue in ues if ue.type != UE_SPORT])
+        row_ects["_moy_gen_class"] = "col_moy_gen"
 
         # --- MIN, MAX, MOY
-        row_min, row_max, row_moy = {}, {}, {}
+
         row_min["moy_gen"] = fmt_note(self.etud_moy_gen.min())
         row_max["moy_gen"] = fmt_note(self.etud_moy_gen.max())
         row_moy["moy_gen"] = fmt_note(self.etud_moy_gen.mean())
-        for ue in [ue for ue in ues if ue.type != UE_SPORT]:
+        for ue in ues:
             col_id = f"moy_ue_{ue.id}"
             row_min[col_id] = fmt_note(self.etud_moy_ue[ue.id].min())
             row_max[col_id] = fmt_note(self.etud_moy_ue[ue.id].max())
@@ -593,16 +594,19 @@ class ResultatsSemestre(ResultatsCache):
                         coef = self.modimpl_coefs_df[modimpl.id][ue.id]
                     else:
                         coef = modimpl.module.coefficient or 0
-                    bottom_infos["coef"][col_id] = fmt_note(coef)
+                    row_coef[col_id] = fmt_note(coef)
                     notes = self.modimpl_notes(modimpl.id, ue.id)
                     row_min[col_id] = fmt_note(np.nanmin(notes))
                     row_max[col_id] = fmt_note(np.nanmax(notes))
                     row_moy[col_id] = fmt_note(np.nanmean(notes))
 
-        bottom_infos["min"] = row_min
-        bottom_infos["max"] = row_max
-        bottom_infos["moy"] = row_moy
-        return bottom_infos
+        return {  # { key : row } avec key = min, max, moy, coef
+            "min": row_min,
+            "max": row_max,
+            "moy": row_moy,
+            "coef": row_coef,
+            "ects": row_ects,
+        }
 
     def _recap_etud_groups_infos(self, etudid: int, row: dict, titles: dict):
         """Table recap: ajoute à row les colonnes sur les groupes pour cet etud"""
diff --git a/app/scodoc/sco_recapcomplet.py b/app/scodoc/sco_recapcomplet.py
index 2d002f9fd005d66a378378c2739ed35bc1c2b274..117ce5673f1a9fbb52a646664b1ea92365f6c0bc 100644
--- a/app/scodoc/sco_recapcomplet.py
+++ b/app/scodoc/sco_recapcomplet.py
@@ -1015,9 +1015,10 @@ def _gen_cell(key: str, row: dict, elt="td"):
         attrs += f' data-order="{order}"'
     content = row.get(key, "")
     target = row.get(f"_{key}_target")
-    if content or target:  # avec lien
+    target_attrs = row.get(f"_{key}_target_attrs", "")
+    if target or target_attrs:  # avec lien
         href = f'href="{target}"' if target else ""
-        content = f'<a {href} {row.get(f"_{key}_target_attrs", "")}>{content}</a>'
+        content = f"<a {href} {target_attrs}>{content}</a>"
     return f"<{elt} {attrs}>{content}</{elt}>"
 
 
@@ -1039,7 +1040,9 @@ def gen_formsemestre_recapcomplet_html(
             '<div class="table_recap"><div class="message">aucun étudiant !</div></div>',
             "",
         )
-    H = ['<div class="table_recap"><table class="table_recap">']
+    H = [
+        f"""<div class="table_recap"><table class="table_recap {'apc' if formsemestre.formation.is_apc() else ''}">"""
+    ]
     # header
     H.append(
         f"""
diff --git a/app/static/css/scodoc.css b/app/static/css/scodoc.css
index 47f6a769d8d7c13228d0b6cb896efc6f052d6e9d..2196b4da32d20aaac6c6561ca293935488de0a82 100644
--- a/app/static/css/scodoc.css
+++ b/app/static/css/scodoc.css
@@ -3155,7 +3155,14 @@ table.table_recap tr.selected td:first-child {
 table.table_recap tr.selected td:last-child {
   border-right: 1px solid rgb(248, 0, 33); 
 }
-
+table.table_recap tbody td {
+  padding-top: 4px !important;
+  padding-bottom: 4px !important;
+}
+table.table_recap tbody td:hover {
+  color: rgb(163, 0, 0);
+  text-decoration: dashed underline;
+}
 table.table_recap .identite_court  {
   white-space:nowrap;
   text-align: left;
@@ -3169,6 +3176,7 @@ table.table_recap .col_ue, table.table_recap .col_moy_gen, table.table_recap .gr
 }
 table.table_recap .group {
   border-left: 1px dashed rgb(160, 160, 160);
+  white-space:nowrap;
 }
 
 table.table_recap tbody tr td a:hover {
diff --git a/app/static/js/table_recap.js b/app/static/js/table_recap.js
index 31344b7324202ba2be30465fc1f8ccbdde119d68..2b41cf5ac915cd25caacd091afae910fa2e76209 100644
--- a/app/static/js/table_recap.js
+++ b/app/static/js/table_recap.js
@@ -1,6 +1,49 @@
 // Tableau recap notes
 $(function () {
     $(function () {
+        // Les boutons dépendent du mode BUT ou classique:
+        let buttons = [
+            {
+                name: "toggle_ident",
+                text: "Civ/Nom/Prénom",
+                action: function (e, dt, node, config) {
+                    let visible = dt.columns(".identite_detail").visible()[0];
+                    dt.columns(".identite_detail").visible(!visible);
+                    dt.columns(".identite_court").visible(visible);
+                    dt.buttons('toggle_ident:name').text(visible ? "Civ/Nom/Prénom" : "Nom");
+                }
+            },
+            $('table.table_recap').hasClass("apc") ?
+                {
+                    name: "toggle_res",
+                    text: "Cacher les ressources",
+                    action: function (e, dt, node, config) {
+                        let visible = dt.columns(".col_res").visible()[0];
+                        dt.columns(".col_res").visible(!visible);
+                        dt.buttons('toggle_res:name').text(visible ? "Montrer les ressources" : "Cacher les ressources");
+                    }
+                } : {
+                    name: "toggle_mod",
+                    text: "Cacher les modules",
+                    action: function (e, dt, node, config) {
+                        let visible = dt.columns(".col_mod").visible()[0];
+                        dt.columns(".col_mod").visible(!visible);
+                        dt.buttons('toggle_mod:name').text(visible ? "Montrer les modules" : "Cacher les modules");
+                    }
+                }
+        ];
+        if ($('table.table_recap').hasClass("apc")) {
+            buttons.push({
+                name: "toggle_sae",
+                text: "Cacher les SAÉs",
+                action: function (e, dt, node, config) {
+                    let visible = dt.columns(".col_sae").visible()[0];
+                    dt.columns(".col_sae").visible(!visible);
+                    dt.buttons('toggle_sae:name').text(visible ? "Montrer les SAÉs" : "Cacher les SAÉs");
+                }
+            })
+
+        }
         $('table.table_recap').DataTable(
             {
                 paging: false,
@@ -9,7 +52,7 @@ $(function () {
                 autoWidth: false,
                 fixedHeader: {
                     header: true,
-                    footer: true
+                    footer: false
                 },
                 orderCellsTop: true, // cellules ligne 1 pour tri 
                 aaSorting: [], // Prevent initial sorting
@@ -22,42 +65,12 @@ $(function () {
                     },
                 ],
                 dom: 'Bfrtip',
-                buttons: [
-                    'copy', 'excel', 'pdf',
+                buttons: ['copy', 'excel', 'pdf',
                     {
                         extend: 'collection',
                         text: 'Réglages affichage',
                         autoClose: true,
-                        buttons: [
-                            {
-                                name: "toggle_ident",
-                                text: "Civ/Nom/Prénom",
-                                action: function (e, dt, node, config) {
-                                    let visible = dt.columns(".identite_detail").visible()[0];
-                                    dt.columns(".identite_detail").visible(!visible);
-                                    dt.columns(".identite_court").visible(visible);
-                                    dt.buttons('toggle_ident:name').text(visible ? "Civ/Nom/Prénom" : "Nom");
-                                }
-                            },
-                            {
-                                name: "toggle_res",
-                                text: "Cacher les ressources",
-                                action: function (e, dt, node, config) {
-                                    let visible = dt.columns(".col_res").visible()[0];
-                                    dt.columns(".col_res").visible(!visible);
-                                    dt.buttons('toggle_res:name').text(visible ? "Montrer les ressources" : "Cacher les ressources");
-                                }
-                            },
-                            {
-                                name: "toggle_sae",
-                                text: "Cacher les SAÉs",
-                                action: function (e, dt, node, config) {
-                                    let visible = dt.columns(".col_sae").visible()[0];
-                                    dt.columns(".col_sae").visible(!visible);
-                                    dt.buttons('toggle_sae:name').text(visible ? "Montrer les SAÉs" : "Cacher les SAÉs");
-                                }
-                            },
-                        ]
+                        buttons: buttons,
                     }
                 ]
             }