.visuallyhidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.language-switch li::after {
    content: "\00a0|\00a0";
}

.language-switch li:last-child::after {
    content: "";
}


.image-fullwidth video {
    display: block;
    width: 100%
}

.text-image video, .text-image iframe{
    display: block;
    width: 100%;
    min-height: 250px;
    margin-bottom: 5px;
}
.tx-indexedsearch-redMarkup {
    color: #de4e13;
    font-weight: 100 !important;
    font-family: Roboto-Light, sans-serif;
}

.locations-wrapper .locations {
    position: relative;
}

.uc-embedding-more-info {
    border-radius: 0;
}

.uc-embedding-accept {
    border-radius: 0;
    background: #de4e13;
}

.uc-embedding-container {
    background: var(--rd-bgcolor-1);
    margin-bottom: 50px;
}

header .page-width .logo img {height: auto;}

/* Single-item teaser-slider centering (e.g. Ship Detail's "Unsere Schiffe"/"Our ships"): both
   ryze_basetemplate's own teaser-slider Content Block and ryze_ships' Ship/Show.html wrap the
   slide's <a> AROUND its .size-wrapper (<a><div class="size-wrapper">...), the opposite of the
   nesting each site's own style.css's ".teaser-slider--single-image .faux-active .size-wrapper"
   centering rule assumes (it centers .size-wrapper's own inline content, which does nothing when
   .size-wrapper has no such content of its own). The anchor itself is already the thing that
   needs centering here, and its own direct parent is the glide__slide section carrying
   "faux-active" (added by teaser-slider.js when there is exactly one slide) — center that
   instead, matching live's actual behaviour (verified against meyerwerft.de's own
   silver_nova.jsp, 2026-07-31). */
.teaser-slider.teaser-slider--single-image .glide__track .faux-active {
    text-align: center;
}

/* text-align is inherited, so the rule above also recentres the slide's own caption
   (.text, e.g. "Silver Ray"), which live keeps left-aligned — reset it back explicitly. */
.teaser-slider.teaser-slider--single-image .glide__track .faux-active .text,
.teaser-slider.teaser-slider--single-image .glide__track .faux-active .subtext {
    text-align: left;
}

/* Ship List thumbnail (#ship-search .ships .ship a img, ryze_ships' Ship/Search.html): live's own
   CSS (Sites/MeyerWerft/style.css, kept in sync with meyerwerft.de's own stylesheet verbatim — do
   not edit) only ever sets max-width here and lets the image's own native aspect ratio determine
   the rendered height, because live's own backend serves a DIFFERENT, separately pre-cropped image
   per breakpoint (640x500 below 1020px, 304x217 at/above it), each already sized so plain
   max-width scaling lands on the right proportions with no cropping needed. ryze_ships' own
   `list_image` field is deliberately a single image (see docs/DECISIONS.md), sourced from the
   640x500 crop — correct as-is at the mobile breakpoint (identical file to live's own, untouched
   here), but taller/narrower than live's own 304x217 image once shown at the desktop breakpoint's
   width, unless re-cropped here. `width` (not just `max-width`) must be set explicitly alongside
   `height` — an <img> with only `height` specified and `width: auto` has its box width computed
   from that height times the image's own intrinsic ratio, not from `max-width`, so without an
   explicit `width` here the box renders narrower than 13.9375rem regardless of `object-fit`.
   The extra leading `body` (rather than repeating just `#ship-search .ships .ship a img`) bumps
   specificity above style.css's own same-selector rule — needed because, despite custom.css's own
   TypoScript key (903) being numerically higher than style.css's (902) in
   Configuration/Sets/MeyerWerft/setup.typoscript, custom.css is actually rendered into <head>
   BEFORE Sites/MeyerWerft/style.css (verified in the served page's own <link> order), so on equal
   specificity style.css's later rule would otherwise win the cascade and silently no-op this. */
@media (min-width: 1020px) {
    body #ship-search .ships .ship a img {
        width: 13.9375rem;
        height: 9.9488rem;
        object-fit: cover;
    }
}

/* Pressearchiv teaser text (Resources/Private/Extensions/News/Partials/List/Item.html): live's
   own markup is a bare `<p class="text">` (a direct flex child of `.press-teaser a`), styled by
   Sites/MeyerWerft/style.css's own `.press-teaser .text` rule (flex: 1 1 auto; margin: 0 0 14px;
   do not edit). Ours renders `<div class="text"><p>...</p></div>` instead: `f:format.html()` runs
   the news item's plain-text teaser through TYPO3's own RTE parseFunc, which always wraps a bare
   text block in a `<p>` - so the "text" class ends up on the outer div while the actual copy sits
   in a browser-default-margined `<p>` nested inside it. `.press-teaser .text` still matches (class
   selector, tag-agnostic) and still sizes the *div* correctly as the flex item, but the nested
   `<p>`'s own default user-agent margin (~1em top/bottom) adds extra vertical space inside that
   div which live's flat, single-element markup never has. Zero it out so the div's own explicit
   margin is the only spacing in effect, matching live's rendered layout exactly. */
