
body,
html {
    height: 100%;
    width: 100%;
    margin: 0;
    /* stop iOS Safari inflating text in scrollable blocks (log view) */
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    font-family: var(--font-sans);
    display: flex;
    flex-direction: column;
    justify-content: stretch;
    /*-webkit-user-select: none;
    -ms-user-select: none;
    user-select: none;*/
    -webkit-touch-callout: none;
    overflow: hidden;
    touch-action: none;
}

.cursor-move {
    cursor: move;
}

.draggable.dragging {
    cursor: grabbing;
}

a {
    color: var(--color-link);
    text-decoration: none;
}

a:hover,
a:focus {
    color: var(--color-link-hover);
    text-decoration: underline;
}

.header {
    background: var(--color-brand);
    flex: 0 0 var(--size-topbar);
    font-size: var(--fs-2xl);
    display: flex;
    justify-content: stretch;
    color: var(--color-brand-ink);
    position: relative;
}

.header-title {
    flex: 1 1 auto;
    min-width: 0;
    background-color: var(--color-brand-accent);
    border-top-right-radius: 25% 50%;
    border-bottom-right-radius: 25% 50%;
    display: flex;
    flex-direction: row;
    padding-right: 14px;
}

.header-title span {
    padding: 15px;
    padding-top: 17px;
    line-height: 20px;
    padding-right: 50px;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.header-title div {
    background: var(--color-brand);
    padding: 10px;
    margin: auto 0;
    border-radius: var(--radius-2xl);
    font-size: var(--fs-lg);
    line-height: 15px;
}

.small-icon {
    font-size: var(--fs-xl);
}

.tabcontent {
    flex: 1 0 1px;
}

.addscrollbar {
    overflow: auto;
}

@media only screen and (max-width: 750px) {
    .header-title div {
        display: none;
    }

    .header-title span {
        padding-right: 15px;
    }
}

.header-title div i {
    padding: 0px 14px;
    font-size: var(--fs-xl);
    transition: var(--transition-hover);
}

.header-title div i:hover {
    cursor: pointer;
    transform: var(--hover-lift);
}

.header-title div i.active {
    color: var(--color-active);
}

.header-icon {
    width: 35px;
    flex: none;
    border-radius: var(--radius-circle);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: var(--transition-hover);
    font-size: var(--fs-lg);
    line-height: 15px;
}

.receiver-list {
    display: flex;
    flex-direction: column;
}

.receiver-option {
    padding: 10px 4px;
    font-size: var(--fs-base);
    color: var(--color-text);
    cursor: pointer;
    border-radius: var(--radius-md);
    overflow-wrap: anywhere;
}

.receiver-option + .receiver-option {
    border-top: 1px solid var(--color-menu-divider);
}

.receiver-option:hover {
    background: var(--color-menu-hover);
}

.receiver-option.active {
    color: var(--color-accent);
    font-weight: var(--fw-semibold);
}

.pulsating {
    animation: pulse-streaming 1.5s ease-in-out infinite;
}

@keyframes pulse-streaming {

    0%,
    100% {
        opacity: 1;
    }

    50% {
        opacity: 0;
    }
}

.header-icon:hover {
    cursor: pointer;
    transform: var(--hover-lift);
}

.header-icon.active {
    color: var(--color-ok);
}

.header-menubutton {
    background: var(--color-menu);
    color: var(--color-text);
    transition: var(--transition-hover);
    font-size: var(--fs-3xl);
    width: 40px;
    flex: none;
    border-right: 1px solid var(--color-border-strong);
}

.header-menubutton>div {
    padding: 15px 9px;
    margin: auto;
}

@media (hover: hover) {
    .header-menubutton:hover {
        cursor: pointer;
    }
}

.bottombar {
    display: none;
    flex: 0 0 5px;
    background: var(--color-bottombar);
}

#realtime_content {
    background: var(--color-surface-raised);
    color: var(--color-text);
}

#menubar-overlay {
    z-index: var(--z-menu-scrim);
}

#menubar {
    position: relative;
    z-index: var(--z-menu);
    background: var(--color-menu);
    color: var(--color-text);
    text-align: center;
    align-items: stretch;
    display: none;
    flex-direction: row;
    visibility: visible;
    width: 100%;
    margin: 0;
    border-radius: 0;
}

#menubar div {
    flex: 0 1 150px;
    margin: 0 10px;
    border: none;
    cursor: pointer;
    display: flex;
    justify-content: center;
    align-items: center;
    transition: var(--transition-hover);
    flex-direction: column;
}

#menubar div i {
    padding-top: 10px;
    padding-bottom: 10px;
    font-size: var(--fs-3xl);
    line-height: 24px;
}

#menubar div span {
    padding-bottom: 10px;
    font-size: var(--fs-2xs);
    line-height: 10px;
}

#menubar div.active {
    border-bottom: 4px solid var(--color-active);
    color: var(--color-active);
}

#menubar.visible {
    display: flex;
}

.mainspace-container {
    flex: 1 0 0;
    position: relative;
    background: var(--color-bg);
    display: flex;
    flex-direction: column;
    justify-content: stretch;
}

.mainspace {
    background: var(--color-canvas);
    margin: 0px;
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: stretch;
}

@media only screen and (max-height: 1000px) {
    .header-menubutton {
        display: block;
    }
}

.plots-tabs {
    margin: 4px 25px 0;
}

#plots .compare-panel {
    display: none;
}

#plots.compare-mode .compare-panel {
    display: block;
}

#plots.compare-mode .graph-panel:not(.compare-panel) {
    display: none;
}

.chart-sources {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 18px;
    margin: 14px 25px 0;
    color: var(--color-text-muted);
    font-size: var(--fs-sm);
}

.chart-sources label {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.chart-sources select {
    background: var(--color-surface-raised);
    color: var(--color-text);
    border: 1px solid var(--color-field-border);
    border-radius: var(--radius-md);
    padding: 4px 8px;
    font-size: var(--fs-sm);
    cursor: pointer;
    transition: border-color var(--dur-fast) ease;
}

.chart-sources select:hover {
    border-color: var(--color-accent);
}

.graphtab {
    padding: 15px;
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    column-gap: 15px;
    row-gap: 15px;
    margin: 10px;
}

@media only screen and (max-width: 2250px) {
    .graphtab {
        grid-template-columns: 1fr 1fr 1fr;
        padding: 5px;
    }
}

@media only screen and (max-width: 1500px) {
    .graphtab {
        grid-template-columns: 1fr 1fr;
        padding: 5px;
    }
}

@media only screen and (max-width: 800px) {
    .graphtab {
        grid-template-columns: 1fr;
        padding: 0px;
    }
}

.graph-panel {
    padding: 10px;
    overflow: auto;
    background-color: var(--color-surface);
    margin: 0px;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    border: none;
}

.graph-panel>header,
.stat-panel>header {
    margin: 20px auto 30px;
    padding: 5px 0px;
    border-radius: var(--radius-lg);
    max-width: 400px;
    width: calc(100% - 30px);
    align-items: center;
    border-left: 10px solid var(--color-band);
    border-right: 10px solid var(--color-band);
    background-color: var(--color-band-accent);
    color: var(--color-text);
    text-align: center;
    font-size: var(--fs-base);
    font-weight: var(--fw-medium);
}

.graph-panel>canvas {
    width: 100%;
    height: 100%;
}

.aboutpage {
    background-color: var(--color-surface);
    color: var(--color-text);
}

/* Table styling */

#shipTable {
    max-height: calc(100vh - 135px);
    max-width: 100vw;
}

.tabulator {
    border-color: var(--color-border);
}

.tabulator .tabulator-cell {
    border: none;
    border-bottom: 1px solid var(--color-border);
    padding: 6px 14px;
    /* fixed rowHeight is 37px; line-height fills it so single-line content
       is vertically centered (cells are inline-block, so text would otherwise
       sit at the top) */
    line-height: 24px;
    font-size: var(--fs-sm);
    vertical-align: middle;
    color: var(--color-text);
}

/* keep inline icons (flags, ship-type markers) centered with the text */
.tabulator .tabulator-cell img,
.tabulator .tabulator-cell svg,
.tabulator .tabulator-cell span {
    vertical-align: middle;
}

.tabulator .tabulator-header {
    border: none;
}

/* typography comes from .col-header in components.css */
.tabulator .tabulator-header .tabulator-col {
    background-color: var(--color-band-accent);
    border: none;
    padding: 8px 14px;
    border-collapse: collapse;
}

.tabulator .tabulator-header .tabulator-col.tabulator-sortable.tabulator-col-sorter-element:hover {
    background-color: var(--color-band-accent);
    background-image: linear-gradient(var(--color-hover), var(--color-hover));
}

.tabulator .tabulator-header .tabulator-col .tabulator-arrow {
    border-top-color: var(--color-text-muted) !important;
    border-bottom-color: var(--color-text-muted) !important;
}

.tabulator .tabulator-header .tabulator-col[aria-sort="ascending"] .tabulator-arrow,
.tabulator .tabulator-header .tabulator-col[aria-sort="descending"] .tabulator-arrow {
    border-top-color: var(--color-text) !important;
    border-bottom-color: var(--color-text) !important;
}

.tabulator-row:hover {
    background-color: var(--color-selected) !important;
}

.tabulator-row-odd {
    background-color: var(--color-surface);
}

.tabulator-row-even {
    background-color: var(--color-surface-alt) !important;
}

.tablesection {
    font-size: var(--fs-md);
    display: flex;
    flex-direction: column;
    height: 100%;
    margin: 10px auto;
    color: var(--color-text);
    background-color: var(--color-surface);
    width: fit-content;
}

.search-container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 10px;
    margin-bottom: 10px;
    padding-left: 12px;
    padding-right: 8px;
    position: sticky;
    left: 0;
    box-sizing: border-box;
    width: 100%;
    overflow: visible;
}

.mytable {
    height: 100%;
    width: 100%;
    table-layout: fixed;
    box-sizing: border-box;
    border-collapse: collapse;
}

.mytable>tbody>tr>td {
    padding: 5px 4px;
}


/* Map styling */

#map {
    height: 100%;
    width: 100%;
    /* void outside the loaded tiles; black in both themes on purpose */
    background-color: black;
}

.crosshair_cursor {
    cursor: crosshair;
}

/* Ticker: a strip along the top of the map. It sits at map-control depth, so
   the settings panel (z-panel-top) and the side table (z-panel) both pass over
   it, and it gives the table its width back rather than sliding underneath. */
.ticker {
    position: absolute;
    box-sizing: border-box;
    top: var(--size-map-gap);
    left: var(--size-map-gap);
    right: var(--ticker-right, var(--size-map-gap));
    height: var(--size-ticker);
    display: none;
    align-items: center;
    /* A ticker that wraps stops being a strip: the height is fixed, so a second
       line would be clipped rather than shown. Nothing here may wrap, and
       whatever still will not fit is cut at the edge. */
    flex-wrap: nowrap;
    overflow: hidden;
    gap: 12px;
    padding: 0 14px;
    z-index: var(--z-map-control);
    /* the map keeps showing through, but blurred, so a busy chart underneath
       never competes with the headline; the palette is themed in tokens.css */
    background: var(--color-ticker-bg);
    backdrop-filter: blur(8px);
    border: 2px solid var(--color-ticker-border);
    border-radius: var(--radius-lg);
    color: var(--color-ticker-ink);
    font-size: var(--fs-sm);
    box-shadow: var(--shadow-md);
    transition: right var(--dur-slow) ease-out;
}

.ticker .stat-item {
    color: var(--color-ticker-ink);
}

.ticker.visible {
    display: flex;
}

.ticker.active {
    right: calc(var(--size-panel) + var(--ticker-right, var(--size-map-gap)));
}

/* outlined rather than filled: a solid block of accent at the head of the bar
   outweighs the news it introduces */
.ticker-count {
    display: flex;
    align-items: center;
    white-space: nowrap;
    gap: 6px;
    flex: none;
    padding: 2px 10px;
    border-radius: var(--radius-2xl);
    background: transparent;
    border: 1px solid var(--color-ticker-accent);
    color: var(--color-ticker-accent);
    fill: var(--color-ticker-accent);
    font-weight: var(--fw-bold);
    cursor: pointer;
}

@media (hover: hover) {
    .ticker-count:hover,
    .ticker-item:hover,
    .ticker-buckets .stat-item[data-action]:hover {
        background: var(--color-ticker-hover);
    }
}

.ticker-feed {
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    gap: 16px;
    min-width: 0;
    flex: 1;
    overflow: hidden;
}

.ticker-item {
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    gap: 8px;
    min-width: 0;
    flex: 0 1 auto;
    cursor: pointer;
    border-radius: var(--radius-sm);
    padding: 2px 6px;
}


.ticker-buckets {
    display: none;
    align-items: center;
    flex-wrap: nowrap;
    white-space: nowrap;
    gap: 4px;
    flex: 1;
    overflow: hidden;
}

