From 53d6f389e3a0c5d7a45bc378e751f870d56acc0e Mon Sep 17 00:00:00 2001 From: Andrew Mudrov Date: Mon, 31 Oct 2022 21:40:35 +0400 Subject: [PATCH] feat(main): style changes and mobile version (#58) Co-authored-by: msramalho <19508417+msramalho@users.noreply.github.com> --- config.js | 9 +- index.html | 39 ++- src/common/data/copy.json | 84 ++++-- src/components/Layout.js | 46 +--- src/components/TemplateCover.js | 5 +- src/components/Toolbar.js | 33 ++- src/components/atoms/Checkbox.js | 18 +- src/components/atoms/Popup.js | 4 + src/components/controls/Card.js | 55 +++- src/components/controls/CardStack.js | 5 +- src/components/controls/DownloadPanel.js | 11 +- src/components/controls/FilterListPanel.js | 18 +- src/components/controls/atoms/PanelTree.js | 1 - src/components/controls/atoms/Text.js | 1 + src/components/time/Axis.js | 8 +- src/components/time/Categories.js | 15 +- src/components/time/Timeline.js | 162 ++++++----- src/components/time/atoms/Clip.js | 2 +- src/components/time/atoms/Events.js | 2 +- src/components/time/atoms/Handles.js | 43 +-- src/components/time/atoms/Header.js | 2 +- src/components/time/atoms/Markers.js | 2 +- src/components/time/atoms/ZoomControls.js | 8 +- src/scss/_burger.scss | 122 ++------- src/scss/_variables.scss | 9 +- src/scss/card.scss | 95 ++++++- src/scss/cardstack.scss | 30 +- src/scss/common.scss | 26 +- src/scss/cover.scss | 101 +++---- src/scss/infopopup.scss | 90 +++++- src/scss/map.scss | 2 +- src/scss/satelliteoverlaytoggle.scss | 12 +- src/scss/search.scss | 5 - src/scss/tabs.scss | 10 +- src/scss/timeline.scss | 169 +++++++++--- src/scss/toolbar.scss | 302 +++++++++++++++------ src/store/initial.js | 4 +- 37 files changed, 966 insertions(+), 584 deletions(-) diff --git a/config.js b/config.js index 1624dc1..85676d4 100755 --- a/config.js +++ b/config.js @@ -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: [ - '
', + '
Image: Vyacheslav Madiyevskyy/Reuters
Image: Järva Teataja/Scanpix Baltics via Reuters
', '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 here. ', - "Image left: Vyacheslav Madiyevskyy/Reuters. Image right: Järva Teataja/Scanpix Baltics via Reuters.", ], flags: { isInfopoup: false, isCover: false }, diff --git a/index.html b/index.html index a53bb5b..34dc5a0 100644 --- a/index.html +++ b/index.html @@ -1,23 +1,39 @@ + TimeMap - Forensic Architecture - + + + + + + + + + -
@@ -27,4 +43,5 @@
- + + \ No newline at end of file diff --git a/src/common/data/copy.json b/src/common/data/copy.json index 5a0e63e..eac9782 100644 --- a/src/common/data/copy.json +++ b/src/common/data/copy.json @@ -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.

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.

If no filters are selected, all datapoints are displayed.", "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 %n events that occurred between", "default_categories_label": "" }, "cardstack": { diff --git a/src/components/Layout.js b/src/components/Layout.js index 4171f20..97bfe47 100644 --- a/src/components/Layout.js +++ b/src/components/Layout.js @@ -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 ? ( -
-

- This platform may not work correctly on mobile. If possible, please - re-visit the site on a device with a larger screen. -

-
- ) : 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} - + > ); } 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 (
- {checkMobile ? null : ( + { - )} + } this.handleSelect(ev, 1), }} /> - {checkMobile ? null : ( + { - )} + }
) : null} -

+