.press-teaser .text p {
    margin: 0;
}

/* Press Detail breadcrumb ONLY (News/BreadcrumbViewHelper.php + shared Templates/Partials/
   Breadcrumb.html, wrapped in Detail.html's own `.news-detail-breadcrumb` div specifically so this
   rule can be scoped to just this one rendering path): live's own raw markup always has literal
   whitespace (newlines/tabs) between its <li> elements, which is what lets the trailing space in
   Sites/MeyerWerft/style.css's own `nav.breadcrumb ul li:after { content: " › "; }` render as a
   visible gap before the next <li>'s text - `display: inline-block` siblings only get that
   trailing-space rendering treatment when there is *some* whitespace/character at the box boundary
   in the source. This project's own News Fluid output has zero inter-tag whitespace (every News
   template in this project is written compact, and Extbase's own TemplateView renders it exactly
   as authored, unlike the page-level PAGEVIEW/dataProcessing-driven breadcrumb, which keeps the
   partial's natural indentation) - so the same " › " content rendered zero visible gap after the
   arrow ("Presse ›Presse Detail", verified via a rendered screenshot against live's own, which
   shows "Presse › Presse Detail"). Overridden here with non-breaking spaces (\00a0), which are
   never subject to that collapsing behavior regardless of surrounding markup whitespace.
   Deliberately scoped to `.news-detail-breadcrumb` rather than a sitewide `nav.breadcrumb` - an
   earlier version of this rule had no such scope and applied everywhere, which DOUBLED the gap on
   every other page's breadcrumb (e.g. the Pressearchiv list page, still page-level-rendered with
   its own natural whitespace already providing a correct single gap) - the non-breaking spaces
   added their own fixed gap on top of the whitespace-based gap that was already correct there,
   reported by the user as "our breadcrumb have more space" (see docs/DECISIONS.md). The extra
   class ancestor here already gives this selector more specificity than style.css's own bare
   `nav.breadcrumb ul li:after`, so no `body`-prefix/cascade-order trick is needed this time. */
.news-detail-breadcrumb nav.breadcrumb ul li:after {
    content: "\00a0›\00a0";
}

/* Press Detail media lightbox arrow centering (#press-media-overlay, News/Detail.html): live's own
   per-site style.css (Css/Sites/<Site>/style.css) positions `.glide--controls` (the prev/next
   arrow wrapper) at a fixed `top: 40%` of `.glide`'s own rendered height (image + caption row
   combined) - do not edit that
   file. That 40% was whatever landed on the image's own vertical center for live's own overlay
   images, which (verified via their actual rendered/natural size, not their misleading
   "_752x414"-suffixed filename) come out at a live-side-inconsistent aspect per photo - anywhere
   from roughly square to ~1.48:1, driven entirely by whichever of a given article's photos happens
   to need the least "contain"-fit scaling, not a deliberate design. Our own overlay image
   (News/Detail.html's `data-overlay-image`) is instead cropped to a single fixed `752c`x`533c`
   aspect - same ratio as the already-correct 480:340 thumbnail crop, just larger, chosen because a
   literal 752x414 crop-to-exact-size cut off the subject's own head and torso on portrait photos
   (see docs/PROJECT-STATE.md, 2026-08-17) - so every one of our own slides renders at the exact
   same height, unlike live's own carousel (confirmed: one outlier photo, closer to a square aspect,
   stretches live's ENTIRE carousel height to match it, since Glide's flex-row slide track sizes to
   its tallest child regardless of which slide is active - not something to replicate here, since
   our own uniform crop means there's no tallest-outlier slide to size against in the first place).
   With our own taller/differently-proportioned image, live's 40% now lands visibly above our own
   image's actual vertical center (reported by the user as the arrows sitting "a little upper").
   Recalculated for our own fixed image aspect: the image always starts exactly at `.glide`'s own
   top (confirmed via measurement - the image is the first thing in each slide), so the image's own
   vertical center as a fraction of the full `.glide` height (image + margin + caption row) is
   (533 / 752 rendered width-relative height) ÷ 2, over that same height plus the caption row -
   measured directly against our own rendered layout at 43.8%, replacing live's 40%. The extra
   leading `body` bumps specificity above style.css's own same-selector rule - needed because,
   despite custom.css's own TypoScript key being numerically higher than style.css's in
   Configuration/Sets/MeyerWerft/setup.typoscript, custom.css is actually rendered into <head>
   BEFORE Sites/MeyerWerft/style.css (verified in the served page's own <link> order, same
   cascade-order quirk documented above for `#ship-search .ships .ship a img`), so on equal
   specificity style.css's later rule would otherwise win and silently no-op this. */
