/*
 * Layout on top of the Pulse theme: fixed navbar, mobile tab bar, fixed audio player.
 * No colour values here - everything comes from the Bootstrap variables of the theme.
 */
:root {
    --nld-nav-h: 66px;     /* height of the fixed top navbar */
    --nld-tabbar-h: 4.6rem; /* height of the mobile tab bar incl. safe area */

    /*
     * Square corners everywhere (decided 23.09.2026). Every component of the theme builds its radius from
     * these variables, and so do the `.rounded*` utilities - setting them here covers cards, accordions,
     * buttons, form fields, pictures and modals at once, instead of chasing classes through the templates.
     *
     * The pill radius stays: it belongs to badges and switches, which are meant to read as round. So does
     * `.rounded-circle` (50%), which carries the round play buttons and the avatar of the navigation.
     * Deliberately rounded as well (decided 09.10.2026): the platform notices in the chat (`.bubble.notice`), so
     * they stand apart from the messages.
     */
    --bs-border-radius: 0;
    --bs-border-radius-sm: 0;
    --bs-border-radius-lg: 0;
    --bs-border-radius-xl: 0;
    --bs-border-radius-xxl: 0;
}

html {
    /* anchors must not end up behind the fixed navbar */
    scroll-padding-top: calc(var(--nld-nav-h) + .5rem);
}

/* the word mark new-lvl.dating (element brand_name): the name as written, ".dating" set off */
.nld-brand {
    letter-spacing: normal;
    text-transform: none;
    white-space: nowrap;
}

.nld-brand__tld {
    color: var(--bs-secondary);
}

/* the logo in the navbar: signet + word mark with the heart (img/logo/logo-inverse.svg, bin/cake logo_graphics) */
.nld-brand-logo {
    display: block;
    width: auto;
    height: 2.125rem;
}

/* footer, left side (element navigation/footer): copyright, BETA mark, 5data logo */
.nld-footer-meta__line {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    column-gap: .5rem;
    row-gap: .25rem;
}

.nld-footer-beta {
    padding: .1em .45em;
    border: 1px solid var(--bs-primary);
    color: var(--bs-primary);
    font-size: .7em;
    font-weight: 700;
    letter-spacing: .08em;
    line-height: 1.2;
}

.nld-footer-5data {
    width: auto;
    height: 1.1em;
    vertical-align: -.2em;
}

.nld-footer-5data-link {
    opacity: .85;
}

.nld-footer-5data-link:hover,
.nld-footer-5data-link:focus-visible {
    opacity: 1;
}

body {
    min-height: 100vh;
    padding-top: calc(var(--nld-nav-h) + .25rem);
    background: var(--bs-light);
}

/* a flash message under a notice bar (service notice, happy hour) keeps some air instead of sticking to it;
   closing a bar removes it, so the gap goes with it */
.service-notice ~ .nld-flash > .alert:first-child,
.happy-hour-notice ~ .nld-flash > .alert:first-child {
    margin-top: .75rem;
}

@media (max-width: 767.98px) {
    body {
        padding-bottom: var(--nld-tabbar-h);
    }
}

/* ---- list groups ----
 * Pulse puts list groups on a nearly black surface (--bs-list-group-bg: #17141f). Inside the light
 * layout that looks like a foreign body, so the group is moved back onto the light surfaces of the
 * theme. The active entry gets the same colours as an open accordion header - those are built from
 * the primary variables below, which unlike --bs-accordion-* are available on :root.
 */
.list-group {
    --bs-list-group-color: var(--bs-body-color);
    --bs-list-group-bg: var(--bs-body-bg);
    --bs-list-group-border-color: var(--bs-border-color);
    --bs-list-group-action-color: var(--bs-body-color);
    --bs-list-group-action-hover-color: var(--bs-body-color);
    --bs-list-group-action-hover-bg: var(--bs-secondary-bg);
    --bs-list-group-action-active-color: var(--bs-primary-text-emphasis);
    --bs-list-group-action-active-bg: var(--bs-primary-border-subtle);
    --bs-list-group-active-color: var(--bs-primary-text-emphasis);
    --bs-list-group-active-bg: var(--bs-primary-bg-subtle);
    --bs-list-group-active-border-color: var(--bs-primary-border-subtle);
    --bs-list-group-disabled-color: var(--bs-secondary-color);
    --bs-list-group-disabled-bg: var(--bs-body-bg);
}

/* Pulse also hardcodes white text and a dark hover on top of those variables - undo that as well */
.list-group-item {
    color: var(--bs-list-group-color);
}

/* plain items (no link, not active) have no hover - Pulse turns their text white there */
.list-group-item:not(.list-group-item-action):not(.active):hover,
.list-group-item:not(.list-group-item-action):not(.active):focus {
    color: var(--bs-list-group-color);
}

.list-group-item-action:hover,
.list-group-item-action:focus {
    color: var(--bs-list-group-action-hover-color);
    background-color: var(--bs-list-group-action-hover-bg);
}

.list-group-item.active,
.list-group-item.active:hover,
.list-group-item.active:focus {
    color: var(--bs-list-group-active-color);
    background-color: var(--bs-list-group-active-bg);
    font-weight: 500;
}

.list-group-item.disabled,
.list-group-item.disabled:hover {
    color: var(--bs-list-group-disabled-color);
    background-color: var(--bs-list-group-disabled-bg);
}

/* ---- top navbar ---- */
.navbar.fixed-top {
    padding-top: .5rem;
    padding-bottom: .5rem;
    min-height: var(--nld-nav-h);
}

.nav-avatar {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    color: var(--bs-white);
    background: linear-gradient(135deg, var(--bs-primary), var(--bs-secondary));
    flex: 0 0 auto;
}

/* ---- mobile tab bar ---- */
.tabbar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1030;
    background: var(--bs-body-bg);
    border-top: 1px solid var(--bs-border-color);
    padding-bottom: env(safe-area-inset-bottom);
}

.tabbar .nav {
    flex-wrap: nowrap;
}

.tabbar .nav-link {
    flex: 1;
    text-align: center;
    font-size: .7rem;
    padding: .45rem 0 .35rem;
    color: var(--bs-secondary-color);
}

.tabbar .nav-link i {
    display: block;
    font-size: 1.45rem;
    line-height: 1.15;
}

.tabbar .nav-link.active {
    color: var(--bs-primary);
}

.tabbar .badge {
    position: absolute;
    top: .25rem;
    left: calc(50% + .35rem);
}

/* ---- horizontally scrolling pill navigation (mobile sub navigation) ---- */
.subnav-scroll {
    overflow-x: auto;
    flex-wrap: nowrap;
    white-space: nowrap;
    scrollbar-width: none;
}

.subnav-scroll::-webkit-scrollbar {
    display: none;
}

/* the arrows on the side where more pills are hidden (profile-hub.js): a grey chevron on a fade into the page
   (the body background is --bs-light) */
