:root {
    --SCALE: 1;
    /* Surfaces */
    --BGCOLOR1: #F5F7FA;
    --BGCOLOR2: #D6DEE6;
    /* Brand (from logo): bright blue for fills, deeper blue for text/links on light */
    --BRAND: #0D93F5;
    --BRAND-DARK: #0A5FA0;
    --BRAND-SOFT: #7DBBEF;
    --ACCENT: #0A74C4;
    --INK: #14202B;
    --FS1: calc( 10px * var(--SCALE));
    --FS2: calc( 13px * var(--SCALE));
    --FS3: calc( 17px * var(--SCALE));
    /* Text */
    --TXTCOLOR1: #0A4A80;
    --TXTCOLOR2: #14181D;
    --TXTCOLOR3: #5B6772;
}

/* Dark palette: the light scheme inverted, keeping the blue-slate tint.
   Toggled by the Dark Mode setting (script.js adds class "dark" to <html>). */
:root.dark {
    --BGCOLOR1: #0F1720;
    --BGCOLOR2: #1B2733;
    --BRAND: #0D93F5;
    --BRAND-DARK: #0A5FA0;
    --BRAND-SOFT: #2E6FA8;
    --ACCENT: #0E7FD6;
    --INK: #070B10;
    --TXTCOLOR1: #8CCBFF;
    --TXTCOLOR2: #E3EAF0;
    --TXTCOLOR3: #9AABBB;
}

/* Logo: invert lightness but keep hue, so the blue ".uk" stays blue.
   Close icons are plain black glyphs, so a straight invert is enough. */
:root.dark .mlatLogo {
    filter: invert(1) hue-rotate(180deg);
}
:root.dark .infoblockCloseBox,
:root.dark .settingsCloseBox {
    filter: invert(1);
}

a, button, input, select, textarea, .svgButton {
    -webkit-tap-highlight-color: transparent;
}

html, body {
    -ms-overflow-style: -ms-autohiding-scrollbar;
    margin: calc( 0px * var(--SCALE));
    padding: calc( 0px * var(--SCALE));
    background: var(--BGCOLOR1);
    background-color: var(--BGCOLOR1);
    font-family: "Helvetica Neue", Helvetica, Verdana, sans-serif;
    font-size: var(--FS2);
    overflow: hidden;
    height: 100%;
    color: var(--TXTCOLOR2);
}

select {
    font-size: var(--FS2);
    height: calc(22px * var(--SCALE));
}

#planesTable {
    font-size: var(--FS2);
    white-space: nowrap;
    cursor: default;
    will-change: transform;
    transform: translateZ(0);
}

#layout_container {
    display: flex;
    height: 100%;
    position: relative;   /* the bottom sheet / sidebar anchor to the map area, not the page */
}

#selected_infoblock {
    position: absolute;
    left: 0px;
    bottom: 0px;
    width:  calc(180px * var(--SCALE));
    height: 100%;
    overflow: auto;
    z-index: 1;
    background-color: var(--BGCOLOR1);
    will-change: transform;
}
.aggregator-selected-bg:before {
    content: ' ';
    position:absolute;
    display:block;
    left:0;
    top:0;
    width:100%;
    height:100%;
    background-size: calc( 148 * var(--SCALE)) calc( 148 * var(--SCALE));
    background-repeat: no-repeat;
    background-position: calc( 7px * var(--SCALE)) calc( 108px * var(--SCALE));
    background-image: url("images/aggregator-logo.png");
    z-index:2;
    opacity: 0.12;
}
#infoblock-container {
    position:relative;
    overflow: auto;
    height: 100%;
    z-index:3;
}
#sidebar_canvas {
    padding: calc( 5px * var(--SCALE));
    overflow: auto;
}

#sidebar_container {
    display: flex;
    flex-direction: column;
    left: calc( 0px * var(--SCALE)) !important;
    height: 100%;
    will-change: transform;
}

#map_container {
    flex: 1 1 auto;
    position: relative;
    height: 100%;
}

#map_canvas {
    position: absolute;
    width: 100%;
    height: 100%;
}
#iconTestCanvas {
    position: absolute;
    width: 100%;
    height: 100%;
}

.sidebar_button {
    width: calc( 32px * var(--SCALE));
    height: calc( 38px * var(--SCALE));
    border-radius: calc( 2px * var(--SCALE));
    background-color: rgba(255,255,255,.2);

    cursor: pointer;
    background-size: calc( 26px * var(--SCALE)) calc( 30px * var(--SCALE));
    background-repeat: no-repeat;
    background-position: center;

    border: none;
}

#toggle_sidebar_button.show_sidebar {
    transform: scaleX(-1);
    background-image: url("images/hide_sidebar.png");
}

#toggle_sidebar_button.hide_sidebar {
    background-image: url("images/hide_sidebar.png");
}

#shrink_sidebar_button {
    background-image: url("images/hide_sidebar.png");
}

#expand_sidebar_button {
    transform: scaleX(-1);
    background-image: url("images/hide_sidebar.png");
}

#credits {
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0.8;
    position: absolute;
    bottom: calc( 10px * var(--SCALE));
    left: calc(50% - 60px * var(--SCALE));
}
.credits-text {
    font-size: var(--FS2);
}
.credits-image {
    display: block;
    width: calc( 24px * var(--SCALE));
    height: calc( 24px * var(--SCALE));
    background-size: calc( 24px * var(--SCALE)) calc( 24px * var(--SCALE));
    background-repeat: no-repeat;
    background-position: 0;
    background-color: transparent;
    border: none;
    background-image: url("images/aggregator-logo.png");
    z-index: 99;
    opacity: 0.7;
    margin: 4px;
}
.withOverflowingBackground::before {
   z-index: -1;
   background-image: url(https://www.exratione.com/assets/color_background.png);
}

#splitter {
    cursor: ew-resize;
    display: block;
    position: absolute;
    z-index: 99;
    top:  calc( 5px * var(--SCALE));
    left: calc( 0px * var(--SCALE));
    float: right;
    width: calc( 30px * var(--SCALE));
    height: calc( 30px * var(--SCALE));
    background-size: calc( 30px * var(--SCALE)) calc( 30px * var(--SCALE));
    background-repeat: no-repeat;
    background-color: transparent;
    border: none;
    background-image: url("images/toggle-width.png");
    background-size: cover;
    transform: scaleX(-1);
}

#splitter-infoblock {
    cursor: ns-resize;
    display: inline-block;
    position: absolute;
    top: calc( 0px * var(--SCALE));
    right: 0;
    margin-left: auto;
    width: 100%;
    height: calc( 4px * var(--SCALE));
    background-size: calc( 24px * var(--SCALE)) calc( 25px * var(--SCALE));
    background-repeat: no-repeat;
    background-position: calc( 0px * var(--SCALE));
    border: none;
    border-bottom: var(--BRAND-DARK);
    background-color: var(--BRAND);
    border-bottom-width: calc( 1px * var(--SCALE));
    border-bottom-style: solid;
}

/* remove the blue highlighting around the map buttons */
.ol-control button {
    outline: none;
    z-index: 999;
}

.ol-zoom-in {
    background-image: url("images/zoom-in.png");
    background-size: cover;
    color:transparent !important;
    width: calc( 25px * var(--SCALE)) !important;
    height: calc( 25px * var(--SCALE)) !important;
    background-color: transparent !important;
    margin-bottom: calc( 5px * var(--SCALE)) !important;
}

.ol-zoom-out {
    background-image: url("images/zoom-out.png");
    background-size: cover;
    color:transparent !important;
    width: calc( 25px * var(--SCALE)) !important;
    height: calc( 25px * var(--SCALE)) !important;
    background-color: transparent !important;
}

.ol-zoom {
    background-color: transparent !important;
    left: calc(100% - calc( 65px * var(--SCALE)));
    top: calc(100% - calc( 85px * var(--SCALE)));
}

.ol-attribution {
    font-size: var(--FS1);
}

.warning {
    margin-top: 1em;
    border: calc( 2px * var(--SCALE)) solid yellow;
    background-color: #FFFFA3;
    padding: calc( 5px * var(--SCALE));
    color: black;
}

.error_box {
    position: absolute; 
    bottom: calc( 90px * var(--SCALE)); 
    left: calc( 25px * var(--SCALE)); 
    border: calc( 2px * var(--SCALE)) solid red;
    background-color: #FFFFA3; 
    opacity: 0.75; 
    filter:alpha(opacity=75); 
    padding: calc( 5px * var(--SCALE));
    color: black;
    font-weight: bold;
    font-size: var(--FS3);
    line-height: 150%;
    text-align: center;
}

.inaccurate_warning {
    position: absolute; 
    top: calc( calc( 25px * var(--SCALE)) + var(--SAFE-T, 0px)); 
    left: calc( 280px * var(--SCALE));
    width: 50%;
    background-color: var(--BGCOLOR1);
    padding: calc( 5px * var(--SCALE));
}

#js_error {
    position: absolute;
    bottom: 5px;
    left: 5px;
    border: calc( 2px * var(--SCALE)) solid red;
    background-color: #FFFFA3; 
    opacity: 0.75; 
    filter:alpha(opacity=75); 
    padding: calc( 5px * var(--SCALE));
    color: black;
    font-size: var(--FS2);
    line-height: 150%;
    text-align: center;
    z-index: 999;
    white-space: pre-line;
}

/* Loading card (first load, coming back to the tab, heatmap): a plane circles the word. The <progress> inside is still the real one - the code
   sets its value and max for the heatmap - so it shows as a thin bar when it has a value, and as a sliding stripe when it has none. */
#loader { position: fixed; inset: 0; z-index: 9999; pointer-events: none; }
#loader.hidden { display: none; }
.loaderCard {
    position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);   /* centred whatever display the code gives #loader */
    display: flex; flex-direction: column; align-items: center; gap: 10px;
    min-width: 190px; padding: 18px 28px 16px;
    background: var(--BGCOLOR1); color: var(--TXTCOLOR2);
    border: 0.5px solid var(--BGCOLOR2); border-radius: 18px;
    box-shadow: 0 10px 34px rgba(0, 0, 0, 0.22);
    font-family: -apple-system, system-ui, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
    animation: loaderIn 0.25s ease-out;
}
.loaderOrbit { position: relative; width: 64px; height: 64px; }
.loaderTrack, .loaderSpin { position: absolute; inset: 0; width: 100%; height: 100%; }
.loaderTrack circle { fill: none; stroke: var(--ACCENT); stroke-opacity: 0.28; stroke-width: 1.6; stroke-dasharray: 2 5; stroke-linecap: round; }
.loaderSpin { animation: loaderOrbit 2.4s linear infinite; }
.loaderPlane { position: absolute; left: 50%; top: 0; width: 24px; height: 24px; margin: -3px 0 0 -12px; transform: rotate(90deg); fill: var(--ACCENT); stroke: var(--INK); stroke-width: 0.8; stroke-linejoin: round; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.35)); }
.loaderText { font-size: 15px; font-weight: 600; letter-spacing: 0.01em; }
.loaderDots i { font-style: normal; animation: loaderDot 1.2s ease-in-out infinite; }
.loaderDots i:nth-child(2) { animation-delay: 0.2s; }
.loaderDots i:nth-child(3) { animation-delay: 0.4s; }
#loader_progress { -webkit-appearance: none; appearance: none; width: 150px; height: 4px; border: 0; border-radius: 4px; overflow: hidden; background: var(--BGCOLOR2); color: var(--ACCENT); }
#loader_progress::-webkit-progress-bar { background: var(--BGCOLOR2); border-radius: 4px; }
#loader_progress::-webkit-progress-value { background: var(--ACCENT); border-radius: 4px; transition: width 0.3s ease; }
#loader_progress::-moz-progress-bar { background: var(--ACCENT); border-radius: 4px; }
#loader_progress:indeterminate { background: linear-gradient(90deg, var(--BGCOLOR2) 0%, var(--ACCENT) 50%, var(--BGCOLOR2) 100%) 0 0 / 200% 100%; animation: loaderSlide 1.3s linear infinite; }
#loader_progress:indeterminate::-webkit-progress-bar { background: transparent; }
@keyframes loaderOrbit { to { transform: rotate(360deg); } }
@keyframes loaderSlide { to { background-position: -200% 0; } }
@keyframes loaderDot { 0%, 80%, 100% { opacity: 0.25; } 40% { opacity: 1; } }
@keyframes loaderIn { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
    .loaderSpin, .loaderDots i, #loader_progress:indeterminate { animation: none; }
    .loaderCard { animation: none; }
}

.aircraft_table_header {
    background-color: var(--ACCENT);
    color: #FFFFFF;
    cursor: pointer;
    position: sticky;
    top: 0;
    z-index: 10;
    box-shadow: 0 -2px 2px -1px rgba(0, 0, 0, 0.5), 0 2px 2px -1px rgba(0, 0, 0, 0.7);
}
.aircraft_table_header td {
    font-size: smaller;
    padding: calc( 5px * var(--SCALE));
    text-align: center;
}

.verticalRateTriangle {
    font-family: "Courier New",monospace;
}

.icaoCodeColumn {
    font-family: monospace;
    text-transform: uppercase;
}

.plane_table_row {
    cursor: default;
    height: var(--FS2);
}

.hidden { display: none; }

.infoblock_heading a { text-decoration: none; color: blue; font-size: var(--FS2); }

.dim { opacity: 0.3; filter:alpha(opacity=30); }

.pointer { cursor: pointer; }

.sidebarButton {
    background-color: var(--ACCENT);
    padding: calc( 4px * var(--SCALE));
    color: #FFFFFF;
    font-weight: normal;
    font-size: var(--FS2);
}

.sidebarButton:hover {
    background-color: var(--BRAND-DARK);
}

.altitudeFilterInput {
    width: calc( 50px * var(--SCALE));
    height: calc( 15px * var(--SCALE));
    color:var(--TXTCOLOR2);
    background-color: var(--BGCOLOR2);
    border-color: var(--BGCOLOR1);
}
.searchInput {
    width: calc(100px * var(--SCALE));
    height: calc(15px * var(--SCALE));
    color:var(--TXTCOLOR2);
    background-color: var(--BGCOLOR2);
    border-color: var(--BGCOLOR1);
}

.formButton {
    font-size: var(--FS2);
    color:var(--TXTCOLOR2);
    background-color: var(--BGCOLOR2);
    border-color: var(--BGCOLOR1);
}
.formButton:disabled {
    color:var(--TXTCOLOR3);
}

select.error, textarea.error, input.error {
    color: #FF0000;
}

.layer-switcher button {
    background-size: calc( 26px * var(--SCALE)) calc( 26px * var(--SCALE));
    background-repeat: no-repeat;
    background-position: center;
    width: calc( 30px * var(--SCALE));
    height: calc( 30px * var(--SCALE));
}
.layer-switcher.shown .panel {
    overflow-y: auto;
    height: 95vh;
}

.dateTime {
    font-weight: bold;
    font-size: calc( 12px * var(--SCALE));
    line-height: calc( 26px * var(--SCALE));
    color: #FFFFFF;
    text-align: right;
    display: inline-block;
    padding-right: calc( 20px * var(--SCALE));
    padding-left: calc( 20px * var(--SCALE));
}

@media screen and (max-width: 1000px) {
    .dateTime {
        display: none;
    }
}

.sectionTitle {
    width: 100%;
    text-transform: uppercase;
    text-align: center;
    color: #E8EEF4;
    background: var(--INK);
}

.section-title-content {
    padding: calc( 3px * var(--SCALE)) calc( 20px * var(--SCALE));
}

.legend {
    font-size: 110%;
    color:var(--TXTCOLOR2);
    display: flex;
    flex-wrap: wrap;
    padding-top: calc( 10px * var(--SCALE));
}

.settingsText {
    font-size: calc( 14px * var(--SCALE));
    line-height: calc( 20px * var(--SCALE));
}

.link, .link a {
    color: var(--TXTCOLOR1);
    text-decoration: underline;
}

#header_side {
    position: absolute;
    right: calc( 0px * var(--SCALE));
    top: calc( calc( 0px * var(--SCALE)) + var(--SAFE-T, 0px));
    width: calc( 38px * var(--SCALE));
    z-index: 9;
}

.svgButton {
    background-color: var(--ACCENT);
    width: calc( 27px * var(--SCALE));
    height: calc( 27px * var(--SCALE));
    cursor: pointer;
    background-position: center;
    background-repeat: no-repeat;
    margin: calc( 2px * var(--SCALE));
    display: inline-block;
    border-radius: calc( 2px * var(--SCALE));
    position: relative;
}

.fullscreenButton {
    background-image: url('images/fullscreen.svg');
    background-size: 90%;
}

.settingsCog {
    background-image: url('images/cog-white.svg');
    background-size: 120%;
}

.replayButton {
    background-image: url('images/replay-white.svg');
    background-size: 120%;
}


.button {
    background-color: var(--ACCENT);
    width: calc( 27px * var(--SCALE));
    height: calc( 27px * var(--SCALE));
    border-radius: calc( 2px * var(--SCALE));
    margin: calc( 2px * var(--SCALE));
    display: inline-block;
    cursor: pointer;
    text-align: center;
    background-clip: padding-box;
}

.buttonContainer {
    display: block;
    margin: calc( 1px * var(--SCALE));
    text-align: center;
}
.buttonSpacer {
    margin: calc( 9px * var(--SCALE));
}

.buttonText {
    font-weight: bold;
    font-size: calc( 15px * var(--SCALE));
    line-height: calc( 27px * var(--SCALE));
    text-align: center;
    margin: calc( 5px * var(--SCALE));
}

.activeButton {
 color:#000
}
.inActiveButton {
 color:#fff
}

#highlighted_infoblock {
    background-color: var(--BGCOLOR1);
    position: absolute;
    left: calc( 40px * var(--SCALE));
    top: calc( calc( 60px * var(--SCALE)) + var(--SAFE-T, 0px));
    min-width: calc(132px * var(--SCALE));
    padding-right: calc( 5px * var(--SCALE));
    box-shadow: calc( 4px * var(--SCALE)) calc( 4px * var(--SCALE)) calc( 10px * var(--SCALE)) #444444;
    cursor: pointer;
    z-index: 998;   /* under the menus (1003) and the bars */
    display: none;
}

.highlightedTitle {
    border-bottom: calc( 1px * var(--SCALE)) solid var(--BRAND-SOFT);
    display: inline-block;
    width: 90%;
}