.ticker.ticker-idle .ticker-feed {
    display: none;
}

.ticker.ticker-idle .ticker-buckets {
    display: flex;
}

/* one line, clipped at the edge: a ticker that wraps stops being a strip */
.ticker-text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The change reads like the shipcard's timeline: the old value steps back, the
   new one is what the eye should land on. */
.tk-name {
    font-weight: var(--fw-bold);
}

.tk-sep,
.tk-label,
.tk-was,
.tk-arrow {
    color: var(--color-ticker-muted);
}

.tk-to {
    color: var(--color-ticker-accent);
}

.ticker-text > span + span {
    margin-left: 6px;
}

/* right after the headline it dates, not banished to the far edge */
.ticker-age {
    flex: none;
    color: var(--color-ticker-muted);
    font-size: var(--fs-xs);
    white-space: nowrap;
}

.ticker-dot {
    flex: none;
    width: 8px;
    height: 8px;
    border-radius: var(--radius-circle);
    background: var(--color-ok-strong);
}

.ticker-new {
    background: var(--color-accent);
}

.ticker.ticker-idle .ticker-dot {
    background: var(--color-off);
}

/* the top control pill would otherwise sit on the strip */
/* Everything the bar pushes down derives from the same two tokens; the only
   variation is each element's own resting inset (10, 16 and 60 respectively). */
body.ticker-open .map-pill {
    top: var(--size-ticker-inset) !important;
}

/* Given room, the bar stops short of the control column instead of running under
   it, and the controls keep their place. What decides that is the width actually
   available - the map minus the side table when it is out - so the two cases
   have their own thresholds: 900px on its own, and 900 + the 430px panel with
   the table open. Below either, the bar takes the full width it has and the
   controls step down, exactly as on a narrow screen. */
@media only screen and (min-width: 900px) {
    .ticker:not(.active) {
        --ticker-right: calc(var(--size-map-gap) + var(--size-map-controls) + var(--size-map-gap));
    }

    body.ticker-open .map-pill:not(.active) {
        top: var(--size-map-gap) !important;
    }
}

/* 900px of usable bar again, measured after the panel has taken its share */
@media only screen and (min-width: 1330px) {
    .ticker.active {
        --ticker-right: calc(var(--size-map-gap) + var(--size-map-controls) + var(--size-map-gap));
    }

    body.ticker-open .map-pill.active {
        top: var(--size-map-gap) !important;
    }
}

body.ticker-open #statcard {
    top: var(--size-ticker-inset);
}

body.ticker-open #measurecard {
    top: calc(var(--size-ticker-inset) + 6px);
}

body.ticker-open .filter-empty {
    top: calc(var(--size-ticker-inset) + 50px);
}

/* The full-bleed measure card reaches the top edge on a phone, and the offset
   above - more specific than the layout rule that puts it there - must not win. */
@media only screen and (max-width: 500px) {
    body.ticker-open #measurecard {
        top: 0;
    }
}

.map-button-box {
    position: absolute;
    right: 10px;
    /* below the map cards: the shipcard covers the controls */
    z-index: var(--z-map-control);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border: 2px solid var(--color-border-strong);
    border-radius: var(--radius-lg);
    background-color: var(--color-surface-raised);
    fill: var(--color-text);
    color: var(--color-text);
    box-shadow: var(--shadow-md);
    transition: transform var(--dur-slow) ease-out;
}

/* Pill-shaped group (capsule ends) for the top "more tools" controls */
.map-button-box.map-pill {
    border-radius: var(--radius-2xl);
}

/* slide left by the ship table's width so the controls stay visible */
.map-button-box.active {
    transform: translateX(calc(-1 * var(--size-panel)));
}

.map-button {
    position: relative;
    width: var(--size-map-button) !important;
    height: 34px !important;
    border: none !important;
    margin: 0px !important;
    padding: 0 !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    background-color: var(--color-surface-raised) !important;
    fill: var(--color-text) !important;
    color: var(--color-text) !important;
    border-radius: 0 !important;
}

/* Thin divider between stacked buttons within a group */
.map-button+.map-button {
    border-top: 1px solid var(--color-border-strong) !important;
}

.map-button:hover {
    color: var(--color-highlight) !important;
    fill: var(--color-highlight) !important;
    outline: none !important;
}

.map-button:hover svg {
    transform: scale(1.2);
}

/* suppress the focus ring for pointer clicks only; keyboard focus stays visible */
.map-button:focus:not(:focus-visible) {
    outline: none !important;
}

.map-button:focus-visible {
    outline: 2px solid var(--color-accent-soft) !important;
    outline-offset: -2px;
}

.map-button svg {
    width: 19px !important;
    height: 19px !important;
    transition: transform var(--dur-fast) ease;
}

/* An engaged toggle is ringed rather than filled: the glyph and a circle around
   it take the accent, which reads at the pill's 15px glyph size without a solid
   block of colour sitting in the middle of the map. */
.map-button.is-active {
    color: var(--color-accent) !important;
    fill: var(--color-accent) !important;
}

.map-button.is-active::before {
    content: "";
    position: absolute;
    width: 26px;
    height: 26px;
    border-radius: var(--radius-circle);
    border: 2px solid var(--color-accent);
}

.map-button.is-active>* {
    position: relative;
}

.map-button.is-active:hover::before {
    background: var(--color-hover-overlay);
}

/* Top pill holds denser glyphs (ship/ruler) — render them a touch smaller
   so they don't look heavier than the bottom group's line icons */
.map-pill .map-button svg {
    width: 15px !important;
    height: 15px !important;
}

.map-attribution-foldout {
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--duration-slow, 400ms) ease;
    position: absolute;
    right: 54px;
    bottom: 10px;
    max-width: 320px;
    z-index: var(--z-map-control);
    padding: 6px 10px;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-lg);
    background-color: var(--color-surface-raised);
    color: var(--color-text);
    box-shadow: var(--shadow-md);
    font-size: var(--fs-2xs);
    line-height: 1.4;
}

.map-attribution-foldout.visible {
    opacity: 1;
    pointer-events: auto;
}

.map-attribution-foldout a {
    color: inherit;
}

.map-attribution-note {
    font-size: var(--fs-2xs);
    line-height: 1.4;
    color: var(--color-text-muted);
}

.map-attribution-note a {
    color: inherit;
}

#hover-info {
    position: absolute;
    display: flex;
    flex-direction: column;
    /* Overall container stacks cards vertically */
    flex: 0 0 auto;
    height: auto;
    width: auto;
    z-index: var(--z-map-label);
    font-size: var(--fs-sm);
    background-color: var(--color-scrim);
    color: var(--overlay-ink);
    text-align: center;
    border-radius: var(--radius-sm);
    padding: 5px;
    left: 0;
    top: 0;
    visibility: hidden;
    max-width: 350px;
    overflow: hidden;
    pointer-events: none;
}

.tooltip-card {
    display: flex;
    flex-direction: row;
    /* For flag and text side-by-side */
    align-items: center;
    width: 100%;
    margin-bottom: 5px;
}

.tooltip-sub,
.tooltip-dim {
    color: var(--overlay-ink-muted);
}

#hover-info div div {
    text-align: left;
}

#hover-info div span:not(.tooltip-dim) {
    font-size: var(--fs-3xl);
}

.fill-red {
    fill: var(--color-alert) !important;
}

.fill-green {
    fill: var(--color-ok-text) !important;
}

.fill-accent {
    fill: var(--color-accent) !important;
}

.filter-empty {
    display: none;
    position: absolute;
    top: 60px;
    left: 50%;
    transform: translateX(-50%);
    z-index: var(--z-card);
    align-items: center;
    gap: 12px;
    padding: 8px 10px 8px 16px;
    border-radius: var(--radius-2xl);
    background: var(--overlay-bg);
    color: var(--overlay-ink);
    box-shadow: var(--shadow-md);
    font-size: var(--fs-sm);
}

.filter-empty.visible {
    display: flex;
}

.filter-empty button {
    padding: 2px 12px;
    border: none;
    border-radius: var(--radius-2xl);
    background: var(--color-accent);
    color: var(--color-accent-ink);
    font-size: var(--fs-sm);
    cursor: pointer;
}

.count-filtered {
    color: var(--color-accent);
    font-weight: 600;
}

.fill-orange {
    /* mid level between ok and alert; no status token sits here */
    fill: #ff9900 !important;
}

.fill-gray {
    fill: var(--color-text-subtle) !important;
}

