diff --git a/assets/js/contentNavigation.js b/assets/js/contentNavigation.js index b61e21ed..8da2a51d 100644 --- a/assets/js/contentNavigation.js +++ b/assets/js/contentNavigation.js @@ -19,6 +19,8 @@ const initAside = () => { let isClosed = true; const closeSheet = () => { + if (isClosed) return; + isClosed = true; aside.classList.remove("o-aside--open"); asideContent.removeAttribute("role"); @@ -107,10 +109,9 @@ const initAside = () => { wasMobile = true; closeSheet(); } - if (!isMobile()) { + if (wasMobile && !isMobile()) { wasMobile = false; - closeOverlay(); - aside.classList.remove("o-aside--open"); + closeSheet(); } }; diff --git a/assets/js/dialog.js b/assets/js/dialog.js new file mode 100644 index 00000000..76932ae9 --- /dev/null +++ b/assets/js/dialog.js @@ -0,0 +1,63 @@ +function getCloseButton(dialog) { + return dialog.querySelector(".o-dialog__header > .a-button"); +} + +function openDialog(dialogId) { + const dialog = document.getElementById(dialogId); + if (!dialog) return; + + dialog.showModal(); +} + +function openDialogOnHash() { + const hash = window.location.hash; + if (!hash) return; + + const targetId = decodeURIComponent(hash.substring(1)); + const targetElement = document.getElementById(targetId); + + if (targetElement) { + const dialog = targetElement.closest("dialog"); + if (dialog && !dialog.open) { + dialog.showModal(); + } + } +} + +function initDialogs() { + document.querySelectorAll("dialog").forEach((dialog) => { + dialog.addEventListener("click", (e) => { + if (e.target === dialog) { + dialog.close(); + } + }); + + const closeButton = getCloseButton(dialog); + if (closeButton) { + closeButton.addEventListener("click", () => dialog.close()); + } + }); + + document.querySelectorAll("[data-dialog-trigger]").forEach((trigger) => { + const handler = (e) => { + if (e.type === "click" || (e.type === "keydown" && e.key === "Enter")) { + e.preventDefault(); + const dialogId = trigger.getAttribute("data-dialog-trigger"); + openDialog(dialogId); + } + }; + + trigger.addEventListener("click", handler); + trigger.addEventListener("keydown", handler); + }); + + // Initialize hash check + openDialogOnHash(); + window.addEventListener("hashchange", openDialogOnHash); +} + +if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", initDialogs); +} else { + initDialogs(); +} diff --git a/assets/js/main.js b/assets/js/main.js index 964b1f43..830c8a4e 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -9,3 +9,4 @@ import "./dropdown.js"; import "./search.js"; import "./interactiveMap.js"; import "./expander.js"; +import "./dialog.js"; diff --git a/assets/js/mobileMenu.js b/assets/js/mobileMenu.js index 7190d65f..4ffe0c09 100644 --- a/assets/js/mobileMenu.js +++ b/assets/js/mobileMenu.js @@ -39,6 +39,8 @@ function closeMobileMenu() { const navContainer = document.querySelector(".o-header__nav"); const menuButton = document.querySelector(".o-nav__menu-button"); + if (!navContainer.classList.contains("o-header__nav--open")) return; + navContainer.classList.remove("o-header__nav--open"); menuButton.setAttribute("aria-expanded", false); closeOverlay(); diff --git a/assets/sass/button.scss b/assets/sass/button.scss index 7d6b7a82..a8b94a33 100644 --- a/assets/sass/button.scss +++ b/assets/sass/button.scss @@ -3,7 +3,6 @@ display: inline-flex; align-items: center; gap: 0.4rem; - border: 0.2rem solid var(--link-default); border-radius: var(--border-radius-m); font-size: 1.5rem; cursor: pointer; @@ -25,4 +24,12 @@ padding: 0.6rem; display: block; } + + &__external { + border: 0.2rem solid var(--link-default); + } + + &__internal { + border: none; + } } diff --git a/assets/sass/dialog.scss b/assets/sass/dialog.scss new file mode 100644 index 00000000..a31c389c --- /dev/null +++ b/assets/sass/dialog.scss @@ -0,0 +1,69 @@ +.o-dialog { + max-height: calc(100dvh - 14rem); + overflow: auto; + display: flex; + flex-direction: column; + + .a-anchorlink { + margin-bottom: 0; + + &__link { + display: none; + } + + > h2 { + margin-bottom: 1rem; + } + } + + .o-divider { + display: none; + } + + &__wrapper { + width: fit-content; + border: none; + padding: 0; + background-color: var(--bg-default); + color: var(--color-body); + border-radius: var(--border-radius-m); + border: var(--border); + overflow: hidden; + + &::backdrop { + background-color: rgba(0, 0, 0, 0.6); + backdrop-filter: blur(4px); + } + } + + &__header { + position: sticky; + top: 0; + background-color: var(--bg-default); + display: flex; + column-gap: 1rem; + align-items: center; + justify-content: space-between; + padding: 1rem 1rem 1rem 2rem; + border-bottom: var(--border); + border-color: var(--color-table-border); + + .o-divider { + display: none; + } + + > h1 { + margin: 0; + font-size: 2.2rem; + } + } + + &__body { + padding: 2rem; + overflow: auto; + + > *:last-child { + margin-bottom: 0; + } + } +} diff --git a/assets/sass/header.scss b/assets/sass/header.scss index 12ab3273..cfeba756 100644 --- a/assets/sass/header.scss +++ b/assets/sass/header.scss @@ -102,6 +102,12 @@ z-index: 14; } -body:has(.overlay--show) { +#header:has(.overlay--dialog), +.overlay--dialog { + z-index: 10; +} + +body:has(.overlay--show), +body:has(dialog[open]) { overflow: hidden; } diff --git a/assets/sass/main.scss b/assets/sass/main.scss index 45cbf8c9..eb8db79a 100644 --- a/assets/sass/main.scss +++ b/assets/sass/main.scss @@ -23,3 +23,4 @@ @import "tag.scss"; @import "floatImage.scss"; @import "teamMember.scss"; +@import "dialog.scss"; diff --git a/assets/sass/styles.scss b/assets/sass/styles.scss index 53da76e6..e87f1b5e 100644 --- a/assets/sass/styles.scss +++ b/assets/sass/styles.scss @@ -57,13 +57,16 @@ button { @include focus-indicator(0.2rem); } -a { +a, +.o-link { color: var(--link-default); transition: color 0.3s ease, background-color 0.3s ease; text-underline-offset: 0.2rem; border-radius: var(--border-radius-s); + text-decoration: underline; + cursor: pointer; &:hover, &:focus { @@ -80,6 +83,10 @@ a { display: none; } } + + & > .material-symbols-rounded { + margin: 0 0.2rem; + } } main { diff --git a/content/country/belgium/index.en.md b/content/country/belgium/index.en.md index c5331490..66a531fd 100644 --- a/content/country/belgium/index.en.md +++ b/content/country/belgium/index.en.md @@ -17,7 +17,7 @@ Additionally, international [Eurostar](/operator/eurostar "Eurostar") trains ope Furthermore, international `TGV` trains of the [SNCF](/operator/sncf "SNCF") from France operate, for which the FIP Coupon of SNCB are not valid. Only special FIP Global Fares can be booked for these trains. For the Eurocity trains from Brussels to Paris operated by OUIGO, no FIP discounts apply. {{< identify-operator sources="db-website,vagonweb" >}} -Not all trains in the country (e. g. `ICE`) are shown in the [SNCB / NMBS online timetable](https://www.belgiantrain.be/en/). +Not all trains in the country (e.g. `ICE`) are shown in the [SNCB / NMBS online timetable](https://www.belgiantrain.be/en/). {{< /identify-operator >}} ## Interesting diff --git a/content/identify-operator/renfe-commuter-website/index.en.md b/content/identify-operator/renfe-commuter-website/index.en.md index da086cc4..deb30144 100644 --- a/content/identify-operator/renfe-commuter-website/index.en.md +++ b/content/identify-operator/renfe-commuter-website/index.en.md @@ -4,4 +4,4 @@ params: url: "https://www.renfe.com/es/en/suburban" --- -On the Renfe Cercanías website (suburban trains), you can search for train connections in any suburban train network. To do this, select the relevant region on the website and then click on _Timetables_. In suburban train networks with multiple operators (e. g. Barcelona), only Renfe trains are displayed. +On the Renfe Cercanías website (suburban trains), you can search for train connections in any suburban train network. To do this, select the relevant region on the website and then click on _Timetables_. In suburban train networks with multiple operators (e.g. Barcelona), only Renfe trains are displayed. diff --git a/content/operator/stl/index.de.md b/content/operator/stl/index.de.md index 88a1afb0..fe298451 100644 --- a/content/operator/stl/index.de.md +++ b/content/operator/stl/index.de.md @@ -186,4 +186,40 @@ Stena Line bietet eine tolle Möglichkeit, um vor 10 Uhr in London zu sein, wenn [^3]: [Website Stena Line](https://www.stenaline.de/routen/hoek-van-holland-harwich) -[^4]: [E-Mail-Anfrage des FIP Guide Teams bei Stena Line](https://github.com/fipguide/fipguide.github.io/issues/528) +[^4]: [E-Mail-Anfrage des FIP Guide Teams bei Stena Line](dialog:stena-line-email) + +{{% dialog + id="stena-line-email" + title="E-Mail-Anfrage des FIP Guide Teams bei Stena Line" +%}} + +# RE: Vielen Dank für Ihre E-Mail - CASE:172468 + +**Von:** Stena Line UK contact.uk.info@stenaline.com \ +**An:** Robert Schuster nextstop@fipguide.org \ +**Datum:** Mo. 1. Dez. 2025, 10:59 + +Hello, + +Thank you for contacting us. + +Concessions bookings can be made by phone or on the day of travel, subject to availability. + +The cost of the booking depends on the type of concessions pass you hold. Generally, the overnight sailing is more expensive than the daytime crossing, as the fare for the overnight journey is higher and cabins are mandatory. + +The concessions fare only provides a discount on the fare price; any additional extras are charged at full price and are not discounted. + +For more information or a travel quote, please contact [03447 7070 70](tel:03447707070), and a member of our team will be glad to assist you. + +Thank you + +Best regards + +Stacey + +Contact Centre agent + +Call: [03447 707070](tel:03447707070) (UK) [+353 1871 4711](tel:+35318714711) (IRL) + +Internet: www.stenaline.co.uk +{{% /dialog %}} diff --git a/content/operator/stl/index.en.md b/content/operator/stl/index.en.md index ef17a4b9..173a5d0d 100644 --- a/content/operator/stl/index.en.md +++ b/content/operator/stl/index.en.md @@ -186,4 +186,40 @@ Stena Line offers a great way to be in London before 10 am if you invest a littl [^3]: [Stena Line Website](https://www.stenaline.de/routen/hoek-van-holland-harwich) -[^4]: [FIP Guide Team email inquiry to Stena Line](https://github.com/fipguide/fipguide.github.io/issues/528) +[^4]: [FIP Guide Team email inquiry to Stena Line](dialog:stena-line-email) + +{{% dialog + id="stena-line-email" + title="FIP Guide Team email inquiry to Stena Line" +%}} + +# RE: Vielen Dank für Ihre E-Mail - CASE:172468 + +**From:** Stena Line UK contact.uk.info@stenaline.com \ +**To:** Robert Schuster nextstop@fipguide.org \ +**Date:** Mon, 1 Dec 2025, 10:59 + +Hello, + +Thank you for contacting us. + +Concessions bookings can be made by phone or on the day of travel, subject to availability. + +The cost of the booking depends on the type of concessions pass you hold. Generally, the overnight sailing is more expensive than the daytime crossing, as the fare for the overnight journey is higher and cabins are mandatory. + +The concessions fare only provides a discount on the fare price; any additional extras are charged at full price and are not discounted. + +For more information or a travel quote, please contact [03447 7070 70](tel:03447707070), and a member of our team will be glad to assist you. + +Thank you + +Best regards + +Stacey + +Contact Centre agent + +Call: [03447 707070](tel:03447707070) (UK) [+353 1871 4711](tel:+35318714711) (IRL) + +Internet: www.stenaline.co.uk +{{% /dialog %}} diff --git a/content/operator/stl/index.fr.md b/content/operator/stl/index.fr.md index 27e0e5ef..4259b35d 100644 --- a/content/operator/stl/index.fr.md +++ b/content/operator/stl/index.fr.md @@ -184,4 +184,40 @@ Stena Line offre une excellente possibilité d’arriver à Londres avant 10h si [^3]: [Site Web Stena Line](https://www.stenaline.de/routen/hoek-van-holland-harwich) -[^4]: [Demande par e-mail de l’équipe FIP Guide à Stena Line](https://github.com/fipguide/fipguide.github.io/issues/528) +[^4]: [Demande par e-mail de l’équipe FIP Guide à Stena Line](dialog:stena-line-email) + +{{% dialog + id="stena-line-email" + title="Demande par e-mail de l’équipe FIP Guide à Stena Line" +%}} + +# RE: Vielen Dank für Ihre E-Mail - CASE:172468 + +**De :** Stena Line UK contact.uk.info@stenaline.com \ +**À :** Robert Schuster nextstop@fipguide.org \ +**Date :** lun. 1 déc. 2025, 10:59 + +Hello, + +Thank you for contacting us. + +Concessions bookings can be made by phone or on the day of travel, subject to availability. + +The cost of the booking depends on the type of concessions pass you hold. Generally, the overnight sailing is more expensive than the daytime crossing, as the fare for the overnight journey is higher and cabins are mandatory. + +The concessions fare only provides a discount on the fare price; any additional extras are charged at full price and are not discounted. + +For more information or a travel quote, please contact [03447 7070 70](tel:03447707070), and a member of our team will be glad to assist you. + +Thank you + +Best regards + +Stacey + +Contact Centre agent + +Call: [03447 707070](tel:03447707070) (UK) [+353 1871 4711](tel:+35318714711) (IRL) + +Internet: www.stenaline.co.uk +{{% /dialog %}} diff --git a/i18n/de.yaml b/i18n/de.yaml index a2361e11..165bf5ea 100644 --- a/i18n/de.yaml +++ b/i18n/de.yaml @@ -39,6 +39,9 @@ country: many: Länder one: Land other: Länder +dialog: + close: Schließen + open: Öffnet Dialog discord: FIP Guide Community donation: Spenden editPage: Seite bearbeiten diff --git a/i18n/en.yaml b/i18n/en.yaml index 0064abea..a05a2510 100644 --- a/i18n/en.yaml +++ b/i18n/en.yaml @@ -38,6 +38,9 @@ country: many: countries one: country other: countries +dialog: + close: Close + open: Opens dialog discord: FIP Guide Community donation: Donate editPage: Edit page diff --git a/i18n/fr.yaml b/i18n/fr.yaml index e7d45673..12c0d752 100644 --- a/i18n/fr.yaml +++ b/i18n/fr.yaml @@ -39,6 +39,9 @@ country: one: pays other: pays countryselection: Choisir un pays +dialog: + close: Fermer + open: Ouvre le dialogue discord: Communauté FIP Guide donation: Donation editPage: Modifier la page diff --git a/layouts/partials/booking.html b/layouts/partials/booking.html index d28991f0..e59b5139 100644 --- a/layouts/partials/booking.html +++ b/layouts/partials/booking.html @@ -85,7 +85,6 @@ {{- $content := partial "increase-headings" (dict "content" .page.Content "offset" 2) -}} {{- $content := partial "prefix-footnotes" (dict "content" $content "prefix" .page.File.ContentBaseName) -}} {{- $content := partial "prefix-heading-ids" (dict "content" $content "prefix" .page.File.ContentBaseName) -}} - {{- $content := partial "remove-newlines" $content -}} {{- $content | safeHTML -}} diff --git a/layouts/partials/button.html b/layouts/partials/button.html index 647ca8d7..0c781999 100644 --- a/layouts/partials/button.html +++ b/layouts/partials/button.html @@ -1,8 +1,17 @@ - - {{- .Text -}}{{- partial "icon" "arrow_outward" -}} - +{{ if .Destination }} + + {{- .Text -}}{{- partial "icon" "arrow_outward" -}} + +{{ else }} + + {{- .Text -}} + +{{ end }} diff --git a/layouts/partials/dialog.html b/layouts/partials/dialog.html new file mode 100644 index 00000000..2ad259d5 --- /dev/null +++ b/layouts/partials/dialog.html @@ -0,0 +1,15 @@ + + + + {{ .Title }} + {{- partial "button" (dict "Text" (partial "icon" "close") "Title" (i18n "dialog.close")) -}} + + + {{- partial "increase-headings" (dict "content" .Content) | safeHTML -}} + + + diff --git a/layouts/partials/link.html b/layouts/partials/link.html index 841a93ab..767e9f31 100644 --- a/layouts/partials/link.html +++ b/layouts/partials/link.html @@ -1,6 +1,6 @@ {{- $url := .Destination -}} {{- if and (strings.HasPrefix $url "http") (not (strings.HasPrefix $url site.BaseURL)) -}} - {{- /* Absolute links pointing to external pages, e. g. `https://example.com` */ -}} + {{- /* Absolute links pointing to external pages, e.g. `https://example.com` */ -}} {{- .Text -}}{{- partial "icon" "arrow_outward" -}} +{{- else if strings.HasPrefix $url "dialog:" -}} + {{- /* Dialog triggers, e.g. `dialog:test` */ -}} + + {{- .Text -}}{{- partial "icon" "open_in_browser" -}} + {{- else if strings.HasPrefix $url "mailto:" -}} - {{- /* Email links, e. g. `mailto:example@example.com` */ -}} + {{- /* Email links, e.g. `mailto:example@example.com` */ -}} {{- else if strings.HasPrefix $url "tel:" -}} - {{- /* Telephone links, e. g. `tel:+1234567890` */ -}} + {{- /* Telephone links, e.g. `tel:+1234567890` */ -}} {{- else if .Page.Ref (dict "path" $url) -}} - {{- /* Internal links, referenced by path (e. g. `/news/1`) */ -}} + {{- /* Internal links, referenced by path (e.g. `/news/1`) */ -}} {{- else if or (strings.HasPrefix $url "/") (strings.HasPrefix $url site.BaseURL) -}} - {{- /* Internal links, referenced by URL (e. g. `/en/news/1`) */ -}} + {{- /* Internal links, referenced by URL (e.g. `/en/news/1`) */ -}}