浏览代码

layout, mdi, static menu & page, font, ...

bach 1 年之前
父节点
当前提交
a8883be9b7
共有 32 个文件被更改,包括 1687 次插入47 次删除
  1. 256 0
      package-lock.json
  2. 4 0
      package.json
  3. 6 7
      src/App.vue
  4. 6 0
      src/api/gql/statics.fragment.gql
  5. 0 3
      src/assets/base.css
  6. 16 0
      src/assets/base.scss
  7. 5 0
      src/assets/fonts/snap_it/generator_config.txt
  8. 102 0
      src/assets/fonts/snap_it/snap-itmono-1.6-regular-demo.html
  9. 二进制
      src/assets/fonts/snap_it/snap-itmono-1.6-regular-webfont.woff
  10. 二进制
      src/assets/fonts/snap_it/snap-itmono-1.6-regular-webfont.woff2
  11. 11 0
      src/assets/fonts/snap_it/snap_it.css
  12. 370 0
      src/assets/fonts/snap_it/specimen_files/grid_12-825-55-15.css
  13. 502 0
      src/assets/fonts/snap_it/specimen_files/specimen_stylesheet.css
  14. 27 0
      src/assets/fonts/snap_it_mono/README.md
  15. 二进制
      src/assets/fonts/snap_it_mono/font-files/Snap-itmono-1.6-Regular.otf
  16. 二进制
      src/assets/fonts/snap_it_mono/font-files/Snap-itmono-1.6-Regular.woff
  17. 二进制
      src/assets/fonts/snap_it_mono/font-files/Snap-itmono-1.6-Regular.woff2
  18. 96 0
      src/assets/fonts/snap_it_mono/license.md
  19. 28 0
      src/assets/layout.scss
  20. 0 10
      src/assets/main.css
  21. 23 0
      src/assets/main.scss
  22. 46 0
      src/components/Header.vue
  23. 1 1
      src/components/MapConcernements.vue
  24. 56 0
      src/components/block/StaticMenu.vue
  25. 1 0
      src/components/block/UserBlock.vue
  26. 24 16
      src/components/block/UserTools.vue
  27. 3 1
      src/main.js
  28. 10 8
      src/router/index.js
  29. 52 0
      src/stores/statics.js
  30. 1 1
      src/views/Home.vue
  31. 40 0
      src/views/Static.vue
  32. 1 0
      vite.config.js

+ 256 - 0
package-lock.json

@@ -8,6 +8,9 @@
       "name": "ouatterrir",
       "version": "0.0.0",
       "dependencies": {
+        "@csstools/normalize.css": "^12.0.0",
+        "@material-design-icons/svg": "^0.14.2",
+        "@mdi/font": "^7.1.96",
         "pinia": "^2.0.21",
         "vue": "^3.2.38",
         "vue-router": "^4.1.5"
@@ -24,6 +27,7 @@
         "graphql-tag": "^2.12.6",
         "prettier": "^2.7.1",
         "querystring-es3": "^0.2.1",
+        "sass": "^1.57.1",
         "vite": "^3.0.9"
       }
     },
@@ -37,6 +41,11 @@
         "node": ">=6.0.0"
       }
     },
+    "node_modules/@csstools/normalize.css": {
+      "version": "12.0.0",
+      "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.0.0.tgz",
+      "integrity": "sha512-M0qqxAcwCsIVfpFQSlGN5XjXWu8l5JDZN+fPt1LeW5SZexQTgnaEvgXAY+CeygRw0EeppWHi12JxESWiWrB0Sg=="
+    },
     "node_modules/@eslint/eslintrc": {
       "version": "1.3.1",
       "dev": true,
@@ -98,6 +107,16 @@
       "dev": true,
       "license": "BSD-3-Clause"
     },
+    "node_modules/@material-design-icons/svg": {
+      "version": "0.14.2",
+      "resolved": "https://registry.npmjs.org/@material-design-icons/svg/-/svg-0.14.2.tgz",
+      "integrity": "sha512-QjAzZmqV+7VI8+0eONVYBvSSlytpR+QQ/elT+YADoYq7R5Tc7kU1PaR0xOrEhwMR9MYK2yhUXqXymP8QY01ehg=="
+    },
+    "node_modules/@mdi/font": {
+      "version": "7.1.96",
+      "resolved": "https://registry.npmjs.org/@mdi/font/-/font-7.1.96.tgz",
+      "integrity": "sha512-Imag6npmfkBDi2Ze2jiZVAPTDIKLxhz2Sx82xJ2zctyAU5LYJejLI5ChnDwiD9bMkQfVuzEsI98Q8toHyC+HCg=="
+    },
     "node_modules/@nodelib/fs.scandir": {
       "version": "2.1.5",
       "dev": true,
@@ -347,6 +366,19 @@
         "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
+    "node_modules/anymatch": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+      "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+      "dev": true,
+      "dependencies": {
+        "normalize-path": "^3.0.0",
+        "picomatch": "^2.0.4"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
     "node_modules/argparse": {
       "version": "2.0.1",
       "dev": true,
@@ -380,6 +412,15 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/binary-extensions": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+      "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/boolbase": {
       "version": "1.0.0",
       "dev": true,
@@ -428,6 +469,45 @@
         "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
+    "node_modules/chokidar": {
+      "version": "3.5.3",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+      "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://paulmillr.com/funding/"
+        }
+      ],
+      "dependencies": {
+        "anymatch": "~3.1.2",
+        "braces": "~3.0.2",
+        "glob-parent": "~5.1.2",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.6.0"
+      },
+      "engines": {
+        "node": ">= 8.10.0"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/chokidar/node_modules/glob-parent": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+      "dev": true,
+      "dependencies": {
+        "is-glob": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/color-convert": {
       "version": "2.0.1",
       "dev": true,
@@ -954,6 +1034,20 @@
       "dev": true,
       "license": "ISC"
     },
+    "node_modules/fsevents": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+      "dev": true,
+      "hasInstallScript": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
     "node_modules/function-bind": {
       "version": "1.1.1",
       "dev": true,
@@ -1081,6 +1175,12 @@
         "node": ">= 4"
       }
     },
+    "node_modules/immutable": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.2.2.tgz",
+      "integrity": "sha512-fTMKDwtbvO5tldky9QZ2fMX7slR0mYpY5nbnFWYp0fOzDhHqhgIw9KoYgxLWsoNTS9ZHGauHj18DTyEw6BK3Og==",
+      "dev": true
+    },
     "node_modules/import-fresh": {
       "version": "3.3.0",
       "dev": true,
@@ -1118,6 +1218,18 @@
       "dev": true,
       "license": "ISC"
     },
+    "node_modules/is-binary-path": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+      "dev": true,
+      "dependencies": {
+        "binary-extensions": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/is-core-module": {
       "version": "2.10.0",
       "dev": true,
@@ -1306,6 +1418,15 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/normalize-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/nth-check": {
       "version": "2.1.1",
       "dev": true,
@@ -1586,6 +1707,18 @@
       ],
       "license": "MIT"
     },