.shipicon {
    background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKAAAAAoCAYAAAB5LPGYAAATHElEQVR42u3be3BU130H8O8599593H2BpJUwRgIhHlrJKwsQSCCJlWweIyLXBo+BWDZqhqi0zTgKSWcoQ6d/dPpHp4SSNDOdEcqOChlSO8UiMSi2k9iKi2RbjhCGBUEAFyyBESteq9Xu3d37OP3DKs56tbpXjz86U/1m9Me95+qz59793d8597HAbMzG//VwNbpEV6PLPlPe7uxd4u7sXTPmzcttEuflNs2YV+XlxCovN2PeNqtD3GZ1zJhXW20Wa6vNM+aJheWiWFg+Y169xSvWW7yGPGpIpNx+UG7fTHWQgu6noPtm7hSh+zGDHgH2E2DGPA7Yz82gx/PYz/Mz54Hy+0H5Gdxfup8z+H0QA9XPKm/fMAAAwi9+lxc6GpKmWf2sL8Z3DADAm+Y38vzBY9Py5uU2WeOxrQMAYLaczBsabJ2WV+XlrBUsewAAPibBvK6AOi1vm9Vh/XNFHgCAf+eFvHYpPC2vttpsfe176gAA/ORHXF7nmfi0PLGw3Mpv/usBAFDe/be86JWeaXn1Fq/126aKAQD4aeLjvNOxgDTdCvhKfPWirPjqRVkAXpmBE+SVsujqrLLo6hnzIuGyrEi4bMa8AmbPKmD2GfPKVTmrXJVnzFtXqWatq1RnzOOWr8nilq+ZMW8tn5+1ls835OkmoLJxbbPqtkN126FsXNs83d49I29sdstuuGU3npE3TtuTE7XNiZgbiZgbcqJ22p6XZTQ7mQAnE+BlGdP2nlOV5mxNRbam4jlVmbb38qtac04OQ04Ow8uvatP2uModzcSVDeLKBle5Y9reNt7bnE0dyKYObOO9zdNKQFejy5eoWFz8v8uJisXFrkaXbxrDr688tvaxVx5bW7w7e9eUvXm5TT4puuaxJ0XXFM/LbZqyV+XlfEuZ47G3lDmKq7zclL1tVoevUpUfe5WqXLzN6piyV1tt9q33qY+99T61uLbaPGVPLCz3cZ7Kxx7nqSwWC8un7NVbvL4qoeCxVyUUFNdbvL4pJ6Dm9eyTC9xfVZsCNzSvZ8qT1WK1ZF+BVPB4uUAqQLFaMmVPVYv2RcNfedFwAVS1aMpeLuz7cpjl8XIOsyAX9il7ZZq2b6mqPF5eqioo07Qpe+tr2b5ly7THy8uWaVhfy6bs0cLqffSJJV8tP7EEtLB6yl45l7dvKZf91f5y2Sjn8vZNKQFdjS5Porao7uvrE7VFda5Gl2cK1c9TE69N8WritXW7s3d5plD9PDHJl+LFJF/dvNwmzxSqn6dYm5PiFWtz6qq8nGcK1c+zUZVTvI2qXLfN6vBMofp5tmxRU7wtW9S62mqzZwrVz8Ot2JTicSs21YmF5Z4pVD/PZsGT4m0WPHX1Fq9n0gnIsnOaE975KesT3vlg2TmTniu4WXbzUxFvyvqnIl64WfakPcaymkdDT6WsHw09BcayJu05ITTnMTFlfR4T4YQwaW8+Y81PK3LK+qcVGfMZm7SXv5g1r1ippqxfsVJF/uLJe8Sd38zll6TOCfNLQNz5k/YWEFdzKb8gZX0pvwALiKt5gltU41a/zMRLvjalwG1K/Q8KIpg9Ngy2xM8buwWwO3tX5ovx7W2L4wWm1A5wEHiTh3OxlnOR85LB6pcZk7a2xaKLU/vHOPAC75mbJbSMjvRJBqtfZgXLbsthFlPqGUrAE+phOdGWgSCTDFa/zFdVuW2JppjGO+BmQjyjZrHlspKQDFa/zL/8jta2bJmW6nGAVSSe258LLTcHjN0yEgvLM/mN326jTyxJPX6UA0xWD3d/oEW+d1syWP0yv2Uqb1vKZY+zvxQW8J6HJNZyVQlKRitgY2LVQlu6Dxxra5zECdK4KrIqrTfWNikvMpLeG2ublLdYs6f1xtom5a1R5LTeWNukvIoKNa031jYpj1u6Oq031jYpr1xYlNYba2s0VAFdjS4iP19zMvH0grSPUpiZB8cspaJl6FD8fFyv+pHnEi+cLJGeTuuZmBlMQKnNaT50LnJer/qRRPwbJyPhkrSepplgsmilrgzHodGRPr3qR8pY1smFzJbW40EBQkr5nNihgSDTq37km6pycoUqp/XMYOAoV6qarIcuKwm96kf+4q+0k6vK1PSeGTBbaOmDoHDo5oCqV/0I9+zuk9zi0rQeEcxggqWUDwcPyfdu61U/8qpQdnIln5u+f4QHz0hpjKqHripB3QrYkKjIz0nqkKKCKMk7NrZNg4Gzo2FNtDzJU4gChSjJVeHLbQx5kdE1yf2jCghN9sa2MeQtYY4kTwWDiuREG9vGkLdOSSTvLwiUrz10GtvGkFddrSZ5svzl35/G2DaGPK5wbU7y7QTly78/rUxfbmPIqxQWJ/cPKmQk58vYNg26FVB4rcofW79sPgBww6OwfPjZqLX1/Tbze/1nKbhC5rSamM0EzWGBcF/JS7x1o3Wi3r1mfs1fPeqbDwD3hGF86Oge9Tta2zrF985CYIVOzWkSNRscqgP3zQ/yfiW9NaFnEV/zhx9WzwcAk+UeHHM+HHXNbWuzOX5/VjCxQk1zmlRFhCo7YBHv50VHfzWhtyk7w+9hrvkAMEJk/JGGR9+nd9ou0kdnQUihFZzJDA5WcBglal5fUJrQ+y7H+2uVxHwAGKYczvDm0Z+YLG3v8qazlNBCF5jJxhgcjOEhx+d1qPKE3vd/QP0bNqrzASAYJOjs5Ed/+M982+lT3FmOJ4Vz5jCTzQY4nQwjYZr39jvahJ657jt+3ls7HwBYaBhqf9eofOrHbWrfO2dB+UIiukzEYgOxOqBJo3mJC+9N6DVbavzPCsu/7J8Wxgfy9dEfx37f9rbcf5aCFLqI1WQjZjiJBY+0aN6vE5eSPPK14bdS+sH2LvAUpo8/6+U++EMrgOOho6HIWLsNQIPqW92UqCgog6LBeugXVaGjoe40w2/l9yJ/08UzHh9bPurt4j9oBXDcHzwWGWu3AWioUnxNFbG1ZQpR8CPbD6v8wWPdaYbfytGR73YxxsMq9vTyQncrgONDg62RsXYbgAZFrmySouVlhCiwO/+1amiwtTvN8Fv5DS23iwPBNTLSe5k8agVwvCugRsbabQAaPGxO01LmLFPB0EEHq7oCanea4bfy7+VYl8CALl7ofZdyrQCOt0vhyFi7DUDDZk1tqlLkMpkA/yBYqtqlcHea4bfyX36sdPEC8MHvae+bv6CtAI53nolHxtptABpe3K41+Wq0MkUGvt/MV3WeiXenGX4rhVf/qQucALW/q1f75GQrgOPRKz2RsXYbgAa6ZmsTV1RVBlWG/LO/rYpe6elOM/xW/qNlSxcPDmeU670dyuVWAMdPxwKRsXYbgIZv8J6man5JmQIVfxf7ddXpWKA7XQIeZvmLRHLjZkvoaKhP5ynJSpa/aA+5cTMaOhramyYBDy/U8sXP6Y0Wf/BYn85cceVCLX/P5/RG1B88tjdNAh7WtDyR0oGWocHWPp254kpNy9tD6UB0aLB1b5oEPOyGRRxGrKUroPbpzBVXumHZM4xYtCug7k2TgIeXMSZeJaSlXQr36cwVVy5jbM9VQqLtUnhvmgQ8XFLKxAufkpbOM/E+nbniypJStufCpyTaeSa+N00CHiZ5JSIbuNASvdLTpzNXXEnySvawgQvR6JWevWkS8LCHZouXtWDL6VigT2euuNJDs/dc1oLR07HAXszGbMzGbMzGbMzGbMzGbMzGbMzGbMzGbMzGbMzG/5sw9Ks4AB4ADMCnoaMhNp0P3J29K8nzB49Ny5uX25TkDQ22Tsur8nJJXldAnZa3zepI8tql8LS82mpzktd5Jj4tTywsT/KiV3qm5dVbvEne6VhgQo+fIPGKWF7ewcS65XXqgrkEAPirdyVnxqUT5MG9A6GjocFJJl5RrrbwYEV8Xd0CeQFhhOG6cE2a68448ZA8OOAPHhucZOIVadqCg/FYRZ2ceJIADCbzdSlnwdwThDw8MDTYOjjJxCvKguXgUuasy2RmAgB3iCTZvY9OjEI50BVQByeZeEVLGDu4XpHrcplKAOCPlJeyLfYTQUIOtEvhwUkmXlFxCTu4YaNat3AhIwBwuZ9KT+aaT9wexIHOM/HBSSZeEVlQfJDz1tYRdy4BA7Tbf5RsGU+eYA9uH4he6RmcZOIVLaPugzX8krqFNIMwAFfUISmHOE7cZeEDp2OBQcMV0NXoqlE2reuIblspMktyjtJwDOLPe25xH53bHDoa6jeYfDXPyps6toVeFM2aJaktzIXxuuv4rR7+o83+4LF+g8lXIyee6Xh4b6uoqebkM0oIY07W67d4/g+bhwZb+w0mX00Jy+hYo2WKwtdeEJKgopsO37pGQpu7Amq/weSreV5VOrbLMdHCkgtAmFAcNVludVJuc7sU7jeYfDUNu7SOhlcU0WJJ9kZGCH7ayt86/Su6ufNMvN9g8tVwlTs7hOrtIoTk74NJYcjvHb2lnfv15uiVnn6DyVfzIl/SsdO8SrQQIbl/LIa22Me3fqde3Xw6Fkjxxnsf0K2uL+uJNpTbmCn1hWlm5iE/nesUrj/aYH0y4o+fjys6yeeuUnw9Lz96xSaw1BdwzcyMktjTzuvWaxvy7E/6z0XOKzrJ51bkdT0Pgt+0MU1Iadc0M6RoiVO0Xd/gmLPIPzrSp+gkn7uQzemp0tw2fpy30wRQLGQ25xCNbZibo/gHgkzRST73Jk3taUxINtM47WYwrFAV5zWe35AhWPyXlYSik3zubS9pPd9ukm2mcUCzGShbrTk/+4zbwBPef3NAVXSSz01Xv9BjerbRBj4VJIIZXMEKpzp0c4NA4Zfv3VZ0ks+9hff0fMuy1mYiqQOqmfBYJeQ6rynBDQ7O6r+qBJO88d4HbJa2rrQzLv0P5pjAIf7CquUAthg4QZqfH9lq5xiXdgOBCXg+stWwF3r4vJ1N4DFNQGT0zwx7a7RMO51gOsyBoEzLNOy9lIjZ+Qk2EMCwXU4Y9l5uUOz8BKAgAA2vKoY9oeolO2j64wdOgFC13bC3w7TKzk/wA0sBHHaaxs+XlP9SK0p96lxR91MTy3PA3Nmb9LZbrVT45ipzdb1l0nJkMbeupyhlPjmu70VGloGxTF1vCXP6bOB1vfnMCgcEXc+nqb4Mpul6haqMeYzpelue03wZGfrXBUVFGhYugq5HS+t8xK5//OiCQpCshbres9xSXwbVzxcPPw/ziXOTbgIqT+VajU481TXLdb+5p2SvYa9MKdf15ESxYU+Wy3S9XNgMe0uYU9cr1VTDXpWm6nqrVjHD3jMbNF2PLi417NFin663gl9g2FvPF/C6CcgN3jd8GU6vfqF7qg/yg4a9a9xVXY/nbxn2eP66rncfxm9j3CFRXe9zQg17lynV9W7cIIa9wAWi67Hg54Y9bfCSrndTfWDY61eHNN0E5H/b001isv6XeycEeu2zXr3t3hd+0x2jMf0v1/QFPqNXdT3B1NnNcfqeWbwDSvX7FyAPuhPQHzIfkgSGIOl6pzi+WyK6t1fxBeVwiVBd7z+O025J0vdu36Lo/YToeuqHb3QzA78G1R58AfbfZ3W9k8qFbonp58tt7REuaHd6dRMQmnrE+m7/xFnNAMtbn94HcEJ3R6Ad+Y3zXTYxx3DafsqQB2hHXJm/1TnrGByuDkMeA45coI90z+Kz5IEhTwWOvC2YdfYXaBfMxjwFR069xU3sMeCNNzhjx09Tjyhn39E9fspH7Qb3lx3pSFzU3d834+PnS8qlUPx8fFg037lLXXPrlfys1Mt0RYPYEZD43360I3Q0FNDr4LnI+WGb03TXwbnq8+P5qRcVRMHbczqk94Tf7PAHj+l6oyN9w64M+13e5KiPRRel9o8qmJv1tmQyvb9jaLBV1xsIsmE+R7orEqE+m1nGO8A4Rx9KAfJgR1dA1fUuK4lhxWS9m0lI/WIt9SeSCgjeMlmktzh+R7sU1vVuDqjD9+8Kd+c9QeqXLNHGuSgD2t/kpZ//jNvReSau68n3bg/zI3fvYs68ejpv8bgZL39yStK6X98RvdKj611VgsMSVe66IdYXcO5x9lfDL+PnpXblwo7TsUBANwHHkrDXhsGLwlDMB4vJDkpAIwmYLn0B65u9/XznJztDR0PvGx37z0XO9/IuXBwy3/WZicVOQRHlIrgkXsJJx4n+D4TOnf7gMcPe6Ehf75xM00WLbchHOYsdhILjo7A5LsE595f9gunMzqHBVsPeQJD1spzoxUdE9pnA2SkB4kTDLSKhh97r7yePdnYFVMPeZSXRGzGLF4Mc77MS2CkIooQiwAl4XbD0v83xO9ulsGHv5oDae3tAuHjvPvWJIrFTCkQiBOc/5XDsmND/n6/TnZ1n4oY9+d7tXu7+wEUt/MAHk2gnlANiEWifX4TyX6/3az1v7oxe6THsXVWCvQ9J7GJQHfFZicnOgSLC4rigfIGfJ3r7TymXdp6OBcb1JpxcuBpdBEAlvnq296HRpx9pbkqneEaffqS5KZ3iGX36keamdIpn9OlHmpvSKZ7Rpx9pbkqneEaffqS5KZ3iGX36MV7UW7wp3nhPP2ZjNmZjNmYDAP4HqVQD1I/1cCYAAAAASUVORK5CYII=");
    width: 20px;
    height: 20px;
    opacity: 1;
    display: inline-block;
}

.staticon {
    background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAAUCAYAAADRA14pAAACXUlEQVRYhe3Ru47aQABG4UMWKSGJUJRqW9JlN+yKJim59duQBwD2kShyqXBtkheghJ4KF0gICewCISxRMgg7BYYYe2ZtME0uI42EMDr6Pwz/j/S8A1L/Su9+MGCmaXy5UPQeBjPQLtYbwEzjMvvuDAPTdXGFYKNpfE0YvQPDBNcFsQEtcc8A0wVXwEYj2b68YWC5Lu7+JkTnwbB22P1NhM4bYPliidAfglgJ+tkpvTA2hD6pF8RK0LF7SmwA/S1m9AnsETp2T4UNoGP1bqOwfnS7HRm9jcb60e3IXhTWj25HoG9k2NGIZb9PazhkokB/V0Rv5NjREvotGE4UaGVPhh3Bsg+tIUwUaGnvvQy73SIKBR6833xarRAStPDQV/6eHLsVUDj0YCUkaOGhj3oy7BZEAd8+EBK08NBX7OW1GtfZLC8k/6qby/Ha+/wmlcIN/iCdhkyGt8Dz/XcpateQlfYgd+hBKtSDNJA56n2G6yyKffj2IdkHZDjeB0C9TtU0sYNv0LKwez264zGL4DPHQeg6P4GX4S31Kph2+A1aNvS6MF6EnzkCdGmvDlUT7OAbtMDuQXcMi+AzB4SOah/QaFCRoWXXw/5QxnbFihwtu44A/cleAyoytOx62Ih9MdHxsKego7GnoGNj96fZpKxCe9hO7NiuWFajHQH6Sb0mlFVoD3vivh26FEQ7DutO54zYrlgKo501dM7qNaEURDuw7pyDPUR9aA+rA6/Oiu2Kpd9oZw2dRD0/2sMm3Ac8PlKcTpknxx6KRZjOk2IPNShOYX4RrO98vGTsD+j9PecXIj9PVcetObkAAAAASUVORK5CYII=");
    width: 20px;
    height: 20px;
    opacity: 1;
    display: inline-block;
}

