/* ============================================================
   UrbanSetu design layer 2 — category colour, motion, card anatomy.

   Built from an audit of Urban Company, Thumbtack, TaskRabbit, Fiverr,
   Upwork, Airbnb, Booking, Uber and DoorDash. The load-bearing idea:
   photography is not what makes those sites feel expensive — colour
   discipline, real numbers and restrained motion are. This file supplies
   all three so the site works with illustration only.
   ============================================================ */

:root {
    /* ---- Category hues -------------------------------------------------
       Same lightness and chroma, hue rotated. Keeping L and C fixed is what
       stops twelve coloured tiles reading as a clown car. Never hand-pick
       a replacement — rotate the hue angle instead. */
    --c-cleaning:  oklch(0.62 0.14 195);
    --c-beauty:    oklch(0.62 0.14 350);
    --c-repair:    oklch(0.62 0.14  55);
    --c-plumbing:  oklch(0.62 0.14 240);
    --c-electric:  oklch(0.62 0.14  90);
    --c-painting:  oklch(0.62 0.14 300);
    --c-pest:      oklch(0.62 0.14 145);
    --c-moving:    oklch(0.62 0.14  25);
    --c-design:    oklch(0.62 0.14 320);
    --c-dev:       oklch(0.62 0.14 265);
    --c-marketing: oklch(0.62 0.14  15);
    --c-writing:   oklch(0.62 0.14 170);

    /* Accent is reserved for price and offers only — never decoration. */
    --accent-amber: oklch(0.78 0.17 75);

    /* ---- Motion: one easing, three durations. Everything else is noise. */
    --ease-brand: cubic-bezier(.2, .8, .2, 1);
    --t-fast: 140ms;
    --t-base: 280ms;
    --t-slow: 700ms;
}

/* ============================================================
   HERO — layered radial "aurora" + grain.
   A mesh gradient without WebGL. Positions animate, not colours:
   cheaper to composite and far less nauseating.
   ============================================================ */
