/*
Design tokens and values below come from the OLD BY site (its live computed styles and main.css): a visual rebuild
with clean markup and CSS, not a copy of the old templates.

--by-primary/--by-dark/--by-dark-2/--by-muted/--by-green are the brand colours:
- --by-primary: buttons, logo, links, hover accents
- --by-dark/--by-dark-2: two-tone footer (old site's .footer--dark .footer__top/.footer__bottom)
- --by-muted: secondary text on light backgrounds, default (non-hover) nav links
- --by-muted-on-dark: the same on the dark footer and newsletter band

Contrast (owner, 2026-09-26, WCAG AA = at least 4.5:1 for text): the old site's grey #767e94 reached only 3.8-4.0 on
white and the light surface and 3.0-4.0 on the dark footer. One grey cannot pass on both, so there are two:
--by-muted #687087 (white 4.93, --by-surface 4.60) and --by-muted-on-dark #a0a7b9 (--by-dark 6.79, --by-dark-2 5.14).
The blog comment date (#939aad, 2.8 on white) uses --by-muted now. --by-icon-muted stays: icons only.
- --by-green: the homepage's boat-count CTA pills (.hero-pill)
*/

@font-face {
    font-family: 'Nunito';
    src: url('../fonts/nunito/nunito-regular.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Nunito';
    src: url('../fonts/nunito/nunito-600.woff2') format('woff2');
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Nunito Sans';
    src: url('../fonts/nunito-sans/nunito-sans-regular.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Nunito Sans';
    src: url('../fonts/nunito-sans/nunito-sans-600.woff2') format('woff2');
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Nunito Sans';
    src: url('../fonts/nunito-sans/nunito-sans-700.woff2') format('woff2');
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

:root {
    --by-primary: #1d8dc6;

    /* Bootstrap's blue -> this colour, see shared/css/base.css. */
    --brand-primary: var(--by-primary);
    --brand-primary-rgb: 29, 141, 198;
    --brand-primary-hover: #1877a3;
    --by-dark: #191f33;
    --by-dark-2: #2e3447;
    --by-muted: #687087;
    --by-muted-on-dark: #a0a7b9;
    --by-icon-muted: #939aad;
    --by-green: #27c200;
    --by-red: #ff4f4f;

    /* The bar's height - a result, not a setting: .site-header's own padding
    and logo size below produce it. It exists so that everything which has to
    dodge the fixed bar (body offset, anchor targets, the sticky contact card
    on the detail page) reads one number instead of guessing. Change the
    padding or the logo there and change this with it.

    The height never changes while scrolling: shrinking the bar would save
    only ~20px (about 2% of a desktop window) and pay for it with movement in
    the corner of the eye and nav links that wander out from under the cursor.
    The shadow that .is-scrolled adds already says "this is stuck now". */
    --by-header-h: 82px;

    /* Consumed by shared/css/boat-detail.css, which is loaded by every site
    group but only BY has a fixed header to dodge - it falls back to 0px
    where this is not set. */
    --sticky-header-offset: var(--by-header-h);

    /* Values written many times below: light grey surface (site header, list cards, search bars, contact card), secondary
    text of form labels and list meta, hairline dividers, light blue tint of the home tiles. */
    --by-surface: #f5f7fa;
    --by-text-2: #636a80;
    --by-line: #ebeef7;
    --by-tint: #e8f7ff;

    /* The soft shadow a card gets under the mouse (boat list, blog list, the homepage's tiles). */
    --by-card-shadow: 0 12px 80px rgba(0, 26, 102, .1);

    /* Corner rounding of BY's own boxes: the 12px every group gets through --bs-border-radius (shared/css/base.css). */
    --by-radius: var(--bs-border-radius);
}

/* The page background is white, not the shared light grey: on the old site the body is white and only .site-header
below carries the light grey. */
body {
    background-color: #fff;
    font-family: 'Nunito', sans-serif;
}

/* The scrollbar is always shown (empty on a page that fits the window): a page short enough to fit (the expert request
on a tall screen) had none, was 15px wider and moved logo, menu and heading to the right compared with a longer page
(Carsten, 2026-10-29). Not scrollbar-gutter: stable, which keeps the room free but leaves a white strip beside the grey
header and the dark footer there. */
html {
    overflow-y: scroll;
}

/* 600, not 700: most of the old site's content headings are 600; its hero H1 and CTA buttons are genuinely 700 and keep
their own, more specific overrides. The .h1-.h6 classes are listed too: Bootstrap gives them weight 500, which
Nunito Sans (it has 400, 600 and 700) renders as 400, so a heading written as h1 class="h3" would look lighter than a plain one. */
h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
    font-family: 'Nunito Sans', sans-serif;
    font-weight: 600;
}

.btn-primary {
    font-weight: 700;
}

/* Header - light/solid variant, used on every page but the homepage, which
has its own transparent-over-photo treatment (.site-header-transparent below;
the old site switches header style per page, header--home-three vs. a plain
light header). Light grey #f5f7fa, the value also used for .list-search-bar,
.boat-list-card etc. below. */
/* Bar height matches the old BY site: 20px padding above and below a 32px
logo (.header--four; its homepage variant .header--three uses 19px - close
enough that one rule covers both). That lands at 82px, not the old site's
88px: its right-hand side carries a real button, ours only icons, so nothing
there outgrows the logo. Bootstrap's .navbar brings its own 8px padding-y that
the old markup has no equivalent for; left at the default it silently adds
16px to the bar on every page, so it goes to 0 here. */
.site-header {
    position: fixed;
    top: 0;
    right: 0;
    left: 0;
    z-index: 1030;
    background-color: var(--by-surface);
    box-shadow: 0 1px 0 0 var(--by-line);
    padding: 20px 0;
    transition: transform 0.25s ease, background-color 0.2s ease, box-shadow 0.2s ease;
}

/* The bar is out of the flow, so the page has to make room for it itself -
the old BY site does the same thing (.no-breadcrumbs { padding-top: 88px }).
The homepage is the exception: its header floats over the hero photo, which
starts at the very top, so it must NOT be pushed down (by/layouts/app.blade.
php puts .has-transparent-header on <body> for exactly this one case). */
body:not(.has-transparent-header) {
    padding-top: var(--by-header-h);
}

/* Anchor targets have to clear the bar as well, otherwise a jump lands with
the heading hidden underneath it. */
html {
    scroll-padding-top: calc(var(--by-header-h) + 1rem);
}

/* Phone: 9px to the screen's edge instead of Bootstrap's 12px (half of its 1.5rem gutter), so the content gets the
width (owner, 2026-10-15). The rows' gutter shrinks with it - a row reaches half its gutter beyond the container's
padding, a bigger one would stick out of the screen. Rows with a deliberately small gutter (g-0 to g-2, e.g. the
homepage's boat type boxes) keep theirs.
The basic text on a phone stays the browser's 16px, as on most big sites (owner, 2026-10-15, after comparing them; an
18px basic size was tried for a day). Single texts are bigger where reading or legibility asks for it (blog cards,
homepage tiles, hero search), each in its own rule below. */
@media (max-width: 575.98px) {
    .container,
    .container-fluid,
    .row:not(.g-0):not(.g-1):not(.g-2):not(.gx-0):not(.gx-1):not(.gx-2) {
        --bs-gutter-x: 1.125rem;
    }
}

.site-header .navbar {
    --bs-navbar-padding-y: 0;
}

.site-header .site-logo img {
    height: 32px;
}

/* Phone: the wordmark (303px at 32px height) left no room for the burger button, which dropped into a second line
(owner, 2026-10-14). At most 280px (owner, 2026-10-15: 243px was smaller than needed), and never wider than what the
button leaves (its 3.375rem plus border and the logo's own 1rem margin), so even a bigger text size set in the browser
keeps the button beside it. */
@media (max-width: 767.98px) {
    .site-header .site-logo {
        max-width: calc(100% - 4.75rem);
    }

    .site-header .site-logo img {
        width: 100%;
        max-width: 280px;
        height: auto;
    }
}

/* nav-item spacing (40px margin) and link weight (400) match the old site. */
.site-header .navbar-nav .nav-item {
    margin-right: 40px;
}

/* Below Bootstrap's xxl container (1320px) those 40px stop fitting: the menu
wrapped to two lines between roughly 1200 and 1400px, which pushed the bar
from 88px to 130px on exactly the laptop widths most visitors use (1366px).
The old site does the same thing at the same point (.header--four .menu__item
goes to 8px below 1200px). nowrap is the actual guarantee - a translated label
longer than the German one must shorten the gaps, never grow the bar. */
.site-header .navbar-nav .nav-link {
    white-space: nowrap;
}

@media (max-width: 1399.98px) {
    .site-header .navbar-nav .nav-item {
        margin-right: 16px;
    }
}

/* Below 1200px the menu is the burger panel (navbar-expand-xl in by/layouts/app.blade.php): between 992 and 1200px
the entries, the icons and the logo did not fit into one line (the language flag ran out of the bar, in French
"Service" too). In the open panel the entries stand below each other, so their right margin means nothing there. */
@media (max-width: 1199.98px) {
    .site-header .navbar-nav .nav-item {
        margin-right: 0;
    }

    .site-header .navbar-collapse {
        padding: .75rem 0 .25rem;
    }
}

/* Phone: the entries of the open menu bigger than the 16px text - 19px, the entries of its lists (Service, watchlist,
account) 18px (owner, 2026-10-15). */
@media (max-width: 767.98px) {
    .site-header .navbar-collapse .nav-link {
        font-size: 1.1875rem;
    }

    .site-header .navbar-collapse .dropdown-item {
        font-size: 1.125rem;
    }

    /* The icons (account, watchlist, language) stood right below the last entry, "Service". */
    .site-header .nav-icons {
        margin-top: 1rem;
    }
}

/* More room between the logo and the first menu entry than Bootstrap's 1rem, less on the laptop widths where the
entries are already packed (see above). */
@media (min-width: 1200px) {
    .site-header .site-logo {
        margin-right: 32px;
    }
}

@media (min-width: 1400px) {
    .site-header .site-logo {
        margin-right: 56px;
    }
}

.site-header .nav-link {
    color: var(--by-muted);
    font-weight: 400;
}

/* An entry under the mouse, an open one (Bootstrap's .show after a click; .dropdown:hover while its list stands open
under the mouse) and the current one (.active: "Boot kaufen" on a sale list, "Yachtcharter" on a charter list) are
the dark text colour, not the brand blue (owner, 2026-10-05). Over the homepage's photo they are white, see
.site-header-transparent below. */
.site-header .nav-link:hover,
.site-header .nav-link.active,
.site-header .nav-link.show,
.site-header .dropdown:hover > .nav-link {
    color: var(--by-dark);
}

/* An entry of a list (the lists of "Service", account, watchlist, language) under the mouse or the keyboard focus: a
light tint of the brand colour behind it, text and icon in the brand colour (the icon takes the text's colour). */
.site-header .dropdown-menu {
    --bs-dropdown-link-hover-bg: rgba(var(--brand-primary-rgb), .1);
    --bs-dropdown-link-hover-color: var(--brand-primary);
}

.site-header .nav-icon-link {
    color: var(--by-muted);
    font-size: 1.15rem;
    line-height: 1;
}

.site-header .nav-icon-link:hover,
.site-header .nav-icon-link.show,
.site-header .dropdown:hover > .nav-icon-link {
    color: var(--by-dark);
}

/* The two scroll states, both set by by/js/header-scroll.js. .is-scrolled
only means "not at the top of the page any more" - it adds the shadow, and
the solid background on the homepage variant below. .is-hidden answers the
objection that a bar which follows you costs vertical space (on a phone about
a tenth): below lg the whole bar gets out of the way while scrolling down and
comes back on the smallest upward move, which returns all 82px rather than a
fraction of them.

Desktop keeps the bar at its full height instead - see --by-header-h above
for why shrinking it was dropped. */
.site-header.is-scrolled {
    box-shadow: 0 2px 12px 0 #001a6614;
}

@media (max-width: 991.98px) {
    .site-header.is-hidden {
        transform: translateY(-100%);
    }
}

@media (prefers-reduced-motion: reduce) {
    .site-header {
        transition: none;
    }
}

/* Homepage-only hero variant (by/home/index.blade.php sets the
transparentHeader section, see by/layouts/app.blade.php) - the header floats
transparently over the hero photo instead of its own light bar (old site:
header--home-three). It is fixed like every other page's header; what changes
is that it has to earn its own background the moment it stops sitting on the
photo, which is what .is-scrolled does here.

No text colour override: on the old site's transparent-header homepage the nav
text is the SAME muted gray as on the solid header (rgb(118,126,148) ==
--by-muted), not white. The .site-header .nav-link/.nav-icon-link rules above
already apply here; only the logo swaps to its white variant, since that is an
image, not colourable text. */
.site-header-transparent {
    background-color: transparent;
    box-shadow: none;
}

.site-header-transparent.is-scrolled {
    background-color: var(--by-surface);
}

/* Logo swap for that variant. Both files are in the markup (by/layouts/app.
blade.php) rather than one src being rewritten at runtime - a swap in JS
would show the wrong wordmark for as long as the new file takes to load,
right at the moment the visitor is looking at it. */
.site-header .site-logo-light {
    display: none;
}

.site-header-transparent:not(.is-scrolled) .site-logo-light {
    display: inline;
}

.site-header-transparent:not(.is-scrolled) .site-logo-dark {
    display: none;
}

/* While the header floats over the photo, the dark colour of an entry under the mouse or an open one would vanish
in it: white there. Not with the burger panel open - that one has the solid bar's light background (below). */
.site-header-transparent:not(.is-scrolled):not(:has(.navbar-toggler[aria-expanded="true"])) :is(
    .nav-link:hover,
    .nav-link.active,
    .nav-link.show,
    .dropdown:hover > .nav-link,
    .nav-icon-link:hover,
    .nav-icon-link.show,
    .dropdown:hover > .nav-icon-link
) {
    color: #fff;
}

/* The three lines of the burger button are the brand colour - white only while the header floats over the
homepage's photo (owner, 2026-10-13; the last rule below). Drawn as a mask over a coloured box, not as Bootstrap's
picture with a fixed colour in it, so they follow --brand-primary. */
.site-header .navbar-toggler-icon {
    background-color: var(--brand-primary);
    background-image: none;
    -webkit-mask: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23000' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") center / 100% no-repeat;
    mask: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23000' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") center / 100% no-repeat;
}

/* Not with the panel open: the header is the solid bar then (below), and white would vanish on it. */
.site-header-transparent:not(.is-scrolled) .navbar-toggler[aria-expanded="false"] .navbar-toggler-icon {
    background-color: #fff;
}

/* The open burger panel needs a background of its own: its entries are the muted grey of the solid bar and cannot
be read on the photo. So an open menu turns the floating header into the solid one (bar, logo, button), exactly as
scrolling does. aria-expanded is set by Bootstrap at the click, before the panel unfolds. */
.site-header-transparent:has(.navbar-toggler[aria-expanded="true"]) {
    background-color: var(--by-surface);
    box-shadow: 0 2px 12px 0 #001a6614;
}

.site-header-transparent:has(.navbar-toggler[aria-expanded="true"]) .site-logo-light {
    display: none;
}

.site-header-transparent:has(.navbar-toggler[aria-expanded="true"]) .site-logo-dark {
    display: inline;
}

/* Hero (by/home/index.blade.php) - the old site's hero photo has NO dark
overlay at all (no ::before, no overlay div, just the photo).

Vertical layout as measured on the old site at 1280x720: a compact block, NOT
evenly spread via space-between - padding-top puts the pills at 259px from the
hero's own top (the transparent header overlays this, it doesn't push the hero
down), then just small gaps between pills/heading/form (28px, 65px - see
.hero-pills/h1 below), with the rest of the fixed 858px height left over as
visual bottom padding. */
.hero-section {
    position: relative;
    background: url('../images/hero-background.jpg') center/cover no-repeat;
    padding-top: 259px;
    min-height: 858px;
    color: #fff;
}

.hero-section h1 {
    color: #fff;
    font-weight: 700;
    font-size: 4.5rem;
    /* The heading has an explicit width, not the full one, so the German text wraps onto 2 lines right before
    "oder" ("Boote und Yachten kaufen" is 873px wide at this size; owner, 2026-10-13). 910px also keeps the French
    "à vendre" (903px) in the first line. Centered independently of the hero's own text-center so it doesn't
    just clip at the container edge on narrower viewports. */
    max-width: 910px;
    margin-left: auto;
    margin-right: auto;
    margin-bottom: 65px;
}

/* Tablet widths (the pills stand below each other, the heading takes three lines, the search form two rows): the
desktop's 259px above the pills left a hole under the header, and the taller content used up the fixed height, so
the form touched the lower edge of the photo. Here the height follows the content, with room above and below. */
@media (min-width: 768px) and (max-width: 991.98px) {
    .hero-section {
        min-height: 0;
        padding: 150px 0 5rem;
    }

    .hero-section h1 {
        font-size: 3.5rem;
        margin-bottom: 48px;
    }
}

@media (max-width: 767.98px) {
    .hero-section {
        min-height: 0;
        padding: 8rem 0 3rem;
    }

    .hero-section h1 {
        font-size: 2.25rem;
        max-width: 100%;
    }
}

/* Gap between the two pills - bigger than Bootstrap's gap-3 (1rem).
margin-bottom (pill-to-heading gap) matches the old site: 28px. */
.hero-pills {
    gap: 1.75rem;
    margin-bottom: 28px;
}

/* CTA pills ("25.493 Boote zu verkaufen" / "4.443 Charterboote") - bg/radius/
padding/font-weight/text-transform as the old site's .banner__tag (20px, 600,
uppercase). On the old site both pills are the same width (351px at desktop)
whatever their text length; reproduced with a shared min-width instead of that
exact px (stays correct if the hit count's digit count changes), 340px - a
touch narrower than the original. */
.hero-pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Never wider than the screen: with a bigger text size set on the phone the pill wraps instead of sticking out. */
    min-width: min(340px, 100%);
    max-width: 100%;
    background-color: var(--by-green);
    color: #fff;
    border-radius: var(--by-radius);
    padding: .6rem 1.25rem;
    font-weight: 600;
    font-size: 1.25rem;
    text-transform: uppercase;
    text-decoration: none;
}

.hero-pill:hover {
    color: #fff;
    opacity: .9;
}

/* Search bar (by/home/index.blade.php) - as on the old site: the outer bar is translucent DARK gray over the photo, each
field inside is its own translucent WHITE pill with an icon, spread out with space-between rather than a fixed gap.
The boat list's search bar (.list-search-*, further down) uses the same fields on a plain light section. */
.hero-search-card {
    background-color: rgba(116, 116, 116, .5);
    border-radius: var(--by-radius);
    padding: .8rem .75rem;
    display: flex;
    flex-wrap: wrap;
    gap: .75rem;
    justify-content: space-between;
}

.hero-search-field,
.list-search-field {
    position: relative;
    flex: 1 1 200px;
}

.hero-search-field i,
.list-search-field i {
    position: absolute;
    top: 50%;
    left: 1rem;
    transform: translateY(-50%);
    color: var(--by-primary);
    pointer-events: none;
}

.hero-search-field .form-control,
.hero-search-field .form-select,
.list-search-field .form-control,
.list-search-field .form-select {
    border: none;
    height: 54px;
    padding-left: 2.75rem;
}

/* Text colour is dark (the old site's select2-rendered field text is rgb(90,95,107), not white), also more legible
against a translucent white pill than white-on-near-white. */
.hero-search-field .form-control,
.hero-search-field .form-select {
    background-color: rgba(255, 255, 255, .5);
    color: #5a5f6b;
}

.hero-search-field .form-control::placeholder {
    color: #5a5f6b;
    opacity: .85;
}

/* Bootstrap's :focus state adds a blue border and a shadow ring; the old site's fields have none. The keyboard focus
still needs a mark (WCAG 2.4.7): a solid outline on :focus-visible, which a mouse click on a select does not trigger
(a text field shows it on a click too, like every browser's own fields). White over the homepage photo, the brand
colour elsewhere. */
.hero-search-field .form-control:focus,
.hero-search-field .form-select:focus,
.list-search-field .form-control:focus,
.list-search-field .form-select:focus {
    border-color: transparent;
    box-shadow: none;
}

.list-search-field .form-control:focus-visible,
.list-search-field .form-select:focus-visible {
    outline: 2px solid var(--brand-primary);
    outline-offset: 2px;
}

.hero-search-field .form-control:focus-visible,
.hero-search-field .form-select:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 2px;
}