.helicoptericon {
    background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAADxUlEQVRIx61VXWgcVRg9d+7Mnd3Zmd1N405oE5KakLbYgDTFH5BUEFo1WJuUNkiLEkVFxSb4UEVsUCutbWPAH1y10qAP2tJa6kMJltKU+CDqKmxQMNZV2ZikSkKSNTP7Mz97fcnCMuxuNq3n8Z7vO+fe7565A6wOr3wSDM5up/RL3AS2UuAogJoSXPiYovwV13V+OhRaAnBvGY37KPAmAFJYEDwFzW+r6r49ongRQJ2H69zq96sAsFGW6TrgwRIGe48oyqdPMdZVyeTcAcOIdvh8Db2S9BWAhgJRA2yIUBpcbvL3+nxtnt7HBwOBwWnHSX1oWT0A8uVMAOBEv2Gc2MyY9jRjlwC0AMB+xjYW10cobS/a7fNDgcDAhGWlopbVBeCnYkGhzFzfP2iabzSJotQny5cAtNWLYlNxwS2iuGb57l5+V1UP/pjLzZ6y7YcAJLxitEIIxkdte+ZhWd7VLgjddaJY3yhJSoHMcb54JZttf0vT9n6dzSbPOE4XgJlSQnSFtP0yats/389Y13ZVrSNFJw8IArmbMe28aV674Lq7AMyVExFWMFkPoHHOdVPEsyGREH8mn1cuuu73ABqL0+QFKeO8+5Dff6iVsfVNkiQHBUEpJ5DjPDdt2/nfLOvvkWz2s7F8fsBbI5ZqfEKStu3WtC3VfL0yIXIzY2hm7FZFELrHDKM6k89t+1pbOp3QKQ01SVIgUOEkNufmjOPwSdv+N5bLjVc9riJsALDvPVXt71CUcIlRzW2bnU3mgD4AMQD2jVy8uV8UOzmQOT4/H8sD2QJxfmkpNriw8PuQqq7VgZ0AnBt5LFselaTYUCCQBHAAwCNXa2sX47rO47rOd1IaBaB1Uno5qml/rAPeKTf+critj7GJo4ryK4Dewui+CIdTcV3nP0QiBoD+5XXfPYJw4aSmJbcQMlytUfsLspw4oihTAHqK1tWPNG0xrut8tLZ2EcCe4pDdQcjpU8HgP3cKwjkAcsX/yYs+X+J1v38SQKeXPKYo38V1nZ8Nh1MAWr1JvZ2Q4Y81bXIHpSOVnvqWaceZfzWTeQzAiNfkuutOAsC860oAkh7aGef8ycOGcSZMSH0VoSqNTYS8Ftf1/HFF+WY1fatym+B8Lsu5Ne26U6vpqyYJzwIgD1DasFkUO1zOxRpB2PQcYx9ELetPAD4AhysJkBUdGBvuDYW6ZUJC3nqHc/OKaV5/KZ1uvamTcCD/bSZjraHU0CmlEVGUFlzXnHddOmXbbppzEf8DegCMAVgLYMddgpAA8AyAZgADAE6uJPAfk1U+b+R6xyUAAAAASUVORK5CYII=");
    width: 25px;
    height: 25px;
    opacity: 1;
    display: inline-block;
}

.sprites {
    background: url('data:image/png;base64,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');
    width: 25px;
    height: 25px;
    opacity: 1;
    display: inline-block;
}

.table-shiptype-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    vertical-align: middle;
    transform: scale(0.8);
}

#statcard {
    top: 10px;
    left: auto;
    right: 60px;
    display: none;
    z-index: var(--z-map-card);
    position: absolute;
    max-width: calc(100vw - 80px);
    background: var(--color-surface-raised);
    color: var(--color-text);
    cursor: auto;
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border-strong);
    padding: 4px 6px;
    transition: transform var(--dur-slow) ease-out;
}

/* rides with the controls: same shift, same easing, so the pair stays aligned */
#statcard.active {
    transform: translateX(calc(-1 * var(--size-panel)));
}

.statcard_inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    font-size: var(--fs-xs);
    gap: 0;
    column-gap: 2px;
    row-gap: 0;
}

.stat-item {
    display: inline-flex;
    align-items: center;
    gap: 1px;
    padding: 1px 4px;
}

/* Dimmed, not removed. Hiding an empty bucket makes the row reflow every time a
   count crosses zero - and with single-vessel buckets that is constant - while
   a category you never receive simply looks like it was never there. */
.stat-item[data-zero="true"] {
    opacity: 0.35;
}

.stat-item[data-action] {
    cursor: pointer;
    border-radius: var(--radius-sm);
}

.stat-item[data-action]:hover {
    background: var(--color-control);
}

.stat-item.stat-off {
    opacity: 0.4;
}

.stat-item.stat-off span:last-child {
    text-decoration: line-through;
}

.stat-item + .stat-item {
    border-left: 1px solid var(--color-border-strong);
    padding-left: 6px;
}

.stat-item .shipicon,
.stat-item .staticon,
.stat-item .helicoptericon {
    flex-shrink: 0;
    margin: -4px;
}

.tablecard_inner table {
    font-size: var(--fs-2xs);
    margin: 5px 0;
    color: var(--color-text);
    border: 1px solid var(--color-panel);
}

.tablecard_inner table thead {
    background-color: var(--color-panel);
    color: var(--color-text-muted);
}

/* typography comes from .col-header in components.css */
.tablecard_inner table thead>tr>th {
    border-bottom: 1px solid var(--color-border);
    text-align: left;
    padding: 10px 4px;
    border-collapse: collapse;
}

.tablecard_inner table>tbody>th,
.tablecard_inner table>tbody>td {
    border: none;
    margin: 0px;
    padding: 0px;
}

.tablecard_inner table>tbody>tr:nth-child(even) {
    background: var(--color-surface-alt);
}

.tablecard_inner table>tbody>tr:hover {
    background: var(--color-selected);
}

.tablecard_inner table th:nth-child(1),
.tablecard_inner table td:nth-child(1) {
    /* Flag */
    width: 28px;
}

.tablecard_inner table th:nth-child(2),
.tablecard_inner table td:nth-child(2) {
    /* Name */
    /* no width: Name flexes to absorb slack so other columns hold exact px */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.tablecard_inner table th:nth-child(3),
.tablecard_inner table td:nth-child(3) {
    /* Distance */
    width: 46px;
}

.tablecard_inner table th:nth-child(4),
.tablecard_inner table td:nth-child(4) {
    /* Speed */
    width: 46px;
}

.tablecard_inner table th:nth-child(5),
.tablecard_inner table td:nth-child(5) {
    /* Type */
    width: 30px;
}

.tablecard_inner table th:nth-child(6),
.tablecard_inner table td:nth-child(6) {
    /* Last */
    width: 70px;
}

.sort-icon::after {
    content: "\25B2";
    font-size: var(--fs-2xs);
    margin-left: 2px;
    vertical-align: middle;
    color: transparent;
}

.sort-icon.ascending::after {
    content: "\25B2";
    color: var(--color-text);
}

.sort-icon.descending::after {
    content: "\25BC";
    color: var(--color-text);
}

/* Shipcard styling */

.pinned {
    /* glass edge over the blurred map; translucent white in both themes */
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.2);
}

.opacity-50 {
    opacity: 0.5;
}

.mapcard {
    top: 10px;
    left: 10px;
    display: flex;
    flex-direction: column;
    justify-content: stretch;
    z-index: var(--z-card);
    position: absolute;
    visibility: hidden;
    background: var(--color-surface-raised);
    color: var(--color-text);
    cursor: auto;
    border-radius: var(--radius-md);
}

.shipcard-width {
    width: 400px;
}

.mapcard.floating {
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
}

.measurecard-width {
    width: 450px;
}

#measurecard {
    border-radius: var(--radius-lg);
    overflow: hidden;
    box-shadow: var(--shadow-lg);
    top: 16px;
    left: 16px;
}

.mapcard.visible {
    visibility: visible;
}

.mapcard_content {
    flex: 1;
    overflow: auto;
    display: flex;
    flex-direction: column;
}

.mapcard_header {
    flex: 0 0 35px;
    padding: 5px;
    margin: 5px;
    margin-top: 10px;
    font-size: var(--fs-lg);
    color: var(--color-text);
    background-color: var(--color-shipcard-header);
    align-items: center;
    display: flex;
    flex-direction: row;
    justify-content: stretch;
}

#shipcard_header_title {
    flex: 1;
}

#shipcard_header_flag {
    flex: 0 1 auto;
    margin-right: 5px;
}

.shipcard-validated {
    border-left: 10px solid var(--color-ok-strong);
}

.shipcard-not-validated {
    border-left: 10px solid var(--color-off);
}

.shipcard-dubious {
    border-left: 10px solid var(--color-error);
}

.message-badge {
    position: absolute;
    top: -4px;
    right: -4px;
    background-color: var(--color-alert);
    color: var(--overlay-ink);
    border-radius: var(--radius-circle);
    min-width: 16px;
    height: 16px;
    font-size: var(--fs-xs);
    font-weight: var(--fw-bold);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 2px;
    box-sizing: border-box;
    box-shadow: 0 1px 2px var(--color-shadow);
    z-index: var(--z-map-label);
    pointer-events: none;
}

#shipcard_footer>div {
    position: relative;
}

/* flush with the card: an inset band leaves a rim of card behind it, which
   reads as a misprint against the card's rounded corners */
.mapcard-footer {
    background-color: var(--color-menu);
    color: var(--color-text);
    flex: 0 0 60px;
    display: flex;
    flex-direction: row;
    padding: 0 5px;
    justify-content: center;
    border-radius: 0 0 var(--radius-md) var(--radius-md);
}

.mapcard.floating .mapcard-footer {
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}

.mapcard-footer>div {
    flex: 0 1 100px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    border-radius: var(--radius-lg);
    transition: var(--transition-hover);
}

@media (hover: hover) {
    .mapcard-footer>div:hover {
        cursor: pointer;
        background: var(--color-hover-overlay);
        transform: var(--hover-lift);
    }
}

.mapcard-footer>div>i {
    flex: none;
    font-size: var(--fs-2xl);
    padding: 0;
}

.mapcard-footer>div>span {
    flex: none;
    font-size: var(--fs-2xs);
    line-height: 1;
    text-align: center;
}

.mapcard-footer>div.disabled {
    opacity: 0.4;
    pointer-events: none;
}

.mapcard-footer>div.shipcard-icon-active {
    background: var(--color-hover-overlay);
    color: var(--color-accent);
}

.mapcard header>span:first-child {
    flex: 1 0 0;
}

.mapcard-header-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 1 0;
    padding: 0px;
    border-radius: var(--radius-lg);
    font-size: var(--fs-3xl);
    transition: var(--transition-hover);
    cursor: pointer;
}

@media (hover: hover) {
    .mapcard-header-icon:hover {
        cursor: pointer;
        transform: var(--hover-lift);
    }
}

.mapcard-table {
    width: 100%;
    border-collapse: collapse;
}

.mapcard-table th,
.mapcard-table td {
    line-height: 14px;
    font-size: var(--fs-2xs);
    text-align: left;
    padding: 2px 5px;
}

.mapcard-table th {
    color: var(--color-text-muted);
}

.mapcard-content-row {
    display: flex;
    flex-direction: row;
    justify-content: stretch;
    padding: 10px;
    transition: var(--transition-hover);
}

.mapcard-content-row:hover {
    cursor: pointer;
}

.mapcard-content-row>div {
    overflow: hidden;
    flex: 1;
    display: flex;
    justify-content: stretch;
    flex-direction: column;
}

/* a row whose first field needs the room of two columns, so the field beside it
   still lines up with the third column of the rows above and below */
.row-wide-first>div:first-child { flex: 2; }

.mapcard-content-row>div>span:first-child {
    color: var(--color-text-muted);
    text-transform: uppercase;
    font-size: var(--fs-2xs);
    line-height: 14px;
}

.mapcard-content-row>div>span:last-child {
    line-height: 20px;
    font-size: var(--fs-base);
    text-transform: initial;
}

.mapcard-content-row>div>span:last-child:empty:after {
    content: "-";
}

/* the !importants outrank icons.css, which sets masked icons to display: block */
.shipcard-tech-icon {
    font-size: var(--fs-sm) !important;
    cursor: help;
    color: var(--color-text-muted);
    display: inline-block !important;
    vertical-align: middle;
    margin-left: 4px;
    margin-top: -2px;
    line-height: 1;
}

.shipcard-min-only {
    display: none;
}

.shipcard-min-only.visible {
    display: inherit;
}

/* Marks a row as one the collapsed card keeps. Right edge only, so the label
   column stays flush with every other row. */
.shipcard-row-selected {
    display: flex;
    flex-direction: row;
    border-right: 3px solid var(--color-shipcard-edge);
    padding-right: 7px;   /* the border comes out of the padding */
}