.hero-aurora {
    position: relative;
    isolation: isolate;
    background:
        radial-gradient(60% 55% at 12% 8%,   oklch(0.72 0.16 275 / .40), transparent 62%),
        radial-gradient(50% 45% at 88% 4%,   oklch(0.75 0.14 195 / .34), transparent 60%),
        radial-gradient(70% 60% at 50% 108%, oklch(0.80 0.12 340 / .26), transparent 65%),
        var(--bg, #FCFCFE);
    background-size: 140% 140%;
    animation: aurora-drift 22s ease-in-out infinite alternate;
}
@keyframes aurora-drift {
    50% { background-position: 3% 2%, -2% 1%, 1% -3%; }
}

/* Grain is the finishing 2% that separates "a CSS gradient" from "designed".
   Above .08 it looks dirty, below .03 it is invisible. */
.hero-grain {
    position: absolute;
    inset: 0;
    opacity: .055;
    mix-blend-mode: multiply;
    pointer-events: none;
    z-index: 0;
}
.hero-aurora > .container { position: relative; z-index: 1; }

/* ============================================================
   INTENT TOGGLE — a two-sided marketplace forks here, not in two
   competing hero CTAs (Upwork's pattern).
   ============================================================ */
.intent-toggle {
    display: inline-flex;
    gap: 4px;
    padding: 4px;
    background: color-mix(in oklch, var(--brand, #5B21B6) 7%, #fff);
    border: 1px solid color-mix(in oklch, var(--brand, #5B21B6) 14%, transparent);
    border-radius: 9999px;
    margin-bottom: var(--space-5, 20px);
}
.intent-option {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 9px 18px;
    border-radius: 9999px;
    font-size: 14px;
    font-weight: 600;
    color: var(--text-secondary, #5B5B66);
    background: transparent;
    border: 0;
    cursor: pointer;
    transition: background var(--t-fast) var(--ease-brand),
                color var(--t-fast) var(--ease-brand),
                box-shadow var(--t-fast) var(--ease-brand);
}
.intent-option[aria-selected="true"] {
    background: #fff;
    color: var(--brand, #5B21B6);
    box-shadow: 0 1px 3px rgb(26 26 31 / .12);
}

/* Rotating word in the headline — reads as a live product for ~15 lines of CSS */
.word-rotator {
    display: inline-grid;
    vertical-align: bottom;
    overflow: hidden;
}
.word-rotator > span {
    grid-area: 1 / 1;
    opacity: 0;
    transform: translateY(100%);
    animation: word-cycle 11s infinite;
}
.word-rotator > span:nth-child(1) { animation-delay: 0s; }
.word-rotator > span:nth-child(2) { animation-delay: 2.2s; }
.word-rotator > span:nth-child(3) { animation-delay: 4.4s; }
.word-rotator > span:nth-child(4) { animation-delay: 6.6s; }
.word-rotator > span:nth-child(5) { animation-delay: 8.8s; }
@keyframes word-cycle {
    0%, 2%    { opacity: 0; transform: translateY(100%); }
    4%, 18%   { opacity: 1; transform: translateY(0); }
    20%, 100% { opacity: 0; transform: translateY(-100%); }
}

/* ============================================================
   CATEGORY TILE — illustration on a tinted panel.
   The category hue is never a fill: it appears only as a low-alpha
   tint, the illustration's blob, and the hover edge. Every tile stays
   ~92% white, which is why twelve of them still look like one set.
   ============================================================ */
.cat-tile {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--hairline, #E6E6EC);
    border-radius: 12px;
    overflow: hidden;
    background: #fff;
    text-decoration: none;
    color: inherit;
    /* No shadow at rest — Airbnb's rule. Shadow is a hover affordance. */
    transition: transform var(--t-base) var(--ease-brand),
                box-shadow var(--t-base) var(--ease-brand),
                border-color var(--t-base) var(--ease-brand);
}
.cat-tile:hover,
.cat-tile:focus-visible {
    transform: translateY(-4px);
    box-shadow: 0 12px 28px -8px rgb(26 26 31 / .16);
    border-color: color-mix(in oklch, var(--cat, #5B21B6) 35%, transparent);
}

.cat-tile-panel {
    position: relative;
    aspect-ratio: 4 / 3;
    display: grid;
    place-items: center;
    background:
        radial-gradient(120% 90% at 85% 110%, color-mix(in oklch, var(--cat, #5B21B6) 20%, transparent), transparent 70%),
        color-mix(in oklch, var(--cat, #5B21B6) 7%, #fff);
}
.cat-tile-panel > svg,
.cat-tile-panel > img {
    width: 45%;
    height: auto;
    max-height: 72%;
}
/* When a real photo replaces the illustration it should fill the panel */
.cat-tile-panel > img.is-photo {
    width: 100%;
    height: 100%;
    max-height: none;
    object-fit: cover;
}

/* Price / offer chips float on the panel */
.cat-chip {
    position: absolute;
    bottom: 10px;
    padding: 4px 10px;
    border-radius: 9999px;
    background: rgb(255 255 255 / .92);
    backdrop-filter: blur(8px);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: -0.1px;
    color: var(--text-primary, #1A1A1F);
    box-shadow: 0 1px 4px rgb(26 26 31 / .12);
}
.cat-chip.is-price { left: 10px; }
.cat-chip.is-offer { right: 10px; color: oklch(0.52 0.17 25); }

.cat-tile-body { padding: 12px 14px 14px; }
.cat-tile-title {
    font-size: 14px;
    font-weight: 600;
    margin: 0 0 3px;
    color: var(--text-primary, #1A1A1F);
}
/* Rating reads as a bare numeral — the star is decoration beside it.
   tabular-nums stops the row jittering between cards. */
.cat-tile-meta {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 12px;
    color: var(--text-tertiary, #8A8A96);
    font-variant-numeric: tabular-nums;
}
.cat-tile-meta .star { color: var(--accent-amber); }
.cat-tile-meta .rating { font-weight: 600; color: var(--text-secondary, #5B5B66); }

/* ---- The four-layer illustration: blob / mass / line / spark ---- */
.cat-art * {
    transform-box: fill-box;
    transform-origin: center;
    transition: transform .35s var(--ease-brand);
}
.cat-art .blob  { fill: color-mix(in oklch, var(--cat, #5B21B6) 30%, transparent); }
.cat-art .mass  { fill: #fff; stroke: var(--text-primary, #1A1A1F); stroke-width: 6; }
.cat-art .line  { stroke: var(--text-secondary, #5B5B66); stroke-width: 6; stroke-linecap: round; stroke-linejoin: round; fill: none; }
.cat-art .spark { fill: var(--accent-amber); }

.cat-tile:hover .cat-art .spark { transform: translateY(-3px) scale(1.12); }
.cat-tile:hover .cat-art .blob  { transform: rotate(-4deg) scale(1.04); }

/* ============================================================
   STAT TILES — numbers are the cheapest premium signal there is.
   Rendered only when a real value exists; see the Blade partial.
   ============================================================ */
.stat-band { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; }
.stat-tile { text-align: center; }
.stat-value {
    font-size: 52px;
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    color: var(--text-primary, #1A1A1F);
}
.stat-value .suffix {
    font-size: 0.6em;
    font-weight: 600;
    color: var(--brand, #5B21B6);
}
.stat-label {
    margin-top: 8px;
    font-size: 13px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--text-tertiary, #8A8A96);
}
@media (max-width: 760px) {
    .stat-band { grid-template-columns: repeat(2, 1fr); gap: 32px 16px; }
    .stat-value { font-size: 40px; }
}

/* ============================================================
   SCROLL REVEAL — pure CSS, no library, no JS.
   Falls back to fully visible where view() is unsupported.
   ============================================================ */
@supports (animation-timeline: view()) {
    .reveal {
        animation: reveal-rise linear both;
        animation-timeline: view();
        animation-range: entry 8% cover 34%;
    }
    @keyframes reveal-rise {
        from { opacity: 0; transform: translateY(24px); }
        to   { opacity: 1; transform: none; }
    }
}

/* ============================================================
   Respect the OS setting. Non-negotiable.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
    .hero-aurora { animation: none; }
}
