diff --git a/.dockerignore b/.dockerignore index a3e99c6..19cb398 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,3 +4,5 @@ npm-debug.log* .gitignore *.pdf README.md +src/images +scripts diff --git a/README.md b/README.md index 800dbd7..48259c7 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,18 @@ # calendrier_republicain -Convertisseur date actuelle en date du calendrier républicain \ No newline at end of file +Convertisseur date actuelle en date du calendrier républicain. + +Deux vues : la date du jour (ou d'une date choisie) sur une stèle illustrée de la gravure du mois, et la page « Le calendrier complet » (`#/calendar`) qui reprend la disposition de l'estampe de 1794 : quatre saisons, douze mois, les 360 jours et leurs noms, plus les jours complémentaires. + +## Lancer + +``` +node server.js # http://localhost:3000 +docker compose up --build +``` + +## Ressources graphiques + +- `src/images/` : gravures d'origine (scans). `public/assets/months/` en contient les versions recadrées et allégées, générées par `scripts/prepare-images.cjs` (`npm i --no-save sharp` au préalable ; sharp n'est pas une dépendance du projet). +- `public/assets/fonts/` : Old Standard TT (texte) et IM Fell English SC (titres), toutes deux sous licence SIL OFL (textes de licence dans le même dossier), servies localement. +- `public/data/day-names.json` : noms des 360 jours (Fabre d'Églantine), en français dans les deux langues. diff --git a/locales/en/common.json b/locales/en/common.json index 233c805..9a8167c 100644 --- a/locales/en/common.json +++ b/locales/en/common.json @@ -10,7 +10,8 @@ "aboutHistory": "History of the calendar", "aboutLeapYears": "Sextile years", "aboutComplementaryDays": "The complementary days", - "language": "Language" + "language": "Language", + "calendar": "Full calendar" }, "home": { "todayHeading": "Today is", @@ -44,5 +45,30 @@ "text": "Dates computed with the perpetual arithmetic rule proposed by Gilbert Romme (19 Floréal, Year III / 8 May 1795).", "sourceNote": "Historical content adapted from the \"French Republican calendar\" reference article." }, - "loading": "Loading…" + "loading": "Loading…", + "calendar": { + "title": "Calendar of the French Republic", + "subtitle": "The twelve months, the three décades and the days of the year", + "seasons": { + "autumn": "Autumn", + "winter": "Winter", + "spring": "Spring", + "summer": "Summer" + }, + "decades": [ + "1st décade", + "2nd décade", + "3rd décade" + ], + "dayColumn": "Days", + "explanationTitle": "Explanation", + "explanation": [ + "The Republican year begins at the autumnal equinox. It has twelve months of thirty days, split into three décades of ten days, plus five complementary days, or six in sextile years.", + "Each day is named after a plant, an animal, a mineral or a farming tool: the fifth day of each décade honours an animal, the tenth a tool, and in Nivôse the days honour minerals. The day names are given in French, as in the original.", + "Tap a month name to see its engraving and its origin. The day shown on the home page is highlighted." + ], + "feastsTitle": "Complementary days", + "sextileOnly": "sextile years only", + "close": "Close" + } } diff --git a/locales/fr/common.json b/locales/fr/common.json index 63c9925..4795272 100644 --- a/locales/fr/common.json +++ b/locales/fr/common.json @@ -10,7 +10,8 @@ "aboutHistory": "Histoire du calendrier", "aboutLeapYears": "Les années sextiles", "aboutComplementaryDays": "Les jours complémentaires", - "language": "Langue" + "language": "Langue", + "calendar": "Le calendrier complet" }, "home": { "todayHeading": "Nous sommes aujourd'hui le", @@ -44,5 +45,30 @@ "text": "Dates calculées selon la règle arithmétique perpétuelle proposée par Gilbert Romme (19 floréal an III / 8 mai 1795).", "sourceNote": "Contenu historique inspiré de l'article « Calendrier républicain »." }, - "loading": "Chargement…" + "loading": "Chargement…", + "calendar": { + "title": "Calendrier de la République française", + "subtitle": "Les douze mois, les trois décades et les jours de l'année", + "seasons": { + "autumn": "Automne", + "winter": "Hiver", + "spring": "Printemps", + "summer": "Été" + }, + "decades": [ + "1re décade", + "2e décade", + "3e décade" + ], + "dayColumn": "Jours", + "explanationTitle": "Explication", + "explanation": [ + "L'année républicaine commence à l'équinoxe d'automne. Elle compte douze mois de trente jours, partagés en trois décades de dix jours, auxquels s'ajoutent cinq jours complémentaires, six les années sextiles.", + "Chaque jour porte le nom d'une plante, d'un animal, d'un minéral ou d'un outil des travaux des champs : le quintidi est consacré à un animal, le décadi à un outil, et en nivôse les jours honorent les minéraux.", + "Touchez le nom d'un mois pour voir sa gravure et son origine. Le jour affiché sur la page d'accueil est surligné." + ], + "feastsTitle": "Jours complémentaires", + "sextileOnly": "années sextiles", + "close": "Fermer" + } } diff --git a/public/assets/complementary.svg b/public/assets/complementary.svg new file mode 100644 index 0000000..21f3cdf --- /dev/null +++ b/public/assets/complementary.svg @@ -0,0 +1,50 @@ + diff --git a/public/assets/fasces.svg b/public/assets/fasces.svg new file mode 100644 index 0000000..2aebac8 --- /dev/null +++ b/public/assets/fasces.svg @@ -0,0 +1,29 @@ + diff --git a/public/assets/favicon.svg b/public/assets/favicon.svg new file mode 100644 index 0000000..0c7ee2e --- /dev/null +++ b/public/assets/favicon.svg @@ -0,0 +1,5 @@ + diff --git a/public/assets/fonts/LICENSE-im-fell.txt b/public/assets/fonts/LICENSE-im-fell.txt new file mode 100644 index 0000000..046fc66 --- /dev/null +++ b/public/assets/fonts/LICENSE-im-fell.txt @@ -0,0 +1,93 @@ +Google Inc. + +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. diff --git a/public/assets/fonts/LICENSE-old-standard-tt.txt b/public/assets/fonts/LICENSE-old-standard-tt.txt new file mode 100644 index 0000000..a4a51b0 --- /dev/null +++ b/public/assets/fonts/LICENSE-old-standard-tt.txt @@ -0,0 +1,93 @@ +Copyright 2011 The Old Standard Project Authors (amkryukov@gmail.com) OldStandard-Italic.ttf: Copyright 2011 The Old Standard Project Authors (amkryukov@gmail.com) OldStandard-Bold.ttf: Copyright 2011 The Old Standard Project Authors (amkryukov@gmail.com) + +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. diff --git a/public/assets/fonts/im-fell-english-sc.woff2 b/public/assets/fonts/im-fell-english-sc.woff2 new file mode 100644 index 0000000..d8df2f9 Binary files /dev/null and b/public/assets/fonts/im-fell-english-sc.woff2 differ diff --git a/public/assets/fonts/old-standard-tt-400-italic.woff2 b/public/assets/fonts/old-standard-tt-400-italic.woff2 new file mode 100644 index 0000000..8696e0b Binary files /dev/null and b/public/assets/fonts/old-standard-tt-400-italic.woff2 differ diff --git a/public/assets/fonts/old-standard-tt-400.woff2 b/public/assets/fonts/old-standard-tt-400.woff2 new file mode 100644 index 0000000..947259b Binary files /dev/null and b/public/assets/fonts/old-standard-tt-400.woff2 differ diff --git a/public/assets/fonts/old-standard-tt-700.woff2 b/public/assets/fonts/old-standard-tt-700.woff2 new file mode 100644 index 0000000..f4aed73 Binary files /dev/null and b/public/assets/fonts/old-standard-tt-700.woff2 differ diff --git a/public/assets/months/brumaire.jpg b/public/assets/months/brumaire.jpg new file mode 100644 index 0000000..0b87b43 Binary files /dev/null and b/public/assets/months/brumaire.jpg differ diff --git a/public/assets/months/brumaire.svg b/public/assets/months/brumaire.svg deleted file mode 100644 index e2d826d..0000000 --- a/public/assets/months/brumaire.svg +++ /dev/null @@ -1,9 +0,0 @@ - diff --git a/public/assets/months/complementary.svg b/public/assets/months/complementary.svg deleted file mode 100644 index b2d2f90..0000000 --- a/public/assets/months/complementary.svg +++ /dev/null @@ -1,9 +0,0 @@ - diff --git a/public/assets/months/floreal.jpg b/public/assets/months/floreal.jpg new file mode 100644 index 0000000..f44bf5b Binary files /dev/null and b/public/assets/months/floreal.jpg differ diff --git a/public/assets/months/floreal.svg b/public/assets/months/floreal.svg deleted file mode 100644 index 6645b54..0000000 --- a/public/assets/months/floreal.svg +++ /dev/null @@ -1,14 +0,0 @@ - diff --git a/public/assets/months/frimaire.jpg b/public/assets/months/frimaire.jpg new file mode 100644 index 0000000..0f59e2a Binary files /dev/null and b/public/assets/months/frimaire.jpg differ diff --git a/public/assets/months/frimaire.svg b/public/assets/months/frimaire.svg deleted file mode 100644 index 17faade..0000000 --- a/public/assets/months/frimaire.svg +++ /dev/null @@ -1,13 +0,0 @@ - diff --git a/public/assets/months/fructidor.jpg b/public/assets/months/fructidor.jpg new file mode 100644 index 0000000..284cf52 Binary files /dev/null and b/public/assets/months/fructidor.jpg differ diff --git a/public/assets/months/fructidor.svg b/public/assets/months/fructidor.svg deleted file mode 100644 index 5e3b4ba..0000000 --- a/public/assets/months/fructidor.svg +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/public/assets/months/germinal.jpg b/public/assets/months/germinal.jpg new file mode 100644 index 0000000..326f758 Binary files /dev/null and b/public/assets/months/germinal.jpg differ diff --git a/public/assets/months/germinal.svg b/public/assets/months/germinal.svg deleted file mode 100644 index e26d3e9..0000000 --- a/public/assets/months/germinal.svg +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/public/assets/months/messidor.jpg b/public/assets/months/messidor.jpg new file mode 100644 index 0000000..48a08bf Binary files /dev/null and b/public/assets/months/messidor.jpg differ diff --git a/public/assets/months/messidor.svg b/public/assets/months/messidor.svg deleted file mode 100644 index cea0607..0000000 --- a/public/assets/months/messidor.svg +++ /dev/null @@ -1,16 +0,0 @@ - diff --git a/public/assets/months/nivose.jpg b/public/assets/months/nivose.jpg new file mode 100644 index 0000000..cfc36f5 Binary files /dev/null and b/public/assets/months/nivose.jpg differ diff --git a/public/assets/months/nivose.svg b/public/assets/months/nivose.svg deleted file mode 100644 index 4dc32f8..0000000 --- a/public/assets/months/nivose.svg +++ /dev/null @@ -1,14 +0,0 @@ - diff --git a/public/assets/months/pluviose.jpg b/public/assets/months/pluviose.jpg new file mode 100644 index 0000000..c6ac05c Binary files /dev/null and b/public/assets/months/pluviose.jpg differ diff --git a/public/assets/months/pluviose.svg b/public/assets/months/pluviose.svg deleted file mode 100644 index 24188df..0000000 --- a/public/assets/months/pluviose.svg +++ /dev/null @@ -1,10 +0,0 @@ - diff --git a/public/assets/months/prairial.jpg b/public/assets/months/prairial.jpg new file mode 100644 index 0000000..a2e5d9d Binary files /dev/null and b/public/assets/months/prairial.jpg differ diff --git a/public/assets/months/prairial.svg b/public/assets/months/prairial.svg deleted file mode 100644 index 1d8c9f1..0000000 --- a/public/assets/months/prairial.svg +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/public/assets/months/thermidor.jpg b/public/assets/months/thermidor.jpg new file mode 100644 index 0000000..d1fe5e8 Binary files /dev/null and b/public/assets/months/thermidor.jpg differ diff --git a/public/assets/months/thermidor.svg b/public/assets/months/thermidor.svg deleted file mode 100644 index e22af25..0000000 --- a/public/assets/months/thermidor.svg +++ /dev/null @@ -1,14 +0,0 @@ - diff --git a/public/assets/months/vendemiaire.jpg b/public/assets/months/vendemiaire.jpg new file mode 100644 index 0000000..ae6dcea Binary files /dev/null and b/public/assets/months/vendemiaire.jpg differ diff --git a/public/assets/months/vendemiaire.svg b/public/assets/months/vendemiaire.svg deleted file mode 100644 index 49965be..0000000 --- a/public/assets/months/vendemiaire.svg +++ /dev/null @@ -1,16 +0,0 @@ - diff --git a/public/assets/months/ventose.jpg b/public/assets/months/ventose.jpg new file mode 100644 index 0000000..5b352f1 Binary files /dev/null and b/public/assets/months/ventose.jpg differ diff --git a/public/assets/months/ventose.svg b/public/assets/months/ventose.svg deleted file mode 100644 index a136e81..0000000 --- a/public/assets/months/ventose.svg +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/public/css/style.css b/public/css/style.css index 5f98a24..ad3b128 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -1,14 +1,50 @@ +/* Fonts: Old Standard TT (body) and IM Fell English SC (titles), both SIL OFL, self-hosted. */ +@font-face { + font-family: 'Old Standard TT'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url('../assets/fonts/old-standard-tt-400.woff2') format('woff2'); +} + +@font-face { + font-family: 'Old Standard TT'; + font-style: italic; + font-weight: 400; + font-display: swap; + src: url('../assets/fonts/old-standard-tt-400-italic.woff2') format('woff2'); +} + +@font-face { + font-family: 'Old Standard TT'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url('../assets/fonts/old-standard-tt-700.woff2') format('woff2'); +} + +@font-face { + font-family: 'IM Fell English SC'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url('../assets/fonts/im-fell-english-sc.woff2') format('woff2'); +} + :root { - --cream-bg: #faf3e6; - --cream-panel: #f6efe0; - --cream-panel-alt: #efe4cc; - --ink: #3a2e22; - --ink-soft: #6b5a45; - --accent: #b5652b; - --accent-soft: #d99a5b; - --brass: #8a6b45; - --border: #d8c9a8; - --shadow: 0 6px 20px rgba(90, 66, 34, 0.12); + --paper: #eadfc4; + --paper-light: #f3ead3; + --paper-dark: #ddcfa9; + --ink: #2f2519; + --ink-soft: #5e4f3b; + --sepia: #7a6445; + --rule: #8a7753; + --rouge: #8e2b26; + --bleu: #2c4268; + --shadow: 0 10px 28px rgba(60, 40, 15, 0.28); + --font-body: 'Old Standard TT', 'Georgia', 'Times New Roman', serif; + --font-title: 'IM Fell English SC', 'Old Standard TT', 'Georgia', serif; + --noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .35 0 0 0 0 .25 0 0 0 0 .1 0 0 0 .22 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); color-scheme: light; } @@ -26,19 +62,24 @@ html, body { } body { - background: var(--cream-bg); - background-image: radial-gradient(circle at 10% 10%, rgba(181, 101, 43, 0.05), transparent 40%), - radial-gradient(circle at 90% 20%, rgba(138, 107, 69, 0.06), transparent 45%); + background-color: var(--paper); + background-image: + radial-gradient(ellipse at 50% 40%, transparent 50%, rgba(92, 58, 22, 0.3) 100%), + var(--noise); + background-attachment: fixed, scroll; color: var(--ink); - font-family: 'Inter', 'Segoe UI', sans-serif; + font-family: var(--font-body); + font-size: 1.05rem; line-height: 1.55; min-height: 100vh; display: flex; flex-direction: column; } -h1, h2, .brand-title, .republican-date, .republican-year { - font-family: 'Fraunces', 'Georgia', serif; +h1, h2, h3 { + font-family: var(--font-title); + font-weight: 400; + letter-spacing: 0.04em; } .sr-only { @@ -50,40 +91,74 @@ h1, h2, .brand-title, .republican-date, .republican-year { white-space: nowrap; } +/* Ornamental rule: two hairlines with a lozenge between them */ +.ornament { + position: relative; + width: min(320px, 70%); + height: 12px; + margin: 0.9rem auto; + color: var(--rule); + background: + linear-gradient(currentColor, currentColor) left center / calc(50% - 14px) 1px no-repeat, + linear-gradient(currentColor, currentColor) right center / calc(50% - 14px) 1px no-repeat; +} + +.ornament::before { + content: ''; + position: absolute; + top: 50%; + left: 50%; + width: 8px; + height: 8px; + border: 1px solid currentColor; + transform: translate(-50%, -50%) rotate(45deg); +} + /* Header */ .site-header { display: flex; align-items: center; justify-content: space-between; - padding: 1rem 1.5rem; - border-bottom: 1px solid var(--border); - background: var(--cream-panel); + padding: 0.9rem 1.5rem 0.8rem; + background: var(--paper-light); + background-image: var(--noise); + border-bottom: 3px double var(--ink); + box-shadow: 0 3px 10px rgba(60, 40, 15, 0.18); position: sticky; top: 0; z-index: 20; } +.site-header::before { + content: ''; + position: absolute; + inset: 0 0 auto 0; + height: 5px; + background: linear-gradient(90deg, var(--bleu) 0 33.3%, var(--paper-light) 33.3% 66.6%, var(--rouge) 66.6% 100%); + border-bottom: 1px solid var(--ink); +} + .brand { display: flex; align-items: center; - gap: 0.6rem; + gap: 0.7rem; text-decoration: none; color: var(--ink); } -.brand-mark { - font-family: 'Fraunces', serif; - font-style: italic; - font-size: 0.9rem; - color: var(--accent); - border: 1px solid var(--accent); - border-radius: 999px; - padding: 0.1rem 0.6rem; +.cockade { + width: 26px; + height: 26px; + border-radius: 50%; + border: 1.5px solid var(--ink); + background: radial-gradient(circle, var(--bleu) 0 28%, var(--paper-light) 29% 58%, var(--rouge) 59%); + flex: none; } .brand-title { - font-size: 1.15rem; - font-weight: 600; + font-family: var(--font-title); + font-size: 1.4rem; + letter-spacing: 0.06em; } .header-actions { @@ -93,18 +168,19 @@ h1, h2, .brand-title, .republican-date, .republican-year { } .lang-switch { - border: 1px solid var(--brass); + border: 1px solid var(--ink); background: transparent; color: var(--ink); - border-radius: 999px; - padding: 0.35rem 0.75rem; - font-weight: 600; - font-size: 0.85rem; + border-radius: 2px; + padding: 0.3rem 0.7rem; + font-family: var(--font-title); + font-size: 0.95rem; + letter-spacing: 0.08em; cursor: pointer; } .lang-switch:hover { - background: var(--cream-panel-alt); + background: var(--paper-dark); } .menu-toggle { @@ -114,18 +190,21 @@ h1, h2, .brand-title, .republican-date, .republican-year { gap: 5px; width: 40px; height: 36px; - border: 1px solid var(--border); - border-radius: 8px; - background: var(--cream-bg); + border: 1px solid var(--ink); + border-radius: 2px; + background: transparent; cursor: pointer; padding: 0 8px; } +.menu-toggle:hover { + background: var(--paper-dark); +} + .burger-bar { display: block; height: 2px; background: var(--ink); - border-radius: 2px; } /* Nav panel */ @@ -134,14 +213,15 @@ h1, h2, .brand-title, .republican-date, .republican-year { top: 0; right: 0; height: 100%; - width: min(300px, 85vw); - background: var(--cream-panel); - border-left: 1px solid var(--border); + width: min(310px, 85vw); + background: var(--paper-light); + background-image: var(--noise); + border-left: 3px double var(--ink); box-shadow: var(--shadow); padding: calc(1.5rem + env(safe-area-inset-top, 0px)) 1.5rem 1.5rem; display: flex; flex-direction: column; - gap: 0.5rem; + gap: 0.35rem; transform: translateX(100%); transition: transform 0.25s ease; z-index: 30; @@ -154,28 +234,32 @@ h1, h2, .brand-title, .republican-date, .republican-year { .nav-link { color: var(--ink); text-decoration: none; - padding: 0.6rem 0.5rem; - border-radius: 8px; - font-weight: 500; + padding: 0.5rem 0.6rem; + border-bottom: 1px dotted var(--rule); + font-size: 1.05rem; } .nav-link:hover, .nav-link.active { - background: var(--cream-panel-alt); - color: var(--accent); + background: var(--paper-dark); + color: var(--rouge); +} + +.nav-link.active { + font-style: italic; } .nav-section-label { - margin: 1rem 0 0.1rem; - font-size: 0.75rem; - text-transform: uppercase; - letter-spacing: 0.08em; - color: var(--ink-soft); + margin: 1.2rem 0 0.1rem; + font-family: var(--font-title); + font-size: 0.95rem; + letter-spacing: 0.12em; + color: var(--sepia); } .nav-backdrop { position: fixed; inset: 0; - background: rgba(58, 46, 34, 0.35); + background: rgba(47, 37, 25, 0.5); z-index: 25; } @@ -185,112 +269,153 @@ main#app { width: 100%; max-width: 1080px; margin: 0 auto; - padding: 2rem 1.25rem 3rem; + padding: 2.2rem 1.25rem 3rem; +} + +/* The stele: an arched tablet, like the pewter plaque */ +.tablet { + position: relative; + background: var(--paper-light); + background-image: var(--noise); + border: 6px double var(--ink); + border-radius: 50% 50% 6px 6px / 110px 110px 6px 6px; + padding: 3.2rem 2.2rem 2.2rem; + box-shadow: var(--shadow), inset 0 0 0 1px var(--rule), inset 0 0 40px rgba(122, 100, 69, 0.25); +} + +.tablet-head { + text-align: center; } .today-heading { - text-align: center; - font-weight: 400; - font-size: 1.4rem; + margin: 0; + font-size: clamp(1.15rem, 3vw, 1.6rem); color: var(--ink-soft); - margin-bottom: 1.5rem; } -.calendar-card { +.tablet-body { display: grid; - grid-template-columns: minmax(180px, 220px) 1fr minmax(220px, 320px); + grid-template-columns: minmax(230px, 290px) 46px 1fr; gap: 1.5rem; - align-items: stretch; - background: var(--cream-panel); - border: 1px solid var(--border); - border-radius: 16px; - padding: 2rem; - box-shadow: var(--shadow); -} - -.month-illustration { - display: flex; - flex-direction: column; align-items: center; - gap: 0.75rem; - text-align: center; - border-right: 1px dashed var(--border); - padding-right: 1.5rem; + margin-top: 0.6rem; } -.month-illustration img { +/* Engraved plate: thin-lined frame around the picture and a caption below */ +.plate { + margin: 0; + text-align: center; +} + +.plate-frame { + padding: 6px; + border: 1px solid var(--ink); + background: var(--paper-light); + box-shadow: 0 0 0 4px var(--paper-light), 0 0 0 5px var(--ink), 2px 4px 14px rgba(60, 40, 15, 0.3); +} + +.plate-frame img { + display: block; width: 100%; - max-width: 150px; height: auto; + filter: sepia(0.28) contrast(1.03); +} + +.plate figcaption { + margin-top: 1.1rem; +} + +.month-name { + margin: 0; + font-size: 1.7rem; + letter-spacing: 0.1em; + text-transform: lowercase; + font-variant: small-caps; } .month-period { - font-size: 0.85rem; + margin: 0.15rem 0 0; + font-size: 0.9rem; color: var(--ink-soft); font-style: italic; } +.fasces { + width: 100%; + height: auto; + max-height: 460px; + justify-self: center; + filter: drop-shadow(1px 2px 1px rgba(60, 40, 15, 0.3)); +} + +.decree { + text-align: center; +} + .date-display { display: flex; flex-direction: column; align-items: center; - justify-content: center; - text-align: center; - gap: 0.3rem; + gap: 0.2rem; } .decade-day { - text-transform: uppercase; - letter-spacing: 0.12em; - font-size: 0.85rem; - color: var(--accent); - font-weight: 600; margin: 0; + font-family: var(--font-title); + font-size: 1.15rem; + letter-spacing: 0.25em; + color: var(--rouge); } .republican-date { - font-size: clamp(1.8rem, 4vw, 2.6rem); + font-family: var(--font-title); + font-size: clamp(2rem, 5vw, 3.2rem); + line-height: 1.1; + letter-spacing: 0.04em; margin: 0.1rem 0; - font-weight: 600; } .republican-year { - font-size: 1.1rem; + font-family: var(--font-title); + font-size: 1.3rem; + letter-spacing: 0.1em; color: var(--ink-soft); margin: 0; } +/* Rubber-stamp look */ .sextile-badge { display: inline-block; - margin-top: 0.5rem; - background: var(--accent); - color: var(--cream-bg); - border-radius: 999px; - padding: 0.2rem 0.75rem; - font-size: 0.75rem; - font-weight: 600; - letter-spacing: 0.04em; + margin-top: 0.6rem; + color: var(--rouge); + border: 2px solid var(--rouge); + outline: 1px solid var(--rouge); + outline-offset: 2px; + padding: 0.1rem 0.8rem; + font-family: var(--font-title); + font-size: 0.95rem; + letter-spacing: 0.15em; + transform: rotate(-3deg); + opacity: 0.85; } .gregorian-equivalent { - margin-top: 0.75rem; - font-size: 0.85rem; + margin: 0.8rem 0 0; + font-size: 0.95rem; + font-style: italic; color: var(--ink-soft); } .description-panel { - border-left: 1px dashed var(--border); - padding-left: 1.5rem; -} - -.month-name { - margin: 0 0 0.2rem; - font-size: 1.3rem; + max-width: 34rem; + margin: 0 auto; } .month-season-suffix { - font-size: 0.8rem; - color: var(--brass); + font-family: var(--font-title); + font-size: 0.9rem; + letter-spacing: 0.06em; + color: var(--sepia); margin: 0 0 0.6rem; } @@ -302,27 +427,41 @@ main#app { .month-description { margin: 0; + text-align: justify; + hyphens: auto; } -/* Form */ +.month-description::first-letter { + font-family: var(--font-title); + font-size: 1.9em; + line-height: 1; + color: var(--rouge); +} + +/* Form: a small printed notice */ .convert-form { - margin-top: 2rem; - background: var(--cream-panel-alt); - border: 1px solid var(--border); - border-radius: 16px; - padding: 1.5rem; + margin-top: 2.2rem; + background: var(--paper-dark); + background-image: var(--noise); + border: 1px solid var(--ink); + outline: 1px solid var(--ink); + outline-offset: -5px; + padding: 1.6rem; + box-shadow: 0 4px 12px rgba(60, 40, 15, 0.2); } .convert-form h2 { margin-top: 0; - font-size: 1.1rem; + font-size: 1.3rem; + text-align: center; } .convert-form label { display: block; - font-size: 0.85rem; + font-size: 0.95rem; margin-bottom: 0.4rem; color: var(--ink-soft); + font-style: italic; } .convert-form-row { @@ -335,64 +474,388 @@ main#app { .convert-form-row input[type="date"] { font-family: inherit; font-size: 1rem; - padding: 0.5rem 0.75rem; - border: 1px solid var(--border); - border-radius: 8px; - background: var(--cream-bg); + padding: 0.45rem 0.7rem; + border: 1px solid var(--ink); + border-radius: 0; + background: var(--paper-light); color: var(--ink); } .convert-form-row button { - font-family: inherit; - font-size: 0.95rem; - font-weight: 600; - padding: 0.55rem 1.1rem; - border-radius: 8px; - border: 1px solid var(--accent); - background: var(--accent); - color: #fff; + font-family: var(--font-title); + font-size: 1.05rem; + letter-spacing: 0.08em; + padding: 0.45rem 1.1rem; + border-radius: 0; + border: 1px solid var(--ink); + background: var(--rouge); + color: var(--paper-light); cursor: pointer; } .convert-form-row button.secondary { background: transparent; - color: var(--accent); + color: var(--ink); } .convert-form-row button:hover { - filter: brightness(1.05); + filter: brightness(1.12); } .form-help { margin: 0.75rem 0 0; - font-size: 0.8rem; + font-size: 0.85rem; + font-style: italic; color: var(--ink-soft); } .form-error { margin: 0.75rem 0 0; - font-size: 0.85rem; - color: #a13f2b; - font-weight: 600; + font-size: 0.95rem; + color: var(--rouge); + font-weight: 700; +} + +/* Full calendar: a printed poster */ +#view-calendar { + margin: 0 -0.5rem; +} + +.poster { + background: var(--paper-light); + background-image: var(--noise); + border: 6px double var(--ink); + padding: 1.8rem 1.4rem 1.6rem; + box-shadow: var(--shadow), inset 0 0 0 1px var(--rule), inset 0 0 50px rgba(122, 100, 69, 0.22); +} + +.poster-head { + text-align: center; +} + +.poster-head h1 { + margin: 0; + font-size: clamp(1.4rem, 4vw, 2.3rem); +} + +.poster-subtitle { + margin: 0.2rem 0 0; + font-style: italic; + color: var(--ink-soft); +} + +.poster-grid { + display: grid; + grid-template-columns: 1fr; + gap: 1.8rem 1.2rem; + margin-top: 0.6rem; +} + +.season, +.poster-center { + min-width: 0; +} + +.arch { + height: 110px; + border: 2px solid var(--ink); + border-radius: 50% 50% 0 0 / 100% 100% 0 0; + overflow: hidden; + background: var(--paper-dark); + box-shadow: inset 0 0 0 3px var(--paper-light), inset 0 0 0 4px var(--ink); +} + +.arch img { + display: block; + width: 100%; + height: 100%; + object-fit: cover; + object-position: 50% 18%; + filter: grayscale(1) sepia(0.55) contrast(1.15) brightness(1.05); + mix-blend-mode: multiply; +} + +.season-title { + margin: 0.5rem 0 0.3rem; + text-align: center; + font-size: 1.5rem; + letter-spacing: 0.18em; + border-bottom: 1px solid var(--ink); + padding-bottom: 0.2rem; +} + +.season-table { + width: 100%; + border-collapse: collapse; + table-layout: fixed; + font-size: 0.8rem; + line-height: 1.25; +} + +.season-table th, +.season-table td { + padding: 0.12rem 0.25rem; + text-align: left; + vertical-align: baseline; + overflow-wrap: anywhere; + border-bottom: 1px dotted rgba(138, 119, 83, 0.6); +} + +.season-table thead th { + font-weight: 400; + text-align: center; + border-bottom: 1px solid var(--ink); + padding-bottom: 0.3rem; +} + +.season-table col.col-day { + width: 4.4em; +} + +.season-table abbr { + margin-left: 0.2em; + text-decoration: none; +} + +.season-table thead th { + overflow-wrap: normal; +} + +.day-head { + font-family: var(--font-title); + font-size: 0.8rem; + letter-spacing: 0.08em; + color: var(--ink-soft); +} + +.month-button { + font-family: var(--font-title); + font-size: 0.95rem; + letter-spacing: 0.04em; + color: var(--ink); + background: none; + border: none; + padding: 0; + cursor: pointer; + border-bottom: 1px dotted var(--rouge); +} + +.month-button:hover, +.month-button:focus-visible { + color: var(--rouge); +} + +.season-table tbody th { + font-weight: 400; + color: var(--ink-soft); + white-space: nowrap; +} + +.season-table .day-number { + display: inline-block; + min-width: 1.4em; + text-align: right; + margin-right: 0.15em; + font-weight: 700; + color: var(--ink); +} + +.season-table .decade-row th { + padding: 0.35rem 0.25rem 0.1rem; + font-family: var(--font-title); + font-size: 0.82rem; + letter-spacing: 0.12em; + text-align: center; + color: var(--sepia); + border-bottom: 1px solid var(--rule); +} + +.season-table .decade-end th, +.season-table .decade-end td { + background: rgba(122, 100, 69, 0.1); +} + +.season-table td.today, +.season-table th.today-row, +.season-table th.today-row .day-number { + background: var(--rouge); + color: var(--paper-light); + font-weight: 700; +} + +.month-button.is-current { + color: var(--rouge); + border-bottom-style: solid; +} + +.poster-center { + text-align: center; +} + +.medallion { + width: min(190px, 70%); + aspect-ratio: 1; + margin: 0 auto; + border-radius: 50%; + border: 2px solid var(--ink); + padding: 10px; + background: + repeating-conic-gradient(var(--ink) 0 0.6deg, transparent 0.6deg 6deg) center / 100% 100% no-repeat, + var(--paper-dark); + box-shadow: inset 0 0 0 2px var(--paper-light), inset 0 0 0 3px var(--ink); +} + +.medallion-inner { + position: relative; + width: 100%; + height: 100%; + border-radius: 50%; + border: 1px solid var(--ink); + background: var(--paper-light); +} + +.medallion-inner img { + position: absolute; + top: 9%; + left: 50%; + height: 82%; + width: auto; + transform: translateX(-50%); +} + +.explanation { + margin: 1.1rem 0 0; + text-align: left; + font-size: 0.88rem; + line-height: 1.45; +} + +.explanation h2 { + margin: 0 0 0.4rem; + font-size: 1.3rem; + text-align: center; + letter-spacing: 0.2em; +} + +.explanation p { + margin: 0 0 0.6rem; + text-align: justify; + hyphens: auto; +} + +.poster-feasts { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); + gap: 0.6rem; + margin-top: 1.8rem; + padding-top: 1rem; + border-top: 3px double var(--ink); +} + +.feast { + text-align: center; + padding: 0.5rem 0.4rem; + border: 1px solid var(--ink); + outline: 1px solid var(--rule); + outline-offset: -4px; + background: var(--paper-dark); + font-size: 0.9rem; + line-height: 1.3; +} + +.feast-day { + display: block; + font-family: var(--font-title); + font-size: 0.95rem; + letter-spacing: 0.12em; + color: var(--ink-soft); +} + +.feast-name { + display: block; +} + +.feast-note { + display: block; + font-size: 0.78rem; + font-style: italic; + color: var(--ink-soft); +} + +.feast.today { + background: var(--rouge); + color: var(--paper-light); +} + +.feast.today .feast-day, +.feast.today .feast-note { + color: var(--paper-light); +} + +/* Month dialog */ +.month-dialog { + width: min(560px, calc(100vw - 2rem)); + max-height: calc(100vh - 2rem); + overflow: auto; + padding: 1.6rem 1.6rem 1.4rem; + color: var(--ink); + background: var(--paper-light); + background-image: var(--noise); + border: 6px double var(--ink); + box-shadow: var(--shadow); +} + +.month-dialog::backdrop { + background: rgba(47, 37, 25, 0.6); +} + +.month-dialog .plate { + max-width: 280px; + margin: 0 auto; +} + +.dialog-close { + position: absolute; + top: 0.4rem; + right: 0.6rem; + background: none; + border: none; + font-size: 1.8rem; + line-height: 1; + color: var(--ink); + cursor: pointer; +} + +.dialog-close:hover { + color: var(--rouge); +} + +.dialog-text { + margin-top: 1rem; + text-align: center; } /* About view */ .about-view { - background: var(--cream-panel); - border: 1px solid var(--border); - border-radius: 16px; - padding: 2rem; - box-shadow: var(--shadow); + background: var(--paper-light); + background-image: var(--noise); + border: 6px double var(--ink); + padding: 2rem 2.2rem; + box-shadow: var(--shadow), inset 0 0 0 1px var(--rule), inset 0 0 40px rgba(122, 100, 69, 0.2); } .about-view h1 { margin-top: 0; + text-align: center; + font-size: clamp(1.4rem, 4vw, 2rem); + padding-bottom: 0.6rem; + border-bottom: 3px double var(--ink); } .about-content h2 { - font-size: 1.15rem; - color: var(--accent); - margin: 1.5rem 0 0.5rem; + font-size: 1.3rem; + color: var(--rouge); + margin: 1.6rem 0 0.5rem; } .about-content h2:first-child { @@ -400,47 +863,143 @@ main#app { } .about-content p { - margin: 0 0 0.75rem; + margin: 0 0 0.8rem; + text-align: justify; + hyphens: auto; } /* Footer */ .site-footer { text-align: center; - padding: 1.5rem 1rem calc(1.5rem + env(safe-area-inset-bottom, 0px)); - font-size: 0.8rem; + padding: 0.5rem 1rem calc(1.5rem + env(safe-area-inset-bottom, 0px)); + font-size: 0.9rem; + font-style: italic; color: var(--ink-soft); - border-top: 1px solid var(--border); +} + +.site-footer p { + margin: 0 auto; + max-width: 44rem; } /* Responsive */ -@media (max-width: 820px) { - .calendar-card { +@media (min-width: 820px) { + .poster-grid { + grid-template-columns: repeat(2, 1fr); + } + + .poster-center { + grid-column: 1 / -1; + display: grid; + grid-template-columns: 190px 1fr; + gap: 1.5rem; + align-items: center; + text-align: left; + order: -1; + } + + .poster-center .medallion { + width: 190px; + } + + .poster-center .explanation { + margin: 0; + } +} + +/* Five columns like the original poster: autumn, winter, key, spring, summer */ +@media (min-width: 1420px) { + main#app:has(#view-calendar:not([hidden])) { + max-width: 1640px; + } + + .poster-grid { + grid-template-columns: 1.25fr 1.25fr 0.95fr 1.25fr 1.25fr; + } + + .poster-center { + display: block; + order: 0; + grid-row: 1; + grid-column: 3; + } + + .poster-center .medallion { + width: min(190px, 70%); + } + + .poster-center .explanation { + margin-top: 1.1rem; + } + + .season-table { + font-size: 0.72rem; + } + + .season-table .month-button { + font-size: 0.78rem; + letter-spacing: 0; + } +} + +@media (max-width: 819px) { + .tablet { + border-radius: 50% 50% 6px 6px / 70px 70px 6px 6px; + padding: 2.4rem 1.3rem 1.6rem; + } + + .tablet-body { grid-template-columns: 1fr; - text-align: center; + gap: 1.2rem; } - .month-illustration, - .description-panel { - border: none; - padding: 0; + + .plate { + max-width: 280px; + margin: 0 auto; } - .month-illustration { - padding-bottom: 1rem; - border-bottom: 1px dashed var(--border); + + .fasces { + display: none; } - .description-panel { - padding-top: 1rem; - border-top: 1px dashed var(--border); + + .about-view { + padding: 1.4rem 1.2rem; } } @media (max-width: 480px) { .site-header { - padding: 0.75rem 1rem; + padding: 0.9rem 1rem 0.7rem; } + + .brand-title { + font-size: 1.15rem; + } + main#app { - padding: 1.5rem 0.9rem 2rem; + padding: 1.4rem 0.8rem 2rem; } - .calendar-card, .convert-form, .about-view { - padding: 1.25rem; + + .tablet { + border-width: 4px; + border-radius: 50% 50% 4px 4px / 48px 48px 4px 4px; + padding: 1.8rem 1rem 1.3rem; + } + + .convert-form { + padding: 1.2rem; + } + + .poster { + padding: 1.2rem 0.6rem; + border-width: 4px; + } + + #view-calendar { + margin: 0 -0.4rem; + } + + .season-table { + font-size: 0.72rem; } } diff --git a/public/data/day-names.json b/public/data/day-names.json new file mode 100644 index 0000000..df135ca --- /dev/null +++ b/public/data/day-names.json @@ -0,0 +1,14 @@ +{ + "vendemiaire": ["Raisin", "Safran", "Châtaigne", "Colchique", "Cheval", "Balsamine", "Carotte", "Amaranthe", "Panais", "Cuve", "Pomme de terre", "Immortelle", "Potiron", "Réséda", "Âne", "Belle de nuit", "Citrouille", "Sarrasin", "Tournesol", "Pressoir", "Chanvre", "Pêche", "Navet", "Amaryllis", "Bœuf", "Aubergine", "Piment", "Tomate", "Orge", "Tonneau"], + "brumaire": ["Pomme", "Céleri", "Poire", "Betterave", "Oie", "Héliotrope", "Figue", "Scorsonère", "Alisier", "Charrue", "Salsifis", "Mâcre", "Topinambour", "Endive", "Dindon", "Chervis", "Cresson", "Dentelaire", "Grenade", "Herse", "Bacchante", "Azerole", "Garance", "Orange", "Faisan", "Pistache", "Macjonc", "Coing", "Cormier", "Rouleau"], + "frimaire": ["Raiponce", "Turneps", "Chicorée", "Nèfle", "Cochon", "Mâche", "Chou-fleur", "Miel", "Genièvre", "Pioche", "Cire", "Raifort", "Cèdre", "Sapin", "Chevreuil", "Ajonc", "Cyprès", "Lierre", "Sabine", "Hoyau", "Érable à sucre", "Bruyère", "Roseau", "Oseille", "Grillon", "Pignon", "Liège", "Truffe", "Olive", "Pelle"], + "nivose": ["Tourbe", "Houille", "Bitume", "Soufre", "Chien", "Lave", "Terre végétale", "Fumier", "Salpêtre", "Fléau", "Granit", "Argile", "Ardoise", "Grès", "Lapin", "Silex", "Marne", "Pierre à chaux", "Marbre", "Van", "Pierre à plâtre", "Sel", "Fer", "Cuivre", "Chat", "Étain", "Plomb", "Zinc", "Mercure", "Crible"], + "pluviose": ["Lauréole", "Mousse", "Fragon", "Perce-neige", "Taureau", "Laurier-thym", "Amadouvier", "Mézéréon", "Peuplier", "Coignée", "Ellébore", "Brocoli", "Laurier", "Avelinier", "Vache", "Buis", "Lichen", "If", "Pulmonaire", "Serpette", "Thlaspi", "Thimelé", "Chiendent", "Trainasse", "Lièvre", "Guède", "Noisetier", "Cyclamen", "Chélidoine", "Traîneau"], + "ventose": ["Tussilage", "Cornouiller", "Violier", "Troène", "Bouc", "Asaret", "Alaterne", "Violette", "Marceau", "Bêche", "Narcisse", "Orme", "Fumeterre", "Vélar", "Chèvre", "Épinard", "Doronic", "Mouron", "Cerfeuil", "Cordeau", "Mandragore", "Persil", "Cochléaria", "Pâquerette", "Thon", "Pissenlit", "Sylve", "Capillaire", "Frêne", "Plantoir"], + "germinal": ["Primevère", "Platane", "Asperge", "Tulipe", "Poule", "Bette", "Bouleau", "Jonquille", "Aulne", "Couvoir", "Pervenche", "Charme", "Morille", "Hêtre", "Abeille", "Laitue", "Mélèze", "Ciguë", "Radis", "Ruche", "Gainier", "Romaine", "Marronnier", "Roquette", "Pigeon", "Lilas", "Anémone", "Pensée", "Myrtille", "Greffoir"], + "floreal": ["Rose", "Chêne", "Fougère", "Aubépine", "Rossignol", "Ancolie", "Muguet", "Champignon", "Hyacinthe", "Râteau", "Rhubarbe", "Sainfoin", "Bâton-d'or", "Chamérisier", "Ver à soie", "Consoude", "Pimprenelle", "Corbeille d'or", "Arroche", "Sarcloir", "Statice", "Fritillaire", "Bourrache", "Valériane", "Carpe", "Fusain", "Civette", "Buglosse", "Sénevé", "Houlette"], + "prairial": ["Luzerne", "Hémérocalle", "Trèfle", "Angélique", "Canard", "Mélisse", "Fromental", "Martagon", "Serpolet", "Faux", "Fraise", "Bétoine", "Pois", "Acacia", "Caille", "Œillet", "Sureau", "Pavot", "Tilleul", "Fourche", "Barbeau", "Camomille", "Chèvrefeuille", "Caille-lait", "Tanche", "Jasmin", "Verveine", "Thym", "Pivoine", "Chariot"], + "messidor": ["Seigle", "Avoine", "Oignon", "Véronique", "Mulet", "Romarin", "Concombre", "Échalote", "Absinthe", "Faucille", "Coriandre", "Artichaut", "Girofle", "Lavande", "Chamois", "Tabac", "Groseille", "Gesse", "Cerise", "Parc", "Menthe", "Cumin", "Haricot", "Orcanète", "Pintade", "Sauge", "Ail", "Vesce", "Blé", "Chalémie"], + "thermidor": ["Épeautre", "Bouillon-blanc", "Melon", "Ivraie", "Bélier", "Prêle", "Armoise", "Carthame", "Mûre", "Arrosoir", "Panic", "Salicorne", "Abricot", "Basilic", "Brebis", "Guimauve", "Lin", "Amande", "Gentiane", "Écluse", "Carline", "Câprier", "Lentille", "Aunée", "Loutre", "Myrte", "Colza", "Lupin", "Coton", "Moulin"], + "fructidor": ["Prune", "Millet", "Lycoperdon", "Escourgeon", "Saumon", "Tubéreuse", "Sucrion", "Apocyn", "Réglisse", "Échelle", "Pastèque", "Fenouil", "Épine-vinette", "Noix", "Truite", "Citron", "Cardère", "Nerprun", "Tagète", "Hotte", "Églantier", "Noisette", "Houblon", "Sorgho", "Écrevisse", "Bigarade", "Verge d'or", "Maïs", "Marron", "Panier"] +} diff --git a/public/index.html b/public/index.html index 8ed4131..86c9338 100644 --- a/public/index.html +++ b/public/index.html @@ -4,16 +4,15 @@