├── .gitignore ├── LICENSE-MIT ├── package.json ├── test ├── reset.css └── test.css ├── Gruntfile.coffee ├── README.md ├── src └── parker.coffee └── tasks └── parker.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | tmp 4 | report.md -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 leny 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "grunt-parker", 3 | "version": "0.2.0", 4 | "description": "Grunt plugin for parker, a stylesheet analysis tool.", 5 | "keywords": [ 6 | "gruntplugin", 7 | "parker", 8 | "stylesheet", 9 | "analysis", 10 | "css" 11 | ], 12 | "homepage": "https://github.com/leny/grunt-parker", 13 | "author": { 14 | "name": "leny", 15 | "email": "info@flatland.be", 16 | "url": "http://leny.me" 17 | }, 18 | "contributors": [ 19 | { 20 | "name": "Oliver Farrell", 21 | "url": "http://oliverjfarrell.co.uk" 22 | }, 23 | { 24 | "name": "Tane Morgan", 25 | "url": "https://github.com/tanem" 26 | }, 27 | { 28 | "name": "Lars Olesen", 29 | "url": "https://github.com/lsolesen" 30 | }, 31 | { 32 | "name": "Jason Weir", 33 | "url": "https://github.com/Gidgidonihah" 34 | } 35 | ], 36 | "repository": { 37 | "type": "git", 38 | "url": "git://github.com/leny/grunt-parker.git" 39 | }, 40 | "bugs": { 41 | "url": "https://github.com/leny/grunt-parker/issues" 42 | }, 43 | "licenses": [ 44 | { 45 | "type": "MIT", 46 | "url": "https://github.com/leny/grunt-parker/blob/master/LICENSE-MIT" 47 | } 48 | ], 49 | "engines": { 50 | "node": ">= 0.10.0" 51 | }, 52 | "scripts": { 53 | "test": "grunt test" 54 | }, 55 | "devDependencies": { 56 | "grunt": "^1.0.1", 57 | "grunt-coffeelint": "0.0.16", 58 | "grunt-contrib-coffee": "^2.1.0", 59 | "matchdep": "^2.0.0" 60 | }, 61 | "dependencies": { 62 | "chalk": "^4.0.0", 63 | "parker": "0.0.10" 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /test/reset.css: -------------------------------------------------------------------------------- 1 | html, 2 | body, 3 | div, 4 | span, 5 | applet, 6 | object, 7 | iframe, 8 | h1, 9 | h2, 10 | h3, 11 | h4, 12 | h5, 13 | h6, 14 | p, 15 | blockquote, 16 | pre, 17 | a, 18 | abbr, 19 | acronym, 20 | address, 21 | big, 22 | cite, 23 | code, 24 | del, 25 | dfn, 26 | em, 27 | img, 28 | ins, 29 | kbd, 30 | q, 31 | s, 32 | samp, 33 | small, 34 | strike, 35 | strong, 36 | sub, 37 | sup, 38 | tt, 39 | var, 40 | b, 41 | u, 42 | i, 43 | center, 44 | dl, 45 | dt, 46 | dd, 47 | ol, 48 | ul, 49 | li, 50 | fieldset, 51 | form, 52 | label, 53 | legend, 54 | table, 55 | caption, 56 | tbody, 57 | tfoot, 58 | thead, 59 | tr, 60 | th, 61 | td, 62 | article, 63 | aside, 64 | canvas, 65 | details, 66 | embed, 67 | figure, 68 | figcaption, 69 | footer, 70 | header, 71 | hgroup, 72 | menu, 73 | nav, 74 | output, 75 | ruby, 76 | section, 77 | summary, 78 | time, 79 | mark, 80 | audio, 81 | video { 82 | margin: 0; 83 | padding: 0; 84 | border: 0; 85 | font-size: 100%; 86 | font: inherit; 87 | vertical-align: baseline; 88 | } 89 | article, 90 | aside, 91 | details, 92 | figcaption, 93 | figure, 94 | footer, 95 | header, 96 | hgroup, 97 | menu, 98 | nav, 99 | section { 100 | display: block; 101 | } 102 | body { 103 | line-height: 1; 104 | } 105 | ol, 106 | ul { 107 | list-style: none; 108 | } 109 | blockquote, 110 | q { 111 | quotes: none; 112 | } 113 | blockquote:before, 114 | blockquote:after, 115 | q:before, 116 | q:after { 117 | content: ""; 118 | content: none; 119 | } 120 | table { 121 | border-collapse: collapse; 122 | border-spacing: 0; 123 | } 124 | a { 125 | color: #33a; 126 | } 127 | abbr { 128 | border-bottom: 0.1rem dotted #808080; 129 | cursor: help; 130 | } 131 | -------------------------------------------------------------------------------- /Gruntfile.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | * grunt-parker 3 | * https://github.com/leny/grunt-parker 4 | * 5 | * Copyright (c) 2014 leny 6 | * Licensed under the MIT license. 7 | ### 8 | 9 | "use strict" 10 | 11 | module.exports = ( grunt ) -> 12 | 13 | require( "matchdep" ).filterDev( "grunt-*" ).forEach grunt.loadNpmTasks 14 | 15 | grunt.initConfig 16 | coffeelint: 17 | options: 18 | arrow_spacing: 19 | level: "error" 20 | camel_case_classes: 21 | level: "error" 22 | duplicate_key: 23 | level: "error" 24 | indentation: 25 | level: "ignore" 26 | max_line_length: 27 | level: "ignore" 28 | no_backticks: 29 | level: "error" 30 | no_empty_param_list: 31 | level: "error" 32 | no_stand_alone_at: 33 | level: "error" 34 | no_tabs: 35 | level: "error" 36 | no_throwing_strings: 37 | level: "error" 38 | no_trailing_semicolons: 39 | level: "error" 40 | no_unnecessary_fat_arrows: 41 | level: "error" 42 | space_operators: 43 | level: "error" 44 | task: 45 | files: 46 | src: [ "src/*.coffee" ] 47 | coffee: 48 | options: 49 | bare: yes 50 | task: 51 | files: 52 | "tasks/parker.js": "src/parker.coffee" 53 | parker: 54 | default: 55 | src: [ "test/*.css" ] 56 | custom: 57 | options: 58 | metrics: [ 59 | "TotalRules" 60 | "TotalSelectors" 61 | "TotalIdentifiers" 62 | "TotalDeclarations" 63 | ] 64 | file: "report.md" 65 | colophon: yes 66 | usePackage: yes 67 | src: [ "test/*.css" ] 68 | 69 | grunt.loadTasks "tasks" 70 | 71 | grunt.registerTask "default", [ 72 | "coffeelint" 73 | "coffee" 74 | "parker" 75 | ] 76 | 77 | grunt.registerTask "build", [ 78 | "coffeelint" 79 | "coffee" 80 | ] 81 | 82 | grunt.registerTask "test", [ 83 | "parker" 84 | ] 85 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # grunt-parker 2 | 3 | ![NPM version](http://img.shields.io/npm/v/grunt-parker.svg) ![Dependency Status](https://david-dm.org/leny/grunt-parker.svg) ![Downloads counter](http://img.shields.io/npm/dm/grunt-parker.svg) 4 | 5 | > Grunt plugin for [parker](https://github.com/katiefenn/parker), a stylesheet analysis tool. 6 | 7 | * * * 8 | 9 | ## Getting Started 10 | 11 | This plugin requires Grunt `~0.4.5` 12 | 13 | If you haven't used [Grunt](http://gruntjs.com/) before, be sure to check out the [Getting Started](http://gruntjs.com/getting-started) guide, as it explains how to create a [Gruntfile](http://gruntjs.com/sample-gruntfile) as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command: 14 | 15 | ```shell 16 | npm install grunt-parker --save-dev 17 | ``` 18 | 19 | Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript: 20 | 21 | ```js 22 | grunt.loadNpmTasks('grunt-parker'); 23 | ``` 24 | 25 | ## The "parker" task 26 | 27 | ### Overview 28 | In your project's Gruntfile, add a section named `parker` to the data object passed into `grunt.initConfig()`. 29 | 30 | ```js 31 | grunt.initConfig({ 32 | parker: { 33 | options: { 34 | // Task-specific options go here. 35 | }, 36 | your_target: { 37 | // Target-specific file lists and/or options go here. 38 | }, 39 | }, 40 | }); 41 | ``` 42 | 43 | ### Options 44 | 45 | #### options.metrics 46 | 47 | Type: `Array` (metric names) 48 | Default value: `false` 49 | 50 | An array of the metrics to use in parker. 51 | By default, grunt-parker use all available metrics. 52 | 53 | By now, grunt-parker accepts the following metrics : 54 | 55 | - `TotalStylesheets` 56 | - `TotalStylesheetSize` 57 | - `TotalRules` 58 | - `TotalSelectors` 59 | - `TotalIdentifiers` 60 | - `TotalDeclarations` 61 | - `SelectorsPerRule` 62 | - `IdentifiersPerSelector` 63 | - `SpecificityPerSelector` 64 | - `TopSelectorSpecificity` 65 | - `TopSelectorSpecificitySelector` 66 | - `TotalIdSelectors` 67 | - `TotalUniqueColours` 68 | - `UniqueColours` 69 | - `TotalImportantKeywords` 70 | - `TotalMediaQueries` 71 | - `MediaQueries` 72 | 73 | #### options.file 74 | 75 | Type: `String` (file path) 76 | Default value: `false` 77 | 78 | A file path to log the reported results, in *markdown* format. 79 | If `false` is given, the file will not be written. 80 | **Note:** using a file as output will silence the console output. 81 | 82 | #### options.title 83 | 84 | Type: `String` 85 | Default value: `Grunt Parker Report` 86 | 87 | When logging the reported results to file, use this as title of the markdown document. 88 | 89 | #### options.colophon 90 | 91 | Type: `Boolean` 92 | Default value: `false` 93 | 94 | When logging the reported results to file, use colophon and timestamp as footer of the markdown document. 95 | 96 | #### options.usePackage 97 | 98 | Type: `Boolean` 99 | Default value: `false` 100 | 101 | When enabled, if you launch your grunt-packer task from a folder containing a `package.json` file (like 99% of use cases), grunt-packer will use some of the package's informations to make the report file a little more informative (use project's name as title, show version and description, links to the homepage…). 102 | 103 | ### Usage Examples 104 | 105 | #### Default Options 106 | 107 | In this example, the default options are used to shows the results of the parker analysis for the given files. 108 | 109 | ```js 110 | grunt.initConfig({ 111 | parker: { 112 | options: {}, 113 | src: [ 114 | 'test/*.css' 115 | ], 116 | }, 117 | }); 118 | ``` 119 | 120 | #### Custom Options 121 | 122 | In this example, custom options are used to shows the results of the parker analysis for the given files, with only the four given metrics, and write the results on a file named `report.md` 123 | 124 | ```js 125 | grunt.initConfig({ 126 | parker: { 127 | options: { 128 | metrics: [ 129 | "TotalRules", 130 | "TotalSelectors", 131 | "TotalIdentifiers", 132 | "TotalDeclarations" 133 | ], 134 | file: "report.md", 135 | colophon: true, 136 | usePackage: true 137 | }, 138 | src: [ 139 | 'test/*.css' 140 | ] 141 | } 142 | }); 143 | ``` 144 | 145 | ## Contributing 146 | 147 | In lieu of a formal styleguide, take care to maintain the existing coding style. 148 | Lint and test your code using [Grunt](http://gruntjs.com/). 149 | 150 | ## Release History 151 | 152 | * **2016/04/07** : v0.2.0 153 | * **2016/02/05** : v0.1.4 154 | * **2014/12/14** : v0.1.3 155 | * **2014/09/16** : v0.1.2 156 | * **2014/09/14** : v0.1.0 157 | -------------------------------------------------------------------------------- /src/parker.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | * grunt-todo 3 | * https://github.com/Leny/grunt-todo 4 | * 5 | * Copyright (c) 2014 leny 6 | * Licensed under the MIT license. 7 | ### 8 | 9 | "use strict" 10 | 11 | chalk = require "chalk" 12 | Parker = require "parker" 13 | 14 | module.exports = ( grunt ) -> 15 | 16 | grunt.registerMultiTask "parker", "Stylesheet analysis", -> 17 | oOptions = @options 18 | metrics: no 19 | file: no 20 | title: no 21 | colophon: no 22 | usePackage: no 23 | aLogFileLines = [] 24 | sDefaultTitle = "Grunt Parker Report" 25 | 26 | if grunt.util.kindOf( oOptions.metrics ) is "array" 27 | aMetrics = ( require "parker/metrics/#{ sMetric }.js" for sMetric in oOptions.metrics ) 28 | else 29 | aMetrics = require "parker/metrics/All.js" 30 | 31 | parker = new Parker aMetrics 32 | 33 | oParsedMetrics = {} 34 | oParsedMetrics[ oMetric.id ] = oMetric for oMetric in aMetrics 35 | 36 | if oOptions.usePackage 37 | try 38 | oProjectPackage = grunt.file.readJSON "#{ process.cwd() }/package.json" 39 | catch oError 40 | grunt.log.writeln "" 41 | grunt.log.writeln chalk.yellow.bold( "Oops:" ), "No #{ chalk.cyan( 'package.json' ) } file found. Disabling #{ chalk.green( 'usePackage' ) } option." 42 | oOptions.usePackage = no 43 | 44 | if oOptions.file 45 | if sTitle = ( oOptions.title or ( if oOptions.usePackage and oProjectPackage.name then oProjectPackage.name else no ) or sDefaultTitle ) 46 | if oOptions.usePackage 47 | if sHomePage = oProjectPackage.homepage 48 | aLogFileLines.push "# [#{ sTitle }]( #{ sHomePage } )" 49 | else 50 | aLogFileLines.push "# #{ sTitle }" 51 | aLogFileLines.push "" 52 | if sVersion = oProjectPackage.version 53 | aLogFileLines.push "**Version:** `#{ sVersion }`" 54 | aLogFileLines.push "" 55 | if sDescription = oProjectPackage.description 56 | aLogFileLines.push "> #{ sDescription }" 57 | aLogFileLines.push "" 58 | aLogFileLines.push "* * *" 59 | aLogFileLines.push "" 60 | else 61 | aLogFileLines.push "# #{ sTitle }" 62 | aLogFileLines.push "" 63 | aLogFileLines.push "## Parker Report" unless sTitle is sDefaultTitle 64 | else 65 | aLogFileLines.push "# #{ sDefaultTitle }" 66 | aLogFileLines.push "" 67 | 68 | @filesSrc 69 | .filter ( sFilePath ) -> 70 | grunt.file.exists( sFilePath ) and grunt.file.isFile( sFilePath ) 71 | .forEach ( sFilePath ) -> 72 | aResults = [] 73 | aFileResults = [] 74 | oParkerMetrics = parker.run grunt.file.read sFilePath 75 | 76 | if oParkerMetrics 77 | for sMetric, mValue of oParkerMetrics 78 | aResults.push [ 79 | oParsedMetrics[ sMetric ].name 80 | mValue 81 | ] 82 | 83 | if aResults.length 84 | unless oOptions.file 85 | grunt.log.writeln() 86 | grunt.log.writeln chalk.underline sFilePath 87 | grunt.log.writeln() 88 | for aResult in aResults 89 | sValue = switch grunt.util.kindOf aResult[ 1 ] 90 | when "array" 91 | unless oOptions.file 92 | grunt.log.writeln chalk.cyan( "#{ aResult[ 0 ] }:" ) 93 | grunt.log.writeln "\t#{ sResult }" for sResult in aResult[ 1 ] 94 | aFileResults.push "- **#{ aResult[ 0 ] }:**" 95 | for sResult in aResult[ 1 ] 96 | if sResult.substring( 0, 1 ) is "#" 97 | sResult = "`#{ sResult }`" 98 | aFileResults.push "\t- #{ sResult }" 99 | when "number" 100 | unless oOptions.file 101 | grunt.log.writeln chalk.cyan( "#{ aResult[ 0 ] }:" ), chalk.yellow aResult[ 1 ] 102 | aFileResults.push "- **#{ aResult[ 0 ] }:** #{ aResult[ 1 ] }" 103 | else 104 | unless oOptions.file 105 | grunt.log.writeln chalk.cyan( "#{ aResult[ 0 ] }:" ), aResult[ 1 ] 106 | aFileResults.push "- **#{ aResult[ 0 ] }:** #{ aResult[ 1 ] }" 107 | 108 | if oOptions.file and aFileResults.length 109 | aLogFileLines.push "### #{ sFilePath }" 110 | aLogFileLines.push "" 111 | aLogFileLines = aLogFileLines.concat aFileResults 112 | aLogFileLines.push "" 113 | 114 | if oOptions.file 115 | 116 | if oOptions.colophon 117 | aLogFileLines.push "" 118 | aLogFileLines.push "* * *" 119 | aLogFileLines.push "" 120 | aLogFileLines.push "Last generated: #{ grunt.template.today() } by [grunt-parker](https://github.com/leny/grunt-parker)." 121 | aLogFileLines.push "" 122 | 123 | grunt.file.write oOptions.file, aLogFileLines.join "\n" 124 | grunt.log.writeln() 125 | grunt.log.writeln "Logged in #{ chalk.yellow( oOptions.file ) }" 126 | -------------------------------------------------------------------------------- /tasks/parker.js: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * grunt-todo 4 | * https://github.com/Leny/grunt-todo 5 | * 6 | * Copyright (c) 2014 leny 7 | * Licensed under the MIT license. 8 | */ 9 | "use strict"; 10 | var Parker, chalk; 11 | 12 | chalk = require("chalk"); 13 | 14 | Parker = require("parker"); 15 | 16 | module.exports = function(grunt) { 17 | return grunt.registerMultiTask("parker", "Stylesheet analysis", function() { 18 | var aLogFileLines, aMetrics, error, i, len, oError, oMetric, oOptions, oParsedMetrics, oProjectPackage, parker, sDefaultTitle, sDescription, sHomePage, sMetric, sTitle, sVersion; 19 | oOptions = this.options({ 20 | metrics: false, 21 | file: false, 22 | title: false, 23 | colophon: false, 24 | usePackage: false 25 | }); 26 | aLogFileLines = []; 27 | sDefaultTitle = "Grunt Parker Report"; 28 | if (grunt.util.kindOf(oOptions.metrics) === "array") { 29 | aMetrics = (function() { 30 | var i, len, ref, results; 31 | ref = oOptions.metrics; 32 | results = []; 33 | for (i = 0, len = ref.length; i < len; i++) { 34 | sMetric = ref[i]; 35 | results.push(require("parker/metrics/" + sMetric + ".js")); 36 | } 37 | return results; 38 | })(); 39 | } else { 40 | aMetrics = require("parker/metrics/All.js"); 41 | } 42 | parker = new Parker(aMetrics); 43 | oParsedMetrics = {}; 44 | for (i = 0, len = aMetrics.length; i < len; i++) { 45 | oMetric = aMetrics[i]; 46 | oParsedMetrics[oMetric.id] = oMetric; 47 | } 48 | if (oOptions.usePackage) { 49 | try { 50 | oProjectPackage = grunt.file.readJSON((process.cwd()) + "/package.json"); 51 | } catch (error) { 52 | oError = error; 53 | grunt.log.writeln(""); 54 | grunt.log.writeln(chalk.yellow.bold("Oops:"), "No " + (chalk.cyan('package.json')) + " file found. Disabling " + (chalk.green('usePackage')) + " option."); 55 | oOptions.usePackage = false; 56 | } 57 | } 58 | if (oOptions.file) { 59 | if (sTitle = oOptions.title || (oOptions.usePackage && oProjectPackage.name ? oProjectPackage.name : false) || sDefaultTitle) { 60 | if (oOptions.usePackage) { 61 | if (sHomePage = oProjectPackage.homepage) { 62 | aLogFileLines.push("# [" + sTitle + "]( " + sHomePage + " )"); 63 | } else { 64 | aLogFileLines.push("# " + sTitle); 65 | } 66 | aLogFileLines.push(""); 67 | if (sVersion = oProjectPackage.version) { 68 | aLogFileLines.push("**Version:** `" + sVersion + "`"); 69 | aLogFileLines.push(""); 70 | } 71 | if (sDescription = oProjectPackage.description) { 72 | aLogFileLines.push("> " + sDescription); 73 | aLogFileLines.push(""); 74 | aLogFileLines.push("* * *"); 75 | aLogFileLines.push(""); 76 | } 77 | } else { 78 | aLogFileLines.push("# " + sTitle); 79 | aLogFileLines.push(""); 80 | } 81 | if (sTitle !== sDefaultTitle) { 82 | aLogFileLines.push("## Parker Report"); 83 | } 84 | } else { 85 | aLogFileLines.push("# " + sDefaultTitle); 86 | } 87 | aLogFileLines.push(""); 88 | } 89 | this.filesSrc.filter(function(sFilePath) { 90 | return grunt.file.exists(sFilePath) && grunt.file.isFile(sFilePath); 91 | }).forEach(function(sFilePath) { 92 | var aFileResults, aResult, aResults, j, len1, mValue, oParkerMetrics, sResult, sValue; 93 | aResults = []; 94 | aFileResults = []; 95 | oParkerMetrics = parker.run(grunt.file.read(sFilePath)); 96 | if (oParkerMetrics) { 97 | for (sMetric in oParkerMetrics) { 98 | mValue = oParkerMetrics[sMetric]; 99 | aResults.push([oParsedMetrics[sMetric].name, mValue]); 100 | } 101 | if (aResults.length) { 102 | if (!oOptions.file) { 103 | grunt.log.writeln(); 104 | grunt.log.writeln(chalk.underline(sFilePath)); 105 | grunt.log.writeln(); 106 | } 107 | for (j = 0, len1 = aResults.length; j < len1; j++) { 108 | aResult = aResults[j]; 109 | sValue = (function() { 110 | var k, l, len2, len3, ref, ref1, results; 111 | switch (grunt.util.kindOf(aResult[1])) { 112 | case "array": 113 | if (!oOptions.file) { 114 | grunt.log.writeln(chalk.cyan(aResult[0] + ":")); 115 | ref = aResult[1]; 116 | for (k = 0, len2 = ref.length; k < len2; k++) { 117 | sResult = ref[k]; 118 | grunt.log.writeln("\t" + sResult); 119 | } 120 | } 121 | aFileResults.push("- **" + aResult[0] + ":**"); 122 | ref1 = aResult[1]; 123 | results = []; 124 | for (l = 0, len3 = ref1.length; l < len3; l++) { 125 | sResult = ref1[l]; 126 | if (sResult.substring(0, 1) === "#") { 127 | sResult = "`" + sResult + "`"; 128 | } 129 | results.push(aFileResults.push("\t- " + sResult)); 130 | } 131 | return results; 132 | break; 133 | case "number": 134 | if (!oOptions.file) { 135 | grunt.log.writeln(chalk.cyan(aResult[0] + ":"), chalk.yellow(aResult[1])); 136 | } 137 | return aFileResults.push("- **" + aResult[0] + ":** " + aResult[1]); 138 | default: 139 | if (!oOptions.file) { 140 | grunt.log.writeln(chalk.cyan(aResult[0] + ":"), aResult[1]); 141 | } 142 | return aFileResults.push("- **" + aResult[0] + ":** " + aResult[1]); 143 | } 144 | })(); 145 | } 146 | } 147 | } 148 | if (oOptions.file && aFileResults.length) { 149 | aLogFileLines.push("### " + sFilePath); 150 | aLogFileLines.push(""); 151 | aLogFileLines = aLogFileLines.concat(aFileResults); 152 | return aLogFileLines.push(""); 153 | } 154 | }); 155 | if (oOptions.file) { 156 | if (oOptions.colophon) { 157 | aLogFileLines.push(""); 158 | aLogFileLines.push("* * *"); 159 | aLogFileLines.push(""); 160 | aLogFileLines.push("Last generated: " + (grunt.template.today()) + " by [grunt-parker](https://github.com/leny/grunt-parker)."); 161 | aLogFileLines.push(""); 162 | } 163 | grunt.file.write(oOptions.file, aLogFileLines.join("\n")); 164 | grunt.log.writeln(); 165 | return grunt.log.writeln("Logged in " + (chalk.yellow(oOptions.file))); 166 | } 167 | }); 168 | }; 169 | -------------------------------------------------------------------------------- /test/test.css: -------------------------------------------------------------------------------- 1 | a { 2 | color: #33a; 3 | } 4 | abbr { 5 | border-bottom: 0.1rem dotted #808080; 6 | cursor: help; 7 | } 8 | html { 9 | background-image: url("img/old_mathematics.png"); 10 | font: normal 62.5%/1.5 "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 11 | -webkit-font-smoothing: antialiased; 12 | -webkit-text-size-adjust: 100%; 13 | } 14 | @media only screen and (-webkit-min-device-pixel-ratio: 1.3), only screen and (min--moz-device-pixel-ratio: 1.3), only screen and (-o-min-device-pixel-ratio: 1.3/1), only screen and (min-device-pixel-ratio: 1.3), only screen and (min-resolution: 125dpi), only screen and (min-resolution: 1.3dppx) { 15 | html { 16 | background-image: url("img/old_mathematics_@2X.png"); 17 | background-size: 200px 200px; 18 | } 19 | } 20 | body { 21 | padding: 1rem; 22 | color: #333; 23 | } 24 | article { 25 | position: relative; 26 | } 27 | header { 28 | margin: 0 auto 2rem; 29 | padding: 0 0 0.5rem; 30 | border-bottom: 0.1rem solid #999; 31 | box-shadow: 0 0.1rem 0.1rem #fff; 32 | } 33 | header:before, 34 | header:after { 35 | content: " "; 36 | display: table; 37 | } 38 | header:after { 39 | clear: both; 40 | } 41 | header h1 { 42 | font: bold 3rem "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 43 | color: #555; 44 | text-align: center; 45 | } 46 | header h2 { 47 | font: 200 2rem "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 48 | color: #666; 49 | text-align: center; 50 | } 51 | figure { 52 | width: 10rem; 53 | margin: 1rem auto; 54 | padding: 0.75rem 0.75rem 0.25rem; 55 | background-image: url("img/ricepaper2.png"); 56 | box-shadow: 0 0.5rem 1rem rgba(0,0,0,0.33); 57 | } 58 | @media only screen and (-webkit-min-device-pixel-ratio: 1.3), only screen and (min--moz-device-pixel-ratio: 1.3), only screen and (-o-min-device-pixel-ratio: 1.3/1), only screen and (min-device-pixel-ratio: 1.3), only screen and (min-resolution: 125dpi), only screen and (min-resolution: 1.3dppx) { 59 | figure { 60 | background-image: url("img/ricepaper2_@2X.png"); 61 | background-size: 485px 485px; 62 | } 63 | } 64 | figure img { 65 | display: block; 66 | max-width: 100%; 67 | margin: 0 auto 0.25rem; 68 | } 69 | figure figcaption { 70 | color: #444; 71 | text-align: right; 72 | } 73 | section { 74 | margin: 0 auto 3rem; 75 | } 76 | section h3 { 77 | position: relative; 78 | margin: 0 auto 0.75rem; 79 | padding: 0 0 0.25rem; 80 | border-bottom: 0.1rem solid #999; 81 | box-shadow: 0 0.1rem 0.1rem #fff; 82 | font: 200 2.5rem "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 83 | color: #666; 84 | text-align: right; 85 | } 86 | section h3:before { 87 | position: absolute; 88 | bottom: -0.6rem; 89 | left: 0; 90 | margin: 0; 91 | font: normal 4rem "Entypo"; 92 | vertical-align: middle; 93 | } 94 | section p { 95 | margin: 0 auto 1.2rem; 96 | font: normal 1.4rem/1.5 "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 97 | } 98 | section h4 { 99 | margin: 0 auto 1.5rem; 100 | padding: 0 0 0.25rem; 101 | border-bottom: 0.1rem dotted #999; 102 | box-shadow: 0 0.1rem 0.1rem #fff; 103 | font: 200 1.6rem "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 104 | color: #666; 105 | text-align: right; 106 | } 107 | section dl { 108 | margin: 0 auto 1rem; 109 | } 110 | section dl dt { 111 | margin: 0 auto 0.25rem; 112 | font: bold 1.3rem "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 113 | color: #555; 114 | } 115 | section dl dd { 116 | margin: 0 auto 1rem 2.6rem; 117 | font: 200 1.3rem/1.5 "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 118 | color: #555; 119 | } 120 | section[id="identite"] { 121 | margin: 2rem auto 3rem; 122 | } 123 | section[id="identite"] p { 124 | margin: 0 auto 0.75rem; 125 | font: normal 1.5rem "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 126 | } 127 | section[id="identite"] address ~ p { 128 | margin: 0.5rem 0 1rem; 129 | } 130 | section[id="identite"] address ~ p strong { 131 | display: none; 132 | } 133 | section[id="identite"] address ~ p a { 134 | text-decoration: none; 135 | } 136 | section[id="identite"] address ~ p a:before { 137 | margin: 0 0.5rem 0 0; 138 | font: normal 3rem/1.5rem "Entypo"; 139 | vertical-align: middle; 140 | } 141 | section[id="identite"] address ~ p.mail a:before { 142 | content: "\2709"; 143 | } 144 | section[id="identite"] address ~ p.site a:before { 145 | content: "\1F517"; 146 | } 147 | section[id="parcours"] h3:before { 148 | content: "\E723"; 149 | } 150 | section[id="formation"] h3:first-of-type:before { 151 | content: "\E728"; 152 | } 153 | section[id="formation"] h3:last-of-type:before { 154 | content: "\1F3C6"; 155 | } 156 | section[id="parcours"] ol, 157 | section[id="formation"] ol { 158 | list-style: inside none; 159 | } 160 | section[id="parcours"] ol li, 161 | section[id="formation"] ol li { 162 | margin: 0 auto 2rem; 163 | padding: 1rem; 164 | border: 0.1rem solid #c0c0c0; 165 | border-radius: 0.6rem; 166 | background-image: url("img/subtle_freckles.png"); 167 | } 168 | @media only screen and (-webkit-min-device-pixel-ratio: 1.3), only screen and (min--moz-device-pixel-ratio: 1.3), only screen and (-o-min-device-pixel-ratio: 1.3/1), only screen and (min-device-pixel-ratio: 1.3), only screen and (min-resolution: 125dpi), only screen and (min-resolution: 1.3dppx) { 169 | section[id="parcours"] ol li, 170 | section[id="formation"] ol li { 171 | background-image: url("img/subtle_freckles_@2X.png"); 172 | background-size: 198px 198px; 173 | } 174 | } 175 | section[id="parcours"] ol li h4:before, 176 | section[id="formation"] ol li h4:before, 177 | section[id="parcours"] ol li p:before, 178 | section[id="formation"] ol li p:before { 179 | font: normal 3rem "Entypo"; 180 | margin: 0 0.5rem 0 0; 181 | vertical-align: middle; 182 | } 183 | section[id="parcours"] ol li h4, 184 | section[id="formation"] ol li h4 { 185 | font: bold 1.4rem "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 186 | margin: 0 auto 0.25rem; 187 | color: #444; 188 | text-align: left; 189 | border-bottom: 0; 190 | box-shadow: none; 191 | } 192 | section[id="parcours"] ol li h4 a, 193 | section[id="formation"] ol li h4 a { 194 | text-decoration: none; 195 | } 196 | section[id="parcours"] ol li h4:before, 197 | section[id="formation"] ol li h4:before { 198 | line-height: 1.6rem; 199 | vertical-align: bottom; 200 | } 201 | section[id="parcours"] ol li p, 202 | section[id="formation"] ol li p { 203 | font: normal 1.25rem/1.5 "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 204 | margin: 0 auto 0.5rem; 205 | } 206 | section[id="parcours"] ol li p strong, 207 | section[id="formation"] ol li p strong { 208 | font-weight: bold; 209 | } 210 | section[id="parcours"] ol li p:before, 211 | section[id="formation"] ol li p:before { 212 | vertical-align: -0.1rem; 213 | } 214 | section[id="parcours"] ol li .time, 215 | section[id="formation"] ol li .time { 216 | display: inline-block; 217 | margin: 0 1rem 0 0; 218 | font: normal 1.25rem/1.5 "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 219 | } 220 | section[id="parcours"] ol li .time:before, 221 | section[id="formation"] ol li .time:before { 222 | font: normal 3rem "Entypo"; 223 | content: "\1F4C5"; 224 | vertical-align: -0.25rem; 225 | margin: 0 0.25rem 0 0; 226 | } 227 | section[id="parcours"] ol li .time ~ p, 228 | section[id="formation"] ol li .time ~ p { 229 | display: inline-block; 230 | font: normal 1.25rem/1.5 "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 231 | margin: 0 auto; 232 | } 233 | section[id="parcours"] ol li .time ~ p:before, 234 | section[id="formation"] ol li .time ~ p:before { 235 | font: normal 3rem "Entypo"; 236 | content: "\E728"; 237 | vertical-align: middle; 238 | margin: 0 0.25rem 0 0; 239 | } 240 | section[id="parcours"] ol:first-of-type li h4:before, 241 | section[id="formation"] ol:first-of-type li h4:before { 242 | content: "\1F4D6"; 243 | } 244 | section[id="parcours"] ol:last-of-type li h4:before, 245 | section[id="formation"] ol:last-of-type li h4:before { 246 | content: "\1F4BC"; 247 | } 248 | section[id="parcours"] ol:last-of-type li h4 + p:before, 249 | section[id="formation"] ol:last-of-type li h4 + p:before { 250 | content: "\1F464"; 251 | } 252 | section[id="competences"] h3:before { 253 | content: "\26A1"; 254 | } 255 | section[id="presentation"] dl, 256 | section[id="presentation"] p { 257 | margin: 0 auto 3rem; 258 | } 259 | section[id="presentation"] h3:nth-of-type(1):before { 260 | content: "\E720"; 261 | } 262 | section[id="presentation"] h3:nth-of-type(2):before { 263 | content: "\1F342"; 264 | } 265 | section[id="presentation"] h3:nth-of-type(3):before { 266 | content: "\1F50A"; 267 | } 268 | @media screen and (min-width: 30rem) { 269 | header h1 br { 270 | display: none; 271 | } 272 | figure { 273 | float: left; 274 | margin: 0 2rem 0.5rem 1.5rem; 275 | -webkit-transform: rotate(-2deg) translate3d(0, 0, 0); 276 | -ms-transform: rotate(-2deg) translate3d(0, 0, 0); 277 | transform: rotate(-2deg) translate3d(0, 0, 0); 278 | } 279 | section[id="identite"] { 280 | margin: 3rem auto 3rem; 281 | } 282 | section[id="identite"]:before, 283 | section[id="identite"]:after { 284 | content: " "; 285 | display: table; 286 | } 287 | section[id="identite"]:after { 288 | clear: both; 289 | } 290 | section[id="parcours"] ol li h4, 291 | section[id="formation"] ol li h4 { 292 | margin: 0 auto 0.05rem; 293 | font: bold 1.6rem "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 294 | } 295 | } 296 | @media screen and (min-width: 40rem) { 297 | header h1 { 298 | float: left; 299 | } 300 | header h2 { 301 | float: right; 302 | margin: 0.25rem 0 0; 303 | font: 200 2.25rem "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 304 | } 305 | figure { 306 | width: 15rem; 307 | margin: -2.5rem 3rem 0.5rem 1.5rem; 308 | -webkit-transform-style: preserve-3d; 309 | transform-style: preserve-3d; 310 | -webkit-transform: rotate(-3deg) translate3d(0, 0, 0); 311 | -ms-transform: rotate(-3deg) translate3d(0, 0, 0); 312 | transform: rotate(-3deg) translate3d(0, 0, 0); 313 | } 314 | section h3 { 315 | padding-left: 2.75rem; 316 | text-align: left; 317 | } 318 | section h3:before { 319 | bottom: -0.35rem; 320 | font-size: 4rem; 321 | } 322 | section h4 { 323 | text-align: left; 324 | } 325 | } 326 | @media screen and (min-width: 48rem) { 327 | article { 328 | -webkit-column-count: 2; 329 | -moz-column-count: 2; 330 | column-count: 2; 331 | -webkit-column-gap: 3%; 332 | -moz-column-gap: 3%; 333 | column-gap: 3%; 334 | -webkit-column-width: 46%; 335 | -moz-column-width: 46%; 336 | column-width: 46%; 337 | } 338 | header { 339 | -webkit-column-span: all; 340 | -moz-column-span: all; 341 | column-span: all; 342 | } 343 | section h4 { 344 | text-align: right; 345 | } 346 | section[id="identite"] { 347 | -webkit-column-span: all; 348 | -moz-column-span: all; 349 | column-span: all; 350 | } 351 | section[id="competences"] { 352 | -moz-break-before: column; 353 | -webkit-column-break-before: always; 354 | } 355 | } 356 | @media screen and (min-width: 60rem) { 357 | html { 358 | background: #110416; 359 | background-image: url("img/dark_wood.png"); 360 | } 361 | article { 362 | width: 90%; 363 | margin: 3rem auto; 364 | padding: 2rem; 365 | background: #fff; 366 | background-image: url("img/old_mathematics.png"); 367 | box-shadow: 0 5px 20px rgba(0,0,0,0.5); 368 | } 369 | header h2 { 370 | margin-right: 17.5rem; 371 | } 372 | figure { 373 | position: absolute; 374 | width: 20rem; 375 | float: none; 376 | top: -0.5rem; 377 | right: -1.5rem; 378 | margin: 0; 379 | z-index: 150; 380 | -webkit-transform: rotate(5deg) translate3d(0, 0, 0); 381 | -ms-transform: rotate(5deg) translate3d(0, 0, 0); 382 | transform: rotate(5deg) translate3d(0, 0, 0); 383 | } 384 | } 385 | @media screen and (min-width: 80rem) { 386 | article { 387 | max-width: 115rem; 388 | margin: 0 auto; 389 | -webkit-column-count: auto; 390 | -moz-column-count: auto; 391 | column-count: auto; 392 | -webkit-column-gap: normal; 393 | -moz-column-gap: normal; 394 | column-gap: normal; 395 | -webkit-column-width: auto; 396 | -moz-column-width: auto; 397 | column-width: auto; 398 | background: transparent; 399 | box-shadow: none; 400 | } 401 | article:before, 402 | article:after { 403 | content: " "; 404 | display: table; 405 | } 406 | article:after { 407 | clear: both; 408 | } 409 | figure { 410 | position: absolute; 411 | top: 1rem; 412 | right: -1.5rem; 413 | z-index: 100; 414 | -webkit-transform: rotate(-2deg) translate3d(0, 0, 0); 415 | -ms-transform: rotate(-2deg) translate3d(0, 0, 0); 416 | transform: rotate(-2deg) translate3d(0, 0, 0); 417 | -webkit-transition: all 0.15s ease-in-out; 418 | transition: all 0.15s ease-in-out; 419 | } 420 | figure:hover { 421 | -webkit-transform: rotate(0deg) translate3d(0, 0, 0); 422 | -ms-transform: rotate(0deg) translate3d(0, 0, 0); 423 | transform: rotate(0deg) translate3d(0, 0, 0); 424 | } 425 | header { 426 | position: absolute; 427 | width: 50rem; 428 | top: 1rem; 429 | left: 0; 430 | margin: 0; 431 | z-index: 10; 432 | box-shadow: none; 433 | border: 0; 434 | } 435 | header:before, 436 | header:after { 437 | content: " "; 438 | display: table; 439 | } 440 | header:after { 441 | clear: both; 442 | } 443 | header h1 { 444 | float: none; 445 | margin: 0 auto; 446 | border-bottom: 0.1rem solid #999; 447 | font: bold 3.5rem "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 448 | color: #ddd; 449 | text-align: left; 450 | } 451 | header h2 { 452 | float: none; 453 | margin-right: 0; 454 | font: normal 2.75rem "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 455 | color: #c0c0c0; 456 | text-align: right; 457 | } 458 | section { 459 | position: absolute; 460 | border: 0; 461 | margin: 0; 462 | -webkit-transition: all 0.1s ease-in; 463 | transition: all 0.1s ease-in; 464 | -webkit-transform-style: preserve-3d; 465 | transform-style: preserve-3d; 466 | } 467 | section:before, 468 | section:after { 469 | content: " "; 470 | display: table; 471 | } 472 | section:after { 473 | clear: both; 474 | } 475 | section h3 { 476 | box-shadow: none; 477 | color: #c0c0c0; 478 | } 479 | section h4 { 480 | box-shadow: none; 481 | color: #ccc; 482 | } 483 | section ol li, 484 | section dl, 485 | section h3 + p { 486 | padding: 1rem; 487 | background: #fff; 488 | background-image: url("img/subtle_freckles.png"); 489 | border: 0; 490 | border-radius: 0; 491 | box-shadow: 0 0 0.5rem rgba(0,0,0,0.5); 492 | -webkit-transition: all 0.15s ease-in-out; 493 | transition: all 0.15s ease-in-out; 494 | } 495 | section ol li:nth-of-type(1 ), 496 | section dl:nth-of-type(1 ), 497 | section h3 + p:nth-of-type(1 ) { 498 | -webkit-transform: rotate(2deg) translate3d(0, 0, 0); 499 | -ms-transform: rotate(2deg) translate3d(0, 0, 0); 500 | transform: rotate(2deg) translate3d(0, 0, 0); 501 | } 502 | section ol li:nth-of-type(2 ), 503 | section dl:nth-of-type(2 ), 504 | section h3 + p:nth-of-type(2 ) { 505 | -webkit-transform: rotate(-1deg) translate3d(0, 0, 0); 506 | -ms-transform: rotate(-1deg) translate3d(0, 0, 0); 507 | transform: rotate(-1deg) translate3d(0, 0, 0); 508 | } 509 | section ol li:nth-of-type(3 ), 510 | section dl:nth-of-type(3 ), 511 | section h3 + p:nth-of-type(3 ) { 512 | -webkit-transform: rotate(1deg) translate3d(0, 0, 0); 513 | -ms-transform: rotate(1deg) translate3d(0, 0, 0); 514 | transform: rotate(1deg) translate3d(0, 0, 0); 515 | } 516 | section ol li:nth-of-type(4 ), 517 | section dl:nth-of-type(4 ), 518 | section h3 + p:nth-of-type(4 ) { 519 | -webkit-transform: rotate(-2deg) translate3d(0, 0, 0); 520 | -ms-transform: rotate(-2deg) translate3d(0, 0, 0); 521 | transform: rotate(-2deg) translate3d(0, 0, 0); 522 | } 523 | section ol li:nth-of-type(5 ), 524 | section dl:nth-of-type(5 ), 525 | section h3 + p:nth-of-type(5 ) { 526 | -webkit-transform: rotate(3deg) translate3d(0, 0, 0); 527 | -ms-transform: rotate(3deg) translate3d(0, 0, 0); 528 | transform: rotate(3deg) translate3d(0, 0, 0); 529 | } 530 | section ol li:nth-of-type(6 ), 531 | section dl:nth-of-type(6 ), 532 | section h3 + p:nth-of-type(6 ) { 533 | -webkit-transform: rotate(-1deg) translate3d(0, 0, 0); 534 | -ms-transform: rotate(-1deg) translate3d(0, 0, 0); 535 | transform: rotate(-1deg) translate3d(0, 0, 0); 536 | } 537 | section ol li:nth-of-type(7 ), 538 | section dl:nth-of-type(7 ), 539 | section h3 + p:nth-of-type(7 ) { 540 | -webkit-transform: rotate(2deg) translate3d(0, 0, 0); 541 | -ms-transform: rotate(2deg) translate3d(0, 0, 0); 542 | transform: rotate(2deg) translate3d(0, 0, 0); 543 | } 544 | section ol li:nth-of-type(8 ), 545 | section dl:nth-of-type(8 ), 546 | section h3 + p:nth-of-type(8 ) { 547 | -webkit-transform: rotate(-3deg) translate3d(0, 0, 0); 548 | -ms-transform: rotate(-3deg) translate3d(0, 0, 0); 549 | transform: rotate(-3deg) translate3d(0, 0, 0); 550 | } 551 | section ol li:nth-of-type(9 ), 552 | section dl:nth-of-type(9 ), 553 | section h3 + p:nth-of-type(9 ) { 554 | -webkit-transform: rotate(1deg) translate3d(0, 0, 0); 555 | -ms-transform: rotate(1deg) translate3d(0, 0, 0); 556 | transform: rotate(1deg) translate3d(0, 0, 0); 557 | } 558 | section ol li:hover, 559 | section dl:hover, 560 | section h3 + p:hover { 561 | -webkit-transform: rotate(0deg) translate3d(0, 0, 0); 562 | -ms-transform: rotate(0deg) translate3d(0, 0, 0); 563 | transform: rotate(0deg) translate3d(0, 0, 0); 564 | } 565 | section[id="identite"] { 566 | width: 50rem; 567 | top: 5.5rem; 568 | left: 0; 569 | z-index: 50; 570 | } 571 | section[id="identite"] p { 572 | color: #c0c0c0; 573 | } 574 | section[id="identite"] address ~ p { 575 | display: inline; 576 | } 577 | section[id="identite"] address ~ p a { 578 | color: #4d4dca; 579 | } 580 | section[id="identite"] address + p { 581 | margin-right: 1.5rem; 582 | } 583 | section[id="parcours"] ol li, 584 | section[id="formation"] ol li { 585 | border-radius: 0; 586 | } 587 | section[id="parcours"] ol li + li, 588 | section[id="formation"] ol li + li { 589 | margin-top: -2rem; 590 | } 591 | section[id="formation"] { 592 | width: 22%; 593 | top: 18rem; 594 | left: 0; 595 | } 596 | section[id="parcours"] { 597 | width: 22%; 598 | left: 24%; 599 | top: 18rem; 600 | margin: 0 auto 2.5rem; 601 | z-index: 60; 602 | } 603 | section[id="competences"] { 604 | width: 26%; 605 | left: 48%; 606 | top: 18rem; 607 | z-index: 70; 608 | } 609 | section[id="presentation"] { 610 | width: 24%; 611 | left: 76%; 612 | top: 26rem; 613 | z-index: 80; 614 | } 615 | } 616 | @media print { 617 | abbr { 618 | border-bottom: 0; 619 | } 620 | html { 621 | font: normal 8.5pt/1.25 "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 622 | } 623 | header { 624 | margin: 0 auto 0; 625 | padding: 0; 626 | box-shadow: none; 627 | border-bottom: 0; 628 | } 629 | header h1 { 630 | float: none; 631 | border-bottom: 0.1rem solid #999; 632 | font: bold 3rem/1 "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 633 | color: #666; 634 | text-align: left; 635 | } 636 | header h1 br { 637 | display: none; 638 | } 639 | header h2 { 640 | float: none; 641 | margin: 0 0.25rem 0 0; 642 | font: 200 2rem/1.25 "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 643 | color: #666; 644 | text-align: right; 645 | } 646 | figure { 647 | display: none; 648 | } 649 | section { 650 | page-break-inside: avoid; 651 | margin: 0 auto 2rem; 652 | } 653 | section h3 { 654 | margin: 0.5rem auto 1.5rem; 655 | border-bottom: 0.1rem dotted #999; 656 | box-shadow: none; 657 | font: bold 1.5rem "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 658 | color: #666; 659 | } 660 | section h3:before { 661 | margin: 0 0.5rem 0 0; 662 | font: normal 3rem "Entypo"; 663 | vertical-align: middle; 664 | } 665 | section p { 666 | margin: 0 auto 0.6rem; 667 | font: normal 1.1rem/1.5 "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 668 | } 669 | section blockquote { 670 | position: relative; 671 | margin: 0 auto 1.2rem; 672 | padding: 2rem; 673 | border: 0.1rem dashed #c0c0c0; 674 | border-radius: 6px; 675 | box-shadow: 0 0 2rem #c0c0c0; 676 | background: #fff url("subtle_freckles.png") top left repeat; 677 | } 678 | section blockquote:before { 679 | content: ""; 680 | position: absolute; 681 | bottom: 1rem; 682 | right: 1rem; 683 | z-index: 10; 684 | font: normal 15rem "Entypo"; 685 | color: #ccc; 686 | } 687 | section blockquote p { 688 | position: relative; 689 | z-index: 11; 690 | } 691 | section h4 { 692 | margin: 0 auto 1rem; 693 | padding: 0; 694 | border-bottom: 0; 695 | box-shadow: none; 696 | font: 200 1.3rem "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 697 | color: #444; 698 | text-align: left; 699 | } 700 | section dl { 701 | margin: 0 auto 1rem; 702 | } 703 | section dl dt { 704 | float: left; 705 | margin: 0 0.1rem 0.25rem 0; 706 | font: normal 1.1rem "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 707 | color: #333; 708 | } 709 | section dl dd { 710 | margin: 0 0 1rem; 711 | font: normal 1.1rem/1.5 "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 712 | color: #555; 713 | } 714 | section dl dd:after { 715 | content: ""; 716 | display: table; 717 | clear: both; 718 | } 719 | section[id="identite"] { 720 | margin: 2rem 0; 721 | } 722 | section[id="identite"] p { 723 | font: normal 1.1rem/1 "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 724 | margin: 0 auto 0.6rem; 725 | } 726 | section[id="identite"] address ~ p { 727 | display: inline-block; 728 | margin: 0.5rem 3rem 0 0; 729 | font: normal 1rem/1 "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 730 | } 731 | section[id="identite"] address ~ p strong { 732 | display: none; 733 | } 734 | section[id="identite"] address ~ p a { 735 | color: #333; 736 | } 737 | section[id="identite"] address ~ p a:before { 738 | margin: 0 0.3rem 0 0; 739 | font: normal 2rem "Entypo"; 740 | vertical-align: top; 741 | } 742 | section[id="identite"] address ~ p.mail a:before { 743 | content: "\2709"; 744 | } 745 | section[id="identite"] address ~ p.site a:before { 746 | content: "\2709"; 747 | } 748 | section[id="parcours"] ol, 749 | section[id="formation"] ol { 750 | list-style: inside none; 751 | } 752 | section[id="parcours"] ol li, 753 | section[id="formation"] ol li { 754 | margin: 0 auto 1rem 1rem; 755 | padding: 0; 756 | border: 0; 757 | border-radius: 0; 758 | background: transparent; 759 | } 760 | section[id="parcours"] ol li h4, 761 | section[id="formation"] ol li h4 { 762 | margin: 0 auto; 763 | border-bottom: 0; 764 | box-shadow: none; 765 | font: bold 1.4rem/1 "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 766 | color: #333; 767 | text-align: left; 768 | } 769 | section[id="parcours"] ol li h4 a, 770 | section[id="formation"] ol li h4 a { 771 | font: bold 1.4rem "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 772 | color: #444; 773 | } 774 | section[id="parcours"] ol li p, 775 | section[id="formation"] ol li p { 776 | display: inline-block; 777 | margin: 0 0.5rem 0 0; 778 | font: normal 1.2rem/1.25 "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 779 | color: #666; 780 | } 781 | section[id="parcours"] ol li p strong, 782 | section[id="formation"] ol li p strong { 783 | margin: 0 0.5rem 0 0; 784 | font-weight: bold; 785 | } 786 | section[id="parcours"] ol li p br, 787 | section[id="formation"] ol li p br { 788 | display: none; 789 | line-height: 0; 790 | } 791 | section[id="parcours"] ol li p:first-of-type, 792 | section[id="formation"] ol li p:first-of-type { 793 | margin-left: 2.5rem; 794 | } 795 | section[id="parcours"] ol li .time, 796 | section[id="formation"] ol li .time { 797 | display: inline-block; 798 | margin: 0 0.5rem 0 0; 799 | font: normal 1.2rem/1.25 "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 800 | color: #666; 801 | } 802 | section[id="parcours"] ol li .time:before, 803 | section[id="formation"] ol li .time:before { 804 | content: "\1F4C5"; 805 | margin: 0 0.5rem 0 0; 806 | font: normal 2.4rem "Entypo"; 807 | vertical-align: baseline; 808 | } 809 | section[id="parcours"] ol li .time ~ p, 810 | section[id="formation"] ol li .time ~ p { 811 | display: inline-block; 812 | font: normal 1.2rem/1.25 "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; 813 | color: #666; 814 | } 815 | section[id="parcours"] ol li .time ~ p:before, 816 | section[id="formation"] ol li .time ~ p:before { 817 | content: "\E728"; 818 | margin: 0 0.25rem 0 0; 819 | font: normal 2rem "Entypo"; 820 | vertical-align: baseline; 821 | } 822 | section[id="parcours"] ol:first-of-type li h4:before, 823 | section[id="formation"] ol:first-of-type li h4:before { 824 | content: "\1F4D6"; 825 | margin: 0 0.5rem 0 0; 826 | font: normal 3.5rem "Entypo"; 827 | vertical-align: middle; 828 | } 829 | section[id="parcours"] ol:last-of-type li h4:before, 830 | section[id="formation"] ol:last-of-type li h4:before { 831 | content: "\1F4BC"; 832 | margin: 0 0.5rem 0 0; 833 | font: normal 3.5rem "Entypo"; 834 | vertical-align: middle; 835 | } 836 | section[id="parcours"] ol:last-of-type li h4 + p:before, 837 | section[id="formation"] ol:last-of-type li h4 + p:before { 838 | content: "\1F464"; 839 | margin: 0 0.5rem 0 0; 840 | font: normal 2.75rem "Entypo"; 841 | vertical-align: -0.25rem; 842 | } 843 | section[id="parcours"] h3:before { 844 | content: "\E723"; 845 | } 846 | section[id="parcours"] ol li p { 847 | display: block; 848 | } 849 | section[id="parcours"] ol li .time { 850 | margin-left: 2.5rem; 851 | } 852 | section[id="parcours"] ol li:last-of-type p:nth-child(3 ) { 853 | display: none; 854 | } 855 | section[id="formation"] h3:first-of-type:before { 856 | content: "\E728"; 857 | } 858 | section[id="formation"] h3:last-of-type { 859 | display: none; 860 | } 861 | section[id="formation"] ol:first-of-type li:nth-child(2 ) { 862 | display: none; 863 | } 864 | section[id="formation"] ol:last-of-type { 865 | display: none; 866 | } 867 | section[id="competences"] h3:before { 868 | content: "\26A1"; 869 | } 870 | section[id="presentation"] h3 { 871 | margin-top: 2rem; 872 | } 873 | section[id="presentation"] h3:nth-of-type(1 ):before { 874 | content: "\E720"; 875 | } 876 | section[id="presentation"] h3:nth-of-type(2 ):before { 877 | content: "\1F342"; 878 | } 879 | section[id="presentation"] h3:nth-of-type(3 ):before { 880 | content: "\1F50A"; 881 | } 882 | } 883 | --------------------------------------------------------------------------------