/* Collapsing strips the selected class from every row, so the link back to the
   expanded card is drawn on whichever row survives: the same line, thinner. */
#shipcard:not(.shipcard-ismax) .shipcard-content-row:not(.shipcard-max-only) {
    border-right: 2px solid var(--color-shipcard-edge);
    padding-right: 8px;
}

/* Technical details popover */
.tech-popover {
    position: absolute;
    background: var(--color-surface-raised);
    color: var(--color-text);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    /* Capped by the shipcard's own stacking context (--z-card), so a token above
       that is a promise the DOM cannot keep. This only has to clear its
       siblings inside the card. */
    z-index: var(--z-sticky);
    min-width: 200px;
    max-width: 300px;
    font-size: var(--fs-sm);
    padding: 8px 12px;
}

.dim-svg {
    display: block;
    width: 100%;
    height: auto;
    overflow: visible;
}

.dim-hull {
    fill: var(--color-accent);
    fill-opacity: .10;
    stroke: var(--color-accent);
    stroke-width: 1.6;
    stroke-linejoin: round;
}

.dim-axis {
    stroke: var(--color-text-subtle);
    stroke-width: .9;
    stroke-dasharray: 4 4;
}

.dim-ext { stroke: var(--color-text-subtle); stroke-width: .7; stroke-dasharray: 2 2; }
.dim-arrow { stroke: var(--color-text-muted); stroke-width: .9; }

.dim-t {
    fill: var(--color-text-muted);
    font-size: 9.5px;
    font-family: inherit;
}


.spd-line {
    fill: none;
    stroke: var(--color-accent);
    stroke-width: 1.6;
    stroke-linejoin: round;
}

.spd-axis { stroke: var(--color-text-subtle); stroke-width: .9; }
.spd-grid { stroke: var(--color-rule); stroke-width: .8; stroke-dasharray: 3 3; }

/* Section headings inside the shipcard: a full-width band, set like the field
   labels around it so the card reads as one type system. Max-only, so a
   collapsed card stays a single compact block. */
.shipcard-section {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 6px 10px;
    background-color: var(--color-band-accent);
    color: var(--color-text-muted);
    font-size: var(--fs-2xs);
    font-weight: var(--fw-medium);
    text-transform: uppercase;
    letter-spacing: .06em;
    line-height: 14px;
    cursor: pointer;
    user-select: none;
}

.shipcard-section:hover { filter: brightness(0.97); }

.shipcard-caret-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--color-surface);
    color: var(--color-text);
    flex: none;
}

.shipcard-section:hover .shipcard-caret-chip { background: var(--color-surface-raised); }

.shipcard-section-caret {
    width: 13px;
    height: 13px;
    flex: none;
}

/* folded by the user, or empty for this vessel */
.sec-collapsed,
.sec-empty { display: none !important; }

.hist-wrap { display: block; width: 100%; }

/* Reported changes as a timeline: a rail down the left, one entry per change,
   with what it was and what it became. */
.tl {
    position: relative;
    list-style: none;
    margin: 0;
    padding: 10px 12px 8px 28px;
}

.tl::before {
    content: "";
    position: absolute;
    left: 15px;
    top: 14px;
    bottom: 14px;
    width: 1px;
    background: var(--color-rule);
}

.tl-item {
    position: relative;
    padding: 9px 0 11px;
}

.tl-item + .tl-item { border-top: 1px solid var(--color-rule); }

.tl-dot {
    position: absolute;
    left: -17px;
    top: 50%;
    transform: translateY(-50%);
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--color-surface);
    border: 2px solid var(--color-shipcard-edge);
}

.tl-head {
    position: relative;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
}

.tl-title {
    color: var(--color-text-muted);
    text-transform: uppercase;
    font-size: var(--fs-2xs);
    letter-spacing: .04em;
}

.tl-time {
    color: var(--color-text-subtle);
    font-size: var(--fs-2xs);
    white-space: nowrap;
}

.tl-vals {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 6px;
}

.tl-pill {
    color: var(--color-text);
    font-size: var(--fs-sm);
}

.tl-was { color: var(--color-text-subtle); }

.tl-arrow { color: var(--color-text-subtle); font-size: var(--fs-sm); }

.tl-firstseen {
    color: var(--color-text-subtle);
    font-size: var(--fs-2xs);
    font-style: italic;
}

.chart-grad-top { stop-color: var(--color-accent); stop-opacity: .28; }
.chart-grad-bottom { stop-color: var(--color-accent); stop-opacity: .02; }

.dim-note {
    display: block;
    padding: 10px 2px;
    color: var(--color-text-muted);
    font-size: var(--fs-sm);
    text-align: center;
}

.dim-origin { fill: var(--color-antenna); }
.dim-origin-ring { fill: none; stroke: var(--color-antenna); stroke-width: 1; opacity: .5; }
.dim-origin-line { stroke: var(--color-text-subtle); opacity: .6; }
.dim-origin-t { fill: var(--color-text-muted); }

.tech-popover > div {
    display: flex;
    justify-content: space-between;
    padding: 4px 0;
    border-bottom: 1px solid var(--color-rule);
}

.tech-popover > div:last-child {
    border-bottom: none;
}

.tech-popover > div > span:first-child {
    font-weight: var(--fw-medium);
    color: var(--color-text-muted);
}

.tech-popover > div > span:last-child {
    font-weight: var(--fw-bold);
    margin-left: 12px;
}

@media only screen and (max-width: 500px) {
    .mapcard {
        left: 0;
        top: 0;
        border-radius: 0px;
    }

    .mapcard header {
        font-size: var(--fs-base);
    }

    #measurecard {
        border-radius: 0px;
        box-shadow: none;
        top: 0;
        left: 0;
    }

    #measurecard .mapcard_header {
        flex-basis: 35px;
        font-size: var(--fs-base);
    }

    .measurecard-width {
        width: 100%;
    }

    .shipcard-width {
        width: 100%;
    }
}

@media only screen and (max-height: 800px) {
    .shipcard-ismax {
        height: 100%;
    }

    .mapcard {
        left: 0;
        top: 0;
        border-radius: 0px;
    }

    .mapcard header {
        font-size: var(--fs-base);
    }
}

/* Summary tab */
.stat-tab {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    column-gap: 25px;
    row-gap: 25px;
    max-width: min(calc(100% - 30px), 3000px);
    margin: 0 auto;
    margin-top: 10px;
    justify-content: center;
}

@media only screen and (max-width: 2250px) {
    .stat-tab {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        padding: 5px;
    }
}

@media only screen and (max-width: 1500px) {
    .stat-tab {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        padding: 5px;
    }
}

@media only screen and (max-width: 750px) {
    .stat-tab {
        grid-template-columns: repeat(1, minmax(0, 1fr));
        padding: 0px;
    }
}

.stat-panel-page {
    max-width: 750px;
    width: 100%;
}

.stat-panel {
    margin: 0px;
    background-color: var(--color-surface);
    padding: 0px;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    border: none;
}

#output_stats {
    max-height: 500px;
    overflow-y: auto;
}

@media only screen and (max-width: 750px) {
    #output_stats {
        max-height: none;
        overflow-y: visible;
    }
}

.settings-bg {
    background-color: var(--color-panel);
}

.stat-panel section {
    padding: 10px;
    margin: 0 auto;
    font-size: var(--fs-base);
}

.stat-panel section div {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}

#stat_devices .device-row {
    cursor: pointer;
}

#stat_devices .device-value {
    position: relative;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding-right: 34px;
}

#stat_devices .device-value .info_icon {
    position: absolute;
    right: 12px;
    top: 50%;
    transform: translateY(-50%);
    background-color: var(--color-text-muted);
}

#stat_devices .device-row:hover .info_icon {
    background-color: var(--color-text);
}

.stat-panel section div span:first-child {
    text-align: right;
    color: var(--color-text-muted);
    padding: 5px 20px;
    display: flex;
    flex-direction: column;
}

.stat-panel section div span:last-child {
    text-align: left;
    color: var(--color-text);
    padding: 5px 20px;
    /*font-weight: 550;*/
    overflow-x: auto;
    white-space: nowrap;
    border-left: solid 1px var(--color-stat-divider);
    scrollbar-width: thin;
    /*scrollbar-color: transparent transparent;*/
}

.stat-panel section div span:last-child::-webkit-scrollbar {
    width: 0.5rem;
}

.stat-panel section div span:last-child:empty:after {
    content: "-";
}

.blue {
    color: var(--color-secondary);
}

.green {
    color: var(--color-ok-text);
}

.red {
    color: var(--color-error);
}

.grey {
    color: var(--color-text-muted);
}

.lightgrey {
    color: var(--color-text-subtle);
}

.floating-menu {
    position: fixed;
    display: none;
    background-color: var(--color-surface-raised);
    border: 1px solid var(--color-menu-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    list-style-type: none;
    padding: 8px 0;
    /* below dialogs: a menu is opened from the page, and a modal that is up
       must stay in front of it */
    z-index: var(--z-menu);
    font-size: var(--fs-base);
    color: var(--color-text);
    width: auto;
    margin: 0;
}

.floating-menu li {
    display: flex;
    align-items: center;
    height: 24px;
    margin: auto;
    padding: 0 16px;
    cursor: pointer;
    white-space: nowrap;
}

.floating-menu .divider {
    height: 1px;
    background-color: var(--color-menu-divider);
    margin: 0.5rem 0;
    pointer-events: none;
}

/* Always in the DOM so the row keeps one width as the state flips; the check
   is the only thing that appears. */
.floating-menu li .ctx-check {
    margin-left: auto;
    padding-left: 24px;
    color: var(--color-accent);
    font-weight: var(--fw-bold);
    visibility: hidden;
}

.floating-menu li.checked .ctx-check {
    visibility: visible;
}

/* the rule sits in the margin rather than on the row, so the hover highlight
   keeps the same box a row without one has */
.floating-menu li.group-start {
    position: relative;
    margin-top: 17px;
}

.floating-menu li.group-start::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: -9px;
    height: 1px;
    background-color: var(--color-menu-divider);
}

.floating-menu li:hover {
    background-color: var(--color-menu-hover);
}

.floating-menu li.disabled {
    opacity: 0.4;
    pointer-events: none;
}

.floating-menu i {
    margin-right: 8px;
    font-size: var(--fs-lg);
    width: 16px;
}

/* Map & overlays selection dialog */
#map-menu {
    width: 300px;
    padding: 16px 18px;
}

#map-menu table {
    width: 100%;
    border-collapse: collapse;
}

#map-menu td {
    padding: 6px 0;
    vertical-align: top;
}

#map-menu td:first-child {
    white-space: nowrap;
    padding-right: 16px;
    padding-top: 9px;
    font-weight: var(--fw-medium);
    color: var(--color-text-muted);
}

#baseMapSelector {
    width: 100%;
    cursor: pointer;
}

#overlayContainer input[type="checkbox"] {
    width: 16px;
    height: 16px;
    margin: 0 9px 0 0;
    vertical-align: -3px;
    accent-color: var(--color-accent);
    cursor: pointer;
}

.overlay-row {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    margin-bottom: 6px;
}

.overlay-row .map-attribution-note {
    grid-column: 2;
    margin-top: -2px;
}

.overlay-dim {
    grid-column: 2;
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 8px;
    margin-left: 2px;
}

.overlay-dim .slider {
    width: 100%;
    margin: 0;
}

.overlay-dim-value {
    font-size: var(--fs-sm);
    font-weight: var(--fw-normal);
    color: var(--color-text-muted);
    min-width: 32px;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.overlay-row.overlay-off .overlay-dim {
    display: none;
}

#overlayContainer {
    display: block;
    max-height: 42vh;
    overflow-y: auto;
    overscroll-behavior: contain;
}

#overlayContainer label {
    cursor: pointer;
    line-height: 1.5;
}

#overlayContainer label:hover {
    color: var(--color-accent);
}

/* Meteo Tooltip Styling */
.meteo-tooltip {
    margin-top: 0;
    padding: 4px 8px 6px;
    max-width: 280px;
    color: inherit;
    border-top: 1px solid currentColor;
    border-top-color: var(--color-rule);
}

/* .band / .band-slot / .band-title live in components.css */

/* same treatment as .dialog-header .close_icon in components.css */
.settings_header>.close_icon {
    flex: none;
    align-self: center;
    display: flex;
    align-items: center;
    color: var(--color-icon);
    font-size: var(--fs-lg);
    margin: 0 16px 0 12px;
    cursor: pointer;
    transition: opacity var(--dur-fast) ease;
}

.settings_header>.close_icon:hover {
    opacity: 0.65;
}

.dialog-title-hint {
    font-size: var(--fs-sm);
    font-weight: var(--fw-normal);
    color: var(--color-text-muted);
    margin-left: 6px;
}

.kv-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--fs-md);
}

.kv-table td {
    padding: 6px 14px;
    border-top: 1px solid var(--color-border);
    vertical-align: top;
}

.kv-table tr:first-child td {
    border-top: none;
}

