Upgrade Febrary

This commit is contained in:
Siroco 2019-02-06 14:36:51 +01:00
parent 0d50695302
commit 0d709bc1a7
20 changed files with 274 additions and 42 deletions

View File

@ -2,10 +2,11 @@ import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { TextInfoComponent } from './text-info/text-info.component';
const routes: Routes = [ const routes: Routes = [
{ path: '', component: AppComponent }, // { path: '', component: AppComponent },
{ path: ':slug', component: AppComponent }, // { path: 'sound/:slug', component: TextInfoComponent }
// { path: '/test/', component: PageComponent}. // { path: '/test/', component: PageComponent}.
// { path: '/item/:idno', component: AppComponent} // { path: '/item/:idno', component: AppComponent}
]; ];

View File

@ -1,8 +1,19 @@
@import url('https://fonts.googleapis.com/css?family=Open+Sans:700|Raleway'); @import url('https://fonts.googleapis.com/css?family=Open+Sans:700|Raleway');
* { font-family:"Raleway",sans-serif;} * { font-family:"Raleway",sans-serif;}
map-box {margin:0;} map-box {margin:0;}
div.title {position:absolute;z-index:10;}
div.title {font-size:1em;text-align:left;padding:10px;position:absolute;bottom:0;left:0;width:30vw;background-color:rgba(0,0,0,0);color:#fff;} div.title {font-size:1em;text-align:left;padding:10px;position:absolute;bottom:0;left:0;width:30vw;background-color:rgba(0,0,0,0);color:#fff;}
div.title h1 {font-family:"Open Sans";font-size:4em;} div.title h1 {font-family:"Open Sans";font-size:4em;width:30vw;}
div.title h1 span {background:#d52b1e;padding:0 10px;} div.title h1 span {background:#d52b1e;padding:0 10px;}
div.title h2 span {background:#fff;padding:2px;color:#000;} div.title h2 span {background:#fff;padding:2px;color:#000;cursor:pointer;background-color:#333;padding:5px 15px;margin:0 5px;}
div.title p span {line-height:1.4;background:#021011;} div.title p span {line-height:1.4;background:#021011;}
div.title h3 {position:absolute;max-width:50vw;}
div.title h3 span.tablet-term { background:#d52b1e;color:#fff; padding:2px 10px;}
div.title h3 span.tablet-term b {font-weight:bold;cursor:pointer;}
div.title h3 span.tablet-term b:hover {transform:rotate(-45deg);opacity:0.6;}
@media screen and (max-device-width: 720px) {
div.title {position:relative;width:100vw;padding:10px 0; background:#d52b1e;}
div.title h2 span {float:left;width:40%;margin:5px 5px;text-align:center;}
}

View File

@ -1,8 +1,11 @@
<div class="title"> <div class="title">
<h1><span>Ticino Soundmap</span></h1> <h3 style="color:#000;" *ngIf="filter">Filtered by : <span class="tablet-term">{{filter.name}} <b (click)="delFilter(filter)">x</b></span></h3>
<!-- <h2><span>Listen</span> | <span>About</span> | <span>Contact</span></h2> --> <h1><span>Ticino</span> <span>Soundmap</span></h1>
<h2><span *ngFor="let page of pages" style="" (click)="goToAnchor(page.slug)"><a style="color:#fff;" [innerHTML]="page.title.rendered"></a></span></h2>
<!-- <p><span>Welcome to SOINUMAPA.NET Basque country Sound Map open archive project. Based on phonography or the art of recording environmental sounds, our aim is to show, share and exchange field recordings made in the Basque Country. Right now, you will find more than 1500 sound recordings: city noises, natural ambiences, animals, celebrations and parties, places, happenings, cultural events… including images and texts that behind their apparent silence, keep many sounds (see ABOUT) inside. <!-- <p><span>Welcome to SOINUMAPA.NET Basque country Sound Map open archive project. Based on phonography or the art of recording environmental sounds, our aim is to show, share and exchange field recordings made in the Basque Country. Right now, you will find more than 1500 sound recordings: city noises, natural ambiences, animals, celebrations and parties, places, happenings, cultural events… including images and texts that behind their apparent silence, keep many sounds (see ABOUT) inside.
You are free to listen, read, watch, consult and use our archive for any research, creative or educational purposes</span></p> --> You are free to listen, read, watch, consult and use our archive for any research, creative or educational purposes</span></p> -->
</div> </div>
<map-box></map-box> <map-box></map-box>
<app-pages [pages]="pages"></app-pages>
<text-info></text-info> <text-info></text-info>
<router-outlet></router-outlet>

View File

@ -2,6 +2,7 @@ import { Component } from '@angular/core';
import { WordpressService } from './wordpress.service'; import { WordpressService } from './wordpress.service';
import { ActivatedRoute,Router, NavigationEnd } from "@angular/router"; import { ActivatedRoute,Router, NavigationEnd } from "@angular/router";
import {PageItem} from './page'; import {PageItem} from './page';
import {MapService} from './map.service';
@Component({ @Component({
@ -11,20 +12,44 @@ import {PageItem} from './page';
}) })
export class AppComponent { export class AppComponent {
pages:PageItem[]; pages:PageItem[] = [];
public filter;
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
private wordpressService:WordpressService, private wordpressService:WordpressService,
private mapService:MapService
) { ) {
this.route.params.subscribe( params => {
let slug = params.slug; this.mapService.filter$
console.log(slug) .subscribe( (term) => {
this.wordpressService.getPage(slug) this.filter = term
.subscribe(data=> { })
this.pages = data;
console.log(data) this.wordpressService.getPage()
}) .subscribe( data => {
}) this.pages = data as PageItem[];
})
this.route.params.subscribe();
// this.route.params.subscribe( params => {
// console.log(params)
// if (params) {
// this.wordpressService.getPage(params.slug)
// .subscribe(data=> {
// this.pages = data;
// console.log(data)
// })
// }
// })
}
goToAnchor(e) {
// console.log(e);
let loc = document.getElementById(e);
loc.scrollIntoView({block:"start"});
}
delFilter(filter) {
this.mapService.delFilter(filter);
} }
} }

View File

@ -1,6 +1,6 @@
import { BrowserModule } from '@angular/platform-browser'; import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { MapBoxComponent } from './map-box/map-box.component'; import { MapBoxComponent } from './map-box/map-box.component';
@ -11,6 +11,7 @@ import { MessageService } from './message.service';
import { TextInfoComponent } from './text-info/text-info.component'; import { TextInfoComponent } from './text-info/text-info.component';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { HttpClientModule } from '@angular/common/http'; import { HttpClientModule } from '@angular/common/http';
import { PagesComponent } from './pages/pages.component';
@ -18,13 +19,15 @@ import { HttpClientModule } from '@angular/common/http';
declarations: [ declarations: [
AppComponent, AppComponent,
MapBoxComponent, MapBoxComponent,
TextInfoComponent TextInfoComponent,
PagesComponent
], ],
imports: [ imports: [
BrowserModule, BrowserModule,
HttpClientModule, HttpClientModule,
AppRoutingModule, AppRoutingModule,
], ],
exports: [ RouterModule ],
providers: [ providers: [
MapService, MapService,
WordpressService, WordpressService,

View File

@ -1 +1,5 @@
div.map {z-index:-10;position:absolute;top:0;left:0;width:100%;width:100vw;height:100%;height:100vh; } div.map {z-index:1;position:absolute;top:0;left:0;width:100%;width:100vw;height:100%;height:100vh; }
@media screen and (max-device-width: 720px) {
div.map {position:relative;}
}

View File

@ -31,12 +31,24 @@ export class MapBoxComponent implements OnInit {
public source:any; public source:any;
private popup = new mapboxgl.Popup({closeButton: true, closeOnClick: true, offset: 0}); private popup = new mapboxgl.Popup({closeButton: true, closeOnClick: true, offset: 0});
public filter;
// this.data = new FeatureCollection;
constructor( constructor(
private mapService: MapService, private mapService: MapService,
private wordpressService:WordpressService, private wordpressService:WordpressService,
private mService:MessageService private mService:MessageService
) { ) {
this.featurecollection = new FeatureCollection([]); this.featurecollection = new FeatureCollection([]);
// this.mapService.featureCollection$.subscribe()
this.mapService.filter$
.subscribe( (term) => {
this.source.setData(new FeatureCollection([]))
if( term!="") this.getSource(term);
this.filter = term;
})
} }
ngOnInit() { ngOnInit() {
@ -103,6 +115,7 @@ export class MapBoxComponent implements OnInit {
this.source = this.map.getSource('ticino') this.source = this.map.getSource('ticino')
//set srouce from wordpress map //set srouce from wordpress map
this.getSource(); this.getSource();
//this.source.setData()
//layers //layers
this.map.addLayer({ this.map.addLayer({
@ -143,10 +156,10 @@ export class MapBoxComponent implements OnInit {
}) })
} }
private getSource():void { private getSource(term:any=''):void {
//get All markers and converto to geoJSON for map Source //get All markers and converto to geoJSON for map Source
let fc = new FeatureCollection([]); let fc = new FeatureCollection([]);
this.wordpressService.getMarker() this.wordpressService.getMarker("",term)
.subscribe( data => { .subscribe( data => {
data.map( data.map(
marker => { marker => {
@ -165,8 +178,8 @@ export class MapBoxComponent implements OnInit {
); );
this.featurecollection = fc; this.featurecollection = fc;
this.source.setData(fc) this.source.setData(fc)
console.log(fc);
}); });
//this.source.setData(this.mapService.getSource(term))
} }

View File

@ -1,20 +1,55 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { environment } from '../environments/environment'; import { environment } from '../environments/environment';
import { WordpressService } from './wordpress.service';
import { GeoJson, FeatureCollection } from './map';
import { Subject,of } from 'rxjs';
import { GeoJson } from './map';
import * as mapboxgl from 'mapbox-gl'; import * as mapboxgl from 'mapbox-gl';
@Injectable() @Injectable()
export class MapService { export class MapService {
constructor() { private featureCollectionSource = new Subject<FeatureCollection>();
public filterSource = new Subject<string>();
constructor(
private wordpressService:WordpressService,
) {
mapboxgl.accessToken = environment.mapbox.accessToken mapboxgl.accessToken = environment.mapbox.accessToken
} }
filter$ = this.filterSource.asObservable();
featureCollection$ = this.featureCollectionSource.asObservable();
// getMarkers(): Observable<any> { setFeatureCollection() {
// return this.db.list('/markers') let fc = new FeatureCollection([]);
// } this.wordpressService.getMarker()
.subscribe( data => {
data.map(
marker => {
let geojson = new GeoJson(
[marker.georeference[0],marker.georeference[1]],
{
title:marker.title.rendered,
content:marker.content.rendered,
id:marker.id,
slug:marker.slug,
}
);
geojson['id']=marker.id;
fc.features.push(geojson)
}
);
this.featureCollectionSource.next(fc)
});
}
public setFilter(filter:any) {
this.filterSource.next(filter);
}
public delFilter(filter:any) {
this.filterSource.next()
}
} }

View File

@ -10,12 +10,14 @@ export class MessageService {
constructor() { } constructor() { }
public addMessage(pageItem:PageItem):void { public addMessage(pageItem:PageItem):void {
console.log('addPage'); let b = document.getElementsByTagName('body')
console.log(pageItem); b[0].style.overflowY = 'hidden';
this.message = [pageItem]; this.message = [pageItem];
} }
public clean() { public clean() {
let b = document.getElementsByTagName('body')
b[0].style.overflowY = 'scroll';
this.message = []; this.message = [];
} }

View File

@ -0,0 +1,28 @@
div.container {background-color:#d52b1e;}
div.page-container {min-height:100vh; background-color:#d52b1e;padding-top:15px;position:relative;clear:both;}
div.page-container h1 {font-family:"Raleway"; font-size:2.5rem;font-weight:bold;color:#fff; padding:0;border:5px solid #fff;width:80%;text-align:center;margin:15px 15px;}
div.page-container div.col-left { text-align:center; min-height:100vh; position:relative;float:left;width:45%;max-width:500px;min-width:320px;}
div.page-container div.col-right { position:relative; color:#fff !important;font-size:14pt;float:left;width:45%;min-width:320px;}
div.page-container div.col-right a {text-decoration:none; padding:0 5px; margin:2px 0; background-color:#333; color:#fff !important;font-weight:bold;}
div.middle-container {max-width:1000px;margin:auto;}
div.page-header {clear:both;width:100%;text-align:center;color:#fff;padding-top:20px;}
/* tricks */
.up_arrow {transform:rotate(-90deg); display: block; font-size:3em; color:#fff;}
.arrow { cursor:pointer; border: solid black; transition:0.3s; border-width: 0 5px 5px 0; display: inline-block; padding: 10px; transform: rotate(-135deg); -webkit-transform: rotate(-135deg); border-color:#fff;}
.arrow:hover { border-width:0 5px 5px 0; opacity:0.8;}
footer {width:100%;padding:20px 0;clear:both;}
footer div.info-footer {max-width:1000px;font-size:0.8rem;text-align:center;margin:auto;}
/* media query */
@media screen and (max-device-width: 720px) {
div.page-container div.col-left {margin:auto; width:100%;width:100%; min-height:0;clear:both;}
div.page-container div.col-right {background-color:#d52b1e;margin:auto; width:100%;width:80vw;clear:both;}
div.page-container h1 {min-width:0;width:100%;height:80%;margin:auto;padding:0;text-align:center;}
div.page-container {padding:0 20px;}
div.container-map-pages {background-color:#d52b1e;}
}

View File

@ -0,0 +1,14 @@
<div class="container-map-pages" id="pages">
<div class="page-container" *ngFor="let page of pages">
<span [id]="page.slug"></span>
<div class="page-header"><span class="arrow" (click)="goUp()"></span></div>
<div class="middle-container">
<div class="col-left"><h1>{{page.title.rendered}}</h1></div>
<div class="col-right" [innerHTML]="page.content.rendered"></div>
</div>
<!-- <div class="page-header" style="width:100%;text-align:center;color:#fff;padding-top:20px;"><span style="transform: rotate(-315deg);" class="arrow" (click)="goUp()"></span></div> -->
</div>
</div>
<footer>
<div class="info-footer">© 2019 SUPSI - <a target="_blank" href="http://www.supsi.ch/home/strumenti/disclaimer.html">Disclaimer</a> - <a target="_blank" href="http://www.supsi.ch/home/supsi/contatti.html">Contatti</a> - UX Develop and mantained by <a href="https://www.audio-lab.org" target="_blank">Audiolab</a></div>
</footer>

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { PagesComponent } from './pages.component';
describe('PagesComponent', () => {
let component: PagesComponent;
let fixture: ComponentFixture<PagesComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ PagesComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(PagesComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,24 @@
import { Component, OnInit, Input } from '@angular/core';
import { WordpressService } from '../wordpress.service';
import { PageItem } from '../page';
@Component({
selector: 'app-pages',
templateUrl: './pages.component.html',
styleUrls: ['./pages.component.css']
})
export class PagesComponent implements OnInit {
@Input() pages:PageItem[] = []
constructor(
private wordpressService:WordpressService,
) { }
ngOnInit() {}
goUp() {
window.scrollTo(0,0)
}
}

View File

@ -0,0 +1,6 @@
ul.categories li ,
ul.tags li
{ cursor:pointer; transition:0.3s; }
ul.categories li:hover,
ul.tags li:hover { color:#d52b1e; font-weight: bold; background:#fff;}

View File

@ -13,6 +13,9 @@
<div class="content-container" [innerHTML]="page.content.rendered"></div> <div class="content-container" [innerHTML]="page.content.rendered"></div>
</div> </div>
<div class="col-right-30 content-col"> <div class="col-right-30 content-col">
<div *ngFor="let m of page.media" class="audio-box">
<audio style="width:100%;" [src]="m.url" controls autoplay></audio>
</div>
<div class="date-container"> <div class="date-container">
<strong>Date:</strong> <p>{{ page.date | date }}</p> <strong>Date:</strong> <p>{{ page.date | date }}</p>
</div> </div>
@ -21,14 +24,14 @@
</div> </div>
<div class="categories-container" *ngIf="page._embedded && page._embedded['wp:term']"> <div class="categories-container" *ngIf="page._embedded && page._embedded['wp:term']">
<strong i18n>Categories</strong> <strong i18n>Categories</strong>
<ul class="categories"><li *ngFor="let cat of page._embedded['wp:term'][0]">{{cat.name}}</li></ul> <ul class="categories"><li *ngFor="let cat of page._embedded['wp:term'][0]" (click)="setTerm(cat)">{{cat.name}}</li></ul>
</div> </div>
<div class="tags-container" *ngIf="page._embedded && page._embedded['wp:term']"> <div class="tags-container" *ngIf="page._embedded && page._embedded['wp:term']">
<strong i18n>Tags</strong> <strong i18n>Tags</strong>
<ul class="tags"><li *ngFor="let cat of page._embedded['wp:term'][1]">{{cat.name}}</li></ul> <ul class="tags"><li *ngFor="let cat of page._embedded['wp:term'][1]" (click)="setTerm(cat)">{{cat.name}}</li></ul>
</div> </div>
<div *ngFor="let m of page.media" class="audio-box"> <div *ngFor="let m of page.media" class="audio-box">
<audio style="width:100%;" [src]="m.url" controls autoplay></audio> <!-- <audio style="width:100%;" [src]="m.url" controls autoplay></audio> -->
<div class="content-metadata" (click)="showMetadata=!showMetadata" style="cursor:pointer;"><strong>Metadata <span *ngIf="!showMetadata || showMetadata==false">&darr;</span><span *ngIf="showMetadata==true">&uarr;</span></strong></div> <div class="content-metadata" (click)="showMetadata=!showMetadata" style="cursor:pointer;"><strong>Metadata <span *ngIf="!showMetadata || showMetadata==false">&darr;</span><span *ngIf="showMetadata==true">&uarr;</span></strong></div>
<ul *ngIf="showMetadata && m"> <ul *ngIf="showMetadata && m">
<li>Title: {{m.title}}</li> <li>Title: {{m.title}}</li>

View File

@ -1,5 +1,6 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { MessageService } from '../message.service' import { MessageService } from '../message.service'
import {MapService} from '../map.service'
@Component({ @Component({
selector: 'text-info', selector: 'text-info',
@ -9,10 +10,19 @@ import { MessageService } from '../message.service'
export class TextInfoComponent implements OnInit { export class TextInfoComponent implements OnInit {
constructor( constructor(
public mService:MessageService public mService:MessageService,
public mapService:MapService
) { } ) { }
ngOnInit() { ngOnInit() {
} }
setTerm(term) {
// console.log("setTerm: "+term);
//this.mapService.filter = term;
this.mapService.setFilter(term);
this.mService.clean();
// this.wordpressService.getMarker('',term);
}
} }

View File

@ -6,7 +6,7 @@ import {PageItem} from './page';
@Injectable() @Injectable()
export class WordpressService { export class WordpressService {
apiUrl : string = "https://chiasso.soinumapa.net/wp-json/wp/v2" apiUrl : string = "https://ticino.soinumapa.net/wp-json/wp/v2"
constructor( constructor(
private http:HttpClient, private http:HttpClient,
@ -29,9 +29,14 @@ export class WordpressService {
return this.http.get<PageItem[]>(url,{ headers:headers, params: searchParams }) return this.http.get<PageItem[]>(url,{ headers:headers, params: searchParams })
} }
public getMarker(slug:string = ""):Observable<PageItem[]> { public getMarker(slug:string = "", term:any = ''):Observable<PageItem[]> {
let params = "?_embed"; let params = "?_embed";
if (slug!="") params = params+"&slug="+slug; if (slug!="") params = params+"&slug="+slug;
if (term!="") {
let collection = term["_links"]['collection'][0]['href']
let collectionStr = collection.split("/").slice(-1)[0]
params = params+"&"+collectionStr+"="+term.id
}
let url = this.apiUrl+"/marker"+params; let url = this.apiUrl+"/marker"+params;
return this.http.get<PageItem[]>(url); return this.http.get<PageItem[]>(url);
} }

View File

@ -1,3 +1,6 @@
export const environment = { export const environment = {
production: true production: true,
mapbox: {
accessToken: 'pk.eyJ1IjoibHJ1bGxvIiwiYSI6ImNpaDUydjdoNTAwd3BzdGx5bGlhOTh6bXYifQ.tE8QgNbVSgwP8V5LnJWA3w'
}
}; };

View File

@ -4,7 +4,6 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>Ticino Soundmap</title> <title>Ticino Soundmap</title>
<base href="/"> <base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico"> <link rel="icon" type="image/x-icon" href="favicon.ico">
<link href='https://api.mapbox.com/mapbox-gl-js/v0.38.0/mapbox-gl.css' rel='stylesheet' /> <link href='https://api.mapbox.com/mapbox-gl-js/v0.38.0/mapbox-gl.css' rel='stylesheet' />

View File

@ -1,14 +1,17 @@
/* You can add global styles to this file, and also import other style files */ /* You can add global styles to this file, and also import other style files */
@import url('https://fonts.googleapis.com/css?family=Oswald|Raleway'); @import url('https://fonts.googleapis.com/css?family=Oswald|Raleway');
body {padding:0;font-size:12pt;overflow:hidden;font-family:'Raleway',sans-serif;} html { scroll-behavior: smooth;}
body {padding:0;font-size:12pt;overflow-x:hidden;font-family:'Raleway',sans-serif;margin:0}
a {color:#fff;padding:0 5px;background-color:#333;font-weight:bold;text-decoration:none;}
h1,h2,h3,h4,h5,h6 {font-family:'Oswald';} h1,h2,h3,h4,h5,h6 {font-family:'Oswald';}
div.modal {display:block;position:absolute;top:0;left:0;width:100vw;height:100vh;width:100%;height:100%; background-color:rgba(255,255,255,0.8);overflow-y:scroll;} div.modal {z-index:20;display:block;position:absolute;top:0;left:0;width:100vw;height:100vh;width:100%;height:100%; background-color:rgba(255,255,255,0.8);overflow-y:scroll;}
div.content { position:relative;display:block;height:100%;overflow:auto;font-size:1em;background:#fff;border:1px solid #eee;padding:30px;border-radius:1px; position:relative; width:80vw;min-height:50vh;margin:auto;margin-top:10vh;margin-bottom:10vh;} div.content { position:relative;display:block;height:100%;overflow:auto;font-size:1em;background:#fff;border:1px solid #eee;padding:30px;border-radius:1px; position:relative; width:80vw;min-height:50vh;margin:auto;margin-top:2vh;margin-bottom:10vh;}
div.col-left-70 {position:relative;float:right;width:66%;padding-left:1%;padding-right:1%;} div.col-left-70 {position:relative;float:right;width:66%;padding-left:1%;padding-right:1%;}
div.col-right-30 {border-right:1px solid #ccc;position:relative;float:right;width:28%;padding-left:1%;padding-right:1%;} div.col-right-30 {border-right:1px solid #ccc;position:relative;float:right;width:28%;padding-left:1%;padding-right:1%;}
div.content h1 span {background-color:#d52b1e;color:#fff;font-size:3em;padding:0 20px;} div.content h1 span {font-size:3em;padding:0 20px;}
div.content h1,h2,h3,h4,h5 {font-size:1em;color:#d52b1e;} div.title h2 span { background:#ccc; color:#fff; padding:0 20px;}
div.content h1,h2,h3,h4,h5 {text-decoration:none; font-size:1em;color:#d52b1e;}
div.content div.content-col > * {margin:0 20px;height:100%;display:block;} div.content div.content-col > * {margin:0 20px;height:100%;display:block;}
div.content div.col-right-30 > * {margin-bottom:20px;} div.content div.col-right-30 > * {margin-bottom:20px;}
div.content div.tags-container, div.content div.tags-container,
@ -24,3 +27,18 @@ div.content ul.tags li {float:left;padding:5px;margin:2px;background-color:#d52b
div.content div.audio-box audio {margin-top:10px;margin-bottom:10px;} div.content div.audio-box audio {margin-top:10px;margin-bottom:10px;}
div.close-button {cursor:pointer;position:absolute;right:0;top:0;z-index:100;padding:10px;} div.close-button {cursor:pointer;position:absolute;right:0;top:0;z-index:100;padding:10px;}
div close-button:hover {background:#eee;} div close-button:hover {background:#eee;}
div.content div.audio-box {clear:both;}
div.content-metadata {top:20px;position:relative;}
div.content div.audio-box ul li {padding:3px 0;font-size:0.8em;}
/* pages */
app-pages div.container-map-pages {padding-top:100vh;background-color:#d52b1e;}
/* trick */
div.mapboxgl-ctrl-bottom-right,
div.mapboxgl-ctrl-bottom-left { display:none;}
@media screen and (max-device-width: 720px) {
body { background-color:#d52b1e}
}