{"id":333,"date":"2025-09-15T14:00:37","date_gmt":"2025-09-15T14:00:37","guid":{"rendered":"https:\/\/aiportcenter.nl\/?page_id=333"},"modified":"2025-12-16T19:19:13","modified_gmt":"2025-12-16T19:19:13","slug":"port-call","status":"publish","type":"page","link":"https:\/\/aiportcenter.nl\/index.php\/port-call\/","title":{"rendered":"Port-Call-Data-Hub"},"content":{"rendered":"\n<div style=\"position:relative; padding:0 20px 20px; margin-top:-110px;\">\n\n  <style>\n    \/* Hide default WP title *\/\n    h1.entry-title, .post-title, .page-title { display: none !important; }\n\n    :root{\n      --ink: #0b1220;\n      --muted: #5a6a78;\n      \/* Lighter blue palette *\/\n      --b1: #9ad8ff;  \/* light sky *\/\n      --b2: #74c9ff;  \/* sky *\/\n      --b3: #4fb8f6;  \/* azure *\/\n      --b4: #2aa7e8;  \/* rotor blue *\/\n      --b5: #1e8fd0;  \/* medium *\/\n      --b6: #187ab5;  \/* slightly deeper but still lightish *\/\n      --b7: #136698;  \/* accent *\/\n      --b8: #0f5580;  \/* darkest accent *\/\n      --glass: rgba(255,255,255,0.98);\n      --border: rgba(0,0,0,.10);\n\n      --shadow: 0 10px 30px rgba(10, 29, 56, .20);\n      --radius: 16;\n      --hover-lift: -6px;\n      --sub-scale: 1.0;\n      --main-step-height: 100px;\n      --sub-step-height: calc(var(--main-step-height) * 1.0);\n\n      \/* Subprocess UI variables *\/\n      --sub-pop-shift-x: 0px;\n      --sub-pop-shift-y: 0px;\n      --sub-hit-nudge-y: 0px;\n      --sub-hit-expand: -8px;\n\n      \/* Unified minimum width for all subprocess boxes (JS can override) *\/\n      --sub-min-width: 110px;\n\n      \/* Animation timings *\/\n      --t-fast: .18s;\n      --t-med: .28s;\n  --t-slow: .6s;\n  \/* gradient animation duration for process bars *\/\n  --grad-t: 16s;\n\n      \/* Bracket palette *\/\n      --bracket-a: rgba(255,223,96,0.92);\n      --bracket-b: rgba(255,203,36,0.85);\n    }\n\n    .background-box { box-shadow: none !important; border: none !important; background: #fff; }\n    .overlay-content { position: relative; padding: 20px; box-sizing: border-box; color: var(--ink); }\n\n    h1{font-weight:700; letter-spacing:.3px; margin:0 0 16px; color: var(--ink);}\n    .sub{color:var(--muted); margin:0 0 24px;}\n\n    .highlight-dot{\n      display:inline-block; width:14px; height:14px; border-radius:50%;\n      background: linear-gradient(90deg, var(--b2), var(--b4));\n      box-shadow: 0 2px 6px rgba(42,175,244,0.18); margin-right:10px; vertical-align:middle;\n      animation: pulseDot 2.2s ease-in-out infinite;\n    }\n\n    \/* Darker variant for the first instruction dot *\/\n    .highlight-dot--dark{\n      background: linear-gradient(90deg, var(--b6), var(--b8));\n      box-shadow: 0 3px 8px rgba(13,85,128,0.22);\n    }\n\n    .figure-between { width: 105%; height: auto; max-width: none; transition: transform var(--t-slow) ease; will-change: transform; }\n    .figure-between:hover { transform: scale(1.01); }\n\n    .timeline{\n      list-style:none; margin:0; padding:0; display:grid; grid-auto-flow:column; grid-auto-columns:1fr; gap:0; position:relative; isolation:isolate;\n    }\n\n    \/* MAIN (processes) *\/\n    .step{\n      position:relative; height:var(--main-step-height); display:flex; align-items:center; justify-content:center; cursor:pointer;\n      overflow:visible; color:#fff; text-align:center; font-weight:700; letter-spacing:.2px; user-select:none; outline:none;\n      transition: transform var(--t-fast) ease, filter var(--t-fast) ease; z-index:1;\n    }\n    .step .label{ position:relative; z-index:2; padding:0 10px; filter: drop-shadow(0 2px 6px rgba(0,0,0,.25)); }\n\n    .step::before{\n      content:\"\"; position:absolute; inset:0 -40px 0 0; z-index:1; transform:skewX(-18deg);\n      border-right: 10px solid rgba(255,255,255,.18);\n      transition: transform var(--t-med) ease, filter var(--t-med) ease, opacity var(--t-med) ease, background-position var(--t-slow) ease;\n      opacity:.97;\n      border-top-left-radius: 0px; border-top-right-radius: 10px; border-bottom-left-radius: 0px; border-bottom-right-radius: 10px;\n\n      \/* Animated gradient (slow, smooth) *\/\n      background-size: 300% 100%;\n      animation: gradientShift var(--grad-t) linear infinite;\n      will-change: background-position;\n    }\n    .step:first-child::before { border-top-left-radius: 20px; border-bottom-left-radius: 0px; }\n    .step:last-child::before  { border-top-right-radius: 0px; border-bottom-right-radius: 20px; }\n\n  .step:hover, .step:focus-visible { transform: translateY(var(--hover-lift)); z-index: 99998; }\n  .step:hover::before, .step:focus-visible::before { transform: skewX(-18deg); filter: brightness(1.04); animation-duration: calc(var(--grad-t) \/ 2); }\n\n    \/* Hover bridge so you can reach the popover above the box *\/\n    .step::after{\n      content:\"\"; position:absolute; left:-40px; right:-40px; bottom:100%; height:56px;\n      background:transparent; pointer-events:auto; z-index:2;\n    }\n\n    \/* Lighter blue gradients for each step *\/\n  \/* Smooth adjacent-pair gradients across the timeline for a continuous flow *\/\n  .c1::before{ background-image: linear-gradient(90deg, var(--b1), var(--b2)); }\n  .c2::before{ background-image: linear-gradient(90deg, var(--b2), var(--b3)); }\n  .c3::before{ background-image: linear-gradient(90deg, var(--b3), var(--b4)); }\n  .c4::before{ background-image: linear-gradient(90deg, var(--b4), var(--b5)); }\n  .c5::before{ background-image: linear-gradient(90deg, var(--b5), var(--b6)); }\n  .c6::before{ background-image: linear-gradient(90deg, var(--b6), var(--b7)); }\n  .c7::before{ background-image: linear-gradient(90deg, var(--b7), var(--b8)); }\n  \/* wrap-around so the last step gently blends back to the light end *\/\n  .c8::before{ background-image: linear-gradient(90deg, var(--b8), var(--b1)); }\n\n    \/* MAIN popover \u2014 hover only *\/\n    .popover{\n      position:absolute; z-index:2147484000; bottom: 132px; left: 50%;\n      transform: translateX(-50%) translateY(10px);\n      width: 355px; opacity:0; pointer-events:none; transition: opacity var(--t-fast) ease, transform var(--t-fast) ease;\n      background: var(--glass); color:#1d2a38; border:1px solid var(--border); border-radius:12px; box-shadow: var(--shadow); padding:12px 14px; text-align:left; box-sizing:border-box; font-size:.92rem;\n      font-weight: normal;\n      backdrop-filter: saturate(130%) blur(2px);\n    }\n    .popover::after{\n      content:\"\"; position:absolute; left:50%; transform: translateX(-50%) rotate(45deg);\n      bottom:-8px; width:14px; height:14px; background:var(--glass); border-right:1px solid var(--border); border-bottom:1px solid var(--border);\n      backdrop-filter: inherit;\n    }\n    .step:hover .popover { opacity:1; transform: translateX(-50%) translateY(0); pointer-events:auto; }\n\n    .pop-title{ font-weight:800; margin:0 0 6px; color:#0d3b5e; }\n    .pop-meta{ font-size:.82rem; color:#446178; margin:0 0 8px; }\n    .popover .pop-meta strong{ font-weight: 700; color: inherit; }\n    .pop-body{ font-size:.9rem; line-height:1.35rem; color:#24384a; }\n    .pop-body2{ font-size:.9rem; line-height:1.35rem; color:#24384a; margin-top:8px; }\n\n    \/* Placeholder for subtimeline; also positioning context *\/\n    #subtimeline-placeholder{\n      height: 0px;\n      position: relative;\n      transition: height .34s cubic-bezier(.2,.9,.3,1);\n      overflow: visible;\n      \/* extra vertical spacing so bar doesn\u2019t overlap main timeline *\/\n      margin-top: 16px;\n    }\n\n    \/* SUBPROCESS boxes *\/\n    .substep{\n      position:relative; height: var(--sub-step-height); display:flex; align-items:center; justify-content:center; cursor:default;\n      overflow:visible; color:#04314d; text-align:center; font-weight:700; letter-spacing:.2px; user-select:none;\n      border-radius:10px; transition: transform var(--t-fast) ease, filter var(--t-fast) ease;\n      min-width: var(--sub-min-width, 110px);\n      box-sizing:border-box; z-index:1; flex: 0 1 auto;\n      text-shadow: 0 1px 0 rgba(255,255,255,.4);\n    }\n    .substep .label{ position:relative; z-index:3; padding:0 8px; display:block; white-space:normal; overflow-wrap:anywhere; text-align:center; }\n\n    .substep::before{\n      content:\"\"; position:absolute; inset:0 var(--sub-overlap-right, -25px) 0 0; z-index:1; transform:skewX(-18deg);\n      border-right: 10px solid rgba(255,255,255,.18);\n      transition: transform var(--t-med) ease, filter var(--t-med) ease, background-position var(--t-slow) ease; opacity:.97;\n      pointer-events: none;\n      border-top-left-radius: 0px; border-top-right-radius: 10px; border-bottom-left-radius: 0px; border-bottom-right-radius: 10px;\n      background-size: 200% 100%;\n      animation: gradientShift 14s ease-in-out infinite;\n    }\n\n    .substep:hover, .substep:focus-visible::before { transform: translateY(var(--hover-lift)); z-index: 2147483500; }\n    .substep:hover::before, .substep:focus-visible::before { transform: skewX(-18deg); filter: brightness(1.02); animation-duration: 7s; }\n\n    \/* Lighter amber\/solar accents for subprocess *\/\n    .sc1::before{ background-image: linear-gradient(90deg, rgba(255,235,153,0.85), rgba(255,219,88,0.65)); }\n    .sc2::before{ background-image: linear-gradient(90deg, rgba(255,224,120,0.80), rgba(255,205,64,0.60)); }\n    .sc3::before{ background-image: linear-gradient(90deg, rgba(255,210,96,0.78), rgba(255,191,36,0.58)); }\n\n    \/* Subprocess endcap radii rules *\/\n    .subtimeline-container .substep:first-child::before{ border-top-left-radius: 20px; border-bottom-left-radius: 0px; }\n    .subtimeline-container .substep:last-child::before{ border-top-right-radius: 0px; border-bottom-right-radius: 10px; }\n\n    \/* SECOND-LEVEL popover *\/\n    .sub-pop{\n      position:absolute; z-index: 2147483999;\n      top: calc(100% + 6px + var(--sub-pop-shift-y, 0px));\n      left: calc(50% + var(--sub-pop-shift-x, 0px));\n      transform: translateX(-50%) translateY(8px);\n      width: 300px; opacity:0; pointer-events:none; transition: opacity var(--t-fast) ease, transform var(--t-fast) ease;\n      background: var(--glass); color:#1d2a38; border:1px solid var(--border); border-radius:10px; box-shadow: var(--shadow); padding:10px 12px; text-align:left; box-sizing:border-box; font-size:.88rem;\n      backdrop-filter: saturate(130%) blur(2px);\n    }\n\n    .subtimeline-container{ animation: subIn .28s cubic-bezier(.2,.9,.3,1) both; }\n\n    .popover .pop-link-btn {\n      display: inline-block; margin-top: 10px; padding: 8px 16px; background: var(--b4); color: #fff; font-weight: 600; text-decoration: none; border-radius: 8px;\n      text-align: center; transition: background var(--t-fast) ease, transform var(--t-fast) ease, box-shadow var(--t-fast) ease; box-shadow: 0 4px 8px rgba(42, 175, 244, 0.25);\n    }\n    .popover .pop-link-btn:hover { background: var(--b3); transform: translateY(-2px); box-shadow: 0 8px 16px rgba(42,175,244,0.25); }\n    .popover .pop-link-btn:active { transform: translateY(0); }\n\n    \/* Keyframes *\/\n    @keyframes gradientShift { 0%{background-position:0% 50%;} 50%{background-position:100% 50%;} 100%{background-position:0% 50%;} }\n    @keyframes pulseDot { 0%,100%{transform:scale(1)} 50%{transform:scale(1.15)} }\n    @keyframes subIn { from{opacity:0;transform:translateY(-6px)} to{opacity:1;transform:translateY(0)} }\n\n    @media (prefers-reduced-motion: reduce){\n      .figure-between,.step,.substep,.step::before,.substep::before,.popover,.sub-pop,.subtimeline-container{ transition:none !important; animation:none !important; }\n    }\n\n    \/* === NEW: ultra-thin yellow bracket bar positioned above subprocesses === *\/\n    .subtimeline-bracket{\n      position:absolute;\n      height:0.7mm; \/* super thin *\/\n      background:linear-gradient(90deg,var(--bracket-a),var(--bracket-b));\n      border-radius:2mm;\n      top:-10px;         \/* close to subprocess rectangles *\/\n      left:50%;\n      transform:translateX(-50%) scaleX(0);\n      width:0;\n      opacity:0;\n      transition:transform .5s ease, width .5s ease, opacity .35s ease, left .5s ease;\n      z-index:2147483300;\n      pointer-events:none;\n    }\n    \/* The triangle pinpoints the exact center of the related process *\/\n    .subtimeline-bracket::after{\n      content:\"\";\n      position:absolute;\n      top:-7px;  \/* above the bar so it points upward *\/\n      left:var(--tri-left, 50%);  \/* set by JS in px within container *\/\n      transform:translateX(calc(-50% - 3mm));\n      width:0;height:0;\n      border-left:6px solid transparent;\n      border-right:6px solid transparent;\n      border-bottom:7px solid var(--bracket-b);\n      filter:drop-shadow(0 1px 1px rgba(0,0,0,0.08));\n    }\n    .subtimeline-bracket.active{ opacity:1; transform:translateX(-50%) scaleX(1); }\n  <\/style>\n\n  <div class=\"background-box\">\n    <div class=\"overlay-content\" aria-hidden=\"false\">\n      <h1>Port-Call Processes Timeline<\/h1>\n      <div class=\"sub\">\n        The <strong>Port-Call Data-Hub Optimization Project<\/strong> is a collaborative initiative aimed at connecting industry practitioners and academic researchers to advance data-driven innovation in port logistics. Below, we present a visual overview of the <strong>Port-Call Processes at the Port of Rotterdam<\/strong>.\n      <\/div>\n      <p class=\"sub\"><span class=\"highlight-dot highlight-dot--dark\" aria-hidden=\"true\"><\/span>Hover a step for details. Click a main step to show its subprocesses below.<\/p>\n      <p class=\"sub\"><span class=\"highlight-dot\" aria-hidden=\"true\"><\/span>Click on the push button to acces an in-depth description of the process and available data.<\/p>\n      <!-- Image -->\n      <img decoding=\"async\" src=\"https:\/\/aiportcenter.nl\/wp-content\/uploads\/2025\/10\/background21.png\" alt=\"Figure\" class=\"figure-between\">\n\n      <!-- MAIN TIMELINE -->\n      <ul class=\"timeline\" role=\"list\">\n        <li class=\"step c1\" tabindex=\"0\" aria-describedby=\"pop1\"><div class=\"label\">Pre-Arrival<\/div>\n          <div id=\"pop1\" class=\"popover\" role=\"dialog\" aria-hidden=\"true\">\n            <div class=\"pop-title\">Pre-Arrival<\/div>\n            <div class=\"pop-meta\"><strong>Execution Party:<\/strong><br>\n            <strong>\u2022<\/strong> <span class=\"pop-meta\">Rhenus Port Agency<\/span><br>\n            <strong>\u2022<\/strong> Kentra Rotterdam Port Agency<br>\n            <strong>\u2022<\/strong> Stolt Tankers \/ Vroon Shipping \/ Maersk Line\n          <\/div>\n            <div class=\"pop-meta\"><strong>Planning Party:<\/strong><br>\n            <strong>\u2022<\/strong> Rotterdam Port Authority<br>\n            <strong>\u2022<\/strong> APM Terminals Operations<br>\n            <strong>\u2022<\/strong> Cargill Shipping Agent<\/div>\n            <div class=\"pop-meta\"><strong>Data:<\/strong> PAN \/ Portbase MVA \/ IMO FAL \/ DGD \/ AIS \/ Lloyd\u2019s Register.<\/div>\n            <a href=\"https:\/\/aiportcenter.nl\/index.php\/pre-arrival\/\" class=\"pop-link-btn\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More<\/a>\n          <\/div>\n        <\/li>\n\n        <li class=\"step c2\" tabindex=\"0\" aria-describedby=\"pop2\"><div class=\"label\">Port Arrival<\/div>\n          <div id=\"pop2\" class=\"popover\" role=\"dialog\" aria-hidden=\"true\">\n            <div class=\"pop-title\">Port Arrival<\/div>\n            <div class=\"pop-meta\"><strong>Execution Party:<\/strong><br>\n            <strong>\u2022<\/strong> Loodswezen Rotterdam-Rijnmond<br>\n            <strong>\u2022<\/strong> Port of Rotterdam Authority<br>\n            <strong>\u2022<\/strong> Redwise Maritime Services<\/div>\n            <div class=\"pop-meta\"><strong>Planning Party:<\/strong><br>\n            <strong>\u2022<\/strong> Port of Rotterdam Authority<br>\n            <strong>\u2022<\/strong> Boluda Towage Rotterdam<br>\n            <strong>\u2022<\/strong> Maersk Line Agent<\/div>\n            <div class=\"pop-meta\"><strong>Data:<\/strong> AIS\/VHF \/ Portbase Vessel Notification \/ HaMIS \/ KNMI \/ Tide Tables.<\/div>\n            <a href=\"https:\/\/aiportcenter.nl\/index.php\/port-arrival\/\" class=\"pop-link-btn\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More<\/a>\n          <\/div>\n        <\/li>\n\n  <li class=\"step c3\" tabindex=\"0\" aria-describedby=\"pop5\"><div class=\"label\">Anchoring<\/div>\n          <div id=\"pop3\" class=\"popover\" role=\"dialog\" aria-hidden=\"true\">\n            <div class=\"pop-title\">Anchoring<\/div>\n            <div class=\"pop-meta\"><strong>Execution Party:<\/strong><br>\n            <strong>\u2022<\/strong> Port of Rotterdam Authority<br>\n            <strong>\u2022<\/strong> Loodswezen Rotterdam-Rijnmond<br>\n            <strong>\u2022<\/strong> Redwise Maritime Services<\/div>\n            <div class=\"pop-meta\"><strong>Planning Party:<\/strong><br>\n            <strong>\u2022<\/strong> Port of Rotterdam Authority<br>\n            <strong>\u2022<\/strong> MSC<br>\n            <strong>\u2022<\/strong> Maersk<\/div>\n            <div class=\"pop-meta\"><strong>Data:<\/strong> Anchorage Plan \/ Stability Book \/ KNMI \/ PORTbase \/ Traffic Notices.<\/div>\n            <a href=\"https:\/\/aiportcenter.nl\/index.php\/anchoring\/\" class=\"pop-link-btn\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More<\/a>\n          <\/div>\n        <\/li>\n\n  <li class=\"step c4\" tabindex=\"0\" aria-describedby=\"pop3\"><div class=\"label\">Port Maneuvering<\/div>\n          <div id=\"pop4\" class=\"popover\" role=\"dialog\" aria-hidden=\"true\">\n            <div class=\"pop-title\">Port Maneuvering<\/div>\n            <div class=\"pop-meta\"><strong>Execution Party:<\/strong><br>\n            <strong>\u2022<\/strong> Boluda Towage Rotterdam<br>\n            <strong>\u2022<\/strong> Kotug International<br>\n            <strong>\u2022<\/strong> Smit Lamnalco<br>\n            <strong>\u2022<\/strong> KRVE Rotterdam Boatmen<\/div>\n            <div class=\"pop-meta\"><strong>Planning Party:<\/strong><br>\n            <strong>\u2022<\/strong> Port of Rotterdam Authority<br>\n            <strong>\u2022<\/strong> ECT Terminals<br>\n            <strong>\u2022<\/strong> Vopak Operations<\/div>\n            <div class=\"pop-meta\"><strong>Data:<\/strong> ENC \/ VTS \/ PORTbase \/ Tug Operators Schedules.<\/div>\n            <a href=\"https:\/\/aiportcenter.nl\/index.php\/port-maneuvering\/\" class=\"pop-link-btn\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More<\/a>\n          <\/div>\n        <\/li>\n\n  <li class=\"step c5\" tabindex=\"0\" aria-describedby=\"pop4\"><div class=\"label\">Berth Visit<\/div>\n          <div id=\"pop5\" class=\"popover\" role=\"dialog\" aria-hidden=\"true\">\n            <div class=\"pop-title\">Berth Visit<\/div>\n            <div class=\"pop-meta\"><strong>Execution Party:<\/strong><br>\n            <strong>\u2022<\/strong> ECT Rotterdam (Delta, Euromax)<br>\n            <strong>\u2022<\/strong> APMT MVII<br>\n            <strong>\u2022<\/strong> Vopak Vlaardingen\/Botlek<br>\n            <strong>\u2022<\/strong> AET (Rotterdam)<\/div>\n            <div class=\"pop-meta\"><strong>Planning Party:<\/strong><br>\n            <strong>\u2022<\/strong> Port of Rotterdam Authority<br>\n            <strong>\u2022<\/strong> ECT Planning<br>\n            <strong>\u2022<\/strong> Maersk Terminal Planning<\/div>\n            <div class=\"pop-meta\"><strong>Data:<\/strong> TOS \/ Navis N4 \/ DG List \/ AMS.<\/div>\n            <a href=\"https:\/\/aiportcenter.nl\/index.php\/berth-visit\/\" class=\"pop-link-btn\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More<\/a>\n          <\/div>\n        <\/li>\n\n        <li class=\"step c6\" tabindex=\"0\" aria-describedby=\"pop6\"><div class=\"label\">Terminal Operations<\/div>\n          <div id=\"pop6\" class=\"popover\" role=\"dialog\" aria-hidden=\"true\">\n            <div class=\"pop-title\">Terminal Operations<\/div>\n            <div class=\"pop-meta\"><strong>Execution Party:<\/strong><br>\n            <strong>\u2022<\/strong> ECT Rotterdam<br>\n            <strong>\u2022<\/strong> APMT MVII<br>\n            <strong>\u2022<\/strong> Rhenus Port Logistics<br>\n            <strong>\u2022<\/strong> Hanseatic Global Terminals<\/div>\n            <div class=\"pop-meta\"><strong>Planning Party:<\/strong><br>\n            <strong>\u2022<\/strong> Port of Rotterdam Authority<br>\n            <strong>\u2022<\/strong> VRTO<br>\n            <strong>\u2022<\/strong> Hapag-Lloyd<br>\n            <strong>\u2022<\/strong> Evergreen<\/div>\n            <div class=\"pop-meta\"><strong>Data:<\/strong> TOS \/ Navis \/ SAP-TERMINAL \/ Yard Planning \/ AMS.<\/div>\n            <a href=\"https:\/\/aiportcenter.nl\/index.php\/terminal-operations\/\" class=\"pop-link-btn\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More<\/a>\n          <\/div>\n        <\/li>\n\n        <li class=\"step c7\" tabindex=\"0\" aria-describedby=\"pop7\"><div class=\"label\">Customs<\/div>\n          <div id=\"pop7\" class=\"popover\" role=\"dialog\" aria-hidden=\"true\">\n            <div class=\"pop-title\">Customs<\/div>\n            <div class=\"pop-meta\"><strong>Execution Party:<\/strong><br>\n            <strong>\u2022<\/strong> Dutch Customs (Douane)<br>\n            <strong>\u2022<\/strong> Hemetex B.V.<br>\n            <strong>\u2022<\/strong> OTS Broker<br>\n            <strong>\u2022<\/strong> Gaston Schul<\/div>\n            <div class=\"pop-meta\"><strong>Planning Party:<\/strong><br>\n            <strong>\u2022<\/strong> Portbase<br>\n            <strong>\u2022<\/strong> Nedcargo<br>\n            <strong>\u2022<\/strong> DB Schenker<br>\n            <strong>\u2022<\/strong> Panalpina<\/div>\n            <div class=\"pop-meta\"><strong>Data:<\/strong> Customs Declarations \/ Tariff DB \/ ATLAS \/ NCTS \/ Inspection Reports.<\/div>\n            <a href=\"https:\/\/aiportcenter.nl\/index.php\/customs\/\" class=\"pop-link-btn\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More<\/a>\n          <\/div>\n        <\/li>\n\n        <li class=\"step c8\" tabindex=\"0\" aria-describedby=\"pop8\"><div class=\"label\">Hinterland Transport<\/div>\n          <div id=\"pop8\" class=\"popover\" role=\"dialog\" aria-hidden=\"true\">\n            <div class=\"pop-title\">Hinterland Transport<\/div>\n            <div class=\"pop-meta\"><strong>Execution Party:<\/strong><br>\n            <strong>\u2022<\/strong> ECT InlandLinks<br>\n            <strong>\u2022<\/strong> Kuehne+Nagel<br>\n            <strong>\u2022<\/strong> DHL Global Forwarding<br>\n            <div class=\"pop-meta\"><strong>Planning Party:<\/strong><br>\n            <strong>\u2022<\/strong> ECT InlandLinks<br>\n            <strong>\u2022<\/strong> Kuehne+Nagel<br>\n            <strong>\u2022<\/strong> DHL Global Forwarding<br>\n            <div class=\"pop-meta\"><strong>Data:<\/strong> Hinterland Transport System \/ TAS \/ Trucking Schedule \/ Manifest \/ DG Info \/ ATLAS \/ NCTS.<\/div>\n            <a href=\"https:\/\/aiportcenter.nl\/index.php\/hinterland-transport\/\" class=\"pop-link-btn\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More<\/a>\n          <\/div>\n        <\/li>\n      <\/ul>\n\n      <div id=\"subtimeline-placeholder\" aria-hidden=\"true\"><\/div>\n    <\/div>\n  <\/div>\n\n  <script>\n  (function(){\n    \/* ============================\n       TUNABLE CONSTANTS\n       ============================ *\/\n    const MIN_SUB_WIDTH_PX   = 160; \/\/ unified min width for each subprocess box\n    const SUB_OVERLAP_PX     = 25;  \/\/ right overlap amount for subprocess boxes\n    const EDGE_BLEED_PX      = 36;  \/\/ permits a bit of left\/right overflow so clamping doesn't cancel nudges\n    const STEP_NUDGES        = {\n      0: -36, \/\/ first step: small left bleed\n      6: -50  \/\/ CUSTOMS (index 6): negative = shift left, positive = shift right\n    };\n\n    \/\/ Vertical spacing controls (unchanged)\n    const SUB_GAP_TOP_PX      = 4;\n    const SUB_PADDING_V_PX    = 6;\n    const SUB_PLACEHOLDER_PAD = 8;\n\n    \/\/ Skew-compensation: shift bar ~2mm to the right per subprocess (1mm\u22483.78px)\n    const PER_SUB_RIGHT_SHIFT_PX = 2 * 3.78; \/\/ \u22487.56px\n\n    \/* ============================\n       DATA (unchanged)\n       ============================ *\/\n    const subs = [\n      [ { label: \"Origin<br>Sailing\", title: \"Origin Sailing\", body: '<p class=\"pop-meta\">The vessel departs from its port of origin after completing cargo operations and clearance formalities.' },\n        { label: \"Advance<br>Notice\", title: \"Advance Notice\", body: '<p class=\"pop-meta\">Preliminary notice with ETA, vessel and voyage info.<\/p>' },\n        { label: \"Announcement\", title: \"Announcement\", body: '<p class=\"pop-meta\">Formal confirmation to port authority and terminal operators.<\/p>' }\n      ],\n      [ { label: \"Pilotage\", title: \"Pilotage\", body: '<p class=\"pop-meta\">Maritime pilot boards and navigates to berth.<\/p>' },\n        { label: \"Towage\", title: \"Towage\", body: '<p class=\"pop-meta\">Tugboats assist within the port.<\/p>' },\n        { label: \"Berth<br>Arrival\", title: \"Berth Arrival\", body: '<p class=\"pop-meta\">Vessel moored and prepared for ops.<\/p>' }\n      ],\n      [ { label: \"Gangway &<br>Security\", title: \"Gangway & Security\", body: '<p class=\"pop-meta\">Safe access and security measures.<\/p>' },\n        { label: \"Workers\\'<br>Assistance\", title: \"Workers\\' Assistance\", body: '<p class=\"pop-meta\">Inspections, maintenance, certifications.<\/p>' },\n        { label: \"Cargo<br>Support\", title: \"Cargo Support\", body: '<p class=\"pop-meta\">Equipment and labor support.<\/p>' },\n        { label: \"Cargo<br>Survey\", title: \"Cargo Survey\", body: '<p class=\"pop-meta\">Independent cargo inspection.<\/p>' }\n      ],\n      [ { label: \"Mooring\", title: \"Mooring\", body: '<p class=\"pop-meta\">Vessel secured alongside.<\/p>' },\n        { label: \"Unmooring\", title: \"Unmooring\", body: '<p class=\"pop-meta\">Release from berth for departure.<\/p>' },\n        { label: \"Berth<br>Shifting\", title: \"Berth Shifting\", body: '<p class=\"pop-meta\">Move to another berth if needed.<\/p>' }\n      ],\n      [ { label: \"Agent<br>Attendance\", title: \"Agent Attendance\", body: '<p class=\"pop-meta\">Agent coordinates formalities and services.<\/p>' },\n        { label: \"Bunkering &<br>Lub Oil\", title: \"Bunkering & Lub Oil\", body: '<p class=\"pop-meta\">Fuel and lub oil delivery.<\/p>' },\n        { label: \"Provisions\", title: \"Provisions\", body: '<p class=\"pop-meta\">Water, food, and necessities supplied.<\/p>' },\n        { label: \"Waste<br>Disposal\", title: \"Waste Disposal\", body: '<p class=\"pop-meta\">Regulated removal of ship-generated waste.<\/p>' }\n      ],\n      [ { label: \"Cargo<br>Unloading\", title: \"Cargo Unloading\", body: '<p class=\"pop-meta\">Discharge to storage\/yard.<\/p>' },\n        { label: \"Cargo<br>Loading\", title: \"Cargo Loading\", body: '<p class=\"pop-meta\">Load from yard to vessel.<\/p>' },\n        { label: \"Containers<br>Allocation\", title: \"Containers Allocation\", body: '<p class=\"pop-meta\">Position containers by plan.<\/p>' },\n        { label: \"Handling<br>Equipment\", title: \"Handling Equipment\", body: '<p class=\"pop-meta\">Cranes, forklifts, etc.<\/p>' }\n      ],\n      [ { label: \"Document<br>Submission\", title: \"Document Submission\", body: '<p class=\"pop-meta\">File manifests and declarations.<\/p>' },\n        { label: \"Cargo<br>Inspection\", title: \"Cargo Inspection\", body: '<p class=\"pop-meta\">Physical examination by customs.<\/p>' },\n        { label: \"Clearance<br>Issuance\", title: \"Clearance Issuance\", body: '<p class=\"pop-meta\">Cargo released for entry\/onward transport.<\/p>' }\n      ],\n      [ { label: \"Cargo<br>Pick-up\", title: \"Cargo Pick-up\", body: '<p class=\"pop-meta\">Collect from terminal\/yard.<\/p>' },\n        { label: \"Intermodal<br>Transfer\", title: \"Intermodal Transfer\", body: '<p class=\"pop-meta\">Shift between modes.<\/p>' },\n        { label: \"Final<br>Delivery\", title: \"Final Delivery\", body: '<p class=\"pop-meta\">Delivered to consignee.<\/p>' }\n      ]\n    ];\n\n    \/* ============================\n       DOM refs\n       ============================ *\/\n    const placeholder = document.getElementById('subtimeline-placeholder');\n    const overlay     = document.querySelector('.overlay-content');\n    const mainSteps   = Array.from(document.querySelectorAll('.timeline .step')); \/\/ DECLARED ONCE\n\n    let lastIdx = null;\n    let lastAnchorStep = null;\n\n    function setUnifiedSubMinWidth() {\n      document.documentElement.style.setProperty('--sub-min-width', MIN_SUB_WIDTH_PX + 'px');\n    }\n    setUnifiedSubMinWidth();\n    window.addEventListener('resize', setUnifiedSubMinWidth);\n\n    function clearPlaceholder(){\n      document.querySelectorAll('.sub-pop').forEach(p => { if(p.parentNode) p.parentNode.removeChild(p); });\n      placeholder.innerHTML = '';\n      placeholder.style.height = '0px';\n    }\n\n    function buildSubtimeline(idx, anchorStep){\n      clearPlaceholder();\n      const items = subs[idx] || [];\n      if(!items.length || !anchorStep) return;\n\n      lastIdx = idx;\n      lastAnchorStep = anchorStep;\n\n      const container = document.createElement('div');\n      container.className = 'subtimeline-container';\n      container.style.position = 'absolute';\n      container.style.top = SUB_GAP_TOP_PX + 'px';\n      container.style.display = 'flex';\n      container.style.gap = '0';\n      container.style.padding = SUB_PADDING_V_PX + 'px 8px';\n      container.style.boxSizing = 'border-box';\n      container.style.width = 'max-content';\n      container.style.maxWidth = overlay.clientWidth + 'px';\n      container.style.justifyContent = 'center';\n      container.style.pointerEvents = 'auto';\n      container.style.zIndex = 2147483200;\n      container.style.background = 'transparent';\n\n      \/* Ultra-thin bracket bar *\/\n      const bracket = document.createElement('div');\n      bracket.className = 'subtimeline-bracket';\n      container.appendChild(bracket);\n\n      \/* Subprocess boxes *\/\n      items.forEach((it, si) => {\n        const s = document.createElement('div');\n        s.className = 'substep sc' + ((si % 3) + 1);\n        s.tabIndex = 0;\n        s.style.setProperty('--sub-overlap-right', `-${SUB_OVERLAP_PX}px`);\n\n        const label = document.createElement('div');\n        label.className = 'label';\n        label.innerHTML = it.label;\n\n        const hit = document.createElement('div');\n        hit.className = 'sub-hit';\n        hit.style.position = 'absolute';\n        hit.style.inset = '-14px -18px -14px -18px';\n        hit.style.background = 'transparent';\n        hit.style.cursor = 'pointer';\n        hit.tabIndex = 0;\n\n        const pop = document.createElement('div');\n        pop.className = 'sub-pop';\n        pop.setAttribute('role','dialog');\n        pop.setAttribute('aria-hidden','true');\n        pop.style.position = 'absolute';\n        pop.style.minWidth = '220px';\n        pop.style.maxWidth = '340px';\n        pop.style.zIndex = 999999;\n        pop.style.opacity = '0';\n        pop.style.pointerEvents = 'none';\n        pop.style.transform = 'translateY(6px)';\n        pop.style.transition = 'opacity .16s ease, transform .16s ease';\n        pop.innerHTML = `<div class=\"pop-title\">${it.title || it.label}<\/div><div class=\"pop-body\">${it.body || ''}<\/div>`;\n        document.body.appendChild(pop);\n\n        s.appendChild(hit);\n        s.appendChild(label);\n        container.appendChild(s);\n\n        let hideTimer = null;\n        const clearHide = ()=>{ if(hideTimer){ clearTimeout(hideTimer); hideTimer = null; } };\n\n        function showPop(){\n          clearHide();\n          const rect = s.getBoundingClientRect();\n          pop.style.opacity = '1';\n          pop.style.pointerEvents = 'auto';\n          pop.setAttribute('aria-hidden','false');\n\n          requestAnimationFrame(() => {\n            const popRect = pop.getBoundingClientRect();\n            const margin = 8;\n            let left = rect.left + window.scrollX + (rect.width\/2) - (popRect.width\/2);\n            let top  = rect.top  + window.scrollY + rect.height + 8;\n\n            const winLeft  = window.scrollX + margin;\n            const winRight = window.scrollX + window.innerWidth - margin;\n            if(left < winLeft) left = winLeft;\n            if(left + popRect.width > winRight) left = Math.max(winLeft, winRight - popRect.width);\n\n            if(top + popRect.height > window.scrollY + window.innerHeight - margin){\n              top = rect.top + window.scrollY - popRect.height - 8;\n            }\n            pop.style.left = Math.round(left) + 'px';\n            pop.style.top  = Math.round(top)  + 'px';\n            pop.style.transform = 'translateY(0)';\n          });\n        }\n\n        function hidePopDelayed(){ if(hideTimer) clearTimeout(hideTimer); hideTimer = setTimeout(hidePopImmediate, 60); }\n        function hidePopImmediate(){ if(hideTimer) clearTimeout(hideTimer); pop.style.opacity = '0'; pop.style.pointerEvents = 'none'; pop.style.transform = 'translateY(6px)'; pop.setAttribute('aria-hidden','true'); }\n\n        [hit, label, s].forEach(el => {\n          el.addEventListener('mouseenter', showPop);\n          el.addEventListener('focus', showPop);\n          el.addEventListener('mouseleave', hidePopDelayed);\n          el.addEventListener('blur', hidePopImmediate);\n        });\n\n        s._cleanup = () => { hidePopImmediate(); if(pop && pop.parentNode) pop.parentNode.removeChild(pop); };\n      });\n\n      placeholder.appendChild(container);\n\n      \/* === Positioning under clicked process (center + clamps + nudges) === *\/\n      const overlayRect   = overlay.getBoundingClientRect();\n      const stepRect      = anchorStep.getBoundingClientRect();\n      const containerRect = container.getBoundingClientRect();\n\n      let desiredLeft = (stepRect.left - overlayRect.left) + (stepRect.width \/ 2) - (containerRect.width \/ 2);\n      const stepIndex = mainSteps.indexOf(anchorStep);\n      desiredLeft += (STEP_NUDGES[stepIndex] || 0);\n\n      const minLeft = -EDGE_BLEED_PX;\n      const maxLeft = overlay.clientWidth - containerRect.width + EDGE_BLEED_PX;\n      desiredLeft = Math.max(minLeft, Math.min(Math.max(minLeft, maxLeft), desiredLeft));\n      container.style.left = Math.round(desiredLeft) + 'px';\n\n      \/* === Bracket: span width, skew-aligned small right shift, triangle to exact process center === *\/\n      requestAnimationFrame(() => {\n        const contNow = container.getBoundingClientRect();\n        const stepCenterX = stepRect.left + stepRect.width\/2;  \/\/ absolute center of process\n        const triLeftInContainer = stepCenterX - contNow.left; \/\/ px relative to container\n\n        \/\/ span full subtimeline width\n        bracket.style.width = container.offsetWidth + 'px';\n        bracket.classList.add('active');\n\n        \/\/ small right shift (~2mm per subprocess) to visually align with skewed rectangles\n        const skewShiftPx = (items.length * PER_SUB_RIGHT_SHIFT_PX);\n        bracket.style.left = `calc(50% + ${skewShiftPx}px)`;\n\n        \/\/ triangle placed exactly under process center in container coordinates\n        bracket.style.setProperty('--tri-left', `${Math.round(triLeftInContainer)}px`);\n      });\n\n      \/\/ Reserve height beneath\n      placeholder.style.height = (container.offsetHeight + SUB_PLACEHOLDER_PAD) + 'px';\n    }\n\n    function hideSubtimeline(){\n      clearPlaceholder();\n      lastIdx = null;\n      lastAnchorStep = null;\n    }\n\n    \/\/ Interactions\n    mainSteps.forEach((step, idx) => {\n      step.addEventListener('click', (ev) => {\n        ev.stopPropagation();\n        buildSubtimeline(idx, step);\n        step.blur();\n      });\n      step.addEventListener('keydown', (ev) => {\n        if(ev.key === 'Enter' || ev.key === ' '){\n          ev.preventDefault();\n          buildSubtimeline(idx, step);\n        }\n      });\n    });\n\n    \/\/ Dismiss on outside click \/ Esc\n    document.addEventListener('click', (ev) => {\n      const inside = placeholder.contains(ev.target) || document.querySelector('.background-box').contains(ev.target);\n      if(!inside) hideSubtimeline();\n    });\n    window.addEventListener('keydown', (ev) => { if(ev.key === 'Escape') hideSubtimeline(); });\n\n    \/\/ Reposition on resize\n    window.addEventListener('resize', () => {\n      if(lastIdx === null || !lastAnchorStep) return;\n      buildSubtimeline(lastIdx, lastAnchorStep);\n    });\n\n  })();\n  <\/script>\n<\/div>\n\n\n\n<div style=\"position:relative; padding:20px;\">\n\n  <style>\n    \/* Scoped so it doesn't clash with other blocks *\/\n    .portcall-cards {\n      --ink: #0b1220;\n      --muted: #5a6a78;\n      --b2: #74c9ff;\n      --b3: #4fb8f6;\n      --b4: #2aa7e8;\n      --shadow: 0 10px 30px rgba(10,29,56,0.20);\n      --hover-lift: -8px;\n    }\n\n    .portcall-cards .background-box { background:#fff; border-radius:12px; box-shadow:none; }\n    .portcall-cards .overlay-content { position:relative; padding:6px 20px; box-sizing:border-box; color:var(--ink); }\n\n    .portcall-cards h1 { font-weight:700; letter-spacing:.3px; margin:0 0 12px; color:var(--ink); font-size:1.6rem; }\n    .portcall-cards .sub { color:var(--muted); margin:6px 0 10px; font-size:.95rem; }\n    .portcall-cards .instruction { color:var(--muted); margin:4px 0 10px; font-size:.95rem; }\n    .portcall-cards .highlight-dot {\n      display:inline-block; width:14px; height:14px; border-radius:50%;\n      background: linear-gradient(90deg, var(--b2), var(--b4));\n      box-shadow: 0 2px 6px rgba(42,175,244,0.18);\n      margin-right:10px; vertical-align:middle;\n      animation: pulseDot 2.2s ease-in-out infinite;\n    }\n\n    @keyframes pulseDot { 0%,100%{transform:scale(1)} 50%{transform:scale(1.15)} }\n\n    \/* Cards Grid *\/\n    .portcall-cards .cards-grid {\n      display:grid; gap:6px;\n      grid-template-columns:repeat(3,1fr);\n      margin-top:6px;\n    }\n    @media(max-width:1100px){.portcall-cards .cards-grid{grid-template-columns:repeat(2,1fr);} }\n    @media(max-width:680px){.portcall-cards .cards-grid{grid-template-columns:1fr;} }\n\n    \/* ==== CARD ==== *\/\n    .portcall-cards .card {\n      display:flex;\n      flex-direction:column;\n      position:relative; overflow:hidden;\n      border-radius:12px; padding:6px 16px;\n      background:linear-gradient(180deg,rgba(255,255,255,0.76),rgba(250,252,255,0.92));\n      box-shadow:var(--shadow);\n      border:1px solid rgba(10,30,60,0.04);\n      cursor:pointer;\n      min-height: calc(155px - 1.5cm); \/* Reduced min-height by half a centimeter *\/\n      text-decoration:none; color:inherit;\n      transition:transform 0.6s cubic-bezier(.2,.8,.25,1), box-shadow 0.6s cubic-bezier(.2,.8,.25,1);\n    }\n    .portcall-cards .card::before {\n      content:\"\"; position:absolute; left:8px; top:6px; bottom:6px; width:4px;\n      background:linear-gradient(180deg,var(--b2),var(--b4));\n      border-radius:4px; opacity:0.95;\n    }\n    .portcall-cards .card:hover {\n      box-shadow:0 22px 48px rgba(10,29,56,0.16);\n      transform:translateY(var(--hover-lift));\n    }\n\n    \/* Card Titles with icons *\/\n    .portcall-cards .card-title {\n      display:flex; align-items:center; gap:8px;\n      font-weight:800; letter-spacing:.3px;\n      margin:4px 0 4px; color:#0d3b5e; font-size:1rem; \/* Increased font size *\/\n    }\n\n    .portcall-cards .card-icon {\n      display:inline-grid; place-items:center;\n      width:20px; height:20px; border-radius:6px;\n      background:linear-gradient(135deg,rgba(10,106,176,.15),rgba(43,176,237,.15));\n      color:var(--b4);\n      flex-shrink:0;\n    }\n\n    \/* Optimization Problem Titles - Reversed Font Size *\/\n    .portcall-cards .card-field {\n      color:#24384a; font-size:1rem; line-height:1.2rem; margin:4px 0; \/* Increased font size *\/\n    }\n    .portcall-cards .card-field b {\n      color:#446178; font-weight:700; font-size:.85rem; display:block; margin-bottom:4px;\n    }\n    .portcall-cards .card-body {\n      display:inline-block; position:relative; padding-left:14px; color:#24384a;\n      font-size: .85rem; \/* Decreased font size for descriptions *\/\n    }\n    .portcall-cards .card-body::before {\n      content:\"\u2022\"; position:absolute; left:0; top:0; color:var(--ink); font-weight:700;\n    }\n  <\/style>\n\n  <div class=\"portcall-cards\">\n    <div class=\"background-box\">\n      <div class=\"overlay-content\">\n        <h1 id=\"research-section\">Maritime Research Problems<\/h1>\n        <div class=\"sub\">\n          This project identifies, classifies, and illustrates key optimization problems in port-call operations, providing benchmark data to support research and innovation in maritime logistics.\n        <\/div>\n        <p class=\"instruction\"><span class=\"highlight-dot\"><\/span>Click any card below for an in-depth description and access available data sets.<\/p>\n\n        <div class=\"cards-grid\">\n\n          <!-- 1. Berth Allocation -->\n          <a class=\"card\" href=\"https:\/\/aiportcenter.nl\/index.php\/berth-allocation\/\" target=\"_blank\" rel=\"noopener\">\n            <div class=\"card-content\">\n              <div class=\"card-title\">\n                <span class=\"card-icon\">\n                  <svg viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"currentColor\"><path d=\"M12 2a2 2 0 1 0 0 4h1v6h3l-4 5-4-5h3V6h1a2 2 0 1 0 0-4Zm-1 19v-2H8v2H5v-3H3v5h18v-5h-2v3h-3v-2h-3v2h-2Z\"\/><\/svg>\n                <\/span>\n                Berth Allocation\n              <\/div>\n              <div class=\"card-field\"><span>Assign vessels to berths, balancing berth utilization, vessel priorities, and time windows.<\/span><\/div>\n            <\/div>\n          <\/a>\n\n          <!-- 2. Quay-Crane Scheduling -->\n          <a class=\"card\" href=\"https:\/\/aiportcenter.nl\/index.php\/quay-crane\/\" target=\"_blank\" rel=\"noopener\">\n            <div class=\"card-content\">\n              <div class=\"card-title\">\n                <span class=\"card-icon\">\n                  <svg viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"currentColor\"><path d=\"M5 3h8v6H3V3Zm10 0h8v6h-8V3ZM3 9h8v6H3V9Zm10 0h8v6h-8V9ZM3 15h8v6H3v-6Zm10 0h8v6h-8v-6Z\"\/><\/svg>\n                <\/span>\n                Quay-Crane Scheduling\n              <\/div>\n              <div class=\"card-field\"><span>Determine the optimal sequence of crane moves per vessel bay while respecting crane interference.<\/span><\/div>\n            <\/div>\n          <\/a>\n\n          <!-- 3. Yard-Crane Scheduling -->\n          <a class=\"card\" href=\"https:\/\/aiportcenter.nl\/index.php\/yard-crane\/\" target=\"_blank\" rel=\"noopener\">\n            <div class=\"card-content\">\n              <div class=\"card-title\">\n                <span class=\"card-icon\">\n                  <svg viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"currentColor\"><path d=\"M3 3h8v6H3V3Zm10 0h8v6h-8V3ZM3 9h8v6H3V9Zm10 0h8v6h-8V9ZM3 15h8v6H3v-6Zm10 0h8v6h-8v-6Z\"\/><\/svg>\n                <\/span>\n                Yard-Crane Scheduling\n              <\/div>\n              <div class=\"card-field\"><span>Allocate yard cranes to stacks, while minimizing rehandles &#038; crane idle times.<\/span><\/div>\n            <\/div>\n          <\/a>\n\n          <!-- 4. Truck Appointment Scheduling -->\n          <a class=\"card\" href=\"https:\/\/aiportcenter.nl\/index.php\/truck-appointment-scheduling\/\" target=\"_blank\" rel=\"noopener\">\n            <div class=\"card-content\">\n              <div class=\"card-title\">\n                <span class=\"card-icon\">\n                  <svg viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"currentColor\"><path d=\"M3 4h13v7h5l1 2v5h-2a2 2 0 1 1-4 0H9a2 2 0 1 1-4 0H3V4Zm2 2v9h11V6H5Zm14 7v2h2v-2h-2ZM7 18a1 1 0 1 0 0-2 1 1 0 0 0 0 2Zm10 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z\"\/><\/svg>\n                <\/span>\n                Truck Appointment Scheduling\n              <\/div>\n              <div class=\"card-field\"><span>Optimize the booking of time slots for inbound and outbound trucks while leveling arrivals to avoid gate bottlenecks.<\/span><\/div>\n            <\/div>\n          <\/a>\n\n          <!-- 5. Tug & Pilot Assignment -->\n          <a class=\"card\" href=\"https:\/\/aiportcenter.nl\/index.php\/tug-pilot-assignment\/\" target=\"_blank\" rel=\"noopener\">\n            <div class=\"card-content\">\n              <div class=\"card-title\">\n                <span class=\"card-icon\">\n                  <svg viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"currentColor\"><path d=\"M3 15h18v2H3v-2Zm4-4h10v2H7v-2Zm3-4h4v2h-4V7ZM2 19h20v2H2v-2Z\"\/><\/svg>\n                <\/span>\n                Tug &#038; Pilot Assignment\n              <\/div>\n              <div class=\"card-field\"><span>Assign tugs and pilots to vessels while scheduling routes to minimize idle steaming time.<\/span><\/div>\n            <\/div>\n          <\/a>\n\n          <!-- 6. Yard-Vehicle Routing -->\n          <a class=\"card\" href=\"https:\/\/aiportcenter.nl\/index.php\/yard-vehicle-routing\/\" target=\"_blank\" rel=\"noopener\">\n            <div class=\"card-content\">\n              <div class=\"card-title\">\n                <span class=\"card-icon\">\n                  <svg viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"currentColor\"><path d=\"M3 6l6-2 6 2 6-2v14l-6 2-6-2-6 2V6Zm6 0v12l6-2V4L9 6Z\"\/><\/svg>\n                <\/span>\n                Yard-Vehicle Routing\n              <\/div>\n              <div class=\"card-field\"><span>Optimize the path for straddles and tractors to avoid conflicts and minimize empty runs.<\/span><\/div>\n            <\/div>\n          <\/a>\n\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/div>\n\n\n\n<div style=\"position:relative; padding:8px 20px 12px; margin-top:-10px;\">\n\n  <style>\n    \/* Keep your existing look & feel *\/\n    .background-box { background: #fff; border-radius: 12px; box-shadow: none; margin-top: -10px; }\n    .overlay-content { position: relative; padding: 12px 20px 16px; box-sizing: border-box; color: var(--ink); }\n\n    \/* Title + arrow *\/\n    h1 {\n      font-weight: 700;\n      letter-spacing: .3px;\n      margin: 0 0 8px;   \/* tighter vertical spacing *\/\n      color: var(--ink);\n      font-size: 1.6rem;\n      cursor: pointer;\n      display: inline-flex;\n      align-items: center;\n      gap: 10px;\n      user-select: none;\n      transition: color .25s ease;\n    }\n    h1:hover { color: #0d3b5e; }\n\n    \/* Arrow circular icon *\/\n    .arrow-button {\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      width: 38px;\n      height: 38px;\n      border-radius: 50%;\n      background: #f2f4f7;\n      color: var(--muted, #607080);\n      font-size: 1.9rem;\n      line-height: 1;\n      box-shadow: 0 2px 5px rgba(0,0,0,0.05);\n      transition: transform .35s ease, box-shadow .35s ease, background .35s ease;\n    }\n    .arrow-button:hover {\n      transform: scale(1.15);\n      background: #e9edf2;\n      box-shadow: 0 5px 10px rgba(0,0,0,0.12);\n    }\n\n    \/* Text styles *\/\n    h2 { font-weight: 800; letter-spacing: .2px; margin: 18px 0 10px; color: #0d3b5e; font-size: 1.05rem; }\n    p { color: #24384a; line-height: 1.5; }\n    .sub { color: var(--muted); margin: 8px 0 18px; }\n    .section { margin-top: 8px; }\n    .muted { color: var(--muted); }\n\n    \/* Code box *\/\n    .codebox {\n      background: #0b12200a;\n      border: 1px solid rgba(10,30,60,.08);\n      border-radius: 10px;\n      padding: 10px;\n      font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, \"Liberation Mono\", monospace;\n      font-size: .85rem;\n      line-height: 1.35;\n      color: #24384a;\n      overflow: auto;\n      white-space: pre;\n      max-height: 260px;\n    }\n\n    \/* Copy button row *\/\n    .copy-row { display: flex; gap: 8px; align-items: center; justify-content: flex-start; margin-top: 10px; }\n    .copy-btn {\n      display: inline-block;\n      padding: 6px 12px;\n      border-radius: 8px;\n      border: 1px solid rgba(10,30,60,.12);\n      background: #fff;\n      font-weight: 600;\n      font-size: .82rem;\n      cursor: pointer;\n      transition: transform .18s ease, box-shadow .18s ease, background .18s ease;\n      box-shadow: 0 2px 6px rgba(10,29,56,.08);\n    }\n    .copy-btn:hover { transform: translateY(-1px); box-shadow: 0 6px 14px rgba(10,29,56,.12); }\n    .copy-ok { font-size: .82rem; color: #2aa7e8; opacity: 0; transition: opacity .3s ease; }\n    .copy-ok.show { opacity: 1; }\n\n    \/* Toggle behavior \u2014 collapsed by default. Use max-height + opacity + transform\n       so both open and close animate smoothly (avoids instant display:none). *\/\n    .toggle-content {\n      max-height: 0; \/* collapse *\/\n      overflow: hidden;\n      opacity: 0;\n      transform: translateY(-6px);\n      transition: max-height 0.6s cubic-bezier(.2,.8,.2,1),\n                  opacity 0.55s cubic-bezier(.2,.8,.2,1),\n                  transform 0.6s cubic-bezier(.2,.8,.2,1);\n      will-change: max-height, opacity, transform;\n    }\n    .toggle-content.show {\n      max-height: 1000px; \/* large enough for content *\/\n      opacity: 1;\n      transform: translateY(0);\n    }\n  <\/style>\n\n  <div class=\"background-box\">\n    <div class=\"overlay-content\">\n\n      <!-- Title + Arrow immediately after -->\n      <h1 id=\"toggle-title\" role=\"button\" tabindex=\"0\" aria-expanded=\"false\" aria-controls=\"toggle-body\">\n        Citation &#038; Attribution Guidelines\n        <span class=\"arrow-button\" id=\"toggle-arrow\">\u25be<\/span>\n      <\/h1>\n\n      <!-- Hidden by default -->\n      <div id=\"toggle-body\" class=\"toggle-content\">\n        <p class=\"sub\">\n          This Data-Hub represents a joint effort between the <strong>AI Port Center<\/strong>, \n          industrial stakeholders, and academic collaborators.  \n          We warmly encourage both practitioners and researchers to use and reference this resource in their own work.\n        <\/p>\n\n        <div class=\"section\">\n          <h2>BibTeX Reference<\/h2>\n          <div class=\"codebox\" id=\"bibtex-ref\">\n@misc{aiport_datahub_portcall_2025,\n  author       = {Campuzano, Giovanni and Wenzel, Peter and Schulte, Frederik},\n  title        = {AI Port Data-Hub: Port-Call Optimization Problem Instances and Data},\n  year         = {2025},\n  howpublished = {\\url{https:\/\/aiportcenter.nl\/index.php\/port-call\/}},\n  note         = {Joint effort of the AI Port Center, industry stakeholders, and academic partners. Accessed: 2025-10-15}\n}\n          <\/div>\n          <div class=\"copy-row\">\n            <button class=\"copy-btn\" data-copy-target=\"#bibtex-ref\" aria-label=\"Copy BibTeX\">Copy BibTeX<\/button>\n            <span class=\"copy-ok\" aria-live=\"polite\">Copied!<\/span>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n\n  <script>\n    (function(){\n      const title = document.getElementById('toggle-title');\n      const body  = document.getElementById('toggle-body');\n      const arrow = document.getElementById('toggle-arrow');\n\n      function toggle() {\n        const willShow = !body.classList.contains('show');\n        title.setAttribute('aria-expanded', String(willShow));\n        arrow.style.transition = 'transform .6s cubic-bezier(.2,.8,.2,1)';\n        arrow.style.transform = willShow ? 'rotate(180deg)' : 'rotate(0deg)';\n\n        if (willShow) {\n          \/\/ Measure and animate to the exact height so opening matches closing speed\n          const fullH = body.scrollHeight;\n          \/\/ Ensure starting point is 0\n          body.style.maxHeight = '0px';\n          \/\/ trigger a reflow so the transition occurs\n          \/\/ eslint-disable-next-line no-unused-expressions\n          body.offsetHeight;\n          \/\/ set to full height to animate open\n          body.style.maxHeight = fullH + 'px';\n          body.classList.add('show');\n        } else {\n          \/\/ animate closing: set maxHeight to current height then to 0\n          const fullH = body.scrollHeight;\n          body.style.maxHeight = fullH + 'px';\n          \/\/ force reflow\n          \/\/ eslint-disable-next-line no-unused-expressions\n          body.offsetHeight;\n          body.classList.remove('show');\n          body.style.maxHeight = '0px';\n        }\n      }\n\n      \/\/ After opening, clear max-height so content can grow naturally later\n      body.addEventListener('transitionend', (ev) => {\n        if (ev.propertyName === 'max-height') {\n          if (body.classList.contains('show')) {\n            body.style.maxHeight = 'none';\n          }\n        }\n      });\n\n      title.addEventListener('click', toggle);\n      title.addEventListener('keydown', (e) => {\n        if (e.key === 'Enter' || e.key === ' ') {\n          e.preventDefault();\n          toggle();\n        }\n      });\n\n      \/\/ Copy-to-clipboard helper\n      function copyFrom(sel, okEl) {\n        const el = document.querySelector(sel);\n        if (!el) return;\n        const text = el.innerText.trim();\n        if (navigator.clipboard && navigator.clipboard.writeText) {\n          navigator.clipboard.writeText(text).then(() => {\n            okEl.classList.add('show');\n            setTimeout(() => okEl.classList.remove('show'), 1400);\n          }).catch(fallback);\n        } else {\n          fallback();\n        }\n        function fallback() {\n          const ta = document.createElement('textarea');\n          ta.value = text;\n          ta.style.position = 'fixed';\n          ta.style.opacity = '0';\n          document.body.appendChild(ta);\n          ta.focus(); ta.select();\n          try { document.execCommand('copy'); } catch(e) {}\n          document.body.removeChild(ta);\n          okEl.classList.add('show');\n          setTimeout(() => okEl.classList.remove('show'), 1400);\n        }\n      }\n\n      document.querySelectorAll('.copy-btn').forEach(btn => {\n        btn.addEventListener('click', function(e) {\n          e.preventDefault();\n          const target = this.getAttribute('data-copy-target');\n          const ok = this.parentElement.querySelector('.copy-ok');\n          copyFrom(target, ok);\n        });\n      });\n    })();\n  <\/script>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Port-Call Processes Timeline The Port-Call Data-Hub Optimization Project is a collaborative initiative aimed at connecting industry practitioners and academic researchers to advance data-driven innovation in port logistics. Below, we present a visual overview of the Port-Call Processes at the Port of Rotterdam. Hover a step for details. Click a main step to show its subprocesses [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_uag_custom_page_level_css":"","footnotes":""},"class_list":["post-333","page","type-page","status-publish","hentry"],"blocksy_meta":{"styles_descriptor":{"styles":{"desktop":"","tablet":"","mobile":""},"google_fonts":[],"version":7}},"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"peterwenzel","author_link":"https:\/\/aiportcenter.nl\/index.php\/author\/peterwenzel\/"},"uagb_comment_info":0,"uagb_excerpt":"Port-Call Processes Timeline The Port-Call Data-Hub Optimization Project is a collaborative initiative aimed at connecting industry practitioners and academic researchers to advance data-driven innovation in port logistics. Below, we present a visual overview of the Port-Call Processes at the Port of Rotterdam. Hover a step for details. Click a main step to show its subprocesses&hellip;","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/aiportcenter.nl\/index.php\/wp-json\/wp\/v2\/pages\/333","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/aiportcenter.nl\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/aiportcenter.nl\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/aiportcenter.nl\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/aiportcenter.nl\/index.php\/wp-json\/wp\/v2\/comments?post=333"}],"version-history":[{"count":694,"href":"https:\/\/aiportcenter.nl\/index.php\/wp-json\/wp\/v2\/pages\/333\/revisions"}],"predecessor-version":[{"id":1683,"href":"https:\/\/aiportcenter.nl\/index.php\/wp-json\/wp\/v2\/pages\/333\/revisions\/1683"}],"wp:attachment":[{"href":"https:\/\/aiportcenter.nl\/index.php\/wp-json\/wp\/v2\/media?parent=333"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}