.kv-table .kv-key {
    color: var(--color-text-muted);
    white-space: nowrap;
    padding-left: 0;
    border-right: 1px solid var(--color-border);
}

.kv-table .kv-value {
    overflow-wrap: anywhere;
}

.kv-empty {
    color: var(--color-text-muted);
}

.dialog-message {
    padding: 15px 20px 25px;
    font-size: var(--fs-base);
    user-select: text;
    overflow-y: auto;
    flex: 1 1 auto;
    min-height: 0;
    box-sizing: border-box;
}

/* Binary Messages Dialog Styling */
.binary-messages-list {
    padding: 10px 0;
}

.binary-message-count {
    font-size: var(--fs-base);
    color: var(--color-text);
    margin-bottom: 15px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--color-border);
    display: none;
    /* Hide this since we'll show count in title */
}

.binary-message-item {
    padding: 12px;
    margin-bottom: 15px;
    border-radius: var(--radius-md);
    background-color: var(--color-surface-alt);
}

.binary-message-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
    font-size: var(--fs-base);
}

.binary-message-time {
    font-weight: var(--fw-bold);
    color: var(--color-text);
}

.binary-message-source {
    color: var(--color-active);
}

.binary-message-details {
    margin-top: 10px;
    font-size: var(--fs-base);
    background-color: var(--color-surface);
    border-radius: var(--radius-sm);
}

.binary-raw-data {
    margin-top: 10px;
}

.binary-raw-data summary {
    cursor: pointer;
    font-size: var(--fs-sm);
    color: var(--color-text-muted);
    padding: 5px 0;
}

.binary-raw-data pre {
    margin-top: 10px;
    padding: 10px;
    background-color: var(--color-surface);
    border-radius: var(--radius-sm);
    font-size: var(--fs-sm);
    overflow-x: auto;
    white-space: pre-wrap;
    word-break: break-word;
}

/* Mobile Adjustments */
@media only screen and (max-width: 600px) {
    .dialog-title {
        font-size: var(--fs-lg);
        padding: 12px 15px;
    }

    .dialog-message {
        padding: 12px 15px;
        font-size: var(--fs-md);
    }

    .binary-message-item {
        padding: 8px;
    }

    .meteo-tooltip {
        max-width: 250px;
    }
}

.can-copy {
    user-select: text;
}

.showflex {
    display: flex;
}


.flash-up {
    opacity: 0;
    animation: flash var(--dur-slow) ease forwards;
}

@keyframes flash {
    0% {
        opacity: 0;
    }

    100% {
        opacity: 1;
    }
}

.color-picker {
    -webkit-appearance: none;
    border-radius: 0;
    border: none;
    width: 100px;
    height: 20px;
    cursor: pointer;
    vertical-align: middle;
    background-color: transparent;
}

.color-picker::-webkit-color-swatch-wrapper {
    padding: 0;
}

.color-picker::-webkit-color-swatch {
    border: none;
}

.tableside_window {
    display: flex;
    flex-direction: column;
    background-color: var(--color-panel);
    width: var(--size-panel);
    height: calc(100% - var(--size-header-tall));
    top: var(--size-header-tall);
    right: 0px;
    position: fixed;
    z-index: var(--z-panel);
    border: 1px solid var(--color-panel);
    padding: 0px;
    margin: 0px;
    transform: translateX(calc(var(--size-panel) + 2px));
    visibility: hidden;
    transition: transform var(--dur-slow) ease-out, visibility 0s linear var(--dur-slow);
}

.tableside_window.active {
    transform: translateX(0);
    visibility: visible;
    transition: transform var(--dur-slow) ease-out, visibility 0s;
    box-shadow: var(--shadow-panel);
}

.settings_window {
    display: flex;
    flex-direction: column;
    background-color: var(--color-panel);
    width: var(--size-panel-wide);
    height: 100%;
    top: 0px;
    left: 0px;
    position: absolute;
    /* above the map controls: unlike the ship table, they do not slide aside
       for this panel, and it goes full width under 750px */
    z-index: var(--z-panel-top);
    border: 1px solid var(--color-panel);
    border-radius: var(--radius-md);
    padding: 0px;
    margin: 0px;
    transform: translateX(-110%);
    visibility: hidden;
    transition: transform var(--dur-slow) ease-out, visibility 0s linear var(--dur-slow);
}

.settings_window.active {
    transform: translateX(0);
    visibility: visible;
    transition: transform var(--dur-slow) ease-out, visibility 0s;
    box-shadow: var(--shadow-panel);
}

@media (max-width: 750px) {
    .settings_window {
        width: 100%;
        transform: translateX(-100%);
    }
}

.settings_main {
    overflow: auto;
    font-size: var(--fs-base);
    flex: 1 1 auto;
}

/* --color-control is its own light/dark pair, so no .dark override is needed */
.settings_main select,
.settings_main section div>span[data-action],
.settings_main section div.filter-checks {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    align-self: stretch;
    gap: 2px 20px;
    margin: 4px 0 2px;
    padding: 8px 12px;
    border-radius: var(--radius-md);
    background: var(--color-band-soft);
}

.settings_main section div.filter-allnone {
    flex-direction: row;
    align-self: flex-start;
    gap: 8px;
    margin: 6px 0 0;
}

.settings_main section div.filter-allnone button {
    padding: 0;
    font-size: var(--fs-sm);
    background: none;
    border: none;
    color: var(--color-accent);
    cursor: pointer;
    width: auto;
}

.settings_main section div.filter-allnone button:hover {
    text-decoration: underline;
}

.filter-check {
    display: flex;
    align-items: center;
    gap: 12px;
    font-size: var(--fs-base);
    white-space: nowrap;
    cursor: pointer;
    padding: 7px 6px;
    margin: 0 -6px;
    border-radius: var(--radius-sm);
}

.filter-check:hover {
    background: var(--color-band-accent);
}

.settings_main .filter-check input[type="checkbox"] {
    appearance: auto;
    -webkit-appearance: auto;
    width: 15px;
    height: 15px;
    min-width: 0;
    margin: 0;
    padding: 0;
    border: none;
    border-radius: 0;
    background: none;
    accent-color: var(--color-accent);
    cursor: pointer;
}

.settings_main .filter-check input[type="checkbox"]::before,
.settings_main .filter-check input[type="checkbox"]::after {
    content: none;
}

.filter-check .shipicon,
.filter-check .staticon,
.filter-check .helicoptericon {
    flex: none;
    margin: -2px 2px;
}

.filter-topbar {
    flex-direction: row !important;
    align-items: center !important;
    justify-content: space-between;
    gap: 12px;
}

#filter_summary {
    font-size: var(--fs-sm);
    color: var(--color-text-muted);
}

#filter_summary.filter-on {
    color: var(--color-accent);
    font-weight: 600;
}

.settings_main section div.dualrange {
    align-self: stretch;
    display: block;
    margin: 0;
}

.settings_main section div.dr-track {
    display: block;
    position: relative;
    height: 24px;
    margin: 0;
}

.settings_main section div.dr-fill {
    margin: 0;
}

.dr-track::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 8px;
    height: 8px;
    border-radius: var(--radius-lg);
    background: var(--color-track);
}

.dr-fill {
    position: absolute;
    top: 8px;
    height: 8px;
    border-radius: var(--radius-lg);
    background: var(--color-accent);
    opacity: 0.25;
}

.dr-track input[type="range"] {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 24px;
    margin: 0;
    background: none;
    pointer-events: none;
    appearance: none;
    -webkit-appearance: none;
}

.dr-track input[type="range"]::-webkit-slider-runnable-track {
    background: none;
    border: none;
    height: 24px;
}

.dr-track input[type="range"]::-moz-range-track {
    background: none;
    border: none;
    height: 24px;
}

.dr-track input[type="range"]::-webkit-slider-thumb {
    pointer-events: auto;
    appearance: none;
    -webkit-appearance: none;
    width: 16px;
    height: 16px;
    margin-top: 4px;
    border: none;
    border-radius: var(--radius-circle);
    background: var(--color-accent);
    box-shadow: 0 1px 2px var(--color-shadow-soft);
    cursor: pointer;
}

.dr-track input[type="range"]::-moz-range-thumb {
    pointer-events: auto;
    width: 16px;
    height: 16px;
    border: none;
    border-radius: var(--radius-circle);
    background: var(--color-accent);
    box-shadow: 0 1px 2px var(--color-shadow-soft);
    cursor: pointer;
}

.dr-track input[type="range"]:hover::-webkit-slider-thumb {
    box-shadow: 0 1px 2px var(--color-shadow-soft), 0 0 0 2px var(--color-accent);
}

.dr-track input[type="range"]:hover::-moz-range-thumb {
    box-shadow: 0 1px 2px var(--color-shadow-soft), 0 0 0 2px var(--color-accent);
}

.settings_main button:not(.tab-scroll-btn) {
    background-color: var(--color-control);
}

/* typography comes from .col-header in components.css */
.settings_main>header {
    margin: 18px 16px 4px;
    padding: 0 0 4px;
    max-width: none;
    width: auto;
    border: none;
    border-bottom: 1px solid var(--color-border);
    border-radius: 0;
    background: none;
    text-align: left;
}

/* .tab-scroll-wrap / .tab-scroll-btn live in components.css */
.settings_nav {
    position: sticky;
    top: 0;
    background: var(--color-panel);
    --tab-fade: var(--color-panel);
    z-index: var(--z-base);
}

.tab-scroll-wrap .settings_tabs {
    padding: 0 0.3rem 0 0.6rem;
}

/* .tabs / .tab live in components.css, shared with the control hub */

.settings_header .settings_tabs {
    border-bottom: none;
    padding: 0 0.3rem;
    align-self: stretch;
    align-items: stretch;
    font-size: var(--fs-base);
    min-width: 0;
}

/* the header strip sits on the swoosh, so the arrows must fade into that */
.settings_header .tab-scroll-wrap {
    flex: 1 1 0;
    min-width: 0;
    align-self: stretch;
    --tab-fade: var(--color-band-accent);
}

.settings_header .settings_tab {
    display: flex;
    align-items: center;
}

.settings_subtabs .settings_tab {
    padding: 0.55rem 0.65rem;
}


/* .fieldset / .field / .field-label / .field-desc live in components.css;
   these are the viewer's own section chrome */
.settings_main section div {
    align-items: flex-start;
}

.settings_main section {
    margin: 0 1.25rem;
    padding: 1rem 0 0.5rem;
    border-top: 1px solid var(--color-border);
    font-size: inherit;
}

.settings_main section.st-first {
    border-top: none;
}

.settings_main .st-break {
    flex: 1 1 100%;
    height: 0;
    margin: 0;
    padding: 0;
}

.settings_main .st-title {
    flex: 1 1 100%;
    margin: 0 0 var(--space-1) 2px;
    font-size: var(--fs-sm);
    font-weight: var(--fw-semibold);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--color-text-muted);
}


.settings_main section>div.third {
    flex: 0 1 calc(33.333% - 0.5rem);
    white-space: nowrap;
}

.settings_main section>div.half {
    flex: 0 1 calc(50% - 0.375rem);
    white-space: nowrap;
}

.settings_main section>div.quarter {
    flex: 0 1 calc(25% - 0.5625rem);
    white-space: nowrap;
}

.settings_main section>div.threequarter {
    flex: 1 1 calc(75% - 0.5625rem);
}

@media (max-width: 480px) {

    .settings_main section>div.half,
    .settings_main section>div.threequarter {
        flex-basis: 100%;
    }

    .settings_main section>div.third,
    .settings_main section>div.quarter {
        flex-basis: calc(50% - 0.375rem);
    }

    .settings_main section>div {
        white-space: normal;
    }

    .settings_main button {
        max-width: 100%;
    }
}

.settings_main section div span:nth-of-type(2) {
    padding: 0;
    border-left: none;
    display: flex;
    align-items: center;
    width: 100%;
    color: var(--color-text);
}

/* .input / .select / .toggle / .slider / .btn live in components.css; these are
   the viewer's own sizing, which differs from the hub's full-width fields */
.settings_main select {
    max-width: 100%;
}

.settings_main button:not(.tab-scroll-btn),
.settings_main section div>span[data-action] {
    /* re-asserted after .settings_main section div span:nth-of-type(2), which
       zeroes padding/border-left for the generic control slot */
    padding: 8px 16px;
    border-left: 1px solid var(--color-field-border);
    width: fit-content;
    min-width: 7rem;
    max-width: 100%;
    text-align: center;
    margin: 0;
}

.settings_main select,
.settings_main input[type="range"] {
    width: 100%;
}

/* range-input track/thumb styling is shared with the hub in components.css */

/* Preview of the speed palette: the gradient the map draws tracks with. The
   generic field rule would make a stretching column of it, hence the sizing.
   The margins pad the 14px band out to the 28px box of the slider beside it,
   so both columns' descriptions sit on the same line. */