+    "node_modules/readdirp": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+      "dev": true,
+      "dependencies": {
+        "picomatch": "^2.2.1"
+      },
+      "engines": {
+        "node": ">=8.10.0"
+      }
+    },
     "node_modules/regexpp": {
       "version": "3.2.0",
       "dev": true,
@@ -1680,6 +1813,23 @@
         "queue-microtask": "^1.2.2"
       }
     },
+    "node_modules/sass": {
+      "version": "1.57.1",
+      "resolved": "https://registry.npmjs.org/sass/-/sass-1.57.1.tgz",
+      "integrity": "sha512-O2+LwLS79op7GI0xZ8fqzF7X2m/m8WFfI02dHOdsK5R2ECeS5F62zrwg/relM1rjSLy7Vd/DiMNIvPrQGsA0jw==",
+      "dev": true,
+      "dependencies": {
+        "chokidar": ">=3.0.0 <4.0.0",
+        "immutable": "^4.0.0",
+        "source-map-js": ">=0.6.2 <2.0.0"
+      },
+      "bin": {
+        "sass": "sass.js"
+      },
+      "engines": {
+        "node": ">=12.0.0"
+      }
+    },
     "node_modules/semver": {
       "version": "7.3.7",
       "dev": true,
@@ -1982,6 +2132,11 @@
     "@babel/parser": {
       "version": "7.18.13"
     },
+    "@csstools/normalize.css": {
+      "version": "12.0.0",
+      "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.0.0.tgz",
+      "integrity": "sha512-M0qqxAcwCsIVfpFQSlGN5XjXWu8l5JDZN+fPt1LeW5SZexQTgnaEvgXAY+CeygRw0EeppWHi12JxESWiWrB0Sg=="
+    },
     "@eslint/eslintrc": {
       "version": "1.3.1",
       "dev": true,
@@ -2018,6 +2173,16 @@
       "version": "1.2.1",
       "dev": true
     },
+    "@material-design-icons/svg": {
+      "version": "0.14.2",
+      "resolved": "https://registry.npmjs.org/@material-design-icons/svg/-/svg-0.14.2.tgz",
+      "integrity": "sha512-QjAzZmqV+7VI8+0eONVYBvSSlytpR+QQ/elT+YADoYq7R5Tc7kU1PaR0xOrEhwMR9MYK2yhUXqXymP8QY01ehg=="
+    },
+    "@mdi/font": {
+      "version": "7.1.96",
+      "resolved": "https://registry.npmjs.org/@mdi/font/-/font-7.1.96.tgz",
+      "integrity": "sha512-Imag6npmfkBDi2Ze2jiZVAPTDIKLxhz2Sx82xJ2zctyAU5LYJejLI5ChnDwiD9bMkQfVuzEsI98Q8toHyC+HCg=="
+    },
     "@nodelib/fs.scandir": {
       "version": "2.1.5",
       "dev": true,
@@ -2187,6 +2352,16 @@
         "color-convert": "^2.0.1"
       }
     },
+    "anymatch": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+      "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+      "dev": true,
+      "requires": {
+        "normalize-path": "^3.0.0",
+        "picomatch": "^2.0.4"
+      }
+    },
     "argparse": {
       "version": "2.0.1",
       "dev": true
@@ -2212,6 +2387,12 @@
       "version": "1.0.2",
       "dev": true
     },
+    "binary-extensions": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+      "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+      "dev": true
+    },
     "boolbase": {
       "version": "1.0.0",
       "dev": true
@@ -2243,6 +2424,33 @@
         "supports-color": "^7.1.0"
       }
     },
+    "chokidar": {
+      "version": "3.5.3",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+      "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+      "dev": true,
+      "requires": {
+        "anymatch": "~3.1.2",
+        "braces": "~3.0.2",
+        "fsevents": "~2.3.2",
+        "glob-parent": "~5.1.2",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.6.0"
+      },
+      "dependencies": {
+        "glob-parent": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+          "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+          "dev": true,
+          "requires": {
+            "is-glob": "^4.0.1"
+          }
+        }
+      }
+    },
     "color-convert": {
       "version": "2.0.1",
       "dev": true,
@@ -2569,6 +2777,13 @@
       "version": "1.0.0",
       "dev": true
     },
+    "fsevents": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+      "dev": true,
+      "optional": true
+    },
     "function-bind": {
       "version": "1.1.1",
       "dev": true
@@ -2645,6 +2860,12 @@
       "version": "5.2.0",
       "dev": true
     },
+    "immutable": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.2.2.tgz",
+      "integrity": "sha512-fTMKDwtbvO5tldky9QZ2fMX7slR0mYpY5nbnFWYp0fOzDhHqhgIw9KoYgxLWsoNTS9ZHGauHj18DTyEw6BK3Og==",
+      "dev": true
+    },
     "import-fresh": {
       "version": "3.3.0",
       "dev": true,
@@ -2669,6 +2890,15 @@
       "version": "2.0.4",
       "dev": true
     },
+    "is-binary-path": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+      "dev": true,
+      "requires": {
+        "binary-extensions": "^2.0.0"
+      }
+    },
     "is-core-module": {
       "version": "2.10.0",
       "dev": true,
@@ -2787,6 +3017,12 @@
       "version": "1.4.0",
       "dev": true
     },
