/* ==========================================================================
   Åuman — motion & refinement layer
   ==========================================================================

   Loads after luxury.css and builds on its tokens (--primary-gold,
   --warm-black, --font-primary …) rather than introducing a parallel system.

   The reference for this is the restraint of a maison house page: motion is
   slow, scarce and always in service of hierarchy. Nothing bounces, nothing
   springs, nothing competes with the product photography. Three devices only:

     1. a measured entrance, so a page settles rather than snapping in
     2. reveal-on-scroll, to pace a long page into deliberate sections
     3. a single considered hover gesture per interactive element

   Every transform is GPU-friendly (transform/opacity only) so nothing
   triggers layout. Every animation is disabled under prefers-reduced-motion.
   ========================================================================== */

:root {
    /* One easing curve used throughout: a slow start and a long settle reads
       as expensive. Multiple competing curves read as a template. */
    --ease-maison: cubic-bezier(0.22, 0.61, 0.36, 1);
    --ease-exit: cubic-bezier(0.4, 0, 0.6, 1);

    --dur-quick: 240ms;
    --dur-base: 420ms;
    --dur-slow: 720ms;

    --hairline: rgba(26, 26, 26, 0.12);
    --gold-veil: rgba(212, 175, 55, 0.14);
}

/* --------------------------------------------------------------------------
   1. Typographic refinement
   -------------------------------------------------------------------------- */

body {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}

/* Display type reads as set rather than typed: tighter tracking at size,
   balanced line breaks so headings do not leave a single orphaned word. */
h1, h2, h3,
.hero-title, .section-title, .payments-title {
    letter-spacing: -0.015em;
    text-wrap: balance;
}

h1, .hero-title { line-height: 1.06; }
h2, .section-title { line-height: 1.14; }

/* Small uppercase labels need the opposite treatment — open tracking, or they
   read as a solid block. */
.eyebrow, .label, .badge, .tag,
.btn, button, .luxury-btn,
th, .table th {
    letter-spacing: 0.08em;
}

p, li { text-wrap: pretty; }

/* Running text sits at a comfortable measure regardless of container width. */
.prose, .product-description, .tailor-bio, .address-info {
    max-width: 68ch;
}

/* --------------------------------------------------------------------------
   2. Page entrance
   -------------------------------------------------------------------------- */

@keyframes maison-rise {
    from { opacity: 0; transform: translate3d(0, 14px, 0); }
    to   { opacity: 1; transform: none; }
}

/* Applied by motion.js once it has confirmed JS is available, so a page never
   sits invisible if the script fails to load. */
.js-motion main > *,
.js-motion .luxury-hero-section,
.js-motion .payments-hero {
    animation: maison-rise var(--dur-slow) var(--ease-maison) both;
}

/* A short stagger reads as choreography; a long one reads as lag. */
.js-motion main > *:nth-child(1) { animation-delay: 0ms; }
.js-motion main > *:nth-child(2) { animation-delay: 70ms; }
.js-motion main > *:nth-child(3) { animation-delay: 140ms; }
.js-motion main > *:nth-child(n+4) { animation-delay: 190ms; }

/* --------------------------------------------------------------------------
   3. Reveal on scroll
   -------------------------------------------------------------------------- */

.js-motion [data-reveal] {
    opacity: 0;
    transform: translate3d(0, 20px, 0);
    transition:
        opacity var(--dur-slow) var(--ease-maison),
        transform var(--dur-slow) var(--ease-maison);
    will-change: opacity, transform;
}

.js-motion [data-reveal].is-revealed {
    opacity: 1;
    transform: none;
    will-change: auto;
}

/* Grid children reveal in sequence rather than as one slab. */
.js-motion [data-reveal-group] > * {
    opacity: 0;
    transform: translate3d(0, 18px, 0);
    transition:
        opacity var(--dur-base) var(--ease-maison),
        transform var(--dur-base) var(--ease-maison);
}
.js-motion [data-reveal-group].is-revealed > * {
    opacity: 1;
    transform: none;
}
.js-motion [data-reveal-group].is-revealed > *:nth-child(1) { transition-delay: 0ms; }
.js-motion [data-reveal-group].is-revealed > *:nth-child(2) { transition-delay: 60ms; }
.js-motion [data-reveal-group].is-revealed > *:nth-child(3) { transition-delay: 120ms; }
.js-motion [data-reveal-group].is-revealed > *:nth-child(4) { transition-delay: 180ms; }
.js-motion [data-reveal-group].is-revealed > *:nth-child(5) { transition-delay: 220ms; }
.js-motion [data-reveal-group].is-revealed > *:nth-child(n+6) { transition-delay: 260ms; }

/* --------------------------------------------------------------------------
   4. Product imagery
   -------------------------------------------------------------------------- */

/* The image scales inside a fixed frame, so the grid never reflows. */
.product-card .product-image,
.tailor-card .tailor-avatar,
.item-image,
.category-tile .tile-image {
    overflow: hidden;
    position: relative;
    background: var(--light-gray, #f5f5f5);
}

.product-card .product-image img,
.tailor-card .tailor-avatar img,
.item-image img,
.category-tile .tile-image img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform var(--dur-slow) var(--ease-maison);
}