.identLarge {
    font-size: calc( 22px * var(--SCALE));
    line-height: calc( 24px * var(--SCALE));
    color: var(--TXTCOLOR1);
    font-weight: lighter;
}

.identMedium {
    font-size: calc( 17px * var(--SCALE));
    line-height: calc( 22px * var(--SCALE));
    color: var(--TXTCOLOR1);
    font-weight: lighter;
}

.identSmall {
    font-size: calc( 14px * var(--SCALE));
    font-weight: bold;
    color: var(--TXTCOLOR1);
}

.infoSectionTable {
    width: 100%;
    border-collapse: collapse;
    padding: 0;
    margin: 0;
    cursor: default;
}

table.infoSectionTable tr td {
    padding: 0;
    margin: 0;
}

.rSpacer {
    padding-top: calc( 3px * var(--SCALE));
    padding-bottom: calc( 3px * var(--SCALE));
}

.infoHeading {
    margin-top: calc( 2px * var(--SCALE));
    margin-bottom: calc( 2px * var(--SCALE));
    display: inline-block;
}

.infoHeading sub {
    font-weight: normal;
}

.infoData {
    margin-top: calc( 2px * var(--SCALE));
    margin-bottom: calc( 2px * var(--SCALE));
    float: right;
    text-align: right;
}

.infoBlockSection {
    padding: calc( 7px * var(--SCALE));
}

.largeText a, .largeText {
    font-weight: bold;
    color: var(--TXTCOLOR1);
    font-size: var(--FS3);
}

.infoBlockTitleText {
    font-weight: bold;
    color:var(--TXTCOLOR3);
}

.legendTitle {
    line-height: calc( 19px * var(--SCALE));
    padding-right: calc( 3px * var(--SCALE));
    padding-left: calc( 3px * var(--SCALE));
    margin: calc( 2px * var(--SCALE));
}

#settings_infoblock {
    position: fixed;
    top: calc( 1% + var(--SAFE-T, 0px));
    left: 1%;
    overflow: auto;
    max-height: calc( 90% - var(--SAFE-T, 0px));
    box-shadow: calc( 4px * var(--SCALE)) calc( 4px * var(--SCALE)) calc( 10px * var(--SCALE)) #444444;
    padding: calc( 20px * var(--SCALE));
    z-index: 9999;
    display: none;
    background-color: var(--BGCOLOR1);
}

.settingsColumn {
    display: table-cell;
    width: calc(199px * var(--SCALE));
}
.settingsOptionContainer {
    display: table;
    padding-top: calc( 3.5px * var(--SCALE));
    padding-bottom: calc( 3.5px * var(--SCALE));
}

.settingsCheckbox {
    width: calc( 12px * var(--SCALE));
    height: calc( 12px * var(--SCALE));
    background-size: calc( 12px * var(--SCALE)) calc( 12px * var(--SCALE));
    margin-left: calc( 5px * var(--SCALE));
    margin-right: calc( 5px * var(--SCALE));
    background-image: url('images/box-empty.png');
    background-repeat: no-repeat;
    background-position: center;
    cursor: pointer;
}

.settingsCheckboxChecked {
    background-image: url('images/box-checked.png') !important;
}

.settingsCloseBox {
    position: absolute;
    right: calc( 8px * var(--SCALE));
    top: calc( 8px * var(--SCALE));
    background-image: url('images/close-settings.png');
    background-size: cover;
    width: calc( 20px * var(--SCALE));
    height: calc( 20px * var(--SCALE));
    cursor: pointer;
}

#about_infoblock {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 90%;
    box-sizing: border-box;
    max-height: 90%;
    box-shadow: calc( 4px * var(--SCALE)) calc( 4px * var(--SCALE)) calc( 10px * var(--SCALE)) #444444;
    z-index: 9999;
    display: none;
    flex-direction: column;
    background-color: var(--BGCOLOR1);
    overflow: hidden;
}

.aboutHeader {
    position: relative;
    flex-shrink: 0;
    padding: calc( 20px * var(--SCALE)) calc( 20px * var(--SCALE)) calc( 10px * var(--SCALE));
    border-bottom: calc( 1px * var(--SCALE)) solid var(--BGCOLOR2);
}

.aboutBody {
    overflow-y: auto;
    padding: calc( 10px * var(--SCALE)) calc( 20px * var(--SCALE)) calc( 20px * var(--SCALE));
}

.aboutLogo {
    position: absolute;
    left: calc( 8px * var(--SCALE));
    top: calc( 8px * var(--SCALE));
    height: calc( 28px * var(--SCALE));
    width: auto;
}

.aboutTitle {
    font-size: var(--FS3);
    font-weight: bold;
    color: var(--TXTCOLOR1);
    text-align: center;
    margin-bottom: calc( 10px * var(--SCALE));
    padding-left: calc( 40px * var(--SCALE));
    padding-right: calc( 24px * var(--SCALE));
}

#about_infoblock hr {
    border: none;
    border-top: calc( 1px * var(--SCALE)) solid var(--BGCOLOR2);
    margin: calc( 10px * var(--SCALE)) 0;
}

.aboutSection {
    padding: calc( 6px * var(--SCALE)) 0;
}

.aboutText {
    color: var(--TXTCOLOR2);
    font-size: var(--FS2);
    line-height: 1.4;
    margin: 0;
}

.aboutSectionTitle {
    font-weight: bold;
    color: var(--TXTCOLOR3);
    font-size: var(--FS3);
    margin-bottom: calc( 6px * var(--SCALE));
}

.aboutIconRow {
    display: flex;
    align-items: center;
    gap: calc( 12px * var(--SCALE));
}
.aboutOutsideNetworkRow { margin-top: calc( 8px * var(--SCALE)); }

.aboutIcon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: calc( 34px * var(--SCALE));
    height: calc( 34px * var(--SCALE));
    flex-shrink: 0;
}

.aboutIcon svg {
    width: 100%;
    height: 100%;
}

.aboutIconTable {
    width: 100%;
    border-collapse: collapse;
}

.aboutIconTable td {
    padding: calc( 6px * var(--SCALE)) 0;
    vertical-align: middle;
}

.aboutIconCell {
    width: calc( 44px * var(--SCALE));
    text-align: center;
}

.aboutIconCell .aboutIcon {
    margin: 0 auto;
}

.aboutDescriptorCell {
    color: var(--TXTCOLOR2);
    font-size: var(--FS2);
    padding-left: calc( 10px * var(--SCALE));
}

.aboutFootnote {
    color: var(--TXTCOLOR3);
    font-size: var(--FS1);
    font-style: italic;
    margin-top: calc( 4px * var(--SCALE));
}

.aboutLinkRow {
    text-align: center;
    margin-top: calc( 14px * var(--SCALE));
}

.infoblockCloseBox {
    position: absolute;
    right: calc( 20px * var(--SCALE));
    top: calc( 8px * var(--SCALE));
    background-image: url('images/close-settings.png');
    background-size: cover;
    width: calc( 20px * var(--SCALE));
    height: calc( 20px * var(--SCALE));
    cursor: pointer;
    z-index: 99;
}

.settingsText {
    line-height: calc( 20px * var(--SCALE));
    display: table-cell;
}

#altitude_chart {
    float: right;
    width: calc(100% - calc( 5px * var(--SCALE)));
    max-width: calc(800px * var(--SCALE));
    right: calc( 85px * var(--SCALE));
    bottom: calc( 35px * var(--SCALE));
    background-color: transparent !important;
}

#altitude_chart_button {
    background-size: cover;
    background-color: transparent;
    width: 100%;
    height: 0;
    padding: 0;
    padding-bottom: calc(100% * 56 / 1815);
}

#selected_flightaware_link a {
    background-color: var(--ACCENT);
    color: white;
    text-decoration: none;
    padding: calc( 4px * var(--SCALE));
    line-height: calc( 22px * var(--SCALE));
    border-radius: calc( 4px * var(--SCALE));
}
.bottom-info-container {
    padding-top: calc( 10px * var(--SCALE));
    padding-bottom: calc( 10px * var(--SCALE));
    text-align: center;
    color: var(--TXTCOLOR1);
    line-height: calc( 18px * var(--SCALE));
}
.bottom-info-container img {
    vertical-align: middle;
}
.bottom-info-container .bottom-info-text {
    vertical-align: middle;
    display: inline;
}

.ui-tabs {
    background-color: var(--BGCOLOR1);
}
.ui-tabs-nav {
    background-color: var(--BGCOLOR2);
}
.ui-tabs-panel {
    background-color: var(--BGCOLOR1);
}
.greyButton {
    background-color: var(--BGCOLOR2);
    cursor: pointer;
    padding: calc( 4px * var(--SCALE));
    width: 100%;
    border: none;
    text-align: left;
    outline: none;
    font-size: calc( 15px * var(--SCALE));
    font-weight: bold;
    color: var(--TXTCOLOR1);
}
.greyButton:after {
    content: '\02795\FE0E';
    float: right;
    margin-left: calc( 5px * var(--SCALE));
}
.greyButton.active:after {
    content: "\2796\FE0E";
}

.ui-tabs-nav li a:focus {
    outline: none;
}

.ui-tabs .ui-tabs-panel {
    padding: 1em 0.5em;
}
.ui-tabs .ui-tabs-nav {
    padding: 2px;
    margin: 1px;
    margin-bottom: 1px;
}
.ui-tabs .ui-tabs-nav li.ui-tabs-active {
    padding-bottom: 0px;
}
.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr {
    border-radius: 3px;
}

.buttonFilter {
    list-style-type: none;
    margin: 0;
    padding: 0;
    width: calc( 240px * var(--SCALE));
    cursor: pointer;
}

.ui-widget-content .ui-selectable .ui-selected {
    border-color: var(--BRAND);
}

.buttonFilter li {
    border-width: 2px;
    border-color: var(--BGCOLOR2);
    margin-right: 5px;
    margin-bottom: 5px;
    padding: 1px;
    float: left;
    width: calc( 85px * var(--SCALE));
    color:var(--TXTCOLOR2);
    font-size: var(--FS2);
    text-align: center;
}

#sortableColumns {
    list-style-type: none;
    margin: 0;
    padding: 0;
    max-width: calc( 2 * 130px * var(--SCALE));
}

#sortableColumns li {
    margin: 3px;
    padding: calc( 0px * var(--SCALE));
    float: left;
    width: calc( 120px * var(--SCALE));
    border-color: var(--ACCENT);
    background-color: var(--BGCOLOR2);
}
#copyrightInfo {
  position: relative;
  font-size: var(--FS1);
  text-align: center;
  min-height: 1.4em;   /* same height with or without a credit line */
}
#selected_photo{
  text-align: center;
  display: block;
}
/* One image box for every object: 171 x 114 (3:2), centred. Every image -
   aircraft, vessel or satellite - is zoomed to fill it and cropped evenly at
   the edges if its shape differs, so there are never bars at the sides.
   Fixed height means the panel no longer jumps as images load. */
#selected_photo #airplanePhoto {
  display: block;
  width: 171px !important;
  height: 114px;
  margin: 0 auto;
  object-fit: cover;
  object-position: center;
  border-radius: 4px;
  background: var(--BGCOLOR2);
}
#selected_photo > p {
  height: 114px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
}
#selected_photo a { display: block; }
/* In the bottom sheet the section table must span the sheet, or "centred"
   only means centred within a shrink-wrapped table. */
#reg_info .infoSectionTable {
  width: 100%;
}
.ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default, .ui-button, html .ui-button.ui-state-disabled:hover, html .ui-button.ui-state-disabled:active {
  background: var(--BGCOLOR1);
  border: none;
}
.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active, a.ui-button:active, .ui-button:active, .ui-button.ui-state-active:hover{
  background: var(--BRAND-DARK);
}
.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited, a.ui-button, a:link.ui-button, a:visited.ui-button, .ui-button {
  color:var(--TXTCOLOR2);
}
.ui-widget-header .ui-state-default, .ui-button, html .ui-button.ui-state-disabled:hover, html .ui-button.ui-state-disabled:active {
  color:var(--TXTCOLOR2);
}
.ui-widget-header, .ui-widget.ui-widget-content {
    border: none;
}
.ui-widget-content {
  color:var(--TXTCOLOR2);
}

.ui-slider {
    background-color: var(--BGCOLOR2);
}
.ui-slider .ui-slider-handle {
    background-color: var(--BRAND);
}

input {
  color:var(--TXTCOLOR1);
}
#histDatePicker {
  background: var(--BGCOLOR1);
}


tr.emergencyRow {
    animation: flashEmergencyRow 1.3s infinite;
}
@keyframes flashEmergencyRow {
    0%, 100% { background-color: #d40000; color: #fff; }
    50% { background-color: #500000; color: #fff; }
}

tr.emergencyRowAmber {
    animation: flashEmergencyRowAmber 1.3s infinite;
}
@keyframes flashEmergencyRowAmber {
    0%, 100% { background-color: #d48a00; color: #000; }
    50% { background-color: #503300; color: #fff; }
}

/* About box: data credit / disclaimer */
.aboutBody .mlat-disclaimer {
    font-size: var(--FS1);
    font-style: italic;
    line-height: 1.4;
    color: var(--TXTCOLOR3);
    text-align: center;
    margin: calc( 14px * var(--SCALE)) 0 0;
    padding-top: calc( 10px * var(--SCALE));
    border-top: calc( 1px * var(--SCALE)) solid var(--BGCOLOR2);
}
.aboutBody .mlat-disclaimer a {
    color: var(--TXTCOLOR1);
}

/* Sidebar support link - plain link, replaces the third-party
   Buy Me a Coffee widget script (which blocked page start-up). */
.supportLink {
    display: inline-block;
    padding: calc( 4px * var(--SCALE)) calc( 10px * var(--SCALE));
    border-radius: calc( 4px * var(--SCALE));
    background-color: var(--ACCENT);
    color: #FFFFFF;
    font-size: var(--FS2);
    font-weight: bold;
    text-decoration: none;
}
.supportLink:hover {
    background-color: var(--BRAND-DARK);
}

/* ---- Domain-aware info panel ------------------------------------------
   script.js sets domain-air / domain-vessel / domain-sat on #selected_infoblock.
   acOnly    = aircraft only (FMS, wind, air data, Mode S accuracy, KML, history)
   notSat    = aircraft and vessels, not satellites (receiver metrics, direction)
   notVessel = aircraft and satellites, not vessels (altitude, vertical rate)
   !important because some of these rows are also toggled inline by jQuery. */
#selected_infoblock.domain-vessel .acOnly,
#selected_infoblock.domain-sat .acOnly,
#selected_infoblock.domain-sat .notSat,
#selected_infoblock.domain-vessel .notVessel {
    display: none !important;
}

/* ---- Mobile bottom sheet ----------------------------------------------
   Narrow screens only: the info panel docks to the bottom of the map instead
   of covering its left side. Height is set by script.js (peek / half / full);
   the map view gets matching bottom padding so centring and Follow (F) use
   the uncovered area above the sheet. */
.sheetOnly {
    display: none;
}
#selected_infoblock.sheet {
    border-radius: calc( 12px * var(--SCALE)) calc( 12px * var(--SCALE)) 0 0;
    box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.35);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    z-index: 1001;
    transition: height 0.2s ease;
}
#selected_infoblock.sheet.sheetDragging {
    transition: none;              /* follow the finger exactly while dragging */
}
#selected_infoblock.sheet .sheetOnly {
    display: block;
}
#selected_infoblock.sheet #infoblock-container {
    flex: 1 1 auto;
    height: auto;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding-bottom: var(--SAFE-B);    /* last rows scroll clear of the home bar */
}
#sheetHandle {
    flex: 0 0 auto;
    padding: calc( 6px * var(--SCALE)) calc( 44px * var(--SCALE)) calc( 8px * var(--SCALE)) calc( 12px * var(--SCALE));
    cursor: pointer;
    touch-action: none;            /* swipe on the handle doesn't scroll the page */
    user-select: none;
    -webkit-user-select: none;
    border-bottom: calc( 1px * var(--SCALE)) solid var(--BGCOLOR2);
}
.sheetGrip {
    width: calc( 36px * var(--SCALE));
    height: calc( 4px * var(--SCALE));
    margin: 0 auto calc( 6px * var(--SCALE));
    border-radius: calc( 2px * var(--SCALE));
    background-color: var(--TXTCOLOR3);
    opacity: 0.6;
}
#sheetTitle {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
#sheetFacts {
    font-size: var(--FS2);
    color: var(--TXTCOLOR3);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* The sheet header already shows the name and key facts, so hide the panel's
   own title block (name repeated, hex, copy link) in sheet mode only. */
#selected_infoblock.sheet #infoblock-container > .highlightedTitle {
    display: none;
}
#selected_infoblock.sheet .infoblockCloseBox {
    top: calc( 10px * var(--SCALE));
    right: calc( 12px * var(--SCALE));
}
/* Mobile sheet open: zoom buttons and altitude bar are hidden behind the
   sheet (pinch-zoom still works); both come back when the sheet closes. */
html.sheetOpen .ol-zoom,
html.sheetOpen #altitude_chart {
    visibility: hidden;
}

/* Image box placeholder when no photo exists: representative outline
   (aircraft/satellite map shape, vessel class silhouette) + "no image" text. */
.photoPlaceholder {
    width: 171px;
    height: 114px;             /* same box as a photo */
    margin: 0 auto;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}
.photoPlaceholder svg {
    display: block;
    overflow: visible;         /* a few map shapes are cut tight to their outline; don't trim the stroke */
    margin: 0 auto 4px;
    max-width: 100%;
    max-height: 88px;
    height: auto;
    color: var(--TXTCOLOR2);   /* outline colour (stroke="currentColor") */
}
.photoPlaceholder .noImageText {
    font-size: 12px;
    color: var(--TXTCOLOR3);
}

/* Satellite orbital elements older than SAT_TLE_STALE_DAYS */
.satTleStale { color: #D9822B; font-weight: 600; }

/* Country flag in the mobile sheet header, left of the ID */
.sheetFlag {
    display: inline-block;
    width: 21px;
    height: 14px;
    margin-right: 7px;
    vertical-align: -1px;
    border-radius: 2px;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.15);
    object-fit: cover;
}
.sheetFlag[hidden] { display: none; }

