The Waymarked Trails raster overlay has no queryable features (just pixels), so this answers "what trail is this" with a one-off Overpass query on click instead: way(around:40m) finds candidate ways, then rel(bw) walks backward to their parent route=hiking relations. Overpass has permissive CORS, so this runs straight from the browser, no server proxy needed — verified against a real KST route in the Tatras. Route length isn't tagged directly, so it's summed from each member way's own geometry (measure.js's existing haversine lineLength, now exported and reused rather than duplicated). The colour tag is only ever used as a CSS background after matching a strict hex/word regex — untrusted free text otherwise.
1913 lines
32 KiB
CSS
1913 lines
32 KiB
CSS
html, body {
|
|
height: 100%;
|
|
margin: 0;
|
|
font-family: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
}
|
|
|
|
/* Router-carved-signage display face (docs/nps-resources.adoc), used only
|
|
for the topbar wordmark below — a full body-text swap is a separate,
|
|
bigger decision this isn't. Bold is the only weight vendored since
|
|
.topbar__brand only ever renders at font-weight 700. */
|
|
@font-face {
|
|
font-family: "National Park";
|
|
src: url("/vendor/national-park-typeface/NationalPark-Bold.woff2") format("woff2");
|
|
font-weight: 700;
|
|
font-style: normal;
|
|
font-display: swap;
|
|
}
|
|
|
|
#app {
|
|
height: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.topbar {
|
|
flex: 0 0 auto;
|
|
display: flex;
|
|
align-items: center;
|
|
height: 44px;
|
|
padding: 0 16px;
|
|
background: #1a1a1a;
|
|
}
|
|
|
|
.topbar__brand {
|
|
font-family: "National Park", -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
font-size: 20px;
|
|
font-weight: 700;
|
|
letter-spacing: 0.12em;
|
|
text-transform: uppercase;
|
|
color: #fff;
|
|
}
|
|
|
|
.topbar__center {
|
|
margin: 0 auto;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 14px;
|
|
}
|
|
|
|
.topbar__coords,
|
|
.topbar__sun {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 5px;
|
|
font-size: 12px;
|
|
font-variant-numeric: tabular-nums;
|
|
color: #bbb;
|
|
}
|
|
|
|
.topbar__sun {
|
|
gap: 14px;
|
|
}
|
|
|
|
.topbar__group {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 5px;
|
|
}
|
|
|
|
.topbar__icon {
|
|
display: flex;
|
|
width: 13px;
|
|
height: 13px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.topbar__icon svg {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.topbar__coords {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.topbar__coords:hover {
|
|
color: #fff;
|
|
}
|
|
|
|
.topbar__sun[hidden] {
|
|
display: none;
|
|
}
|
|
|
|
.topbar__offline-status {
|
|
width: 8px;
|
|
height: 8px;
|
|
border-radius: 50%;
|
|
background: #666;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.topbar__offline-status--ready {
|
|
background: #2a9d8f;
|
|
}
|
|
|
|
.topbar__auth {
|
|
margin-left: auto;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
font-size: 13px;
|
|
color: #ccc;
|
|
}
|
|
|
|
.topbar__auth a {
|
|
color: #fff;
|
|
}
|
|
|
|
.app-body {
|
|
flex: 1;
|
|
display: flex;
|
|
min-height: 0;
|
|
}
|
|
|
|
.sidebar {
|
|
flex: 0 0 52px;
|
|
position: relative;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 4px;
|
|
padding: 8px 0;
|
|
background: #fff;
|
|
border-right: 1px solid #ddd;
|
|
/* No overflow-y:auto here: setting only one axis to a clipping value
|
|
forces the browser to compute the other axis as "auto" too (CSS
|
|
Overflow spec), which would clip the flyouts — they intentionally
|
|
poke out past the sidebar's own width via left:44px. */
|
|
}
|
|
|
|
.sidebar-item {
|
|
position: relative;
|
|
}
|
|
|
|
.sidebar-group-label {
|
|
width: 28px;
|
|
height: 1px;
|
|
margin: 4px 0;
|
|
background: #ddd;
|
|
}
|
|
|
|
.sidebar-group-label:first-child {
|
|
display: none;
|
|
}
|
|
|
|
.sidebar-icon {
|
|
width: 36px;
|
|
height: 36px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border: none;
|
|
border-radius: 6px;
|
|
background: none;
|
|
color: #444;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.sidebar-icon svg {
|
|
width: 20px;
|
|
height: 20px;
|
|
}
|
|
|
|
.sidebar-icon:hover {
|
|
background: #f0f0f0;
|
|
}
|
|
|
|
.sidebar-icon.active {
|
|
background: #dbe9ff;
|
|
color: #1a5fb4;
|
|
}
|
|
|
|
.sidebar-flyout {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 44px;
|
|
z-index: 20;
|
|
min-width: max-content;
|
|
background: #fff;
|
|
border: 1px solid #ddd;
|
|
border-radius: 6px;
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
padding: 6px;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.sidebar-flyout[hidden] {
|
|
display: none;
|
|
}
|
|
|
|
.sidebar-flyout__option {
|
|
display: block;
|
|
width: 100%;
|
|
padding: 6px 10px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
background: none;
|
|
font: inherit;
|
|
font-size: 13px;
|
|
text-align: left;
|
|
white-space: nowrap;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.sidebar-flyout__option:hover {
|
|
background: #f0f0f0;
|
|
}
|
|
|
|
.sidebar-flyout__option.active {
|
|
background: #dbe9ff;
|
|
font-weight: 600;
|
|
}
|
|
|
|
#map {
|
|
flex: 1;
|
|
min-width: 0;
|
|
position: relative;
|
|
}
|
|
|
|
.radar-control__playback {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
}
|
|
|
|
.radar-control__play {
|
|
border: none;
|
|
background: none;
|
|
padding: 2px 4px;
|
|
font-size: 13px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.radar-control__scrub {
|
|
width: 110px;
|
|
}
|
|
|
|
.radar-control__time {
|
|
font-variant-numeric: tabular-nums;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.radar-control__forecast {
|
|
margin-top: 6px;
|
|
padding-top: 6px;
|
|
border-top: 1px solid #eee;
|
|
}
|
|
|
|
.radar-control__forecast-hours {
|
|
display: flex;
|
|
gap: 10px;
|
|
overflow-x: auto;
|
|
padding-bottom: 6px;
|
|
margin-bottom: 4px;
|
|
border-bottom: 1px solid #eee;
|
|
}
|
|
|
|
.radar-control__forecast-hour {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 2px;
|
|
flex: 0 0 auto;
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
.radar-control__forecast-hour span:first-child {
|
|
color: #888;
|
|
font-size: 11px;
|
|
}
|
|
|
|
.radar-control__forecast-day {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 2px 0;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.radar-control__forecast-day span:first-child {
|
|
width: 2.2em;
|
|
color: #888;
|
|
}
|
|
|
|
.radar-control__forecast-day span:nth-child(3) {
|
|
margin-left: auto;
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
.radar-control__forecast-stale {
|
|
margin: 4px 0 0;
|
|
color: #888;
|
|
font-size: 11px;
|
|
}
|
|
|
|
.shadow-control__time {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
}
|
|
|
|
.shadow-control__slider {
|
|
width: 110px;
|
|
}
|
|
|
|
.shadow-control__clock {
|
|
font-variant-numeric: tabular-nums;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.shadow-control__hint {
|
|
margin: 6px 0 0;
|
|
color: #888;
|
|
font-size: 11px;
|
|
}
|
|
|
|
.basemap-panel {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 52px;
|
|
width: 300px;
|
|
max-width: 90vw;
|
|
height: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
background: #fff;
|
|
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);
|
|
font-size: 13px;
|
|
z-index: 10;
|
|
}
|
|
|
|
.basemap-panel[hidden] {
|
|
display: none;
|
|
}
|
|
|
|
.basemap-panel__header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 10px 12px;
|
|
border-bottom: 1px solid #eee;
|
|
}
|
|
|
|
.basemap-panel__close {
|
|
border: none;
|
|
background: none;
|
|
font-size: 18px;
|
|
line-height: 1;
|
|
padding: 0 4px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.basemap-panel__list {
|
|
padding: 6px;
|
|
}
|
|
|
|
.basemap-panel__option {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
width: 100%;
|
|
padding: 10px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
background: none;
|
|
font: inherit;
|
|
font-size: 14px;
|
|
text-align: left;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.basemap-panel__option:hover {
|
|
background: #f0f0f0;
|
|
}
|
|
|
|
.basemap-panel__option.active {
|
|
background: #dbe9ff;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.basemap-panel__check {
|
|
color: #1a5fb4;
|
|
visibility: hidden;
|
|
}
|
|
|
|
.basemap-panel__option.active .basemap-panel__check {
|
|
visibility: visible;
|
|
}
|
|
|
|
.offline-data-panel__body {
|
|
padding: 8px 12px;
|
|
}
|
|
|
|
.offline-data-panel__regions-label {
|
|
margin: 0 0 4px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.offline-data-panel__region-list {
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: 0;
|
|
max-height: 220px;
|
|
overflow-y: auto;
|
|
border: 1px solid #eee;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.offline-data-panel__region-list li {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 6px;
|
|
}
|
|
|
|
.offline-data-panel__region-list label {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
padding: 4px 8px;
|
|
min-width: 0;
|
|
flex: 1;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.offline-data-panel__region-list label:hover {
|
|
background: #f0f0f0;
|
|
}
|
|
|
|
.offline-data-panel__cache-info {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
padding-right: 8px;
|
|
color: #888;
|
|
font-size: 11px;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.offline-data-panel__cache-delete {
|
|
border: none;
|
|
background: none;
|
|
padding: 0 2px;
|
|
color: #a33;
|
|
font-size: 11px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.offline-data-panel__cache-delete:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.offline-data-panel__cache-delete:disabled {
|
|
opacity: 0.5;
|
|
cursor: default;
|
|
}
|
|
|
|
/* Same rounded-square badge ratio as icons.js's own MAP_MARKER_ICON
|
|
(rx 5 of a 22-wide square) — a consistent frame rather than however
|
|
each flag's own artwork happens to fill an unbordered square. */
|
|
.offline-data-panel__flag {
|
|
flex-shrink: 0;
|
|
width: 18px;
|
|
height: 18px;
|
|
border-radius: 4px;
|
|
border: 1px solid rgba(0, 0, 0, 0.15);
|
|
object-fit: cover;
|
|
}
|
|
|
|
.offline-data-panel__region-status {
|
|
padding: 6px 8px;
|
|
color: #888;
|
|
}
|
|
|
|
.offline-data-panel__apply {
|
|
margin-top: 8px;
|
|
width: 100%;
|
|
border: 1px solid #ccc;
|
|
border-radius: 4px;
|
|
background: #fff;
|
|
padding: 6px 8px;
|
|
font: inherit;
|
|
font-size: 12px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.offline-data-panel__apply:hover {
|
|
background: #f0f0f0;
|
|
}
|
|
|
|
.offline-data-panel__apply:disabled {
|
|
opacity: 0.5;
|
|
cursor: default;
|
|
}
|
|
|
|
.offline-data-panel__row {
|
|
margin-top: 14px;
|
|
padding-top: 10px;
|
|
border-top: 1px solid #eee;
|
|
}
|
|
|
|
.offline-data-panel__row-head {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 8px;
|
|
}
|
|
|
|
.offline-data-panel__delete {
|
|
border: 1px solid #ccc;
|
|
border-radius: 4px;
|
|
background: #fff;
|
|
padding: 2px 8px;
|
|
font: inherit;
|
|
font-size: 11px;
|
|
color: #a33;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.offline-data-panel__delete:hover {
|
|
background: #fdecec;
|
|
}
|
|
|
|
.offline-data-panel__delete:disabled {
|
|
opacity: 0.5;
|
|
cursor: default;
|
|
}
|
|
|
|
.offline-data-panel__status {
|
|
margin: 6px 0 0;
|
|
color: #666;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.offline-data-panel__status--error {
|
|
white-space: pre-wrap;
|
|
word-break: break-word;
|
|
max-height: 200px;
|
|
overflow-y: auto;
|
|
color: #b3261e;
|
|
}
|
|
|
|
.offline-data-panel__update-badge {
|
|
color: #b8860b;
|
|
}
|
|
|
|
.gpx-panel {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 52px;
|
|
width: 300px;
|
|
max-width: 90vw;
|
|
height: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
background: #fff;
|
|
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);
|
|
font-size: 13px;
|
|
z-index: 10;
|
|
}
|
|
|
|
.gpx-panel[hidden] {
|
|
display: none;
|
|
}
|
|
|
|
.gpx-panel__header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 10px 12px;
|
|
border-bottom: 1px solid #eee;
|
|
}
|
|
|
|
.gpx-panel__actions {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 2px;
|
|
}
|
|
|
|
.gpx-panel__action {
|
|
width: 30px;
|
|
height: 30px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border: none;
|
|
border-radius: 6px;
|
|
background: none;
|
|
color: #444;
|
|
cursor: pointer;
|
|
}
|
|
|
|
/* This class's own "display: flex" above otherwise wins over the browser
|
|
default "[hidden] { display: none }" — same specificity, but an author
|
|
rule always outranks a user-agent one — so GpxPanelControl#mount hiding
|
|
these (logged out: no upload/new-folder) had no visual effect at all. */
|
|
.gpx-panel__action[hidden] {
|
|
display: none;
|
|
}
|
|
|
|
.gpx-panel__action svg {
|
|
width: 18px;
|
|
height: 18px;
|
|
}
|
|
|
|
.gpx-panel__action:hover {
|
|
background: #f0f0f0;
|
|
}
|
|
|
|
.gpx-panel__close {
|
|
border: none;
|
|
background: none;
|
|
font-size: 18px;
|
|
line-height: 1;
|
|
padding: 0 4px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.gpx-upload__status {
|
|
margin: 0 12px 10px;
|
|
color: #666;
|
|
}
|
|
|
|
.gpx-tree {
|
|
/* flex:1 (not just overflow-y) so the tree fills the rest of the panel
|
|
even when short/empty — otherwise the blank space below it wouldn't
|
|
be part of the drop target and dropping a file there would silently
|
|
do nothing. */
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
padding: 8px 12px;
|
|
}
|
|
|
|
.gpx-tree ul {
|
|
list-style: none;
|
|
margin: 0;
|
|
padding-left: 16px;
|
|
}
|
|
|
|
.gpx-tree > ul {
|
|
padding-left: 0;
|
|
}
|
|
|
|
.gpx-tree summary {
|
|
cursor: pointer;
|
|
font-weight: 600;
|
|
border-radius: 3px;
|
|
}
|
|
|
|
.gpx-tree__folder-row {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 4px;
|
|
width: calc(100% - 18px);
|
|
}
|
|
|
|
.gpx-tree summary.gpx-drop-hover {
|
|
background: #eef5fd;
|
|
outline: 1px dashed #4a90d9;
|
|
}
|
|
|
|
.gpx-tree__file {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
padding: 2px 0;
|
|
cursor: grab;
|
|
}
|
|
|
|
.gpx-tree__file label {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
flex: 1;
|
|
min-width: 0;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.gpx-tree__file-name {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
color: inherit;
|
|
text-decoration: none;
|
|
}
|
|
|
|
.gpx-tree__file-name:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.gpx-tree__kind-icon {
|
|
flex-shrink: 0;
|
|
display: flex;
|
|
color: #999;
|
|
}
|
|
|
|
.gpx-tree__kind-icon svg {
|
|
width: 14px;
|
|
height: 14px;
|
|
}
|
|
|
|
.gpx-tree__download-wrapper {
|
|
position: relative;
|
|
flex-shrink: 0;
|
|
display: flex;
|
|
}
|
|
|
|
.gpx-tree__download {
|
|
flex-shrink: 0;
|
|
display: flex;
|
|
border: none;
|
|
background: none;
|
|
color: #999;
|
|
padding: 0 4px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.gpx-tree__download svg {
|
|
width: 14px;
|
|
height: 14px;
|
|
}
|
|
|
|
.gpx-tree__download:hover {
|
|
color: #333;
|
|
}
|
|
|
|
.gpx-tree__download-menu {
|
|
position: absolute;
|
|
top: 100%;
|
|
right: 0;
|
|
z-index: 20;
|
|
min-width: max-content;
|
|
background: #fff;
|
|
border: 1px solid #ddd;
|
|
border-radius: 6px;
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
padding: 4px;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.gpx-tree__download-menu[hidden] {
|
|
display: none;
|
|
}
|
|
|
|
.gpx-tree__download-menu-item {
|
|
display: block;
|
|
padding: 6px 10px;
|
|
border-radius: 4px;
|
|
color: inherit;
|
|
text-decoration: none;
|
|
white-space: nowrap;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.gpx-tree__download-menu-item:hover {
|
|
background: #f0f0f0;
|
|
}
|
|
|
|
.gpx-tree__delete {
|
|
flex-shrink: 0;
|
|
border: none;
|
|
background: none;
|
|
color: #999;
|
|
font-size: 14px;
|
|
line-height: 1;
|
|
padding: 0 4px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.gpx-tree__delete:hover {
|
|
color: #e63946;
|
|
}
|
|
|
|
.gpx-tree__empty {
|
|
color: #888;
|
|
font-style: italic;
|
|
}
|
|
|
|
.gpx-tree.gpx-drop-hover {
|
|
outline: 1px dashed #4a90d9;
|
|
outline-offset: -2px;
|
|
}
|
|
|
|
.gpx-legend {
|
|
flex-shrink: 0;
|
|
max-height: 160px;
|
|
overflow-y: auto;
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 2px 8px;
|
|
padding: 8px 12px;
|
|
border-top: 1px solid #1a1a1a;
|
|
}
|
|
|
|
.gpx-legend[hidden] {
|
|
display: none;
|
|
}
|
|
|
|
.gpx-legend__item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
padding: 3px 4px;
|
|
border: none;
|
|
border-radius: 3px;
|
|
background: none;
|
|
font: inherit;
|
|
text-align: left;
|
|
cursor: pointer;
|
|
color: #1a1a1a;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.gpx-legend__item:hover {
|
|
background: #f0f0f0;
|
|
}
|
|
|
|
.gpx-legend__item--hidden {
|
|
opacity: 0.35;
|
|
}
|
|
|
|
.gpx-legend__label {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.gpx-legend__icon {
|
|
display: flex;
|
|
width: 14px;
|
|
height: 14px;
|
|
flex-shrink: 0;
|
|
color: #1a1a1a;
|
|
}
|
|
|
|
.gpx-legend__icon svg {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.gpx-legend__swatch {
|
|
width: 10px;
|
|
height: 10px;
|
|
border-radius: 50%;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
#map.gpx-drop-hover::after {
|
|
content: "";
|
|
position: absolute;
|
|
inset: 0;
|
|
outline: 3px dashed #4a90d9;
|
|
outline-offset: -3px;
|
|
background: rgba(74, 144, 217, 0.08);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.maplibregl-popup-content p {
|
|
margin: 4px 0 0;
|
|
}
|
|
|
|
.debug-popup .maplibregl-popup-content {
|
|
max-height: 320px;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.debug-popup__feature {
|
|
font-size: 11px;
|
|
font-family: monospace;
|
|
}
|
|
|
|
.debug-popup__feature + .debug-popup__feature {
|
|
margin-top: 8px;
|
|
padding-top: 8px;
|
|
border-top: 1px solid #eee;
|
|
}
|
|
|
|
.debug-popup__feature table {
|
|
border-collapse: collapse;
|
|
width: 100%;
|
|
}
|
|
|
|
.debug-popup__feature th {
|
|
text-align: left;
|
|
color: #888;
|
|
font-weight: normal;
|
|
padding: 1px 6px 1px 0;
|
|
vertical-align: top;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.debug-popup__feature td {
|
|
word-break: break-word;
|
|
}
|
|
|
|
.maplibregl-ctrl-overview-map {
|
|
border-radius: 4px;
|
|
overflow: hidden;
|
|
box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.measure-ctrl {
|
|
position: relative;
|
|
}
|
|
|
|
.measure-ctrl__button svg {
|
|
display: block;
|
|
margin: 0 auto;
|
|
width: 18px;
|
|
height: 18px;
|
|
}
|
|
|
|
.measure-ctrl__button.active {
|
|
background: #dbe9ff;
|
|
}
|
|
|
|
.measure-panel {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 100%;
|
|
margin-left: 8px;
|
|
z-index: 20;
|
|
min-width: max-content;
|
|
background: #fff;
|
|
border: 1px solid #ddd;
|
|
border-radius: 6px;
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
padding: 6px 8px;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.measure-panel[hidden] {
|
|
display: none;
|
|
}
|
|
|
|
.measure-panel__controls {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
}
|
|
|
|
/* Same "author display wins over the UA [hidden] rule" gotcha as
|
|
.gpx-panel__action[hidden]/.notes-panel__form[hidden] elsewhere in this
|
|
file — this sets its own "display" too. */
|
|
.measure-panel__controls[hidden] {
|
|
display: none;
|
|
}
|
|
|
|
.measure-panel .measure-panel__save {
|
|
width: auto;
|
|
height: auto;
|
|
display: inline-block;
|
|
border: none;
|
|
border-radius: 4px;
|
|
background: none;
|
|
font-size: 14px;
|
|
line-height: 1;
|
|
cursor: pointer;
|
|
padding: 2px 4px;
|
|
}
|
|
|
|
.measure-panel__save:disabled {
|
|
opacity: 0.3;
|
|
cursor: default;
|
|
}
|
|
|
|
/* Same "author display wins over the UA [hidden] rule" gotcha as
|
|
.gpx-panel__action[hidden] elsewhere in this file. */
|
|
.measure-panel__save[hidden] {
|
|
display: none;
|
|
}
|
|
|
|
.measure-panel .notes-panel__form {
|
|
width: 200px;
|
|
}
|
|
|
|
/* ".measure-panel " prefix (not just ".measure-panel__mode") to outrank
|
|
".maplibregl-ctrl-group button" (higher specificity, since these buttons
|
|
sit inside a maplibregl-ctrl-group container for the ruler icon's own
|
|
sake) — its fixed 29x29 square + zero padding otherwise wins, clipping
|
|
"Distance"/"Area" into overlapping text instead of sizing to fit it. */
|
|
.measure-panel .measure-panel__mode {
|
|
width: auto;
|
|
height: auto;
|
|
display: inline-block;
|
|
white-space: nowrap;
|
|
padding: 4px 8px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
background: none;
|
|
font: inherit;
|
|
font-size: 12px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.measure-panel__mode:hover {
|
|
background: #f0f0f0;
|
|
}
|
|
|
|
.measure-panel__mode.active {
|
|
background: #dbe9ff;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.measure-panel__result {
|
|
min-width: 4em;
|
|
color: #333;
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
.measure-panel .measure-panel__clear {
|
|
width: auto;
|
|
height: auto;
|
|
display: inline-block;
|
|
border: none;
|
|
background: none;
|
|
font-size: 16px;
|
|
line-height: 1;
|
|
color: #888;
|
|
cursor: pointer;
|
|
padding: 0 2px;
|
|
}
|
|
|
|
.measure-panel__clear:hover {
|
|
color: #333;
|
|
}
|
|
|
|
.search-ctrl {
|
|
position: relative;
|
|
}
|
|
|
|
.search-ctrl__button svg {
|
|
display: block;
|
|
margin: 0 auto;
|
|
width: 18px;
|
|
height: 18px;
|
|
}
|
|
|
|
.search-ctrl__button.active {
|
|
background: #dbe9ff;
|
|
}
|
|
|
|
.search-panel {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 100%;
|
|
margin-left: 8px;
|
|
z-index: 20;
|
|
width: 240px;
|
|
background: #fff;
|
|
border: 1px solid #ddd;
|
|
border-radius: 6px;
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
padding: 6px 8px;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.search-panel[hidden] {
|
|
display: none;
|
|
}
|
|
|
|
.search-panel__input {
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
border: 1px solid #ccc;
|
|
border-radius: 4px;
|
|
padding: 5px 7px;
|
|
font: inherit;
|
|
}
|
|
|
|
.search-panel__results {
|
|
list-style: none;
|
|
margin: 6px 0 0;
|
|
padding: 0;
|
|
max-height: 220px;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.search-panel__result {
|
|
padding: 6px 4px;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.search-panel__result:hover {
|
|
background: #f0f0f0;
|
|
}
|
|
|
|
.search-panel__status {
|
|
padding: 6px 4px;
|
|
color: #888;
|
|
}
|
|
|
|
.notes-ctrl {
|
|
position: relative;
|
|
}
|
|
|
|
.notes-ctrl__button svg {
|
|
display: block;
|
|
margin: 0 auto;
|
|
width: 18px;
|
|
height: 18px;
|
|
}
|
|
|
|
.notes-ctrl__button.active {
|
|
background: #dbe9ff;
|
|
}
|
|
|
|
.notes-panel {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 100%;
|
|
margin-left: 8px;
|
|
z-index: 20;
|
|
width: 200px;
|
|
background: #fff;
|
|
border: 1px solid #ddd;
|
|
border-radius: 6px;
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
padding: 8px;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.notes-panel[hidden] {
|
|
display: none;
|
|
}
|
|
|
|
.notes-panel__modes {
|
|
display: flex;
|
|
gap: 4px;
|
|
margin-bottom: 6px;
|
|
}
|
|
|
|
.notes-panel__mode {
|
|
flex: 1;
|
|
width: auto;
|
|
height: auto;
|
|
padding: 4px 8px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
background: #f0f0f0;
|
|
font: inherit;
|
|
font-size: 12px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.notes-panel__mode.active {
|
|
background: #dbe9ff;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.notes-panel__hint {
|
|
margin: 0 0 6px;
|
|
color: #888;
|
|
}
|
|
|
|
.notes-panel__finish {
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
margin-bottom: 6px;
|
|
padding: 4px 8px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
background: #1a5fb4;
|
|
color: #fff;
|
|
font: inherit;
|
|
font-size: 12px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.notes-panel__form {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
}
|
|
|
|
/* Same "author display wins over the UA [hidden] rule" gotcha as
|
|
.gpx-panel__action[hidden] above — both this and .notes-panel__modes set
|
|
their own "display", so hiding them needs an explicit override too. */
|
|
.notes-panel__form[hidden],
|
|
.notes-panel__modes[hidden] {
|
|
display: none;
|
|
}
|
|
|
|
.notes-panel__title,
|
|
.notes-panel__body {
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
font: inherit;
|
|
font-size: 12px;
|
|
padding: 4px 6px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.notes-panel__title {
|
|
font-weight: 600;
|
|
}
|
|
|
|
.notes-panel__body {
|
|
resize: vertical;
|
|
}
|
|
|
|
.notes-panel__icons {
|
|
display: grid;
|
|
grid-template-columns: repeat(6, 1fr);
|
|
gap: 2px;
|
|
margin: 2px 0;
|
|
}
|
|
|
|
/* Same "author display wins over the UA [hidden] rule" gotcha as
|
|
.gpx-panel__action[hidden] elsewhere in this file. */
|
|
.notes-panel__icons[hidden] {
|
|
display: none;
|
|
}
|
|
|
|
.notes-panel__icon-option {
|
|
width: auto;
|
|
height: auto;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 3px;
|
|
border: 1px solid transparent;
|
|
border-radius: 4px;
|
|
background: none;
|
|
color: #555;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.notes-panel__icon-option svg {
|
|
width: 16px;
|
|
height: 16px;
|
|
}
|
|
|
|
.notes-panel__icon-option:hover {
|
|
background: #f0f0f0;
|
|
}
|
|
|
|
.notes-panel__icon-option.active {
|
|
border-color: #1a5fb4;
|
|
color: #1a5fb4;
|
|
background: #dbe9ff;
|
|
}
|
|
|
|
/* The pending-note marker shown on the map while the save form is open —
|
|
updates live to whatever icon is picked (see notes.js's onIconChange). A
|
|
plain round badge (not a drop-pin shape) since MapLibre anchors a custom
|
|
marker element at its center, and a pin's usual tip-points-at-the-spot
|
|
shape needs a bottom anchor to line up correctly. */
|
|
.notes-panel__preview-marker {
|
|
width: 26px;
|
|
height: 26px;
|
|
border-radius: 50%;
|
|
background: #c0392b;
|
|
border: 2px solid #fff;
|
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: #fff;
|
|
}
|
|
|
|
.notes-panel__preview-marker svg {
|
|
width: 15px;
|
|
height: 15px;
|
|
}
|
|
|
|
.notes-panel__target,
|
|
.notes-panel__new-name {
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
font: inherit;
|
|
font-size: 12px;
|
|
padding: 4px 6px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.notes-panel__actions {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 6px;
|
|
}
|
|
|
|
.notes-panel__actions button {
|
|
/* Without this, some browsers (GTK-themed Chrome on Linux in
|
|
particular) paint their own native hover/active highlight over a
|
|
button's background instead of leaving a custom one alone — the
|
|
Save button visibly went white on hover because of exactly this. */
|
|
appearance: none;
|
|
width: auto;
|
|
height: auto;
|
|
padding: 4px 10px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
background: #f0f0f0;
|
|
font: inherit;
|
|
font-size: 12px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
/* ".notes-panel__actions " prefix (not just ".notes-panel__save") to
|
|
outrank ".notes-panel__actions button" — same class-count-vs-class+
|
|
element specificity trap as elsewhere in this file; without it this
|
|
lost and the Save button just looked like a second Cancel button. */
|
|
.notes-panel__actions .notes-panel__save {
|
|
background: #1a5fb4;
|
|
color: #fff;
|
|
}
|
|
|
|
.zoom-level-ctrl__value {
|
|
width: 29px;
|
|
height: 29px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
color: #333;
|
|
user-select: none;
|
|
}
|
|
|
|
.pitch-toggle-ctrl__button {
|
|
width: 29px;
|
|
height: 29px;
|
|
font-size: 11px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.pitch-toggle-ctrl__button.active {
|
|
background: #dbe9ff;
|
|
}
|
|
|
|
.gpx-popup__header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 8px;
|
|
margin: -15px -10px 8px;
|
|
padding: 10px 12px;
|
|
background: #1a1a1a;
|
|
color: #fff;
|
|
}
|
|
|
|
.hiking-trail-popup__swatch {
|
|
flex-shrink: 0;
|
|
width: 14px;
|
|
height: 14px;
|
|
border-radius: 50%;
|
|
border: 1px solid rgba(255, 255, 255, 0.6);
|
|
}
|
|
|
|
.gpx-popup__header-icon {
|
|
flex-shrink: 0;
|
|
width: 18px;
|
|
height: 18px;
|
|
color: #fff;
|
|
}
|
|
|
|
.gpx-popup__header-icon svg {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.gpx-popup__time {
|
|
color: #888;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.gpx-popup__wiki {
|
|
margin-top: 6px;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.gpx-popup__category {
|
|
color: #888;
|
|
font-size: 12px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.02em;
|
|
}
|
|
|
|
.gpx-popup__description {
|
|
line-height: 1.4;
|
|
}
|
|
|
|
.gpx-popup__photos {
|
|
display: flex;
|
|
gap: 4px;
|
|
margin: 4px 0;
|
|
overflow-x: auto;
|
|
}
|
|
|
|
.gpx-popup__photo {
|
|
width: 64px;
|
|
height: 64px;
|
|
flex-shrink: 0;
|
|
object-fit: cover;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.gpx-popup__meta {
|
|
margin-top: 8px;
|
|
padding-top: 6px;
|
|
border-top: 1px solid #eee;
|
|
font-size: 12px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.gpx-popup__meta-row + .gpx-popup__meta-row {
|
|
margin-top: 2px;
|
|
}
|
|
|
|
.gpx-popup__meta-label {
|
|
color: #888;
|
|
margin-right: 4px;
|
|
}
|
|
|
|
.gpx-popup__tags {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 4px 10px;
|
|
margin-top: 2px;
|
|
}
|
|
|
|
.gpx-popup__tag {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 3px;
|
|
}
|
|
|
|
.gpx-popup__tag-icon {
|
|
display: flex;
|
|
width: 13px;
|
|
height: 13px;
|
|
color: #555;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.gpx-popup__tag-icon svg {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.gpx-popup__link {
|
|
margin-top: 6px;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.gpx-popup__note-actions,
|
|
.gpx-popup__edit-actions {
|
|
display: flex;
|
|
gap: 6px;
|
|
margin-top: 8px;
|
|
padding-top: 6px;
|
|
border-top: 1px solid #eee;
|
|
}
|
|
|
|
.gpx-popup__note-actions button,
|
|
.gpx-popup__edit-actions button {
|
|
border: none;
|
|
border-radius: 4px;
|
|
background: #f0f0f0;
|
|
padding: 3px 8px;
|
|
font: inherit;
|
|
font-size: 12px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.gpx-popup__edit-actions .gpx-popup__edit-save {
|
|
background: #1a5fb4;
|
|
color: #fff;
|
|
}
|
|
|
|
.gpx-popup__edit-title,
|
|
.gpx-popup__edit-body {
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
font: inherit;
|
|
font-size: 13px;
|
|
padding: 4px 6px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
margin-bottom: 6px;
|
|
}
|
|
|
|
.gpx-popup__edit-title {
|
|
font-weight: 600;
|
|
}
|
|
|
|
.gpx-popup__edit-body {
|
|
resize: vertical;
|
|
}
|
|
|
|
.gnss-control__status {
|
|
color: #888;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.gnss-marker {
|
|
width: 14px;
|
|
height: 14px;
|
|
border: 2px solid #fff;
|
|
border-radius: 50%;
|
|
background: #2a9d8f;
|
|
box-shadow: 0 0 0 2px rgba(42, 157, 143, 0.4);
|
|
}
|
|
|
|
.overlays-panel__list {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: 8px 12px;
|
|
}
|
|
|
|
.overlays-panel__item label {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 6px 4px;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.overlays-panel__item label:hover {
|
|
background: #f0f0f0;
|
|
}
|
|
|
|
.overlays-panel__icon {
|
|
display: flex;
|
|
width: 16px;
|
|
height: 16px;
|
|
flex-shrink: 0;
|
|
color: #555;
|
|
}
|
|
|
|
.overlays-panel__icon svg {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.overlays-panel__row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 6px 4px;
|
|
}
|
|
|
|
.overlays-panel__name {
|
|
border: none;
|
|
background: none;
|
|
padding: 0;
|
|
font: inherit;
|
|
color: inherit;
|
|
text-align: left;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.overlays-panel__name:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.overlays-panel__details {
|
|
margin: 0 4px 6px 26px;
|
|
padding-top: 6px;
|
|
border-top: 1px solid #eee;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.livetrack-panel__list {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: 8px 12px;
|
|
}
|
|
|
|
.livetrack-panel__item {
|
|
border-bottom: 1px solid #f0f0f0;
|
|
}
|
|
|
|
.livetrack-panel__row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
width: 100%;
|
|
padding: 6px 4px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
background: none;
|
|
font: inherit;
|
|
text-align: left;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.livetrack-panel__row:hover {
|
|
background: #f0f0f0;
|
|
}
|
|
|
|
.livetrack-panel__row.active {
|
|
background: #f1e6fb;
|
|
}
|
|
|
|
.livetrack-panel__row.loading {
|
|
opacity: 0.6;
|
|
cursor: wait;
|
|
}
|
|
|
|
.livetrack-panel__row:disabled {
|
|
opacity: 0.5;
|
|
cursor: default;
|
|
}
|
|
|
|
.livetrack-panel__label {
|
|
flex: 1;
|
|
min-width: 0;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.livetrack-panel__label--id {
|
|
font-family: monospace;
|
|
}
|
|
|
|
.livetrack-badge {
|
|
flex-shrink: 0;
|
|
padding: 2px 6px;
|
|
border-radius: 3px;
|
|
background: #e5e5e5;
|
|
color: #666;
|
|
font-size: 10px;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.02em;
|
|
}
|
|
|
|
.livetrack-badge--live {
|
|
background: #d7f3e3;
|
|
color: #1b7a43;
|
|
}
|
|
|
|
.livetrack-panel__time {
|
|
flex-shrink: 0;
|
|
color: #888;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.profile-panel {
|
|
position: fixed;
|
|
left: 52px;
|
|
right: 0;
|
|
bottom: 0;
|
|
max-height: 45vh;
|
|
display: flex;
|
|
flex-direction: column;
|
|
background: #fcfcfb;
|
|
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.15);
|
|
z-index: 10;
|
|
}
|
|
|
|
.profile-panel[hidden] {
|
|
display: none;
|
|
}
|
|
|
|
.profile-panel__header {
|
|
display: flex;
|
|
align-items: baseline;
|
|
gap: 10px;
|
|
padding: 10px 14px;
|
|
border-bottom: 1px solid #e1e0d9;
|
|
}
|
|
|
|
.profile-panel__title {
|
|
font-size: 14px;
|
|
}
|
|
|
|
.profile-panel__stats {
|
|
flex: 1;
|
|
min-width: 0;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
color: #52514e;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.profile-panel__close {
|
|
border: none;
|
|
background: none;
|
|
font-size: 18px;
|
|
line-height: 1;
|
|
padding: 0 4px;
|
|
cursor: pointer;
|
|
color: #898781;
|
|
}
|
|
|
|
.profile-panel__charts {
|
|
position: relative;
|
|
overflow-y: auto;
|
|
padding: 8px 14px 14px;
|
|
}
|
|
|
|
.profile-chart {
|
|
padding-top: 8px;
|
|
}
|
|
|
|
.profile-chart + .profile-chart {
|
|
border-top: 1px solid #e1e0d9;
|
|
}
|
|
|
|
.profile-chart__label {
|
|
font-size: 11px;
|
|
color: #898781;
|
|
margin-bottom: 2px;
|
|
}
|
|
|
|
.profile-chart__unit {
|
|
font-weight: normal;
|
|
}
|
|
|
|
.profile-chart__plot {
|
|
position: relative;
|
|
}
|
|
|
|
.profile-chart__svg {
|
|
display: block;
|
|
width: 100%;
|
|
height: 100%;
|
|
cursor: crosshair;
|
|
}
|
|
|
|
.profile-chart__crosshair {
|
|
stroke: #898781;
|
|
stroke-width: 1;
|
|
vector-effect: non-scaling-stroke;
|
|
}
|
|
|
|
/* Overlaid as plain HTML, not SVG text: the chart's viewBox scales width
|
|
and height independently (preserveAspectRatio="none", so the line fills
|
|
a responsive width at a fixed pixel height) — text drawn inside that
|
|
coordinate space would get stretched by the same mismatched factor. */
|
|
.profile-chart__axis-value {
|
|
position: absolute;
|
|
left: 4px;
|
|
color: #898781;
|
|
font-size: 10px;
|
|
line-height: 1;
|
|
background: rgba(252, 252, 251, 0.75);
|
|
padding: 1px 3px;
|
|
border-radius: 2px;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.profile-chart__axis-value--max {
|
|
top: 2px;
|
|
}
|
|
|
|
.profile-chart__axis-value--min {
|
|
bottom: 2px;
|
|
}
|
|
|
|
.profile-panel__xaxis-toggle {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 4px;
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
.profile-panel__xaxis-toggle-btn {
|
|
border: 1px solid #e1e0d9;
|
|
background: #fcfcfb;
|
|
color: #52514e;
|
|
font-size: 11px;
|
|
padding: 2px 8px;
|
|
border-radius: 3px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.profile-panel__xaxis-toggle-btn.active {
|
|
background: #0b0b0b;
|
|
border-color: #0b0b0b;
|
|
color: #fff;
|
|
}
|
|
|
|
.profile-panel__xaxis {
|
|
position: relative;
|
|
height: 14px;
|
|
margin-top: 6px;
|
|
}
|
|
|
|
.profile-panel__xaxis-tick {
|
|
position: absolute;
|
|
top: 0;
|
|
transform: translateX(-50%);
|
|
font-size: 10px;
|
|
color: #898781;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.profile-panel__xaxis-tick:first-child {
|
|
transform: translateX(0);
|
|
}
|
|
|
|
.profile-panel__xaxis-tick:last-child {
|
|
transform: translateX(-100%);
|
|
}
|
|
|
|
.profile-panel__tooltip {
|
|
position: absolute;
|
|
top: 0;
|
|
z-index: 1;
|
|
pointer-events: none;
|
|
background: #0b0b0b;
|
|
color: #fff;
|
|
border-radius: 4px;
|
|
padding: 6px 8px;
|
|
font-size: 12px;
|
|
white-space: nowrap;
|
|
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
|
|
}
|
|
|
|
.profile-panel__tooltip[hidden] {
|
|
display: none;
|
|
}
|
|
|
|
.profile-panel__tooltip-distance {
|
|
font-weight: 600;
|
|
margin-bottom: 2px;
|
|
}
|
|
|
|
.profile-panel__tooltip-label {
|
|
color: #c3c2b7;
|
|
}
|
|
|
|
.plugins-panel__hint {
|
|
margin: 0 0 6px;
|
|
max-width: 200px;
|
|
color: #888;
|
|
font-size: 11px;
|
|
}
|
|
|
|
.plugins-panel__list {
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
.plugins-panel__item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 4px 0;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.plugins-panel__label {
|
|
flex: 1;
|
|
}
|
|
|
|
.plugins-panel__run {
|
|
/* See .notes-panel__actions button's own comment — without this some
|
|
browsers paint their own hover/active highlight over a custom
|
|
background. */
|
|
appearance: none;
|
|
padding: 4px 10px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
background: #1a5fb4;
|
|
color: #fff;
|
|
font: inherit;
|
|
font-size: 12px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.plugins-panel__run:disabled {
|
|
opacity: 0.6;
|
|
cursor: default;
|
|
}
|
|
|
|
.plugins-panel__status {
|
|
min-width: 3.5em;
|
|
max-width: 200px;
|
|
color: #888;
|
|
font-size: 11px;
|
|
/* Overrides the parent's nowrap: "Running…"/"Done" never wrap either
|
|
way, but a real RunError message (e.g. "plugin exited with status 1")
|
|
needs to, or it just overflows the flyout unreadably. */
|
|
white-space: normal;
|
|
}
|
|
|
|
.plugins-panel__status--error {
|
|
color: #c62828;
|
|
}
|
|
|
|
.plugins-panel__empty {
|
|
color: #888;
|
|
white-space: normal;
|
|
max-width: 200px;
|
|
}
|