/* ============================================================================
   Uptown booking engine — DESIGN TOKENS (single source of truth)
   ----------------------------------------------------------------------------
   Every colour, font size, weight, radius, shadow and layout constant lives
   here as a CSS custom property. Components must reference these tokens
   (var(--up-*)) instead of hardcoding values, so a brand change is a one-line
   edit that cascades to every component and page.

   Tokens are global (defined on :root) and therefore inherit into Blazor
   scoped CSS (*.razor.css) as well — no import needed.

   This file also holds the styles for elements injected at runtime by
   uptown-map.js (Mapbox pins/popups), which scoped CSS cannot reach.
   ========================================================================== */

:root {
    /* ===================== COLOUR ===================== */

    /* Brand */
    --up-gold: #d9b65a;
    --up-gold-dark: #c79a33;
    --up-gold-light: #ecd9a0;       /* lighter gold — highlights / gradient stop */
    --up-gold-soft: #fbf6ea;        /* faint gold tint — subtle hover backgrounds */
    --up-gold-grad: linear-gradient(135deg, #e8cd84 0%, #d9b65a 45%, #c79a33 100%);
    --up-gold-grad-dark: linear-gradient(135deg, #d9b65a 0%, #c79a33 60%, #b07f1f 100%);
    --up-gold-glow: 0 10px 30px rgba(199, 154, 51, .35);

    /* Text */
    --up-ink: #0a0a0a;              /* primary text */
    --up-muted: #6b7280;           /* secondary / supporting text */

    /* Surfaces */
    --up-white: #ffffff;           /* pure white — cards, buttons-on-colour */
    --up-bg: #ffffff;              /* page background */
    --up-bg-soft: #f7f7f5;         /* soft surface — image placeholders, notes */
    --up-bg-alt: #f3f3f1;          /* alt soft surface — light button hover */
    --up-bg-warm: #faf8f3;         /* warm section background — adds depth between white blocks */
    --up-skeleton-base: #eeede8;   /* skeleton placeholder base */
    --up-skeleton-sheen: #f7f6f2;  /* skeleton shimmer highlight */

    /* Lines */
    --up-line: #e6e6e6;            /* borders & dividers */
    --up-line-strong: #cfcfcf;     /* stronger control border (e.g. toggle off) */

    /* Feedback — success */
    --up-success-bg: #f1f8ef;
    --up-success-line: #cfe6c8;
    --up-success-ink: #3a6b2f;

    /* Overlays / scrims (over imagery) */
    --up-overlay: rgba(0, 0, 0, .28);                                      /* page-hero scrim */
    --up-hero-scrim: linear-gradient(180deg, rgba(8, 10, 18, .46) 0%, rgba(8, 10, 18, .26) 42%, rgba(8, 10, 18, .66) 100%); /* home hero */
    --up-loc-scrim: rgba(20, 22, 28, .55);                                 /* card location banner */
    --up-glass: rgba(255, 255, 255, .96);                                  /* frosted search panel */
    --up-glass-search: rgba(255, 255, 255, .82);                           /* frosted glass (with blur) — search/nav */
    --up-nav-glass: rgba(255, 255, 255, .80);                              /* frosted sticky nav */
    --up-card-img-scrim: linear-gradient(to top, rgba(10, 12, 20, .55) 0%, rgba(10, 12, 20, 0) 42%); /* legibility scrim on card images */

    /* ===================== TYPOGRAPHY ===================== */

    --up-font: "Roboto", -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;

    /* Size scale */
    --up-fs-2xs: 11px;
    --up-fs-xs: 13px;
    --up-fs-sm: 14px;
    --up-fs-md: 15px;
    --up-fs-lg: 16px;
    --up-fs-xl: 17px;
    --up-fs-2xl: 18px;
    --up-fs-h3: 24px;
    --up-fs-h2: 26px;
    --up-fs-h2-lg: 30px;
    --up-fs-h1: 34px;
    --up-fs-display: 40px;
    --up-fs-display-lg: 46px;

    /* Weights */
    --up-fw-regular: 400;
    --up-fw-medium: 500;
    --up-fw-semibold: 600;
    --up-fw-bold: 700;
    --up-fw-extrabold: 800;

    /* Line heights */
    --up-lh-tight: 1.1;
    --up-lh-snug: 1.3;
    --up-lh-base: 1.5;
    --up-lh-normal: 1.6;
    --up-lh-relaxed: 1.65;
    --up-lh-loose: 1.7;

    /* ===================== RADIUS ===================== */
    --up-radius-sm: 8px;
    --up-radius-md: 10px;
    --up-radius: 14px;             /* default / large surfaces */
    --up-radius-lg: 18px;          /* cards, panels */
    --up-radius-xl: 24px;          /* hero search, feature blocks */
    --up-radius-pill: 999px;       /* pills & toggles */

    /* ===================== SHADOW ===================== */
    --up-shadow-xs: 0 1px 2px rgba(16, 24, 40, .06);
    --up-shadow-sm: 0 2px 10px rgba(16, 24, 40, .06);
    --up-shadow: 0 1px 2px rgba(16, 24, 40, .04), 0 10px 28px rgba(16, 24, 40, .08);
    --up-shadow-md: 0 8px 30px rgba(16, 24, 40, .10);
    --up-shadow-lg: 0 30px 70px rgba(16, 24, 40, .18);
    --up-shadow-pin: 0 2px 6px rgba(0, 0, 0, .18);

    /* ===================== LAYOUT ===================== */
    --up-container: 1320px;        /* standard content width */
    --up-container-narrow: 1080px; /* detail / reading width */
    --up-container-text: 1000px;   /* long-form text blocks */

    /* ===================== MOTION ===================== */
    --up-transition: .15s ease;
    --up-ease-out: cubic-bezier(.22, .61, .36, 1);  /* smooth "settle" easing for entrances/hovers */
    --up-focus-ring: 0 0 0 4px rgba(217, 182, 90, .25);  /* soft gold ring for focused inputs */
    --up-shadow-hover: 0 24px 50px rgba(16, 24, 40, .18); /* lift shadow on hover */

    /* ===================== SPACING (4px scale) =====================
       Available for new components. Reach for these instead of ad-hoc px. */
    --up-space-1: 4px;
    --up-space-2: 8px;
    --up-space-3: 12px;
    --up-space-4: 16px;
    --up-space-5: 20px;
    --up-space-6: 24px;
    --up-space-8: 32px;
    --up-space-10: 40px;
    --up-space-12: 48px;
}

html, body {
    font-family: var(--up-font);
    color: var(--up-ink);
    background: var(--up-bg);
    /* Mobile safety net: never let a stray wide element create a horizontal
       scroll that shoves the whole page (and the sticky nav) off-centre.
       `clip` — not `hidden` — because clip does NOT create a scroll container,
       so it leaves `position: sticky` on the nav working. */
    overflow-x: clip;
}

/* ---- Mapbox: price pins + popups (created in uptown-map.js, styled globally) ---- */
.uptown-map-pin {
    background: var(--up-white);
    color: var(--up-ink);
    border: 1px solid var(--up-line);
    border-radius: var(--up-radius-pill);
    padding: 5px 11px;
    font: var(--up-fw-semibold) var(--up-fs-xs)/1 var(--up-font);
    box-shadow: var(--up-shadow-pin);
    cursor: pointer;
    white-space: nowrap;
    transition: transform .12s ease, background .12s ease, color .12s ease;
}

.uptown-map-pin:hover {
    transform: scale(1.06);
    background: var(--up-ink);
    color: var(--up-white);
    z-index: 2;
}

.uptown-map-popup {
    font-family: var(--up-font);
    min-width: 150px;
}

.uptown-map-popup-name {
    font-weight: var(--up-fw-semibold);
    font-size: var(--up-fs-xs);
    margin-bottom: 2px;
}

.uptown-map-popup-price {
    font-size: var(--up-fs-xs);
    color: var(--up-ink);
}

.uptown-map-popup-price span {
    color: var(--up-muted);
    font-weight: var(--up-fw-regular);
}

.uptown-map-msg {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    padding: 24px;
    text-align: center;
    color: var(--up-muted);
    background: var(--up-bg-soft);
    font-size: var(--up-fs-sm);
    line-height: var(--up-lh-base);
}

/* keep the price pill highlighted while its hover card is open */
.uptown-map-pin.active {
    background: var(--up-ink);
    color: var(--up-white);
    z-index: 4;
}

/* standard location pin (single property / no-price markers) */
.uptown-map-marker {
    cursor: pointer;
    line-height: 0;
    filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .3));
}

