mirror of
https://github.com/bellingcat/ukraine-timemap.git
synced 2026-06-07 19:08:37 +03:00
feat(main): style changes and mobile version (#58)
Co-authored-by: msramalho <19508417+msramalho@users.noreply.github.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
const one_day = 1440;
|
||||
module.exports = {
|
||||
title: "ukraine",
|
||||
display_title: "Civilian Harm in Ukraine",
|
||||
display_title: "Civilian Harm\nin Ukraine",
|
||||
SERVER_ROOT: "https://ukraine.bellingcat.com/ukraine-server",
|
||||
EVENTS_EXT: "/api/ukraine/export_events/deeprows",
|
||||
SOURCES_EXT: "/api/ukraine/export_sources/deepids",
|
||||
@@ -29,8 +29,8 @@ module.exports = {
|
||||
},
|
||||
timeline: {
|
||||
dimensions: {
|
||||
height: 150,
|
||||
contentHeight: 150,
|
||||
height: 90,
|
||||
contentHeight: 90,
|
||||
},
|
||||
zoomLevels: [
|
||||
{ label: "Zoom to 2 weeks", duration: 14 * one_day },
|
||||
@@ -59,9 +59,8 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
intro: [
|
||||
'<div style="display:flex; flex-direction: row; width: 100%; min-width: calc(100% - 20px); max-width: 25vw; margin-top: 20px; gap: 20px; justify-content: space-between;"><img style="max-width:35vw; width:50%;" src="https://bellingcat-embeds.ams3.cdn.digitaloceanspaces.com/ukraine-timemap/cover01-s.jpg" frameborder="0"></img><img style="max-width:35vw; width:50%;" src="https://bellingcat-embeds.ams3.cdn.digitaloceanspaces.com/ukraine-timemap/cover02-s.jpg" frameborder="0"></img></div>',
|
||||
'<div class="two-columns"><div class="two-columns_column"><figure><img style="width: 100%; display:block;" src="https://bellingcat-embeds.ams3.cdn.digitaloceanspaces.com/ukraine-timemap/cover01-s.jpg" frameborder="0"><figcaption>Image: Vyacheslav Madiyevskyy/Reuters</figcaption></figure></div><div class="two-columns_column"><figure><img style="width: 100%; display:block;" src="https://bellingcat-embeds.ams3.cdn.digitaloceanspaces.com/ukraine-timemap/cover02-s.jpg" frameborder="0"><figcaption>Image: Järva Teataja/Scanpix Baltics via Reuters</figcaption></figure></div></div>',
|
||||
'This map plots out and highlights incidents that have resulted in potential civilian impact or harm since Russia began its invasion of Ukraine. The incidents detailed have been collected by Bellingcat researchers. Included in the map are instances where civilian areas and infrastructure have been damaged or destroyed, where the presence of civilian injuries are visible and/or there is the presence of immobile civilian bodies. Collection for the incidences contained in this map began on February 24, 2022. Users can explore incidents by date and location. We intend this to be a living project that will continue to be updated as long as the conflict persists. For more detailed information about the entries included in this map, please refer to our methodology and explainer article which can be read <a href="https://www.bellingcat.com/news/2022/03/17/hospitals-bombed-and-apartments-destroyed-mapping-incidents-of-civilian-harm-in-ukraine/" >here</a>. ',
|
||||
"Image left: Vyacheslav Madiyevskyy/Reuters. Image right: Järva Teataja/Scanpix Baltics via Reuters.",
|
||||
],
|
||||
|
||||
flags: { isInfopoup: false, isCover: false },
|
||||
|
||||
39
index.html
39
index.html
@@ -1,23 +1,39 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>TimeMap - Forensic Architecture</title>
|
||||
<link rel="stylesheet" href="https://api.mapbox.com/mapbox.js/v3.1.1/mapbox.css">
|
||||
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
|
||||
<!-- <link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet"> -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
|
||||
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<!-- Styles are always go to the head, never the body -->
|
||||
<style>
|
||||
@media (hover: none) {
|
||||
#id {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#nodisplay {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
#nodisplay {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<style>
|
||||
@media (hover: none) {
|
||||
#id { display: none; }
|
||||
#nodisplay { display: block; }
|
||||
}
|
||||
@media (hover: hover) {
|
||||
#nodisplay {display: none; }
|
||||
}
|
||||
</style>
|
||||
<div class="page">
|
||||
<div class="page">
|
||||
<div id="explore-app"></div>
|
||||
@@ -27,4 +43,5 @@
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
||||
@@ -12,11 +12,26 @@
|
||||
"Cada evento estará coloreado según la persona que dio el testimonio del evento."
|
||||
],
|
||||
"colors": [
|
||||
{ "class": "category_group00", "label": "Categoría Grupo 00" },
|
||||
{ "class": "category_group01", "label": "Categoría Grupo 01" },
|
||||
{ "class": "category_group02", "label": "Categoría Grupo 02" },
|
||||
{ "class": "category_group03", "label": "Categoría Grupo 03" },
|
||||
{ "class": "other", "label": "Otras categorías" }
|
||||
{
|
||||
"class": "category_group00",
|
||||
"label": "Categoría Grupo 00"
|
||||
},
|
||||
{
|
||||
"class": "category_group01",
|
||||
"label": "Categoría Grupo 01"
|
||||
},
|
||||
{
|
||||
"class": "category_group02",
|
||||
"label": "Categoría Grupo 02"
|
||||
},
|
||||
{
|
||||
"class": "category_group03",
|
||||
"label": "Categoría Grupo 03"
|
||||
},
|
||||
{
|
||||
"class": "other",
|
||||
"label": "Otras categorías"
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
@@ -54,12 +69,30 @@
|
||||
},
|
||||
"timeline": {
|
||||
"zoomLevels": [
|
||||
{ "label": "20 años", "duration": 10512000 },
|
||||
{ "label": "2 años", "duration": 1051200 },
|
||||
{ "label": "3 meses", "duration": 129600 },
|
||||
{ "label": "3 días", "duration": 4320 },
|
||||
{ "label": "12 horas", "duration": 720 },
|
||||
{ "label": "1 hora", "duration": 60 }
|
||||
{
|
||||
"label": "20 años",
|
||||
"duration": 10512000
|
||||
},
|
||||
{
|
||||
"label": "2 años",
|
||||
"duration": 1051200
|
||||
},
|
||||
{
|
||||
"label": "3 meses",
|
||||
"duration": 129600
|
||||
},
|
||||
{
|
||||
"label": "3 días",
|
||||
"duration": 4320
|
||||
},
|
||||
{
|
||||
"label": "12 horas",
|
||||
"duration": 720
|
||||
},
|
||||
{
|
||||
"label": "1 hora",
|
||||
"duration": 60
|
||||
}
|
||||
],
|
||||
"labels_title": "Testimonios",
|
||||
"labels": [
|
||||
@@ -106,11 +139,26 @@
|
||||
"Each event is colored according the person that gave category of the event."
|
||||
],
|
||||
"colors": [
|
||||
{ "class": "category_group00", "label": "Category Group 00" },
|
||||
{ "class": "category_group01", "label": "Category Group 01" },
|
||||
{ "class": "category_group02", "label": "Category Group 02" },
|
||||
{ "class": "category_group03", "label": "Category Group 03" },
|
||||
{ "class": "other", "label": "Other categories" }
|
||||
{
|
||||
"class": "category_group00",
|
||||
"label": "Category Group 00"
|
||||
},
|
||||
{
|
||||
"class": "category_group01",
|
||||
"label": "Category Group 01"
|
||||
},
|
||||
{
|
||||
"class": "category_group02",
|
||||
"label": "Category Group 02"
|
||||
},
|
||||
{
|
||||
"class": "category_group03",
|
||||
"label": "Category Group 03"
|
||||
},
|
||||
{
|
||||
"class": "other",
|
||||
"label": "Other categories"
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
@@ -149,7 +197,7 @@
|
||||
"filters": "Filters",
|
||||
"filters_label": "Filters",
|
||||
"explore_by_filter__title": "Explore by filter",
|
||||
"explore_by_filter__description": "'Filters' refer to the types of incident. Select multiple filters to introduce colour-coding, up to a maximum of four filters.<br><br>If no filters are selected, all datapoints are displayed.",
|
||||
"explore_by_filter__description": "'Filters' refer to the types of incident. Select multiple filters to introduce colour-coding, up to a maximum of four filters.<br><br><span class='hint'>If no filters are selected, all datapoints are displayed.</span>",
|
||||
"categories": "Categories",
|
||||
"categories_label": "Categories",
|
||||
"explore_by_category__title": "Explore events by category",
|
||||
@@ -187,7 +235,7 @@
|
||||
"Testimony Group 03",
|
||||
"Other"
|
||||
],
|
||||
"info": "Seeing %n events that occurred between",
|
||||
"info": "Showing <span>%n events</span> that occurred between",
|
||||
"default_categories_label": ""
|
||||
},
|
||||
"cardstack": {
|
||||
|
||||
@@ -2,7 +2,6 @@ import React from "react";
|
||||
|
||||
import { bindActionCreators } from "redux";
|
||||
import { connect } from "react-redux";
|
||||
import { isMobileOnly } from "react-device-detect";
|
||||
import * as actions from "../actions";
|
||||
import * as selectors from "../selectors";
|
||||
|
||||
@@ -248,18 +247,8 @@ class Dashboard extends React.Component {
|
||||
}
|
||||
|
||||
renderIntroPopup(styles) {
|
||||
const checkMobile = isMobileOnly || window.innerWidth < 600;
|
||||
const { app, actions } = this.props;
|
||||
|
||||
const extraContent = checkMobile ? (
|
||||
<div style={{ position: "relative", bottom: 0 }}>
|
||||
<h3 style={{ color: "var(--error-red)" }}>
|
||||
This platform may not work correctly on mobile. If possible, please
|
||||
re-visit the site on a device with a larger screen.
|
||||
</h3>
|
||||
</div>
|
||||
) : null;
|
||||
|
||||
let searchParams = new URLSearchParams(window.location.href.split("?")[1]);
|
||||
let rememberDismissedIntro =
|
||||
localStorage.getItem("rememberDismissedIntro") === "true";
|
||||
@@ -281,9 +270,7 @@ class Dashboard extends React.Component {
|
||||
}}
|
||||
content={app.intro}
|
||||
styles={styles}
|
||||
>
|
||||
{extraContent}
|
||||
</Popup>
|
||||
></Popup>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
@@ -292,33 +279,12 @@ class Dashboard extends React.Component {
|
||||
|
||||
render() {
|
||||
const { actions, app, domain, timeline, features } = this.props;
|
||||
const dateHeight = 80;
|
||||
const padding = 2;
|
||||
const checkMobile = isMobileOnly || window.innerWidth < 600;
|
||||
|
||||
const popupStyles = {
|
||||
height: checkMobile ? "100vh" : "fit-content",
|
||||
display: checkMobile ? "block" : "table",
|
||||
width: checkMobile
|
||||
? "100vw"
|
||||
: window.innerWidth > 768
|
||||
? "60vw"
|
||||
: "calc(100vw - var(--toolbar-width))",
|
||||
maxWidth: checkMobile ? "100vw" : 600,
|
||||
maxHeight: checkMobile
|
||||
? "100vh"
|
||||
: window.innerHeight > 768
|
||||
? `calc(100vh - ${timeline.dimensions.height}px - ${dateHeight}px)`
|
||||
: "100vh",
|
||||
left: checkMobile ? padding : "var(--toolbar-width)",
|
||||
top: 0,
|
||||
overflowY: "scroll",
|
||||
textAlign: "justify",
|
||||
};
|
||||
const popupStyles = {};
|
||||
|
||||
return (
|
||||
<div>
|
||||
{checkMobile ? null : (
|
||||
{
|
||||
<Toolbar
|
||||
isNarrative={!!app.associations.narrative}
|
||||
domain={domain}
|
||||
@@ -332,7 +298,7 @@ class Dashboard extends React.Component {
|
||||
onSelectNarrative: this.setNarrative,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
}
|
||||
<Space
|
||||
kind={"map" in app ? "map" : "space3d"}
|
||||
onKeyDown={this.onKeyDown}
|
||||
@@ -344,7 +310,7 @@ class Dashboard extends React.Component {
|
||||
: (ev) => this.handleSelect(ev, 1),
|
||||
}}
|
||||
/>
|
||||
{checkMobile ? null : (
|
||||
{
|
||||
<Timeline
|
||||
onKeyDown={this.onKeyDown}
|
||||
methods={{
|
||||
@@ -355,7 +321,7 @@ class Dashboard extends React.Component {
|
||||
getCategoryColor: this.getCategoryColor,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
}
|
||||
<CardStack
|
||||
timelineDims={timeline.dimensions}
|
||||
onViewSource={this.handleViewSource}
|
||||
|
||||
@@ -186,10 +186,7 @@ class TemplateCover extends React.Component {
|
||||
</video>
|
||||
</div>
|
||||
) : null}
|
||||
<h2
|
||||
style={{ margin: 0 }}
|
||||
dangerouslySetInnerHTML={{ __html: marked(this.props.cover.title) }}
|
||||
/>
|
||||
<h2 dangerouslySetInnerHTML={{ __html: this.props.cover.title }} />
|
||||
{this.props.cover.subtitle ? (
|
||||
<h3 style={{ marginTop: 0 }}>{this.props.cover.subtitle}</h3>
|
||||
) : null}
|
||||
|
||||
@@ -29,12 +29,15 @@ class Toolbar extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.onSelectFilter = this.onSelectFilter.bind(this);
|
||||
this.state = { _selected: -1 };
|
||||
this.state = { _selected: 0, _active: false };
|
||||
}
|
||||
|
||||
selectTab(selected) {
|
||||
const _selected = this.state._selected === selected ? -1 : selected;
|
||||
this.setState({ _selected });
|
||||
let active = true;
|
||||
if (this.state._selected === selected && this.state._active === true) {
|
||||
active = false;
|
||||
}
|
||||
this.setState({ _selected: selected, _active: active });
|
||||
}
|
||||
|
||||
onSelectFilter(key, matchingKeys) {
|
||||
@@ -79,14 +82,17 @@ class Toolbar extends React.Component {
|
||||
|
||||
renderClosePanel() {
|
||||
return (
|
||||
<div className="panel-header" onClick={() => this.selectTab(-1)}>
|
||||
<div
|
||||
className="panel-header"
|
||||
onClick={() => this.selectTab(this.state._selected)}
|
||||
>
|
||||
<div className="caret" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
goToNarrative(narrative) {
|
||||
this.selectTab(-1); // set all unselected within this component
|
||||
// this.selectTab(-1); // set all unselected within this component
|
||||
this.props.methods.onSelectNarrative(narrative);
|
||||
}
|
||||
|
||||
@@ -202,7 +208,9 @@ class Toolbar extends React.Component {
|
||||
key={key}
|
||||
label={label}
|
||||
iconKey={iconKey}
|
||||
isActive={this.state._selected === _selected}
|
||||
isActive={
|
||||
this.state._selected === _selected && this.state._active === true
|
||||
}
|
||||
onClick={() => {
|
||||
this.selectTab(_selected);
|
||||
}}
|
||||
@@ -229,7 +237,7 @@ class Toolbar extends React.Component {
|
||||
renderToolbarPanels() {
|
||||
const { features, narratives } = this.props;
|
||||
const classes =
|
||||
this.state._selected >= 0 ? "toolbar-panels" : "toolbar-panels folded";
|
||||
this.state._active === true ? "toolbar-panels" : "toolbar-panels folded";
|
||||
return (
|
||||
<div className={classes}>
|
||||
{this.renderClosePanel()}
|
||||
@@ -247,7 +255,8 @@ class Toolbar extends React.Component {
|
||||
renderToolbarNavs() {
|
||||
if (this.props.narratives) {
|
||||
return this.props.narratives.map((nar, idx) => {
|
||||
const isActive = idx === this.state._selected;
|
||||
const isActive =
|
||||
idx === this.state._selected && this.state._active === true;
|
||||
|
||||
const classes = isActive ? "toolbar-tab active" : "toolbar-tab";
|
||||
|
||||
@@ -344,6 +353,14 @@ class Toolbar extends React.Component {
|
||||
}}
|
||||
features={this.props.features}
|
||||
/>
|
||||
|
||||
<div id="made-with">
|
||||
Made with{" "}
|
||||
<a href="https://github.com/forensic-architecture/timemap">TimeMap</a>
|
||||
<br />
|
||||
Free software from{" "}
|
||||
<a href="https://forensic-architecture.org">Forensic Architecture</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,14 +13,26 @@ const Checkbox = ({ label, isActive, onClickCheckbox, color, styleProps }) => {
|
||||
const checkboxStyles = styleProps
|
||||
? styleProps.checkboxStyles
|
||||
: baseStyles.checkboxStyles;
|
||||
|
||||
const generatedId = label.toLowerCase().replaceAll(" ", "-");
|
||||
const onClickCheckboxWrapper = (e) => {
|
||||
// stop propagation in order to call method only one time
|
||||
e.stopPropagation();
|
||||
onClickCheckbox(e);
|
||||
};
|
||||
return (
|
||||
<div className={isActive ? "item active" : "item"}>
|
||||
<span style={{ color: color }}>{label}</span>
|
||||
<button onClick={onClickCheckbox}>
|
||||
<div
|
||||
className={isActive ? "item active" : "item"}
|
||||
onClick={onClickCheckboxWrapper}
|
||||
>
|
||||
<button id={generatedId} onClick={onClickCheckboxWrapper}>
|
||||
<div className="border" style={containerStyles}>
|
||||
<div className="checkbox" style={checkboxStyles} />
|
||||
</div>
|
||||
</button>
|
||||
<label htmlFor={generatedId} style={{ color: color }}>
|
||||
{label}
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -13,6 +13,10 @@ const Popup = ({
|
||||
children,
|
||||
}) => (
|
||||
<div>
|
||||
<div
|
||||
className={`infopopup__bg ${isOpen ? "" : "hidden"}`}
|
||||
onClick={onClose}
|
||||
></div>
|
||||
<div
|
||||
className={`infopopup ${isOpen ? "" : "hidden"} ${
|
||||
theme === "dark" ? "dark" : "light"
|
||||
|
||||
@@ -67,13 +67,20 @@ export const generateCardLayout = {
|
||||
scaleFont: 1.1,
|
||||
},
|
||||
],
|
||||
...event.sources.flatMap((source) => [
|
||||
source.paths.map((p) => ({
|
||||
kind: "media",
|
||||
title: "Media",
|
||||
value: [{ src: p, title: null, graphic: event.graphic === "TRUE" }],
|
||||
})),
|
||||
]),
|
||||
[
|
||||
{
|
||||
kind: "sources",
|
||||
values: event.sources.flatMap((source) => [
|
||||
source.paths.map((p) => ({
|
||||
kind: "media",
|
||||
title: "Media",
|
||||
value: [
|
||||
{ src: p, title: null, graphic: event.graphic === "TRUE" },
|
||||
],
|
||||
})),
|
||||
]),
|
||||
},
|
||||
],
|
||||
];
|
||||
},
|
||||
};
|
||||
@@ -210,12 +217,14 @@ export const Card = ({
|
||||
}
|
||||
}
|
||||
|
||||
function renderRow(row, cardIdx) {
|
||||
function renderRow(row, cardIdx, salt) {
|
||||
return (
|
||||
<div className="card-row" key={hash(row)}>
|
||||
<div className="card-row" key={hash({ ...row, salt })}>
|
||||
{row.map((field) => (
|
||||
// src by src meaning wrapGrahpic must be called around a map of renderField for sources
|
||||
<span key={hash(field)}>{renderField(field, cardIdx)}</span>
|
||||
<span key={hash({ ...field, row: row })}>
|
||||
{renderField(field, cardIdx)}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
@@ -230,14 +239,34 @@ export const Card = ({
|
||||
className={`event-card ${isSelected ? "selected" : ""}`}
|
||||
onClick={onSelect}
|
||||
>
|
||||
{content.map((row) => renderRow(row, cardIdx))}
|
||||
{isOpen && (
|
||||
{content.map((row) => {
|
||||
if (row[0].kind === "sources" && row[0].values.length > 0) {
|
||||
return (
|
||||
<div>
|
||||
<details open="true">
|
||||
<summary>
|
||||
<span className="summary-line"></span>
|
||||
<span className="summary-text">
|
||||
<span className="summary-show">Show</span>{" "}
|
||||
<span className="summary-hide">Hide</span> sources (
|
||||
{row[0].values.length})
|
||||
</span>
|
||||
<span className="summary-line"></span>
|
||||
</summary>
|
||||
{row[0].values.map((r) => renderRow(r, cardIdx, row[0]))}
|
||||
</details>
|
||||
</div>
|
||||
);
|
||||
} else return renderRow(row, cardIdx);
|
||||
})}
|
||||
|
||||
{/* {isOpen && (
|
||||
<div className="card-bottomhalf">
|
||||
{sources.map(() => (
|
||||
<div className="card-row"></div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
)} */}
|
||||
{sources.length > 0 ? renderCaret() : null}
|
||||
</li>
|
||||
);
|
||||
|
||||
@@ -126,7 +126,10 @@ class CardStack extends React.Component {
|
||||
|
||||
renderCardStackContent() {
|
||||
return (
|
||||
<div id="card-stack-content" className="card-stack-content">
|
||||
<div
|
||||
id="card-stack-content"
|
||||
className="card-stack-content scrollbar-black"
|
||||
>
|
||||
<ul>{this.renderSelectedCards()}</ul>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -4,8 +4,15 @@ import { DownloadButton } from "./DownloadButton";
|
||||
const DownloadPanel = ({ language, title, description, domain }) => {
|
||||
return (
|
||||
<div className="react-innertabpanel">
|
||||
<h2>{title}</h2>
|
||||
<p>{description}</p>
|
||||
<div className="sticky-header">
|
||||
<h2>{title}</h2>
|
||||
</div>
|
||||
<div
|
||||
className="panel-description"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: description,
|
||||
}}
|
||||
/>
|
||||
<hr />
|
||||
<DownloadButton language={language} domain={domain} format="csv" />
|
||||
<DownloadButton language={language} domain={domain} format="json" />
|
||||
|
||||
@@ -56,7 +56,10 @@ function FilterListPanel({
|
||||
<Checkbox
|
||||
label={pathLeaf}
|
||||
isActive={activeFilters.includes(key)}
|
||||
onClickCheckbox={() => onSelectFilter(key, matchingKeys)}
|
||||
onClickCheckbox={(e) => {
|
||||
e.preventDefault();
|
||||
onSelectFilter(key, matchingKeys);
|
||||
}}
|
||||
color={assignedColor}
|
||||
/>
|
||||
{Object.keys(children).length > 0 ? (
|
||||
@@ -74,18 +77,21 @@ function FilterListPanel({
|
||||
const aggregatedFilterPaths = aggregateFilterPaths(filters);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="scrolled-area">
|
||||
{Object.entries(aggregatedFilterPaths).map((filter) =>
|
||||
createNodeComponent(filter, 1)
|
||||
createNodeComponent(filter, 0)
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="react-innertabpanel">
|
||||
<h2>{title}</h2>
|
||||
<p
|
||||
<div>
|
||||
<div className="sticky-header">
|
||||
<h2>{title}</h2>
|
||||
</div>
|
||||
<div
|
||||
className="panel-description"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: marked(description),
|
||||
}}
|
||||
|
||||
@@ -12,7 +12,6 @@ const PanelTree = ({ data, activeValues, onSelect, type }) => {
|
||||
<li
|
||||
key={val.title.replace(/ /g, "_")}
|
||||
className="filter-filter active"
|
||||
style={{ marginLeft: "20px" }}
|
||||
>
|
||||
<Checkbox
|
||||
label={val.title}
|
||||
|
||||
@@ -7,6 +7,7 @@ const CardText = ({ title, value, hoverValue = null }) => {
|
||||
<div className="card-cell">
|
||||
{title ? <h4>{title}</h4> : null}
|
||||
<div
|
||||
className="card-cell__text"
|
||||
style={{
|
||||
width: `fit-content`,
|
||||
}}
|
||||
|
||||
@@ -31,12 +31,12 @@ class TimelineAxis extends React.Component {
|
||||
fstFmt = "";
|
||||
}
|
||||
|
||||
const { marginTop, contentHeight } = this.props.dims;
|
||||
let { marginTop } = this.props.dims;
|
||||
if (this.props.scaleX) {
|
||||
this.x0 = axisBottom(this.props.scaleX)
|
||||
.ticks(this.props.ticks)
|
||||
.tickPadding(0)
|
||||
.tickSize(contentHeight - TEXT_HEIGHT - marginTop)
|
||||
.tickPadding(marginTop + 30)
|
||||
.tickSize(100 - TEXT_HEIGHT - marginTop)
|
||||
.tickFormat(timeFormat(fstFmt));
|
||||
|
||||
this.x1 = axisBottom(this.props.scaleX)
|
||||
@@ -66,7 +66,7 @@ class TimelineAxis extends React.Component {
|
||||
<>
|
||||
<g
|
||||
ref={this.xAxis0Ref}
|
||||
transform={`translate(0, ${this.props.dims.marginTop})`}
|
||||
transform={`translate(0, 24)`}
|
||||
clipPath="url(#clip)"
|
||||
className="axis xAxis"
|
||||
/>
|
||||
|
||||
@@ -40,15 +40,11 @@ class TimelineCategories extends React.Component {
|
||||
className="tick"
|
||||
style={{ strokeWidth }}
|
||||
opacity="0.5"
|
||||
transform={`translate(0,${this.props.getCategoryY(cat)})`}
|
||||
transform={`translate(0, 66)`}
|
||||
>
|
||||
<line x1={dims.marginLeft} x2={dims.width - dims.width_controls} />
|
||||
<line x1={dims.marginLeft} x2={dims.width - dims.marginLeft} />
|
||||
</g>
|
||||
<g
|
||||
className="tick"
|
||||
opacity="1"
|
||||
transform={`translate(0,${this.props.getCategoryY(cat)})`}
|
||||
>
|
||||
<g className="tick" opacity="1" transform={`translate(0, 66)`}>
|
||||
<text x={dims.marginLeft - 5} dy="0.32em">
|
||||
{cat}
|
||||
</text>
|
||||
@@ -72,10 +68,7 @@ class TimelineCategories extends React.Component {
|
||||
className="drag-grabber"
|
||||
x={dims.marginLeft}
|
||||
y={dims.marginTop}
|
||||
width={Math.max(
|
||||
0,
|
||||
dims.width - dims.marginLeft - dims.width_controls
|
||||
)}
|
||||
width={Math.max(0, dims.width - dims.marginLeft * 2)}
|
||||
height={dims.contentHeight}
|
||||
/>
|
||||
</g>
|
||||
|
||||
@@ -97,7 +97,7 @@ class Timeline extends React.Component {
|
||||
.domain(this.state.timerange)
|
||||
.range([
|
||||
this.state.dims.marginLeft,
|
||||
this.state.dims.width - this.state.dims.width_controls,
|
||||
this.state.dims.width - this.state.dims.marginLeft,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -369,12 +369,6 @@ class Timeline extends React.Component {
|
||||
let classes = `timeline-wrapper ${this.state.isFolded ? " folded" : ""}`;
|
||||
classes += app.narrative !== null ? " narrative-mode" : "";
|
||||
const { dims } = this.state;
|
||||
const foldedStyle = {
|
||||
bottom: this.state.isFolded ? -dims.height : 0,
|
||||
left: 110,
|
||||
};
|
||||
const heightStyle = { height: dims.height };
|
||||
const extraStyle = { ...heightStyle, ...foldedStyle };
|
||||
const contentHeight = { height: dims.contentHeight };
|
||||
const { activeCategories: categories } = this.props;
|
||||
|
||||
@@ -384,12 +378,7 @@ class Timeline extends React.Component {
|
||||
);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classes}
|
||||
style={extraStyle}
|
||||
onKeyDown={this.props.onKeyDown}
|
||||
tabIndex="1"
|
||||
>
|
||||
<div className={classes} onKeyDown={this.props.onKeyDown} tabIndex="1">
|
||||
<Header
|
||||
title={title}
|
||||
from={this.state.timerange[0]}
|
||||
@@ -399,87 +388,94 @@ class Timeline extends React.Component {
|
||||
}}
|
||||
hideInfo={isNarrative}
|
||||
/>
|
||||
<div className="timeline-content" style={heightStyle}>
|
||||
<div
|
||||
id={this.props.ui.dom.timeline}
|
||||
className="timeline"
|
||||
style={contentHeight}
|
||||
>
|
||||
<svg ref={this.svgRef} width={dims.width} style={contentHeight}>
|
||||
<Clip dims={dims} />
|
||||
<Axis
|
||||
ticks={timeline.dimensions.ticks}
|
||||
dims={dims}
|
||||
extent={this.getTimeScaleExtent()}
|
||||
transitionDuration={this.state.transitionDuration}
|
||||
scaleX={this.state.scaleX}
|
||||
/>
|
||||
<Categories
|
||||
dims={dims}
|
||||
getCategoryY={(category) =>
|
||||
this.getY({ category, project: null })
|
||||
}
|
||||
onDragStart={this.onDragStart}
|
||||
onDrag={this.onDrag}
|
||||
onDragEnd={this.onDragEnd}
|
||||
categories={categories}
|
||||
features={this.props.features}
|
||||
fallbackLabel={
|
||||
copy[this.props.app.language].timeline
|
||||
.default_categories_label
|
||||
}
|
||||
/>
|
||||
{timeline.dimensions.ticks === 1 && (
|
||||
<Handles
|
||||
<div className="timeline-content">
|
||||
<div id={this.props.ui.dom.timeline} className="timeline">
|
||||
<div className="timeline-container">
|
||||
<svg ref={this.svgRef} width={dims.width} style={contentHeight}>
|
||||
<Clip dims={dims} />
|
||||
<Axis
|
||||
ticks={timeline.dimensions.ticks}
|
||||
dims={dims}
|
||||
onMoveTime={(dir) => {
|
||||
this.onMoveTime(dir);
|
||||
}}
|
||||
extent={this.getTimeScaleExtent()}
|
||||
transitionDuration={this.state.transitionDuration}
|
||||
scaleX={this.state.scaleX}
|
||||
/>
|
||||
)}
|
||||
<Categories
|
||||
dims={dims}
|
||||
getCategoryY={(category) =>
|
||||
this.getY({ category, project: null })
|
||||
}
|
||||
onDragStart={this.onDragStart}
|
||||
onDrag={this.onDrag}
|
||||
onDragEnd={this.onDragEnd}
|
||||
categories={categories}
|
||||
features={this.props.features}
|
||||
fallbackLabel={
|
||||
copy[this.props.app.language].timeline
|
||||
.default_categories_label
|
||||
}
|
||||
/>
|
||||
<Markers
|
||||
dims={dims}
|
||||
selected={this.props.app.selected}
|
||||
getEventX={(ev) => this.getDatetimeX(ev.datetime)}
|
||||
getEventY={this.getY}
|
||||
categories={categories}
|
||||
transitionDuration={this.state.transitionDuration}
|
||||
styles={this.props.ui.styles}
|
||||
features={this.props.features}
|
||||
eventRadius={this.props.ui.eventRadius}
|
||||
/>
|
||||
<Events
|
||||
events={this.props.domain.events}
|
||||
projects={this.props.domain.projects}
|
||||
categories={categories}
|
||||
styleDatetime={this.styleDatetime}
|
||||
narrative={this.props.app.narrative}
|
||||
getDatetimeX={this.getDatetimeX}
|
||||
getY={this.getY}
|
||||
getHighlights={(group) => {
|
||||
if (group === "None") {
|
||||
return [];
|
||||
}
|
||||
return categories.map((c) => c.group === group);
|
||||
}}
|
||||
getCategoryColor={this.props.methods.getCategoryColor}
|
||||
transitionDuration={this.state.transitionDuration}
|
||||
onSelect={this.onSelect}
|
||||
dims={dims}
|
||||
features={this.props.features}
|
||||
setLoading={this.props.actions.setLoading}
|
||||
setNotLoading={this.props.actions.setNotLoading}
|
||||
eventRadius={this.props.ui.eventRadius}
|
||||
filterColors={this.props.ui.filterColors}
|
||||
coloringSet={this.props.app.coloringSet}
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div className="timeline-bottom">
|
||||
<Handles
|
||||
dims={dims}
|
||||
onMoveTime={(dir) => {
|
||||
this.onMoveTime(dir);
|
||||
}}
|
||||
backward={true}
|
||||
/>
|
||||
<ZoomControls
|
||||
extent={this.getTimeScaleExtent()}
|
||||
zoomLevels={timeline.zoomLevels}
|
||||
dims={dims}
|
||||
onApplyZoom={this.onApplyZoom}
|
||||
/>
|
||||
<Markers
|
||||
<Handles
|
||||
dims={dims}
|
||||
selected={this.props.app.selected}
|
||||
getEventX={(ev) => this.getDatetimeX(ev.datetime)}
|
||||
getEventY={this.getY}
|
||||
categories={categories}
|
||||
transitionDuration={this.state.transitionDuration}
|
||||
styles={this.props.ui.styles}
|
||||
features={this.props.features}
|
||||
eventRadius={this.props.ui.eventRadius}
|
||||
/>
|
||||
<Events
|
||||
events={this.props.domain.events}
|
||||
projects={this.props.domain.projects}
|
||||
categories={categories}
|
||||
styleDatetime={this.styleDatetime}
|
||||
narrative={this.props.app.narrative}
|
||||
getDatetimeX={this.getDatetimeX}
|
||||
getY={this.getY}
|
||||
getHighlights={(group) => {
|
||||
if (group === "None") {
|
||||
return [];
|
||||
}
|
||||
return categories.map((c) => c.group === group);
|
||||
onMoveTime={(dir) => {
|
||||
this.onMoveTime(dir);
|
||||
}}
|
||||
getCategoryColor={this.props.methods.getCategoryColor}
|
||||
transitionDuration={this.state.transitionDuration}
|
||||
onSelect={this.onSelect}
|
||||
dims={dims}
|
||||
features={this.props.features}
|
||||
setLoading={this.props.actions.setLoading}
|
||||
setNotLoading={this.props.actions.setNotLoading}
|
||||
eventRadius={this.props.ui.eventRadius}
|
||||
filterColors={this.props.ui.filterColors}
|
||||
coloringSet={this.props.app.coloringSet}
|
||||
backward={false}
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,7 @@ const TimelineClip = ({ dims }) => (
|
||||
<rect
|
||||
x={dims.marginLeft}
|
||||
y="0"
|
||||
width={Math.max(0, dims.width - dims.marginLeft - dims.width_controls)}
|
||||
width={Math.max(0, dims.width - dims.marginLeft * 2)}
|
||||
height={dims.contentHeight}
|
||||
/>
|
||||
</clipPath>
|
||||
|
||||
@@ -26,7 +26,7 @@ function renderDot(event, styles, props) {
|
||||
key={event.id}
|
||||
className="timeline-event"
|
||||
onClick={props.onSelect}
|
||||
transform={`translate(${props.x}, ${props.y})`}
|
||||
transform={`translate(${props.x}, ${props.y + 40})`}
|
||||
>
|
||||
<ColoredMarkers
|
||||
radius={props.eventRadius}
|
||||
|
||||
@@ -1,34 +1,21 @@
|
||||
import React from "react";
|
||||
|
||||
const TimelineHandles = ({ dims, onMoveTime }) => {
|
||||
const transform = "scale(1.5,1.5)";
|
||||
const size = 45;
|
||||
const handleOffset = dims.contentHeight / 2;
|
||||
const TimelineHandles = ({ dims, onMoveTime, backward }) => {
|
||||
if (backward === true) {
|
||||
return (
|
||||
<div className="timeline-handle" onClick={() => onMoveTime("backwards")}>
|
||||
<span className="timeline-handle__triangle"></span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<g className="time-controls-inline">
|
||||
<g
|
||||
transform={`translate(${dims.marginLeft - 20}, ${handleOffset})`}
|
||||
onClick={() => onMoveTime("backwards")}
|
||||
>
|
||||
<circle r={size} />
|
||||
<path
|
||||
d="M0,-7.847549217020565L6.796176979388489,3.9237746085102825L-6.796176979388489,3.9237746085102825Z"
|
||||
transform={`rotate(270) ${transform}`}
|
||||
/>
|
||||
</g>
|
||||
<g
|
||||
transform={`translate(${
|
||||
dims.width - dims.width_controls + 20
|
||||
}, ${handleOffset})`}
|
||||
onClick={() => onMoveTime("forward")}
|
||||
>
|
||||
<circle r={size} />
|
||||
<path
|
||||
d="M0,-7.847549217020565L6.796176979388489,3.9237746085102825L-6.796176979388489,3.9237746085102825Z"
|
||||
transform={`rotate(90) ${transform}`}
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
<div
|
||||
className="timeline-handle right"
|
||||
onClick={() => onMoveTime("forward")}
|
||||
>
|
||||
<span className="timeline-handle__triangle"></span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ const TimelineHeader = ({ title, from, to, onClick, hideInfo }) => {
|
||||
</p>
|
||||
</div>
|
||||
<div className={`timeline-info ${hideInfo ? "hidden" : ""}`}>
|
||||
<p>{title}</p>
|
||||
<p dangerouslySetInnerHTML={{ __html: title }} />
|
||||
<p>
|
||||
{d0} - {d1}
|
||||
</p>
|
||||
|
||||
@@ -33,7 +33,7 @@ const TimelineMarkers = ({
|
||||
strokeLinejoin="round"
|
||||
strokeDasharray={styles ? styles["stroke-dasharray"] : "2,2"}
|
||||
style={{
|
||||
transform: `translate(${getEventX(event)}px, ${y}px)`,
|
||||
transform: `translate(${getEventX(event)}px, ${y + 40}px)`,
|
||||
WebkitTransition: `transform ${transitionDuration / 1000}s ease`,
|
||||
MozTransition: "none",
|
||||
opacity: 1,
|
||||
|
||||
@@ -23,7 +23,7 @@ const TimelineZoomControls = ({ extent, zoomLevels, dims, onApplyZoom }) => {
|
||||
);
|
||||
const isActive = zoomIsActive(zoom.duration, extent, max.duration);
|
||||
return (
|
||||
<text
|
||||
<div
|
||||
className={`zoom-level-button ${isActive ? "active" : ""}`}
|
||||
x="60"
|
||||
y={idx * 15 + 20}
|
||||
@@ -31,7 +31,7 @@ const TimelineZoomControls = ({ extent, zoomLevels, dims, onApplyZoom }) => {
|
||||
key={idx}
|
||||
>
|
||||
{zoom.label}
|
||||
</text>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -39,9 +39,9 @@ const TimelineZoomControls = ({ extent, zoomLevels, dims, onApplyZoom }) => {
|
||||
zoomLevels = DEFAULT_ZOOM_LEVELS;
|
||||
}
|
||||
return (
|
||||
<g transform={`translate(${dims.width - dims.width_controls}, 0)`}>
|
||||
<div className="zoom-controls">
|
||||
{zoomLevels.map((z, idx) => renderZoom(z, idx))}
|
||||
</g>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,110 +1,46 @@
|
||||
// Burger transition
|
||||
.side-menu-burg {
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
float: right;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
appearance: none;
|
||||
box-shadow: none;
|
||||
border-radius: none;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
position: relative;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
padding: 3px;
|
||||
box-sizing: content-box;
|
||||
|
||||
&:before,
|
||||
&:after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
right: 50%;
|
||||
right: calc(50% - 1px);
|
||||
top: 3px;
|
||||
width: 2px;
|
||||
height: 18px;
|
||||
background-color: $midwhite;
|
||||
}
|
||||
&:before {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
&:after {
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
&:hover:after,
|
||||
&:hover:before {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
&.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
span {
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 9px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
height: 2px;
|
||||
background: $offwhite;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
span::before,
|
||||
span::after {
|
||||
position: absolute;
|
||||
display: block;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
background: $offwhite;
|
||||
border-radius: 4px;
|
||||
content: "";
|
||||
transition-duration: 0.2s, 0.2s;
|
||||
transition-delay: 0.2s, 0s;
|
||||
}
|
||||
|
||||
span::before {
|
||||
transition-property: top, transform;
|
||||
top: -8px;
|
||||
}
|
||||
|
||||
span::after {
|
||||
transition-property: bottom, transform;
|
||||
bottom: -8px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
span::before {
|
||||
top: -6px;
|
||||
}
|
||||
|
||||
span::after {
|
||||
bottom: -6px;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
span {
|
||||
background: $midwhite;
|
||||
transform: rotate(45deg);
|
||||
transition-delay: 0s, 0.2s;
|
||||
}
|
||||
|
||||
span::before,
|
||||
span::after {
|
||||
background: $midwhite;
|
||||
transition-delay: 0s, 0.2s;
|
||||
}
|
||||
|
||||
span::before {
|
||||
top: 0;
|
||||
transform: rotate(0deg);
|
||||
-webkit-transform: rotate(0deg);
|
||||
}
|
||||
|
||||
span::after {
|
||||
bottom: 0;
|
||||
transform: rotate(-90deg);
|
||||
-webkit-transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
span,
|
||||
span::before,
|
||||
span::after {
|
||||
transition: 0.2s ease;
|
||||
background: $offwhite;
|
||||
}
|
||||
}
|
||||
|
||||
&.over-white:hover {
|
||||
span,
|
||||
span:before,
|
||||
span:after {
|
||||
transition: 0.2s ease;
|
||||
background: $darkgrey;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ $green: rgb(61, 241, 79);
|
||||
$midgrey: rgb(44, 44, 44);
|
||||
$darkgrey: #232323;
|
||||
$black: #000000;
|
||||
$active: #7e56c2;
|
||||
$black-transparent: rgba(0, 0, 0, 0.7);
|
||||
|
||||
// Category colors
|
||||
@@ -37,7 +38,7 @@ $other: yellow;
|
||||
background: $beta;
|
||||
}
|
||||
|
||||
$mainfont: "GT-Zirkon", "Lato", Helvetica, sans-serif;
|
||||
$mainfont: "Roboto", Helvetica, sans-serif;
|
||||
|
||||
// Font sizes
|
||||
$xsmall: 10px; //0.7em;
|
||||
@@ -52,7 +53,7 @@ $xxxlarge: 32px;
|
||||
$final-level: 10000;
|
||||
$loading-overlay: 500;
|
||||
$overheader: 100;
|
||||
$header: 10;
|
||||
$header: 20;
|
||||
$map-overlay: 2;
|
||||
$map: 1;
|
||||
$scene: 1;
|
||||
@@ -67,8 +68,8 @@ $card-width: 500px;
|
||||
$card-right: 2px;
|
||||
$narrative-info-height: 205px;
|
||||
$narrative-info-desc-height: 153px;
|
||||
$timeline-height: 250px;
|
||||
$toolbar-width: 110px;
|
||||
$timeline-height: 130px;
|
||||
$toolbar-width: 0px;
|
||||
|
||||
$panel-width: 1000px;
|
||||
$panel-height: 1000px;
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
.event-card {
|
||||
box-sizing: border-box;
|
||||
border: 1px solid black;
|
||||
margin: 0;
|
||||
padding: 15px;
|
||||
transition: 0.2 ease;
|
||||
background: $midwhite;
|
||||
opacity: 0.92;
|
||||
color: $darkgrey;
|
||||
border: 0;
|
||||
opacity: 1;
|
||||
color: $black;
|
||||
list-style-type: none;
|
||||
font-size: $large;
|
||||
line-height: $xxlarge;
|
||||
transition: background-color 0.4s;
|
||||
text-align: left;
|
||||
overflow-y: scroll;
|
||||
overflow-y: auto;
|
||||
height: 100%;
|
||||
max-width: $card-width;
|
||||
|
||||
& + .event-card {
|
||||
border-top: 1px solid #dedede;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $lightwhite;
|
||||
transition: background-color 0.4s;
|
||||
@@ -26,9 +27,10 @@
|
||||
margin-bottom: 0;
|
||||
margin-right: 5px;
|
||||
text-transform: uppercase;
|
||||
font-size: $small;
|
||||
color: $darkwhite;
|
||||
font-weight: 800;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
color: $midwhite;
|
||||
margin-bottom: 3px;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
@@ -54,9 +56,18 @@
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
|
||||
& > span,
|
||||
.card-cell {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
flex-wrap: wrap;
|
||||
& > span {
|
||||
display: block;
|
||||
min-width: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-col {
|
||||
@@ -104,6 +115,7 @@
|
||||
}
|
||||
|
||||
.card-cell {
|
||||
font-size: 16px;
|
||||
a {
|
||||
transition: color 0.2s;
|
||||
}
|
||||
@@ -260,10 +272,22 @@
|
||||
|
||||
.card-row {
|
||||
border-color: darkgray;
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
& > span {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.embedded {
|
||||
width: calc(#{$card-width} - 50px) !important;
|
||||
// width: calc(#{$card-width} - 50px) !important;
|
||||
width: 100%;
|
||||
max-width: 90vw;
|
||||
|
||||
.twitter-tweet {
|
||||
max-width: 450px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.source-hidden,
|
||||
@@ -282,15 +306,60 @@
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
details {
|
||||
margin-top: 18px;
|
||||
}
|
||||
/* Styling the Disclosure Widgets */
|
||||
details > summary {
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
&:hover {
|
||||
.summary-text {
|
||||
background: rgba($active, 0.3);
|
||||
}
|
||||
}
|
||||
.summary-hide {
|
||||
display: none;
|
||||
}
|
||||
.summary-line {
|
||||
height: 1px;
|
||||
flex: 1;
|
||||
background: #000;
|
||||
}
|
||||
.summary-text {
|
||||
padding: 5px 9px;
|
||||
border-radius: 6px;
|
||||
margin: 0 6px;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
}
|
||||
|
||||
details[open] {
|
||||
.summary-hide {
|
||||
display: inline;
|
||||
}
|
||||
.summary-show {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
details > summary > * {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
.media.source-graphic {
|
||||
background-color: darken($red, 26%);
|
||||
h4 {
|
||||
color: white;
|
||||
color: $midwhite;
|
||||
transition: font-size 0.3s ease;
|
||||
}
|
||||
h4:hover {
|
||||
font-size: 103%;
|
||||
color: lighten(yellow, 20%);
|
||||
color: $offwhite;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,31 @@
|
||||
// @import 'burger';
|
||||
@import "card";
|
||||
|
||||
$card-stack-header-height: 38px;
|
||||
.card-stack {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
top: #{$card-right};
|
||||
padding-top: #{$card-stack-header-height};
|
||||
right: $card-right;
|
||||
max-height: calc(100% - #{$timeline-height} + 60px);
|
||||
max-height: calc(100% - #{$timeline-height} - 35px);
|
||||
height: auto;
|
||||
width: $card-width;
|
||||
overflow-y: scroll;
|
||||
box-shadow: 0 19px 38px rgba(0, 0, 0, 0.3), 0 15px 12px rgba(0, 0, 0, 0.22);
|
||||
z-index: $header;
|
||||
color: white;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
overflow: hidden;
|
||||
max-width: 100vw;
|
||||
background: $offwhite;
|
||||
border-radius: 6px;
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
max-height: 100vh;
|
||||
}
|
||||
|
||||
&.narrative-mode {
|
||||
right: $card-right;
|
||||
@@ -30,10 +39,8 @@ $card-stack-header-height: 38px;
|
||||
}
|
||||
|
||||
.card-stack-header {
|
||||
position: fixed;
|
||||
position: initial;
|
||||
top: $card-right;
|
||||
min-height: $card-stack-header-height;
|
||||
line-height: $card-stack-header-height;
|
||||
width: 100%;
|
||||
max-width: $card-width;
|
||||
box-sizing: border-box;
|
||||
@@ -77,8 +84,13 @@ $card-stack-header-height: 38px;
|
||||
}
|
||||
|
||||
.card-stack-content {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
max-width: $card-width;
|
||||
overflow: auto;
|
||||
padding-right: 10px;
|
||||
display: block;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
ul {
|
||||
padding: 0;
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
@import "variables";
|
||||
|
||||
html {
|
||||
font-family: $mainfont;
|
||||
font-size: 14px;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
@media screen and (max-width: 600px) {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
@@ -15,12 +24,17 @@ body {
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: $mainfont;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.3rem;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1rem;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.login-wrapper {
|
||||
@@ -58,7 +72,6 @@ h2 {
|
||||
height: 30px;
|
||||
border: 1px solid $offwhite;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
margin-top: 10px;
|
||||
@@ -132,6 +145,13 @@ Scrollbar
|
||||
background: $offwhite;
|
||||
}
|
||||
|
||||
.scrollbar-black {
|
||||
*::-webkit-scrollbar-thumb,
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: $black;
|
||||
}
|
||||
}
|
||||
|
||||
.hidden {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
width: 100%;
|
||||
opacity: 1;
|
||||
transition: top 0.4s ease;
|
||||
z-index: $loading-overlay + 1;
|
||||
z-index: 2;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
color: $offwhite;
|
||||
@@ -15,6 +15,7 @@
|
||||
&.showing {
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: $loading-overlay + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,42 +23,39 @@
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
left: 0;
|
||||
display: flex;
|
||||
width: 100vw;
|
||||
width: 64px;
|
||||
right: 7px;
|
||||
left: auto;
|
||||
top: 7px;
|
||||
bottom: auto;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
max-width: initial;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
transition: all 0.6s ease;
|
||||
transition-delay: 0.3s;
|
||||
|
||||
@media only screen and (max-width: 1200px) {
|
||||
position: inherit;
|
||||
&.minimized {
|
||||
top: 78px;
|
||||
right: 7px;
|
||||
transition: all 0.6s ease;
|
||||
transition-delay: 0s;
|
||||
z-index: 10;
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
top: 145px;
|
||||
}
|
||||
}
|
||||
|
||||
.cover-logo-container {
|
||||
padding: 20px 0 0 20px;
|
||||
display: flex;
|
||||
|
||||
&.minimized {
|
||||
}
|
||||
|
||||
.cover-logo {
|
||||
transition: all 1s;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
&.minimized {
|
||||
bottom: 150px;
|
||||
max-width: $toolbar-width;
|
||||
max-height: 30px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
|
||||
.cover-logo-container {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.cover-logo {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
display: block;
|
||||
padding: 0;
|
||||
img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,26 +150,15 @@
|
||||
|
||||
.hero {
|
||||
min-width: 100%;
|
||||
min-height: 80px;
|
||||
margin: auto;
|
||||
margin: 20px 0 40px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 60px;
|
||||
|
||||
@media only screen and (max-width: 1200px) {
|
||||
min-height: 250px;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: row;
|
||||
|
||||
@media only screen and (max-width: 1200px) {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
justify-content: space-around;
|
||||
|
||||
&.vertical {
|
||||
@@ -200,37 +187,30 @@
|
||||
min-height: 10px;
|
||||
background-color: black;
|
||||
letter-spacing: 1px;
|
||||
|
||||
@media only screen and (max-width: 1200px) {
|
||||
min-height: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
&.yellow {
|
||||
color: black !important;
|
||||
color: $offwhite;
|
||||
background-color: $yellow;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
background-color: $darkwhite;
|
||||
color: white;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1200px) {
|
||||
min-height: 100px;
|
||||
background-color: $offwhite;
|
||||
color: $yellow;
|
||||
border-color: $yellow;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cover-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
padding-bottom: 10em;
|
||||
padding-bottom: 2em;
|
||||
|
||||
h1,
|
||||
h2,
|
||||
@@ -239,6 +219,9 @@
|
||||
h5 {
|
||||
text-align: center;
|
||||
}
|
||||
h2 {
|
||||
margin: 75px 0 15px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-bottom: -15px;
|
||||
@@ -264,6 +247,8 @@
|
||||
|
||||
p {
|
||||
text-align: justify;
|
||||
font-size: 1.2rem;
|
||||
line-height: 1.65em;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,32 +1,93 @@
|
||||
@import "burger";
|
||||
|
||||
.infopopup {
|
||||
width: $infopopup-width;
|
||||
box-shadow: 10px -10px 38px rgba(0, 0, 0, 0.3),
|
||||
10px 15px 12px rgba(0, 0, 0, 0.22);
|
||||
color: $darkgrey;
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 600px;
|
||||
max-width: calc(min(60vw, 100%));
|
||||
color: $darkgrey;
|
||||
background: $offwhite-transparent;
|
||||
bottom: $timeline-height;
|
||||
left: $toolbar-width;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
border: 3px solid $offwhite;
|
||||
border-radius: 1px;
|
||||
padding: 20px;
|
||||
padding: 20px 15px 15px;
|
||||
box-sizing: border-box;
|
||||
font-size: $large;
|
||||
transition: opacity 0.5s ease 0.1s, z-index 0.1s ease 0s;
|
||||
opacity: 1;
|
||||
z-index: $overheader;
|
||||
border: 2px solid $midwhite;
|
||||
border-radius: 6px;
|
||||
box-shadow: 10px -10px 38px rgba(0, 0, 0, 0.3),
|
||||
10px 15px 12px rgba(0, 0, 0, 0.22);
|
||||
|
||||
&__bg {
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 100;
|
||||
cursor: pointer;
|
||||
&.hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
font-size: 18px;
|
||||
width: 98vw;
|
||||
max-width: none;
|
||||
max-height: 95vh;
|
||||
background: rgba(0, 0, 0, 0.95);
|
||||
overflow: auto;
|
||||
figcaption {
|
||||
overflow-wrap: break-word;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
}
|
||||
p:nth-last-child(1) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&.hidden {
|
||||
transition: 0.5s ease;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.two-columns {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
margin-top: 20px;
|
||||
gap: 20px;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
&_column {
|
||||
flex: 1;
|
||||
|
||||
figure {
|
||||
margin: 0;
|
||||
}
|
||||
figcaption {
|
||||
margin-top: 6px;
|
||||
text-align: left;
|
||||
color: $midwhite;
|
||||
}
|
||||
img {
|
||||
border-radius: 9px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.side-menu-burg {
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 10px;
|
||||
right: 6px;
|
||||
top: 6px;
|
||||
&.light {
|
||||
&.is-active span:after,
|
||||
&.is-active span:before {
|
||||
@@ -39,6 +100,9 @@
|
||||
// background: $black-transparent;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
color: white;
|
||||
@media screen and (max-width: 600px) {
|
||||
background: rgba(0, 0, 0, 0.9);
|
||||
}
|
||||
}
|
||||
|
||||
iframe {
|
||||
@@ -67,14 +131,10 @@
|
||||
}
|
||||
|
||||
.legend-header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
h2 {
|
||||
display: flex;
|
||||
font-size: 12pt;
|
||||
letter-spacing: 2px;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
left: 110px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
||||
&.mobile {
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
@import "variables";
|
||||
|
||||
.satellite-overlay-toggle {
|
||||
background-color: rgb(53, 53, 53);
|
||||
opacity: 0.9;
|
||||
position: fixed;
|
||||
top: 0.5em;
|
||||
right: 0.5em;
|
||||
z-index: $map-overlay;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
top: 75px;
|
||||
}
|
||||
|
||||
.satellite-overlay-toggle-button {
|
||||
cursor: pointer;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
opacity: 0.8;
|
||||
opacity: 0.85;
|
||||
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
|
||||
border: none;
|
||||
color: white;
|
||||
|
||||
@@ -46,11 +46,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.folded {
|
||||
left: -400px;
|
||||
transition: 0.2s ease;
|
||||
}
|
||||
|
||||
.search-outer-container {
|
||||
position: absolute;
|
||||
left: 110px;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
.react-tabs {
|
||||
padding-top: 0;
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
|
||||
[role="tablist"] {
|
||||
padding: 0;
|
||||
@@ -40,6 +39,13 @@
|
||||
|
||||
.react-innertabpanel {
|
||||
box-sizing: border-box;
|
||||
padding-top: 20px;
|
||||
padding-top: 0;
|
||||
|
||||
hr {
|
||||
border-top: 0;
|
||||
border-bottom: 1px solid $midwhite;
|
||||
margin-block-start: 0.5em;
|
||||
margin-block-end: 1.5em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
.timeline-wrapper {
|
||||
position: fixed;
|
||||
box-sizing: border-box;
|
||||
left: 110px;
|
||||
right: 0px;
|
||||
height: $timeline-height;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: auto;
|
||||
background: rgba($black, 0.8);
|
||||
box-shadow: 0 -10px 38px rgba(0, 0, 0, 0.3), 0 15px 12px rgba(0, 0, 0, 0.22);
|
||||
color: white;
|
||||
transition: left 0.2s ease, bottom 0.2s ease;
|
||||
bottom: 0px;
|
||||
transition: transform 0.3s ease;
|
||||
z-index: $timeline;
|
||||
border-top: 1px solid black;
|
||||
|
||||
&.folded {
|
||||
transition: bottom 0.2s ease;
|
||||
transform: translateY(100%);
|
||||
|
||||
.timeline-header .timeline-toggle p .arrow-down {
|
||||
transform: translate(0, 0px) rotate(-135deg);
|
||||
@@ -44,6 +44,7 @@
|
||||
margin: 0 auto;
|
||||
background: rgba($black, 0.8);
|
||||
margin-top: -25px;
|
||||
border-radius: 6px 6px 0 0;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
@@ -65,38 +66,59 @@
|
||||
border-bottom: 2px solid $midwhite;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 1040px) {
|
||||
.timeline-toggle p {
|
||||
margin: -25px 10px 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.timeline-info {
|
||||
width: calc(#{$card-width} - 20px);
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
margin-bottom: 6px;
|
||||
margin-left: 10px;
|
||||
background: rgba($black, 0.8);
|
||||
padding: 9px 15px 11px;
|
||||
box-sizing: border-box;
|
||||
min-height: 20px;
|
||||
border-radius: 6px;
|
||||
&.hidden {
|
||||
display: none;
|
||||
}
|
||||
width: calc(#{$card-width} - 20px);
|
||||
position: absolute;
|
||||
margin-top: -70px;
|
||||
margin-left: 10px;
|
||||
background: rgba($black, 0.8);
|
||||
padding: 10px;
|
||||
min-height: 20px;
|
||||
p {
|
||||
margin: 0;
|
||||
height: 20px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
font-size: 1.15rem;
|
||||
|
||||
span {
|
||||
color: $offwhite;
|
||||
}
|
||||
&:first-child {
|
||||
text-transform: none;
|
||||
font-size: $normal;
|
||||
letter-spacing: 0.05em;
|
||||
font-size: 1rem;
|
||||
color: $midwhite;
|
||||
font-weight: 400;
|
||||
}
|
||||
@media screen and (max-width: 600px) {
|
||||
font-size: 1rem;
|
||||
&:nth-child(1) {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// mobile styles
|
||||
@media screen and (max-width: 600px) {
|
||||
bottom: 115%;
|
||||
bottom: calc(100% + 25px);
|
||||
width: 96vw;
|
||||
margin: 0 2vw 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.timeline-content {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.timeline-labels {
|
||||
padding-top: 2px;
|
||||
padding-left: 20px;
|
||||
@@ -134,15 +156,11 @@
|
||||
}
|
||||
|
||||
.timeline {
|
||||
/*width: calc(100% - 200px);*/
|
||||
width: calc(100% - 40px);
|
||||
margin-left: 20px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
float: left;
|
||||
|
||||
svg {
|
||||
display: inline-block;
|
||||
float: left;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.domain {
|
||||
@@ -261,21 +279,45 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.zoom-level-button {
|
||||
font-size: $xsmall;
|
||||
cursor: pointer;
|
||||
text-anchor: middle;
|
||||
letter-spacing: 0.05em;
|
||||
transition: 0.2s ease;
|
||||
fill: $midwhite;
|
||||
.zoom-controls {
|
||||
display: flex;
|
||||
padding: 6px 20px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
grid-gap: 9px;
|
||||
@media screen and (max-width: 600px) {
|
||||
padding: 6px 3px;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&.active {
|
||||
transition: 0.2s ease;
|
||||
fill: $offwhite;
|
||||
}
|
||||
}
|
||||
.zoom-level-button {
|
||||
padding: 6px 9px;
|
||||
font-size: 0.875rem;
|
||||
cursor: pointer;
|
||||
text-anchor: middle;
|
||||
letter-spacing: 0.05em;
|
||||
transition: 0.2s ease;
|
||||
color: $midwhite;
|
||||
border-radius: 3px;
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
font-size: 0.65rem;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $offwhite;
|
||||
background-color: rgba($active, 0.3);
|
||||
}
|
||||
&.active {
|
||||
color: $offwhite;
|
||||
background-color: $active;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -302,6 +344,49 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.handle {
|
||||
fill: $offwhite;
|
||||
/*
|
||||
* Handles
|
||||
*/
|
||||
.timeline-bottom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.timeline-handle {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
text-align: right;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-left: 5px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background-color: rgba($active, 0.4);
|
||||
.timeline-handle__triangle {
|
||||
border-color: transparent $offwhite transparent transparent;
|
||||
}
|
||||
}
|
||||
&__triangle {
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
border-width: 7px 10px 7px 0;
|
||||
border-color: transparent $midwhite transparent transparent;
|
||||
}
|
||||
&.right {
|
||||
margin-right: 5px;
|
||||
&:hover {
|
||||
background-color: rgba($active, 0.4);
|
||||
.timeline-handle__triangle {
|
||||
border-color: transparent transparent transparent $offwhite;
|
||||
}
|
||||
}
|
||||
.timeline-handle__triangle {
|
||||
border-width: 7px 0 7px 10px;
|
||||
border-color: transparent transparent transparent $midwhite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,52 +5,67 @@
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
bottom: 0px;
|
||||
z-index: $header;
|
||||
background: $midgrey;
|
||||
background: transparent;
|
||||
|
||||
&.narrative-mode {
|
||||
left: -$toolbar-width;
|
||||
left: -0;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
position: relative;
|
||||
width: $toolbar-width;
|
||||
height: 100%;
|
||||
padding: 20px 0px 0px 0px;
|
||||
display: flex;
|
||||
width: auto;
|
||||
height: 70px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
color: $offwhite;
|
||||
background: $darkgrey;
|
||||
text-align: center;
|
||||
font-size: $normal;
|
||||
font-weight: 100;
|
||||
transition: 0.2s ease;
|
||||
font-weight: 400;
|
||||
z-index: $header;
|
||||
|
||||
button {
|
||||
background: #222222;
|
||||
}
|
||||
|
||||
.react-tabs__tab-list {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
grid-gap: 15px;
|
||||
margin-left: 10px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.toolbar-header {
|
||||
margin: 0 15px 10px 15px;
|
||||
padding: 10px 0 25px 0;
|
||||
padding: 5px 15px 5px 10px;
|
||||
border-radius: 0 0 6px 0;
|
||||
background-color: $midgrey;
|
||||
transition: 0.2s ease;
|
||||
border-bottom: 2px solid $midwhite;
|
||||
// border-bottom: 2px solid $midwhite;
|
||||
text-transform: uppercase;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
p {
|
||||
font-size: $normal;
|
||||
white-space: pre-wrap;
|
||||
font-size: 1.15rem;
|
||||
line-height: 1.3em;
|
||||
font-weight: 400;
|
||||
text-transform: uppercase;
|
||||
margin: 0;
|
||||
}
|
||||
p:first-child {
|
||||
font-size: $xsmall;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
transition: 0.2s ease;
|
||||
border-bottom: 2px solid $offwhite;
|
||||
@media screen and (max-width: 600px) {
|
||||
height: 60px;
|
||||
.toolbar-header p {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +74,7 @@
|
||||
}
|
||||
|
||||
.bottom-actions {
|
||||
position: absolute;
|
||||
display: none;
|
||||
width: $toolbar-width;
|
||||
bottom: 10px;
|
||||
box-sizing: border-box;
|
||||
@@ -186,37 +201,57 @@
|
||||
}
|
||||
}
|
||||
|
||||
.download-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.download-row + .download-row {
|
||||
margin-top: 14px;
|
||||
}
|
||||
.download-button {
|
||||
flex: 1 1 auto;
|
||||
aspect-ratio: 1 / 1;
|
||||
width: 50px;
|
||||
height: auto;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
display: inline-flex;
|
||||
vertical-align: middle;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: $black;
|
||||
border: 1px solid $offwhite;
|
||||
background: $offwhite;
|
||||
border-radius: 6px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: background 0.3s ease;
|
||||
&:hover {
|
||||
background: rgba(#fff, 0.6);
|
||||
}
|
||||
}
|
||||
.download-description {
|
||||
flex: 1 5 auto;
|
||||
text-align: justify;
|
||||
margin: auto;
|
||||
display: inline-block;
|
||||
width: calc(100% - 52px);
|
||||
padding-left: 12px;
|
||||
box-sizing: border-box;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.toolbar-tab,
|
||||
.download-button {
|
||||
.toolbar-tab {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
height: 60px;
|
||||
width: $toolbar-width;
|
||||
padding: 5px 0;
|
||||
font-weight: 400;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
height: auto;
|
||||
width: 45px;
|
||||
aspect-ratio: 1 / 1;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: 0.2s ease;
|
||||
color: $midwhite;
|
||||
|
||||
svg {
|
||||
transform: scale(0.7);
|
||||
// transform: scale(0.7);
|
||||
path,
|
||||
circle,
|
||||
polygon,
|
||||
@@ -238,15 +273,42 @@
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.tab-caption {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
.tab-caption {
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-size: $xsmall;
|
||||
letter-spacing: 0.05em;
|
||||
font-size: 1rem;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
top: calc(100% + 5px);
|
||||
background: #000;
|
||||
padding: 3px 6px;
|
||||
font-size: 1rem;
|
||||
color: #fff;
|
||||
border-radius: 3px;
|
||||
transform: scale(0);
|
||||
transition: transform 0.15s ease;
|
||||
user-select: none;
|
||||
&:after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
transform: rotate(45deg);
|
||||
background-color: #000;
|
||||
left: 50%;
|
||||
left: calc(50% - 3px);
|
||||
top: -3px;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: $black;
|
||||
background: $active;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
@@ -277,43 +339,72 @@
|
||||
}
|
||||
|
||||
.toolbar-panels {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
justify-content: flex-start;
|
||||
width: 440px;
|
||||
top: 15px;
|
||||
bottom: 0;
|
||||
top: 75px;
|
||||
left: 15px;
|
||||
padding: 15px 15px 30px;
|
||||
box-sizing: border-box;
|
||||
padding: 30px 10px 10px 30px;
|
||||
font-size: $normal;
|
||||
background: $black;
|
||||
color: $offwhite;
|
||||
position: fixed;
|
||||
transition: 0.2s ease;
|
||||
left: $toolbar-width;
|
||||
max-height: calc(100vh - #{$timeline-height});
|
||||
max-height: calc(100vh - #{$timeline-height} - 50px);
|
||||
box-shadow: 10px -10px 38px rgba(0, 0, 0, 0.3),
|
||||
10px 15px 12px rgba(0, 0, 0, 0.22);
|
||||
z-index: 20;
|
||||
|
||||
h2 {
|
||||
font-size: $large;
|
||||
text-transform: none;
|
||||
letter-spacing: normal;
|
||||
@media screen and (max-width: 600px) {
|
||||
left: 3px;
|
||||
right: 3px;
|
||||
width: auto;
|
||||
top: 65px;
|
||||
max-height: calc(100vh - 65px - 5px);
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: $normal;
|
||||
line-height: 1.4em;
|
||||
.sticky-header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background: #000;
|
||||
z-index: 100;
|
||||
padding: 0 0 10px;
|
||||
h2 {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
.panel-description {
|
||||
margin-bottom: 1.5rem;
|
||||
.hint {
|
||||
color: $midwhite;
|
||||
}
|
||||
p:nth-last-child(1) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
p:nth-child(1) {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
text-transform: none;
|
||||
letter-spacing: normal;
|
||||
&:nth-child(1) {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-header {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
width: 36px;
|
||||
float: right;
|
||||
margin-left: 20px;
|
||||
margin-right: -45px;
|
||||
height: 36px;
|
||||
padding-top: 5px;
|
||||
box-sizing: border-box;
|
||||
margin-top: 10px;
|
||||
border-radius: 3px;
|
||||
top: 0;
|
||||
left: 100%;
|
||||
border-radius: 0 3px 3px 0;
|
||||
background: $black;
|
||||
padding: 8px 6px;
|
||||
cursor: pointer;
|
||||
@@ -347,7 +438,6 @@
|
||||
}
|
||||
|
||||
.react-tabs__tab-panel--selected {
|
||||
height: calc(100% - 40px);
|
||||
overflow-y: auto;
|
||||
margin-top: 0;
|
||||
|
||||
@@ -368,9 +458,14 @@
|
||||
height: calc(100% - 310px);
|
||||
}
|
||||
|
||||
transition: opacity 0.3s ease, margin 0.3s ease, left 0s linear 0s;
|
||||
&.folded {
|
||||
transition: 0.2s ease;
|
||||
left: -440px;
|
||||
transition: opacity 0.3s ease, margin 0.3s ease, left 0s linear 1s;
|
||||
opacity: 0;
|
||||
margin-top: 20px;
|
||||
left: -110%;
|
||||
right: auto;
|
||||
max-width: 100vw;
|
||||
|
||||
ul {
|
||||
height: 0;
|
||||
@@ -410,22 +505,32 @@
|
||||
|
||||
.item {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
background: none;
|
||||
font-size: $large;
|
||||
font-size: 1rem;
|
||||
padding: 3px 0;
|
||||
margin: 0 0 3px;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button,
|
||||
label {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
button {
|
||||
height: 36px;
|
||||
aspect-ratio: 1 / 1;
|
||||
border: 1px transparent;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
color: $offwhite;
|
||||
outline: none;
|
||||
transition: 0.2s ease;
|
||||
padding: 0 10px;
|
||||
text-align: left;
|
||||
float: left;
|
||||
padding: 4px;
|
||||
margin-right: 3px;
|
||||
|
||||
.border {
|
||||
width: 16px;
|
||||
@@ -441,7 +546,6 @@
|
||||
border: 1px solid $offwhite;
|
||||
box-sizing: border-box;
|
||||
background: none;
|
||||
float: left;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
@@ -455,7 +559,6 @@
|
||||
display: inline-block;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
float: left;
|
||||
color: $offwhite;
|
||||
font-size: $normal;
|
||||
overflow: hidden;
|
||||
@@ -543,23 +646,48 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-height: 678px) {
|
||||
.toolbar-wrapper {
|
||||
.toolbar-tab {
|
||||
height: 60px;
|
||||
padding: 0;
|
||||
|
||||
&:hover {
|
||||
.tab-caption {
|
||||
transition: 0.2s ease;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
.toolbar .bottom-actions {
|
||||
.action-button {
|
||||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Made with block
|
||||
*/
|
||||
#made-with {
|
||||
position: fixed;
|
||||
top: 75px;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
left: 5px;
|
||||
padding: 5px 12px;
|
||||
margin-bottom: 6px;
|
||||
border-radius: 4px;
|
||||
width: 115px;
|
||||
text-align: left;
|
||||
font-size: 0.75rem;
|
||||
opacity: 0.65;
|
||||
color: $midwhite;
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
@media screen and (max-width: 600px) {
|
||||
top: 65px;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
// @media (max-height: 678px) {
|
||||
// .toolbar-wrapper {
|
||||
// .toolbar-tab {
|
||||
// height: 60px;
|
||||
// padding: 0;
|
||||
|
||||
// &:hover {
|
||||
// .tab-caption {
|
||||
// transition: 0.2s ease;
|
||||
// opacity: 1;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// .toolbar .bottom-actions {
|
||||
// .action-button {
|
||||
// margin-top: 5px;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -77,7 +77,7 @@ const initial = {
|
||||
ticks: 15,
|
||||
height: isSmallLaptop ? 170 : 250,
|
||||
width: 0,
|
||||
marginLeft: 70,
|
||||
marginLeft: 20,
|
||||
marginTop: isSmallLaptop ? 5 : 10, // the padding used for the day/month labels inside the timeline
|
||||
marginBottom: 60,
|
||||
contentHeight: isSmallLaptop ? 160 : 200,
|
||||
@@ -159,7 +159,7 @@ const initial = {
|
||||
tiles: {
|
||||
current: "openstreetmap", // ['openstreetmap', 'streets', 'satellite']
|
||||
default: "openstreetmap", // ['openstreetmap', 'streets', 'satellite']
|
||||
satellite: "satellite"
|
||||
satellite: "satellite",
|
||||
},
|
||||
style: {
|
||||
categories: {
|
||||
|
||||
Reference in New Issue
Block a user