.subnav-wrap {
    position: relative;
}

.subnav-arrow {
    position: absolute;
    top: 0;
    bottom: .25rem; /* the pb-1 of the pills */
    z-index: 2;
    display: flex;
    align-items: center;
    width: 2.75rem;
    padding: 0;
    border: 0;
    color: var(--bs-secondary-color);
    font-size: 1.1rem;
}

.subnav-arrow[hidden] {
    display: none;
}

.subnav-arrow--prev {
    left: 0;
    justify-content: flex-start;
    background: linear-gradient(to right, var(--bs-light) 45%, rgba(var(--bs-light-rgb), 0));
}

.subnav-arrow--next {
    right: 0;
    justify-content: flex-end;
    background: linear-gradient(to left, var(--bs-light) 45%, rgba(var(--bs-light-rgb), 0));
}

/* the tabs of a section's pages (Premium-Funktionen, Spotlight buchen, Umtauschen) scroll the same way. A scrolling
   list clips what hangs out of it, so the line under the tabs is drawn inside it and the active tab covers it
   with its own bottom border instead of its usual -1px margin */
.subnav-tabs {
    border-bottom: 0;
    box-shadow: inset 0 calc(-1 * var(--bs-nav-tabs-border-width)) 0 var(--bs-nav-tabs-border-color);
}

.subnav-tabs > .nav-item {
    flex-shrink: 0;
}

.subnav-tabs .nav-link {
    margin-bottom: 0;
}

.subnav-wrap--tabs .subnav-arrow {
    bottom: var(--bs-border-width); /* keeps the line under the tabs visible */
}

/* ---- fixed audio player of the finder (sits above the tab bar on phones) ---- */
#custom-audio-player {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 1031;
    padding: 10px;
    background-color: var(--bs-body-bg);
    border-top: 1px solid var(--bs-border-color);
    box-shadow: 0 -2px 10px rgba(0, 0, 0, .1);
}

@media (max-width: 767.98px) {
    #custom-audio-player {
        bottom: var(--nld-tabbar-h);
    }
}

/* ---- sticky side navigation below the fixed navbar ---- */
.sidebar-sticky {
    position: sticky;
    top: calc(var(--nld-nav-h) + 1rem);
}

/* ---- sticky save bar of long forms (sits above the tab bar on phones) ---- */
.sticky-actions {
    position: sticky;
    bottom: 0;
    z-index: 1020;
    background: var(--bs-body-bg);
    border-top: 1px solid var(--bs-border-color);
    padding: .6rem 0;
    margin-top: 1rem;
}

@media (max-width: 767.98px) {
    .sticky-actions {
        bottom: var(--nld-tabbar-h);
    }
}

/* inside the filter offcanvas the bar sits at the very bottom - the panel covers the tab bar */
.offcanvas-body .sticky-actions {
    bottom: 0;
}

.min-w-0 { min-width: 0; }

/* ---- messages ---- */
.msg-thumb {
    width: 48px;
    height: 48px;
    flex: 0 0 auto;
}

.conversation {
    height: calc(100vh - var(--nld-nav-h) - 3rem);
}

@media (max-width: 767.98px) {
    .conversation {
        height: calc(100vh - var(--nld-nav-h) - var(--nld-tabbar-h) - 1.5rem);
    }
}

.conversation-body {
    flex: 1 1 auto;
    overflow-y: auto;
    overscroll-behavior: contain;
    background: var(--bs-light);
}

/* the composer of a conversation grows with its text (webroot/js/conversation.js) */
.composer-input {
    resize: none;
    overflow-y: hidden;
}

/*
 * Messages of the two users are speech bubbles: the first bubble of a run gets a triangle at its top outer
 * corner, the top edge running out into the tip (square corners like everything else). The `margin` makes
 * room for the tip, so bubbles with and without a tail stay aligned.
 */
.bubble {
    position: relative;
    max-width: 80%;
    padding: .5rem .8rem;
    overflow-wrap: anywhere;
}

.bubble.me {
    margin-left: auto;
    margin-right: 12px;
    color: var(--bs-white);
    background: var(--bs-primary);
}

.bubble.me.tail::after {
    content: "";
    position: absolute;
    top: 0;
    right: -12px;
    width: 12px;
    height: 14px;
    background: var(--bs-primary);
    clip-path: polygon(0 0, 100% 0, 0 100%);
}

.bubble.them {
    margin-left: 13px;
    margin-right: auto; /* as wide as its text, like .me - the column would otherwise stretch it to max-width */
    background: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
}

/*
 * The bubble has a 1px border, so the tip takes two layers: the outline (::before, 12 x 14px from the outer
 * corner) and the fill on top (::after), whose slanted edge sits 1px further in. It also covers the border
 * of the bubble where the tip joins it. Positions count from the padding box, i.e. 1px inside the border.
 */
.bubble.them.tail::before,
.bubble.them.tail::after {
    content: "";
    position: absolute;
    clip-path: polygon(0 0, 100% 0, 100% 100%);
}

.bubble.them.tail::before {
    top: -1px;
    left: -13px;
    width: 13px;
    height: 14px;
    background: var(--bs-border-color);
}

.bubble.them.tail::after {
    top: 0;
    left: -10.7px;
    width: 10.7px;
    height: 11.5px;
    background: var(--bs-body-bg);
}

/* a notice of the platform (MessageKind), e.g. "has recorded new audios" - rounded on purpose (decided
   09.10.2026), the one exception to the square corners, so it stands apart from the messages */
.bubble.notice {
    margin: .25rem auto;
    text-align: center;
    background: var(--bs-primary-bg-subtle);
    border: 1px dashed var(--bs-primary-border-subtle);
    border-radius: .5rem;
}

.bubble.notice .bubble-meta {
    text-align: center;
}

.bubble-meta {
    display: block;
    margin-top: .15rem;
    font-size: .7rem;
    opacity: .75;
    text-align: right;
}

/* report a message of the other one (report.js): quiet until the bubble is hovered or the button focused */
.bubble-report {
    border: 0;
    background: none;
    padding: 0 .25rem 0 0;
    color: inherit;
    font-size: inherit;
    opacity: .5;
}

.bubble:hover .bubble-report,
.bubble-report:focus-visible {
    opacity: 1;
}

/*
 * Voice messages (webroot/js/chat-voice.js, chat-recorder.js): play button, waveform of the recorder (one bar
 * per peak, played bars stronger), time. The colours follow the bubble: white on the own one, primary on the
 * other one's and in the recorder.
 */
.bubble-voice {
    width: 18rem;
}

.voice {
    --voice-bar: rgba(var(--bs-secondary-rgb), .45);
    --voice-played: var(--bs-primary);
    display: flex;
    align-items: center;
    gap: .5rem;
}

.bubble.me .voice {
    --voice-bar: rgba(255, 255, 255, .45);
    --voice-played: var(--bs-white);
}