.uptown-map-marker svg {
    display: block;
    transition: transform .12s ease;
    transform-origin: bottom center;
}

.uptown-map-marker:hover svg {
    transform: scale(1.1);
}

/* Airbnb-style property card shown on marker hover */
.uptown-map-card {
    width: 232px;
    background: var(--up-white);
    border-radius: var(--up-radius-md);
    box-shadow: 0 10px 30px rgba(0, 0, 0, .20);
    overflow: hidden;
    font-family: var(--up-font);
    cursor: pointer;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity .14s ease;
    z-index: 3;
}

.uptown-map-card.show {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    z-index: 7;
}

.uptown-map-card-img {
    height: 128px;
    background: var(--up-bg-soft) center / cover no-repeat;
}

.uptown-map-card-body { padding: 10px 12px 12px; }

.uptown-map-card-title {
    font-size: var(--up-fs-sm);
    font-weight: var(--up-fw-semibold);
    color: var(--up-ink);
    margin-bottom: 2px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.uptown-map-card-sub {
    font-size: var(--up-fs-xs);
    color: var(--up-muted);
    margin-bottom: 6px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.uptown-map-card-meta {
    font-size: var(--up-fs-xs);
    color: var(--up-ink);
    margin-bottom: 6px;
}

.uptown-map-card-price {
    font-size: var(--up-fs-sm);
    font-weight: var(--up-fw-bold);
    color: var(--up-ink);
}

.uptown-map-card-price span {
    color: var(--up-muted);
    font-weight: var(--up-fw-regular);
    font-size: var(--up-fs-xs);
}

/* ============================================================================
   ANIMATION PRIMITIVES — shared keyframes (global, usable from scoped CSS)
   ========================================================================== */

/* Fade in while rising slightly — the workhorse entrance for headings & cards.
   Note: end state matches a component's resting state, so use fill-mode
   "backwards" (not "forwards") to avoid locking transform and breaking :hover. */
@keyframes up-fade-up {
    from { opacity: 0; transform: translateY(16px); }
    to   { opacity: 1; transform: none; }
}

@keyframes up-fade-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* Auto-dismissing success toast: fade in, hold, then fade out over ~3s. */
@keyframes up-toast {
    0%   { opacity: 0; transform: translateY(-4px); }
    8%   { opacity: 1; transform: translateY(0); }
    82%  { opacity: 1; transform: translateY(0); }
    100% { opacity: 0; transform: translateY(-4px); }
}

/* Slow cinematic zoom for hero imagery (Ken Burns). */
@keyframes up-kenburns {
    from { transform: scale(1); }
    to   { transform: scale(1.08); }
}

/* Shimmer sweep for skeleton loaders. */
@keyframes up-shimmer {
    from { background-position: 200% 0; }
    to   { background-position: -200% 0; }
}

/* Spinner rotation. */
@keyframes up-spin {
    to { transform: rotate(360deg); }
}

/* Gentle vertical float — for badges / accents. */
@keyframes up-float {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-6px); }
}

