/* =============================================================
   LURAN — Responsive utility layer (additive, conservative)
   -----------------------------------------------------------
   Loaded AFTER every other stylesheet so its rules win.
   Strategy: mobile-first, RTL-safe via logical properties.
   Breakpoints: sm 480, md 768, lg 1024, xl 1280, 2xl 1536.

   Naming convention: every utility is prefixed with .lr- so it
   never collides with existing class names.

   IMPORTANT — DO NO HARM:
   - Auto-rules (those that target generic existing classes) MUST
     only adjust safe properties: spacing/sizing/wrap. Anything that
     could break a layout (display, flex-direction, position) must be
     opt-in via .lr-* classes.
   - Opt-in transformations (table → cards, drawers, sticky CTAs)
     are scoped to .lr-* classes the developer adds intentionally.
   ============================================================= */

/* -------------------------------------------------------------
   1) Global safety: prevent horizontal scroll on every screen
   ----------------------------------------------------------- */
html, body {
    overflow-x: clip;
}

img, video, canvas, svg, iframe {
    max-width: 100%;
}

/* Defensive: FontAwesome (and similar icon CSS) set `.fas { display: inline-block }`
   at specificity 0,1,0 — same as the UA `[hidden] { display: none }` — and being
   author-level it wins, leaving "hidden" icons visible. Re-assert [hidden] at the
   author level with !important so it always wins.  */
[hidden] { display: none !important; }

/* ─── LURAN UI: helpers for luran-ui.js patterns ─────────────
   These work hand-in-hand with public/js/luran-ui.js (the
   vanilla-JS replacement for Alpine.js). Loading order is
   guaranteed because responsive.css ships last in every layout. */

/* Guide-pane (admin show pages) — visible only when the parent
   [data-lr-tabs] has the .is-guide-open class flipped on by the
   "Show guide" button (data-lr-class-toggle="is-guide-open"). */
[data-lr-guide-pane] { display: none; }
[data-lr-tabs].is-guide-open [data-lr-panel].is-active [data-lr-guide-pane],
[data-lr-tabs].is-guide-open [data-lr-panel]:not([hidden]) [data-lr-guide-pane] {
    display: block;
}

/* Two-span label flip — used by class-toggle buttons so the label
   text changes between "Show X" ↔ "Hide X" without JS string ops. */
.is-guide-open .lr-when-off,
.is-open       .lr-when-off { display: none; }
.is-guide-open .lr-when-on,
.is-open       .lr-when-on  { display: inline; }

/* Active state on data-lr-tab buttons — matches the `.is-active`
   class that components/dash CSS already styles. No new styling
   needed; this is just a documentation anchor. */

/* Error-trace expand toggle — admin/error-logs/show.blade.php.
   When the panel gets .is-expanded (via data-lr-class-toggle),
   the inner <pre> stretches to the full-height variant defined
   in admin-luxury.css (.error-trace-pre.is-expanded). */
.error-trace-panel.is-expanded .error-trace-pre { max-height: 1600px; }

/* Pro filter — advanced section collapses by default, opens via
   .is-advanced-open on the wrapper form. Chevron rotates 180°. */
.pro-filter:not(.is-advanced-open) .pro-filter-advanced { display: none; }
.pro-filter-chevron { transition: transform 0.2s ease; }
.pro-filter.is-advanced-open .pro-filter-chevron { transform: rotate(180deg); }

/* Lang switcher (admin forms) — bridge between old `.active` and
   new `.is-active` toolkit convention. luran-ui.js sets `.is-active`,
   but the existing admin.css styles target `.active`. Adding parity
   here keeps both the converted forms and any not-yet-converted file
   visually consistent. */
.lang-switcher button.is-active {
    background: var(--bg-main);
    color: var(--brand);
    box-shadow: 0 1px 3px rgba(0,0,0,0.08);
}
.lang-pane.is-active { display: block; }

/* Storefront catalog toolbar — filter panel is hidden until the
   toolbar's "Filter" button (data-lr-class-toggle="is-panel-open")
   flips the wrapper class. Pure CSS — no JS for visibility. */
.catalog-toolbar:not(.is-panel-open) [data-lr-show-panel] { display: none; }
.catalog-toolbar.is-panel-open [data-lr-show-panel] { display: block; }

/* -------------------------------------------------------------
   2) RTL helper
   ----------------------------------------------------------- */
:root { --lr-rtl-flip: 1; }
[dir="rtl"] { --lr-rtl-flip: -1; }
.lr-mirror-rtl { transform: scaleX(var(--lr-rtl-flip, 1)); }

/* -------------------------------------------------------------
   3) Spacing variables (used by our utilities only)
   ----------------------------------------------------------- */
:root {
    --lr-sp-1: 4px;  --lr-sp-2: 8px;   --lr-sp-3: 12px;
    --lr-sp-4: 16px; --lr-sp-5: 20px;  --lr-sp-6: 24px;
    --lr-sp-8: 32px; --lr-sp-10: 40px; --lr-sp-14: 56px;
    --lr-sp-18: 72px;
}

/* -------------------------------------------------------------
   4) Stack ↔ Inline helpers (opt-in)
   ----------------------------------------------------------- */
.lr-stack    { display: flex; flex-direction: column; gap: var(--lr-sp-3); }
.lr-stack-sm { gap: var(--lr-sp-2); }
.lr-stack-lg { gap: var(--lr-sp-5); }

.lr-row         { display: flex; align-items: center; gap: var(--lr-sp-3); flex-wrap: wrap; }
.lr-row-tight   { gap: var(--lr-sp-2); }
.lr-row-between { justify-content: space-between; }

.lr-stack-md-row { display: flex; flex-direction: column; gap: var(--lr-sp-3); }
@media (min-width: 768px) {
    .lr-stack-md-row { flex-direction: row; align-items: center; gap: var(--lr-sp-4); }
}