+    "normalize-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+      "dev": true
+    },
     "nth-check": {
       "version": "2.1.1",
       "dev": true,
@@ -2921,6 +3157,15 @@
       "version": "1.2.3",
       "dev": true
     },
+    "readdirp": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+      "dev": true,
+      "requires": {
+        "picomatch": "^2.2.1"
+      }
+    },
     "regexpp": {
       "version": "3.2.0",
       "dev": true
@@ -2963,6 +3208,17 @@
         "queue-microtask": "^1.2.2"
       }
     },
+    "sass": {
+      "version": "1.57.1",
+      "resolved": "https://registry.npmjs.org/sass/-/sass-1.57.1.tgz",
+      "integrity": "sha512-O2+LwLS79op7GI0xZ8fqzF7X2m/m8WFfI02dHOdsK5R2ECeS5F62zrwg/relM1rjSLy7Vd/DiMNIvPrQGsA0jw==",
+      "dev": true,
+      "requires": {
+        "chokidar": ">=3.0.0 <4.0.0",
+        "immutable": "^4.0.0",
+        "source-map-js": ">=0.6.2 <2.0.0"
+      }
+    },
     "semver": {
       "version": "7.3.7",
       "dev": true,

+ 4 - 0
package.json

@@ -8,6 +8,9 @@
     "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore"
   },
   "dependencies": {
+    "@csstools/normalize.css": "^12.0.0",
+    "@material-design-icons/svg": "^0.14.2",
+    "@mdi/font": "^7.1.96",
     "pinia": "^2.0.21",
     "vue": "^3.2.38",
     "vue-router": "^4.1.5"
@@ -24,6 +27,7 @@
     "graphql-tag": "^2.12.6",
     "prettier": "^2.7.1",
     "querystring-es3": "^0.2.1",
+    "sass": "^1.57.1",
     "vite": "^3.0.9"
   }
 }

+ 6 - 7
src/App.vue

@@ -4,7 +4,7 @@
   import { onMounted } from 'vue';
   import { RouterLink, RouterView } from 'vue-router'
   import { UserStore } from '@/stores/user'
-  import UserBlock from '@components/block/UserBlock.vue'
+  import Header from '@components/Header.vue'
 
 
   const userStore = UserStore()
@@ -18,12 +18,11 @@
 </script>
 
 <template>
-  <header>
-    <h1>Où atterrir</h1>
-    <UserBlock/>
-  </header>
-  <RouterView />
+  <Header />
+  <div id="main-content">
+    <RouterView />
+  </div>
 </template>
 
-<style scoped>
+<style lang="scss" scoped>
 </style>

+ 6 - 0
src/api/gql/statics.fragment.gql

@@ -0,0 +1,6 @@
+fragment StaticsFields on Static {
+  id
+  texte
+  title
+  author
+}

+ 0 - 3
src/assets/base.css

@@ -1,3 +0,0 @@
-body{
-  font-size: 16px;
-}

+ 16 - 0
src/assets/base.scss

@@ -0,0 +1,16 @@
+body{
+  font-size: 16px;
+}
+
+@for $i from 1 to 6 {
+  h#{$i}{
+    margin:0;
+  }
+}
+
+p{margin:0;}
+
+a, a:visited, a:hover, a:active{
+  text-decoration: none;
+  color: inherit;
+}

+ 5 - 0
src/assets/fonts/snap_it/generator_config.txt

@@ -0,0 +1,5 @@
+# Font Squirrel Font-face Generator Configuration File
+# Upload this file to the generator to recreate the settings
+# you used to create these fonts.
+
+{"mode":"optimal","formats":["woff","woff2"],"tt_instructor":"default","fix_gasp":"xy","fix_vertical_metrics":"Y","metrics_ascent":"","metrics_descent":"","metrics_linegap":"","add_spaces":"Y","add_hyphens":"Y","fallback":"none","fallback_custom":"100","options_subset":"basic","subset_custom":"","subset_custom_range":"","subset_ot_features_list":"","css_stylesheet":"stylesheet.css","filename_suffix":"-webfont","emsquare":"2048","spacing_adjustment":"0"}

文件差异内容过多而无法显示
+ 102 - 0
src/assets/fonts/snap_it/snap-itmono-1.6-regular-demo.html


二进制
src/assets/fonts/snap_it/snap-itmono-1.6-regular-webfont.woff


二进制
src/assets/fonts/snap_it/snap-itmono-1.6-regular-webfont.woff2


+ 11 - 0
src/assets/fonts/snap_it/snap_it.css

@@ -0,0 +1,11 @@
+/*! Generated by Font Squirrel (https://www.fontsquirrel.com) on January 30, 2023 */
+
+
+
+@font-face {
+    font-family: 'snap-it';
+    src: url('snap-itmono-1.6-regular-webfont.woff2') format('woff2'),
+         url('snap-itmono-1.6-regular-webfont.woff') format('woff');
+    font-weight: 400;
+    font-style: normal;
+}

+ 370 - 0
src/assets/fonts/snap_it/specimen_files/grid_12-825-55-15.css

