Trying to learn Vue.js... This is a remix of one of my previous pens that we used at work for an internal hackathon. Converted this to Vue.js from AngularJS. Boo! Firefox doesn't like CSS writing-mode yet.
A Pen by adammmanka on CodePen.
| <main> | |
| <section v-for="(day, index) in schedule"> | |
| <header> | |
| Day {{index+1}} — {{day.date | date}} | |
| </header> | |
| <ul> | |
| <li v-for="slot in day.agenda" v-bind:class="{ current: checkTime(slot.range[0], slot.range[1]) }"> | |
| <h3><b>{{slot.display.h}}</b>{{slot.display.m}}{{slot.display.a}}</h3> | |
| <div v-html="slot.desc"></div> | |
| <div><small v-html="slot.location"></small></div> | |
| </li> | |
| <li class="after-hours"> | |
| <div> | |
| <b>Day {{index+1}}</b> | |
| <br />Before / After Hours | |
| <br /><small><small>Click the Event Scroller</small></small> | |
| </div> | |
| </li> | |
| </ul> | |
| </section> | |
| </main> | |
| <aside> | |
| <div class="clock"> | |
| <h3>{{time}}</h3> | |
| </div> | |
| <div class="control" v-bind:class="{ show: showTimeTraveller }"> | |
| <header v-on:click="showTimeTraveller = !showTimeTraveller"> | |
| <div><b>Event Scroller</b></div> | |
| <button><span>_</span></button> | |
| </header> | |
| <div> | |
| <p><input type="range" min="0" max="23.9" step="0.1" v-model="now" id="traveler" /></p> | |
| <p>To-do: Multi-day Traversing</p> | |
| </div> | |
| </div> | |
| <h1>Coinvention</h1> | |
| <svg class="logo" viewBox="0 0 300 300"> | |
| <path d=""></path> | |
| <path d="M177.832 138.417 C 162.089 155.760,169.908 184.435,192.333 191.598 C 220.200 200.501,244.954 171.302,231.731 145.126 C 230.159 142.014,225.344 135.864,224.868 136.360 C 224.457 136.787,220.000 144.673,220.000 144.974 C 220.000 145.171,220.521 146.057,221.158 146.944 C 229.404 158.421,225.273 174.618,212.513 180.845 C 191.460 191.117,170.367 166.950,183.391 147.478 C 184.305 146.111,185.004 144.878,184.943 144.739 C 184.482 143.671,180.119 136.338,179.945 136.336 C 179.823 136.335,178.872 137.271,177.832 138.417 M219.344 264.250 L 219.333 277.000 220.828 277.000 L 222.323 277.000 222.411 268.046 L 222.500 259.093 231.654 268.713 C 236.688 274.004,240.851 278.333,240.904 278.333 C 240.957 278.333,241.000 272.558,241.000 265.500 L 241.000 252.667 239.500 252.667 L 238.000 252.667 237.996 261.750 L 237.991 270.833 234.903 267.667 C 233.205 265.925,229.012 261.575,225.585 258.000 L 219.355 251.500 219.344 264.250 M322.000 264.333 L 322.000 277.000 323.495 277.000 L 324.989 277.000 325.078 267.992 L 325.167 258.985 334.288 268.576 C 339.305 273.851,343.542 278.217,343.705 278.278 C 343.873 278.341,344.000 272.859,344.000 265.528 L 344.000 252.667 342.339 252.667 L 340.677 252.667 340.589 261.679 L 340.500 270.692 331.500 261.208 C 326.550 255.992,322.387 251.711,322.250 251.695 C 322.112 251.680,322.000 257.367,322.000 264.333 M66.000 252.437 C 53.266 255.346,52.827 273.841,65.412 277.192 C 67.774 277.820,71.216 277.787,73.295 277.116 L 75.000 276.565 75.000 273.140 L 75.000 269.715 73.103 270.858 C 68.374 273.705,62.785 271.013,62.401 265.704 C 61.905 258.847,69.321 255.118,74.250 259.745 L 75.000 260.450 75.000 256.923 L 75.000 253.396 73.454 252.869 C 71.276 252.127,68.150 251.946,66.000 252.437 M93.927 252.324 C 81.719 254.530,79.781 272.189,91.251 276.708 C 100.075 280.183,109.551 274.686,109.955 265.858 C 110.375 256.687,103.220 250.645,93.927 252.324 M295.095 252.799 C 281.361 257.271,284.693 277.455,299.167 277.455 C 315.817 277.455,316.308 252.926,299.667 252.435 C 297.643 252.375,295.993 252.506,295.095 252.799 M119.667 264.833 L 119.667 277.000 122.500 277.000 L 125.333 277.000 125.333 264.833 L 125.333 252.667 122.500 252.667 L 119.667 252.667 119.667 264.833 M136.000 264.833 L 136.000 277.000 138.827 277.000 L 141.654 277.000 141.744 269.457 L 141.833 261.914 148.142 269.457 L 154.451 277.000 157.059 277.000 L 159.667 277.000 159.667 264.833 L 159.667 252.667 156.840 252.667 L 154.013 252.667 153.923 260.237 L 153.833 267.807 147.500 260.246 L 141.167 252.685 138.583 252.676 L 136.000 252.667 136.000 264.833 M167.976 253.417 C 168.137 253.829,170.249 259.342,172.669 265.667 C 175.089 271.992,177.208 277.525,177.377 277.963 C 177.547 278.401,177.757 278.688,177.844 278.600 C 178.049 278.396,187.665 253.249,187.666 252.917 C 187.667 252.477,184.416 252.635,184.250 253.083 C 184.165 253.313,182.700 257.294,180.994 261.930 C 179.289 266.567,177.790 270.242,177.663 270.097 C 177.536 269.952,176.022 265.972,174.299 261.252 L 171.167 252.670 169.425 252.668 C 167.754 252.667,167.695 252.697,167.976 253.417 M196.333 264.833 L 196.333 277.000 202.667 277.000 L 209.000 277.000 209.000 275.667 L 209.000 274.333 204.167 274.333 L 199.333 274.333 199.333 269.833 L 199.333 265.333 204.167 265.333 L 209.000 265.333 209.000 263.833 L 209.000 262.333 204.167 262.333 L 199.333 262.333 199.333 258.833 L 199.333 255.333 204.167 255.333 L 209.000 255.333 209.000 254.000 L 209.000 252.667 202.667 252.667 L 196.333 252.667 196.333 264.833 M249.667 254.000 L 249.667 255.333 252.667 255.333 L 255.667 255.333 255.667 266.167 L 255.667 277.000 257.167 277.000 L 258.667 277.000 258.667 266.167 L 258.667 255.333 261.667 255.333 L 264.667 255.333 264.667 254.000 L 264.667 252.667 257.167 252.667 L 249.667 252.667 249.667 254.000 M273.333 264.833 L 273.333 277.000 274.833 277.000 L 276.333 277.000 276.333 264.833 L 276.333 252.667 274.833 252.667 L 273.333 252.667 273.333 264.833 M302.916 256.001 C 310.287 259.257,310.697 269.590,303.611 273.515 C 299.685 275.690,294.425 274.521,291.627 270.852 C 285.599 262.949,293.906 252.022,302.916 256.001 M99.836 258.288 C 102.658 259.570,104.178 262.320,103.933 265.704 C 103.314 274.263,90.353 274.263,89.734 265.704 C 89.316 259.925,94.715 255.962,99.836 258.288 " transform="translate(159.603449, 185.823334) rotate(180.000000) translate(-159.603449, -185.823334)"></path> | |
| </svg> | |
| </aside> |
Trying to learn Vue.js... This is a remix of one of my previous pens that we used at work for an internal hackathon. Converted this to Vue.js from AngularJS. Boo! Firefox doesn't like CSS writing-mode yet.
A Pen by adammmanka on CodePen.
| ((window) => { | |
| let now = moment() | |
| // JSON DATA | |
| let schedule = [ | |
| { | |
| date: now, | |
| agenda: [ | |
| {range: ['08:00', '08:59'], display: {h:8, m:'', a: 'am'}, location: '', desc: 'Morning Reception'}, | |
| {range: ['09:00', '09:10'], display: {h:9, m:'', a: 'am'}, location: '', desc: 'Opening Remarks - The Future Will Be In Blockchain'}, | |
| {range: ['09:15', '09:34'], display: {h:9, m:15, a: 'am'}, location: '', desc: ''}, | |
| {range: ['09:35', '09:54'], display: {h:9, m:35, a: 'am'}, location: 'Thomas Jay Rush (*MORE TBA*)', desc: 'Fireside Chat: The Value Of Blockchains'}, | |
| {range: ['09:55', '10:10'], display: {h:9, m:55, a: 'am'}, location: 'Bryan Dube', desc: 'Building the Infrastructure of Change: Educating and educating the future generation'}, | |
| {range: ['10:10', '10:39'], display: {h:10, m:10, a: 'am'}, location: '', desc: 'Community Engagements Within Blockchain Technology'}, | |
| {range: ['10:40', '10:59'], display: {h:10, m:40, a: 'am'}, location: 'Simon Manka', desc: 'Careers in Cryptocurrency'}, | |
| {range: ['11:00', '11:25'], display: {h:11, m:'', a: 'am'}, location: '', desc: 'Cryptoeconomics - Blockchain governance mechanisms, consensus mechanisms, chain interoperability'}, | |
| {range: ['11:30', '11:59'], display: {h:11, m:30, a: 'am'}, location: 'Kevin Owocki', desc: 'Developers Developers Developers: The Job Market in a Blockchain World'}, | |
| {range: ['12:00', '12:14'], display: {h:'Noon', m:'', a: '-ish'}, location: '', desc: 'TBA'}, | |
| {range: ['12:15', '12:44'], display: {h:12, m:15, a: 'pm'}, location: '', desc: 'Legal - Regulations, Utility vs Equity, ICO vs STO, Decentralized business models and the law'}, | |
| {range: ['12:45', '13:39'], display: {h:12, m:45, a: 'pm'}, location: '', desc: 'LUNCH'}, | |
| {range: ['13:40', '14:24'], display: {h:1, m:40, a: 'pm'}, location: '', desc: 'ICO/STO Presentation Period'}, | |
| {range: ['14:25', '14:45'], display: {h:2, m:25, a: 'pm'}, location: '', desc: 'The Philadelphia Blockchain Community: <br> Discussing Philadelphia’s Blockchain Strengths, Weaknesses, and Future'}, | |
| {range: ['14:55', '15:14'], display: {h:2, m:55, a: 'pm'}, location: 'Alexandra Levin Kramer Esq.', desc: ''}, | |
| {range: ['15:15', '15:35'], display: {h:3, m:15, a: 'pm'}, location: '', desc: ''}, | |
| {range: ['15:40', '15:54'], display: {h:3, m:40, a: 'pm'}, location: 'Ready set crypto, Crypto Love, (*More TBA*)', desc: 'Youtube influencer panel: Their picks, their thoughts and their vision of the Future in Blockchain'}, | |
| {range: ['15:55', '16:19'], display: {h:3, m:55, a: 'pm'}, location: '', desc: 'The Great Healthcare & Data Exchange: The implications and social impact of bringing blockchain technology to forefront of healthcare markets.'}, | |
| {range: ['16:20', '16:35'], display: {h:4, m:20, a: 'pm'}, location: '', desc: 'TBA'}, | |
| {range: ['16:40', '17:59'], display: {h:4, m:40, a: 'pm'}, location: 'Samson Williams', desc: 'Humans - The only customers you’ve got til AIs take over'}, | |
| {range: ['17:00', '17:24'], display: {h:5, m:10, a: 'pm'}, location: '', desc: 'TBA'}, | |
| {range: ['17:25', '17:40'], display: {h:5, m:25, a: 'pm'}, location: 'Philip Forte and Tyler Wellner', desc: 'Block Venture Coalition'}, | |
| {range: ['17:45', '17:59'], display: {h:5, m:45, a: 'pm'}, location: '', desc: 'TBA'}, | |
| {range: ['18:00', '18:29'], display: {h:6, m:'', a: 'pm'}, location: '', desc: 'Self Sovereign Identity & Data Privacy- The protection of our data is growing ever more important with the rise of decentralized systems.<br> These experts are working on not letting data become compromised in an open network.'}, | |
| {range: ['18:30', '18:49'], display: {h:6, m:30, a: 'pm'}, location: '', desc: 'TBA'}, | |
| {range: ['18:50', '19:00'], display: {h:6, m:50, a: 'pm'}, location: '', desc: 'Closing Remarks'} | |
| ] | |
| // }, | |
| // { | |
| // date: moment(now).add(1, 'day'), | |
| // agenda: [ | |
| // {start: 0, end: 859, display: {h:8, m:30, a: 'am'}, location: 'Underscore Coffee Bar', desc: 'Breakfast Club Donuts + Coffee'}, | |
| // {start: 900, end: 959, display: {h:9, m:'', a: 'am'}, location: 'Solaris Terminal', desc: 'Aspirin Session Open forum to discuss headaches and pains, Q&A, tools & tricks, etc.'}, | |
| // {start: 1000, end: 1159, display: {h:10, m:'', a: 'am'}, location: '', desc: 'Hacking Session 3'}, | |
| // {start: 1200, end: 1229, display: {h:'Noon', m:'', a: '-ish'}, location: 'Break Room', desc: 'LUNCH: Taco Tuesday!'}, | |
| // {start: 1230, end: 1529, display: {h:12, m:30, a: 'pm'}, location: '', desc: 'Hacking Session 4'}, | |
| // {start: 1530, end: 1900, display: {h:3, m:30, a: 'pm'}, location: 'Underscore Coffee Bar', desc: 'Team Check-in'}, | |
| // {start: 1901, end: 1959, display: {h:7, m:'', a: 'pm'}, location: 'Hackers Bar & Grill <br /><small>@ Second and Main</small>', desc: 'Dinner!'} | |
| // ] | |
| // }, | |
| // { | |
| // date: moment(now).add(2, 'day'), | |
| // agenda: [ | |
| // {start: 0, end: 829, display: {h:8, m:30, a: 'am'}, location: 'Underscore Coffee Bar', desc: 'Breakfast Club Donuts + Coffee'}, | |
| // {start: 1000, end: 1159, display: {h:10, m:'', a: 'am'}, location: '', desc: 'Hacking Session 5'}, | |
| // {start: 1200, end: 1229, display: {h:'Noon', m:'', a: '-ish'}, location: 'Break Room', desc: 'LUNCH: Taco Tuesday!'}, | |
| // {start: 1230, end: 1529, display: {h:12, m:30, a: 'pm'}, location: '', desc: 'am Hacking Session 6'}, | |
| // {start: 1530, end: 1900, display: {h:3, m:30, a: 'pm'}, location: 'Underscore Coffee Bar', desc: 'Show & Tell Happy Hour'}, | |
| // ] | |
| } | |
| ] | |
| let timeFromNum = (num, sep, ampm) => { | |
| let hh = parseInt(num) | |
| let mm = Math.round((num-hh) * 60) | |
| sep = sep || '' | |
| return (hh>12&&m?hh-12:hh)+sep+('00'+mm).substr(-2)+(ampm?(hh>11?' pm':' am'):'') | |
| } | |
| let numFromTime = (time) => { | |
| let set = time.split(/[.:]/) | |
| let hh = parseInt(set[0]) | |
| let mm = set[1] ? parseInt(set[1]) : 0 | |
| return parseFloat((hh + mm / 60).toFixed(1)) | |
| } | |
| let app = new Vue({ | |
| el: 'aside', | |
| data: { | |
| now: numFromTime(moment(now).format('HH:mm')), | |
| time: moment().format('h:mm a'), | |
| showTimeTraveller: false | |
| } | |
| }) | |
| let sked = new Vue({ | |
| el: 'main', | |
| filters: { | |
| date: function(date) { | |
| return date.format('ddd, MMM D'); | |
| } | |
| }, | |
| data: { | |
| now: numFromTime(moment(now).format('HH:mm')), | |
| schedule: schedule | |
| }, | |
| methods: { | |
| checkTime: function(ts, te) { | |
| return (this.now >= numFromTime(ts) && this.now < numFromTime(te)) | |
| } | |
| } | |
| }) | |
| let setClockPos = () => { | |
| setTimeout(() => { | |
| let anchor = document.querySelector('.current') | |
| let t = '1em' | |
| if(anchor) { | |
| t = Math.round(anchor.getBoundingClientRect().top) + 'px' | |
| } | |
| document.documentElement.style.setProperty('--y', t) | |
| }, 350) | |
| } | |
| let timeTraveler | |
| let setTime = function() { | |
| let now = moment() | |
| app.now = sked.now = numFromTime(moment(now).format('HH:mm')) | |
| app.time = moment(now).format('h:mm a') | |
| } | |
| let runTimer = () => { | |
| setClockPos() | |
| timeTraveler = setInterval(function() { | |
| setTime() | |
| }, 30000) | |
| } | |
| runTimer() | |
| document.querySelector('#traveler').addEventListener('input', (e) => { | |
| app.time = timeFromNum(e.target.value, ':', true) | |
| sked.now = e.target.value | |
| setClockPos() | |
| clearInterval(timeTraveler) | |
| }, false) | |
| document.querySelector('.control header').addEventListener('click', (e) => { | |
| setTime() | |
| runTimer() | |
| }, false) | |
| let randum = function(min, max) { | |
| return Math.round((Math.random() * min) + (Math.random() * max)); | |
| } | |
| let randex = function() { | |
| return '#' + ( '00' + Math.floor( Math.random() * 16777216 ).toString(16) ).substr(-6) | |
| } | |
| let colorizer = () => { | |
| let hex = randex() | |
| let reverseHex = '#' + hex.replace('#', '').split("").reverse().join("") | |
| document.documentElement.style.setProperty('--bg', hex) | |
| document.documentElement.style.setProperty('--accent', reverseHex) | |
| } | |
| let transformer = () => { | |
| document.documentElement.style.setProperty('--transform', 'translate(-50%, -50%) rotate(' + randum(-360, 360) + 'deg)'); | |
| } | |
| setTimeout(() => { | |
| colorizer() | |
| }, 1000) | |
| setTimeout(() => { | |
| transformer() | |
| }, 100) | |
| let adventureTime = window.setInterval(function() { | |
| colorizer() | |
| }, 7500); | |
| let partyTime = window.setInterval(function() { | |
| transformer() | |
| }, 12000); | |
| // resize capture | |
| let resizeTimer | |
| window.addEventListener('resize', (e) => { | |
| clearTimeout(resizeTimer); | |
| resizeTimer = setTimeout(() => { | |
| setClockPos() | |
| }, 60); | |
| }, false) | |
| })(window) |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.1/vue.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.1/moment.min.js"></script> |
| @import url('https://fonts.googleapis.com/css?family=News+Cycle'); | |
| :root { | |
| --font: 'News Cycle', Helvetica, sans-serif; | |
| --accent: #9ccf5e; | |
| --bg: #403638; | |
| --transform: translate(-50%, -50%); | |
| } | |
| // primary layout | |
| aside { | |
| position: relative; | |
| flex: 1; | |
| order: 1; | |
| } | |
| main { | |
| position: relative; | |
| flex: 1; | |
| order: 2; | |
| overflow: auto; | |
| height: 100vh; | |
| section { | |
| display: flex; | |
| min-height: 100vh; | |
| } | |
| } | |
| svg.logo { | |
| position: absolute; | |
| pointer-event: none; | |
| font-size: 100vmax; | |
| width: 1em; | |
| height: 400px; | |
| top: 50%; | |
| left: 50%; | |
| will-change: transform; | |
| transform: var(--transform); | |
| transition: transform 12000ms ease-in-out; | |
| mix-blend-mode: overlay; | |
| path { | |
| fill: var(--accent); | |
| transition: fill 3000ms linear; | |
| } | |
| } | |
| // schedule listing | |
| main { | |
| background: rgba(#001, .8); | |
| color: #fff; | |
| header { | |
| flex: 0 0 auto; | |
| writing-mode: vertical-rl; | |
| padding: 1em .5em; | |
| color: rgba(#001, .4); | |
| background: #fff; | |
| } | |
| ul { | |
| list-style: none; | |
| margin: 0; | |
| padding: 2rem; | |
| flex: 1; | |
| display: flex; | |
| flex-direction: column; | |
| justify-content: space-between; | |
| } | |
| li { | |
| position: relative; | |
| transition: font-size 300ms ease-in, opacity 300ms ease-in; | |
| font-size: .5em; | |
| opacity: .2; | |
| line-height: 1.2; | |
| &.current { | |
| font-size: 1em; | |
| opacity: 1; | |
| &::after { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: -2rem; | |
| transform: translateY(-.5rem); | |
| border: .5em solid; | |
| border-width: 1em 0 1em .625em; | |
| border-color: transparent; | |
| border-left-color: currentColor; | |
| } | |
| ~ li { | |
| opacity: .4; | |
| } | |
| + li { | |
| font-size: .675em; | |
| opacity: .7; | |
| } | |
| } | |
| } | |
| } | |
| h1 { | |
| position: relative; | |
| top: .65em; | |
| left: .65em; | |
| margin: 0; | |
| line-height: 1; | |
| display: inline; | |
| } | |
| h3 { | |
| margin: 0; | |
| text-transform: uppercase; | |
| font-weight: 200; | |
| font-size: 1.325em; | |
| b { | |
| font-weight: 900; | |
| } | |
| } | |
| // playground | |
| .clock { | |
| position: absolute; | |
| font-size: 1em; | |
| top: 1em; | |
| right: 1em; | |
| transform: translate(0, calc(-1.3em + var(--y))); | |
| transition: transform 300ms ease-out; | |
| } | |
| small { | |
| font-size: .75em; | |
| color: var(--accent); | |
| transition: color 3000ms linear; | |
| small { | |
| font-size: .85em; | |
| } | |
| } | |
| // before/after hours | |
| main li.after-hours { | |
| animation: fade-in 1000ms ease-in 80ms forwards; | |
| position: fixed; | |
| font-size: 1.2em; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| bottom: 0; | |
| background: rgba(#000, .85); | |
| line-height: 1.5; | |
| width: 100vw; | |
| height: 100vh; | |
| display: flex; | |
| opacity: 0; | |
| // z-index: 1; | |
| text-align: center; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| main li.current ~ li.after-hours { | |
| display: none; | |
| opacity: 0; | |
| } | |
| // multi-day presentation | |
| // main section + section { | |
| // ul { | |
| // box-shadow: 0 1px 0 0 inset; | |
| // } | |
| // header { | |
| // box-shadow: 0 1px 0 0 inset; | |
| // } | |
| // } | |
| // animations | |
| @keyframes fade-in { | |
| 100% {opacity: 1;} | |
| } | |
| // demo | |
| .control { | |
| position: absolute; | |
| z-index: 2; | |
| bottom: 0; | |
| right: 0; | |
| font-size: .5em; | |
| background: rgba(#000, .7); | |
| transform: translateY(calc(100% - 2em)); | |
| transition: transform 300ms ease-out; | |
| header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| text-transform: uppercase; | |
| cursor: pointer; | |
| div { | |
| padding-left: 1em; | |
| } | |
| } | |
| > div { | |
| padding: 1em; | |
| } | |
| p { | |
| margin: 0; | |
| + p { | |
| margin-top: 1em; | |
| } | |
| } | |
| input[type=range] { | |
| padding: 0; | |
| border: 0; | |
| width: 15em; | |
| vertical-align: middle; | |
| border-radius: 1em; | |
| background: rgba(#fff, 0.3); | |
| font-size: 1rem; | |
| line-height: 1; | |
| appearance: none; | |
| outline: none; | |
| transition: all .3s; | |
| outline-offset: 0; | |
| margin: 0; | |
| &::-webkit-slider-thumb { | |
| appearance: none; | |
| width: 1em; | |
| height: 1em; | |
| border: none; | |
| border-radius: 1em; | |
| background: #E2E4E6; | |
| background-image: none; | |
| transform: scale(2); | |
| transition: all .3s; | |
| } | |
| } | |
| button { | |
| font: inherit; | |
| border: none; | |
| color: inherit; | |
| width: 2em; | |
| height: 2em; | |
| font-size: 1em; | |
| font-weight: 100; | |
| background: rgba(#fff, .4); | |
| outline: none; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| line-height: 0; | |
| transform: rotate(180deg); | |
| } | |
| &.show { | |
| transform: translateY(0%); | |
| button { | |
| transform: rotate(0deg); | |
| } | |
| } | |
| } | |
| // boring | |
| *, *::before, *::after {box-sizing: border-box;} | |
| html, body { | |
| background: var(--bg); // fixes chrome 58+ mix-blend-mode bug | |
| } | |
| body { | |
| margin: 0; | |
| min-height: 100vh; | |
| display: flex; | |
| flex-flow: row wrap; | |
| justify-content: center; | |
| overflow: hidden; | |
| font-family: var(--font); | |
| font-size: calc(1em + 1.5vmin); | |
| // background: var(--bg); | |
| transition: background 1500ms linear; | |
| color: #fff; | |
| } | |
| // safari fix | |
| main header { | |
| height: 100%; | |
| } | |
| // firefox fix | |
| main header { | |
| width: 0px; | |
| padding: 1em 1.25em; | |
| line-height: 0; | |
| } |