/* Sheet header third line: route (aircraft, as cities) / destination (vessels) */
#sheetRoute {
    font-size: var(--FS2);
    color: var(--TXTCOLOR1);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-top: 1px;
}
#sheetRoute[hidden] { display: none; }
/* Flag before the callsign in the sidebar title */
.titleFlag {
    width: 24px;
    height: 16px;
    margin-right: 8px;
    vertical-align: 0;
}

/* Phones / narrow maps: the credits box is uncollapsible (the basemap requires
   visible attribution), so instead of spanning the whole bottom edge it stays
   right of the scale bar (whose right edge never passes ~140px) and wraps. */
@media (max-width: 800px) {
    /* altitude bar: fit between the left edge and the zoom buttons instead of
       full width shifted 85px left (which ran off the screen) */
    #altitude_chart {
        left: var(--EDGE-INSET);
        right: calc( 85px * var(--SCALE));
        width: auto;
    }
}

/* Touch screens (phones, tablets): no zoom buttons - pinch and double-tap
   zoom instead, as on other mobile maps. The altitude bar then takes the
   full width. Desktop (mouse/trackpad) keeps the stock tar1090 buttons.
   Note: the sheet rule above (html.sheetOpen) still hides the zoom buttons
   in a narrow desktop window, where they would poke out above the sheet. */
@media (hover: none) and (pointer: coarse) {
    .ol-zoom {
        display: none !important;
    }
    #altitude_chart {
        left: var(--EDGE-INSET);
        right: var(--EDGE-INSET);
        width: auto;
    }
}

/* Home-screen web app on iPhone (viewport-fit=cover): the page draws under the
   home bar and, in landscape, beside the camera notch. --SAFE-B lifts the
   bottom controls clear of the home bar (0 on other devices); the side insets
   keep the map and buttons out from behind the notch in landscape. */
:root {
    --SAFE-B: env(safe-area-inset-bottom, 0px);
    --SAFE-T: env(safe-area-inset-top, 0px);
}
body {
    box-sizing: border-box;
    padding-left: env(safe-area-inset-left, 0px);
    padding-right: env(safe-area-inset-right, 0px);
}
#sidebar_container {
    box-sizing: border-box;
    padding-bottom: var(--SAFE-B);
}

/* Installed iPhone app only */
@media (display-mode: standalone) {
    /* Bottom sheet header: extra side room so text clears the curved screen
       corners (the close box keeps its space on the right). */
    #selected_infoblock.sheet #sheetHandle {
        padding-left: calc( 20px * var(--SCALE));
        padding-right: calc( 52px * var(--SCALE));
    }
    #selected_infoblock.sheet #infoblock-container {
        padding-left: 8px;
        padding-right: 8px;
        box-sizing: border-box;
    }
}

/* "Install the app" prompt (script.js, installPrompt()): a small card at the
   top of the map, clear of the mobile bottom sheet and the notch. */
#installPrompt {
    position: fixed;
    top: calc( 10px + env(safe-area-inset-top, 0px));
    left: 50%;
    width: min(400px, calc(100% - 24px));
    transform: translate(-50%, -16px);
    opacity: 0;
    transition: transform 0.2s ease, opacity 0.2s ease;
    z-index: 1100;
    box-sizing: border-box;
    padding: 14px 14px 12px;
    border-radius: 14px;
    background: var(--BGCOLOR1);
    color: var(--TXTCOLOR2);
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.22), 0 0 0 1px rgba(0, 0, 0, 0.06);
    font-family: -apple-system, system-ui, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
    font-size: 14px;
    line-height: 1.4;
}
#installPrompt.installPromptIn {
    transform: translate(-50%, 0);
    opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
    #installPrompt { transition: none; }
}
#installPrompt .installHead {
    display: flex;
    align-items: center;
    gap: 12px;
}
#installPrompt .installIcon {
    width: 44px;
    height: 44px;
    border-radius: 10px;
    flex: 0 0 auto;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08);
}
#installPrompt .installTitles { flex: 1 1 auto; min-width: 0; }
#installPrompt .installTitle { font-weight: 600; font-size: 16px; }
#installPrompt .installSub { color: var(--TXTCOLOR3); font-size: 13px; }
#installPrompt .installClose {
    flex: 0 0 auto;
    width: 44px;                 /* 44pt minimum touch target (Apple HIG) */
    height: 44px;
    margin: -8px -8px -8px 0;
    border: 0;
    background: transparent;
    color: var(--TXTCOLOR3);
    font-size: 24px;
    line-height: 1;
    cursor: pointer;
}
#installPrompt .installText { margin: 10px 0 12px; }
#installPrompt .installShareIcon {
    vertical-align: -3px;
    color: var(--ACCENT);
}
#installPrompt .installActions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}
#installPrompt .installBtn {
    min-height: 40px;
    padding: 0 16px;
    border-radius: 20px;
    border: 0;
    background: transparent;
    color: var(--ACCENT);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}
#installPrompt .installBtnPrimary {
    background: var(--ACCENT);
    color: #ffffff;
}
#installPrompt .installBtn:focus-visible,
#installPrompt .installClose:focus-visible {
    outline: 2px solid var(--ACCENT);
    outline-offset: 2px;
}
:root.dark #installPrompt {
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.08);
}
/* first visit: the welcome tips above the install offer */
#installPrompt.welcome { width: min(420px, calc(100% - 24px)); }
#installPrompt .welcomeTips {
    list-style: none;
    margin: 12px 0 4px;
    padding: 0;
    display: grid;
    gap: 10px;
}
#installPrompt .welcomeTips li { display: flex; gap: 12px; align-items: flex-start; }
#installPrompt .welcomeTips b { display: block; color: var(--TXTCOLOR1); font-weight: 600; }
#installPrompt .welcomeIcon {
    flex: 0 0 auto;
    width: 34px;
    height: 34px;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--ACCENT);
    background: color-mix(in srgb, var(--ACCENT) 12%, transparent);
}
#installPrompt .installSep {
    padding-top: 10px;
    border-top: 0.5px solid color-mix(in srgb, var(--TXTCOLOR3) 30%, transparent);
}
#installPrompt .welcomeTips + .installActions { margin-top: 14px; }
#installPrompt .installLink {
    display: inline-flex;
    align-items: center;
    margin-right: auto;
    text-decoration: none;
}

/* Installed iPhone app (html.iosApp, set by the inline script in index.html) */
html.iosApp,
html.iosApp body {
    height: var(--APP-H, 100%);
}
/* Hover box + desktop sidebar title, in the same form as the mobile popup:
   flag + name, a one-line summary, then the route / destination. */
.summaryFacts {
    font-size: var(--FS2);
    color: var(--TXTCOLOR3);
    margin-top: 1px;
}
.summaryRoute {
    font-size: var(--FS2);
    color: var(--TXTCOLOR1);
}
.summaryRoute[hidden] { display: none; }
#highlighted_infoblock .highlightedTitle { padding-bottom: 3px; display: block; width: auto; }
#highlighted_infoblock .summaryFacts { white-space: nowrap; }  /* one row; the box widens to fit */
/* Hover box rows: only what the summary doesn't already say, per domain */
#highlighted_infoblock .hlNone { display: none !important; }
#highlighted_infoblock:not(.hl-air) .hlAir,
#highlighted_infoblock:not(.hl-vessel) .hlVessel,
#highlighted_infoblock:not(.hl-sat) .hlSat,
#highlighted_infoblock.hl-sat .notSatHl {
    display: none !important;
}

/* ===== App shell ============================================================
   One layout for desktop, mobile browser and the installed app, following
   Apple's HIG: a solid top bar (menu, search, logo), the map filling the
   rest of the screen to the bottom edge, and a floating pill of layer and
   filter switches. Settings and About open as full-screen sheets.
   The top bar spans the full width; the map and both desktop sidebars sit
   below it. The pill is centred on the map, beside the selected-object panel
   (--PANEL-L, set by script.js).
   Bottom of the map, from the edge up: scale bar and credits, the pill, then
   the altitude bar and zoom buttons. */
:root {
    --BAR-H: 50px;          /* top bar, below the status bar */
    --DOCK-BTN: 46px;
    --DOCK-H: calc( var(--DOCK-BTN) + 10px);
    /* side inset for the bottom corners: clear of the iPhone's rounded
       screen corners when there is a home bar (--SAFE-B > 0), 8px otherwise */
    --EDGE-INSET: max(8px, calc( var(--SAFE-B) * 0.65));
    /* bottom row (scale bar, credits): just above the home bar */
    --BASE-B: max(6px, calc( var(--SAFE-B) - 14px));
    /* --ATTR-H: credits height, measured in script.js (wraps on phones) */
    --DOCK-B: calc( var(--BASE-B) + max(var(--ATTR-H, 16px), 18px) + 6px);
    /* top of the pill: the altitude bar and zoom buttons sit above this */
    --DOCK-TOP: calc( var(--DOCK-B) + var(--DOCK-H));
    --PANEL-L: 0px;
    --DOCK-ON: #000000;
    --DOCK-OFF: #9AA3AD;
    --DOCK-BG: var(--BGCOLOR1);
    --DOCK-BG: color-mix(in srgb, var(--BGCOLOR1) 88%, transparent);
    --DOCK-ALERT-RED: #E53935;
    --DOCK-ALERT-AMBER: #F2A900;
    --DOCK-MIL: #2EAD4B;
    --DT: 1;                       /* iOS Text Size setting (script.js) */
}
:root.dark {
    --DOCK-ON: #FFFFFF;
    --DOCK-OFF: #5F6E7C;
}
@media (prefers-reduced-transparency: reduce) {
    :root { --DOCK-BG: var(--BGCOLOR1); }
}
/* tar1090's own button column: hidden, the menu rows click its buttons */
#header_side { display: none !important; }
html.kiosk { --BAR-H: 0px; --DOCK-H: 0px; }
html.kiosk #appBar, html.kiosk #appDock, html.kiosk #mapMenu { display: none !important; }

/* status bar colour for the installed iPhone app (see index.html) */
#statusBarSampler {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 1px;
    z-index: 10000;
    pointer-events: none;
    background-color: var(--BGCOLOR1);
}

/* --- touch behaviour ------------------------------------------------------ */
html { -webkit-tap-highlight-color: transparent; -webkit-text-size-adjust: 100%; }
button, [role="button"], .settingsCheckbox, .settingsText, select, .ui-slider-handle,
#sheetHandle, .formButton {
    touch-action: manipulation;           /* no double-tap zoom delay */
}
#appBar, #appDock, .mapMenu, #replayBar, #sheetHandle, .sheetBar,
.settingsOptionContainer, .aboutHeader, #map_canvas {
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;          /* no long-press callout */
}
#searchInput { -webkit-user-select: text; user-select: text; }
#selected_infoblock table, .aboutBody { -webkit-user-select: text; user-select: text; }

/* --- the page: top bar, then the map and sidebars to the very bottom ---------- */
#layout_container {
    margin-top: calc( var(--BAR-H) + var(--SAFE-T));
    height: calc(100% - var(--BAR-H) - var(--SAFE-T));
}

/* --- top bar ---------------------------------------------------------------- */
.appBar {
    position: fixed;
    z-index: 1002;
    top: 0;
    left: 0;
    right: 0;
    height: var(--BAR-H);
    padding: var(--SAFE-T) calc( 12px + env(safe-area-inset-right, 0px)) 0 calc( 12px + env(safe-area-inset-left, 0px));
    display: flex;
    align-items: center;
    gap: 12px;
    background: var(--BGCOLOR1);
    border-bottom: 0.5px solid var(--BGCOLOR2);
    box-shadow: 0 1px 0 rgba(0, 0, 0, 0.04);
    font-family: -apple-system, system-ui, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
    color: var(--TXTCOLOR2);
}
.appBarButton {
    flex: none;
    width: 44px;
    height: 44px;
    margin-left: -6px;
    border: 0;
    border-radius: 50%;
    padding: 0;
    background: none;
    color: var(--TXTCOLOR2);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}
.appBarButton svg {
    width: 24px;
    height: 24px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
}
.appBarButton[aria-expanded="true"] {
    background: color-mix(in srgb, var(--TXTCOLOR3) 14%, transparent);
}
.appSearch {
    position: relative;
    flex: 1 1 auto;
    min-width: 0;
    max-width: 560px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    gap: 10px;
}
/* Wider screens: the search box is centred over the map, on the same line
   as the bottom pill (--SEARCH-CX / --SEARCH-W, measured in script.js so it
   never runs into the menu button or the logo). Phones keep the field
   filling the bar between them. */
html:not(.phoneUI) .appSearch {
    position: absolute;
    top: var(--SAFE-T);
    left: var(--SEARCH-CX, 50%);
    width: var(--SEARCH-W, 560px);
    max-width: none;
    height: var(--BAR-H);
    margin: 0;
    transform: translateX(-50%);
}
.searchField {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 7px;
    height: 38px;
    padding: 0 6px 0 12px;
    border-radius: 19px;
    background: color-mix(in srgb, var(--TXTCOLOR3) 13%, var(--BGCOLOR1));
    border: 1px solid color-mix(in srgb, var(--TXTCOLOR3) 22%, transparent);
    cursor: text;
}
.searchField:focus-within {
    border-color: var(--ACCENT);
    background: var(--BGCOLOR1);
}
.searchField > svg {
    flex: none;
    width: 18px;
    height: 18px;
    fill: none;
    stroke: var(--TXTCOLOR3);
    stroke-width: 2.2;
    stroke-linecap: round;
}
#searchInput {
    flex: 1;
    min-width: 0;
    height: 100%;
    padding: 0;
    border: 0;
    outline: none;
    background: none;
    color: var(--TXTCOLOR2);
    font: inherit;
    font-size: max(16px, calc( 16px * var(--DT)));   /* 16px+: iOS never zooms in */
    -webkit-appearance: none;
    appearance: none;
}
#searchInput::placeholder { color: var(--TXTCOLOR3); opacity: 1; }
#searchInput::-webkit-search-cancel-button { display: none; }
.searchClear {
    flex: none;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
}
.searchClear[hidden] { display: none; }
.searchClear svg { width: 18px; height: 18px; }
.searchClear circle { fill: var(--TXTCOLOR3); opacity: 0.6; }
.searchClear path { stroke: var(--BGCOLOR1); stroke-width: 2; stroke-linecap: round; fill: none; }
.searchCancel {
    display: none;
    flex: none;
    min-height: 44px;
    padding: 0 2px;
    border: 0;
    background: none;
    color: var(--ACCENT);
    font: inherit;
    font-size: calc( 16px * var(--DT));
    cursor: pointer;
}
:root.dark .searchCancel { color: var(--TXTCOLOR1); }
.appLogo {
    flex: none;
    margin-left: auto;
    display: flex;
    align-items: center;
    height: 44px;
}
.appLogo img {
    height: 34px;
    width: auto;
    display: block;
}
/* phones: while searching, Cancel takes the logo's place (as in iOS) */
html.phoneUI .appBar {
    gap: 8px;
    padding-left: calc( 8px + env(safe-area-inset-left, 0px));
    padding-right: calc( 10px + env(safe-area-inset-right, 0px));
}
html.phoneUI .appLogo img { height: 28px; }