.voice-play {
    flex: 0 0 auto;
    width: 2.25rem;
    height: 2.25rem;
    padding: 0;
    border: 0;
    border-radius: 50%;
    color: var(--bs-white);
    background: var(--bs-primary);
    font-size: 1.25rem;
    line-height: 1;
}

.bubble.me .voice-play {
    color: var(--bs-primary);
    background: var(--bs-white);
}

.voice-play:disabled {
    opacity: .6;
}

.voice-wave {
    flex: 1 1 auto;
    min-width: 0;
    height: 2rem;
    display: flex;
    align-items: center;
    gap: 2px;
    cursor: pointer;
    touch-action: manipulation;
}

.voice-wave > span {
    flex: 1 1 0;
    min-width: 1px;
    background: var(--voice-bar);
}

.voice-wave > span.played {
    background: var(--voice-played);
}

.voice-time {
    flex: 0 0 auto;
    min-width: 2.5rem;
    font-size: .75rem;
    font-variant-numeric: tabular-nums;
    text-align: right;
}

/*
 * Speed button of every player of other profiles' audios (element/audio/rate_toggle, webroot/js/playback-rate.js):
 * Finder player, "Nochmal reinhören" tiles, voice messages. Outlined at 1x, filled when faster, a lock without
 * the membership. Follows the text colour - white on the own bubble.
 */
.rate-toggle {
    --rate-color: var(--bs-primary);
    --rate-contrast: var(--bs-white);
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: .2rem;
    min-width: 2.6rem;
    justify-content: center;
    padding: .15rem .45rem;
    border: 1px solid var(--rate-color);
    color: var(--rate-color);
    background: transparent;
    font-size: .75rem;
    font-weight: 600;
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
    vertical-align: middle;
    touch-action: manipulation;
}

.rate-toggle.is-fast {
    color: var(--rate-contrast);
    background: var(--rate-color);
}

.rate-toggle.is-locked {
    opacity: .7;
}

.rate-toggle .bi {
    font-size: .65rem;
}

.bubble.me .rate-toggle {
    --rate-color: var(--bs-white);
    --rate-contrast: var(--bs-primary);
}

.voice-expired {
    font-style: italic;
    opacity: .8;
}

/* the rows of the recorder are flex boxes: Bootstrap's `.d-flex` would win over `hidden` */
.voice-recorder [hidden] {
    display: none !important;
}

.voice-draft {
    padding: .25rem .5rem;
    border: 1px solid var(--bs-border-color);
    background: var(--bs-body-bg);
}

.voice-rec-dot {
    width: .6rem;
    height: .6rem;
    border-radius: 50%;
    background: var(--bs-danger);
    animation: voice-rec-blink 1s steps(2, start) infinite;
}

@keyframes voice-rec-blink {
    to {
        visibility: hidden;
    }
}

@media (prefers-reduced-motion: reduce) {
    .voice-rec-dot {
        animation: none;
    }
}

/* ---- finder filters (element/finder/filter_form, webroot/js/finder-filters.js) ---- */
.finder-wide-head { display: none; }

.finder-plan-chevron { transition: transform .2s; }
.finder-plan-toggle:not(.collapsed) .finder-plan-chevron { transform: rotate(180deg); }

@media (min-width: 992px) {
    /* never taller than the window: the column scrolls in itself and stays while the results scroll, so a few
       results do not stand next to a long column (the offcanvas has no position from lg up). The max-height is the
       fallback - finder-filters.js measures from where the column really starts, so "Filter anwenden" stays in view */
    .finder-filter-column {
        position: sticky;
        top: calc(var(--nld-nav-h) + 1rem);
        max-height: calc(100vh - var(--nld-nav-h) - 2rem);
        overflow-y: auto;
        overscroll-behavior: contain;
    }

    /* folding the plan cards is for phones - on a desktop they are open */
    .finder-plan-body.collapse { display: block; }
    .finder-plan-toggle { pointer-events: none; }
    .finder-plan-chevron { display: none; }

    /* from Premium on the column sums the plan filters up, the cards come with "Alle Filter" */
    .finder-filters--compact .finder-plan-card { display: none; }

    /* "Alle Filter": every card side by side over the whole width, instead of the results */
    .finder-page.is-wide .finder-aside { width: 100%; }
    .finder-page.is-wide .finder-results { display: none; }
    .finder-page.is-wide .finder-filter-column { position: static; max-height: none; overflow: visible; }
    .finder-page.is-wide .finder-filter-grid {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
        gap: 0 1rem;
        align-items: start;
    }
    .finder-page.is-wide .finder-plan-card { display: block; }
    .finder-page.is-wide .finder-plan-summary { display: none; }
    .finder-page.is-wide .finder-wide-head { display: flex; }
}

@media (max-width: 991.98px) {
    .finder-plan-summary { display: none; }
}

/* ---- finder (variant E: spotlight, Premium+ strip, mosaic blocks) ---- */
/* the wrapper is a flex box so the card fills its grid area, whether the tile spans one row or two */
.finder-item {
    display: flex;
    min-width: 0;
}

.finder-item > .card {
    flex: 1 1 auto;
    cursor: pointer;
}

.finder-item .card {
    display: flex;
    flex-direction: column;
}

.finder-item .background-layer {
    overflow: hidden;
    /* the picture grid keeps its height: a landscape picture sits in the middle of the tile, a portrait one
       that is taller than the tile starts at the top (safe) - stretching it would pull the rows apart */
    align-items: flex-start;
    align-items: safe center;
}

/* the picture grid keeps its own aspect ratio - let it fill the tile, the rest is cropped */
.finder-item .background-layer > * {
    width: 100%;
}

/* a step of the main picture effect (MainPictureRevealHelper): as wide as the tile, its own height like the
   puzzle; after an unlock the previous step lies on top and fades out (finder.js crossfade()) */
.reveal-step {
    position: relative;
}

.reveal-step__previous {
    position: absolute;
    top: 0;
    left: 0;
    display: block;
    width: 100%;
    height: auto;
    transition: opacity .9s ease;
}

.reveal-step__previous.is-fading {
    opacity: 0;
}

/* the effect cards of the main picture (element premium/reveal_preview): one strip of frames (steps, the whole
   picture, a pause), shown one frame at a time - the example photo or the own one (reveal-effects.js) */
.reveal-anim {
    width: 100%;
    max-width: 220px;
    margin: 0 auto;
    aspect-ratio: var(--ratio, 1 / 1);
    background-color: var(--bs-tertiary-bg);
    background-repeat: no-repeat;
    background-size: calc(var(--frames) * 100%) 100%;
    background-position: 0 0;
    animation: reveal-play calc(var(--frames) * .8s) steps(var(--frames), jump-none) infinite;
}

.reveal-anim:hover {
    animation-play-state: paused;
}

