diff --git a/app/comp/res_common.py b/app/comp/res_common.py
index d7240598a010d677356db63969bebeca8b8ebec3..7245439f405a169f2dcc2b9b4a71850761dfcaf7 100644
--- a/app/comp/res_common.py
+++ b/app/comp/res_common.py
@@ -18,7 +18,7 @@ from app.auth.models import User
 from app.comp.res_cache import ResultatsCache
 from app.comp import res_sem
 from app.comp.moy_mod import ModuleImplResults
-from app.models import FormSemestre, FormSemestreUECoef
+from app.models import FormSemestre, FormSemestreUECoef, formsemestre
 from app.models import Identite
 from app.models import ModuleImpl, ModuleImplInscription
 from app.models.ues import UniteEns
@@ -388,7 +388,9 @@ class ResultatsSemestre(ResultatsCache):
 
     # --- TABLEAU RECAP
 
-    def get_table_recap(self, convert_values=False, include_evaluations=False):
+    def get_table_recap(
+        self, convert_values=False, include_evaluations=False, modejury=False
+    ):
         """Result: tuple avec
         - rows: liste de dicts { column_id : value }
         - titles: { column_id : title }
@@ -538,6 +540,9 @@ class ResultatsSemestre(ResultatsCache):
                     titles_bot[
                         f"_{col_id}_target_attrs"
                     ] = f"""title="{ue.titre} S{ue.semestre_idx or '?'}" """
+                    if modejury:
+                        # pas d'autre colonnes de résultats
+                        continue
                     # Bonus (sport) dans cette UE ?
                     # Le bonus sport appliqué sur cette UE
                     if (self.bonus_ues is not None) and (ue.id in self.bonus_ues):
@@ -632,6 +637,18 @@ class ResultatsSemestre(ResultatsCache):
             elif nb_ues_validables < len(ues_sans_bonus):
                 row["_ues_validables_class"] += " moy_inf"
             row["_ues_validables_order"] = nb_ues_validables  # pour tri
+            if modejury:
+                idx = add_cell(
+                    row,
+                    "jury_link",
+                    "",
+                    f"""<a href="{url_for('notes.formsemestre_validation_etud_form',
+                    scodoc_dept=g.scodoc_dept, formsemestre_id=self.formsemestre.id, etudid=etudid
+                    )
+                    }">saisir décision</a>""",
+                    "col_jury_link",
+                    1000,
+                )
             rows.append(row)
 
         self._recap_add_partitions(rows, titles)
diff --git a/app/scodoc/sco_formsemestre_status.py b/app/scodoc/sco_formsemestre_status.py
index 275605d880e72e47b0725efd7cb734d6099eb18b..50b11f6fa566831fb80ec2d96db49e491fb4ce03 100644
--- a/app/scodoc/sco_formsemestre_status.py
+++ b/app/scodoc/sco_formsemestre_status.py
@@ -404,9 +404,6 @@ def formsemestre_status_menubar(sem):
             "args": {
                 "formsemestre_id": formsemestre_id,
                 "modejury": 1,
-                "hidemodules": 1,
-                "hidebac": 1,
-                "pref_override": 0,
             },
             "enabled": sco_permissions_check.can_validate_sem(formsemestre_id),
         },
diff --git a/app/scodoc/sco_formsemestre_validation.py b/app/scodoc/sco_formsemestre_validation.py
index ba517e6aedf8931659fb16f1ba251c6739abc7ab..f4896a8dc206071cc0a34285a65e7c0caadbff3b 100644
--- a/app/scodoc/sco_formsemestre_validation.py
+++ b/app/scodoc/sco_formsemestre_validation.py
@@ -31,6 +31,7 @@ import time
 
 import flask
 from flask import url_for, g, request
+from app.models.etudiants import Identite
 
 import app.scodoc.notesdb as ndb
 import app.scodoc.sco_utils as scu