/* Live connection dot, top right of the logo (wsclient.js): green WebSocket, amber HTTP fallback, red offline. */
.appLogo { position: relative; }
.connDot {
    position: absolute;
    top: 1.5px;
    right: -4px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    --CONN: #9AA4AE;      /* resting colour: grey while connected and idle */
    --FLASH: #9AA4AE;     /* colour of the activity flash */
    background: var(--CONN);
    pointer-events: auto;
}
.connDot[data-state="ws"] { --FLASH: #2EBD59; }        /* green flash: streaming connection activity */
.connDot[data-state="poll"] { --FLASH: #F2A900; }      /* amber flash: JSON fetch (HTTP fallback) activity */
.connDot[data-state="offline"] { --CONN: #E53935; }    /* red: offline */
/* a 0.2 s hard flash on each data arrival (the on/off style of the emergency icon, dockIconFlash) */
.connDot.tx { animation: connFlash 0.2s linear 1; }
.connDot[data-state="connecting"] { animation: connBlink 1s steps(1, end) infinite; }
/* the halo (as on the counts above the pill, .dockCount) shows only during the green / amber flash */
@keyframes connFlash { from, to { background: var(--FLASH); box-shadow: 0 0 2px var(--DOCK-HALO, transparent), 0 0 4px var(--DOCK-HALO, transparent); } }
@keyframes connBlink { 50% { opacity: 0.35; } }
@media (prefers-reduced-motion: reduce) {
    .connDot.tx, .connDot[data-state="connecting"] { animation: none; }
}

/* First-visit data sync (searchcache.js): the search box fills left to right and is disabled until done. */
.searchField { position: relative; overflow: hidden; }
.searchField > *:not(.searchProgress) { position: relative; z-index: 1; }
.searchProgress {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 0;
    background: color-mix(in srgb, var(--ACCENT) 22%, transparent);
    transition: width 0.3s ease;
    pointer-events: none;
}
.searchField.searchLoading { cursor: progress; }
.searchField.searchLoading input::placeholder { color: var(--TXTCOLOR1); opacity: 1; }
html.phoneUI .appBar.searching .appLogo { display: none; }
html.phoneUI .appBar.searching .searchCancel { display: block; }

/* search results */
.searchDropdown {
    position: absolute;
    top: calc( 100% + 8px);
    left: 0;
    right: 0;
    min-width: 340px;
    z-index: 1003;
    background: var(--BGCOLOR1);
    border: 0.5px solid var(--BGCOLOR2);
    border-radius: 14px;
    box-shadow: 0 10px 34px rgba(0, 0, 0, 0.22);
    overflow: hidden;
}
.searchDropdown[hidden] { display: none; }
html.phoneUI .searchDropdown {
    position: fixed;
    top: calc( var(--BAR-H) + var(--SAFE-T) + 6px);
    left: 8px;
    right: 8px;
    min-width: 0;
}
/* five rows in view, the rest by scrolling; never taller than the space
   left above the on-screen keyboard (--VVH) */
.searchResults {
    max-height: min(calc( 5 * 72px), calc( var(--VVH, 100vh) - var(--BAR-H) - var(--SAFE-T) - 24px));
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
}
.searchResult {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    min-height: 56px;
    box-sizing: border-box;
    padding: 8px 14px;
    border: 0;
    border-bottom: 0.5px solid var(--BGCOLOR2);
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}
.searchResult[aria-selected="true"] {
    background: color-mix(in srgb, var(--ACCENT) 11%, transparent);
}
.searchIcon {
    flex: none;
    width: 34px;
    height: 34px;
    border-radius: 10px;
    background: color-mix(in srgb, var(--ACCENT) 14%, transparent);
    color: var(--ACCENT);
    display: flex;
    align-items: center;
    justify-content: center;
}
:root.dark .searchIcon { color: var(--TXTCOLOR1); }
.searchIcon .dockMask { width: 22px; height: 22px; }
.searchText { flex: 1; min-width: 0; }
.searchTitle {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: calc( 15px * var(--DT));
    font-weight: 600;
    color: var(--TXTCOLOR2);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.searchTitle img { flex: none; height: 0.8em; width: auto; border-radius: 2px; }
.searchTitle mark { background: none; color: var(--ACCENT); }
:root.dark .searchTitle mark { color: var(--TXTCOLOR1); }
.searchSub {
    display: block;
    font-size: calc( 13px * var(--DT));
    color: var(--TXTCOLOR3);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* "Show all N on the map": first row of the results */
.searchAll {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    min-height: 48px;
    box-sizing: border-box;
    padding: 8px 14px;
    border: 0;
    border-bottom: 0.5px solid var(--BGCOLOR2);
    background: none;
    color: var(--ACCENT);
    font: inherit;
    font-size: calc( 15px * var(--DT));
    font-weight: 600;
    text-align: left;
    cursor: pointer;
}
:root.dark .searchAll { color: var(--TXTCOLOR1); }
.searchAll svg {
    flex: none;
    width: 34px;
    height: 22px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.9;
    stroke-linejoin: round;
}
@media (hover: hover) { .searchAll:hover { background: color-mix(in srgb, var(--ACCENT) 11%, transparent); } }
/* while the map is filtered to the search: tinted field + "On map" tag */
.appSearch.filtering .searchField {
    border-color: var(--ACCENT);
    background: color-mix(in srgb, var(--ACCENT) 10%, var(--BGCOLOR1));
}
.searchFilterTag {
    flex: none;
    padding: 2px 8px;
    border-radius: 999px;
    background: var(--ACCENT);
    color: #fff;
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
}
.searchFilterTag[hidden] { display: none; }

/* the route line, as in the hover box and the selected header */
.searchRoute {
    display: block;
    font-size: calc( 13px * var(--DT));
    color: var(--TXTCOLOR1);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.searchAlso {
    flex: none;
    font-size: calc( 12px * var(--DT));
    font-weight: 500;
    color: var(--TXTCOLOR3);
}
.searchAlso mark { color: inherit; font-weight: 700; }
.searchHidden {
    flex: none;
    font-size: calc( 11px * var(--DT));
    color: var(--TXTCOLOR3);
    border: 1px solid var(--BGCOLOR2);
    border-radius: 6px;
    padding: 1px 6px;
}
.searchEmpty {
    padding: 18px 16px;
    color: var(--TXTCOLOR3);
    font-size: calc( 14px * var(--DT));
    text-align: center;
}

/* --- main menu (left) ------------------------------------------------------- */
.mapMenu {
    position: fixed;
    z-index: 1003;
    top: calc( var(--BAR-H) + var(--SAFE-T) + 6px);
    left: calc( 8px + env(safe-area-inset-left, 0px));
    width: 300px;
    max-width: calc(100% - 16px);
    max-height: calc(100% - var(--BAR-H) - var(--SAFE-T) - var(--DOCK-H) - var(--DOCK-B) - 10px);
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    box-sizing: border-box;
    padding: 0;
    background: var(--BGCOLOR1);
    color: var(--TXTCOLOR2);
    border: 0.5px solid var(--BGCOLOR2);
    border-radius: 14px;
    box-shadow: 0 10px 34px rgba(0, 0, 0, 0.22);
    font-family: -apple-system, system-ui, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
    font-size: calc( 15px * var(--DT));
    text-align: left;
    transform-origin: top left;
    animation: menuIn 0.18s cubic-bezier(0.2, 0.9, 0.25, 1);
}
.mapMenu[hidden], .menuPage[hidden] { display: none; }
@keyframes menuIn {
    from { opacity: 0; transform: scale(0.96); }
    to   { opacity: 1; transform: none; }
}
.menuPage { animation: pageIn 0.2s cubic-bezier(0.2, 0.9, 0.25, 1); }
.menuPage.back { animation-name: pageBack; }
@keyframes pageIn   { from { opacity: 0; transform: translateX(24px); }  to { opacity: 1; transform: none; } }
@keyframes pageBack { from { opacity: 0; transform: translateX(-24px); } to { opacity: 1; transform: none; } }
.mapMenuItem {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    min-height: 44px;
    box-sizing: border-box;
    padding: 6px 16px;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}
.mapMenuItem:focus-visible { background: var(--BGCOLOR2); outline: none; }
.mapMenuItem[hidden] { display: none; }
.mapMenuLabel { flex: 1; }
.mapMenuKey {
    color: var(--TXTCOLOR3);
    font-size: 12px;
    min-width: 1.4em;
    text-align: center;
}
.mapMenuChevron {
    flex: none;
    width: 14px;
    height: 14px;
    fill: none;
    stroke: var(--TXTCOLOR3);
    stroke-width: 2.4;
    stroke-linecap: round;
    stroke-linejoin: round;
}
/* iOS switch */
.mapMenuSwitch {
    flex: none;
    position: relative;
    width: 42px;
    height: 25px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--TXTCOLOR3) 30%, transparent);
    transition: background-color 0.15s ease;
}
.mapMenuSwitch::after {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 21px;
    height: 21px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
    transition: transform 0.15s ease;
}
.mapMenuItem[aria-checked="true"] .mapMenuSwitch { background: #34C759; }
.mapMenuItem[aria-checked="true"] .mapMenuSwitch::after { transform: translateX(17px); }
/* satellite filter sections: the row opens a list of its groups, and its switch sets them all */
.mapMenuCount { color: var(--TXTCOLOR3); font-size: 12px; font-variant-numeric: tabular-nums; }
.mapMenuExpand { transition: transform 0.15s ease; }
.mapMenuItem.open .mapMenuExpand { transform: rotate(90deg); }
.mapMenuItem.mixed .mapMenuSwitch { background: color-mix(in srgb, #34C759 45%, transparent); }
.mapMenuItem.mixed .mapMenuSwitch::after { transform: translateX(8px); }
.mapMenuItem.mapMenuSub { padding-left: 38px; }
.mapMenuDivider { height: 0.5px; margin: 6px 16px; background: var(--BGCOLOR2); }
@media (hover: none) and (pointer: coarse) {
    .mapMenuKey { display: none; }
}
/* mouse and trackpad: a denser list, as in macOS menus */
@media (hover: hover) and (pointer: fine) {
    .mapMenuItem { min-height: 34px; padding: 4px 14px; }
    .mapMenu { font-size: 14px; }
    .mapMenuSwitch { width: 34px; height: 20px; }
    .mapMenuSwitch::after { width: 16px; height: 16px; }
    .mapMenuItem[aria-checked="true"] .mapMenuSwitch::after { transform: translateX(14px); }
}
/* focus ring only for keyboard users */
.settingsCloseBox:focus, .sheetGrabber:focus { outline: none; }
.settingsCloseBox:focus-visible, .sheetGrabber:focus-visible { outline: 2px solid var(--ACCENT); outline-offset: 2px; }
.menuPage { padding: 6px 0; }
#menuPageLayers, #menuPageOptions { padding-top: 0; }
/* the Layers page's header stays put while the list scrolls under it */
.menuPageHead {
    position: sticky;
    top: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: 6px;
    min-height: 50px;
    padding: 0 12px 0 6px;
    background: var(--BGCOLOR1);
    border-bottom: 0.5px solid var(--BGCOLOR2);
    margin-bottom: 4px;
}
.menuBack {
    display: flex;
    align-items: center;
    gap: 2px;
    min-height: 44px;
    padding: 0 8px 0 4px;
    border: 0;
    background: none;
    color: var(--ACCENT);
    font: inherit;
    cursor: pointer;
}
:root.dark .menuBack { color: var(--TXTCOLOR1); }
.menuBack svg {
    width: 20px;
    height: 20px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2.4;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.menuPageTitle { flex: 1; font-weight: 600; }
/* the layer switcher, moved into the menu: always open, no button of its own */
.layer-switcher > button { display: none !important; }
.menuLayersHost .layer-switcher {
    position: static;
    float: none;
    background: none;
    border: 0;
    padding: 0;
}
.menuLayersHost .layer-switcher .panel {
    display: block;
    position: static;
    height: auto !important;
    max-height: none !important;
    margin: 0;
    padding: 0 8px 4px;
    border: 0 !important;
    background: none !important;
    overflow: visible;
    font-size: calc( 15px * var(--DT));
}
.menuLayersHost .layer-switcher li.layer {
    display: flex;
    align-items: center;
    min-height: 40px;
}
.menuLayersHost .layer-switcher input { width: 20px; height: 20px; margin-right: 10px; accent-color: var(--ACCENT); }
.menuLayersHost .layer-switcher label { flex: 1; cursor: pointer; }
.menuLayersHost .layer-switcher li.group > label {
    display: block;
    margin: 10px 0 2px;
    color: var(--TXTCOLOR3);
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

/* --- bottom pill ------------------------------------------------------------ */
.appDock {
    position: absolute;
    z-index: 1000;          /* the mobile object sheet (1001) covers it */
    bottom: var(--DOCK-B);
    left: calc( var(--PANEL-L) + (100% - var(--PANEL-L)) / 2);
    transform: translateX(-50%);
    display: flex;
    gap: 2px;
    padding: 5px;
    border-radius: 999px;
    background: var(--DOCK-BG);
    -webkit-backdrop-filter: blur(20px) saturate(180%);
    backdrop-filter: blur(20px) saturate(180%);
    border: 0.5px solid color-mix(in srgb, var(--TXTCOLOR3) 25%, transparent);
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.20), 0 1px 3px rgba(0, 0, 0, 0.10);
}
/* Object list tab: a half-pill on the right edge of the map, in the pill's
   material; "<" opens the list, ">" closes it */
.listTab {
    position: absolute;
    z-index: 1000;
    top: 12px;
    right: 0;
    width: 40px;
    height: 48px;
    padding: 0 0 0 4px;
    border: 0.5px solid color-mix(in srgb, var(--TXTCOLOR3) 25%, transparent);
    border-right: 0;
    border-radius: 24px 0 0 24px;
    background: var(--DOCK-BG);
    -webkit-backdrop-filter: blur(20px) saturate(180%);
    backdrop-filter: blur(20px) saturate(180%);
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.20), 0 1px 3px rgba(0, 0, 0, 0.10);
    color: var(--DOCK-ON);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: transform 0.12s ease;
}
.listTab svg {
    width: 22px;
    height: 22px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2.4;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.listTab:active { transform: scale(0.94); }
.listTab:focus-visible { outline: 2px solid var(--ACCENT); outline-offset: -2px; }
html.kiosk .listTab { display: none !important; }
@media (hover: hover) {
    .listTab:hover { background: color-mix(in srgb, var(--BGCOLOR1) 70%, var(--TXTCOLOR3)); }
}

/* Mobile sheet: minimised, the pill floats just above it (and the scale bar
   above the pill); at half or full height the sheet covers the pill. */
.appDock {
    transition: bottom 0.22s cubic-bezier(0.2, 0.9, 0.25, 1), opacity 0.15s ease;
}
html.sheetPeek .appDock {
    bottom: calc( var(--SHEET-PEEK-H, 0px) + 10px);
    z-index: 1002;                 /* above the sheet (1001) */
}
html.sheetOpen:not(.sheetPeek) .appDock {
    opacity: 0;
    pointer-events: none;
}
html.sheetPeek .ol-scale-line {
    bottom: calc( var(--SHEET-PEEK-H, 0px) + 10px + var(--DOCK-H) + 8px);
}
@media (prefers-reduced-motion: reduce) {
    .appDock { transition: none; }
}
.dockButton {
    position: relative;
    width: calc( var(--DOCK-BTN) + 8px);
    height: var(--DOCK-BTN);
    padding: 0;
    border: 0;
    border-radius: 999px;
    background: none;
    color: var(--DOCK-ON);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: color 0.15s ease, transform 0.12s ease, background-color 0.15s ease;
}
.dockButton:active { transform: scale(0.9); }
.dockButton:focus-visible { outline: 2px solid var(--ACCENT); outline-offset: -2px; }
.dockButton.inActiveButton { color: var(--DOCK-OFF); }
.dockButton svg {
    width: 26px;
    height: 26px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.9;
    stroke-linecap: round;
    stroke-linejoin: round;
    transform: translateY(0px);
}
.dockButton.activeButton svg { stroke-width: 2.2; }
/* Special / Alerts by step: grey when off, white (black on light) while highlighted, Home's blue once isolated */
.dockButton.isolating, .dockButton.isolating.activeButton { color: var(--ACCENT); }
:root.dark .dockButton.isolating, :root.dark .dockButton.isolating.activeButton { color: var(--TXTCOLOR1); }   /* the same blue as Home in each theme */
/* Home: the theme colour (the "you are here" tab) */
.dockHome {
    color: var(--ACCENT);
}
:root.dark .dockHome { color: var(--TXTCOLOR1); }
/* the domain icons are image files: masked so they take the button colour */
.dockMask {
    display: block;
    width: 28px;
    height: 28px;
    background-color: currentColor;
    -webkit-mask: var(--ICON) center / contain no-repeat;
    mask: var(--ICON) center / contain no-repeat;
    transform: translateY(0px);
}
.dockMaskAir   { --ICON: url('images/adsb-white.svg'); }
.dockMaskSea   { --ICON: url('images/ais-white.svg'); }
.dockMaskSpace { --ICON: url('images/satellite-white.svg'); }
/* counts on the pill (script.js, setDockCount): how many of each kind are on
   screen, always shown - just the number, in the icon's colour
   (black on, grey off),
   with the icons' soft halo so it reads on the glass. Only the emergency
   icon itself flashes, red (squawk) or amber. */
.dockCount {
    position: absolute;
    top: 1.5px;
    right: calc(50% - 16px);   /* right-aligned: longer numbers grow leftwards */
    color: currentColor;
    font: 700 11px/1 -apple-system, BlinkMacSystemFont, system-ui, "Segoe UI", Roboto, sans-serif;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
    white-space: nowrap;
    text-shadow: 0 0 2px var(--DOCK-HALO, transparent), 0 0 4px var(--DOCK-HALO, transparent);
    pointer-events: none;
}
/* labels under the pill icons: centred horizontally, 3px up from the bottom
   of each button - mirroring the count's 3px down from the top. Absolutely
   placed so the pill and buttons keep their current size. */
.dockLabel {
    position: absolute;
    bottom: 1.5px;
    left: 50%;
    transform: translateX(-50%);
    color: currentColor;
    font: 600 11px/1 -apple-system, BlinkMacSystemFont, system-ui, "Segoe UI", Roboto, sans-serif;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
    white-space: nowrap;
    text-shadow: 0 0 2px var(--DOCK-HALO, transparent), 0 0 4px var(--DOCK-HALO, transparent);
    pointer-events: none;
}
#E.emergencyAlert, #E.emergencyAlertAmber { --FLASH: var(--DOCK-ALERT-RED); }
#E.emergencyAlertAmber { --FLASH: var(--DOCK-ALERT-AMBER); }
#E.emergencyAlert svg, #E.emergencyAlertAmber svg {
    color: var(--FLASH);
    opacity: 1;
    stroke-width: 2.3;
    animation: dockIconFlash 1s steps(1, end) infinite;
}
@keyframes dockIconFlash { 50% { color: var(--DOCK-OFF); } }
@media (prefers-reduced-motion: reduce) {
    #E svg { animation: none !important; }
    .mapMenu, .menuPage { animation: none; }
}

/* --- bottom stack ------------------------------------------------------------- */
/* scale bar (left) and credits (right): the bottom row, inset from the
   rounded screen corners. The scale bar rises above the mobile sheet; the
   credits stay put and the sheet covers them. #map_canvas prefix: OpenLayers'
   own ".ol-attribution.ol-uncollapsible { bottom: 0 }" is more specific. */
.ol-scale-line {
    left: var(--EDGE-INSET);
    bottom: max(var(--BASE-B), calc( var(--SHEET-OFFSET, 0px) + 8px));
}
#map_canvas .ol-attribution {
    right: var(--EDGE-INSET);
    bottom: var(--BASE-B);
    /* never reaches the scale bar: --SCALE-R is its right edge (script.js) */
    max-width: min(50%, calc(100% - var(--SCALE-R, 130px) - var(--EDGE-INSET) - 8px));
    box-sizing: border-box;
}
/* altitude bar and zoom buttons: just above the pill */
#altitude_chart {
    bottom: calc( var(--DOCK-TOP) + 8px);
}
.ol-zoom {
    top: auto;
    bottom: calc( var(--DOCK-TOP) + 8px);
    right: var(--EDGE-INSET);
    left: auto;
}
#installPrompt { top: calc( var(--BAR-H) + var(--SAFE-T) + 10px); }
.inaccurate_warning { top: 10px; }

/* --- Settings and About: popups over a dimmed map ----------------------------- */
/* Desktop: a centred card, 90% of the window. Phones: a sheet from the
   bottom, stopping just below the status bar (iOS page sheet). Settings can
   also rest at half height. A tap on the dimmed map closes them. */
#settings_infoblock,
#about_infoblock {
    position: fixed;
    z-index: 9999;
    top: 5vh;
    bottom: 5vh;
    left: 0;
    right: 0;
    width: min(90vw, 1200px);
    max-width: none;
    max-height: none;
    transform: none;
    box-sizing: border-box;
    padding: 0;
    margin: 0 auto;
    overflow: hidden;
    border-radius: 16px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35), 0 0 0 0.5px rgba(0, 0, 0, 0.08);
    background: var(--BGCOLOR1);
    color: var(--TXTCOLOR2);
    font-family: -apple-system, system-ui, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
    animation: popIn 0.24s cubic-bezier(0.2, 0.9, 0.25, 1);
    transition: top 0.28s cubic-bezier(0.2, 0.9, 0.25, 1);
}
#about_infoblock { width: min(90vw, 820px); }
#settings_infoblock:focus, #about_infoblock:focus { outline: none; }
@keyframes popIn { from { opacity: 0; transform: scale(0.96); } to { opacity: 1; transform: none; } }
html.phoneUI #settings_infoblock,
html.phoneUI #about_infoblock {
    top: calc( var(--SAFE-T) + 4vh);
    bottom: 0;
    width: auto;
    border-radius: 16px 16px 0 0;
    box-shadow: 0 -6px 30px rgba(0, 0, 0, 0.25);
    animation: sheetUp 0.32s cubic-bezier(0.2, 0.9, 0.25, 1);
}
@keyframes sheetUp { from { transform: translateY(100%); } to { transform: none; } }
/* Settings, half height: the map stays visible above */
#settings_infoblock.sheetHalf,
html.phoneUI #settings_infoblock.sheetHalf {
    top: 50%;
}
/* dimmed map behind them (script.js adds it) */
.sheetBackdrop {
    position: fixed;
    inset: 0;
    z-index: 9998;
    background: rgba(0, 0, 0, 0.32);
    animation: fadeIn 0.2s ease;
}
.sheetBackdrop[hidden] { display: none; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
#settings_infoblock.sheetDragging,
#about_infoblock.sheetDragging { transition: none; }
.sheetBar {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 2;
    height: 56px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--BGCOLOR1);
    border-bottom: 0.5px solid var(--BGCOLOR2);
}
.sheetBarTitle {
    margin: 0;
    font-size: 17px;
    font-weight: 600;
    color: var(--TXTCOLOR2);
}
.sheetGrabber {
    position: absolute;
    top: 0;
    left: 0;
    right: 64px;
    height: 100%;
    cursor: grab;
    touch-action: none;
}
.sheetGrabber::before {
    content: '';
    position: absolute;
    top: 6px;
    left: calc(50% + 32px);
    width: 36px;
    height: 5px;
    margin-left: -18px;
    border-radius: 3px;
    background: var(--TXTCOLOR3);
    opacity: 0.45;
}
/* the exit button: a round X, as in iOS 26 */
#settings_infoblock .sheetBar .settingsCloseBox,
#about_infoblock .sheetBar .settingsCloseBox {
    position: absolute;
    top: auto;
    right: 14px;
    bottom: 10px;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--TXTCOLOR3) 18%, transparent);
    filter: none;
    cursor: pointer;
}
.sheetBar .settingsCloseBox::before,
.sheetBar .settingsCloseBox::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 14px;
    height: 2px;
    margin: -1px 0 0 -7px;
    border-radius: 1px;
    background: var(--TXTCOLOR2);
    transform: rotate(45deg);
}
.sheetBar .settingsCloseBox::after { transform: rotate(-45deg); }
/* 44pt hit area round the 34pt button */
.sheetBar .settingsCloseBox > i {
    position: absolute;
    inset: -5px;
}
.sheetBody {
    position: absolute;
    top: 56px;
    left: 0;
    right: 0;
    bottom: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    padding: 12px 20px calc( 24px + var(--SAFE-B));
    box-sizing: border-box;
}
.sheetBodyInner { max-width: 1120px; margin: 0 auto; }
/* Settings options flow into as many columns as fit, up to four */
#settingsColumns {
    column-width: 240px;
    column-count: 4;
    column-gap: 32px;
}
#settingsColumns .settingsColumn { display: contents; }
#settingsColumns .settingsOptionContainer { break-inside: avoid; }
#about_infoblock .sheetBodyInner { max-width: 760px; }
#about_infoblock .aboutHeader { border-bottom: 0; padding-top: 4px; }
#about_infoblock .aboutBody { overflow: visible; max-height: none; }
@media (prefers-reduced-motion: reduce) {
    #settings_infoblock, #about_infoblock, .sheetBackdrop { animation: none; transition: none; }
}

