/* ==========================================================================
   Strehëza — site-wide rules that utilities cannot express.
   Tailwind handles the layout and styling; these rules cover the rest.
   1. Interface is never selected or dragged   2. Scrollbars   3. Fields
   4. Brand button   5. Header   6. Search bar   7. Favorite hearts
   8. Entrance reveal   9. Overlays   10. Loading states   11. Property cards
   12. Reduced motion
   ========================================================================== */

/* 1. Interface elements are never selected or dragged like a document */

/* The page never bounces or stretches past its top and bottom edges, with a trackpad,
   a mouse or a finger, and a sideways trackpad swipe never pulls the page away */
html,
body {
    overscroll-behavior: none;
}

img,
svg,
picture,
video,
canvas {
    -webkit-user-select: none;
    user-select: none;
    -webkit-user-drag: none;
    -webkit-touch-callout: none;
}

a,
button,
label,
legend,
nav,
summary,
select,
option,
input[type='checkbox'],
input[type='radio'],
input[type='range'],
input[type='file'],
input[type='button'],
input[type='submit'],
input[type='reset'],
input[type='color'],
input::file-selector-button,
[role='button'],
[role='switch'],
[role='tab'],
[role='tablist'],
[role='option'],
[role='listbox'],
[role='menu'],
[role='menuitem'],
[role='group'],
[aria-pressed],
[data-ui] {
    -webkit-user-select: none;
    user-select: none;
}

a,
button,
label,
[role='button'],
[role='option'],
[role='menuitem'] {
    -webkit-user-drag: none;
    -webkit-touch-callout: none;
}

/* Typing fields stay selectable and editable, and so do body copy, prices and contact
   details marked to be copied */
input:not([type='checkbox']):not([type='radio']):not([type='range']):not([type='file']):not([type='button']):not([type='submit']):not([type='reset']):not([type='color']),
textarea,
[contenteditable='true'],
.select-text,
.select-text * {
    -webkit-user-select: text;
    user-select: text;
}

/* Touch screens: no grey flash on tap, no double-tap zoom wait, steady text size */
html {
    -webkit-tap-highlight-color: transparent;
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

a,
button,
label,
summary,
[role='button'],
[role='tab'],
[role='option'] {
    touch-action: manipulation;
}

/* 2. Scrollbars in the colors of the site */
html {
    scrollbar-color: hsl(var(--foreground) / 0.28) hsl(var(--background));
}

* {
    scrollbar-width: thin;
}

::-webkit-scrollbar {
    width: 12px;
    height: 12px;
}

::-webkit-scrollbar-track {
    background: transparent;
}

::-webkit-scrollbar-thumb {
    background-color: hsl(var(--foreground) / 0.2);
    border: 3px solid transparent;
    border-radius: 999px;
    background-clip: content-box;
}

::-webkit-scrollbar-thumb:hover {
    background-color: hsl(var(--foreground) / 0.4);
}

.dark ::-webkit-scrollbar-thumb {
    background-color: hsl(var(--muted-foreground) / 0.45);
}

/* Horizontal swipe rows hide their bar */
.no-scrollbar {
    scrollbar-width: none;
}

.no-scrollbar::-webkit-scrollbar {
    display: none;
}

/* 3. Fields without browser decorations */
input[type='number'] {
    -moz-appearance: textfield;
    appearance: textfield;
}

input[type='number']::-webkit-outer-spin-button,
input[type='number']::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

input[type='search']::-webkit-search-cancel-button,
input[type='search']::-webkit-search-decoration {
    -webkit-appearance: none;
}

/* Phones never zoom into a field when it is tapped (that happens below 16px) */
@media (pointer: coarse) {
    input:not([type='checkbox']):not([type='radio']):not([type='range']),
    textarea,
    select {
        font-size: max(16px, 1em);
    }
}

input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus {
    -webkit-box-shadow: 0 0 0 40px hsl(var(--background)) inset;
    -webkit-text-fill-color: hsl(var(--foreground));
}

/* 4. Brand button: a red gradient whose light follows the pointer */
.btn-brand {
    color: hsl(var(--primary-foreground));
    background-color: hsl(var(--primary));
    background-image: linear-gradient(
        to right,
        hsl(var(--brand-from)) 0%,
        hsl(var(--primary)) 50%,
        hsl(var(--brand-to)) 100%
    );
}

@media (hover: hover) {
    .btn-brand:hover:not(:disabled) {
        background-image: radial-gradient(
            circle at var(--mx, 50%) var(--my, 50%),
            hsl(var(--brand-from)) 0%,
            hsl(var(--primary)) 32%,
            hsl(var(--brand-to)) 100%
        );
    }
}

.btn-brand:disabled {
    opacity: 0.7;
}

/* The tagline: "në një vend" in the same red gradient as the brand buttons */
.text-brand {
    color: hsl(var(--primary));
    background-image: linear-gradient(
        to right,
        hsl(var(--brand-from)) 0%,
        hsl(var(--primary)) 55%,
        hsl(var(--brand-to)) 100%
    );
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    -webkit-box-decoration-break: clone;
    box-decoration-break: clone;
}

/* 5. Header: full search at the top, compact pill once the page scrolls */
html .site-header {
    transition: box-shadow 0.2s ease;
}

html .site-header.is-scrolled {
    box-shadow: 0 1px 0 hsl(var(--hairline));
}

@media (min-width: 768px) {
    html .site-header {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
    }

    html .site-header[data-variant='static'] {
        position: absolute;
    }

    html .site-header.is-scrolled {
        box-shadow: none;
    }

    .hdr-spacer {
        height: 81px;
    }

    .site-header[data-variant='expanded'] + .hdr-spacer {
        height: 171px;
    }
}

html .hdr-tabs,
html .hdr-search,
html .hdr-pill {
    transition-property: opacity, transform, visibility, height, box-shadow;
    transition-duration: 0.2s, 0.32s, 0s, 0.32s, 0.2s;
    transition-timing-function: ease, cubic-bezier(0.2, 0.8, 0.2, 1), linear, cubic-bezier(0.2, 0.8, 0.2, 1), ease;
}

html .hdr-tabs {
    opacity: 0;
    visibility: hidden;
    transform: translateY(-12px) scale(0.92);
    pointer-events: none;
    transition-delay: 0s, 0s, 0.32s, 0s, 0s;
}

html .hdr-search {
    height: 0;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-40px) scale(0.62);
    transform-origin: 50% 0;
    pointer-events: none;
    transition-delay: 0s, 0s, 0.32s, 0s, 0s;
}

