Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • mediatek/site-interludes
  • aeltheos/site-kwei
  • mediatek/site-kwei
3 results
Show changes
Showing
with 855 additions and 50 deletions
# Generated by Django 3.2.16 on 2022-12-09 09:28
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('home', '0004_participantmodel_paid'),
]
operations = [
migrations.AddField(
model_name='participantmodel',
name='meal_sunday_evening',
field=models.BooleanField(default=False, verbose_name='repas de dimanche soir'),
),
migrations.AlterField(
model_name='participantmodel',
name='meal_sunday_midday',
field=models.BooleanField(default=False, verbose_name='repas de dimanche midi'),
),
]
# Generated by Django 3.2.16 on 2022-12-09 10:34
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('home', '0005_auto_20221209_1028'),
]
operations = [
migrations.AddField(
model_name='participantmodel',
name='amount_paid',
field=models.PositiveIntegerField(default=0, verbose_name='Montant payé'),
),
]
import datetime
from django.db import models
from django.forms import ValidationError
from django.utils.translation import gettext_lazy as _
from django.utils import timezone
from accounts.models import EmailUser
from site_settings.models import Colors, SiteSettings
def validate_nonzero(value):
"""Make a positive integer field non-zero"""
if value == 0:
raise ValidationError(
_('Cette valeur doit-être non-nulle'),
)
class InterludesActivity(models.Model):
class ActivityModel(models.Model):
"""une activité des interludes (i.e. JDR, murder)..."""
class Status(models.TextChoices):
"""en presentiel ou non"""
PRESENT = "P", _("En présentiel uniquement")
DISTANT = "D", _("En distanciel uniquement")
BOTH = "2", _("Les deux")
class ActivityTypes(models.TextChoices):
"""quantité d'activité"""
GAME = "1 partie", _("Une partie")
GAMES = "2+ parties", _("Quelques parties")
TOURNAMENT = "Tournoi", _("Tournoi")
FREEPLAY = "freeplay", _("Freeplay")
OTHER = "other", _("Autre")
class GameTypes(models.TextChoices):
"""types de jeu"""
CARD_GAME = "jeu cartes", _("Jeu de cartes")
BOARD_GAME = "jeu plateau", _("Jeu de société")
TABLETOP_RPG = "table RPG", _("Jeu de rôle sur table")
LARGE_RPG = "large RPG", _("Jeu de rôle grandeur nature")
VIDEOGAME = "videogame", _("Jeu vidéo")
PARTYGAME = "partygame", _("Party game")
PUZZLE = "puzzle", _("Puzzle ou analogue")
SECRET_ROLES = "secret roles", _("Jeu à rôles secrets")
COOP = "coop", _("Jeu coopératif")
OTHER = "other", _("Autre")
class Availability(models.TextChoices):
"""Diponibilité à un moment donné"""
IDEAL = "0", _("Idéal")
POSSIBLE = "1", _("Acceptable")
UNAVAILABLE = "2", _("Indisponible")
display = models.BooleanField("afficher dans la liste", default=False,
help_text="Si vrai, s'affiche sur la page activités"
)
show_email = models.BooleanField("afficher l'email de l'orga", default=True,
help_text="Si l'affichage d'email global et cette case sont vrai, affiche l'email de l'orga"
)
title = models.CharField("Titre", max_length=200)
duration = models.DurationField("Durée", help_text="format hh:mm:ss")
act_type = models.CharField("Type d'activité", choices=ActivityTypes.choices, max_length=12)
game_type = models.CharField("Type de jeu", choices=GameTypes.choices, max_length=12)
description = models.TextField(
"description", max_length=10000,
help_text='Texte ou html selon la valeur de "Description HTML".\n'
)
desc_as_html = models.BooleanField("Description au format HTML", default=False,
help_text="Assurer vous que le texte est bien formaté, cette option peut casser la page activités."
)
host = models.ForeignKey(
EmailUser, on_delete=models.SET_NULL, verbose_name="Organisateur",
blank=True, null=True
)
host_name = models.CharField(
"nom de l'organisateur", max_length=50, null=True, blank=True,
help_text="Peut-être laissé vide pour des simples activités sans orga"
)
host_email = models.EmailField(
"email de l'organisateur",
help_text="Utilisé pour communiquer la liste des participants si demandé"
)
host_info = models.TextField(
"Autre orgas/contacts", max_length=1000, blank=True, null=True
)
must_subscribe = models.BooleanField("sur inscription", default=False,
help_text="Informatif, il faut utiliser les créneaux pour ajouter dans la liste d'inscription"
)
communicate_participants = models.BooleanField("communiquer la liste des participants à l'orga avant l'événement")
max_participants = models.PositiveIntegerField(
"Nombre maximum de participants", help_text="0 pour illimité"
"Nombre maximum de participants", help_text="0 pour illimité", default=0
)
min_paricipants = models.PositiveIntegerField(
"Nombre minimum de participants"
min_participants = models.PositiveIntegerField(
"Nombre minimum de participants", default=0
)
display = models.BooleanField("afficher cette activité", default=False)
must_subscribe = models.BooleanField("sur inscription", default=False)
host_name = models.CharField("nom de l'organisateur", max_length=50)
host_email = models.EmailField("email de l'organisateur")
description = models.TextField("description", max_length=2000)
on_planning = models.BooleanField("afficher sur le planning", default=False)
start = models.DateTimeField("début", null=True, blank=True)
room = models.CharField("salle", max_length=100, null=True, blank=True)
## Information fournies par le respo
duration = models.DurationField("Durée", help_text="format hh:mm:ss")
desired_slot_nb = models.PositiveIntegerField(
"Nombre de créneaux souhaités", default=1,
validators=[validate_nonzero]
)
notes = models.TextField("Notes privées", max_length=2000, blank=True)
available_friday_evening = models.CharField(
"Crénau vendredi soir", choices=Availability.choices, max_length=1,
default=Availability.POSSIBLE,
)
available_friday_night = models.CharField(
"Crénau vendredi nuit", choices=Availability.choices, max_length=1,
default=Availability.POSSIBLE,
)
available_saturday_morning = models.CharField(
"Crénau samedi matin", choices=Availability.choices, max_length=1,
default=Availability.POSSIBLE,
)
available_saturday_afternoon = models.CharField(
"Crénau samedi après-midi", choices=Availability.choices, max_length=1,
default=Availability.POSSIBLE,
)
available_saturday_evening = models.CharField(
"Crénau samedi soir", choices=Availability.choices, max_length=1,
default=Availability.POSSIBLE,
)
available_saturday_night = models.CharField(
"Crénau samedi nuit", choices=Availability.choices, max_length=1,
default=Availability.POSSIBLE,
)
available_sunday_morning = models.CharField(
"Crénau dimanche matin", choices=Availability.choices, max_length=1,
default=Availability.POSSIBLE,
)
available_sunday_afternoon = models.CharField(
"Crénau dimanche après-midi", choices=Availability.choices, max_length=1,
default=Availability.POSSIBLE,
)
constraints = models.TextField(
"Contraintes particulières", max_length=2000, blank=True, null=True
)
status = models.CharField(
"Présentiel/distanciel", choices=Status.choices, max_length=1,
default=Status.PRESENT, blank=True
)
needs = models.TextField(
"Besoin particuliers", max_length=2000, blank=True, null=True
)
comments = models.TextField(
"Commentaires", max_length=2000, blank=True, null=True
)
@property
def nb_participants(self) -> str:
if self.max_participants == 0:
return "Illimité"
return "{} - {}".format(self.min_paricipants, self.max_participants)
ret = "Illimités"
elif self.max_participants == self.min_participants:
ret = "{}".format(self.min_participants)
else:
ret = "{} - {}".format(self.min_participants, self.max_participants)
if self.must_subscribe:
ret += " (sur inscription)"
return ret
@property
def pretty_duration(self) -> str:
hours, rem = divmod(self.duration.seconds, 3600)
minutes = "{:02}".format(rem // 60) if rem // 60 else ""
return "{}h{}".format(hours, minutes)
@property
def pretty_type(self) -> str:
type = self.ActivityTypes(self.act_type).label
game = self.GameTypes(self.game_type).label
return "{}, {}".format(game, type.lower())
@property
def slug(self) -> str:
"""Returns the planning/display slug for this activity"""
return "act-{}".format(self.id)
@property
def slots(self):
"""Returns a list of slots related to self"""
return SlotModel.objects.filter(activity=self, on_activity=True).order_by("start")
def __str__(self):
return self.title
......@@ -38,7 +195,113 @@ class InterludesActivity(models.Model):
verbose_name = "activité"
class InterludesParticipant(models.Model):
class SlotModel(models.Model):
"""Crénaux indiquant ou une activité se place dans le planning
Dans une table à part car un activité peut avoir plusieurs créneaux.
Les inscriptions se font à des créneaux et non des activités"""
TITLE_SPECIFIER = "{act_title}"
activity = models.ForeignKey(ActivityModel, on_delete=models.CASCADE, verbose_name="Activité")
title = models.CharField(
"Titre", max_length=200, default=TITLE_SPECIFIER,
help_text="Utilisez '{}' pour insérer le titre de l'activité correspondante".format(
TITLE_SPECIFIER),
)
start = models.DateTimeField("début")
duration = models.DurationField(
"durée", blank=True, null=True,
help_text="Format 00:00:00. Laisser vide pour prendre la durée de l'activité correspondante"
)
room = models.CharField("salle", max_length=100, null=True, blank=True)
on_planning = models.BooleanField(
"afficher sur le planning", default=True,
)
on_activity = models.BooleanField(
"afficher dans la description de l'activité", default=True,
)
subscribing_open = models.BooleanField("ouvert aux inscriptions", default=False,
help_text="Si vrai, apparaît dans la liste du formulaire d'inscription"
)
color = models.CharField(
"Couleur", choices=Colors.choices, max_length=1, default=Colors.RED,
help_text="La légende des couleurs est modifiable dans les paramètres"
)
@property
def participants(self):
return ActivityChoicesModel.objects.filter(slot=self, accepted=True)
@property
def end(self):
"""Heure de fin du créneau"""
if self.duration:
return self.start + self.duration
return self.start + self.activity.duration
def conflicts(self, other: "SlotModel") -> bool:
"""Check whether these slots overlap"""
if self.start <= other.start:
return other.start <= self.end
return self.start <= other.end
@staticmethod
def relative_day(date: datetime.datetime) -> int:
"""Relative day to start.
- friday 04:00 -> 03:59 = day 0
- saturday 04:00 -> 03:59 = day 1
- sunday 04:00 -> 03:59 = day 2
returns 0 if no date_start is defined in settings"""
settings = SiteSettings.load()
if settings.date_start:
return (date - timezone.datetime.combine(
settings.date_start, datetime.time(hour=4), timezone.get_current_timezone()
)).days
else:
return 0
@staticmethod
def fake_date(date: datetime.datetime):
"""Fake day for display on the (single day planning)"""
settings = SiteSettings.load()
if settings.date_start:
time = date.timetz()
offset = datetime.timedelta(0)
if time.hour < 4:
offset = datetime.timedelta(days=1)
return timezone.datetime.combine(
settings.date_start + offset,
date.timetz()
)
return None
@property
def start_day(self) -> int:
"""returns a day (0-2)"""
return self.relative_day(self.start)
@property
def end_day(self) -> int:
"""returns a day (0-2)"""
return self.relative_day(self.end)
@property
def planning_start(self) -> int:
return self.fake_date(self.start)
@property
def planning_end(self) -> int:
return self.fake_date(self.end)
def __str__(self) -> str:
return self.title.replace(self.TITLE_SPECIFIER, self.activity.title)
class Meta:
verbose_name = "créneau"
verbose_name_plural = "créneaux"
class ParticipantModel(models.Model):
"""un participant aux interludes"""
class ENS(models.TextChoices):
......@@ -58,36 +321,59 @@ class InterludesParticipant(models.Model):
meal_saturday_midday = models.BooleanField("repas de samedi midi", default=False)
meal_saturday_evening = models.BooleanField("repas de samedi soir", default=False)
meal_sunday_morning = models.BooleanField("repas de dimanche matin", default=False)
meal_sunday_midday = models.BooleanField("repas de dimanche soir", default=False)
meal_sunday_midday = models.BooleanField("repas de dimanche midi", default=False)
meal_sunday_evening = models.BooleanField("repas de dimanche soir", default=False)
sleeps = models.BooleanField("dormir sur place", default=False)
mug = models.BooleanField("commander une tasse", default=False)
paid = models.BooleanField("payé(e)", default=False)
# mug = models.BooleanField("commander une tasse", default=False)
nb_murder = models.PositiveIntegerField("Nombre de murder réalisées", default=0)
comment = models.TextField("Commentaire", max_length=2000, blank=True, null=True)
amount_paid = models.PositiveIntegerField("Montant payé", default=0)
def __str__(self) -> str:
return "{} {} ({})".format(self.user.first_name, self.user.last_name, self.school)
school = self.ENS(self.school).label.replace("ENS ", "") if self.school else ""
return "{} {} ({})".format(self.user.first_name, self.user.last_name, school)
@property
def nb_meals(self) -> int:
return (
self.meal_friday_evening + self.meal_saturday_evening + self.meal_saturday_midday +
self.meal_saturday_morning + self.meal_sunday_midday + self.meal_sunday_morning +
self.meal_sunday_evening
)
@property
def cost(self) -> int:
return (
(self.is_registered*2 + self.nb_meals) * (2+self.paid) - (self.paid*self.meal_sunday_evening)
)
class Meta:
verbose_name = "participant"
class ActivityList(models.Model):
class ActivityChoicesModel(models.Model):
"""liste d'activités souhaitée de chaque participant,
avec un order de priorité"""
priority = models.PositiveIntegerField("priorité")
participant = models.ForeignKey(
InterludesParticipant, on_delete=models.CASCADE, db_column="participant"
ParticipantModel, on_delete=models.CASCADE, verbose_name="participant",
)
activity = models.ForeignKey(
InterludesActivity, on_delete=models.CASCADE, db_column="activité"
slot = models.ForeignKey(
SlotModel, on_delete=models.CASCADE, verbose_name="créneau",
)
accepted = models.BooleanField(default=False)
accepted = models.BooleanField("Obtenue", default=False)
class Meta:
# couples uniques
unique_together = (("priority", "participant"), ("participant", "activity"))
unique_together = (("priority", "participant"), ("participant", "slot"))
ordering = ("participant", "priority")
verbose_name = "choix d'activités"
verbose_name_plural = "choix d'activités"
EmailUser.profile = property(lambda user: InterludesParticipant.objects.get_or_create(user=user)[0])
EmailUser.profile = property(lambda user: ParticipantModel.objects.get_or_create(user=user)[0])
......@@ -4,12 +4,12 @@
--color_bg_2: #26263c;
--color_bg_3: #39395c;
--color_sep: #eb811b;
--color_header: #e4e4e4;
}
html, body {
background-color: #dddddd;
color: #333;
font-size: 18px;
font-weight: 300;
line-height: 1.5;
font-family: Arial, Roboto, Helvetica, sans-serif;
......@@ -27,6 +27,10 @@ body {
margin: 0px 0px 50px;
}
/* ===========================
// Header
// =========================== */
header {
display: flex;
background-color: var(--color_bg_1);
......@@ -37,7 +41,7 @@ header {
}
header > * {
color: #ddd;
color: var(--color_header);
}
header h1, header h1 a, header h1 a:visited, header h1 a:active {
......@@ -47,6 +51,14 @@ header h1, header h1 a, header h1 a:visited, header h1 a:active {
margin: 10px 0;
flex: 1;
}
header h1 a {
display: flex;
justify-content: space-between;
align-items: center;
}
header h1 img {
height: 80px;
}
header #head_main_infos {
display: flex;
......@@ -60,25 +72,49 @@ header #head_main_infos {
header h1, header h1 a {
font-size: 50px;
}
header h1 img {
height: 60px;
}
header #head_main_infos {
font-size: 10pt;
font-size: 15pt;
}
}
@media (max-width: 600px) {
@media (max-width: 700px) {
header, header h1 a {
flex-direction: column;
}
header h1, header h1 a {
font-size: 30px;
}
header #head_main_infos {
font-size: 8pt;
font-size: 12pt;
flex-direction: row;
}
header #head_main_infos div {
padding: 0 10px 10px;
}
}
div.easter_egg {
display: inline-block;
}
#circle {
-webkit-clip-path: circle(50% at 50% 50%);
clip-path: circle(50% at 50% 50%)
}
/* ===========================
// Navbar
// =========================== */
nav {
text-align: center;
display: flex;
justify-content: center space-around;
background-color: var(--color_bg_2);
color: white;
color: var(--color_header);
margin: 0;
padding: 0 20px;
border-bottom: 6px solid var(--color_bg_1);
......@@ -87,7 +123,7 @@ nav {
nav a {
padding: 5px;
font-size: 20px;
color: white;
color: var(--color_header);
text-decoration: none;
text-emphasis: bold;
width: 100%;
......@@ -99,10 +135,49 @@ nav a:hover {
background-color: var(--color_bg_3);
transition-duration: 0.5s;
}
nav a:focus {
background-color: var(--color_bg_3);
}
nav a.current {
background-color: var(--color_bg_1);
}
nav a.icon {
display: none;
width: 40px;
}
/* hide all links except home and display menu icon */
@media (max-width: 600px) {
nav {
padding: 0;
}
nav a:not(:first-child) {display: none;}
nav a.icon {
float: right;
display: block;
}
/* The "responsive" class is added bu JS when the user click the menu icon */
nav.responsive {
position: relative;
flex-direction: column;
justify-content: start;
}
nav.responsive a.icon {
position: absolute;
right: 0px;
top: 0;
}
nav.responsive a {
float: none;
display: block;
}
}
/* ===========================
// Main
// =========================== */
main {
background-color: var(--color-bg);
......@@ -111,7 +186,6 @@ main {
padding: 1px 30px 50px;
max-width: 920px;
margin: 0 auto 0 auto;
min-height: calc(100vh - 370px); /* viewport-height - (header+footer+nav bar) */
}
main h2 {
......@@ -133,24 +207,92 @@ main h3 {
border-image-source: linear-gradient(to right, var(--color_bg_1) 0%, transparent 75%);
border-image-slice: 1;
}
@media (max-width: 600px) {
main {
padding-left: 10px;
padding-right: 10px;
}
main h2 {
font-size: 1.1rem;
}
main h3 {
font-size: 1rem;
}
}
main p {
font-size: 1rem;
}
strong {
font-weight: bold;
}
.underline {
text-decoration: underline;
}
main a:link {
text-decoration: underline;
color: rgb(62, 62, 255);
}
.flex {
display: flex;
}
.wrap {
flex-flow: row wrap;
flex-wrap: wrap;
}
.antispam {
unicode-bidi: bidi-override;
direction: rtl;
}
/* ===========================
// Metrics
// =========================== */
.lines {
border-top: 2px solid #333;
border-bottom: 2px solid #333;
justify-content: left
}
.stat {
min-width: 120px;
text-align: center;
padding: 5px;
}
.stat .qty {
font-size: 1.2em;
}
.stat .nb_big {
font-size: 3em;
}
.stat .nb_small {
font-size: 2em;
}
@media (max-width:600px) {
.stat {
min-width: 0;
}
}
/* ===========================
// Lists
// =========================== */
dl {
list-style: none;
display: grid;
grid-template-columns: 1fr 4fr;
grid-template-columns: auto auto;
justify-content: left;
padding-left: 10px;
margin-bottom: 5px;
}
dl dt {
grid-column: 1 / span 1;
justify-self: end;
text-align: right;
font-weight: bold;
......@@ -160,20 +302,25 @@ dl dd {
justify-self: start;
text-align: left;
}
span.helptext {
color: #444444;
font-size: 0.8em;
font-style: italic;
div.desc {
margin-top: 0;
padding: 0 10px 20px;
}
.flex {
display: flex;
div.desc p {
margin: 0;
}
div.desc p.indent {
text-indent: 25px;
}
/* ===========================
// Forms
// =========================== */
.button, .button:link, .button:visited, input[type=submit] {
color: white;
text-decoration: none;
font-size: 1em;
background-color: var(--color_bg_1);
padding: 7px 10px;
margin: 5px;
......@@ -183,6 +330,25 @@ span.helptext {
.button:hover, input[type=submit]:hover {
background-color: var(--color_bg_2);
}
.disabled, .disabled:hover {
color: black;
background-color: #888;
cursor: not-allowed;
}
span.helptext {
color: #444444;
font-size: 0.8em;
font-style: italic;
}
.activity-form p {
flex-grow: 1;
max-width: 500px;
}
.activity-form select {
width: 100%;
}
ul.errorlist {
color: red;
......@@ -206,6 +372,10 @@ div.error {
margin: 10px;
}
/* ===========================
// Messages
// =========================== */
ul.messagelist {
padding: 0;
margin-top: 20px;
......@@ -221,6 +391,7 @@ ul.messagelist li {
ul.messagelist li:before {
font-family: "Font Awesome 5 Free";
padding-right: 10px;
margin-left: -30px;
font-weight: 900;
}
ul.messagelist li.success {
......@@ -248,21 +419,180 @@ ul.messagelist li.info:before {
content: "\f05a";
}
/* ===========================
// Location
// =========================== */
.centered {
font-size: 1.5rem;
text-align: center;
}
#interactive-map {
width: 100%;
margin-bottom: 10px;
}
#public-transport-info {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
font-size: 1.3rem;
margin-left: -20%;
white-space: nowrap;
}
#public-transport-info > * {
margin: 5px;
justify-self: left;
}
#public-transport-info img {
width: 40px;
height: 35px;
margin: 0 5px 0 0;
}
#transport-ratp-metro-icon,
#transport-ratp-metro-stop,
#transport-ratp-bus-1-icon,
#transport-ratp-bus-1-stop,
#transport-tcl-metro,
#transport-tcl-bus-1 {
grid-row: 1;
}
#transport-ratp-rer-icon,
#transport-ratp-rer-stop,
#transport-ratp-bus-2-icon,
#transport-ratp-bus-2-stop,
#transport-tcl-tram-1,
#transport-tcl-bus-2,
#transport-tcl-stop {
grid-row: 2;
}
#transport-ratp-noctilien-icon,
#transport-ratp-noctilien-stop,
#transport-tcl-tram-2,
#transport-tcl-bus-3 {
grid-row: 3;
}
#transport-ratp-metro-icon,
#transport-ratp-rer-icon{
grid-column: 1;
justify-self: end;
}
#transport-ratp-metro-stop,
#transport-ratp-rer-stop,
#transport-tcl-stop {
grid-column: 2;
}
#transport-ratp-bus-1-icon,
#transport-ratp-bus-2-icon,
#transport-ratp-noctilien-icon,
#transport-tcl-metro,
#transport-tcl-tram-1,
#transport-tcl-tram-2 {
grid-column: 3;
justify-self: end;
}
#transport-ratp-bus-1-stop,
#transport-ratp-bus-2-stop,
#transport-ratp-noctilien-stop,
#transport-tcl-bus-1,
#transport-tcl-bus-2,
#transport-tcl-bus-3 {
grid-column: 4;
}
@media (max-width: 800px) {
.centered {
font-size: 1.2rem;
}
#public-transport-info {
grid-template-columns: 1fr 1fr;
grid-template-rows: auto auto auto auto auto;
align-items: center;
}
#transport-ratp-metro-icon,
#transport-ratp-metro-stop {
grid-row: 1;
}
#transport-ratp-rer-icon,
#transport-ratp-rer-stop {
grid-row: 2;
}
#transport-ratp-bus-1-icon,
#transport-ratp-bus-1-stop {
grid-row: 3;
}
#transport-ratp-bus-2-icon,
#transport-ratp-bus-2-stop {
grid-row: 4;
}
#transport-ratp-noctilien-icon,
#transport-ratp-noctilien-stop {
grid-row: 5;
}
#transport-ratp-metro-icon,
#transport-ratp-rer-icon,
#transport-ratp-bus-1-icon,
#transport-ratp-bus-2-icon,
#transport-ratp-noctilien-icon {
grid-column: 1;
justify-self: end;
}
#transport-ratp-metro-stop,
#transport-ratp-rer-stop,
#transport-ratp-bus-1-stop,
#transport-ratp-bus-2-stop,
#transport-ratp-noctilien-stop {
grid-column: 2;
}
}
@media (max-width: 600px) {
#public-transport-info {
font-size: 1em;
}
#public-transport-info img {
width: 30px;
height: 25px;
}
}
/* ===========================
// Footer
// =========================== */
footer {
position: absolute;
bottom: 0;
width: calc(100% - 80px); /* viewport width - padding */
padding: 10px 40px;
height: 50px;
color: white;
width: 100%;
text-align: center;
color: var(--color_header);
display: flex;
background-color: var(--color_bg_1);
border-top: 5px solid var(--color_bg_2);
align-items: center;
justify-content: space-around;
}
footer #sponsors img {
margin: 0;
height: 40px;
margin-right: 20px;
}
\ No newline at end of file
padding: 5px;
}
@media (max-width: 500px) {
main {
padding-bottom: 80px;
}
footer #sponsors img {
margin: 0;
height: 30px;
}
footer {
flex-direction: column;
}
footer p {
margin: 5px;
}
}
home/static/imgs/2021/favicon.ico

