{"id":12,"date":"2024-03-13T13:50:12","date_gmt":"2024-03-13T13:50:12","guid":{"rendered":"https:\/\/rostocktrelleborg.com\/nl\/?page_id=12"},"modified":"2026-11-13T09:22:29","modified_gmt":"2026-11-13T09:22:29","slug":"homepage","status":"publish","type":"page","link":"https:\/\/rostocktrelleborg.com\/nl\/","title":{"rendered":"Veerboot Rostock Trelleborg"},"content":{"rendered":"\n<div class=\"wp-block-group rtf-hero is-layout-flow wp-block-group-is-layout-flow\">\n<div class=\"wp-block-group rtf-hero-inner is-layout-flow wp-block-group-is-layout-flow\">\n<p class=\"rtf-kicker wp-block-paragraph\">Rostock &rarr; Trelleborg &middot; Oostzee<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Met de veerboot van Rostock naar Trelleborg<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">De boot van Rostock naar Trelleborg doet er ongeveer zes uur over. TT Line en Stena Line varen de route allebei, een paar keer per dag en ook &#8217;s nachts.<\/p>\n\n\n\n<div class=\"rtf-route\">\n<span class=\"rtf-route-port\"><small>ROS<\/small><strong>Rostock<\/strong><\/span>\n<span class=\"rtf-route-line\"><span>6 UUR &middot; 150 KM<\/span><\/span>\n<span class=\"rtf-route-port\"><small>TRG<\/small><strong>Trelleborg<\/strong><\/span>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-group rtf-book is-layout-flow wp-block-group-is-layout-flow\">\n<form action=\"\/nl\/go\/ttout\" method=\"get\" target=\"_blank\" rel=\"nofollow sponsored noopener\">\n<div class=\"rtf-field\">\n<label for=\"rtf-from\">Vertrek<\/label>\n<select id=\"rtf-from\" name=\"from\"><option value=\"rostock\">Rostock (Duitsland)<\/option><option value=\"trelleborg\">Trelleborg (Zweden)<\/option><\/select>\n<\/div>\n<div class=\"rtf-field\">\n<label for=\"rtf-to\">Aankomst<\/label>\n<select id=\"rtf-to\" name=\"to\"><option value=\"trelleborg\">Trelleborg (Zweden)<\/option><option value=\"rostock\">Rostock (Duitsland)<\/option><\/select>\n<\/div>\n<div class=\"rtf-field\">\n<label for=\"rtf-date\">Datum<\/label>\n<input id=\"rtf-date\" name=\"date\" type=\"date\">\n<\/div>\n<button type=\"submit\">Afvaarten zoeken<\/button>\n<\/form>\n<p class=\"rtf-book-note\">Prijzen en beschikbaarheid via Direct Ferries<\/p>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-group rtf-cols is-layout-flow wp-block-group-is-layout-flow\">\n<div class=\"wp-block-group rtf-rail-left is-layout-flow wp-block-group-is-layout-flow\">\n<p class=\"rtf-kicker wp-block-paragraph\">Vanuit Nederland<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Waarom via Rostock?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Via Rostock rijd je niet door Denemarken en betaal je geen tol voor de Sontbrug. Op de boot kun je eten of een paar uur slapen voordat je in Zweden verder rijdt.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"rtf-kicker wp-block-paragraph\">Inchecken<\/p>\n\n\n\n<p class=\"rtf-stat\">60&ndash;90<span> MIN<\/span><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Zo lang voor vertrek moet je bij de terminal zijn. Met een camper of caravan iets eerder.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"rtf-kicker wp-block-paragraph\">Naar de haven<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Uit de richting Berlijn neem je de A19, die eindigt vlak bij de haven. Vanuit Hamburg rijd je over de A20. Meer over de <a href=\"\/nl\/rostock-haven\/\">haven van Rostock<\/a>.<\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-group rtf-main is-layout-flow wp-block-group-is-layout-flow\">\n\n\n<p class=\"wp-block-paragraph\">Tussen Rostock in Noord-Duitsland en Trelleborg in het zuiden van Zweden varen twee rederijen: TT Line en Stena Line. Op deze pagina zie je de afvaarten van vandaag, hoe lang je onderweg bent, waar de prijs van afhangt en wat je over de twee havens moet weten.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">De route in het kort<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Route<\/strong><\/td><td>Rostock (Duitsland) \u2013 Trelleborg (Zweden)<\/td><\/tr><tr><td><strong>Rederijen<\/strong><\/td><td>TT Line en Stena Line<\/td><\/tr><tr><td><strong>Vaartijd<\/strong><\/td><td>ongeveer 6 uur, &#8217;s nachts 7 tot 8 uur<\/td><\/tr><tr><td><strong>Afstand<\/strong><\/td><td>ruim 150 kilometer over de Oostzee<\/td><\/tr><tr><td><strong>Afvaarten<\/strong><\/td><td>meestal 6 tot 8 per dag, per richting<\/td><\/tr><tr><td><strong>Voertuigen<\/strong><\/td><td>auto, camper, caravan, motor, vrachtwagen<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Met de boot van Nederland naar Zweden<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ga je met de auto van Nederland naar Zweden, dan heb je grofweg drie keuzes:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Via Denemarken.<\/strong> Je rijdt door Duitsland en Denemarken en gaat over de Sontbrug naar Malm\u00f6. Onderweg betaal je bruggentol, of je neemt in Puttgarden de korte boot naar R\u00f8dby.<\/li>\n\n\n\n<li><strong>Via Rostock.<\/strong> Je rijdt door Duitsland naar Rostock en neemt daar de boot naar Trelleborg. Je komt niet in Denemarken en betaalt geen bruggentol, maar je bent wel zes uur op zee.<\/li>\n\n\n\n<li><strong>Via Kiel.<\/strong> De nachtboot van Kiel naar G\u00f6teborg is handig als je naar West-Zweden of Noorwegen gaat.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Wat het handigst is, hangt af van waar je heen gaat en of je liever rijdt of vaart. Heb je haast, dan is de route via Denemarken meestal sneller. Wil je onderweg een paar uur rust, of ga je naar het zuiden of oosten van Zweden, dan is Rostock een goede keus.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Afvaarten Rostock \u2013 Trelleborg vandaag<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Dit zijn de eerstvolgende boten van Rostock naar Trelleborg, van beide rederijen. De tijden worden vanzelf bijgewerkt.<\/p>\n\n\n<div class=\"tp-wrap tp-theme-extended_cards tp-day-setup-classic\" data-config=\"{&quot;rest&quot;:&quot;https:\\\/\\\/rostocktrelleborg.com\\\/nl\\\/wp-json\\\/timetables-pro\\\/v1\\\/timetables&quot;,&quot;routes&quot;:[157],&quot;days&quot;:1,&quot;autoload&quot;:true,&quot;theme&quot;:&quot;extended_cards&quot;,&quot;daySetup&quot;:&quot;classic&quot;,&quot;limit10&quot;:false,&quot;routeLabels&quot;:{&quot;157&quot;:&quot;Rostock-Trelleborg&quot;},&quot;opFilter&quot;:[&quot;13&quot;,&quot;36&quot;],&quot;labels&quot;:{&quot;ui_date&quot;:&quot;Datum&quot;,&quot;ui_days&quot;:&quot;Dagen&quot;,&quot;ui_button&quot;:&quot;Afvaarten tonen&quot;,&quot;status_idle&quot;:&quot;Kies een datum en klik op Afvaarten tonen&quot;,&quot;status_loading&quot;:&quot;Laden...&quot;,&quot;status_empty&quot;:&quot;Geen afvaarten gevonden&quot;,&quot;status_found&quot;:&quot;%d afvaarten gevonden&quot;,&quot;th_date&quot;:&quot;Datum&quot;,&quot;th_dep&quot;:&quot;Vertrek&quot;,&quot;th_arr&quot;:&quot;Aankomst&quot;,&quot;th_dur&quot;:&quot;Duur&quot;,&quot;th_ship&quot;:&quot;Schip&quot;,&quot;th_op&quot;:&quot;Operator&quot;,&quot;th_route&quot;:&quot;Route&quot;,&quot;wd_sun&quot;:&quot;ZO&quot;,&quot;wd_mon&quot;:&quot;MA&quot;,&quot;wd_tue&quot;:&quot;DI&quot;,&quot;wd_wed&quot;:&quot;WO&quot;,&quot;wd_thu&quot;:&quot;DO&quot;,&quot;wd_fri&quot;:&quot;VR&quot;,&quot;wd_sat&quot;:&quot;ZA&quot;,&quot;summary_footer_one&quot;:&quot;\\u00bb Bekijk alle %s afvaarten in onze dienstregeling&quot;,&quot;summary_footer_two&quot;:&quot;\\u00bb Bekijk meer %1$s en %2$s afvaarten in onze dienstregeling&quot;,&quot;summary_footer_generic&quot;:&quot;Bekijk onze dienstregeling voor meer afvaarten&quot;,&quot;summary_header&quot;:&quot;De volgende twee afvaarten:&quot;,&quot;summary_no_upcoming&quot;:&quot;Geen aankomende afvaarten gevonden&quot;,&quot;more_link&quot;:&quot;Meer afvaarten&quot;,&quot;more_departures_button&quot;:&quot;Meer afvaarten tonen&quot;,&quot;day_nav_previous&quot;:&quot;Vorige dag tonen&quot;,&quot;day_nav_next&quot;:&quot;Volgende dag tonen&quot;,&quot;day_nav_today&quot;:&quot;Vandaag tonen&quot;,&quot;day_nav_tomorrow&quot;:&quot;Morgen tonen&quot;,&quot;local_time_pair&quot;:&quot;Lokale tijd vertrekhaven: %1$s \\\/ Lokale tijd aankomsthaven: %2$s&quot;,&quot;local_time_combined&quot;:&quot;Lokale tijd vertrek- en aankomsthaven: %s&quot;,&quot;tag_often_booked&quot;:&quot;\\u2b50 Vaak geboekt&quot;,&quot;tag_leaving_soon&quot;:&quot;\\ud83d\\udd34 Vertrekt binnenkort&quot;,&quot;tag_currently_sailing&quot;:&quot;\\ud83d\\udfe2 Nu onderweg&quot;,&quot;tag_arrived&quot;:&quot;\\u26ab Aangekomen&quot;,&quot;tag_overnight&quot;:&quot;Nachtvaart&quot;},&quot;showLogo&quot;:true,&quot;activityBoosters&quot;:true,&quot;title&quot;:&quot;&quot;,&quot;shipMap&quot;:[],&quot;shipLinks&quot;:[],&quot;showShip&quot;:true,&quot;departurePort&quot;:&quot;Rostock&quot;,&quot;arrivalPort&quot;:&quot;Trelleborg&quot;,&quot;departureTimezone&quot;:&quot;Europe\\\/Berlin&quot;,&quot;arrivalTimezone&quot;:&quot;Europe\\\/Berlin&quot;}\">\n  <div class=\"tp-controls\" role=\"group\" aria-label=\"Timetable controls\">\n    <div>\n      <label for=\"tp-date-ops\">Datum<\/label><br>\n      <input id=\"tp-date-ops\" class=\"tp-date\" type=\"date\" aria-label=\"Datum\">\n    <\/div>\n    <div class=\"tp-day-field\">\n      <label for=\"tp-range-ops\">Dagen<\/label><br>\n      <select id=\"tp-range-ops\" class=\"tp-range\" aria-label=\"Dagen\">\n        <option value=\"1\">1<\/option><option value=\"3\">3<\/option><option value=\"7\">7<\/option><option value=\"14\">14<\/option>\n      <\/select>\n    <\/div>\n    <div><button id=\"tp-load-ops\" class=\"tp-btn\">Afvaarten tonen<\/button><\/div>\n  <\/div>\n\n  <div class=\"tp-local-nav-row\">\n    <div class=\"tp-local-times\" id=\"tp-local-times-ops\" aria-live=\"polite\"><\/div>\n    <div class=\"tp-day-nav-host\"><\/div>\n  <\/div>\n\n  \n  <div id=\"tp-status-ops\" class=\"tp-muted\" aria-live=\"polite\">Kies een datum en klik op Afvaarten tonen<\/div>\n\n  <div id=\"tp-ops-results\"><\/div>\n\n  <div class=\"tp-loader\" aria-hidden=\"true\">\n    <div class=\"tp-loader-card\">\n      <div class=\"tp-spinner\" aria-hidden=\"true\"><\/div>\n      <div class=\"tp-loader-text\">Laden...<\/div>\n    <\/div>\n  <\/div>\n<\/div>\n\n<script>\n(function(){\n  const wrap   = document.currentScript.previousElementSibling;\n  const cfg    = JSON.parse(wrap.getAttribute('data-config')||'{}');\n  const L      = cfg.labels||{};\n  const dateEl = wrap.querySelector('#tp-date-ops');\n  const daysEl = wrap.querySelector('#tp-range-ops');\n  const btn    = wrap.querySelector('#tp-load-ops');\n  const status = wrap.querySelector('#tp-status-ops');\n  const out    = wrap.querySelector('#tp-ops-results');\n  const loader = wrap.querySelector('.tp-loader');\n  const navHost = wrap.querySelector('.tp-day-nav-host');\n  const localTimesEl = wrap.querySelector('#tp-local-times-ops');\n\n  const showShip = (cfg.showShip !== false && cfg.showShip !== 0 && cfg.showShip !== '0');\n  const activityBoosters = !!cfg.activityBoosters;\n  const daySetup = (cfg.daySetup === 'modern') ? 'modern' : 'classic';\n  const limit10 = !!cfg.limit10;\n  let featuredKey = '';\n  let soonKey = '';\n  let revealAll = false;\n\n  if (daySetup === 'modern') {\n    const dayField = wrap.querySelector('.tp-day-field');\n    if (dayField) dayField.style.display = 'none';\n  }\n\n  dateEl.valueAsDate = new Date();\n  dateEl.min = new Date().toISOString().split('T')[0];\n  Array.from(daysEl.options).forEach(o=>{ if(parseInt(o.value,10)===parseInt(cfg.days||7,10)) o.selected=true; });\n\n  function pad(n){ return String(n).padStart(2,'0'); }\n  function iso(d){ return d.getFullYear()+'-'+pad(d.getMonth()+1)+'-'+pad(d.getDate()); }\n  function toLocal(s){ return new Date(s); }\n  function hhmm(d){ return d.toLocaleTimeString([], {hour:'2-digit', minute:'2-digit'}); }\n  function dShort(d){ return d.toLocaleDateString([], {day:'numeric', month:'short'}); }\n  function dur(m){ const h=Math.floor(m\/60), r=m%60; return r? (h+'h '+r+'m') : (h+'h'); }\n\n  const WD = [\n    L.wd_sun || 'SUN',\n    L.wd_mon || 'MON',\n    L.wd_tue || 'TUE',\n    L.wd_wed || 'WED',\n    L.wd_thu || 'THU',\n    L.wd_fri || 'FRI',\n    L.wd_sat || 'SAT'\n  ];\n\n  function setLoader(v){ loader.classList.toggle('show', !!v); loader.setAttribute('aria-hidden', v?'false':'true'); }\n\n  function formatZoneTime(tz){\n    if (!tz) return '--:--';\n    try {\n      return new Intl.DateTimeFormat([], {hour:'2-digit', minute:'2-digit', hour12:false, timeZone: tz}).format(new Date());\n    } catch (e) {\n      return '--:--';\n    }\n  }\n\n  function renderLocalTimes(){\n    if (!localTimesEl) return;\n    if (!cfg.departureTimezone || !cfg.arrivalTimezone) {\n      localTimesEl.textContent = '';\n      return;\n    }\n    const depTime = formatZoneTime(cfg.departureTimezone);\n    const arrTime = formatZoneTime(cfg.arrivalTimezone);\n    const pairTpl = L.local_time_pair || 'Departure Port Local Time: %1$s \/ Arrival Port Local Time: %2$s';\n    const combinedTpl = L.local_time_combined || 'Departure & Arrival Port Local Time: %s';\n    if (depTime === arrTime) {\n      localTimesEl.textContent = combinedTpl.replace('%s', depTime);\n      return;\n    }\n    localTimesEl.textContent = pairTpl.replace('%1$s', depTime).replace('%2$s', arrTime);\n  }\n\n  function setStatusInline(html){\n    let box = wrap.querySelector('.tp-controls-status');\n    if (!box) {\n      box = document.createElement('div');\n      box.className = 'tp-controls-status';\n      wrap.querySelector('.tp-controls').appendChild(box);\n    }\n    box.innerHTML = html || '';\n  }\n\n  function clearStatusInline(){\n    const box = wrap.querySelector('.tp-controls-status');\n    if (box) box.innerHTML = '';\n  }\n\n  function navHtml(){\n    if (daySetup !== 'modern') return '';\n    const base = new Date(dateEl.value || new Date());\n    const today = new Date();\n    const tomorrow = new Date(today);\n    tomorrow.setDate(today.getDate() + 1);\n    const isToday = base.toDateString() === today.toDateString();\nlet prevLabel = L.day_nav_previous || 'Show previous day';\nlet nextLabel = L.day_nav_next || 'Show next day';\nif (isToday) nextLabel = L.day_nav_tomorrow || 'Show tomorrow';\nif (base.toDateString() === tomorrow.toDateString()) prevLabel = L.day_nav_today || 'Show today';\n    return '<div class=\"tp-day-nav\">'\n      + (isToday ? '' : '<a href=\"#\" data-shift=\"-1\">'+prevLabel+'<\/a>')\n      + '<a href=\"#\" data-shift=\"1\">'+nextLabel+'<\/a>'\n      + '<\/div>';\n  }\n\n  function shiftDate(delta){\n    const base = new Date(dateEl.value || new Date());\n    base.setDate(base.getDate() + delta);\n    dateEl.value = iso(base);\n    load();\n  }\n\n  function moreButtonHtml(hiddenCount){\n    if (!limit10 || revealAll || hiddenCount <= 0) return '';\n    return '<div style=\"margin-top:12px;text-align:center\">'\n      + '<button type=\"button\" class=\"tp-btn tp-more-btn\">'+(L.more_departures_button || 'Show more departures')+' ('+hiddenCount+')<\/button>'\n      + '<\/div>';\n  }\n\n  function opCell(r){\n    const name = r.opName || ('Operator '+(r.opId||''));\n    const logo = (cfg.showLogo && r.opLogo) ? '<img decoding=\"async\" src=\"'+r.opLogo+'\" alt=\"'+name+'\"> ' : '';\n    const label = logo + '<span>'+name+'<\/span>';\n    return r.opLink ? '<a class=\"tp-op\" href=\"'+r.opLink+'\" target=\"_blank\" rel=\"nofollow noopener\">'+label+'<\/a>' : '<span class=\"tp-op\">'+label+'<\/span>';\n  }\n\n  function shipInfo(original){\n    const key = (original||'').toLowerCase().trim();\n    const label = (cfg.shipMap && cfg.shipMap[key]) || original || '';\n    const href  = (cfg.shipLinks && cfg.shipLinks[key]) || '';\n    return {label, href};\n  }\n\n  function shipBadge(original){\n    const s = shipInfo(original);\n    const badge = '<span class=\"tp-badge\">'+(s.label||'')+'<\/span>';\n    return s.href ? ('<a href=\"'+s.href+'\" target=\"_blank\" rel=\"nofollow noopener\">'+badge+'<\/a>') : badge;\n  }\n\n  function rowKey(r){\n    return [String(r.routeId||''), String(r.opId||''), String(+r.dep||0), String(+r.arr||0)].join('|');\n  }\n\n  function pickFeaturedKey(rows, avoidKey){\n    if (!activityBoosters || !rows.length) return '';\n    const routesSum = Array.isArray(cfg.routes) ? cfg.routes.reduce((acc, n)=>acc + (parseInt(n,10)||0), 0) : 0;\n    const dateSeed = parseInt(String(dateEl.value || '').replace(\/-\/g,''), 10) || 0;\n\n    let pool = rows;\n    if (avoidKey) {\n      const soonIdx = rows.findIndex(r => rowKey(r) === avoidKey);\n      if (soonIdx >= 0) {\n        const later = rows.slice(soonIdx + 1).filter(r => rowKey(r) !== avoidKey);\n        pool = later.length ? later : rows.filter(r => rowKey(r) !== avoidKey);\n      } else {\n        pool = rows.filter(r => rowKey(r) !== avoidKey);\n      }\n    }\n\n    if (!pool.length) return '';\n    const idx = Math.abs((routesSum + dateSeed + rows.length) % pool.length);\n    return rowKey(pool[idx]);\n  }\n\n  function pickSoonKey(rows){\n    if (!activityBoosters || !rows.length) return '';\n    const now = Date.now();\n    const todayStr = new Date(now).toDateString();\n    const firstUpcoming = rows.find(r => (r.dep instanceof Date) && r.dep.getTime() > now && r.dep.toDateString() === todayStr);\n    return firstUpcoming ? rowKey(firstUpcoming) : '';\n  }\n\n  function boostersFor(r){\n    if (!activityBoosters) return [];\n    const now = Date.now();\n    const depMs = (r.dep instanceof Date) ? r.dep.getTime() : 0;\n    const arrMs = (r.arr instanceof Date) ? r.arr.getTime() : 0;\n    const depIsToday = (r.dep instanceof Date) && (new Date(now).toDateString() === r.dep.toDateString());\n\n    if (depMs > 0 && arrMs > 0 && depMs <= now && arrMs > now) {\n      return [{cls:'tp-booster-sailing', text:(L.tag_currently_sailing || '\ud83d\udfe2 Currently sailing')}];\n    }\n    if (depIsToday && arrMs > 0 && arrMs <= now) {\n      return [{cls:'tp-booster-arrived', text:(L.tag_arrived || '\u26ab Arrived')}];\n    }\n    if (rowKey(r) === soonKey) return [{cls:'tp-booster-soon', text:(L.tag_leaving_soon || '\ud83d\udd34 Leaving soon')}];\n    if (r.dep && r.arr && r.dep.toDateString() !== r.arr.toDateString()) return [{cls:'tp-booster-overnight', text:(L.tag_overnight || 'Overnight')}];\n\n    return [];\n  }\n\n  function boostersHtml(r, floating){\n    const tags = boostersFor(r);\n    if (!tags.length) return '';\n    const cls = floating ? 'tp-boosters tp-boosters-float' : 'tp-boosters';\n    return '<div class=\"'+cls+'\">' + tags.map(t => '<span class=\"tp-booster '+t.cls+'\">'+boosterLabelHtml(t.text)+'<\/span>').join('') + '<\/div>';\n  }\n\n  function boosterLabelHtml(text){\n    return String(text || '').replace(\/^(\ud83d\udd34|\ud83d\udfe2|\u26ab|\u2b50)\\s*\/, '<span class=\"tp-booster-emoji\">$1<\/span>');\n  }\n\n  function routeTicketHtml(label){\n    const raw = String(label || '').trim();\n    if (!raw) return '';\n    if (cfg.theme !== 'small_cards') return escAttr(raw);\n    const parts = raw.split(\/\\s*[\\-\u2013]\\s*\/, 2);\n    if (parts.length < 2) return escAttr(raw);\n    return escAttr(parts[0]) + '<br>' + escAttr(parts[1]);\n  }\n\n  function escAttr(v){\n    return String(v||'').replace(\/[&<>\"']\/g, m => ({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[m]));\n  }\n\n  function bindRowLinks(){\n    if (cfg.theme !== 'max_clickouts') return;\n    out.querySelectorAll('tr.tp-row-link').forEach((row)=>{\n      row.setAttribute('role','link');\n      row.setAttribute('tabindex','0');\n      row.addEventListener('click', (e)=>{\n        if (e.target && e.target.closest('a')) return;\n        const href = row.getAttribute('data-row-link');\n        if (!href) return;\n        window.open(href, '_blank', 'noopener,noreferrer');\n      });\n      row.addEventListener('keydown', (e)=>{\n        if (e.key !== 'Enter' && e.key !== ' ') return;\n        e.preventDefault();\n        row.click();\n      });\n    });\n  }\n\n  function routeLabel(rid){\n    return (cfg.routeLabels && (cfg.routeLabels[String(rid)] || cfg.routeLabels[rid])) || String(rid);\n  }\n\n  function renderTable(rows){\n    const th = {date:L.th_date,dep:L.th_dep,arr:L.th_arr,dur:L.th_dur,ship:L.th_ship,route:L.th_route,op:L.th_op};\n\n    const headCells = [\n      '<th>'+th.date+'<\/th>',\n      '<th>'+th.dep+'<\/th>',\n      '<th>'+th.arr+'<\/th>',\n      '<th>'+th.dur+'<\/th>'\n    ];\n    if (showShip) {\n      headCells.push('<th>'+th.ship+'<\/th>');\n    }\n    headCells.push('<th>'+th.route+'<\/th>');\n    headCells.push('<th>'+th.op+'<\/th>');\n\n    let html = '<table class=\"tp-table\"><thead><tr>'+headCells.join('')+'<\/tr><\/thead><tbody>';\n    rows.forEach(r=>{\n      const dow = WD[r.dep.getDay()] || '';\n      const clickable = (cfg.theme === 'max_clickouts' && r.opLink);\n      const rowAttr = clickable ? (' class=\"tp-row-link\" data-row-link=\"'+escAttr(r.opLink)+'\"') : '';\n      const dateBoosters = (cfg.theme === 'max_clickouts') ? '' : boostersHtml(r, false);\n      const routeBoosters = (cfg.theme === 'max_clickouts') ? boostersHtml(r, false) : '';\n      const cells = [\n        '<td>'+dShort(r.dep)+' <span class=\"tp-day\">'+dow+'<\/span>'+dateBoosters+'<\/td>',\n        '<td>'+hhmm(r.dep)+'<\/td>',\n        '<td>'+hhmm(r.arr)+'<\/td>',\n        '<td>'+dur(r.min)+'<\/td>'\n      ];\n      if (showShip) {\n        cells.push('<td>'+shipBadge(r.ship)+'<\/td>');\n      }\n      cells.push('<td>'+routeBoosters+'<div>'+routeLabel(r.routeId)+'<\/div><\/td>');\n      cells.push('<td>'+opCell(r)+'<\/td>');\n      html += '<tr'+rowAttr+'>'+cells.join('')+'<\/tr>';\n    });\n    html += '<\/tbody><\/table>';\n    return html;\n  }\n\n  function renderCards(rows){\n    if (cfg.theme === 'extended_cards') {\n      return renderExtendedCards(rows);\n    }\n\n    let html = '<div class=\"tp-cardlist\">';\n    rows.forEach(r=>{\n      const dow   = WD[r.dep.getDay()] || '';\n      const times = hhmm(r.dep) + ' <span class=\"tp-arrow\">\u2192<\/span> ' + hhmm(r.arr);\n      html += '<div class=\"tp-card\">'+boostersHtml(r, true)+\n        \/\/ Row 1: Date + weekday + times\n        '<div class=\"tp-mrow\">'+\n          '<div class=\"lhs\"><span class=\"tp-sub\">'+dShort(r.dep)+'<\/span><span class=\"tp-day\">'+dow+'<\/span><\/div>'+\n          '<div class=\"rhs\"><span class=\"tp-time\">'+times+'<\/span><\/div>'+\n        '<\/div>';\n\n      if (showShip) {\n        html +=\n        \/\/ Row 2: Ship\n        '<div class=\"tp-mrow\">'+\n          '<div class=\"lhs\">'+shipBadge(r.ship)+'<\/div>'+\n          '<div class=\"rhs\"><\/div>'+\n        '<\/div>';\n      }\n\n      html +=\n        \/\/ Row 3: Operator + route label\n        '<div class=\"tp-mrow\">'+\n          '<div class=\"lhs\">'+opCell(r)+'<\/div>'+\n          '<div class=\"rhs\"><span class=\"tp-route-ticket\">'+routeTicketHtml(routeLabel(r.routeId))+'<\/span><\/div>'+\n        '<\/div>'+\n      '<\/div>';\n    });\n    html += '<\/div>';\n    return html;\n  }\n\n  function renderExtendedCards(rows){\n    const ctaText = L.more_link || 'More sailings';\n    let html = '<div class=\"tp-cardlist\">';\n    rows.forEach(r=>{\n      const dow = WD[r.dep.getDay()] || '';\n      const link = r.opLink ? ('<a class=\"tp-ext-cta\" href=\"'+r.opLink+'\" target=\"_blank\" rel=\"nofollow noopener\">'+ctaText+' <span class=\"tp-ext-cta-arrow\">\u00bb<\/span><\/a>') : '<span class=\"tp-ext-cta\">'+ctaText+' <span class=\"tp-ext-cta-arrow\">\u00bb<\/span><\/span>';\n      html += '<div class=\"tp-ext-card\">'\n        + boostersHtml(r, true)\n        + '<div class=\"tp-ext-left\">'\n        +   '<div>'+opCell(r)+'<\/div>'\n        +   (showShip ? ('<div>'+shipBadge(r.ship)+'<\/div>') : '')\n        + '<\/div>'\n        + '<div class=\"tp-ext-mid\">'\n        +   '<div class=\"tp-ext-top\"><span class=\"tp-sub\">'+dShort(r.dep)+' <span class=\"tp-day\">'+dow+'<\/span><\/span><span class=\"tp-ext-dur\">'+dur(r.min)+'<\/span><\/div>'\n        +   '<div class=\"tp-ext-times\"><span class=\"tp-ext-time\">'+hhmm(r.dep)+'<\/span><span class=\"tp-ext-line\"><\/span><span class=\"tp-ext-dur\">'+dur(r.min)+'<\/span><span class=\"tp-ext-line\"><\/span><span class=\"tp-ext-time\">'+hhmm(r.arr)+'<\/span><\/div>'\n        +   '<div class=\"tp-ext-route\">'+routeLabel(r.routeId)+'<\/div>'\n        + '<\/div>'\n        + '<div class=\"tp-ext-right\">'+link+'<\/div>'\n        + '<\/div>';\n    });\n    html += '<\/div>';\n    return html;\n  }\n\n  \/\/ Safe fetch helper\n  async function fetchOne(routeId, from, to){\n    try{\n      const url = new URL(cfg.rest);\n      url.searchParams.set('route', String(routeId));\n      url.searchParams.set('from', from);\n      url.searchParams.set('to', to);\n      const res = await fetch(url.toString(), {credentials:'same-origin'});\n      if(!res.ok) return { rid: routeId, error: 'HTTP '+res.status };\n      const json = await res.json();\n      const list = (json && json.data && Array.isArray(json.data.rows)) ? json.data.rows : [];\n      return { rid: routeId, rows: list };\n    }catch(e){\n      return { rid: routeId, error: String(e && e.message ? e.message : e) };\n    }\n  }\n\n  async function load(){\n    btn.disabled = true; setLoader(true); status.textContent = L.status_loading;\n\n    const start = new Date(dateEl.value || new Date());\n    const days  = (daySetup === 'modern') ? 1 : Math.max(1, parseInt(daysEl.value,10)||1);\n    const end   = new Date(start); end.setDate(start.getDate()+days-1);\n    const fromIso = iso(start), toIso = iso(end);\n\n    try{\n      const results  = await Promise.all((cfg.routes||[]).map(rid=>fetchOne(rid, fromIso, toIso)));\n      const oks  = results.filter(r => !r.error);\n      const errs = results.filter(r =>  r.error);\n\n      const all = [];\n      oks.forEach(({rid, rows})=>{\n        rows.forEach(t=>{\n          all.push({\n            routeId: rid,\n            opId: t.operatorId || null,\n            opName: t.operatorName || '',\n            opLogo: t.operatorLogo || '',\n            opLink: t.operatorLink || '',\n            dep: toLocal(t.departureTime),\n            arr: toLocal(t.arrivalTime),\n            min: t.durationInMinutes || 0,\n            ship: t.shipName || ''\n          });\n        });\n      });\n\n      let rows = all;\n      if (Array.isArray(cfg.opFilter) && cfg.opFilter.length>0) {\n        rows = all.filter(r => r.opId && cfg.opFilter.includes(String(r.opId)));\n      }\n\n      rows.sort((a,b)=> a.dep - b.dep);\n\n      const todayStr = new Date().toDateString();\n      const nowMs = Date.now();\n      const arrivedToday = rows\n        .filter(r => (r.dep instanceof Date) && (r.arr instanceof Date) && r.dep.toDateString() === todayStr && r.arr.getTime() <= nowMs)\n        .sort((a,b) => b.arr - a.arr);\n      if (arrivedToday.length > 2) {\n        const keep = new Set(arrivedToday.slice(0,2).map(rowKey));\n        rows = rows.filter(r => {\n          const isArrivedToday = (r.dep instanceof Date) && (r.arr instanceof Date) && r.dep.toDateString() === todayStr && r.arr.getTime() <= nowMs;\n          return !isArrivedToday || keep.has(rowKey(r));\n        });\n      }\n\n      const total = rows.length;\n      if (total===0){\n        status.textContent = L.status_empty + (errs.length ? ' (some routes returned no data or errors)' : '');\n        clearStatusInline();\n        out.innerHTML='';\n        setLoader(false); btn.disabled=false; return;\n      }\n\n      const visibleRows = (limit10 && !revealAll && rows.length > 10) ? rows.slice(0,10) : rows;\n      const hiddenCount = rows.length - visibleRows.length;\n      soonKey = pickSoonKey(visibleRows);\n      featuredKey = pickFeaturedKey(visibleRows, soonKey);\n\n      status.textContent = errs.length ? ('Skipped '+errs.length+' route'+(errs.length>1?'s':'')) : '';\n      setStatusInline(\n  (L.status_found || '%d sailings found').replace('%d', '<strong>'+total+'<\/strong>')\n);\n      out.innerHTML = renderTable(visibleRows) + renderCards(visibleRows) + moreButtonHtml(hiddenCount);\n      bindRowLinks();\n      if (navHost) navHost.innerHTML = navHtml();\n\n    } catch(e){\n      status.textContent = 'Failed to load data';\n      out.innerHTML = '<pre>'+String(e.message||e)+'<\/pre>';\n    } finally {\n      setLoader(false);\n      btn.disabled = false;\n    }\n  }\n\n  wrap.addEventListener('click', function(e){\n    const nav = e.target.closest('.tp-day-nav a[data-shift]');\n    if (nav) {\n      e.preventDefault();\n      shiftDate(parseInt(nav.getAttribute('data-shift'),10) || 0);\n      return;\n    }\n    const more = e.target.closest('.tp-more-btn');\n    if (more) {\n      e.preventDefault();\n      revealAll = true;\n      load();\n    }\n  });\n\n  btn.addEventListener('click', load);\n  if (navHost) navHost.innerHTML = navHtml();\n  renderLocalTimes();\n  setInterval(renderLocalTimes, 30000);\n  if (cfg.autoload) load();\n})();\n<\/script>\n\n\n\n\n<h3 class=\"wp-block-heading\">Terug: Trelleborg \u2013 Rostock<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">En dit zijn de afvaarten de andere kant op.<\/p>\n\n\n<div class=\"tp-wrap tp-theme-extended_cards tp-day-setup-classic\" data-config=\"{&quot;rest&quot;:&quot;https:\\\/\\\/rostocktrelleborg.com\\\/nl\\\/wp-json\\\/timetables-pro\\\/v1\\\/timetables&quot;,&quot;routes&quot;:[158],&quot;days&quot;:1,&quot;autoload&quot;:true,&quot;theme&quot;:&quot;extended_cards&quot;,&quot;daySetup&quot;:&quot;classic&quot;,&quot;limit10&quot;:false,&quot;routeLabels&quot;:{&quot;158&quot;:&quot;Trelleborg-Rostock&quot;},&quot;opFilter&quot;:[&quot;13&quot;,&quot;36&quot;],&quot;labels&quot;:{&quot;ui_date&quot;:&quot;Datum&quot;,&quot;ui_days&quot;:&quot;Dagen&quot;,&quot;ui_button&quot;:&quot;Afvaarten tonen&quot;,&quot;status_idle&quot;:&quot;Kies een datum en klik op Afvaarten tonen&quot;,&quot;status_loading&quot;:&quot;Laden...&quot;,&quot;status_empty&quot;:&quot;Geen afvaarten gevonden&quot;,&quot;status_found&quot;:&quot;%d afvaarten gevonden&quot;,&quot;th_date&quot;:&quot;Datum&quot;,&quot;th_dep&quot;:&quot;Vertrek&quot;,&quot;th_arr&quot;:&quot;Aankomst&quot;,&quot;th_dur&quot;:&quot;Duur&quot;,&quot;th_ship&quot;:&quot;Schip&quot;,&quot;th_op&quot;:&quot;Operator&quot;,&quot;th_route&quot;:&quot;Route&quot;,&quot;wd_sun&quot;:&quot;ZO&quot;,&quot;wd_mon&quot;:&quot;MA&quot;,&quot;wd_tue&quot;:&quot;DI&quot;,&quot;wd_wed&quot;:&quot;WO&quot;,&quot;wd_thu&quot;:&quot;DO&quot;,&quot;wd_fri&quot;:&quot;VR&quot;,&quot;wd_sat&quot;:&quot;ZA&quot;,&quot;summary_footer_one&quot;:&quot;\\u00bb Bekijk alle %s afvaarten in onze dienstregeling&quot;,&quot;summary_footer_two&quot;:&quot;\\u00bb Bekijk meer %1$s en %2$s afvaarten in onze dienstregeling&quot;,&quot;summary_footer_generic&quot;:&quot;Bekijk onze dienstregeling voor meer afvaarten&quot;,&quot;summary_header&quot;:&quot;De volgende twee afvaarten:&quot;,&quot;summary_no_upcoming&quot;:&quot;Geen aankomende afvaarten gevonden&quot;,&quot;more_link&quot;:&quot;Meer afvaarten&quot;,&quot;more_departures_button&quot;:&quot;Meer afvaarten tonen&quot;,&quot;day_nav_previous&quot;:&quot;Vorige dag tonen&quot;,&quot;day_nav_next&quot;:&quot;Volgende dag tonen&quot;,&quot;day_nav_today&quot;:&quot;Vandaag tonen&quot;,&quot;day_nav_tomorrow&quot;:&quot;Morgen tonen&quot;,&quot;local_time_pair&quot;:&quot;Lokale tijd vertrekhaven: %1$s \\\/ Lokale tijd aankomsthaven: %2$s&quot;,&quot;local_time_combined&quot;:&quot;Lokale tijd vertrek- en aankomsthaven: %s&quot;,&quot;tag_often_booked&quot;:&quot;\\u2b50 Vaak geboekt&quot;,&quot;tag_leaving_soon&quot;:&quot;\\ud83d\\udd34 Vertrekt binnenkort&quot;,&quot;tag_currently_sailing&quot;:&quot;\\ud83d\\udfe2 Nu onderweg&quot;,&quot;tag_arrived&quot;:&quot;\\u26ab Aangekomen&quot;,&quot;tag_overnight&quot;:&quot;Nachtvaart&quot;},&quot;showLogo&quot;:true,&quot;activityBoosters&quot;:true,&quot;title&quot;:&quot;&quot;,&quot;shipMap&quot;:[],&quot;shipLinks&quot;:[],&quot;showShip&quot;:true,&quot;departurePort&quot;:&quot;Trelleborg&quot;,&quot;arrivalPort&quot;:&quot;Rostock&quot;,&quot;departureTimezone&quot;:&quot;Europe\\\/Berlin&quot;,&quot;arrivalTimezone&quot;:&quot;Europe\\\/Berlin&quot;}\">\n  <div class=\"tp-controls\" role=\"group\" aria-label=\"Timetable controls\">\n    <div>\n      <label for=\"tp-date-ops\">Datum<\/label><br>\n      <input id=\"tp-date-ops\" class=\"tp-date\" type=\"date\" aria-label=\"Datum\">\n    <\/div>\n    <div class=\"tp-day-field\">\n      <label for=\"tp-range-ops\">Dagen<\/label><br>\n      <select id=\"tp-range-ops\" class=\"tp-range\" aria-label=\"Dagen\">\n        <option value=\"1\">1<\/option><option value=\"3\">3<\/option><option value=\"7\">7<\/option><option value=\"14\">14<\/option>\n      <\/select>\n    <\/div>\n    <div><button id=\"tp-load-ops\" class=\"tp-btn\">Afvaarten tonen<\/button><\/div>\n  <\/div>\n\n  <div class=\"tp-local-nav-row\">\n    <div class=\"tp-local-times\" id=\"tp-local-times-ops\" aria-live=\"polite\"><\/div>\n    <div class=\"tp-day-nav-host\"><\/div>\n  <\/div>\n\n  \n  <div id=\"tp-status-ops\" class=\"tp-muted\" aria-live=\"polite\">Kies een datum en klik op Afvaarten tonen<\/div>\n\n  <div id=\"tp-ops-results\"><\/div>\n\n  <div class=\"tp-loader\" aria-hidden=\"true\">\n    <div class=\"tp-loader-card\">\n      <div class=\"tp-spinner\" aria-hidden=\"true\"><\/div>\n      <div class=\"tp-loader-text\">Laden...<\/div>\n    <\/div>\n  <\/div>\n<\/div>\n\n<script>\n(function(){\n  const wrap   = document.currentScript.previousElementSibling;\n  const cfg    = JSON.parse(wrap.getAttribute('data-config')||'{}');\n  const L      = cfg.labels||{};\n  const dateEl = wrap.querySelector('#tp-date-ops');\n  const daysEl = wrap.querySelector('#tp-range-ops');\n  const btn    = wrap.querySelector('#tp-load-ops');\n  const status = wrap.querySelector('#tp-status-ops');\n  const out    = wrap.querySelector('#tp-ops-results');\n  const loader = wrap.querySelector('.tp-loader');\n  const navHost = wrap.querySelector('.tp-day-nav-host');\n  const localTimesEl = wrap.querySelector('#tp-local-times-ops');\n\n  const showShip = (cfg.showShip !== false && cfg.showShip !== 0 && cfg.showShip !== '0');\n  const activityBoosters = !!cfg.activityBoosters;\n  const daySetup = (cfg.daySetup === 'modern') ? 'modern' : 'classic';\n  const limit10 = !!cfg.limit10;\n  let featuredKey = '';\n  let soonKey = '';\n  let revealAll = false;\n\n  if (daySetup === 'modern') {\n    const dayField = wrap.querySelector('.tp-day-field');\n    if (dayField) dayField.style.display = 'none';\n  }\n\n  dateEl.valueAsDate = new Date();\n  dateEl.min = new Date().toISOString().split('T')[0];\n  Array.from(daysEl.options).forEach(o=>{ if(parseInt(o.value,10)===parseInt(cfg.days||7,10)) o.selected=true; });\n\n  function pad(n){ return String(n).padStart(2,'0'); }\n  function iso(d){ return d.getFullYear()+'-'+pad(d.getMonth()+1)+'-'+pad(d.getDate()); }\n  function toLocal(s){ return new Date(s); }\n  function hhmm(d){ return d.toLocaleTimeString([], {hour:'2-digit', minute:'2-digit'}); }\n  function dShort(d){ return d.toLocaleDateString([], {day:'numeric', month:'short'}); }\n  function dur(m){ const h=Math.floor(m\/60), r=m%60; return r? (h+'h '+r+'m') : (h+'h'); }\n\n  const WD = [\n    L.wd_sun || 'SUN',\n    L.wd_mon || 'MON',\n    L.wd_tue || 'TUE',\n    L.wd_wed || 'WED',\n    L.wd_thu || 'THU',\n    L.wd_fri || 'FRI',\n    L.wd_sat || 'SAT'\n  ];\n\n  function setLoader(v){ loader.classList.toggle('show', !!v); loader.setAttribute('aria-hidden', v?'false':'true'); }\n\n  function formatZoneTime(tz){\n    if (!tz) return '--:--';\n    try {\n      return new Intl.DateTimeFormat([], {hour:'2-digit', minute:'2-digit', hour12:false, timeZone: tz}).format(new Date());\n    } catch (e) {\n      return '--:--';\n    }\n  }\n\n  function renderLocalTimes(){\n    if (!localTimesEl) return;\n    if (!cfg.departureTimezone || !cfg.arrivalTimezone) {\n      localTimesEl.textContent = '';\n      return;\n    }\n    const depTime = formatZoneTime(cfg.departureTimezone);\n    const arrTime = formatZoneTime(cfg.arrivalTimezone);\n    const pairTpl = L.local_time_pair || 'Departure Port Local Time: %1$s \/ Arrival Port Local Time: %2$s';\n    const combinedTpl = L.local_time_combined || 'Departure & Arrival Port Local Time: %s';\n    if (depTime === arrTime) {\n      localTimesEl.textContent = combinedTpl.replace('%s', depTime);\n      return;\n    }\n    localTimesEl.textContent = pairTpl.replace('%1$s', depTime).replace('%2$s', arrTime);\n  }\n\n  function setStatusInline(html){\n    let box = wrap.querySelector('.tp-controls-status');\n    if (!box) {\n      box = document.createElement('div');\n      box.className = 'tp-controls-status';\n      wrap.querySelector('.tp-controls').appendChild(box);\n    }\n    box.innerHTML = html || '';\n  }\n\n  function clearStatusInline(){\n    const box = wrap.querySelector('.tp-controls-status');\n    if (box) box.innerHTML = '';\n  }\n\n  function navHtml(){\n    if (daySetup !== 'modern') return '';\n    const base = new Date(dateEl.value || new Date());\n    const today = new Date();\n    const tomorrow = new Date(today);\n    tomorrow.setDate(today.getDate() + 1);\n    const isToday = base.toDateString() === today.toDateString();\nlet prevLabel = L.day_nav_previous || 'Show previous day';\nlet nextLabel = L.day_nav_next || 'Show next day';\nif (isToday) nextLabel = L.day_nav_tomorrow || 'Show tomorrow';\nif (base.toDateString() === tomorrow.toDateString()) prevLabel = L.day_nav_today || 'Show today';\n    return '<div class=\"tp-day-nav\">'\n      + (isToday ? '' : '<a href=\"#\" data-shift=\"-1\">'+prevLabel+'<\/a>')\n      + '<a href=\"#\" data-shift=\"1\">'+nextLabel+'<\/a>'\n      + '<\/div>';\n  }\n\n  function shiftDate(delta){\n    const base = new Date(dateEl.value || new Date());\n    base.setDate(base.getDate() + delta);\n    dateEl.value = iso(base);\n    load();\n  }\n\n  function moreButtonHtml(hiddenCount){\n    if (!limit10 || revealAll || hiddenCount <= 0) return '';\n    return '<div style=\"margin-top:12px;text-align:center\">'\n      + '<button type=\"button\" class=\"tp-btn tp-more-btn\">'+(L.more_departures_button || 'Show more departures')+' ('+hiddenCount+')<\/button>'\n      + '<\/div>';\n  }\n\n  function opCell(r){\n    const name = r.opName || ('Operator '+(r.opId||''));\n    const logo = (cfg.showLogo && r.opLogo) ? '<img decoding=\"async\" src=\"'+r.opLogo+'\" alt=\"'+name+'\"> ' : '';\n    const label = logo + '<span>'+name+'<\/span>';\n    return r.opLink ? '<a class=\"tp-op\" href=\"'+r.opLink+'\" target=\"_blank\" rel=\"nofollow noopener\">'+label+'<\/a>' : '<span class=\"tp-op\">'+label+'<\/span>';\n  }\n\n  function shipInfo(original){\n    const key = (original||'').toLowerCase().trim();\n    const label = (cfg.shipMap && cfg.shipMap[key]) || original || '';\n    const href  = (cfg.shipLinks && cfg.shipLinks[key]) || '';\n    return {label, href};\n  }\n\n  function shipBadge(original){\n    const s = shipInfo(original);\n    const badge = '<span class=\"tp-badge\">'+(s.label||'')+'<\/span>';\n    return s.href ? ('<a href=\"'+s.href+'\" target=\"_blank\" rel=\"nofollow noopener\">'+badge+'<\/a>') : badge;\n  }\n\n  function rowKey(r){\n    return [String(r.routeId||''), String(r.opId||''), String(+r.dep||0), String(+r.arr||0)].join('|');\n  }\n\n  function pickFeaturedKey(rows, avoidKey){\n    if (!activityBoosters || !rows.length) return '';\n    const routesSum = Array.isArray(cfg.routes) ? cfg.routes.reduce((acc, n)=>acc + (parseInt(n,10)||0), 0) : 0;\n    const dateSeed = parseInt(String(dateEl.value || '').replace(\/-\/g,''), 10) || 0;\n\n    let pool = rows;\n    if (avoidKey) {\n      const soonIdx = rows.findIndex(r => rowKey(r) === avoidKey);\n      if (soonIdx >= 0) {\n        const later = rows.slice(soonIdx + 1).filter(r => rowKey(r) !== avoidKey);\n        pool = later.length ? later : rows.filter(r => rowKey(r) !== avoidKey);\n      } else {\n        pool = rows.filter(r => rowKey(r) !== avoidKey);\n      }\n    }\n\n    if (!pool.length) return '';\n    const idx = Math.abs((routesSum + dateSeed + rows.length) % pool.length);\n    return rowKey(pool[idx]);\n  }\n\n  function pickSoonKey(rows){\n    if (!activityBoosters || !rows.length) return '';\n    const now = Date.now();\n    const todayStr = new Date(now).toDateString();\n    const firstUpcoming = rows.find(r => (r.dep instanceof Date) && r.dep.getTime() > now && r.dep.toDateString() === todayStr);\n    return firstUpcoming ? rowKey(firstUpcoming) : '';\n  }\n\n  function boostersFor(r){\n    if (!activityBoosters) return [];\n    const now = Date.now();\n    const depMs = (r.dep instanceof Date) ? r.dep.getTime() : 0;\n    const arrMs = (r.arr instanceof Date) ? r.arr.getTime() : 0;\n    const depIsToday = (r.dep instanceof Date) && (new Date(now).toDateString() === r.dep.toDateString());\n\n    if (depMs > 0 && arrMs > 0 && depMs <= now && arrMs > now) {\n      return [{cls:'tp-booster-sailing', text:(L.tag_currently_sailing || '\ud83d\udfe2 Currently sailing')}];\n    }\n    if (depIsToday && arrMs > 0 && arrMs <= now) {\n      return [{cls:'tp-booster-arrived', text:(L.tag_arrived || '\u26ab Arrived')}];\n    }\n    if (rowKey(r) === soonKey) return [{cls:'tp-booster-soon', text:(L.tag_leaving_soon || '\ud83d\udd34 Leaving soon')}];\n    if (r.dep && r.arr && r.dep.toDateString() !== r.arr.toDateString()) return [{cls:'tp-booster-overnight', text:(L.tag_overnight || 'Overnight')}];\n\n    return [];\n  }\n\n  function boostersHtml(r, floating){\n    const tags = boostersFor(r);\n    if (!tags.length) return '';\n    const cls = floating ? 'tp-boosters tp-boosters-float' : 'tp-boosters';\n    return '<div class=\"'+cls+'\">' + tags.map(t => '<span class=\"tp-booster '+t.cls+'\">'+boosterLabelHtml(t.text)+'<\/span>').join('') + '<\/div>';\n  }\n\n  function boosterLabelHtml(text){\n    return String(text || '').replace(\/^(\ud83d\udd34|\ud83d\udfe2|\u26ab|\u2b50)\\s*\/, '<span class=\"tp-booster-emoji\">$1<\/span>');\n  }\n\n  function routeTicketHtml(label){\n    const raw = String(label || '').trim();\n    if (!raw) return '';\n    if (cfg.theme !== 'small_cards') return escAttr(raw);\n    const parts = raw.split(\/\\s*[\\-\u2013]\\s*\/, 2);\n    if (parts.length < 2) return escAttr(raw);\n    return escAttr(parts[0]) + '<br>' + escAttr(parts[1]);\n  }\n\n  function escAttr(v){\n    return String(v||'').replace(\/[&<>\"']\/g, m => ({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[m]));\n  }\n\n  function bindRowLinks(){\n    if (cfg.theme !== 'max_clickouts') return;\n    out.querySelectorAll('tr.tp-row-link').forEach((row)=>{\n      row.setAttribute('role','link');\n      row.setAttribute('tabindex','0');\n      row.addEventListener('click', (e)=>{\n        if (e.target && e.target.closest('a')) return;\n        const href = row.getAttribute('data-row-link');\n        if (!href) return;\n        window.open(href, '_blank', 'noopener,noreferrer');\n      });\n      row.addEventListener('keydown', (e)=>{\n        if (e.key !== 'Enter' && e.key !== ' ') return;\n        e.preventDefault();\n        row.click();\n      });\n    });\n  }\n\n  function routeLabel(rid){\n    return (cfg.routeLabels && (cfg.routeLabels[String(rid)] || cfg.routeLabels[rid])) || String(rid);\n  }\n\n  function renderTable(rows){\n    const th = {date:L.th_date,dep:L.th_dep,arr:L.th_arr,dur:L.th_dur,ship:L.th_ship,route:L.th_route,op:L.th_op};\n\n    const headCells = [\n      '<th>'+th.date+'<\/th>',\n      '<th>'+th.dep+'<\/th>',\n      '<th>'+th.arr+'<\/th>',\n      '<th>'+th.dur+'<\/th>'\n    ];\n    if (showShip) {\n      headCells.push('<th>'+th.ship+'<\/th>');\n    }\n    headCells.push('<th>'+th.route+'<\/th>');\n    headCells.push('<th>'+th.op+'<\/th>');\n\n    let html = '<table class=\"tp-table\"><thead><tr>'+headCells.join('')+'<\/tr><\/thead><tbody>';\n    rows.forEach(r=>{\n      const dow = WD[r.dep.getDay()] || '';\n      const clickable = (cfg.theme === 'max_clickouts' && r.opLink);\n      const rowAttr = clickable ? (' class=\"tp-row-link\" data-row-link=\"'+escAttr(r.opLink)+'\"') : '';\n      const dateBoosters = (cfg.theme === 'max_clickouts') ? '' : boostersHtml(r, false);\n      const routeBoosters = (cfg.theme === 'max_clickouts') ? boostersHtml(r, false) : '';\n      const cells = [\n        '<td>'+dShort(r.dep)+' <span class=\"tp-day\">'+dow+'<\/span>'+dateBoosters+'<\/td>',\n        '<td>'+hhmm(r.dep)+'<\/td>',\n        '<td>'+hhmm(r.arr)+'<\/td>',\n        '<td>'+dur(r.min)+'<\/td>'\n      ];\n      if (showShip) {\n        cells.push('<td>'+shipBadge(r.ship)+'<\/td>');\n      }\n      cells.push('<td>'+routeBoosters+'<div>'+routeLabel(r.routeId)+'<\/div><\/td>');\n      cells.push('<td>'+opCell(r)+'<\/td>');\n      html += '<tr'+rowAttr+'>'+cells.join('')+'<\/tr>';\n    });\n    html += '<\/tbody><\/table>';\n    return html;\n  }\n\n  function renderCards(rows){\n    if (cfg.theme === 'extended_cards') {\n      return renderExtendedCards(rows);\n    }\n\n    let html = '<div class=\"tp-cardlist\">';\n    rows.forEach(r=>{\n      const dow   = WD[r.dep.getDay()] || '';\n      const times = hhmm(r.dep) + ' <span class=\"tp-arrow\">\u2192<\/span> ' + hhmm(r.arr);\n      html += '<div class=\"tp-card\">'+boostersHtml(r, true)+\n        \/\/ Row 1: Date + weekday + times\n        '<div class=\"tp-mrow\">'+\n          '<div class=\"lhs\"><span class=\"tp-sub\">'+dShort(r.dep)+'<\/span><span class=\"tp-day\">'+dow+'<\/span><\/div>'+\n          '<div class=\"rhs\"><span class=\"tp-time\">'+times+'<\/span><\/div>'+\n        '<\/div>';\n\n      if (showShip) {\n        html +=\n        \/\/ Row 2: Ship\n        '<div class=\"tp-mrow\">'+\n          '<div class=\"lhs\">'+shipBadge(r.ship)+'<\/div>'+\n          '<div class=\"rhs\"><\/div>'+\n        '<\/div>';\n      }\n\n      html +=\n        \/\/ Row 3: Operator + route label\n        '<div class=\"tp-mrow\">'+\n          '<div class=\"lhs\">'+opCell(r)+'<\/div>'+\n          '<div class=\"rhs\"><span class=\"tp-route-ticket\">'+routeTicketHtml(routeLabel(r.routeId))+'<\/span><\/div>'+\n        '<\/div>'+\n      '<\/div>';\n    });\n    html += '<\/div>';\n    return html;\n  }\n\n  function renderExtendedCards(rows){\n    const ctaText = L.more_link || 'More sailings';\n    let html = '<div class=\"tp-cardlist\">';\n    rows.forEach(r=>{\n      const dow = WD[r.dep.getDay()] || '';\n      const link = r.opLink ? ('<a class=\"tp-ext-cta\" href=\"'+r.opLink+'\" target=\"_blank\" rel=\"nofollow noopener\">'+ctaText+' <span class=\"tp-ext-cta-arrow\">\u00bb<\/span><\/a>') : '<span class=\"tp-ext-cta\">'+ctaText+' <span class=\"tp-ext-cta-arrow\">\u00bb<\/span><\/span>';\n      html += '<div class=\"tp-ext-card\">'\n        + boostersHtml(r, true)\n        + '<div class=\"tp-ext-left\">'\n        +   '<div>'+opCell(r)+'<\/div>'\n        +   (showShip ? ('<div>'+shipBadge(r.ship)+'<\/div>') : '')\n        + '<\/div>'\n        + '<div class=\"tp-ext-mid\">'\n        +   '<div class=\"tp-ext-top\"><span class=\"tp-sub\">'+dShort(r.dep)+' <span class=\"tp-day\">'+dow+'<\/span><\/span><span class=\"tp-ext-dur\">'+dur(r.min)+'<\/span><\/div>'\n        +   '<div class=\"tp-ext-times\"><span class=\"tp-ext-time\">'+hhmm(r.dep)+'<\/span><span class=\"tp-ext-line\"><\/span><span class=\"tp-ext-dur\">'+dur(r.min)+'<\/span><span class=\"tp-ext-line\"><\/span><span class=\"tp-ext-time\">'+hhmm(r.arr)+'<\/span><\/div>'\n        +   '<div class=\"tp-ext-route\">'+routeLabel(r.routeId)+'<\/div>'\n        + '<\/div>'\n        + '<div class=\"tp-ext-right\">'+link+'<\/div>'\n        + '<\/div>';\n    });\n    html += '<\/div>';\n    return html;\n  }\n\n  \/\/ Safe fetch helper\n  async function fetchOne(routeId, from, to){\n    try{\n      const url = new URL(cfg.rest);\n      url.searchParams.set('route', String(routeId));\n      url.searchParams.set('from', from);\n      url.searchParams.set('to', to);\n      const res = await fetch(url.toString(), {credentials:'same-origin'});\n      if(!res.ok) return { rid: routeId, error: 'HTTP '+res.status };\n      const json = await res.json();\n      const list = (json && json.data && Array.isArray(json.data.rows)) ? json.data.rows : [];\n      return { rid: routeId, rows: list };\n    }catch(e){\n      return { rid: routeId, error: String(e && e.message ? e.message : e) };\n    }\n  }\n\n  async function load(){\n    btn.disabled = true; setLoader(true); status.textContent = L.status_loading;\n\n    const start = new Date(dateEl.value || new Date());\n    const days  = (daySetup === 'modern') ? 1 : Math.max(1, parseInt(daysEl.value,10)||1);\n    const end   = new Date(start); end.setDate(start.getDate()+days-1);\n    const fromIso = iso(start), toIso = iso(end);\n\n    try{\n      const results  = await Promise.all((cfg.routes||[]).map(rid=>fetchOne(rid, fromIso, toIso)));\n      const oks  = results.filter(r => !r.error);\n      const errs = results.filter(r =>  r.error);\n\n      const all = [];\n      oks.forEach(({rid, rows})=>{\n        rows.forEach(t=>{\n          all.push({\n            routeId: rid,\n            opId: t.operatorId || null,\n            opName: t.operatorName || '',\n            opLogo: t.operatorLogo || '',\n            opLink: t.operatorLink || '',\n            dep: toLocal(t.departureTime),\n            arr: toLocal(t.arrivalTime),\n            min: t.durationInMinutes || 0,\n            ship: t.shipName || ''\n          });\n        });\n      });\n\n      let rows = all;\n      if (Array.isArray(cfg.opFilter) && cfg.opFilter.length>0) {\n        rows = all.filter(r => r.opId && cfg.opFilter.includes(String(r.opId)));\n      }\n\n      rows.sort((a,b)=> a.dep - b.dep);\n\n      const todayStr = new Date().toDateString();\n      const nowMs = Date.now();\n      const arrivedToday = rows\n        .filter(r => (r.dep instanceof Date) && (r.arr instanceof Date) && r.dep.toDateString() === todayStr && r.arr.getTime() <= nowMs)\n        .sort((a,b) => b.arr - a.arr);\n      if (arrivedToday.length > 2) {\n        const keep = new Set(arrivedToday.slice(0,2).map(rowKey));\n        rows = rows.filter(r => {\n          const isArrivedToday = (r.dep instanceof Date) && (r.arr instanceof Date) && r.dep.toDateString() === todayStr && r.arr.getTime() <= nowMs;\n          return !isArrivedToday || keep.has(rowKey(r));\n        });\n      }\n\n      const total = rows.length;\n      if (total===0){\n        status.textContent = L.status_empty + (errs.length ? ' (some routes returned no data or errors)' : '');\n        clearStatusInline();\n        out.innerHTML='';\n        setLoader(false); btn.disabled=false; return;\n      }\n\n      const visibleRows = (limit10 && !revealAll && rows.length > 10) ? rows.slice(0,10) : rows;\n      const hiddenCount = rows.length - visibleRows.length;\n      soonKey = pickSoonKey(visibleRows);\n      featuredKey = pickFeaturedKey(visibleRows, soonKey);\n\n      status.textContent = errs.length ? ('Skipped '+errs.length+' route'+(errs.length>1?'s':'')) : '';\n      setStatusInline(\n  (L.status_found || '%d sailings found').replace('%d', '<strong>'+total+'<\/strong>')\n);\n      out.innerHTML = renderTable(visibleRows) + renderCards(visibleRows) + moreButtonHtml(hiddenCount);\n      bindRowLinks();\n      if (navHost) navHost.innerHTML = navHtml();\n\n    } catch(e){\n      status.textContent = 'Failed to load data';\n      out.innerHTML = '<pre>'+String(e.message||e)+'<\/pre>';\n    } finally {\n      setLoader(false);\n      btn.disabled = false;\n    }\n  }\n\n  wrap.addEventListener('click', function(e){\n    const nav = e.target.closest('.tp-day-nav a[data-shift]');\n    if (nav) {\n      e.preventDefault();\n      shiftDate(parseInt(nav.getAttribute('data-shift'),10) || 0);\n      return;\n    }\n    const more = e.target.closest('.tp-more-btn');\n    if (more) {\n      e.preventDefault();\n      revealAll = true;\n      load();\n    }\n  });\n\n  btn.addEventListener('click', load);\n  if (navHost) navHost.innerHTML = navHtml();\n  renderLocalTimes();\n  setInterval(renderLocalTimes, 30000);\n  if (cfg.autoload) load();\n})();\n<\/script>\n\n\n\n\n<p class=\"wp-block-paragraph\">Wil je verder vooruit kijken? In de <a href=\"\/nl\/dienstregeling\/\">dienstregeling<\/a> staan alle afvaarten.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Hoe lang duurt de overtocht?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Overdag ben je ongeveer zes uur onderweg. &#8217;s Nachts duurt het meestal zeven tot acht uur, omdat de nachtboten zo zijn gepland dat je vroeg in de ochtend aankomt.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Bij harde wind of hoge golven kan het wat langer duren.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wat kost de overtocht?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Er is geen vaste prijs. Wat je betaalt hangt vooral af van je voertuig: met een camper of een auto met caravan ben je duurder uit dan met alleen een auto. Verder maakt het uit met hoeveel mensen je reist, wanneer je gaat en hoe vroeg je boekt. Op een nachtboot betaal je vaak ook voor een hut.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">TT Line en Stena Line hebben elk hun eigen tarieven, dus vergelijken loont. Op de pagina <a href=\"\/nl\/prijzen\/\">prijzen<\/a> zie je ze naast elkaar.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">TT Line en Stena Line<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Omdat er twee rederijen op deze route varen, heb je keuze in vertrektijden en kun je de prijzen vergelijken.<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-7387b849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<h3 class=\"wp-block-heading\">TT Line<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">TT Line vaart al tientallen jaren tussen Rostock en Trelleborg, overdag en &#8217;s nachts. Veel camperreizigers en vrachtwagenchauffeurs gaan met deze rederij.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"\/nl\/tt-line\/\">Meer over TT Line<\/a><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<h3 class=\"wp-block-heading\">Stena Line<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Stena Line vaart ook een paar keer per dag. Aan boord zijn restaurants en winkels, en afhankelijk van het schip kun je een hut boeken voor de nacht.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"\/nl\/stena-line\/\">Meer over Stena Line<\/a><\/p>\n<\/div>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">De havens<\/h2>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-7387b849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<h3 class=\"wp-block-heading\">Rostock<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Rostock is een van de grootste veerhavens van Duitsland aan de Oostzee. Je komt er makkelijk via de A19 en de A20.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"\/nl\/rostock-haven\/\">Route, inchecken en parkeren in Rostock<\/a><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<h3 class=\"wp-block-heading\">Trelleborg<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Trelleborg ligt helemaal in het zuiden van Zweden. Malm\u00f6 is ongeveer een halfuur rijden, en van daaruit ga je verder naar G\u00f6teborg, Stockholm of Noorwegen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"\/nl\/trelleborg-haven\/\">Route, terminal en webcam in Trelleborg<\/a><\/p>\n<\/div>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Het weer op de Oostzee<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In de zomer is de zee meestal rustig. In de herfst en winter kan het flink waaien, en bij storm worden afvaarten soms vertraagd of geschrapt. Kijk daarom even naar de <a href=\"\/nl\/weersverwachting\/\">weersverwachting voor de route<\/a> voordat je vertrekt.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Veelgestelde vragen<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Hoe lang duurt de boot van Rostock naar Trelleborg?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Ongeveer zes uur. &#8217;s Nachts meestal zeven tot acht uur.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Welke rederijen varen tussen Rostock en Trelleborg?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">TT Line en Stena Line. Ze varen allebei in beide richtingen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Vaart er vandaag een boot?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Bijna elke dag wel, en meestal meerdere keren. De tijden van vandaag staan hierboven.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Is er een nachtboot?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Ja, in beide richtingen. Je slaapt aan boord en rijdt &#8217;s ochtends verder.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Wat kost de overtocht?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Dat hangt af van je voertuig, het seizoen, hoe vroeg je boekt en bij welke rederij. Op de <a href=\"\/nl\/prijzen\/\">prijzenpagina<\/a> zie je de actuele tarieven.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Kan ik een camper of caravan meenemen?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Ja. Beide rederijen nemen auto&#8217;s, campers, caravans, motoren en vrachtwagens mee. Hoe langer en hoger je voertuig, hoe duurder de overtocht.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Hoeveel afvaarten zijn er per dag?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Meestal zes tot acht per richting, beide rederijen samen. Dat verschilt per seizoen en per dag van de week.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Hoe vroeg moet ik in de haven zijn?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Een uur tot anderhalf uur voor vertrek. Met een camper of aanhanger, of in de zomervakantie, liever wat eerder.<\/p>\n\n\n\n<script type=\"application\/ld+json\">\n{\"@context\":\"https:\/\/schema.org\",\"@type\":\"FAQPage\",\"mainEntity\":[{\"@type\":\"Question\",\"name\":\"Hoe lang duurt de boot van Rostock naar Trelleborg?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Ongeveer zes uur. 's Nachts meestal zeven tot acht uur.\"}},{\"@type\":\"Question\",\"name\":\"Welke rederijen varen tussen Rostock en Trelleborg?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"TT Line en Stena Line. Ze varen allebei in beide richtingen.\"}},{\"@type\":\"Question\",\"name\":\"Vaart er vandaag een boot?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Bijna elke dag wel, en meestal meerdere keren. De tijden van vandaag staan op deze pagina.\"}},{\"@type\":\"Question\",\"name\":\"Is er een nachtboot?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Ja, in beide richtingen. Je slaapt aan boord en rijdt 's ochtends verder.\"}},{\"@type\":\"Question\",\"name\":\"Wat kost de overtocht?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Dat hangt af van je voertuig, het seizoen, hoe vroeg je boekt en bij welke rederij.\"}},{\"@type\":\"Question\",\"name\":\"Kan ik een camper of caravan meenemen?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Ja. Beide rederijen nemen auto's, campers, caravans, motoren en vrachtwagens mee. Hoe langer en hoger je voertuig, hoe duurder de overtocht.\"}},{\"@type\":\"Question\",\"name\":\"Hoeveel afvaarten zijn er per dag?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Meestal zes tot acht per richting, beide rederijen samen. Dat verschilt per seizoen en per dag van de week.\"}},{\"@type\":\"Question\",\"name\":\"Hoe vroeg moet ik in de haven zijn?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Een uur tot anderhalf uur voor vertrek. Met een camper of aanhanger, of in de zomervakantie, liever wat eerder.\"}}]}\n<\/script>\n<\/div>\n\n\n\n<div class=\"wp-block-group rtf-rail-right is-layout-flow wp-block-group-is-layout-flow\">\n<div class=\"wp-block-group rtf-convert is-layout-flow wp-block-group-is-layout-flow\">\n<p class=\"rtf-kicker wp-block-paragraph\">Vergelijken<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Prijzen van beide rederijen<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Kies je datum en zie de tarieven van TT Line en Stena Line naast elkaar.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"\/nl\/go\/ttout\" target=\"_blank\" rel=\"nofollow sponsored noopener\">Bekijk prijzen<\/a><\/div>\n<\/div>\n<\/div>\n\n\n\n<p class=\"rtf-kicker wp-block-paragraph\">Tip<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Vroeg boeken is op deze route meestal goedkoper, zeker in de zomer. <a href=\"\/nl\/prijzen\/\">Meer over prijzen<\/a><\/p>\n\n\n\n<div class=\"wp-block-group rtf-convert rtf-sticky is-layout-flow wp-block-group-is-layout-flow\">\n<p class=\"rtf-kicker wp-block-paragraph\">Boeken<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Afvaart kiezen<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Bekijk de tijden en prijzen voor jouw datum.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"\/nl\/go\/ttout\" target=\"_blank\" rel=\"nofollow sponsored noopener\">Bekijk prijzen<\/a><\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Rostock &rarr; Trelleborg &middot; Oostzee Met de veerboot van Rostock naar Trelleborg De boot van Rostock naar Trelleborg doet er [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_yoast_wpseo_title":"Veerboot Rostock Trelleborg | Tijden, prijs, overtocht","_yoast_wpseo_metadesc":"De boot van Rostock naar Trelleborg vandaag: actuele afvaarten van TT Line en Stena Line, vaartijd, prijzen en beide havens.","inline_featured_image":false,"site-sidebar-layout":"no-sidebar","site-content-layout":"","ast-site-content-layout":"full-width-container","site-content-style":"unboxed","site-sidebar-style":"unboxed","ast-global-header-display":"","ast-banner-title-visibility":"disabled","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"disabled","ast-breadcrumbs-content":"disabled","ast-featured-img":"disabled","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-12","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Veerboot Rostock Trelleborg | Tijden, prijs, overtocht<\/title>\n<meta name=\"description\" content=\"De boot van Rostock naar Trelleborg vandaag: actuele afvaarten van TT Line en Stena Line, vaartijd, prijzen en beide havens.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/rostocktrelleborg.com\/nl\/\" \/>\n<meta property=\"og:locale\" content=\"nl_NL\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Veerboot Rostock Trelleborg | Tijden, prijs, overtocht\" \/>\n<meta property=\"og:description\" content=\"De boot van Rostock naar Trelleborg vandaag: actuele afvaarten van TT Line en Stena Line, vaartijd, prijzen en beide havens.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/rostocktrelleborg.com\/nl\/\" \/>\n<meta property=\"og:site_name\" content=\"Rostock Trelleborg Veerboot\" \/>\n<meta property=\"article:modified_time\" content=\"2026-11-13T09:22:29+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Geschatte leestijd\" \/>\n\t<meta name=\"twitter:data1\" content=\"5 minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/rostocktrelleborg.com\\\/nl\\\/\",\"url\":\"https:\\\/\\\/rostocktrelleborg.com\\\/nl\\\/\",\"name\":\"Veerboot Rostock Trelleborg | Tijden, prijs, overtocht\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/rostocktrelleborg.com\\\/nl\\\/#website\"},\"datePublished\":\"2024-03-13T13:50:12+00:00\",\"dateModified\":\"2026-11-13T09:22:29+00:00\",\"description\":\"De boot van Rostock naar Trelleborg vandaag: actuele afvaarten van TT Line en Stena Line, vaartijd, prijzen en beide havens.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/rostocktrelleborg.com\\\/nl\\\/#breadcrumb\"},\"inLanguage\":\"nl-NL\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/rostocktrelleborg.com\\\/nl\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/rostocktrelleborg.com\\\/nl\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/rostocktrelleborg.com\\\/nl\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Veerboot Rostock Trelleborg\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/rostocktrelleborg.com\\\/nl\\\/#website\",\"url\":\"https:\\\/\\\/rostocktrelleborg.com\\\/nl\\\/\",\"name\":\"Rostock Trelleborg Veerboot\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/rostocktrelleborg.com\\\/nl\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"nl-NL\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Veerboot Rostock Trelleborg | Tijden, prijs, overtocht","description":"De boot van Rostock naar Trelleborg vandaag: actuele afvaarten van TT Line en Stena Line, vaartijd, prijzen en beide havens.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/rostocktrelleborg.com\/nl\/","og_locale":"nl_NL","og_type":"article","og_title":"Veerboot Rostock Trelleborg | Tijden, prijs, overtocht","og_description":"De boot van Rostock naar Trelleborg vandaag: actuele afvaarten van TT Line en Stena Line, vaartijd, prijzen en beide havens.","og_url":"https:\/\/rostocktrelleborg.com\/nl\/","og_site_name":"Rostock Trelleborg Veerboot","article_modified_time":"2026-11-13T09:22:29+00:00","twitter_card":"summary_large_image","twitter_misc":{"Geschatte leestijd":"5 minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/rostocktrelleborg.com\/nl\/","url":"https:\/\/rostocktrelleborg.com\/nl\/","name":"Veerboot Rostock Trelleborg | Tijden, prijs, overtocht","isPartOf":{"@id":"https:\/\/rostocktrelleborg.com\/nl\/#website"},"datePublished":"2024-03-13T13:50:12+00:00","dateModified":"2026-11-13T09:22:29+00:00","description":"De boot van Rostock naar Trelleborg vandaag: actuele afvaarten van TT Line en Stena Line, vaartijd, prijzen en beide havens.","breadcrumb":{"@id":"https:\/\/rostocktrelleborg.com\/nl\/#breadcrumb"},"inLanguage":"nl-NL","potentialAction":[{"@type":"ReadAction","target":["https:\/\/rostocktrelleborg.com\/nl\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/rostocktrelleborg.com\/nl\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/rostocktrelleborg.com\/nl\/"},{"@type":"ListItem","position":2,"name":"Veerboot Rostock Trelleborg"}]},{"@type":"WebSite","@id":"https:\/\/rostocktrelleborg.com\/nl\/#website","url":"https:\/\/rostocktrelleborg.com\/nl\/","name":"Rostock Trelleborg Veerboot","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/rostocktrelleborg.com\/nl\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"nl-NL"}]}},"_links":{"self":[{"href":"https:\/\/rostocktrelleborg.com\/nl\/wp-json\/wp\/v2\/pages\/12","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rostocktrelleborg.com\/nl\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/rostocktrelleborg.com\/nl\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/rostocktrelleborg.com\/nl\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/rostocktrelleborg.com\/nl\/wp-json\/wp\/v2\/comments?post=12"}],"version-history":[{"count":39,"href":"https:\/\/rostocktrelleborg.com\/nl\/wp-json\/wp\/v2\/pages\/12\/revisions"}],"predecessor-version":[{"id":357,"href":"https:\/\/rostocktrelleborg.com\/nl\/wp-json\/wp\/v2\/pages\/12\/revisions\/357"}],"wp:attachment":[{"href":"https:\/\/rostocktrelleborg.com\/nl\/wp-json\/wp\/v2\/media?parent=12"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}