{this.props.cover.subtitle ? (

{this.props.cover.subtitle}

) : null} diff --git a/src/components/Toolbar.js b/src/components/Toolbar.js index dfbbf84..547ddcd 100644 --- a/src/components/Toolbar.js +++ b/src/components/Toolbar.js @@ -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 ( -
this.selectTab(-1)}> +
this.selectTab(this.state._selected)} + >
); } 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 (
{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} /> + +
+ Made with{" "} + TimeMap +
+ Free software from{" "} + Forensic Architecture +
); } diff --git a/src/components/atoms/Checkbox.js b/src/components/atoms/Checkbox.js index f90c1fa..4cd4aad 100644 --- a/src/components/atoms/Checkbox.js +++ b/src/components/atoms/Checkbox.js @@ -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 ( -
- {label} - +
); }; diff --git a/src/components/atoms/Popup.js b/src/components/atoms/Popup.js index eeea84d..c76ffbb 100644 --- a/src/components/atoms/Popup.js +++ b/src/components/atoms/Popup.js @@ -13,6 +13,10 @@ const Popup = ({ children, }) => (
+
[ - 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 ( -
+
{row.map((field) => ( // src by src meaning wrapGrahpic must be called around a map of renderField for sources - {renderField(field, cardIdx)} + + {renderField(field, cardIdx)} + ))}
); @@ -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 ( +
+
+ + + + Show{" "} + Hide sources ( + {row[0].values.length}) + + + + {row[0].values.map((r) => renderRow(r, cardIdx, row[0]))} +
+
+ ); + } else return renderRow(row, cardIdx); + })} + + {/* {isOpen && (
{sources.map(() => (
))}
- )} + )} */} {sources.length > 0 ? renderCaret() : null} ); diff --git a/src/components/controls/CardStack.js b/src/components/controls/CardStack.js index 974402b..0efe12d 100644 --- a/src/components/controls/CardStack.js +++ b/src/components/controls/CardStack.js @@ -126,7 +126,10 @@ class CardStack extends React.Component { renderCardStackContent() { return ( -
+
    {this.renderSelectedCards()}
); diff --git a/src/components/controls/DownloadPanel.js b/src/components/controls/DownloadPanel.js index e68f3d4..30059c1 100644 --- a/src/components/controls/DownloadPanel.js +++ b/src/components/controls/DownloadPanel.js @@ -4,8 +4,15 @@ import { DownloadButton } from "./DownloadButton"; const DownloadPanel = ({ language, title, description, domain }) => { return (
-

{title}

-

{description}

+
+

{title}

+
+

diff --git a/src/components/controls/FilterListPanel.js b/src/components/controls/FilterListPanel.js index 52376da..ae5843b 100644 --- a/src/components/controls/FilterListPanel.js +++ b/src/components/controls/FilterListPanel.js @@ -56,7 +56,10 @@ function FilterListPanel({ 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 ( -
+
{Object.entries(aggregatedFilterPaths).map((filter) => - createNodeComponent(filter, 1) + createNodeComponent(filter, 0) )}
); } return ( -
-

{title}

-

+

+

{title}

+
+
{
  • {
    {title ?

    {title}

    : null}
    diff --git a/src/components/time/Categories.js b/src/components/time/Categories.js index f8e3dbd..66d90c5 100644 --- a/src/components/time/Categories.js +++ b/src/components/time/Categories.js @@ -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)`} > - + - + {cat} @@ -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} /> diff --git a/src/components/time/Timeline.js b/src/components/time/Timeline.js index 9d683c9..295b3c8 100644 --- a/src/components/time/Timeline.js +++ b/src/components/time/Timeline.js @@ -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 ( -
    +
    -
    -
    - - - - - 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 && ( - +
    +
    + + + { - this.onMoveTime(dir); - }} + extent={this.getTimeScaleExtent()} + transitionDuration={this.state.transitionDuration} + scaleX={this.state.scaleX} /> - )} + + 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 + } + /> + 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} + /> + { + 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} + /> + +
    + +
    + { + this.onMoveTime(dir); + }} + backward={true} + /> - 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} - /> - { - 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} /> - +
    diff --git a/src/components/time/atoms/Clip.js b/src/components/time/atoms/Clip.js index 6d82349..254f439 100644 --- a/src/components/time/atoms/Clip.js +++ b/src/components/time/atoms/Clip.js @@ -5,7 +5,7 @@ const TimelineClip = ({ dims }) => ( diff --git a/src/components/time/atoms/Events.js b/src/components/time/atoms/Events.js index be393fa..a3f2cde 100644 --- a/src/components/time/atoms/Events.js +++ b/src/components/time/atoms/Events.js @@ -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})`} > { - const transform = "scale(1.5,1.5)"; - const size = 45; - const handleOffset = dims.contentHeight / 2; +const TimelineHandles = ({ dims, onMoveTime, backward }) => { + if (backward === true) { + return ( +
    onMoveTime("backwards")}> + +
    + ); + } + return ( - - onMoveTime("backwards")} - > - - - - onMoveTime("forward")} - > - - - - +
    onMoveTime("forward")} + > + +
    ); }; diff --git a/src/components/time/atoms/Header.js b/src/components/time/atoms/Header.js index acdfff9..c3e7bd6 100644 --- a/src/components/time/atoms/Header.js +++ b/src/components/time/atoms/Header.js @@ -12,7 +12,7 @@ const TimelineHeader = ({ title, from, to, onClick, hideInfo }) => {

    -

    {title}

    +

    {d0} - {d1}

    diff --git a/src/components/time/atoms/Markers.js b/src/components/time/atoms/Markers.js index 5211c61..778953f 100644 --- a/src/components/time/atoms/Markers.js +++ b/src/components/time/atoms/Markers.js @@ -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, diff --git a/src/components/time/atoms/ZoomControls.js b/src/components/time/atoms/ZoomControls.js index 04358e7..dd9699a 100644 --- a/src/components/time/atoms/ZoomControls.js +++ b/src/components/time/atoms/ZoomControls.js @@ -23,7 +23,7 @@ const TimelineZoomControls = ({ extent, zoomLevels, dims, onApplyZoom }) => { ); const isActive = zoomIsActive(zoom.duration, extent, max.duration); return ( - { key={idx} > {zoom.label} - +
    ); } @@ -39,9 +39,9 @@ const TimelineZoomControls = ({ extent, zoomLevels, dims, onApplyZoom }) => { zoomLevels = DEFAULT_ZOOM_LEVELS; } return ( - +
    {zoomLevels.map((z, idx) => renderZoom(z, idx))} - +
    ); }; diff --git a/src/scss/_burger.scss b/src/scss/_burger.scss index 8add6f9..6962b97 100644 --- a/src/scss/_burger.scss +++ b/src/scss/_burger.scss @@ -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; - } - } } } diff --git a/src/scss/_variables.scss b/src/scss/_variables.scss index 76e3221..5831c1b 100644 --- a/src/scss/_variables.scss +++ b/src/scss/_variables.scss @@ -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; diff --git a/src/scss/card.scss b/src/scss/card.scss index 49e4ca1..470dd77 100644 --- a/src/scss/card.scss +++ b/src/scss/card.scss @@ -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; } } diff --git a/src/scss/cardstack.scss b/src/scss/cardstack.scss index c8a1514..cc3d686 100644 --- a/src/scss/cardstack.scss +++ b/src/scss/cardstack.scss @@ -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; diff --git a/src/scss/common.scss b/src/scss/common.scss index 447fdc4..9ad75c2 100644 --- a/src/scss/common.scss +++ b/src/scss/common.scss @@ -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; } diff --git a/src/scss/cover.scss b/src/scss/cover.scss index 7670b93..f20f430 100644 --- a/src/scss/cover.scss +++ b/src/scss/cover.scss @@ -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; } } diff --git a/src/scss/infopopup.scss b/src/scss/infopopup.scss index c1ffe2e..1917568 100644 --- a/src/scss/infopopup.scss +++ b/src/scss/infopopup.scss @@ -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; } } diff --git a/src/scss/map.scss b/src/scss/map.scss index 42a10c2..edcbf36 100644 --- a/src/scss/map.scss +++ b/src/scss/map.scss @@ -18,7 +18,7 @@ position: fixed; top: 0px; bottom: 0px; - left: 110px; + left: 0; right: 0; &.mobile { diff --git a/src/scss/satelliteoverlaytoggle.scss b/src/scss/satelliteoverlaytoggle.scss index f77d502..9b94479 100644 --- a/src/scss/satelliteoverlaytoggle.scss +++ b/src/scss/satelliteoverlaytoggle.scss @@ -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; diff --git a/src/scss/search.scss b/src/scss/search.scss index 8f9022b..54f785e 100644 --- a/src/scss/search.scss +++ b/src/scss/search.scss @@ -46,11 +46,6 @@ } } -.folded { - left: -400px; - transition: 0.2s ease; -} - .search-outer-container { position: absolute; left: 110px; diff --git a/src/scss/tabs.scss b/src/scss/tabs.scss index 991a8c4..49647f0 100644 --- a/src/scss/tabs.scss +++ b/src/scss/tabs.scss @@ -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; + } } } diff --git a/src/scss/timeline.scss b/src/scss/timeline.scss index 91b1ad4..ea3edd6 100644 --- a/src/scss/timeline.scss +++ b/src/scss/timeline.scss @@ -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; + } + } } diff --git a/src/scss/toolbar.scss b/src/scss/toolbar.scss index 79405e2..6f17b1a 100644 --- a/src/scss/toolbar.scss +++ b/src/scss/toolbar.scss @@ -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; +// } +// } +// } +// } diff --git a/src/store/initial.js b/src/store/initial.js index b54ca36..c57cc9e 100644 --- a/src/store/initial.js +++ b/src/store/initial.js @@ -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: {