@keyframes reveal-play {
    from {
        background-position-x: 0%;
    }
    to {
        background-position-x: 100%;
    }
}

@media (prefers-reduced-motion: reduce) {
    .reveal-anim {
        animation: none;
        cursor: pointer;
    }
}

/* Fotos > Foto-Effekt: the point for "zoom out" and "spotlight" (reveal-effects.js) */

.reveal-point {
    position: relative;
    width: 200px;
    max-width: 100%;
    cursor: crosshair;
}

.reveal-point img {
    display: block;
    width: 100%;
}

.reveal-point__mark {
    position: absolute;
    width: 22px;
    height: 22px;
    margin: -11px 0 0 -11px;
    border: 2px solid #fff;
    border-radius: 50%;
    background: rgba(123, 63, 228, .6);
    box-shadow: 0 0 0 2px rgba(0, 0, 0, .45);
    pointer-events: none;
}

/* the tile size is the only thing the tiers buy - the content is identical everywhere */
.finder-item--tile .background-layer,
.finder-item--spotlight .background-layer {
    aspect-ratio: 1;
}

/* the large tile spans two rows, so its picture takes whatever the text leaves over */
.finder-item--large .background-layer {
    flex: 1 1 auto;
    min-height: 0;
}

.finder-item--strip .background-layer {
    aspect-ratio: 4 / 5;
}

.finder-tier-badge {
    position: absolute;
    top: .4rem;
    left: .4rem;
    z-index: 2;
}

/* report flag of a tile (report.js catches the click before the tile plays); above the effect layer */
.finder-report-btn {
    position: absolute;
    top: .4rem;
    right: .4rem;
    z-index: 4;
    width: 1.9rem;
    height: 1.9rem;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: .85;
}

/* Premium+ : swipeable strip */
.finder-strip {
    display: flex;
    gap: .5rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    /* room for the glow and the stars of tile effects - a scroll box clips them otherwise; the negative
       margin keeps the tiles where they were */
    padding: .75rem .5rem 1rem;
    margin: -.75rem -.5rem -.75rem;
    scroll-padding-inline: .5rem;
}

.finder-strip::-webkit-scrollbar {
    display: none;
}

/* the whole strip is Premium+, the heading says so once */
.finder-strip .finder-tier-badge {
    display: none;
}

.finder-strip > .finder-item {
    flex: 0 0 46%;
    scroll-snap-align: start;
}

@media (min-width: 576px) {
    .finder-strip > .finder-item { flex-basis: 31%; }
}

@media (min-width: 1200px) {
    .finder-strip > .finder-item { flex-basis: 23%; }
}

/* arrows of the strip (finder-strip.js) - only with a mouse, touch screens swipe */
.finder-strip-wrap {
    position: relative;
}

.finder-strip-nav {
    display: none;
    position: absolute;
    top: 50%;
    z-index: 3;
    width: 2.5rem;
    height: 2.5rem;
    padding: 0;
    align-items: center;
    justify-content: center;
    transform: translateY(-50%);
}

.finder-strip-nav--prev { left: .25rem; }
.finder-strip-nav--next { right: .25rem; }

@media (hover: hover) and (pointer: fine) {
    .finder-strip-nav:not([hidden]) { display: flex; }
}

/* mosaic: 3x2 per block, the Premium tile takes 2x2 and always sits on the left (reading direction) */
.finder-blocks {
    display: grid;
    gap: 1rem;
}

@media (min-width: 1200px) {
    .finder-blocks { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.finder-block {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-auto-rows: 1fr;
    gap: .5rem;
}

.finder-item--large {
    grid-column: span 2;
    grid-row: span 2;
}

/* the tile fills the picture column of the spotlight: the puzzle has no width of its own (a locked piece is an
   empty cell), so without this the tile shrank to 0 px and could not be tapped */
.finder-spotlight .finder-item {
    flex: 1 1 auto;
}

/* the spotlight card carries its own picture column: no second border, no second name below it */
.finder-spotlight .finder-item .card {
    border: 0;
    border-radius: 0;
    box-shadow: none !important;
}

.finder-spotlight .finder-item .card-body,
.finder-spotlight .finder-tier-badge {
    display: none;
}

.finder-spotlight .background-layer {
    aspect-ratio: auto;
    flex: 1 1 auto;
    min-height: 0;
}

/* Finder preview (Finder/preview.php): grey tiles standing for everybody else, not clickable */
.finder-placeholder > .card {
    cursor: default;
}

.finder-placeholder .background-layer {
    align-items: center;
}

.finder-placeholder .background-layer > i {
    font-size: 3rem;
    text-align: center;
    opacity: .35;
}

.finder-item--large.finder-placeholder .background-layer > i {
    font-size: 6rem;
}

/* a real spotlight takes its height from the puzzle - the placeholder has none, so it gets a square */
.finder-spotlight--placeholder .background-layer {
    aspect-ratio: 1;
}

/* ---------------------------------------------------------------------------------------------------------
 * Tile effects (App\Model\Enum\TileEffect, element/finder/tile_effect.php) and the golden spotlight.
 * A layer over the tile: frame, glow, sheen and particles never change its size or shape (square corners
 * like every tile), and it lets every click through to the tile. Particles: webroot/js/tile-effects.js.
 * ------------------------------------------------------------------------------------------------------- */
.finder-item {
    position: relative;
}

.tile-fx {
    position: absolute;
    inset: 0;
    z-index: 3;
    pointer-events: none;
    --fx-glow: rgba(123, 79, 208, .4);
    box-shadow: 0 0 14px 1px var(--fx-glow);
}

/* the frame: a 3 px ring cut out of a box (mask), so a gradient can run around it without covering the tile */
.tile-fx__ring {
    position: absolute;
    inset: 0;
    padding: 3px;
    overflow: hidden;
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
}

/* a running light: a large conic square spins behind the ring */
.tile-fx--spin .tile-fx__ring::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 250%;
    aspect-ratio: 1;
    transform: translate(-50%, -50%) rotate(0deg);
    animation: tile-fx-spin 4s linear infinite;
}

@keyframes tile-fx-spin {
    to { transform: translate(-50%, -50%) rotate(360deg); }
}

.tile-fx__sheen {
    position: absolute;
    inset: 0;
    overflow: hidden;
}

.tile-fx__sheen::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(115deg, transparent 30%, rgba(255, 255, 255, .7) 48%, rgba(255, 255, 255, .9) 50%, transparent 68%);
    transform: translateX(-130%);
    animation: tile-fx-sheen 4.5s ease-in-out infinite;
}

@keyframes tile-fx-sheen {
    0% { transform: translateX(-130%); }
    28%, 100% { transform: translateX(130%); }
}

@keyframes tile-fx-halo {
    0%, 100% { box-shadow: 0 0 8px 0 var(--fx-glow); }
    50% { box-shadow: 0 0 28px 5px var(--fx-glow); }
}