.hero-search-submit,
.list-search-submit {
    height: 54px;
}

/* Phone (owner, 2026-10-14, after testing on a Pixel): a lighter gray behind the fields, the button as its own last row
across the whole width (left alone it ended up in a row of its own on the left in Firefox, beside the third field in
Chrome), and the text of fields and button a notch bigger. */
@media (max-width: 575.98px) {
    .hero-search-card {
        background-color: rgba(170, 170, 170, .4);
    }

    .hero-search-card > .flex-grow-0 {
        flex: 1 1 100%;
    }

    .hero-search-submit {
        width: 100%;
    }

    .hero-search-field .form-control,
    .hero-search-field .form-select,
    .hero-search-submit {
        font-size: 1.0625rem;
    }
}

/* Homepage section headings (Blog/Verkauf/Charter) - big, centered. The old
site uses a fixed 40px; clamp() scales that down on narrow viewports, still
reaching the full 40px from ~660px viewport width up. Weight 600, not 700, as
the old site's ".section__title". */
/* At most 2rem, 2.5rem before (Carsten, 2026-11-03: a little smaller); the headings of the link boxes further down
(<x-home-link-columns>) use the same class, above their boxes. */
.section-heading {
    font-size: clamp(1.5rem, 3vw, 2rem);
    font-weight: 600;
    text-align: center;
    color: var(--by-dark);
    margin-bottom: 1.5rem;
}

/* "See everything" link below a homepage section (Weitere Meldungen / Alle
Angebote anzeigen) - matches the old site's .recent-post__btn .btn (52px tall
via line-height, 12px radius, 700 weight), as its own class rather than a
.btn-primary with overrides. */
.btn-section-cta {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    background-color: var(--by-primary);
    color: #fff;
    font-size: 1rem;
    font-weight: 700;
    line-height: 52px;
    padding: 0 1.5rem;
    border-radius: var(--by-radius);
    text-decoration: none;
}

.btn-section-cta:hover {
    filter: brightness(0.92);
    color: #fff;
}

.btn-section-cta i {
    font-size: 1.25rem;
}

/* Per-boat-type icon row above the sale/charter featured sections
(<x-home-boat-type-counts>, capability 'homeBoatTypeCounts') - old site's
".category-card": a light-gray rounded card, brand-colour icon circle, the
hit count and the "Boote anzeigen" link stacked in a 24px-tall clipped
window that swaps one for the other on hover (its own .first/.second
transform, matching the old site exactly instead of just hiding one).
The hover effects of these cards, the homepage's tiles and blog cards and the list cards are inside
@media (hover: hover): a phone browser keeps :hover on whatever the finger touched last (Firefox for Android did, 2026-10-14: some tiles white, the others light blue). */
/* A column of flex: the cards of a row are equally high (the row stretches its columns), and the count line sits at the
bottom of each (.boat-type-count-view's margin-top: auto), so it stands at the same height beside a title of two lines
(owner, 2026-10-14: French). */
.boat-type-count-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    text-align: center;
    padding: 1.5rem;
    background-color: var(--by-surface);
    border-radius: var(--by-radius);
    text-decoration: none;
    transition: background-color .3s ease-in-out, box-shadow .3s ease-in-out;
}

@media (hover: hover) {
    .boat-type-count-card:hover {
        background-color: #fff;
        box-shadow: 0 12px 80px 0 rgba(0, 26, 102, .13);
    }
}

.boat-type-count-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 72px;
    height: 72px;
    margin: 0 auto .9375rem;
    border-radius: 50%;
    background-color: var(--by-primary);
    transition: filter .3s ease-in-out;
}

@media (hover: hover) {
    .boat-type-count-card:hover .boat-type-count-icon {
        filter: brightness(0.92);
    }
}

.boat-type-count-title {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--by-dark);
    margin-bottom: .625rem;
}

/* margin-top: auto puts the count at the bottom of the card (see .boat-type-count-card); the title's margin-bottom
gives the hover-revealed "Boote anzeigen" link (see the .first/.second transform below) more air below the title than
the default count line alone would need - both share this one box. */
.boat-type-count-view {
    display: flex;
    flex-direction: column;
    max-height: 1.5rem;
    margin-top: auto;
    overflow: hidden;
}

.boat-type-count-hits,
.boat-type-count-link {
    font-size: 1rem;
    line-height: 1.5rem;
    transition: transform .3s ease-in-out;
}

.boat-type-count-hits {
    color: var(--by-text-2);
}

.boat-type-count-link {
    color: var(--by-primary);
    font-weight: 600;
}

.boat-type-count-link i {
    font-size: .9rem;
}

@media (hover: hover) {
    .boat-type-count-card:hover .boat-type-count-hits,
    .boat-type-count-card:hover .boat-type-count-link {
        transform: translateY(-1.5625rem);
    }
}

/* Phone: two cards side by side (col-6). Less padding leaves the text more room, and a long word ("Schlauchboote" with
a bigger text size set on the phone) is hyphenated instead of sticking out of its card. */
@media (max-width: 575.98px) {
    .boat-type-count-card {
        padding: 1.25rem .25rem;
    }

    .boat-type-count-title {
        font-size: 1.125rem;
        hyphens: auto;
        overflow-wrap: break-word;
    }
}

/* Homepage featured tiles (by/home/card-sboat/card-cboat) - vertical (image on
top, text below), light-blue tint background, as the old site's "cards
cards--one cards--highlight" (bg rgb(232,247,255), 12px radius, 200px image
height, 16px/600 title+price, 14px muted category/location). Deliberately its
own class, not reusing .boat-list-card - visually and structurally a different
card. */
.featured-card {
    background-color: var(--by-tint);
    border-radius: var(--by-radius);
    overflow: hidden;
}

/* The homepage's "Aktuelle Verkaufsangebote der Woche" and "Aktuelle Charterangebote der Woche" (by/home/index) and
"Ähnliche Boote" of a detail page (<x-card.carousel>) have grey tiles instead of the light blue (Carsten, 2026-10-29);
the sell page's sample tile keeps the tint. */
.home-sale-offers .featured-card,
.home-charter-offers .featured-card,
.boat-carousel-track .featured-card {
    background-color: var(--by-surface);
}

.featured-card-img {
    width: 100%;
    height: 200px;
    object-fit: cover;
    display: block;
}

/* Mobile homepage featured tiles (col-12 below md) - 200px is the old site's
value, which reads as cramped on mobile. aspect-ratio (not a fixed px height)
so it scales with the phone's width; height:auto is required for aspect-ratio
to take over sizing, since the base rule above sets an explicit height (both
set = aspect-ratio has no effect, per spec). 4:3, not 16:9: 16:9 computes
SHORTER than the old 200px at typical phone widths (~197px at 350px card
width), 4:3 gives ~263px there. */
@media (max-width: 767.98px) {
    .featured-card-img {
        height: auto;
        aspect-ratio: 4 / 3;
    }
}

/* Bottom padding trimmed to 0.5rem, not the full 1rem the top/sides keep: the
gap below the price felt too big. */
.featured-card-body {
    padding: 1rem 1rem 0.5rem;
}

/* gap: the icon-to-text gap of the category row's <x-boat-type-icon> (the row
is .d-flex without Bootstrap's gap-1, on request - 0.4rem reads as ~2-3px more
air than gap-1's 0.25rem gave it; harmless on .featured-card-location, which
never carries .d-flex, so gap has no effect there). */
.featured-card-category {
    color: var(--by-muted);
    gap: .4rem;
}

/* .featured-card-location's <x-location-icon> sits inline with its text (no
flex row here, unlike .boat-list-meta-row - the surrounding text-truncate
needs the plain inline box), so it needs its own baseline nudge instead of a
flex align-items:center. */
.featured-card-location svg {
    vertical-align: -2px;
    margin-right: .15rem;
}

/* Homepage featured tiles and "Ähnliche Boote" (by/home/card-sboat/card-cboat): the icons of a list card
(<x-card.action-icons>: video, request, star) stand right-aligned in a row of their own at the bottom of the box,
below a hairline, and look as in the list - transparent, the round tint only on hover (Carsten, 2026-10-29; request
and star used to sit on the image; the size and hover rules are those of .boat-list-price-row further down). The tile
is a flex column and the body link takes the free height, so the row is at the bottom of every tile of a row,
whatever the lines above it hold. */
.featured-card {
    display: flex;
    flex-direction: column;
}