html .hdr-pill {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition-delay: 0s;
}

html .hdr-pill:hover {
    box-shadow: 0 2px 4px rgb(0 0 0 / 0.18);
}

html .site-header[data-variant='expanded']:not(.is-scrolled) .hdr-tabs,
html .site-header.is-open .hdr-tabs {
    opacity: 1;
    visibility: visible;
    transform: none;
    pointer-events: auto;
    transition-delay: 0s;
}

html .site-header[data-variant='expanded']:not(.is-scrolled) .hdr-search,
html .site-header.is-open .hdr-search {
    height: 90px;
    opacity: 1;
    visibility: visible;
    transform: none;
    pointer-events: auto;
    transition-delay: 0s;
}

html .site-header[data-variant='expanded']:not(.is-scrolled) .hdr-pill,
html .site-header.is-open .hdr-pill {
    opacity: 0;
    visibility: hidden;
    transform: translateY(24px) scale(1.35);
    pointer-events: none;
    transition-delay: 0s, 0s, 0.32s, 0s, 0s;
}

/* Home: the full search sits in the intro, so the top line keeps only the logo and the
   account; the compact pill slides into that line once the search scrolls under it */
html .site-header[data-variant='hero']:not(.is-scrolled):not(.is-open) .hdr-pill {
    opacity: 0;
    visibility: hidden;
    transform: translateY(10px) scale(0.94);
    pointer-events: none;
    transition-delay: 0s, 0s, 0.32s, 0s, 0s;
}

html .hdr-search.in-hero {
    height: auto;
    opacity: 1;
    visibility: visible;
    transform: none;
    pointer-events: auto;
    transition: none;
}

.hero-search-slot {
    min-height: 66px;
}

.hdr-search.in-hero .search-bar {
    margin-left: 0;
    border-color: transparent;
    box-shadow: 0 10px 30px rgb(0 0 0 / 0.28);
}

.hdr-search.in-hero .search-bar .search-panel {
    color: hsl(var(--foreground));
}

.hdr-backdrop {
    position: fixed;
    inset: 0;
    z-index: 45;
    background-color: hsl(var(--scrim) / 0.35);
    opacity: 0;
    visibility: hidden;
    transition:
        opacity 0.25s ease,
        visibility 0s linear 0.25s;
}

.hdr-backdrop.is-visible {
    opacity: 1;
    visibility: visible;
    transition-delay: 0s;
}

/* The illustrated tab icons bounce gently on hover */
.tab-ico {
    transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}