/* Settings rows: whole row is the target, iOS-sized boxes on touch screens */
#settings_infoblock .settingsOptionContainer { min-height: 36px; }
#settings_infoblock .settingsText { font-size: calc( 15px * var(--DT)); cursor: pointer; }
@media (hover: none) and (pointer: coarse) {
    #settings_infoblock .settingsOptionContainer { min-height: 44px; }
    .settingsCheckbox {
        width: 24px;
        height: 24px;
        background-size: 22px 22px;
        vertical-align: middle;
    }
    .ui-slider-horizontal { height: 8px; margin: 14px 12px; }
    .ui-slider-horizontal .ui-slider-handle {
        width: 28px;
        height: 28px;
        top: -11px;
        margin-left: -14px;
        border-radius: 50%;
    }
    select, input[type="text"], .formButton { font-size: 16px; min-height: 40px; }
    /* object panel close: bigger invisible hit area */
    .infoblockCloseBox::after { content: ''; position: absolute; inset: -10px; }
}

/* hover highlights for mouse and trackpad only (no sticky hover on touch) */
@media (hover: hover) {
    .appBarButton:hover { background: color-mix(in srgb, var(--TXTCOLOR3) 14%, transparent); }
    .searchResult:hover { background: color-mix(in srgb, var(--ACCENT) 11%, transparent); }
    .mapMenuItem:hover { background: var(--BGCOLOR2); }
    .dockButton:hover { background: color-mix(in srgb, var(--TXTCOLOR3) 12%, transparent); }
    .dockHome:hover { background: color-mix(in srgb, var(--ACCENT) 22%, transparent); }
    .sheetBar .settingsCloseBox:hover { background: color-mix(in srgb, var(--TXTCOLOR3) 28%, transparent); }
}

/* ===== Object list ============================================================
   The sidebar in the same style as the rest of the app: system type, a
   segmented control for Search / Filters / Columns, a plain list with hairline
   separators, the data source as a coloured stripe at the start of each row
   (legend chips show the same colours) and the selected row in the accent
   tint. */
#sidebar_container {
    background: var(--BGCOLOR1);
    border-left: 0.5px solid var(--BGCOLOR2);
    font-family: -apple-system, system-ui, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
    color: var(--TXTCOLOR2);
}
#sidebar_canvas { padding: 12px 12px 0; }
/* resize handle: a slim grab strip along the left edge */
#splitter {
    top: 0;
    bottom: 0;
    left: -4px;
    width: 9px;
    height: auto;
    background: none;
    transform: none;
}
#splitter::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 2px;
    width: 5px;
    height: 40px;
    margin-top: -20px;
    border-radius: 3px;
    background: var(--TXTCOLOR3);
    opacity: 0.35;
    transition: opacity 0.15s ease;
}
@media (hover: hover) { #splitter:hover::after { opacity: 0.7; } }
/* counts */
#sidebar-table .infoblock_heading td,
#sidebar-table .infoblock_body td {
    font-size: 13px;
    padding: 2px 0;
}
#sidebar-table .infoBlockTitleText { font-weight: 500; color: var(--TXTCOLOR3); }
/* Search / Filters / Columns: iOS segmented control */
#tabs.ui-tabs { background: none; border: 0; padding: 0; }
#tabs .ui-tabs-nav {
    display: flex;
    gap: 2px;
    margin: 12px 0 8px;
    padding: 2px;
    border: 0;
    border-radius: 9px;
    background: color-mix(in srgb, var(--TXTCOLOR3) 16%, transparent);
    list-style: none;
}
#tabs .ui-tabs-nav::before, #tabs .ui-tabs-nav::after { display: none; }
#tabs .ui-tabs-nav li {
    flex: 1;
    float: none;
    margin: 0;
    padding: 0;
    border: 0 !important;
    border-radius: 7px;
    background: none !important;
    white-space: nowrap;
}
#tabs .ui-tabs-nav li a {
    float: none;
    display: block;
    padding: 6px 4px;
    text-align: center;
    font-size: 13px;
    font-weight: 500;
    color: var(--TXTCOLOR2) !important;
}
#tabs .ui-tabs-nav li.ui-tabs-active {
    background: var(--BGCOLOR1) !important;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.16), 0 0 0 0.5px rgba(0, 0, 0, 0.04);
}
:root.dark #tabs .ui-tabs-nav li.ui-tabs-active { background: var(--BGCOLOR2) !important; }
#tabs .ui-tabs-panel { padding: 8px 2px; background: none; }
/* the list */
#planesTable {
    border-collapse: collapse;
    font-size: 13px;
    font-variant-numeric: tabular-nums;
}
.aircraft_table_header {
    background: var(--BGCOLOR1);
    color: var(--TXTCOLOR3);
    box-shadow: inset 0 -0.5px 0 var(--BGCOLOR2);
}
.aircraft_table_header td {
    padding: 8px 6px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    white-space: nowrap;
}
@media (hover: hover) { .aircraft_table_header td:hover { color: var(--TXTCOLOR2); } }
#planesTable tbody td {
    padding: 7px 6px;
    border-bottom: 0.5px solid var(--BGCOLOR2);
}
#planesTable tr.listRow > td:first-child {
    box-shadow: inset 4px 0 0 var(--src, transparent);
    padding-left: 10px;
}
#planesTable tr.listRow { cursor: pointer; }
@media (hover: hover) {
    #planesTable tr.listRow:hover { background-color: color-mix(in srgb, var(--TXTCOLOR3) 10%, transparent); }
}
#planesTable tr.listRow.rowSelected {
    background-color: color-mix(in srgb, var(--ACCENT) 18%, transparent);
}
.tableTruncatedNote {
    padding: 8px 6px !important;
    font-size: 12px;
    color: var(--TXTCOLOR3);
}
/* source legend: chips with a coloured dot */
.legend { gap: 6px; padding-top: 12px; font-size: 12px; }
.legend br { display: none; }
.legendTitle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 0;
    padding: 3px 10px 3px 8px;
    line-height: 18px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--TXTCOLOR3) 12%, transparent);
    color: var(--TXTCOLOR2);
}
.legendDot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
/* source / flag filters: rounded tiles */
.buttonFilter li { border-radius: 8px; }

/* ===== Zoom buttons (desktop) =================================================
   One rounded group in the bottom pill's material, with plain + and − glyphs
   in the pill's icon colour, instead of the old image buttons. */
.ol-zoom {
    display: flex;
    flex-direction: column;
    padding: 0 !important;
    border-radius: 14px !important;
    overflow: hidden;
    background: var(--DOCK-BG) !important;
    -webkit-backdrop-filter: blur(20px) saturate(180%);
    backdrop-filter: blur(20px) saturate(180%);
    border: 0.5px solid color-mix(in srgb, var(--TXTCOLOR3) 25%, transparent);
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.20), 0 1px 3px rgba(0, 0, 0, 0.10);
}
.ol-zoom .ol-zoom-in,
.ol-zoom .ol-zoom-out {
    width: 40px !important;
    height: 40px !important;
    margin: 0 !important;
    padding: 0;
    border: 0;
    border-radius: 0 !important;
    background: none !important;
    background-image: none !important;
    color: var(--DOCK-ON) !important;
    font: 300 24px/1 -apple-system, system-ui, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}
.ol-zoom .ol-zoom-in { border-bottom: 0.5px solid color-mix(in srgb, var(--TXTCOLOR3) 30%, transparent); }
.ol-zoom .ol-zoom-in:focus-visible,
.ol-zoom .ol-zoom-out:focus-visible { outline: 2px solid var(--ACCENT); outline-offset: -2px; }
.ol-zoom .ol-zoom-in:active,
.ol-zoom .ol-zoom-out:active { background: color-mix(in srgb, var(--TXTCOLOR3) 20%, transparent) !important; }
@media (hover: hover) {
    .ol-zoom .ol-zoom-in:hover,
    .ol-zoom .ol-zoom-out:hover { background: color-mix(in srgb, var(--TXTCOLOR3) 12%, transparent) !important; }
}

/* ===== Altitude key ===========================================================
   Just the colour bar, centred over the map above the pill, labelled on the
   bar itself (built by script.js). Hidden when no aircraft are on screen. */
#altitude_chart {
    position: absolute;
    float: none;
    left: calc( var(--PANEL-L) + (100% - var(--PANEL-L)) / 2) !important;
    right: auto !important;
    transform: translateX(-50%);
    width: min(520px, calc(100% - var(--PANEL-L) - 130px)) !important;
    max-width: none;
    margin: 0;
    padding: 0 !important;
    border: 0;
    border-radius: 999px !important;
    background: none !important;
    box-shadow: none;
    opacity: 0.7;                 /* a quiet key, not a control */
    pointer-events: none;
    transition: opacity 0.3s ease, visibility 0.3s;
}
html.noAirInView #altitude_chart { opacity: 0; visibility: hidden; }
#altitude_chart_button {
    display: block;
    width: 100%;
    height: auto !important;
    padding: 0 !important;
    margin: 0 !important;
    border: 0;
    background: none !important;
    cursor: default;
}
.altBar {
    position: relative;
    display: block;
    height: 18px;
    border-radius: 999px;
    font-family: -apple-system, system-ui, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
}
.altLabel {
    position: absolute;
    top: 0;
    transform: translateX(-50%);
    font-size: 11px;
    font-weight: 700;
    line-height: 18px;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    color: #fff;
    text-shadow: 0 0 3px rgba(0, 0, 0, 0.75), 0 0 1px rgba(0, 0, 0, 0.9);
}
.altLabel.altLast { transform: translateX(calc(-100% - 8px)); }
html.phoneUI #altitude_chart { width: min(520px, calc(100% - var(--EDGE-INSET) * 2)) !important; }
html.phoneUI .altBar { height: 20px; }
html.phoneUI .altLabel { font-size: 12px; line-height: 20px; }
html.phoneUI .altLabel.altMinor { display: none; }
@media (prefers-reduced-motion: reduce) { #altitude_chart { transition: none; } }

/* ===== Credits ================================================================
   Only what the data sources require (AISHub, OpenMapTiles, OpenStreetMap -
   see layers.js), as plain small text on the map: no box, a soft halo in the
   theme's background colour so it reads over any map. */
#map_canvas .ol-attribution {
    background: none !important;
    padding: 0 !important;
    border-radius: 0 !important;
}
#map_canvas .ol-attribution ul {
    margin: 0;
    padding: 0 !important;
    background: none !important;
    font-family: -apple-system, system-ui, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
    font-size: 10px !important;
    line-height: 1.35 !important;
    color: var(--TXTCOLOR2);
    text-align: right;
    text-shadow: 0 0 2px var(--BGCOLOR1), 0 0 4px var(--BGCOLOR1);
}
#map_canvas .ol-attribution li { display: inline; }
#map_canvas .ol-attribution li + li::before { content: '\00a0\00b7\00a0'; }
/* phones: one credit per line (AISHub, then the map data), each kept on its
   own single line - never wrapping into a third - within 60% of the width */
html.phoneUI #map_canvas .ol-attribution {
    max-width: min(60%, calc(100% - var(--SCALE-R, 130px) - var(--EDGE-INSET) - 8px));
}
html.phoneUI #map_canvas .ol-attribution li { display: block; white-space: nowrap; }
html.phoneUI #map_canvas .ol-attribution li + li::before { content: none; }
#map_canvas .ol-attribution a { color: inherit; text-decoration: none; }
@media (hover: hover) { #map_canvas .ol-attribution a:hover { text-decoration: underline; } }
#map_canvas .ol-attribution button { display: none; }

/* ===== Scale bar ==============================================================
   A plain ruler, no box. */
#map_canvas .ol-scale-line {
    background: none !important;
    padding: 0 !important;
}
#map_canvas .ol-scale-line-inner {
    border: 1.5px solid var(--TXTCOLOR2) !important;
    border-top: 0 !important;
    margin: 0 !important;
    font-family: -apple-system, system-ui, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
    font-size: 10px;
    font-weight: 600;
    line-height: 14px;
    color: var(--TXTCOLOR2) !important;
    text-shadow: 0 0 2px var(--BGCOLOR1), 0 0 4px var(--BGCOLOR1);
    box-shadow: 0 1px 0 color-mix(in srgb, var(--BGCOLOR1) 70%, transparent);
}

/* ===== Replay =================================================================
   A panel across the bottom of the map, in the app's sheet style. While it
   is open the whole bottom stack (credits, scale bar, pill, altitude key,
   zoom) moves up above it: --BASE-B starts from the top of the panel. */