.featured-card > a {
    flex-grow: 1;
}

.featured-card-actions {
    display: flex;
    justify-content: flex-end;
    margin: 0 1rem;
    padding: .25rem 0;
    border-top: 1px solid var(--by-line);
}

/* Country line in the location/price row (by/home/card-sboat/card-cboat) -
country names can be long ("Vereinigte Arabische Emirate") and sit in a flex
row next to a price that must never itself get compressed. min-width:0 is what
lets a flex child's own text-truncate ellipsis kick in - Bootstrap's flex
utilities alone don't set it (a flex item's content-based min-width otherwise
wins over its shrink factor). font-size:1rem overrides the "small" utility
class also on this element: the row is align-items-start, so the country and
the PRICE ITSELF (not the price+vatPaid block as a whole) need matching font
sizes to come out flush at the bottom; vatPaid, when shown, is an extra line
below the price and stays smaller/italic regardless. */
.featured-card-location {
    min-width: 0;
    flex: 1 1 auto;
    font-size: 1rem;
}

.featured-card-title {
    font-size: 1rem;
    font-weight: 600;
    color: var(--by-dark);
}

/* line-height:1.2, not Bootstrap's inherited 1.5: at 1.5 the price's own line
box has ~6px of leading above/below the glyph, which reads as extra space
before .featured-card-vat below it although the two boxes already sit flush
(margin/gap: 0). */
.featured-card-price {
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.2;
    color: var(--by-red);
}

/* The words around a charter "from" price (by/home/card-cboat: "ab", "/Woche"): much smaller than the amount and in the
text colour, on the amount's baseline - like the old site (which top-aligned them), where French "à partir de … /semaine" would otherwise crowd
out the location next to it. */
.featured-card-price-note {
    font-size: .7em;
    font-weight: 400;
    color: var(--bs-body-color);
    vertical-align: baseline;
}

/* "inkl./exkl. MwSt." under the price (by/home/card-sboat) - a notch smaller
than Bootstrap's .small (0.875em) and italic. line-height:1.2 to match
.featured-card-price above it, same reasoning. */
.featured-card-vat {
    font-size: 0.75rem;
    line-height: 1.2;
}

/* Phone (one tile per row): every text a notch bigger (owner, 2026-10-14: too small). Country and price stay the
same size, see .featured-card-location. */
@media (max-width: 767.98px) {
    .featured-card-category {
        font-size: 1rem;
    }

    .featured-card-title {
        font-size: 1.125rem;
    }

    .featured-card-location,
    .featured-card-price {
        font-size: 1.0625rem;
    }

    .featured-card-vat {
        font-size: .875rem;
    }
}

/* Blog teaser cards (by/home/index.blade.php) - plain, light card, no border,
matching the general .boat-list-card bg/radius language on BY. Vertical (image
top) by default; .blog-card--featured switches the first 2 homepage posts to
horizontal (image left), as the old site's homepage blog block does. The card
itself has no overflow:hidden/radius clipping: the image sits in its own
separately rounded and clipped box (.blog-card-img-wrapper), INSET within the
card's 1rem padding on all sides - the old site's image box is rounded on all
4 corners and never touches the card's edges, unlike a typical edge-to-edge
card image. */
.blog-card {
    display: flex;
    flex-direction: column;
    border: none;
    border-radius: var(--by-radius);
    background-color: #fff;
    box-shadow: 0 1px 0 0 var(--by-line);
    padding: 1rem;
}

.blog-card-img-wrapper {
    display: block;
    flex-shrink: 0;
    border-radius: var(--by-radius);
    overflow: hidden;
    margin-bottom: 1rem;
}

/* 208px, not 180px (which came out ~20-40px short on mobile): exactly the old
site's blog image wrapper height, a constant at both 1280px desktop and 375px
mobile, not responsive. */
.blog-card-img-wrapper img {
    display: block;
    height: 208px;
    width: 100%;
    object-fit: cover;
}

/* flex:1 1 auto (not the flex-column default of 0) makes this consume the
card's full remaining height - without it, this only grows to fit its own
content, so .blog-card-readmore's margin-top:auto pins it to the bottom of an
undersized box instead of the card's real bottom edge whenever a neighbouring
card in the same row has a longer title/description. "Weiterlesen" must sit at
the same distance from the bottom in every card of a row. */
.blog-card-body {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-width: 0;
}

/* align-items:flex-start (not the flex-row default of stretch) - without
it, the image wrapper stretches to match the text column's own height,
leaving blank space below the (fixed-height) image inside its own rounded
box whenever the text is taller than the image (208px). */
.blog-card--featured {
    flex-direction: row;
    align-items: flex-start;
}

/* 44% below lg is only an approximation (good enough - the featured card
is col-12 there, not part of the 2-vs-4-column split this is about). At
>=lg it's overridden below by exact per-breakpoint px values instead.
margin-right: 1rem + ~5px on request (owner: the image-to-text gap read too
tight). */
.blog-card--featured .blog-card-img-wrapper {
    width: 44%;
    margin-bottom: 0;
    margin-right: 1.3125rem;
}

/* min-height matches the image wrapper's own fixed 208px (.blog-card-img-wrapper img below) - without it,
"Weiterlesen" (.blog-card-readmore's margin-top:auto) only reaches the bottom of the text CONTENT, which floats
above the taller image whenever the title+description together are shorter than 208px. Reset to 0 in the
below-sm media query further down, where the layout stacks and the image no longer sits next to this box. */
.blog-card--featured .blog-card-body {
    min-height: 208px;
}

/* Below sm, a 240px fixed-width image next to the featured card's text
leaves too little room for the title/description - fall back to the
narrow variant's stacked layout. */
@media (max-width: 575.98px) {
    .blog-card--featured {
        flex-direction: column;
    }

    .blog-card--featured .blog-card-img-wrapper {
        width: 100%;
        margin-bottom: 1rem;
        margin-right: 0;
    }

    .blog-card--featured .blog-card-body {
        min-height: 0;
    }
}

/* Exact match for the narrow row's own image width: a plain % of the featured
card's width only approximates it, since the featured card spans 2 of the
row's 4 grid columns plus the gap between them, not a clean 2x multiple of one
narrow column. Bootstrap's .container has a FIXED max-width per breakpoint, so
the narrow row's image width is one specific px value per breakpoint; exact
numbers below rather than a JS measurement, matching Bootstrap's own
lg/xl/xxl min-widths so both switch at the same instant:

  container max-width | narrow (25%) col | -1rem card padding*2 = image
  lg   960px  -> col 0.25*960-24=216  -> 216-32 = 184px
  xl  1140px  -> col 0.25*1140-24=261 -> 261-32 = 229px
  xxl 1320px  -> col 0.25*1320-24=306 -> 306-32 = 274px

(24px = the column's own left+right gutter padding from .row.g-4's
--bs-gutter-x:1.5rem; 32px = .blog-card's own 1rem left+right padding.)
Written ascending (lg, then xl, then xxl) on purpose - at eg. 1450px all
three min-widths match at once, and since they're equal specificity, the last
one in source order wins, so ascending order is what makes the xxl value
actually override the lg/xl ones instead of the reverse. */
@media (min-width: 992px) {
    .blog-card--featured .blog-card-img-wrapper {
        width: 184px;
    }
}

@media (min-width: 1200px) {
    .blog-card--featured .blog-card-img-wrapper {
        width: 229px;
    }
}

@media (min-width: 1400px) {
    .blog-card--featured .blog-card-img-wrapper {
        width: 274px;
    }
}

/* Date + category row (clock/box icons), above the title (<x-blog-meta>, the
layout is its Bootstrap utilities). .blog-card-meta-item groups one icon with its
own text so the gap between them is controlled independently from the gap between
the date and the category. */
.blog-card-meta {
    color: var(--by-muted);
}

.blog-card-meta-item {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
}

/* A bit bigger than the (small) meta text itself: 1rem against the .small
text's 0.875rem. Sizes both the bi-clock glyph (font-size) and the inline
category SVG (explicit width/height, since an SVG doesn't scale with font-size
on its own). */
.blog-card-meta-icon {
    color: var(--by-primary);
    font-size: 1rem;
    flex-shrink: 0;
}

svg.blog-card-meta-icon {
    width: 1rem;
    height: 1rem;
}

/* Category link, and the comment-count link of the detail page's meta row (a link only when comments > 0): the same
look on purpose, they sit next to each other. */
.blog-card-category-link,
.blog-comment-count-link {
    color: var(--by-primary);
    font-weight: 600;
    text-decoration: none;
}

.blog-card-category-link:hover,
.blog-comment-count-link:hover {
    text-decoration: underline;
}

/* Texts clamped to --lines lines with an ellipsis (a plain text-truncate only handles a single line); each rule below
sets its own count. */
.blog-card-title,
.blog-card-description,
.blog-sidebar-post-title,
.blog-list-title,
.blog-list-description {
    display: -webkit-box;
    -webkit-line-clamp: var(--lines);
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Font-size a notch above the 1rem body default. */
.blog-card-title {
    --lines: 2;
    color: var(--by-dark);
    font-weight: 600;
    font-size: 1.125rem;
}

/* Clamped to 3 lines by default; blog-card-clamp.js switches individual cards
to 4 lines (--short-title) when their title took only 1 line instead of its
full 2-line allowance, so the description always fills the room the title left
free. The 3-line default is also what a card keeps if that script fails to
run. Colour: the old site's muted grey (--by-muted). */
.blog-card-description {
    --lines: 3;
    color: var(--by-muted);
}

.blog-card-description--short-title {
    --lines: 4;
}

/* position: relative keeps the hidden post title inside the link (.visually-hidden is absolute): without it, in a
scrolling row of cards it is placed at the row's far end and makes the whole page scroll sideways on a phone. */
.blog-card-readmore {
    position: relative;
    color: var(--by-primary);
    font-weight: 600;
    margin-top: auto;
}

/* Blog list page sidebar (by/blog/list.blade.php) - three ".blog-sidebar-box"
blocks (search, "Kategorien", "Aktuelle Beiträge") after the old site's
layout: light-grey background + rounded corners + generous left/right padding
on EVERY block. Reuses the #f5f7fa/var(--by-radius) "light grey box" language
of .boat-list-card, .list-search-bar and .boat-contact-card rather than the
old site's literal 5px radius. Padding is 2rem all round (the old site's
".blog__sidebar-item" padding: 32px); margin-bottom stays the Bootstrap .mb-4
utility on each block in the blade (1.5rem), which already matches the old
site's 24px, so no rule is needed for it here. */
.blog-sidebar-box {
    background-color: var(--by-surface);
    border-radius: var(--by-radius);
    padding: 2rem;
}

/* Quicksearch box only: .list-search-field's leading icon is gone from the
blade markup here (the submit button's own icon is the only one left), so its
reserved padding-left (2.75rem, sized for that icon) is reset to a plain 1rem
- scoped to .blog-sidebar-box so the other .list-search-field usages (the boat
search topbar/sidebar, which keep their icon) are untouched.

height: 44px on both the input and the submit button: both were 54px through
the shared .list-search-field/.list-search-submit rules (sized for the boat
search bar's bigger touch targets) - shorter here, scoped the same way, so
this search box reads as a normal-height field next to the much taller 65px
category buttons below it. */
.blog-sidebar-box .list-search-field .form-control {
    height: 44px;
    padding-left: 1rem;
}

.blog-sidebar-box .list-search-submit {
    height: 44px;
}

/* 1.25rem: the page's own <h1> renders at Bootstrap's .h3 size (1.75rem,
by/blog/list.blade.php), so this stays clearly below it rather than competing
with it. */
.blog-sidebar-heading {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--by-dark);
    margin-bottom: 0.75rem;
}

/* Two columns of narrower, taller buttons rather than full-bleed-width pills:
min-height 65px is the old site's ".category-item" height; width calc(80% +
24px) + margin:0 auto keeps each button narrower than its grid cell instead of
stretching edge to edge. The +24px widens each side by roughly 12px - a calc()
addition splits evenly across both auto margins, unlike a pure percentage
bump, which would also change how much the button grows on wider screens.
flex+center handles a label that wraps to 2 lines ("Yachthäfen") the same way
as a short one-line label ("Video"). */
.blog-category-list {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.75rem;
}

.blog-category-list .btn {
    width: calc(80% + 24px);
    min-height: 65px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
}

/* Active/current category: every button is already .btn-primary
(var(--by-primary) background, white text), so the selected one needs its OWN
visual difference: the darker hover shade of .btn-primary (--brand-primary-hover), the same "this one is pressed"
language as the hover state. */
.blog-category-list .btn-primary.active {
    background-color: var(--brand-primary-hover);
    border-color: var(--brand-primary-hover);
}

/* 4:3, after the old site's ".post-img" (a close-but-not-exact 100x80/5:4
box; a literal aspect-ratio here instead of hand-picked pixel dimensions).
width:120px (fixed) + aspect-ratio + height:auto, not a fixed height - same
reasoning as .boat-list-img's mobile aspect-ratio rule: an explicit height
would fight a portrait source image's intrinsic sizing, aspect-ratio doesn't. */
/* The picture of a recent post in the blog sidebar (by/blog/sidebar) stands in a rounded box that clips it, so it can
grow inside it under the mouse like the pictures of the cards (Carsten, 2026-10-29). */
.blog-sidebar-post-img-box {
    display: block;
    width: 120px;
    flex-shrink: 0;
    align-self: flex-start;
    border-radius: var(--by-radius);
    overflow: hidden;
}

.blog-sidebar-post-img {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 3;
    height: auto;
    object-fit: cover;
    transition: transform .3s ease-in-out;
}

/* Each recent post is a box of its own that turns white with the card shadow under the mouse, like the cards of the
blog list (Carsten, 2026-10-29). .5rem of padding gives the white room around picture and text; the same negative margin
keeps everything where it was (the gap to the next entry is mb-2 in the view plus the two paddings = 1rem as before). */
.blog-sidebar-post {
    margin: -.5rem -.5rem 0;
    padding: .5rem;
    border-radius: var(--by-radius);
    transition: background-color .15s ease, box-shadow .15s ease;
}

.blog-sidebar-post:last-child {
    margin-bottom: -.5rem;
}

@media (hover: hover) {
    .blog-sidebar-post:hover {
        background-color: #fff;
        box-shadow: var(--by-card-shadow);
    }

    .blog-sidebar-post:hover .blog-sidebar-post-img {
        transform: scale(1.1);
    }
}

