diff --git a/src/c3nav/mapdata/views.py b/src/c3nav/mapdata/views.py index cc4cafd1..3d362bea 100644 --- a/src/c3nav/mapdata/views.py +++ b/src/c3nav/mapdata/views.py @@ -18,7 +18,7 @@ def tile(request, level, zoom, x, y, format): x, y = int(x), int(y) size = 256/2**zoom minx = size * x - miny = size * y + miny = size * (-y-1) maxx = minx + size maxy = miny + size diff --git a/src/c3nav/site/static/site/css/c3nav.css b/src/c3nav/site/static/site/css/c3nav.css index c93c6652..23c2230d 100644 --- a/src/c3nav/site/static/site/css/c3nav.css +++ b/src/c3nav/site/static/site/css/c3nav.css @@ -1,342 +1,29 @@ -body, .btn { - font-size:16px; +body { + margin-top: 58px; } - -.main-view.mode-location .locations > .origin-select, -.main-view.mode-location .locations > .destination-select, -.main-view.mode-route .locations > .location-select, -.main-view.mode-location .routing { - display:none +header { + position: fixed; + left: 0; + right: 0; + top: 0; + height: 50px; + padding: 8px; } -.locationselect .input-lg { - height: 62px; -} -.locationselect > div { - position:relative; -} -.locationselect .locationselect-selected, .locationselect .locationselect-error { - display:none; -} -.location-group.selected .locationselect-selected { - display:block; -} -.location-group.selected .locationselect-input, .location-group.error .locationselect-input { - display:none; -} -.location-group.error .locationselect-error { - display:block; -} -.locationselect .icons { - height:48px; +main.map { position:absolute; - right:7px; - top:7px; - opacity:0.5; -} -.locationselect .icons a { - display:inline-block; - width:48px; - height:48px; -} -.locationselect .icons .reset, .locationselect .icons .errorreset { - background-image:url('../img/icons/cross.svg'); -} -.locationselect .icons .link { - background-image:url('../img/icons/link.svg'); -} -.locationselect .icons .map { - background-image:url('../img/icons/map.svg'); -} -.locationselect .icons .locate { - background-image:url('../img/icons/locate.svg'); + left:0; + top:50px; + right:0; + bottom:0; + background: url('../../img/loader.gif') no-repeat center; } -.location-group .only-if-selected { - display:none; -} -.location-group.selected .only-if-selected { - display:block; -} -.location-group.selected.loading .only-if-selected { - display:none; -} - -.locationselect-map { - display:none; - position:relative; -} -.location-group.map .locationselect-map { - display:block; -} -.location-group.map .locationselect-input { - display:none; -} -.locationselect-map .map-container { - width:100%; - overflow:auto; - height:300px; - position:relative; -} -.locationselect-map .map-container img, .locationselect-map .map-container input { +section#map { position:absolute; left:0; top:0; -} -.locationselect-map .map-buttons { - position:absolute; - top:8px; - left:8px; -} -.locationselect-map .close-map { - margin-left:8px; -} -.locationselect-map .scroll-hint { - color:#FFFFFF; - position:absolute; - top:250px; - left:16px; -} - - -.location { - font-size:18px; -} -.location small { - font-size:14px; - display:block; -} -.location.form-control { - padding: 9px 16px; - -webkit-box-shadow: none; - box-shadow: none; -} - - -/* Typehead */ -.twitter-typeahead { - display:block !important; -} -.tt-input { - margin-bottom: 0; -} -.tt-hint { - color: #999; -} -.tt-menu { - width:100%; - min-width: 160px; - margin-top:-1px; - padding: 0; - overflow:hidden; - padding-bottom:4px; -} -.tt-menu.noscript { - margin-top:0; -} -.tt-dataset { - background-color: #ffffff; - border-width: 1px; - border-style: solid; - border-color: #cccccc #66afe9 #66afe9; - border-radius: 0 0 4px 4px; - margin:0 6px; - -webkit-box-shadow: 0 0 8px rgba(102, 175, 233, 0.6); - box-shadow: 0 0 8px rgba(102, 175, 233, 0.6); -} -.noscript .tt-dataset { - border-width:0 1px 1px; - border-color: #E7E7E7; - -webkit-box-shadow: 0 0 8px rgba(231, 231, 231, 0.6); - box-shadow: 0 0 8px rgba(231, 231, 231, 0.6); -} -.tt-suggestion { - padding: 6px 10px; - display:block; -} -.tt-suggestion.tt-cursor { - color: #fff; - background-color: #428bca; -} -.tt-suggestion.tt-cursor a { - color: #fff; -} -.tt-suggestion p { - margin: 0; -} - -.routing { - display:none; -} -.can-route .routing { - display:block; -} - -svg { - width:100%; - height:auto; - vertical-align:bottom; - margin-bottom:10px; -} -line { - stroke:#FF0000; - stroke-width:2.5px; -} -marker path { - fill: #FF0000; - stroke: 0; -} -circle.pos { - fill:#3399FF; - stroke-width:10px; - stroke:rgba(51, 153, 255, 0.2); -} - -.routepart { - margin-bottom:20px; -} - -.desc { - line-height:35px; - position:relative; - min-height:35px; - margin-bottom:8px; -} -.desc .icon { - display:inline-block; - vertical-align:middle; - width:35px; - height:35px; - text-align:center; - - background-image:url('../img/icons/arrow.svg'); - background-repeat: no-repeat; - background-size: contain; - background-position:center; -} -.desc .icon.light_right { - transform: rotate(45deg); -} -.desc .icon.light_left { - transform: rotate(-45deg); -} -.desc .icon.right { - transform: rotate(90deg); -} -.desc .icon.left { - transform: rotate(-90deg); -} -.desc .icon.location { - background-image:url('../img/icons/location.svg'); -} -.desc .icon.stairs_up { - background-image:url('../img/icons/stairs-up.svg'); -} -.desc .icon.stairs_down { - background-image:url('../img/icons/stairs-down.svg'); -} -.desc .icon.escalator_up { - background-image:url('../img/icons/escalator-up.svg'); -} -.desc .icon.escalator_down { - background-image:url('../img/icons/escalator-down.svg'); -} -.desc .icon.elevator_up { - background-image:url('../img/icons/elevator-up.svg'); -} -.desc .icon.elevator_down { - background-image:url('../img/icons/elevator-down.svg'); -} -.desc .icon.destination { - background-image:url('../img/icons/destination.svg'); -} - -.desc .icon img { - max-width:35px; -} -.desc p { - white-space:normal; - display:inline-block; - padding-left:8px; - margin:0; - box-sizing:border-box; - width:auto; - vertical-align:middle; - line-height: 1.42857143; -} - - -.location-group.selected.loading .locationselect-selected .location, -.locationselect-map .map-container { - background-image:url('/static/img/loader.gif'); - background-repeat:no-repeat; - background-position:center; -} -.only-if-selected { - margin-bottom:16px; -} - - -footer { - text-align:center; -} -.showsettings { - display:none; -} -@media (min-width: 992px) { - .showsettings { - padding-top: 18px; - padding-bottom: 18px; - } -} - -.languages { - margin-bottom:0; - height:2px; -} -.languages button { - text-transform:none; - font-weight:normal; - margin-top:0 !important; - border-width:0 !important; - padding:0; -} - - -#qr_modal { - position:absolute; - top:0; - left:0; - width:100%; - height:100%; - background-color:rgba(0, 0, 0, 0.2); - display:none; - z-index:100; -} -#qr_modal .inner { - background-color:#FFFFFF; - padding:20px; - box-sizing:border-box; - text-align:center; - margin:30px auto; - width:400px; - max-width:95vw; -} -#qr_modal button { - margin:0 4px 8px; -} - - -body.nomobileclient .app-only { - display:none; -} - - -h1 a { - color:#333333; -} -h1 a:hover { - text-decoration:none; - color:#333333; + right:0; + bottom:0; } diff --git a/src/c3nav/site/static/site/js/c3nav.js b/src/c3nav/site/static/site/js/c3nav.js index 5bbc2a44..93801dba 100644 --- a/src/c3nav/site/static/site/js/c3nav.js +++ b/src/c3nav/site/static/site/js/c3nav.js @@ -1,314 +1,23 @@ c3nav = { init: function() { - c3nav.main_view = $('.main-view'); - if (!c3nav.main_view.length) return; - - c3nav.svg_width = parseInt(c3nav.main_view.attr('data-svg-width')); - c3nav.svg_height = parseInt(c3nav.main_view.attr('data-svg-height')); - c3nav.visible_areas = c3nav.main_view.attr('data-visible-areas').split(';'); - c3nav.qr_modal = $('#qr_modal'); - - c3nav.mobileclient = (typeof mobileclient !== "undefined"); - if (c3nav.mobileclient) { - $('body').removeClass('nomobileclient'); - } - - c3nav._typeahead_locations = new Bloodhound({ - datumTokenizer: function(data) { - var result = [data.id] - result = result.concat(data.title.split(' ')); - return result - }, - queryTokenizer: Bloodhound.tokenizers.whitespace, - identify: function(data) { - return data.id; - }, - prefetch: { - url: '/api/locations/', - cache: false - } + // Init Map + c3nav.bounds = JSON.parse($('#map').attr('data-bounds')); + c3nav.map = L.map('map', { + renderer: L.svg({ padding: 2 }), + zoom: 2, + maxZoom: 10, + minZoom: 0, + crs: L.CRS.Simple, + maxBounds: c3nav.bounds, + closePopupOnClick: false, }); - c3nav._typeahead_options = { - source: c3nav._typeahead_locations, - limit: 7, - display: function(item) { - return item.title; - }, - templates: { - suggestion: function(data) { - return '
'+data.title+''+data.subtitle+'
'; - } - } - }; - - c3nav.init_typeahead($('.locationselect input:text')); - c3nav.locationselect_focus(); - - $('.locationselect .icons .reset').click(c3nav._locationselect_reset); - $('.locationselect .icons .errorreset').click(c3nav._locationselect_errorreset); - $('.locationselect .icons .map').click(c3nav._locationselect_activate_map); - $('.locationselect .icons .link').click(c3nav._locationselect_click_link); - $('.locationselect .icons .locate').click(c3nav._locationselect_click_locate); - $('.locationselect .close-map').click(c3nav._locationselect_close_map); - $('.locationselect .level-selector a').click(c3nav._locationselect_click_level); - $('.locationselect .map-container').on('click', 'img', c3nav._locationselect_click_image); - $('.location-group .swap').click(c3nav.swap_locations); - $('#route-from-here').click(c3nav._click_route_from_here); - $('#route-to-here').click(c3nav._click_route_to_here); - - c3nav.qr_modal.find('.qr-close').click(function() { - c3nav.qr_modal.hide(); - }); - c3nav.qr_modal.find('.share').click(function() { - mobileclient.shareUrl(c3nav.qr_modal.find('strong').text()); - }); - c3nav.qr_modal.find('.shortcut').click(function() { - mobileclient.createShortcut(c3nav.qr_modal.find('strong').text(), c3nav.qr_modal.data('title')); - }); - - $('.showsettings').show(); - $('.savesettings, .settings').hide(); - $('.showsettings a').click(function(e) { - e.preventDefault(); - $('.showsettings').hide(); - $('.savesettings, .settings').show(); - }); - - window.onpopstate = c3nav._onpopstate; - }, - - swap_locations: function(e) { - e.preventDefault(); - var origin_select = $('.origin-select'); - var destination_select = $('.destination-select'); - var has_orig = origin_select.is('.selected'); - var has_dest = destination_select.is('.selected'); - - var orig_id = '', - orig_html = '', - dest_id = '', - dest_html = ''; - - if (has_orig) { - orig_id = origin_select.find('.id-field').val(); - orig_html = origin_select.find('.locationselect-selected .location').html(); - } - if (has_dest) { - dest_id = destination_select.find('.id-field').val(); - dest_html = destination_select.find('.locationselect-selected .location').html(); - destination_select.toggleClass('selected', has_orig); - destination_select.find('.id_field').val(orig_id); - destination_select.find('.locationselect-selected .location').html(orig_html); - } - if (has_orig) { - origin_select.toggleClass('selected', has_dest); - origin_select.find('.id_field').val(dest_id); - origin_select.find('.locationselect-selected .location').html(dest_html); - } - }, - _locationselect_reset: function(e) { - e.preventDefault(); - var location_group = $(this).closest('.location-group'); - location_group.find('.id-field').val(''); - location_group.removeClass('selected').find('.tt-input').focus().removeData('enter_item'); - location_group.find('.tt-suggestion').remove(); - c3nav._locations_changed(); - }, - _locationselect_errorreset: function(e) { - e.preventDefault(); - var location_group = $(this).closest('.location-group'); - location_group.removeClass('error').find('.tt-input').focus(); - location_group.find('.tt-suggestion').remove(); - }, - _locationselect_click_link: function(e) { - e.preventDefault(); - var location_group = $(this).closest('.location-group'); - var location_id = location_group.find('.id-field').val(); - var location_title = location_group.find('.title').text(); - c3nav.qr_modal.find('strong').text(window.location.origin+'/l/'+location_id+'/'); - c3nav.qr_modal.find('img').attr('src', '/qr/'+location_id+'.png'); - c3nav.qr_modal.data('title', location_title); - c3nav.qr_modal.show(); - }, - _locationselect_activate_map: function(e) { - e.preventDefault(); - var location_group = $(this).closest('.location-group'); - location_group.addClass('map'); - var map_container = location_group.find('.map-container'); - map_container.scrollTop((c3nav.svg_height-map_container.height())/2).scrollLeft((c3nav.svg_width-map_container.width())/2); - location_group.find('.level-selector a').first().click(); - }, - _locationselect_close_map: function(e) { - e.preventDefault(); - var location_group = $(this).closest('.location-group'); - location_group.removeClass('map').find('.tt-input').focus(); - }, - _locationselect_click_level: function(e) { - e.preventDefault(); - var location_group = $(this).closest('.location-group'); - var map_container = location_group.find('.map-container'); - var level = $(this).attr('data-level'); - $(this).siblings().removeClass('active'); - $(this).addClass('active'); - map_container.find('img').remove(); - for (var i=0;i').attr({ - 'src': '/map/'+level+'/'+c3nav.visible_areas[i]+'.png', - 'width': c3nav.svg_width, - 'height': c3nav.svg_height - })); - } - map_container.attr('data-level', level); - }, - _locationselect_click_image: function(e) { - var level = $(e.delegateTarget).attr('data-level'); - var coords = 'c:'+level+':'+parseInt(e.offsetX/6*100)+':'+parseInt((c3nav.svg_height-e.offsetY)/6*100); - var location_group = $(this).closest('.location-group'); - location_group.removeClass('map').addClass('selected').addClass('loading'); - var selected = location_group.find('.locationselect-selected'); - selected.find('.title').text(''); - selected.find('.subtitle').text(''); - selected.find('.id-field').val(coords); - $.getJSON('/api/locations/'+coords, function(data) { - selected.find('.title').text(data.title); - selected.find('.subtitle').text(data.subtitle); - selected.closest('.location-group').removeClass('loading'); - }); - c3nav._locations_changed(); - c3nav.locationselect_focus(); - }, - locationselect_focus: function() { - $('.location-group:visible:not(.selected) .locationselect-input .tt-input').first().focus(); - }, - - - _last_scan: 0, - _scan_for: [], - _scan_now: function() { - if (c3nav._last_scan < (new Date().getTime() / 1000 - 3000)) { - c3nav._last_scan = new Date().getTime() / 1000; - mobileclient.scanNow(); - } else { - nearby_stations_available(); - } - }, - _locationselect_click_locate: function(e) { - e.preventDefault(); - var location_group = $(this).closest('.location-group'); - location_group.addClass('loading').addClass('selected'); - c3nav._scan_for.push(location_group.attr('data-name')); - c3nav._scan_now(); - }, - nearby_stations_available: function() { - $.ajax({ - type: "POST", - url: '/api/locations/wifilocate/', - data: { stations: mobileclient.getNearbyStations() }, - dataType: 'json', - success: c3nav._wifilocate_callback - }); - }, - _wifilocate_callback: function(data) { - var location_group, selected; - var location = data.location; - for(var i=0;i + + + + + + c3nav + {% compress css %} + + + + {% endcompress %} + + + +
+ c3nav +
+
+
+ +
+
+ {% compress js %} + + + + + {% endcompress %} + + diff --git a/src/c3nav/site/urls.py b/src/c3nav/site/urls.py index 1512dced..1a6206b8 100644 --- a/src/c3nav/site/urls.py +++ b/src/c3nav/site/urls.py @@ -1,6 +1,6 @@ from django.conf.urls import url -from c3nav.site.views import main, map_image, qr_code +from c3nav.site.views import main, map_image, map_index, qr_code urlpatterns = [ url(r'^map/(?P[a-z0-9-_:]+)/(?P[a-z0-9-_:]+).png$', map_image, name='site.level_image'), @@ -9,5 +9,5 @@ urlpatterns = [ url(r'^o/(?P[a-z0-9-_:]+)/$', main, name='site.origin'), url(r'^d/(?P[a-z0-9-_:]+)/$', main, name='site.destination'), url(r'^r/(?P[a-z0-9-_:]+)/(?P[a-z0-9-_:]+)/$', main, name='site.route'), - url(r'^$', main, name='site.index') + url(r'^$', map_index, name='site.index') ] diff --git a/src/c3nav/site/views.py b/src/c3nav/site/views.py index 711d0b6f..81dd271a 100644 --- a/src/c3nav/site/views.py +++ b/src/c3nav/site/views.py @@ -1,4 +1,5 @@ # flake8: noqa +import json from datetime import timedelta import qrcode @@ -8,6 +9,7 @@ from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse from django.utils import timezone +from c3nav.mapdata.models import Source from c3nav.mapdata.models.level import Level ctype_mapping = { @@ -58,6 +60,13 @@ def qr_code(request, location): return response +def map_index(request): + ctx = { + 'bounds': json.dumps(Source.max_bounds()) + } + return render(request, 'site/map.html', ctx) + + def main(request, location=None, origin=None, destination=None): location = get_location_or_404(request, location) origin = get_location_or_404(request, origin) diff --git a/src/c3nav/static/milligram/milligram.css b/src/c3nav/static/milligram/milligram.css new file mode 100644 index 00000000..d253355e --- /dev/null +++ b/src/c3nav/static/milligram/milligram.css @@ -0,0 +1,602 @@ +/*! + * Milligram v1.3.0 + * https://milligram.github.io + * + * Copyright (c) 2017 CJ Patoilo + * Licensed under the MIT license + */ + +*, +*:after, +*:before { + box-sizing: inherit; +} + +html { + box-sizing: border-box; + font-size: 62.5%; +} + +body { + color: #606c76; + font-family: 'Roboto', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif; + font-size: 1.6em; + font-weight: 300; + letter-spacing: .01em; + line-height: 1.6; +} + +blockquote { + border-left: 0.3rem solid #d1d1d1; + margin-left: 0; + margin-right: 0; + padding: 1rem 1.5rem; +} + +blockquote *:last-child { + margin-bottom: 0; +} + +.button, +button, +input[type='button'], +input[type='reset'], +input[type='submit'] { + background-color: #9b4dca; + border: 0.1rem solid #9b4dca; + border-radius: .4rem; + color: #fff; + cursor: pointer; + display: inline-block; + font-size: 1.1rem; + font-weight: 700; + height: 3.8rem; + letter-spacing: .1rem; + line-height: 3.8rem; + padding: 0 3.0rem; + text-align: center; + text-decoration: none; + text-transform: uppercase; + white-space: nowrap; +} + +.button:focus, .button:hover, +button:focus, +button:hover, +input[type='button']:focus, +input[type='button']:hover, +input[type='reset']:focus, +input[type='reset']:hover, +input[type='submit']:focus, +input[type='submit']:hover { + background-color: #606c76; + border-color: #606c76; + color: #fff; + outline: 0; +} + +.button[disabled], +button[disabled], +input[type='button'][disabled], +input[type='reset'][disabled], +input[type='submit'][disabled] { + cursor: default; + opacity: .5; +} + +.button[disabled]:focus, .button[disabled]:hover, +button[disabled]:focus, +button[disabled]:hover, +input[type='button'][disabled]:focus, +input[type='button'][disabled]:hover, +input[type='reset'][disabled]:focus, +input[type='reset'][disabled]:hover, +input[type='submit'][disabled]:focus, +input[type='submit'][disabled]:hover { + background-color: #9b4dca; + border-color: #9b4dca; +} + +.button.button-outline, +button.button-outline, +input[type='button'].button-outline, +input[type='reset'].button-outline, +input[type='submit'].button-outline { + background-color: transparent; + color: #9b4dca; +} + +.button.button-outline:focus, .button.button-outline:hover, +button.button-outline:focus, +button.button-outline:hover, +input[type='button'].button-outline:focus, +input[type='button'].button-outline:hover, +input[type='reset'].button-outline:focus, +input[type='reset'].button-outline:hover, +input[type='submit'].button-outline:focus, +input[type='submit'].button-outline:hover { + background-color: transparent; + border-color: #606c76; + color: #606c76; +} + +.button.button-outline[disabled]:focus, .button.button-outline[disabled]:hover, +button.button-outline[disabled]:focus, +button.button-outline[disabled]:hover, +input[type='button'].button-outline[disabled]:focus, +input[type='button'].button-outline[disabled]:hover, +input[type='reset'].button-outline[disabled]:focus, +input[type='reset'].button-outline[disabled]:hover, +input[type='submit'].button-outline[disabled]:focus, +input[type='submit'].button-outline[disabled]:hover { + border-color: inherit; + color: #9b4dca; +} + +.button.button-clear, +button.button-clear, +input[type='button'].button-clear, +input[type='reset'].button-clear, +input[type='submit'].button-clear { + background-color: transparent; + border-color: transparent; + color: #9b4dca; +} + +.button.button-clear:focus, .button.button-clear:hover, +button.button-clear:focus, +button.button-clear:hover, +input[type='button'].button-clear:focus, +input[type='button'].button-clear:hover, +input[type='reset'].button-clear:focus, +input[type='reset'].button-clear:hover, +input[type='submit'].button-clear:focus, +input[type='submit'].button-clear:hover { + background-color: transparent; + border-color: transparent; + color: #606c76; +} + +.button.button-clear[disabled]:focus, .button.button-clear[disabled]:hover, +button.button-clear[disabled]:focus, +button.button-clear[disabled]:hover, +input[type='button'].button-clear[disabled]:focus, +input[type='button'].button-clear[disabled]:hover, +input[type='reset'].button-clear[disabled]:focus, +input[type='reset'].button-clear[disabled]:hover, +input[type='submit'].button-clear[disabled]:focus, +input[type='submit'].button-clear[disabled]:hover { + color: #9b4dca; +} + +code { + background: #f4f5f6; + border-radius: .4rem; + font-size: 86%; + margin: 0 .2rem; + padding: .2rem .5rem; + white-space: nowrap; +} + +pre { + background: #f4f5f6; + border-left: 0.3rem solid #9b4dca; + overflow-y: hidden; +} + +pre > code { + border-radius: 0; + display: block; + padding: 1rem 1.5rem; + white-space: pre; +} + +hr { + border: 0; + border-top: 0.1rem solid #f4f5f6; + margin: 3.0rem 0; +} + +input[type='email'], +input[type='number'], +input[type='password'], +input[type='search'], +input[type='tel'], +input[type='text'], +input[type='url'], +textarea, +select { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background-color: transparent; + border: 0.1rem solid #d1d1d1; + border-radius: .4rem; + box-shadow: none; + box-sizing: inherit; + height: 3.8rem; + padding: .6rem 1.0rem; + width: 100%; +} + +input[type='email']:focus, +input[type='number']:focus, +input[type='password']:focus, +input[type='search']:focus, +input[type='tel']:focus, +input[type='text']:focus, +input[type='url']:focus, +textarea:focus, +select:focus { + border-color: #9b4dca; + outline: 0; +} + +select { + background: url('data:image/svg+xml;utf8,') center right no-repeat; + padding-right: 3.0rem; +} + +select:focus { + background-image: url('data:image/svg+xml;utf8,'); +} + +textarea { + min-height: 6.5rem; +} + +label, +legend { + display: block; + font-size: 1.6rem; + font-weight: 700; + margin-bottom: .5rem; +} + +fieldset { + border-width: 0; + padding: 0; +} + +input[type='checkbox'], +input[type='radio'] { + display: inline; +} + +.label-inline { + display: inline-block; + font-weight: normal; + margin-left: .5rem; +} + +.container { + margin: 0 auto; + max-width: 112.0rem; + padding: 0 2.0rem; + position: relative; + width: 100%; +} + +.row { + display: flex; + flex-direction: column; + padding: 0; + width: 100%; +} + +.row.row-no-padding { + padding: 0; +} + +.row.row-no-padding > .column { + padding: 0; +} + +.row.row-wrap { + flex-wrap: wrap; +} + +.row.row-top { + align-items: flex-start; +} + +.row.row-bottom { + align-items: flex-end; +} + +.row.row-center { + align-items: center; +} + +.row.row-stretch { + align-items: stretch; +} + +.row.row-baseline { + align-items: baseline; +} + +.row .column { + display: block; + flex: 1 1 auto; + margin-left: 0; + max-width: 100%; + width: 100%; +} + +.row .column.column-offset-10 { + margin-left: 10%; +} + +.row .column.column-offset-20 { + margin-left: 20%; +} + +.row .column.column-offset-25 { + margin-left: 25%; +} + +.row .column.column-offset-33, .row .column.column-offset-34 { + margin-left: 33.3333%; +} + +.row .column.column-offset-50 { + margin-left: 50%; +} + +.row .column.column-offset-66, .row .column.column-offset-67 { + margin-left: 66.6666%; +} + +.row .column.column-offset-75 { + margin-left: 75%; +} + +.row .column.column-offset-80 { + margin-left: 80%; +} + +.row .column.column-offset-90 { + margin-left: 90%; +} + +.row .column.column-10 { + flex: 0 0 10%; + max-width: 10%; +} + +.row .column.column-20 { + flex: 0 0 20%; + max-width: 20%; +} + +.row .column.column-25 { + flex: 0 0 25%; + max-width: 25%; +} + +.row .column.column-33, .row .column.column-34 { + flex: 0 0 33.3333%; + max-width: 33.3333%; +} + +.row .column.column-40 { + flex: 0 0 40%; + max-width: 40%; +} + +.row .column.column-50 { + flex: 0 0 50%; + max-width: 50%; +} + +.row .column.column-60 { + flex: 0 0 60%; + max-width: 60%; +} + +.row .column.column-66, .row .column.column-67 { + flex: 0 0 66.6666%; + max-width: 66.6666%; +} + +.row .column.column-75 { + flex: 0 0 75%; + max-width: 75%; +} + +.row .column.column-80 { + flex: 0 0 80%; + max-width: 80%; +} + +.row .column.column-90 { + flex: 0 0 90%; + max-width: 90%; +} + +.row .column .column-top { + align-self: flex-start; +} + +.row .column .column-bottom { + align-self: flex-end; +} + +.row .column .column-center { + -ms-grid-row-align: center; + align-self: center; +} + +@media (min-width: 40rem) { + .row { + flex-direction: row; + margin-left: -1.0rem; + width: calc(100% + 2.0rem); + } + .row .column { + margin-bottom: inherit; + padding: 0 1.0rem; + } +} + +a { + color: #9b4dca; + text-decoration: none; +} + +a:focus, a:hover { + color: #606c76; +} + +dl, +ol, +ul { + list-style: none; + margin-top: 0; + padding-left: 0; +} + +dl dl, +dl ol, +dl ul, +ol dl, +ol ol, +ol ul, +ul dl, +ul ol, +ul ul { + font-size: 90%; + margin: 1.5rem 0 1.5rem 3.0rem; +} + +ol { + list-style: decimal inside; +} + +ul { + list-style: circle inside; +} + +.button, +button, +dd, +dt, +li { + margin-bottom: 1.0rem; +} + +fieldset, +input, +select, +textarea { + margin-bottom: 1.5rem; +} + +blockquote, +dl, +figure, +form, +ol, +p, +pre, +table, +ul { + margin-bottom: 2.5rem; +} + +table { + border-spacing: 0; + width: 100%; +} + +td, +th { + border-bottom: 0.1rem solid #e1e1e1; + padding: 1.2rem 1.5rem; + text-align: left; +} + +td:first-child, +th:first-child { + padding-left: 0; +} + +td:last-child, +th:last-child { + padding-right: 0; +} + +b, +strong { + font-weight: bold; +} + +p { + margin-top: 0; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-weight: 300; + letter-spacing: -.1rem; + margin-bottom: 2.0rem; + margin-top: 0; +} + +h1 { + font-size: 4.6rem; + line-height: 1.2; +} + +h2 { + font-size: 3.6rem; + line-height: 1.25; +} + +h3 { + font-size: 2.8rem; + line-height: 1.3; +} + +h4 { + font-size: 2.2rem; + letter-spacing: -.08rem; + line-height: 1.35; +} + +h5 { + font-size: 1.8rem; + letter-spacing: -.05rem; + line-height: 1.5; +} + +h6 { + font-size: 1.6rem; + letter-spacing: 0; + line-height: 1.4; +} + +img { + max-width: 100%; +} + +.clearfix:after { + clear: both; + content: ' '; + display: table; +} + +.float-left { + float: left; +} + +.float-right { + float: right; +} + +/*# sourceMappingURL=milligram.css.map */ \ No newline at end of file