/* -------------------------------------------------------------
   5) Auto-fit grid utilities (opt-in)
   ----------------------------------------------------------- */
.lr-grid-auto {
    display: grid;
    gap: var(--lr-sp-4);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
}
.lr-grid-auto-sm {
    display: grid; gap: var(--lr-sp-3);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 180px), 1fr));
}
.lr-grid-auto-lg {
    display: grid; gap: var(--lr-sp-5);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
}
@media (min-width: 768px)  { .lr-grid-auto, .lr-grid-auto-sm, .lr-grid-auto-lg { gap: var(--lr-sp-5); } }
@media (min-width: 1280px) { .lr-grid-auto, .lr-grid-auto-lg { gap: var(--lr-sp-6); } }

.lr-grid-1-2-3 {
    display: grid; gap: var(--lr-sp-4); grid-template-columns: 1fr;
}
@media (min-width: 768px)  { .lr-grid-1-2-3 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .lr-grid-1-2-3 { grid-template-columns: repeat(3, 1fr); } }

.lr-grid-1-2-4 {
    display: grid; gap: var(--lr-sp-4); grid-template-columns: 1fr;
}
@media (min-width: 768px)  { .lr-grid-1-2-4 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1280px) { .lr-grid-1-2-4 { grid-template-columns: repeat(4, 1fr); } }

/* -------------------------------------------------------------
   6) Table → Card list on mobile (OPT-IN: add .lr-table-cards to <table>)
   -----------------------------------------------------------
   Each <td> can optionally have a data-label="..." for the
   bold prefix label. Cells with block-level children should
   wrap them in a span/div if they want inline display.

   Cell behaviour is "stack": label on its own line, content below.
   This is safer than space-between because it handles multi-line
   content (img + name + small) reliably without truncation.
   ----------------------------------------------------------- */