.settings_main .speed-legend {
    flex: 0 0 auto;
    width: 100%;
    height: 12px;
    margin: 7px 0;
    border: 1px solid var(--color-field-border);
    border-radius: var(--radius-md);
}

/* border/radius/shadow come from the shared field styling in components.css */
.settings_main .color-picker {
    width: 110px;
    height: 32px;
    padding: 4px;
    background: var(--color-surface-raised);
}

.settings_main .color-picker::-webkit-color-swatch {
    border-radius: var(--radius-md);
}

.settings_main section div>span[data-action]:hover,
.settings_main button:not(.tab-scroll-btn):hover,
.settings_main .color-picker:hover,
.settings_main select:hover {
    border-color: var(--color-accent);
}


/* .band / .band-slot live in components.css, shared with the control hub */
.settings_header {
    flex-direction: row;
    position: relative;
    z-index: var(--z-sticky);
}

.settings_header .hdr-slot {
    padding: 0;
}

.tableside_window .settings_header .hdr-slot {
    padding: 0 20px 0 1rem;
}

.settings_header .search-box {
    font-size: var(--fs-md);
    height: 32px;
    padding: 5px 12px 5px 34px;
    background-position: 10px center;
    margin: 0;
    background-color: var(--color-band-accent);
    max-width: 320px;
}

/* chrome, focus and placeholder come from .input; only the glyph and the
   compact sizing live here */
.search-box {
    width: 100%;
    height: 38px;
    padding: 5px 12px 5px 36px;
    margin: 2px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23999' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: 12px center;
    background-size: 15px;
    max-width: 500px;
    font-size: var(--fs-md);
}

.ship-table-column-dropdown {
    position: relative;
    flex-shrink: 0;
    margin-left: 8px;
}

/* chrome from .btn; compact sizing to match the search box beside it */
.ship-table-columns-btn {
    gap: 7px;
    height: 38px;
    padding: 0 12px;
}

@media (max-width: 700px) {
    .ship-table-columns-btn span {
        display: none;
    }

    .ship-table-columns-btn {
        gap: 4px;
        padding: 0 10px;
    }
}

#shipTableFilterBtn {
    margin-left: auto;
}

.search-container .search-box {
    margin-right: 12px;
}

#shipTableFilterBtn.filter-on {
    color: var(--color-accent);
    border-color: var(--color-accent);
}

.ship-table-columns-btn .chevron {
    color: var(--color-text-muted);
}

.ship-table-column-dropdown-menu {
    display: none;
    position: fixed;
    background-color: var(--color-surface-raised);
    color: var(--color-text);
    font-size: var(--fs-md);
    min-width: 220px;
    border: 1px solid var(--color-menu-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
    z-index: var(--z-panel);
}

/* typography comes from .col-header in components.css */
.column-menu-header {
    padding: 10px 14px;
    border-bottom: 1px solid var(--color-menu-border);
}

.column-menu-list {
    max-height: 280px;
    overflow-y: auto;
    padding: 6px;
}

.ship-table-column-dropdown-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 10px;
    border-radius: var(--radius-md);
    cursor: pointer;
}

.ship-table-column-dropdown-item:hover {
    background-color: var(--color-menu-hover);
}

.ship-table-column-dropdown-item input {
    margin: 0;
    width: 15px;
    height: 15px;
    accent-color: var(--color-accent);
    cursor: pointer;
}

.dark .tabulator .tabulator-footer {
    background: var(--color-surface-alt);
    color: var(--color-text);
    border-top: 1px solid var(--color-border);
}

.dark .tabulator .tabulator-footer .tabulator-page,
.dark .tabulator .tabulator-footer .tabulator-page-size {
    background: var(--color-control);
    color: var(--color-text);
    border-color: var(--color-field-border);
}

.dark .tabulator .tabulator-footer .tabulator-page.active {
    color: var(--color-highlight);
}

.dark .tabulator .tabulator-footer .tabulator-paginator>label {
    color: var(--color-text);
}

.column-menu-footer {
    border-top: 1px solid var(--color-menu-border);
    padding: 8px;
}

/* chrome from .btn-quiet; full-width row inside the menu */
.column-menu-reset {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 8px 10px;
    border-radius: var(--radius-md);
    font-size: var(--fs-md);
}

.column-menu-reset:hover {
    background-color: var(--color-menu-hover);
    color: var(--color-accent);
}

.info-panel {
    position: fixed;
    top: 0;
    right: 0;
    width: var(--size-panel-narrow);
    height: 100%;
    background: var(--color-panel);
    color: var(--color-text);
    box-shadow: var(--shadow-panel);
    font-size: var(--fs-md);
    transform: translateX(100%);
    transition: transform var(--dur-slow) ease;
    z-index: var(--z-info);
    display: flex;
    flex-direction: column;
}

.info-panel.active {
    transform: translateX(0);
}

.overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: var(--color-scrim);
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--dur-slow), visibility var(--dur-slow);
    z-index: var(--z-overlay);
}

.overlay.active {
    opacity: 1;
    visibility: visible;
}

/* a .band in brand colors: taller, no rule under it */
.header-info-panel {
    align-items: center;
    height: var(--size-header-tall);
    background: var(--color-brand);
    border-bottom: none;
}

.header-info-panel .info-title {
    background: var(--color-brand-accent);
    font-size: var(--fs-xl);
    color: var(--color-brand-ink);
}

.header-info-panel .close_icon {
    cursor: pointer;
    border: none;
    color: var(--color-brand-ink);
    margin: 0 10px 0 12px;
    font-size: var(--fs-xl);
    padding: 0;
    width: 35px;
    height: 35px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-circle);
    background: none;
    transition: var(--transition-hover);
}

.header-info-panel .close_icon::before {
    content: "";
    width: 18px;
    height: 18px;
    background-color: currentColor;
    -webkit-mask-image: var(--svg);
    mask-image: var(--svg);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-size: 100% 100%;
    mask-size: 100% 100%;
}

.header-info-panel .close_icon:hover {
    transform: var(--hover-lift);
}

.info-panel .content {
    padding: 20px 16px;
    overflow-y: auto;
    flex: 1;
}

.quick-links {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 14px;
    margin-bottom: 22px;
}

.quick-link {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    text-decoration: none;
    color: var(--color-text);
    padding: 12px 8px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    font-size: var(--fs-sm);
    transition: background var(--dur-med);
    cursor: pointer;
}

.quick-link svg {
    width: 28px;
    height: 28px;
    fill: currentColor;
}

.quick-link svg path[fill="#d1d5db"] {
    fill: currentColor;
}

.quick-link:hover {
    border-color: var(--color-accent);
    color: var(--color-text);
    text-decoration: none;
}

.quick-link span {
    margin-top: 4px;
}

.info-panel-section {
    margin-bottom: 22px;
}

.link-list {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.link-list a {
    padding: 12px 14px;
    border-bottom: 1px solid var(--color-border);
    text-decoration: none;
    color: var(--color-text);
    transition: background var(--dur-med);
}

.link-list a:last-child {
    border-bottom: none;
}

.link-list a:hover {
    color: var(--color-accent);
    text-decoration: none;
}

.link-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.link-item span {
    display: inline-flex;
    align-items: center;
}

.link-item .arrow_right_alt_icon {
    margin-left: auto;
    font-size: var(--fs-2xl);
    color: var(--color-text-muted);
}

.social-box {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: 14px 16px;
}

.social-links {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.social-links > span {
    font-size: var(--fs-md);
    font-weight: var(--fw-medium);
    color: var(--color-text);
}

.social-links > a {
    display: inline-flex;
    gap: 16px;
}

.social-icons {
    display: flex;
    gap: 16px;
}

.social-icons a {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    color: var(--color-icon);
    transition: color var(--dur-med), transform var(--dur-med);
}

.social-icons a:hover {
    transform: var(--hover-lift);
}

.social-icons a svg path[fill="#d1d5db"] {
    fill: currentColor;
}

.social-icons a svg {
    width: 26px;
    height: 26px;
}

.log-viewer {
    display: flex;
    flex-direction: column;
    height: 100%;
}

.log-state-indicator {
    padding: var(--space-2) var(--space-4);
    color: var(--color-text-muted);
    font-size: var(--fs-base);
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.log-content-container {
    flex: 1;
    overflow-y: auto;
    padding: var(--space-4);
}

.log-content {
    margin: 0;
    font-family: var(--font-sans);
    font-size: var(--fs-base);
    line-height: 1.5;
    white-space: pre-wrap;
    word-break: break-word;
}

.log-entry {
    display: flex;
    gap: var(--space-2);
    margin-bottom: var(--space-2);
    align-items: flex-start;
}

.log-entry.info {
    color: var(--color-text);
}

.log-entry.warning {
    background-color: var(--color-log-warn);
    color: var(--overlay-ink);
    padding: var(--space-2);
    border-radius: var(--radius-sm);
}

.log-entry.error {
    background-color: var(--color-log-error);
    color: var(--overlay-ink);
    padding: var(--space-2);
    border-radius: var(--radius-sm);
}

.log-entry.error .timestamp,
.log-entry.warning .timestamp {
    color: var(--color-log-ink);
}

.log-entry.info .timestamp {
    color: var(--color-timestamp);
}

.realtime-viewer {
    display: flex;
    flex-direction: column;
    height: 100%;
}

.realtime-tabs {
    display: flex;
    gap: var(--space-2);
    padding: var(--space-1) var(--space-4) 0 var(--space-4);
    border-bottom: 1px solid var(--color-border);
    align-items: center;
}

.realtime-filter-bar {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-4);
    background: var(--color-surface-raised);
    border-bottom: 1px solid var(--color-border);
    color: var(--color-text);
    font-size: var(--fs-base);
}

.realtime-filter-bar i.filter_list_icon {
    font-size: var(--fs-lg);
    color: var(--color-text-muted);
}

.realtime-filter-bar .filter-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    flex: 1;
}

/* .realtime-filter-input joins .input / .select in components.css; the add and
   clear buttons are .btn. All three sit on the control surface. */
.realtime-filter-input,
.realtime-filter-add,
.realtime-filter-clear {
    background-color: var(--color-control);
    color: var(--color-text-strong);
}

/* primary affordance of the row: accent-bordered even at rest */
.realtime-filter-add {
    border-color: var(--color-accent);
}

.realtime-filter-row {
    display: flex;
    gap: var(--space-2);
    align-items: center;
}

.realtime-filter-row .realtime-filter-input:nth-child(2) {
    flex: 1;
}

.realtime-filter-active {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    margin-top: var(--space-4);
}

.realtime-filter-active .filter-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    flex: 1;
}

.realtime-filter-none,
.realtime-filter-hint {
    margin-top: var(--space-4);
    color: var(--color-text-muted);
    font-size: var(--fs-md);
}

.realtime-control-btn span.realtime-filter-count {
    display: none;
    position: absolute;
    top: 3px;
    right: 1px;
    min-width: 15px;
    height: 15px;
    padding: 0 3px;
    border-radius: var(--radius-full);
    font-size: var(--fs-2xs);
    font-weight: var(--fw-semibold);
}

.realtime-control-btn.active span.realtime-filter-count {
    display: flex;
    background: var(--color-accent);
    color: var(--color-surface);
}

.filter-chip-kind {
    color: var(--color-text-muted);
    font-size: var(--fs-sm);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.filter-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: var(--space-1) var(--space-2);
    background: var(--color-surface-raised);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    color: var(--color-text);
    font-size: var(--fs-md);
}

/* one inline icon-button idiom for the chip remove and table clear */
.filter-chip button,
.realtime-clear-btn {
    padding: 0;
    margin-left: 3px;
    background: transparent;
    border: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: opacity var(--dur-med) ease;
    color: var(--color-alert);
    width: 20px;
    height: 20px;
}

.filter-chip button {
    color: var(--color-text-muted);
}

.filter-chip button:hover {
    color: var(--color-text-strong);
}

.filter-chip button i {
    font-size: var(--fs-sm);
}

.realtime-spacer {
    flex: 1;
}

.realtime-clear-btn:hover {
    opacity: 0.7;
}

.realtime-clear-btn i {
    font-size: var(--fs-base);
}

/* chrome from .btn-quiet; a fixed square with its own hover accent */
.realtime-control-btn {
    position: relative;
    border-radius: var(--radius-sm);
    color: var(--color-text);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background var(--dur-med) ease, color var(--dur-med) ease;
    width: 40px;
    height: 40px;
}

.realtime-control-btn:hover {
    background: var(--color-menu-hover);
    color: var(--color-accent);
}

.realtime-control-btn span {
    font-size: var(--fs-2xl);
    display: flex;
    align-items: center;
    justify-content: center;
}

.realtime-background-toggle {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-left: var(--space-4);
    font-size: var(--fs-base);
    cursor: pointer;
    color: var(--color-text);
    user-select: none;
}

.realtime-background-toggle input[type="checkbox"] {
    cursor: pointer;
    width: 16px;
    height: 16px;
}

