.ship-cruise-loading {
        color: #9ca3af;
        font-size: 12px;
      }
      
      /* The ship info bar overlays the bottom edge of the map, so the zoom
         group and the OpenStreetMap credit sit permanently above where it
         appears (41-62px tall on desktop, up to ~100px on phones) instead of
         jumping up and down every time a ship is highlighted. */
      #cruise-map .maplibregl-ctrl-bottom-right {
        bottom: 68px;
      }
      @media (max-width: 768px) {
        #cruise-map .maplibregl-ctrl-bottom-right {
          bottom: 104px;
        }
      }
      
      /* Fuse the (i) onto the bottom of the zoom group so the corner reads as
         one control. The two are separate MapLibre controls, so this squares
         off the facing corners, drops the gap between them, and matches the
         group's 29px button size, white fill and 1px divider. */
      .maplibregl-ctrl-bottom-right .maplibregl-ctrl-group {
        margin-bottom: 0;
        border-bottom-left-radius: 0;
        border-bottom-right-radius: 0;
        /* MapLibre rings these controls with a 2px box-shadow on all four
           sides. Stacking two of them at the join drew a 2px seam, twice the
           1px divider between + and -. Ring three sides only and let the (i)
           below supply the 1px line. */
        box-shadow: -2px 0 0 0 rgba(0, 0, 0, 0.1),
                     2px 0 0 0 rgba(0, 0, 0, 0.1),
                     0 -2px 0 0 rgba(0, 0, 0, 0.1);
      }

      /* Only the (i) keeps the white button; the control never widens. The
         credit itself hangs outside it, straight over the map. */
      .maplibregl-ctrl-bottom-right .maplibregl-ctrl-attrib.maplibregl-compact {
        position: relative;
        margin-top: 0;
        width: 29px;
        min-height: 29px;
        padding: 0;
        background: #fff;
        border-top: 1px solid #ddd;
        border-radius: 0 0 4px 4px;
        /* Open at the top, matching the group above. */
        box-shadow: -2px 0 0 0 rgba(0, 0, 0, 0.1),
                     2px 0 0 0 rgba(0, 0, 0, 0.1),
                     0 2px 0 0 rgba(0, 0, 0, 0.1);
        overflow: visible;
      }

      /* The credit hangs off the left of the (i), straight over the map. Its
         right edge is pinned to the button, so animating width slides the
         text out from underneath it and back again -- the overflowing tail
         stays clipped at the button's edge throughout.

         The animation lives on this element rather than a wrapper inside it
         because MapLibre rewrites the inner HTML whenever the attribution
         set changes, which would discard anything injected in there. */
      .maplibregl-ctrl-bottom-right .maplibregl-ctrl-attrib.maplibregl-compact .maplibregl-ctrl-attrib-inner {
        /* MapLibre display:none's this when collapsed, which would make the
           reveal an instant swap. Keep it rendered and let width do the work
           -- this selector has to out-specify theirs to win. */
        display: block;
        position: absolute;
        top: 0;
        right: 100%;
        margin-right: 7px;
        height: 29px;
        width: 0;
        overflow: hidden;
        line-height: 29px;
        white-space: nowrap;
        font-size: 11px;
        /* Same ink and halo the map's own place labels use, so the credit
           stays legible over both the pale land and the darker sea. */
        color: #10233a;
        text-shadow: 0 0 3px rgba(255, 255, 255, 0.95),
                     0 0 8px rgba(255, 255, 255, 0.75);
        transition: width 320ms ease;
      }

      .maplibregl-ctrl-bottom-right .maplibregl-ctrl-attrib.maplibregl-compact-show .maplibregl-ctrl-attrib-inner {
        width: var(--credit-width, auto);
      }

      /* MapLibre pins the 24px glyph to the button's top-left and lets it
         repeat; in a 29px button that sits 2.5px off centre both ways.
         Centring alone isn't enough: (29 - 24) / 2 is a half pixel, which
         Chrome snaps outwards, leaving the glyph 0.5px right and low. Sizing
         it 25px makes the offset a whole 2px and it lands dead centre. */
      /* Selector carries the extra classes to out-specify MapLibre's own
         .maplibregl-compact-show rule, which tints the button 5% black while
         the credit is out -- it read as the button staying stuck on. */
      .maplibregl-ctrl-bottom-right .maplibregl-ctrl-attrib.maplibregl-compact .maplibregl-ctrl-attrib-button {
        width: 29px;
        height: 29px;
        background-color: transparent;
        background-position: center center;
        background-repeat: no-repeat;
        background-size: 25px 25px;
        border-radius: 0 0 4px 4px;
      }

      /* MapLibre rings this button blue on :focus and only cancels it for
         mouse users on the zoom group, not here. Left as-is a click would
         paint a blue box over the corner; keyboard focus still shows. */
      .maplibregl-ctrl-bottom-right .maplibregl-ctrl-attrib-button:focus:not(:focus-visible) {
        box-shadow: none;
      }

      .maplibregl-ctrl-bottom-right .maplibregl-ctrl-attrib-inner a {
        color: inherit;
        text-decoration: none;
      }

      .maplibregl-ctrl-bottom-right .maplibregl-ctrl-attrib-inner a:hover {
        text-decoration: underline;
      }
      
      

      /* Rocking animation for ships at sea */
      /* Create a wrapper for the bobbing animation */
      .ship-bobbing-wrapper {
        width: 100%;
        height: 100%;
        animation: ship-bob 3s linear infinite;
        will-change: transform;
      }

      @keyframes ship-bob {
        0% {
          transform: translateY(0) rotate(0deg);
        }
        10% {
          transform: translateY(-0.5px) rotate(-0.25deg);
        }
        20% {
          transform: translateY(-1.4px) rotate(-0.5deg);
        }
        30% {
          transform: translateY(-1.8px) rotate(-0.75deg);
        }
        40% {
          transform: translateY(-2px) rotate(-1deg);
        }
        50% {
          transform: translateY(-1.4px) rotate(-0.5deg);
        }
        60% {
          transform: translateY(0) rotate(0deg);
        }
        70% {
          transform: translateY(1.4px) rotate(0.5deg);
        }
        80% {
          transform: translateY(1.8px) rotate(0.75deg);
        }
        90% {
          transform: translateY(2px) rotate(1deg);
        }
        100% {
          transform: translateY(0) rotate(0deg);
        }
      }

      /* Popup styling */
      .maplibregl-popup-content {
        padding: 14px 18px;
        font-family: Inter, Arial, sans-serif;
        font-size: 15px;
        min-width: 280px;
        width: max-content;
        border-radius: 10px;
        box-shadow: 0 4px 12px rgba(0,0,0,0.15);
        animation: popup-fade-in 200ms ease-out;
      }
      
      .maplibregl-popup-content > * {
        white-space: nowrap;
      }
      
      .maplibregl-popup-content b {
        font-size: 16px;
      }
      
      @keyframes popup-fade-in {
        from {
          opacity: 0;
          transform: translateY(5px);
        }
        to {
          opacity: 1;
          transform: translateY(0);
        }
      }
      
      .maplibregl-popup-content a {
        color: #0066cc;
        text-decoration: none;
        outline: none;
        border: none;
      }
      
      .maplibregl-popup-content a:hover {
        text-decoration: underline;
      }
      
      .maplibregl-popup-content a:focus {
        outline: none;
      }
      
      
      /* Ship statistics text */
      .ship-statistics .stat-number {
        font-weight: 600;
        color: #374151;
      }
      
      /* Filter controls */
      .filter-control, .status-toggle {
        padding: 4px 12px;
        border: 1px solid #e5e7eb;
        border-radius: 6px;
        background: white;
        font-size: 14px;
        cursor: pointer;
        transition: all 0.2s;
      }
      
      .filter-control:hover, .status-toggle:hover {
        background: #f3f4f6;
        border-color: #d1d5db;
      }
      
      .status-toggle.active {
        background-color: #006279;
        color: white;
        border-color: #006279;
      }

      .filter-control.active {
        background-color: #006279;
        color: white;
        border-color: #006279;
      }

      .status-toggle.active:hover,
      .filter-control.active:hover {
        background-color: #004d5f;
        border-color: #004d5f;
      }

      .map-quick-jumps {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: 6px;
        margin-top: 8px;
      }

      .map-jump-chip {
        padding: 4px 11px;
        border: 1px solid #bfd6dc;
        border-radius: 9999px;
        background: #edf7f8;
        color: #004d5f;
        font-size: 13px;
        font-weight: 700;
        line-height: 1.25;
        cursor: pointer;
        transition: background-color 0.2s, border-color 0.2s, color 0.2s;
      }

      .map-jump-chip:hover,
      .map-jump-chip:focus-visible {
        border-color: #006279;
        background: #006279;
        color: #ffffff;
        outline: none;
      }
      
      .line-toggle {
        display: inline-flex;
        align-items: center;
        padding: 4px;
        border: none;
        background: none;
        cursor: pointer;
        transition: opacity 0.2s;
        opacity: 0.3;
      }
      
      .line-toggle.active {
        opacity: 1;
      }
      
      .line-toggle img {
        height: 30px;
        width: 30px;
        object-fit: contain;
      }
      
      /* Logo positioning */
      .map-logo {
        position: absolute;
        top: 20px;
        left: 50%;
        transform: translateX(-50%);
        max-width: 1280px;
        width: 100%;
        padding: 0 1rem;
        z-index: 10;
      }
      
      @media (min-width: 1280px) {
        .map-logo {
          padding: 0;
        }
      }
      
      /* Table styling */
      .ship-table-wrapper {
        box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
        border-radius: 8px;
        overflow: hidden;
      }
      
      .ship-name-with-logo {
        display: flex;
        align-items: center;
        gap: 8px;
      }
      
      .table-line-logo {
        width: 20px;
        height: 20px;
        object-fit: contain;
        flex-shrink: 0;
      }
      
      @media (max-width: 768px) {
        #cruise-map {
          height: 50vh;
          min-height: 300px;
        }
        
        #ship-info-box {
          font-size: 12px;
          min-height: 0;
          height: auto;
          padding: 8px 42px 8px 12px;
        }
        
        #ship-info-box b {
          font-size: 14px;
        }

        #ship-info-box .ship-current-cruise {
          margin-right: 0;
        }

        .ship-info-summary {
          gap: 2px 8px;
        }

        .ship-info-name {
          font-size: 14px;
        }

        .ship-info-fact::before,
        .ship-cruise-details::before {
          margin-right: 8px;
        }
        
        .filter-control,
        .map-jump-chip {
          padding: 3px 8px;
          font-size: 12px;
        }
        
        .line-toggle {
          padding: 2px;
        }
        
        .line-toggle img {
          height: 24px;
          width: 24px;
        }
        
        .ship-statistics {
          font-size: 12px;
          flex-direction: column;
          align-items: flex-start;
          gap: 4px;
        }
        
        /* Mobile table adjustments */
        .table-container th {
          padding: 8px 6px;
          font-size: 10px;
        }
        
        .table-container td {
          padding: 10px 6px;
          font-size: 12px;
        }
        
        .table-line-logo {
          width: 16px;
          height: 16px;
        }
      }
