diff --git a/app/but/bulletin_but_court.py b/app/but/bulletin_but_court.py
index 7fb389a5c11e440d8c6b51f7dfcb3609cb514f62..a4fc6ec13ef864fc23aa7b2b6d05e91aff2e6254 100644
--- a/app/but/bulletin_but_court.py
+++ b/app/but/bulletin_but_court.py
@@ -119,6 +119,12 @@ def _build_bulletin_but_infos(
     refcomp = formsemestre.formation.referentiel_competence
     if refcomp is None:
         raise ScoNoReferentielCompetences(formation=formsemestre.formation)
+
+    warn_html = cursus_but.formsemestre_warning_apc_setup(
+        formsemestre, bulletins_sem.res
+    )
+    if warn_html:
+        raise ScoValueError("<b>Formation mal configurée pour le BUT</b>" + warn_html)
     ue_validation_by_niveau = validations_view.get_ue_validation_by_niveau(
         refcomp, etud
     )
diff --git a/app/but/cursus_but.py b/app/but/cursus_but.py
index 1f453882e04cbecd4f1a6a590a2dc6a42759800f..4a16bf05d814d161ea9a5e8550e52894001befc5 100644
--- a/app/but/cursus_but.py
+++ b/app/but/cursus_but.py
@@ -23,29 +23,21 @@ from app.comp.res_but import ResultatsSemestreBUT
 from app.comp.res_compat import NotesTableCompat
 
 from app.models.but_refcomp import (
-    ApcAnneeParcours,
     ApcCompetence,
     ApcNiveau,
     ApcParcours,
-    ApcParcoursNiveauCompetence,
     ApcReferentielCompetences,
 )
-from app.models import Scolog, ScolarAutorisationInscription
-from app.models.but_validations import (
-    ApcValidationAnnee,
-    ApcValidationRCUE,
-)
+from app.models.ues import UEParcours
+from app.models.but_validations import ApcValidationRCUE
 from app.models.etudiants import Identite
 from app.models.formations import Formation
-from app.models.formsemestre import FormSemestre, FormSemestreInscription
+from app.models.formsemestre import FormSemestre
 from app.models.ues import UniteEns
 from app.models.validations import ScolarFormSemestreValidation
 from app.scodoc import codes_cursus as sco_codes
 from app.scodoc.codes_cursus import code_ue_validant, CODES_UE_VALIDES, UE_STANDARD
-
-from app.scodoc import sco_utils as scu
 from app.scodoc.sco_exceptions import ScoNoReferentielCompetences, ScoValueError
-
 from app.scodoc import sco_cursus_dut
 
 
@@ -440,11 +432,16 @@ def formsemestre_warning_apc_setup(
     """
     if not formsemestre.formation.is_apc():
         return ""
+    url_formation = url_for(
+        "notes.ue_table",
+        scodoc_dept=g.scodoc_dept,
+        formation_id=formsemestre.formation.id,
+        semestre_idx=formsemestre.semestre_id,
+    )
     if formsemestre.formation.referentiel_competence is None:
         return f"""<div class="formsemestre_status_warning">
-        La <a class="stdlink" href="{
-            url_for("notes.ue_table", scodoc_dept=g.scodoc_dept, formation_id=formsemestre.formation.id)
-        }">formation n'est pas associée à un référentiel de compétence.</a>
+        La <a class="stdlink" href="{url_formation}">formation
+        n'est pas associée à un référentiel de compétence.</a>
         </div>
         """
     H = []
@@ -462,7 +459,9 @@ def formsemestre_warning_apc_setup(
         )
         if nb_ues_sans_parcours != nb_ues_tot:
             H.append(
-                f"""Le semestre n'est associé à aucun parcours, mais les UEs de la formation ont des parcours"""
+                """Le semestre n'est associé à aucun parcours,
+                mais les UEs de la formation ont des parcours
+                """
             )
     # Vérifie les niveaux de chaque parcours
     for parcour in formsemestre.parcours or [None]:
@@ -489,7 +488,8 @@ def formsemestre_warning_apc_setup(
     if not H:
         return ""
     return f"""<div class="formsemestre_status_warning">
-    Problème dans la configuration de la formation:
+    Problème dans la
+    <a class="stdlink" href="{url_formation}">configuration de la formation</a>:
     <ul>
         <li>{ '</li><li>'.join(H) }</li>
     </ul>
@@ -502,6 +502,76 @@ def formsemestre_warning_apc_setup(
     """
 
 
+def formation_semestre_niveaux_warning(formation: Formation, semestre_idx: int) -> str:
+    """Vérifie que tous les niveaux de compétences de cette année de formation
+    ont bien des UEs.
+    Afin de ne pas générer trop de messages, on ne considère que les parcours
+    du référentiel de compétences pour lesquels au moins une UE a été associée.
+
+    Renvoie fragment de html
+    """
+    annee = (semestre_idx - 1) // 2 + 1  # année BUT
+    ref_comp: ApcReferentielCompetences = formation.referentiel_competence
+    niveaux_sans_ue_by_parcour = {}  # { parcour.code : [ ue ... ] }
+    parcours_ids = {
+        uep.parcours_id
+        for uep in UEParcours.query.join(UniteEns).filter_by(
+            formation_id=formation.id, type=UE_STANDARD
+        )
+    }
+    for parcour in ref_comp.parcours:
+        if parcour.id not in parcours_ids:
+            continue  # saute parcours associés à aucune UE (tous semestres)
+        niveaux_sans_ue = []
+        niveaux = ApcNiveau.niveaux_annee_de_parcours(parcour, annee, ref_comp)
+        # print(f"\n# Parcours {parcour.code} : {len(niveaux)} niveaux")
+        for niveau in niveaux:
+            ues = [ue for ue in formation.ues if ue.niveau_competence_id == niveau.id]
+            if not ues:
+                niveaux_sans_ue.append(niveau)
+                # print( niveau.competence.titre + " " + str(niveau.ordre) + "\t" + str(ue) )
+        if niveaux_sans_ue:
+            niveaux_sans_ue_by_parcour[parcour.code] = niveaux_sans_ue
+    #
+    H = []
+    for parcour_code, niveaux in niveaux_sans_ue_by_parcour.items():
+        H.append(
+            f"""<li>Parcours {parcour_code} : {
+            len(niveaux)} niveaux sans UEs
+            <span>
+            { ', '.join( f'{niveau.competence.titre} {niveau.ordre}'
+                    for niveau in niveaux
+                    )
+            }
+            </span>
+            </li>
+        """
+        )
+    # Combien de compétences de tronc commun ?
+    _, niveaux_by_parcours = ref_comp.get_niveaux_by_parcours(annee)
+    nb_niveaux_tc = len(niveaux_by_parcours["TC"])
+    nb_ues_tc = len(
+        formation.query_ues_parcour(None)
+        .filter(UniteEns.semestre_idx == semestre_idx)
+        .all()
+    )
+    if nb_niveaux_tc != nb_ues_tc:
+        H.append(
+            f"""<li>{nb_niveaux_tc} niveaux de compétences de tronc commun,
+                 mais {nb_ues_tc} UEs de tronc commun !</li>"""
+        )
+
+    if H:
+        return f"""<div class="formation_semestre_niveaux_warning">
+        <div>Problèmes détectés à corriger :</div>
+        <ul>
+            {"".join(H)}
+        </ul>
+        </div>
+        """
+    return ""  # no problem detected
+
+
 def ue_associee_au_niveau_du_parcours(
     ues_possibles: list[UniteEns], niveau: ApcNiveau, sem_name: str = "S"
 ) -> UniteEns:
diff --git a/app/scodoc/sco_bulletins_generator.py b/app/scodoc/sco_bulletins_generator.py
index bda2567e9bfec27f9c39976b9eaaea5dfaa5555f..b8a00f9bfb7b6274b136f8c84e5d4038f1cef393 100644
--- a/app/scodoc/sco_bulletins_generator.py
+++ b/app/scodoc/sco_bulletins_generator.py
@@ -50,14 +50,11 @@ import traceback
 
 import reportlab
 from reportlab.platypus import (
-    SimpleDocTemplate,
     DocIf,
     Paragraph,
-    Spacer,
-    Frame,
     PageBreak,
 )
-from reportlab.platypus import Table, TableStyle, Image, KeepInFrame
+from reportlab.platypus import Table, KeepInFrame
 
 from flask import request
 from flask_login import current_user
@@ -213,26 +210,26 @@ class BulletinGenerator:
                 story.append(PageBreak())  # insert page break at end
 
             return story
-        else:
-            # Generation du document PDF
-            sem = sco_formsemestre.get_formsemestre(formsemestre_id)
-            report = io.BytesIO()  # in-memory document, no disk file
-            document = sco_pdf.BaseDocTemplate(report)
-            document.addPageTemplates(
-                sco_pdf.ScoDocPageTemplate(
-                    document,
-                    author="%s %s (E. Viennet) [%s]"
-                    % (sco_version.SCONAME, sco_version.SCOVERSION, self.description),
-                    title=f"""Bulletin {sem["titremois"]} de {etat_civil}""",
-                    subject="Bulletin de note",
-                    margins=self.margins,
-                    server_name=self.server_name,
-                    filigranne=self.filigranne,
-                    preferences=sco_preferences.SemPreferences(formsemestre_id),
-                )
+
+        # Generation du document PDF
+        sem = sco_formsemestre.get_formsemestre(formsemestre_id)
+        report = io.BytesIO()  # in-memory document, no disk file
+        document = sco_pdf.BaseDocTemplate(report)
+        document.addPageTemplates(
+            sco_pdf.ScoDocPageTemplate(
+                document,
+                author=f"""{sco_version.SCONAME} {
+                    sco_version.SCOVERSION} (E. Viennet) [{self.description}]""",
+                title=f"""Bulletin {sem["titremois"]} de {etat_civil}""",
+                subject="Bulletin de note",
+                margins=self.margins,
+                server_name=self.server_name,
+                filigranne=self.filigranne,
+                preferences=sco_preferences.SemPreferences(formsemestre_id),
             )
-            document.build(story)
-            data = report.getvalue()
+        )
+        document.build(story)
+        data = report.getvalue()
         return data
 
     def buildTableObject(self, P, pdfTableStyle, colWidths):
diff --git a/app/scodoc/sco_edit_apc.py b/app/scodoc/sco_edit_apc.py
index a90d37e57f3c5c3bd589bfb74c2c986320c58a91..b56a93939d02f0b5f2fcb503cdc5f18a8eb923a1 100644
--- a/app/scodoc/sco_edit_apc.py
+++ b/app/scodoc/sco_edit_apc.py
@@ -28,7 +28,7 @@
 from flask.templating import render_template
 
 from app import db
-from app.but import apc_edit_ue
+from app.but import cursus_but
 from app.models import UniteEns, Matiere, Module, FormSemestre, ModuleImpl
 from app.models.validations import ScolarFormSemestreValidation
 from app.scodoc import codes_cursus
@@ -101,18 +101,26 @@ def html_edit_formation_apc(
         ),
     }
 
+    html_ue_warning = {
+        semestre_idx: cursus_but.formation_semestre_niveaux_warning(
+            formation, semestre_idx
+        )
+        for semestre_idx in semestre_ids
+    }
+
     H = [
         render_template(
             "pn/form_ues.j2",
+            codes_cursus=codes_cursus,
+            ects_by_sem=ects_by_sem,
+            editable=editable,
             formation=formation,
+            html_ue_warning=html_ue_warning,
+            icons=icons,
+            scu=scu,
             semestre_ids=semestre_ids,
-            editable=editable,
             tag_editable=tag_editable,
-            icons=icons,
             ues_by_sem=ues_by_sem,
-            ects_by_sem=ects_by_sem,
-            scu=scu,
-            codes_cursus=codes_cursus,
         ),
     ]
     for semestre_idx in semestre_ids:
diff --git a/app/scodoc/sco_edit_ue.py b/app/scodoc/sco_edit_ue.py
index fa40ad552dc2030255defaba129afef5bc2c408b..7e9543ce2554bf5ccb934f211af41946e799d76d 100644
--- a/app/scodoc/sco_edit_ue.py
+++ b/app/scodoc/sco_edit_ue.py
@@ -892,7 +892,9 @@ du programme" (menu "Semestre") si vous avez un semestre en cours);
     <form>
     <input type="checkbox" class="sco_tag_checkbox"
         {'checked' if show_tags else ''}
-    > Montrer les tags des modules voire en ajouter <i>(ceux correspondant aux titres des compétences étant ajoutés par défaut)</i></input>
+    > Montrer les tags des modules voire en ajouter
+    <i>(ceux correspondant aux titres des compétences étant ajoutés par défaut)</i>
+    </input>
     </form>
     """
     )
diff --git a/app/scodoc/sco_formsemestre_inscriptions.py b/app/scodoc/sco_formsemestre_inscriptions.py
index 7ee6439a7209399fc1c725298f510d8f6ce8a43f..f8ddc30d51249b136a60d8184758682522e4894a 100644
--- a/app/scodoc/sco_formsemestre_inscriptions.py
+++ b/app/scodoc/sco_formsemestre_inscriptions.py
@@ -211,8 +211,6 @@ def do_formsemestre_desinscription(
     """Désinscription d'un étudiant.
     Si semestre extérieur et dernier inscrit, suppression de ce semestre.
     """
-    from app.scodoc import sco_formsemestre_edit
-
     formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
     etud = Identite.get_etud(etudid)
     # -- check lock
@@ -258,17 +256,14 @@ def do_formsemestre_desinscription(
     sco_cache.invalidate_formsemestre(formsemestre_id=formsemestre_id)
     # --- Semestre extérieur
     if formsemestre.modalite == "EXT":
-        inscrits = do_formsemestre_inscription_list(
-            args={"formsemestre_id": formsemestre_id}
-        )
-        nbinscrits = len(inscrits)
-        if nbinscrits == 0:
+        if 0 == len(formsemestre.inscriptions):
             log(
                 f"""do_formsemestre_desinscription:
                 suppression du semestre extérieur {formsemestre}"""
             )
-            flash("Semestre exterieur supprimé")
-            sco_formsemestre_edit.do_formsemestre_delete(formsemestre_id)
+            db.session.delete(formsemestre)
+            db.session.commit()
+            flash(f"Semestre extérieur supprimé: {formsemestre.titre_annee()}")
 
     logdb(
         cnx,
@@ -587,26 +582,29 @@ def formsemestre_inscription_option(etudid, formsemestre_id):
         ue_id = ue.id
         ue_descr = ue.acronyme
         if ue.type != UE_STANDARD:
-            ue_descr += " <em>%s</em>" % UE_TYPE_NAME[ue.type]
+            ue_descr += f" <em>{UE_TYPE_NAME[ue.type]}</em>"
         ue_status = nt.get_etud_ue_status(etudid, ue_id)
         if ue_status and ue_status["is_capitalized"]:
             sem_origin = sco_formsemestre.get_formsemestre(ue_status["formsemestre_id"])
-            ue_descr += (
-                ' <a class="discretelink" href="formsemestre_bulletinetud?formsemestre_id=%s&etudid=%s" title="%s">(capitalisée le %s)'
-                % (
-                    sem_origin["formsemestre_id"],
-                    etudid,
-                    sem_origin["titreannee"],
-                    ndb.DateISOtoDMY(ue_status["event_date"]),
-                )
-            )
+            ue_descr += f"""
+                <a class="discretelink" href="{ url_for(
+                    'notes.formsemestre_bulletinetud', scodoc_dept=g.scodoc_dept,
+                    formsemestre_id=sem_origin["formsemestre_id"],
+                    etudid = etudid
+                    )}" title="{sem_origin['titreannee']}">(capitalisée le {
+                        ndb.DateISOtoDMY(ue_status["event_date"])
+                    })
+                """
         descr.append(
             (
-                "sec_%s" % ue_id,
+                f"sec_{ue_id}",
                 {
                     "input_type": "separator",
-                    "title": """<b>%s :</b>  <a href="#" onclick="chkbx_select('%s', true);">inscrire</a> | <a href="#" onclick="chkbx_select('%s', false);">désinscrire</a> à tous les modules"""
-                    % (ue_descr, ue_id, ue_id),
+                    "title": f"""<b>{ue_descr} :</b>
+                    <a href="#" onclick="chkbx_select('{ue_id}', true);">inscrire</a> | <a
+                    href="#" onclick="chkbx_select('{ue_id}', false);">désinscrire</a>
+                    à tous les modules
+                    """,
                 },
             )
         )
@@ -776,9 +774,7 @@ def do_moduleimpl_incription_options(
         # verifie que ce module existe bien
         mods = sco_moduleimpl.moduleimpl_list(moduleimpl_id=moduleimpl_id)
         if len(mods) != 1:
-            raise ScoValueError(
-                "inscription: invalid moduleimpl_id: %s" % moduleimpl_id
-            )
+            raise ScoValueError(f"inscription: invalid moduleimpl_id: {moduleimpl_id}")
         mod = mods[0]
         sco_moduleimpl.do_moduleimpl_inscription_create(
             {"moduleimpl_id": moduleimpl_id, "etudid": etudid},
@@ -790,7 +786,7 @@ def do_moduleimpl_incription_options(
         mods = sco_moduleimpl.moduleimpl_list(moduleimpl_id=moduleimpl_id)
         if len(mods) != 1:
             raise ScoValueError(
-                "desinscription: invalid moduleimpl_id: %s" % moduleimpl_id
+                f"desinscription: invalid moduleimpl_id: {moduleimpl_id}"
             )
         mod = mods[0]
         inscr = sco_moduleimpl.do_moduleimpl_inscription_list(
@@ -798,8 +794,7 @@ def do_moduleimpl_incription_options(
         )
         if not inscr:
             raise ScoValueError(
-                "pas inscrit a ce module ! (etudid=%s, moduleimpl_id=%s)"
-                % (etudid, moduleimpl_id)
+                f"pas inscrit a ce module ! (etudid={etudid}, moduleimpl_id={moduleimpl_id})"
             )
         oid = inscr[0]["moduleimpl_inscription_id"]
         sco_moduleimpl.do_moduleimpl_inscription_delete(
@@ -808,11 +803,13 @@ def do_moduleimpl_incription_options(
 
     H = [
         html_sco_header.sco_header(),
-        """<h3>Modifications effectuées</h3>
-            <p><a class="stdlink" href="%s">
-            Retour à la fiche étudiant</a></p>
-        """
-        % url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid),
+        f"""<h3>Modifications effectuées</h3>
+            <p><a class="stdlink" href="{
+                url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
+            }">
+            Retour à la fiche étudiant</a>
+            </p>
+        """,
         html_sco_header.sco_footer(),
     ]
     return "\n".join(H)
@@ -856,49 +853,59 @@ def formsemestre_inscrits_ailleurs(formsemestre_id):
     """Page listant les étudiants inscrits dans un autre semestre
     dont les dates recouvrent le semestre indiqué.
     """
-    sem = sco_formsemestre.get_formsemestre(formsemestre_id)
     H = [
         html_sco_header.html_sem_header(
             "Inscriptions multiples parmi les étudiants du semestre ",
+            init_qtip=True,
+            javascripts=["js/etud_info.js"],
         )
     ]
     insd = list_inscrits_ailleurs(formsemestre_id)
     # liste ordonnée par nom
-    etudlist = [
-        sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
-        for etudid in insd.keys()
-        if insd[etudid]
-    ]
-    etudlist.sort(key=lambda x: x["nom"])
+    etudlist = [Identite.get_etud(etudid) for etudid, sems in insd.items() if sems]
+    etudlist.sort(key=lambda x: x.sort_key)
     if etudlist:
         H.append("<ul>")
         for etud in etudlist:
             H.append(
-                '<li><a href="%s" class="discretelink">%s</a> : '
-                % (
+                f"""<li><a id="{etud.id}" class="discretelink etudinfo"
+                href={
                     url_for(
                         "scolar.fiche_etud",
                         scodoc_dept=g.scodoc_dept,
-                        etudid=etud["etudid"],
-                    ),
-                    etud["nomprenom"],
-                )
+                        etudid=etud.id,
+                    )
+                }
+                >{etud.nomprenom}</a> :
+                """
             )
             l = []
-            for s in insd[etud["etudid"]]:
+            for s in insd[etud.id]:
                 l.append(
-                    '<a class="discretelink" href="formsemestre_status?formsemestre_id=%(formsemestre_id)s">%(titremois)s</a>'
-                    % s
+                    f"""<a class="discretelink" href="{
+                        url_for('notes.formsemestre_status',
+                            scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id
+                        )}">{s['titremois']}</a>"""
                 )
             H.append(", ".join(l))
             H.append("</li>")