/* Pop-in for chips / badges. */
@keyframes up-pop {
    from { opacity: 0; transform: scale(.92); }
    to   { opacity: 1; transform: none; }
}

/* ----------------------------------------------------------------------------
   Skeleton shimmer base — global so loading placeholders can use it anywhere.
   -------------------------------------------------------------------------- */
.up-skeleton {
    position: relative;
    background: linear-gradient(100deg,
        var(--up-skeleton-base) 30%,
        var(--up-skeleton-sheen) 50%,
        var(--up-skeleton-base) 70%);
    background-size: 200% 100%;
    animation: up-shimmer 1.5s ease-in-out infinite;
    border-radius: var(--up-radius-sm);
}

/* Reveal-on-scroll — uptown-reveal.js sets .up-reveal-ready on <html> (so content is
   never hidden unless JS is running), then adds .in once the element enters view. */
.up-reveal-ready .up-reveal {
    opacity: 0;
    transform: translateY(28px);
    transition: opacity .75s var(--up-ease-out), transform .75s var(--up-ease-out);
    will-change: opacity, transform;
}

.up-reveal-ready .up-reveal.in {
    opacity: 1;
    transform: none;
}

/* Children of a revealed row can stagger via --up-i (set inline). */
.up-reveal-stagger.in > * {
    animation: up-fade-up .6s var(--up-ease-out) backwards;
    animation-delay: calc(min(var(--up-i, 0), 8) * 80ms);
}