.blog-sidebar-post-title {
    --lines: 3;
    color: var(--by-dark);
    font-weight: 600;
    font-size: 0.9rem;
}

.blog-sidebar-post-date {
    color: var(--by-muted);
    font-size: 0.8125rem;
}

/* Blog list page's main card (by/blog/card.blade.php): a grey box over the
full width with the image on the left, inset ~16px from the box's top, left
and bottom and rounded on all corners - unlike the boat list's card. A plain
flex row, not Bootstrap's .row/.col-* grid (see the blade's docblock for the
reasoning): one shared padding on the CARD itself gives the image its inset on
three sides; the fourth side (the gap to the text) comes from
.blog-list-img-col's own margin-right, so the text column isn't squeezed into
that same tight inset. */
.blog-list-card {
    display: flex;
    align-items: flex-start;
    background-color: var(--by-surface);
    border-radius: var(--by-radius);
    margin-bottom: 1.5rem;
    padding: 16px;
}

@media (max-width: 991.98px) {
    .blog-list-card {
        flex-direction: column;
        margin-bottom: 2rem;
    }
}

/* calc(35% - 20px): a share of the card's width minus a flat 20px at every width; the image's aspect-ratio (below)
follows that width. Rounded and clipped on all four corners, since it touches no card edge. .blog-list-card's
align-items:flex-start keeps this column from stretching to the text column's height. */
.blog-list-img-col {
    flex: 0 0 calc(35% - 20px);
    margin-right: 1.5rem;
    border-radius: var(--by-radius);
    overflow: hidden;
}

@media (max-width: 991.98px) {
    .blog-list-img-col {
        flex-basis: auto;
        margin-right: 0;
        margin-bottom: 1rem;
    }
}

/* aspect-ratio, not height:100%: it needs only the image's own width, never a parent's height (the <a> around the
image has none, so a percentage height fell back to each photo's own ratio). object-fit:cover crops the photo. */
.blog-list-img {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
}

/* No padding of its own: the text column sits inside the SAME .blog-list-card
padding as the image; the margin-right on .blog-list-img-col above is what
separates it from the image. */
.blog-list-card-body {
    display: flex;
    flex-direction: column;
    flex-grow: 1;
    min-width: 0;
}

/* Clamped to 2 lines, not the single-line .text-truncate: its white-space:nowrap gives the flex item the whole
unwrapped title as its minimum width, which overflowed on a phone. */
.blog-list-title {
    --lines: 2;
    min-width: 0;
    color: var(--by-dark);
    font-weight: 600;
    font-size: 1.125rem;
    margin: 0.5rem 0;
}

/* Clamped to 3 lines. */
.blog-list-description {
    --lines: 3;
    color: var(--by-muted);
    margin-bottom: 0.75rem;
}

/* Phone: the teaser of a blog post the same on the homepage's cards and in the blog list (owner, 2026-10-15) - the
text at the basic size (on the homepage not the .small of a desktop, which was hard to read), the title 20px. After
both cards' own rules, which it overrides. */
@media (max-width: 767.98px) {
    .blog-card-title,
    .blog-list-title {
        font-size: 1.25rem;
    }

    .blog-card-description,
    .blog-list-description {
        font-size: 1rem;
    }
}

/* Full-width hero image above the two-column content row. 650px, as on the old
site, down to 320px below the same 991.98px breakpoint every other image rule
in this file stacks at (650px would letterbox a phone-width photo far too
aggressively). */
.blog-detail-hero-img {
    display: block;
    width: 100%;
    height: 650px;
    object-fit: cover;
    border-radius: var(--by-radius);
}

/* The author under a post's heading (by/blog/detail): round photo 50px and the name, as on the old site's
".single-blog__author-info" (Carsten, 2026-10-29). */
.blog-detail-author {
    display: flex;
    align-items: center;
    gap: .75rem;
}

.blog-detail-author-img {
    width: 50px;
    height: 50px;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
}

.blog-detail-author-name {
    font-weight: 600;
    color: var(--by-dark);
}

@media (max-width: 991.98px) {
    .blog-detail-hero-img {
        height: 320px;
    }
}

/* #636a80, the old site's colour for the blog post text - the same literal
value used for muted body-adjacent text elsewhere (.boat-list-meta-text), not
var(--by-dark) (near-black, this project's heading colour). $post->text is
already-formatted HTML from the API, printed unescaped (this project's pattern
for trusted API HTML). */
.blog-detail-text {
    color: var(--by-text-2);
    line-height: 1.7;
}

/* <p> margin/padding are 0: a browser default (1em top and bottom, ~32px
combined) already reads as a big gap between two real paragraphs, and the
API's content uses empty "<p>&nbsp;</p>" paragraphs as its OWN spacers on top
of that - the two together compounded to a "3 blank lines" look, and even a
0.5rem margin was still too much. Zero leaves the API's empty spacer
paragraphs as the ONLY vertical gap, as that HTML intends. */
.blog-detail-text p {
    margin: 0;
    padding: 0;
}

/* Embedded video: the API's <iframe> embed (eg. YouTube) carries no
width/height attributes, so it rendered at the browser's small default size
instead of filling the column. width:100% (not max-width, which only caps an
already-large size) plus a 16:9 aspect-ratio scales it with the column like a
responsive video embed; height:auto lets that aspect-ratio determine the
height instead of the iframe's own default. Rounded corners like the hero. */
.blog-detail-text iframe {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
    border-radius: var(--by-radius);
}

/* A stray <img> that the API's HTML includes directly rather than through
$post->image: rounded corners as well. max-width:100% keeps it from
overflowing the column on a narrower screen, same reasoning as the iframe rule
above minus the forced aspect-ratio (an inline content image keeps whatever
aspect ratio it has). 10px top/bottom margin (literal px) separates it from
the <p> directly above/below, now that .blog-detail-text p has none of its
own. */
.blog-detail-text img {
    max-width: 100%;
    margin: 10px 0;
    border-radius: var(--by-radius);
}

/* Comment-form note above the "Senden" button: the same muted tone as this
project's other small-print text (via var(--by-muted)), 0.875em rather than
Bootstrap's .small utility class so the size stays explicit even if this
paragraph's tag ever changes. */
.blog-comment-form-note {
    font-size: 0.875em;
    color: var(--by-muted);
}

/* Existing comments (by/blog/comment.blade.php). Values ported literally from
the old site's ".single-blog__user-comments" rules rather than this project's
tokens: #e6e6e6/#464d61 don't exist as project variables, and this is
a one-off feature, not worth a shared token. --by-dark (#191f33) happens to
match the old site's user-name colour exactly, so that one reuses the token.

.blog-comment-thread carries the padding/divider PER TOP-LEVEL THREAD (a
comment plus all its replies together) - see the blade's docblock for why
that is a separate element from .blog-comment-row. */
.blog-comment-thread {
    padding: 1.5rem 0;
    border-bottom: 1px solid #e6e6e6;
}

.blog-comment-thread:first-child {
    padding-top: 0;
}

.blog-comment-thread:last-child {
    border-bottom: 0;
}

.blog-comment-row {
    display: flex;
    align-items: flex-start;
    margin-top: 1rem;
}

.blog-comment-row:first-child {
    margin-top: 0;
}

/* Reply indent, 50px per nesting level (levels above 3 do not occur: there is no
reply link from level 3 on). */
.blog-comment-level-1 {
    margin-left: 50px;
}

.blog-comment-level-2 {
    margin-left: 100px;
}

.blog-comment-level-3 {
    margin-left: 150px;
}

.blog-comment-avatar {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    object-fit: cover;
    margin-right: 0.75rem;
    flex-shrink: 0;
}

.blog-comment-name {
    color: var(--by-dark);
    font-weight: 600;
}

.blog-comment-date {
    color: var(--by-muted);
    margin-left: 0.375rem;
    font-size: 0.875em;
}

/* "Antworten" link (blog-comment-form.js) - plain <button>, styled as a
text link (no border/background of its own) so it reads as part of the
meta row next to the date rather than a separate control. */
.blog-comment-reply-link {
    border: 0;
    background: none;
    padding: 0;
    margin-left: 0.5rem;
    color: var(--by-primary);
    font-size: 0.875em;
}

.blog-comment-text {
    color: #464d61;
    margin: 0.375rem 0 0;
}

/* "Antworten an: X" banner above the comment form once a reply link was
clicked (blog-comment-form.js) - shown/hidden via .d-none, not its own
component: same background as the form's surrounding .blog-sidebar-box, one
shade darker, so it reads as a status strip rather than a warning. A plain
block, no flex/justify-content:space-between: icon, label, name and "x" flow
left to right as one line of text instead of the "x" being pushed to the far
side of the box. */
.blog-comment-reply-banner {
    background-color: #eceff3;
    border-radius: var(--by-radius);
    padding: 0.5rem 0.75rem;
    margin-bottom: 0.75rem;
    font-size: 0.9375em;
}

.blog-comment-reply-icon {
    color: var(--by-primary);
    margin-right: 0.375rem;
}

/* The "x" itself - plain inline text/glyph right after the name, not
Bootstrap's own .btn-close (a fixed-size square icon button that would sit
as its own separate block rather than flow inline with the sentence
around it). */
.blog-comment-reply-cancel {
    border: 0;
    background: none;
    padding: 0;
    margin-left: 0.25rem;
    color: var(--by-muted);
    font-size: 1.125em;
    line-height: 1;
    vertical-align: middle;
}

/* Full-width light-gray band behind a homepage section (old site: ".bgcolor--gray-10") - the blog section and
"Beliebte Bootsmodelle", the 3 curated link columns above the footer (by/home/index.blade.php,
App\Library\Yachtino\HomeBlocks); the sale/charter sections in between stay on the plain white page background. */
.section-bg-surface,
.home-link-columns-section {
    background-color: var(--by-surface);
}

/* Hairline between the homepage's full-width sections (old site: each of its
"Aktuelles"/"Boote zum Verkauf"/"Aktuelle Verkaufsangebote"/"Yachtcharter"/
"Aktuelle Charterangebote" sections carries an inset box-shadow at its own top
edge, in var(--by-line), the same colour as the header's own hairline further
up in this file). Not on the very last "Beliebte Bootsmodelle" section - the
old site has none there either.

padding-top here, not Bootstrap's py-5 (the markup only carries pb-5): 1.75rem
matches the old site's own 30px section padding (owner: py-5's 48px left ~20px
too much air above the h2), pb-5 keeps the fuller 48px gap before the next
block's own hairline+heading. */
.section-divider-top {
    box-shadow: inset 0 1px 0 0 var(--by-line);
    padding-top: 1.75rem;
}

/* The blog cards and boat tiles of the homepage answer the mouse like a card of the boat list (.boat-list-card:
the text area turns white, the box gets the same soft shadow; owner, 2026-10-13). A blog card is white already, so
only the shadow comes, next to its own hairline. The boat tiles of "Ähnliche Boote" on a detail page do the same
(.boat-carousel-track, Carsten 2026-10-29); their scrolling row has the room for the shadow above and below
(boat-carousel.css). The transition and the tile's hover are grouped with .boat-list-card's further down. */
@media (hover: hover) {
    .section-divider-top .blog-card:hover {
        box-shadow: 0 1px 0 0 var(--by-line), var(--by-card-shadow);
    }
}

/* And the picture grows inside its box, as .boat-list-img does (grouped with it further down). The box has to cut it
off: a blog card's picture stands in .blog-card-img-wrapper, which does; a tile's picture stands in a bare link, so
that link becomes the box (the grown picture would otherwise lie over the text below it). */
.section-divider-top .featured-card > .position-relative > a,
.boat-carousel-track .featured-card > .position-relative > a {
    display: block;
    overflow: hidden;
}

/* Each link column its own white rounded box (old site: ".work-card") inside
the gray band above, not just bare text on it; its heading stands above it (.section-heading). The column is a flex
column, so boxes side by side still end on one line whatever their headings. */
.home-link-column-box {
    flex-grow: 1;
    background-color: #fff;
    border-radius: var(--by-radius);
    padding: 1.875rem;
}

/* Running-text paragraph (comma-separated links) as the old site's ".work-card__description": 16px/24px line-height
muted text for the commas, 16px blue links. */
.home-link-column-text {
    font-size: 1rem;
    line-height: 1.5rem;
    color: var(--by-muted);
    margin-bottom: 0;
}

.home-link-column-text a {
    color: var(--by-primary);
    text-decoration: none;
}

.home-link-column-text a:hover {
    text-decoration: underline;
}

/* The brands as logos (Carsten, 2026-11-02): a grid of equal white tiles with a hairline border (Yachtall's logos are
JPGs on white, they would stand out on grey), each logo fitted into the same height; the brands without a logo follow
below as the usual text. */
.home-link-logos {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
    gap: .75rem;
}

.home-link-logos + .home-link-column-text,
.home-link-images + .home-link-column-text {
    margin-top: 1.25rem;
}

/* In the homepage's own section (the charter countries, under its centred heading) the text links below the pictures
are centred too (Carsten, 2026-11-03). */
.home-link-section .home-link-column-text {
    text-align: center;
}

/* The charter areas with a picture (Carsten, 2026-11-03): picture boxes three in a row, the name below the picture on
the light grey of BY's boxes; the whole box is the link. Under the mouse it answers like the boat cards (white, their
shadow, the picture growing inside its frame: the shared rules further down). */
.home-link-image {
    display: block;
    height: 100%;
    overflow: hidden;
    background-color: var(--by-surface);
    border-radius: var(--by-radius);
    color: var(--by-dark);
    text-decoration: none;
}

.home-link-image img {
    display: block;
    width: 100%;
    height: auto;
}

.home-link-image-name {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0 .75rem;
    padding: .75rem 1rem;
    font-family: 'Nunito Sans', sans-serif;
    font-size: 1.15rem;
    font-weight: 600;
}

.home-link-image:hover .home-link-image-name {
    color: var(--by-primary);
}

/* The number of boats on the right of the name, in the small muted text of the boat type tiles ("8.855 Boote"). */
.home-link-image-count {
    font-family: 'Nunito', sans-serif;
    font-size: .95rem;
    font-weight: 400;
    color: var(--by-muted);
}

/* The picture holds the red "bis zu 55 % Rabatt" badge of the boat cards (.boat-badges, absolutely placed). */
.home-link-image-picture {
    position: relative;
    display: block;
    overflow: hidden;
}

