{"id":110,"date":"2024-05-01T11:59:11","date_gmt":"2024-05-01T11:59:11","guid":{"rendered":"https:\/\/rostocktrelleborg.com\/se\/?page_id=110"},"modified":"2026-06-10T13:27:14","modified_gmt":"2026-06-10T13:27:14","slug":"tidtabell","status":"publish","type":"page","link":"https:\/\/rostocktrelleborg.com\/se\/tidtabell\/","title":{"rendered":"F\u00e4rja Rostock Trelleborg tidtabell"},"content":{"rendered":"\n<style>\n.fd-route-page {\n  --fd-red: #d00c33;\n  --fd-dark: #1e293b;\n  --fd-muted: #64748b;\n  --fd-soft: #f8fafc;\n  --fd-border: #e5e7eb;\n}\n\n.fd-route-hero {\n  background: linear-gradient(135deg, #d00c33 0%, #9f0827 100%);\n  color: #fff;\n  padding: 34px;\n  border-radius: 18px;\n  margin-bottom: 28px;\n}\n\n.fd-route-hero p {\n  max-width: 820px;\n  margin: 0;\n  font-size: 18px;\n  line-height: 1.65;\n}\n\n.fd-route-stats {\n  display: grid;\n  grid-template-columns: repeat(4, 1fr);\n  gap: 16px;\n  margin: 24px 0 32px;\n}\n\n.fd-route-stat {\n  background: #fff;\n  border: 1px solid var(--fd-border);\n  border-radius: 16px;\n  padding: 22px;\n  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.06);\n}\n\n.fd-route-stat strong {\n  display: block;\n  color: var(--fd-red);\n  font-size: 18px;\n  margin-bottom: 6px;\n}\n\n.fd-route-stat span {\n  color: var(--fd-muted);\n  font-size: 14px;\n}\n\n.fd-content-block {\n  background: var(--fd-soft);\n  border: 1px solid var(--fd-border);\n  border-radius: 16px;\n  padding: 26px;\n  margin: 28px 0;\n}\n\n.fd-content-block h2,\n.fd-timetable-block h2,\n.fd-faq h2 {\n  margin-top: 0;\n  color: var(--fd-dark);\n}\n\n.fd-content-block a {\n  color: var(--fd-red);\n  font-weight: 700;\n}\n\n.fd-link-grid {\n  display: grid;\n  grid-template-columns: repeat(5, 1fr);\n  gap: 12px;\n  margin-top: 18px;\n}\n\n.fd-link-grid a {\n  background: #fff;\n  border: 1px solid var(--fd-border);\n  border-radius: 12px;\n  padding: 14px;\n  text-decoration: none;\n  color: var(--fd-dark);\n  font-weight: 700;\n}\n\n.fd-link-grid a:hover {\n  border-color: var(--fd-red);\n  color: var(--fd-red);\n}\n\n.fd-timetable-block {\n  background: #fff;\n  border: 1px solid var(--fd-border);\n  border-top: 5px solid var(--fd-red);\n  border-radius: 16px;\n  padding: 24px;\n  margin: 28px 0;\n  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.05);\n}\n\n.fd-operator-grid {\n  display: grid;\n  grid-template-columns: repeat(2, 1fr);\n  gap: 18px;\n  margin: 28px 0;\n}\n\n.fd-operator-card {\n  background: #fff;\n  border: 1px solid var(--fd-border);\n  border-radius: 16px;\n  padding: 24px;\n  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.05);\n}\n\n.fd-operator-card h2 {\n  margin-top: 0;\n  color: var(--fd-dark);\n}\n\n.fd-operator-card a {\n  color: var(--fd-red);\n  font-weight: 700;\n}\n\n.fd-faq {\n  margin: 32px 0;\n}\n\n.fd-faq-item {\n  background: #fff;\n  border: 1px solid var(--fd-border);\n  border-radius: 14px;\n  padding: 20px 22px;\n  margin-bottom: 14px;\n  box-shadow: 0 6px 18px rgba(15, 23, 42, 0.04);\n}\n\n.fd-faq-item h3 {\n  margin: 0 0 8px;\n  font-size: 18px;\n  color: var(--fd-dark);\n}\n\n.fd-faq-item p {\n  margin: 0;\n  color: var(--fd-muted);\n  line-height: 1.6;\n}\n\n@media (max-width: 900px) {\n  .fd-route-stats,\n  .fd-link-grid {\n    grid-template-columns: repeat(2, 1fr);\n  }\n\n  .fd-operator-grid {\n    grid-template-columns: 1fr;\n  }\n}\n\n@media (max-width: 520px) {\n  .fd-route-stats,\n  .fd-link-grid {\n    grid-template-columns: 1fr;\n  }\n\n  .fd-route-hero {\n    padding: 26px;\n  }\n}\n<\/style>\n\n<div class=\"fd-route-page\">\n\n  <section class=\"fd-route-hero\">\n    <p>F\u00e4rjan mellan Rostock och Trelleborg f\u00f6rbinder norra Tyskland med s\u00f6dra Sverige. Flera avg\u00e5ngar finns varje dag, b\u00e5de dag\u00f6verfarter och natt\u00f6verfarter med TT Line och Stena Line.<\/p>\n  <\/section>\n\n  <div class=\"fd-route-stats\">\n    <div class=\"fd-route-stat\">\n      <strong>2 rederier<\/strong>\n      <span>TT Line och Stena Line<\/span>\n    <\/div>\n    <div class=\"fd-route-stat\">\n      <strong>6 timmar<\/strong>\n      <span>vanlig \u00f6verfartstid<\/span>\n    <\/div>\n    <div class=\"fd-route-stat\">\n      <strong>150 km<\/strong>\n      <span>ungef\u00e4rlig ruttl\u00e4ngd<\/span>\n    <\/div>\n    <div class=\"fd-route-stat\">\n      <strong>6 till 8 avg\u00e5ngar<\/strong>\n      <span>dagligen i b\u00e5da riktningarna<\/span>\n    <\/div>\n  <\/div>\n\n  <div class=\"fd-content-block\">\n    <h2>F\u00e4rja fr\u00e5n Rostock till Trelleborg<\/h2>\n    <p>F\u00e4rjerutten mellan Rostock och Trelleborg \u00e4r en av de viktigaste f\u00f6rbindelserna mellan Tyskland och Sverige. Rutten anv\u00e4nds av semesterresen\u00e4rer, godstrafik, husbilsresen\u00e4rer och resen\u00e4rer som forts\u00e4tter vidare genom Skandinavien med bil.<\/p>\n    <p>Eftersom b\u00e5de TT Line och Stena Line trafikerar denna f\u00e4rjerutt kan resen\u00e4rer j\u00e4mf\u00f6ra flera avg\u00e5ngar varje dag. Tidtabellen nedan samlar aktuella avg\u00e5ngar och g\u00f6r det enklare att v\u00e4lja en avg\u00e5ng som passar resplanen.<\/p>\n  <\/div>\n\n  <div class=\"fd-timetable-block\">\n    <h2>F\u00e4rja Rostock Trelleborg tidtabell<\/h2>\n    <p>Se kommande f\u00e4rjeavg\u00e5ngar fr\u00e5n Rostock till Trelleborg nedan. Tidtabellen inneh\u00e5ller avg\u00e5ngar med b\u00e5de TT Line och Stena Line.<\/p>\n    <div class=\"tp-wrap tp-theme-extended_cards tp-day-setup-classic\" data-config=\"{&quot;rest&quot;:&quot;https:\\\/\\\/rostocktrelleborg.com\\\/se\\\/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;Dagar&quot;,&quot;ui_button&quot;:&quot;Visa avg\\u00e5ngar&quot;,&quot;status_idle&quot;:&quot;V\\u00e4lj ett datum och klicka p\\u00e5 Visa avg\\u00e5ngar&quot;,&quot;status_loading&quot;:&quot;Laddar...&quot;,&quot;status_empty&quot;:&quot;Inga avg\\u00e5ngar hittades&quot;,&quot;status_found&quot;:&quot;%d avg\\u00e5ngar hittades&quot;,&quot;th_date&quot;:&quot;Datum&quot;,&quot;th_dep&quot;:&quot;Avg\\u00e5ng&quot;,&quot;th_arr&quot;:&quot;Ankomst&quot;,&quot;th_dur&quot;:&quot;Restid&quot;,&quot;th_ship&quot;:&quot;Fartyg&quot;,&quot;th_op&quot;:&quot;Operat\\u00f6r&quot;,&quot;th_route&quot;:&quot;Rutt&quot;,&quot;wd_sun&quot;:&quot;S\\u00d6N&quot;,&quot;wd_mon&quot;:&quot;M\\u00c5N&quot;,&quot;wd_tue&quot;:&quot;TIS&quot;,&quot;wd_wed&quot;:&quot;ONS&quot;,&quot;wd_thu&quot;:&quot;TOR&quot;,&quot;wd_fri&quot;:&quot;FRE&quot;,&quot;wd_sat&quot;:&quot;L\\u00d6R&quot;,&quot;summary_footer_one&quot;:&quot;\\u00bb Se alla %s avg\\u00e5ngar i v\\u00e5r tidtabell&quot;,&quot;summary_footer_two&quot;:&quot;\\u00bb Se fler avg\\u00e5ngar f\\u00f6r %1$s och %2$s i v\\u00e5r tidtabell&quot;,&quot;summary_footer_generic&quot;:&quot;Se v\\u00e5r tidtabell f\\u00f6r fler avg\\u00e5ngar&quot;,&quot;summary_header&quot;:&quot;De tv\\u00e5 n\\u00e4sta avg\\u00e5ngarna:&quot;,&quot;summary_no_upcoming&quot;:&quot;Inga kommande avg\\u00e5ngar hittades&quot;,&quot;more_link&quot;:&quot;Fler avg\\u00e5ngar&quot;,&quot;more_departures_button&quot;:&quot;Visa fler avg\\u00e5ngar&quot;,&quot;day_nav_previous&quot;:&quot;Visa f\\u00f6reg\\u00e5ende dag&quot;,&quot;day_nav_next&quot;:&quot;Visa n\\u00e4sta dag&quot;,&quot;day_nav_today&quot;:&quot;Visa idag&quot;,&quot;day_nav_tomorrow&quot;:&quot;Visa imorgon&quot;,&quot;local_time_pair&quot;:&quot;Lokal tid avg\\u00e5ngshamn: %1$s \\\/ Lokal tid ankomsthamn: %2$s&quot;,&quot;local_time_combined&quot;:&quot;Lokal tid avg\\u00e5ngs- och ankomsthamn: %s&quot;,&quot;tag_often_booked&quot;:&quot;\\u2b50 Ofta bokad&quot;,&quot;tag_leaving_soon&quot;:&quot;\\ud83d\\udd34 Avg\\u00e5r snart&quot;,&quot;tag_currently_sailing&quot;:&quot;\\ud83d\\udfe2 P\\u00e5 v\\u00e4g nu&quot;,&quot;tag_arrived&quot;:&quot;\\u26ab Anl\\u00e4nt&quot;,&quot;tag_overnight&quot;:&quot;\\u00d6vernattning&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\">Dagar<\/label><br>\n      <select id=\"tp-range-ops\" class=\"tp-range\" aria-label=\"Dagar\">\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\">Visa avg\u00e5ngar<\/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\">V\u00e4lj ett datum och klicka p\u00e5 Visa avg\u00e5ngar<\/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\">Laddar...<\/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 => ({'&':'&','<':'&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  <\/div>\n\n  <div class=\"fd-timetable-block\">\n    <h2>F\u00e4rja Trelleborg Rostock tidtabell<\/h2>\n    <p>Se kommande f\u00e4rjeavg\u00e5ngar fr\u00e5n Trelleborg till Rostock nedan. \u00d6versikten g\u00f6r det l\u00e4ttare att j\u00e4mf\u00f6ra returresor fr\u00e5n Sverige till Tyskland.<\/p>\n    <div class=\"tp-wrap tp-theme-extended_cards tp-day-setup-classic\" data-config=\"{&quot;rest&quot;:&quot;https:\\\/\\\/rostocktrelleborg.com\\\/se\\\/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;Dagar&quot;,&quot;ui_button&quot;:&quot;Visa avg\\u00e5ngar&quot;,&quot;status_idle&quot;:&quot;V\\u00e4lj ett datum och klicka p\\u00e5 Visa avg\\u00e5ngar&quot;,&quot;status_loading&quot;:&quot;Laddar...&quot;,&quot;status_empty&quot;:&quot;Inga avg\\u00e5ngar hittades&quot;,&quot;status_found&quot;:&quot;%d avg\\u00e5ngar hittades&quot;,&quot;th_date&quot;:&quot;Datum&quot;,&quot;th_dep&quot;:&quot;Avg\\u00e5ng&quot;,&quot;th_arr&quot;:&quot;Ankomst&quot;,&quot;th_dur&quot;:&quot;Restid&quot;,&quot;th_ship&quot;:&quot;Fartyg&quot;,&quot;th_op&quot;:&quot;Operat\\u00f6r&quot;,&quot;th_route&quot;:&quot;Rutt&quot;,&quot;wd_sun&quot;:&quot;S\\u00d6N&quot;,&quot;wd_mon&quot;:&quot;M\\u00c5N&quot;,&quot;wd_tue&quot;:&quot;TIS&quot;,&quot;wd_wed&quot;:&quot;ONS&quot;,&quot;wd_thu&quot;:&quot;TOR&quot;,&quot;wd_fri&quot;:&quot;FRE&quot;,&quot;wd_sat&quot;:&quot;L\\u00d6R&quot;,&quot;summary_footer_one&quot;:&quot;\\u00bb Se alla %s avg\\u00e5ngar i v\\u00e5r tidtabell&quot;,&quot;summary_footer_two&quot;:&quot;\\u00bb Se fler avg\\u00e5ngar f\\u00f6r %1$s och %2$s i v\\u00e5r tidtabell&quot;,&quot;summary_footer_generic&quot;:&quot;Se v\\u00e5r tidtabell f\\u00f6r fler avg\\u00e5ngar&quot;,&quot;summary_header&quot;:&quot;De tv\\u00e5 n\\u00e4sta avg\\u00e5ngarna:&quot;,&quot;summary_no_upcoming&quot;:&quot;Inga kommande avg\\u00e5ngar hittades&quot;,&quot;more_link&quot;:&quot;Fler avg\\u00e5ngar&quot;,&quot;more_departures_button&quot;:&quot;Visa fler avg\\u00e5ngar&quot;,&quot;day_nav_previous&quot;:&quot;Visa f\\u00f6reg\\u00e5ende dag&quot;,&quot;day_nav_next&quot;:&quot;Visa n\\u00e4sta dag&quot;,&quot;day_nav_today&quot;:&quot;Visa idag&quot;,&quot;day_nav_tomorrow&quot;:&quot;Visa imorgon&quot;,&quot;local_time_pair&quot;:&quot;Lokal tid avg\\u00e5ngshamn: %1$s \\\/ Lokal tid ankomsthamn: %2$s&quot;,&quot;local_time_combined&quot;:&quot;Lokal tid avg\\u00e5ngs- och ankomsthamn: %s&quot;,&quot;tag_often_booked&quot;:&quot;\\u2b50 Ofta bokad&quot;,&quot;tag_leaving_soon&quot;:&quot;\\ud83d\\udd34 Avg\\u00e5r snart&quot;,&quot;tag_currently_sailing&quot;:&quot;\\ud83d\\udfe2 P\\u00e5 v\\u00e4g nu&quot;,&quot;tag_arrived&quot;:&quot;\\u26ab Anl\\u00e4nt&quot;,&quot;tag_overnight&quot;:&quot;\\u00d6vernattning&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\">Dagar<\/label><br>\n      <select id=\"tp-range-ops\" class=\"tp-range\" aria-label=\"Dagar\">\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\">Visa avg\u00e5ngar<\/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\">V\u00e4lj ett datum och klicka p\u00e5 Visa avg\u00e5ngar<\/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\">Laddar...<\/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 => ({'&':'&','<':'&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  <\/div>\n\n  <div class=\"fd-operator-grid\">\n    <div class=\"fd-operator-card\">\n      <h2>TT Line Rostock Trelleborg tidtabell<\/h2>\n      <p>M\u00e5nga resen\u00e4rer s\u00f6ker specifikt efter TT Line Rostock Trelleborg tidtabell. TT Line trafikerar rutten regelbundet med b\u00e5de dagavg\u00e5ngar och nattavg\u00e5ngar.<\/p>\n      <p>Tidtabellen p\u00e5 denna sida inneh\u00e5ller tillg\u00e4ngliga TT Line avg\u00e5ngar i b\u00e5da riktningarna mellan Rostock och Trelleborg.<\/p>\n      <p><a href=\"\/se\/tt-line\/\">Mer om TT Line<\/a><\/p>\n    <\/div>\n\n    <div class=\"fd-operator-card\">\n      <h2>Stena Line Rostock Trelleborg tidtabell<\/h2>\n      <p>Stena Line trafikerar ocks\u00e5 rutten mellan Rostock och Trelleborg. Beroende p\u00e5 datum och s\u00e4song finns flera avg\u00e5ngar under dagen.<\/p>\n      <p>Tidtabellen p\u00e5 denna sida inneh\u00e5ller tillg\u00e4ngliga Stena Line avg\u00e5ngar fr\u00e5n Rostock till Trelleborg och fr\u00e5n Trelleborg till Rostock.<\/p>\n      <p><a href=\"\/se\/stena-line\/\">Mer om Stena Line<\/a><\/p>\n    <\/div>\n  <\/div>\n\n  <div class=\"fd-content-block\">\n    <h2>Om f\u00e4rjerutten Rostock Trelleborg<\/h2>\n    <p>Dags\u00f6verfarter tar vanligtvis omkring 6 timmar. Nattavg\u00e5ngar kan ta n\u00e5got l\u00e4ngre tid beroende p\u00e5 fartyg och avg\u00e5ngstid. Rutten \u00e4r s\u00e4rskilt praktisk f\u00f6r resen\u00e4rer som vill korsa \u00d6stersj\u00f6n med bil, husbil, motorcykel eller husvagn.<\/p>\n    <p>Rostock \u00e4r en praktisk avg\u00e5ngshamn f\u00f6r resen\u00e4rer fr\u00e5n Tyskland och Centraleuropa. Trelleborg ligger i s\u00f6dra Sverige, med goda v\u00e4gf\u00f6rbindelser mot Malm\u00f6, G\u00f6teborg, Stockholm och Norge.<\/p>\n  <\/div>\n\n  <div class=\"fd-content-block\">\n    <h2>Bra att veta f\u00f6re avg\u00e5ng<\/h2>\n    <p>Resen\u00e4rer som reser mellan Tyskland och Sverige kan ocks\u00e5 ha nytta av f\u00f6ljande sidor f\u00f6re avg\u00e5ng.<\/p>\n\n    <div class=\"fd-link-grid\">\n      <a href=\"\/se\/rostock-hamn\/\">Rostock hamn<\/a>\n      <a href=\"\/se\/trelleborg-hamn\/\">Trelleborg hamn<\/a>\n      <a href=\"\/se\/priser\/\">F\u00e4rjepriser<\/a>\n      <a href=\"\/se\/tt-line\/\">TT Line<\/a>\n      <a href=\"\/se\/stena-line\/\">Stena Line<\/a>\n    <\/div>\n  <\/div>\n\n  <section class=\"fd-faq\">\n    <h2>Vanliga fr\u00e5gor<\/h2>\n\n    <div class=\"fd-faq-item\">\n      <h3>Hur l\u00e5ng tid tar f\u00e4rjan fr\u00e5n Rostock till Trelleborg?<\/h3>\n      <p>De flesta \u00f6verfarter tar omkring 6 timmar. Vissa nattavg\u00e5ngar tar l\u00e4ngre tid, vanligtvis mellan 7 och 8 timmar.<\/p>\n    <\/div>\n\n    <div class=\"fd-faq-item\">\n      <h3>Vilka rederier trafikerar mellan Rostock och Trelleborg?<\/h3>\n      <p>Rutten trafikeras av TT Line och Stena Line. B\u00e5da rederierna erbjuder regelbundna avg\u00e5ngar mellan Tyskland och Sverige.<\/p>\n    <\/div>\n\n    <div class=\"fd-faq-item\">\n      <h3>Finns det nattf\u00e4rjor mellan Rostock och Trelleborg?<\/h3>\n      <p>Ja. Nattavg\u00e5ngar finns ofta i b\u00e5da riktningarna, vilket kan vara praktiskt f\u00f6r resen\u00e4rer som vill anl\u00e4nda tidigt p\u00e5 morgonen.<\/p>\n    <\/div>\n\n    <div class=\"fd-faq-item\">\n      <h3>Hur m\u00e5nga dagliga avg\u00e5ngar finns det mellan Rostock och Trelleborg?<\/h3>\n      <p>Antalet avg\u00e5ngar varierar beroende p\u00e5 datum och s\u00e4song, men tidtabellen visar ofta omkring 6 till 8 avg\u00e5ngar per dag fr\u00e5n de b\u00e5da rederierna tillsammans.<\/p>\n    <\/div>\n\n    <div class=\"fd-faq-item\">\n      <h3>Vad \u00e4r restiden med f\u00e4rja mellan Rostock och Trelleborg?<\/h3>\n      <p>Den vanliga restiden \u00e4r omkring 6 timmar. Natt\u00f6verfarter kan ta l\u00e4ngre tid beroende p\u00e5 fartyg, rederi och avg\u00e5ngstid.<\/p>\n    <\/div>\n\n    <div class=\"fd-faq-item\">\n      <h3>Vilket rederi \u00e4r b\u00e4st, TT Line eller Stena Line?<\/h3>\n      <p>B\u00e5de TT Line och Stena Line erbjuder regelbundna f\u00e4rjeavg\u00e5ngar mellan Rostock och Trelleborg. Det b\u00e4sta valet beror p\u00e5 \u00f6nskad avg\u00e5ngstid, pris, fartyg och resplan.<\/p>\n    <\/div>\n\n    <div class=\"fd-faq-item\">\n      <h3>Kan jag resa med bil fr\u00e5n Rostock till Trelleborg?<\/h3>\n      <p>Ja. Rutten passar f\u00f6r resen\u00e4rer med bil, husbil, motorcykel eller husvagn.<\/p>\n    <\/div>\n  <\/section>\n\n<\/div>\n\n<script type=\"application\/ld+json\">\n{\n  \"@context\":\"https:\/\/schema.org\",\n  \"@type\":\"FAQPage\",\n  \"mainEntity\":[\n    {\n      \"@type\":\"Question\",\n      \"name\":\"Hur l\u00e5ng tid tar f\u00e4rjan fr\u00e5n Rostock till Trelleborg?\",\n      \"acceptedAnswer\":{\n        \"@type\":\"Answer\",\n        \"text\":\"De flesta \u00f6verfarter tar omkring 6 timmar. Vissa nattavg\u00e5ngar tar l\u00e4ngre tid, vanligtvis mellan 7 och 8 timmar.\"\n      }\n    },\n    {\n      \"@type\":\"Question\",\n      \"name\":\"Vilka rederier trafikerar mellan Rostock och Trelleborg?\",\n      \"acceptedAnswer\":{\n        \"@type\":\"Answer\",\n        \"text\":\"Rutten trafikeras av TT Line och Stena Line. B\u00e5da rederierna erbjuder regelbundna avg\u00e5ngar mellan Tyskland och Sverige.\"\n      }\n    },\n    {\n      \"@type\":\"Question\",\n      \"name\":\"Finns det nattf\u00e4rjor mellan Rostock och Trelleborg?\",\n      \"acceptedAnswer\":{\n        \"@type\":\"Answer\",\n        \"text\":\"Ja. Nattavg\u00e5ngar finns ofta i b\u00e5da riktningarna, vilket kan vara praktiskt f\u00f6r resen\u00e4rer som vill anl\u00e4nda tidigt p\u00e5 morgonen.\"\n      }\n    },\n    {\n      \"@type\":\"Question\",\n      \"name\":\"Hur m\u00e5nga dagliga avg\u00e5ngar finns det mellan Rostock och Trelleborg?\",\n      \"acceptedAnswer\":{\n        \"@type\":\"Answer\",\n        \"text\":\"Antalet avg\u00e5ngar varierar beroende p\u00e5 datum och s\u00e4song, men tidtabellen visar ofta omkring 6 till 8 avg\u00e5ngar per dag fr\u00e5n de b\u00e5da rederierna tillsammans.\"\n      }\n    },\n    {\n      \"@type\":\"Question\",\n      \"name\":\"Vad \u00e4r restiden med f\u00e4rja mellan Rostock och Trelleborg?\",\n      \"acceptedAnswer\":{\n        \"@type\":\"Answer\",\n        \"text\":\"Den vanliga restiden \u00e4r omkring 6 timmar. Natt\u00f6verfarter kan ta l\u00e4ngre tid beroende p\u00e5 fartyg, rederi och avg\u00e5ngstid.\"\n      }\n    },\n    {\n      \"@type\":\"Question\",\n      \"name\":\"Vilket rederi \u00e4r b\u00e4st, TT Line eller Stena Line?\",\n      \"acceptedAnswer\":{\n        \"@type\":\"Answer\",\n        \"text\":\"B\u00e5de TT Line och Stena Line erbjuder regelbundna f\u00e4rjeavg\u00e5ngar mellan Rostock och Trelleborg. Det b\u00e4sta valet beror p\u00e5 \u00f6nskad avg\u00e5ngstid, pris, fartyg och resplan.\"\n      }\n    },\n    {\n      \"@type\":\"Question\",\n      \"name\":\"Kan jag resa med bil fr\u00e5n Rostock till Trelleborg?\",\n      \"acceptedAnswer\":{\n        \"@type\":\"Answer\",\n        \"text\":\"Ja. Rutten passar f\u00f6r resen\u00e4rer med bil, husbil, motorcykel eller husvagn.\"\n      }\n    }\n  ]\n}\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>F\u00e4rjan mellan Rostock och Trelleborg f\u00f6rbinder norra Tyskland med s\u00f6dra Sverige. Flera avg\u00e5ngar finns varje dag, b\u00e5de dag\u00f6verfarter och natt\u00f6verfarter [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"inline_featured_image":false,"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","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-110","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>F\u00e4rja Rostock Trelleborg tidtabell | TT Line &amp; Stena Line<\/title>\n<meta name=\"description\" content=\"Se tidtabell f\u00f6r f\u00e4rja Rostock Trelleborg. J\u00e4mf\u00f6r avg\u00e5ngar med TT Line och Stena Line, restid, priser och dagliga f\u00e4rjor mellan Tyskland och Sverige.\" \/>\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\/se\/tidtabell\/\" \/>\n<meta property=\"og:locale\" content=\"sv_SE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"F\u00e4rja Rostock Trelleborg tidtabell | TT Line &amp; Stena Line\" \/>\n<meta property=\"og:description\" content=\"Se tidtabell f\u00f6r f\u00e4rja Rostock Trelleborg. J\u00e4mf\u00f6r avg\u00e5ngar med TT Line och Stena Line, restid, priser och dagliga f\u00e4rjor mellan Tyskland och Sverige.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/rostocktrelleborg.com\/se\/tidtabell\/\" \/>\n<meta property=\"og:site_name\" content=\"F\u00e4rjor fr\u00e5n Trelleborg till Rostock\" \/>\n<meta property=\"article:modified_time\" content=\"2026-06-10T13:27:14+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Ber\u00e4knad l\u00e4stid\" \/>\n\t<meta name=\"twitter:data1\" content=\"2 minuter\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/rostocktrelleborg.com\\\/se\\\/tidtabell\\\/\",\"url\":\"https:\\\/\\\/rostocktrelleborg.com\\\/se\\\/tidtabell\\\/\",\"name\":\"F\u00e4rja Rostock Trelleborg tidtabell | TT Line & Stena Line\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/rostocktrelleborg.com\\\/se\\\/#website\"},\"datePublished\":\"2024-05-01T11:59:11+00:00\",\"dateModified\":\"2026-06-10T13:27:14+00:00\",\"description\":\"Se tidtabell f\u00f6r f\u00e4rja Rostock Trelleborg. J\u00e4mf\u00f6r avg\u00e5ngar med TT Line och Stena Line, restid, priser och dagliga f\u00e4rjor mellan Tyskland och Sverige.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/rostocktrelleborg.com\\\/se\\\/tidtabell\\\/#breadcrumb\"},\"inLanguage\":\"sv-SE\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/rostocktrelleborg.com\\\/se\\\/tidtabell\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/rostocktrelleborg.com\\\/se\\\/tidtabell\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/rostocktrelleborg.com\\\/se\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"F\u00e4rja Rostock Trelleborg tidtabell\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/rostocktrelleborg.com\\\/se\\\/#website\",\"url\":\"https:\\\/\\\/rostocktrelleborg.com\\\/se\\\/\",\"name\":\"F\u00e4rjor fr\u00e5n Trelleborg till Rostock\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/rostocktrelleborg.com\\\/se\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/rostocktrelleborg.com\\\/se\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"sv-SE\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/rostocktrelleborg.com\\\/se\\\/#organization\",\"name\":\"F\u00e4rjor fr\u00e5n Trelleborg till Rostock\",\"url\":\"https:\\\/\\\/rostocktrelleborg.com\\\/se\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"sv-SE\",\"@id\":\"https:\\\/\\\/rostocktrelleborg.com\\\/se\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/rostocktrelleborg.com\\\/se\\\/wp-content\\\/uploads\\\/sites\\\/4\\\/2026\\\/06\\\/rostocktrelleborg-ferry-logo.png\",\"contentUrl\":\"https:\\\/\\\/rostocktrelleborg.com\\\/se\\\/wp-content\\\/uploads\\\/sites\\\/4\\\/2026\\\/06\\\/rostocktrelleborg-ferry-logo.png\",\"width\":512,\"height\":154,\"caption\":\"F\u00e4rjor fr\u00e5n Trelleborg till Rostock\"},\"image\":{\"@id\":\"https:\\\/\\\/rostocktrelleborg.com\\\/se\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"F\u00e4rja Rostock Trelleborg tidtabell | TT Line & Stena Line","description":"Se tidtabell f\u00f6r f\u00e4rja Rostock Trelleborg. J\u00e4mf\u00f6r avg\u00e5ngar med TT Line och Stena Line, restid, priser och dagliga f\u00e4rjor mellan Tyskland och Sverige.","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\/se\/tidtabell\/","og_locale":"sv_SE","og_type":"article","og_title":"F\u00e4rja Rostock Trelleborg tidtabell | TT Line & Stena Line","og_description":"Se tidtabell f\u00f6r f\u00e4rja Rostock Trelleborg. J\u00e4mf\u00f6r avg\u00e5ngar med TT Line och Stena Line, restid, priser och dagliga f\u00e4rjor mellan Tyskland och Sverige.","og_url":"https:\/\/rostocktrelleborg.com\/se\/tidtabell\/","og_site_name":"F\u00e4rjor fr\u00e5n Trelleborg till Rostock","article_modified_time":"2026-06-10T13:27:14+00:00","twitter_card":"summary_large_image","twitter_misc":{"Ber\u00e4knad l\u00e4stid":"2 minuter"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/rostocktrelleborg.com\/se\/tidtabell\/","url":"https:\/\/rostocktrelleborg.com\/se\/tidtabell\/","name":"F\u00e4rja Rostock Trelleborg tidtabell | TT Line & Stena Line","isPartOf":{"@id":"https:\/\/rostocktrelleborg.com\/se\/#website"},"datePublished":"2024-05-01T11:59:11+00:00","dateModified":"2026-06-10T13:27:14+00:00","description":"Se tidtabell f\u00f6r f\u00e4rja Rostock Trelleborg. J\u00e4mf\u00f6r avg\u00e5ngar med TT Line och Stena Line, restid, priser och dagliga f\u00e4rjor mellan Tyskland och Sverige.","breadcrumb":{"@id":"https:\/\/rostocktrelleborg.com\/se\/tidtabell\/#breadcrumb"},"inLanguage":"sv-SE","potentialAction":[{"@type":"ReadAction","target":["https:\/\/rostocktrelleborg.com\/se\/tidtabell\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/rostocktrelleborg.com\/se\/tidtabell\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/rostocktrelleborg.com\/se\/"},{"@type":"ListItem","position":2,"name":"F\u00e4rja Rostock Trelleborg tidtabell"}]},{"@type":"WebSite","@id":"https:\/\/rostocktrelleborg.com\/se\/#website","url":"https:\/\/rostocktrelleborg.com\/se\/","name":"F\u00e4rjor fr\u00e5n Trelleborg till Rostock","description":"","publisher":{"@id":"https:\/\/rostocktrelleborg.com\/se\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/rostocktrelleborg.com\/se\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"sv-SE"},{"@type":"Organization","@id":"https:\/\/rostocktrelleborg.com\/se\/#organization","name":"F\u00e4rjor fr\u00e5n Trelleborg till Rostock","url":"https:\/\/rostocktrelleborg.com\/se\/","logo":{"@type":"ImageObject","inLanguage":"sv-SE","@id":"https:\/\/rostocktrelleborg.com\/se\/#\/schema\/logo\/image\/","url":"https:\/\/rostocktrelleborg.com\/se\/wp-content\/uploads\/sites\/4\/2026\/06\/rostocktrelleborg-ferry-logo.png","contentUrl":"https:\/\/rostocktrelleborg.com\/se\/wp-content\/uploads\/sites\/4\/2026\/06\/rostocktrelleborg-ferry-logo.png","width":512,"height":154,"caption":"F\u00e4rjor fr\u00e5n Trelleborg till Rostock"},"image":{"@id":"https:\/\/rostocktrelleborg.com\/se\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/rostocktrelleborg.com\/se\/wp-json\/wp\/v2\/pages\/110","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rostocktrelleborg.com\/se\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/rostocktrelleborg.com\/se\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/rostocktrelleborg.com\/se\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/rostocktrelleborg.com\/se\/wp-json\/wp\/v2\/comments?post=110"}],"version-history":[{"count":5,"href":"https:\/\/rostocktrelleborg.com\/se\/wp-json\/wp\/v2\/pages\/110\/revisions"}],"predecessor-version":[{"id":167,"href":"https:\/\/rostocktrelleborg.com\/se\/wp-json\/wp\/v2\/pages\/110\/revisions\/167"}],"wp:attachment":[{"href":"https:\/\/rostocktrelleborg.com\/se\/wp-json\/wp\/v2\/media?parent=110"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}