body #press-media-overlay .glide .glide--controls {
    top: 43.8%;
}


/* Image-Slider: `.image-slider .sections section picture` in Sites/<Site>/style.css pins a fixed
   height (396px from 1020px, 520px from 1200px) with overflow: hidden, but the img in there only
   gets `display: block` — no height, no object-fit. So the delivered file's own height leaks into
   the layout: whenever it is not exactly the pinned value, a gap opens below the image while the
   absolutely positioned `.text` overlay stays glued to the box's bottom: 0.
   That happens as soon as an editor crops with an enforced aspect ratio, because the crop wizard
   never snaps to the mathematically exact full frame — it insets the frame by one or two pixels
   (stored cropArea width 0.996 instead of 1.0), which turns a 1022x520 original into 1018x518 and
   leaves a 2px gap. Choosing a "better" ratio value cannot fix that; the box has to win instead.
   `.stage .sections section picture img` and `.press-media-pool .medium picture img` already do
   exactly this — the slider was the only image wrapper missing the guard.
   The leading `body` is needed because custom.css is rendered into <head> BEFORE
   Sites/<Site>/style.css despite its higher TypoScript key (see the ship-search note above), so on
   equal specificity the site bundle would win. */
body .image-slider .sections section picture img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Accordion item image: the image column is `cell col-md-5 col-lg-4` inside the accordion's inner
   `text-image page-width--md` container, and nothing in Sites/<Site>/style.css styles that image.
   With only the global `img { max-width: 100% }` it therefore rendered at its intrinsic size, so
   its width depended on the aspect ratio: the originals are pre-cut to 270x190, and a 1:1 crop of
   one is 166x166, which then sat at 166px in a ~313px column. The image should fill the column
   regardless of the ratio, with the height following from it. */
.accordion-wrapper .text-image picture,
.accordion-wrapper .text-image picture img {
    display: block;
    width: 100%;
    height: auto;
}

/* CTA teaser / CTA text-image: the image gets `class="logo"` although it is a normal content image,
   and `.contact-teaser .logo` in Sites/<Site>/style.css pins a fixed width (313px, 225px from
   1020px, 223px from 1200px). In the .section-left / .section-right columns of the cta-teaser those
   are only about 67 / 60 / 45 percent of the available width, so the image never filled its column
   and its rendered size depended on the aspect ratio. It should use the full column width, with the
   height following from the ratio; the margins from the site bundle stay untouched.
   Leading `body` for the same load-order reason as the rules above. */
body .contact-teaser .logo {
    width: 100%;
    height: auto;
}

/* CTA teaser, mirrored variant (display_layout = content_right): flex-row-reverse only flips the
   visual order, it does not mirror the asymmetric column paddings. In the default order the gutter
   between the two columns comes from `.contact-teaser .section-right { padding-left }` — 90px from
   1020px, 53px from 1200px — plus a 6px padding-right on .section-left from 1200px. Reversed, that
   left padding would sit against the outer page edge and the gap between the columns would vanish,
   so both are swapped for this row only. Leading `body` because custom.css is rendered into <head>
   BEFORE Sites/<Site>/style.css despite its higher TypoScript key. */
@media (min-width: 1020px) {
    body .contact-teaser .row.flex-row-reverse .section-right {
        padding-left: 0;
        padding-right: 90px;
    }
}

@media (min-width: 1200px) {
    body .contact-teaser .row.flex-row-reverse .section-right {
        padding-right: 53px;
    }

    body .contact-teaser .row.flex-row-reverse .section-left {
        padding-right: 0;
        padding-left: 6px;
    }
}