.product-card:hover .product-image img,
.tailor-card:hover .tailor-avatar img,
.category-tile:hover .tile-image img {
    transform: scale(1.045);
}

/* A hairline that draws in under the caption — the single gold gesture per
   card, rather than gold fills competing across the grid. */
.product-card .product-name,
.category-tile .tile-label {
    position: relative;
    display: inline-block;
}

.product-card .product-name::after,
.category-tile .tile-label::after {
    content: '';
    position: absolute;
    left: 0;
    bottom: -4px;
    width: 100%;
    height: 1px;
    background: var(--primary-gold, #d4af37);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--dur-base) var(--ease-maison);
}

.product-card:hover .product-name::after,
.category-tile:hover .tile-label::after {
    transform: scaleX(1);
}

.product-card {
    transition: box-shadow var(--dur-base) var(--ease-maison);
}
.product-card:hover {
    box-shadow: 0 18px 48px rgba(26, 26, 26, 0.10);
}

/* --------------------------------------------------------------------------
   5. Navigation
   -------------------------------------------------------------------------- */

.navbar-nav .nav-link,
.luxury-nav a,
.footer-links a {
    position: relative;
    transition: color var(--dur-quick) var(--ease-maison);
}

.navbar-nav .nav-link::after,
.luxury-nav a::after,
.footer-links a::after {
    content: '';
    position: absolute;
    left: 0;
    bottom: -2px;
    width: 100%;
    height: 1px;
    background: currentColor;
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--dur-base) var(--ease-maison);
}

.navbar-nav .nav-link:hover::after,
.navbar-nav .nav-link:focus-visible::after,
.luxury-nav a:hover::after,
.footer-links a:hover::after {
    transform: scaleX(1);
}

/* --------------------------------------------------------------------------
   6. Buttons
   -------------------------------------------------------------------------- */

.luxury-btn,
.btn-luxury,
.stripe-button,
button[type="submit"] {
    position: relative;
    overflow: hidden;
    transition:
        transform var(--dur-quick) var(--ease-maison),
        box-shadow var(--dur-base) var(--ease-maison);
}

/* Gold wipes across from the left instead of flashing on. */
.luxury-btn::before,
.btn-luxury::before {
    content: '';
    position: absolute;
    inset: 0;
    background: var(--gold-veil);
    transform: translate3d(-101%, 0, 0);
    transition: transform var(--dur-base) var(--ease-maison);
    pointer-events: none;
}

.luxury-btn:hover::before,
.btn-luxury:hover::before {
    transform: none;
}

.luxury-btn:hover,
.btn-luxury:hover,
.stripe-button:hover,
button[type="submit"]:hover {
    transform: translate3d(0, -2px, 0);
    box-shadow: 0 10px 28px rgba(26, 26, 26, 0.14);
}

.luxury-btn:active,
.btn-luxury:active,
.stripe-button:active,
button[type="submit"]:active {
    transform: translate3d(0, 0, 0);
    transition-duration: 80ms;
}

/* A disabled control must not appear interactive. */
.luxury-btn[disabled],
.stripe-button[disabled],
button[disabled] {
    transform: none !important;
    box-shadow: none !important;
    opacity: 0.55;
    cursor: not-allowed;
}

/* --------------------------------------------------------------------------
   7. Forms
   -------------------------------------------------------------------------- */

input, select, textarea {
    transition:
        border-color var(--dur-quick) var(--ease-maison),
        box-shadow var(--dur-quick) var(--ease-maison);
}

input:focus, select:focus, textarea:focus {
    border-color: var(--primary-gold, #d4af37);
    box-shadow: 0 0 0 3px var(--gold-veil);
    outline: none;
}

/* Keyboard users get a visible, deliberate focus ring everywhere. Removing
   the outline without replacing it makes a site unusable by keyboard. */
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible,
.luxury-btn:focus-visible {
    outline: 2px solid var(--primary-gold, #d4af37);
    outline-offset: 3px;
    border-radius: 2px;
}

/* --------------------------------------------------------------------------
   8. Cart badge
   -------------------------------------------------------------------------- */

@keyframes maison-badge {
    0%   { transform: scale(1); }
    40%  { transform: scale(1.28); }
    100% { transform: scale(1); }
}

.cart-count.is-bumped,
.badge.is-bumped {
    animation: maison-badge var(--dur-base) var(--ease-maison);
}

/* --------------------------------------------------------------------------
   9. Reduced motion
   --------------------------------------------------------------------------
   Honouring this is not optional: for some people this motion causes nausea
   or migraine. Content must still be fully visible, so reveals resolve to
   their final state rather than simply having their transition removed.      */

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }

    .js-motion [data-reveal],
    .js-motion [data-reveal-group] > * {
        opacity: 1 !important;
        transform: none !important;
    }

    .product-card:hover .product-image img,
    .tailor-card:hover .tailor-avatar img {
        transform: none;
    }
}