@@ -0,0 +1,370 @@
+/*Notes about grid:
+Columns:      12
+Grid Width:   825px
+Column Width: 55px
+Gutter Width: 15px
+-------------------------------*/
+
+
+.section {
+	margin-bottom: 18px;
+}
+
+.section:after {
+	content:    '.';
+	display:    block;
+	height:     0;
+	clear:      both;
+	visibility: hidden;
+}
+
+.section {
+	*zoom: 1;
+}
+
+.section .firstcolumn,
+.section .firstcol {
+	margin-left: 0;
+}
+
+
+/* Border on left hand side of a column. */
+.border {
+	padding-left: 7px;
+	margin-left:  7px;
+	border-left:  1px solid #eee;
+}
+
+/* Border with more whitespace, spans one column. */
+.colborder {
+	padding-left: 42px;
+	margin-left:  42px;
+	border-left:  1px solid #eee;
+}
+
+
+/* The Grid Classes */
+.grid1, .grid1_2cols, .grid1_3cols, .grid1_4cols, .grid2, .grid2_3cols, .grid2_4cols, .grid3, .grid3_2cols, .grid3_4cols, .grid4, .grid4_3cols, .grid5, .grid5_2cols, .grid5_3cols, .grid5_4cols, .grid6, .grid6_4cols, .grid7, .grid7_2cols, .grid7_3cols, .grid7_4cols, .grid8, .grid8_3cols, .grid9, .grid9_2cols, .grid9_4cols, .grid10, .grid10_3cols, .grid10_4cols, .grid11, .grid11_2cols, .grid11_3cols, .grid11_4cols, .grid12 {
+	margin-left: 15px;
+	float:       left;
+	display:     inline;
+	overflow:    hidden;
+}
+
+
+.width1, .grid1, .span-1 {
+	width: 55px;
+}
+
+.width1_2cols, .grid1_2cols {
+	width: 20px;
+}
+
+.width1_3cols, .grid1_3cols {
+	width: 8px;
+}
+
+.width1_4cols, .grid1_4cols {
+	width: 2px;
+}
+
+.input_width1 {
+	width: 49px;
+}
+
+.width2, .grid2, .span-2 {
+	width: 125px;
+}
+
+.width2_3cols, .grid2_3cols {
+	width: 31px;
+}
+
+.width2_4cols, .grid2_4cols {
+	width: 20px;
+}
+
+.input_width2 {
+	width: 119px;
+}
+
+.width3, .grid3, .span-3 {
+	width: 195px;
+}
+
+.width3_2cols, .grid3_2cols {
+	width: 90px;
+}
+
+.width3_4cols, .grid3_4cols {
+	width: 37px;
+}
+
+.input_width3 {
+	width: 189px;
+}
+
+.width4, .grid4, .span-4 {
+	width: 265px;
+}
+
+.width4_3cols, .grid4_3cols {
+	width: 78px;
+}
+
+.input_width4 {
+	width: 259px;
+}
+
+.width5, .grid5, .span-5 {
+	width: 335px;
+}
+
+.width5_2cols, .grid5_2cols {
+	width: 160px;
+}
+
+.width5_3cols, .grid5_3cols {
+	width: 101px;
+}
+
+.width5_4cols, .grid5_4cols {
+	width: 72px;
+}
+
+.input_width5 {
+	width: 329px;
+}
+
+.width6, .grid6, .span-6 {
+	width: 405px;
+}
+
+.width6_4cols, .grid6_4cols {
+	width: 90px;
+}
+
+.input_width6 {
+	width: 399px;
+}
+
+.width7, .grid7, .span-7 {
+	width: 475px;
+}
+
+.width7_2cols, .grid7_2cols {
+	width: 230px;
+}
+
+.width7_3cols, .grid7_3cols {
+	width: 148px;
+}
+
+.width7_4cols, .grid7_4cols {
+	width: 107px;
+}
+
+.input_width7 {
+	width: 469px;
+}
+
+.width8, .grid8, .span-8 {
+	width: 545px;
+}
+
+.width8_3cols, .grid8_3cols {
+	width: 171px;
+}
+
+.input_width8 {
+	width: 539px;
+}
+
+.width9, .grid9, .span-9 {
+	width: 615px;
+}
+
+.width9_2cols, .grid9_2cols {
+	width: 300px;
+}
+
+.width9_4cols, .grid9_4cols {
+	width: 142px;
+}
+
+.input_width9 {
+	width: 609px;
+}
+
+.width10, .grid10, .span-10 {
+	width: 685px;
+}
+
+.width10_3cols, .grid10_3cols {
+	width: 218px;
+}
+
+.width10_4cols, .grid10_4cols {
+	width: 160px;
+}
+
+.input_width10 {
+	width: 679px;
+}
+
+.width11, .grid11, .span-11 {
+	width: 755px;
+}
+
+.width11_2cols, .grid11_2cols {
+	width: 370px;
+}
+
+.width11_3cols, .grid11_3cols {
+	width: 241px;
+}
+
+.width11_4cols, .grid11_4cols {
+	width: 177px;
+}
+
+.input_width11 {
+	width: 749px;
+}
+
+.width12, .grid12, .span-12 {
+	width: 825px;
+}
+
+.input_width12 {
+	width: 819px;
+}
+
+/* Subdivided grid spaces */
+.emptycols_left1, .prepend-1 {
+	padding-left: 70px;
+}
+
+.emptycols_right1, .append-1 {
+	padding-right: 70px;
+}
+
+.emptycols_left2, .prepend-2 {
+	padding-left: 140px;
+}
+
+.emptycols_right2, .append-2 {
+	padding-right: 140px;
+}
+
+.emptycols_left3, .prepend-3 {
+	padding-left: 210px;
+}
+
+.emptycols_right3, .append-3 {
+	padding-right: 210px;
+}
+
+.emptycols_left4, .prepend-4 {
+	padding-left: 280px;
+}
+
+.emptycols_right4, .append-4 {
+	padding-right: 280px;
+}
+
+.emptycols_left5, .prepend-5 {
+	padding-left: 350px;
+}
+
+.emptycols_right5, .append-5 {
+	padding-right: 350px;
+}
+
+.emptycols_left6, .prepend-6 {
+	padding-left: 420px;
+}
+
+.emptycols_right6, .append-6 {
+	padding-right: 420px;
+}
+
+.emptycols_left7, .prepend-7 {
+	padding-left: 490px;
+}
+
+.emptycols_right7, .append-7 {
+	padding-right: 490px;
+}
+
+.emptycols_left8, .prepend-8 {
+	padding-left: 560px;
+}
+
+.emptycols_right8, .append-8 {
+	padding-right: 560px;
+}
+
+.emptycols_left9, .prepend-9 {
+	padding-left: 630px;
+}
+
+.emptycols_right9, .append-9 {
+	padding-right: 630px;
+}
+
+.emptycols_left10, .prepend-10 {
+	padding-left: 700px;
+}
+
+.emptycols_right10, .append-10 {
+	padding-right: 700px;
+}
+
+.emptycols_left11, .prepend-11 {
+	padding-left: 770px;
+}
+
+.emptycols_right11, .append-11 {
+	padding-right: 770px;
+}
+
+.pull-1 {
+	margin-left: -70px;
+}
+
+.push-1 {
+	margin-right: -70px;
+	margin-left:  18px;
+	float:        right;
+}
+
+.pull-2 {
+	margin-left: -140px;
+}
+
+.push-2 {
+	margin-right: -140px;
+	margin-left:  18px;
+	float:        right;
+}
+
+.pull-3 {
+	margin-left: -210px;
+}
+
+.push-3 {
+	margin-right: -210px;
+	margin-left:  18px;
+	float:        right;
+}
+
+.pull-4 {
+	margin-left: -280px;
+}
+
+.push-4 {
+	margin-right: -280px;
+	margin-left:  18px;
+	float:        right;
+}