/* "ab € 245/Woche" on its own line below name and number, in the red price of the boat cards. */
.home-link-image-price {
    flex-basis: 100%;
    font-family: 'Nunito', sans-serif;
    font-size: 1rem;
    font-weight: 600;
    color: var(--by-red);
}

.home-link-image-price small {
    font-size: .7em;
    font-weight: 400;
}

.home-link-logo {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 72px;
    padding: .75rem 1rem;
    background-color: #fff;
    border: 1px solid var(--by-line);
    border-radius: var(--by-radius);
    transition: box-shadow .2s;
}

.home-link-logo:hover {
    box-shadow: var(--by-card-shadow);
}

.home-link-logo img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

/* Newsletter sign-up above the footer (<x-newsletter-signup>, homepage): the footer's dark, edge to edge, set off from
it only by a thin light line at its bottom, as on the old site. */
.newsletter-signup {
    background-color: var(--by-dark);
    box-shadow: 0 -1px 0 0 var(--by-dark-2) inset;
}

.newsletter-signup-title {
    font-weight: 700;
    color: #fff;
}

.newsletter-signup-text {
    color: var(--by-muted-on-dark);
}

/* The sign-up box, as on the old site's ".subscribe__input-group": one box on the lighter dark of the footer's bottom
bar (68px high, rounded), the envelope in the brand blue, a field without a border of its own and a button of its own
inside the box, 12px from its edge. The box shows the keyboard focus of the field (:focus-within), the field itself
has no outline. */
.newsletter-signup-box {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem .75rem;
    min-height: 68px;
    padding: 8px 12px 8px 18px;
    background-color: var(--by-dark-2);
    border-radius: var(--by-radius);
}

.newsletter-signup-box:focus-within {
    box-shadow: 0 0 0 .2rem rgba(var(--brand-primary-rgb), .5);
}

.newsletter-signup-icon {
    color: var(--brand-primary);
    font-size: 1.25rem;
    line-height: 1;
}

.newsletter-signup-input {
    flex: 1 1 10rem;
    min-width: 0;
    height: 52px;
    padding: 0;
    background-color: transparent;
    border: 0;
    outline: none;
    color: #fff;
}

.newsletter-signup-input::placeholder {
    color: var(--by-muted-on-dark);
}

.newsletter-signup-button {
    padding: .75rem 1.5rem;
}

/* Phone: the button below the field, across the whole box (owner, 2026-10-15: both in one row was too long). */
@media (max-width: 575.98px) {
    .newsletter-signup-button {
        flex: 1 1 100%;
        margin-bottom: 4px;
    }
}

/* Phone: the button stands below the field (<x-newsletter-signup>), the one inside the input group is hidden but still
its last child, so Bootstrap keeps the field's right corners square. They are rounded again here; the selector has to
outweigh Bootstrap's own (.input-group:not(.has-validation) > :not(:last-child):not(...) ...). */
@media (max-width: 575.98px) {
    .newsletter-signup .input-group.input-group-lg:not(.has-validation) > .form-control:not(:last-child):not(.dropdown-toggle) {
        border-top-right-radius: var(--bs-border-radius-lg);
        border-bottom-right-radius: var(--bs-border-radius-lg);
    }
}

/* Footer - two-tone dark (old site's .footer--dark .footer__top/.footer__bottom, exact colours from its CSS).
The bottom padding is the room of the "Go to top" button (.back-to-top, further down): it stands with its
lower edge 1px above the bottom bar, so at the very end of the page it lies in this padding, its 53px
plus whatever is left over as air. */
.site-footer .footer-top {
    background-color: var(--by-dark);
    padding: 3rem 0 4rem;
}

.site-footer .footer-bottom {
    background-color: var(--by-dark-2);
    padding: 1rem 0;
}

.site-footer .footer-heading {
    font-family: 'Nunito Sans', sans-serif;
    color: #fff;
    font-weight: 600;
    font-size: 1.05rem;
    margin-bottom: 1rem;
}

/* One link per line, but only as wide as its text (display: table): the hover line below is the text's width, as on
the old site - a thin brand-blue line that slides in 4px below the text while the link turns white. */
.site-footer .footer-link {
    position: relative;
    color: var(--by-muted-on-dark);
    text-decoration: none;
    display: table;
    margin-bottom: .6rem;
    white-space: nowrap;
}

.site-footer .footer-link::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 1px;
    background-color: transparent;
    transition: all .2s ease-in-out;
}

.site-footer .footer-link:hover::after {
    bottom: -4px;
    background-color: var(--brand-primary);
}

/* Phone: a link wider than its half of the screen ("Skipper / Bootshandel" with a bigger text size set) wraps. */
@media (max-width: 575.98px) {
    .site-footer .footer-link {
        white-space: normal;
    }
}

/* Six columns of 2/12 from xl up (below: rows of three): the logo shrinks to its column instead of pushing it wider. */
.site-footer .footer-logo img {
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 32px;
}

/* The Nautic-Network logo in front of its link, in the link's own colour. */
.site-footer .footer-link-icon {
    width: 1.25em;
    height: 1.25em;
    vertical-align: -.25em;
}

/* Social media icons under the address: grey like the text, on hover a brand-blue circle with a white icon. The
negative margin lines the first icon up with the text above instead of its circle. */
.site-footer .social-links {
    display: flex;
    gap: .4rem;
    margin: 1rem 0 0 -.6rem;
}

.site-footer .social-links a {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    color: var(--by-muted-on-dark);
    font-size: 1.1rem;
    text-decoration: none;
    transition: all .3s ease-in-out;
}

.site-footer .social-links a:hover {
    color: #fff;
    background-color: var(--brand-primary);
}

.site-footer .footer-link:hover {
    color: #fff;
}

.site-footer .footer-bottom,
.site-footer .footer-bottom a,
.site-footer .footer-bottom-button {
    color: var(--by-muted-on-dark);
    font-size: 1em;
}

/* "Cookie-Einstellungen" is a button (it opens the consent manager), looking like its link neighbours. */
.site-footer .footer-bottom-button {
    padding: 0;
    border: 0;
    background: none;
    text-decoration: underline;
}

.site-footer .footer-bottom a:hover,
.site-footer .footer-bottom-button:hover {
    color: #fff;
}

/* Anbieter box - map pin / globe icon column: fixed width so the address text
(next to the pin) and the website text (next to the globe) both start at the
same x, whatever the two glyphs' own natural widths. text-align:center
centers each glyph within that fixed column. */
.boat-office-icon {
    display: inline-block;
    width: 1.1rem;
    text-align: center;
    flex-shrink: 0;
    color: var(--by-primary);
}

/* Kontakt/Service/Anbieter cards - the three right-column boxes wrapped by
.boat-contact-sticky. Bootstrap's .card-body padding is 1rem each side; 1.25rem
is the next step of Bootstrap's own spacing scale rather than an arbitrary
pixel value. line-height up from the project's 1.5 body default (see body{}
above) to 1.7, for a visibly looser gap between the address/vat-info/etc lines
these boxes are mostly made of. */
.boat-contact-sticky .card-body {
    padding-left: 1.25rem;
    padding-right: 1.25rem;
    line-height: 1.7;
}

/* Service card's "opens elsewhere" icon next to a service link (eg.
"Kaufvertrag"): a touch smaller than the surrounding button text, whatever
that text's own size is. */
.service-link-icon {
    font-size: calc(1em - 2px);
}


/* "Ganzer Text"/"weniger Text" chevron: a single bi-chevron-down, flipped 180°
once expanded instead of swapping in a second bi-chevron-up glyph, so it
animates smoothly rather than jumping between two shapes. */
.boat-description-toggle-icon {
    transition: transform .2s ease;
}

.boat-description-toggle-icon-expanded {
    transform: rotate(180deg);
}

/* #ff4f4f: on the old site both a "Reduziert" listing and a plain one show the
same red price - not conditional on a discount, just its one consistent price
colour. Weight 600, not 700, as the old detail-page price ("h2.text--heading-2",
32px/600). */
.boat-price {
    font-size: 1.75rem;
    font-weight: 600;
    color: var(--by-red);
}

.boat-price-old {
    font-size: .875rem;
    color: var(--by-muted);
    text-decoration: line-through;
}

/* Detail-page price only: the main price in the body colour, not red -
.boat-price itself stays red everywhere else (list cards, see above); this
second class, combined onto the same element only in detail-sboat.blade.php's
sidebar, wins by source order at equal specificity.

line-height:1.2 matches the h1 next to it: Bootstrap's h1..h6 rule sets
line-height:1.2 for every heading, but .boat-price is a plain <div> at the same
1.75rem font-size that inherits the page's 1.5 body line-height, and the
taller line box under the price alone pushed everything below it (the sticky
Kontakt card) down, so the top of the image and the top of the contact form
did not line up (seen on a boat with no old/auction price line to mask it). */
.boat-price-detail {
    color: var(--bs-body-color);
    line-height: 1.2;
}

/* List card (by/article/card-sboat/card-cboat) - horizontal card matching the
old site's "cards cards--two", with its own smaller .boat-price size (old
site: 20px there vs. a heading-level size on the detail page; both share the
bare .boat-price rule above otherwise). The light-grey #f5f7fa default turns
white on hover, like a table row highlight, plus a very soft shadow (old site:
"0 12px 80px 0 #001a661a" == rgba(0,26,102,.1)) so the card visibly lifts off
the page's white background - a background change alone barely reads as a
hover state once the page background is white too. .boat-list-img's
scale(1.1) on hover (further down) is the old site's zoom-the-photo-inside-
the-fixed-box effect (".cards:hover .cards__img-wrapper img"). One rule for
both cards (card-sboat and card-cboat carry the same class). */
.boat-list-card {
    background-color: var(--by-surface);
    border: none;
    border-radius: var(--by-radius);
    overflow: hidden;
    margin-bottom: 1.5rem;
}

/* The blog cards of "Mehr zum Thema" under a blog post (<x-card.carousel> with by.home.card-blogpost) look like the
boat tiles of "Ähnliche Boote" (Carsten, 2026-10-29): grey without the hairline, white with the shadow under the mouse,
the picture growing (grouped below). */
.boat-carousel-track .blog-card {
    background-color: var(--by-surface);
    box-shadow: none;
}

/* The same answer to the mouse for the boat list's and the blog list's cards and the homepage's tiles and blog cards
(their own sections above say why), and for the tiles and blog cards of the scrolling rows under a detail page or post. */
.blog-list-card,
.section-divider-top .featured-card,
.boat-carousel-track .featured-card,
.boat-carousel-track .blog-card,
.section-divider-top .blog-card,
.boat-list-card,
.home-link-image {
    transition: background-color .15s ease, box-shadow .15s ease;
}

@media (hover: hover) {
    .blog-list-card:hover,
    .section-divider-top .featured-card:hover,
    .boat-carousel-track .featured-card:hover,
    .boat-carousel-track .blog-card:hover,
    .boat-list-card:hover,
    .home-link-image:hover {
        background-color: #fff;
        box-shadow: var(--by-card-shadow);
    }
}

/* Extra breathing room above the title (padding-top) and to the left of it
(padding-left, the gap to the image). min-width:0: as a flex item the body would
otherwise not shrink below its widest nowrap text (the seller name), and the
.text-truncate rules inside it could never cut anything. */
.boat-list-card .card-body {
    padding-top: 2.25rem;
    padding-bottom: .25rem;
    padding-left: 1.5rem;
    min-width: 0;
}

.boat-list-card .boat-price {
    font-size: 1.25rem;
    font-weight: 400;
}

/* 220px high: the old site's ".cards--two .cards__img-wrapper" (220x220 there; the width stays the responsive
column). A fixed height, not height:100%: a tall photo would otherwise grow the column it should fill.
object-fit:cover crops any photo to it. */
.boat-list-img {
    width: 100%;
    height: 220px;
    object-fit: cover;
}

/* The picture of every card above grows inside its box under the mouse. */
.blog-list-img,
.section-divider-top .featured-card-img,
.boat-carousel-track .featured-card-img,
.section-divider-top .blog-card-img-wrapper img,
.boat-carousel-track .blog-card-img-wrapper img,
.boat-list-img,
.home-link-image img {
    transition: transform .3s ease-in-out;
}

@media (hover: hover) {
    .blog-list-card:hover .blog-list-img,
    .section-divider-top .featured-card:hover .featured-card-img,
    .boat-carousel-track .featured-card:hover .featured-card-img,
    .section-divider-top .blog-card:hover .blog-card-img-wrapper img,
    .boat-carousel-track .blog-card:hover .blog-card-img-wrapper img,
    .boat-list-card:hover .boat-list-img,
    .home-link-image:hover img {
        transform: scale(1.1);
    }
}

.boat-list-title {
    color: var(--by-dark);
    font-weight: 600;
}

/* Category/dims line (icon + "Klassiker / Motorboot | Gebrauchtboot | Stahl")
and the Länge/Bj./Kabinen line below it - #636a80, the old site's
".cards--two .cards__category-title" colour, one step darker than the #767e94
used for location/date further down.

Font-size 0.9rem: a deliberate middle between the old site's unusually small
.7rem (too small) and 1rem (a tick too big here), not a further measurement of
the old site. The line-height ratio (1.5) is kept relative to the size
(1.35rem) rather than left at an absolute value, so the row doesn't end up
disproportionately tall for its text. */
.boat-list-meta-text {
    font-size: .9rem;
    line-height: 1.35rem;
    color: var(--by-text-2);
}

/* min-width:0 on the category text itself: a flex item's default min-width is
"auto", which resolves to its single-line content width and blocks wrapping
regardless of white-space (the category line ran off the right edge of the
card on mobile). The same issue .card-body's min-width override further up
fixed for the whole column, one level deeper, on the <span>. */
.boat-list-meta-text > span {
    min-width: 0;
}

/* The boat type icon in front of the category line keeps its size when the line wraps (as a flex item it shrank,
owner 2026-10-14: French inflatables). */
.boat-list-meta-text > svg {
    flex-shrink: 0;
}

/* Seller name line - the same #636a80 as .boat-list-meta-text above (the old
site's ".username" inherits it from the same ancestor as its category line)
and the SAME size, kept matched to it. Lives in .boat-list-meta-row next to
the location; min-width:0 + overflow:hidden is what lets its .text-truncate
(blade markup) ellipsize it if location and seller together don't fit; no
flex-grow is needed since there is no fixed-width sibling to fill space
around, and .boat-list-meta-row's flex-wrap usually drops it to its own line
before truncation would even trigger. */
.boat-list-seller {
    font-size: .9rem;
    color: var(--by-text-2);
    min-width: 0;
    overflow: hidden;
}

