Repository with sources and generator of https://larlet.fr/david/ https://larlet.fr/david/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.html 26KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang="fr">
  4. <!-- Has to be within the first 1024 bytes, hence before the `title` element
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset="utf-8">
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name="viewport" content="width=device-width,initial-scale=1">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>Traces — David Larlet</title>
  13. <meta name="description" content="Cet article est un brouillon, pas encore publié. Vous êtes invité·e à NE PAS le partager pour l’instant. Merci.">
  14. <!-- That good ol' feed, subscribe :). -->
  15. <link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
  16. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  17. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
  18. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
  19. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
  20. <link rel="manifest" href="/static/david/icons2/site.webmanifest">
  21. <link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
  22. <link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
  23. <meta name="msapplication-TileColor" content="#f7f7f7">
  24. <meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
  25. <meta name="theme-color" content="#f7f7f7" media="(prefers-color-scheme: light)">
  26. <meta name="theme-color" content="#272727" media="(prefers-color-scheme: dark)">
  27. <!-- Documented, feel free to shoot an email. -->
  28. <link rel="stylesheet" href="/static/david/css/style_2021-01-20.css">
  29. <!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
  30. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  31. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  32. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  33. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  34. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  35. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  36. <script>
  37. function toggleTheme(themeName) {
  38. document.documentElement.classList.toggle(
  39. 'forced-dark',
  40. themeName === 'dark'
  41. )
  42. document.documentElement.classList.toggle(
  43. 'forced-light',
  44. themeName === 'light'
  45. )
  46. }
  47. const selectedTheme = localStorage.getItem('theme')
  48. if (selectedTheme !== 'undefined') {
  49. toggleTheme(selectedTheme)
  50. }
  51. </script>
  52. <body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all">
  53. <article>
  54. <header>
  55. <h1>Traces</h1>
  56. </header>
  57. <nav>
  58. <p class="center">
  59. <nobr>
  60. <a href="/david/" title="Aller à l’accueil"
  61. ><svg class="icon icon-home">
  62. <use
  63. xlink:href="/static/david/icons2/symbol-defs-2022-03.svg#icon-home"
  64. ></use>
  65. </svg>
  66. Accueil</a
  67. >
  68. </nobr>
  69. <nobr>
  70. <a href="/david/recherche/" title="Aller à la page de recherche"
  71. ><svg class="icon icon-search">
  72. <use
  73. xlink:href="/static/david/icons2/symbol-defs-2022-03.svg#icon-search"
  74. ></use>
  75. </svg>
  76. Recherche</a
  77. >
  78. </nobr>
  79. </p>
  80. </nav>
  81. <hr>
  82. <p><em>Cet article est un brouillon, pas encore publié. Vous êtes invité·e à NE PAS le partager pour l’instant. Merci.</em></p>
  83. <details>
  84. <summary>Proposition 24&nbsp;jours de web</summary>
  85. <blockquote>
  86. <p>Je vous propose un article sur ma pratique d’un journal professionnel. Je ne cherche pas à élargir mon audience et je suis conscient que mes privilèges facilitent la diffusion de mes idées et que je suis en capacité de publier mes pensées. Si vous avez d’autres propositions d’articles issues de personnes moins représentées, je leur cède bien volontiers ma place. Ce contenu sera de toute façon en ligne, soit en même temps, soit avec un délai à définir, sur mon propre espace de&nbsp;publication.</p>
  87. <p>Aussi, je peux servir d’article bouche-trou s’il y a un désistement de dernière minute. Je suis volontaire pour participer à la relecture d’autres propositions plus ou moins&nbsp;techniques.</p>
  88. </blockquote>
  89. </details>
  90. <p>Lorsqu’on parle de publication d’un journal sur le web —&nbsp;qu’il soit personnel ou professionnel&nbsp;— on pense tout de suite aux (web)blogs. Je voudrais ici partager avec vous une autre pratique du journal qui me permet de partager mon travail de manière semi-privée au sein des équipes distribuées et asynchrones que je côtoie depuis plus de 5&nbsp;ans. C’est un intermédiaire entre la description d’une facture, un compte rendu d’activité&nbsp;(CRA) et ce qui peut être échangé lors d’un rendez-vous d’équipe oral quotidien. Pour <a href="/david/2020/12/13/#journal">une version courte</a>.</p>
  91. <h2 id="prologue">Prologue <a href="#prologue" title="Ancre vers cette partie">#</a></h2><p>J’ai probablement été inspiré par les carnets de laboratoire si importants pour la recherche scientifique, ayant ensuite participé activement à leur numérisation et à leur passage au web (premier emploi). Il y a certainement des personnes comme <a href="https://ronan.amicel.net/">Ronan</a> et <a href="https://elsif.fr/">Yannick</a> qui m’ont influencé aussi dans cette routine d’écriture. Oh, et peut-être de bloguer depuis 18&nbsp;ans&nbsp;aussi&nbsp;🙃.</p>
  92. <h2 id="genese">Génèse <a href="#genese" title="Ancre vers cette partie">#</a></h2><p>Le plus vieux journal de la sorte que j’ai pu retrouver remonte à mon accompagnement de data.gouv.fr en 2016. C’est étrange d’avoir commencé en cours de mission mais ça correspond aussi à mon arrivée au Québec ce qui justifie probablement l’envie de créer un nouvel espace d’échanges asynchrones car je me retrouvais avec 6&nbsp;heures de décalage horaire. <em>Note&nbsp;: le fait de ne pas être sur la même timezone m’apporte beaucoup dans mon travail quotidien mais ce sera l’objet d’un futur article.</em> Il était aussi probablement plus facile de démarrer l’expérience avec une équipe que je connaissais bien (un an et demi&nbsp;d’ancienneté).</p>
  93. <figure>
  94. <a href="#journal-2016-datagouvfr"
  95. title="Cliquer pour une version haute résolution">
  96. <img src="/static/david/2022/journal-2016-datagouvfr.png" alt="Capture d’écran d’un ancien journal (2016)"
  97. loading="lazy" width="2200" height="1432" />
  98. </a>
  99. <a href="#_" class="lightbox" id="journal-2016-datagouvfr">
  100. <img src="/static/david/2022/journal-2016-datagouvfr.png" alt="Capture d’écran d’un ancien journal (2016)"
  101. loading="lazy" width="2200" height="1432" />
  102. </a>
  103. <figcaption>Capture d’écran d’un journal hebdomadaire pour la deuxième semaine de septembre&nbsp;2016.</figcaption>
  104. </figure>
  105. <p>On peut voir que je comptabilise le nombre de jours de manière publique avec l’équipe, que je partage un <em>mood</em> et que je documente ce que j’ai fait sur la semaine en cours/passée. Il y a aussi beaucoup de liens et d’emojis, on se refait&nbsp;pas&nbsp;🤷.</p>
  106. <p>Lors d’un essai, je trouve ça pertinent de ne pas trop se soucier de la forme ou du lieu où sont stockées les données, cela sera facilement modifiable et récupérable si l’expérience est concluante. Ça reste tout de même du texte brut en <em>markdown</em> qui est aisément&nbsp;transformable.</p>
  107. <p>J’ai continué ce premier journal jusqu’à la fin de l’année avant de valider l’expérience et de passer à une publication chez moi jusqu’à avoir un journal par équipe/produit. Avoir la main sur la conversion en HTML m’a permis de le représenter davantage sous la forme d’une <em>timeline</em> et de comptabiliser automagiquement les jours du mois pour la facturation grâce à des <code>data-attributes</code> bien placés. J’ai aussi la possibilité de replier les entrées très anciennes à l’aide d’un <code>details</code>/<code>summary</code> ce qui devient assez critique car je passe à un format quotidien plus approprié au <a href="https://beta.gouv.fr/startups/zam.html">produit sur lequel je travaille</a> à ce moment&nbsp;là.</p>
  108. <figure>
  109. <a href="#journal-2019-zam"
  110. title="Cliquer pour une version haute résolution">
  111. <img src="/static/david/2022/journal-2019-zam.png" alt="Capture d’écran d’un ancien journal (2019)"
  112. loading="lazy" width="1756" height="1254" />
  113. </a>
  114. <a href="#_" class="lightbox" id="journal-2019-zam">
  115. <img src="/static/david/2022/journal-2019-zam.png" alt="Capture d’écran d’un ancien journal (2019)"
  116. loading="lazy" width="1756" height="1254" />
  117. </a>
  118. <figcaption>Capture d’écran d’un journal quotidien fin&nbsp;2019</figcaption>
  119. </figure>
  120. <p>Il s’agit d’une routine qui demande une certaine rigueur mais en couplant l’écriture au décompte du temps passé —&nbsp;et donc à la rémunération associée&nbsp;— cela motive pour ne pas louper une&nbsp;entrée&nbsp;😅.</p>
  121. <h2 id="evolutions">Évolutions <a href="#evolutions" title="Ancre vers cette partie">#</a></h2><p>Début 2022, je sentais bien que je supportais de moins en moins le contexte du produit sur lequel je travaillais, j’ai donc introduit une notion de fun combinée à une comptabilité du temps plus précise qui ne s’effectuait plus à la (demi-)journée. Je me disais qu’il fallait au moins prendre la mesure de cette démotivation ainsi que son évolution. Cela m’a permis de clairement réaliser qu’il fallait que je mette fin à ma participation à ce&nbsp;produit.</p>
  122. <figure>
  123. <a href="#journal-2022-fun"
  124. title="Cliquer pour une version haute résolution">
  125. <img src="/static/david/2022/journal-2022-fun.png" alt="Capture d’écran d’un journal récent (début 2022)"
  126. loading="lazy" width="2414" height="1762" />
  127. </a>
  128. <a href="#_" class="lightbox" id="journal-2022-fun">
  129. <img src="/static/david/2022/journal-2022-fun.png" alt="Capture d’écran d’un journal récent (début 2022)"
  130. loading="lazy" width="2414" height="1762" />
  131. </a>
  132. <figcaption>Capture d’écran d’un journal début&nbsp;2022</figcaption>
  133. </figure>
  134. <p>Plus récemment, sur un autre journal/produit, j’ai ajouté des graphes du temps passé et de l’humeur du moment. Je voulais voir ce que ça pouvait donner sur une période et visualiser si l’humeur était dépendante d’une surcharge de travail par exemple. Je trouve intéressant d’avoir ce baromètre donnant une information importante pour les collaborateur·ices et pour&nbsp;moi-même.</p>
  135. <p>Au cours de l’évolution dans le temps du format du journal, je remarque que je me concentre davantage sur les émotions que sur ce qui a été fait de manière analytique. C’est peut-être lié à une maturité personnelle qui me fait considérer davantage le côté humain au côté technique dans mon&nbsp;travail.</p>
  136. <figure>
  137. <a href="#journal-2022-stylo"
  138. title="Cliquer pour une version haute résolution">
  139. <img src="/static/david/2022/journal-2022-stylo.png" alt="Capture d’écran d’un journal récent (2022)"
  140. loading="lazy" width="1366" height="1698" />
  141. </a>
  142. <a href="#_" class="lightbox" id="journal-2022-stylo">
  143. <img src="/static/david/2022/journal-2022-stylo.png" alt="Capture d’écran d’un journal récent (2022)"
  144. loading="lazy" width="1366" height="1698" />
  145. </a>
  146. <figcaption>Capture d’écran d’un journal quotidien en&nbsp;2022</figcaption>
  147. </figure>
  148. <p>Pour la source, elle est toujours en <em>markdown</em>, j’ai tenté à un moment d’écrire directement en HTML (et j’ai encore des journaux en cours ainsi) mais ça change ma fluidité d’écriture car je finis par être distrait par l’éditeur. J’ajoute des métadonnées à base d’emojis pour comptabiliser le temps et consigner&nbsp;l’humeur&nbsp;:</p>
  149. <figure>
  150. <a href="#journal-2022-stylo-source"
  151. title="Cliquer pour une version haute résolution">
  152. <img src="/static/david/2022/journal-2022-stylo-source.png" alt="Capture d’écran de la source d’un journal récent (2022)"
  153. loading="lazy" width="2982" height="880" />
  154. </a>
  155. <a href="#_" class="lightbox" id="journal-2022-stylo-source">
  156. <img src="/static/david/2022/journal-2022-stylo-source.png" alt="Capture d’écran de la source d’un journal récent (2022)"
  157. loading="lazy" width="2982" height="880" />
  158. </a>
  159. <figcaption>Capture d’écran de la source d’un journal quotidien en&nbsp;2022</figcaption>
  160. </figure>
  161. <p>Je passe sur certaines adaptations faites au cours du temps sur le générateur de HTML pour pouvoir supporter le décompte du temps de plusieurs personnes ou d’avoir plusieurs journaux combinés sur une même&nbsp;page.</p>
  162. <p>La technique est loin d’être clef dans ce contexte et l’importance est plutôt de rendre le journal accessible facilement aux autre membres de l’équipe. Je poste le lien vers l’entrée du jour plus ou moins régulièrement (en fonction de l’activité du projet) dans l’espace dédié à la discussion&nbsp;instantanée.</p>
  163. <h2 id="interets">Intérêts <a href="#interets" title="Ancre vers cette partie">#</a></h2><p>Le premier gain est personnel, il s’agit d’une mémoire externalisée de ce que j’ai fait avec des notes —&nbsp;parfois technique&nbsp;— de ce qui m’a débloqué à des moments clefs. Le fait de rédiger quotidiennement ou hebdomadairement me permet de faire un bilan de ce que j’ai réussi (ou échoué) à faire et des conditions de travail dans lesquelles j’ai été. Cela donne un sentiment d’avancement assez plaisant, ou lors de certaines périodes de réaliser que l’on piétine un peu aussi. J’y consignais aussi des bouts de code plus technique avant de les externaliser vers un <a href="https://code.larlet.fr/">espace public dédié</a>.</p>
  164. <p>Je relis rarement ce journal de bout en bout <em>a posteriori</em> mais je vais souvent y piocher des lignes de commandes ou des conclusions de réunions. Parfois même des actions à faire lorsque la régularité sur un produit devient plus&nbsp;espacée.</p>
  165. <p>Cela m’offre un certain recul sur le temps passé et ma «&nbsp;productivité&nbsp;» aussi, autant dans un sens (<em>burn-out</em>) que dans l’autre (culpabilité, syndrome de l’imposteur, etc). Il y a toute la réflexion autour de «&nbsp;Est-ce que c’est du travail&#8239;?&nbsp;» qui est intéressante lorsqu’on fait un travail plutôt intellectuel. Est-ce que d’aller me promener une heure est important pour arriver à la résolution de ce _bug_&#8239;? Est-ce que j’ai besoin de trois heures de procrastination pour arriver à développer cette fonctionnalité en 20&nbsp;minutes&#8239;? Si oui, comment facturer cela&#8239;? Etc.</p>
  166. <p>J’apprécie que le temps soit décompté de manière transparente, il y a rarement des surprises ou si elles le sont c’est rapidement expliqué. Je trouve cela important que pour des personnes moins techniques mon métier soit un peu plus tangible. Le fait de raconter les différents errements et recherches technologiques participe probablement à sa compréhension. Lorsqu’on facture au temps passé et qui plus est à distance, la confiance s’installe également par la&nbsp;transparence.</p>
  167. <p>Le gain collectif est difficile à estimer. J’ai souvent des retours positifs et inspirants. J’apprécie que toutes les personnes de l’équipe puissent avoir le même niveau d’information à mon sujet, autant au niveau du cheminement technique que de la forme du moment. Notamment dans des passages difficiles, je trouve ça intéressant de pouvoir m’exprimer à l’écrit de manière asynchrone, de manière un peu plus posée. Ces retours sont souvent à l’origine de discussions qui sont importantes pour que tout le monde se sente bien dans l’équipe. Le journal est une soupape de connaissances afin de ne pas devenir un·e gardien·ne du temple mais aussi une soupape&nbsp;émotionnelle&#8239;!</p>
  168. <p>Est-ce que les autres personnes des équipes lisent ces traces de développement au quotidien&#8239;? Je n’en ai aucune idée, je pense que chaque collaborateur·ice a ses propres routines de lectures et il faut combiner à cela les personnes qui sont plus à l’aise à l’oral. Le journal n’est pas exclusif mais fait partie d’une faculté plus globale à communiquer de plusieurs manières possibles pour essayer de transmettre un message&nbsp;compréhensible.</p>
  169. <h2 id="cooperative">Coopérative <a href="#cooperative" title="Ancre vers cette partie">#</a></h2><p>Dans un autre contexte — la <a href="http://scopyleft.fr/">coopérative</a> dont je fais partie depuis 10&nbsp;ans&nbsp;— j’ai démarré cette année un nouveau journal pour partager autour des petits produits que je mettais en proposition pour la&nbsp;SCOP.</p>
  170. <figure>
  171. <a href="#journal-2022-scopyleft"
  172. title="Cliquer pour une version haute résolution">
  173. <img src="/static/david/2022/journal-2022-scopyleft.png" alt="Capture d’écran de la source d’un journal de coopérative (2022)"
  174. loading="lazy" width="2586" height="952" />
  175. </a>
  176. <a href="#_" class="lightbox" id="journal-2022-scopyleft">
  177. <img src="/static/david/2022/journal-2022-scopyleft.png" alt="Capture d’écran de la source d’un journal de coopérative (2022)"
  178. loading="lazy" width="2586" height="952" />
  179. </a>
  180. <figcaption>Capture d’écran de la source d’un journal de coopérative en&nbsp;2022</figcaption>
  181. </figure>
  182. <p>Celui-ci avait encore une fois le double intérêt de partager mes expérimentations avec les membres de l’équipe et de comptabiliser le temps passé pour d’éventuelles productions immobilisées (du jargon pour dire que je crée de la valeur pour l’entreprise). La porte est ouverte, dans ce moteur de blog/site statique, pour que d’autres personnes puissent participer bien que cela n’ait pas encore été le&nbsp;cas.</p>
  183. <p>Ce journal a tout particulièrement pour objectif de générer des discussions et d’expliquer les attentes et frustrations autour des produits. Certaines entrées sont très techniques, d’autres davantage un résumé du cheminement. Je rédige souvent des entrées en pensant à une personne particulière de la coopérative qui pourrait le lire et y trouver des petites&nbsp;graines.</p>
  184. <p>Le fait d’être en décalage de six heures avec les autres membres me fait davantage utiliser l’écrit et l’asynchrone pour certaines tâches comme le développement pur, cela influence probablement mon attirance pour ces traces numériques. Il n’est pas toujours aisé de travailler côte à côte lorsqu’un océan les&nbsp;sépare.</p>
  185. <h2 id="la-suite">La suite&#8239;? <a href="#la-suite" title="Ancre vers cette partie">#</a></h2><p>Je ne sais pas de quoi mon prochain journal sera fait. La seule certitude que je peux avoir est qu’il existera. J’espère qu’il continuera à s’adapter à mes besoins et à ceux des équipes car c’est aussi un espace de jeu autour du partage et d’une autre forme de&nbsp;travail.</p>
  186. <p>Je vous invite à inventer le vôtre, qui vous correspondra et qui en inspirera d’autres. Peut-être que de nouvelles façons de faire émergeront, des dessins, une photo, un <em>haïku</em>, tout est&nbsp;possible.</p>
  187. <h2 id="epilogue">Épilogue <a href="#epilogue" title="Ancre vers cette partie">#</a></h2><p>Depuis cette année, l’enfant de 9&nbsp;ans qui vit avec moi rédige ce qu’ielles appellent dans sa classe des «&nbsp;traces d’études&nbsp;», ce qui correspond à une page de résumé des apprentissages pour la semaine en&nbsp;cours.</p>
  188. <p>Il n’est jamais trop tôt pour&nbsp;commencer&#8239;!</p>
  189. <figure>
  190. <a href="#journal-2022-traces"
  191. title="Cliquer pour une version haute résolution">
  192. <img src="/static/david/2022/journal-2022-traces.jpg" alt="Photo d’un cahier avec des traces d’études (2022)"
  193. loading="lazy" width="1512" height="1917" />
  194. </a>
  195. <a href="#_" class="lightbox" id="journal-2022-traces">
  196. <img src="/static/david/2022/journal-2022-traces.jpg" alt="Photo d’un cahier avec des traces d’études (2022)"
  197. loading="lazy" width="1512" height="1917" />
  198. </a>
  199. <figcaption>Une photo du cahier avec des traces&nbsp;d’études.</figcaption>
  200. </figure>
  201. <nav>
  202. <p class="center">
  203. <a href="/david/2022/" title="Liste des publications récentes">↑ En 2022</a>
  204. </p>
  205. </nav>
  206. </article>
  207. <hr>
  208. <footer>
  209. <p>
  210. <nobr>
  211. <a href="/david/" title="Aller à l’accueil"
  212. ><svg class="icon icon-home">
  213. <use
  214. xlink:href="/static/david/icons2/symbol-defs-2022-03.svg#icon-home"
  215. ></use>
  216. </svg>
  217. Accueil</a
  218. >
  219. </nobr>
  220. <nobr>
  221. <a href="/david/log/" title="Accès au flux RSS"
  222. ><svg class="icon icon-rss2">
  223. <use xlink:href="/static/david/icons2/symbol-defs-2022-03.svg#icon-rss2"></use>
  224. </svg>
  225. Suivre</a
  226. >
  227. </nobr>
  228. <nobr>
  229. <a href="http://larlet.com" title="Go to my English profile" data-instant
  230. ><svg class="icon icon-user-tie">
  231. <use xlink:href="/static/david/icons2/symbol-defs-2022-03.svg#icon-user-tie"></use>
  232. </svg>
  233. Pro</a
  234. >
  235. </nobr>
  236. <nobr>
  237. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel"
  238. ><svg class="icon icon-mail">
  239. <use xlink:href="/static/david/icons2/symbol-defs-2022-03.svg#icon-mail"></use>
  240. </svg>
  241. Email</a
  242. >
  243. </nobr>
  244. <nobr>
  245. <abbr
  246. class="nowrap"
  247. title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"
  248. ><svg class="icon icon-hammer2">
  249. <use xlink:href="/static/david/icons2/symbol-defs-2022-03.svg#icon-hammer2"></use>
  250. </svg>
  251. Légal</abbr
  252. >
  253. </nobr>
  254. </p>
  255. <template id="theme-selector">
  256. <form>
  257. <fieldset>
  258. <legend><svg class="icon icon-brightness-contrast">
  259. <use xlink:href="/static/david/icons2/symbol-defs-2022-03.svg#icon-brightness-contrast"></use>
  260. </svg> Thème</legend>
  261. <label>
  262. <input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
  263. </label>
  264. <label>
  265. <input type="radio" value="dark" name="chosen-color-scheme"> Foncé
  266. </label>
  267. <label>
  268. <input type="radio" value="light" name="chosen-color-scheme"> Clair
  269. </label>
  270. </fieldset>
  271. </form>
  272. </template>
  273. </footer>
  274. <script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
  275. <script>
  276. function loadThemeForm(templateName) {
  277. const themeSelectorTemplate = document.querySelector(templateName)
  278. const form = themeSelectorTemplate.content.firstElementChild
  279. themeSelectorTemplate.replaceWith(form)
  280. form.addEventListener('change', (e) => {
  281. const chosenColorScheme = e.target.value
  282. localStorage.setItem('theme', chosenColorScheme)
  283. toggleTheme(chosenColorScheme)
  284. })
  285. const selectedTheme = localStorage.getItem('theme')
  286. if (selectedTheme && selectedTheme !== 'undefined') {
  287. form.querySelector(`[value="${selectedTheme}"]`).checked = true
  288. }
  289. }
  290. const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
  291. window.addEventListener('load', () => {
  292. let hasDarkRules = false
  293. for (const styleSheet of Array.from(document.styleSheets)) {
  294. let mediaRules = []
  295. for (const cssRule of styleSheet.cssRules) {
  296. if (cssRule.type !== CSSRule.MEDIA_RULE) {
  297. continue
  298. }
  299. // WARNING: Safari does not have/supports `conditionText`.
  300. if (cssRule.conditionText) {
  301. if (cssRule.conditionText !== prefersColorSchemeDark) {
  302. continue
  303. }
  304. } else {
  305. if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
  306. continue
  307. }
  308. }
  309. mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
  310. }
  311. // WARNING: do not try to insert a Rule to a styleSheet you are
  312. // currently iterating on, otherwise the browser will be stuck
  313. // in a infinite loop…
  314. for (const mediaRule of mediaRules) {
  315. styleSheet.insertRule(mediaRule.cssText)
  316. hasDarkRules = true
  317. }
  318. }
  319. if (hasDarkRules) {
  320. loadThemeForm('#theme-selector')
  321. }
  322. })
  323. </script>
  324. </body>
  325. </html>