+ 502 - 0
src/assets/fonts/snap_it/specimen_files/specimen_stylesheet.css

@@ -0,0 +1,502 @@
+@import url('grid_12-825-55-15.css');
+
+/*  
+	CSS Reset by Eric Meyer - Released under Public Domain
+    http://meyerweb.com/eric/tools/css/reset/
+*/
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, font, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center, dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend, table,
+caption, tbody, tfoot, thead, tr, th, td {
+	margin:         0;
+	padding:        0;
+	border:         0;
+	outline:        0;
+	font-size:      100%;
+	vertical-align: baseline;
+	background:     transparent;
+}
+
+body {
+	line-height: 1;
+}
+
+ol, ul {
+	list-style: none;
+}
+
+blockquote, q {
+	quotes: none;
+}
+
+blockquote:before, blockquote:after,
+q:before, q:after {
+	content: '';
+	content: none;
+}
+
+:focus {
+	outline: 0;
+}
+
+ins {
+	text-decoration: none;
+}
+
+del {
+	text-decoration: line-through;
+}
+
+table {
+	border-collapse: collapse;
+	border-spacing:  0;
+}
+
+
+body {
+	color:            #000;
+	background-color: #dcdcdc;
+}
+
+a {
+	text-decoration: none;
+	color:           #1883ba;
+}
+
+h1 {
+	font-size:     32px;
+	font-weight:   normal;
+	font-style:    normal;
+	margin-bottom: 18px;
+}
+
+h2 {
+	font-size: 18px;
+}
+
+#container {
+	width:  865px;
+	margin: 0px auto;
+}
+
+
+#header {
+	padding:          20px;
+	font-size:        36px;
+	background-color: #000;
+	color:            #fff;
+}
+
+#header span {
+	color: #666;
+}
+
+#main_content {
+	background-color: #fff;
+	padding:          60px 20px 20px;
+}
+
+
+#footer p {
+	margin:         0;
+	padding-top:    10px;
+	padding-bottom: 50px;
+	color:          #333;
+	font:           10px Arial, sans-serif;
+}
+
+.tabs {
+	width:            100%;
+	height:           31px;
+	background-color: #444;
+}
+
+.tabs li {
+	float:            left;
+	margin:           0;
+	overflow:         hidden;
+	background-color: #444;
+}
+
+.tabs li a {
+	display:         block;
+	color:           #fff;
+	text-decoration: none;
+	font:            bold 11px/11px 'Arial';
+	text-transform:  uppercase;
+	padding:         10px 15px;
+	border-right:    1px solid #fff;
+}
+
+.tabs li a:hover {
+	background-color: #00b3ff;
+
+}
+
+.tabs li.active a {
+	color:            #000;
+	background-color: #fff;
+}
+
+
+div.huge {
+
+	font-size:      300px;
+	line-height:    1em;
+	padding:        0;
+	letter-spacing: -.02em;
+	overflow:       hidden;
+}
+
+div.glyph_range {
+	font-size:   72px;
+	line-height: 1.1em;
+}
+
+.size10 {
+	font-size: 10px;
+}
+
+.size11 {
+	font-size: 11px;
+}
+
+.size12 {
+	font-size: 12px;
+}
+
+.size13 {
+	font-size: 13px;
+}
+
+.size14 {
+	font-size: 14px;
+}
+
+.size16 {
+	font-size: 16px;
+}
+
+.size18 {
+	font-size: 18px;
+}
+
+.size20 {
+	font-size: 20px;
+}
+
+.size24 {
+	font-size: 24px;
+}
+
+.size30 {
+	font-size: 30px;
+}
+
+.size36 {
+	font-size: 36px;
+}
+
+.size48 {
+	font-size: 48px;
+}
+
+.size60 {
+	font-size: 60px;
+}
+
+.size72 {
+	font-size: 72px;
+}
+
+.size90 {
+	font-size: 90px;
+}
+
+
+.psample_row1 {
+	height: 120px;
+}
+
+.psample_row1 {
+	height: 120px;
+}
+
+.psample_row2 {
+	height: 160px;
+}
+
+.psample_row3 {
+	height: 160px;
+}
+
+.psample_row4 {
+	height: 160px;
+}
+
+.psample {
+	overflow: hidden;
+	position: relative;
+}
+
+.psample p {
+	line-height: 1.3em;
+	display:     block;
+	overflow:    hidden;
+	margin:      0;
+}
+
+.psample span {
+	margin-right: .5em;
+}
+
+.white_blend {
+	width:            100%;
+	height:           61px;
+	background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAVkAAAA9CAYAAAAH4BojAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAO1JREFUeNrs3TsKgFAMRUE/eer+NxztxMYuEWQG3ECKwwUF58ycAKixOAGAyAKILAAiCyCyACILgMgCiCyAyAIgsgAiCyCyAIgsgMgCiCwAIgsgsgAiC4DIAogsACIL0CWuZ3UGgLrIhjMA1EV2OAOAJQtgyQLwjOzmDAAiCyCyAIgsQFtkd2cAEFkAkQVAZAHaIns4A4AlC2DJAiCyACILILIAiCzAV5H1dQGAJQsgsgCILIDIAvwisl58AViyAJYsACILILIAIgvAe2T9EhxAZAFEFgCRBeiL7HAGgLrIhjMAWLIAliwAt1OAAQDwygTBulLIlQAAAABJRU5ErkJggg==);
+	position:         absolute;
+	bottom:           0;
+}
+
+.black_blend {
+	width:            100%;
+	height:           61px;
+	background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAVkAAAA9CAYAAAAH4BojAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAPJJREFUeNrs3TEKhTAQRVGjibr/9QoxhY2N3Ywo50A28IrLwP9g6b1PAMSYTQAgsgAiC4DIAogsgMgCILIAIgsgsgCILIDIAogsACILILIAIguAyAKILIDIAiCyACILgMgCZCnjLWYAiFGvB0BQZJsZAFyyAC5ZAO6RXc0AILIAIguAyAKkRXYzA4DIAogsACILkBbZ3QwALlkAlywAIgsgsgAiC4DIArwVWf8uAHDJAogsACILILIAv4isH74AXLIALlkARBZAZAFEFoDnyPokOIDIAogsACILkBfZZgaAuMhWMwC4ZAE+p4x3mAEgxinAAJ+XBbPWGkwAAAAAAElFTkSuQmCC);
+	position:         absolute;
+	bottom:           0;
+}
+
+.fullreverse {
+	background:    #000 !important;
+	color:         #fff !important;
+	margin-left:   -20px;
+	padding-left:  20px;
+	margin-right:  -20px;
+	padding-right: 20px;
+	padding:       20px;
+	margin-bottom: 0;
+}
+
+
+.sample_table td {
+	padding-top:    3px;
+	padding-bottom: 5px;
+	padding-left:   5px;
+	vertical-align: middle;
+	line-height:    1.2em;
+}
+
+.sample_table td:first-child {
+	background-color: #eee;
+	text-align:       right;
+	padding-right:    5px;
+	padding-left:     0;
+	padding:          5px;
+	font:             11px/12px 'Courier New', Courier, mono;
+}
+
+code {
+	white-space:      pre;
+	background-color: #eee;
+	display:          block;
+	padding:          10px;
+	margin-bottom:    18px;
+	overflow:         auto;
+}
+
+
+.bottom, .last {
+	margin-bottom:  0 !important;
+	padding-bottom: 0 !important;
+}
+
+.box {
+	padding:       18px;
+	margin-bottom: 18px;
+	background:    #eee;
+}
+
+.reverse, .reversed {
+	background: #000 !important;
+	color:      #fff !important;
+	border:     none !important;
+}
+
+#bodycomparison {
+	position:    relative;
+	overflow:    hidden;
+	font-size:   72px;
+	height:      90px;
+	white-space: nowrap;
+}
+
+#bodycomparison div {
+	font-size:   72px;
+	line-height: 90px;
+	display:     inline;
+	margin:      0 15px 0 0;
+	padding:     0;
+}
+
+#bodycomparison div span {
+	font:     10px Arial;
+	position: absolute;
+	left:     0;
+}
+
+#xheight {
+	float:       none;
+	position:    absolute;
+	color:       #d9f3ff;
+	font-size:   72px;
+	line-height: 90px;
+}
+
+.fontbody {
+	position: relative;
+}
+
+.arialbody {
+	font-family: Arial;
+	position:    relative;
+}
+
+.verdanabody {
+	font-family: Verdana;
+	position:    relative;
+}
+
+.georgiabody {
+	font-family: Georgia;
+	position:    relative;
+}
+
+/* @group Layout page
+ */
+
+#layout h1 {
+	font-size:   36px;
+	line-height: 42px;
+	font-weight: normal;
+	font-style:  normal;
+}
+
+#layout h2 {
+	font-size:   24px;
+	line-height: 23px;
+	font-weight: normal;
+	font-style:  normal;
+}
+
+#layout h3 {
+	font-size:   22px;
+	line-height: 1.4em;
+	margin-top:  1em;
+	font-weight: normal;
+	font-style:  normal;
+}
+
+
+#layout p.byline {
+	font-size:     12px;
+	margin-top:    18px;
+	line-height:   12px;
+	margin-bottom: 0;
+}
+
+#layout p {
+	font-size:     14px;
+	line-height:   21px;
+	margin-bottom: .5em;
+}
+
+#layout p.large {
+	font-size:   18px;
+	line-height: 26px;
+}
+
+#layout .sidebar p {
+	font-size:   12px;
+	line-height: 1.4em;
+}
+
+#layout p.caption {
+	font-size:     10px;
+	margin-top:    -16px;
+	margin-bottom: 18px;
+}
+
+/* @end */
+
+/* @group Glyphs */
+
+#glyph_chart div {
+	background-color: #d9f3ff;
+	color:            black;
+	float:            left;
+	font-size:        36px;
+	height:           1.2em;
+	line-height:      1.2em;
+	margin-bottom:    1px;
+	margin-right:     1px;
+	text-align:       center;
+	width:            1.2em;
+	position:         relative;
+	padding:          .6em .2em .2em;
+}
+
+#glyph_chart div p {
+	position:         absolute;
+	left:             0;
+	top:              0;
+	display:          block;
+	text-align:       center;
+	font:             bold 9px Arial, sans-serif;
+	background-color: #3a768f;
+	width:            100%;
+	color:            #fff;
+	padding:          2px 0;
+}
+
+
+#glyphs h1 {
+	font-family: Arial, sans-serif;
+}
+
+/* @end */
+
+/* @group Installing */
+
+#installing {
+	font: 13px Arial, sans-serif;
+}
+
+#installing p,
+#glyphs p {
+	line-height:   1.2em;
+	margin-bottom: 18px;
+	font:          13px Arial, sans-serif;
+}
+
+
+#installing h3 {
+	font-size:  15px;
+	margin-top: 18px;
+}
+
+/* @end */
+
+#rendering h1 {
+	font-family: Arial, sans-serif;
+}
+
+.render_table td {
+	font:           11px 'Courier New', Courier, mono;
+	vertical-align: middle;
+}
+
+