/* Seller link - blue, no underline by default. #187aac, NOT var(--by-primary): the old site gives plain links a
darker shade of its blue scale than buttons and brand accents (#1d8dc6) - two deliberately different blues. */
.boat-list-seller a {
    color: #187aac;
    text-decoration: none;
}

.boat-list-seller a:hover {
    text-decoration: underline;
}

.boat-list-dims-text {
    flex: 0 0 auto;
}

/* Location + seller row (card-sboat.blade.php) - the same line, not stacked
(the old site's .cards__user-details is a flex row, space-between). #767e94
(== --by-muted) is the old site's location text colour, one step lighter than
.boat-list-meta-text above (the seller name keeps its own #636a80 via
.boat-list-seller). The location pin is <x-location-icon>, ported verbatim
from the old site, so no separate icon-colour rule is needed here. 0.9rem,
kept matched to .boat-list-meta-text's size. */
.boat-list-meta-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: .5rem;
    font-size: .9rem;
    color: var(--by-muted);
    margin-bottom: .75rem;
}

/* Optical left-alignment fix: the location and seller icons sit a few px
further right than the category row's <x-boat-type-icon> or the plain-text
rows - not because of any margin/padding here but because the glyphs have a
built-in inset before their visible shape starts (<x-location-icon>'s pin,
viewBox 0 0 24 24, only spans roughly x 4.5-19.5; bi-person's glyph has a
comparable side-bearing within its em-box), while <x-boat-type-icon>'s artwork
fills its viewBox edge to edge. A small negative margin pulls the visible
pixels back in line with the other rows' text start; the values are this
pair's own measured inset, not a generic constant. */
.boat-list-meta-row svg {
    margin-left: -4px;
}

.boat-list-meta-row .bi-person {
    margin-left: -3px;
}

/* The seller name clips what sticks out (overflow: hidden, for its ellipsis), and so cut off those 3px of the icon
(owner, 2026-10-15). Its box reaches 3px further left (padding) and moves back by as much (margin): nothing moves,
the icon just lies inside the box again. */
.boat-list-meta-row .boat-list-seller {
    margin-left: -3px;
    padding-left: 3px;
}

/* List card below lg, where the image column stacks above the text (col-12 col-lg-4/8 in card-sboat.blade.php):
- more space between the stacked cards (2rem, desktop 1.5rem), for a clearer boundary;
- less space above the title: the desktop 2.25rem clears the card's top edge beside the image, stacked below the photo
  it would push the title needlessly far from it;
- the image 4:3 instead of the fixed 220px, which at full card width would be an extreme letterbox crop (aspect-ratio
  with height:auto scales with the box, object-fit: cover still crops);
- the dims row wraps and its text takes a full-width line (min-width:0 lets flex-basis:100% apply at very narrow
  widths); the time-ago badge is hidden, so the text needs that line even for an unusually long Länge/Bj./Kabinen text;
- the seller name always on its own line, even where it would have fit (the row's flex-wrap only wraps on overflow);
  flex-basis:100% forces the wrap point. It sits in the location row on the sale card, in the dims row on the charter card. */
@media (max-width: 991.98px) {
    .boat-list-card {
        margin-bottom: 2rem;
    }

    .boat-list-card .card-body {
        padding-top: 1rem;
    }

    .boat-list-img {
        height: auto;
        aspect-ratio: 4 / 3;
    }
}

/* Phone: 12px to the card's edge on both sides instead of 24px left and 16px right, so the text under the picture
wraps less, the dimension line above all (owner, 2026-10-15). */
@media (max-width: 575.98px) {
    .boat-list-card .card-body {
        padding-left: 12px;
        padding-right: 12px;
    }
}

@media (max-width: 991.98px) {

    .boat-list-dims-row {
        flex-wrap: wrap;
    }

    .boat-list-dims-row .boat-list-dims-text {
        flex-basis: 100%;
        min-width: 0;
    }

    .boat-list-modified {
        display: none;
    }

    .boat-list-meta-row .boat-list-seller,
    .boat-list-dims-row .boat-list-seller {
        flex-basis: 100%;
    }
}

/* Charter card's own location line (card-cboat.blade.php) - country +
waterway names on ONE ellipsized line, full width (the seller name that shares
.boat-list-meta-row with the location on the sale card sits in the dims row
here, so this row only ever has this one child). flex:1 1 auto makes it claim
the row's full width instead of shrinking to its content the way a lone flex
item would; min-width:0 then lets Bootstrap's .text-truncate (blade markup)
ellipsize it. The -4px that line the pin up with the text above (.boat-list-meta-row svg)
sit on the span here, not on the pin: .text-truncate is overflow:hidden, so a pin pulled
out of the span lost its left edge. */
.boat-list-location-full {
    flex: 1 1 auto;
    min-width: 0;
    margin-left: -4px;
}

.boat-list-location-full svg {
    margin-left: 0;
}

/* Price row - a light divider above it (#ebeef7, the same value as
.list-sidebar-accordion's item divider and .site-header's box-shadow), as the
old site's .cards__info-top border-bottom. margin-top 1.25rem / padding-top
.25rem: margin-top collapses against .boat-list-meta-row's margin-bottom above
(both plain block siblings) to whichever is larger, so raising THIS side's
margin is what grows the gap above the line; padding-top (which never
collapses) shrinks by the same amount below it, nudging the line down without
changing the total space between the two text rows. */
.boat-list-price-row {
    border-top: 1px solid var(--by-line);
    padding-top: .25rem;
    margin-top: 1.25rem;
}

.boat-list-price-row > :last-child {
    flex-shrink: 0;
}

/* Body colour, NOT var(--by-muted): the old site's ".cards__price-title small"
(this VAT note's own rule, unless the more specific ".old-price" rule above
applies) resolves to Bootstrap's plain body-text colour, not a muted tone - so
the italic "inkl. MwSt." reads darker than the old price next to it, not
lighter. */
.boat-price-vat {
    font-size: .875rem;
    color: var(--bs-body-color);
}

/* Price + old price + VAT note vertically centered on one shared middle line:
the three sit at different font sizes (20px/14px/14px), so plain inline flow
(baseline, or the old site's vertical-align:top/bottom split) left them
visibly offset; flex + align-items:center recenters them regardless of
size. */
.boat-price-line {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    min-width: 0;
    overflow: hidden;
}

/* Phone: price, old price and VAT note did not fit one line beside the icons. The VAT note goes below the price, as
on the homepage's tiles (owner, 2026-10-14). */
@media (max-width: 575.98px) {
    .boat-price-line {
        flex-wrap: wrap;
        row-gap: 0;
    }

    .boat-price-vat {
        flex-basis: 100%;
        line-height: 1.2;
    }
}

/* Watchlist star + video icon inside the price row: the shared
.watchlist-heart/.video-icon default (public/shared/css/base.css)
is a small permanent white circle, made for sitting over a
photo (Regio's card overlay). The old site's star button (".btn-icon") is
larger and transparent by default, only tinting light blue on hover. video-icon gets the
same treatment for consistency with the star, and so does .boat-request-icon
(the shared base.css default is likewise a photo-overlay circle, which
doesn't match this row). */
.boat-list-price-row .watchlist-heart,
.boat-list-price-row .video-icon,
.boat-list-price-row .boat-request-icon,
.featured-card-actions .watchlist-heart,
.featured-card-actions .video-icon,
.featured-card-actions .boat-request-icon {
    width: 50px;
    height: 50px;
    background-color: transparent;
    box-shadow: none;
}

/* The icon cluster of a list card (<x-card.action-icons>). */
.boat-card-icons {
    gap: .5rem;
}

/* Phone: the three icons took 166px of the price row and left too little for the price, which was cut off (owner,
2026-10-15, Firefox with a bigger text size). The buttons 44px (the size a finger still hits safely) without a gap
between them, the price 18px instead of 20px - still clearly above the text of the card. The price is never cut off
any more: it keeps its own width, and when even that does not fit, the icons move to the next line. */
@media (max-width: 575.98px) {
    .boat-card-icons {
        gap: 0;
    }

    .boat-list-price-row .watchlist-heart,
    .boat-list-price-row .video-icon,
    .boat-list-price-row .boat-request-icon,
    .featured-card-actions .watchlist-heart,
    .featured-card-actions .video-icon,
    .featured-card-actions .boat-request-icon {
        width: 44px;
        height: 44px;
    }

    .boat-list-card .boat-price {
        font-size: 1.125rem;
    }

    .boat-list-price-row {
        flex-wrap: wrap;
    }

    /* flex-basis 0: the row decides whether the icons fit beside the price by the price line's narrowest width (its
    widest part, the price), not by price, old price and VAT note in one line - otherwise the icons dropped below
    although the price alone fitted. min-width: auto keeps that narrowest width, so nothing is cut off. */
    .boat-list-price-row .boat-price-line {
        flex: 1 1 0;
        min-width: auto;
    }
}

.boat-list-price-row .watchlist-heart:hover,
.boat-list-price-row .video-icon:hover,
.boat-list-price-row .boat-request-icon:hover,
.featured-card-actions .watchlist-heart:hover,
.featured-card-actions .video-icon:hover,
.featured-card-actions .boat-request-icon:hover {
    background-color: var(--by-tint);
    transform: none;
}

/* The same treatment for the detail page's own price block. 34px, not the list card's 50px: the icons must not be
taller than the price's line (1.75rem at line-height 1.2 = 33.6px), or the row grows and the image and the contact
form no longer line up at the top; 34px still fits the 28px star/camera SVGs. */
.boat-detail-price-icons .watchlist-heart,
.boat-detail-price-icons .video-icon {
    width: 34px;
    height: 34px;
    background-color: transparent;
    box-shadow: none;
}

/* "Druckversion" next to them: grey like the meta line, blue under the mouse, so it reads as a link (Carsten,
2026-11-04). !important: the link's text-muted is Bootstrap's own !important colour. */
.detail-print-link {
    transition: color .15s ease;
}

.detail-print-link:hover,
.detail-print-link:focus-visible {
    color: var(--by-primary) !important;
}

.boat-detail-price-icons .watchlist-heart:hover,
.boat-detail-price-icons .video-icon:hover {
    background-color: var(--by-tint);
    transform: none;
}

/* Top/Reduziert(Rabatte)/Neu pills over a boat's photo (list card, homepage tile, detail page) -
<x-card.boat-badges>. One row that wraps when the photo is too narrow: `right` next to `left` gives
the row a width to wrap against. pointer-events:none: the row spans the whole photo, its empty part
would otherwise swallow the click on the photo (the link of a card, the lightbox of the detail page).
.boat-badge carries the pill shape (icon ahead of the text), each variant only its colours.

Size and place as measured on the old BY site (2026-10-13): 15px from the photo's corner, 12px between two pills,
a pill 27px high (the 16px icon plus 5.5px above and below), 8px before the icon, 8px between icon and text, 16px
behind the text, the text 11px. */
.boat-badges {
    position: absolute;
    top: 15px;
    left: 15px;
    right: 15px;
    z-index: 2;
    pointer-events: none;
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 12px;
}

.boat-badge {
    display: flex;
    align-items: center;
    gap: 8px;
    border-radius: 100px;
    padding: 5.5px 16px 5.5px 8px;
    font-size: 11px;
    line-height: 1;
    font-weight: 800;
    text-transform: uppercase;
}

.boat-badge-icon {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}

.boat-badge--reduced {
    background-color: #ffb8b8;
    color: #762222;
}

.boat-badge--top {
    background-color: #ffe38d;
    color: #453300;
}

.boat-badge--new {
    background-color: #d4f3cc;
    color: #104e00;
}

/* Bigger variant for the detail page's own hero photo (<x-card.boat-badges
size="lg">). The list-card size fits a ~220px-tall thumbnail but looked
undersized against the detail page's much larger gallery image; 1rem was too
big, .875rem is the middle ground. CSS width/height on the SVG
(.boat-badge-icon) wins over its width="16"/height="16" presentation
attributes, so every badge's own icon scales with it, not just the pill/text
around it. */
.boat-badges-lg {
    top: 1rem;
    left: 1rem;
    right: 1rem;
    gap: .5rem;
}

.boat-badges-lg .boat-badge {
    gap: .45rem;
    padding: .4rem .85rem .4rem .55rem;
    font-size: .875rem;
    line-height: 1.5;
}

.boat-badges-lg .boat-badge-icon {
    width: 18px;
    height: 18px;
}

/* Fading top border on the text column of a reduced-price, a new and a "Top" boat - ported from the old site's
".cards__info.badgeReduced" (badgeNew, badgeFeature): a 6px border-image gradient in the colour of the boat's pill
(--card-flag: the background-color of .boat-badge--reduced, --new, --top) fading to transparent left to right.
border-image needs a real border-width/style to paint over - top-only; solid is just the fallback for browsers that
ignore border-image entirely. A card has one border: the card views set one of the three classes, red before green
before yellow. */
.boat-list-card-body-reduced {
    --card-flag: #ffb8b8;
}

.boat-list-card-body-new {
    --card-flag: #d4f3cc;
}

.boat-list-card-body-top {
    --card-flag: #ffe38d;
}

.boat-list-card-body-reduced,
.boat-list-card-body-new,
.boat-list-card-body-top {
    border-top: 6px solid var(--card-flag);
    border-image: linear-gradient(to right, var(--card-flag), transparent) 1 / 1 / 0 stretch;
}

/* Phone: no stripe - the picture right above it already carries the pill (owner, 2026-10-15). */
@media (max-width: 767.98px) {
    .boat-list-card-body-reduced,
    .boat-list-card-body-new,
    .boat-list-card-body-top {
        border-top: none;
        border-image: none;
    }
}

/* No line between the rows of the attribute grid (shared/css/attribute-grid.css); Regio and BKM keep theirs. */
.boat-attr-grid {
    --attr-row-border: none;
}

/* Tab icons (Details/Technische Daten/Motor/Segeln/Ausstattung) in the brand
colour: Bootstrap Icons (self-hosted, see CLAUDE.md "Self-hosting only")
rather than the old page's Font Awesome set - this project uses bi-* everywhere
else, and Bootstrap Icons has a close equivalent for every one of the old
page's tab icons. */
.boat-tab-icon {
    color: var(--by-primary);
    margin-right: .35rem;
}