@media (max-width: 767.98px) {
    .lr-table-cards {
        width: 100%;
        border-collapse: separate;
        border-spacing: 0;
        display: block;
    }
    .lr-table-cards thead,
    .lr-table-cards colgroup { display: none; }
    .lr-table-cards tbody { display: block; }
    .lr-table-cards tr {
        display: block;
        background: var(--bg-elevated, var(--bg-main, #fff));
        border: 1px solid var(--border-color, rgba(0,0,0,0.08));
        border-radius: 14px;
        padding: 14px;
        margin-bottom: 12px;
        box-shadow: 0 1px 2px rgba(0,0,0,0.04);
    }
    .lr-table-cards td {
        display: block;
        padding: 8px 0;
        border: 0;
        border-bottom: 1px dashed var(--border-color, rgba(0,0,0,0.08));
        text-align: start;
        font-size: 0.9rem;
        word-break: break-word;
        overflow-wrap: anywhere;
    }
    .lr-table-cards td:last-child { border-bottom: 0; padding-bottom: 0; }
    .lr-table-cards td:first-child { padding-top: 0; }
    .lr-table-cards td[data-label]::before {
        content: attr(data-label);
        display: block;
        font-weight: 600;
        color: var(--text-secondary, #71717a);
        font-size: 0.74rem;
        text-transform: uppercase;
        letter-spacing: 0.4px;
        margin-bottom: 4px;
    }
    /* Action cells: keep buttons in a row even though the cell stacks. */
    .lr-table-cards td.lr-cell-actions .admin-actions {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        justify-content: flex-start;
    }
    /* Hide cells entirely (e.g. ID column) on mobile when the
       developer marks them with .lr-hide-sm */
    .lr-table-cards td.lr-hide-sm { display: none; }
    /* Empty-state rows (single <td> with colspan) should fill the card
       and center their text instead of using the stacked label layout. */
    .lr-table-cards td[colspan] {
        text-align: center;
        padding: 24px 0;
    }
    .lr-table-cards td[colspan]::before { content: none; }
}

/* NO auto card-list. We made this opt-in only by removing the
   `.admin-table-wrap > .admin-table:not(.lr-no-cards)` rule that
   was here previously — it broke complex admin pages that have
   show-tables, nested layouts, and thumbnails. Tables that should
   become cards must add the `lr-table-cards` class explicitly. */

/* -------------------------------------------------------------
   7) Scroll-fallback for any table that doesn't opt-in to cards
   -----------------------------------------------------------
   Lets admin index tables stay tabular but scroll horizontally on
   small screens. Tables already inside .admin-table-wrap (which is
   the common pattern) get this for free.
   ----------------------------------------------------------- */
@media (max-width: 767.98px) {
    .admin-table-wrap {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    .admin-table-wrap > .admin-table:not(.lr-table-cards) {
        min-width: 720px;
    }
}
.lr-table-scroll {
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border-radius: 12px;
}
.lr-table-scroll > table { min-width: 720px; }

/* -------------------------------------------------------------
   8) Tabs scrollable horizontally on mobile (opt-in)
   ----------------------------------------------------------- */
.lr-tabs-scroll {
    display: flex;
    gap: var(--lr-sp-2);
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x mandatory;
    padding-bottom: 4px;
    scrollbar-width: thin;
}
.lr-tabs-scroll > * { scroll-snap-align: start; flex-shrink: 0; }
.lr-tabs-scroll::-webkit-scrollbar { height: 6px; }
.lr-tabs-scroll::-webkit-scrollbar-thumb {
    background: var(--border-color, rgba(0,0,0,0.12));
    border-radius: 999px;
}

/* -------------------------------------------------------------
   9) Sticky CTA on mobile (opt-in)
   ----------------------------------------------------------- */
.lr-sticky-cta {
    position: sticky;
    bottom: 0;
    z-index: 20;
    background: var(--bg-elevated, var(--bg-main, #fff));
    padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
    border-top: 1px solid var(--border-color, rgba(0,0,0,0.08));
    box-shadow: 0 -6px 20px rgba(0,0,0,0.08);
    margin-inline: -16px;
}
@media (min-width: 1024px) {
    .lr-sticky-cta {
        position: static; padding: 0; background: transparent;
        border: 0; box-shadow: none; margin-inline: 0;
    }
}

/* -------------------------------------------------------------
   10) Drawer utility (opt-in)
   ----------------------------------------------------------- */
.lr-drawer {
    position: fixed; inset: 0; z-index: 70;
    pointer-events: none; opacity: 0;
    transition: opacity 0.18s ease;
}
.lr-drawer[aria-hidden="false"] { pointer-events: auto; opacity: 1; }
.lr-drawer-backdrop { position: absolute; inset: 0; background: rgba(0,0,0,0.5); }
.lr-drawer-panel {
    position: absolute; top: 0; bottom: 0;
    inset-inline-start: 0; width: min(86vw, 360px);
    background: var(--bg-elevated, var(--bg-main, #fff));
    overflow-y: auto; overscroll-behavior: contain;
    padding: 16px;
    transform: translateX(-100%);
    transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
    box-shadow: 0 10px 40px rgba(0,0,0,0.2);
}
[dir="rtl"] .lr-drawer-panel { transform: translateX(100%); }
.lr-drawer[aria-hidden="false"] .lr-drawer-panel { transform: translateX(0); }

.lr-drawer-panel.lr-drawer-end {
    inset-inline-start: auto; inset-inline-end: 0;
    transform: translateX(100%);
}
[dir="rtl"] .lr-drawer-panel.lr-drawer-end { transform: translateX(-100%); }
.lr-drawer[aria-hidden="false"] .lr-drawer-panel.lr-drawer-end { transform: translateX(0); }

@media (min-width: 1024px) {
    .lr-drawer.lr-drawer-md-static {
        position: static; opacity: 1; pointer-events: auto;
    }
    .lr-drawer.lr-drawer-md-static .lr-drawer-backdrop { display: none; }
    .lr-drawer.lr-drawer-md-static .lr-drawer-panel {
        position: static; transform: none; width: auto;
        background: transparent; box-shadow: none; padding: 0; overflow: visible;
    }
}

body.lr-no-scroll { overflow: hidden; touch-action: none; }

/* -------------------------------------------------------------
   11) Touch target safety (opt-in)
   ----------------------------------------------------------- */
@media (max-width: 767.98px) {
    .lr-touch,
    .lr-touch button,
    .lr-touch a {
        min-width: 44px; min-height: 44px;
    }
}

/* -------------------------------------------------------------
   12) Visibility utilities
   ----------------------------------------------------------- */
.lr-hide-md-up { display: initial; }
.lr-show-md-up { display: none; }
@media (min-width: 768px) {
    .lr-hide-md-up { display: none !important; }
    .lr-show-md-up { display: initial; }
    .lr-show-md-up.lr-show-block { display: block; }
    .lr-show-md-up.lr-show-flex  { display: flex; }
    .lr-show-md-up.lr-show-grid  { display: grid; }
}
.lr-hide-lg-up { display: initial; }
.lr-show-lg-up { display: none; }
@media (min-width: 1024px) {
    .lr-hide-lg-up { display: none !important; }
    .lr-show-lg-up { display: initial; }
    .lr-show-lg-up.lr-show-block { display: block; }
    .lr-show-lg-up.lr-show-flex  { display: flex; }
    .lr-show-lg-up.lr-show-grid  { display: grid; }
}

/* -------------------------------------------------------------
   13) Aspect-ratio helpers (opt-in)
   ----------------------------------------------------------- */
.lr-aspect-1     { aspect-ratio: 1 / 1; }
.lr-aspect-4-3   { aspect-ratio: 4 / 3; }
.lr-aspect-4-5   { aspect-ratio: 4 / 5; }
.lr-aspect-16-9  { aspect-ratio: 16 / 9; }
.lr-aspect-3-2   { aspect-ratio: 3 / 2; }
.lr-aspect-fill > * { width: 100%; height: 100%; object-fit: cover; }

/* -------------------------------------------------------------
   14) Typography clamps (opt-in)
   ----------------------------------------------------------- */
.lr-h1   { font-size: clamp(1.6rem, 1.2rem + 1.6vw, 2.4rem); line-height: 1.2; }
.lr-h2   { font-size: clamp(1.35rem, 1.1rem + 1vw, 1.9rem); line-height: 1.25; }
.lr-h3   { font-size: clamp(1.1rem, 1rem + 0.5vw, 1.35rem); line-height: 1.3; }
.lr-lead { font-size: clamp(0.95rem, 0.9rem + 0.3vw, 1.05rem); }

/* -------------------------------------------------------------
   15) Truncation helpers (opt-in)
   ----------------------------------------------------------- */
.lr-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lr-clamp-2, .lr-clamp-3 {
    display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden;
}
.lr-clamp-2 { -webkit-line-clamp: 2; line-clamp: 2; }
.lr-clamp-3 { -webkit-line-clamp: 3; line-clamp: 3; }

/* -------------------------------------------------------------
   16) Container query
   ----------------------------------------------------------- */
.lr-container-q { container-type: inline-size; }

/* -------------------------------------------------------------
   17) Storefront polish (safe, low-risk additive tweaks)
   ----------------------------------------------------------- */
@media (max-width: 767.98px) {
    /* Slightly tighter sections on phones (additive, doesn't alter
       grid structure — just lowers vertical padding). */
    .section { padding-block: 36px; }
    .breadcrumb { flex-wrap: wrap; gap: 4px; font-size: 0.82rem; }
}

/* -------------------------------------------------------------
   17b) Navbar dropdown chrome (CSP-safe, replaces inline styles)
   -----------------------------------------------------------
   These rules replace the `style="..."` and Alpine-driven
   :style/:class bindings that lived in navbar.blade.php. They
   work with the vanilla JS controller embedded in that file.
   ----------------------------------------------------------- */
.nav-dropdown { position: relative; }

.nav-dropdown-toggle {
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.nav-dropdown-chevron {
    font-size: 0.65rem;
    margin-inline-start: 4px;
    transition: transform 0.2s ease;
}
.nav-dropdown.is-open .nav-dropdown-chevron {
    transform: rotate(180deg);
}

/* The .user-dropdown base in components.css uses `right: 0;` which
   the old navbar overrode with inline `style="left:0"` per-locale.
   Now we replace those inline styles with class-based RTL-aware
   alignment. Specificity (0,2,1 via html[dir=...]) beats the
   components.css base (0,1,0). */
.nav-dropdown-menu {
    min-width: 200px;
    /* START-aligned default (Categories sits below+aligned-to-start). */
    left: 0;
    right: auto;
}
html[dir="rtl"] .nav-dropdown-menu {
    left: auto;
    right: 0;
}

/* End-aligned variant (lang switcher, user menu). */
.nav-dropdown-menu-end {
    left: auto;
    right: 0;
}
html[dir="rtl"] .nav-dropdown-menu-end {
    left: 0;
    right: auto;
}

/* Lang switcher icon spacing — replaces the old inline margin styles */
.lang-switch-icon { font-size: 0.85rem; margin-inline-end: 6px; }
.lang-switch .nav-dropdown-chevron { font-size: 0.6rem; margin-inline-start: 6px; }
.lang-flag { font-size: 1rem; }
.lang-check { margin-inline-start: auto; font-size: 0.75rem; color: var(--brand); }

/* Cart/wishlist badge positioning — replaces the long inline style on the
   <span class="nav-badge"> elements in navbar.blade.php. */
.navbar-action-btn-badged { position: relative; }
.nav-badge {
    position: absolute;
    top: -4px;
    inset-inline-end: -4px;
    background: var(--brand);
    color: #fff;
    border-radius: 999px;
    font-size: 0.65rem;
    min-width: 16px;
    height: 16px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 4px;
    font-weight: 700;
    line-height: 1;
}

/* Logout button inside user dropdown — styled like the other items */
.user-dropdown-logout {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 10px 18px;
    background: transparent;
    border: 0;
    color: inherit;
    font: inherit;
    text-align: start;
    cursor: pointer;
    transition: var(--transition);
}
.user-dropdown-logout:hover { background: var(--bg-section); color: var(--brand); }

/* -------------------------------------------------------------
   18) Storefront navbar — mobile drawer (≤1024px)
   -----------------------------------------------------------
   The legacy components.css only handles ≤768px:
     .navbar-links { display: none }
     .mobile-menu-btn { display: flex }
     .navbar-links.active { display: flex; position: absolute; top:header-height; ... }
   This leaves a 769-1023px gap where the hamburger is hidden but
   the menu still tries to lay out horizontally. We extend the
   mobile mode to ≤1024px and reshape the open menu as a side drawer.
   ----------------------------------------------------------- */
@media (max-width: 1023.98px) {
    /* Hamburger MUST be visible across the entire sub-desktop range. */
    .mobile-menu-btn {
        display: inline-flex !important;
        align-items: center;
        justify-content: center;
        width: 40px;
        height: 40px;
        font-size: 1.25rem;
    }

    /* Hide search bar on small screens to declutter the top row. */
    .navbar-search { display: none !important; }

    /* Drawer base — hidden off-screen on the trailing edge. We need
       to be more specific than .navbar-links.active in components.css
       so we use a body+nav chain to win specificity without !important
       on every property. */
    .navbar .navbar-links {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: 4px;
        position: fixed;
        top: 0;
        bottom: 0;
        inset-inline-end: 0;
        inset-inline-start: auto;
        width: min(86vw, 320px);
        height: 100vh;
        height: 100dvh;
        padding: 72px 16px 24px;
        background: var(--bg-header, var(--bg-main, #fff));
        transform: translateX(100%);
        transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1);
        z-index: 95;
        overflow-y: auto;
        overscroll-behavior: contain;
        box-shadow: -10px 0 40px rgba(0,0,0,0.2);
        box-sizing: border-box;
    }
    [dir="rtl"] .navbar .navbar-links {
        transform: translateX(-100%);
    }
    /* Legacy components.css sets `display: none` on .navbar-links at
       ≤768px (no `!important`). Our rule above sets `display: flex`
       at the same specificity (0,2,0 vs 0,1,0 — we win specificity). */

    /* Beats `.navbar-links.active` from components.css (which would
       otherwise reset to position:absolute with 20px padding) AND
       `.navbar-links.active { background: rgba(13,11,20,0.95) }` from
       luxury-polish.css (which would render the drawer as a dark
       translucent panel instead of a solid side drawer).
       Specificity 0,3,0 wins over both. We re-assert every property
       the legacy rules touch so cascade order can't surprise us. */
    .navbar .navbar-links.active {
        display: flex !important;
        flex-direction: column;
        align-items: stretch;
        gap: 4px;
        transform: translateX(0);
        position: fixed;
        top: 0;
        bottom: 0;
        inset-inline-end: 0;
        inset-inline-start: auto;
        width: min(86vw, 320px);
        height: 100vh;
        height: 100dvh;
        padding: 72px 16px 24px;
        background: var(--bg-header, var(--bg-main, #fff));
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
        border-top: 0;
        box-shadow: -10px 0 40px rgba(0,0,0,0.2);
        z-index: 95;
    }
    [dir="rtl"] .navbar .navbar-links.active {
        inset-inline-end: 0;
        inset-inline-start: auto;
        box-shadow: 10px 0 40px rgba(0,0,0,0.2);
    }

    /* Hamburger → close (X) state — used by the JS class-swap. The
       transition is on the parent button so the icon rotates smoothly. */
    .mobile-menu-btn { transition: transform 0.2s ease; }
    .mobile-menu-btn.is-open { transform: rotate(90deg); }

    /* Belt-and-suspenders: even if the JS class-swap is ever skipped
       (e.g. external script error before our inline handler runs), the
       open-state button forces the X glyph by overriding the FontAwesome
       ::before content. Works whether the inner <i> still has fa-bars
       or already has fa-times. \f00d == FA "times" / "xmark". */
    .mobile-menu-btn.is-open [data-nav-icon]::before {
        content: "\f00d" !important;
    }
    .mobile-menu-btn:not(.is-open) [data-nav-icon]::before {
        content: "\f0c9";  /* FA "bars" */
    }

    .navbar .navbar-links > a {
        padding: 14px;
        border-radius: 10px;
        font-size: 1rem;
        width: 100%;
    }
    .navbar .navbar-links > a::after { display: none; }
    .navbar .navbar-links > a:hover,
    .navbar .navbar-links > a.active {
        background: rgba(var(--brand-rgb, 183 132 116), 0.10);
    }

    /* Inside the drawer, the nav-dropdown wrapper flows in document order;
       its menu becomes a collapsible accordion controlled by .is-open
       (toggled by the vanilla JS click handler). */
    .navbar .navbar-links .nav-dropdown {
        position: static;
        width: 100%;
    }
    .navbar .navbar-links .nav-dropdown-toggle {
        display: flex;
        justify-content: space-between;
        align-items: center;
        width: 100%;
        padding: 14px;
        border-radius: 10px;
        font-size: 1rem;
        color: inherit;
    }
    /* Dropdown menu inside drawer: full-width accordion, no shadow */
    .navbar .navbar-links .nav-dropdown-menu {
        position: static;
        box-shadow: none;
        border: 0;
        background: transparent;
        padding: 4px 0 4px 12px;
        min-width: 0;
        width: 100%;
        max-height: 0;
        overflow: hidden;
        opacity: 1;
        visibility: visible;
        transform: none;
        pointer-events: auto;
        transition: max-height 0.3s ease;
    }
    .navbar .navbar-links .nav-dropdown.is-open .nav-dropdown-menu {
        max-height: 80vh;
    }
    .navbar .navbar-links .nav-dropdown-menu a {
        padding: 10px 12px;
        font-size: 0.92rem;
        border-radius: 8px;
    }
}

/* Backdrop behind the open drawer */
.lr-nav-backdrop {
    position: fixed; inset: 0;
    background: rgba(0,0,0,0.5);
    opacity: 0; pointer-events: none;
    transition: opacity 0.22s ease;
    z-index: 90;
}
.lr-nav-backdrop.is-open { opacity: 1; pointer-events: auto; }
@media (min-width: 1024px) { .lr-nav-backdrop { display: none !important; } }

/* -------------------------------------------------------------
   18a) Navbar action buttons — keep them visible on tiny screens
   ----------------------------------------------------------- */
@media (max-width: 1023.98px) {
    .navbar-inner { gap: 8px; }
    .navbar-actions { gap: 6px; flex-wrap: nowrap; }

    .navbar-logo {
        font-size: 1.15rem;
        letter-spacing: 1px;
        gap: 6px;
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .navbar-logo img { height: 32px; }

    .navbar-action-btn,
    .user-menu-toggle {
        width: 40px;
        height: 40px;
        flex-shrink: 0;
    }
    .user-menu-toggle img { width: 32px; height: 32px; }

    /* Lang switcher: keep the icons, hide the long label so the topbar
       doesn't overflow on narrow phones. */
    .lang-switch {
        padding: 0 10px;
        height: 40px;
        font-size: 0.78rem;
    }
    .lang-switch > span { display: none; }
}

@media (max-width: 480px) {
    .navbar-logo { font-size: 1rem; }
    .navbar-logo img { height: 28px; }
    /* Even tighter on tiny phones */
    .navbar-actions { gap: 4px; }
    .lang-switch { padding: 0 8px; }
}

/* -------------------------------------------------------------
   19) Admin polish — SAFE, non-structural tweaks only
   -----------------------------------------------------------
   Removed earlier aggressive rules (.admin-page-header column,
   .admin-form-actions sticky, .admin-card-header column) because
   those broke pages with custom layouts. Keeping ONLY pure
   wrapping/spacing safety net.
   ----------------------------------------------------------- */
@media (max-width: 767.98px) {
    /* Form grids collapse to one column on phones — additive,
       only affects grids that already use these classes. */
    .admin-form-grid,
    .admin-form-grid-2,
    .admin-form-grid-3 {
        grid-template-columns: 1fr !important;
    }

    /* Filter rows wrap nicely — additive */
    .admin-filter-row,
    .admin-filter-bar {
        flex-wrap: wrap;
        gap: 8px;
    }

    /* Pagination wraps on small screens */
    .pagination, .admin-pagination {
        flex-wrap: wrap;
        gap: 4px;
        justify-content: center;
    }
}

/* -------------------------------------------------------------
   20) Print: hide drawers and CTAs
   ----------------------------------------------------------- */
@media print {
    .lr-drawer,
    .lr-nav-backdrop,
    .lr-sticky-cta,
    .mobile-menu-btn {
        display: none !important;
    }
}

/* =============================================================
   21) STOREFRONT FLUID TYPOGRAPHY & MOBILE POLISH
   -----------------------------------------------------------
   Scoped to `body:not(.admin-body)` so NONE of this leaks into
   the admin panel (admin body has class="admin-body"). All sizing
   uses `clamp(min, preferred, max)` so the type and components
   scale smoothly between phones and desktop without media-query
   step-changes. Built mobile-first.

   The viewport-min anchor for clamp is 360px (narrowest common
   phone). The viewport-max anchor is 1280px (XL desktop). Anything
   between scales linearly via the `vw` term.
   ============================================================= */

/* ─── A) Fluid base + heading scale ─────────────────────────────
   Root font-size 15px on a 360px viewport, 16px from 1024px+.
   This makes EVERY rem-based size adapt automatically (cards,
   buttons, paddings declared in rem) without us touching them. */
body:not(.admin-body) {
    font-size: clamp(0.94rem, 0.88rem + 0.30vw, 1rem);
    line-height: 1.65;
}

/* Page headings — the inline `font-size: 1.8rem` on profile stat
   numbers and the `font-size: 1.5rem` on hero <h2> are now fluid
   via these defaults. Inline-styled h1/h2/h3 are overridden later
   in section B (profile-specific). */
body:not(.admin-body) h1,
body:not(.admin-body) .section-title,
body:not(.admin-body) .hero h1 {
    font-size: clamp(1.6rem, 1.2rem + 2.0vw, 2.6rem);
    line-height: 1.2;
}
body:not(.admin-body) h2 {
    font-size: clamp(1.35rem, 1.05rem + 1.4vw, 2rem);
    line-height: 1.25;
}
body:not(.admin-body) h3 {
    font-size: clamp(1.1rem, 0.95rem + 0.8vw, 1.45rem);
    line-height: 1.3;
}
body:not(.admin-body) h4 {
    font-size: clamp(0.98rem, 0.9rem + 0.4vw, 1.15rem);
}
body:not(.admin-body) .section-subtitle {
    font-size: clamp(0.88rem, 0.82rem + 0.3vw, 1rem);
}

/* The .btn padding is fixed (14px 28px in luxury-polish). Make it
   slightly tighter on phones so primary actions don't dominate. */
@media (max-width: 480px) {
    body:not(.admin-body) .btn { padding: 11px 20px; font-size: 0.92rem; }
    body:not(.admin-body) .btn-sm { padding: 7px 14px; font-size: 0.82rem; }
}

/* Universal grid safety: any direct flex/grid child shouldn't be
   prevented from shrinking. This stops long emails, order numbers,
   and SKU strings from forcing the parent wider than the viewport. */
body:not(.admin-body) main > section,
body:not(.admin-body) .container > * {
    min-width: 0;
}

/* ─── B) NAVBAR fluid layout ──────────────────────────────────
   Previous behaviour: 6 fixed-size buttons (40px each) plus the
   logo plus a 50–60px lang switcher easily overflowed 360px wide
   phones, causing horizontal scroll. Fix:
     • container side-padding narrower on phones (96% vs 92%)
     • action buttons scale 34→42px via clamp
     • icon font scales 0.9→1rem
     • logo image scales 26→40px
     • cart/wishlist badges scale with the button
*/
@media (max-width: 1023.98px) {
    body:not(.admin-body) .container,
    body:not(.admin-body) .navbar .container {
        width: min(1200px, 96%);
    }
    body:not(.admin-body) .navbar-inner {
        gap: clamp(4px, 1.5vw, 10px);
        min-width: 0;
        flex-wrap: nowrap;
    }
    body:not(.admin-body) .navbar-actions {
        gap: clamp(3px, 1.2vw, 8px);
        flex-shrink: 0;
        flex-wrap: nowrap;
    }
    body:not(.admin-body) .navbar-logo {
        font-size: clamp(0.92rem, 0.85rem + 0.6vw, 1.15rem);
        gap: clamp(4px, 1vw, 8px);
        letter-spacing: 0.5px;
        min-width: 0;
        flex-shrink: 1;
    }
    body:not(.admin-body) .navbar-logo img {
        height: clamp(26px, 5.5vw, 36px);
        width: auto;
    }
    body:not(.admin-body) .navbar-action-btn,
    body:not(.admin-body) .user-menu-toggle {
        width: clamp(34px, 4.4vw + 24px, 42px);
        height: clamp(34px, 4.4vw + 24px, 42px);
    }
    body:not(.admin-body) .navbar-action-btn { font-size: clamp(0.85rem, 0.7rem + 0.5vw, 1rem); }
    body:not(.admin-body) .user-menu-toggle img,
    body:not(.admin-body) .user-menu-toggle .avatar-initials {
        width: clamp(28px, 4vw + 18px, 36px);
        height: clamp(28px, 4vw + 18px, 36px);
        font-size: clamp(0.72rem, 0.6rem + 0.4vw, 0.9rem);
    }
    body:not(.admin-body) .nav-badge,
    body:not(.admin-body) .count-badge {
        min-width: clamp(14px, 1.8vw + 10px, 20px);
        height: clamp(14px, 1.8vw + 10px, 20px);
        font-size: clamp(0.55rem, 0.4rem + 0.4vw, 0.7rem);
        line-height: 1;
    }
    body:not(.admin-body) .lang-switch {
        height: clamp(34px, 4.4vw + 24px, 42px);
        padding: 0 clamp(6px, 1.2vw, 12px);
        font-size: clamp(0.72rem, 0.65rem + 0.3vw, 0.85rem);
    }
    /* Storefront theme toggle uses .navbar-action-btn → inherits sizing.
       Icons still need to scale with the shrinking button. */
    body:not(.admin-body) .storefront-theme-toggle .storefront-theme-icon-dark,
    body:not(.admin-body) .storefront-theme-toggle .storefront-theme-icon-light {
        font-size: clamp(0.85rem, 0.7rem + 0.5vw, 1rem);
    }
}

/* Ultra-narrow phones (≤380px): just trim spacing here. Lang-switch
   sizing is fully handled in section P below (globe icon kept,
   chevron hidden, becomes a square button matching the others). */
@media (max-width: 380px) {
    body:not(.admin-body) .navbar-actions { gap: 2px; }
    /* Trim breadcrumb on tiny phones */
    body:not(.admin-body) .breadcrumb { font-size: 0.78rem; gap: 4px; }
}

/* ─── C) PROFILE page — header card no longer overflows ────────
   Original (components.css): display:flex; gap:24px; padding:32px.
   At ≤640px the 120px avatar + the long email + the change-password
   button stayed on one row → forced horizontal scroll. We flip to
   column layout below 640px and centre everything. Avatar size and
   stat numbers are clamped so they don't dwarf small screens. */
body:not(.admin-body) .profile-header {
    flex-wrap: wrap;
    padding: clamp(18px, 2vw + 12px, 32px);
    gap: clamp(14px, 2vw, 24px);
}
body:not(.admin-body) .profile-header .profile-avatar,
body:not(.admin-body) .profile-header > [class*="avatar"] {
    width: clamp(76px, 14vw + 50px, 120px) !important;
    height: clamp(76px, 14vw + 50px, 120px) !important;
    flex-shrink: 0;
}
body:not(.admin-body) .profile-info {
    min-width: 0;
    flex: 1 1 220px;
}
body:not(.admin-body) .profile-info h2 {
    word-break: break-word;
    overflow-wrap: anywhere;
}
/* Long emails were the worst offender — force them to wrap on chars
   when they're longer than the column allows. */
body:not(.admin-body) .profile-info p {
    word-break: break-word;
    overflow-wrap: anywhere;
    font-size: clamp(0.85rem, 0.78rem + 0.3vw, 0.95rem);
}

@media (max-width: 640px) {
    body:not(.admin-body) .profile-header {
        flex-direction: column;
        text-align: center;
        align-items: center;
    }
    /* Stack the email/phone icons and the change-password button
       below the avatar so nothing protrudes past the card edge. */
    body:not(.admin-body) .profile-info p {
        justify-content: center;
        display: flex;
        align-items: center;
        gap: 6px;
        flex-wrap: wrap;
    }
    body:not(.admin-body) .profile-info .btn { width: 100%; max-width: 280px; }
}

/* Profile stat cards (`grid-4` → 4 white tiles). Inline `font-size:
   1.8rem` on the numeric h3 was the issue — too big once the tile
   becomes 1-col on mobile. Override with clamp. */
body:not(.admin-body) .grid-4 .card h3,
body:not(.admin-body) .grid-4 .card > h3 {
    font-size: clamp(1.25rem, 0.95rem + 1.4vw, 1.8rem) !important;
    word-break: break-word;
}
body:not(.admin-body) .grid-4 .card i.fa-coins,
body:not(.admin-body) .grid-4 .card i.fa-box,
body:not(.admin-body) .grid-4 .card i.fa-heart,
body:not(.admin-body) .grid-4 .card i.fa-map-marker-alt {
    font-size: clamp(1.4rem, 1.1rem + 0.9vw, 1.8rem) !important;
}

/* ─── D) Generic card / inline-styled padding safety net ───────
   Pages used `<div class="card" style="padding:24px">` widely.
   On small phones that's wasted real-estate. Reduce safely. */
@media (max-width: 480px) {
    body:not(.admin-body) .card[style*="padding:24px"],
    body:not(.admin-body) .card[style*="padding: 24px"] {
        padding: 16px !important;
    }
    body:not(.admin-body) .section { padding: 32px 0; }
    body:not(.admin-body) .grid-4,
    body:not(.admin-body) .grid-products,
    body:not(.admin-body) .grid-categories,
    body:not(.admin-body) .grid-brands,
    body:not(.admin-body) .grid-features { gap: 14px; }
}

/* ─── E) Cart line — 120px image too big on small phones ──────
   Switch to a smaller image column at ≤520px so the body has
   breathing room for name + quantity + remove. */
@media (max-width: 520px) {
    body:not(.admin-body) .cart-grid .cart-item {
        grid-template-columns: 92px 1fr;
        gap: 12px;
        padding: 14px;
    }
    body:not(.admin-body) .cart-grid .cart-item-img {
        width: 92px;
        height: 92px;
    }
    body:not(.admin-body) .cart-grid .cart-item-name {
        font-size: 0.95rem;
    }
    /* The pay/details actions row on profile orders fits two-up */
    body:not(.admin-body) .profile-order-row__actions .btn {
        font-size: 0.78rem;
        padding: 6px 10px;
    }
}

/* ─── F) Address card grid — 2 cols on tablets, 1 on phones ──── */
@media (max-width: 600px) {
    body:not(.admin-body) .grid-2 { grid-template-columns: 1fr; }
}

/* ─── G) Hero + Newsletter — guarantee they never overflow ──── */
body:not(.admin-body) .hero,
body:not(.admin-body) .newsletter-section {
    overflow: hidden;
}
body:not(.admin-body) .newsletter-section {
    margin: 0 clamp(8px, 2vw, 24px);
    padding: clamp(32px, 4vw + 16px, 60px) clamp(16px, 4vw, 40px);
}
@media (max-width: 480px) {
    body:not(.admin-body) .newsletter-form { flex-direction: column; }
}

/* ─── H) Long-text words (URLs, SKUs, order numbers) ──────────
   Any inline `<code>`, `<a>`, or status-badge string that overflows
   gets clipped with an ellipsis or wraps softly. Prevents the page
   width from being held hostage by a stray 60-char hash. */
body:not(.admin-body) .status-badge,
body:not(.admin-body) .profile-order-row__number {
    word-break: break-all;
    overflow-wrap: anywhere;
}

/* ─── I) Form inputs — ALWAYS at least 16px font on mobile ────
   iOS Safari auto-zooms when an input is focused if the font-size
   computes to less than 16px. That zoom is what causes the page to
   shift unexpectedly when the keyboard pops up. */
@media (max-width: 768px) {
    body:not(.admin-body) input[type="text"],
    body:not(.admin-body) input[type="email"],
    body:not(.admin-body) input[type="password"],
    body:not(.admin-body) input[type="tel"],
    body:not(.admin-body) input[type="number"],
    body:not(.admin-body) input[type="search"],
    body:not(.admin-body) input[type="url"],
    body:not(.admin-body) textarea,
    body:not(.admin-body) select {
        font-size: 16px;
    }
}

/* ─── J) Footer columns — pile up neatly on phones ──────────── */
@media (max-width: 480px) {
    body:not(.admin-body) .footer { padding: 36px 0 0; margin-top: 40px; }
    body:not(.admin-body) .footer-grid { gap: 22px; padding-bottom: 28px; }
    body:not(.admin-body) .footer-brand p,
    body:not(.admin-body) .footer-col a { font-size: 0.85rem; }
}

/* ─── K) Breadcrumb wraps instead of overflowing ───────────── */
body:not(.admin-body) .breadcrumb {
    flex-wrap: wrap;
    row-gap: 4px;
}
body:not(.admin-body) .breadcrumb > * {
    min-width: 0;
    overflow-wrap: anywhere;
}

/* ─── L) Inline `style="font-size:Xrem"` override layer ────────
   Multiple storefront views (product/show, home, profile, payment,
   addresses, auth) bake explicit pixel-ish font sizes inline so they
   bypass even our :root clamp(). We can't change every blade file
   without churn, so we use attribute selectors to scale those down
   smoothly on small phones. Scoped to storefront only — never admin. */
@media (max-width: 640px) {
    body:not(.admin-body) [style*="font-size:2.4rem"],
    body:not(.admin-body) [style*="font-size: 2.4rem"] { font-size: 1.7rem !important; }

    body:not(.admin-body) [style*="font-size:1.8rem"],
    body:not(.admin-body) [style*="font-size: 1.8rem"] { font-size: 1.3rem !important; }

    body:not(.admin-body) [style*="font-size:1.5rem"],
    body:not(.admin-body) [style*="font-size: 1.5rem"] { font-size: 1.18rem !important; }

    body:not(.admin-body) [style*="font-size:1.4rem"],
    body:not(.admin-body) [style*="font-size: 1.4rem"] { font-size: 1.1rem !important; }
}
@media (max-width: 380px) {
    body:not(.admin-body) [style*="font-size:1.8rem"],
    body:not(.admin-body) [style*="font-size: 1.8rem"] { font-size: 1.18rem !important; }
}

/* ─── M) Avatar component — override the inline width/height/font-size
   that the <x-storefront::avatar :size="120"> component bakes inline.
   Component output:
       <span class="avatar-initials" style="width:120px;height:120px;
             background:hsl(...); font-size:50px">AA</span>
   Inline styles beat normal CSS, so we use !important on a
   carefully-targeted selector to win the cascade. */
body:not(.admin-body) .profile-header img,
body:not(.admin-body) .profile-header .avatar-initials {
    max-width: 100%;
}
@media (max-width: 640px) {
    body:not(.admin-body) .profile-header img,
    body:not(.admin-body) .profile-header .avatar-initials {
        width: clamp(72px, 18vw, 110px) !important;
        height: clamp(72px, 18vw, 110px) !important;
        font-size: clamp(1.6rem, 5vw, 2.4rem) !important;
    }
}

/* ─── N) Status badges — never exceed their cell ───────────── */
body:not(.admin-body) .status-badge {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ─── O) FIX: Mobile drawer opens at the top of the page instead of
   at the current scroll position when the user has scrolled down.

   Root cause: animations.css line 326 applies
       body:not(.admin-body) { animation: luran-fade-in .3s ease both; }
   The `luran-fade-in` keyframe sets `transform: translateY(0)` at the
   `to` step, and `animation-fill-mode: both` means that transform
   stays on the body forever after the animation ends. Per the CSS
   spec, ANY non-`none` transform on an element creates a new
   containing block for its `position: fixed` descendants — they
   become positioned relative to the body's origin (top of page)
   instead of the viewport. So the drawer that should slide in from
   the right edge of the viewport actually anchors to top:0 of the
   body, which is far above the screen when the user has scrolled.

   The admin layout already worked around the same bug for its own
   sidebar (see admin-luxury.css line ~66 — `animation: none !important;
   transform: none !important;` on `body.admin-body`). We do the
   same here but ONLY for the storefront body — admin still has its
   own override.

   We keep the fade-in EFFECT by re-applying it with an opacity-only
   keyframe defined below, so the entrance animation still works
   without re-introducing the containing-block bug. */
@keyframes luran-storefront-fade-in-opacity {
    from { opacity: 0; }
    to   { opacity: 1; }
}
body:not(.admin-body) {
    animation: luran-storefront-fade-in-opacity 0.3s ease both !important;
    /* Belt-and-braces: even if some other rule re-introduces a transform
       on body later, force it back to none so position:fixed works. */
    transform: none !important;
}

/* ─── P) FIX: Language button looks empty on tiny screens (e.g. Galaxy S8).
   On ≤380px section C above hid BOTH the chevron AND the globe-icon,
   but the text <span> was already hidden at ≤1024px — result: the
   button rendered with zero visible content. We now keep the globe
   icon, hide only the chevron, and turn the button into a square
   42×42 tile so it visually matches the other action buttons. */
@media (max-width: 480px) {
    body:not(.admin-body) .lang-switch {
        /* Match the other circular action buttons (wishlist/cart/theme).
           Override the earlier `padding: 0 8px` rule from section 18a. */
        width: clamp(38px, 10vw + 4px, 42px);
        height: clamp(38px, 10vw + 4px, 42px);
        padding: 0;
        gap: 0;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        border-radius: var(--radius-full);
    }
    /* Keep the globe icon visible — it's the only signal of "language"
       once the label is hidden. Bump its size slightly so it reads. */
    body:not(.admin-body) .lang-switch .lang-switch-icon {
        display: inline-block !important;
        font-size: 0.95rem;
        margin: 0;
    }
    /* Hide the chevron only — saves room, the dropdown still opens. */
    body:not(.admin-body) .lang-switch .nav-dropdown-chevron {
        display: none;
    }
    /* The label span has been hidden on ≤768 since the original
       responsive.css rule; keep it hidden in this layer too. */
    body:not(.admin-body) .lang-switch > span:not(.lang-switch-icon):not(.nav-dropdown-chevron) {
        display: none;
    }
}