/* particles: stars and hearts on the frame line, placed by tile-effects.js */
.tile-fx__particles {
    position: absolute;
    inset: 0;
}

.tile-fx__p {
    position: absolute;
    left: 0;
    top: 0;
    width: 14px;
    height: 14px;
    margin: -7px 0 0 -7px;
    will-change: translate;
}

.tile-fx__p > i {
    display: block;
    width: 100%;
    height: 100%;
}

.tile-fx__p--star > i {
    clip-path: polygon(50% 0, 61% 39%, 100% 50%, 61% 61%, 50% 100%, 39% 61%, 0 50%, 39% 39%);
    animation: tile-fx-twinkle 1.3s ease-in-out infinite;
}

.tile-fx__p--heart > i {
    clip-path: path("M7 13 L1.4 7.3 A3.4 3.4 0 0 1 7 2.7 A3.4 3.4 0 0 1 12.6 7.3 Z");
    animation: tile-fx-beat 1.1s ease-in-out infinite;
}

@keyframes tile-fx-twinkle {
    0%, 100% { transform: scale(.5) rotate(0deg); opacity: .5; }
    50% { transform: scale(1.15) rotate(45deg); opacity: 1; }
}

@keyframes tile-fx-beat {

    0%, 100% { transform: scale(.75); opacity: .75; }
    20% { transform: scale(1.15); opacity: 1; }
    40% { transform: scale(.9); }
    60% { transform: scale(1.08); }
}