/* The tab name at the top of each pane: only for a browser without JavaScript, which shows every pane one below the
other (shared/css/nojs.css); with JavaScript the tab button names the pane. */
.boat-tab-nojs-heading {
    display: none;
}

/* The ACTIVE tab is the exception: standard body text colour (--bs-body-color,
which this project never overrides - see body{} above), not the brand blue
every inactive tab uses, so the selected one reads as "this is where you
already are" rather than another clickable link. cursor:default for the same
reason. */
.nav-tabs .nav-link.active {
    color: var(--bs-body-color);
    font-weight: 700;
    cursor: default;
}

/* The boxes of the detail page's main column (.boat-detail-main: tabs, description, charter prices, share) have no
frame, as on the old BY site (owner, 2026-10-13): their content stands at the column's edge like the heading and the
picture above, and a light line separates a box's heading from its content. The request form at the end of the
column keeps its tinted panel (.boat-contact-card).

The tabs: the tab row keeps what it had - the active tab's own frame and the line under the row (the card header's
lower border) - and the pane below it has no frame any more. */
.boat-detail-main > .card:not(.boat-contact-card) {
    border: none;
}

.boat-detail-main > .card:not(.boat-contact-card) > .card-body {
    padding-right: 0;
    padding-left: 0;
}

.boat-detail-main > .card:not(.boat-tabs-card):not(.boat-contact-card) > .card-body {
    padding-top: 0;
}

.boat-detail-main > .card:not(.boat-tabs-card):not(.boat-contact-card) > .card-body > h2,
.boat-detail-main > .card .share-head {
    border-bottom: 1px solid var(--line-soft);
    padding-bottom: .75rem;
}

/* The share block's heading shares its row with the "copied" note (.share-head): the line stands under the whole
row, not under the word. The heading's own lower margin is the room above the line. */
.boat-detail-main > .card .share-head {
    padding-bottom: .25rem;
    margin-bottom: 1rem;
}

/* The picture gallery (<x-gallery.lightbox>, a card of its own) has no frame either, and its strip of thumbs under
the picture is as wide as the picture: no room left and right of it (owner, 2026-10-13). The card's rounded corners
go with the frame - the picture has its own (.gallery-main), and the card's would cut the lower outer corners of the
first and last thumb. The strip's arrows move back to the edge with it. */
.boat-detail-main [data-gallery-root] {
    border: none;
    border-radius: 0;
}

.boat-detail-main .gallery-strip-page {
    padding: .5rem 0 0;
}

.boat-detail-main .gallery-strip-page .gallery-strip-prev {
    left: .25rem;
}

.boat-detail-main .gallery-strip-page .gallery-strip-next {
    right: .25rem;
}

.boat-tabs-card > .card-header {
    padding-right: 0;
    padding-left: 0;
}

.boat-tabs-card .card-header-tabs {
    margin-right: 0;
    margin-left: 0;
}

/* "Anfrage senden" buttons. Nunito is self-hosted in 400 and 600 only, so font-weight:700 renders as 600; the larger
font-size is what makes the text read heavier. */
.btn-request-send {
    font-weight: 700;
    font-size: 1.1em;
    padding-top: .75rem;
    padding-bottom: .75rem;
}

/* Phone-reveal button, Kontakt card: no border/background at rest - it reads as
plain text until hovered, not as a second call-to-action competing with
"Anfrage senden" above it. The text stays the page's own standard colour; only
the icon is brand blue. The hover fill is --by-primary at 8% opacity rather
than a flat hex, so it follows the brand colour automatically. */
.boat-phone-reveal-btn {
    background-color: transparent;
    border-color: transparent;
    color: var(--bs-body-color);
    /* Smaller than .btn-request-send's own .75rem: it is secondary to "Anfrage senden"
    (see its own comment below on why it has no border/background), and a shorter button
    is what actually shrinks the gap between two stacked numbers - the margin between
    them is already down to 1px. */
    padding-top: .4rem;
    padding-bottom: .4rem;
}

.boat-phone-reveal-btn:hover,
.boat-phone-reveal-btn:focus {
    background-color: rgba(var(--brand-primary-rgb), .08);
    border-color: transparent;
    color: var(--bs-body-color);
}

/* Disabled: the preview of an unpublished boat, and every button once any one of them has
revealed the number(s) - a plain .btn has no disabled border colour of its own, so
Bootstrap would draw a dark rim - keep it looking like at rest, only faded by Bootstrap's disabled opacity. */
.boat-phone-reveal-btn:disabled {
    background-color: transparent;
    border-color: transparent;
    color: var(--bs-body-color);
}

.boat-phone-reveal-btn i {
    color: var(--by-primary);
}

/* A revealed number stays on one line (owner, 2026-10-14: it wrapped on a phone). The hidden "(anzeigen)" no longer
takes room once the number is shown: the button keeps its icon and number, so it does not collapse (the reason
.boat-phone-reveal-hidden keeps its box elsewhere). */
.boat-phone-reveal-btn .boat-phone-number {
    white-space: nowrap;
}

.boat-phone-reveal-btn .boat-phone-reveal-hidden {
    display: none;
}

/* Between two stacked phone numbers: tighter than Bootstrap's smallest utility (mt-1,
.25rem) - they belong together more than the first one belongs to "Anfrage senden"
above it, which keeps its full mt-2. */
.boat-phone-reveal-gap {
    margin-top: .0625rem;
}

/* Kontaktformular cards on the detail page: #f5f7fa, the light-grey tone used
site-wide (.site-header, .boat-list-card, etc.) rather than Bootstrap's
.bg-light. */
.boat-contact-card {
    background-color: var(--by-surface);
}

/* Sale-list search form after the old site's layout - top quick-search bar +
left sidebar accordion. Top bar values (bg #f5f7fa, white 12px-radius fields,
height 54px, text colour #464d61, blue Suchen button) are the old
/boote-kaufen's - the same visual language as .hero-search-* on the homepage,
just on a plain light section instead of a translucent-over-photo one. */
.list-search-bar {
    background-color: var(--by-surface);
    border-radius: var(--by-radius);
    padding: 0.75rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-bottom: 1.5rem;
}

.list-search-field .form-control,
.list-search-field .form-select {
    background-color: #fff;
    color: #464d61;
}

/* Reset links ("Suche zurücksetzen" for the whole form, and the Bootsart-only reset) share this base class so the two
stay identical, apart from the padding below. text-align: left: a native <button> defaults to centered, invisible for a
one-line label but obvious once a longer one wraps (icon alone on a centered line, text centered below it). */
.list-sidebar-reset-link {
    display: inline-block;
    padding: 0;
    border: none;
    background: none;
    font-size: 1rem;
    color: var(--by-primary);
    text-decoration: none;
    text-align: left;
}

/* Only the top-level "Suche zurücksetzen" (a direct child of .list-sidebar, which has no horizontal padding) gets
padding-left 1.25rem, to line up with .accordion-button. The Bootsart-only reset sits inside .accordion-body, which
already carries 1.5rem; the same 1.25rem on top would indent it 20px past "Bootsart" and the checkboxes. The margins
move the button 8px down inside the same total space between the sidebar's top padding and "Bootsart", instead of
growing that space. */
.list-sidebar > .list-sidebar-reset-link {
    padding-left: 1.25rem;
    margin-top: .5rem;
    margin-bottom: .5rem;
}

/* The watchlist switch and the seller box at the top of the sidebar (.filter-top-box), which has no horizontal padding:
the same 1.25rem on both sides as the reset link below them, no box of their own. */
.list-sidebar > .filter-top-box {
    margin: .5rem 0;
    padding: 0 1.25rem;
    background: none;
}

.list-sidebar-reset-link:hover {
    text-decoration: underline;
}

/* Sidebar (.list-sidebar, by/article/search-form-sboat-sidebar): width/padding/
heading style/item divider match the old site's ".list-sidebar" (261-285px
column, 25px 0 padding, 16px/600 dark heading text, light divider between
accordion items). Border #ebeef7, the same value as the item divider below (the
old site has an outer border too). Bootstrap's .accordion-button is heavily
restyled: no default blue-tinted background or box-shadow when open, no default
caret spacing - just the plain dark bold heading + Bootstrap Icons' own
chevron (rotated via [aria-expanded]) instead of Bootstrap's built-in caret
background-image. padding-top .5rem, not the old site's 25px: the first
.accordion-button brings its own 1.25rem on top of it. */
.list-sidebar {
    padding: .5rem 0 25px;
    border: 1px solid var(--by-line);
    border-radius: var(--by-radius);
}

/* Combined mobile search canvas (by/article/list.blade.php): .offcanvas-lg on the column already handles position, width,
transform and backdrop at every breakpoint. Bootstrap's ".offcanvas-lg .offcanvas-body" turns display:flex on from lg
(built for a horizontal navbar menu), which put the sidebar's stacked accordion into one flex row, hence display:block. */
@media (min-width: 992px) {
    .by-search-canvas .offcanvas-body {
        display: block;
    }
}

/* Width below lg (the variable has no effect once .offcanvas-lg goes static): Bootstrap's 400px becomes 460px, which fits
more field labels without wrapping; max-width keeps a narrow phone's screen edge clear of the panel. */
@media (max-width: 991.98px) {
    .by-search-canvas {
        --bs-offcanvas-width: 460px;
        max-width: 88vw;
    }

    /* Extra bottom padding on the scrollable panel, so the last field cannot end up behind a fixed overlay (a mobile
    browser's bottom bar, another app's always-on-top element) with nothing left to scroll past. Not needed at lg+,
    where the sidebar is a plain static block. */
    .by-search-canvas .offcanvas-body {
        padding-bottom: 6rem;
    }
}

/* Quicksearch + Suchen button side by side - the same .list-search-field look
as the top bar's copy of this field (further up), just without that bar's
pill/shadow framing, since it sits inside the canvas's own padding here. */
.by-search-canvas-quick {
    display: flex;
    gap: .5rem;
    margin-bottom: .75rem;
}

.by-search-canvas-quick .list-search-field {
    flex: 1 1 auto;
}

.by-search-canvas-quick .list-search-field .form-control {
    background-color: #fff;
    border: 1px solid #ced4da;
    height: 44px;
    padding-left: 2.5rem;
}

.by-search-canvas-quick .list-search-field i {
    color: var(--by-muted);
}

/* #636a80, not Bootstrap's near-black: the old site's main.css has
".form-check-label{color:#636a80}", the same grey as .boat-list-meta-text/
.boat-list-seller on the list card. Covers every label in this sidebar (bcid,
Boot neu/gebraucht, Flybridge; Bootsart is its own markup without
.form-check-label). */
.list-sidebar .form-check-label {
    color: var(--by-text-2);
}

/* 24px left/right: the old site's ".accordion-item" padding (not on
.list-sidebar itself, which stays 0 horizontal - each section pads itself).
Applies uniformly to every row/heading inside a section, including the
boat-type rows' own +/- toggle and the section heading's own chevron, which
otherwise sat flush against the sidebar's right edge. */
.list-sidebar-accordion .accordion-item {
    border: none;
    border-bottom: 1px solid var(--by-line);
    border-radius: 0;
    padding: 0 24px;
}

.list-sidebar-accordion .accordion-item:last-child {
    border-bottom: none;
}

.list-sidebar-accordion .accordion-header {
    margin: 0;
}

/* Uppercase: as on the old site, section headings ("BOOTSART" etc.) render
uppercase via CSS text-transform on an otherwise normal-case "Bootsart" in the
DOM, while a field-level label like "Länge (m)" stays normal case (see
.list-sidebar-subheading). */
.list-sidebar-accordion .accordion-button {
    padding: 1.25rem 0;
    font-size: 1rem;
    font-weight: 600;
    color: var(--by-dark);
    background-color: transparent;
    box-shadow: none;
    text-transform: uppercase;
}

.list-sidebar-accordion .accordion-button::after {
    background-image: none;
    font-family: 'bootstrap-icons', sans-serif;
    content: '\f282';
    color: var(--by-icon-muted);
    transition: transform 0.2s ease;
}

.list-sidebar-accordion .accordion-button:not(.collapsed)::after {
    transform: rotate(180deg);
}

/* No ring after a click; the keyboard focus gets a solid outline (Bootstrap's pale ring is too faint, WCAG 2.4.7). */
.list-sidebar-accordion .accordion-button:focus {
    box-shadow: none;
}

.list-sidebar-accordion .accordion-button:focus-visible {
    outline: 2px solid var(--brand-primary);
    outline-offset: -2px;
}

.list-sidebar-accordion .accordion-body {
    padding: 0 0 1.5rem;
}

/* Normal case, #636a80: a field-level sub-label ("Länge (m)" etc.), not a
section heading - 14px/400, in the same #636a80 as the list card's own meta
lines (card-sboat.blade.php), not the muted --by-muted tone. */
.list-sidebar-subheading {
    font-size: 0.875rem;
    font-weight: 400;
    color: var(--by-text-2);
    margin-bottom: 0.5rem;
}

/* One boat-type block (row + its expandable subcats) inside the Bootsart
section - border-bottom + padding-bottom after the old site's
".list-sidebar__accordion-inner-item" (#ebeef7, the same value as every other
divider in this file, no divider after the last one). The padding-bottom of
.5rem is a deliberate step down from the old site's 16px, so the blocks don't
end up too far apart when all are collapsed. */
.list-sidebar-boattype {
    padding-bottom: .5rem;
    border-bottom: 1px solid var(--by-line);
}

.list-sidebar-boattype:last-child {
    border-bottom: none;
    padding-bottom: 0;
}

.list-sidebar-boattype + .list-sidebar-boattype {
    margin-top: .5rem;
}

/* Row (icon + real radio + label + expand toggle; see the blade file's
docblock for the interaction). Label colour the body colour, not var(--by-dark) (a
navy-tinted #191f33 reserved for headings elsewhere in this file): it is the
old site's row-label colour, and var(--by-dark) read as noticeably closer to
black. 1rem/16px. "active" (the currently picked btid) gets the primary colour
on the LABEL only, as the old site's selected state - the icon stays the same
muted grey (on the old site only the radio + label recolour). Its bcid
subcategories expand directly below the row (.list-sidebar-subcats), not in a
separate panel. */
.list-sidebar-boattype-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.5rem 0;
}

.list-sidebar-boattype-row svg {
    flex-shrink: 0;
    color: var(--by-icon-muted);
}

.list-sidebar-boattype-label {
    flex: 1 1 auto;
    font-size: 1rem;
    color: var(--bs-body-color);
}