-        H.append("</ul>")
-        H.append("<p>Total: %d étudiants concernés.</p>" % len(etudlist))
         H.append(
-            """<p class="help">Ces étudiants sont inscrits dans le semestre sélectionné et aussi dans d'autres semestres qui se déroulent en même temps ! <br>Sauf exception, cette situation est anormale:</p>
+            f"""
+        </ul>
+        <p><b>Total: {len(etudlist)} étudiants concernés.</b></p>
+
+        <p class="help">Ces étudiants sont inscrits dans le semestre sélectionné et aussi
+        dans d'autres semestres qui se déroulent en même temps !
+        </p>
+        <p>
+            <b>Sauf exception, cette situation est anormale:</b>
+        </p>
         <ul>
-        <li>vérifier que les dates des semestres se suivent sans se chevaucher</li>
-        <li>ou si besoin désinscrire le(s) étudiant(s) de l'un des semestres (via leurs fiches individuelles).</li>
+            <li>vérifier que les dates des semestres se suivent <em>sans se chevaucher</em>
+            </li>
+            <li>ou bien si besoin désinscrire le(s) étudiant(s) de l'un des semestres
+            (via leurs fiches individuelles).
+            </li>
         </ul>
         """
         )
diff --git a/app/scodoc/sco_synchro_etuds.py b/app/scodoc/sco_synchro_etuds.py
index a4a9fd2c8a293eacaa26c7ecb29931327a6f183d..3f5008e3e5142a292abbbdcd3e4637b082e36600 100644
--- a/app/scodoc/sco_synchro_etuds.py
+++ b/app/scodoc/sco_synchro_etuds.py
@@ -110,12 +110,13 @@ def formsemestre_synchro_etuds(
         raise ScoValueError("opération impossible: semestre verrouille")
     if not sem["etapes"]:
         raise ScoValueError(
-            """opération impossible: ce semestre n'a pas de code étape
-        (voir "<a href="formsemestre_editwithmodules?formsemestre_id=%(formsemestre_id)s">Modifier ce semestre</a>")
+            f"""opération impossible: ce semestre n'a pas de code étape
+        (voir <a class="stdlink" href="{
+            url_for('notes.formsemestre_editwithmodules',
+                scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre.id)
+        }">Modifier ce semestre</a>)
         """
-            % sem
         )
