{"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-09-23T08:28:35","modified_gmt":"2026-09-23T08:28:35","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\">Van Duitsland naar Zweden in \u00e9\u00e9n overtocht<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Zes uur over de Oostzee in plaats van een dag rijden door Denemarken. Twee rederijen, zes tot acht afvaarten per dag, en je rijdt uitgerust van boord.<\/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 Rostock?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Rijd je vanuit Nederland naar Zweden, dan scheelt deze overtocht je de hele rit door Denemarken en de tol op de Sontbrug. Je slaapt of eet aan boord in plaats van achter het stuur te zitten.<\/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\">Voor vertrek. Langer met een camper, caravan of aanhanger &mdash; grote voertuigen gaan er als eerste of als laatste op.<\/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\">De A19 loopt vanaf Berlijn zo de haven in, de A20 komt vanuit Hamburg. <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\">De veerboot tussen Rostock en Trelleborg verbindt Noord-Duitsland rechtstreeks met Zuid-Zweden. Twee rederijen varen de route: TT Line en Stena Line. Op deze pagina vind je de dienstregeling van vandaag, de vaartijd, wat de prijs bepaalt, informatie over beide havens en alles wat je voor vertrek wilt weten.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Voor Nederlandse reizigers is dit een veelgebruikte route naar Scandinavi\u00eb. Je rijdt door Duitsland naar Rostock en vaart vandaar in \u00e9\u00e9n keer over naar Zweden, zonder de lange omweg over Denemarken.<\/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, nachtovertochten 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\">Veerboot Rostock Trelleborg vandaag<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Hieronder zie je de eerstvolgende afvaarten van Rostock naar Trelleborg. De dienstregeling toont de overtochten van TT Line en Stena Line samen en wordt automatisch 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\">Veerboot Trelleborg Rostock vandaag<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Voor de terugreis van Zweden naar Duitsland vind je hier de actuele afvaarten van Trelleborg naar Rostock.<\/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, bekijk dan de volledige <a href=\"\/nl\/dienstregeling\/\">dienstregeling van de boot Rostock Trelleborg<\/a>.<\/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 Rostock Trelleborg?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">De overtocht duurt ongeveer <strong>6 uur<\/strong>. Dagafvaarten zitten meestal rond die tijd. Nachtovertochten duren vaak langer, doorgaans 7 tot 8 uur, omdat de dienstregeling is afgestemd op aankomst in de vroege ochtend.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">De werkelijke vaartijd hangt af van de rederij, het schip, het tijdstip van vertrek en het weer op de Oostzee. Bij harde wind of hoge golven kan een overtocht uitlopen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Reken naast de vaartijd op extra tijd voor het inchecken. De rederijen adviseren om minstens 60 tot 90 minuten voor vertrek bij de terminal te zijn, en ruimer als je met een camper of aanhanger reist.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wat kost de veerboot Rostock Trelleborg?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Een vaste prijs bestaat niet op deze route. De tarieven lopen flink uiteen en hangen vooral af van:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Type voertuig<\/strong> \u2013 een auto is een stuk goedkoper dan een camper, een auto met caravan of een vrachtwagen<\/li>\n\n\n\n<li><strong>Aantal passagiers<\/strong> \u2013 de meeste tarieven rekenen bestuurder en meereizenden apart<\/li>\n\n\n\n<li><strong>Reisperiode<\/strong> \u2013 hoogseizoen, schoolvakanties en weekenden zijn merkbaar duurder dan het laagseizoen<\/li>\n\n\n\n<li><strong>Moment van boeken<\/strong> \u2013 vroeg boeken levert meestal een lagere prijs op<\/li>\n\n\n\n<li><strong>Hut<\/strong> \u2013 bij nachtovertochten komt er afhankelijk van het tarief een hut bij<\/li>\n\n\n\n<li><strong>Rederij<\/strong> \u2013 TT Line en Stena Line rekenen verschillend, vergelijken loont bijna altijd<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Omdat beide rederijen dezelfde route varen, kun je afvaarttijden en tarieven direct tegen elkaar afwegen. Een actueel overzicht vind je op de pagina met <a href=\"\/nl\/prijzen\/\">prijzen van de overtocht<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">De rederijen: TT Line en Stena Line<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Op de route Rostock Trelleborg varen twee aanbieders. Dat werkt in je voordeel: meer vertrektijden om uit te kiezen, en de mogelijkheid om schepen en tarieven te 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 de route al decennia, met zowel dag- als nachtafvaarten. De rederij is goed ingeburgerd bij camperreizigers en in het vrachtvervoer.<\/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 de route eveneens meerdere keren per dag. Aan boord vind je restaurants, winkels en, afhankelijk van het schip, hutten voor de nachtovertocht.<\/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: Rostock en Trelleborg<\/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\">Haven van Rostock<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Rostock is een van de belangrijkste veerhavens van Duitsland aan de Oostzee. De haven is goed bereikbaar via de A19, wat het een praktisch vertrekpunt maakt voor reizigers uit Nederland, Berlijn en Hamburg.<\/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\">Haven van Trelleborg<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Trelleborg is de zuidelijkste veerhaven van Zweden en een van de drukste van het land. Vanaf daar lopen goede wegverbindingen naar Malm\u00f6, Lund, G\u00f6teborg, Stockholm en verder naar 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\">Weer en golfslag op de Oostzee<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Het weer maakt een merkbaar verschil tijdens de overtocht. In de zomer is de Oostzee meestal rustig, in het najaar en de winter kan het flink ruwer zijn. Bij stormwaarschuwingen komen vertragingen en afgelaste afvaarten voor.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Bekijk voor vertrek de <a href=\"\/nl\/weersverwachting\/\">weersverwachting voor Rostock, Trelleborg en de overtocht<\/a>, met kaarten voor wind, golfhoogte, temperatuur en storm op de route.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Meer informatie<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"\/nl\/dienstregeling\/\">Dienstregeling<\/a> \u2013 alle afvaarten in beide richtingen<\/li>\n\n\n\n<li><a href=\"\/nl\/prijzen\/\">Prijzen<\/a> \u2013 tarieven vergelijken en boeken<\/li>\n\n\n\n<li><a href=\"\/nl\/weersverwachting\/\">Weersverwachting<\/a> \u2013 wind, golven en storm op de Oostzee<\/li>\n\n\n\n<li><a href=\"\/nl\/rostock-haven\/\">Haven van Rostock<\/a> \u2013 route en terminal<\/li>\n\n\n\n<li><a href=\"\/nl\/trelleborg-haven\/\">Haven van Trelleborg<\/a> \u2013 route en terminal<\/li>\n\n\n\n<li><a href=\"\/nl\/tt-line\/\">TT Line<\/a> en <a href=\"\/nl\/stena-line\/\">Stena Line<\/a> \u2013 de rederijen in detail<\/li>\n<\/ul>\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\">De overtocht duurt ongeveer 6 uur. Nachtovertochten duren vaak 7 tot 8 uur, omdat ze zijn afgestemd op aankomst in de vroege ochtend.<\/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\">De route wordt gevaren door TT Line en Stena Line. Beide bieden regelmatige afvaarten 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\">Op de meeste dagen varen er meerdere afvaarten. De tijden van vandaag staan in de dienstregeling 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 varen regelmatig nachtafvaarten. Handig als je wilt uitrusten voordat je &#8217;s ochtends verder rijdt.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Wat kost de overtocht?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">De prijs hangt af van je voertuig, het seizoen, hoe vroeg je boekt en welke rederij je kiest. Op de prijzenpagina staat een actuele vergelijking.<\/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 vervoeren auto&#8217;s, campers, caravans, motoren en vrachtwagens. Het tarief wordt onder meer bepaald door de lengte en hoogte van het voertuig.<\/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\">Over beide rederijen samen zijn het meestal 6 tot 8 afvaarten per dag per richting, afhankelijk van seizoen en 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\">Reken op minstens 60 tot 90 minuten voor vertrek. Met een camper, aanhanger of in het hoogseizoen kun je beter eerder aanwezig zijn.<\/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\":\"De overtocht duurt ongeveer 6 uur. Nachtovertochten duren vaak 7 tot 8 uur, omdat ze zijn afgestemd op aankomst in de vroege ochtend.\"}},{\"@type\":\"Question\",\"name\":\"Welke rederijen varen tussen Rostock en Trelleborg?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"De route wordt gevaren door TT Line en Stena Line. Beide bieden regelmatige afvaarten in beide richtingen.\"}},{\"@type\":\"Question\",\"name\":\"Vaart er vandaag een boot?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Op de meeste dagen varen er meerdere afvaarten. De tijden van vandaag staan in de dienstregeling op deze pagina.\"}},{\"@type\":\"Question\",\"name\":\"Is er een nachtboot?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Ja. In beide richtingen varen regelmatig nachtafvaarten.\"}},{\"@type\":\"Question\",\"name\":\"Wat kost de overtocht?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"De prijs hangt af van je voertuig, het seizoen, hoe vroeg je boekt en welke rederij je kiest.\"}},{\"@type\":\"Question\",\"name\":\"Kan ik een camper of caravan meenemen?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Ja. Beide rederijen vervoeren auto's, campers, caravans, motoren en vrachtwagens. Het tarief wordt onder meer bepaald door de lengte en hoogte van het voertuig.\"}},{\"@type\":\"Question\",\"name\":\"Hoeveel afvaarten zijn er per dag?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Over beide rederijen samen zijn het meestal 6 tot 8 afvaarten per dag per richting.\"}},{\"@type\":\"Question\",\"name\":\"Hoe vroeg moet ik in de haven zijn?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Reken op minstens 60 tot 90 minuten voor vertrek. Met een camper, aanhanger of in het hoogseizoen kun je beter eerder aanwezig zijn.\"}}]}\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\">Twee rederijen, \u00e9\u00e9n zoekopdracht<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">De prijzen van TT Line en Stena Line naast elkaar. Kies de afvaart die past en boek hem meteen.<\/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\">Wat kost het<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Er is geen vaste prijs<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Vijf dingen bepalen wat je betaalt:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Je voertuig &mdash; een auto kost veel minder dan een camper<\/li>\n\n\n\n<li>Met hoeveel personen je reist<\/li>\n\n\n\n<li>Het seizoen en de dag van de week<\/li>\n\n\n\n<li>Hoe ver van tevoren je boekt<\/li>\n\n\n\n<li>Hut of stoel<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"\/nl\/prijzen\/\">Alle prijzen en manieren om te besparen<\/a><\/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\">Voor je vaart<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Check de Oostzee<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In de zomer is het er meestal rustig, vanaf het najaar een stuk ruwer. Hoge golven kunnen de overtocht verlengen. <a href=\"\/nl\/weersverwachting\/\">Wind, golven en storm op de route<\/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\">Binnenkort varen?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Vroeg boeken is op deze route bijna altijd goedkoper.<\/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 Van Duitsland naar Zweden in \u00e9\u00e9n overtocht Zes uur over de Oostzee in plaats van [&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.5 - 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-09-23T08:28:35+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-09-23T08:28:35+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-09-23T08:28:35+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-09-23T08:28:35+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":37,"href":"https:\/\/rostocktrelleborg.com\/nl\/wp-json\/wp\/v2\/pages\/12\/revisions"}],"predecessor-version":[{"id":322,"href":"https:\/\/rostocktrelleborg.com\/nl\/wp-json\/wp\/v2\/pages\/12\/revisions\/322"}],"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}]}}