+ 27 - 0
src/assets/fonts/snap_it_mono/README.md

@@ -0,0 +1,27 @@
+# Snap-it mono
+
+![Snap-it cover image](cover-image.jpg)
+
+A font designed by [Morgane Bartoli](mailto:conatct@morganebartoli.com) and [Corentin Moussard](hello@alune.fr).  
+We designed it for the project [Print-it](https://gitlab.com/Alune/print-it), a CSS-print fanzine you print yourself 
+using a webpage and a manual, edited by [Objet Papier](https://objetpapier.fr/).
+
+## What's next
+
+We started working on bold and italics, we hope to release it soon. In the meantime feel free to contribute.  
+
+## Specimen
+
+Web specimen available [here](https://objetpapier.fr/snap-it/). We designed Snap-it especialy for our project [Print-it](https://objetpapier.fr/print-it/) 
+which titles was set in [Avara](https://raphaelbastide.com/avara/). We designed it to be the perfect fit as an associated body copy font. 
+Feel free to go check out the project.
+
+## Software
+
+We wanted to build this font with open-source software, for consistency purpose with the Print-it project. 
+The first version of the font was made with [Glyphr Studio](http://www.glyphrstudio.com/). Limitations in Glyphr 
+made us go for a professionnal font design software, so further versions were made with [Glyphs App](https://glyphsapp.com).
+
+## License
+
+Snap-it is under the OFL license.

二进制
src/assets/fonts/snap_it_mono/font-files/Snap-itmono-1.6-Regular.otf


二进制
src/assets/fonts/snap_it_mono/font-files/Snap-itmono-1.6-Regular.woff


二进制
src/assets/fonts/snap_it_mono/font-files/Snap-itmono-1.6-Regular.woff2


+ 96 - 0
src/assets/fonts/snap_it_mono/license.md

@@ -0,0 +1,96 @@
+Copyright (c) 2019, Corentin Moussard [hello@alune.fr](mailto:hello@alune.fr), [Gitlab page](https://gitlab.com/Alune/),
+Copyright (c) 2019, Morgane Bartoli [contact@morganebartoli.com](contact@morganebartoli.com),
+Copyright (c) 2019, Objet Papier [objetpapier.fr](https://objetpapier.fr/),
+with Reserved Font Name Snap-it.
+
+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](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.

+ 28 - 0
src/assets/layout.scss

@@ -0,0 +1,28 @@
+html,body{
+  margin: 0;
+  padding: 0;
+
+}
+
+#app {
+  box-sizing: border-box;
+  max-width: 1920px;
+  height: 100vh;
+  margin: 0 auto;
+  padding: 1rem;
+
+  font-weight: normal;
+
+  display: flex;
+  flex-flow: column-reverse;
+}
+
+#header{
+  flex: 0 0 5rem;
+}
+
+#main-content{
+  flex: 1 1 auto;
+
+}
+

+ 0 - 10
src/assets/main.css

@@ -1,10 +0,0 @@
-@import "./base.css";
-
-#app {
-  max-width: 1280px;
-  margin: 0 auto;
-  padding: 2rem;
-
-  font-weight: normal;
-}
-

+ 23 - 0
src/assets/main.scss

@@ -0,0 +1,23 @@
+// @import './node_modules/@mdi/font/scss/materialdesignicons.scss';
+@import "./base.scss";
+@import "./layout.scss";
+@import "./fonts/snap_it/snap_it.css";
+
+
+#app{
+
+}
+
+#app>header{
+  .row{
+    display: flex;
+    flex-direction: row;
+    >*{
+      margin-right: 1em;
+    }
+  }
+
+  h1{
+    font-family: "snap-it";
+  }
+}

+ 46 - 0
src/components/Header.vue

@@ -0,0 +1,46 @@
+<script>
+
+import { mapState } from 'pinia'
+import { UserStore } from '@/stores/user'
+import UserBlock from '@components/block/UserBlock.vue'
+import StaticMenu from '@components/block/StaticMenu.vue'
+
+
+export default {
+  // data(){
+  //   return {
+  //     block: null
+  //   }
+  // },
+  computed: {
+    ...mapState(UserStore,['isloggedin'])
+  },
+  methods: {
+    
+  },
+  components: {
+    UserBlock,
+    StaticMenu
+  }
+}
+
+</script>
+
+<template>
+    <header>
+    <div class="row top">
+      <h1>
+        <router-link :to="{ name: 'home' }">Où atterrir</router-link>  
+      </h1>
+    </div>
+    <div class="row bottom">
+      <StaticMenu/>
+      <UserBlock/>
+    </div>
+  </header>
+
+</template>
+
+<style lang="scss" scoped>
+
+</style>

+ 1 - 1
src/components/MapConcernements.vue

@@ -34,7 +34,7 @@ export default {
 
 <template>
   <div id="map-concernements">
-    <h1>Concernements</h1>
+    <!-- <h1>Concernements</h1> -->
     <!-- <canvas rel="canvas-map"></canvas> -->
     <ul>
       <li

+ 56 - 0
src/components/block/StaticMenu.vue

@@ -0,0 +1,56 @@
+<script>
+
+import { mapActions, mapState } from 'pinia'
+import { StaticsStore } from '@/stores/statics'
+
+export default {
+  props: [],
+  data(){
+    return {
+      // block: null
+    }
+  },
+  computed: {
+    ...mapState(StaticsStore,['statics'])
+  },
+  created () {
+    console.log("infos created");
+    this.loadStatics()
+  },
+  methods: {
+    ...mapActions(StaticsStore,['loadStatics'])
+  },
+  components: {
+    // LoginBlock,
+    // UserTools
+  }
+}
+
+</script>
+
+<template>
+  <ul>
+    <li
+        v-for="staticnode in statics"
+        v-bind:key="staticnode.id"
+      >
+      <router-link :to="{ name: 'static', params: { id:staticnode.id } }">{{staticnode.title}}</router-link>
+    </li>
+  </ul>
+  
+</template>
+
+<style lang="scss" scoped>
+  ul{
+    padding: 0;
+    margin: 0;
+    display: flex;
+    flex-direction: row;
+  }
+  li{
+    padding: 0;
+    margin: 0;
+    list-style: none;
+  }
+
+</style>

+ 1 - 0
src/components/block/UserBlock.vue

@@ -7,6 +7,7 @@ import { UserStore } from '@/stores/user'
 import LoginBlock from '@components/block/LoginBlock.vue'
 import UserTools from '@components/block/UserTools.vue'
 
+
 // import MA from '/api/ma-axios'
 
 export default {

+ 24 - 16
src/components/block/UserTools.vue

@@ -1,22 +1,7 @@
-<template>
-  <div id="user-tools">
-    <a class="mdi mdi-account" href="/user">
-      <span>{{ name }}</span>
-      <!-- <span v-else>{{ mail }}</span> -->
-    </a><br/>
-    <a href="/user/logout"
-      @click.prevent="onLogout()"
-      class="mdi mdi-logout"
-      title="logout"
-    >logout</a>
-  </div>
-</template>
-
 <script>
 import { mapState } from 'pinia'
 import { UserStore } from '@/stores/user'
 
-
 export default {
   setup() {
     const userStore = UserStore()
@@ -36,9 +21,32 @@ export default {
         console.log('UserTools user logged-out then')
       })
     }
+  },
+  components: {
+    // Loggout
   }
 }
 </script>
 
-<style lang="css" scoped>
+<template>
+  <div id="user-tools">
+    <a class="mdi mdi-account" href="/user">
+      <span>{{ name }}</span>
+      <!-- <span v-else>{{ mail }}</span> -->
+    </a><br/>
+    <a href="/user/logout"
+      @click.prevent="onLogout()"
+      class="mdi mdi-logout"
+      title="logout"
+    />
+  </div>
+</template>
+
+
+<style lang="scss" scoped>
+  #user-tools{
+    display: flex;
+    flex-direction: row;
+    gap: 0.5em;
+  }
 </style>

+ 3 - 1
src/main.js

@@ -4,7 +4,9 @@ import { createPinia } from 'pinia'
 import App from './App.vue'
 import router from './router'
 
-import './assets/main.css'
+import '@csstools/normalize.css';
+import '@mdi/font/css/materialdesignicons.css'
+import './assets/main.scss'
 
 const app = createApp(App)
 

+ 10 - 8
src/router/index.js

@@ -1,5 +1,6 @@
 import { createRouter, createWebHistory } from 'vue-router'
 import HomeView from '@views/Home.vue'
+import StaticView from '@views/Static.vue'
 
 const router = createRouter({
   history: createWebHistory(import.meta.env.BASE_URL),
@@ -8,15 +9,16 @@ const router = createRouter({
       path: '/',
       name: 'home',
       component: HomeView
+    },
+    {
+      path: '/static/:id',
+      name: 'static',
+      // route level code-splitting
+      // this generates a separate chunk (About.[hash].js) for this route
+      // which is lazy-loaded when the route is visited.
+      component: () => import('../views/Static.vue'),
+      props: true
     }
-    // {
-    //   path: '/about',
-    //   name: 'about',
-    //   // route level code-splitting
-    //   // this generates a separate chunk (About.[hash].js) for this route
-    //   // which is lazy-loaded when the route is visited.
-    //   component: () => import('../views/AboutView.vue')
-    // }
   ]
 })
 

+ 52 - 0
src/stores/statics.js

@@ -0,0 +1,52 @@
+import { defineStore } from 'pinia'
+import { print } from 'graphql/language/printer'
+import gql from 'graphql-tag'
+
+// import REST from '@api/rest-axios'
+import GQL from '@api/graphql-axios'
+// import JSONAPI from '@api/json-axios'
+
+import StaticsFields from '@api/gql/statics.fragment.gql'
+
+export const StaticsStore = defineStore({
+  id: 'statics',
+  state: () => ({
+    loaded: false,
+    statics: [],
+    statics_byid: {}
+  }),
+  getters: {
+    
+  },
+  actions: {
+    loadStatics () {
+      console.log('statics store loadStatics');
+      return new Promise((resolve, reject) => {
+        const ast = gql`{
+          allstatics {
+            ...StaticsFields
+          }
+        }
+        ${StaticsFields}
+        `
+        console.log('ast', ast);
+        GQL.post('', { query: print(ast) })
+          .then(({ data : { data  : { allstatics } } }) => {
+            console.log('loadstatics loaded', allstatics)
+            this.statics = allstatics
+            
+            allstatics.forEach((s) => {
+              console.log("s", s);
+              this.statics_byid[s.id] = s
+            });
+            console.log("statics_byid", this.statics_byid);
+            this.loaded = true;
+          })
+          .catch(error => {
+            console.warn('Issue with loadStatics', error)
+            Promise.reject(error)
+          })
+      })
+    }
+  }
+})

+ 1 - 1
src/views/Home.vue

@@ -28,6 +28,6 @@ export default {
   <MapConcernements v-if="isloggedin"/>
 </template>
 
-<style lang="css" scoped>
+<style lang="scss" scoped>
 
 </style>

+ 40 - 0
src/views/Static.vue

@@ -0,0 +1,40 @@
+<script>
+
+import { mapActions, mapState } from 'pinia'
+import { StaticsStore } from '@/stores/statics'
+
+
+export default {
+  props: ['id'],
+  // data(){
+  //   return {
+  //     block: null
+  //   }
+  // },
+  computed: {
+    ...mapState(StaticsStore,['loaded', 'statics_byid'])
+  },
+  created () {
+    console.log("static created, id", this.id);
+    // this.loadStatics()
+  },
+  methods: {
+    ...mapActions(StaticsStore,['loadStatics'])
+  },
+  components: {
+    // MapConcernements
+  }
+}
+
+</script>
+
+<template>
+  <span v-if="!loaded">loading ...</span>
+  <!-- <h2 v-if="loaded">{{ this.id }}</h2> -->
+  <h2 v-if="loaded">{{ statics_byid[id].title }}</h2>
+  <div v-if="loaded" v-html="statics_byid[id].texte"/>
+</template>
+
+<style lang="scss" scoped>
+
+</style>

+ 1 - 0
vite.config.js

@@ -13,6 +13,7 @@ export default defineConfig({
       '@components': fileURLToPath(new URL('./src/components', import.meta.url)),
       '@views': fileURLToPath(new URL('./src/views', import.meta.url)),
       '@api': fileURLToPath(new URL('./src/api', import.meta.url))
+      // '@icons': fileURLToPath(new URL('./node_modules/vue-material-design-icons', import.meta.url)),
     }
   }
 })

部分文件因为文件数量过多而无法显示