/* Bounce — hero scroll-down indicator. */
@keyframes up-bounce {
    0%, 100% { transform: translateX(-50%) translateY(0); }
    50%      { transform: translateX(-50%) translateY(9px); }
}

/* Section kicker — small uppercase gold lead-in above a heading (global). */
.up-kicker {
    display: inline-block;
    font-size: var(--up-fs-xs);
    font-weight: var(--up-fw-bold);
    text-transform: uppercase;
    letter-spacing: .12em;
    color: var(--up-gold-dark);
    margin-bottom: 8px;
}

/* ----------------------------------------------------------------------------
   Respect users who prefer reduced motion — disable animation everywhere.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    .up-reveal { opacity: 1 !important; transform: none !important; }

    *, ::before, ::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }
}

/* ----------------------------------------------------------------------------
   Date pickers — Safari / iOS parity
   ----------------------------------------------------------------------------
   <input type="date"> is a NATIVE control and Safari/iOS paints it very
   differently from Chrome/Android:
     • no calendar glyph on the right-hand side (Chrome draws one), so the
       field looks empty / unfinished on the right,
     • the value can drift instead of sitting flush-left,
     • stray inner spin / clear buttons can appear.
   These rules draw our own calendar glyph and pin the value left so the four
   booking date fields (hero search, filter bar, pricing sidebar, confirm page)
   render identically on every browser. This file is global and loads AFTER the
   scoped component bundle, so it overrides each component's own input styles.
   -------------------------------------------------------------------------- */
.up-field input[type="date"],
.cb-field input[type="date"] {
    box-sizing: border-box; /* the glyph's padding-right stays inside the width */
    width: 100%;
    max-width: 100%;        /* never wider than its column, so it can't run off-screen */
    min-width: 0;
    position: relative;
    background-color: var(--up-white);
    /* Lucide "calendar" glyph, stroked in --up-muted (#6b7280). */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2'/%3E%3Cpath d='M16 2v4M8 2v4M3 10h18'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 14px center;
    background-size: 18px 18px;
    /* Reserve room for the glyph (overrides only the right side of each
       component's `padding` shorthand — top/left/bottom are left intact). */
    padding-right: 42px;
}

/* THE iOS FIX. iOS Safari paints <input type="date"> as a native control whose
   intrinsic width ignores width/min-width — so the field overflowed its column
   and dragged the calendar glyph off the right edge (min-width:0 and
   overflow-x:clip couldn't help because the native control sizes itself).
   This @supports block targets iOS Safari ONLY (-webkit-touch-callout exists
   only there), dropping the native appearance so the width caps above actually
   apply. Desktop browsers keep their native picker indicator untouched. */
@supports (-webkit-touch-callout: none) {
    .up-field input[type="date"],
    .cb-field input[type="date"] {
        -webkit-appearance: none;
        appearance: none;
        width: 100%;
        max-width: 100%;
        min-width: 0;
    }
}

/* iOS centres / drifts the value — keep it flush-left like Chrome. */
.up-field input[type="date"]::-webkit-date-and-time-value,
.cb-field input[type="date"]::-webkit-date-and-time-value {
    text-align: left;
    margin: 0;
}

/* Desktop Chrome draws its own glyph too: keep it (so a click still opens the
   picker) but make it transparent and stretch it over the right edge so it
   overlays our drawn glyph instead of doubling up. (Not rendered on iOS.) */
.up-field input[type="date"]::-webkit-calendar-picker-indicator,
.cb-field input[type="date"]::-webkit-calendar-picker-indicator {
    position: absolute;
    top: 0;
    right: 0;
    width: 42px;
    height: 100%;
    margin: 0;
    padding: 0;
    opacity: 0;
    cursor: pointer;
}

/* Strip the stray inner spin / clear buttons WebKit can inject. */
.up-field input[type="date"]::-webkit-inner-spin-button,
.cb-field input[type="date"]::-webkit-inner-spin-button,
.up-field input[type="date"]::-webkit-clear-button,
.cb-field input[type="date"]::-webkit-clear-button {
    -webkit-appearance: none;
    display: none;
}

/* iOS auto-zooms the page when a focused field is < 16px. The booking controls
   use 14px, so bump to 16px on touch devices to stop the zoom jump on tap. */
@media (pointer: coarse) {
    .up-field input,
    .up-field select,
    .cb-field input,
    .cb-field select,
    .cb-field textarea {
        font-size: 16px;
    }
}
