diff --git a/app/comp/bonus_spo.py b/app/comp/bonus_spo.py
index 7c9f33550b3d0664d0fe30ad01e7edccc718b25e..0c7df638025175cb22994a832c8b4007fffbe437 100644
--- a/app/comp/bonus_spo.py
+++ b/app/comp/bonus_spo.py
@@ -1469,7 +1469,7 @@ class BonusStNazaire(BonusSport):
         self.bonus_moy_gen = None
 
 
-class BonusTarbes(BonusIUTRennes1):
+class BonusTarbes(BonusSportAdditif):
     """Calcul bonus optionnels (sport, culture), règle IUT de Tarbes.
 
     <ul>
@@ -1491,6 +1491,29 @@ class BonusTarbes(BonusIUTRennes1):
     proportion_point = 1 / 30.0
     classic_use_bonus_ues = True
 
+    # S'applique aussi en classic, sur la moy. gen.
+    def compute_bonus(self, sem_modimpl_moys_inscrits, modimpl_coefs_etuds_no_nan):
+        """calcul du bonus"""
+        # Prend la note de chaque modimpl, sans considération d'UE
+        if len(sem_modimpl_moys_inscrits.shape) > 2:  # apc
+            sem_modimpl_moys_inscrits = sem_modimpl_moys_inscrits[:, :, 0]
+        # ici sem_modimpl_moys_inscrits est nb_etuds x nb_mods_bonus, en APC et en classic
+        note_bonus_max = np.max(sem_modimpl_moys_inscrits, axis=1)  # 1d, nb_etuds
+        nb_ues = len(self.formsemestre.get_ues(with_sport=False))
+
+        bonus_moy_arr = np.where(
+            note_bonus_max > self.seuil_moy_gen,
+            (note_bonus_max - self.seuil_moy_gen) * self.proportion_point,
+            0.0,
+        )
+        # Seuil: bonus dans [min, max] (défaut [0,20])
+        bonus_max = self.bonus_max or 20.0
+        np.clip(bonus_moy_arr, self.bonus_min, bonus_max, out=bonus_moy_arr)
+        if self.formsemestre.formation.is_apc():
+            bonus_moy_arr = np.stack([bonus_moy_arr] * nb_ues).T
+
+        self.bonus_additif(bonus_moy_arr)
+
 
 class BonusTours(BonusDirect):
     """Calcul bonus sport & culture IUT Tours.