@media (hover: hover) {
    [data-tab]:hover .tab-ico {
        transform: translateY(-2px) scale(1.08) rotate(-4deg);
    }
}

/* Phones: the search pill and the tabs stay pinned at the top, and once the page
   scrolls the tab pictures fold away so more listings fit on the screen */
.mtabs {
    height: 66px;
    transition: height 0.28s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.mtab-ico {
    transition:
        height 0.28s cubic-bezier(0.2, 0.8, 0.2, 1),
        opacity 0.18s ease,
        transform 0.28s cubic-bezier(0.2, 0.8, 0.2, 1);
}

@media (max-width: 767.98px) {
    html .site-header[data-mobile='tabs'] {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
    }

    .site-header[data-mobile='tabs'] + .hdr-spacer {
        display: block;
        height: 80px;
    }

    html .site-header[data-mobile='tabs'].is-scrolled {
        box-shadow: 0 2px 14px rgb(0 0 0 / 0.08);
    }

    .site-header.is-scrolled .mtabs {
        height: 46px;
    }

    .site-header.is-scrolled .mtab-ico {
        height: 0;
        opacity: 0;
        transform: scale(0.6);
    }
}

/* Property page on phones: a slim bar with back, share and save slides in after the photos */
.mtop {
    transform: translateY(-100%);
    opacity: 0;
    transition:
        transform 0.28s cubic-bezier(0.2, 0.8, 0.2, 1),
        opacity 0.2s ease;
}

.mtop.is-visible {
    transform: none;
    opacity: 1;
}

/* Phone navigation slides away while scrolling down */
.bottom-nav {
    transition: transform 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.bottom-nav.is-hidden {
    transform: translateY(100%);
}

.menu-pop:not(.hidden) {
    animation: pr-drop 0.18s cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* 6. Search bar: the active part lifts out of a grey bar */
.search-bar {
    transition: background-color 0.2s ease;
}

.search-bar.is-active {
    background-color: hsl(var(--hairline));
}

.search-seg {
    border-radius: 9999px;
    transition:
        background-color 0.2s ease,
        box-shadow 0.2s ease;
}

.search-seg:hover {
    background-color: hsl(var(--hairline));
}

.search-bar.is-active .search-seg:hover {
    background-color: hsl(var(--border));
}

.search-seg.is-active,
.search-bar.is-active .search-seg.is-active:hover {
    background-color: hsl(var(--background));
    box-shadow: 0 6px 20px rgb(0 0 0 / 0.2);
}

.search-div {
    flex: none;
    width: 1px;
    height: 32px;
    background-color: hsl(var(--border));
    transition: opacity 0.2s ease;
}

.search-seg:hover + .search-div,
.search-seg.is-active + .search-div,
.search-div:has(+ .search-seg:hover),
.search-div:has(+ .search-seg.is-active) {
    opacity: 0;
}

.search-btn-label {
    max-width: 0;
    opacity: 0;
    overflow: hidden;
    white-space: nowrap;
    transition:
        max-width 0.3s ease,
        opacity 0.2s ease,
        margin 0.3s ease;
}

.search-bar.is-active .search-btn-label {
    max-width: 90px;
    opacity: 1;
    margin-left: 8px;
}

/* Rent or sale now lives inside the search filters, so the old header tabs stay out of view */
.hdr-tabs,
.mtabs {
    display: none !important;
}

/* Two ways to search: in plain words (first) or with filters */
.search-bar[data-mode] {
    max-width: 920px;
}

.search-bar[data-mode='filters'] {
    max-width: 1080px;
}

.search-bar[data-mode='ai'] > .search-div,
.search-bar[data-mode='ai'] > [data-seg]:not([data-seg='ai']),
.search-bar[data-mode='filters'] > [data-seg='ai'] {
    display: none;
}

.search-mode-in {
    animation: pr-fade 0.25s ease;
}

/* The compact pill of the scrolled header shows the same way of searching */
.hdr-pill:not([data-mode='ai']) > [data-pill-part='ai'],
.hdr-pill[data-mode='ai'] > [data-pill-part='f'] {
    display: none;
}

.hdr-pill [data-pill-part='ai'] {
    animation: pr-fade 0.25s ease;
}

.search-panel {
    position: absolute;
    top: calc(100% + 12px);
    z-index: 60;
    padding: 16px;
    border-radius: 32px;
    background-color: hsl(var(--background));
    box-shadow: 0 6px 20px rgb(0 0 0 / 0.2);
    animation: pr-drop 0.2s cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* 7. Favorite hearts: dark see-through on photos, red once saved */
.fav-heart {
    fill: hsl(var(--foreground) / 0.5);
    stroke: hsl(var(--background));
    transition: fill 0.15s ease;
}

[aria-pressed='true'] > .fav-heart {
    fill: hsl(var(--primary));
}

.fav-heart-plain {
    fill: none;
    stroke: currentColor;
    transition:
        fill 0.15s ease,
        stroke 0.15s ease;
}

[aria-pressed='true'] > .fav-heart-plain {
    fill: hsl(var(--primary));
    stroke: hsl(var(--primary));
}

/* 8. One calm entrance for every section and grouped item */
.rv {
    transition:
        opacity 0.6s cubic-bezier(0.22, 1, 0.36, 1),
        transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
    transition-delay: var(--rv-delay, 0ms);
}

.rv-hide {
    opacity: 0;
    transform: translate3d(0, 16px, 0);
}

/* 9. Overlays */
.toast-pill {
    animation: pr-rise 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}

.toast-pill.toast-out {
    opacity: 0;
    transform: translateY(8px);
    transition:
        opacity 0.25s ease,
        transform 0.25s ease;
}

/* One black for every overlay: the windows, the open search bar and the photo viewer */
:root {
    --scrim: 0 0% 0%;
}

html .modal-backdrop {
    background-color: hsl(var(--scrim) / 0.6);
}

html .lightbox {
    background-color: hsl(var(--scrim));
}

.modal-backdrop,
.lightbox {
    animation: pr-fade 0.2s ease;
}

.modal-panel {
    animation: pr-sheet 0.32s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.msheet,
.photo-tour {
    animation: pr-up 0.32s cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* Sign-in window: a tall sheet from the bottom on phones, a centered card on larger screens */
@media (max-width: 767.98px) {
    .auth-sheet {
        height: calc(100% - max(12px, env(safe-area-inset-top, 0px) + 8px));
        border-radius: 20px 20px 0 0;
    }

    .auth-body {
        padding-bottom: calc(2rem + env(safe-area-inset-bottom, 0px));
    }
}

/* Each step of the sign-in window slides in from the side it comes from */
.am-step {
    animation: pr-step 0.28s cubic-bezier(0.2, 0.8, 0.2, 1);
}

@keyframes pr-step {
    from {
        opacity: 0;
        transform: translateX(var(--am-dir, 16px));
    }
    to {
        opacity: 1;
        transform: none;
    }
}

@keyframes pr-rise {
    from {
        opacity: 0;
        transform: translateY(12px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

@keyframes pr-fade {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

@keyframes pr-sheet {
    from {
        opacity: 0;
        transform: translateY(40px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

@keyframes pr-up {
    from {
        opacity: 0;
        transform: translateY(24px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

@keyframes pr-drop {
    from {
        opacity: 0;
        transform: translateY(-6px) scale(0.98);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

/* 10. Loading states */
.skeleton {
    background-color: hsl(var(--secondary));
    background-image: linear-gradient(
        90deg,
        hsl(var(--secondary)) 0%,
        hsl(var(--hairline)) 50%,
        hsl(var(--secondary)) 100%
    );
    background-size: 200% 100%;
    animation: pr-shimmer 1.4s linear infinite;
}

@keyframes pr-shimmer {
    from {
        background-position: 200% 0;
    }
    to {
        background-position: -200% 0;
    }
}

.is-loading {
    opacity: 0.5;
    pointer-events: none;
    transition: opacity 0.2s ease;
}

/* 11. Property cards: on hover the lower part of the photo darkens with the same black as
   every overlay and shows the title and the facts with their icons, while the upper part stays
   light so the photos that play one after the other remain clearly visible */
.lcard-info {
    background-image: linear-gradient(
        to bottom,
        hsl(var(--scrim) / 0.1) 0%,
        hsl(var(--scrim) / 0.22) 40%,
        hsl(var(--scrim) / 0.62) 72%,
        hsl(var(--scrim) / 0.82) 100%
    );
    opacity: 0;
    transition: opacity 0.22s ease;
}

/* The photos a card plays while the pointer rests on it: each one fades in over the last */
.lcard-img.lcard-slide {
    opacity: 0;
    transition:
        opacity 0.45s ease,
        transform 0.6s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.lcard-img.lcard-slide.is-on {
    opacity: 1;
}

/* Small dots at the foot of the photo show where the visitor is among the photos */
.lcard-dots {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 7px;
    z-index: 3;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.25s ease;
}

.lcard-dots.is-on {
    opacity: 1;
}

.lcard-dot {
    width: 6px;
    height: 6px;
    border-radius: 999px;
    background-color: hsl(0 0% 100% / 0.55);
    box-shadow: 0 0 3px rgb(0 0 0 / 0.35);
    transition:
        background-color 0.25s ease,
        transform 0.25s ease;
}

.lcard-dot.is-active {
    background-color: hsl(0 0% 100%);
}

.lcard-dot.is-small {
    transform: scale(0.66);
}

@media (prefers-reduced-motion: reduce) {
    .lcard-img.lcard-slide,
    .lcard-dots,
    .lcard-dot {
        transition: none !important;
    }
}

.lcard-avatar {
    transition: opacity 0.22s ease;
}

.lcard-img {
    transition: transform 0.6s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.lcard:has(a:focus-visible) .lcard-info {
    opacity: 1;
}

.lcard:has(a:focus-visible) .lcard-avatar {
    opacity: 0;
}

@media (hover: hover) and (pointer: fine) {
    .lcard:hover .lcard-info {
        opacity: 1;
    }

    .lcard:hover .lcard-avatar {
        opacity: 0;
    }

    .lcard:hover .lcard-img {
        transform: scale(1.04);
    }

    /* With a mouse the facts and the agency live on the photo, so the text under it stays short */
    .lcard-facts,
    .lcard-by {
        display: none !important;
    }
}

/* 12. People who prefer less motion get everything at once */
@media (prefers-reduced-motion: reduce) {
    .lcard-info,
    .lcard-avatar,
    .lcard-img {
        transition: none !important;
    }

    .lcard:hover .lcard-img {
        transform: none !important;
    }

    .rv,
    .rv-hide {
        opacity: 1 !important;
        transform: none !important;
        transition: none !important;
    }

    .toast-pill,
    .modal-backdrop,
    .modal-panel,
    .am-step,
    .search-mode-in,
    .msheet,
    .photo-tour,
    .lightbox,
    .search-panel,
    .menu-pop:not(.hidden),
    .skeleton {
        animation: none !important;
    }

    html .hdr-tabs,
    html .hdr-search,
    html .hdr-pill,
    .hdr-backdrop,
    .bottom-nav,
    .tab-ico,
    .mtabs,
    .mtab-ico,
    .mtop,
    .search-btn-label {
        transition-duration: 0s !important;
    }

    [data-tab]:hover .tab-ico {
        transform: none;
    }
}

/* 13. Map of the search results: the list on the left and the map on the right on
   computers, the map over the whole screen on phones and tablets */
.map-pane[hidden] {
    display: none !important;
}

.map-frame {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
    background-color: hsl(var(--secondary));
}

.map-canvas {
    position: absolute;
    inset: 0;
}

@media (min-width: 1024px) {
    .search-layout[data-map='on'] {
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(420px, 42%);
        max-width: none;
    }

    .search-layout[data-map='on'] > .search-list {
        padding-left: 2.5rem;
        padding-right: 1.5rem;
    }

    .search-layout[data-map='on'] .results-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .map-pane {
        position: sticky;
        top: var(--map-top, 154px);
        align-self: start;
        height: calc(100vh - var(--map-top, 154px));
        height: calc(100dvh - var(--map-top, 154px));
        border-left: 1px solid hsl(var(--hairline));
    }
}

@media (min-width: 1440px) {
    .search-layout[data-map='on'] .results-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (max-width: 1023.98px) {
    .map-pane {
        position: fixed;
        left: 0;
        right: 0;
        top: var(--map-top, 144px);
        bottom: calc(4rem + env(safe-area-inset-bottom, 0px));
        z-index: 35;
    }
}

@media (min-width: 768px) and (max-width: 1023.98px) {
    .map-pane {
        bottom: 0;
    }
}

/* Round photos drawn on the map */
.map-layer {
    position: absolute;
    left: 0;
    top: 0;
    font-family: Figtree, ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
}

/* Each property is a round photo where it stands; properties close together become a small
   stack of photos with their number on a red badge */
.map-thumb {
    --d: 46px;
    position: absolute;
    width: var(--d);
    height: var(--d);
    padding: 0;
    border: 0;
    border-radius: 999px;
    background: transparent;
    cursor: pointer;
    transform: translate(-50%, -50%);
    transition: transform 0.18s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.map-thumb.is-group {
    --d: 52px;
}

.map-thumb.is-lg {
    --d: 56px;
}

.map-thumb.is-xl {
    --d: 62px;
}

.map-thumb-ph {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    overflow: hidden;
    border: 3px solid hsl(var(--background));
    border-radius: 999px;
    color: hsl(var(--muted-foreground));
    background-color: hsl(var(--secondary));
    box-shadow: 0 2px 8px rgb(0 0 0 / 0.28);
    transition:
        border-color 0.15s ease,
        box-shadow 0.15s ease;
}

.map-thumb-ico {
    width: 46%;
    height: 46%;
}

.map-thumb-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    transition: opacity 0.25s ease;
}

.map-thumb-img.is-in {
    opacity: 1;
}

/* Behind a group a second circle peeks out, so it reads as more than one property */
.map-thumb.is-group::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 999px;
    background-color: hsl(var(--background));
    box-shadow: 0 2px 6px rgb(0 0 0 / 0.22);
    transform: translate(5px, -5px) scale(0.92);
}

.map-thumb-count {
    position: absolute;
    top: -6px;
    right: -9px;
    min-width: 24px;
    height: 24px;
    padding: 0 7px;
    border: 2px solid hsl(var(--background));
    border-radius: 999px;
    font-size: 12px;
    font-weight: 700;
    line-height: 20px;
    text-align: center;
    white-space: nowrap;
    color: hsl(var(--primary-foreground));
    background-color: hsl(var(--primary));
    background-image: linear-gradient(to right, hsl(var(--brand-from)) 0%, hsl(var(--primary)) 50%, hsl(var(--brand-to)) 100%);
    box-shadow: 0 1px 4px rgb(0 0 0 / 0.25);
}

/* The price shows under the photo when it is pointed at, chosen, or lit up from the list */
.map-thumb-tag {
    position: absolute;
    top: calc(100% + 6px);
    left: 50%;
    padding: 4px 8px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 700;
    line-height: 14px;
    white-space: nowrap;
    color: hsl(var(--background));
    background-color: hsl(var(--foreground));
    box-shadow: 0 2px 6px rgb(0 0 0 / 0.25);
    opacity: 0;
    transform: translate(-50%, -3px);
    pointer-events: none;
    transition:
        opacity 0.15s ease,
        transform 0.15s ease;
}

.map-thumb:hover .map-thumb-tag,
.map-thumb.is-hover .map-thumb-tag,
.map-thumb.is-active .map-thumb-tag,
.map-thumb:focus-visible .map-thumb-tag {
    opacity: 1;
    transform: translate(-50%, 0);
}

/* Properties the visitor already opened look a little quieter */
.map-thumb.is-seen .map-thumb-ph {
    border-color: hsl(var(--hairline));
}

.map-thumb.is-seen .map-thumb-img.is-in {
    opacity: 0.7;
}

.map-thumb:hover,
.map-thumb.is-hover {
    z-index: 2;
    transform: translate(-50%, -50%) scale(1.12);
}

.map-thumb:hover .map-thumb-ph,
.map-thumb.is-hover .map-thumb-ph {
    box-shadow: 0 4px 14px rgb(0 0 0 / 0.35);
}

.map-thumb.is-active {
    z-index: 3;
    transform: translate(-50%, -50%) scale(1.15);
}

.map-thumb.is-active .map-thumb-ph {
    border-color: hsl(var(--foreground));
    box-shadow:
        0 0 0 3px hsl(var(--background)),
        0 4px 14px rgb(0 0 0 / 0.35);
}

.map-thumb.is-active .map-thumb-img.is-in {
    opacity: 1;
}

.map-thumb:focus-visible {
    z-index: 4;
    outline: 2px solid hsl(var(--foreground));
    outline-offset: 4px;
}

/* A property placed at the middle of its neighborhood or city carries a dashed ring,
   and the same dashed dot explains it in the map legend and on the card */
.map-thumb.is-approx .map-thumb-ph {
    outline: 1.5px dashed hsl(var(--foreground) / 0.5);
    outline-offset: 2px;
}

.map-approx-dot {
    display: inline-block;
    flex: none;
    width: 11px;
    height: 11px;
    border-radius: 999px;
    background-color: hsl(var(--background));
    border: 1.5px dashed hsl(var(--foreground) / 0.6);
}

/* The card of the chosen property, above its photo on computers */
.map-pop {
    position: absolute;
    z-index: 10;
    transform: translate(calc(-50% + var(--dx, 0px)), calc(-100% - 40px));
}

.map-pop.is-below {
    transform: translate(calc(-50% + var(--dx, 0px)), 40px);
}

/* Over the photo of the chosen property: a light shade at the top for the buttons and a deep
   one at the foot for the title, the price and the facts */
.map-card-shade {
    background-image: linear-gradient(
        to bottom,
        hsl(var(--scrim) / 0.3) 0%,
        hsl(var(--scrim) / 0) 24%,
        hsl(var(--scrim) / 0.08) 40%,
        hsl(var(--scrim) / 0.6) 66%,
        hsl(var(--scrim) / 0.88) 100%
    );
}

/* The dots of the photos that play on hover sit under the top buttons, clear of the text */
.map-card .lcard-dots {
    top: 54px;
    bottom: auto;
}

.map-pop > *,
.map-dock > * {
    animation: pr-drop 0.2s cubic-bezier(0.2, 0.8, 0.2, 1);
}

@media (prefers-reduced-motion: reduce) {
    .map-thumb,
    .map-thumb-ph,
    .map-thumb-img,
    .map-thumb-tag {
        transition: none !important;
    }

    .map-pop > *,
    .map-dock > * {
        animation: none !important;
    }
}

/* 14. Home intro: a deep band with a large, quiet outline of Kosovo as decoration */
.hero-band {
    isolation: isolate;
}

/* "në një vend." in the bright red of the brand, solid so it reads clearly on the band */
.hero-accent {
    color: hsl(var(--brand-from));
}

/* The intro plays in the moment the page shows, with the same rise as every section:
   the band first, then the title, the text and the search one after the other, while
   the outline of Kosovo opens out from Prishtina and settles into place */
.hero-band {
    animation: hero-rise 0.7s cubic-bezier(0.22, 1, 0.36, 1) backwards;
}

.hero-copy > * {
    animation: hero-rise 0.7s cubic-bezier(0.22, 1, 0.36, 1) backwards;
}

.hero-copy > :nth-child(1) {
    animation-delay: 0.12s;
}

.hero-copy > :nth-child(2) {
    animation-delay: 0.22s;
}

.hero-copy > :nth-child(3) {
    animation-delay: 0.32s;
}

.hero-map {
    animation: hero-map-in 1.4s cubic-bezier(0.22, 1, 0.36, 1) 0.18s backwards;
}

.hero-map-hatch {
    animation: hero-hatch-in 1.2s ease 0.6s backwards;
}

@keyframes hero-rise {
    from {
        opacity: 0;
        transform: translate3d(0, 16px, 0);
    }
}

@keyframes hero-map-in {
    from {
        opacity: 0;
        clip-path: circle(0% at 65% 43%);
        transform: translateY(-44%) rotate(-11deg) scale(1.06);
    }
    to {
        opacity: 1;
        clip-path: circle(120% at 65% 43%);
    }
}

@keyframes hero-hatch-in {
    from {
        opacity: 0;
    }
}

@media (prefers-reduced-motion: reduce) {
    .hero-band,
    .hero-copy > *,
    .hero-map,
    .hero-map-hatch {
        animation: none !important;
    }
}

/* The number of properties in the title fades in as it counts up */
.hero-total.is-in {
    animation: pr-fade 0.4s ease;
}

@media (prefers-reduced-motion: reduce) {
    .hero-total.is-in {
        animation: none !important;
    }
}

/* A large, quiet outline of Kosovo sits behind the right side of the band as decoration */
.hero-map {
    position: absolute;
    top: 50%;
    right: -90px;
    width: 300px;
    aspect-ratio: 1308 / 1416;
    color: hsl(var(--background));
    transform: translateY(-46%) rotate(-6deg);
    -webkit-mask-image: linear-gradient(to left, #000 55%, transparent 100%);
    mask-image: linear-gradient(to left, #000 55%, transparent 100%);
}

.hero-map svg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
}

.hero-map-land {
    fill: hsl(var(--background) / 0.035);
}

.hero-map-hatch {
    opacity: 0.08;
}

.hero-map-edge {
    fill: none;
    stroke: hsl(var(--background) / 0.3);
    stroke-width: 1.5px;
    stroke-linejoin: round;
}

/* The city dots are no longer drawn on the intro */
.hero-map [data-hero-cities],
.hero-city,
.hero-city-tag {
    display: none !important;
}

@media (min-width: 768px) {
    html .hero-map {
        right: -60px;
        width: 460px;
    }
}

@media (min-width: 1280px) {
    html .hero-map {
        right: 2%;
        width: 540px;
    }
}

/* A city: the link is the dot, with a wider area to point at than the dot itself */
.hero-city {
    --d: calc(var(--dot-min) + var(--s, 0) * var(--dot-span));
    position: absolute;
    z-index: 1;
    width: var(--d);
    height: var(--d);
    margin: calc(var(--d) / -2) 0 0 calc(var(--d) / -2);
    border-radius: 999px;
    outline: none;
}

.hero-city::before {
    content: '';
    position: absolute;
    inset: -7px;
    border-radius: inherit;
}

.hero-city::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background-color: hsl(var(--brand-from));
    box-shadow: 0 0 0 1.5px hsl(var(--foreground));
    transition:
        transform 0.18s cubic-bezier(0.2, 0.8, 0.2, 1),
        background-color 0.18s ease;
    animation: hero-dot-in 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) backwards;
    animation-delay: calc(var(--i, 0) * 40ms + 150ms);
}

.hero-city:hover,
.hero-city:focus-visible {
    z-index: 3;
}

.hero-city:hover::after,
.hero-city:focus-visible::after {
    transform: scale(1.25);
    background-color: hsl(var(--background));
}

.hero-city:focus-visible::before {
    inset: -5px;
    box-shadow: 0 0 0 2px hsl(var(--background));
}

/* The name and the number of properties of a city, next to its dot */
.hero-city-label {
    position: absolute;
    top: 50%;
    right: calc(100% + 7px);
    display: none;
    align-items: baseline;
    gap: 5px;
    padding: 2px 7px;
    border-radius: 6px;
    white-space: nowrap;
    font-size: 12px;
    font-weight: 600;
    line-height: 16px;
    color: hsl(var(--background));
    background-color: hsl(var(--foreground) / 0.85);
    transform: translateY(-50%);
    pointer-events: none;
}

.hero-city[data-side='right'] .hero-city-label {
    right: auto;
    left: calc(100% + 7px);
}

.hero-city-label span {
    font-weight: 500;
    color: hsl(var(--background) / 0.62);
}

@keyframes hero-dot-in {
    from {
        opacity: 0;
        transform: scale(0);
    }
    to {
        opacity: 1;
        transform: scale(1);
    }
}



/* The city with the most properties always carries its name and number, placed on the
   side of its dot where it covers the fewest other cities */
.hero-city-tag {
    position: absolute;
    z-index: 2;
    display: none;
    flex-direction: column;
    padding: 4px 9px 5px;
    border-radius: 8px;
    white-space: nowrap;
    font-size: 12px;
    font-weight: 700;
    line-height: 15px;
    color: hsl(var(--background));
    background-color: hsl(var(--foreground) / 0.92);
    box-shadow: 0 0 0 1px hsl(var(--background) / 0.16);
    pointer-events: none;
    animation: pr-fade 0.4s ease 0.55s backwards;
}

.hero-city-tag span {
    font-weight: 500;
    color: hsl(var(--background) / 0.65);
}

@media (min-width: 768px) {
    /* Every other city shows its name and number when pointed at */
    .hero-city-label {
        display: flex;
        opacity: 0;
        transition: opacity 0.15s ease;
    }

    .hero-city:hover .hero-city-label,
    .hero-city:focus-visible .hero-city-label {
        opacity: 1;
    }

    .hero-city-tag {
        display: flex;
    }
}



@media (prefers-reduced-motion: reduce) {
    .hero-city::after,
    .hero-city-label,
    .hero-city-tag {
        animation: none !important;
        transition: none !important;
    }
}

/* 15. Page transitions: pages fade softly into each other, and the photo of the
   property the visitor opens grows from its card into the property page */
@view-transition {
    navigation: auto;
}

::view-transition-group(root) {
    animation-duration: 0.22s;
}

::view-transition-group(listing-photo) {
    animation-duration: 0.38s;
    animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1);
}

::view-transition-old(listing-photo),
::view-transition-new(listing-photo) {
    height: 100%;
    object-fit: cover;
    overflow: clip;
}

.vt-from-card [data-vt-target] {
    view-transition-name: listing-photo;
}

/* The card that hands its photo over shows it clean, without the details of the hover */
.lcard.vt-leaving .lcard-info {
    opacity: 0 !important;
    transition: none !important;
}

.lcard.vt-leaving .lcard-img {
    transform: none !important;
    transition: none !important;
}

.lcard.vt-leaving [data-vt-photo] button {
    visibility: hidden;
}

/* A list opening again where the visitor left it shows its rows at once */
.rv-instant .rv {
    transition: none !important;
}

@media (prefers-reduced-motion: reduce) {
    @view-transition {
        navigation: none;
    }
}

/* 16. Publishing a property: while the steps are open, the bar with Back and Next takes the
   place of the phone navigation, and the page footer stays clear of it */
body.pub-wizard [data-bottom-nav] {
    display: none !important;
}

body.pub-wizard > footer {
    padding-bottom: calc(112px + env(safe-area-inset-bottom, 0px)) !important;
}