html.replayOpen { --BASE-B: calc( var(--REPLAY-H, 150px) + 8px); }
#replayBar {
    position: absolute;
    z-index: 999;
    left: 0;
    right: 0;
    bottom: 0;
    width: auto;
    height: auto;
    min-height: 0;
    box-sizing: border-box;
    padding: 12px calc( 16px + env(safe-area-inset-right, 0px)) calc( 12px + var(--SAFE-B)) calc( 16px + env(safe-area-inset-left, 0px));
    background: var(--BGCOLOR1);
    color: var(--TXTCOLOR2);
    border-top: 0.5px solid var(--BGCOLOR2);
    border-radius: 16px 16px 0 0;
    box-shadow: 0 -6px 24px rgba(0, 0, 0, 0.18);
    font-family: -apple-system, system-ui, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
    font-size: 14px;
    animation: sheetUp 0.28s cubic-bezier(0.2, 0.9, 0.25, 1);
}
#replayBar p { margin: 0; }
.replayHead {
    display: flex;
    align-items: center;
    gap: 12px;
    max-width: 1100px;
    margin: 0 auto 10px;
}
#replayPlay {
    position: relative;
    flex: none;
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--ACCENT);
    color: #fff;
    cursor: pointer;
    transition: transform 0.12s ease;
}
#replayPlay:active { transform: scale(0.94); }
#replayPlay:focus-visible { outline: 2px solid var(--ACCENT); outline-offset: 3px; }
#replayPlay svg { width: 20px; height: 20px; fill: currentColor; }
/* both icons are in the button; the one that is not wanted shrinks away */
#replayPlay .icoPlay,
#replayPlay .icoPause {
    transform-origin: 12px 12px;
    transition: opacity 0.16s ease, transform 0.16s ease;
}
#replayPlay .icoPlay { transform: translateX(1px); }
#replayPlay[data-state="paused"] .icoPause,
#replayPlay[data-state="playing"] .icoPlay { opacity: 0; transform: scale(0.55); }
/* while playing, a soft ring spreads out from the button */
#replayPlay::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 50%;
    pointer-events: none;
    opacity: 0;
}
#replayPlay[data-state="playing"]::after { animation: replayPulse 1.8s ease-out infinite; }
@keyframes replayPulse {
    0%   { opacity: 0.7; box-shadow: 0 0 0 0 color-mix(in srgb, var(--ACCENT) 60%, transparent); }
    100% { opacity: 0;   box-shadow: 0 0 0 14px color-mix(in srgb, var(--ACCENT) 0%, transparent); }
}
@media (prefers-reduced-motion: reduce) {
    #replayPlay[data-state="playing"]::after { animation: none; }
    #replayPlay .icoPlay, #replayPlay .icoPause { transition: none; }
}
.replayTitle { flex: 1; min-width: 0; }
#replayTimeHint {
    font-size: 16px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.replayDates {
    font-size: 12px;
    color: var(--TXTCOLOR3);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
#replayLoading { flex: none; font-size: 12px; color: var(--TXTCOLOR3); }
#replayLoading:empty { display: none; }
/* exit: the round X used by Settings and About */
.replayClose {
    flex: none;
    position: relative;
    width: 34px;
    height: 34px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: color-mix(in srgb, var(--TXTCOLOR3) 18%, transparent);
    cursor: pointer;
}
.replayClose::before,
.replayClose::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 14px;
    height: 2px;
    margin: -1px 0 0 -7px;
    border-radius: 1px;
    background: var(--TXTCOLOR2);
    transform: rotate(45deg);
}
.replayClose::after { transform: rotate(-45deg); }
@media (hover: hover) { .replayClose:hover { background: color-mix(in srgb, var(--TXTCOLOR3) 28%, transparent); } }
.replayControls {
    display: grid;
    grid-template-columns: minmax(130px, 1fr) 2fr 2fr 1.5fr;
    gap: 6px 20px;
    align-items: end;
    max-width: 1100px;
    margin: 0 auto;
}
.replayField { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.replayLabel {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--TXTCOLOR3);
}
#replayDatepicker {
    box-sizing: border-box;
    width: 100%;
    height: 34px;
    padding: 0 10px;
    border: 1px solid color-mix(in srgb, var(--TXTCOLOR3) 25%, transparent);
    border-radius: 10px;
    background: color-mix(in srgb, var(--TXTCOLOR3) 10%, var(--BGCOLOR1));
    color: var(--TXTCOLOR2);
    font: inherit;
    font-size: 15px;
    font-variant-numeric: tabular-nums;
}
/* iOS-style sliders: thin track, round white thumb */
#replayBar .ui-slider-horizontal {
    height: 4px;
    margin: 15px 11px 15px;
    border: 0;
    border-radius: 2px;
    background: color-mix(in srgb, var(--TXTCOLOR3) 30%, transparent);
}
#replayBar .ui-slider-horizontal .ui-slider-handle {
    top: -9px;
    width: 22px;
    height: 22px;
    margin-left: -11px;
    border: 0;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 0 0.5px rgba(0, 0, 0, 0.1);
    cursor: grab;
}
#replayBar .ui-slider-handle:focus-visible { outline: 2px solid var(--ACCENT); outline-offset: 2px; }
/* phones: Date and Speed, then Hour and Minute */
html.phoneUI .replayControls { grid-template-columns: 1fr 1fr; }
html.phoneUI #replayTimeHint { font-size: 15px; }
@media (hover: none) and (pointer: coarse) {
    #replayBar .ui-slider-horizontal .ui-slider-handle { top: -12px; width: 28px; height: 28px; margin-left: -14px; }
    #replayDatepicker { height: 40px; font-size: 16px; }
    #replayPlay { width: 44px; height: 44px; }
    .replayClose { width: 40px; height: 40px; }
}

/* Object list resize handle: a wider strip and a bigger grip on touch
   screens, where the 9px desktop strip is too thin to catch with a finger */
@media (hover: none) and (pointer: coarse) {
    #splitter {
        left: -14px;
        width: 28px;
        touch-action: none;
    }
    #splitter::after {
        left: 10px;
        width: 8px;
        height: 64px;
        margin-top: -32px;
        border-radius: 4px;
        opacity: 0.55;
    }
}

/* ===== Search: multi-select and "What's nearby" ============================= */
.searchResult { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
.searchResult.multiOn { background: color-mix(in srgb, var(--ACCENT) 16%, transparent); }
.searchResult.multiOn .searchIcon { background: var(--ACCENT); }
.searchResult.multiOn .searchIcon .dockMask { display: none; }
.searchResult.multiOn .searchIcon::after {
    content: '';
    width: 12px;
    height: 7px;
    margin-top: -3px;
    border: solid #fff;
    border-width: 0 0 2.5px 2.5px;
    transform: rotate(-45deg);
}
.searchRadius {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 14px;
    border-bottom: 0.5px solid var(--BGCOLOR2);
    font-size: calc( 14px * var(--DT));
    color: var(--TXTCOLOR2);
}
.searchRadius[hidden] { display: none; }
.searchRadiusLabel { flex: none; color: var(--TXTCOLOR3); }
.searchRadius input { flex: 1; min-width: 0; accent-color: var(--ACCENT); height: 28px; }
.searchRadiusValue { flex: none; min-width: 52px; text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; }

/* wind particles: a canvas over the map (script.js), clicks pass through */
/* OpenLayers resets every canvas in its viewport ("all: unset"), so this
   needs the more specific selector */
.nightCanvas, .ol-viewport canvas.nightCanvas,
.auroraCanvas, .ol-viewport canvas.auroraCanvas,
.windCanvas, .ol-viewport canvas.windCanvas {
    display: block;
    position: absolute;
    top: 0;
    left: 0;
    /* in the map's own layer list (windLayer): stacking follows that order */
    pointer-events: none;
}
/* the map's own controls and overlays (zoom, popups) above the wind */
.ol-viewport > .ol-overlaycontainer,
.ol-viewport > .ol-overlaycontainer-stopevent { z-index: 2; }
.windCanvas[hidden], .ol-viewport canvas.windCanvas[hidden] { display: none; }

/* ===== Share toast */
.appToast {
    position: fixed; left: 50%; transform: translateX(-50%);
    top: calc(var(--SAFE-T, 0px) + var(--BAR-H, 52px) + 12px);
    z-index: 3000; max-width: min(90vw, 520px);
    padding: 8px 16px; border-radius: 999px;
    background: rgba(28, 28, 30, 0.88); color: #fff;
    font-size: 14px; line-height: 1.3; text-align: center;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
    pointer-events: none;
}
.appToast[hidden] { display: none; }
.mapMenuShare { width: 18px; height: 18px; stroke-width: 2; }

/* ===== Desktop flyout sub-menus */
.mapMenuFly {
    width: 300px;
    max-height: calc(100% - var(--BAR-H) - var(--SAFE-T) - 20px);
    animation: flyIn 0.14s cubic-bezier(0.2, 0.9, 0.25, 1);
    transform-origin: top left;
}
.mapMenuFly .menuPage { animation: none; }
.mapMenuFly .menuBack { display: none; }
.mapMenuFly .menuPageHead { min-height: 40px; padding: 0 14px; }
@keyframes flyIn { from { opacity: 0; transform: translateX(-6px); } to { opacity: 1; transform: none; } }
.mapMenuItem.flyOpen { background: var(--BGCOLOR2); }
html.kiosk #mapMenuFly { display: none !important; }

/* ===== One switch style: menu, layers, settings
   (knob drawn as a gradient so it works on <input> and <div> alike) */
:root { --swW: 42px; --swH: 25px; }
@media (hover: hover) and (pointer: fine) { :root { --swW: 34px; --swH: 20px; } }
.menuLayersHost .layer-switcher input[type="checkbox"],
#settings_infoblock .settingsOptionContainer > .settingsCheckbox,
#sortableColumns .settingsOptionContainer > .settingsCheckbox {
    -webkit-appearance: none; appearance: none;
    flex: none; order: 2;
    width: var(--swW) !important; height: var(--swH) !important;
    margin: 0 !important; padding: 0; border: 0;
    border-radius: 999px;
    background: radial-gradient(circle calc(var(--swH) / 2 - 2px) at calc(var(--swH) / 2) 50%, #fff calc(100% - 1px), transparent 100%) no-repeat,
                color-mix(in srgb, var(--TXTCOLOR3) 30%, transparent) !important;
    background-size: auto !important;
    box-shadow: none;
    cursor: pointer;
    transition: background-color 0.15s ease;
}
.menuLayersHost .layer-switcher input[type="checkbox"]:checked,
#settings_infoblock .settingsOptionContainer > .settingsCheckbox.settingsCheckboxChecked,
#sortableColumns .settingsOptionContainer > .settingsCheckbox.settingsCheckboxChecked {
    background: radial-gradient(circle calc(var(--swH) / 2 - 2px) at calc(100% - var(--swH) / 2) 50%, #fff calc(100% - 1px), transparent 100%) no-repeat,
                #34C759 !important;
    background-size: auto !important;
}
.menuLayersHost .layer-switcher input:focus-visible,
#settings_infoblock .settingsCheckbox:focus-visible { outline: 2px solid var(--ACCENT); outline-offset: 2px; }

/* ===== Layers page: rows as menu rows */
.menuLayersHost .layer-switcher .panel { padding: 0 0 4px !important; font-size: inherit; }
.menuLayersHost .layer-switcher ul { list-style: none; margin: 0 !important; padding: 0 !important; }
.menuLayersHost .layer-switcher li { margin: 0 !important; padding: 0; }
.menuLayersHost .layer-switcher li.layer {
    display: flex !important;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    padding: 0 16px;
    box-sizing: border-box;
}
@media (hover: hover) and (pointer: fine) { .menuLayersHost .layer-switcher li.layer { min-height: 34px; padding: 0 14px; } }
@media (hover: hover) { .menuLayersHost .layer-switcher li.layer:hover { background: var(--BGCOLOR2); } }
.menuLayersHost .layer-switcher li.layer label {
    display: block !important;
    order: 1; flex: 1;
    padding: 6px 0;
    color: var(--TXTCOLOR2);
    line-height: 1.3;
}
/* base maps pick one: a tick on the right, as iOS lists do */
.menuLayersHost .layer-switcher input[type="radio"] {
    -webkit-appearance: none; appearance: none;
    flex: none; order: 2;
    width: 18px; height: 18px; margin: 0 !important; border: 0;
    background: transparent;
    cursor: pointer;
}
.menuLayersHost .layer-switcher input[type="radio"]:checked {
    background: var(--ACCENT);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12.5l5 5L20 6.5'/%3E%3C/svg%3E") center / contain no-repeat;
            mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12.5l5 5L20 6.5'/%3E%3C/svg%3E") center / contain no-repeat;
}
:root.dark .menuLayersHost .layer-switcher input[type="radio"]:checked { background: var(--TXTCOLOR1); }
.menuLayersHost .layer-switcher li.group > label {
    margin: 0 !important;
    padding: 14px 16px 4px;
}
.menuLayersHost .layer-switcher li.group > button { display: none; }

/* ===== Settings: rows as menu rows */
#settings_infoblock .settingsOptionContainer {
    display: block;
    min-height: 44px;
    padding: 6px 0;
    box-sizing: border-box;
    border-bottom: 0.5px solid var(--BGCOLOR2);
}
@media (hover: hover) and (pointer: fine) { #settings_infoblock .settingsOptionContainer { min-height: 38px; } }
#settings_infoblock .settingsOptionContainer > .settingsText {
    order: 1; flex: 1; min-width: 0;
    color: var(--TXTCOLOR2);
    line-height: 1.3;
}
#settings_infoblock .settingsOptionContainer > label { flex: 1; }
#settings_infoblock .infoBlockTitleText { font-weight: 400; color: var(--TXTCOLOR2); }
#settings_infoblock select {
    -webkit-appearance: none; appearance: none;
    min-height: 32px;
    padding: 4px 30px 4px 12px;
    border: 0;
    border-radius: 8px;
    background: var(--BGCOLOR2) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 10l4 4 4-4'/%3E%3C/svg%3E") no-repeat right 8px center / 16px;
    color: var(--TXTCOLOR1);
    font: inherit;
    cursor: pointer;
}
#settings_infoblock input[type="text"], #settings_infoblock input[type="number"] {
    min-height: 32px;
    padding: 4px 10px;
    border: 0;
    border-radius: 8px;
    background: var(--BGCOLOR2);
    color: var(--TXTCOLOR1);
    font: inherit;
    box-sizing: border-box;
}
#settings_infoblock .formButton {
    min-height: 34px;
    padding: 6px 16px;
    border: 0;
    border-radius: 999px;
    background: var(--BGCOLOR2);
    color: var(--TXTCOLOR1);
    font: inherit;
    font-weight: 500;
    cursor: pointer;
}
@media (hover: hover) {
    #settings_infoblock .formButton:hover { background: color-mix(in srgb, var(--TXTCOLOR3) 28%, transparent); }
}
#settings_infoblock .settingsOptionContainer:has(> .settingsCheckbox),
#settings_infoblock .settingsOptionContainer:has(> select),
#settings_infoblock .settingsOptionContainer:has(> .formButton) {
    display: flex;
    align-items: center;
    gap: 12px;
}
#settings_infoblock .settingsOptionContainer .ui-slider { margin: 12px 10px 6px; }
/* ol-layerswitcher's own layout (absolute inputs, indents) undone in the menu */
.menuLayersHost .layer-switcher,
.menuLayersHost .layer-switcher.shown { padding: 0 !important; }
.menuLayersHost .layer-switcher li input {
    position: static !important;
    left: auto !important; top: auto !important;
    font-size: inherit;
}
.menuLayersHost .layer-switcher li label,
.menuLayersHost .layer-switcher li.group > label,
.menuLayersHost .layer-switcher li.layer-switcher-base-group > label {
    padding-left: 0 !important;
    padding-right: 0 !important;
    margin-top: 0 !important;
}
.menuLayersHost .layer-switcher li.group > label { padding: 14px 16px 4px !important; }
@media (hover: hover) and (pointer: fine) { .menuLayersHost .layer-switcher li.group > label { padding: 12px 14px 4px !important; } }

/* ===== Settings groups */
#settingsColumns .settingsGroup { break-inside: avoid; margin: 0 0 22px; }
#settingsColumns .settingsGroup[hidden] { display: none; }
.homeZoom { padding: 4px 0 2px; }
.menuSettingsHost .homeZoom { padding: 6px 16px 10px; }   /* the same inset as the other settings rows */
@media (hover: hover) and (pointer: fine) { .menuSettingsHost .homeZoom { padding: 4px 14px 10px; } }
/* the slider itself is the settings' own (.settingsSliderRow); a phone has no map to watch behind the page, so it keeps only the buttons */
html.phoneUI #settingsHomeZoom #homeZoomSlider { display: none !important; }
.menuSettingsHost .homeZoomSliderRow + .homeZoom { padding-top: 0; }
.homeZoomButtons { display: flex; justify-content: center; gap: 10px; margin: 10px 0 4px; }
/* Reset All Settings' tinted look in the accent colour instead of red, with the softer rounded-rectangle corners */
.homeZoomButtons .formButton {
    min-height: 34px;
    padding: 4px 16px;
    border: 0;
    border-radius: 10px;
    background: color-mix(in srgb, var(--ACCENT) 12%, transparent);
    color: var(--ACCENT);
    font: inherit;
    font-weight: 500;
    cursor: pointer;
}
.homeZoomHint { margin: 4px 0 0; font-size: 0.82em; color: var(--TXTCOLOR3); }
.settingsGroupTitle {
    margin: 0 0 2px;
    padding: 4px 0;
    color: var(--TXTCOLOR3);
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
#settingsColumns .settingsGroup > .settingsOptionContainer:last-child { border-bottom: 0; }
#settings_infoblock .settingsOptionContainer.settingsReset {
    display: flex;
    justify-content: center;
    margin: 4px 0 8px;
    padding-top: 16px;
    border-bottom: 0;
    border-top: 0.5px solid var(--BGCOLOR2);
}
#settings_infoblock .settingsReset .formButton { color: #FF3B30; }
.settingsSliders {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    column-gap: 32px;
    margin: 0 0 18px;
    padding-bottom: 10px;
    border-bottom: 0.5px solid var(--BGCOLOR2);
}
.settingsSliderRow { padding: 4px 0 6px; }
.settingsSliderRow > .settingsOptionContainer { display: flex; align-items: baseline; justify-content: space-between; }
.settingsSliderRow > .settingsOptionContainer > .settingsText { flex: 1; }
.settingsValue { order: 2; flex: none; font-variant-numeric: tabular-nums; opacity: 0.8; }
#settings_infoblock .settingsSliderRow > .settingsOptionContainer { min-height: 0; padding: 4px 0 0; border-bottom: 0; }
#settings_infoblock .settingsSliderRow > .ui-slider { margin: 12px 10px 4px; }
.rSpacer[hidden] { display: none; }