@@ -107,29 +108,57 @@ def formsemestre_validation_etud_form(
     if not Se.sem["etat"]:
         raise ScoValueError("validation: semestre verrouille")
 
+    url_tableau = url_for(
+        "notes.formsemestre_recapcomplet",
+        scodoc_dept=g.scodoc_dept,
+        modejury=1,
+        formsemestre_id=formsemestre_id,
+        selected_etudid=etudid,  # va a la bonne ligne
+    )
+
     H = [
         html_sco_header.sco_header(
-            page_title="Parcours %(nomprenom)s" % etud,
+            page_title=f"Parcours {etud['nomprenom']}",
             javascripts=["js/recap_parcours.js"],
         )
     ]
 
-    Footer = ["<p>"]
     # Navigation suivant/precedent
-    if etud_index_prev != None:
-        etud_p = sco_etud.get_etud_info(etudid=T[etud_index_prev][-1], filled=True)[0]
-        Footer.append(
-            '<span><a href="formsemestre_validation_etud_form?formsemestre_id=%s&etud_index=%s">Etud. précédent (%s)</a></span>'
-            % (formsemestre_id, etud_index_prev, etud_p["nomprenom"])
+    if etud_index_prev is not None:
+        etud_prev = Identite.query.get(T[etud_index_prev][-1])
+        url_prev = url_for(
+            "notes.formsemestre_validation_etud_form",
+            scodoc_dept=g.scodoc_dept,
+            formsemestre_id=formsemestre_id,
+            etud_index=etud_index_prev,
         )
-    if etud_index_next != None:
-        etud_n = sco_etud.get_etud_info(etudid=T[etud_index_next][-1], filled=True)[0]
-        Footer.append(
-            '<span style="padding-left: 50px;"><a href="formsemestre_validation_etud_form?formsemestre_id=%s&etud_index=%s">Etud. suivant (%s)</a></span>'
-            % (formsemestre_id, etud_index_next, etud_n["nomprenom"])
+    else:
+        url_prev = None
+    if etud_index_next is not None:
+        etud_next = Identite.query.get(T[etud_index_next][-1])
+        url_next = url_for(
+            "notes.formsemestre_validation_etud_form",
+            scodoc_dept=g.scodoc_dept,
+            formsemestre_id=formsemestre_id,
+            etud_index=etud_index_next,
+        )
+    else:
+        url_next = None
+    footer = ["""<div class="jury_footer"><span>"""]
+    if url_prev:
+        footer.append(
+            f'< <a class="stdlink" href="{url_prev}">{etud_prev.nomprenom}</a>'
         )
-    Footer.append("</p>")
-    Footer.append(html_sco_header.sco_footer())
+    footer.append(
+        f"""</span><span><a class="stdlink" href="{url_tableau}">retour à la liste</a></span><span>"""
+    )
+    if url_next:
+        footer.append(
+            f'<a class="stdlink" href="{url_next}">{etud_next.nomprenom}</a> >'
+        )
+    footer.append("</span></div>")
+
+    footer.append(html_sco_header.sco_footer())
 
     H.append('<table style="width: 100%"><tr><td>')
     if not check:
@@ -171,7 +200,7 @@ def formsemestre_validation_etud_form(
                 """
             )
         )
-        return "\n".join(H + Footer)
+        return "\n".join(H + footer)
 
     H.append(
         formsemestre_recap_parcours_table(
@@ -180,18 +209,10 @@ def formsemestre_validation_etud_form(
     )
     if check:
         if not desturl:
-            desturl = url_for(
-                "notes.formsemestre_recapcomplet",
-                scodoc_dept=g.scodoc_dept,
-                modejury=1,
-                formsemestre_id=formsemestre_id,
-                sortcol=sortcol
-                or None,  # pour refaire tri sorttable du tableau de notes
-                _anchor="etudid%s" % etudid,  # va a la bonne ligne
-            )
+            desturl = url_tableau
         H.append(f'<ul><li><a href="{desturl}">Continuer</a></li></ul>')
 
-        return "\n".join(H + Footer)
+        return "\n".join(H + footer)
 
     decision_jury = Se.nt.get_etud_decision_sem(etudid)
 
@@ -207,7 +228,7 @@ def formsemestre_validation_etud_form(
                 """
             )
         )
-        return "\n".join(H + Footer)
+        return "\n".join(H + footer)
 
     # Infos si pas de semestre précédent
     if not Se.prev:
@@ -345,7 +366,7 @@ def formsemestre_validation_etud_form(
     else:
         H.append("sans semestres décalés</p>")
 
-    return "".join(H + Footer)
+    return "".join(H + footer)
 
 
 def formsemestre_validation_etud(
@@ -937,19 +958,23 @@ def do_formsemestre_validation_auto(formsemestre_id):
     )
     if conflicts:
         H.append(
-            """<p><b>Attention:</b> %d étudiants non modifiés car décisions différentes
-        déja saisies :<ul>"""
-            % len(conflicts)
+            f"""<p><b>Attention:</b> {len(conflicts)} étudiants non modifiés 
+            car décisions différentes déja saisies :
+            <ul>"""
         )
         for etud in conflicts:
             H.append(
-                '<li><a href="formsemestre_validation_etud_form?formsemestre_id=%s&etudid=%s&check=1">%s</li>'
-                % (formsemestre_id, etud["etudid"], etud["nomprenom"])
+                f"""<li><a href="{
+                    url_for('notes.formsemestre_validation_etud_form',
+                    scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id,
+                    etudid=etud["etudid"], check=1)
+                }">{etud["nomprenom"]}</li>"""
             )
         H.append("</ul>")
     H.append(
-        '<a href="formsemestre_recapcomplet?formsemestre_id=%s&modejury=1&hidemodules=1&hidebac=1&pref_override=0">continuer</a>'
-        % formsemestre_id
+        f"""<a href="{url_for('notes.formsemestre_recapcomplet',
+        scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id, modejury=1)
+        }">continuer</a>"""
     )
     H.append(html_sco_header.sco_footer())
     return "\n".join(H)
diff --git a/app/scodoc/sco_recapcomplet.py b/app/scodoc/sco_recapcomplet.py
index 72d16012ce48c58b9872a08755adfe0a137af042..0dc6b19c48292c90de5853df18baf6e978c1043e 100644
--- a/app/scodoc/sco_recapcomplet.py
+++ b/app/scodoc/sco_recapcomplet.py
@@ -32,7 +32,7 @@ import time
 from xml.etree import ElementTree
 
 from flask import g, request
-from flask import make_response, url_for
+from flask import url_for
 
 from app import log
 from app.but import bulletin_but
@@ -40,39 +40,29 @@ from app.comp import res_sem
 from app.comp.res_compat import NotesTableCompat
 from app.models import FormSemestre
 from app.models.etudiants import Identite
-from app.models.evaluations import Evaluation
 
 from app.scodoc.gen_tables import GenTable
 import app.scodoc.sco_utils as scu
 from app.scodoc import html_sco_header
 from app.scodoc import sco_bulletins_json
 from app.scodoc import sco_bulletins_xml
-from app.scodoc import sco_bulletins, sco_excel
 from app.scodoc import sco_cache
-from app.scodoc import sco_codes_parcours
 from app.scodoc import sco_evaluations
-from app.scodoc import sco_evaluation_db
 from app.scodoc.sco_exceptions import ScoValueError
-from app.scodoc import sco_formations
 from app.scodoc import sco_formsemestre
 from app.scodoc import sco_formsemestre_status
-from app.scodoc import sco_groups
 from app.scodoc import sco_permissions_check
 from app.scodoc import sco_preferences
-from app.scodoc import sco_etud
-from app.scodoc import sco_users
-from app.scodoc import sco_xml
-from app.scodoc.sco_codes_parcours import DEF, UE_SPORT
 
 
 def formsemestre_recapcomplet(
     formsemestre_id=None,
-    modejury=False,  # affiche lien saisie decision jury
+    modejury=False,
     tabformat="html",
     sortcol=None,
-    xml_with_decisions=False,  # XML avec decisions
-    rank_partition_id=None,  # si None, calcul rang global
-    force_publishing=True,  # publie les XML/JSON meme si bulletins non publiés
+    xml_with_decisions=False,
+    force_publishing=True,
+    selected_etudid=None,
 ):
     """Page récapitulant les notes d'un semestre.
     Grand tableau récapitulatif avec toutes les notes de modules
@@ -89,7 +79,9 @@ def formsemestre_recapcomplet(
         pdf : NON SUPPORTE (car tableau trop grand pour générer un pdf utilisable)
 
     modejury: cache modules, affiche lien saisie decision jury
-
+    xml_with_decisions: publie décisions de jury dans xml et json
+    force_publishing: publie les xml et json même si bulletins non publiés
+    selected_etudid: etudid sélectionné (pour scroller au bon endroit)
     """
     formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
 
@@ -98,98 +90,92 @@ def formsemestre_recapcomplet(
     xml_with_decisions = int(xml_with_decisions)
     force_publishing = int(force_publishing)
     is_file = tabformat in {"csv", "json", "xls", "xlsx", "xlsall", "xml"}
-    H = []
-    if not is_file:
-        H += [
-            html_sco_header.sco_header(
-                page_title="Récapitulatif",
-                no_side_bar=True,
-                init_qtip=True,
-                javascripts=["js/etud_info.js", "js/table_recap.js"],
-            ),
-            sco_formsemestre_status.formsemestre_status_head(
-                formsemestre_id=formsemestre_id
-            ),
-        ]
-        if len(formsemestre.inscriptions) > 0:
-            H.append(
-                f"""<form name="f" method="get" action="{request.base_url}">
-                <input type="hidden" name="formsemestre_id" value="{formsemestre_id}"></input>
-                """
-            )
-            if modejury:
-                H.append(
-                    f'<input type="hidden" name="modejury" value="{modejury}"></input>'
-                )
-            H.append(
-                '<select name="tabformat" onchange="document.f.submit()" class="noprint">'
-            )
-            for (format, label) in (
-                ("html", "Tableau"),
-                ("evals", "Avec toutes les évaluations"),
-                ("xml", "Bulletins XML (obsolète)"),
-                ("json", "Bulletins JSON"),
-            ):
-                if format == tabformat:
-                    selected = " selected"
-                else:
-                    selected = ""
-                H.append(f'<option value="{format}"{selected}>{label}</option>')
-            H.append("</select>")
-
-            H.append(
-                f"""&nbsp;(cliquer sur un nom pour afficher son bulletin ou <a class="stdlink"
-                href="{url_for('notes.formsemestre_bulletins_pdf',
-                scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id)
-                }">ici avoir le classeur papier</a>)
-                """
-            )
-
-    data = do_formsemestre_recapcomplet(
+    data = _do_formsemestre_recapcomplet(
         formsemestre_id,
         format=tabformat,
         modejury=modejury,
         sortcol=sortcol,
         xml_with_decisions=xml_with_decisions,
-        rank_partition_id=rank_partition_id,
         force_publishing=force_publishing,
+        selected_etudid=selected_etudid,
     )
-    if tabformat == "xml":
-        response = make_response(data)
-        response.headers["Content-Type"] = scu.XML_MIMETYPE
-        return response
-    H.append(data)
-
-    if not is_file:
-        if len(formsemestre.inscriptions) > 0:
-            H.append("</form>")
+    if is_file:
+        return data
+    H = [
+        html_sco_header.sco_header(
+            page_title="Récapitulatif",
+            no_side_bar=True,
+            init_qtip=True,
+            javascripts=["js/etud_info.js", "js/table_recap.js"],
+        ),
+        sco_formsemestre_status.formsemestre_status_head(
+            formsemestre_id=formsemestre_id
+        ),
+    ]
+    if len(formsemestre.inscriptions) > 0:
+        H.append(
+            f"""<form name="f" method="get" action="{request.base_url}">
+            <input type="hidden" name="formsemestre_id" value="{formsemestre_id}"></input>
+            """
+        )
+        if modejury:
             H.append(
-                f"""<p><a class="stdlink" href="{url_for('notes.formsemestre_pvjury',
-                scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id)
-                }">Voir les décisions du jury</a></p>"""
+                f'<input type="hidden" name="modejury" value="{modejury}"></input>'
             )
-            if sco_permissions_check.can_validate_sem(formsemestre_id):
-                H.append("<p>")
-                if modejury:
-                    H.append(
-                        f"""<a class="stdlink" href="{url_for('formsemestre_validation_auto',
-                        formsemestre_id=formsemestre_id)
-                        }">Calcul automatique des décisions du jury</a></p>"""
-                    )
-                else:
-                    H.append(
-                        f"""<a class="stdlink" href="{url_for('notes.formsemestre_recapcomplet',
-                        scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id, modejury=1)
-                        }">Saisie des décisions du jury</a>"""
-                    )
-                H.append("</p>")
-            if sco_preferences.get_preference("use_ue_coefs", formsemestre_id):
+        H.append(
+            '<select name="tabformat" onchange="document.f.submit()" class="noprint">'
+        )
+        for (format, label) in (
+            ("html", "Tableau"),
+            ("evals", "Avec toutes les évaluations"),
+            ("xml", "Bulletins XML (obsolète)"),
+            ("json", "Bulletins JSON"),
+        ):
+            if format == tabformat:
+                selected = " selected"
+            else:
+                selected = ""
+            H.append(f'<option value="{format}"{selected}>{label}</option>')
+        H.append("</select>")
+
+        H.append(
+            f"""&nbsp;(cliquer sur un nom pour afficher son bulletin ou <a class="stdlink"
+            href="{url_for('notes.formsemestre_bulletins_pdf',
+            scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id)
+            }">ici avoir le classeur papier</a>)
+            """
+        )
+    H.append(data)
+
+    if len(formsemestre.inscriptions) > 0:
+        H.append("</form>")
+        H.append(
+            f"""<p><a class="stdlink" href="{url_for('notes.formsemestre_pvjury',
+            scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id)
+            }">Voir les décisions du jury</a></p>"""
+        )
+        if sco_permissions_check.can_validate_sem(formsemestre_id):
+            H.append("<p>")
+            if modejury:
                 H.append(
-                    """
-                <p class="infop">utilise les coefficients d'UE pour calculer la moyenne générale.</p>
-                """
+                    f"""<a class="stdlink" href="{url_for('notes.formsemestre_validation_auto',
+                    scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id)
+                    }">Calcul automatique des décisions du jury</a></p>"""
+                )
+            else:
+                H.append(
+                    f"""<a class="stdlink" href="{url_for('notes.formsemestre_recapcomplet',
+                    scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id, modejury=1)
+                    }">Saisie des décisions du jury</a>"""
                 )
-        H.append(html_sco_header.sco_footer())
+            H.append("</p>")
+        if sco_preferences.get_preference("use_ue_coefs", formsemestre_id):
+            H.append(
+                """
+            <p class="infop">utilise les coefficients d'UE pour calculer la moyenne générale.</p>
+            """
+            )
+    H.append(html_sco_header.sco_footer())
     # HTML or binary data ?
     if len(H) > 1:
         return "".join(H)
@@ -199,18 +185,15 @@ def formsemestre_recapcomplet(
         return H
 
 
-def do_formsemestre_recapcomplet(
+def _do_formsemestre_recapcomplet(
     formsemestre_id=None,
     format="html",  # html, xml, xls, xlsall, json
-    hidemodules=False,  # ne pas montrer les modules (ignoré en XML)
-    hidebac=False,  # pas de colonne Bac (ignoré en XML)
     xml_nodate=False,  # format XML sans dates (sert pour debug cache: comparaison de XML)
     modejury=False,  # saisie décisions jury
     sortcol=None,  # indice colonne a trier dans table T
     xml_with_decisions=False,
-    disable_etudlink=False,
-    rank_partition_id=None,  # si None, calcul rang global
     force_publishing=True,
+    selected_etudid=None,
 ):
     """Calcule et renvoie le tableau récapitulatif."""
     formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
@@ -219,13 +202,15 @@ def do_formsemestre_recapcomplet(
         f"""recap-{formsemestre.titre_num()}-{time.strftime("%Y-%m-%d")}"""
     )
 
-    if (format == "html" or format == "evals") and not modejury:
+    if format == "html" or format == "evals":
         res: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
         data = gen_formsemestre_recapcomplet_html(
             formsemestre,
             res,
             include_evaluations=(format == "evals"),
+            modejury=modejury,
             filename=filename,
+            selected_etudid=selected_etudid,
         )
         return data
     elif format.startswith("xls") or format == "csv":
@@ -388,35 +373,51 @@ def _gen_cell(key: str, row: dict, elt="td"):
     return f"<{elt} {attrs}>{content}</{elt}>"
 
 
-def _gen_row(keys: list[str], row, elt="td"):
+def _gen_row(keys: list[str], row, elt="td", selected_etudid=None):
     klass = row.get("_tr_class")
     tr_class = f'class="{klass}"' if klass else ""
-    return f'<tr {tr_class}>{"".join([_gen_cell(key, row, elt) for key in keys])}</tr>'
+    tr_id = (
+        f"""id="row_selected" """ if (row.get("etudid", "") == selected_etudid) else ""
+    )
+    return f'<tr {tr_id} {tr_class}>{"".join([_gen_cell(key, row, elt) for key in keys])}</tr>'
 
 
 def gen_formsemestre_recapcomplet_html(
     formsemestre: FormSemestre,
     res: NotesTableCompat,
     include_evaluations=False,
+    modejury=False,
     filename="",
+    selected_etudid=None,
 ):
     """Construit table recap pour le BUT
-    Cache le résultat pour le semestre.
+    Cache le résultat pour le semestre (sauf en mode jury).
+
+    Si modejury, cache colonnes modules et affiche un lien vers la saisie de la décision de jury
+
     Return: data, filename
     data est une chaine, le <div>...</div> incluant le tableau.
     """
-    if include_evaluations:
-        table_html = sco_cache.TableRecapWithEvalsCache.get(formsemestre.id)
-    else:
-        table_html = sco_cache.TableRecapCache.get(formsemestre.id)
-    if table_html is None:
-        table_html = _gen_formsemestre_recapcomplet_html(
-            formsemestre, res, include_evaluations, filename
-        )
+    table_html = None
+    if not (modejury or selected_etudid):
         if include_evaluations:
-            sco_cache.TableRecapWithEvalsCache.set(formsemestre.id, table_html)
+            table_html = sco_cache.TableRecapWithEvalsCache.get(formsemestre.id)
         else:
-            sco_cache.TableRecapCache.set(formsemestre.id, table_html)
+            table_html = sco_cache.TableRecapCache.get(formsemestre.id)
+    if modejury or (table_html is None):
+        table_html = _gen_formsemestre_recapcomplet_html(
+            formsemestre,
+            res,
+            include_evaluations,
+            modejury,
+            filename,
+            selected_etudid=selected_etudid,
+        )
+        if not modejury:
+            if include_evaluations:
+                sco_cache.TableRecapWithEvalsCache.set(formsemestre.id, table_html)
+            else:
+                sco_cache.TableRecapCache.set(formsemestre.id, table_html)
 
     return table_html
 
@@ -425,11 +426,13 @@ def _gen_formsemestre_recapcomplet_html(
     formsemestre: FormSemestre,
     res: NotesTableCompat,
     include_evaluations=False,
+    modejury=False,
     filename: str = "",
+    selected_etudid=None,
 ) -> str:
     """Génère le html"""
     rows, footer_rows, titles, column_ids = res.get_table_recap(
-        convert_values=True, include_evaluations=include_evaluations
+        convert_values=True, include_evaluations=include_evaluations, modejury=modejury
     )
     if not rows:
         return (
@@ -437,7 +440,8 @@ def _gen_formsemestre_recapcomplet_html(
         )
     H = [
         f"""<div class="table_recap"><table class="table_recap {
-            'apc' if formsemestre.formation.is_apc() else 'classic'}"
+            'apc' if formsemestre.formation.is_apc() else 'classic'
+            } {'jury' if modejury else ''}"
             data-filename="{filename}">"""
     ]
     # header
@@ -451,7 +455,7 @@ def _gen_formsemestre_recapcomplet_html(
     # body
     H.append("<tbody>")
     for row in rows:
-        H.append(f"{_gen_row(column_ids, row)}\n")
+        H.append(f"{_gen_row(column_ids, row, selected_etudid=selected_etudid)}\n")
     H.append("</tbody>\n")
     # footer
     H.append("<tfoot>")
diff --git a/app/static/css/scodoc.css b/app/static/css/scodoc.css
index e9712ba772333654c9515174da24b2f9d0f06664..3625d5f0139668fc6cf750ecac4e804fadeed955 100644
--- a/app/static/css/scodoc.css
+++ b/app/static/css/scodoc.css
@@ -1146,6 +1146,18 @@ span.jurylink a {
   text-decoration: underline;
 }
 
+div.jury_footer {
+  display: flex;
+  justify-content: space-evenly;
+}
+
+div.jury_footer>span {
+  border: 2px solid rgb(90, 90, 90);
+  border-radius: 4px;
+  padding: 4px;
+  background-color: rgb(230, 242, 230);
+}
+
 .eval_description p {
   margin-left: 15px;
   margin-bottom: 2px;
diff --git a/app/static/js/table_recap.js b/app/static/js/table_recap.js
index 174fb186b8c2cbbc1b69fe63ef3b7618754bea5b..4dcd0c23a5e7b7cd757092005654c421775a8303 100644
--- a/app/static/js/table_recap.js
+++ b/app/static/js/table_recap.js
@@ -21,43 +21,54 @@ $(function () {
                     dt.columns(".partition_aux").visible(!visible);
                     dt.buttons('toggle_partitions:name').text(visible ? "Toutes les partitions" : "Cacher les partitions");
                 }
-            },
-            $('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.columns(".col_ue_bonus").visible(!visible);
-                        dt.columns(".col_malus").visible(!visible);
-                        dt.buttons('toggle_res:name').text(visible ? "Montrer les ressources" : "Cacher les ressources");
+            }];
+        if (!$('table.table_recap').hasClass("jury")) {
+            buttons.push(
+                $('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.columns(".col_ue_bonus").visible(!visible);
+                            dt.columns(".col_malus").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:not(.col_empty)").visible()[0];
+                            dt.columns(".col_mod:not(.col_empty)").visible(!visible);
+                            dt.columns(".col_ue_bonus").visible(!visible);
+                            dt.columns(".col_malus").visible(!visible);
+                            dt.buttons('toggle_mod:name').text(visible ? "Montrer les modules" : "Cacher les modules");
+                            visible = dt.columns(".col_empty").visible()[0];
+                            dt.buttons('toggle_col_empty:name').text(visible ? "Cacher mod. vides" : "Montrer mod. vides");
+                        }
                     }
-                } : {
-                    name: "toggle_mod",
-                    text: "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_mod:not(.col_empty)").visible()[0];
-                        dt.columns(".col_mod:not(.col_empty)").visible(!visible);
-                        dt.columns(".col_ue_bonus").visible(!visible);
-                        dt.columns(".col_malus").visible(!visible);
-                        dt.buttons('toggle_mod:name').text(visible ? "Montrer les modules" : "Cacher les modules");
-                        visible = dt.columns(".col_empty").visible()[0];
-                        dt.buttons('toggle_col_empty:name').text(visible ? "Cacher mod. vides" : "Montrer mod. vides");
+                        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");
                     }
-                }
-        ];
-        if ($('table.table_recap').hasClass("apc")) {
+                })
+            }
             buttons.push({
-                name: "toggle_sae",
-                text: "Cacher les SAÉs",
+                name: "toggle_col_empty",
+                text: "Montrer mod. vides",
                 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");
+                    let visible = dt.columns(".col_empty").visible()[0];
+                    dt.columns(".col_empty").visible(!visible);
+                    dt.buttons('toggle_col_empty:name').text(visible ? "Montrer mod. vides" : "Cacher mod. vides");
                 }
             })
-
         }
         buttons.push({
             name: "toggle_admission",
@@ -68,15 +79,6 @@ $(function () {
                 dt.buttons('toggle_admission:name').text(visible ? "Montrer infos admission" : "Cacher infos admission");
             }
         })
-        buttons.push({
-            name: "toggle_col_empty",
-            text: "Montrer mod. vides",
-            action: function (e, dt, node, config) {
-                let visible = dt.columns(".col_empty").visible()[0];
-                dt.columns(".col_empty").visible(!visible);
-                dt.buttons('toggle_col_empty:name').text(visible ? "Montrer mod. vides" : "Cacher mod. vides");
-            }
-        })
         $('table.table_recap').DataTable(
             {
                 paging: false,
@@ -143,4 +145,10 @@ $(function () {
             $(this).addClass('selected');
         }
     });
+    // Pour montrer et highlihter l'étudiant sélectionné:
+    $(function () {
+        document.querySelector("#row_selected").scrollIntoView();
+        window.scrollBy(0, -50);
+        document.querySelector("#row_selected").classList.add("selected");
+    });
 });