177 KiB

home/static/imgs/2021/logo.png

184 KiB

home/static/imgs/2021/logo_easter_egg.png

207 KiB

home/static/imgs/2021/logo_grey.png

183 KiB

home/static/imgs/2021/logointerludes.png

184 KiB

home/static/imgs/2022/bul.png

147 KiB

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="561.182px" height="235.275px" viewBox="0 0 561.182 235.275" enable-background="new 0 0 561.182 235.275"
xml:space="preserve">
<g>
<path d="M40.278,35.72c0,0.807-0.149,1.384-0.446,1.733c-0.297,0.347-0.591,0.521-1.158,0.521c-0.551,0-0.86-0.184-1.162-0.549
c-0.303-0.366-0.454-0.934-0.454-1.706V27.1H34.71v8.62c0,1.346,0.376,2.387,1.128,3.123c0.753,0.737,1.619,1.105,2.836,1.105
c1.218,0,2.062-0.365,2.815-1.101c0.752-0.733,1.128-1.775,1.128-3.128V27.1h-2.339V35.72z"/>
<polygon points="50.723,35.172 50.672,35.191 46.996,27.1 44.64,27.1 44.64,39.766 46.996,39.766 46.996,31.684 47.045,31.667
50.723,39.766 53.062,39.766 53.062,27.1 50.723,27.1 "/>
<rect x="55.424" y="27.1" width="2.339" height="12.666"/>
<polygon points="65.112,39.766 68.476,27.1 66.005,27.1 63.997,36.555 63.906,37.016 63.857,37.016 63.765,36.531 61.773,27.1
59.303,27.1 62.665,39.766 "/>
<polygon points="76.998,37.791 72.245,37.791 72.245,34.207 76.287,34.207 76.287,32.233 72.245,32.233 72.245,29.075
76.981,29.075 76.981,27.1 69.891,27.1 69.891,39.767 76.998,39.767 "/>
<path d="M83.912,35.25c0.245,0.348,0.367,0.839,0.367,1.471v0.861c0,0.436,0.025,0.86,0.075,1.277
c0.049,0.418,0.17,0.72,0.363,0.906h2.43v-0.184c-0.194-0.18-0.328-0.468-0.406-0.864c-0.076-0.399-0.114-0.771-0.114-1.119v-0.895
c0-0.766-0.137-1.404-0.41-1.915c-0.272-0.511-0.718-0.876-1.334-1.097c0.54-0.282,0.949-0.665,1.23-1.143
c0.282-0.478,0.422-1.049,0.422-1.71c0-1.171-0.337-2.085-1.012-2.744c-0.676-0.658-1.604-0.988-2.79-0.988h-3.924v12.658h2.346
v-5.038h1.702C83.315,34.729,83.665,34.904,83.912,35.25 M82.725,32.755h-1.57v-3.672h1.578c0.474,0,0.836,0.173,1.083,0.514
c0.247,0.342,0.371,0.803,0.371,1.383c0,0.569-0.124,1.006-0.371,1.314C83.568,32.602,83.204,32.755,82.725,32.755"/>
<path d="M92.926,32.371c-0.722-0.329-1.229-0.629-1.521-0.899c-0.291-0.27-0.438-0.614-0.438-1.031c0-0.451,0.13-0.828,0.393-1.127
c0.261-0.299,0.627-0.447,1.095-0.447c0.502,0,0.89,0.179,1.165,0.54c0.276,0.359,0.413,0.828,0.413,1.409h2.282l0.016-0.053
c0.022-1.107-0.326-2.025-1.041-2.754c-0.717-0.728-1.649-1.091-2.794-1.091c-1.13,0-2.058,0.325-2.785,0.978
c-0.728,0.652-1.091,1.498-1.091,2.536c0,1.05,0.312,1.866,0.938,2.448c0.625,0.583,1.563,1.104,2.814,1.562
c0.611,0.278,1.038,0.562,1.28,0.849c0.244,0.287,0.365,0.679,0.365,1.172c0,0.475-0.12,0.851-0.361,1.129
c-0.239,0.279-0.606,0.417-1.102,0.417c-0.634,0-1.108-0.17-1.421-0.511c-0.314-0.344-0.471-0.906-0.471-1.689h-2.29l-0.017,0.053
c-0.026,1.316,0.379,2.327,1.218,3.031c0.842,0.704,1.835,1.058,2.981,1.058c1.15,0,2.073-0.312,2.768-0.931
c0.695-0.621,1.042-1.48,1.042-2.577c0-1.06-0.289-1.902-0.865-2.525S94.066,32.778,92.926,32.371"/>
<rect x="98.383" y="27.1" width="2.338" height="12.666"/>
<polygon points="102.186,29.075 104.879,29.075 104.879,39.767 107.226,39.767 107.226,29.075 109.938,29.075 109.938,27.1
102.186,27.1 "/>
<polygon points="117.583,23.933 117.559,23.882 115.086,23.882 113.632,26.19 115.525,26.196 "/>
<polygon points="113.847,37.791 113.847,34.207 117.889,34.207 117.889,32.233 113.847,32.233 113.847,29.075 118.583,29.075
118.583,27.1 111.492,27.1 111.492,39.767 118.599,39.767 118.599,37.791 "/>
<path d="M38.337,42.279h-3.635v12.665h3.635c1.235,0,2.254-0.489,3.059-1.47c0.804-0.979,1.206-2.244,1.206-3.792V47.55
c0-1.549-0.402-2.814-1.206-3.797S39.573,42.279,38.337,42.279 M40.254,49.679c0,0.993-0.176,1.789-0.532,2.39
c-0.355,0.601-0.862,0.901-1.516,0.901h-1.149v-8.717h1.149c0.654,0,1.161,0.3,1.516,0.896c0.356,0.599,0.532,1.392,0.532,2.378
V49.679z"/>
<polygon points="46.993,49.386 51.034,49.386 51.034,47.411 46.993,47.411 46.993,44.252 51.727,44.252 51.727,42.279
44.638,42.279 44.638,54.944 51.745,54.944 51.745,52.97 46.993,52.97 "/>
<polygon points="59.74,42.279 57.385,42.279 57.385,54.944 63.842,54.944 63.842,52.97 59.74,52.97 "/>
<polygon points="67.282,47.707 67.232,47.707 65.247,42.279 62.679,42.279 66.058,50.282 66.058,54.944 68.407,54.944
68.407,50.438 71.843,42.279 69.29,42.279 "/>
<path d="M76.657,42.097c-1.267,0-2.281,0.421-3.04,1.264c-0.761,0.845-1.14,2.007-1.14,3.485v3.548c0,1.485,0.379,2.646,1.14,3.481
c0.759,0.834,1.776,1.253,3.049,1.253s2.292-0.419,3.058-1.253c0.765-0.836,1.148-1.996,1.148-3.481v-3.548
c0-1.479-0.384-2.641-1.155-3.485C78.945,42.518,77.926,42.097,76.657,42.097 M78.534,50.396c0,0.919-0.16,1.608-0.48,2.067
c-0.319,0.46-0.782,0.688-1.388,0.688c-0.611,0-1.075-0.228-1.389-0.688c-0.312-0.459-0.47-1.148-0.47-2.067v-3.577
c0-0.913,0.153-1.599,0.462-2.058c0.309-0.461,0.772-0.69,1.388-0.69c0.613,0,1.078,0.231,1.397,0.693
c0.32,0.464,0.48,1.147,0.48,2.055V50.396z"/>
<polygon points="88.996,50.351 88.946,50.369 85.269,42.279 82.913,42.279 82.913,54.943 85.269,54.943 85.269,46.863
85.319,46.846 88.996,54.943 91.334,54.943 91.334,42.279 88.996,42.279 "/>
<path d="M112.127,142.275c-0.009,11.787-0.019,27.052-0.019,27.19c0,19.518-15.883,35.401-35.424,35.405
c-0.069,0-0.136-0.004-0.203-0.006h-0.009h-0.003c-0.068,0.002-0.134,0.006-0.202,0.006c-19.542-0.004-35.426-15.889-35.426-35.405
c0-0.14-0.009-15.414-0.017-27.19H34.3c0.01,11.768,0.019,27.03,0.019,27.193c0,23.116,18.811,41.926,41.933,41.926
c0.076,0,0.149-0.005,0.223-0.005c0.075,0,0.147,0.005,0.223,0.005c23.123,0,41.933-18.81,41.933-41.926
c0-0.16,0.009-15.414,0.018-27.193H112.127z"/>
<path d="M99.046,142.275c-0.01,11.852-0.018,27.126-0.018,27.17c0,12.315-10.018,22.335-22.331,22.335
c-0.073,0-0.143-0.006-0.216-0.009v-0.003c0,0-0.005,0.003-0.009,0.003c0,0-0.001-0.003-0.003-0.003v0.003
c-0.072,0.003-0.143,0.009-0.215,0.009c-12.314,0-22.331-10.02-22.331-22.335c0-0.044-0.009-15.323-0.019-27.17h-6.567
l0.013,20.296c0.004,4.075,0.006,6.825,0.006,6.878c0,15.935,12.969,28.898,28.912,28.898c0.07,0,0.137-0.003,0.207-0.003
c0.068,0,0.137,0.003,0.207,0.003c15.941,0,28.913-12.965,28.913-28.898c0-0.053,0.001-2.803,0.005-6.878l0.013-20.296H99.046
L99.046,142.275z"/>
<path d="M85.884,142.275c-0.008,12.051-0.019,26.914-0.019,26.957c0,5.168-4.183,9.378-9.342,9.414h-0.048h-0.049
c-5.157-0.036-9.342-4.246-9.342-9.414c0-0.043-0.009-14.9-0.019-26.957h-6.582c0.01,12.057,0.019,26.914,0.019,26.957
c0,8.813,7.161,15.98,15.967,15.995v0.003h0.006h0.005l0.001-0.003c8.807-0.015,15.968-7.183,15.968-15.995
c0-0.043,0.009-14.906,0.019-26.957H85.884z"/>
<rect x="34.468" y="129.298" width="84.191" height="6.49"/>
<rect x="34.468" y="116.319" width="84.191" height="6.49"/>
<path d="M120.642,68.449c0,0-0.134-0.244-0.406-0.542c-0.269-0.304-0.949-0.714-1.276-1.034c-0.323-0.334-0.712-0.853-0.903-0.986
c-0.184-0.138-0.574-0.753-0.753-0.894c-0.199-0.137-0.417-1.142-0.443-1.253c-0.021-0.107-0.1-0.413-0.4-0.572
c-0.17-0.072-0.635-0.381-0.939-0.623c-0.293-0.246-1.048-0.981-1.048-0.981s-0.198-1.223-0.491-1.87
c-0.295-0.657-0.414-0.9-0.554-1.146c-0.13-0.247-0.216-0.297-0.289-0.68c0,0-0.411-0.031-0.793,0.214c0,0-0.786-0.598-1.57-1.058
c-0.791-0.467-1.721-0.951-2.105-1.027c-0.371-0.086-0.88-0.381-1.077-0.572c0,0-0.557-0.027-1.009,0.05
c-0.325,0.042-1.401,0.152-1.972,0.238c-0.568,0.075-1.971,0.311-2.291,0.333c-0.677,0.047-0.817,0.099-1.835,0.291
c0,0-0.806,0.142-1.08,0.247c-0.276,0.109-1.145,0.447-1.748,0.522c-0.661,0.08-1.352,0.083-2.148,0.211
c-0.357,0.064-1.706,0.603-2.342,0.751c-0.286,0.07-0.671,0.115-0.671,0.115s0.13,0.451,0.482,0.532c0,0-0.188,0.404-0.625,0.618
c-0.435,0.225-0.892,0.41-1.488,0.632c-0.606,0.209-1.553,0.589-1.798,0.783c0,0,0.19,0.378,0.562,0.579
c0,0,0.09,0.052-0.423,0.313c-0.522,0.279-1.701,0.769-2.234,1.012c-0.552,0.248-1.296,0.689-1.662,0.869
c-0.52,0.271-0.571,0.284-1.067,0.594c-0.486,0.296-0.239,0.279-0.239,0.279s0.244,0.054,0.589,0.079
c0.357,0.027,0.547,0.165,0.547,0.165s0.038,0.189-0.211,0.411c-0.244,0.215-0.599,0.7-1.439,1.276
c-0.417,0.282-0.78,0.607-1.238,0.929c-0.462,0.319-0.929,0.869-1.093,0.98l0.492,0.434l-0.074,0.34
c-0.213,0.133-0.48,0.281-0.818,0.414c-0.382,0.168-3.65,0.608-7.427,0.562c-6.309-0.087-8.048-0.9-11.26-1.046
c-3.219-0.15-5.606,0.563-8.544,1.458c-0.578,0.176-1.031,0.353-1.374,0.527c-1.235,0.256-2.481,0.6-3.623,1.04
c-4.087,1.567-11.221,7.473-13.218,8.313c-1.969,0.832-3.079,0.872-4.478,0.697c-1.397-0.172-1.948-0.524-1.948-0.524
s-0.713-1.516-1.533-2.134c-1.069-0.786-3.702-1.718-3.702-1.718s-0.459,1.729,0.475,3.396c1.123,1.987,3.317,1.862,4.11,2.187
c1.399,0.563,4.736,1.239,7.551,0.109c2.526-1.016,5.088-2.697,6.912-3.722c1.817-1.018,4.73-1.903,7.183-2.178
c-0.114,0.426-0.238,0.843-0.369,1.213c-0.687,2.087-3.223,6.515-3.74,7.251c-0.597,0.866-2.968,3.738-3.387,4.088
c-0.408,0.357-1.413,0.754-2.673,0.986c-1.385,0.258-5.36,0.657-5.36,0.657s-0.701,3.553-1.582,5.722
c-0.359,0.882-1.209,2.636-1.209,2.636s1.492,1.391,1.966,3.132c0.233,0.446,0.624,1.179,0.93,1.407v6.168h0.006v0.178h84.191
v-6.488h-0.002c0.157-0.494,0.384-1.61-0.587-2.074c-1.257-0.6-0.246-1.075-3.162-2.181c-0.835-0.318-2.228-0.765-2.7-1.154
c-0.469-0.381-2.995-3.911-4.248-5.397c-1.263-1.497-3.837-4.915-3.837-4.915l-0.567-1.35l0.102-1.02
c0.159-0.167,0.331-0.331,0.481-0.522c0.457-0.49,1.152-1.218,1.349-1.623c0.479-0.97,0.309-0.023,0.605-0.55
c0.222-0.4,1.087-0.877,1.447-1.106c0.354-0.215,0.882-0.869,0.882-0.869s0.013,0.39,0.16,0.767c0,0,0.252-0.208,0.653-0.699
c0.401-0.487,0.264-0.534,0.755-1.029c0.492-0.485,0.841-1.456,1.151-2.089c0.318-0.621,0.503-0.803,0.585-0.938
c0,0,0.208,0.498,0.345,0.849c0,0,0.322-0.311,0.457-0.621c0.132-0.311,0.224-0.714,0.446-1.067c0.222-0.36,0.39-0.823,0.605-0.915
c0.227-0.092,0.65-0.354,1.104-0.377c0.33-0.016,0.784,0.173,1.195,0.258c0.391,0.095,0.576-0.085,0.846,0.267
c0.264,0.357,0.625,0.543,0.625,0.543s0.006-0.056,0.331-0.219c0.33-0.167,0.349-0.162,0.655-0.38
c0.302-0.221,0.254-0.33,0.482-0.549c0.251-0.214,0.392-0.459,0.492-0.872c0.113-0.399-0.073-0.642,0.124-0.832
c0.193-0.187,0.583-0.196,0.782-0.668c0.188-0.457,0.131-0.54,0.214-0.618c0.079-0.083,0.13-0.41,0.13-0.41s0.551-0.46,0.629-0.84
c0.078-0.379,0.161-0.519,0.332-0.684C121.52,69.451,121.376,68.902,120.642,68.449 M76.793,89.907
c0.589,0.271,2.061,0.904,3.655,1.511c0.158,0.416,0.275,1.017,0.225,1.854c-0.145,2.091-2.219,4.689-2.219,4.689
s1.05,2.591,1.35,2.969c0.294,0.37,1.254,1.144,1.578,1.767c0.092,0.186,0.208,0.437,0.3,0.637h-5.697
c0.094-0.778-0.417-1.104-0.554-1.237c-0.311-0.308-0.581-0.915-1.342-1.184c-2.661-0.948-2.619-0.564-3.387-1.18
c-0.522-0.416-1.844-1.293-2.143-1.832c-0.297-0.538-0.836-2.983-0.845-5.072c0.004-1.263-0.087-2.462-0.175-3.212
C69.991,89.192,73.858,88.584,76.793,89.907 M37.519,95.526c0.854-0.354,2.739,0.37,4.623,0.026
c2.878-0.523,6.984-1.96,8.368-2.582c1.257-0.548,3.501-2.704,4.196-3.275c0.683-0.578,1.401-0.743,1.401-0.743
s0.834,0.896,2.511,2.38c1.682,1.489,2.25,2.181,2.836,2.664c0.573,0.484,1.276,1.471,1.392,1.864
c0.462,1.482,0.298,3.948,0.298,3.948s2.62,0.929,3.46,1.678c0.592,0.525,1.088,1.386,1.33,1.848H41.117
c0.067-0.445,0.098-1.435-0.87-1.775c-0.704-0.298-0.561-0.556-2.051-1.072c-0.599-0.214-0.934-0.462-1.242-1.241
c-0.298-0.784-0.302-2.082-0.302-2.082S36.786,95.824,37.519,95.526 M104.179,98.05c0,0,2.712,1.033,3.361,1.943
c0.422,0.596,2.881,1.294,2.881,1.294s0.751,0.053,1.728,0.947c0.746,0.684,0.986,0.966,1.453,1.099H88.694
c0.077-0.406,0.1-1.081-0.503-1.425c-0.397-0.223-0.741-0.657-1.187-0.873c-1.718-0.82-1.906-0.521-2.625-1.095
c-0.404-0.297-0.673-1.614-0.673-1.614s3.143-3.1,3.744-3.883c0.755-0.977,1.053-1.367,1.391-1.85
c2.364-0.222,4.844-0.647,5.697-1.135c0.242-0.145,0.462-0.274,0.671-0.396c0.269,0.152,0.507,0.291,0.714,0.416
c1.26,0.747,4.436,2.085,5.554,2.976C102.599,95.356,104.179,98.05,104.179,98.05"/>
<rect x="174.743" y="25.038" width="1.096" height="186.355"/>
<path d="M230.258,79.797h90.524v12.284h-90.524V79.797z M230.258,115.657v-12.038h90.655v12.038H230.258z M320.782,127.689v12.28
h-90.524v-12.28H320.782z"/>
<path d="M333.062,79.796h67.562c15.308,0,22.962,4.098,22.962,12.283H333.06V79.796H333.062z M333.062,103.62h23.502v12.032
h-23.502V103.62z M356.563,127.691v12.274l-23.502,0.129v-12.403H356.563L356.563,127.691z M400.623,103.62h23.101v12.032h-23.101
V103.62z M400.623,127.691h22.964v12.28h-22.964V127.691z"/>
<path d="M526.718,127.691c0,8.182-7.742,12.274-23.232,12.274h-67.29v-12.274H526.718z M459.424,79.794h67.294v12.281h-90.523
C436.194,83.894,443.94,79.794,459.424,79.794 M526.718,115.653h-90.522v-12.03h90.522V115.653z"/>
<polygon points="381.374,153.397 390.235,153.397 390.235,154.829 383.162,154.829 383.162,160.764 389.875,160.764
389.875,162.199 383.162,162.199 383.162,168.608 390.545,168.608 390.545,170.043 381.374,170.043 "/>
<polygon points="394.101,153.397 396.354,153.397 405.558,168.036 405.604,168.036 405.604,153.397 407.397,153.397
407.397,170.043 404.985,170.043 395.938,155.683 395.888,155.683 395.888,170.043 394.101,170.043 "/>
<path d="M411.127,167.914c1.06,0.618,2.308,0.979,3.99,0.979c2.228,0,4.069-1.047,4.069-3.409c0-3.266-8.293-3.672-8.293-8.033
c0-2.672,2.539-4.34,5.728-4.34c0.887,0,2.308,0.119,3.555,0.555l-0.284,1.499c-0.81-0.405-2.078-0.625-3.3-0.625
c-1.866,0-3.911,0.722-3.911,2.863c0,3.343,8.294,3.36,8.294,8.225c0,3.365-3.135,4.698-5.938,4.698
c-1.762,0-3.131-0.336-4.092-0.716L411.127,167.914z"/>
<path d="M431.631,153.397h4.481c6.477,0,9.043,3.437,9.043,8.301c0,6.03-4.377,8.343-10.366,8.343h-3.158V153.397z
M433.413,168.608h1.479c5.134,0,8.477-1.906,8.477-7.01c0-5.074-3.293-6.771-7.332-6.771h-2.624V168.608L433.413,168.608z"/>
<polygon points="449.069,153.397 457.935,153.397 457.935,154.829 450.857,154.829 450.857,160.764 457.57,160.764 457.57,162.199
450.857,162.199 450.857,168.608 458.246,168.608 458.246,170.043 449.069,170.043 "/>
<polygon points="469.077,153.397 470.868,153.397 470.868,168.608 478.129,168.608 478.129,170.043 469.077,170.043 "/>
<polygon points="482.66,162.986 475.947,153.4 478.023,153.4 483.546,161.533 489.222,153.4 491.164,153.4 484.451,162.986
484.451,170.037 482.66,170.037 "/>
<path d="M500.834,153.115c5.441,0,8.008,4.097,7.955,8.6c-0.053,5.104-2.75,8.608-7.955,8.608c-5.209,0-7.908-3.504-7.965-8.608
C492.823,157.211,495.387,153.115,500.834,153.115 M494.663,161.714c0,3.531,1.918,7.18,6.171,7.18c4.248,0,6.171-3.647,6.171-7.18
c0-3.523-1.923-7.167-6.171-7.167C496.581,154.547,494.663,158.191,494.663,161.714"/>
<polygon points="512.184,153.397 514.435,153.397 523.639,168.036 523.69,168.036 523.69,153.397 525.481,153.397 525.481,170.043
523.072,170.043 514.021,155.683 513.968,155.683 513.968,170.043 512.184,170.043 "/>
</g>
</svg>
home/static/imgs/2022/favicon.ico

36.6 KiB

home/static/imgs/2022/logo.png

115 KiB

home/static/imgs/2022/trois_ptits_pois.png

41.4 KiB

home/static/imgs/2022/trollune.png

255 KiB

home/static/imgs/2023/bdl.png

213 KiB

home/static/imgs/2023/ens_ps.png

14.5 KiB