Import initial de Vivier depuis l'hebergement OVH

This commit is contained in:
Yann PILLA committed 2026-10-16 21:52:44 +02:00
commit 839e5e57c5
126 files changed
+22447

No files matched your search

+19
View File
@@ -0,0 +1,19 @@
Options -Indexes
DirectoryIndex index.php
# HTTPS obligatoire : toute adresse en http:// est redirigée vers https://
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP:X-Forwarded-Proto} !=https
RewriteCond %{HTTP_HOST} !^(localhost|127\.0\.0\.1)(:\d+)?$ [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>
<IfModule mod_headers.c>
Header always set X-Content-Type-Options "nosniff"
# Rien de ce site ne doit figurer dans un moteur de recherche. Pas de blocage par robots.txt :
# un moteur qui ne peut pas lire une page ne voit pas cette consigne et peut en afficher l'adresse.
Header always set X-Robots-Tag "noindex, nofollow, noarchive"
# Le navigateur retient pendant un an qu'il ne doit venir qu'en HTTPS (les pages PHP l'envoient aussi)
Header always set Strict-Transport-Security "max-age=31536000" env=HTTPS
</IfModule>
+480
View File
@@ -0,0 +1,480 @@
(function () {
'use strict';
var csrf = document.querySelector('meta[name="csrf"]').content;
var textes = JSON.parse(document.querySelector('meta[name="textes"]').content);
// -------------------------------------------------------------------------
// Menu des écrans étroits
// -------------------------------------------------------------------------
var boutonMenu = document.querySelector('.menu-bouton');
if (boutonMenu) {
var menu = document.getElementById('menu');
boutonMenu.addEventListener('click', function () {
var ouvert = menu.classList.toggle('ouvert');
boutonMenu.setAttribute('aria-expanded', ouvert ? 'true' : 'false');
});
}
// Sous-menus (Gestion, compte, CV IT Club) : un seul ouvert à la fois, fermés au clic ailleurs et à la touche Échap
var sousMenus = Array.prototype.slice.call(document.querySelectorAll('.menu-plus, .menu-deroulant'));
sousMenus.forEach(function (m) {
m.addEventListener('toggle', function () {
if (m.open) { sousMenus.forEach(function (autre) { if (autre !== m) { autre.open = false; } }); }
});
});
document.addEventListener('click', function (e) {
sousMenus.forEach(function (m) { if (m.open && !m.contains(e.target)) { m.open = false; } });
});
document.addEventListener('keydown', function (e) {
if (e.key !== 'Escape') { return; }
sousMenus.forEach(function (m) { if (m.open) { m.open = false; m.querySelector('summary').focus(); } });
});
// -------------------------------------------------------------------------
// Envoi long : le bouton annonce l'attente et empêche un second envoi
// -------------------------------------------------------------------------
document.querySelectorAll('form[data-attente]').forEach(function (form) {
form.addEventListener('submit', function () {
var bouton = form.querySelector('button[type="submit"]');
bouton.disabled = true;
bouton.textContent = form.dataset.attenteBouton || textes.analyseEnCours;
var p = document.createElement('p');
p.className = 'flash flash-info';
p.setAttribute('role', 'status');
p.textContent = form.dataset.attente;
form.appendChild(p);
});
});
// -------------------------------------------------------------------------
// Kanban : glisser-déposer entre colonnes
// -------------------------------------------------------------------------
var kanban = document.querySelector('.kanban');
if (kanban && window.Sortable) {
var dialogue = document.getElementById('dialogue-motif');
var annonce = document.getElementById('annonce');
var compter = function () {
kanban.querySelectorAll('.colonne').forEach(function (col) {
col.querySelector('.compteur').textContent = col.querySelectorAll('.fiche').length;
});
};
var annuler = function (evt, message) {
evt.from.insertBefore(evt.item, evt.from.children[evt.oldIndex] || null);
compter();
if (message) {
annonce.textContent = message;
annonce.hidden = false;
}
};
var envoyer = function (evt, motif) {
var corps = new URLSearchParams();
corps.set('csrf', csrf);
corps.set('id', evt.item.dataset.id);
corps.set('statut', evt.to.dataset.statut);
corps.set('ordre', Array.prototype.map.call(evt.to.children, function (li) { return li.dataset.id; }).join(','));
if (motif) { corps.set('motif', motif); }
fetch(kanban.dataset.url, {
method: 'POST',
headers: { 'X-Requested-With': 'fetch' },
body: corps,
credentials: 'same-origin'
})
.then(function (r) { return r.json().then(function (j) { return { ok: r.ok && j.ok, erreur: j.erreur }; }); })
.then(function (res) {
if (!res.ok) { annuler(evt, res.erreur || textes.echecEnregistrement); return; }
annonce.hidden = true;
var ancien = evt.item.querySelector('.motif');
if (ancien) { ancien.remove(); }
if (motif) {
var p = document.createElement('p');
p.className = 'motif';
p.textContent = motif;
evt.item.appendChild(p);
}
})
.catch(function () { annuler(evt, textes.connexionPerdue); });
};
var demanderMotif = function (evt) {
var zone = dialogue.querySelector('textarea');
zone.value = '';
dialogue.returnValue = '';
dialogue.addEventListener('close', function () {
var motif = zone.value.trim();
if (dialogue.returnValue === 'valider' && motif) { envoyer(evt, motif); } else { annuler(evt); }
}, { once: true });
dialogue.showModal();
};
dialogue.querySelector('button[value="annuler"]').addEventListener('click', function () {
dialogue.close('annuler');
});
kanban.querySelectorAll('.cartes').forEach(function (liste) {
Sortable.create(liste, {
group: 'kanban',
animation: 150,
// Sur écran tactile, un appui bref fait défiler la page ; un appui maintenu saisit la carte
delay: 180,
delayOnTouchOnly: true,
disabled: kanban.dataset.modifiable !== '1',
ghostClass: 'fantome',
chosenClass: 'saisie',
dragClass: 'glisse',
onStart: function () { kanban.classList.add('en-glisse'); },
onEnd: function (evt) {
kanban.classList.remove('en-glisse');
if (evt.from === evt.to && evt.oldIndex === evt.newIndex) { return; }
compter();
if (evt.to.dataset.statut === 'non_retenu' && evt.from !== evt.to) {
demanderMotif(evt);
} else {
envoyer(evt, null);
}
}
});
});
}
// -------------------------------------------------------------------------
// Kanban : filtre instantané des cartes
// -------------------------------------------------------------------------
var filtre = document.getElementById('filtre-kanban');
if (filtre && kanban) {
var sansAccent = function (t) { return t.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, ''); };
var texte = document.getElementById('filtre-texte');
var seniorite = document.getElementById('filtre-seniorite');
var filtrer = function () {
var mots = sansAccent(texte.value).split(/\s+/).filter(Boolean);
kanban.querySelectorAll('.colonne').forEach(function (col) {
var visibles = 0;
col.querySelectorAll('.fiche').forEach(function (fiche) {
var contenu = sansAccent(fiche.textContent);
var garde = (!seniorite.value || fiche.dataset.seniorite === seniorite.value) &&
mots.every(function (m) { return contenu.indexOf(m) !== -1; });
fiche.classList.toggle('cachee', !garde);
if (garde) { visibles++; }
});
col.querySelector('.compteur').textContent = visibles;
});
};
filtre.addEventListener('submit', function (e) { e.preventDefault(); });
texte.addEventListener('input', filtrer);
seniorite.addEventListener('change', filtrer);
}
// -------------------------------------------------------------------------
// Import en lot : les CV en attente sont analysés l'un après l'autre, une requête par CV
// -------------------------------------------------------------------------
var lot = document.getElementById('lot');
if (lot && lot.dataset.auto === '1') {
var enAttente = Array.prototype.slice.call(lot.querySelectorAll('tr[data-etat="en_attente"]'));
var avancement = document.getElementById('lot-avancement');
var total = enAttente.length;
enAttente.forEach(function (tr) {
var b = tr.querySelector('.bouton-analyse');
if (b) { b.hidden = true; }
});
var analyserSuivant = function () {
var tr = enAttente.shift();
if (!tr) {
if (total) {
if (avancement) { avancement.textContent = textes.lotTermine; }
window.location.reload();
}
return;
}
var badge = tr.querySelector('.etat-lot');
var detail = tr.querySelector('.detail-lot');
badge.textContent = textes.analyseEnCours;
badge.className = 'badge badge-lot-analyse etat-lot';
var corps = new URLSearchParams();
corps.set('csrf', csrf);
corps.set('id', tr.dataset.id);
fetch(lot.dataset.url, { method: 'POST', headers: { 'X-Requested-With': 'fetch' }, body: corps, credentials: 'same-origin' })
.then(function (r) { return r.json(); })
.then(function (j) {
var etat = j.etat || 'erreur';
tr.dataset.etat = etat;
badge.className = 'badge badge-lot-' + etat + ' etat-lot';
badge.textContent = etat === 'pret' ? textes.lotPret : (etat === 'erreur' ? textes.lotErreur : textes.lotEnAttente);
if (j.candidat) { tr.querySelector('.candidat-lot').textContent = j.candidat; }
if (j.erreur) { detail.textContent = j.erreur; detail.hidden = false; }
})
.catch(function () {
badge.className = 'badge badge-lot-erreur etat-lot';
badge.textContent = textes.lotErreur;
detail.textContent = textes.connexionPerdue;
detail.hidden = false;
})
.then(analyserSuivant);
};
analyserSuivant();
}
// -------------------------------------------------------------------------
// Messages : fermeture d'un clic ; une confirmation s'efface seule après 6 secondes
// -------------------------------------------------------------------------
document.querySelectorAll('main > .flash[role="status"]').forEach(function (flash) {
var partir = function () {
flash.classList.add('part');
window.setTimeout(function () { flash.remove(); }, 260);
};
var texte = document.createElement('span');
while (flash.firstChild) { texte.appendChild(flash.firstChild); }
var fermer = document.createElement('button');
fermer.type = 'button';
fermer.className = 'fermer';
fermer.setAttribute('aria-label', textes.fermer);
fermer.textContent = '×';
fermer.addEventListener('click', partir);
flash.appendChild(texte);
flash.appendChild(fermer);
flash.classList.add('fermable');
if (flash.classList.contains('flash-succes')) { window.setTimeout(partir, 6000); }
});
// Photo introuvable : les initiales la remplacent
document.querySelectorAll('img.avatar').forEach(function (img) {
var remplacer = function () {
var s = document.createElement('span');
s.className = img.className + ' avatar-vide';
s.setAttribute('aria-hidden', 'true');
s.textContent = img.dataset.initiales || '';
img.replaceWith(s);
};
if (img.complete && img.naturalWidth === 0) { remplacer(); } else { img.addEventListener('error', remplacer); }
});
// Bouton d'impression (aide)
document.querySelectorAll('[data-imprimer]').forEach(function (b) {
b.addEventListener('click', function () { window.print(); });
});
// -------------------------------------------------------------------------
// Confirmation avant une action irréversible
// -------------------------------------------------------------------------
document.querySelectorAll('form[data-confirmer]').forEach(function (form) {
form.addEventListener('submit', function (e) {
if (!window.confirm(form.dataset.confirmer)) { e.preventDefault(); }
});
});
// -------------------------------------------------------------------------
// Fiche profil : le motif n'apparaît que pour « Non retenu »
// -------------------------------------------------------------------------
document.querySelectorAll('select[data-motif]').forEach(function (select) {
var champ = document.getElementById(select.dataset.motif);
var saisie = champ.querySelector('input');
var basculer = function () {
var refus = select.value === 'non_retenu';
champ.hidden = !refus;
saisie.required = refus;
};
select.addEventListener('change', basculer);
basculer();
});
// -------------------------------------------------------------------------
// Fiche profil : onglets Profil, Suivi, Missions, Dossier
// L'adresse garde l'onglet (#suivi) ou une section (#relances) : un retour après
// enregistrement, un lien de la page Suivi ou un rechargement rouvre le bon onglet.
// -------------------------------------------------------------------------
var barreOnglets = document.querySelector('[data-onglets]');
if (barreOnglets) {
var onglets = Array.prototype.slice.call(barreOnglets.querySelectorAll('[data-onglet]'));
var panneaux = onglets.map(function (o) { return document.getElementById(o.dataset.onglet); });
document.body.classList.add('avec-onglets');
barreOnglets.setAttribute('role', 'tablist');
onglets.forEach(function (o, i) {
o.setAttribute('role', 'tab');
o.setAttribute('aria-controls', panneaux[i].id);
panneaux[i].setAttribute('role', 'tabpanel');
panneaux[i].setAttribute('tabindex', '-1');
});
var activer = function (n) {
onglets.forEach(function (o, i) {
var choisi = i === n;
o.setAttribute('aria-selected', choisi ? 'true' : 'false');
o.tabIndex = choisi ? 0 : -1;
panneaux[i].hidden = !choisi;
});
};
// Ancre → onglet à ouvrir et élément à montrer. Une ancre inconnue ne change rien.
var cibleDe = function (ancre) {
var id = decodeURIComponent((ancre || '').replace(/^#/, ''));
if (!id) { return null; }
var el = document.getElementById(id);
var panneau = el && el.closest('.panneau');
return panneau ? { n: panneaux.indexOf(panneau), el: el, section: el !== panneau } : null;
};
// Le panneau commence sous la barre collée : on n'y descend que si la barre est déjà collée
var montrer = function (cible) {
if (cible.section) {
cible.el.scrollIntoView({ block: 'start' });
var replie = cible.el.closest('details');
if (replie) { replie.open = true; }
} else if (barreOnglets.getBoundingClientRect().top <= parseFloat(getComputedStyle(barreOnglets).top) + 1) {
cible.el.scrollIntoView({ block: 'start' });
}
};
var aller = function (ancre, defiler) {
var cible = cibleDe(ancre);
if (!cible) { return false; }
activer(cible.n);
if (defiler) { montrer(cible); }
return true;
};
if (!aller(window.location.hash, true)) { activer(0); }
// Clic sur un onglet ou sur un lien interne de la fiche (ligne « À faire »)
document.addEventListener('click', function (e) {
var lien = e.target.closest('a[href^="#"]');
if (!lien || e.defaultPrevented || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
var ancre = lien.getAttribute('href');
if (!cibleDe(ancre)) { return; }
e.preventDefault();
if (window.history.replaceState) { window.history.replaceState(null, '', ancre); }
aller(ancre, true);
});
window.addEventListener('hashchange', function () { aller(window.location.hash, true); });
// Clavier : flèches, Début et Fin d'un onglet à l'autre ; Espace ouvre l'onglet
barreOnglets.addEventListener('keydown', function (e) {
var i = onglets.indexOf(document.activeElement);
if (i === -1) { return; }
var n = { ArrowRight: i + 1, ArrowLeft: i - 1, Home: 0, End: onglets.length - 1 }[e.key];
if (e.key === ' ') { e.preventDefault(); onglets[i].click(); return; }
if (n === undefined) { return; }
e.preventDefault();
n = (n + onglets.length) % onglets.length;
onglets[n].focus();
onglets[n].click();
});
}
// -------------------------------------------------------------------------
// Filtres : une liste déroulante changée relance la recherche, sans bouton à cliquer.
// Sur écran étroit, les filtres des Profils se replient derrière un bouton « Filtres ».
// -------------------------------------------------------------------------
document.querySelectorAll('form[data-auto]').forEach(function (form) {
form.querySelectorAll('select').forEach(function (select) {
select.addEventListener('change', function () {
if (form.requestSubmit) { form.requestSubmit(); } else { form.submit(); }
});
});
form.querySelectorAll('[data-auto-masquer]').forEach(function (b) { b.hidden = true; });
});
document.querySelectorAll('form[data-repli]').forEach(function (form) {
var listes = Array.prototype.slice.call(form.querySelectorAll('select'));
var actifs = listes.filter(function (s) { return s.selectedIndex > 0; }).length;
var bouton = document.createElement('button');
bouton.type = 'button';
bouton.className = 'secondaire bouton-filtres';
bouton.textContent = textes.filtres + (actifs ? ' (' + actifs + ')' : '');
var replier = function (replie) {
form.classList.toggle('replie', replie);
bouton.setAttribute('aria-expanded', replie ? 'false' : 'true');
};
bouton.addEventListener('click', function () { replier(!form.classList.contains('replie')); });
var recherche = form.querySelector('label.large');
form.insertBefore(bouton, recherche ? recherche.nextSibling : form.firstChild);
replier(actifs === 0);
});
// -------------------------------------------------------------------------
// Double authentification : le QR code se dessine à partir de l'adresse otpauth://
// La clé reste écrite en clair à côté, pour une saisie à la main.
// -------------------------------------------------------------------------
document.querySelectorAll('[data-qr]').forEach(function (zone) {
if (!window.qrcode) { zone.hidden = true; return; }
var qr = window.qrcode(0, 'M');
qr.addData(zone.dataset.qr);
qr.make();
zone.innerHTML = qr.createSvgTag({ cellSize: 5, margin: 3, scalable: true });
});
// Copier un lien ou des codes dans le presse-papiers
document.querySelectorAll('[data-copier]').forEach(function (bouton) {
bouton.addEventListener('click', function () {
var texte = bouton.dataset.copier;
var fait = function () {
var avant = bouton.textContent;
bouton.textContent = bouton.dataset.copie || textes.copie;
window.setTimeout(function () { bouton.textContent = avant; }, 2000);
};
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard.writeText(texte).then(fait);
} else {
var zone = document.createElement('textarea');
zone.value = texte;
document.body.appendChild(zone);
zone.select();
try { document.execCommand('copy'); fait(); } catch (e) { /* le texte reste sélectionnable à l'écran */ }
zone.remove();
}
});
});
// -------------------------------------------------------------------------
// Traduction des profils en arrière-plan : une par requête, tant que la page reste ouverte.
// Une erreur arrête la série ; la page Comptes la montre au gestionnaire.
// -------------------------------------------------------------------------
var fileTraduction = document.querySelector('meta[name="traductions"]');
if (fileTraduction && parseInt(fileTraduction.content, 10) > 0) {
var traduireSuivante = function () {
var corps = new URLSearchParams();
corps.set('csrf', csrf);
fetch(fileTraduction.dataset.url, { method: 'POST', headers: { 'X-Requested-With': 'fetch' }, body: corps, credentials: 'same-origin' })
.then(function (r) { return r.json(); })
.then(function (j) {
if (j.fait && j.reste > 0) { window.setTimeout(traduireSuivante, 1500); }
})
.catch(function () { /* nouvel essai au prochain chargement de page */ });
};
window.setTimeout(traduireSuivante, 2500);
}
// -------------------------------------------------------------------------
// Modifier la fiche : la date n'apparaît que pour « Date précise » ;
// le permis de travail ne concerne que les profils sans nationalité UE, EEE ou suisse
// -------------------------------------------------------------------------
var choixDispo = document.querySelector('select[name="disponibilite_code"]');
if (choixDispo) {
var champDate = document.getElementById('champ-disponible-le');
var montrerDate = function () {
var date = choixDispo.value === 'date';
champDate.hidden = !date;
champDate.querySelector('input').required = date;
};
choixDispo.addEventListener('change', montrerDate);
montrerDate();
}
var nationalites = document.querySelectorAll('select[data-nationalite]');
var blocPermis = document.getElementById('bloc-permis');
if (nationalites.length && blocPermis) {
var libres = (blocPermis.dataset.libres || '').split(',');
var nonRequis = document.getElementById('permis-non-requis');
var majPermis = function () {
var codes = Array.prototype.map.call(nationalites, function (s) { return s.value; }).filter(Boolean);
var libre = codes.some(function (c) { return libres.indexOf(c) !== -1; });
blocPermis.hidden = libre;
nonRequis.hidden = !libre;
};
nationalites.forEach(function (s) { s.addEventListener('change', majPermis); });
majPermis();
}
})();
+150
View File
@@ -0,0 +1,150 @@
/* CV au format IT Club : A4, noir et or (#ceb73b, couleur du logo). */
:root {
--noir: #111111;
--or: #ceb73b;
--or-texte: #7d6c12; /* or assombri : lisible en petit corps sur fond blanc */
--gris: #555555;
--trait: #d9d6cc;
--marge: 14mm;
}
/* Marges latérales et haute à zéro : le bandeau noir va jusqu'au bord de la feuille.
Les marges du texte viennent du tableau .corps, répété sur chaque page. */
@page {
size: A4;
margin: 0 0 10mm;
@bottom-right {
content: counter(page) " / " counter(pages);
font: 7.5pt Arial, Helvetica, sans-serif;
color: #555555;
padding-right: 14mm;
vertical-align: top;
}
}
* { box-sizing: border-box; }
html { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
body {
margin: 0;
background: #e9e7e1;
color: var(--noir);
font: 9.3pt/1.36 Arial, "Helvetica Neue", Helvetica, sans-serif;
}
/* Barre d'outils, hors impression ---------------------------------------- */
.outils {
display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap;
padding: 0.6rem 1.25rem; background: var(--noir); color: #fff; font-size: 0.9rem;
}
.outils a { color: #fff; }
.versions { display: flex; gap: 0.25rem; }
.versions:first-of-type { margin-left: auto; }
.versions:last-of-type { margin-right: auto; }
.versions a { padding: 0.25rem 0.75rem; border: 1px solid #555; border-radius: 999px; text-decoration: none; }
.versions a[aria-current] { background: var(--or); border-color: var(--or); color: var(--noir); font-weight: 700; }
.outils .action {
font: inherit; font-weight: 700; cursor: pointer; padding: 0.4rem 1rem; text-decoration: none;
border: 1px solid var(--or); border-radius: 6px; background: var(--or); color: var(--noir);
}
.outils a:focus-visible, .outils button:focus-visible { outline: 3px solid #fff; outline-offset: 2px; }
/* Messages au-dessus de la feuille, hors impression */
.note { max-width: 210mm; margin: 1rem auto 0; padding: 0.75rem 1rem; background: #fff; border-left: 4px solid var(--or); font-size: 0.9rem; }
.note p { margin: 0 0 0.5rem; }
.note-erreur { border-left-color: #a3341f; }
.note-actions { display: flex; flex-wrap: wrap; gap: 0.75rem 1.5rem; align-items: flex-start; }
.note button { font: inherit; font-weight: 700; cursor: pointer; padding: 0.4rem 1rem; border: 1px solid var(--noir); border-radius: 6px; background: var(--noir); color: #fff; }
.note button[disabled] { opacity: 0.6; cursor: progress; }
.note details summary { cursor: pointer; font-weight: 700; padding: 0.4rem 0; }
.note ol { margin: 0.4rem 0 0; padding-left: 1.2rem; display: grid; gap: 0.5rem; }
.note label { display: block; margin-bottom: 0.4rem; }
.note a { color: var(--noir); }
/* Feuille ---------------------------------------------------------------- */
.page {
width: 210mm; max-width: 100%; min-height: 297mm; margin: 1.5rem auto; padding: var(--marge);
background: #fff; box-shadow: 0 2px 14px rgba(0, 0, 0, 0.18);
}
.bandeau {
display: flex; align-items: center; gap: 7mm;
margin: calc(-1 * var(--marge)) calc(-1 * var(--marge)) 5mm; padding: 6.5mm var(--marge) 6mm;
background: var(--noir); color: #fff; border-bottom: 1mm solid var(--or);
}
.logo { width: 36mm; height: auto; flex: none; }
.identite { border-left: 0.3mm solid var(--or); padding-left: 7mm; min-width: 0; }
h1 { margin: 0; font: 400 19pt/1.1 Georgia, "Times New Roman", serif; letter-spacing: 0.01em; overflow-wrap: anywhere; }
.titre { margin: 1mm 0 0; color: var(--or); font-size: 10.5pt; letter-spacing: 0.03em; }
.reperes { display: flex; flex-wrap: wrap; gap: 0.8mm 7mm; margin: 0 0 3.6mm; padding: 0 0 2.6mm; border-bottom: 0.2mm solid var(--trait); }
.reperes span { white-space: nowrap; }
.reperes small { font-size: 6.8pt; text-transform: uppercase; letter-spacing: 0.08em; color: var(--gris); margin-right: 0.6mm; }
section { margin: 0 0 3.6mm; }
h2 {
margin: 0 0 1.6mm; padding: 0 0 0.7mm; border-bottom: 0.4mm solid var(--or);
font: 400 11pt/1.2 Georgia, "Times New Roman", serif; letter-spacing: 0.02em;
break-after: avoid;
}
h3 { margin: 0 0 0.6mm; font-size: 9.8pt; }
p { margin: 0 0 0.6mm; }
.competences { width: 100%; border-collapse: collapse; }
.competences th { width: 31mm; text-align: left; vertical-align: top; padding: 0.35mm 3mm 0.35mm 0; font-size: 7.3pt; text-transform: uppercase; letter-spacing: 0.06em; color: var(--gris); font-weight: 400; line-height: 1.7; }
.competences td { padding: 0.35mm 0; }
.techno { white-space: nowrap; }
.techno small { color: var(--or-texte); font-size: 7.5pt; }
.experience { display: grid; grid-template-columns: 17mm 1fr; gap: 0 4mm; padding: 1.7mm 0; border-top: 0.2mm solid var(--trait); break-inside: avoid; }
.experience:first-of-type { border-top: 0; padding-top: 0; }
.periode .fleche { display: none; }
.periode { margin: 0.3mm 0 0; font-size: 8pt; color: var(--or-texte); font-weight: 700; line-height: 1.3; }
.employeur { color: var(--gris); font-weight: 400; font-size: 9pt; margin-left: 1.5mm; }
.environnement { font-size: 8.3pt; color: #333; margin: 0.4mm 0 0; }
.cadre { font-size: 8.5pt; color: var(--gris); margin: 0.3mm 0 0.6mm; }
.mission { font-style: italic; margin: 0 0 0.8mm; }
.deux { display: grid; grid-template-columns: 1fr 1fr; gap: 0 7mm; break-inside: avoid; }
.deux ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.6mm; }
.contact {
display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 1mm 6mm;
margin-top: 4.5mm; padding: 2.4mm 4mm; background: #f6f3e4; border-left: 1mm solid var(--or); break-inside: avoid;
}
.signature { font: italic 10pt Georgia, "Times New Roman", serif; }
.mentions { margin: 4mm 0 0; font-size: 6.8pt; color: var(--gris); text-align: center; letter-spacing: 0.02em; }
.corps { width: 100%; border-collapse: collapse; }
.corps > * > tr > td { padding: 0; }
.marge-haut, .marge-bas { height: 0; }
/* Aperçu sur petit écran : la feuille occupe la largeur disponible */
@media screen and (max-width: 820px) {
:root { --marge: 5vw; }
.page { margin: 0 auto; min-height: 0; box-shadow: none; }
.bandeau { flex-wrap: wrap; gap: 4mm; }
.identite { border-left: 0; padding-left: 0; }
.experience { grid-template-columns: 1fr; }
.periode br { display: none; }
.periode .fleche { display: inline; }
.periode { margin-bottom: 0.5mm; }
.deux { grid-template-columns: 1fr; gap: 3mm; }
.versions { margin: 0; }
.outils .action { flex: 1 1 auto; text-align: center; }
}
/* Impression ------------------------------------------------------------- */
@media print {
body { background: #fff; }
.outils, .note { display: none; }
.page { width: auto; min-height: 0; margin: 0; padding: 0 var(--marge); box-shadow: none; }
.bandeau { margin: 0 calc(-1 * var(--marge)); }
.marge-haut { height: 7mm; }
.marge-bas { height: 7mm; }
.mentions { position: fixed; left: 0; right: 0; bottom: 0; margin: 0; }
a { color: inherit; text-decoration: none; }
}
+12
View File
@@ -0,0 +1,12 @@
document.getElementById('imprimer').addEventListener('click', function () {
window.print();
});
// Envoi long (traduction) : le bouton annonce l'attente et empêche un second envoi
document.querySelectorAll('form[data-attente]').forEach(function (form) {
form.addEventListener('submit', function () {
var bouton = form.querySelector('button[type="submit"]');
bouton.disabled = true;
bouton.textContent = form.dataset.attente;
});
});
+153
View File
@@ -0,0 +1,153 @@
/* CV au format Europass : A4, bandeau bleu, police Open Sans (licence SIL OFL, hébergée ici). */
@font-face {
font-family: "Open Sans"; font-style: normal; font-weight: 300 800; font-display: swap;
src: url("polices/open-sans-latin-wght-normal.woff2") format("woff2");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: "Open Sans"; font-style: normal; font-weight: 300 800; font-display: swap;
src: url("polices/open-sans-latin-ext-wght-normal.woff2") format("woff2");
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
font-family: "Open Sans"; font-style: italic; font-weight: 300 800; font-display: swap;
src: url("polices/open-sans-latin-wght-italic.woff2") format("woff2");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: "Open Sans"; font-style: italic; font-weight: 300 800; font-display: swap;
src: url("polices/open-sans-latin-ext-wght-italic.woff2") format("woff2");
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
:root {
--bleu: #004b80; /* bandeau */
--bleu-clair: #4d9acb; /* filets et puces des titres */
--filet: #c0dbed;
--fond-ligne: #f2f8fc;
--texte: #1a1a1a;
--gris: #404040;
--gris-clair: #6f6f6f;
--marge: 14mm;
}
/* Le bandeau va jusqu'au bord de la feuille ; les marges du texte viennent du tableau .corps, répété à chaque page */
@page {
size: A4;
margin: 0 0 10mm;
@bottom-right {
content: counter(page) " / " counter(pages);
font: 7.5pt "Open Sans", Arial, sans-serif;
color: #6f6f6f;
padding-right: 14mm;
vertical-align: top;
}
}
* { box-sizing: border-box; }
html { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
body {
margin: 0;
background: #e6ebef;
color: var(--texte);
font: 9.4pt/1.42 "Open Sans", Arial, Helvetica, sans-serif;
}
/* Barre d'outils, hors impression ---------------------------------------- */
.outils {
display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap;
padding: 0.6rem 1.25rem; background: #0b1f30; color: #fff; font-size: 0.9rem;
}
.outils a { color: #fff; }
.versions { display: flex; gap: 0.25rem; }
.versions:first-of-type { margin-left: auto; }
.versions:last-of-type { margin-right: auto; }
.versions a { padding: 0.25rem 0.75rem; border: 1px solid #4a6378; border-radius: 999px; text-decoration: none; }
.versions a[aria-current], .versions a[aria-pressed="true"] { background: var(--bleu-clair); border-color: var(--bleu-clair); color: #fff; font-weight: 700; }
.versions a[aria-pressed="false"] { color: #b9c9d6; text-decoration: line-through; text-decoration-thickness: 1px; }
.outils .action {
font: inherit; font-weight: 700; cursor: pointer; padding: 0.4rem 1rem; text-decoration: none;
border: 1px solid #fff; border-radius: 6px; background: #fff; color: var(--bleu);
}
.outils a:focus-visible, .outils button:focus-visible { outline: 3px solid #ffd54a; outline-offset: 2px; }
.note { max-width: 210mm; margin: 1rem auto 0; padding: 0.75rem 1rem; background: #fff; border-left: 4px solid var(--bleu-clair); font-size: 0.9rem; }
.note p { margin: 0 0 0.5rem; }
.note-erreur { border-left-color: #a3341f; }
.note button { font: inherit; font-weight: 700; cursor: pointer; padding: 0.4rem 1rem; border: 1px solid var(--bleu); border-radius: 6px; background: var(--bleu); color: #fff; }
.note button[disabled] { opacity: 0.6; cursor: progress; }
/* Feuille A4 ------------------------------------------------------------- */
.page { width: 210mm; min-height: 297mm; margin: 1.25rem auto 2rem; background: #fff; box-shadow: 0 4px 22px rgba(0, 0, 0, 0.14); }
.bandeau {
position: relative; display: flex; gap: 6mm; align-items: center;
background: var(--bleu); color: #fff; padding: 9mm var(--marge) 8mm;
}
.bandeau .identite { flex: 1; min-width: 0; padding-right: 42mm; }
.bandeau h1 { margin: 0; font-size: 17pt; font-weight: 700; line-height: 1.15; }
.bandeau .titre { margin: 1mm 0 0; font-size: 10.5pt; font-weight: 400; color: #dbe9f4; }
.bandeau .coordonnees { margin: 3.5mm 0 0; display: flex; flex-wrap: wrap; gap: 1mm 0; font-size: 8.8pt; }
.bandeau .coordonnees span { padding-right: 2.5mm; margin-right: 2.5mm; border-right: 0.3mm solid #6e95b8; }
.bandeau .coordonnees span:last-child { border-right: 0; }
.bandeau .coordonnees b { font-weight: 700; }
.bandeau a { color: #fff; }
.bandeau .logo { position: absolute; top: 7mm; right: var(--marge); width: 34mm; height: auto; }
.portrait { width: 30mm; height: 30mm; flex: none; object-fit: cover; object-position: center 20%; border-radius: 50%; border: 0.8mm solid #fff; }
table.corps { width: 100%; border-collapse: collapse; }
table.corps > thead td, table.corps > tfoot td, table.corps > tbody > tr > td { padding: 0 var(--marge); }
.marge-haut { height: 5mm; }
.marge-bas { height: 4mm; }
section { margin: 0 0 4mm; }
h2 {
position: relative; margin: 2mm 0 2.5mm; padding: 0 0 1mm; font-size: 11pt; font-weight: 800; text-transform: uppercase; letter-spacing: 0.01em;
border-bottom: 0.6mm solid var(--bleu-clair); break-after: avoid;
}
h2::before { content: ""; position: absolute; left: -5.5mm; top: 1.4mm; width: 2.4mm; height: 2.4mm; border-radius: 50%; background: var(--bleu-clair); }
h3 { margin: 0 0 1mm; font-size: 10pt; font-weight: 700; color: var(--gris); text-transform: none; }
h4 { margin: 2.5mm 0 1mm; font-size: 9.5pt; font-weight: 700; color: var(--gris-clair); break-after: avoid; }
p { margin: 0 0 1mm; }
ul { margin: 0.5mm 0 1mm; padding-left: 7mm; }
li { margin: 0 0 0.6mm; }
.element { padding: 0 0 2.5mm; margin: 0 0 2.5mm; border-bottom: 0.3mm solid var(--filet); break-inside: avoid-page; }
.element:last-child { border-bottom: 0; margin-bottom: 0; }
.date { color: var(--gris-clair); font-size: 8.8pt; margin: 0 0 0.6mm; }
.maison { font-weight: 400; color: var(--gris); }
.employeur { margin: 0 0 0.4mm; font-size: 9.6pt; }
.employeur b { font-weight: 700; }
.dates { font-weight: 400; color: var(--bleu); }
.sous-titre { margin-top: 1.2mm; }
table.grille { width: 100%; border-collapse: collapse; margin: 1mm 0 1mm; font-size: 8.8pt; break-inside: avoid; }
table.grille th, table.grille td { padding: 1.5mm 1.5mm; text-align: center; vertical-align: middle; }
table.grille thead th { font-weight: 700; }
table.grille thead tr:first-child { border-bottom: 0.3mm solid var(--bleu-clair); }
table.grille tr.sous th { font-weight: 400; font-size: 8.3pt; line-height: 1.25; }
table.grille tbody tr { border-top: 0.3mm solid var(--bleu-clair); }
table.grille tbody tr:last-child { border-bottom: 0.3mm solid var(--bleu-clair); }
table.grille tbody tr:nth-child(odd) { background: var(--fond-ligne); }
table.grille tbody th { text-align: left; font-weight: 800; width: 18%; }
.legende { font-style: italic; color: var(--gris-clair); font-size: 8pt; }
.langues-simples { list-style: none; padding: 0; margin: 0 0 1mm; display: flex; flex-wrap: wrap; gap: 1mm 6mm; }
.liste { line-height: 1.7; }
.liste .sep { color: #aab4bc; padding: 0 0.6mm; }
.benevolat { font-weight: 700; }
@media screen and (max-width: 840px) {
.page { width: auto; min-height: 0; margin: 0.75rem; }
.bandeau { flex-wrap: wrap; }
.bandeau .identite { padding-right: 0; }
.bandeau .logo { position: static; order: -1; width: 30mm; }
}
@media print {
body { background: #fff; }
.outils, .note { display: none !important; }
.page { width: auto; min-height: 0; margin: 0; box-shadow: none; }
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Whitespace-only changes.
@@ -0,0 +1,93 @@
Copyright 2022 The Instrument Sans Project Authors (https://github.com/Instrument/instrument-sans) InstrumentSans-Italic[wdth,wght].ttf: Copyright 2022 The Instrument Sans Project Authors (https://github.com/Instrument/instrument-sans)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
@@ -0,0 +1,93 @@
Copyright 2020 The Open Sans Project Authors (https://github.com/googlefonts/opensans) OpenSans-Italic[wdth,wght].ttf: Copyright 2020 The Open Sans Project Authors (https://github.com/googlefonts/opensans)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
File diff suppressed because it is too large. Load diff
+2
View File
@@ -0,0 +1,2 @@
/*! Sortable 1.15.2 - MIT | git://github.com/SortableJS/Sortable.git */
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sortable=e()}(this,function(){"use strict";function e(e,t){var n,o=Object.keys(e);return Object.getOwnPropertySymbols&&(n=Object.getOwnPropertySymbols(e),t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),o.push.apply(o,n)),o}function I(o){for(var t=1;t<arguments.length;t++){var i=null!=arguments[t]?arguments[t]:{};t%2?e(Object(i),!0).forEach(function(t){var e,n;e=o,t=i[n=t],n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t}):Object.getOwnPropertyDescriptors?Object.defineProperties(o,Object.getOwnPropertyDescriptors(i)):e(Object(i)).forEach(function(t){Object.defineProperty(o,t,Object.getOwnPropertyDescriptor(i,t))})}return o}function o(t){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function a(){return(a=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n,o=arguments[e];for(n in o)Object.prototype.hasOwnProperty.call(o,n)&&(t[n]=o[n])}return t}).apply(this,arguments)}function i(t,e){if(null==t)return{};var n,o=function(t,e){if(null==t)return{};for(var n,o={},i=Object.keys(t),r=0;r<i.length;r++)n=i[r],0<=e.indexOf(n)||(o[n]=t[n]);return o}(t,e);if(Object.getOwnPropertySymbols)for(var i=Object.getOwnPropertySymbols(t),r=0;r<i.length;r++)n=i[r],0<=e.indexOf(n)||Object.prototype.propertyIsEnumerable.call(t,n)&&(o[n]=t[n]);return o}function r(t){return function(t){if(Array.isArray(t))return l(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(t){if("string"==typeof t)return l(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Map"===(n="Object"===n&&t.constructor?t.constructor.name:n)||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?l(t,e):void 0}}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function l(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,o=new Array(e);n<e;n++)o[n]=t[n];return o}function t(t){if("undefined"!=typeof window&&window.navigator)return!!navigator.userAgent.match(t)}var y=t(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i),w=t(/Edge/i),s=t(/firefox/i),u=t(/safari/i)&&!t(/chrome/i)&&!t(/android/i),n=t(/iP(ad|od|hone)/i),c=t(/chrome/i)&&t(/android/i),d={capture:!1,passive:!1};function h(t,e,n){t.addEventListener(e,n,!y&&d)}function f(t,e,n){t.removeEventListener(e,n,!y&&d)}function p(t,e){if(e&&(">"===e[0]&&(e=e.substring(1)),t))try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return}}function P(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"!==e[0]||t.parentNode===n)&&p(t,e)||o&&t===n)return t}while(t!==n&&(t=(i=t).host&&i!==document&&i.host.nodeType?i.host:i.parentNode))}var i;return null}var g,m=/\s+/g;function k(t,e,n){var o;t&&e&&(t.classList?t.classList[n?"add":"remove"](e):(o=(" "+t.className+" ").replace(m," ").replace(" "+e+" "," "),t.className=(o+(n?" "+e:"")).replace(m," ")))}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];o[e=!(e in o||-1!==e.indexOf("webkit"))?"-webkit-"+e:e]=n+("string"==typeof n?"":"px")}}function v(t,e){var n="";if("string"==typeof t)n=t;else do{var o=R(t,"transform")}while(o&&"none"!==o&&(n=o+" "+n),!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return i&&new i(n)}function b(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i<r;i++)n(o[i],i);return o}return[]}function O(){var t=document.scrollingElement;return t||document.documentElement}function X(t,e,n,o,i){if(t.getBoundingClientRect||t===window){var r,a,l,s,c,u,d=t!==window&&t.parentNode&&t!==O()?(a=(r=t.getBoundingClientRect()).top,l=r.left,s=r.bottom,c=r.right,u=r.height,r.width):(l=a=0,s=window.innerHeight,c=window.innerWidth,u=window.innerHeight,window.innerWidth);if((e||n)&&t!==window&&(i=i||t.parentNode,!y))do{if(i&&i.getBoundingClientRect&&("none"!==R(i,"transform")||n&&"static"!==R(i,"position"))){var h=i.getBoundingClientRect();a-=h.top+parseInt(R(i,"border-top-width")),l-=h.left+parseInt(R(i,"border-left-width")),s=a+r.height,c=l+r.width;break}}while(i=i.parentNode);return o&&t!==window&&(o=(e=v(i||t))&&e.a,t=e&&e.d,e&&(s=(a/=t)+(u/=t),c=(l/=o)+(d/=o))),{top:a,left:l,bottom:s,right:c,width:d,height:u}}}function Y(t,e,n){for(var o=M(t,!0),i=X(t)[e];oLine truncated
+816
View File
@@ -0,0 +1,816 @@
/* Vivier — interface.
Identité IT Club : noir et or du logo. Les barres empilées du logo deviennent l'échelle d'avancement des profils.
Titres en Bodoni Moda, texte en Instrument Sans, les deux hébergées ici (licence SIL OFL). */
@font-face {
font-family: "Instrument Sans"; font-style: normal; font-weight: 400 700; font-display: swap;
src: url("polices/instrument-sans-latin-wght-normal.woff2") format("woff2");
}
@font-face {
font-family: "Bodoni Moda"; font-style: normal; font-weight: 400 900; font-display: swap;
src: url("polices/bodoni-moda-latin-wght-normal.woff2") format("woff2");
}
@font-face {
font-family: "Bodoni Moda"; font-style: italic; font-weight: 400 900; font-display: swap;
src: url("polices/bodoni-moda-latin-wght-italic.woff2") format("woff2");
}
:root {
--noir: #000000;
--encre: #1c1c1a;
--gris: #5a6066;
--trait: #d3d8dc;
--fond: #eceff1;
--surface: #ffffff;
--or: #ceb73b;
--or-fonce: #74640c; /* texte doré lisible sur blanc */
--or-pale: #f7f2d4;
--petrole: #0d4a5d; /* liens et repère de focus */
--brique: #a3341f;
--brique-pale: #fbe9e4;
--texte: "Instrument Sans", "Segoe UI", system-ui, -apple-system, Arial, sans-serif;
--titre: "Bodoni Moda", "Didot", "Bodoni MT", Georgia, serif;
--gouttiere: clamp(1rem, 3vw, 2rem);
}
*, *::before, *::after { box-sizing: border-box; }
html { font-size: 100%; -webkit-text-size-adjust: 100%; }
body {
margin: 0;
background: var(--fond);
color: var(--encre);
font: 400 0.9375rem/1.5 var(--texte);
}
a { color: var(--petrole); text-underline-offset: 0.15em; text-decoration-thickness: 1px; }
/* Survol : :where() ôte tout poids à la règle. Un lien coloré par une classe (logo, menu, bouton, lien sur fond noir)
garde sa couleur au survol. Sans cela, « Vivier » passait en noir sur l'en-tête noir. */
:where(a:hover) { color: var(--noir); }
h1 { font: 500 clamp(1.6rem, 1.2rem + 1.6vw, 2.25rem)/1.1 var(--titre); margin: 0; letter-spacing: -0.005em; }
main > h1 { margin-bottom: 1.25rem; }
h1 small { font: 400 0.9375rem var(--texte); color: var(--gris); margin-left: 0.6rem; letter-spacing: 0; }
h2 { font: 600 1rem/1.3 var(--texte); margin: 0 0 0.8rem; }
h3 { font: 600 1rem/1.3 var(--texte); margin: 0; }
p { margin: 0 0 0.6rem; }
em { color: var(--gris); }
code { font-size: 0.9em; background: var(--fond); padding: 0.05em 0.3em; border-radius: 3px; }
:focus-visible { outline: 3px solid var(--petrole); outline-offset: 2px; }
.entete :focus-visible, .porte :focus-visible { outline-color: var(--or); }
.evitement { position: absolute; left: -999rem; top: 0; background: var(--or); color: var(--noir); padding: 0.6rem 1rem; z-index: 10; font-weight: 600; }
.evitement:focus { left: 0; }
[hidden], .cachee { display: none !important; }
/* En-tête ----------------------------------------------------------------
Une seule ligne, fixe en haut de page : la marque, cinq rubriques, le sous-menu Gestion,
puis la recherche, le bouton Importer et le menu du compte. */
.entete { position: sticky; top: 0; z-index: 30; background: var(--noir); color: #fff; padding: 0 var(--gouttiere); display: flex; align-items: center; gap: 1.75rem; min-height: 3.25rem; view-transition-name: entete; }
.entete-barre { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.marque { display: flex; align-items: center; gap: 0.65rem; color: #fff; text-decoration: none; }
.marque img { height: 24px; width: auto; display: block; }
.marque span { font: italic 500 1.3rem/1 var(--titre); padding-left: 0.65rem; border-left: 1px solid #4a4a4a; transition: color 0.12s; }
.marque:hover { color: #fff; }
.marque:hover span { color: var(--or); }
.menu-bouton { display: none; }
.entete-menu { display: flex; align-items: center; gap: 0.75rem; flex: 1; min-width: 0; }
.entete nav { display: flex; align-items: stretch; gap: 0 1.35rem; flex: 1; font-size: 0.9375rem; }
.entete nav > a, .menu-plus > summary {
display: flex; align-items: center; gap: 0.4rem; min-height: 3.25rem; color: #cfcfcf; text-decoration: none; white-space: nowrap;
box-shadow: inset 0 -3px 0 transparent; transition: color 0.12s, box-shadow 0.12s;
}
.entete nav > a:hover, .menu-plus > summary:hover, .menu-plus[open] > summary { color: #fff; }
.entete nav > a[aria-current], .menu-plus.actif > summary { color: #fff; box-shadow: inset 0 -3px 0 var(--or); }
.pastille { background: var(--or); color: var(--noir); border-radius: 999px; padding: 0 0.42rem; font-size: 0.75rem; font-weight: 700; line-height: 1.5; }
/* Sous-menus : Gestion et compte */
.menu-plus { position: relative; margin: 0; }
.menu-plus > summary { list-style: none; cursor: pointer; font-weight: 400; padding: 0; margin: 0; }
.menu-plus > summary::-webkit-details-marker { display: none; }
.menu-plus > summary::after { content: ""; width: 0.36rem; height: 0.36rem; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: translateY(-0.12rem) rotate(45deg); transition: transform 0.15s; }
.menu-plus[open] > summary::after { transform: translateY(0.08rem) rotate(225deg); }
.menu-plus-liste {
position: absolute; left: -1rem; top: 100%; z-index: 40; min-width: 13.5rem; display: grid; padding: 0.35rem;
background: #141414; border: 1px solid #333; border-top: 0; border-radius: 0 0 8px 8px; box-shadow: 0 14px 28px rgba(0, 0, 0, 0.35);
animation: derouler 0.14s ease-out;
}
.menu-plus-liste a, .menu-plus-liste .lien {
display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; width: 100%; min-height: 2.4rem; padding: 0.4rem 0.7rem;
color: #dedede; text-decoration: none; text-align: left; border-radius: 4px; font-size: 0.9375rem;
}
.menu-plus-liste a:hover, .menu-plus-liste .lien:hover { background: #262626; color: #fff; }
.menu-plus-liste a[aria-current] { color: #fff; box-shadow: inset 3px 0 0 var(--or); }
@keyframes derouler { from { opacity: 0; transform: translateY(-4px); } }
/* Recherche, import, compte */
.recherche-rapide { display: flex; position: relative; }
.recherche-rapide input[type="search"] {
width: 13rem; min-height: 2.15rem; padding: 0.3rem 2.3rem 0.3rem 0.75rem; font: inherit; font-size: 0.9375rem; color: #fff;
background: #1c1c1c; border: 1px solid #4a4a4a; border-radius: 999px; transition: width 0.18s ease, border-color 0.12s, background 0.12s;
}
.recherche-rapide input[type="search"]::placeholder { color: #9c9c9c; }
.recherche-rapide input[type="search"]:hover { border-color: #777; }
.recherche-rapide input[type="search"]:focus { width: 19rem; background: #000; border-color: var(--or); outline: 0; }
.recherche-rapide button { position: absolute; right: 0.15rem; top: 50%; transform: translateY(-50%); min-height: 0; width: 1.9rem; height: 1.9rem; padding: 0; background: none; border: 0; border-radius: 50%; color: #cfcfcf; }
.recherche-rapide button:hover { background: #2a2a2a; color: var(--or); }
.recherche-rapide svg { width: 1rem; height: 1rem; display: block; }
.bouton.bouton-entete { min-height: 2.15rem; padding: 0.3rem 0.95rem; font-size: 0.9375rem; white-space: nowrap; }
.bouton.bouton-entete[aria-current] { background: #fff; border-color: #fff; }
.menu-compte > summary { gap: 0.5rem; }
.menu-compte .initiales { display: grid; place-items: center; width: 1.9rem; height: 1.9rem; border-radius: 50%; border: 1px solid #6a6a6a; font-size: 0.75rem; font-weight: 600; color: #fff; letter-spacing: 0.02em; transition: border-color 0.12s; }
.menu-compte > summary:hover .initiales, .menu-compte[open] .initiales, .menu-compte.actif .initiales { border-color: var(--or); }
.menu-compte.actif > summary { box-shadow: none; }
.menu-compte .menu-plus-liste { left: auto; right: -0.5rem; min-width: 15rem; }
.compte-qui { margin: 0; padding: 0.55rem 0.7rem 0.6rem; border-bottom: 1px solid #2c2c2c; color: #fff; font-weight: 600; line-height: 1.3; }
.compte-qui small { display: block; color: #9c9c9c; font-weight: 400; font-size: 0.8125rem; }
.compte-langue { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; padding: 0.45rem 0.7rem; color: #dedede; font-size: 0.9375rem; }
.menu-plus-liste .sortie form { display: contents; }
.menu-plus[open] > summary { margin-bottom: 0; }
.menu-plus-liste .lien { background: none; border: 0; font-weight: 400; cursor: pointer; }
.menu-plus-liste .sortie { border-top: 1px solid #2c2c2c; margin-top: 0.25rem; padding-top: 0.25rem; }
.menu-plus-liste .sortie .lien { text-decoration: none; }
main { padding: 1.5rem var(--gouttiere) 3rem; max-width: 100rem; margin: 0 auto; }
/* Page de connexion ------------------------------------------------------ */
body.accueil { background: var(--noir); color: #fff; min-height: 100vh; display: grid; place-items: center; }
body.accueil main { width: 100%; max-width: 24rem; padding: 2rem 1.25rem; }
.porte { text-align: center; }
.porte img { width: 14rem; max-width: 70%; height: auto; }
.porte-nom { font: italic 500 3.25rem/1 var(--titre); margin: 1.4rem 0 0.4rem; color: #fff; }
.porte-role { color: #bdbdbd; margin-bottom: 2rem; }
.porte form { text-align: left; }
.porte label { color: #e6e6e6; }
.porte input[type="text"], .porte input[type="password"] { background: #151515; border-color: #555; color: #fff; }
.porte button { margin-top: 0.4rem; }
.porte .flash { text-align: left; }
/* Blocs ------------------------------------------------------------------ */
.carte { background: var(--surface); border: 1px solid var(--trait); border-radius: 6px; padding: 1.15rem 1.3rem; margin: 0 0 1rem; }
.carte.etroit { max-width: 28rem; margin-left: auto; margin-right: auto; }
.carte.etroit.gauche { margin-left: 0; }
.carte.moyen { max-width: 56rem; margin-left: auto; margin-right: auto; }
.carte.attention { border-left: 4px solid var(--or); }
.carte.mise-en-avant { border-top: 4px solid var(--or); }
.carte > :last-child { margin-bottom: 0; }
.carte ul { margin: 0; padding-left: 1.1rem; }
.carte h1 + .aide { margin-top: 0.5rem; }
.carte > h1 { margin-bottom: 1rem; }
.barre-titre { display: flex; justify-content: space-between; align-items: flex-end; gap: 1rem 2rem; flex-wrap: wrap; margin: 0 0 1.25rem; }
.fil { margin: 0 0 0.9rem; font-size: 0.875rem; color: var(--gris); }
.aide, .vide { color: var(--gris); font-size: 0.875rem; max-width: 70ch; }
.centre { text-align: center; }
.retard { color: var(--brique); font-weight: 600; }
.deux-colonnes { display: grid; grid-template-columns: minmax(0, 1.7fr) minmax(19rem, 1fr); gap: 1rem; align-items: start; }
.deux-colonnes.inverse { grid-template-columns: minmax(18rem, 24rem) minmax(0, 1fr); }
.deux-egales { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr)); gap: 1rem; align-items: start; }
.deux-colonnes > *, .deux-egales > * { min-width: 0; }
.deux-egales > .carte { margin: 0; }
/* Formulaires ------------------------------------------------------------ */
.pile { display: grid; gap: 0.9rem; }
label { display: grid; gap: 0.3rem; font-size: 0.875rem; font-weight: 600; }
input, select, textarea, button { font: inherit; color: inherit; }
input[type="text"], input[type="email"], input[type="password"], input[type="search"], select, textarea {
width: 100%; min-height: 2.6rem; padding: 0.5rem 0.7rem; font-weight: 400;
background: #fff; border: 1px solid #98a1a8; border-radius: 4px;
}
textarea { min-height: 5rem; resize: vertical; }
input[type="file"] { font-weight: 400; max-width: 100%; }
input[type="file"]::file-selector-button {
font: inherit; font-weight: 600; margin-right: 0.7rem; padding: 0.45rem 0.8rem; cursor: pointer;
background: #fff; border: 1px solid var(--encre); border-radius: 4px;
}
button, .bouton {
display: inline-flex; align-items: center; justify-content: center; gap: 0.4rem; min-height: 2.6rem;
padding: 0.5rem 1.1rem; cursor: pointer; text-decoration: none; text-align: center; font-weight: 600; line-height: 1.2;
background: var(--or); color: var(--noir); border: 1px solid var(--or); border-radius: 4px;
}
button:hover, .bouton:hover { background: #e0cb55; border-color: #e0cb55; color: var(--noir); }
button.secondaire, .bouton.secondaire { background: #fff; border-color: var(--encre); color: var(--encre); }
button.secondaire:hover, .bouton.secondaire:hover { background: var(--encre); color: #fff; }
button.dangereux { background: #fff; border-color: var(--brique); color: var(--brique); }
button.dangereux:hover { background: var(--brique); color: #fff; }
button.lien { min-height: 0; padding: 0; background: none; border: 0; border-radius: 0; color: var(--petrole); font-weight: 400; text-decoration: underline; text-underline-offset: 0.15em; }
button.lien:hover { background: none; color: var(--noir); }
button[disabled] { opacity: 0.6; cursor: progress; }
.actions { display: flex; gap: 0.6rem; justify-content: flex-end; flex-wrap: wrap; margin-top: 1rem; }
.actions-ligne { display: flex; flex-wrap: wrap; gap: 0.4rem 1rem; align-items: center; font-size: 0.875rem; }
td.actions-ligne { justify-content: flex-end; }
.actions-ligne form { display: inline; }
.filtres { display: flex; flex-wrap: wrap; gap: 0.7rem; align-items: flex-end; margin: 0 0 1rem; }
.filtres label { min-width: 10rem; flex: 0 1 12rem; }
.filtres label.large { flex: 1 1 18rem; }
.filtres .fin { margin-left: auto; }
.barre-titre .filtres { margin: 0; flex: 1 1 28rem; justify-content: flex-end; }
.champs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.9rem; }
.champs .large { grid-column: 1 / -1; }
details { margin: 0 0 0.8rem; }
summary { cursor: pointer; color: var(--petrole); font-weight: 600; padding: 0.3rem 0; }
details[open] summary { margin-bottom: 0.7rem; }
.danger { border-top: 1px solid var(--trait); padding-top: 0.9rem; }
/* Messages --------------------------------------------------------------- */
.flash { padding: 0.7rem 0.95rem; margin: 0 0 1rem; border-radius: 4px; border-left: 4px solid var(--petrole); background: #e4eef1; color: var(--encre); }
.flash-succes { border-left-color: #2e7d4f; background: #e5f2ea; }
.flash-erreur { border-left-color: var(--brique); background: var(--brique-pale); }
.flash-info { border-left-color: var(--or); background: var(--or-pale); }
.flash ul { margin: 0.4rem 0 0; padding-left: 1.1rem; }
/* Tableaux et listes ----------------------------------------------------- */
.defile { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; }
th { text-align: left; font-weight: 600; font-size: 0.8125rem; color: var(--gris); }
th, td { padding: 0.5rem 0.9rem 0.5rem 0; border-bottom: 1px solid var(--trait); vertical-align: top; }
tbody tr:last-child > * { border-bottom: 0; }
.nombre { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; padding-right: 0; }
td small, li small { color: var(--gris); font-size: 0.8125rem; }
.grille { display: grid; grid-template-columns: 8rem minmax(0, 1fr); gap: 0.4rem 1rem; margin: 0 0 1rem; align-items: baseline; }
.grille.serre { grid-template-columns: 6.5rem minmax(0, 1fr); }
.grille dt { color: var(--gris); font-size: 0.875rem; }
.grille dd { margin: 0; overflow-wrap: anywhere; }
ul.simple { list-style: none; padding: 0 !important; margin: 0 0 0.9rem; display: grid; gap: 0.6rem; }
ul.simple small { display: block; }
/* Repères : séniorité, statut, échelle d'avancement ---------------------- */
.badge { display: inline-block; padding: 0.05rem 0.5rem; border: 1px solid #98a1a8; border-radius: 3px; font-size: 0.75rem; font-weight: 600; color: var(--encre); background: #fff; white-space: nowrap; }
.badge-expert { background: var(--noir); border-color: var(--noir); color: var(--or); }
.badge-confirme { background: var(--or-pale); border-color: #cbbb62; color: #4d4204; }
.badge-junior { color: var(--gris); }
.etat { display: inline-flex; align-items: center; gap: 0.5rem; font-weight: 600; font-size: 0.875rem; white-space: nowrap; }
.echelle { display: inline-grid; gap: 2px; flex: none; vertical-align: middle; }
.echelle i { display: block; width: 14px; height: 2px; background: #c4cace; }
.echelle i.plein { background: var(--noir); }
.echelle-refus i:last-child { background: var(--brique); }
.echelle-grande { gap: 4px; }
.echelle-grande i { width: 34px; height: 5px; }
.echelle-grande i.plein { background: var(--or); box-shadow: 0 0 0 1px #b8a22f inset; }
.technos { display: flex; flex-wrap: wrap; gap: 0.3rem; margin: 0.5rem 0 0; }
.technos span { background: var(--fond); border-radius: 3px; padding: 0.05rem 0.45rem; font-size: 0.8125rem; }
.technos span.trouve { background: var(--or); color: var(--noir); font-weight: 600; }
.technos-ligne { margin: 0.35rem 0 0; font-size: 0.8125rem; color: var(--gris); }
/* Kanban ----------------------------------------------------------------- */
.kanban { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(10.75rem, 1fr); gap: 0.9rem; overflow-x: auto; padding: 0.25rem 0 1.5rem; align-items: start; scroll-snap-type: x proximity; }
.colonne { min-width: 0; scroll-snap-align: start; }
.colonne h2 { display: flex; align-items: center; gap: 0.6rem; margin: 0 0 0.7rem; padding-bottom: 0.6rem; border-bottom: 2px solid var(--noir); font-size: 0.9375rem; line-height: 1.2; min-height: 3.1rem; }
.colonne-non_retenu h2 { border-bottom-color: var(--brique); }
.nom-colonne { flex: 1; }
.compteur { font: 500 1.25rem/1 var(--titre); color: var(--gris); }
.cartes { list-style: none; margin: 0; padding: 0; min-height: 5rem; display: grid; gap: 0.5rem; align-content: start; }
.fiche { background: var(--surface); border: 1px solid var(--trait); border-radius: 4px; padding: 0.65rem 0.75rem; }
.kanban[data-modifiable="1"] .fiche { cursor: grab; }
.kanban[data-modifiable="1"] .fiche:hover { border-color: var(--encre); }
.fiche > a { font-weight: 600; color: var(--encre); text-decoration: none; }
.fiche > a:hover { text-decoration: underline; }
.fiche .poste { margin: 0.1rem 0 0.45rem; color: var(--gris); font-size: 0.875rem; line-height: 1.35; }
.fiche .meta { margin: 0; font-size: 0.8125rem; display: flex; gap: 0.5rem; align-items: center; }
.fiche .motif { margin: 0.5rem 0 0; padding-top: 0.4rem; border-top: 1px solid var(--trait); font-size: 0.8125rem; color: var(--brique); }
.fantome { opacity: 0.35; }
/* Fiche profil ----------------------------------------------------------- */
.entete-profil { display: flex; justify-content: space-between; align-items: flex-end; gap: 1rem 2rem; flex-wrap: wrap; margin-bottom: 1rem; }
.identite-profil { display: flex; align-items: center; gap: 1.1rem; min-width: 0; }
.sous-titre { margin: 0.45rem 0 0; color: var(--gris); display: flex; gap: 0.3rem 0.9rem; align-items: center; flex-wrap: wrap; }
.exports { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.barre-statut { margin-bottom: 1rem; padding: 0.8rem 1rem; background: var(--surface); border: 1px solid var(--trait); border-radius: 6px; }
.statut-form { display: flex; gap: 0.7rem; align-items: flex-end; flex-wrap: wrap; }
.statut-form label { flex: 0 1 16rem; }
.statut-form label + label { flex: 1 1 16rem; }
.experience { padding: 0.9rem 0; border-top: 1px solid var(--trait); }
.experience:first-of-type { border-top: 0; padding-top: 0; }
.experience:last-child { padding-bottom: 0; }
.experience p { margin: 0.3rem 0 0; max-width: 75ch; }
.periode { font-size: 0.8125rem; color: var(--or-fonce); font-weight: 600; margin: 0 0 0.15rem !important; }
.employeur { color: var(--gris); }
.commentaire { border-top: 1px solid var(--trait); padding-top: 0.7rem; margin-top: 0.7rem; }
.commentaire p { margin: 0; }
.auteur { font-size: 0.8125rem; color: var(--gris); margin-bottom: 0.15rem !important; }
.historique { list-style: none; padding: 0 !important; margin: 0 0 0.8rem; display: grid; gap: 0.55rem; font-size: 0.875rem; }
.historique span { display: block; font-size: 0.8125rem; color: var(--gris); }
.groupe-mots { margin: 0.7rem 0 0.3rem; font-size: 0.8125rem; color: var(--gris); }
.mots { list-style: none; display: flex; flex-wrap: wrap; gap: 0.3rem; margin: 0; padding: 0 !important; }
.mots li { display: inline-flex; align-items: center; background: var(--fond); border-radius: 3px; padding: 0.1rem 0.15rem 0.1rem 0.5rem; font-size: 0.8125rem; }
.mots li.manuel { background: var(--or-pale); }
.mots form { display: inline-flex; }
.mots button { min-height: 1.5rem; min-width: 1.5rem; padding: 0; background: none; border: 0; color: var(--gris); font-weight: 700; }
.mots button:hover { background: none; color: var(--brique); }
.ajout-mot { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 9rem) auto; gap: 0.5rem; align-items: end; margin-top: 1rem; }
/* Recherche -------------------------------------------------------------- */
.resultats { list-style: none; margin: 0; padding: 0; }
.resultats .carte { margin-bottom: 0.6rem; padding: 0.9rem 1.2rem; }
.resultat-tete { display: flex; justify-content: space-between; align-items: baseline; gap: 0.3rem 1rem; flex-wrap: wrap; }
.resultats .nom { font: 500 1.35rem/1.2 var(--titre); color: var(--encre); text-decoration: none; }
.resultats .nom:hover { text-decoration: underline; }
.resultats .sous-titre { font-size: 0.875rem; margin-top: 0.3rem; }
/* Comptes ---------------------------------------------------------------- */
.comptes { list-style: none; margin: 0; padding: 0; }
.comptes .carte.inactif { background: #f6f7f8; }
.compte-nom { font-weight: 600; font-size: 1.0625rem; margin: 0 0 0.2rem; }
.compte-meta { display: flex; flex-wrap: wrap; gap: 0.2rem 1.1rem; color: var(--gris); font-size: 0.875rem; margin-bottom: 0.7rem; }
.compte-meta strong { color: var(--encre); }
/* Tableau de bord -------------------------------------------------------- */
.chiffres { display: grid; grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr)); gap: 0; margin: 0 0 1.25rem; background: var(--noir); color: #fff; border-radius: 6px; overflow: hidden; }
.chiffres div { padding: 1.1rem 1.3rem 1.2rem; border-left: 1px solid #333; display: flex; flex-direction: column; justify-content: flex-start; gap: 0.4rem; }
.chiffres div:first-child { border-left: 0; }
.chiffres dt { color: #c9c9c9; font-size: 0.875rem; }
.chiffres dt a { color: inherit; }
.chiffres dd { order: -1; margin: 0; font: 500 3rem/1 var(--titre); color: var(--or); font-variant-numeric: lining-nums; }
.mesures th { color: var(--encre); font-size: 0.9375rem; font-weight: 400; white-space: nowrap; width: 1%; vertical-align: middle; }
.mesures th:has(.echelle) { position: relative; padding-left: 1.6rem; }
.mesures th .echelle { position: absolute; left: 0; top: 50%; transform: translateY(-50%); }
.mesures td { vertical-align: middle; }
.mesures .nombre { width: 1%; font-weight: 600; }
.mesures .nombre small { font-weight: 400; margin-left: 0.3rem; }
.barre { display: block; height: 0.6rem; background: var(--fond); min-width: 4rem; }
.barre span { display: block; height: 100%; background: var(--noir); }
.l0 { width: 0; } .l1 { width: 5%; } .l2 { width: 10%; } .l3 { width: 15%; } .l4 { width: 20%; } .l5 { width: 25%; }
.l6 { width: 30%; } .l7 { width: 35%; } .l8 { width: 40%; } .l9 { width: 45%; } .l10 { width: 50%; }
.l11 { width: 55%; } .l12 { width: 60%; } .l13 { width: 65%; } .l14 { width: 70%; } .l15 { width: 75%; }
.l16 { width: 80%; } .l17 { width: 85%; } .l18 { width: 90%; } .l19 { width: 95%; } .l20 { width: 100%; }
/* Rapport ---------------------------------------------------------------- */
.rapport h2 { font: 500 1.75rem/1.15 var(--titre); margin: 0 0 1rem; }
.rapport h3 { font: 600 1.0625rem/1.3 var(--texte); margin: 1.5rem 0 0.5rem; padding-bottom: 0.3rem; border-bottom: 2px solid var(--or); }
.rapport h4, .rapport h5 { font-size: 1rem; margin: 1rem 0 0.3rem; }
.rapport p, .rapport li { max-width: 75ch; }
.rapport ul, .rapport ol { margin: 0 0 0.8rem; padding-left: 1.3rem; }
.rapport pre { background: var(--fond); padding: 0.7rem; border-radius: 4px; overflow-x: auto; }
.rapport table { margin-bottom: 1rem; }
dialog { border: 1px solid var(--encre); border-radius: 6px; padding: 1.3rem; width: min(27rem, 92vw); }
dialog::backdrop { background: rgba(0, 0, 0, 0.55); }
/* Écrans étroits --------------------------------------------------------- */
@media (max-width: 1180px) {
.entete { display: block; position: static; }
.entete-barre { min-height: 3.25rem; }
.menu-bouton {
display: inline-flex; min-height: 2.15rem; padding: 0.25rem 0.9rem;
background: none; border: 1px solid #777; color: #fff;
}
.menu-bouton:hover { background: #222; border-color: #fff; color: #fff; }
.menu-bouton[aria-expanded="true"] { background: var(--or); border-color: var(--or); color: var(--noir); }
.entete-menu { display: none; flex-direction: column; align-items: stretch; gap: 0.8rem; padding: 0.2rem 0 1.1rem; }
.entete-menu.ouvert { display: flex; animation: derouler 0.16s ease-out; }
.entete nav { flex-direction: column; gap: 0; font-size: 1rem; }
.entete nav > a, .menu-plus > summary { min-height: 2.9rem; border-bottom: 1px solid #2c2c2c; box-shadow: inset 3px 0 0 transparent; justify-content: space-between; }
.entete nav > a[aria-current], .menu-plus.actif > summary { box-shadow: inset 3px 0 0 var(--or); padding-left: 0.75rem; }
.menu-plus > summary::after { margin-right: 0.3rem; }
.menu-plus-liste, .menu-compte .menu-plus-liste { position: static; min-width: 0; border: 0; box-shadow: none; background: none; padding: 0.2rem 0 0.4rem 0.75rem; animation: none; }
.recherche-rapide input[type="search"], .recherche-rapide input[type="search"]:focus { flex: 1; width: auto; min-height: 2.6rem; }
.bouton.bouton-entete { min-height: 2.6rem; }
.menu-compte > summary { border-bottom: 0; border-top: 1px solid #2c2c2c; }
.menu-compte .nom-compte { flex: 1; }
}
@media (max-width: 900px) {
.deux-colonnes, .deux-colonnes.inverse { grid-template-columns: minmax(0, 1fr); }
.kanban { grid-auto-columns: min(82vw, 20rem); scroll-snap-type: x mandatory; margin-right: calc(-1 * var(--gouttiere)); padding-right: var(--gouttiere); }
.colonne h2 { min-height: 0; }
}
@media (max-width: 640px) {
.carte { padding: 1rem; }
.champs { grid-template-columns: minmax(0, 1fr); }
.ajout-mot { grid-template-columns: minmax(0, 1fr); }
.grille, .grille.serre { grid-template-columns: minmax(0, 1fr); gap: 0.1rem; }
.grille dd { margin-bottom: 0.5rem; }
.filtres label, .filtres label.large, .statut-form label, .statut-form label + label { flex: 1 1 100%; }
.filtres > button, .filtres > .bouton, .statut-form > button { flex: 1 1 100%; }
.filtres .fin { margin-left: 0; }
.exports { width: 100%; }
.exports .bouton { flex: 1 1 calc(50% - 0.25rem); }
.actions > * { flex: 1 1 auto; }
.echelle-grande i { width: 24px; height: 4px; }
.chiffres { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.chiffres div { border-left: 0; border-top: 1px solid #333; }
.chiffres div:nth-child(-n+2) { border-top: 0; }
.chiffres div:nth-child(even) { border-left: 1px solid #333; }
.chiffres div:last-child:nth-child(odd) { grid-column: 1 / -1; }
.chiffres dd { font-size: 2.4rem; }
.barre-titre .filtres label { flex: 1 1 40%; min-width: 0; }
.mesures th { white-space: normal; }
.barre { min-width: 2.5rem; }
th, td { padding-right: 0.6rem; }
}
@media (prefers-reduced-motion: reduce) {
* { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
}
@media print {
.entete, .filtres, .exports, .barre-statut form { display: none; }
body { background: #fff; }
}
/* Portraits -------------------------------------------------------------- */
.avatar { display: inline-grid; place-items: center; flex: none; width: 2.25rem; height: 2.25rem; border-radius: 50%; object-fit: cover; object-position: center 20%; background: var(--fond); }
.avatar-vide { font-size: 0.75rem; font-weight: 600; color: var(--gris); border: 1px solid var(--trait); letter-spacing: 0.02em; }
.avatar-moyen { width: 3.5rem; height: 3.5rem; }
.avatar-moyen.avatar-vide { font-size: 1.05rem; }
.avatar-grand { width: 6rem; height: 6rem; border-radius: 6px; }
.avatar-grand.avatar-vide { font: 500 2rem var(--titre); }
.fiche-tete { display: flex; gap: 0.6rem; align-items: flex-start; }
.fiche-tete > div { min-width: 0; }
.fiche-tete a { font-weight: 600; color: var(--encre); text-decoration: none; }
.fiche-tete a:hover { text-decoration: underline; }
.resultat { display: flex; gap: 1rem; align-items: flex-start; }
.resultat-corps { flex: 1; min-width: 0; }
.relecture { display: flex; gap: 1.5rem; align-items: flex-start; flex-wrap: wrap; }
.relecture .grille { flex: 1 1 20rem; }
.relecture-photo { display: grid; gap: 0.5rem; justify-items: start; }
label.case { display: flex; align-items: center; gap: 0.45rem; font-weight: 400; }
label.case input { width: 1.1rem; height: 1.1rem; }
/* Choix de la langue ----------------------------------------------------- */
.langues { display: inline-flex; border: 1px solid #555; border-radius: 4px; overflow: hidden; }
.langues button { min-height: 1.75rem; padding: 0.05rem 0.55rem; background: none; border: 0; border-radius: 0; color: #d9d9d9; font-size: 0.8125rem; font-weight: 600; }
.langues button:hover { background: #2a2a2a; color: #fff; }
.langues button[aria-pressed="true"] { background: var(--or); color: var(--noir); }
.langues-accueil { position: absolute; top: 1rem; right: 1rem; }
@media (max-width: 640px) {
.avatar-grand { width: 4.5rem; height: 4.5rem; }
.resultat { gap: 0.7rem; }
.avatar-moyen { width: 2.75rem; height: 2.75rem; }
}
/* Version 1.4 : suivi, besoins, lot, sauvegarde -------------------------- */
input[type="date"], input[type="time"] {
width: 100%; min-height: 2.6rem; padding: 0.5rem 0.7rem; font-weight: 400;
background: #fff; border: 1px solid #98a1a8; border-radius: 4px;
}
h2 small { font-weight: 400; color: var(--gris); margin-left: 0.3rem; }
.barre-titre h2 { margin: 0; }
.carte.inactif { background: #f6f7f8; }
.actions.gauche { justify-content: flex-start; }
details.ajout { margin: 0.9rem 0 0; padding-top: 0.6rem; border-top: 1px solid var(--trait); }
.depot { margin-bottom: 1rem; }
/* Repères sur les cartes du Kanban */
.fiche .reperes { margin: 0.45rem 0 0; padding-top: 0.4rem; border-top: 1px solid var(--trait); font-size: 0.8125rem; display: grid; gap: 0.1rem; color: var(--or-fonce); font-weight: 600; }
/* Badges d'état */
.badge-attente { background: var(--or-pale); border-color: #cbbb62; color: #4d4204; }
.badge-avis-favorable, .badge-besoin-pourvu, .badge-proposition-retenu, .badge-lot-pret { background: #e5f2ea; border-color: #7fb597; color: #1d5a37; }
.badge-avis-reserve, .badge-proposition-presente, .badge-lot-analyse { background: var(--or-pale); border-color: #cbbb62; color: #4d4204; }
.badge-avis-defavorable, .badge-lot-erreur { background: var(--brique-pale); border-color: #d99a8c; color: var(--brique); }
.badge-besoin-ouvert { background: var(--noir); border-color: var(--noir); color: var(--or); }
.badge-besoin-ferme, .badge-proposition-ecarte, .badge-lot-en_attente { color: var(--gris); }
.etat .badge { margin-right: 0.2rem; }
/* Entretiens et relances sur la fiche */
.entretien { padding: 0.9rem 0; border-top: 1px solid var(--trait); }
.entretien:first-of-type { border-top: 0; padding-top: 0; }
.entretien p { margin: 0.3rem 0 0; max-width: 75ch; }
.entretien .periode { display: flex; flex-wrap: wrap; gap: 0.3rem 0.6rem; align-items: center; }
.entretien details { margin: 0.5rem 0 0; }
.relances li.faite, .agenda li.faite { color: var(--gris); }
.relances li.faite > span { text-decoration: line-through; }
.bandeau-archive { display: flex; gap: 0.8rem 1.5rem; align-items: center; justify-content: space-between; flex-wrap: wrap; }
.bandeau-archive p { margin: 0; }
/* Listes avec portrait : suivi, propositions, rapprochement */
.agenda li { display: flex; gap: 0.75rem; align-items: flex-start; padding-bottom: 0.7rem; border-bottom: 1px solid var(--trait); }
.agenda li:last-child { border-bottom: 0; padding-bottom: 0; }
.agenda li > div { flex: 1; min-width: 0; display: grid; gap: 0.2rem; }
.agenda li > div > a { font-weight: 600; color: var(--encre); justify-self: start; }
.agenda p { margin: 0; }
.agenda .technos { margin: 0.15rem 0; }
.agenda details { margin: 0.2rem 0 0; }
.agenda .badge { justify-self: start; }
.rapprochement li > div { position: relative; padding-right: 4.2rem; }
.note-rapprochement { position: absolute; right: 0; top: 0; font: 500 1.6rem/1 var(--titre); color: var(--encre); font-variant-numeric: lining-nums; }
.note-rapprochement small { font: 400 0.75rem var(--texte); color: var(--gris); margin-left: 0.1rem; }
.technos span.absent { background: #fff; border: 1px dashed #98a1a8; color: var(--gris); }
.description-besoin { margin-top: 0.8rem; max-width: 75ch; }
.besoin-etroit .champs { grid-template-columns: minmax(0, 1fr); }
.entete-profil .statut-form label { flex: 0 1 12rem; }
/* Import en lot */
table.lot td { vertical-align: middle; }
table.lot .detail-lot { margin: 0.3rem 0 0; font-size: 0.8125rem; font-weight: 400; max-width: 46ch; }
@media (max-width: 640px) {
.rapprochement li > div { padding-right: 0; }
.note-rapprochement { position: static; }
}
.deux-egales { margin-bottom: 1rem; }
.carte > form + form { margin-top: 0.8rem; }
.actions-ligne.droite { display: flex; justify-content: flex-end; }
.entete-profil .statut-form { flex-wrap: nowrap; }
/* Finitions ---------------------------------------------------------------
Le mouvement répond à un geste : ouvrir, déposer, confirmer. Rien ne bouge tout seul. */
@view-transition { navigation: auto; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: 0.14s; }
html { scroll-behavior: smooth; scroll-padding-top: 4.5rem; }
::selection { background: var(--or); color: var(--noir); }
.carte { border-radius: 8px; box-shadow: 0 1px 2px rgba(28, 28, 26, 0.04); }
.carte h2 { font-size: 1.0625rem; }
.barre-statut { border-radius: 8px; }
button, .bouton { transition: background-color 0.12s, border-color 0.12s, color 0.12s, transform 0.06s; }
button:active, .bouton:active { transform: translateY(1px); }
button.lien:active { transform: none; }
input[type="text"], input[type="email"], input[type="password"], input[type="search"], input[type="date"], input[type="time"], select, textarea { transition: border-color 0.12s, box-shadow 0.12s; }
main input[type="text"]:focus, main input[type="email"]:focus, main input[type="password"]:focus, main input[type="search"]:focus, main input[type="date"]:focus, main input[type="time"]:focus, main select:focus, main textarea:focus {
border-color: var(--petrole); box-shadow: 0 0 0 3px rgba(13, 74, 93, 0.16); outline: 0;
}
body.accueil main input:focus { border-color: var(--or); box-shadow: 0 0 0 3px rgba(206, 183, 59, 0.25); }
/* Blocs repliables : une flèche qui tourne, un contenu qui se déroule */
summary { list-style: none; display: flex; align-items: center; gap: 0.45rem; }
summary::-webkit-details-marker { display: none; }
main summary::before { content: ""; flex: none; width: 0.4rem; height: 0.4rem; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(-45deg); transition: transform 0.15s; }
main details[open] > summary::before { transform: translateY(-0.1rem) rotate(45deg); }
main details[open] > :not(summary) { animation: derouler 0.16s ease-out; }
dialog[open] { animation: derouler 0.16s ease-out; }
/* Messages : ils arrivent, se ferment d'un clic, et les confirmations s'effacent seules */
.flash { animation: derouler 0.2s ease-out; }
.flash.fermable { display: flex; gap: 1rem; align-items: flex-start; justify-content: space-between; }
.flash .fermer { flex: none; min-height: 0; width: 1.6rem; height: 1.6rem; padding: 0; margin: -0.1rem -0.3rem 0 0; background: none; border: 0; border-radius: 50%; color: inherit; font-size: 1.15rem; line-height: 1; opacity: 0.6; }
.flash .fermer:hover { background: rgba(0, 0, 0, 0.08); opacity: 1; }
.flash.part { opacity: 0; transform: translateY(-4px); transition: opacity 0.25s, transform 0.25s; }
tbody tr { transition: background-color 0.1s; }
.defile tbody tr:hover { background: #f5f7f8; }
/* Kanban : des couloirs visibles, une carte qui se soulève, une zone de dépôt qui s'annonce */
.kanban { gap: 0.6rem; }
.colonne { background: rgba(255, 255, 255, 0.45); border-radius: 8px; padding: 0.7rem 0.55rem 0.55rem; }
.colonne h2 { padding: 0 0.2rem 0.6rem; min-height: 2.9rem; }
.cartes { min-height: 6rem; border-radius: 6px; transition: background-color 0.12s, box-shadow 0.12s; }
.cartes:not(:has(.fiche:not(.cachee)))::after { content: attr(data-vide); display: block; padding: 1.2rem 0.5rem; text-align: center; color: #8a9096; font-size: 0.8125rem; border: 1px dashed #c4cace; border-radius: 6px; }
.fiche { border-radius: 6px; transition: border-color 0.12s, box-shadow 0.12s; }
.kanban[data-modifiable="1"] .fiche:hover { box-shadow: 0 2px 6px rgba(28, 28, 26, 0.08); }
.kanban.en-glisse .cartes { background: rgba(206, 183, 59, 0.1); box-shadow: inset 0 0 0 1px rgba(206, 183, 59, 0.55); }
.fiche.saisie { cursor: grabbing; }
.fiche.glisse { box-shadow: 0 12px 24px rgba(0, 0, 0, 0.18); transform: rotate(1.2deg); border-color: var(--encre); }
.fantome { opacity: 1; background: var(--or-pale); border: 1px dashed #b8a22f; }
.fantome > * { visibility: hidden; }
.resultats .carte { transition: border-color 0.12s; }
.resultats .carte:hover { border-color: #98a1a8; }
/* Fiche profil : bandeau, onglets, panneaux ------------------------------
Le bandeau reste en tête de fiche. Les onglets restent collés sous l'en-tête.
Sans JavaScript, les onglets servent de sommaire et les quatre panneaux s'enchaînent. */
.barre-statut-ligne { display: flex; flex-wrap: wrap; gap: 0.9rem 2.5rem; align-items: flex-end; justify-content: space-between; }
.barre-statut-ligne .statut-form { flex: 1 1 26rem; }
.statut-lecture { margin: 0; }
.reperes-profil { display: flex; flex-wrap: wrap; gap: 0.5rem 2rem; margin: 0; }
.reperes-profil div { display: grid; gap: 0.1rem; min-width: 0; }
.reperes-profil dt { color: var(--gris); font-size: 0.8125rem; }
.reperes-profil dd { margin: 0; font-weight: 600; }
.reperes-profil dd em { font-weight: 400; }
.motif-profil { margin: 0.8rem 0 0; padding-top: 0.7rem; border-top: 1px solid var(--trait); color: var(--brique); }
.a-faire { list-style: none; margin: 0.8rem 0 0 !important; padding: 0.75rem 0 0 !important; border-top: 1px solid var(--trait); display: flex; flex-wrap: wrap; gap: 0.5rem; }
.a-faire a { display: inline-flex; align-items: center; gap: 0.45rem; padding: 0.3rem 0.8rem; border-radius: 999px; background: var(--fond); color: var(--encre); text-decoration: none; font-size: 0.875rem; font-weight: 600; transition: box-shadow 0.12s; }
.a-faire a::before { content: ""; flex: none; width: 0.45rem; height: 0.45rem; border-radius: 50%; background: var(--or); }
.a-faire .urgent a { background: var(--brique-pale); color: var(--brique); }
.a-faire .urgent a::before { background: var(--brique); }
.a-faire a:hover { box-shadow: inset 0 0 0 1px currentColor; color: inherit; }
.a-faire .urgent a:hover { color: var(--brique); }
/* CV IT Club : un bouton, deux versions */
.menu-deroulant { position: relative; margin: 0; }
.menu-deroulant > summary { padding: 0.5rem 1.1rem; }
main .menu-deroulant > summary::before { display: none; }
.menu-deroulant > summary::after { content: ""; flex: none; width: 0.36rem; height: 0.36rem; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: translateY(-0.12rem) rotate(45deg); transition: transform 0.15s; }
.menu-deroulant[open] > summary { margin-bottom: 0; }
.menu-deroulant[open] > summary::after { transform: translateY(0.1rem) rotate(225deg); }
.menu-deroulant-liste { position: absolute; right: 0; top: calc(100% + 0.3rem); z-index: 20; min-width: 12rem; display: grid; padding: 0.3rem; background: #fff; border: 1px solid var(--trait); border-radius: 8px; box-shadow: 0 12px 28px rgba(28, 28, 26, 0.14); }
.menu-deroulant-liste a { display: block; padding: 0.55rem 0.75rem; border-radius: 4px; color: var(--encre); text-decoration: none; }
.menu-deroulant-liste a:hover { background: var(--fond); color: var(--noir); }
.onglets { position: sticky; top: 3.25rem; z-index: 5; display: flex; gap: 0.15rem; margin: 0 calc(-1 * var(--gouttiere)) 1.25rem; padding: 0 var(--gouttiere); overflow-x: auto; background: rgba(236, 239, 241, 0.94); backdrop-filter: blur(6px); border-bottom: 1px solid var(--trait); scrollbar-width: none; }
.onglets::-webkit-scrollbar { display: none; }
.onglets a { flex: none; display: inline-flex; align-items: center; gap: 0.45rem; min-height: 2.9rem; padding: 0 1rem; color: var(--gris); text-decoration: none; font-weight: 600; font-size: 0.9375rem; white-space: nowrap; box-shadow: inset 0 -3px 0 transparent; transition: color 0.12s, box-shadow 0.12s; }
.onglets a:hover { color: var(--encre); box-shadow: inset 0 -3px 0 var(--trait); }
.onglets a[aria-selected="true"] { color: var(--noir); box-shadow: inset 0 -3px 0 var(--or); }
.onglets a:focus-visible { outline-offset: -3px; }
.onglets small { color: var(--gris); font-weight: 400; font-size: 0.8125rem; font-variant-numeric: tabular-nums; }
.pastille-alerte { background: var(--brique); color: #fff; }
html:has(.onglets) { scroll-padding-top: 7rem; }
.titre-panneau { font: 500 1.35rem/1.2 var(--titre); margin: 1.75rem 0 0.9rem; }
.panneau:first-of-type .titre-panneau { margin-top: 0; }
.avec-onglets .titre-panneau { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; margin: 0; }
.avec-onglets .panneau:not([hidden]) { animation: derouler 0.16s ease-out; }
.panneau:focus { outline: 0; }
details.suite { margin: 0.9rem 0 0; padding-top: 0.6rem; border-top: 1px solid var(--trait); }
details.suite .experience:first-of-type { padding-top: 0.2rem; }
details.suite table { margin-top: 0.2rem; }
.suite-historique { margin-top: 0.6rem; }
@media (max-width: 1180px) {
.onglets { top: 0; }
html:has(.onglets) { scroll-padding-top: 3.6rem; }
html { scroll-padding-top: 1rem; }
}
@media (max-width: 640px) {
.onglets a { padding: 0 0.75rem; }
.barre-statut-ligne { gap: 0.9rem; }
.barre-statut-ligne .statut-form { flex-basis: 100%; }
.reperes-profil { gap: 0.5rem 1.5rem; }
.exports .menu-deroulant { flex: 1 1 calc(50% - 0.25rem); }
.exports .menu-deroulant > summary { width: 100%; }
.menu-deroulant-liste { left: 0; right: auto; }
}
@media (prefers-reduced-motion: reduce) {
@view-transition { navigation: none; }
html { scroll-behavior: auto; }
}
@media print {
.onglets { display: none; }
.avec-onglets .panneau[hidden] { display: block !important; }
.avec-onglets .titre-panneau { position: static; width: auto; height: auto; clip: auto; margin: 1.5rem 0 0.8rem; }
}
/* Aide --------------------------------------------------------------------- */
.lien-aide { flex: none; display: grid; place-items: center; width: 1.9rem; height: 1.9rem; border-radius: 50%; border: 1px solid #6a6a6a; color: #fff; text-decoration: none; font-weight: 600; font-size: 0.9375rem; transition: border-color 0.12s, color 0.12s; }
.lien-aide:hover, .lien-aide[aria-current] { border-color: var(--or); color: var(--or); }
.lien-aide b { display: none; font-weight: 400; }
.aide-tete { align-items: center; }
.aide-outils { display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap; }
.versions { display: inline-flex; border: 1px solid #98a1a8; border-radius: 4px; overflow: hidden; background: #fff; }
.versions a { padding: 0.45rem 0.8rem; color: var(--encre); text-decoration: none; font-weight: 600; font-size: 0.875rem; }
.versions a[aria-current] { background: var(--noir); color: var(--or); }
.aide-page { display: grid; grid-template-columns: 17rem minmax(0, 1fr); gap: 1.5rem; align-items: start; }
.aide-sommaire { position: sticky; top: 4.25rem; max-height: calc(100vh - 5.25rem); overflow-y: auto; font-size: 0.9375rem; }
.aide-sommaire ol { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.1rem; }
.aide-sommaire ol a { display: block; padding: 0.35rem 0.7rem; border-left: 2px solid var(--trait); color: var(--encre); text-decoration: none; line-height: 1.3; transition: border-color 0.12s, background-color 0.12s; }
.aide-sommaire ol a:hover { border-left-color: var(--or); background: #fff; }
.aide-guides { display: grid; gap: 0.3rem; margin: 0 0 1rem; }
.aide-guides a { padding: 0.45rem 0.7rem; border: 1px solid var(--trait); border-radius: 6px; background: #fff; color: var(--encre); text-decoration: none; font-weight: 600; }
.aide-guides a[aria-current] { background: var(--noir); border-color: var(--noir); color: var(--or); }
.aide-texte { padding: 1.6rem 2rem 2rem; margin: 0; }
.aide-texte h2 { margin-top: 2.6rem; padding-top: 1.6rem; border-top: 1px solid var(--trait); }
.aide-texte h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.aide-texte h3 { margin-top: 1.7rem; }
.aide-texte p, .aide-texte li { max-width: 72ch; line-height: 1.6; }
.aide-texte li { margin-bottom: 0.25rem; }
.aide-texte .defile { margin: 0.4rem 0 1.1rem; }
.aide-texte table { max-width: 60rem; }
.aide-texte th { white-space: nowrap; }
.aide-texte td:first-child { white-space: nowrap; font-weight: 600; }
.aide-texte code { white-space: nowrap; }
@media (max-width: 1180px) {
.lien-aide { width: auto; height: auto; min-height: 2.6rem; display: flex; justify-content: flex-start; border: 0; border-radius: 0; border-top: 1px solid #2c2c2c; font-weight: 400; font-size: 1rem; }
.lien-aide span { display: none; }
.lien-aide b { display: inline; }
}
@media (max-width: 900px) {
.aide-page { grid-template-columns: minmax(0, 1fr); }
.aide-sommaire { position: static; max-height: none; }
.aide-sommaire ol { grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr)); }
.aide-texte { padding: 1.1rem 1rem 1.4rem; }
.aide-texte td:first-child, .aide-texte th, .aide-texte code { white-space: normal; }
}
@media print {
.aide-page { display: block; }
.aide-sommaire, .aide-outils, .evitement, main > .flash { display: none; }
.aide-texte { border: 0; box-shadow: none; padding: 0; }
.aide-texte h2 { break-after: avoid; }
.aide-texte h3 { break-after: avoid; }
.aide-texte table, .aide-texte li { break-inside: avoid; }
.aide-texte .defile { overflow: visible; }
}
/* Les guides et les rapports gardent leurs grands titres */
.carte.rapport h2 { font-size: 1.75rem; }
.carte.rapport h3 { font-size: 1.125rem; }
/* Version 1.5 : demande de compte, validation, corbeille ------------------ */
.porte-lien { margin: 1.4rem 0 0; font-size: 0.9375rem; }
.porte-lien a { color: var(--or); }
.porte-lien a:hover { color: #fff; }
/* Champ piège de la demande de compte : hors de l'écran, ignoré des lecteurs d'écran et du clavier */
.piege { position: absolute; left: -999rem; width: 1px; height: 1px; overflow: hidden; }
.carte.demandes { border-left: 4px solid var(--or); }
.carte.demandes h2 small { color: var(--gris); font-weight: 400; }
.liste-demandes { list-style: none; margin: 0; padding: 0; }
.liste-demandes li { display: flex; flex-wrap: wrap; gap: 0.6rem 1.5rem; align-items: center; justify-content: space-between; padding: 0.8rem 0; border-top: 1px solid var(--trait); }
.liste-demandes .compte-meta { margin-bottom: 0; }
.compte-menu { color: #9a9a9a; font-weight: 400; }
.profil-ligne { display: flex; gap: 0.7rem; align-items: center; }
.profil-ligne .avatar { flex: none; }
p.aide.danger { margin-bottom: 0; }
@page { margin: 16mm 15mm; }
@media print { main { padding: 0; max-width: none; } .aide-tete h1 { font-size: 26pt; margin-bottom: 6mm; } }
/* Version 1.7 : finitions d'usage ------------------------------------------ */
/* Un bouton d'état ne se coupe pas sur deux lignes */
.statut-form button { white-space: nowrap; }
/* Profils : sur écran étroit, les filtres se replient derrière un bouton (le script l'ajoute) */
.bouton-filtres { display: none; }
@media (max-width: 640px) {
.bouton-filtres { display: inline-flex; flex: 1 1 100%; }
.bouton-filtres[aria-expanded="true"] { background: var(--encre); color: #fff; }
form[data-repli].replie > label:not(.large) { display: none; }
}
/* Écran tactile : des cibles d'au moins 24 px pour les liens d'action et les noms cliquables */
@media (pointer: coarse), (max-width: 640px) {
button.lien { min-height: 1.75rem; }
.fiche > a, .fiche-tete a, .agenda li > div > a, .resultat a.nom { display: inline-block; padding: 0.15rem 0; }
.mots button { min-width: 1.75rem; min-height: 1.75rem; }
}
/* Formulaire de la fiche : trois blocs titrés */
fieldset.groupe { border: 0; border-top: 1px solid var(--trait); margin: 0; padding: 1.1rem 0 0; min-width: 0; }
fieldset.groupe legend { font: 600 1.0625rem/1.3 var(--texte); padding: 0 0.6rem 0 0; }
fieldset.groupe > .aide { margin: 0.2rem 0 0.9rem; }
.aide-champ { font-weight: 400; color: var(--gris); font-size: 0.8125rem; }
.champs > label { align-content: start; }
/* Version 1.8 : sécurité des accès, traductions, nationalité, Europass ------ */
/* Pages d'entrée : connexion, code, invitation, double authentification */
.porte-note { margin: 1rem 0 0; color: #bdbdbd; font-size: 0.875rem; text-align: left; }
.porte-texte { text-align: left; color: #e6e6e6; }
.porte-texte p { margin: 0 0 0.8rem; }
.porte-details { margin: 1.2rem 0 0; text-align: left; color: #d0d0d0; font-size: 0.9375rem; }
.porte-details summary { cursor: pointer; color: var(--or); }
.porte-details p { margin: 0.6rem 0 0; }
body.accueil main:has(.porte-large) { max-width: 34rem; }
.code-saisie { font: 600 1.5rem/1.2 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; letter-spacing: 0.25em; text-align: center; }
.porte input.code-saisie { background: #151515; border-color: #555; color: #fff; }
.etapes-2fa { counter-reset: etape; list-style: none; margin: 0; padding: 0; display: grid; gap: 1.1rem; text-align: left; }
.etapes-2fa > li { counter-increment: etape; position: relative; padding-left: 2.4rem; display: grid; gap: 0.5rem; justify-items: start; }
.etapes-2fa > li::before {
content: counter(etape); position: absolute; left: 0; top: 0; width: 1.7rem; height: 1.7rem; border-radius: 50%;
display: grid; place-items: center; background: var(--or); color: var(--noir); font-weight: 700; font-size: 0.875rem;
}
.etapes-2fa > li > span { color: var(--gris); font-size: 0.9375rem; }
.porte .etapes-2fa > li > span { color: #c9c9c9; }
.etapes-2fa form { width: 100%; }
.qr { display: block; width: 12rem; max-width: 100%; aspect-ratio: 1; background: #fff; border-radius: 6px; padding: 0.3rem; }
.qr svg { display: block; width: 100%; height: 100%; }
.cle-2fa { display: inline-block; font-size: 1rem; letter-spacing: 0.08em; padding: 0.35rem 0.6rem; user-select: all; overflow-wrap: anywhere; }
.porte .cle-2fa { background: #151515; color: #fff; border: 1px solid #555; }
.codes-secours { list-style: none; margin: 0 0 1rem; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr)); gap: 0.5rem; }
.codes-secours code { display: block; text-align: center; font-size: 1.0625rem; padding: 0.5rem; letter-spacing: 0.06em; border: 1px dashed var(--trait); }
/* Page publique : guide Sécurité lu sans être connecté */
body.public { background: var(--fond); }
.entete-public { justify-content: space-between; }
/* Comptes et invitations */
.intertitre { margin: 1.1rem 0 0.6rem; font-size: 0.9375rem; }
.ajout-ligne { display: flex; flex-wrap: wrap; gap: 0.6rem 1rem; align-items: flex-end; margin: 0 0 0.8rem; }
.ajout-ligne label { flex: 1 1 16rem; }
.lien-invitation { background: var(--or-pale); border-left: 4px solid var(--or); padding: 0.8rem 1rem; margin: 0 0 1rem; border-radius: 4px; }
.lien-invitation p { margin: 0 0 0.5rem; }
.copie { display: flex; gap: 0.5rem; }
.copie input { flex: 1 1 auto; min-width: 0; font: 0.875rem ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; background: #fff; }
.copie button { flex: none; }
.ligne-action { display: flex; flex-wrap: wrap; gap: 0.3rem 1rem; align-items: baseline; justify-content: space-between; }
.ligne-action form { display: inline; }
.connexions-courtes li { font-size: 0.9375rem; }
.bloc-action { margin: 0.9rem 0 0.4rem; }
.comptes details { margin: 0.4rem 0 0; }
.comptes details > summary { cursor: pointer; color: var(--petrole); font-size: 0.9375rem; }
.comptes details[open] > summary { margin-bottom: 0.6rem; }
.comptes .actions-ligne { margin-top: 0.8rem; }
/* Profil : traduction et mission */
.bandeau-traduction { display: flex; flex-wrap: wrap; gap: 0.5rem 1rem; align-items: center; justify-content: space-between; }
.bandeau-traduction p { margin: 0; flex: 1 1 24rem; }
.bandeau-traduction form { flex: none; }
.note-traduction { color: var(--gris); font-size: 0.8125rem; margin: -0.4rem 0 0.9rem; }
.note-traduction a { margin-left: 0.4rem; }
.cadre-mission { color: var(--gris); font-size: 0.875rem; margin: 0.2rem 0 0.4rem; }
.mission { font-style: italic; }
.permis-libre { margin: 0 0 0.9rem; }
@media print {
body:has(.codes-secours) .entete, body:has(.codes-secours) .actions { display: none; }
}
+1635
View File
File diff suppressed because it is too large. Load diff