/* Quote teaser: the image field now also accepts a video (mp4/YouTube/Vimeo), rendered via
   f:media as a <video> or <iframe> instead of the <picture> markup. The image never gets a CSS
   width - Sites/<Site>/style.css's `.quotes .sections section img` only sets `max-width: 100%`,
   so the <picture>'s rendered size is just whatever the delivered, already-cropped file's own
   pixel dimensions are (480x480/292x292/460x460 per the same breakpoints as below). A first
   version of this rule set `width: 100%` on the video/iframe, which stretched it to fill the
   full ~569px column instead of matching that same fixed size, making it visibly larger than
   the image (reported by the user, 2026-09-07). Pinning the same explicit widths here instead
   keeps image and video identically sized regardless of which one an editor picks.
   `display: inline-block` (not `block`) for the same reason the img rule below uses it: on the
   "image-right" variant (image_alignment: right), `.quotes .sections section.image-right > .row
   .image-cell` sets `text-align: right` so the image hugs the inner edge next to the text
   column instead of the outer edge - that only affects inline-level boxes, so `display: block`
   made the video/iframe ignore it and sit flush left instead, opening a large, wrong gap
   between it and the quote text on that variant (reported by the user, 2026-09-07). */
.quotes .sections section .image-cell video,
.quotes .sections section .image-cell iframe {
    display: inline-block;
    width: 480px;
    max-width: 100%;
    aspect-ratio: 1 / 1;
    border: 0;
}

.quotes .sections section .image-cell video {
    object-fit: cover;
}

@media (min-width: 1020px) {
    .quotes .sections section .image-cell video,
    .quotes .sections section .image-cell iframe {
        width: 292px;
        margin: 5rem 0 0;
    }
}

@media (min-width: 1200px) {
    .quotes .sections section .image-cell video,
    .quotes .sections section .image-cell iframe {
        width: 460px;
        margin: 0;
    }
}

/* Quote teaser, YouTube/Vimeo before consent: Usercentrics swaps the iframe for its own
   `.uc-embedding-container` placeholder (poster image + "Akzeptieren" prompt) BEFORE this
   stylesheet or the iframe rule above ever applies to it, and sizes that placeholder off the
   original iframe's own width/height HTML attributes (TYPO3's YouTube/Vimeo renderer default,
   ~284x320) rather than our square crop size - so pre-consent it rendered far smaller than the
   460x460/292x292/480x480 box the image and the (accepted) video use, with its own message text
   overflowing into an internal scrollbar (reported by the user, 2026-09-07). Same width/aspect
   rule as the video/iframe above, so consent-accepted and consent-pending look identically
   sized. */
body .quotes .sections section .image-cell .uc-embedding-container {
    display: inline-block;
    width: 480px;
    max-width: 100%;
    height: 480px;
    max-height: none;
}

@media (min-width: 1020px) {
    body .quotes .sections section .image-cell .uc-embedding-container {
        width: 292px;
        height: 292px;
        margin: 5rem 0 0;
    }
}

@media (min-width: 1200px) {
    body .quotes .sections section .image-cell .uc-embedding-container {
        width: 460px;
        height: 460px;
        margin: 0;
    }
}

/* Teaser-slider subline (.subtext, e.g. a ship's cruise line under its name). Each site's own
   style.css already styles this element for the landscape layout
   (".teaser-slider--dynamic-height .subtext" plus its larger ".faux-active" variant) - it was
   simply never rendered by any template until the teaser-slider gained its ship reference, so
   that layout needs nothing here. Only the portrait ("--fixed-height") layout has no rule: there
   .text is position:absolute over the image, so the subline is nested INSIDE it (see the
   teaser-slider's frontend.html) and only needs its own size and the same Roboto-Black treatment
   the landscape .subtext gets from style.css. Colour is inherited from .text on purpose (white
   over the image). */
.teaser-slider.teaser-slider--fixed-height .text .subtext {
    display: block;
    font-family: Roboto-Black, sans-serif;
    font-weight: var(--font-weight-normal);
    font-size: 1.125rem;
    line-height: 1.5rem;
}

/* Single-column text-image rows: `cell` carries no styling of its own, it only anchors the
   column gutters in every Sites/<Site>/style.css (".text-image .cell:first-child" sets
   padding-right, ":last-child" sets padding-left). With just one column in the row that div is
   first AND last child, so both rules hit it and it ends up indented by 30px on both sides -
   which the reference site never did, because it only emitted `cell` for the two-column layouts.
   The templates now follow that (text-image v5, image-less accordion items), and this rule keeps
   any future single-column variant from re-introducing the indent. 6px is the gutter the grid
   itself gives every ".col*" in Sites/<Site>/style.css, so this restores exactly what a plain
   column would have. The two-column-text layout stays untouched on purpose:
   ".text-image .cell.auto-col:first-child" is more specific and keeps its own 6px, matching the
   reference site. */
.text-image .cell:only-child {
    padding-left: 6px;
    padding-right: 6px;
}