/* violet particles of the bookable effects */
.tile-fx__p--star { filter: drop-shadow(0 0 4px rgba(200, 107, 250, .95)); }
.tile-fx__p--star > i { background: linear-gradient(#fff, #e7c8ff); }
.tile-fx__p--heart { filter: drop-shadow(0 0 4px rgba(224, 95, 208, .95)); }
.tile-fx__p--heart > i { background: linear-gradient(#ffd6f5, #e05fd0); }

/* the effects */
.tile-fx--aura { animation: tile-fx-halo 2.8s ease-in-out infinite; --fx-glow: rgba(200, 107, 250, .6); }
.tile-fx--aura .tile-fx__ring { background: linear-gradient(135deg, #593196, #c86bfa); }

.tile-fx--colour-flow .tile-fx__ring::before {
    background: conic-gradient(#593196, #7b4fd0, #c86bfa, #e05fd0, #a991d4, #593196);
    animation-duration: 5s;
}

.tile-fx--stardust { --fx-glow: rgba(200, 107, 250, .4); }
.tile-fx--stardust .tile-fx__ring { background: linear-gradient(135deg, #7b4fd0, #c86bfa); }

.tile-fx--love-spell { --fx-glow: rgba(224, 95, 208, .45); }
.tile-fx--love-spell .tile-fx__ring { background: linear-gradient(135deg, #7b4fd0, #e05fd0); }

.tile-fx--shimmer { --fx-glow: rgba(169, 145, 212, .45); }
.tile-fx--shimmer .tile-fx__ring { background: linear-gradient(135deg, #593196, #a991d4, #c86bfa); }
.tile-fx--shimmer .tile-fx__sheen::after {
    background: linear-gradient(115deg, transparent 30%, rgba(233, 214, 255, .7) 48%, rgba(255, 255, 255, .85) 50%, transparent 68%);
}

.tile-fx--comet { --fx-glow: rgba(123, 79, 208, .35); }
.tile-fx--comet .tile-fx__ring { background: #593196; }
.tile-fx--comet .tile-fx__ring::before {
    background: conic-gradient(transparent 0 62%, rgba(200, 107, 250, .25) 78%, #f0d6ff 96%, #fff 100%);
    animation-duration: 3s;
}

/* the spotlight: always gold, whatever its profile booked - running light, breathing glow, sheen, stars and
   hearts */
.tile-fx--spotlight {
    --fx-glow: rgba(255, 196, 0, .6);
    animation: tile-fx-halo-gold 3s ease-in-out infinite;
}

@keyframes tile-fx-halo-gold {
    0%, 100% { box-shadow: 0 0 18px 2px rgba(255, 196, 0, .45); }
    50% { box-shadow: 0 0 40px 10px rgba(255, 196, 0, .7); }
}

.tile-fx--spotlight .tile-fx__ring::before {
    background: conic-gradient(#8a6d1d, #d4a017, #ffd700, #fff3b0, #fff, #fff3b0, #ffd700, #d4a017, #8a6d1d);
}

.tile-fx--spotlight .tile-fx__p--star { filter: drop-shadow(0 0 4px rgba(255, 210, 60, .95)); }
.tile-fx--spotlight .tile-fx__p--star > i { background: linear-gradient(#fff3b0, #ffd700); }
.tile-fx--spotlight .tile-fx__p--heart { filter: drop-shadow(0 0 4px rgba(255, 140, 170, .9)); }
.tile-fx--spotlight .tile-fx__p--heart > i { background: linear-gradient(#ffe7b0, #f2a93b); }

/* with "reduce motion" the frame and the glow stay, nothing moves */
@media (prefers-reduced-motion: reduce) {
    .tile-fx,
    .tile-fx *,
    .tile-fx *::before,
    .tile-fx *::after {
        animation: none !important;
    }

    .tile-fx__sheen,
    .tile-fx__particles {
        display: none;
    }
}

/* the hard filters with several values: seventeen orientations need their own scroll area */
.nld-choice-list {
    max-height: 14rem;
    overflow-y: auto;
}

/* the labels come from FormHelper and carry no class of their own, see element/form/value_checkboxes.php */
.nld-choice-list .form-check > label {
    margin-bottom: 0;
    cursor: pointer;
}

.nld-choice-list .form-check > input:disabled + label {
    color: var(--bs-secondary-color);
    cursor: default;
}

/* ---------------------------------------------------------------------------------------------------------
 * "Mein Profil" > Premium-Funktionen (templates/Premium): the spotlight shines gold, the tiers stay purple
 * ------------------------------------------------------------------------------------------------------- */
.nld-spotlight {
    border: 2px solid var(--bs-warning);
    box-shadow: 0 0 0 4px rgba(var(--bs-warning-rgb), .16);
    background: var(--bs-body-bg);
}

.nld-spotlight--shine {
    position: relative;
    /* the golden layer brings its own glow */
    box-shadow: none;
}

/* on top of the 2 px border, so the running light is the frame */
.nld-spotlight--shine > .tile-fx {
    inset: -2px;
}

.nld-spotlight > .nld-spotlight-head {
    background: var(--bs-warning-bg-subtle);
    border-bottom: 1px solid var(--bs-warning-border-subtle);
    color: var(--bs-warning-text-emphasis);
}

/* a running or announced happy hour on pages with prices (element/happy_hour/box.php) */
.nld-happy-box {
    border: 2px solid var(--bs-warning);
    border-left-width: 6px;
    background: linear-gradient(100deg, var(--bs-warning-bg-subtle), var(--bs-body-bg) 70%);
    color: var(--bs-warning-text-emphasis);
    padding: .75rem 1rem;
}

.nld-happy-box__icon {
    font-size: 1.25rem;
    line-height: 1;
}

/* the badge next to a discounted price or on a section head (HappyHourHelper::badge()) */
.nld-happy-badge {
    white-space: nowrap;
}

/* "Mein Profil" > Fotos: the main picture at a fixed width, so its card is only as high as its own content */
.nld-main-photo {
    width: 100%;
    max-width: 240px;
}

/* the head of each section of a page (element/section_head.php): badge, then a bar like a progress bar */
/* room before every section, more on wide screens */
.nld-section-head {
    margin-top: 2rem;
}

.nld-section-head:first-child {
    margin-top: 0;
}

@media (min-width: 768px) {
    .nld-section-head:not(:first-child) {
        margin-top: 3.5rem;
    }
}

.nld-section-bar {
    flex-grow: 1;
    height: 6px;
    border-radius: var(--bs-border-radius-pill);
    background: linear-gradient(90deg, var(--bs-primary), rgba(var(--bs-primary-rgb), .15));
}

/* something not available, e.g. a plan the profile does not have (Angaben) */
.nld-section-bar--muted {
    background: linear-gradient(90deg, var(--bs-secondary-color), rgba(var(--bs-secondary-rgb), .1));
    opacity: .5;
}

.nld-section-bar--gold {
    position: relative;
    overflow: hidden;
    background: linear-gradient(90deg, #d4a017, #ffd700 40%, rgba(255, 215, 0, .25));
    box-shadow: 0 0 8px rgba(255, 196, 0, .45);
}

/* a glint running along it, like the sheen on the spotlight card */
.nld-section-bar--gold::after {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    left: -30%;
    width: 30%;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .85), transparent);
    animation: nld-section-bar-sheen 4s ease-in-out infinite;
}

@keyframes nld-section-bar-sheen {
    0% { left: -30%; }
    60%, 100% { left: 100%; }
}

@media (prefers-reduced-motion: reduce) {
    .nld-section-bar--gold::after {
        display: none;
    }
}

/* "Premium-Funktionen" > Effekte: the own tile with the effect, small and not clickable */
.nld-effect-stage {
    display: flex;
    justify-content: center;
    padding: .75rem 0 .5rem;
}

.nld-effect-stage > .finder-item {
    width: 9.5rem;
}

.nld-effect-stage .card {
    cursor: default;
}

.nld-stat {
    font-size: 1.4rem;
    font-weight: 700;
    line-height: 1.1;
}

/* Admin > Übersicht: a chart of webroot/js/admin/dashboard.js (Chart.js needs a box with a fixed height) */
.nld-chart {
    position: relative;
    height: 220px;
}

/* head of an admin section (element/admin/section_head): a plain hairline instead of the badge + colour bar of the
   user pages, so the admin area reads as a tool */
.nld-admin-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    column-gap: .75rem;
    margin-bottom: .75rem;
    padding-bottom: .25rem;
    border-bottom: 1px solid var(--bs-primary-border-subtle);
    /* below the fixed navbar and the sticky jump navigation (.nld-admin-jump) */
    scroll-margin-top: 3rem;
}

.nld-admin-head__label {
    font-size: .8rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--bs-primary);
}

/* jump navigation of an admin page: plain text links, sticks under the fixed navbar */
.nld-admin-jump {
    position: sticky;
    top: var(--nld-nav-h);
    z-index: 10;
    display: flex;
    flex-wrap: wrap;
    gap: .25rem 1.25rem;
    padding: .4rem 0;
    background: var(--bs-body-bg);
    border-bottom: 1px solid var(--bs-border-color);
    font-size: .85rem;
}

.nld-admin-jump a {
    color: var(--bs-secondary-color);
    text-decoration: none;
}

.nld-admin-jump a:hover,
.nld-admin-jump a:focus-visible {
    color: var(--bs-primary);
}

.nld-admin-head__text {
    font-size: .8rem;
    color: var(--bs-secondary-color);
}

.nld-admin-section:hover {
    background: var(--bs-tertiary-bg);
}

/* the little drawings of where a tile sits in the Finder */
.nld-tier-sketch {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-auto-rows: 1.9rem;
    gap: 4px;
}

.nld-tier-sketch > span {
    background: var(--bs-border-color);
}

.nld-tier-sketch > .me {
    background: var(--bs-primary);
}

.nld-tier-sketch > .big {
    grid-column: span 2;
    grid-row: span 2;
}

.nld-tier-strip {
    display: flex;
    gap: 4px;
    margin-bottom: 4px;
}

.nld-tier-strip > span {
    width: 1.5rem;
    height: 2rem;
    background: var(--bs-primary);
}

.nld-tier-strip > span.more {
    background: var(--bs-secondary);
}

/* the groups of what a membership brings (Premium page, TierBenefitsService) */
.nld-benefit-head {
    margin-bottom: .2rem;
    padding-bottom: .15rem;
    border-bottom: 1px solid var(--bs-border-color);
    color: var(--bs-secondary-color);
    font-size: .7rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
}

/* the running membership, the chosen effect and the current plan: lifted a little towards the viewer, besides the purple border */
.nld-card-active {
    box-shadow: 0 .75rem 1.5rem -.5rem rgba(var(--bs-primary-rgb), .45), 0 .125rem .375rem rgba(0, 0, 0, .08);
    transform: translateY(-3px);
}

/* the head of a group of effect cards: Standard, free for all, Premium, Premium+ */
.nld-effect-group-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .25rem .5rem;
    margin-bottom: .5rem;
    font-size: .875rem;
}

/* one paragraph per membership below a line ("+ Sternenstaub, ...") */
.nld-benefit-detail + .nld-benefit-detail {
    margin-top: .2rem;
}

/* the calendar: one button per 30 minute block */
.nld-slots {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: .5rem;
}

@media (min-width: 768px) {
    .nld-slots {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

.nld-slot {
    position: relative; /* for the badge .nld-slot-badge */
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    padding: .55rem .75rem;
    border: 1px solid var(--bs-border-color);
    background: var(--bs-body-bg);
    color: var(--bs-body-color);
    cursor: pointer;
    user-select: none;
    margin: 0;
}

.nld-slot > small {
    color: var(--bs-secondary-color);
}

/* "−37 %" in the top right corner of a cheaper block (happy hour, running block), like a sticker - the same on the
   cards of the effects (element/premium/effect_cards.php; .card is positioned by Bootstrap) */
.nld-slot-badge,
.nld-sale-badge {
    position: absolute;
    top: -.55rem;
    right: -.35rem;
    font-size: .7rem;
    z-index: 1;
}

.nld-sale-badge {
    font-size: .8rem;
}

.nld-slot.peak {
    background: var(--bs-warning-bg-subtle);
    border-color: var(--bs-warning-border-subtle);
}

.nld-slot.peak > small {
    color: var(--bs-warning-text-emphasis);
}

.btn-check:checked + .nld-slot {
    background: var(--bs-primary);
    border-color: var(--bs-primary);
    color: #fff;
}

.btn-check:checked + .nld-slot > small {
    color: rgba(255, 255, 255, .85);
}

.btn-check:focus-visible + .nld-slot {
    outline: 2px solid var(--bs-primary);
    outline-offset: 2px;
}

.nld-slot.taken,
.nld-slot.past,
.nld-slot.unpriced {
    background: var(--bs-secondary-bg);
    border-color: var(--bs-secondary-bg);
    color: var(--bs-secondary-color);
    cursor: default;
}

.nld-slot.mine {
    background: var(--bs-primary-bg-subtle);
    border-color: var(--bs-primary-border-subtle);
    color: var(--bs-primary-text-emphasis);
    cursor: default;
}

.nld-legend {
    display: inline-block;
    width: .8rem;
    height: .8rem;
    border: 1px solid var(--bs-border-color);
    vertical-align: -1px;
}

/* the status strip on top of the page: stacked on phones, side by side from md up */
.nld-status > div + div {
    border-top: 1px solid var(--bs-border-color);
}

@media (min-width: 768px) {
    .nld-status > div + div {
        border-top: 0;
        border-left: 1px solid var(--bs-border-color);
    }

    /* every column the same width, whatever it holds - boxes on top of each other line up (11.10.2026) */
    .nld-status > .flex-fill {
        flex: 1 1 0 !important;
        min-width: 0;
    }
}

/* Photo gallery of the profile view (profile-gallery.js): one big stage, thumbnails below */
.nld-gallery-stage {
    position: relative;
    overflow: hidden;
    background: var(--bs-tertiary-bg);
}

.nld-gallery-stage > img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* same round light buttons as the arrows of the Premium+ strip (.finder-strip-nav), but always shown */
.nld-gallery-step {
    position: absolute;
    top: 50%;
    z-index: 3;
    width: 2.5rem;
    height: 2.5rem;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    transform: translateY(-50%);
}

.nld-gallery-step.prev {
    left: .5rem;
}

.nld-gallery-step.next {
    right: .5rem;
}

/* report the photo on the stage (report.js, profile-gallery.js moves it along) */
.nld-gallery-report {
    position: absolute;
    top: .5rem;
    right: .5rem;
    z-index: 3;
}

.nld-gallery-report .btn {
    width: 2.25rem;
    height: 2.25rem;
    padding: 0;
}

/* description of the shown photo as a quote on its lower edge, styled like the motto (accent bar, italic,
   German quotation marks); at most two lines and no space of its own, so a missing one moves nothing */
.nld-gallery-caption {
    position: absolute;
    left: .75rem;
    bottom: .75rem;
    max-width: calc(100% - 1.5rem);
    margin: 0;
    padding: .5rem .85rem .5rem .75rem;
    border-left: 3px solid var(--bs-primary);
    background: rgba(255, 255, 255, .9);
    background: color-mix(in srgb, var(--bs-body-bg) 90%, transparent);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .18);
    color: var(--bs-body-color);
    font-size: 1rem;
    font-style: italic;
    line-height: 1.4;
    pointer-events: none;
}

.nld-gallery-caption > span {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.nld-gallery-caption > span::before {
    content: "\201E";
}

.nld-gallery-caption > span::after {
    content: "\201C";
}

/* cut off: a tap shows the whole text (profile-gallery.js), at most as high as the photo */
.nld-gallery-caption.is-clamped,
.nld-gallery-caption.is-expanded {
    pointer-events: auto;
    cursor: pointer;
}

.nld-gallery-caption:focus-visible {
    outline: 2px solid var(--bs-primary);
    outline-offset: 2px;
}

.nld-gallery-caption.is-expanded {
    max-height: calc(100% - 1.5rem);
    overflow-y: auto;
}

.nld-gallery-caption.is-expanded > span {
    display: block;
    overflow: visible;
}

.nld-gallery-caption.is-new {
    animation: nld-caption-in .25s ease-out;
}

@keyframes nld-caption-in {
    from {
        opacity: 0;
        transform: translateY(.35rem);
    }
}

@media (prefers-reduced-motion: reduce) {
    .nld-gallery-caption.is-new {
        animation: none;
    }
}

@media (min-width: 768px) {
    .nld-gallery-caption {
        font-size: 1.0625rem;
    }
}

.nld-gallery-caption[hidden] {
    display: none;
}

.nld-gallery-thumb {
    width: 100%;
    padding: 0;
    border: 2px solid transparent;
    background: var(--bs-tertiary-bg);
    opacity: .7;
}

.nld-gallery-thumb:hover,
.nld-gallery-thumb:focus-visible,
.nld-gallery-thumb.active {
    opacity: 1;
}

.nld-gallery-thumb.active {
    border-color: var(--bs-primary);
}

.nld-gallery-thumb > img {
    object-fit: cover;
}

/* Currency symbols as inline SVG (CreditsHelper::icon()/iconAmount()), 1em = as large as the text */
.currency-icon {
    display: inline-block;
    flex-shrink: 0;
    vertical-align: -.15em;
}

.currency-amount {
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.currency-amount > .currency-icon {
    margin-right: .25em;
}

/* ---- Badges (FLAMMEN_KONZEPT.md) ----------------------------------------------------------------------------
 * element/badge/medal: the graphic of a level (BadgeHelper, webroot/img/badges/), the blank one-colour graphic in grey
 * while not reached, a level pale while it waits for its holding time. */
.nld-medal {
    --nld-medal-size: 2.5rem;
    display: inline-flex;
    flex-shrink: 0;
    width: var(--nld-medal-size);
    height: var(--nld-medal-size);
}
.nld-medal > svg {
    display: block;
    width: 100%;
    height: 100%;
}
/* Profile page on desktop: the chosen badges below the photos, loose on the background - at most four in a row,
   the fewer the bigger, up to a cap (element/profile/badges, layout grid) */
.nld-profile-badges {
    --nld-badge-cols: 4;
    --nld-badge-gap: 1rem;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--nld-badge-gap);
}
.nld-profile-badge {
    display: flex;
    flex: 0 0 calc((100% - (var(--nld-badge-cols) - 1) * var(--nld-badge-gap)) / var(--nld-badge-cols));
    flex-direction: column;
    align-items: center;
    gap: .4rem;
    max-width: 5rem;
    min-width: 0;
    text-align: center;
    line-height: 1.2;
}
.nld-profile-badge .nld-medal {
    width: 100%;
    height: auto;
    aspect-ratio: 1;
}
.nld-medal--waiting { opacity: .45; }
.nld-medal--none { color: var(--bs-secondary-color); opacity: .6; }

/* ---- highlights from other services (element embed/frame, CONSENT_KONZEPT.md) ---- */
.embed-frame {
    width: 100%;
    aspect-ratio: 16 / 9;
}

.embed-frame iframe {
    display: block;
    width: 100%;
    height: 100%;
    border: 0;
}

.embed-consent {
    background: var(--bs-body-bg);
}

/* the logo stands on the background its brand rules allow, with room around it */
.embed-consent__logo {
    display: inline-block;
    padding: .5rem;
}

/* ---- one-time notice about cookies and external content (element cookie_notice) ---- */
.cookie-notice {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1035;
    background: var(--bs-body-bg);
    border-top: 1px solid var(--bs-border-color);
    box-shadow: 0 -2px 10px rgba(0, 0, 0, .1);
}

@media (max-width: 767.98px) {
    .cookie-notice--above-tabbar {
        bottom: var(--nld-tabbar-h);
    }
}

/* ---- surveys (UMFRAGEN_KONZEPT.md, templates/Surveys, element/survey) ---- */
/* banner: a block in the primary colour until an image is uploaded; narrow on the question pages */
.nld-survey-banner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .25rem .75rem;
    min-height: 9rem;
    padding: 1.5rem;
    background: var(--bs-primary);
    color: #fff;
}

.nld-survey-banner--small {
    min-height: 0;
    padding: .5rem .75rem;
}

.nld-survey-banner__icon {
    font-size: 1.75rem;
}

.nld-survey-banner--small .nld-survey-banner__icon {
    font-size: 1rem;
}

.nld-survey-banner__title {
    font-size: 1.35rem;
    font-weight: 500;
}

.nld-survey-banner--small .nld-survey-banner__title {
    font-size: .9rem;
}

.nld-survey-banner__sponsor {
    margin-left: auto;
    font-size: .75rem;
    opacity: .9;
}

.nld-survey-option:has(.form-check-input:checked) {
    border-color: var(--bs-primary) !important;
    background: rgba(var(--bs-primary-rgb), .06);
}

/* a scale: equal square buttons; 1-10 in two rows of five on phones */
.nld-survey-scale__buttons {
    display: grid;
    grid-template-columns: repeat(var(--nld-scale-count), minmax(2.5rem, 3.25rem));
    gap: .25rem;
}

.nld-survey-scale__ends {
    display: flex;
    justify-content: space-between;
    max-width: calc(var(--nld-scale-count) * 3.5rem);
    margin-top: .25rem;
}

@media (max-width: 575.98px) {
    .nld-survey-scale[style*="--nld-scale-count: 10"] .nld-survey-scale__buttons {
        grid-template-columns: repeat(5, minmax(2.5rem, 1fr));
    }

    .nld-survey-scale[style*="--nld-scale-count: 11"] .nld-survey-scale__buttons {
        grid-template-columns: repeat(6, minmax(2.5rem, 1fr));
    }
}

.nld-survey-ranking__handle {
    cursor: grab;
}

.nld-survey-ranking .sortable-ghost {
    opacity: .4;
}

/* hint of a survey bound to this page (element survey/hint): a bar above the tab bar on phones, a card in the
   bottom right corner from md up */
.nld-survey-hint {
    position: fixed;
    left: 0;
    right: 0;
    bottom: var(--nld-tabbar-h);
    z-index: 1031;
    padding: .6rem 1rem;
    background: var(--bs-body-bg);
    border-top: 3px solid var(--bs-primary);
    box-shadow: 0 -2px 10px rgba(0, 0, 0, .12);
}

@media (min-width: 768px) {
    .nld-survey-hint {
        left: auto;
        right: 1.25rem;
        bottom: 1.25rem;
        width: 23rem;
        padding: .85rem 1rem;
        border: 1px solid var(--bs-border-color);
        border-top: 3px solid var(--bs-primary);
        box-shadow: 0 .5rem 1.5rem rgba(0, 0, 0, .15);
    }
}

.nld-survey-hint .min-w-0 {
    min-width: 0;
}

/* uploaded survey banner (Media/SurveyStorage): the cut keeps its ratio, a sponsor label sits on it */
.nld-survey-banner-image {
    position: relative;
    aspect-ratio: 3 / 1;
    background: var(--bs-secondary-bg);
}

.nld-survey-banner-image--small {
    aspect-ratio: 7.5 / 1;
}

.nld-survey-banner-image img {
    height: 100%;
    object-fit: cover;
}

.nld-survey-banner-image .nld-survey-banner__sponsor {
    position: absolute;
    right: .5rem;
    bottom: .4rem;
    padding: .1rem .4rem;
    background: rgba(0, 0, 0, .55);
    color: #fff;
}

/* Admin > Umfragen > Allgemein: regions country > state > districts (element/admin/survey/region_picker) */
.nld-region-picker__list {
    max-height: 22rem;
    overflow-y: auto;
}

.nld-region-picker__country {
    position: sticky;
    top: 0;
    z-index: 1;
    padding: .25rem .5rem;
    background: var(--bs-tertiary-bg);
    font-size: .8rem;
    font-weight: 600;
    color: var(--bs-secondary-color);
    text-transform: uppercase;
    letter-spacing: .03em;
}

.nld-region-picker__row {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .2rem .5rem;
}

.nld-region-picker__row:hover {
    background: var(--bs-secondary-bg);
}

.nld-region-picker__row label {
    cursor: pointer;
}

.nld-region-picker__districts .nld-region-picker__row {
    padding-left: 2rem;
}

/* Admin > Umfragen > Ergebnisse (element/survey/result/*): a bar per option, the scale chart, the texts */
.nld-survey-bar {
    height: .5rem;
    background: var(--bs-secondary-bg);
}

.nld-survey-bar__fill {
    height: 100%;
    background: var(--bs-primary);
}

.nld-chart--small {
    height: 160px;
}

.nld-survey-texts {
    max-height: 20rem;
    overflow-y: auto;
}

/* the logo of a survey sponsor (element survey/sponsor) */
.nld-survey-sponsor-logo {
    width: 4rem;
    height: 4rem;
    object-fit: contain;
}

/* Profile page: when the Profile was last seen (LastSeen), a dot from green (just now) to red (long ago) */
.nld-seen-dot {
    display: inline-block;
    width: .55rem;
    height: .55rem;
    margin-right: .35rem;
    border-radius: 50%;
    vertical-align: .05em;
}

.nld-seen-dot--day {
    background: var(--bs-success);
}

.nld-seen-dot--three-days {
    background: #7cbf3a;
}

.nld-seen-dot--week {
    background: var(--bs-warning);
}

.nld-seen-dot--a-while {
    background: #f0702a;
}

.nld-seen-dot--long-ago {
    background: var(--bs-danger);
}
