use charte from www
97
app/assets/fonts/OFL.txt
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
Young Serif
|
||||
Copyright 2023 The Young Serif Project Authors (https://github.com/noirblancrouge/YoungSerif)
|
||||
|
||||
Atkinson Hyperlegible Next
|
||||
Copyright 2020-2024 The Atkinson Hyperlegible Next Project Authors (https://github.com/googlefonts/atkinson-hyperlegible-next)
|
||||
|
||||
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.
|
||||
BIN
app/assets/fonts/atkinson-hyperlegible-next-400-italic.woff2
Normal file
BIN
app/assets/fonts/atkinson-hyperlegible-next-400.woff2
Normal file
BIN
app/assets/fonts/young-serif-400.woff2
Normal file
1
app/assets/images/charte/favicon.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M4 4 L7 24 Q7.5 28 11.5 28 L19.5 28 Q23.5 28 24 24 L27 4 Z" fill="#5F9B59" stroke="#2E2A26" stroke-width="2.5" stroke-linejoin="round"/><path d="M26.5 9 C32 9 32 20 25 21" fill="none" stroke="#2E2A26" stroke-width="3" stroke-linecap="round"/></svg>
|
||||
|
After Width: | Height: | Size: 318 B |
48
app/assets/images/charte/illustration-tasses.svg
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 580 214" role="img" aria-labelledby="t">
|
||||
<title id="t">Trois tasses de couleur alignées sur la table, et une quatrième posée sur la Kluk, fumante.</title>
|
||||
<style>
|
||||
.table { fill: #D9BC94; }
|
||||
.table-fil, .tasse-corps, .tasse-anse, .kluk-socle, .vapeur path {
|
||||
stroke: #2E2A26; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round;
|
||||
}
|
||||
.tasse-anse { fill: none; stroke-width: 6; }
|
||||
.tasse-corps { fill: currentColor; }
|
||||
.tasse-reflet { fill: none; stroke: #fff; stroke-opacity: 0.45; stroke-width: 4; stroke-linecap: round; }
|
||||
.kluk-socle { fill: #B48D5F; }
|
||||
.kluk-voyant { fill: #F5F6F0; }
|
||||
.vapeur path { fill: none; stroke-width: 2.5; stroke: #5A534C; }
|
||||
.humeur-gris { color: #8D97A8; }
|
||||
.humeur-orange { color: #EDA33D; }
|
||||
.humeur-rouge { color: #D8573F; }
|
||||
.humeur-vert { color: #5F9B59; }
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.vapeur path { animation: vapeur 5s ease-in-out infinite; }
|
||||
.vapeur path + path { animation-delay: 2.5s; }
|
||||
}
|
||||
@keyframes vapeur {
|
||||
0%, 100% { opacity: 0.25; transform: translateY(6px); }
|
||||
50% { opacity: 0.9; transform: translateY(-6px); }
|
||||
}
|
||||
</style>
|
||||
<defs>
|
||||
<g id="tasse">
|
||||
<path class="tasse-anse" d="M63 22 C86 20 88 60 60 62" />
|
||||
<path class="tasse-corps" d="M3 6 L10 78 Q11 86 20 86 L48 86 Q57 86 58 78 L65 6 Z" />
|
||||
<path class="tasse-reflet" d="M13 18 L17 62" />
|
||||
</g>
|
||||
</defs>
|
||||
<rect class="table" x="0" y="200" width="580" height="14" rx="3" />
|
||||
<path class="table-fil" d="M0 200 H580" />
|
||||
<use href="#tasse" x="34" y="114" class="humeur-gris" />
|
||||
<use href="#tasse" x="132" y="114" class="humeur-orange" />
|
||||
<use href="#tasse" x="230" y="114" class="humeur-rouge" />
|
||||
<g transform="translate(410 98)">
|
||||
<g class="vapeur">
|
||||
<path d="M22 -6 c-9 -11 9 -20 0 -31 c-9 -11 9 -20 0 -31" />
|
||||
<path d="M44 -10 c-9 -11 9 -20 0 -31 c-9 -11 9 -20 0 -31" />
|
||||
</g>
|
||||
<use href="#tasse" x="0" y="0" class="humeur-vert" />
|
||||
<rect class="kluk-socle" x="-22" y="86" width="112" height="16" rx="8" />
|
||||
<circle class="kluk-voyant" cx="34" cy="94" r="2.6" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
1
app/assets/images/charte/photo-attente.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-2 -2 44 36"><path d="M3 3 L6 25 Q6.5 29 10.5 29 L24.5 29 Q28.5 29 29 25 L32 3 Z M31.5 8 C39 8 39.5 21 30 22" fill="none" stroke="#B48D5F" stroke-width="2.5" stroke-linejoin="round" stroke-linecap="round"/></svg>
|
||||
|
After Width: | Height: | Size: 262 B |
1
app/assets/images/charte/tasse-gris.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-3 -3 95 95"><path d="M63 22 C86 20 88 60 60 62" fill="none" stroke="#2E2A26" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 6 L10 78 Q11 86 20 86 L48 86 Q57 86 58 78 L65 6 Z" fill="#8D97A8" stroke="#2E2A26" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path d="M13 18 L17 62" fill="none" stroke="#fff" stroke-opacity="0.45" stroke-width="4" stroke-linecap="round"/></svg>
|
||||
|
After Width: | Height: | Size: 472 B |
1
app/assets/images/charte/tasse-orange.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-3 -3 95 95"><path d="M63 22 C86 20 88 60 60 62" fill="none" stroke="#2E2A26" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 6 L10 78 Q11 86 20 86 L48 86 Q57 86 58 78 L65 6 Z" fill="#EDA33D" stroke="#2E2A26" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path d="M13 18 L17 62" fill="none" stroke="#fff" stroke-opacity="0.45" stroke-width="4" stroke-linecap="round"/></svg>
|
||||
|
After Width: | Height: | Size: 472 B |
1
app/assets/images/charte/tasse-rouge.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-3 -3 95 95"><path d="M63 22 C86 20 88 60 60 62" fill="none" stroke="#2E2A26" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 6 L10 78 Q11 86 20 86 L48 86 Q57 86 58 78 L65 6 Z" fill="#D8573F" stroke="#2E2A26" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path d="M13 18 L17 62" fill="none" stroke="#fff" stroke-opacity="0.45" stroke-width="4" stroke-linecap="round"/></svg>
|
||||
|
After Width: | Height: | Size: 472 B |
1
app/assets/images/charte/tasse-vert.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-3 -3 95 95"><path d="M63 22 C86 20 88 60 60 62" fill="none" stroke="#2E2A26" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 6 L10 78 Q11 86 20 86 L48 86 Q57 86 58 78 L65 6 Z" fill="#5F9B59" stroke="#2E2A26" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path d="M13 18 L17 62" fill="none" stroke="#fff" stroke-opacity="0.45" stroke-width="4" stroke-linecap="round"/></svg>
|
||||
|
After Width: | Height: | Size: 472 B |
62
app/assets/stylesheets/_charte-bulma.scss
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
// Raccords entre Bulma et la charte : ce que ni l'un ni l'autre ne règle seul.
|
||||
|
||||
// Les titres Bulma suivent ceux de la charte : Young Serif en 400.
|
||||
.title,
|
||||
.subtitle {
|
||||
font-family: var(--serif);
|
||||
font-weight: 400;
|
||||
letter-spacing: -0.005em;
|
||||
}
|
||||
|
||||
// La charte souligne tous les liens ; pas les liens habillés en bouton ou en étiquette.
|
||||
a.button,
|
||||
a.tag,
|
||||
a.navbar-item,
|
||||
a.dropdown-item {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
// La charte ne prépare les <button class="bouton"> que dans un .formulaire :
|
||||
// on les prépare partout (button_to, f.submit…).
|
||||
button.bouton,
|
||||
input.bouton {
|
||||
border: 0;
|
||||
font: inherit;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
}
|
||||
button.bouton:disabled,
|
||||
input.bouton:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: progress;
|
||||
}
|
||||
|
||||
// button_to enveloppe son bouton dans un formulaire : le garder en ligne dans la navigation.
|
||||
.nav form.button_to {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
// La charte ne vise que les champs email et les zones de texte : on étend aux autres types.
|
||||
.formulaire {
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
input[type="date"],
|
||||
input[type="number"],
|
||||
select {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0.7rem 0.85rem;
|
||||
border: 2px solid var(--bordure-champ);
|
||||
border-radius: var(--arrondi-petit);
|
||||
background: var(--blanc);
|
||||
color: var(--encre);
|
||||
font: inherit;
|
||||
line-height: 1.4;
|
||||
|
||||
&:focus-visible {
|
||||
outline: 3px solid var(--vert);
|
||||
outline-offset: 1px;
|
||||
border-color: var(--encre);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +1,29 @@
|
|||
// @charset "utf-8";
|
||||
// Bulma, habillé aux couleurs et typographies de la charte Kluk (charte.css).
|
||||
// Les valeurs reprennent les variables de charte.css : garder les deux en phase.
|
||||
// Version sans mode sombre : la charte n'en a pas, et Bulma basculerait sinon
|
||||
// champs, titres et fonds en sombre quand le système le demande.
|
||||
@use 'bulma/versions/bulma-no-dark-mode' with (
|
||||
$family-primary: ("Atkinson Hyperlegible Next", "Atkinson Hyperlegible", system-ui, sans-serif),
|
||||
$family-secondary: ("Young Serif", Georgia, serif),
|
||||
$primary: #2E2A26, // --encre : les boutons de la charte sont à l'encre
|
||||
$link: #3F7A3B, // --vert-lien
|
||||
$success: #5F9B59, // --vert
|
||||
$warning: #EDA33D, // --orange
|
||||
$danger: #D8573F, // --rouge
|
||||
$info: #8D97A8, // --gris
|
||||
$text: #2E2A26, // --encre
|
||||
$text-strong: #2E2A26,
|
||||
$text-weak: #5A534C, // --encre-douce
|
||||
$scheme-main: #F5F6F0, // --porcelaine
|
||||
$background: #E9ECE2, // --porcelaine-fonce
|
||||
$border: #8A8279, // --bordure-champ
|
||||
$radius: 0.5rem, // --arrondi-petit
|
||||
$radius-large: 0.75rem, // --arrondi
|
||||
);
|
||||
|
||||
// Import a Google Font
|
||||
// @import url('https://fonts.googleapis.com/css?family=Nunito:400,700');
|
||||
// La charte vient après Bulma pour que ses règles de base l'emportent.
|
||||
@use 'charte';
|
||||
@use 'charte-bulma';
|
||||
|
||||
// Import only what you need from Bulma
|
||||
// @import "bulma/sass/utilities/_all.sass";
|
||||
// @import "bulma/sass/base/_all.sass";
|
||||
// @import "bulma/sass/elements/button.sass";
|
||||
// @import "bulma/sass/elements/container.sass";
|
||||
// @import "bulma/sass/elements/title.sass";
|
||||
// @import "bulma/sass/form/_all.sass";
|
||||
// @import "bulma/sass/components/navbar.sass";
|
||||
// @import "bulma/sass/layout/hero.sass";
|
||||
// @import "bulma/sass/layout/section.sass";
|
||||
|
||||
@use 'bulma/bulma';
|
||||
@use 'bulma/sass/utilities/_index.scss' as v;
|
||||
@use './kluk';
|
||||
|
||||
// Set your brand colors
|
||||
// $purple: #8A4D76;
|
||||
// $pink: #FA7C91;
|
||||
// $brown: #757763;
|
||||
// $beige-light: #D0D1CD;
|
||||
// $beige-lighter: #EFF0EB;
|
||||
|
||||
// Update Bulma's global variables
|
||||
// $family-sans-serif: "Nunito", sans-serif;
|
||||
// $grey-dark: $brown;
|
||||
// $grey-light: $beige-light;
|
||||
// $primary: $purple;
|
||||
// $link: $pink;
|
||||
// $widescreen-enabled: false;
|
||||
// $fullhd-enabled: false;
|
||||
|
||||
// Update some of Bulma's component variables
|
||||
// $body-background-color: $beige-lighter;
|
||||
// $control-border-width: 2px;
|
||||
// $input-border-color: transparent;
|
||||
// $input-shadow: none;
|
||||
// Styles propres à l'application
|
||||
@use 'kluk';
|
||||
|
|
|
|||
531
app/assets/stylesheets/charte.css
Normal file
|
|
@ -0,0 +1,531 @@
|
|||
/*
|
||||
* Kluk — charte graphique, feuille de style réutilisable.
|
||||
* Extraite de assets/css/style.scss (site kluk.fr), en CSS pur, sans Sass.
|
||||
* Copie de charte/css/kluk.css : seuls les chemins des polices changent, ils
|
||||
* pointent vers app/assets/fonts/ (Propshaft les réécrit avec l'empreinte).
|
||||
* Ne pas modifier ici : les ajustements pour Bulma sont dans _charte-bulma.scss.
|
||||
*
|
||||
* Palette : la porcelaine du matin, l'encre du thé, le chêne de la table,
|
||||
* et les quatre couleurs des tasses en accent.
|
||||
*
|
||||
* Sommaire
|
||||
* 1. Polices
|
||||
* 2. Variables (couleurs, typographies, mise en page)
|
||||
* 3. Base
|
||||
* 4. Liens, focus, lien d'évitement
|
||||
* 5. Boutons
|
||||
* 6. En-tête et navigation
|
||||
* 7. Colonne de texte et titres
|
||||
* 8. Illustration « tasses »
|
||||
* 9. Calendrier d'humeurs
|
||||
* 10. Photos
|
||||
* 11. Formulaire
|
||||
* 12. Pied de page
|
||||
* 13. Impression
|
||||
*/
|
||||
|
||||
/* ---------- 1. Polices ---------- */
|
||||
|
||||
@font-face {
|
||||
font-family: "Young Serif";
|
||||
src: url("/young-serif-400.woff2") format("woff2");
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
/* Fichier variable : couvre toutes les graisses de 200 à 800 */
|
||||
@font-face {
|
||||
font-family: "Atkinson Hyperlegible Next";
|
||||
src: url("/atkinson-hyperlegible-next-400.woff2") format("woff2");
|
||||
font-weight: 200 800;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Atkinson Hyperlegible Next";
|
||||
src: url("/atkinson-hyperlegible-next-400-italic.woff2") format("woff2");
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
/* ---------- 2. Variables ---------- */
|
||||
|
||||
:root {
|
||||
/* Fonds et texte */
|
||||
--porcelaine: #F5F6F0;
|
||||
--porcelaine-fonce: #E9ECE2;
|
||||
--encre: #2E2A26;
|
||||
--encre-douce: #5A534C;
|
||||
--chene: #D9BC94;
|
||||
--chene-fonce: #B48D5F;
|
||||
|
||||
/* Humeurs (les quatre tasses) */
|
||||
--gris: #8D97A8;
|
||||
--orange: #EDA33D;
|
||||
--vert: #5F9B59;
|
||||
--rouge: #D8573F;
|
||||
--vert-lien: #3F7A3B;
|
||||
|
||||
/* Teintes utilitaires (écrites en dur dans le site d'origine) */
|
||||
--encre-survol: #45403A;
|
||||
--surface: #FBFCF8;
|
||||
--bordure-champ: #8A8279;
|
||||
--erreur-fond: #FBE9E5;
|
||||
--blanc: #fff;
|
||||
|
||||
/* Typographies */
|
||||
--serif: "Young Serif", Georgia, serif;
|
||||
--sans: "Atkinson Hyperlegible Next", "Atkinson Hyperlegible", system-ui, sans-serif;
|
||||
|
||||
/* Mise en page */
|
||||
--colonne: 36rem;
|
||||
--gouttiere: 1.25rem;
|
||||
--largeur-entete: 64rem;
|
||||
|
||||
/* Arrondis */
|
||||
--arrondi-petit: 0.5rem;
|
||||
--arrondi: 0.75rem;
|
||||
--arrondi-pilule: 999px;
|
||||
}
|
||||
|
||||
/* ---------- 3. Base ---------- */
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after { box-sizing: border-box; }
|
||||
|
||||
html {
|
||||
-webkit-text-size-adjust: 100%;
|
||||
text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: var(--porcelaine);
|
||||
color: var(--encre);
|
||||
font-family: var(--sans);
|
||||
font-size: 1.1875rem;
|
||||
line-height: 1.65;
|
||||
font-kerning: normal;
|
||||
hyphens: manual;
|
||||
}
|
||||
|
||||
main { flex: 1; outline: none; }
|
||||
|
||||
img, svg { display: block; max-width: 100%; }
|
||||
|
||||
/* ---------- 4. Liens, focus, lien d'évitement ---------- */
|
||||
|
||||
a {
|
||||
color: var(--encre);
|
||||
text-decoration-line: underline;
|
||||
text-decoration-color: var(--vert);
|
||||
text-decoration-thickness: 0.12em;
|
||||
text-underline-offset: 0.2em;
|
||||
}
|
||||
a:hover { text-decoration-color: var(--encre); }
|
||||
|
||||
:focus-visible {
|
||||
outline: 3px solid var(--encre);
|
||||
outline-offset: 3px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.evitement {
|
||||
position: absolute;
|
||||
left: var(--gouttiere);
|
||||
top: -4rem;
|
||||
padding: 0.5rem 1rem;
|
||||
background: var(--encre);
|
||||
color: var(--porcelaine);
|
||||
z-index: 10;
|
||||
}
|
||||
.evitement:focus { top: 0.75rem; }
|
||||
|
||||
/* ---------- 5. Boutons ---------- */
|
||||
|
||||
.bouton {
|
||||
display: inline-block;
|
||||
padding: 0.8rem 1.6rem;
|
||||
border-radius: var(--arrondi-pilule);
|
||||
background: var(--encre);
|
||||
color: var(--porcelaine);
|
||||
font-weight: 700;
|
||||
line-height: 1.3;
|
||||
text-decoration: none;
|
||||
transition: background-color 0.15s ease;
|
||||
}
|
||||
.bouton:hover { background: var(--encre-survol); color: var(--porcelaine); }
|
||||
.bouton:focus-visible { outline-offset: 4px; border-radius: var(--arrondi-pilule); }
|
||||
|
||||
.bouton-petit {
|
||||
padding: 0.45rem 1rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
/* Un bouton seul dans son paragraphe respire davantage */
|
||||
p:has(> .bouton:only-child) { margin: 2rem 0; }
|
||||
|
||||
/* ---------- 6. En-tête et navigation ---------- */
|
||||
|
||||
.entete {
|
||||
max-width: var(--largeur-entete);
|
||||
margin: 0 auto;
|
||||
padding: 1.25rem var(--gouttiere);
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 1rem 2rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: inline-block;
|
||||
padding: 0.05rem 0.55rem 0.15rem;
|
||||
border: 2.5px solid var(--encre);
|
||||
border-radius: var(--arrondi-petit);
|
||||
font-family: var(--sans);
|
||||
font-weight: 800;
|
||||
font-size: 1.35rem;
|
||||
line-height: 1.2;
|
||||
letter-spacing: 0.01em;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.nav ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 0.35rem 1.35rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
.nav a:not(.bouton) {
|
||||
text-decoration-color: transparent;
|
||||
}
|
||||
.nav a:not(.bouton):hover,
|
||||
.nav a[aria-current="page"]:not(.bouton) {
|
||||
text-decoration-color: var(--vert);
|
||||
}
|
||||
.nav a.bouton[aria-current="page"] {
|
||||
background: var(--porcelaine);
|
||||
color: var(--encre);
|
||||
box-shadow: inset 0 0 0 2px var(--encre);
|
||||
}
|
||||
|
||||
/* ---------- 7. Colonne de texte et titres ---------- */
|
||||
|
||||
.texte {
|
||||
max-width: calc(var(--colonne) + 2 * var(--gouttiere));
|
||||
margin: 0 auto;
|
||||
padding: 2rem var(--gouttiere) 5rem;
|
||||
}
|
||||
|
||||
h1, h2, h3 {
|
||||
font-family: var(--serif);
|
||||
font-weight: 400;
|
||||
line-height: 1.15;
|
||||
letter-spacing: -0.005em;
|
||||
text-wrap: balance;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: clamp(2.35rem, 1.6rem + 3.6vw, 3.75rem);
|
||||
margin: 1.5rem 0 1.5rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: clamp(1.6rem, 1.35rem + 1vw, 2rem);
|
||||
margin: 4.5rem 0 1.25rem;
|
||||
}
|
||||
|
||||
p { margin: 0 0 1.15rem; }
|
||||
|
||||
/* Le chapeau : paragraphe entièrement en italique juste sous le titre */
|
||||
h1 + p:has(> em:only-child) {
|
||||
font-size: 1.3rem;
|
||||
line-height: 1.55;
|
||||
color: var(--encre-douce);
|
||||
}
|
||||
|
||||
.note {
|
||||
margin-top: 2.5rem;
|
||||
color: var(--encre-douce);
|
||||
font-size: 1.0625rem;
|
||||
}
|
||||
|
||||
.exergue {
|
||||
margin: 2.25rem 0;
|
||||
padding-left: 1.25rem;
|
||||
border-left: 4px solid var(--orange);
|
||||
font-family: var(--serif);
|
||||
font-size: 1.45rem;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 0.9em;
|
||||
background: var(--porcelaine-fonce);
|
||||
padding: 0.05em 0.3em;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
/* ---------- 8. Illustration « tasses » ---------- */
|
||||
|
||||
.tasses {
|
||||
margin: 1.5rem 0 0;
|
||||
}
|
||||
/* L'illustration déborde légèrement de la colonne sur grand écran */
|
||||
@media (min-width: 48rem) {
|
||||
.tasses { margin-inline: -4rem; }
|
||||
}
|
||||
.tasses svg { width: 100%; height: auto; overflow: visible; }
|
||||
|
||||
.table { fill: var(--chene); }
|
||||
.table-fil,
|
||||
.tasse-corps,
|
||||
.tasse-anse,
|
||||
.kluk-socle,
|
||||
.vapeur path {
|
||||
stroke: var(--encre);
|
||||
stroke-width: 3;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
}
|
||||
.tasse-anse { fill: none; stroke-width: 6; }
|
||||
.tasse-corps { fill: currentColor; }
|
||||
.tasse-reflet { fill: none; stroke: var(--blanc); stroke-opacity: 0.45; stroke-width: 4; stroke-linecap: round; }
|
||||
.kluk-socle { fill: var(--chene-fonce); }
|
||||
.kluk-voyant { fill: var(--porcelaine); }
|
||||
.vapeur path { fill: none; stroke-width: 2.5; stroke: var(--encre-douce); }
|
||||
|
||||
.humeur-gris { color: var(--gris); }
|
||||
.humeur-orange { color: var(--orange); }
|
||||
.humeur-rouge { color: var(--rouge); }
|
||||
.humeur-vert { color: var(--vert); }
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.vapeur path {
|
||||
animation: vapeur 5s ease-in-out infinite;
|
||||
}
|
||||
.vapeur path + path { animation-delay: 2.5s; }
|
||||
}
|
||||
@keyframes vapeur {
|
||||
0%, 100% { opacity: 0.25; transform: translateY(6px); }
|
||||
50% { opacity: 0.9; transform: translateY(-6px); }
|
||||
}
|
||||
|
||||
/* ---------- 9. Calendrier d'humeurs (décoratif) ---------- */
|
||||
|
||||
.calendrier {
|
||||
display: grid;
|
||||
grid-template-rows: repeat(7, auto);
|
||||
grid-auto-flow: column;
|
||||
grid-auto-columns: 1fr;
|
||||
gap: 4px;
|
||||
margin: 2.25rem 0 1rem;
|
||||
padding: 1.25rem;
|
||||
background: var(--surface);
|
||||
border-radius: var(--arrondi);
|
||||
box-shadow: inset 0 0 0 1px var(--porcelaine-fonce);
|
||||
}
|
||||
.jour {
|
||||
aspect-ratio: 1;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.jour-g { background: var(--gris); }
|
||||
.jour-o { background: var(--orange); }
|
||||
.jour-v { background: var(--vert); }
|
||||
.jour-r { background: var(--rouge); }
|
||||
|
||||
@media (max-width: 30rem) {
|
||||
.calendrier { gap: 3px; padding: 0.9rem; }
|
||||
}
|
||||
|
||||
/* ---------- 10. Photos ---------- */
|
||||
|
||||
.photo {
|
||||
margin: 2rem 0;
|
||||
}
|
||||
.photo img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
border-radius: var(--arrondi);
|
||||
}
|
||||
.photo figcaption {
|
||||
margin-top: 0.6rem;
|
||||
font-size: 0.95rem;
|
||||
color: var(--encre-douce);
|
||||
}
|
||||
|
||||
.photo-attente {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1.25rem;
|
||||
aspect-ratio: 3 / 2;
|
||||
padding: 1.5rem;
|
||||
border: 2px dashed var(--chene-fonce);
|
||||
border-radius: var(--arrondi);
|
||||
background: var(--porcelaine-fonce);
|
||||
color: var(--encre-douce);
|
||||
font-size: 1rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.photo-attente svg {
|
||||
flex: none;
|
||||
width: 2.75rem;
|
||||
fill: none;
|
||||
stroke: var(--chene-fonce);
|
||||
stroke-width: 2.5;
|
||||
stroke-linejoin: round;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
.photo-attente p { margin: 0; }
|
||||
.photo-attente strong { color: var(--encre); }
|
||||
|
||||
/* ---------- 11. Formulaire ---------- */
|
||||
|
||||
.formulaire {
|
||||
margin: 2.5rem 0 1rem;
|
||||
padding: 1.75rem 1.25rem;
|
||||
background: var(--surface);
|
||||
border-radius: var(--arrondi);
|
||||
box-shadow: inset 0 0 0 1px var(--porcelaine-fonce);
|
||||
}
|
||||
@media (min-width: 40rem) {
|
||||
.formulaire { padding: 2.25rem 2.5rem; }
|
||||
}
|
||||
|
||||
.champ {
|
||||
margin: 0 0 1.75rem;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.champ > label,
|
||||
.champ > legend {
|
||||
display: block;
|
||||
padding: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.precision {
|
||||
font-weight: 400;
|
||||
color: var(--encre-douce);
|
||||
}
|
||||
|
||||
.formulaire input[type="email"],
|
||||
.formulaire textarea {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0.7rem 0.85rem;
|
||||
border: 2px solid var(--bordure-champ);
|
||||
border-radius: var(--arrondi-petit);
|
||||
background: var(--blanc);
|
||||
color: var(--encre);
|
||||
font: inherit;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.formulaire textarea { resize: vertical; min-height: 8rem; }
|
||||
|
||||
.formulaire input[type="email"]:focus-visible,
|
||||
.formulaire textarea:focus-visible {
|
||||
outline: 3px solid var(--vert);
|
||||
outline-offset: 1px;
|
||||
border-color: var(--encre);
|
||||
}
|
||||
|
||||
.choix {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.choix li {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 0.75rem;
|
||||
padding: 0.35rem 0;
|
||||
}
|
||||
.choix input {
|
||||
flex: none;
|
||||
width: 1.35rem;
|
||||
height: 1.35rem;
|
||||
margin: 0.2rem 0 0;
|
||||
accent-color: var(--vert-lien);
|
||||
cursor: pointer;
|
||||
}
|
||||
.choix label { cursor: pointer; }
|
||||
|
||||
/* Champ piège anti-robots, invisible */
|
||||
.piege {
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.formulaire-erreur {
|
||||
padding: 0.75rem 1rem;
|
||||
border-left: 4px solid var(--rouge);
|
||||
background: var(--erreur-fond);
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.formulaire .bouton {
|
||||
border: 0;
|
||||
font: inherit;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
}
|
||||
.formulaire .bouton:disabled { opacity: 0.6; cursor: progress; }
|
||||
|
||||
.formulaire-secours {
|
||||
margin: 1rem 0 0;
|
||||
font-size: 1rem;
|
||||
color: var(--encre-douce);
|
||||
}
|
||||
|
||||
/* ---------- 12. Pied de page : la table en bois ---------- */
|
||||
|
||||
.pied {
|
||||
background: var(--chene);
|
||||
border-top: 3px solid var(--encre);
|
||||
font-size: 1rem;
|
||||
}
|
||||
.pied-interieur {
|
||||
max-width: calc(var(--colonne) + 2 * var(--gouttiere));
|
||||
margin: 0 auto;
|
||||
padding: 2rem var(--gouttiere) 2.5rem;
|
||||
}
|
||||
.pied-phrase {
|
||||
font-family: var(--serif);
|
||||
font-size: 1.15rem;
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
.pied-liens {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem 2rem;
|
||||
}
|
||||
.pied a { text-decoration-color: var(--encre); text-decoration-thickness: 1px; }
|
||||
.pied a:hover { text-decoration-thickness: 2px; }
|
||||
|
||||
/* ---------- 13. Impression ---------- */
|
||||
|
||||
@media print {
|
||||
.entete .nav, .pied, .tasses, .calendrier { display: none; }
|
||||
body { background: var(--blanc); }
|
||||
}
|
||||
|
|
@ -1,31 +1,8 @@
|
|||
/*
|
||||
* This is a manifest file that'll be compiled into application.css.
|
||||
*
|
||||
* With Propshaft, assets are served efficiently without preprocessing steps. You can still include
|
||||
* application-wide styles in this file, but keep in mind that CSS precedence will follow the standard
|
||||
* cascading order, meaning styles declared later in the document or manifest will override earlier ones,
|
||||
* depending on specificity.
|
||||
*
|
||||
* Consider organizing styles into separate files for maintainability.
|
||||
* Styles propres à l'application (tableau de bord, journal).
|
||||
* La charte graphique est dans charte.css, les raccords avec Bulma dans _charte-bulma.scss.
|
||||
*/
|
||||
|
||||
body {
|
||||
margin: 0px;
|
||||
font-family: "Sour Gummy", sans-serif;
|
||||
font-weight: 350;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
main {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
#navbar-top {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
|
||||
.tracker {
|
||||
align-content: center;
|
||||
}
|
||||
|
|
@ -36,9 +13,9 @@ main {
|
|||
}
|
||||
|
||||
.current-day {
|
||||
background-color: white;
|
||||
background-color: var(--porcelaine);
|
||||
position: sticky;
|
||||
top: 64px;
|
||||
top: 0;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
|
|
@ -71,14 +48,14 @@ main {
|
|||
|
||||
.selected-day {
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 0 3px white, 0 0 0 5px black;
|
||||
box-shadow: 0 0 0 3px var(--porcelaine), 0 0 0 5px var(--encre);
|
||||
margin: 4px;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
.empty-day {
|
||||
border: 1px dashed #aaa;
|
||||
border: 1px dashed var(--bordure-champ);
|
||||
margin: 4px;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
|
|
|
|||
7
app/controllers/charte_controller.rb
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# Page de démonstration des composants de la charte graphique (développement seulement).
|
||||
class CharteController < ApplicationController
|
||||
allow_unauthenticated_access
|
||||
|
||||
def show
|
||||
end
|
||||
end
|
||||
|
|
@ -1,2 +1,8 @@
|
|||
module ApplicationHelper
|
||||
# Lien de navigation de l'en-tête : marqué aria-current="page" sur la page courante,
|
||||
# ce qui déclenche le soulignement vert (ou l'inversion du bouton) de la charte.
|
||||
def lien_nav(nom, chemin, **options)
|
||||
options[:"aria-current"] = "page" if current_page?(chemin)
|
||||
link_to nom, chemin, **options
|
||||
end
|
||||
end
|
||||
|
|
|
|||
13
app/views/application/_entete.html.erb
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<header class="entete">
|
||||
<%= link_to "kluk", root_path, class: "logo", "aria-label": "Kluk, retour à l'accueil" %>
|
||||
<nav class="nav" aria-label="Navigation principale">
|
||||
<ul>
|
||||
<% if authenticated? %>
|
||||
<li><%= lien_nav "Mon tableau de bord", dashboard_path %></li>
|
||||
<li><%= button_to "Se déconnecter", session_path, method: :delete, class: "bouton bouton-petit" %></li>
|
||||
<% else %>
|
||||
<li><%= lien_nav "Se connecter", new_session_path, class: "bouton bouton-petit" %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
9
app/views/application/_pied.html.erb
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<footer class="pied">
|
||||
<div class="pied-interieur">
|
||||
<p class="pied-phrase">Comment ça Kluk aujourd’hui ?</p>
|
||||
<ul class="pied-liens">
|
||||
<li><%= link_to "Découvrir la Kluk", "https://kluk.fr/" %></li>
|
||||
<li><%= link_to "Mentions légales", "https://kluk.fr/mentions-legales/" %></li>
|
||||
</ul>
|
||||
</div>
|
||||
</footer>
|
||||
5
app/views/charte/_bouton.html.erb
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<%# Bouton de la charte (pilule encre). Pour un bouton d'envoi : f.submit "…", class: "bouton".
|
||||
render "charte/bouton", texte: "Je veux ma Kluk", href: dashboard_path
|
||||
render "charte/bouton", texte: "Voir", href: "#", petit: true, data: { turbo_frame: "x" } %>
|
||||
<%# locals: (texte:, href:, petit: false, **attributs) -%>
|
||||
<%= link_to texte, href, class: ["bouton", ("bouton-petit" if petit)], **attributs %>
|
||||
10
app/views/charte/_calendrier.html.erb
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<%# Calendrier d'humeurs décoratif : une case par jour, colonnes de 7 jours (une semaine par colonne).
|
||||
jours : suite de lettres g (gris), o (orange), v (vert), r (rouge), en chaîne ou en tableau.
|
||||
render "charte/calendrier", jours: "vvovvvg vvvvovv ovvrvvv" %>
|
||||
<%# locals: (jours:) -%>
|
||||
<% jours = jours.is_a?(String) ? jours.delete(" ").chars : Array(jours) %>
|
||||
<div class="calendrier" aria-hidden="true">
|
||||
<% jours.each do |jour| %>
|
||||
<span class="jour jour-<%= jour %>"></span>
|
||||
<% end %>
|
||||
</div>
|
||||
12
app/views/charte/_champ.html.erb
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<%# Champ de formulaire de la charte (dans un form de classe "formulaire") :
|
||||
libellé en gras au-dessus, précision facultative en encre douce. Le bloc donne la saisie.
|
||||
render("charte/champ", form: f, attribut: :email_address, libelle: "Votre adresse mail", precision: "(obligatoire)") { f.email_field :email_address, required: true }
|
||||
(en ERB, avec « do » / « end » et la saisie dans le bloc) %>
|
||||
<%# locals: (form:, attribut:, libelle:, precision: nil) -%>
|
||||
<div class="champ">
|
||||
<%= form.label attribut do %>
|
||||
<%= libelle %>
|
||||
<% if precision %><span class="precision"><%= precision %></span><% end %>
|
||||
<% end %>
|
||||
<%= yield %>
|
||||
</div>
|
||||
4
app/views/charte/_exergue.html.erb
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<%# Phrase mise en valeur, en serif, avec un trait orange.
|
||||
render "charte/exergue", texte: "Une phrase à mettre en valeur." %>
|
||||
<%# locals: (texte:) -%>
|
||||
<%= tag.p texte, class: "exergue" %>
|
||||
8
app/views/charte/_formulaire_erreur.html.erb
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<%# Message d'erreur de formulaire (trait rouge sur fond rosé). Rien n'est affiché sans message.
|
||||
render "charte/formulaire_erreur", messages: @day_log.errors.full_messages
|
||||
render "charte/formulaire_erreur", messages: flash[:alert] %>
|
||||
<%# locals: (messages:) -%>
|
||||
<% messages = Array(messages).compact_blank %>
|
||||
<% if messages.any? %>
|
||||
<p class="formulaire-erreur" role="alert"><%= safe_join(messages, tag.br) %></p>
|
||||
<% end %>
|
||||
4
app/views/charte/_note.html.erb
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<%# Précision discrète, en fin de page.
|
||||
render "charte/note", texte: "Une précision." %>
|
||||
<%# locals: (texte:) -%>
|
||||
<%= tag.p texte, class: "note" %>
|
||||
10
app/views/charte/_photo.html.erb
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<%# Photo arrondie avec légende facultative. Toujours un alt descriptif, et width/height
|
||||
pour éviter les sauts de mise en page (format du site : 1200 × 900).
|
||||
render "charte/photo", src: "croisiere.jpg", alt: "…", width: 1200, height: 900, legende: "…" %>
|
||||
<%# locals: (src:, alt:, width: nil, height: nil, legende: nil) -%>
|
||||
<figure class="photo">
|
||||
<%= image_tag src, alt: alt, width: width, height: height, loading: "lazy", decoding: "async" %>
|
||||
<% if legende %>
|
||||
<figcaption><%= legende %></figcaption>
|
||||
<% end %>
|
||||
</figure>
|
||||
12
app/views/charte/_photo_attente.html.erb
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<%# Emplacement de photo, en attendant l'image : cadre 3:2 en pointillés chêne.
|
||||
render "charte/photo_attente", description: "La Kluk posée sur la table du petit-déjeuner." %>
|
||||
<%# locals: (description:, titre: nil, legende: nil) -%>
|
||||
<figure class="photo">
|
||||
<div class="photo-attente">
|
||||
<svg viewBox="0 0 40 32" aria-hidden="true" focusable="false"><path d="M3 3 L6 25 Q6.5 29 10.5 29 L24.5 29 Q28.5 29 29 25 L32 3 Z M31.5 8 C39 8 39.5 21 30 22" /></svg>
|
||||
<p><strong><%= titre || "Photo à venir" %></strong><br><%= description %></p>
|
||||
</div>
|
||||
<% if legende %>
|
||||
<figcaption><%= legende %></figcaption>
|
||||
<% end %>
|
||||
</figure>
|
||||
30
app/views/charte/_tasses.html.erb
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<%# Illustration « table et tasses », en SVG dans la page pour suivre les variables CSS.
|
||||
Une seule par page (identifiants #tasse et #tasses-titre).
|
||||
render "charte/tasses" %>
|
||||
<%# locals: () -%>
|
||||
<figure class="tasses">
|
||||
<svg viewBox="0 0 580 214" role="img" aria-labelledby="tasses-titre">
|
||||
<title id="tasses-titre">Illustration : trois tasses de couleur alignées sur la table, et une quatrième posée sur la Kluk, fumante.</title>
|
||||
<defs>
|
||||
<g id="tasse">
|
||||
<path class="tasse-anse" d="M63 22 C86 20 88 60 60 62" />
|
||||
<path class="tasse-corps" d="M3 6 L10 78 Q11 86 20 86 L48 86 Q57 86 58 78 L65 6 Z" />
|
||||
<path class="tasse-reflet" d="M13 18 L17 62" />
|
||||
</g>
|
||||
</defs>
|
||||
<rect class="table" x="0" y="200" width="580" height="14" rx="3" />
|
||||
<path class="table-fil" d="M0 200 H580" />
|
||||
<use href="#tasse" x="34" y="114" class="humeur-gris" />
|
||||
<use href="#tasse" x="132" y="114" class="humeur-orange" />
|
||||
<use href="#tasse" x="230" y="114" class="humeur-rouge" />
|
||||
<g class="kluk-illu" transform="translate(410 98)">
|
||||
<g class="vapeur" aria-hidden="true">
|
||||
<path d="M22 -6 c-9 -11 9 -20 0 -31 c-9 -11 9 -20 0 -31" />
|
||||
<path d="M44 -10 c-9 -11 9 -20 0 -31 c-9 -11 9 -20 0 -31" />
|
||||
</g>
|
||||
<use href="#tasse" x="0" y="0" class="humeur-vert" />
|
||||
<rect class="kluk-socle" x="-22" y="86" width="112" height="16" rx="8" />
|
||||
<circle class="kluk-voyant" cx="34" cy="94" r="2.6" />
|
||||
</g>
|
||||
</svg>
|
||||
</figure>
|
||||
47
app/views/charte/show.html.erb
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<% content_for :title, "Charte Kluk" %>
|
||||
<article class="texte">
|
||||
<h1>Charte graphique Kluk</h1>
|
||||
<p><em>Les composants de la charte, rendus par les partials de app/views/charte.</em></p>
|
||||
|
||||
<p>Texte courant en Atkinson Hyperlegible Next, avec <a href="#">un lien souligné de vert</a>, du <strong>gras</strong>, de l’<em>italique</em> et du <code>code</code>.</p>
|
||||
|
||||
<p><%= render "charte/bouton", texte: "Bouton principal", href: "#" %></p>
|
||||
<p><%= render "charte/bouton", texte: "Petit bouton", href: "#", petit: true %></p>
|
||||
|
||||
<%= render "charte/tasses" %>
|
||||
|
||||
<h2>Intertitre de section</h2>
|
||||
<p>Les intertitres ménagent un grand espace au-dessus d’eux pour découper la page en respirations.</p>
|
||||
|
||||
<%= render "charte/exergue", texte: "Une phrase mise en exergue, en serif, soulignée d’un trait orange." %>
|
||||
|
||||
<%= render "charte/photo", src: "croisiere.jpg", alt: "Photo d’exemple", legende: "Légende facultative sous la photo." %>
|
||||
<%= render "charte/photo_attente", description: "Description de la photo attendue." %>
|
||||
|
||||
<%= render "charte/calendrier", jours: "vvovvvg vvvvovv ovvrvvv vvgvvvo ovvvvvv rrovrrr rorrvvo gvggggg gggvggg gogggvg ggoggvg vvgvvvv ovvvovv vrvvvov vvvvovv ovvgvvv vvovvrv vvvovvv vgvvvvo vvvvovv" %>
|
||||
|
||||
<%= form_with url: "#", class: "formulaire", data: { turbo: false } do |f| %>
|
||||
<%= render "charte/champ", form: f, attribut: :email, libelle: "Votre adresse mail", precision: "(obligatoire)" do %>
|
||||
<%= f.email_field :email, autocomplete: "email" %>
|
||||
<% end %>
|
||||
<%= render "charte/champ", form: f, attribut: :mot_de_passe, libelle: "Mot de passe" do %>
|
||||
<%= f.password_field :mot_de_passe %>
|
||||
<% end %>
|
||||
<%= render "charte/champ", form: f, attribut: :message, libelle: "Un mot, une idée, une question ?", precision: "(facultatif)" do %>
|
||||
<%= f.text_area :message, rows: 5 %>
|
||||
<% end %>
|
||||
<%= render "charte/formulaire_erreur", messages: ["Message d’erreur du formulaire."] %>
|
||||
<%= f.submit "Envoyer", class: "bouton" %>
|
||||
<% end %>
|
||||
|
||||
<h2>Bulma aux couleurs de la charte</h2>
|
||||
<div class="buttons">
|
||||
<a class="button is-primary" href="#">is-primary</a>
|
||||
<a class="button is-link" href="#">is-link</a>
|
||||
<a class="button is-light" href="#">is-light</a>
|
||||
</div>
|
||||
<p class="title is-4">Titre Bulma</p>
|
||||
<div class="notification is-danger">Notification is-danger</div>
|
||||
|
||||
<%= render "charte/note", texte: "Une note discrète en fin de page." %>
|
||||
</article>
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
%main.columns.m-auto
|
||||
.columns.m-auto
|
||||
.current-day.column.is-hidden-mobile
|
||||
%section.m-4
|
||||
%figure.image.has-ratio
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
%article.texte
|
||||
%h1 Comment ça KLUK ?
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
<article class="texte">
|
||||
<div>
|
||||
<h1>Set up your password</h1>
|
||||
<p>Please set your password to activate your account.</p>
|
||||
|
|
@ -22,3 +23,4 @@
|
|||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</article>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<title><%= content_for(:title) || "Moodie" %></title>
|
||||
<title><%= content_for(:title) || "Kluk" %></title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<meta name="theme-color" content="#F5F6F0">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<%= csrf_meta_tags %>
|
||||
|
|
@ -14,13 +15,11 @@
|
|||
<%# Enable PWA manifest for installable apps (make sure to enable in config/routes.rb too!) %>
|
||||
<%#= tag.link rel: "manifest", href: pwa_manifest_path(format: :json) %>
|
||||
|
||||
<link rel="icon" href="/icon.png" type="image/png">
|
||||
<link rel="icon" href="/icon.svg" type="image/svg+xml">
|
||||
<%= favicon_link_tag "charte/favicon.svg", type: "image/svg+xml" %>
|
||||
<link rel="apple-touch-icon" href="/icon.png">
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Delius&family=Sour+Gummy:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
||||
<%= preload_link_tag "young-serif-400.woff2" %>
|
||||
<%= preload_link_tag "atkinson-hyperlegible-next-400.woff2" %>
|
||||
|
||||
<script src="https://kit.fontawesome.com/079b06296f.js" crossorigin="anonymous"></script>
|
||||
|
||||
|
|
@ -30,7 +29,11 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<%= render 'menu' %>
|
||||
<a class="evitement" href="#contenu">Aller au contenu</a>
|
||||
<%= render "entete" %>
|
||||
<main id="contenu" tabindex="-1">
|
||||
<%= yield %>
|
||||
</main>
|
||||
<%= render "pied" %>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<main data-controller="mood" class="columns m-auto">
|
||||
<div data-controller="mood" class="columns m-auto">
|
||||
<div class="current-day column is-hidden-mobile">
|
||||
<section class="m-4">
|
||||
<figure class="image has-ratio">
|
||||
|
|
@ -60,4 +60,4 @@
|
|||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
<article class="texte">
|
||||
<h1>Update your password</h1>
|
||||
|
||||
<%= tag.div(flash[:alert], style: "color:red") if flash[:alert] %>
|
||||
|
|
@ -7,3 +8,4 @@
|
|||
<%= form.password_field :password_confirmation, required: true, autocomplete: "new-password", placeholder: "Repeat new password", maxlength: 72 %><br>
|
||||
<%= form.submit "Save" %>
|
||||
<% end %>
|
||||
</article>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
<article class="texte">
|
||||
<h1>Forgot your password?</h1>
|
||||
|
||||
<%= tag.div(flash[:alert], style: "color:red") if flash[:alert] %>
|
||||
|
|
@ -6,3 +7,4 @@
|
|||
<%= form.email_field :email_address, required: true, autofocus: true, autocomplete: "username", placeholder: "Enter your email address", value: params[:email_address] %><br>
|
||||
<%= form.submit "Email reset instructions" %>
|
||||
<% end %>
|
||||
</article>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
%main.columns.m-auto{"data-controller" => "mood"}
|
||||
.columns.m-auto{"data-controller" => "mood"}
|
||||
.column.is-hidden-mobile
|
||||
%section.m-4
|
||||
%figure.image.has-ratio
|
||||
|
|
|
|||
389
charte-graphique.md
Normal file
|
|
@ -0,0 +1,389 @@
|
|||
# Charte graphique Kluk
|
||||
|
||||
Charte extraite du site kluk.fr (`assets/css/style.scss`, `_layouts/`, `_includes/`).
|
||||
Tout ce qu'il faut pour la réutiliser ailleurs se trouve dans le dossier [`charte/`](charte/) :
|
||||
|
||||
```
|
||||
charte/
|
||||
├── css/kluk.css Feuille de style complète, en CSS pur (sans Sass)
|
||||
├── fonts/ Young Serif, Atkinson Hyperlegible Next (woff2) + licence OFL
|
||||
├── img/
|
||||
│ ├── favicon.svg Icône du site (tasse verte)
|
||||
│ ├── illustration-tasses.svg Illustration « table et tasses », autonome (styles intégrés)
|
||||
│ ├── tasse-{gris,orange,vert,rouge}.svg Une tasse seule, dans chaque couleur d'humeur
|
||||
│ └── photo-attente.svg Pictogramme de l'emplacement de photo
|
||||
└── exemple.html Page de démonstration de tous les composants
|
||||
```
|
||||
|
||||
Pour démarrer : copier `charte/` dans le projet, puis dans le `<head>` :
|
||||
|
||||
```html
|
||||
<meta name="theme-color" content="#F5F6F0">
|
||||
<link rel="preload" href="charte/fonts/young-serif-400.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="charte/fonts/atkinson-hyperlegible-next-400.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="stylesheet" href="charte/css/kluk.css">
|
||||
<link rel="icon" href="charte/img/favicon.svg" type="image/svg+xml">
|
||||
```
|
||||
|
||||
Les chemins des polices dans `kluk.css` sont relatifs (`../fonts/`) : garder la structure `css/` + `fonts/` côte à côte.
|
||||
|
||||
---
|
||||
|
||||
## 1. Esprit
|
||||
|
||||
Un univers de petit-déjeuner, calme et chaleureux : **la porcelaine du matin** (fond), **l'encre du thé** (texte), **le chêne de la table** (pied de page, illustration), et **les quatre couleurs des tasses** (gris, orange, vert, rouge) comme accents, qui sont aussi les quatre « humeurs ».
|
||||
|
||||
Principes :
|
||||
|
||||
- une seule colonne de lecture étroite (36 rem), beaucoup d'air ;
|
||||
- des titres en serif ronde et amicale, un texte courant très lisible ;
|
||||
- des formes arrondies (boutons en pilule, cartes arrondies), des traits d'encre épais façon dessin ;
|
||||
- l'accessibilité d'abord : contrastes élevés, focus très visible, lien d'évitement, animations coupées si l'utilisateur le demande.
|
||||
|
||||
---
|
||||
|
||||
## 2. Couleurs
|
||||
|
||||
Toutes les couleurs sont des variables CSS déclarées sur `:root`.
|
||||
|
||||
### Fonds et texte
|
||||
|
||||
| Variable | Valeur | Rôle |
|
||||
|---|---|---|
|
||||
| `--porcelaine` | `#F5F6F0` | Fond de page, texte sur fond encre, `theme-color` |
|
||||
| `--porcelaine-fonce` | `#E9ECE2` | Fond de `code`, emplacement de photo, liseré des cartes |
|
||||
| `--encre` | `#2E2A26` | Texte, bordures, fond des boutons |
|
||||
| `--encre-douce` | `#5A534C` | Texte secondaire : chapeau, notes, légendes, précisions |
|
||||
| `--chene` | `#D9BC94` | Pied de page, plateau de la table (illustration) |
|
||||
| `--chene-fonce` | `#B48D5F` | Socle de la Kluk, pointillés et picto de l'emplacement photo |
|
||||
|
||||
### Humeurs (accents)
|
||||
|
||||
| Variable | Valeur | Rôle |
|
||||
|---|---|---|
|
||||
| `--gris` | `#8D97A8` | Humeur grise |
|
||||
| `--orange` | `#EDA33D` | Humeur orange, trait de l'exergue |
|
||||
| `--vert` | `#5F9B59` | Humeur verte, soulignement des liens, focus des champs, favicon |
|
||||
| `--rouge` | `#D8573F` | Humeur rouge, trait des messages d'erreur |
|
||||
| `--vert-lien` | `#3F7A3B` | Vert foncé pour les cases à cocher (`accent-color`) |
|
||||
|
||||
### Teintes utilitaires
|
||||
|
||||
Écrites en dur dans le site d'origine ; `kluk.css` les expose en variables, avec les mêmes valeurs.
|
||||
|
||||
| Variable | Valeur | Rôle |
|
||||
|---|---|---|
|
||||
| `--encre-survol` | `#45403A` | Fond des boutons au survol |
|
||||
| `--surface` | `#FBFCF8` | Fond des cartes (formulaire, calendrier) |
|
||||
| `--bordure-champ` | `#8A8279` | Bordure des champs de saisie |
|
||||
| `--erreur-fond` | `#FBE9E5` | Fond des messages d'erreur |
|
||||
| `--blanc` | `#fff` | Fond des champs, reflet des tasses, fond à l'impression |
|
||||
|
||||
### Contrastes (WCAG)
|
||||
|
||||
| Couple | Ratio | Usage autorisé |
|
||||
|---|---|---|
|
||||
| encre / porcelaine | 13,1 : 1 | tout texte |
|
||||
| encre-douce / porcelaine | 7,0 : 1 | tout texte |
|
||||
| encre / chêne | 7,8 : 1 | tout texte (pied de page) |
|
||||
| porcelaine / encre-survol | 9,4 : 1 | texte des boutons au survol |
|
||||
| vert-lien / porcelaine | 4,8 : 1 | texte possible |
|
||||
| vert / porcelaine | 3,1 : 1 | éléments graphiques seulement (soulignés, contours) |
|
||||
| rouge / porcelaine | 3,6 : 1 | éléments graphiques seulement |
|
||||
| gris / porcelaine | 2,7 : 1 | décoratif seulement |
|
||||
| orange / porcelaine | 2,0 : 1 | décoratif seulement |
|
||||
|
||||
Règle : **le texte est toujours en encre ou encre douce**. Les couleurs d'humeur ne servent qu'aux traits, soulignés, pastilles et illustrations, jamais au texte.
|
||||
|
||||
---
|
||||
|
||||
## 3. Typographies
|
||||
|
||||
| Variable | Pile | Usage |
|
||||
|---|---|---|
|
||||
| `--serif` | `"Young Serif", Georgia, serif` | Titres `h1`–`h3`, exergue, phrase du pied de page |
|
||||
| `--sans` | `"Atkinson Hyperlegible Next", "Atkinson Hyperlegible", system-ui, sans-serif` | Tout le reste, y compris le logo |
|
||||
|
||||
Fichiers fournis (`charte/fonts/`, licence SIL OFL 1.1 dans `OFL.txt`) :
|
||||
|
||||
- `young-serif-400.woff2` : Young Serif, une seule graisse (400) ;
|
||||
- `atkinson-hyperlegible-next-400.woff2` : Atkinson Hyperlegible Next **variable**, graisses 200 à 800 ;
|
||||
- `atkinson-hyperlegible-next-400-italic.woff2` : italique 400.
|
||||
|
||||
Graisses utilisées : 400 (texte), 700 (boutons, libellés, `strong`), 800 (logo). Les titres restent en 400 : c'est la serif qui porte le caractère.
|
||||
|
||||
### Échelle
|
||||
|
||||
| Élément | Taille | Interlignage | Remarques |
|
||||
|---|---|---|---|
|
||||
| Corps (`body`) | `1.1875rem` (19 px) | 1.65 | `font-kerning: normal` |
|
||||
| `h1` | `clamp(2.35rem, 1.6rem + 3.6vw, 3.75rem)` | 1.15 | serif, `text-wrap: balance` |
|
||||
| `h2` | `clamp(1.6rem, 1.35rem + 1vw, 2rem)` | 1.15 | serif |
|
||||
| Chapeau | `1.3rem` | 1.55 | italique, encre douce |
|
||||
| Exergue | `1.45rem` | 1.4 | serif |
|
||||
| Logo | `1.35rem` | 1.2 | sans 800, `letter-spacing: 0.01em` |
|
||||
| Phrase du pied | `1.15rem` | — | serif |
|
||||
| Note | `1.0625rem` | — | encre douce |
|
||||
| Navigation, petit bouton, pied, formulaire (erreur, secours), emplacement photo | `1rem` | — | |
|
||||
| Légende de photo | `0.95rem` | — | encre douce |
|
||||
| `code` | `0.9em` | — | |
|
||||
|
||||
Titres : `letter-spacing: -0.005em`.
|
||||
|
||||
### Typographie française
|
||||
|
||||
Le site applique automatiquement (plugin Jekyll `_plugins/typographie.rb`) une espace fine insécable avant `; ! ?` et une espace insécable avant `:` et `»` et après `«`. Dans un autre projet, taper ces espaces directement (` ` fine, ` ` insécable) ou reprendre ce plugin. Apostrophe typographique `’` et guillemets `« »`.
|
||||
|
||||
---
|
||||
|
||||
## 4. Espacements et mise en page
|
||||
|
||||
| Variable | Valeur | Rôle |
|
||||
|---|---|---|
|
||||
| `--colonne` | `36rem` | Largeur de la colonne de texte (~ 65 caractères) |
|
||||
| `--gouttiere` | `1.25rem` | Marge latérale sur mobile, padding horizontal des conteneurs |
|
||||
| `--largeur-entete` | `64rem` | Largeur maximale de l'en-tête |
|
||||
| `--arrondi-petit` | `0.5rem` | Logo, champs de saisie |
|
||||
| `--arrondi` | `0.75rem` | Photos, cartes (formulaire, calendrier, emplacement photo) |
|
||||
| `--arrondi-pilule` | `999px` | Boutons |
|
||||
|
||||
Rythme vertical (marges) :
|
||||
|
||||
| Élément | Marge |
|
||||
|---|---|
|
||||
| Paragraphe | `0 0 1.15rem` |
|
||||
| `h1` | `1.5rem 0` |
|
||||
| `h2` | `4.5rem 0 1.25rem` (grande respiration avant chaque section) |
|
||||
| Paragraphe contenant seulement un bouton | `2rem 0` |
|
||||
| Photo | `2rem 0` |
|
||||
| Exergue, calendrier | `2.25rem 0` (calendrier : `2.25rem 0 1rem`) |
|
||||
| Formulaire | `2.5rem 0 1rem` |
|
||||
| Note | `margin-top: 2.5rem` |
|
||||
| Colonne `.texte` | padding `2rem` en haut, `5rem` en bas |
|
||||
|
||||
Points de rupture : `30rem` (calendrier resserré), `40rem` (formulaire plus aéré), `48rem` (l'illustration déborde de 4 rem de chaque côté de la colonne).
|
||||
|
||||
Structure de page : `body` en flex colonne avec `min-height: 100vh`, `main` en `flex: 1`, pour que le pied de page reste en bas.
|
||||
|
||||
Traits : encre, 2 à 3 px (boutons actifs 2 px, logo 2,5 px, pied de page 3 px, illustration 3 px, anses 6 px). Trait latéral de 4 px pour l'exergue (orange) et les erreurs (rouge).
|
||||
|
||||
---
|
||||
|
||||
## 5. Composants
|
||||
|
||||
La page [`charte/exemple.html`](charte/exemple.html) les montre tous.
|
||||
|
||||
### Squelette de page
|
||||
|
||||
```html
|
||||
<body>
|
||||
<a class="evitement" href="#contenu">Aller au contenu</a>
|
||||
<header class="entete">…</header>
|
||||
<main id="contenu" tabindex="-1">
|
||||
<article class="texte">
|
||||
…contenu…
|
||||
</article>
|
||||
</main>
|
||||
<footer class="pied">…</footer>
|
||||
</body>
|
||||
```
|
||||
|
||||
`.evitement` est caché au-dessus de l'écran et n'apparaît qu'au focus clavier.
|
||||
|
||||
### En-tête, logo et navigation
|
||||
|
||||
```html
|
||||
<header class="entete">
|
||||
<a class="logo" href="/" aria-label="Kluk, retour à l'accueil">kluk</a>
|
||||
<nav class="nav" aria-label="Navigation principale">
|
||||
<ul>
|
||||
<li><a href="/" aria-current="page">Accueil</a></li>
|
||||
<li><a href="/histoire/">Comment est née l'idée</a></li>
|
||||
<li><a href="/je-veux-ma-kluk/" class="bouton bouton-petit">Je veux ma Kluk</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
```
|
||||
|
||||
- Le logo est un mot-symbole en minuscules, en Atkinson Hyperlegible Next graisse 800, encadré d'un trait d'encre arrondi.
|
||||
- Les liens de navigation ne sont pas soulignés ; le soulignement vert apparaît au survol et sur la page courante (`aria-current="page"`).
|
||||
- Une seule entrée de navigation est mise en valeur en bouton. Quand c'est la page courante, le bouton s'inverse (fond porcelaine, contour encre).
|
||||
|
||||
### Liens
|
||||
|
||||
Texte en encre, soulignement vert épais (`0.12em`, décalé de `0.2em`) qui passe à l'encre au survol. Dans le pied de page, soulignement encre fin (1 px, 2 px au survol).
|
||||
|
||||
### Focus
|
||||
|
||||
Contour encre de 3 px, décalé de 3 px, coins arrondis à 4 px, sur tous les éléments (`:focus-visible`). Les champs de formulaire utilisent un contour vert.
|
||||
|
||||
### Bouton
|
||||
|
||||
```html
|
||||
<p><a class="bouton" href="/je-veux-ma-kluk/">Je veux ma Kluk</a></p>
|
||||
|
||||
<a class="bouton bouton-petit" href="…">Petit bouton</a>
|
||||
|
||||
<button class="bouton" type="submit">Envoyer</button>
|
||||
```
|
||||
|
||||
Pilule encre, texte porcelaine en 700. Un bouton seul dans son paragraphe prend une marge de 2 rem. Dans un `.formulaire`, un `<button class="bouton">` perd sa bordure native et passe à `opacity: 0.6` quand il est `disabled`.
|
||||
|
||||
### Titres, chapeau, texte
|
||||
|
||||
```html
|
||||
<h1>Titre de la page</h1>
|
||||
<p><em>Le chapeau : une phrase d'accroche en italique.</em></p>
|
||||
<p>Texte courant…</p>
|
||||
<h2>Intertitre</h2>
|
||||
```
|
||||
|
||||
Le chapeau n'a pas de classe : c'est **le paragraphe qui suit directement le `h1` et ne contient qu'un `<em>`** (sélecteur `h1 + p:has(> em:only-child)`).
|
||||
|
||||
### Exergue
|
||||
|
||||
```html
|
||||
<p class="exergue">Une phrase à mettre en valeur.</p>
|
||||
```
|
||||
|
||||
### Note
|
||||
|
||||
```html
|
||||
<p class="note">Une précision discrète, en fin de page.</p>
|
||||
```
|
||||
|
||||
### Code en ligne
|
||||
|
||||
```html
|
||||
<code>exemple</code>
|
||||
```
|
||||
|
||||
### Photo
|
||||
|
||||
```html
|
||||
<figure class="photo">
|
||||
<img src="photo.jpg" alt="Description de la photo" width="1200" height="900" loading="lazy" decoding="async">
|
||||
<figcaption>Légende facultative.</figcaption>
|
||||
</figure>
|
||||
```
|
||||
|
||||
Toujours un `alt` descriptif, et `width`/`height` pour éviter les sauts de mise en page. Format des photos du site : 1200 × 900 (4:3) ; image de partage : 1200 × 630.
|
||||
|
||||
### Emplacement de photo (en attendant l'image)
|
||||
|
||||
```html
|
||||
<figure class="photo">
|
||||
<div class="photo-attente">
|
||||
<svg viewBox="0 0 40 32" aria-hidden="true" focusable="false"><path d="M3 3 L6 25 Q6.5 29 10.5 29 L24.5 29 Q28.5 29 29 25 L32 3 Z M31.5 8 C39 8 39.5 21 30 22" /></svg>
|
||||
<p><strong>Photo à venir</strong><br>Description de la photo attendue.</p>
|
||||
</div>
|
||||
</figure>
|
||||
```
|
||||
|
||||
Cadre 3:2 en pointillés chêne foncé. Le pictogramme est aussi fourni seul : `img/photo-attente.svg`.
|
||||
|
||||
### Illustration « table et tasses »
|
||||
|
||||
Deux façons de l'utiliser :
|
||||
|
||||
1. **En image**, le plus simple (couleurs et animation intégrées au fichier) :
|
||||
|
||||
```html
|
||||
<figure class="tasses">
|
||||
<img src="charte/img/illustration-tasses.svg" alt="Trois tasses de couleur alignées sur la table, et une quatrième posée sur la Kluk, fumante.">
|
||||
</figure>
|
||||
```
|
||||
|
||||
2. **En SVG dans la page**, pour qu'elle suive les variables CSS : copier le bloc `<figure class="tasses">` de `charte/exemple.html`. La couleur de chaque tasse vient de sa classe d'humeur (`humeur-gris`, `humeur-orange`, `humeur-rouge`, `humeur-vert`) via `currentColor`. On peut donc réutiliser le symbole `#tasse` :
|
||||
|
||||
```html
|
||||
<use href="#tasse" x="34" y="114" class="humeur-orange" />
|
||||
```
|
||||
|
||||
La vapeur ondule doucement (5 s, deux volutes décalées de 2,5 s), seulement si `prefers-reduced-motion` ne le refuse pas. À partir de 48 rem, la figure déborde de 4 rem de part et d'autre de la colonne.
|
||||
|
||||
Tasses seules : `img/tasse-gris.svg`, `tasse-orange.svg`, `tasse-vert.svg`, `tasse-rouge.svg`.
|
||||
|
||||
### Calendrier d'humeurs (décoratif)
|
||||
|
||||
```html
|
||||
<div class="calendrier" aria-hidden="true">
|
||||
<span class="jour jour-v"></span>
|
||||
<span class="jour jour-o"></span>
|
||||
<span class="jour jour-g"></span>
|
||||
<span class="jour jour-r"></span>
|
||||
<!-- … une case par jour ; la grille remplit des colonnes de 7 jours (une semaine par colonne) -->
|
||||
</div>
|
||||
```
|
||||
|
||||
`jour-g` gris, `jour-o` orange, `jour-v` vert, `jour-r` rouge. Carte de fond `--surface` avec liseré intérieur `--porcelaine-fonce`.
|
||||
|
||||
### Formulaire
|
||||
|
||||
```html
|
||||
<form class="formulaire">
|
||||
<div class="champ">
|
||||
<label for="champ-email">Votre adresse mail <span class="precision">(obligatoire)</span></label>
|
||||
<input id="champ-email" name="Email" type="email" required autocomplete="email">
|
||||
</div>
|
||||
|
||||
<fieldset class="champ">
|
||||
<legend>Ce que vous aimeriez faire <span class="precision">(cochez tout ce qui vous ressemble)</span></legend>
|
||||
<ul class="choix">
|
||||
<li>
|
||||
<input id="choix-1" type="checkbox" name="choix[]" value="1">
|
||||
<label for="choix-1">Premier choix</label>
|
||||
</li>
|
||||
</ul>
|
||||
</fieldset>
|
||||
|
||||
<div class="champ">
|
||||
<label for="champ-message">Un mot, une idée, une question ? <span class="precision">(facultatif)</span></label>
|
||||
<textarea id="champ-message" name="Message" rows="5"></textarea>
|
||||
</div>
|
||||
|
||||
<!-- Champ piège anti-robots : invisible, laissé vide par les humains -->
|
||||
<div class="piege" aria-hidden="true">
|
||||
<label for="champ-site">Ne pas remplir</label>
|
||||
<input id="champ-site" name="_site" type="text" tabindex="-1" autocomplete="off">
|
||||
</div>
|
||||
|
||||
<p class="formulaire-erreur" role="alert" hidden></p>
|
||||
|
||||
<button class="bouton" type="submit">Envoyer</button>
|
||||
|
||||
<noscript><p class="formulaire-secours">Ce formulaire a besoin de JavaScript.</p></noscript>
|
||||
</form>
|
||||
```
|
||||
|
||||
- Libellés en 700 au-dessus des champs, précisions en 400 encre douce entre parenthèses.
|
||||
- Champs : fond blanc, bordure 2 px `--bordure-champ`, arrondi 0,5 rem ; au focus, contour vert 3 px et bordure encre.
|
||||
- Les styles ne visent que `input[type="email"]` et `textarea` : ajouter les autres types au sélecteur si besoin.
|
||||
- Cases à cocher agrandies (1,35 rem), teintées `--vert-lien`.
|
||||
- Message d'erreur : trait rouge à gauche sur fond rosé.
|
||||
|
||||
### Pied de page
|
||||
|
||||
```html
|
||||
<footer class="pied">
|
||||
<div class="pied-interieur">
|
||||
<p class="pied-phrase">Une petite phrase facultative.</p>
|
||||
<ul class="pied-liens">
|
||||
<li><a href="/je-veux-ma-kluk/">Je veux ma Kluk</a></li>
|
||||
<li><a href="/mentions-legales/">Mentions légales</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</footer>
|
||||
```
|
||||
|
||||
C'est « la table en bois » : fond chêne, trait d'encre de 3 px en haut, comme le plateau de l'illustration.
|
||||
|
||||
---
|
||||
|
||||
## 6. Impression
|
||||
|
||||
La navigation, le pied de page, l'illustration et le calendrier sont masqués ; le fond devient blanc.
|
||||
|
||||
## 7. Icône
|
||||
|
||||
`img/favicon.svg` : une tasse verte (`--vert`) cernée d'encre. `theme-color` : `#F5F6F0`.
|
||||
528
charte/css/kluk.css
Normal file
|
|
@ -0,0 +1,528 @@
|
|||
/*
|
||||
* Kluk — charte graphique, feuille de style réutilisable.
|
||||
* Extraite de assets/css/style.scss (site kluk.fr), en CSS pur, sans Sass.
|
||||
*
|
||||
* Palette : la porcelaine du matin, l'encre du thé, le chêne de la table,
|
||||
* et les quatre couleurs des tasses en accent.
|
||||
*
|
||||
* Sommaire
|
||||
* 1. Polices
|
||||
* 2. Variables (couleurs, typographies, mise en page)
|
||||
* 3. Base
|
||||
* 4. Liens, focus, lien d'évitement
|
||||
* 5. Boutons
|
||||
* 6. En-tête et navigation
|
||||
* 7. Colonne de texte et titres
|
||||
* 8. Illustration « tasses »
|
||||
* 9. Calendrier d'humeurs
|
||||
* 10. Photos
|
||||
* 11. Formulaire
|
||||
* 12. Pied de page
|
||||
* 13. Impression
|
||||
*/
|
||||
|
||||
/* ---------- 1. Polices ---------- */
|
||||
|
||||
@font-face {
|
||||
font-family: "Young Serif";
|
||||
src: url("../fonts/young-serif-400.woff2") format("woff2");
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
/* Fichier variable : couvre toutes les graisses de 200 à 800 */
|
||||
@font-face {
|
||||
font-family: "Atkinson Hyperlegible Next";
|
||||
src: url("../fonts/atkinson-hyperlegible-next-400.woff2") format("woff2");
|
||||
font-weight: 200 800;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Atkinson Hyperlegible Next";
|
||||
src: url("../fonts/atkinson-hyperlegible-next-400-italic.woff2") format("woff2");
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
/* ---------- 2. Variables ---------- */
|
||||
|
||||
:root {
|
||||
/* Fonds et texte */
|
||||
--porcelaine: #F5F6F0;
|
||||
--porcelaine-fonce: #E9ECE2;
|
||||
--encre: #2E2A26;
|
||||
--encre-douce: #5A534C;
|
||||
--chene: #D9BC94;
|
||||
--chene-fonce: #B48D5F;
|
||||
|
||||
/* Humeurs (les quatre tasses) */
|
||||
--gris: #8D97A8;
|
||||
--orange: #EDA33D;
|
||||
--vert: #5F9B59;
|
||||
--rouge: #D8573F;
|
||||
--vert-lien: #3F7A3B;
|
||||
|
||||
/* Teintes utilitaires (écrites en dur dans le site d'origine) */
|
||||
--encre-survol: #45403A;
|
||||
--surface: #FBFCF8;
|
||||
--bordure-champ: #8A8279;
|
||||
--erreur-fond: #FBE9E5;
|
||||
--blanc: #fff;
|
||||
|
||||
/* Typographies */
|
||||
--serif: "Young Serif", Georgia, serif;
|
||||
--sans: "Atkinson Hyperlegible Next", "Atkinson Hyperlegible", system-ui, sans-serif;
|
||||
|
||||
/* Mise en page */
|
||||
--colonne: 36rem;
|
||||
--gouttiere: 1.25rem;
|
||||
--largeur-entete: 64rem;
|
||||
|
||||
/* Arrondis */
|
||||
--arrondi-petit: 0.5rem;
|
||||
--arrondi: 0.75rem;
|
||||
--arrondi-pilule: 999px;
|
||||
}
|
||||
|
||||
/* ---------- 3. Base ---------- */
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after { box-sizing: border-box; }
|
||||
|
||||
html {
|
||||
-webkit-text-size-adjust: 100%;
|
||||
text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: var(--porcelaine);
|
||||
color: var(--encre);
|
||||
font-family: var(--sans);
|
||||
font-size: 1.1875rem;
|
||||
line-height: 1.65;
|
||||
font-kerning: normal;
|
||||
hyphens: manual;
|
||||
}
|
||||
|
||||
main { flex: 1; outline: none; }
|
||||
|
||||
img, svg { display: block; max-width: 100%; }
|
||||
|
||||
/* ---------- 4. Liens, focus, lien d'évitement ---------- */
|
||||
|
||||
a {
|
||||
color: var(--encre);
|
||||
text-decoration-line: underline;
|
||||
text-decoration-color: var(--vert);
|
||||
text-decoration-thickness: 0.12em;
|
||||
text-underline-offset: 0.2em;
|
||||
}
|
||||
a:hover { text-decoration-color: var(--encre); }
|
||||
|
||||
:focus-visible {
|
||||
outline: 3px solid var(--encre);
|
||||
outline-offset: 3px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.evitement {
|
||||
position: absolute;
|
||||
left: var(--gouttiere);
|
||||
top: -4rem;
|
||||
padding: 0.5rem 1rem;
|
||||
background: var(--encre);
|
||||
color: var(--porcelaine);
|
||||
z-index: 10;
|
||||
}
|
||||
.evitement:focus { top: 0.75rem; }
|
||||
|
||||
/* ---------- 5. Boutons ---------- */
|
||||
|
||||
.bouton {
|
||||
display: inline-block;
|
||||
padding: 0.8rem 1.6rem;
|
||||
border-radius: var(--arrondi-pilule);
|
||||
background: var(--encre);
|
||||
color: var(--porcelaine);
|
||||
font-weight: 700;
|
||||
line-height: 1.3;
|
||||
text-decoration: none;
|
||||
transition: background-color 0.15s ease;
|
||||
}
|
||||
.bouton:hover { background: var(--encre-survol); color: var(--porcelaine); }
|
||||
.bouton:focus-visible { outline-offset: 4px; border-radius: var(--arrondi-pilule); }
|
||||
|
||||
.bouton-petit {
|
||||
padding: 0.45rem 1rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
/* Un bouton seul dans son paragraphe respire davantage */
|
||||
p:has(> .bouton:only-child) { margin: 2rem 0; }
|
||||
|
||||
/* ---------- 6. En-tête et navigation ---------- */
|
||||
|
||||
.entete {
|
||||
max-width: var(--largeur-entete);
|
||||
margin: 0 auto;
|
||||
padding: 1.25rem var(--gouttiere);
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 1rem 2rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: inline-block;
|
||||
padding: 0.05rem 0.55rem 0.15rem;
|
||||
border: 2.5px solid var(--encre);
|
||||
border-radius: var(--arrondi-petit);
|
||||
font-family: var(--sans);
|
||||
font-weight: 800;
|
||||
font-size: 1.35rem;
|
||||
line-height: 1.2;
|
||||
letter-spacing: 0.01em;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.nav ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 0.35rem 1.35rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
.nav a:not(.bouton) {
|
||||
text-decoration-color: transparent;
|
||||
}
|
||||
.nav a:not(.bouton):hover,
|
||||
.nav a[aria-current="page"]:not(.bouton) {
|
||||
text-decoration-color: var(--vert);
|
||||
}
|
||||
.nav a.bouton[aria-current="page"] {
|
||||
background: var(--porcelaine);
|
||||
color: var(--encre);
|
||||
box-shadow: inset 0 0 0 2px var(--encre);
|
||||
}
|
||||
|
||||
/* ---------- 7. Colonne de texte et titres ---------- */
|
||||
|
||||
.texte {
|
||||
max-width: calc(var(--colonne) + 2 * var(--gouttiere));
|
||||
margin: 0 auto;
|
||||
padding: 2rem var(--gouttiere) 5rem;
|
||||
}
|
||||
|
||||
h1, h2, h3 {
|
||||
font-family: var(--serif);
|
||||
font-weight: 400;
|
||||
line-height: 1.15;
|
||||
letter-spacing: -0.005em;
|
||||
text-wrap: balance;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: clamp(2.35rem, 1.6rem + 3.6vw, 3.75rem);
|
||||
margin: 1.5rem 0 1.5rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: clamp(1.6rem, 1.35rem + 1vw, 2rem);
|
||||
margin: 4.5rem 0 1.25rem;
|
||||
}
|
||||
|
||||
p { margin: 0 0 1.15rem; }
|
||||
|
||||
/* Le chapeau : paragraphe entièrement en italique juste sous le titre */
|
||||
h1 + p:has(> em:only-child) {
|
||||
font-size: 1.3rem;
|
||||
line-height: 1.55;
|
||||
color: var(--encre-douce);
|
||||
}
|
||||
|
||||
.note {
|
||||
margin-top: 2.5rem;
|
||||
color: var(--encre-douce);
|
||||
font-size: 1.0625rem;
|
||||
}
|
||||
|
||||
.exergue {
|
||||
margin: 2.25rem 0;
|
||||
padding-left: 1.25rem;
|
||||
border-left: 4px solid var(--orange);
|
||||
font-family: var(--serif);
|
||||
font-size: 1.45rem;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 0.9em;
|
||||
background: var(--porcelaine-fonce);
|
||||
padding: 0.05em 0.3em;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
/* ---------- 8. Illustration « tasses » ---------- */
|
||||
|
||||
.tasses {
|
||||
margin: 1.5rem 0 0;
|
||||
}
|
||||
/* L'illustration déborde légèrement de la colonne sur grand écran */
|
||||
@media (min-width: 48rem) {
|
||||
.tasses { margin-inline: -4rem; }
|
||||
}
|
||||
.tasses svg { width: 100%; height: auto; overflow: visible; }
|
||||
|
||||
.table { fill: var(--chene); }
|
||||
.table-fil,
|
||||
.tasse-corps,
|
||||
.tasse-anse,
|
||||
.kluk-socle,
|
||||
.vapeur path {
|
||||
stroke: var(--encre);
|
||||
stroke-width: 3;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
}
|
||||
.tasse-anse { fill: none; stroke-width: 6; }
|
||||
.tasse-corps { fill: currentColor; }
|
||||
.tasse-reflet { fill: none; stroke: var(--blanc); stroke-opacity: 0.45; stroke-width: 4; stroke-linecap: round; }
|
||||
.kluk-socle { fill: var(--chene-fonce); }
|
||||
.kluk-voyant { fill: var(--porcelaine); }
|
||||
.vapeur path { fill: none; stroke-width: 2.5; stroke: var(--encre-douce); }
|
||||
|
||||
.humeur-gris { color: var(--gris); }
|
||||
.humeur-orange { color: var(--orange); }
|
||||
.humeur-rouge { color: var(--rouge); }
|
||||
.humeur-vert { color: var(--vert); }
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.vapeur path {
|
||||
animation: vapeur 5s ease-in-out infinite;
|
||||
}
|
||||
.vapeur path + path { animation-delay: 2.5s; }
|
||||
}
|
||||
@keyframes vapeur {
|
||||
0%, 100% { opacity: 0.25; transform: translateY(6px); }
|
||||
50% { opacity: 0.9; transform: translateY(-6px); }
|
||||
}
|
||||
|
||||
/* ---------- 9. Calendrier d'humeurs (décoratif) ---------- */
|
||||
|
||||
.calendrier {
|
||||
display: grid;
|
||||
grid-template-rows: repeat(7, auto);
|
||||
grid-auto-flow: column;
|
||||
grid-auto-columns: 1fr;
|
||||
gap: 4px;
|
||||
margin: 2.25rem 0 1rem;
|
||||
padding: 1.25rem;
|
||||
background: var(--surface);
|
||||
border-radius: var(--arrondi);
|
||||
box-shadow: inset 0 0 0 1px var(--porcelaine-fonce);
|
||||
}
|
||||
.jour {
|
||||
aspect-ratio: 1;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.jour-g { background: var(--gris); }
|
||||
.jour-o { background: var(--orange); }
|
||||
.jour-v { background: var(--vert); }
|
||||
.jour-r { background: var(--rouge); }
|
||||
|
||||
@media (max-width: 30rem) {
|
||||
.calendrier { gap: 3px; padding: 0.9rem; }
|
||||
}
|
||||
|
||||
/* ---------- 10. Photos ---------- */
|
||||
|
||||
.photo {
|
||||
margin: 2rem 0;
|
||||
}
|
||||
.photo img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
border-radius: var(--arrondi);
|
||||
}
|
||||
.photo figcaption {
|
||||
margin-top: 0.6rem;
|
||||
font-size: 0.95rem;
|
||||
color: var(--encre-douce);
|
||||
}
|
||||
|
||||
.photo-attente {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1.25rem;
|
||||
aspect-ratio: 3 / 2;
|
||||
padding: 1.5rem;
|
||||
border: 2px dashed var(--chene-fonce);
|
||||
border-radius: var(--arrondi);
|
||||
background: var(--porcelaine-fonce);
|
||||
color: var(--encre-douce);
|
||||
font-size: 1rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.photo-attente svg {
|
||||
flex: none;
|
||||
width: 2.75rem;
|
||||
fill: none;
|
||||
stroke: var(--chene-fonce);
|
||||
stroke-width: 2.5;
|
||||
stroke-linejoin: round;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
.photo-attente p { margin: 0; }
|
||||
.photo-attente strong { color: var(--encre); }
|
||||
|
||||
/* ---------- 11. Formulaire ---------- */
|
||||
|
||||
.formulaire {
|
||||
margin: 2.5rem 0 1rem;
|
||||
padding: 1.75rem 1.25rem;
|
||||
background: var(--surface);
|
||||
border-radius: var(--arrondi);
|
||||
box-shadow: inset 0 0 0 1px var(--porcelaine-fonce);
|
||||
}
|
||||
@media (min-width: 40rem) {
|
||||
.formulaire { padding: 2.25rem 2.5rem; }
|
||||
}
|
||||
|
||||
.champ {
|
||||
margin: 0 0 1.75rem;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.champ > label,
|
||||
.champ > legend {
|
||||
display: block;
|
||||
padding: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.precision {
|
||||
font-weight: 400;
|
||||
color: var(--encre-douce);
|
||||
}
|
||||
|
||||
.formulaire input[type="email"],
|
||||
.formulaire textarea {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0.7rem 0.85rem;
|
||||
border: 2px solid var(--bordure-champ);
|
||||
border-radius: var(--arrondi-petit);
|
||||
background: var(--blanc);
|
||||
color: var(--encre);
|
||||
font: inherit;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.formulaire textarea { resize: vertical; min-height: 8rem; }
|
||||
|
||||
.formulaire input[type="email"]:focus-visible,
|
||||
.formulaire textarea:focus-visible {
|
||||
outline: 3px solid var(--vert);
|
||||
outline-offset: 1px;
|
||||
border-color: var(--encre);
|
||||
}
|
||||
|
||||
.choix {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.choix li {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 0.75rem;
|
||||
padding: 0.35rem 0;
|
||||
}
|
||||
.choix input {
|
||||
flex: none;
|
||||
width: 1.35rem;
|
||||
height: 1.35rem;
|
||||
margin: 0.2rem 0 0;
|
||||
accent-color: var(--vert-lien);
|
||||
cursor: pointer;
|
||||
}
|
||||
.choix label { cursor: pointer; }
|
||||
|
||||
/* Champ piège anti-robots, invisible */
|
||||
.piege {
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.formulaire-erreur {
|
||||
padding: 0.75rem 1rem;
|
||||
border-left: 4px solid var(--rouge);
|
||||
background: var(--erreur-fond);
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.formulaire .bouton {
|
||||
border: 0;
|
||||
font: inherit;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
}
|
||||
.formulaire .bouton:disabled { opacity: 0.6; cursor: progress; }
|
||||
|
||||
.formulaire-secours {
|
||||
margin: 1rem 0 0;
|
||||
font-size: 1rem;
|
||||
color: var(--encre-douce);
|
||||
}
|
||||
|
||||
/* ---------- 12. Pied de page : la table en bois ---------- */
|
||||
|
||||
.pied {
|
||||
background: var(--chene);
|
||||
border-top: 3px solid var(--encre);
|
||||
font-size: 1rem;
|
||||
}
|
||||
.pied-interieur {
|
||||
max-width: calc(var(--colonne) + 2 * var(--gouttiere));
|
||||
margin: 0 auto;
|
||||
padding: 2rem var(--gouttiere) 2.5rem;
|
||||
}
|
||||
.pied-phrase {
|
||||
font-family: var(--serif);
|
||||
font-size: 1.15rem;
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
.pied-liens {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem 2rem;
|
||||
}
|
||||
.pied a { text-decoration-color: var(--encre); text-decoration-thickness: 1px; }
|
||||
.pied a:hover { text-decoration-thickness: 2px; }
|
||||
|
||||
/* ---------- 13. Impression ---------- */
|
||||
|
||||
@media print {
|
||||
.entete .nav, .pied, .tasses, .calendrier { display: none; }
|
||||
body { background: var(--blanc); }
|
||||
}
|
||||
122
charte/exemple.html
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
<!doctype html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#F5F6F0">
|
||||
<title>Charte Kluk — exemple</title>
|
||||
<link rel="preload" href="fonts/young-serif-400.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="fonts/atkinson-hyperlegible-next-400.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="stylesheet" href="css/kluk.css">
|
||||
<link rel="icon" href="img/favicon.svg" type="image/svg+xml">
|
||||
</head>
|
||||
<body>
|
||||
<a class="evitement" href="#contenu">Aller au contenu</a>
|
||||
|
||||
<header class="entete">
|
||||
<a class="logo" href="#" aria-label="Kluk, retour à l'accueil">kluk</a>
|
||||
<nav class="nav" aria-label="Navigation principale">
|
||||
<ul>
|
||||
<li><a href="#" aria-current="page">Accueil</a></li>
|
||||
<li><a href="#">Une autre page</a></li>
|
||||
<li><a href="#" class="bouton bouton-petit">Appel à l’action</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main id="contenu" tabindex="-1">
|
||||
<article class="texte">
|
||||
<h1>Titre de page en Young Serif</h1>
|
||||
<p><em>Le chapeau : un paragraphe entièrement en italique, juste sous le titre.</em></p>
|
||||
|
||||
<p>Texte courant en Atkinson Hyperlegible Next, avec <a href="#">un lien souligné de vert</a>, du <strong>gras</strong>, de l’<em>italique</em> et du <code>code</code>.</p>
|
||||
|
||||
<p><a class="bouton" href="#">Bouton principal</a></p>
|
||||
|
||||
<figure class="tasses">
|
||||
<svg viewBox="0 0 580 214" role="img" aria-labelledby="tasses-titre">
|
||||
<title id="tasses-titre">Illustration : trois tasses de couleur alignées sur la table, et une quatrième posée sur la Kluk, fumante.</title>
|
||||
<defs>
|
||||
<g id="tasse">
|
||||
<path class="tasse-anse" d="M63 22 C86 20 88 60 60 62" />
|
||||
<path class="tasse-corps" d="M3 6 L10 78 Q11 86 20 86 L48 86 Q57 86 58 78 L65 6 Z" />
|
||||
<path class="tasse-reflet" d="M13 18 L17 62" />
|
||||
</g>
|
||||
</defs>
|
||||
<rect class="table" x="0" y="200" width="580" height="14" rx="3" />
|
||||
<path class="table-fil" d="M0 200 H580" />
|
||||
<use href="#tasse" x="34" y="114" class="humeur-gris" />
|
||||
<use href="#tasse" x="132" y="114" class="humeur-orange" />
|
||||
<use href="#tasse" x="230" y="114" class="humeur-rouge" />
|
||||
<g class="kluk-illu" transform="translate(410 98)">
|
||||
<g class="vapeur" aria-hidden="true">
|
||||
<path d="M22 -6 c-9 -11 9 -20 0 -31 c-9 -11 9 -20 0 -31" />
|
||||
<path d="M44 -10 c-9 -11 9 -20 0 -31 c-9 -11 9 -20 0 -31" />
|
||||
</g>
|
||||
<use href="#tasse" x="0" y="0" class="humeur-vert" />
|
||||
<rect class="kluk-socle" x="-22" y="86" width="112" height="16" rx="8" />
|
||||
<circle class="kluk-voyant" cx="34" cy="94" r="2.6" />
|
||||
</g>
|
||||
</svg>
|
||||
</figure>
|
||||
|
||||
<h2>Intertitre de section</h2>
|
||||
<p>Les intertitres ménagent un grand espace au-dessus d’eux (4,5 rem) pour découper la page en respirations.</p>
|
||||
|
||||
<p class="exergue">Une phrase mise en exergue, en serif, soulignée d’un trait orange.</p>
|
||||
|
||||
<figure class="photo">
|
||||
<div class="photo-attente">
|
||||
<svg viewBox="0 0 40 32" aria-hidden="true" focusable="false"><path d="M3 3 L6 25 Q6.5 29 10.5 29 L24.5 29 Q28.5 29 29 25 L32 3 Z M31.5 8 C39 8 39.5 21 30 22" /></svg>
|
||||
<p><strong>Photo à venir</strong><br>Description de la photo attendue.</p>
|
||||
</div>
|
||||
<figcaption>Légende facultative sous la photo.</figcaption>
|
||||
</figure>
|
||||
|
||||
<div class="calendrier" aria-hidden="true" id="calendrier"></div>
|
||||
|
||||
<form class="formulaire" onsubmit="return false">
|
||||
<div class="champ">
|
||||
<label for="champ-email">Votre adresse mail <span class="precision">(obligatoire)</span></label>
|
||||
<input id="champ-email" name="Email" type="email" required autocomplete="email">
|
||||
</div>
|
||||
<fieldset class="champ">
|
||||
<legend>Ce que vous aimeriez faire <span class="precision">(cochez tout ce qui vous ressemble)</span></legend>
|
||||
<ul class="choix">
|
||||
<li><input id="choix-1" type="checkbox" name="choix[]" value="1" checked><label for="choix-1">Premier choix</label></li>
|
||||
<li><input id="choix-2" type="checkbox" name="choix[]" value="2"><label for="choix-2">Deuxième choix</label></li>
|
||||
</ul>
|
||||
</fieldset>
|
||||
<div class="champ">
|
||||
<label for="champ-message">Un mot, une idée, une question ? <span class="precision">(facultatif)</span></label>
|
||||
<textarea id="champ-message" name="Message" rows="5"></textarea>
|
||||
</div>
|
||||
<p class="formulaire-erreur" role="alert">Message d’erreur (masqué par défaut avec l’attribut <code>hidden</code>).</p>
|
||||
<button class="bouton" type="submit">Envoyer</button>
|
||||
<p class="formulaire-secours">Texte de secours, affiché dans un <code><noscript></code>.</p>
|
||||
</form>
|
||||
|
||||
<p class="note">Une note discrète en fin de page.</p>
|
||||
</article>
|
||||
</main>
|
||||
|
||||
<footer class="pied">
|
||||
<div class="pied-interieur">
|
||||
<p class="pied-phrase">Une petite phrase en serif, facultative.</p>
|
||||
<ul class="pied-liens">
|
||||
<li><a href="#">Premier lien</a></li>
|
||||
<li><a href="#">Mentions légales</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
// Remplit le calendrier de démonstration : chaque groupe de 7 lettres est une semaine.
|
||||
// g = gris, o = orange, v = vert, r = rouge.
|
||||
var semaines = "vvovvvg vvvvovv ovvrvvv vvgvvvo ovvvvvv rrovrrr rorrvvo gvggggg gggvggg gogggvg ggoggvg vvgvvvv ovvvovv vrvvvov vvvvovv ovvgvvv vvovvrv vvvovvv vgvvvvo vvvvovv";
|
||||
document.getElementById("calendrier").innerHTML = semaines.replace(/ /g, "").split("").map(function (j) {
|
||||
return '<span class="jour jour-' + j + '"></span>';
|
||||
}).join("");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
97
charte/fonts/OFL.txt
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
Young Serif
|
||||
Copyright 2023 The Young Serif Project Authors (https://github.com/noirblancrouge/YoungSerif)
|
||||
|
||||
Atkinson Hyperlegible Next
|
||||
Copyright 2020-2024 The Atkinson Hyperlegible Next Project Authors (https://github.com/googlefonts/atkinson-hyperlegible-next)
|
||||
|
||||
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.
|
||||
BIN
charte/fonts/atkinson-hyperlegible-next-400-italic.woff2
Normal file
BIN
charte/fonts/atkinson-hyperlegible-next-400.woff2
Normal file
BIN
charte/fonts/young-serif-400.woff2
Normal file
1
charte/img/favicon.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M4 4 L7 24 Q7.5 28 11.5 28 L19.5 28 Q23.5 28 24 24 L27 4 Z" fill="#5F9B59" stroke="#2E2A26" stroke-width="2.5" stroke-linejoin="round"/><path d="M26.5 9 C32 9 32 20 25 21" fill="none" stroke="#2E2A26" stroke-width="3" stroke-linecap="round"/></svg>
|
||||
|
After Width: | Height: | Size: 318 B |
48
charte/img/illustration-tasses.svg
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 580 214" role="img" aria-labelledby="t">
|
||||
<title id="t">Trois tasses de couleur alignées sur la table, et une quatrième posée sur la Kluk, fumante.</title>
|
||||
<style>
|
||||
.table { fill: #D9BC94; }
|
||||
.table-fil, .tasse-corps, .tasse-anse, .kluk-socle, .vapeur path {
|
||||
stroke: #2E2A26; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round;
|
||||
}
|
||||
.tasse-anse { fill: none; stroke-width: 6; }
|
||||
.tasse-corps { fill: currentColor; }
|
||||
.tasse-reflet { fill: none; stroke: #fff; stroke-opacity: 0.45; stroke-width: 4; stroke-linecap: round; }
|
||||
.kluk-socle { fill: #B48D5F; }
|
||||
.kluk-voyant { fill: #F5F6F0; }
|
||||
.vapeur path { fill: none; stroke-width: 2.5; stroke: #5A534C; }
|
||||
.humeur-gris { color: #8D97A8; }
|
||||
.humeur-orange { color: #EDA33D; }
|
||||
.humeur-rouge { color: #D8573F; }
|
||||
.humeur-vert { color: #5F9B59; }
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.vapeur path { animation: vapeur 5s ease-in-out infinite; }
|
||||
.vapeur path + path { animation-delay: 2.5s; }
|
||||
}
|
||||
@keyframes vapeur {
|
||||
0%, 100% { opacity: 0.25; transform: translateY(6px); }
|
||||
50% { opacity: 0.9; transform: translateY(-6px); }
|
||||
}
|
||||
</style>
|
||||
<defs>
|
||||
<g id="tasse">
|
||||
<path class="tasse-anse" d="M63 22 C86 20 88 60 60 62" />
|
||||
<path class="tasse-corps" d="M3 6 L10 78 Q11 86 20 86 L48 86 Q57 86 58 78 L65 6 Z" />
|
||||
<path class="tasse-reflet" d="M13 18 L17 62" />
|
||||
</g>
|
||||
</defs>
|
||||
<rect class="table" x="0" y="200" width="580" height="14" rx="3" />
|
||||
<path class="table-fil" d="M0 200 H580" />
|
||||
<use href="#tasse" x="34" y="114" class="humeur-gris" />
|
||||
<use href="#tasse" x="132" y="114" class="humeur-orange" />
|
||||
<use href="#tasse" x="230" y="114" class="humeur-rouge" />
|
||||
<g transform="translate(410 98)">
|
||||
<g class="vapeur">
|
||||
<path d="M22 -6 c-9 -11 9 -20 0 -31 c-9 -11 9 -20 0 -31" />
|
||||
<path d="M44 -10 c-9 -11 9 -20 0 -31 c-9 -11 9 -20 0 -31" />
|
||||
</g>
|
||||
<use href="#tasse" x="0" y="0" class="humeur-vert" />
|
||||
<rect class="kluk-socle" x="-22" y="86" width="112" height="16" rx="8" />
|
||||
<circle class="kluk-voyant" cx="34" cy="94" r="2.6" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
1
charte/img/photo-attente.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-2 -2 44 36"><path d="M3 3 L6 25 Q6.5 29 10.5 29 L24.5 29 Q28.5 29 29 25 L32 3 Z M31.5 8 C39 8 39.5 21 30 22" fill="none" stroke="#B48D5F" stroke-width="2.5" stroke-linejoin="round" stroke-linecap="round"/></svg>
|
||||
|
After Width: | Height: | Size: 262 B |
1
charte/img/tasse-gris.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-3 -3 95 95"><path d="M63 22 C86 20 88 60 60 62" fill="none" stroke="#2E2A26" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 6 L10 78 Q11 86 20 86 L48 86 Q57 86 58 78 L65 6 Z" fill="#8D97A8" stroke="#2E2A26" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path d="M13 18 L17 62" fill="none" stroke="#fff" stroke-opacity="0.45" stroke-width="4" stroke-linecap="round"/></svg>
|
||||
|
After Width: | Height: | Size: 472 B |
1
charte/img/tasse-orange.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-3 -3 95 95"><path d="M63 22 C86 20 88 60 60 62" fill="none" stroke="#2E2A26" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 6 L10 78 Q11 86 20 86 L48 86 Q57 86 58 78 L65 6 Z" fill="#EDA33D" stroke="#2E2A26" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path d="M13 18 L17 62" fill="none" stroke="#fff" stroke-opacity="0.45" stroke-width="4" stroke-linecap="round"/></svg>
|
||||
|
After Width: | Height: | Size: 472 B |
1
charte/img/tasse-rouge.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-3 -3 95 95"><path d="M63 22 C86 20 88 60 60 62" fill="none" stroke="#2E2A26" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 6 L10 78 Q11 86 20 86 L48 86 Q57 86 58 78 L65 6 Z" fill="#D8573F" stroke="#2E2A26" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path d="M13 18 L17 62" fill="none" stroke="#fff" stroke-opacity="0.45" stroke-width="4" stroke-linecap="round"/></svg>
|
||||
|
After Width: | Height: | Size: 472 B |
1
charte/img/tasse-vert.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-3 -3 95 95"><path d="M63 22 C86 20 88 60 60 62" fill="none" stroke="#2E2A26" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 6 L10 78 Q11 86 20 86 L48 86 Q57 86 58 78 L65 6 Z" fill="#5F9B59" stroke="#2E2A26" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path d="M13 18 L17 62" fill="none" stroke="#fff" stroke-opacity="0.45" stroke-width="4" stroke-linecap="round"/></svg>
|
||||
|
After Width: | Height: | Size: 472 B |
|
|
@ -13,6 +13,7 @@ Rails.application.routes.draw do
|
|||
# get "service-worker" => "rails/pwa#service_worker", as: :pwa_service_worker
|
||||
|
||||
mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.development?
|
||||
get "/charte", to: "charte#show" if Rails.env.development?
|
||||
|
||||
# Defines the root path route ("/")
|
||||
root "home#index"
|
||||
|
|
|
|||