/* ===== Object list: Search / Filters / Columns panels */
#tabs table, #tabs tbody, #tabs tr, #tabs td { display: block; width: 100%; padding: 0; border: 0; }
#tabs form {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin: 0;
    padding: 10px 2px 12px;
    border-bottom: 0.5px solid var(--BGCOLOR2);
    font-size: 14px;
    color: var(--TXTCOLOR2);
}
#tabs form > .infoBlockTitleText, #tabs form .infoBlockTitleText {
    flex: 0 0 100%;
    margin: 0 0 2px;
    font-size: 12px;
    font-weight: 500;
    color: var(--TXTCOLOR3);
}
#tabs .searchInput, #tabs .altitudeFilterInput {
    flex: 1 1 0;
    min-width: 0;
    width: auto;
    height: 32px;
    box-sizing: border-box;
    padding: 0 10px;
    border: 0;
    border-radius: 8px;
    background: color-mix(in srgb, var(--TXTCOLOR3) 13%, transparent);
    color: var(--TXTCOLOR1);
    font: inherit;
    outline: none;
}
#tabs .altitudeFilterInput { flex: 1 1 60px; }
#tabs .searchInput:focus, #tabs .altitudeFilterInput:focus {
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--ACCENT) 55%, transparent);
}
#tabs .altitudeUnit { color: var(--TXTCOLOR3); font-size: 13px; }
#tabs .formButton {
    flex: none;
    height: 32px;
    padding: 0 14px;
    border: 0;
    border-radius: 999px;
    background: color-mix(in srgb, var(--ACCENT) 15%, transparent);
    color: var(--ACCENT);
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}
:root.dark #tabs .formButton { color: var(--TXTCOLOR1); background: color-mix(in srgb, var(--ACCENT) 35%, transparent); }
#tabs .formButton[type="button"], #tabs .formButton[id*="reset"], #tabs .formButton[id*="clear"] {
    background: color-mix(in srgb, var(--TXTCOLOR3) 14%, transparent);
    color: var(--TXTCOLOR2);
    font-weight: 500;
}
@media (hover: hover) {
    #tabs .formButton:hover { filter: brightness(0.94); }
}
/* source / flag chips, then their buttons on the right */
#tabs form td:has(> .formButton) { display: flex; justify-content: flex-end; gap: 6px; margin-top: 4px; }
#tabs .buttonFilter {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    width: auto;
    margin: 2px 0;
}
#tabs .buttonFilter li {
    float: none;
    width: auto;
    margin: 0;
    padding: 4px 12px;
    border: 2px solid transparent;
    border-radius: 999px;
    font-size: 13px;
    line-height: 18px;
}
#tabs .buttonFilter li.ui-selected { border-color: var(--ACCENT); box-shadow: 0 0 0 1px var(--BGCOLOR1) inset; }
:root.dark #tabs .buttonFilter li.ui-selected { border-color: var(--TXTCOLOR1); }
#tabs .warning { margin: 6px 2px; font-size: 13px; }
/* columns: two-up list of switches, drag to reorder */
#sortableColumns {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    column-gap: 16px;
    max-width: none;
    margin: 0;
    padding: 0 2px;
}
#sortableColumns li {
    float: none;
    width: auto;
    margin: 0;
    padding: 0;
    border: 0 !important;
    border-bottom: 0.5px solid var(--BGCOLOR2) !important;
    border-radius: 0;
    background: none !important;
    cursor: grab;
}
#sortableColumns li.ui-sortable-helper {
    background: var(--BGCOLOR1) !important;
    border-radius: 8px;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2);
    cursor: grabbing;
}
#sortableColumns .settingsOptionContainer {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 38px;
    padding: 0;
}
#sortableColumns .settingsText {
    order: 1; flex: 1; min-width: 0;
    font-size: 14px;
    color: var(--TXTCOLOR2);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#sortableColumns .settingsOptionContainer::before {
    content: '';
    order: 0;
    flex: none;
    width: 10px; height: 12px;
    opacity: 0.45;
    background: radial-gradient(circle, var(--TXTCOLOR3) 1.3px, transparent 1.6px) 0 0 / 5px 4px;
}
@media (hover: none) and (pointer: coarse) {
    #sortableColumns .settingsOptionContainer { min-height: 44px; }
    #tabs .searchInput, #tabs .altitudeFilterInput, #tabs .formButton { height: 38px; min-height: 0; font-size: 16px; }
}
/* settings: groups on a grid so their headings line up; the sliders use the same tracks */
#settingsColumns, .settingsSliders {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    column-gap: 32px;
    columns: auto;
    column-count: auto;
    align-items: start;
}
#settingsColumns .settingsGroup { margin: 0 0 22px; }

/* ===== Settings as a menu page */
#settings_infoblock { display: none !important; }
.mapMenuFly.flyWide { width: 340px; }
.menuSettingsHost { padding-bottom: 6px; }
.menuSettingsHost .settingsGroup { margin: 0; }
.menuSettingsHost .settingsGroup[hidden] { display: none; }
.menuSettingsHost .settingsGroupTitle {
    margin: 0;
    padding: 14px 16px 4px;
    color: var(--TXTCOLOR3);
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.menuSettingsHost .settingsOptionContainer {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    padding: 6px 16px;
    box-sizing: border-box;
    border: 0;
    color: var(--TXTCOLOR2);
}
@media (hover: hover) and (pointer: fine) {
    .menuSettingsHost .settingsOptionContainer { min-height: 34px; padding: 4px 14px; }
    .menuSettingsHost .settingsGroupTitle { padding: 12px 14px 4px; }
}
@media (hover: hover) { .menuSettingsHost .settingsOptionContainer:has(> .settingsCheckbox):hover { background: var(--BGCOLOR2); } }
.menuSettingsHost .settingsOptionContainer > .settingsText {
    order: 1; flex: 1; min-width: 0;
    font-size: inherit;
    line-height: 1.3;
    cursor: pointer;
}
.menuSettingsHost .settingsOptionContainer > label { flex: 1; }
.menuSettingsHost .infoBlockTitleText { font-weight: 400; color: var(--TXTCOLOR2); }
.menuSettingsHost .settingsOptionContainer > .settingsCheckbox {
    -webkit-appearance: none; appearance: none;
    flex: none; order: 2;
    width: var(--swW) !important; height: var(--swH) !important;
    margin: 0 !important; padding: 0; border: 0;
    border-radius: 999px;
    background: radial-gradient(circle calc(var(--swH) / 2 - 2px) at calc(var(--swH) / 2) 50%, #fff calc(100% - 1px), transparent 100%) no-repeat,
                color-mix(in srgb, var(--TXTCOLOR3) 30%, transparent) !important;
    background-size: auto !important;
    cursor: pointer;
}
.menuSettingsHost .settingsOptionContainer > .settingsCheckbox.settingsCheckboxChecked {
    background: radial-gradient(circle calc(var(--swH) / 2 - 2px) at calc(100% - var(--swH) / 2) 50%, #fff calc(100% - 1px), transparent 100%) no-repeat,
                #34C759 !important;
    background-size: auto !important;
}
.menuSettingsHost select {
    -webkit-appearance: none; appearance: none;
    min-height: 30px;
    padding: 3px 28px 3px 10px;
    border: 0;
    border-radius: 8px;
    background: var(--BGCOLOR2) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 10l4 4 4-4'/%3E%3C/svg%3E") no-repeat right 7px center / 15px;
    color: var(--TXTCOLOR1);
    font: inherit;
    cursor: pointer;
}
/* sliders: label above, slider below, inside Appearance */
.menuSettingsHost .settingsSliders { display: block; margin: 0; padding: 0; border: 0; }
.menuSettingsHost .settingsSliderRow { padding: 6px 16px 10px; border: 0 !important; }
@media (hover: hover) and (pointer: fine) { .menuSettingsHost .settingsSliderRow { padding: 4px 14px 8px; } }
.menuSettingsHost .settingsSliderRow > .settingsOptionContainer { min-height: 0; padding: 0; }
.menuSettingsHost .settingsSliderRow > .ui-slider { margin: 12px 9px 4px; }
.menuSettingsHost .ui-slider-horizontal { height: 4px; border: 0; border-radius: 2px; background: color-mix(in srgb, var(--TXTCOLOR3) 28%, transparent); }
.menuSettingsHost .ui-slider-horizontal .ui-slider-handle {
    top: -8px; width: 20px; height: 20px; margin-left: -10px;
    border: 0; border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
    cursor: grab;
}
@media (hover: none) and (pointer: coarse) {
    .menuSettingsHost .ui-slider-horizontal .ui-slider-handle { top: -12px; width: 28px; height: 28px; margin-left: -14px; }
}
/* Reset: last, centred, red */
.menuSettingsHost .settingsOptionContainer.settingsReset {
    justify-content: center;
    margin-top: 8px;
    padding-top: 12px;
    border-top: 0.5px solid var(--BGCOLOR2);
}
.menuSettingsHost .settingsReset .formButton {
    min-height: 32px;
    padding: 4px 16px;
    border: 0;
    border-radius: 999px;
    background: color-mix(in srgb, #FF3B30 12%, transparent);
    color: #FF3B30;
    font: inherit;
    font-weight: 500;
    cursor: pointer;
}

/* ===== Glass: top bar and bottom pill =======================================
   The map runs up under the top bar so the bar's blur has something to show;
   the view is padded by the same amount (applyViewPadding). The status-bar
   strip (--SAFE-T) stays solid, and #statusBarSampler keeps Safari's toolbar
   tint a flat colour - no gradient from the map showing through. */
:root {
    /* lighter tint and blur, crisper edge: Liquid Glass at a medium setting */
    --GLASS-BG: color-mix(in srgb, var(--BGCOLOR1) 30%, transparent);
    --GLASS-EDGE: rgba(255, 255, 255, 0.6);
    --GLASS-HI: rgba(255, 255, 255, 0.75);
    --GLASS-BLUR: blur(3px) saturate(170%) brightness(1.06);
    --BAR-SOLID: color-mix(in srgb, var(--TXTCOLOR3) 12%, var(--BGCOLOR1));
}
:root.dark {
    --GLASS-BG: color-mix(in srgb, var(--BGCOLOR1) 38%, transparent);
    --GLASS-EDGE: rgba(255, 255, 255, 0.16);
    --GLASS-HI: rgba(255, 255, 255, 0.2);
    --GLASS-BLUR: blur(3px) saturate(160%) brightness(0.9);
}
#map_canvas {
    top: calc( -1 * (var(--BAR-H) + var(--SAFE-T)));
    height: calc(100% + var(--BAR-H) + var(--SAFE-T));
    /* and on under the object list (--LIST-W, script.js), as it does under the
       details panel: the list then stops at the bar, with map behind the bar */
    /* always the full page width, so opening or closing the list never
       resizes (and re-renders) the map - the list just covers its edge */
    width: calc(100vw - env(safe-area-inset-left, 0px) - env(safe-area-inset-right, 0px));
}
#sidebar_container { position: relative; z-index: 2; }
.ol-zoom { right: calc( var(--EDGE-INSET) + var(--LIST-W, 0px)); }
#map_canvas .ol-attribution {
    right: calc( var(--EDGE-INSET) + var(--LIST-W, 0px));
    /* desktop: as wide as the credits need (one row), up to the scale bar */
    max-width: calc(100% - var(--LIST-W, 0px) - var(--SCALE-R, 130px) - var(--EDGE-INSET) - 8px);
}
html.phoneUI #map_canvas .ol-attribution {
    max-width: min(calc((100% - var(--LIST-W, 0px)) * 0.6), calc(100% - var(--LIST-W, 0px) - var(--SCALE-R, 130px) - var(--EDGE-INSET) - 8px));
}
.appBar {
    background: var(--GLASS-BG);
    -webkit-backdrop-filter: var(--GLASS-BLUR);
    backdrop-filter: var(--GLASS-BLUR);
    border-bottom: 0.5px solid color-mix(in srgb, var(--TXTCOLOR3) 22%, transparent);
    box-shadow: inset 0 -0.5px 0 var(--GLASS-HI), 0 4px 18px rgba(0, 0, 0, 0.08);
}
.appBar::before {                 /* status-bar strip: solid, never glass */
    content: '';
    position: absolute;
    left: 0; right: 0; top: 0;
    height: var(--SAFE-T);
    background: var(--BGCOLOR1);
    pointer-events: none;
}
.appDock, .listTab, .ol-zoom {
    --DOCK-BG: var(--GLASS-BG);
    -webkit-backdrop-filter: var(--GLASS-BLUR);
    backdrop-filter: var(--GLASS-BLUR);
    border-color: var(--GLASS-EDGE);
    box-shadow: inset 0 1px 0 var(--GLASS-HI), inset 0 -1px 0 rgba(0, 0, 0, 0.04),
                0 8px 28px rgba(0, 0, 0, 0.18), 0 1px 3px rgba(0, 0, 0, 0.10);
}
/* the search field stays solid on the glass */
.searchField { background: color-mix(in srgb, var(--TXTCOLOR3) 10%, var(--BGCOLOR1)); }
@media (prefers-reduced-transparency: reduce) {
    :root, :root.dark { --GLASS-BG: var(--BGCOLOR1); }
}
/* zoom buttons: the glass group, with clear buttons inside it */
.ol-zoom { background: var(--GLASS-BG) !important; border: 0.5px solid var(--GLASS-EDGE) !important; }
.ol-zoom button { background: transparent !important; }
/* pill icons on clear glass: a firmer "off" grey and a soft halo so they
   read over a busy map */
:root { --DOCK-OFF: #5E6873; --DOCK-HALO: rgba(255, 255, 255, 0.85); }
:root.dark { --DOCK-OFF: #A3AEB9; --DOCK-HALO: rgba(0, 0, 0, 0.7); }
.dockButton svg, .listTab svg, .ol-zoom button { filter: drop-shadow(0 0 1.5px var(--DOCK-HALO)); }
.dockButton.inActiveButton svg { opacity: 0.75; }

/* ===== Details panel: one look on phone and desktop =========================
   Desktop gets the phone sheet's header (name, facts, route) in a floating
   card; section titles on both are the menus' small grey headings. */
#selected_infoblock:not(.sheet) {
    top: 10px;
    left: 10px;
    bottom: 10px;
    height: auto !important;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border-radius: 16px;
    border: 0.5px solid color-mix(in srgb, var(--TXTCOLOR3) 22%, transparent);
    box-shadow: 0 10px 34px rgba(0, 0, 0, 0.22), 0 1px 3px rgba(0, 0, 0, 0.08);
}
#selected_infoblock:not(.sheet) #sheetHandle {
    display: block;
    flex: none;
    padding: 12px 44px 10px 14px;
    background: var(--BGCOLOR1);
    cursor: default;
}
#selected_infoblock:not(.sheet) .sheetGrip { display: none; }
#selected_infoblock:not(.sheet) #infoblock-container {
    flex: 1 1 auto;
    height: auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
}
#selected_infoblock:not(.sheet) #infoblock-container > .highlightedTitle { display: none; }
#selected_infoblock:not(.sheet) .infoblockCloseBox { top: 12px; right: 12px; z-index: 5; }
/* section titles: as in Settings and Layers */
#selected_infoblock .sectionTitle {
    background: none;
    color: var(--TXTCOLOR3);
    text-align: left;
    border-top: 0.5px solid var(--BGCOLOR2);
    margin-top: 6px;
}
#selected_infoblock .section-title-content {
    padding: 12px 12px 4px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.04em;
}
/* share, beside close: desktop card and phone sheet */
.infoblockShare { display: none; }
#selected_infoblock .infoblockShare {
    display: flex;
    align-items: center;
    justify-content: center;
    position: absolute;
    top: 10px;
    right: 42px;
    z-index: 5;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: none;
    color: var(--TXTCOLOR3);
    cursor: pointer;
}
#selected_infoblock .infoblockShare svg {
    width: 18px; height: 18px;
    fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
@media (hover: hover) { #selected_infoblock:not(.sheet) .infoblockShare:hover { background: var(--BGCOLOR2); color: var(--TXTCOLOR2); } }
#selected_infoblock:not(.sheet) #sheetHandle { padding-right: 76px; }
/* the map (and everything drawn into it: wind, overlays) is one layer at the
   bottom; panels, list, pill, bars and menus always sit above it */
#map_canvas { z-index: 0; }
#altitude_chart { z-index: 5; }
/* phone sheet: share sits left of the close box, in the header row; the
   header text keeps clear of both */
#selected_infoblock.sheet .infoblockShare {
    top: calc( 4px * var(--SCALE));
    right: calc( 12px * var(--SCALE) + 20px * var(--SCALE) + 8px);
    width: 34px;
    height: 34px;
}
#selected_infoblock.sheet .infoblockShare svg { width: 20px; height: 20px; }
#selected_infoblock.sheet #sheetHandle { padding-right: calc( 12px * var(--SCALE) + 20px * var(--SCALE) + 50px); }

/* Kp chip (script.js): glass pill under the top bar, left edge, level with
   the object list tab; tap for the explainer card (.kpCard) */
.kpChip {
    position: absolute;
    top: calc(var(--BAR-H) + var(--SAFE-T) + 12px);
    left: var(--EDGE-INSET);
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 30px;
    padding: 0 12px 0 10px;
    border-radius: 999px;
    font: 600 12.5px/1 -apple-system, BlinkMacSystemFont, system-ui, 'Segoe UI', Roboto, sans-serif;
    font-variant-numeric: tabular-nums;
    color: var(--TXTCOLOR1);
    background: var(--GLASS-BG);
    -webkit-backdrop-filter: var(--GLASS-BLUR);
    backdrop-filter: var(--GLASS-BLUR);
    border: 0.5px solid var(--GLASS-EDGE);
    box-shadow: inset 0 1px 0 var(--GLASS-HI), 0 6px 20px rgba(0, 0, 0, 0.16), 0 1px 3px rgba(0, 0, 0, 0.10);
    cursor: pointer;
    pointer-events: auto;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
}
.kpChip:active { transform: scale(0.96); }
.kpChip:focus-visible { outline: 2px solid var(--ACCENT); outline-offset: 2px; }
.kpChip[hidden] { display: none; }
.kpDot { width: 9px; height: 9px; border-radius: 50%; background: #2EBD59; box-shadow: 0 0 0 2px color-mix(in srgb, #2EBD59 25%, transparent); }
.kpChip[data-level="active"] .kpDot { background: #F2A900; box-shadow: 0 0 0 2px rgba(242, 169, 0, 0.25); }
.kpChip[data-level="storm"] .kpDot { background: #E53935; box-shadow: 0 0 0 2px rgba(229, 57, 53, 0.25); }
html.kiosk .kpChip { display: none; }

/* State chip for the Special / Alerts buttons: the same glass as the Kp chip, centred under the top bar (under the Kp chip on a phone).
   A hollow dot while the rest is only dimmed, a solid one once it is hidden. */
.stateChip {
    position: absolute;
    top: calc(var(--BAR-H) + var(--SAFE-T) + 12px);
    left: 50%;
    transform: translateX(-50%);
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 30px;
    padding: 0 10px 0 11px;
    border-radius: 999px;
    font: 600 12.5px/1 -apple-system, BlinkMacSystemFont, system-ui, 'Segoe UI', Roboto, sans-serif;
    color: var(--TXTCOLOR1);
    background: var(--GLASS-BG);
    -webkit-backdrop-filter: var(--GLASS-BLUR);
    backdrop-filter: var(--GLASS-BLUR);
    border: 0.5px solid var(--GLASS-EDGE);
    box-shadow: inset 0 1px 0 var(--GLASS-HI), 0 6px 20px rgba(0, 0, 0, 0.16), 0 1px 3px rgba(0, 0, 0, 0.10);
    cursor: pointer;
    pointer-events: auto;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
    white-space: nowrap;
}
.stateChip[hidden] { display: none; }
.stateChip:active { transform: translateX(-50%) scale(0.96); }
.stateChip:focus-visible { outline: 2px solid var(--ACCENT); outline-offset: 2px; }
.stateDot { width: 9px; height: 9px; box-sizing: border-box; border-radius: 50%; border: 2px solid var(--ACCENT); background: transparent; }
.stateChip.isolate .stateDot { background: var(--ACCENT); box-shadow: 0 0 0 2px color-mix(in srgb, var(--ACCENT) 25%, transparent); }
.stateX { opacity: 0.55; font-size: 15px; line-height: 1; margin-left: 1px; }
html.kiosk .stateChip { display: none; }
html.phoneUI .stateChip { left: var(--EDGE-INSET); transform: none; top: calc(var(--BAR-H) + var(--SAFE-T) + 12px + 38px); }
html.phoneUI .stateChip:active { transform: scale(0.96); }

/* ===== Phones: bottom stack =====================================================
   Credits take the full width of the bottom row (wrapping between credits as
   layers add more), the pill sits above them, and the scale bar moves up
   into the altitude bar's row: scale bar left in a fixed 100px slot (its
   ruler is 40-100px, script.js), altitude bar filling the rest. */
html.phoneUI #map_canvas .ol-attribution {
    left: var(--EDGE-INSET);
    right: var(--EDGE-INSET);
    max-width: none;
    text-align: center;
}
/* the list is a flex item: let it shrink to the row and wrap between credits,
   each credit kept whole, the lines centred (a gap rather than dots, so a
   wrapped line never starts with a separator) */
html.phoneUI #map_canvas .ol-attribution ul {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    column-gap: 10px;
    row-gap: 1px;
}
html.phoneUI #map_canvas .ol-attribution li { display: block; white-space: nowrap; }
html.phoneUI #map_canvas .ol-scale-line {
    left: var(--EDGE-INSET);
    bottom: calc( var(--DOCK-TOP) + 10px);
    width: 100px;
}
html.phoneUI.sheetPeek #map_canvas .ol-scale-line {
    bottom: calc( var(--SHEET-PEEK-H, 0px) + 10px + var(--DOCK-H) + 10px);
}
html.phoneUI #altitude_chart {
    left: calc( var(--EDGE-INSET) + 110px) !important;
    right: auto !important;
    transform: none;
    width: calc(100% - var(--EDGE-INSET) * 2 - 110px) !important;
}
/* a narrow desktop window keeps its zoom buttons on the right of that row */
@media (hover: hover) and (pointer: fine) {
    html.phoneUI #altitude_chart { width: calc(100% - var(--EDGE-INSET) * 2 - 110px - 50px) !important; }
}

