NewsAtlas/frontend/css/style.css

502 lines
14 KiB
CSS

* { box-sizing: border-box; }
/*
* CyberQueer theme — sourced from the user's ~/Dotfiles/colors.conf:
* COLOR_TEXT=D6ABAB COLOR_BG=1A1A1A COLOR_HIGHLIGHT=E40046
* COLOR_DARK=5018DD COLOR_RED=F50505
* Everything else here is a derived tint/shade of those five anchors.
*/
:root {
--rail-width: 320px;
--topbar-height: 52px;
--drawer-handle-height: 38px;
--c-bg: #1a1a1a;
--c-bg-deep: #0f0d16; /* darker-than-bg base for the page behind panels */
--c-text: #d6abab;
--c-text-muted: #a68a9c;
--c-highlight: #e40046; /* hot pink — primary accent */
--c-highlight-soft: #ff4d82; /* lightened highlight for small text/links on dark bg */
--c-dark: #5018dd; /* electric violet — secondary accent */
--c-dark-soft: #9d7cff; /* lightened violet for small text/links on dark bg */
--c-red: #f50505; /* danger / down */
--c-green: #34d399; /* gain — kept distinct from theme for finance semantics */
--c-magenta: #ff33ff; /* flagged-military flights — must match MILITARY_FLIGHT_HEX in app.js */
--c-panel: rgba(24, 15, 33, 0.97);
--c-panel-border: #3a2159;
--c-panel-hover: #241533;
--c-tag-bg: #2a1a45;
}
html, body {
margin: 0;
height: 100%;
background: var(--c-bg-deep);
color: var(--c-text);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
overflow: hidden;
}
#globeViz {
position: absolute;
top: var(--topbar-height);
left: var(--rail-width);
right: var(--rail-width);
bottom: 0;
}
#topbar {
position: absolute;
top: 0;
left: 0;
right: 0;
height: var(--topbar-height);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 18px;
background: #120a1e;
border-bottom: 1px solid var(--c-panel-border);
z-index: 30;
}
#topbarLeft { display: flex; align-items: center; }
#topbar h1 {
font-size: 18px;
letter-spacing: 0.08em;
margin: 0;
font-weight: 600;
background: linear-gradient(90deg, var(--c-dark-soft), var(--c-highlight-soft));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
#layerToggles {
display: flex;
align-items: center;
gap: 14px;
font-size: 13px;
color: var(--c-text);
}
#layerToggles label {
display: flex;
align-items: center;
gap: 4px;
cursor: pointer;
white-space: nowrap;
}
#layerToggles input[type="checkbox"] { accent-color: var(--c-highlight); }
#layerToggles select {
background: #1c1030;
color: var(--c-text);
border: 1px solid var(--c-panel-border);
border-radius: 4px;
font-size: 12px;
padding: 2px 4px;
}
#refreshBtn {
background: var(--c-tag-bg);
color: var(--c-text);
border: 1px solid var(--c-panel-border);
border-radius: 6px;
padding: 4px 10px;
cursor: pointer;
font-size: 12px;
}
#refreshBtn:hover { background: #3d2260; border-color: var(--c-dark); }
#lastUpdated { opacity: 0.6; font-size: 11px; }
/* ---- docked rails (left = news, right = markets) ---- */
.rail {
position: absolute;
top: var(--topbar-height);
bottom: 0;
width: var(--rail-width);
background: var(--c-panel);
z-index: 15;
overflow-y: auto;
padding: 14px 14px 20px;
}
#leftPanel { left: 0; border-right: 1px solid var(--c-panel-border); }
#rightPanel { right: 0; border-left: 1px solid var(--c-panel-border); }
.rail h2 {
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--c-dark-soft);
margin: 4px 0 10px;
position: sticky;
top: 0;
background: inherit;
}
.scroll-list { display: flex; flex-direction: column; gap: 2px; }
/* news feed items */
.news-item {
padding: 9px 0;
border-bottom: 1px solid #241533;
cursor: default;
}
.news-item a {
color: var(--c-text);
text-decoration: none;
font-size: 13.5px;
line-height: 1.35;
}
.news-item a:hover { color: var(--c-highlight-soft); text-decoration: underline; }
.favicon {
width: 13px;
height: 13px;
border-radius: 3px;
vertical-align: -2px;
margin-right: 5px;
background: #241533; /* placeholder box while loading / if the icon is transparent */
}
.news-item .article-meta { font-size: 11px; color: var(--c-text-muted); margin-top: 3px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.locate-btn {
background: var(--c-tag-bg);
border: 1px solid var(--c-panel-border);
color: #c9a8d8;
border-radius: 3px;
font-size: 10px;
padding: 0 4px;
cursor: pointer;
}
.locate-btn:hover { background: #3d2260; color: #fff; }
.bias-tag {
display: inline-block;
font-size: 10px;
background: var(--c-tag-bg);
border: 1px solid var(--c-panel-border);
border-radius: 3px;
padding: 1px 5px;
color: #c9a8d8;
}
/* markets rail items */
.market-item {
padding: 9px 4px;
border-bottom: 1px solid #241533;
cursor: pointer;
}
.market-item:hover { background: var(--c-panel-hover); }
.market-item.frozen, .market-item.error { position: relative; }
.market-item.frozen > .market-row, .market-item.error > .market-row,
.market-item.frozen > .spark-container, .market-item.error > .spark-container { opacity: 0.35; }
.frozen-overlay, .error-overlay {
position: absolute;
inset: 0;
z-index: 3;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 2px;
background: rgba(11, 20, 36, 0.55);
border-radius: 6px;
font-size: 13px;
font-weight: 700;
letter-spacing: 0.08em;
cursor: help;
text-align: center;
}
.frozen-overlay .overlay-name, .error-overlay .overlay-name {
font-size: 10px;
font-weight: 500;
letter-spacing: normal;
text-shadow: none;
opacity: 0.85;
}
.frozen-overlay {
border: 1px solid #4fd1e6;
color: #9fe8f5;
text-shadow: 0 0 6px rgba(79, 209, 230, 0.6);
}
.error-overlay {
border: 1px solid var(--c-red);
color: #ffb3b3;
text-shadow: 0 0 6px rgba(245, 5, 5, 0.6);
}
.market-row { display: flex; justify-content: space-between; align-items: baseline; font-size: 13px; }
.market-row .label { color: var(--c-text); }
.market-row .price { font-weight: 600; }
.market-detail { margin-top: 8px; font-size: 12px; }
.market-detail.hidden { display: none; }
.spark-container { position: relative; margin-top: 6px; }
.spark { display: block; width: 100%; height: 44px; overflow: visible; }
.spark-tooltip {
position: absolute;
top: -4px;
background: #1c1030;
border: 1px solid var(--c-panel-border);
border-radius: 4px;
padding: 2px 6px;
font-size: 10px;
color: var(--c-text);
white-space: nowrap;
pointer-events: none;
z-index: 2;
}
.up { color: var(--c-green); }
.down { color: var(--c-red); }
/* ---- cluster modal ---- */
.modal { position: absolute; inset: 0; z-index: 40; display: flex; align-items: center; justify-content: center; }
.modal.hidden { display: none; }
.modal-backdrop { position: absolute; inset: 0; background: rgba(10, 0, 20, 0.65); }
.modal-card {
position: relative;
width: 420px;
max-width: 88vw;
max-height: 82vh;
overflow-y: auto;
background: #150a24;
border: 1px solid var(--c-panel-border);
border-radius: 10px;
padding: 20px 18px;
box-shadow: 0 12px 40px rgba(0,0,0,0.6), 0 0 60px rgba(80, 24, 221, 0.15);
}
.modal-card.wide { width: 760px; max-height: 88vh; }
.modal-close {
position: absolute;
top: 8px;
right: 10px;
background: none;
border: none;
color: var(--c-text-muted);
font-size: 22px;
cursor: pointer;
}
.modal-close:hover { color: var(--c-highlight-soft); }
#infoBtn {
width: 26px;
height: 26px;
border-radius: 50%;
background: var(--c-tag-bg);
border: 1px solid var(--c-panel-border);
color: var(--c-dark-soft);
font-size: 13px;
font-weight: 700;
font-style: italic;
font-family: Georgia, "Times New Roman", serif;
cursor: pointer;
margin-left: 4px;
}
#infoBtn:hover { background: #3d2260; color: #fff; }
.econ-select {
background: #1c1030;
color: var(--c-text);
border: 1px solid var(--c-panel-border);
border-radius: 4px;
font-size: 12px;
padding: 4px 6px;
}
.econ-incident { padding: 14px 0; border-bottom: 1px solid #241533; }
.incident-datetime {
font-size: 21px;
font-weight: 700;
color: var(--c-magenta);
text-shadow: 0 0 10px rgba(255, 51, 255, 0.35);
margin-bottom: 6px;
}
.econ-incident h3 { margin: 0 0 4px; font-size: 14px; color: #f2dede; display: flex; flex-wrap: wrap; gap: 8px 14px; font-weight: 600; }
.instrument-chip { display: inline-flex; gap: 6px; align-items: baseline; }
.econ-incident .window { font-size: 11px; color: var(--c-text-muted); margin-bottom: 8px; }
.econ-incident .articles { margin-top: 8px; }
.overlay-toggle-btn, .articles-toggle-btn {
background: var(--c-tag-bg);
border: 1px solid var(--c-panel-border);
color: var(--c-dark-soft);
border-radius: 6px;
padding: 4px 10px;
font-size: 11px;
cursor: pointer;
margin: 4px 6px 6px 0;
}
.overlay-toggle-btn:hover, .articles-toggle-btn:hover { background: #3d2260; color: #fff; }
.overlay-charts { margin: 6px 0 12px; }
.overlay-charts h4 { font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--c-text-muted); margin: 12px 0 4px; font-weight: 600; }
.overlay-charts h4:first-child { margin-top: 0; }
.overlay-chart-container { position: relative; }
.overlay-chart-svg { width: 100%; height: 200px; display: block; overflow: visible; }
.overlay-tooltip {
position: absolute;
top: 4px;
background: #1c1030;
border: 1px solid var(--c-panel-border);
border-radius: 6px;
padding: 6px 8px;
font-size: 11px;
pointer-events: none;
z-index: 2;
max-width: 220px;
}
.overlay-tooltip-row { display: flex; justify-content: space-between; gap: 10px; white-space: nowrap; }
.overlay-legend { display: flex; flex-wrap: wrap; gap: 6px 12px; margin-top: 6px; font-size: 10px; color: var(--c-text-muted); }
.overlay-legend-item { display: inline-flex; align-items: center; gap: 4px; }
.overlay-legend .swatch { width: 8px; height: 8px; border-radius: 2px; display: inline-block; }
.keyword-tags { margin: 6px 0 10px; font-size: 11px; display: flex; flex-wrap: wrap; align-items: center; gap: 5px; }
.keyword-tag {
display: inline-block;
background: var(--c-tag-bg);
border: 1px solid var(--c-panel-border);
color: var(--c-dark-soft);
border-radius: 10px;
padding: 2px 8px;
font-size: 11px;
}
.panel-section { margin-bottom: 20px; }
.panel-section h2 {
font-size: 13px;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--c-dark-soft);
margin: 0 0 8px;
border-bottom: 1px solid var(--c-panel-border);
padding-bottom: 4px;
}
.headline { font-size: 17px; font-weight: 600; margin: 4px 0 4px; line-height: 1.3; color: #f2dede; }
.subtle { color: var(--c-text-muted); font-size: 12px; }
.article-item { padding: 10px 0; border-bottom: 1px solid #241533; }
.article-item a { color: var(--c-text); text-decoration: none; font-size: 14px; line-height: 1.35; }
.article-item a:hover { color: var(--c-highlight-soft); text-decoration: underline; }
.article-meta { font-size: 11px; color: var(--c-text-muted); margin-top: 3px; }
.wiki-box { display: flex; gap: 10px; }
.wiki-box img { width: 84px; height: 84px; object-fit: cover; border-radius: 6px; flex-shrink: 0; }
.wiki-box p { font-size: 13px; line-height: 1.4; margin: 0 0 6px; color: #c9b2ba; }
.wiki-box a { color: var(--c-dark-soft); font-size: 12px; }
.parliament-diagram { max-width: 100%; border-radius: 6px; background: #fff; padding: 6px; }
/* ---- wikipedia text-selection popup ---- */
#flightTooltip {
position: absolute;
z-index: 45;
background: #1c1030;
border: 1px solid var(--c-panel-border);
border-radius: 6px;
padding: 6px 9px;
box-shadow: 0 4px 16px rgba(0,0,0,0.5);
font-size: 11px;
line-height: 1.5;
pointer-events: none;
max-width: 220px;
}
#flightTooltip.hidden { display: none; }
#flightTooltip b { color: var(--c-text); }
#flightTooltip .mil { color: var(--c-magenta); font-weight: 600; }
#wikiSelectPopup {
position: absolute;
z-index: 50;
background: #1c1030;
border: 1px solid var(--c-panel-border);
border-radius: 6px;
padding: 6px;
box-shadow: 0 4px 16px rgba(0,0,0,0.5);
font-size: 12px;
max-width: 280px;
}
#wikiSelectPopup.hidden { display: none; }
#wikiSelectPopup button.trigger {
background: var(--c-tag-bg);
border: 1px solid var(--c-panel-border);
color: var(--c-text);
border-radius: 4px;
padding: 4px 8px;
cursor: pointer;
font-size: 12px;
}
#wikiSelectPopup .wiki-result {
display: block;
padding: 6px 4px;
border-top: 1px solid var(--c-panel-border);
color: #d8c3cc;
text-decoration: none;
}
#wikiSelectPopup .wiki-result:hover { background: #2a1a45; }
#wikiSelectPopup .wiki-result b { color: var(--c-highlight-soft); display: block; }
/* ---- bottom drawer: military / conflict event log ---- */
#militaryDrawer {
position: absolute;
left: var(--rail-width);
right: var(--rail-width);
bottom: 0;
z-index: 25;
background: var(--c-panel);
border-top: 1px solid var(--c-panel-border);
max-height: 46vh;
display: flex;
flex-direction: column;
transition: max-height 0.2s ease;
}
#militaryDrawer.collapsed { max-height: var(--drawer-handle-height); }
#drawerHandle {
height: var(--drawer-handle-height);
flex-shrink: 0;
width: 100%;
background: none;
border: none;
color: var(--c-text);
font-size: 12px;
letter-spacing: 0.04em;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
justify-content: center;
}
#drawerHandle:hover { background: var(--c-panel-hover); }
#drawerArrow { display: inline-block; transition: transform 0.2s ease; font-size: 10px; color: var(--c-highlight); }
#militaryDrawer.collapsed #drawerArrow { transform: rotate(180deg); }
.drawer-body { overflow-y: auto; padding: 4px 18px 16px; }
#militaryDrawer.collapsed .drawer-body { display: none; }
.conflict-item {
display: flex;
justify-content: space-between;
gap: 10px;
padding: 7px 0;
border-bottom: 1px solid #241533;
font-size: 12.5px;
}
.conflict-item .desc { color: var(--c-text); }
.conflict-item .meta { color: var(--c-text-muted); font-size: 11px; white-space: nowrap; }
.conflict-item .fatalities { color: var(--c-red); }
.hidden { display: none !important; }