/* Phone: the filter panel gives its room to the text (owner, 2026-10-15: "Schlauchboote" pushed the + out, Spanish
names wrapped). The panel a little wider, the panel's and the sections' side padding halved (16 to 12px, 24 to 12px,
the top links with them, so everything stays flush), and no boat type icons. */
@media (max-width: 575.98px) {
    .by-search-canvas {
        max-width: 92vw;
    }

    .by-search-canvas .offcanvas-body {
        padding-left: 12px;
        padding-right: 12px;
    }

    .list-sidebar-accordion .accordion-item,
    .list-sidebar > .filter-top-box {
        padding-left: 12px;
        padding-right: 12px;
    }

    .list-sidebar > .list-sidebar-reset-link {
        padding-left: 12px;
    }

    .list-sidebar-boattype-row svg {
        display: none;
    }
}

.list-sidebar-boattype-label.active {
    color: var(--by-primary);
    font-weight: 600;
}

/* font-size 1rem: the old site's +/- SVG is 16px too. */
.list-sidebar-boattype-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 1.5rem;
    height: 1.5rem;
    border: none;
    background: none;
    padding: 0;
    color: var(--by-icon-muted);
    font-size: 1rem;
}

/* A type with subcategories is a <details> and its row the <summary>: the browser opens and closes it, the row keeps
no marker of its own, the +/- sign shows the state. */
summary.list-sidebar-boattype-row {
    list-style: none;
    cursor: pointer;
}

summary.list-sidebar-boattype-row::-webkit-details-marker {
    display: none;
}

.list-sidebar-boattype-minus,
.list-sidebar-boattype[open] .list-sidebar-boattype-plus {
    display: none;
}

.list-sidebar-boattype[open] .list-sidebar-boattype-minus {
    display: inline;
}

/* Left-aligned with the boat-type ICON above it, not the radio: the icon is
.list-sidebar-boattype-row's own first child at the row's left edge, so an
indent of 0 lines the checkboxes up with it. */
.list-sidebar-subcats-inner {
    padding: 0 0 0.5rem;
}

/* Checklists in the sidebar (a boat type's subcategories, the charter Revier list): at most about 10 rows, a scrollbar
for the rest. The manufacturer list carries search-form-checklist too but needs no rule, ManufacturerFinder already
caps it at 10. 21.75rem, not 21rem: a row measures 24px plus a 0.6rem gap, so 10 rows are 21rem, and the extra
.75rem cuts the 11th row in half so the list visibly goes on if the scrollbar is overlooked. */
.list-sidebar-subcats-inner.search-form-checklist,
.list-sidebar-waterways.search-form-checklist {
    max-height: 21.75rem;
    overflow-y: auto;
    overflow-x: hidden;
}

/* overflow-wrap: a long unbroken label like "Wasserski-/Wakeboard-Boote" would force a horizontal scrollbar (overflow-x
cannot stay visible once overflow-y is not, hence the overflow-x: hidden above); as a last resort it wraps mid-word. */
.list-sidebar-subcats-inner .form-check-label,
.list-sidebar-waterways .form-check-label {
    overflow-wrap: anywhere;
}

/* Space between the checkboxes: more than Bootstrap's tight .form-check default. */
.list-sidebar-subcats-inner .form-check,
.list-sidebar-waterways .form-check,
.list-sidebar-radio-list .form-check {
    margin-bottom: 0.6rem;
}

.list-sidebar-subcats-inner .form-check,
.list-sidebar-waterways .form-check {
    line-height: 1.4;
}

.list-sidebar-subcats-inner .form-check:last-child,
.list-sidebar-waterways .form-check:last-child,
.list-sidebar-radio-list .form-check:last-child {
    margin-bottom: 0;
}

/* Always-visible "Sort. nach" list at the end of the sidebar (the old site's
version has no accordion-toggle button, unlike the 5 sections above it). The
border-top is the same #ebeef7 that .list-sidebar-accordion .accordion-item's
border-bottom uses between every OTHER pair of sections; that rule stops one
short of here on purpose (:last-child strips its own border-bottom, since the
accordion's last section is followed by this plain, non-accordion block), so
this side owns the divider. */
.list-sidebar-sort {
    padding-top: 1.5rem;
    padding-left: 24px;
    padding-right: 24px;
    border-top: 1px solid var(--by-line);
}

/* Pagination (<x-pagination>, components/pagination.blade.php - shared across
every site group, styled here only because this file only loads on BY pages)
after the old site's /boote-kaufen: 48px square pills, fully rounded
(var(--by-radius), all 4 corners, not just the end ones Bootstrap's own
.page-link rounds), no border, flush against each other (no gap). --by-primary
fill + white text for the active page; #636a80 (this file's meta-text grey)
for every other page number; muted for Prev/Next once disabled. Prev/Next sit
~1rem away from the number group - margin on the first/last :page-item rather
than a gap on the whole list, so the numbers themselves stay flush. */
.pagination .page-link {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    padding: 0;
    border: none;
    border-radius: var(--by-radius);
    margin-left: 0;
    background-color: transparent;
    color: var(--by-text-2);
    font-size: .875rem;
    font-weight: 600;
}

.pagination .page-link:hover {
    background-color: var(--by-surface);
    color: var(--by-text-2);
}

.pagination .page-item.active .page-link {
    background-color: var(--by-primary);
    color: #fff;
}

.pagination .page-item.disabled .page-link {
    color: var(--by-icon-muted);
    background-color: transparent;
}

.pagination .page-item:first-child {
    margin-right: 1rem;
}

.pagination .page-item:last-child {
    margin-left: 1rem;
}

/* Prev/Next arrows bigger + var(--by-primary), the same blue the active page
number's background uses. Scoped to a.page-link (the enabled state -
pagination.blade.php renders disabled Prev/Next as a plain <span>, never
a.page-link), so this doesn't fight .page-item.disabled .page-link's muted
colour further up; the size bump applies to the icon regardless of
enabled/disabled. */
.pagination .page-item:first-child a.page-link,
.pagination .page-item:last-child a.page-link,
.pagination .page-item:first-child a.page-link:hover,
.pagination .page-item:last-child a.page-link:hover {
    color: var(--by-primary);
}

.pagination .page-item:first-child .page-link i,
.pagination .page-item:last-child .page-link i {
    font-size: 1.25rem;
}

/* "Go to top" button - white arrow in a black circle, bottom right, shown once
the page has been scrolled (by/js/back-to-top.js sets .is-visible; without the
script it simply never appears).

Horizontal position: on a desktop the button sits on the right edge of the
CONTENT, not of the window. The content is a Bootstrap .container, whose
max-width is fixed per breakpoint (540/720/960/1140/1320px, below 576px it
fills the window), so its right edge is (window - width) / 2 from the window
edge, plus the container's own 12px padding (--bs-gutter-x / 2), which is
where the text ends. position:fixed resolves percentages against the window
WITHOUT the scrollbar, the same width the centred container is laid out in,
so no 100vw correction is needed. The container is at least as wide as the
window (or wider) below 576px, the difference goes negative and max() falls
back to the 16px margin - which is what "window smaller than the content"
asks for. Breakpoints are written ascending on purpose, see the note on
.blog-card--featured above.

Vertical position: while scrolling the button rests 16px above the window's lower
edge (--back-to-top-rest). Once the footer's bottom bar (the last row) comes into
view, it pushes the button up: by/js/back-to-top.js sets --back-to-top-lift to how
far the bar reaches into the window (+ 1px), and the larger of the two counts. At
the end of the page the lower edge so lies 1px above the bar, in the padding of the
footer's upper part, and covers no link (owner, 2026-10-15; before, it stood that
high all the time). */
.back-to-top {
    --back-to-top-content-width: 100%;
    --back-to-top-rest: 16px;
    --back-to-top-lift: 0px;

    position: fixed;
    right: max(16px, calc((100% - var(--back-to-top-content-width)) / 2 + 12px));
    bottom: max(var(--back-to-top-rest), var(--back-to-top-lift));
    z-index: 1020; /* under the fixed header (1030) and every modal/offcanvas */
    display: flex;
    align-items: center;
    justify-content: center;
    width: 53px;
    height: 53px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background-color: #000;
    color: #fff;
    font-size: 1.65rem;
    line-height: 1;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
    opacity: 0;
    visibility: hidden; /* also takes it out of the tab order while invisible */
    transform: translateY(8px);
    transition: opacity 0.25s ease, transform 0.25s ease, visibility 0s linear 0.25s, background-color 0.2s ease;
}

.back-to-top.is-visible {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition: opacity 0.25s ease, transform 0.25s ease, visibility 0s, background-color 0.2s ease;
}

.back-to-top:hover,
.back-to-top:focus-visible {
    background-color: var(--by-dark-2);
}

.back-to-top:focus-visible {
    outline: 2px solid #fff;
    outline-offset: -4px;
}

@media (min-width: 576px) {
    .back-to-top {
        --back-to-top-content-width: 540px;
    }
}

@media (min-width: 768px) {
    .back-to-top {
        --back-to-top-content-width: 720px;
    }
}

@media (min-width: 992px) {
    .back-to-top {
        --back-to-top-content-width: 960px;
    }
}

@media (min-width: 1200px) {
    .back-to-top {
        --back-to-top-content-width: 1140px;
    }
}

@media (min-width: 1400px) {
    .back-to-top {
        --back-to-top-content-width: 1320px;
    }
}

@media print {
    .back-to-top {
        display: none;
    }
}

/* <x-seo-spec>: the list items of the special SEO text get the triangle of the old site, U+2BC8 (Nunito Sans has none,
the browser takes it from another font). Written as an escape so the file's encoding cannot garble it; the second
space is the one that shows, the first ends the escape. */
.seo-spec ul li {
    list-style-type: '\2BC8  ';
}

/* <x-empty-list>'s and <x-error-page>'s illustrations - shape/sizing (.faded-illustration)
is shared/css/base.css, only the URL (this group's own tinted copy) lives here, like
.hero-section's background-image above. */
.empty-list-img {
    background-image: url('../images/empty-list.jpg');
}

.error-illustration-404 {
    background-image: url('../images/error-404.jpg');
}

.error-illustration-500 {
    background-image: url('../images/error-500.jpg');
}

/* "Teilen" (<x-share>): BY's own pictures instead of the icon font's glyph in a coloured circle (Carsten, 2026-10-29):
one picture as it is, a second one under the mouse. Each service only names its two pictures (--share-img,
--share-img-hover, 120px PNGs shown at the button's 2.5rem); a service without them keeps share.css' look.
".share-links" in front: shared/css/share.css is loaded after this file and would otherwise win with its circle colour
and its darkening on hover. No rounding: the pictures bring their own shape, and the circle of share.css cut off their
edge. The ::after loads the second picture with the page, so the first hover does not flicker. */
.share-links .share-link--whatsapp {
    --share-img: url("../images/share/whatsapp.png");
    --share-img-hover: url("../images/share/whatsapp-hover.png");
}

.share-links .share-link--facebook {
    --share-img: url("../images/share/facebook.png");
    --share-img-hover: url("../images/share/facebook-hover.png");
}

.share-links .share-link--x {
    --share-img: url("../images/share/x.png");
    --share-img-hover: url("../images/share/x-hover.png");
}

.share-links .share-link--linkedin {
    --share-img: url("../images/share/linkedin.png");
    --share-img-hover: url("../images/share/linkedin-hover.png");
}

.share-links .share-link--email {
    --share-img: url("../images/share/email.png");
    --share-img-hover: url("../images/share/email-hover.png");
}

.share-links .share-link--copy {
    --share-img: url("../images/share/link.png");
    --share-img-hover: url("../images/share/link-hover.png");
}

/* The services above, once per rule: a new one is its two lines above plus its class in these four lists. */
.share-links :is(.share-link--whatsapp, .share-link--facebook, .share-link--x, .share-link--linkedin, .share-link--email, .share-link--copy) {
    --share-bg: transparent;
    border-radius: 0;
    background: var(--share-img) center / contain no-repeat;
}

.share-links :is(.share-link--whatsapp, .share-link--facebook, .share-link--x, .share-link--linkedin, .share-link--email, .share-link--copy) i {
    display: none;
}

.share-links :is(.share-link--whatsapp, .share-link--facebook, .share-link--x, .share-link--linkedin, .share-link--email, .share-link--copy)::after {
    content: "";
    width: 0;
    height: 0;
    background-image: var(--share-img-hover);
}

.share-links :is(.share-link--whatsapp, .share-link--facebook, .share-link--x, .share-link--linkedin, .share-link--email, .share-link--copy):is(:hover, :focus-visible) {
    background-image: var(--share-img-hover);
    filter: none;
}

/* Right after "copy" (share.js sets .is-copied for 2 seconds) the chain of the picture gives way to share.css' white
check mark, in a round box in the dark blue of the pictures (#1877a3), so the click still has its answer. After the
hover rule above, so it wins while the mouse is still on the button. */
.share-links .share-link--copy.is-copied {
    border-radius: 50%;
    background: #1877a3;
}

/* The request pages "Transport", "Versicherung" and "Gutachter" (shared/pages/partner-request, the card of
<x-static-page>): the heading (with the insurance partner's logo) stands above a grey box with the form, like the other
grey boxes of BY (Carsten, 2026-10-29: these three pages only). The card itself becomes invisible, only
.static-page-content inside it is the box. */
:is(.static-page-card--transport, .static-page-card--insurance, .static-page-card--expert) {
    background-color: transparent;
    border: 0;
}

:is(.static-page-card--transport, .static-page-card--insurance, .static-page-card--expert) > .card-body {
    padding: 0;
}

:is(.static-page-card--transport, .static-page-card--insurance, .static-page-card--expert) .static-page-content {
    background-color: var(--by-surface);
    border-radius: var(--by-radius);
    padding: 1.5rem;
}

/* "Finanzierung" (partner-request-financing): the white card stays, only without its border, and without the card's
padding, so the heading starts where it does on "Transport" and "Versicherung" (Carsten, 2026-10-29). Nothing of the
embedded yacht-finanz.de calculator is changed. */
.static-page-card--financing {
    border: 0;
}

.static-page-card--financing > .card-body {
    padding: 0;
}

/* The login hint on a guest's watchlist (<x-watchlist-login-hint>): grey like BY's other boxes, without the border
(Carsten, 2026-10-29). !important only against Bootstrap's .border utility, which sets the border with !important. */
.watchlist-login-hint {
    --bs-alert-bg: var(--by-surface);
    border: 0 !important;
}