/* Kp explainer card (script.js): under the chip, in the menus' card style */
.kpCard {
    position: fixed;
    z-index: 1100;
    width: min(320px, calc(100vw - 24px));
    box-sizing: border-box;
    padding: 14px 14px 12px;
    border-radius: 16px;
    background: var(--BGCOLOR1);
    color: var(--TXTCOLOR2);
    box-shadow: 0 10px 34px rgba(0, 0, 0, 0.24), 0 0 0 0.5px color-mix(in srgb, var(--TXTCOLOR3) 30%, transparent);
    font: 13.5px/1.45 -apple-system, BlinkMacSystemFont, system-ui, "Segoe UI", Roboto, sans-serif;
    animation: kpCardIn 0.16s ease-out;
}
@keyframes kpCardIn { from { opacity: 0; transform: translateY(-6px); } }
@media (prefers-reduced-motion: reduce) { .kpCard { animation: none; } }
.kpCard p { margin: 8px 0 0; }
.kpCardHead { display: flex; align-items: center; gap: 12px; }
.kpCardHead > div { flex: 1 1 auto; min-width: 0; }
.kpCardValue {
    flex: none;
    width: 44px;
    height: 44px;
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 17px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: #fff;
    background: #2EBD59;
}
.kpCardValue[data-level="active"] { background: #F2A900; color: #1a1300; }
.kpCardValue[data-level="storm"] { background: #E53935; }
.kpCardTitle { font-weight: 600; font-size: 15px; color: var(--TXTCOLOR1); }
.kpCardSub { font-size: 12.5px; color: var(--TXTCOLOR3); }
.kpCardClose {
    flex: none;
    width: 36px;
    height: 36px;
    margin: -6px -6px -6px 0;
    border: 0;
    background: transparent;
    color: var(--TXTCOLOR3);
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
}
.kpCardActions { display: flex; justify-content: flex-end; margin-top: 12px; }
.kpCardBtn {
    min-height: 38px;
    padding: 0 16px;
    border: 0;
    border-radius: 999px;
    background: var(--ACCENT);
    color: #fff;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}
.kpCardBtn:focus-visible, .kpCardClose:focus-visible { outline: 2px solid var(--ACCENT); outline-offset: 2px; }


/* ===== Object list on phones: a sheet, like Settings and the airport card ================
   Full height to start (stopping just below the status bar), half height when dragged down by the grabber,
   closed by dragging further, by the X, or by choosing an object. The map stays full width behind it. */
html.phoneUI #sidebar_container {
    position: fixed !important;
    z-index: 1004;
    left: 0 !important;
    right: 0;
    bottom: 0;
    top: calc( var(--SAFE-T) + 4vh);
    width: auto !important;
    height: auto !important;
    max-width: none;
    margin: 0 !important;
    border: 0;
    border-radius: 16px 16px 0 0;
    box-shadow: 0 -6px 30px rgba(0, 0, 0, 0.25);
    overflow: hidden;
    transition: top 0.28s cubic-bezier(0.2, 0.9, 0.25, 1);
    animation: sheetUp 0.32s cubic-bezier(0.2, 0.9, 0.25, 1);
}
html.phoneUI #sidebar_container.sheetHalf { top: 50%; }
html.phoneUI #sidebar_container.sheetDragging { transition: none; }
html.phoneUI #splitter { display: none !important; }
html.phoneUI #sidebar_canvas {
    height: 100%;
    box-sizing: border-box;
    padding-top: 64px;
    padding-bottom: calc( var(--SAFE-B) + 16px);
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
}
/* the sheet has its own controls: the edge tab would sit above it for no purpose */
html.phoneUI .listTab.open { display: none; }
html:not(.phoneUI) #sidebar_container > .sheetBar { display: none; }
#sidebar_container .sheetBar .settingsCloseBox {
    position: absolute;
    top: auto;
    right: 14px;
    bottom: 10px;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--TXTCOLOR3) 18%, transparent);
    filter: none;
    cursor: pointer;
}

/* Object list, desktop panel and phone sheet alike: one scrolling area. The section above the table (counts, search,
   filters) and the legend are held at the panel's width (script.js sets --SB-W) and stay where they are when the table is
   scrolled sideways; the table's header row stays in view when scrolling down. */
#sidebar_canvas {
    flex: 1 1 auto;
    min-height: 0;
    overflow: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
}
#sidebar-table {
    width: max-content;
    min-width: 100%;
}
#sidebarTop,
#sidebar-table > #legend {
    position: sticky;
    left: 12px;                           /* the canvas's side padding */
    width: var(--SB-W, auto);
    box-sizing: border-box;
}
#planesTable thead td {
    position: sticky;
    top: -12px;                           /* sticks flush: the canvas has 12px of top padding */
    z-index: 3;
    background: var(--BGCOLOR1);
    box-shadow: 0 1px 0 var(--BGCOLOR2);
}
/* phone sheet: the title bar covers the top 56px of the scrolling area, whose padding is 64px */
html.phoneUI #planesTable thead td { top: -8px; }

.mapConfirmOverlay {
    position: fixed;
    inset: 0;
    z-index: 100000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    background: rgba(0, 0, 0, 0.4);
}
.mapConfirm {
    width: 320px;
    max-width: 100%;
    box-sizing: border-box;
    padding: 20px 20px 16px;
    background: var(--BGCOLOR1);
    color: var(--TXTCOLOR2);
    border: 0.5px solid var(--BGCOLOR2);
    border-radius: 14px;
    box-shadow: 0 10px 34px rgba(0, 0, 0, 0.3);
    font-family: -apple-system, system-ui, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
    font-size: 14px;
    line-height: 1.4;
}
.mapConfirm h2 { margin: 0 0 8px; font-size: 17px; }
.mapConfirm p { margin: 0 0 16px; }
.mapConfirmButtons { display: flex; gap: 10px; justify-content: flex-end; }
.mapConfirmButtons button {
    min-height: 40px;
    padding: 0 16px;
    border: 0;
    border-radius: 10px;
    background: var(--BGCOLOR2);
    color: inherit;
    font: inherit;
    cursor: pointer;
}
.mapConfirmButtons .mapConfirmOk { background: var(--ACCENT); color: #fff; font-weight: 600; }
.mapConfirmButtons button:focus-visible { outline: 2px solid var(--ACCENT); outline-offset: 2px; }
@media (max-width: 480px) {
    .mapConfirmButtons { flex-direction: column-reverse; }
    .mapConfirmButtons button { width: 100%; }
}

/* "Thanks for sharing!" for a visitor whose address is a connected feeder: bolder, in the accent colour, with a live "Online" tag at the right */
.mapMenuItem.mapMenuNote:disabled { opacity: 1; color: var(--ACCENT); cursor: default; min-height: 46px; font-weight: 700; font-size: 1.02em; background: color-mix(in srgb, var(--ACCENT) 9%, transparent); }
.mapMenuTrail { display: inline-flex; align-items: center; }
.mapMenuTrail:empty { display: none; }
.mapMenuOnline { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: #1E9E5A; }
.mapMenuOnline i { width: 8px; height: 8px; border-radius: 50%; background: #34C759; box-shadow: 0 0 0 0 rgba(52, 199, 89, 0.55); animation: mapMenuPulse 2s ease-out infinite; }
@keyframes mapMenuPulse { 0% { box-shadow: 0 0 0 0 rgba(52, 199, 89, 0.55); } 70%, 100% { box-shadow: 0 0 0 7px rgba(52, 199, 89, 0); } }
@media (prefers-reduced-motion: reduce) { .mapMenuOnline i { animation: none; } }
.mapMenuCup { display: block; }
.mapMenuTrail .mapMenuCup + .mapMenuCup { margin-left: 3px; }

/* ===== Views: Map / Around me / Sky dome (aroundme.js) ===== */
#aroundMe {
    position: absolute;
    inset: 0;
    background: #0b1020;
    transition: opacity 0.15s ease;
    touch-action: none;
    -webkit-user-select: none;
    user-select: none;
}
#aroundMe > canvas { position: absolute; inset: 0; display: block; width: 100%; height: 100%; touch-action: none; }
#aroundMe > canvas.amGL { pointer-events: none; }
@media (prefers-reduced-motion: reduce) { #aroundMe { transition: none; } }
html.viewAlt .ol-zoom, html.viewAlt .ol-scale-line { display: none !important; }
/* view pill: the bottom pill's material and buttons, stood on end */
.viewStack {
    position: absolute;
    top: calc(var(--BAR-H) + var(--SAFE-T) + 52px);
    left: calc(var(--AM-L, 0px) + var(--EDGE-INSET));   /* clear of the desktop details panel (aroundme.js sets --AM-L) */
    transition: left 0.2s ease;
    z-index: 1;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 5px;
    border-radius: 999px;
    background: var(--DOCK-BG);
    border: 0.5px solid color-mix(in srgb, var(--TXTCOLOR3) 25%, transparent);
    pointer-events: auto;
}
.viewStack[hidden] { display: none; }
/* the pill is exactly as wide as the bottom pill is tall: square buttons, labels may run into the padding */
.viewStack .dockButton { width: var(--DOCK-BTN); height: var(--DOCK-BTN); flex: none; overflow: visible; }
.viewStack .dockButton svg { width: 22px; height: 22px; transform: translateY(-6px); }
.viewStack .viewCompass svg { transform: none; }
/* Horizon and Sky have no object table: the list tab and the side panel stay hidden until the map returns */
html.viewAlt #listTab, html.viewAlt #sidebar_container { display: none !important; }
/* the compass slides in under the views while Around me is shown */
.viewStack .viewCompass {
    max-height: 0;
    opacity: 0;
    margin-top: -2px;
    overflow: hidden;
    pointer-events: none;
    transition: max-height 0.22s cubic-bezier(0.2, 0.9, 0.25, 1), opacity 0.15s ease, margin-top 0.22s ease, color 0.15s ease;
}
html[data-view="around"] .viewStack .viewCompass { max-height: var(--DOCK-BTN); opacity: 1; margin-top: 0; pointer-events: auto; overflow: visible; }
.viewStack .vcNeedle { transition: transform 0.12s linear; }
@media (prefers-reduced-motion: reduce) { .viewStack .viewCompass, .viewStack .vcNeedle { transition: none; } }
html.kiosk .viewStack { display: none; }
/* compass tape and off-screen counts: the same glass as the pills */
.amTape {
    position: absolute;
    left: 8px;
    right: 8px;
    height: 38px;
    border-radius: 19px;
    background: var(--DOCK-BG);
    border: 0.5px solid color-mix(in srgb, var(--TXTCOLOR3) 25%, transparent);
    color: var(--DOCK-ON);
    pointer-events: none;
    overflow: hidden;
}
.amTape > canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.amTape::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 0;
    margin-left: -5px;
    border: 5px solid transparent;
    border-top: 6px solid var(--ACCENT);
}
.amEdge {
    position: absolute;
    left: calc(var(--AM-L, 0px) + var(--EDGE-INSET));
    height: 30px;
    padding: 0 12px;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    font: 600 12.5px/1 -apple-system, BlinkMacSystemFont, system-ui, 'Segoe UI', Roboto, sans-serif;
    font-variant-numeric: tabular-nums;
    color: var(--DOCK-ON);
    background: var(--DOCK-BG);
    border: 0.5px solid color-mix(in srgb, var(--TXTCOLOR3) 25%, transparent);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: transform 0.12s ease;
}
.amEdge.r { left: auto; right: var(--EDGE-INSET); }
.amEdge.clear { left: calc(var(--AM-L, 0px) + var(--EDGE-INSET) + var(--DOCK-BTN) + 20px); }
.amEdge[hidden] { display: none; }
.amEdge:active { transform: scale(0.94); }
.amEdge:focus-visible { outline: 2px solid var(--ACCENT); outline-offset: 2px; }
.viewStack, .amTape, .amEdge {
    --DOCK-BG: var(--GLASS-BG);
    -webkit-backdrop-filter: var(--GLASS-BLUR);
    backdrop-filter: var(--GLASS-BLUR);
    border-color: var(--GLASS-EDGE);
    box-shadow: inset 0 1px 0 var(--GLASS-HI), inset 0 -1px 0 rgba(0, 0, 0, 0.04),
                0 8px 28px rgba(0, 0, 0, 0.18), 0 1px 3px rgba(0, 0, 0, 0.10);
}
.amCard { top: calc(var(--BAR-H) + var(--SAFE-T) + 52px); left: calc(var(--AM-L, 0px) + var(--EDGE-INSET) + var(--DOCK-BTN) + 22px); width: min(320px, calc(100vw - var(--AM-L, 0px) - var(--EDGE-INSET) - var(--DOCK-BTN) - 34px)); }
.amToast {
    position: fixed;
    left: 50%;
    bottom: calc(var(--DOCK-B) + var(--DOCK-H) + 64px);
    transform: translateX(-50%);
    z-index: 1100;
    padding: 9px 16px;
    border-radius: 999px;
    background: var(--BGCOLOR1);
    color: var(--TXTCOLOR2);
    font: 600 13px/1.2 -apple-system, BlinkMacSystemFont, system-ui, 'Segoe UI', Roboto, sans-serif;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.22);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease;
}
.amToast.on { opacity: 1; }
.mapMenuRadio .mapMenuSwitch { display: none; }
.mapMenuRadio[aria-checked="true"]::after { content: "\2713"; margin-left: auto; color: var(--ACCENT); font-weight: 700; }
.amTag {
    display: inline-block;
    padding: 1px 6px;
    border-radius: 999px;
    font: 700 9px/1.4 -apple-system, BlinkMacSystemFont, system-ui, 'Segoe UI', Roboto, sans-serif;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ACCENT);
    background: color-mix(in srgb, var(--ACCENT) 14%, transparent);
    border: 0.5px solid color-mix(in srgb, var(--ACCENT) 40%, transparent);
}
.amBeta {
    position: absolute;
    top: calc(var(--BAR-H) + var(--SAFE-T) + 6px);
    left: 50%;
    transform: translateX(-50%);
    pointer-events: none;
}
.amBeta .amTag { background: var(--GLASS-BG); -webkit-backdrop-filter: var(--GLASS-BLUR); backdrop-filter: var(--GLASS-BLUR); border-color: var(--GLASS-EDGE); color: var(--TXTCOLOR1); }

.amCredit { position: absolute; right: 14px; font: 500 9.5px/1.2 -apple-system, BlinkMacSystemFont, system-ui, 'Segoe UI', Roboto, sans-serif; color: rgba(255,255,255,0.85); text-shadow: 0 0 3px rgba(0,0,0,0.6); pointer-events: auto; }
.amCredit[hidden] { display: none; }
.amCredit a { color: inherit; }

/* only the map view changes the base map: Horizon is always satellite, Sky is terrain */
html.viewAlt .layer-switcher li.layer:has(> input[type="radio"]) { display: none; }
/* short landscape screens (phones on their side): the vertical view pill keeps its place and the compass tape starts beside it */
@media (orientation: landscape) and (max-height: 520px) {
    .amTape { left: calc(var(--AM-L, 0px) + var(--EDGE-INSET) + var(--DOCK-BTN) + 22px); }
}
.amTape::after { left: var(--TAPE-CX, 50%); }
/* Sky view: an N button (north up) in place of the compass */
.viewStack .viewNorth { max-height: 0; opacity: 0; margin-top: -2px; overflow: hidden; pointer-events: none; transition: max-height 0.22s cubic-bezier(0.2, 0.9, 0.25, 1), opacity 0.15s ease, margin-top 0.22s ease; }
html[data-view="dome"] .viewStack .viewNorth { max-height: var(--DOCK-BTN); opacity: 1; margin-top: 0; pointer-events: auto; overflow: visible; }
.viewStack .viewNorth svg { transform: none; }
@media (prefers-reduced-motion: reduce) { .viewStack .viewNorth { transition: none; } }
/* settings sliders: default-value tick, and the handle ringed while it is on the default (sliderDefault in script.js) */
.ui-slider .sliderDefault { position: absolute; top: 50%; width: 2px; height: 12px; margin: -6px 0 0 -1px; border-radius: 1px; background: var(--TXTCOLOR3); opacity: 0.7; pointer-events: none; z-index: 1; }
.ui-slider.atDefault .ui-slider-handle { box-shadow: 0 0 0 3px color-mix(in srgb, var(--ACCENT) 55%, transparent), 0 1px 4px rgba(0, 0, 0, 0.25); }