-    header = html_sco_header.sco_header(page_title="Synchronisation étudiants")
     footer = html_sco_header.sco_footer()
     base_url = url_for(
         "notes.formsemestre_synchro_etuds",
@@ -166,7 +167,13 @@ def formsemestre_synchro_etuds(
             suffix=scu.XLSX_SUFFIX,
         )
 
-    H = [header]
+    H = [
+        html_sco_header.sco_header(
+            page_title="Synchronisation étudiants",
+            init_qtip=True,
+            javascripts=["js/etud_info.js"],
+        )
+    ]
     if not submitted:
         H += _build_page(
             sem,
diff --git a/app/static/css/scodoc.css b/app/static/css/scodoc.css
index 5d141fd58d07fe976f0f2b760da0fb3e9e4067a4..295be36cff44cd1137c6c345b6dadef169b4c6e5 100644
--- a/app/static/css/scodoc.css
+++ b/app/static/css/scodoc.css
@@ -2411,6 +2411,29 @@ div.formation_list_ues_titre {
   color: #eee;
 }
 
+div.formation_semestre_niveaux_warning {
+  font-weight: bold;
+  color: red;
+  padding: 4px;
+  margin-top: 8px;
+  margin-left: 24px;
+  margin-right: 24px;
+  background-color: yellow;
+  border-radius: 8px;
+}
+div.formation_semestre_niveaux_warning div {
+  color: black;
+  font-size: 110%;
+}
+div.formation_semestre_niveaux_warning ul {
+  list-style-type: none;
+  padding-left: 0;
+}
+div.formation_semestre_niveaux_warning ul li:before {
+  content: '⚠️';
+  margin-right: 10px; /* Adjust space between emoji and text */
+}
+
 div.formation_list_modules,
 div.formation_list_ues {
   border-radius: 18px;
@@ -2426,6 +2449,7 @@ div.formation_list_ues {
 }
 
 div.formation_list_ues_content {
+  margin-top: 4px;
 }
 
 div.formation_list_modules {
@@ -2508,7 +2532,13 @@ div.formation_parcs > div {
   opacity: 0.7;
   border-radius: 4px;
   text-align: center;
-  padding: 4px 8px;
+  padding: 2px 6px;
+  margin-top: 8px;
+  margin-bottom: 2px;
+}
+div.formation_parcs > div.ue_tc {
+  color: black;
+  font-style: italic;
 }
 
 div.formation_parcs > div.focus {
diff --git a/app/templates/pn/form_ues.j2 b/app/templates/pn/form_ues.j2
index 133ccb66a858155b15ee92582f1eb8953f830d8b..437d4da2b3857263ba46cd4113e5712da6fa63be 100644
--- a/app/templates/pn/form_ues.j2
+++ b/app/templates/pn/form_ues.j2
@@ -4,6 +4,7 @@
     <div class="formation_list_ues_titre">Unités d'Enseignement
     semestre {{semestre_idx}} &nbsp;-&nbsp; {{ects_by_sem[semestre_idx] | safe}} ECTS
     </div>
+    {{ html_ue_warning[semestre_idx] | safe }}
     <div class="formation_list_ues_content">
         <ul class="apc_ue_list">
             {% for ue in ues_by_sem[semestre_idx] %}
@@ -62,6 +63,8 @@
                 <div class="formation_parcs">
                             {% for parc in ue.parcours %}
                                 <div>{{ parc.code }}</div>
+                            {% else %}
+                                <div class="ue_tc" title="aucun parcours">Tronc Commun</div>
                             {% endfor %}
                 </div>
                 {% endif %}