.realtime-background-toggle:hover {
    color: var(--color-accent);
}

.realtime-panel {
    flex: 1;
    overflow: auto;
    padding: var(--space-4);
}

.signal-table {
    width: max-content;
    min-width: 100%;
    border-collapse: collapse;
    font-size: var(--fs-base);
}

/* typography comes from .col-header in components.css */
.signal-table thead th {
    position: sticky;
    top: 0;
    background: var(--color-surface-raised);
    padding: var(--space-3);
    text-align: left;
    border-bottom: 2px solid var(--color-border-strong);
}

.signal-table tbody td {
    padding: var(--space-3);
    border-bottom: 1px solid var(--color-border);
    color: var(--color-text);
    white-space: nowrap;
}

.signal-table tbody tr:hover {
    background: var(--color-menu-hover);
}

.signal-table tbody td a {
    color: var(--color-accent);
    text-decoration: none;
}

.signal-table tbody td a:hover {
    text-decoration: underline;
}

.nmea-cell-content {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.nmea-decoder-icon {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    cursor: pointer;
    background: transparent;
    transition: background var(--dur-med) ease;
    font-size: var(--fs-base);
}

.nmea-decoder-icon:hover {
    background: var(--color-menu-hover);
}

.nmea-decoder-icon i {
    font-size: var(--fs-base);
}

.nmea-text {
    flex: 1;
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    white-space: nowrap;
}

.channel-indicator {
    display: flex;
    gap: 2px;
}

.channel-box {
    display: inline-block;
    width: 16px;
    height: 16px;
    background-color: var(--color-off);
    color: transparent;
    text-align: center;
    line-height: 16px;
    font-size: var(--fs-2xs);
    font-weight: var(--fw-bold);
    border-radius: var(--radius-sm);
}

.channel-box.active {
    background-color: var(--color-on);
    color: var(--color-accent-ink);
}

.nmea-mmsi {
    display: inline-block;
    padding: 2px 6px;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: var(--fs-sm);
}

/* glass disc over the map: translucent in both themes on purpose */
.aiscatcher-logo-control {
    background: rgba(0, 0, 0, 0.1) !important;
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
    border: 1px solid rgba(255, 255, 255, 0.1) !important;
    border-radius: var(--radius-circle) !important;
    cursor: pointer;
    transition: background var(--dur-slow) ease;
    width: 60px !important;
    height: 60px !important;
    padding: 5px !important;
    display: flex;
    align-items: center !important;
    justify-content: center !important;
}

.aiscatcher-logo-control:hover {
    background: rgba(0, 0, 0, 0.2) !important;
    backdrop-filter: blur(5px);
    -webkit-backdrop-filter: blur(5px);
}

.aiscatcher-logo-control.disconnected svg path {
    fill: var(--color-alert) !important;
}

.aiscatcher-logo-control.connected svg path {
    fill: var(--color-secondary) !important;
}

/* NMEA Decoder Styles */
.decoder-container {
    display: flex;
    flex-direction: column;
    gap: 20px;
    padding: 20px;
    max-width: 1200px;
    margin: 0 auto;
}

.decoder-panel,
.decoder-message {
    background: var(--color-surface-overlay);
    border: 1px solid var(--color-rule);
    border-radius: var(--radius-lg);
    padding: 20px;
}

.decoder-panel h3 {
    margin-top: 0;
    color: var(--color-text);
    font-size: var(--fs-base);
}

.decoder-panel p {
    color: var(--color-text-muted);
    margin-bottom: 15px;
    font-size: var(--fs-base);
}

#decoder_input {
    width: 100%;
    min-height: 150px;
    padding: 10px;
    font-family: var(--font-mono);
    font-size: var(--fs-base);
    border: 1px solid var(--color-field-border);
    border-radius: var(--radius-lg);
    resize: vertical;
    /* same sheet as .decoder-panel so the field reads as part of the panel */
    background: var(--color-surface-overlay);
    color: var(--color-text);
    box-sizing: border-box;
}

#decoder_input:focus {
    outline: none;
    border-color: var(--color-accent);
    box-shadow: 0 0 0 3px var(--color-focus-ring);
}

.decoder-buttons {
    display: flex;
    gap: 10px;
    margin-top: 15px;
}

/* the example is a hint, not content: keep it clearly below body text */
#decoder_input::placeholder {
    color: var(--color-text-subtle);
    opacity: 1;
}

.decoder-status {
    margin-top: 15px;
    font-size: var(--fs-base);
}

.decoder-error {
    color: var(--color-danger);
}

.decoder-success {
    color: var(--color-success);
}

.decoder-warning {
    color: var(--color-warning);
}

.decoder-info {
    color: var(--color-text-muted);
}

.decoder-output {
    display: flex;
    flex-direction: column;
    gap: 15px;
}

.decoder-message h4 {
    margin-top: 0;
    margin-bottom: 15px;
    color: var(--color-text);
    border-bottom: 1px solid var(--color-rule);
    padding-bottom: 8px;
    font-size: var(--fs-base);
}

.decoder-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--fs-base);
}

.decoder-table tr {
    border-bottom: 1px solid var(--color-rule);
}

.decoder-table tr:last-child {
    border-bottom: none;
}

.decoder-table td {
    padding: 8px 10px;
}

.decoder-field-key {
    color: var(--color-text-muted);
    width: 25%;
    font-family: inherit;
    text-align: right;
}

.decoder-field-value {
    color: var(--color-text);
    font-family: var(--font-mono);
    width: 35%;
    border-left: solid 1px var(--color-rule);
    padding-left: 20px;
    overflow-wrap: anywhere;
}

.decoder-field-description {
    color: var(--color-text-muted);
    width: 40%;
    padding-left: 15px;
}

@media (max-width: 768px) {
    .decoder-container {
        padding: 10px;
    }

    .decoder-panel,
    .decoder-message {
        padding: 15px;
    }

    .decoder-field-key {
        width: 50%;
    }
}
/* ---------------------------------------------------------------------------
   Replay transport bar — a floating capsule pinned to the bottom of the map.
   Hidden until the replay feature is opened.
   --------------------------------------------------------------------------- */

#replaybar {
    position: absolute;
    bottom: 24px;
    left: 50%;
    transform: translateX(-50%) translateY(8px);
    z-index: var(--z-card);

    display: none;
    align-items: center;
    gap: 12px;

    width: min(460px, calc(100% - 32px));
    padding: 8px 14px;
    box-sizing: border-box;

    border-radius: var(--radius-full);
    background: color-mix(in srgb, var(--color-surface-raised) 82%, transparent);
    backdrop-filter: blur(20px) saturate(180%);
    -webkit-backdrop-filter: blur(20px) saturate(180%);
    box-shadow: var(--shadow-lg);
    color: var(--color-text);

    opacity: 0;
    transition: opacity 160ms ease, transform 160ms ease;
}

#replaybar.visible {
    display: flex;
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}

#replaybar button {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--color-text);
    cursor: pointer;
}

#replaybar button:disabled {
    opacity: 0.4;
    cursor: default;
}

#replaybar svg {
    width: 20px;
    height: 20px;
    fill: currentColor;
}

.replaybar-play {
    width: 32px;
    height: 32px;
}

/* one button, three glyphs — which shows depends on state on #replaybar */
.replay-icon-pause,
.replay-icon-wait {
    display: none;
}

#replaybar.playing .replay-icon-play {
    display: none;
}

#replaybar.playing .replay-icon-pause {
    display: block;
}

#replaybar.loading .replay-icon-play,
#replaybar.loading .replay-icon-pause {
    display: none;
}

#replaybar.loading .replay-icon-wait {
    display: block;
    animation: replay-spin 900ms linear infinite;
}

@keyframes replay-spin {
    to {
        transform: rotate(360deg);
    }
}

.replaybar-labels {
    width: 28px;
    height: 28px;
    color: var(--color-text-muted);
}

.replaybar-labels.on {
    color: var(--color-accent);
    background: color-mix(in srgb, var(--color-accent) 16%, transparent);
    border-radius: var(--radius-full);
}

/* one button, two glyphs — open label when on, slashed when off */
.replay-icon-labels-on {
    display: none;
}

.replaybar-labels.on .replay-icon-labels-on {
    display: block;
}

.replaybar-labels.on .replay-icon-labels-off {
    display: none;
}

.replaybar-time {
    flex-shrink: 0;
    min-width: 52px;
    font-size: 12px;
    font-variant-numeric: tabular-nums;
    color: var(--color-text-muted);
    text-align: center;
    user-select: none;
}

/* the wall-clock stamp is the wider of the two, and can carry a date */
#replayElapsed {
    min-width: 76px;
    color: var(--color-text);
}

/* the track is a thin rail that thickens on hover, Apple-style */
.replaybar-track {
    position: relative;
    flex: 1;
    height: 20px;
    display: flex;
    align-items: center;
}

.replaybar-track::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    height: 4px;
    border-radius: var(--radius-full);
    background: color-mix(in srgb, var(--color-text) 18%, transparent);
    transition: height 120ms ease;
}

.replaybar-fill {
    position: absolute;
    left: 0;
    width: 0;
    height: 4px;
    border-radius: var(--radius-full);
    background: var(--cyan-500);
    pointer-events: none;
    transition: height 120ms ease;
}

.replaybar-track:hover::before,
.replaybar-track:hover .replaybar-fill {
    height: 6px;
}

/* the real input sits transparent on top so it keeps native drag behaviour */
.replaybar-track input[type="range"] {
    position: relative;
    width: 100%;
    margin: 0;
    background: transparent;
    -webkit-appearance: none;
    appearance: none;
    cursor: pointer;
}

.replaybar-track input[type="range"]:disabled {
    cursor: default;
}

.replaybar-track input[type="range"]::-webkit-slider-runnable-track {
    height: 20px;
    background: transparent;
}

.replaybar-track input[type="range"]::-moz-range-track {
    height: 20px;
    background: transparent;
}

.replaybar-track input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 12px;
    height: 12px;
    margin-top: 4px;
    border-radius: var(--radius-circle);
    background: var(--color-text);
    box-shadow: var(--shadow-sm);
    opacity: 0;
    transition: opacity 120ms ease;
}

.replaybar-track input[type="range"]::-moz-range-thumb {
    width: 12px;
    height: 12px;
    border: none;
    border-radius: var(--radius-circle);
    background: var(--color-text);
    opacity: 0;
    transition: opacity 120ms ease;
}

.replaybar-track:hover input[type="range"]:not(:disabled)::-webkit-slider-thumb,
.replaybar-track input[type="range"]:active::-webkit-slider-thumb {
    opacity: 1;
}

.replaybar-track:hover input[type="range"]:not(:disabled)::-moz-range-thumb,
.replaybar-track input[type="range"]:active::-moz-range-thumb {
    opacity: 1;
}

.replaybar-speed {
    min-width: 34px;
    height: 22px;
    padding: 0 6px;
    font-size: 11px;
    font-variant-numeric: tabular-nums;
    border-radius: var(--radius-full);
    background: color-mix(in srgb, var(--color-text) 10%, transparent);
    color: var(--color-text-muted);
}

.replaybar-close svg {
    width: 16px;
    height: 16px;
    color: var(--color-text-muted);
}

/* Touch has no hover, so a thumb that only appears on hover is a handle the
   user can never see. Show it always, and make it big enough to grab. */
@media (hover: none) {

    .replaybar-track input[type="range"]::-webkit-slider-thumb,
    .replaybar-track input[type="range"]::-moz-range-thumb {
        opacity: 1;
    }

    .replaybar-track input[type="range"]::-webkit-slider-thumb {
        width: 16px;
        height: 16px;
        margin-top: 2px;
    }

    .replaybar-track input[type="range"]::-moz-range-thumb {
        width: 16px;
        height: 16px;
    }

    .replaybar-track::before,
    .replaybar-fill {
        height: 6px;
    }
}

/* On a phone the capsule becomes a bar across the foot of the map: full width,
   flat against the bottom edge, clear of the home indicator. */
@media (max-width: 560px) {
    #replaybar {
        left: 0;
        right: 0;
        bottom: 0;
        width: auto;
        gap: 6px;
        padding: 10px 8px calc(10px + env(safe-area-inset-bottom, 0px));
        border-radius: 0;
        transform: translateY(8px);
    }

    #replaybar.visible {
        transform: translateY(0);
    }

    /* touch targets, not pointer targets */
    .replaybar-play {
        width: 40px;
        height: 40px;
    }

    #replaybar svg {
        width: 24px;
        height: 24px;
    }

    .replaybar-close svg {
        width: 20px;
        height: 20px;
    }

    .replaybar-time {
        min-width: 38px;
        font-size: 10px;
    }

    #replayElapsed {
        min-width: 38px;
    }

    .replaybar-speed {
        min-width: 32px;
        height: 28px;
        font-size: 10px;
    }

}

/* Replay owns the screen: the map controls have nothing to act on while
   history is being played back. */
body.replay-open .map-button-box {
    display: none;
}
