{"product_id":"decorative-convex-wall-mirror-collection-with-distinct-frame-styles","title":"Decorative Convex Wall Mirror Collection with Distinct Frame Styles","description":"\u003cstyle\u003e\n#fecify-typography-scope { scroll-behavior: auto; overflow-x: visible; display: flow-root; width: 100%; max-width: none; margin: 0; font-weight: 400 !important; }\n#fecify-typography-scope *, #fecify-typography-scope *::before, #fecify-typography-scope *::after { box-sizing: border-box; }\n#fecify-typography-scope img { display: block !important; max-width: 100% !important; width: 100% !important; height: auto !important; margin: 0 !important; padding: 0 !important; border: 0 !important; }\n#fecify-typography-scope video { display: block; max-width: 100%; margin: 0 !important; }\n\n    #fecify-typography-scope {\n      \/* Candlelit salon — warm ivory + antique gilt + soft ink, echo gold\/black mirrors *\/\n      --bg: #f7f1e8;\n      --bg-soft: #ebe2d4;\n      --ink: #241e18;\n      --text: #3a322a;\n      --text-soft: #6e6256;\n      --muted: #9a8b78;\n      --line: rgba(36, 30, 24, 0.1);\n      --accent: #c4a06a;\n      --accent-deep: #8a6840;\n      --gilt: #d8b87a;\n      --ink-soft: #2c2620;\n      --paper: #fff9f1;\n      --band: #efe6d8;\n      --fs-eyebrow: 0.7rem;\n      --fs-meta: 0.875rem;\n      --fs-body: 1rem;\n      --fs-lead: 1.06rem;\n      --fs-h3: 1.32rem;\n      --fs-h2: clamp(1.9rem, 2.9vw, 2.5rem);\n      --fs-display: clamp(2.55rem, 4.5vw, 3.45rem);\n      --font-title: \"Cormorant Garamond\", \"Iowan Old Style\", Georgia, serif;\n      --font-ui: \"Figtree\", \"Helvetica Neue\", Arial, sans-serif;\n      --space: clamp(1.55rem, 3.2vw, 2.6rem);\n      --max: 1180px;\n      --ease: cubic-bezier(0.22, 1, 0.36, 1);\n      --radius: 18px;\n      margin: 0;\n      color: var(--text);\n      background:\n        radial-gradient(ellipse 52% 40% at 12% 8%, rgba(216, 184, 122, 0.22), transparent 58%),\n        radial-gradient(ellipse 44% 36% at 92% 88%, rgba(44, 38, 32, 0.06), transparent 56%),\n        linear-gradient(165deg, #fbf6ee 0%, #f7f1e8 48%, #f0e8dc 100%);\n      font-family: var(--font-ui);\n      font-size: var(--fs-body);\n      font-weight: 400 !important;\n      line-height: 1.65;\n      -webkit-font-smoothing: antialiased;\n    }\n    #fecify-typography-scope *, #fecify-typography-scope *::before, #fecify-typography-scope *::after { box-sizing: border-box; }\n    #fecify-typography-scope img {\n      display: block !important; width: 100% !important; height: auto !important;\n      max-width: 100% !important; margin: 0 !important; padding: 0 !important; border: 0; vertical-align: top;\n    }\n    #fecify-typography-scope a { color: inherit; text-decoration: none; }\n    #fecify-typography-scope p, #fecify-typography-scope span, #fecify-typography-scope li, #fecify-typography-scope div { font-weight: inherit; }\n    #fecify-typography-scope .wrap { width: min(100% - 2rem, var(--max)); margin-inline: auto; }\n    #fecify-typography-scope .eyebrow {\n      margin: 0 0 0.65rem; color: var(--accent);\n      font-size: var(--fs-eyebrow); font-weight: 600 !important;\n      letter-spacing: 0.16em; text-transform: uppercase;\n    }\n    #fecify-typography-scope .display {\n      margin: 0; font-family: var(--font-title); font-size: var(--fs-display);\n      font-weight: 500 !important; line-height: 1.08; letter-spacing: -0.02em; color: var(--ink);\n    }\n    #fecify-typography-scope .display em { font-style: italic; font-weight: 400 !important; color: var(--accent-deep); }\n    #fecify-typography-scope .h2 {\n      margin: 0; font-family: var(--font-title); font-size: var(--fs-h2);\n      font-weight: 500 !important; line-height: 1.16; letter-spacing: -0.015em; color: var(--ink);\n    }\n    #fecify-typography-scope .h3 {\n      margin: 0; font-family: var(--font-title); font-size: var(--fs-h3);\n      font-weight: 500 !important; line-height: 1.28; color: var(--ink);\n    }\n    #fecify-typography-scope h1, #fecify-typography-scope h2, #fecify-typography-scope h3 { font-weight: 500 !important; }\n    #fecify-typography-scope .lead {\n      margin: 0.85rem 0 0; max-width: 34rem; color: var(--text-soft);\n      font-size: var(--fs-lead); font-weight: 400 !important; line-height: 1.65;\n    }\n    #fecify-typography-scope .section-head { margin-bottom: clamp(1rem, 2vw, 1.4rem); }\n    #fecify-typography-scope .section-head .lead { max-width: 38rem; }\n    #fecify-typography-scope .body {\n      margin: 0.4rem 0 0; color: var(--text-soft);\n      font-size: var(--fs-body); font-weight: 400 !important; line-height: 1.55;\n    }\n    #fecify-typography-scope .section { padding: var(--space) 0; }\n    #fecify-typography-scope .section--tight-b { padding-bottom: 0.25rem; }\n    #fecify-typography-scope .section--tight-t { padding-top: 0.5rem; }\n    #fecify-typography-scope .section--motion { padding-bottom: 0; }\n    #fecify-typography-scope .section--motion + .section { padding-top: var(--space); }\n    #fecify-typography-scope .section--band {\n      background:\n        radial-gradient(ellipse 60% 80% at 50% 0%, rgba(216, 184, 122, 0.14), transparent 70%),\n        linear-gradient(180deg, #f0e7da 0%, #e8ddd0 100%);\n      border-block: 1px solid rgba(196, 160, 106, 0.22);\n    }\n    #fecify-typography-scope .divider {\n      width: min(100% - 2rem, var(--max)); margin: clamp(1rem, 2vw, 1.4rem) auto;\n      display: flex; align-items: center; gap: 0.85rem;\n    }\n    #fecify-typography-scope .divider__line {\n      flex: 1; height: 1px;\n      background: linear-gradient(90deg, transparent, rgba(196, 160, 106, 0.55), transparent);\n    }\n    #fecify-typography-scope .divider__mark {\n      flex: 0 0 auto; width: 0.7rem; height: 0.7rem; border-radius: 50%;\n      background:\n        radial-gradient(circle at 35% 30%, #f6e7c4, #c4a06a 55%, #8a6840);\n      box-shadow: 0 0 0 4px rgba(196, 160, 106, 0.12);\n    }\n    #fecify-typography-scope .shot {\n      position: relative; overflow: hidden; border-radius: var(--radius);\n      background: var(--bg-soft); line-height: 0;\n      box-shadow: 0 18px 40px rgba(36, 30, 24, 0.08);\n      border: 1px solid rgba(196, 160, 106, 0.18);\n    }\n    #fecify-typography-scope .hero-grid {\n      display: grid; grid-template-columns: 1.2fr 0.9fr;\n      gap: clamp(1.5rem, 3.2vw, 2.6rem); align-items: center;\n    }\n    #fecify-typography-scope .meta { display: flex; flex-wrap: wrap; gap: 0.45rem; margin: 1.15rem 0 0; }\n    #fecify-typography-scope .chip {\n      display: inline-flex; align-items: center; padding: 0.38rem 0.8rem;\n      border-radius: 999px; background: rgba(255, 249, 241, 0.9);\n      border: 1px solid rgba(196, 160, 106, 0.32); color: var(--accent-deep);\n      font-size: 0.8rem !important; font-weight: 500 !important;\n    }\n    #fecify-typography-scope .detail-card { margin: 0; padding: 0; background: transparent; border: 0; min-width: 0; }\n    #fecify-typography-scope .detail-card .meta { display: block; margin-top: 0.9rem; text-align: center; }\n    #fecify-typography-scope .detail-card .meta .eyebrow { margin: 0 0 0.28rem; color: var(--accent-deep); }\n    #fecify-typography-scope .detail-card .meta .h3 { margin: 0; }\n    #fecify-typography-scope .detail-card .meta .body { margin: 0.35rem auto 0; max-width: 28ch; }\n    #fecify-typography-scope .detail-card .shot img,\n    #fecify-typography-scope .space-card .shot img,\n    #fecify-typography-scope .specs-view .shot img,\n    #fecify-typography-scope .size-view .shot img,\n    #fecify-typography-scope .feature-grid \u003e .shot img,\n    #fecify-typography-scope .feature-grid \u003e .shot video {\n      width: 100% !important; height: auto !important; object-fit: contain;\n      display: block; margin: 0 !important;\n    }\n    #fecify-typography-scope .carousel { position: relative; }\n    #fecify-typography-scope .carousel-stage { position: relative; }\n    #fecify-typography-scope .carousel-btn {\n      position: absolute; z-index: 4;\n      top: 0; left: 0.4rem;\n      display: inline-grid; place-items: center;\n      width: 2.6rem; height: 2.6rem; padding: 0;\n      border-radius: 50%;\n      border: 1px solid rgba(196, 160, 106, 0.45);\n      background: rgba(255, 249, 241, 0.94);\n      color: var(--accent-deep); cursor: pointer;\n      pointer-events: auto !important; touch-action: manipulation;\n      box-shadow: 0 8px 22px rgba(36, 30, 24, 0.12);\n      transform: translateY(-50%);\n    }\n    #fecify-typography-scope .carousel-btn--next { left: auto; right: 0.4rem; }\n    #fecify-typography-scope .carousel-btn.is-hidden { display: none !important; }\n    #fecify-typography-scope .carousel-btn svg { width: 14px; height: 14px; pointer-events: none; }\n    #fecify-typography-scope .detail-grid.carousel-track,\n    #fecify-typography-scope .space-grid.carousel-track {\n      display: flex !important;\n      gap: clamp(0.9rem, 2vw, 1.25rem);\n      overflow-x: scroll !important;\n      overflow-y: hidden !important;\n      overscroll-behavior-x: contain;\n      -webkit-overflow-scrolling: touch !important;\n      touch-action: pan-y !important;\n      cursor: grab;\n      scrollbar-width: none; -ms-overflow-style: none;\n    }\n    #fecify-typography-scope .carousel-track::-webkit-scrollbar { display: none; height: 0; }\n    #fecify-typography-scope .carousel-track img,\n    #fecify-typography-scope .carousel-track a,\n    #fecify-typography-scope .carousel-track button,\n    #fecify-typography-scope .carousel-track .shot,\n    #fecify-typography-scope .carousel-track article {\n      -webkit-user-drag: none !important;\n      user-select: none; -webkit-user-select: none;\n      touch-action: pan-y !important;\n    }\n    #fecify-typography-scope .carousel-track * { touch-action: pan-y !important; }\n    #fecify-typography-scope .detail-grid.carousel-track \u003e *,\n    #fecify-typography-scope .space-grid.carousel-track \u003e * {\n      flex: 0 0 calc((100% - 2 * clamp(0.9rem, 2vw, 1.25rem)) \/ 3);\n      max-width: calc((100% - 2 * clamp(0.9rem, 2vw, 1.25rem)) \/ 3);\n      min-width: 0;\n    }\n    #fecify-typography-scope .carousel-track.is-dragging { cursor: grabbing; user-select: none; }\n    @media (max-width: 980px) {\n      #fecify-typography-scope .detail-grid.carousel-track \u003e *,\n      #fecify-typography-scope .space-grid.carousel-track \u003e * {\n        flex: 0 0 calc((100% - clamp(0.9rem, 2vw, 1.25rem)) \/ 2);\n        max-width: calc((100% - clamp(0.9rem, 2vw, 1.25rem)) \/ 2);\n      }\n    }\n    #fecify-typography-scope .space-card { padding: 0; background: transparent; border: 0; min-width: 0; }\n    #fecify-typography-scope .space-card .h3 { margin-top: 0.85rem; text-align: center; }\n    #fecify-typography-scope .space-card .body { text-align: center; max-width: 26ch; margin-inline: auto; }\n    #fecify-typography-scope .feature-grid {\n      display: grid; grid-template-columns: 1fr 1.05fr;\n      gap: clamp(1.25rem, 2.8vw, 2.1rem); align-items: stretch;\n    }\n    #fecify-typography-scope .feature-copy {\n      position: relative; overflow: hidden;\n      display: flex; flex-direction: column; justify-content: center;\n      min-width: 0; min-height: 0; height: 100%;\n      padding: clamp(1.45rem, 3vw, 2.1rem) clamp(1.3rem, 2.8vw, 1.95rem);\n      border-radius: 2rem 1.2rem 2rem 1.2rem; color: #2f2822;\n      background:\n        radial-gradient(ellipse 70% 55% at 100% 0%, rgba(216, 184, 122, 0.28), transparent 58%),\n        radial-gradient(ellipse 55% 48% at 0% 100%, rgba(44, 38, 32, 0.06), transparent 60%),\n        linear-gradient(155deg, #fff9f1 0%, #f4ebe0 46%, #ebe0d2 100%);\n      border: 1px solid rgba(196, 160, 106, 0.28);\n      box-shadow:\n        inset 0 1px 0 rgba(255, 255, 255, 0.75),\n        0 18px 38px rgba(36, 30, 24, 0.07);\n    }\n    #fecify-typography-scope .feature-copy::before {\n      content: \"\";\n      position: absolute; inset: 0.85rem;\n      border-radius: 1.55rem 0.9rem 1.55rem 0.9rem;\n      border: 1px solid rgba(196, 160, 106, 0.22);\n      pointer-events: none;\n    }\n    #fecify-typography-scope .feature-copy \u003e * { position: relative; z-index: 1; }\n    #fecify-typography-scope .feature-copy .eyebrow { color: var(--accent-deep); }\n    #fecify-typography-scope .feature-copy .h2 { margin: 0; max-width: 16ch; color: var(--ink); }\n    #fecify-typography-scope .feature-copy .lead { color: var(--text-soft); max-width: 34ch; margin: 0.55rem 0 0; }\n    #fecify-typography-scope .feature-points {\n      display: flex; flex-direction: column; gap: 0;\n      margin: 0.95rem 0 0; padding: 0.7rem 0 0;\n      border-top: 1px solid rgba(196, 160, 106, 0.22); list-style: none !important;\n    }\n    #fecify-typography-scope .feature-point {\n      display: flex; align-items: center; gap: 0.65rem;\n      margin: 0; padding: 0.48rem 0;\n      border-bottom: 1px solid rgba(36, 30, 24, 0.08);\n      color: #3f3730; font-size: var(--fs-body);\n    }\n    #fecify-typography-scope .feature-point::before {\n      content: \"\"; flex: 0 0 auto; width: 0.48rem; height: 0.48rem; border-radius: 50%;\n      background: radial-gradient(circle at 35% 30%, #f6e7c4, #c4a06a 55%, #8a6840);\n      box-shadow: 0 0 0 3px rgba(196, 160, 106, 0.14);\n    }\n    #fecify-typography-scope .feature-point:last-child { border-bottom: 0; padding-bottom: 0; }\n    #fecify-typography-scope .feature-grid \u003e .shot {\n      height: 100%; min-height: 0;\n      border-radius: 1.2rem 2rem 1.2rem 2rem;\n      box-shadow: 0 18px 38px rgba(36, 30, 24, 0.1);\n    }\n    #fecify-typography-scope .feature-grid \u003e .shot img,\n    #fecify-typography-scope .feature-grid \u003e .shot video {\n      height: 100% !important; object-fit: cover;\n    }\n    #fecify-typography-scope .carousel-dots { display: none !important; }\n    #fecify-typography-scope .specs-block {\n      padding: clamp(1.4rem, 3vw, 2.1rem); border-radius: calc(var(--radius) + 6px);\n      background: var(--paper);\n      border: 1px solid rgba(196, 160, 106, 0.22);\n      box-shadow: 0 16px 36px rgba(36, 30, 24, 0.05);\n    }\n    #fecify-typography-scope .size-toggle {\n      display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 1rem;\n    }\n    #fecify-typography-scope .size-btn {\n      appearance: none; -webkit-appearance: none; cursor: pointer;\n      padding: 0.42rem 0.75rem; border-radius: 999px;\n      border: 1px solid rgba(196, 160, 106, 0.32);\n      background: #fff; color: var(--accent-deep);\n      font-family: var(--font-ui); font-size: 0.78rem !important; font-weight: 500 !important;\n    }\n    #fecify-typography-scope .size-btn.is-active {\n      background: linear-gradient(145deg, #3a322a, #241e18);\n      color: #f8f1e6; border-color: #241e18;\n    }\n    #fecify-typography-scope .specs-layout {\n      display: grid; grid-template-columns: minmax(0, 1.222fr) minmax(0, 1fr);\n      gap: clamp(1.2rem, 2.8vw, 2rem); align-items: stretch; margin-top: 1.15rem;\n    }\n    #fecify-typography-scope .size-view {\n      display: flex; flex-direction: column; align-items: stretch;\n      gap: 0.75rem; min-width: 0;\n    }\n    #fecify-typography-scope .size-frame {\n      display: grid;\n      grid-template-columns: auto minmax(0, 1fr) auto;\n      align-items: center; gap: 0.45rem;\n      min-width: 0;\n    }\n    #fecify-typography-scope .size-stage {\n      position: relative; overflow: hidden; min-width: 0;\n      border-radius: var(--radius);\n      background: #fff;\n      border: 1px solid rgba(196, 160, 106, 0.18);\n    }\n    #fecify-typography-scope .size-track {\n      display: flex !important;\n      width: 100%;\n      overflow-x: scroll !important; overflow-y: hidden !important;\n      overscroll-behavior-x: contain;\n      -webkit-overflow-scrolling: touch !important;\n      touch-action: pan-y !important;\n      scrollbar-width: none; -ms-overflow-style: none;\n      cursor: grab;\n    }\n    #fecify-typography-scope .size-track::-webkit-scrollbar { display: none; height: 0; }\n    #fecify-typography-scope .size-track.is-dragging { cursor: grabbing; user-select: none; }\n    #fecify-typography-scope .size-panel {\n      flex: 0 0 100%; max-width: 100%; min-width: 0;\n      display: block !important;\n    }\n    #fecify-typography-scope .size-panel .shot {\n      border: 0; border-radius: 0; background: #fff;\n      box-shadow: none;\n    }\n    #fecify-typography-scope .size-track img,\n    #fecify-typography-scope .size-track .shot {\n      -webkit-user-drag: none !important;\n      user-select: none; -webkit-user-select: none;\n      touch-action: pan-y !important;\n    }\n    #fecify-typography-scope .size-nav {\n      position: static; transform: none;\n      display: inline-grid; place-items: center;\n      width: 2.4rem; height: 2.4rem; padding: 0; flex: 0 0 auto;\n      border-radius: 50%;\n      border: 1px solid rgba(196, 160, 106, 0.45);\n      background: rgba(255, 249, 241, 0.96);\n      color: var(--accent-deep); cursor: pointer;\n      pointer-events: auto !important; touch-action: manipulation;\n      box-shadow: 0 6px 16px rgba(36, 30, 24, 0.08);\n    }\n    #fecify-typography-scope .size-nav svg { width: 14px; height: 14px; pointer-events: none; }\n    #fecify-typography-scope .size-nav:hover {\n      background: linear-gradient(145deg, #3a322a, #241e18);\n      color: #f8f1e6; border-color: #241e18;\n    }\n    #fecify-typography-scope .size-dots {\n      display: flex; justify-content: center; align-items: center;\n      gap: 0.42rem;\n      position: static; transform: none;\n      margin: 0; padding: 0; border: 0; background: transparent;\n    }\n    #fecify-typography-scope .size-dot {\n      width: 0.4rem; height: 0.4rem; padding: 0; border: 0; border-radius: 50%;\n      background: rgba(36, 30, 24, 0.2); cursor: pointer;\n      appearance: none; -webkit-appearance: none;\n    }\n    #fecify-typography-scope .size-dot.is-active {\n      background: #8a6840;\n      box-shadow: 0 0 0 3px rgba(196, 160, 106, 0.22);\n    }\n    #fecify-typography-scope .spec-list {\n      display: flex; flex-direction: column; justify-content: center;\n      height: 100%; min-height: 100%; box-sizing: border-box;\n      border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);\n      margin: 0; padding: 0.2rem 0; min-width: 0; gap: 0;\n    }\n    #fecify-typography-scope .spec-row {\n      flex: 0 0 auto;\n      display: grid; grid-template-columns: 7.2rem minmax(0, 1fr);\n      gap: 0.3rem 0.75rem;\n      padding: 0.52rem 0;\n      border-bottom: 1px solid var(--line); align-items: center;\n      min-height: 0;\n    }\n    #fecify-typography-scope .spec-row:last-child { border-bottom: 0; }\n    #fecify-typography-scope .spec-k {\n      margin: 0; color: var(--muted);\n      font-size: 0.88rem !important; font-weight: 600 !important; line-height: 1.35;\n    }\n    #fecify-typography-scope .spec-v {\n      margin: 0; color: var(--text);\n      font-size: 1.02rem !important; font-weight: 400 !important;\n      line-height: 1.4; overflow-wrap: break-word;\n    }\n    #fecify-typography-scope .spec-chips { display: flex; flex-wrap: wrap; gap: 0.3rem; }\n    #fecify-typography-scope .spec-chips span {\n      display: inline-block; padding: 0.22rem 0.6rem; border-radius: 999px; background: #fff;\n      border: 1px solid rgba(196, 160, 106, 0.28); color: var(--accent-deep);\n      font-size: 0.84rem !important; font-weight: 500 !important;\n    }\n    @media (max-width: 980px) {\n      #fecify-typography-scope .hero-grid, #fecify-typography-scope .feature-grid, #fecify-typography-scope .specs-layout {\n        display: grid !important; grid-template-columns: 1fr !important;\n      }\n      #fecify-typography-scope .feature-copy { height: auto; }\n      #fecify-typography-scope .feature-grid \u003e .shot { height: auto; }\n      #fecify-typography-scope .feature-grid \u003e .shot img,\n      #fecify-typography-scope .feature-grid \u003e .shot video { height: auto !important; object-fit: contain; }\n      #fecify-typography-scope .spec-list { height: auto; min-height: 0; justify-content: flex-start; padding: 0; }\n      #fecify-typography-scope .spec-row { padding: 0.5rem 0; }\n      \/* 手机\/窄屏：尺寸图拉满宽度，箭头与圆点并排在下方 *\/\n      #fecify-typography-scope .size-view {\n        display: grid;\n        grid-template-columns: 2.4rem minmax(0, 1fr) 2.4rem;\n        grid-template-areas:\n          \"stage stage stage\"\n          \"prev dots next\";\n        gap: 0.7rem 0.55rem;\n        align-items: center;\n      }\n      #fecify-typography-scope .size-frame { display: contents; }\n      #fecify-typography-scope .size-stage { grid-area: stage; width: 100%; }\n      #fecify-typography-scope .size-nav--prev { grid-area: prev; justify-self: start; }\n      #fecify-typography-scope .size-nav--next { grid-area: next; justify-self: end; }\n      #fecify-typography-scope .size-dots { grid-area: dots; justify-content: center; }\n      #fecify-typography-scope .size-nav {\n        width: 2.25rem; height: 2.25rem;\n        box-shadow: 0 4px 12px rgba(36, 30, 24, 0.08);\n      }\n    }\n    @media (max-width: 720px) {\n      #fecify-typography-scope {\n        --fs-display: 2.35rem; --fs-h2: 1.85rem; --fs-h3: 1.28rem;\n        --fs-body: 0.9375rem; --fs-lead: 0.95rem;\n        width: 100vw !important; max-width: 100vw !important;\n        margin-left: calc(50% - 50vw) !important; margin-right: calc(50% - 50vw) !important;\n        padding-left: max(20px, env(safe-area-inset-left, 0px)) !important;\n        padding-right: max(20px, env(safe-area-inset-right, 0px)) !important;\n        box-sizing: border-box !important; overflow-x: visible;\n      }\n      #fecify-typography-scope .wrap { width: 100%; max-width: none; padding-inline: 0; }\n      #fecify-typography-scope .wrap.specs-block { padding: 1.25rem 1.1rem !important; }\n      #fecify-typography-scope .section { padding-top: 1.4rem; padding-bottom: 1.4rem; }\n      #fecify-typography-scope .divider { width: 100%; }\n      #fecify-typography-scope .section--band {\n        margin-inline: calc(-1 * max(20px, env(safe-area-inset-left, 0px)));\n        padding-inline: max(20px, env(safe-area-inset-left, 0px));\n        width: 100vw; box-sizing: border-box;\n      }\n      #fecify-typography-scope .detail-grid.carousel-track \u003e *,\n      #fecify-typography-scope .space-grid.carousel-track \u003e * {\n        flex: 0 0 min(78%, 300px); max-width: min(78%, 300px);\n      }\n      #fecify-typography-scope .spec-row { grid-template-columns: 1fr; gap: 0.15rem; align-items: start; }\n      #fecify-typography-scope .size-btn { font-size: 0.72rem !important; padding: 0.38rem 0.6rem; }\n    }\n    @media (max-width: 720px) {\n      .el-collapse-item__wrap:has(#ml-convex-pdp), .el-collapse-item__wrap:has(#fecify-typography-scope),\n      .el-collapse-item__content:has(#ml-convex-pdp), .el-collapse-item__content:has(#fecify-typography-scope),\n      .body_html:has(#ml-convex-pdp), .body_html:has(#fecify-typography-scope) {\n        overflow: visible !important; height: auto !important; max-height: none !important;\n      }\n      .body_html:has(#ml-convex-pdp), .body_html:has(#fecify-typography-scope) {\n        width: 100vw !important; max-width: 100vw !important;\n        margin-left: calc(50% - 50vw) !important; margin-right: calc(50% - 50vw) !important;\n        padding-left: 0 !important; padding-right: 0 !important;\n        box-sizing: border-box !important; background: transparent !important;\n      }\n      #ml-convex-pdp { box-shadow: -100vw 0 0 0 #f7f1e8, 100vw 0 0 0 #f7f1e8; }\n    }\n  \n\u003c\/style\u003e\u003cdiv id=\"fecify-typography-scope\"\u003e\n\u003csection class=\"section section--tight-b\"\u003e\u003cdiv class=\"wrap hero-grid\"\u003e\n\u003cdiv class=\"shot\"\u003e\u003cimg src=\"https:\/\/d5754b614d.yunchenkeji.com\/media\/custom_1082\/561\/image\/2026\/10\/20\/0c845abdb5c251e9e51696ab5afac783.jpg\" alt=\"Decorative convex wall mirror collection on a cream gallery wall\" width=\"1536\" height=\"1024\"\u003e\u003c\/div\u003e\n\u003cdiv class=\"hero-copy\"\u003e\n\u003cp class=\"eyebrow\"\u003eConvex wall mirror collection\u003c\/p\u003e\n\u003ch1 class=\"display\"\u003eEight frames.\u003cbr\u003e\u003cem\u003eOne convex glow.\u003c\/em\u003e\n\u003c\/h1\u003e\n\u003cp class=\"lead\"\u003eAntique gold sunbursts and ink-black frames—small convex mirrors that deepen a wall, bounce light, and read as sculpture.\u003c\/p\u003e\n\u003cdiv class=\"meta\"\u003e\n\u003cspan class=\"chip\"\u003e8 frame styles\u003c\/span\u003e \u003cspan class=\"chip\"\u003eConvex glass\u003c\/span\u003e \u003cspan class=\"chip\"\u003eWall hung\u003c\/span\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\u003c\/section\u003e\u003cdiv class=\"divider\" aria-hidden=\"true\"\u003e\n\u003cspan class=\"divider__line\"\u003e\u003c\/span\u003e \u003cspan class=\"divider__mark\"\u003e\u003c\/span\u003e \u003cspan class=\"divider__line\"\u003e\u003c\/span\u003e\n\u003c\/div\u003e\n\u003csection class=\"section section--tight-t\"\u003e\u003cdiv class=\"wrap\"\u003e\u003cdiv class=\"carousel\" data-loop=\"0\"\u003e\n\u003cdiv class=\"section-head\"\u003e\n\u003cp class=\"eyebrow\"\u003eIn detail\u003c\/p\u003e\n\u003ch2 class=\"h2\"\u003eHang, curve, craft.\u003c\/h2\u003e\n\u003cp class=\"lead\"\u003eReady to mount, a true convex glow, and eight styles made for the wall.\u003c\/p\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"carousel-stage\"\u003e\n\u003cbutton type=\"button\" class=\"carousel-btn carousel-btn--prev\" aria-label=\"Previous\"\u003e\u003csvg viewbox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\"\u003e\u003cpath d=\"M9 2L4 7l5 5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/button\u003e\u003cdiv class=\"detail-grid carousel-track\"\u003e\n\u003carticle class=\"detail-card\"\u003e\u003cdiv class=\"shot\"\u003e\u003cimg src=\"https:\/\/d5754b614d.yunchenkeji.com\/media\/custom_1082\/561\/image\/2026\/10\/20\/a8d999c4151efa664e96daf99d327351.jpg\" alt=\"Back hanging hardware on convex wall mirror\" width=\"1254\" height=\"1254\"\u003e\u003c\/div\u003e\n\u003cdiv class=\"meta\"\u003e\n\u003cp class=\"eyebrow\"\u003eMount\u003c\/p\u003e\n\u003ch3 class=\"h3\"\u003eBack hanging ready\u003c\/h3\u003e\n\u003cp class=\"body\"\u003eA secure rear hanger sits flush—lift onto a nail or hook and hang in minutes.\u003c\/p\u003e\n\u003c\/div\u003e\u003c\/article\u003e\u003carticle class=\"detail-card\"\u003e\u003cdiv class=\"shot\"\u003e\u003cimg src=\"https:\/\/d5754b614d.yunchenkeji.com\/media\/custom_1082\/561\/image\/2026\/10\/20\/f2bdb7cad175cec24b314e60f3d57776.jpg\" alt=\"Convex mirror glass reflecting the room\" width=\"1254\" height=\"1254\"\u003e\u003c\/div\u003e\n\u003cdiv class=\"meta\"\u003e\n\u003cp class=\"eyebrow\"\u003eGlass\u003c\/p\u003e\n\u003ch3 class=\"h3\"\u003eTrue convex glow\u003c\/h3\u003e\n\u003cp class=\"body\"\u003eThe curved glass pulls the room in—wider view, softer light, a little depth on the wall.\u003c\/p\u003e\n\u003c\/div\u003e\u003c\/article\u003e\u003carticle class=\"detail-card\"\u003e\u003cdiv class=\"shot\"\u003e\u003cimg src=\"https:\/\/d5754b614d.yunchenkeji.com\/media\/custom_1082\/561\/image\/2026\/10\/20\/775cb670567250da2c7a269150fda705.jpg\" alt=\"Fine crafted frames in multiple styles\" width=\"1254\" height=\"1254\"\u003e\u003c\/div\u003e\n\u003cdiv class=\"meta\"\u003e\n\u003cp class=\"eyebrow\"\u003eCraft\u003c\/p\u003e\n\u003ch3 class=\"h3\"\u003eFine finish, eight styles\u003c\/h3\u003e\n\u003cp class=\"body\"\u003eCast detail in gold and black—from sunburst to bobbin—so one wall or a gallery both feel finished.\u003c\/p\u003e\n\u003c\/div\u003e\u003c\/article\u003e\n\u003c\/div\u003e\n\u003cbutton type=\"button\" class=\"carousel-btn carousel-btn--next\" aria-label=\"Next\"\u003e\u003csvg viewbox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\"\u003e\u003cpath d=\"M5 2l5 5-5 5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/button\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\u003c\/div\u003e\u003c\/section\u003e\u003csection class=\"section section--band\"\u003e\u003cdiv class=\"wrap\"\u003e\u003cdiv class=\"carousel\" data-loop=\"0\"\u003e\n\u003cdiv class=\"section-head\"\u003e\n\u003cp class=\"eyebrow\"\u003eOn the wall\u003c\/p\u003e\n\u003ch2 class=\"h2\"\u003eSolo accent or gallery cluster.\u003c\/h2\u003e\n\u003cp class=\"lead\"\u003eAbove a console, along a sitting wall, or at the stair—small mirrors that finish a vignette and soft-light the room.\u003c\/p\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"carousel-stage\"\u003e\n\u003cbutton type=\"button\" class=\"carousel-btn carousel-btn--prev\" aria-label=\"Previous\"\u003e\u003csvg viewbox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\"\u003e\u003cpath d=\"M9 2L4 7l5 5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/button\u003e\u003cdiv class=\"space-grid carousel-track\"\u003e\n\u003carticle class=\"space-card\"\u003e\u003cdiv class=\"shot\"\u003e\u003cimg src=\"https:\/\/d5754b614d.yunchenkeji.com\/media\/custom_1082\/561\/image\/2026\/10\/20\/576bc47358e5d9cef541faf90711df91.jpg\" alt=\"Convex mirror styling an entry console vignette\" width=\"1254\" height=\"1254\"\u003e\u003c\/div\u003e\n\u003ch3 class=\"h3\"\u003eEntry\u003c\/h3\u003e\n\u003cp class=\"body\"\u003eA warm gleam above the console—welcomes the hall and pulls soft light into the threshold.\u003c\/p\u003e\u003c\/article\u003e\u003carticle class=\"space-card\"\u003e\u003cdiv class=\"shot\"\u003e\u003cimg src=\"https:\/\/d5754b614d.yunchenkeji.com\/media\/custom_1082\/561\/image\/2026\/10\/20\/c630535449008024672d4e65a4de0744.jpg\" alt=\"Convex mirror anchoring a living room wall\" width=\"1254\" height=\"1254\"\u003e\u003c\/div\u003e\n\u003ch3 class=\"h3\"\u003eLiving\u003c\/h3\u003e\n\u003cp class=\"body\"\u003eAnchors the sitting wall between shelves and mantel—adds depth and a quiet sparkle to the room.\u003c\/p\u003e\u003c\/article\u003e\u003carticle class=\"space-card\"\u003e\u003cdiv class=\"shot\"\u003e\u003cimg src=\"https:\/\/d5754b614d.yunchenkeji.com\/media\/custom_1082\/561\/image\/2026\/10\/20\/d0c936860f569f61aa80d4d8f010c344.jpg\" alt=\"Convex mirror above a sideboard vignette\" width=\"1254\" height=\"1254\"\u003e\u003c\/div\u003e\n\u003ch3 class=\"h3\"\u003eSideboard\u003c\/h3\u003e\n\u003cp class=\"body\"\u003eFinishes the wall above the console—adds a soft gleam and pulls the vignette together.\u003c\/p\u003e\u003c\/article\u003e\u003carticle class=\"space-card\"\u003e\u003cdiv class=\"shot\"\u003e\u003cimg src=\"https:\/\/d5754b614d.yunchenkeji.com\/media\/custom_1082\/561\/image\/2026\/10\/20\/4d71cea25fff959187908503f2fa0352.jpg\" alt=\"Convex mirror on a stair landing console\" width=\"1254\" height=\"1254\"\u003e\u003c\/div\u003e\n\u003ch3 class=\"h3\"\u003eStair\u003c\/h3\u003e\n\u003cp class=\"body\"\u003eA quiet note by the stair—grounds the landing and opens a soft reflection of the rooms beyond.\u003c\/p\u003e\u003c\/article\u003e\n\u003c\/div\u003e\n\u003cbutton type=\"button\" class=\"carousel-btn carousel-btn--next\" aria-label=\"Next\"\u003e\u003csvg viewbox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\"\u003e\u003cpath d=\"M5 2l5 5-5 5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/button\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\u003c\/div\u003e\u003c\/section\u003e\u003csection class=\"section section--motion\"\u003e\u003cdiv class=\"wrap feature-grid\"\u003e\n\u003cdiv class=\"feature-copy\"\u003e\u003cdiv\u003e\n\u003cp class=\"eyebrow\"\u003eIn motion\u003c\/p\u003e\n\u003ch2 class=\"h2\"\u003eWatch the room curve in.\u003c\/h2\u003e\n\u003cp class=\"lead\"\u003eA short look at how the convex glass deepens the wall and catches the room.\u003c\/p\u003e\n\u003cdiv class=\"feature-points\"\u003e\n\u003cdiv class=\"feature-point\"\u003eConvex glass widens the view with soft drama\u003c\/div\u003e\n\u003cdiv class=\"feature-point\"\u003eAntique gold catches a warm edge of light\u003c\/div\u003e\n\u003cdiv class=\"feature-point\"\u003eBlack frames quiet a gallery wall\u003c\/div\u003e\n\u003cdiv class=\"feature-point\"\u003eSmall scale, strong silhouette from every angle\u003c\/div\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\u003c\/div\u003e\n\u003cdiv class=\"shot\" aria-label=\"Convex mirror in motion\"\u003e\u003cvideo width=\"300\" height=\"150\" src=\"https:\/\/d5754b614d.yunchenkeji.com\/media\/file_upload\/561\/video\/2026\/10\/21\/f8fee4caff829c76dfecafab6f9b2e00.mp4\" poster=\"https:\/\/d5754b614d.yunchenkeji.com\/media\/custom_1082\/561\/image\/2026\/10\/20\/0c845abdb5c251e9e51696ab5afac783.jpg\" autoplay=\"autoplay\" muted=\"\" loop=\"loop\" controls=\"controls\" playsinline=\"\" preload=\"metadata\" controlslist=\"nodownload\"\u003e\u003c\/video\u003e\u003c\/div\u003e\n\u003c\/div\u003e\u003c\/section\u003e\u003csection class=\"section\"\u003e\u003cdiv class=\"wrap specs-block\"\u003e\n\u003cdiv class=\"section-head\"\u003e\n\u003cp class=\"eyebrow\"\u003eSpecs\u003c\/p\u003e\n\u003ch2 class=\"h2\"\u003eScale by style\u003c\/h2\u003e\n\u003cdiv class=\"size-toggle\" role=\"group\" aria-label=\"Frame style\"\u003e\n\u003cbutton type=\"button\" class=\"size-btn is-active\" data-size=\"spark\"\u003eSpark\u003c\/button\u003e \u003cbutton type=\"button\" class=\"size-btn\" data-size=\"star\"\u003eStar\u003c\/button\u003e \u003cbutton type=\"button\" class=\"size-btn\" data-size=\"sun\"\u003eSun\u003c\/button\u003e \u003cbutton type=\"button\" class=\"size-btn\" data-size=\"convex-sun\"\u003eConvex Sun\u003c\/button\u003e \u003cbutton type=\"button\" class=\"size-btn\" data-size=\"floral\"\u003eBlack Floral\u003c\/button\u003e \u003cbutton type=\"button\" class=\"size-btn\" data-size=\"bobbin\"\u003eBlack Bobbin\u003c\/button\u003e \u003cbutton type=\"button\" class=\"size-btn\" data-size=\"starburst\"\u003eBlack Starburst\u003c\/button\u003e \u003cbutton type=\"button\" class=\"size-btn\" data-size=\"deep\"\u003eBlack Deep Frame\u003c\/button\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"specs-layout\"\u003e\n\u003cdiv class=\"size-view\" data-loop=\"0\"\u003e\n\u003cdiv class=\"size-frame\"\u003e\n\u003cbutton type=\"button\" class=\"size-nav size-nav--prev\" aria-label=\"Previous style\"\u003e\u003csvg viewbox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\"\u003e\u003cpath d=\"M9 2L4 7l5 5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/button\u003e\u003cdiv class=\"size-stage\"\u003e\u003cdiv class=\"size-track\"\u003e\n\u003cdiv class=\"size-panel\" data-size=\"spark\"\u003e\u003cdiv class=\"shot\"\u003e\u003cimg src=\"https:\/\/d5754b614d.yunchenkeji.com\/media\/custom_1082\/561\/image\/2026\/10\/20\/c4f7fc6213b053f6c533e903d792ce96.jpg\" alt=\"Spark size diagram H 7.7 × W 7.7 × D 0.7 in \/ 19.5 × 19.5 × 1.7 cm\" width=\"1254\" height=\"1254\"\u003e\u003c\/div\u003e\u003c\/div\u003e\n\u003cdiv class=\"size-panel\" data-size=\"star\"\u003e\u003cdiv class=\"shot\"\u003e\u003cimg src=\"https:\/\/d5754b614d.yunchenkeji.com\/media\/custom_1082\/561\/image\/2026\/10\/20\/2d25be3f0fd3470bbf92c5ef27d932f2.jpg\" alt=\"Star size diagram H 9.8 × W 9.8 × D 0.6 in \/ 25 × 25 × 1.4 cm\" width=\"1254\" height=\"1254\"\u003e\u003c\/div\u003e\u003c\/div\u003e\n\u003cdiv class=\"size-panel\" data-size=\"sun\"\u003e\u003cdiv class=\"shot\"\u003e\u003cimg src=\"https:\/\/d5754b614d.yunchenkeji.com\/media\/custom_1082\/561\/image\/2026\/10\/20\/5b983b0b0f5a5687fffac1eb2bb4bafd.jpg\" alt=\"Sun size diagram Dia. 12.2 in \/ 31 cm\" width=\"1254\" height=\"1254\"\u003e\u003c\/div\u003e\u003c\/div\u003e\n\u003cdiv class=\"size-panel\" data-size=\"convex-sun\"\u003e\u003cdiv class=\"shot\"\u003e\u003cimg src=\"https:\/\/d5754b614d.yunchenkeji.com\/media\/custom_1082\/561\/image\/2026\/10\/20\/46ae4efc10a4cc3c0145b2be6044208f.jpg\" alt=\"Convex Sun size diagram Dia. 13.4 in \/ 34 cm\" width=\"1254\" height=\"1254\"\u003e\u003c\/div\u003e\u003c\/div\u003e\n\u003cdiv class=\"size-panel\" data-size=\"floral\"\u003e\u003cdiv class=\"shot\"\u003e\u003cimg src=\"https:\/\/d5754b614d.yunchenkeji.com\/media\/custom_1082\/561\/image\/2026\/10\/20\/f0eb610513da3ed3adc0fc8840d98378.jpg\" alt=\"Black Floral size diagram Dia. 7.9 in \/ 20 cm\" width=\"1254\" height=\"1254\"\u003e\u003c\/div\u003e\u003c\/div\u003e\n\u003cdiv class=\"size-panel\" data-size=\"bobbin\"\u003e\u003cdiv class=\"shot\"\u003e\u003cimg src=\"https:\/\/d5754b614d.yunchenkeji.com\/media\/custom_1082\/561\/image\/2026\/10\/20\/f9e835d49e78d60ea400f558393b3580.jpg\" alt=\"Black Bobbin size diagram Dia. 8.3 in \/ 21 cm\" width=\"1254\" height=\"1254\"\u003e\u003c\/div\u003e\u003c\/div\u003e\n\u003cdiv class=\"size-panel\" data-size=\"starburst\"\u003e\u003cdiv class=\"shot\"\u003e\u003cimg src=\"https:\/\/d5754b614d.yunchenkeji.com\/media\/custom_1082\/561\/image\/2026\/10\/20\/3185c42c1bd1745a16bd88da96e9e658.jpg\" alt=\"Black Starburst size diagram Dia. 13.4 in \/ 34 cm\" width=\"1254\" height=\"1254\"\u003e\u003c\/div\u003e\u003c\/div\u003e\n\u003cdiv class=\"size-panel\" data-size=\"deep\"\u003e\u003cdiv class=\"shot\"\u003e\u003cimg src=\"https:\/\/d5754b614d.yunchenkeji.com\/media\/custom_1082\/561\/image\/2026\/10\/20\/998d8de1254975994c89b6a3ab7e5706.jpg\" alt=\"Black Deep Frame size diagram H 7.5 × W 7.5 × D 1.6 in \/ 19 × 19 × 4 cm\" width=\"1254\" height=\"1254\"\u003e\u003c\/div\u003e\u003c\/div\u003e\n\u003c\/div\u003e\u003c\/div\u003e\n\u003cbutton type=\"button\" class=\"size-nav size-nav--next\" aria-label=\"Next style\"\u003e\u003csvg viewbox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\"\u003e\u003cpath d=\"M5 2l5 5-5 5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/button\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"size-dots\" aria-label=\"Style pagination\"\u003e\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"spec-list\"\u003e\n\u003cdiv class=\"spec-row\"\u003e\n\u003cdiv class=\"spec-k\"\u003eType\u003c\/div\u003e\n\u003cdiv class=\"spec-v\"\u003eDecorative convex wall mirror\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"spec-row\"\u003e\n\u003cdiv class=\"spec-k\"\u003eStyle\u003c\/div\u003e\n\u003cdiv class=\"spec-v spec-style\"\u003eSpark\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"spec-row\"\u003e\n\u003cdiv class=\"spec-k\"\u003eOverall\u003c\/div\u003e\n\u003cdiv class=\"spec-v spec-overall\"\u003eH 7.7 × W 7.7 × D 0.7 in \/ 19.5 × 19.5 × 1.7 cm\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"spec-row\"\u003e\n\u003cdiv class=\"spec-k\"\u003eMaterial\u003c\/div\u003e\n\u003cdiv class=\"spec-v spec-material\"\u003eGlass · antique gold frame\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"spec-row\"\u003e\n\u003cdiv class=\"spec-k\"\u003eGlass\u003c\/div\u003e\n\u003cdiv class=\"spec-v\"\u003eConvex mirror centre\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"spec-row\"\u003e\n\u003cdiv class=\"spec-k\"\u003eFinish\u003c\/div\u003e\n\u003cdiv class=\"spec-v\"\u003e\u003cdiv class=\"spec-chips\"\u003e\n\u003cspan\u003eAntique Gold\u003c\/span\u003e\u003cspan\u003eAntique Black\u003c\/span\u003e\n\u003c\/div\u003e\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"spec-row\"\u003e\n\u003cdiv class=\"spec-k\"\u003eMount\u003c\/div\u003e\n\u003cdiv class=\"spec-v\"\u003eWall hung\u003c\/div\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\u003c\/section\u003e\u003cscript\u003e\n    (function () {\n      var roots = [];\n      function addRoot(el) {\n        if (!el || roots.indexOf(el) !== -1) return;\n        roots.push(el);\n      }\n      addRoot(document.getElementById(\"fecify-typography-scope\"));\n      Array.prototype.forEach.call(document.querySelectorAll(\"#fecify-typography-scope\"), addRoot);\n      if (!roots.length) return;\n\n      var wrap = function (i, n) { return ((i % n) + n) % n; };\n\n      function unclipAncestors(root) {\n        var node = root.parentElement;\n        var depth = 0;\n        while (node \u0026\u0026 node !== document.body \u0026\u0026 depth \u003c 14) {\n          var cs = window.getComputedStyle(node);\n          if (cs.overflow !== \"visible\" || cs.overflowX !== \"visible\" || cs.overflowY !== \"visible\") {\n            node.style.setProperty(\"overflow\", \"visible\", \"important\");\n          }\n          if (node.classList) {\n            if (node.classList.contains(\"el-collapse-item__wrap\")) {\n              node.style.setProperty(\"overflow\", \"visible\", \"important\");\n              node.style.setProperty(\"height\", \"auto\", \"important\");\n            }\n            if (\n              node.classList.contains(\"el-collapse-item__content\") ||\n              node.classList.contains(\"body_html\") ||\n              node.classList.contains(\"rte\") ||\n              node.classList.contains(\"product-single__description\")\n            ) {\n              node.style.setProperty(\"overflow\", \"visible\", \"important\");\n              node.style.setProperty(\"height\", \"auto\", \"important\");\n              node.style.setProperty(\"max-height\", \"none\", \"important\");\n            }\n          }\n          node = node.parentElement;\n          depth++;\n        }\n      }\n\n      function applyBleed(root) {\n        unclipAncestors(root);\n      }\n\n      function stepWidth(track) {\n        var first = track.children[0];\n        if (!first) return 0;\n        var style = window.getComputedStyle(track);\n        var gap = parseFloat(style.columnGap || style.gap) || 0;\n        return first.getBoundingClientRect().width + gap;\n      }\n\n      function bindCarousels(root) {\n        root.querySelectorAll(\".carousel\").forEach(function (carousel) {\n          var track = carousel.querySelector(\".carousel-track\");\n          if (!track || track.getAttribute(\"data-bound\") === \"1\") return;\n          track.setAttribute(\"data-bound\", \"1\");\n          var items = track.children;\n          var n = items.length;\n          if (!n) return;\n          var loop = carousel.getAttribute(\"data-loop\") === \"1\";\n          var idx = 0;\n          var lockUntil = 0;\n          var prev = carousel.querySelector(\".carousel-btn--prev\");\n          var next = carousel.querySelector(\".carousel-btn--next\");\n\n          function canScroll() {\n            return track.scrollWidth \u003e track.clientWidth + 8;\n          }\n\n          function maxIdx() {\n            var w = stepWidth(track);\n            if (w \u003c 1) return 0;\n            return Math.max(0, Math.round((track.scrollWidth - track.clientWidth) \/ w));\n          }\n\n          function placeArrows() {\n            var shot = track.querySelector(\".shot\");\n            if (!shot || !prev || !next) return;\n            var sh = shot.getBoundingClientRect().height;\n            if (sh \u003c 8) return;\n            var top = (sh \/ 2) + \"px\";\n            prev.style.top = top;\n            next.style.top = top;\n          }\n\n          function updateNav() {\n            var on = canScroll();\n            if (prev) {\n              prev.classList.toggle(\"is-hidden\", !on);\n              prev.setAttribute(\"aria-hidden\", on ? \"false\" : \"true\");\n              prev.tabIndex = on ? 0 : -1;\n            }\n            if (next) {\n              next.classList.toggle(\"is-hidden\", !on);\n              next.setAttribute(\"aria-hidden\", on ? \"false\" : \"true\");\n              next.tabIndex = on ? 0 : -1;\n            }\n            if (on) placeArrows();\n          }\n\n          function syncFromScroll() {\n            var w = stepWidth(track);\n            if (w \u003c 1) return;\n            var m = maxIdx();\n            idx = Math.max(0, Math.min(m, Math.round(track.scrollLeft \/ w)));\n          }\n\n          function maxScrollLeft() {\n            return Math.max(0, track.scrollWidth - track.clientWidth);\n          }\n\n          function show(i) {\n            if (Date.now() \u003c lockUntil) return;\n            if (!canScroll()) { updateNav(); return; }\n            var m = maxIdx();\n            \/* 到边界停住，不再循环弹回第一张 *\/\n            idx = Math.max(0, Math.min(m, i));\n            var w = stepWidth(track);\n            lockUntil = Date.now() + 320;\n            var left = idx \u003e= m ? maxScrollLeft() : Math.min(idx * w, maxScrollLeft());\n            track.scrollLeft = left;\n          }\n\n          if (prev) prev.addEventListener(\"click\", function (e) { e.preventDefault(); e.stopPropagation(); show(idx - 1); });\n          if (next) next.addEventListener(\"click\", function (e) { e.preventDefault(); e.stopPropagation(); show(idx + 1); });\n\n          \/* 跟手拖拽：横向由 JS 接管，松手吸附一张；两端夹紧不循环 *\/\n          var startX = 0, startY = 0, gesturing = false, axis = null, originLeft = 0, startIdx = 0;\n          track.addEventListener(\"touchstart\", function (e) {\n            if (!e.touches || !e.touches[0] || !canScroll()) return;\n            if (Date.now() \u003c lockUntil) return;\n            startX = e.touches[0].clientX;\n            startY = e.touches[0].clientY;\n            originLeft = track.scrollLeft;\n            syncFromScroll();\n            startIdx = idx;\n            gesturing = true;\n            axis = null;\n          }, { passive: true });\n          track.addEventListener(\"touchmove\", function (e) {\n            if (!gesturing || !e.touches || !e.touches[0]) return;\n            var dx = e.touches[0].clientX - startX;\n            var dy = e.touches[0].clientY - startY;\n            if (!axis \u0026\u0026 (Math.abs(dx) \u003e 6 || Math.abs(dy) \u003e 6)) {\n              axis = Math.abs(dx) \u003e Math.abs(dy) ? \"x\" : \"y\";\n            }\n            if (axis === \"x\") {\n              e.preventDefault();\n              var nextLeft = originLeft - dx;\n              var maxL = maxScrollLeft();\n              if (nextLeft \u003c 0) nextLeft = 0;\n              if (nextLeft \u003e maxL) nextLeft = maxL;\n              track.scrollLeft = nextLeft;\n            }\n          }, { passive: false });\n          track.addEventListener(\"touchend\", function (e) {\n            if (!gesturing) return;\n            gesturing = false;\n            if (axis !== \"x\") return;\n            var tch = e.changedTouches \u0026\u0026 e.changedTouches[0];\n            if (!tch) return;\n            var dx = tch.clientX - startX;\n            if (Date.now() \u003c lockUntil) return;\n            lockUntil = 0;\n            if (Math.abs(dx) \u003c 36) { show(startIdx); return; }\n            show(startIdx + (dx \u003c 0 ? 1 : -1));\n          }, { passive: true });\n\n          track.addEventListener(\"scroll\", function () {\n            if (gesturing || drag) return;\n            window.clearTimeout(track._syncT);\n            track._syncT = window.setTimeout(syncFromScroll, 80);\n          }, { passive: true });\n\n          var drag = false, dStartX = 0, dStartLeft = 0, moved = false, dStartIdx = 0;\n          track.addEventListener(\"pointerdown\", function (e) {\n            if (e.pointerType !== \"mouse\" || e.button !== 0 || !canScroll()) return;\n            if (e.target.closest \u0026\u0026 e.target.closest(\".carousel-btn\")) return;\n            if (Date.now() \u003c lockUntil) return;\n            drag = true; moved = false;\n            dStartX = e.clientX; dStartLeft = track.scrollLeft;\n            syncFromScroll(); dStartIdx = idx;\n            track.classList.add(\"is-dragging\");\n            try { track.setPointerCapture(e.pointerId); } catch (err) {}\n          });\n          track.addEventListener(\"pointermove\", function (e) {\n            if (!drag) return;\n            var dx = e.clientX - dStartX;\n            if (Math.abs(dx) \u003e 3) moved = true;\n            var nextLeft = dStartLeft - dx;\n            var maxL = maxScrollLeft();\n            if (nextLeft \u003c 0) nextLeft = 0;\n            if (nextLeft \u003e maxL) nextLeft = maxL;\n            track.scrollLeft = nextLeft;\n          });\n          track.addEventListener(\"pointerup\", function (e) {\n            if (!drag) return;\n            drag = false;\n            track.classList.remove(\"is-dragging\");\n            if (!moved) return;\n            var dx = e.clientX - dStartX;\n            if (Date.now() \u003c lockUntil) return;\n            lockUntil = 0;\n            if (Math.abs(dx) \u003c 36) show(dStartIdx);\n            else show(dStartIdx + (dx \u003c 0 ? 1 : -1));\n          });\n          track.addEventListener(\"pointercancel\", function () {\n            drag = false; track.classList.remove(\"is-dragging\");\n          });\n          track.addEventListener(\"click\", function (e) {\n            if (moved) { e.preventDefault(); e.stopPropagation(); moved = false; }\n          }, true);\n\n          function refresh() {\n            syncFromScroll();\n            updateNav();\n            if (canScroll()) {\n              var w = stepWidth(track);\n              track.scrollLeft = idx * w;\n            } else {\n              track.scrollLeft = 0;\n              idx = 0;\n            }\n          }\n          window.addEventListener(\"resize\", function () {\n            window.clearTimeout(track._resizeT);\n            track._resizeT = window.setTimeout(refresh, 80);\n          });\n          window.setTimeout(function () { updateNav(); syncFromScroll(); }, 40);\n          window.setTimeout(function () { updateNav(); syncFromScroll(); }, 240);\n          window.setTimeout(updateNav, 600);\n          if (typeof ResizeObserver !== \"undefined\") {\n            try {\n              var ro = new ResizeObserver(function () {\n                window.clearTimeout(track._resizeT);\n                track._resizeT = window.setTimeout(function () { updateNav(); }, 60);\n              });\n              ro.observe(track);\n            } catch (err) {}\n          }\n          Array.prototype.forEach.call(track.querySelectorAll(\"img\"), function (img) {\n            if (img.complete) return;\n            img.addEventListener(\"load\", function () { updateNav(); });\n          });\n        });\n      }\n\n      function bindStyleToggle(root) {\n        var toggle = root.querySelector(\".size-toggle\");\n        var view = root.querySelector(\".size-view\");\n        var track = view \u0026\u0026 view.querySelector(\".size-track\");\n        if (!toggle || !view || !track || view.getAttribute(\"data-bound\") === \"1\") return;\n        view.setAttribute(\"data-bound\", \"1\");\n        toggle.setAttribute(\"data-bound\", \"1\");\n        var overall = root.querySelector(\".spec-overall\");\n        var material = root.querySelector(\".spec-material\");\n        var styleLabel = root.querySelector(\".spec-style\");\n        var finishChips = root.querySelector(\".spec-chips\");\n        var prev = view.querySelector(\".size-nav--prev\");\n        var next = view.querySelector(\".size-nav--next\");\n        var dotsWrap = view.querySelector(\".size-dots\");\n        var panels = Array.prototype.slice.call(track.querySelectorAll(\".size-panel\"));\n        var buttons = Array.prototype.slice.call(toggle.querySelectorAll(\".size-btn\"));\n        var order = panels.map(function (p) { return p.getAttribute(\"data-size\") || \"\"; }).filter(Boolean);\n        var n = order.length;\n        if (!n) return;\n        var loop = view.getAttribute(\"data-loop\") === \"1\";\n        var idx = 0;\n        var lockUntil = 0;\n        var map = {\n          \"spark\": { overall: \"H 7.7 × W 7.7 × D 0.7 in \/ 19.5 × 19.5 × 1.7 cm\", material: \"Glass · antique gold frame\", finish: [\"Antique Gold\"] },\n          \"star\": { overall: \"H 9.8 × W 9.8 × D 0.6 in \/ 25 × 25 × 1.4 cm\", material: \"Glass · antique gold frame\", finish: [\"Antique Gold\"] },\n          \"sun\": { overall: \"Dia. 12.2 in \/ 31 cm\", material: \"Resin · antique gold\", finish: [\"Antique Gold\"] },\n          \"convex-sun\": { overall: \"Dia. 13.4 in \/ 34 cm\", material: \"Iron \u0026 mirror · antiqued gold\", finish: [\"Antique Gold\"] },\n          \"floral\": { overall: \"Dia. 7.9 in \/ 20 cm\", material: \"Resin · antique black with gold accents\", finish: [\"Antique Black\", \"Gold accents\"] },\n          \"bobbin\": { overall: \"Dia. 8.3 in \/ 21 cm\", material: \"Resin · distressed black\", finish: [\"Antique Black\"] },\n          \"starburst\": { overall: \"Dia. 13.4 in \/ 34 cm\", material: \"Resin · antique black\", finish: [\"Antique Black\"] },\n          \"deep\": { overall: \"H 7.5 × W 7.5 × D 1.6 in \/ 19 × 19 × 4 cm\", material: \"Glass · antique black deep frame\", finish: [\"Antique Black\"] }\n        };\n        var labels = {\n          \"spark\": \"Spark\", \"star\": \"Star\", \"sun\": \"Sun\", \"convex-sun\": \"Convex Sun\",\n          \"floral\": \"Black Floral\", \"bobbin\": \"Black Bobbin\", \"starburst\": \"Black Starburst\", \"deep\": \"Black Deep Frame\"\n        };\n\n        function step() {\n          var w = track.clientWidth || track.getBoundingClientRect().width || 0;\n          if (w \u003e= 1) return w;\n          var first = panels[0];\n          return first ? first.getBoundingClientRect().width : 0;\n        }\n\n        function renderDots() {\n          if (!dotsWrap) return;\n          dotsWrap.innerHTML = \"\";\n          for (var i = 0; i \u003c n; i++) {\n            (function (i) {\n              var b = document.createElement(\"button\");\n              b.type = \"button\";\n              b.className = \"size-dot\" + (i === idx ? \" is-active\" : \"\");\n              b.setAttribute(\"aria-label\", \"Go to \" + (labels[order[i]] || (\"style \" + (i + 1))));\n              b.addEventListener(\"click\", function (e) {\n                e.preventDefault(); e.stopPropagation();\n                show(i);\n              });\n              dotsWrap.appendChild(b);\n            })(i);\n          }\n        }\n\n        function syncUI() {\n          var size = order[idx];\n          buttons.forEach(function (b) {\n            b.classList.toggle(\"is-active\", (b.getAttribute(\"data-size\") || \"\") === size);\n          });\n          if (dotsWrap) {\n            Array.prototype.forEach.call(dotsWrap.children, function (d, di) {\n              d.classList.toggle(\"is-active\", di === idx);\n            });\n          }\n          var data = map[size];\n          if (data) {\n            if (overall) overall.textContent = data.overall;\n            if (material) material.textContent = data.material;\n            if (styleLabel) styleLabel.textContent = labels[size] || size;\n            if (finishChips \u0026\u0026 data.finish) {\n              finishChips.innerHTML = data.finish.map(function (f) {\n                return \"\u003cspan\u003e\" + f + \"\u003c\/span\u003e\";\n              }).join(\"\");\n            }\n          }\n        }\n\n        function scrollToIndex() {\n          var w = step();\n          if (w \u003c 1) return false;\n          track.scrollLeft = idx * w;\n          return true;\n        }\n\n        function show(i, force) {\n          if (!force \u0026\u0026 Date.now() \u003c lockUntil) return;\n          idx = Math.max(0, Math.min(n - 1, i));\n          syncUI();\n          if (!scrollToIndex()) {\n            window.requestAnimationFrame(function () { scrollToIndex(); });\n          }\n          if (!force) lockUntil = Date.now() + 280;\n        }\n\n        buttons.forEach(function (btn) {\n          btn.addEventListener(\"click\", function () {\n            var size = btn.getAttribute(\"data-size\") || \"\";\n            var i = order.indexOf(size);\n            if (i \u003e= 0) show(i);\n          });\n        });\n        if (prev) prev.addEventListener(\"click\", function (e) { e.preventDefault(); e.stopPropagation(); show(idx - 1); });\n        if (next) next.addEventListener(\"click\", function (e) { e.preventDefault(); e.stopPropagation(); show(idx + 1); });\n\n        var startX = 0, startY = 0, gesturing = false, axis = null, originLeft = 0, startIdx = 0;\n        track.addEventListener(\"touchstart\", function (e) {\n          if (!e.touches || !e.touches[0] || Date.now() \u003c lockUntil) return;\n          startX = e.touches[0].clientX; startY = e.touches[0].clientY;\n          originLeft = track.scrollLeft; startIdx = idx;\n          gesturing = true; axis = null;\n        }, { passive: true });\n        track.addEventListener(\"touchmove\", function (e) {\n          if (!gesturing || !e.touches || !e.touches[0]) return;\n          var dx = e.touches[0].clientX - startX, dy = e.touches[0].clientY - startY;\n          if (!axis \u0026\u0026 (Math.abs(dx) \u003e 6 || Math.abs(dy) \u003e 6)) axis = Math.abs(dx) \u003e Math.abs(dy) ? \"x\" : \"y\";\n          if (axis === \"x\") {\n            e.preventDefault();\n            var nextLeft = originLeft - dx;\n            var maxL = Math.max(0, track.scrollWidth - track.clientWidth);\n            if (nextLeft \u003c 0) nextLeft = 0;\n            if (nextLeft \u003e maxL) nextLeft = maxL;\n            track.scrollLeft = nextLeft;\n          }\n        }, { passive: false });\n        track.addEventListener(\"touchend\", function (e) {\n          if (!gesturing) return;\n          gesturing = false;\n          if (axis !== \"x\") return;\n          var tch = e.changedTouches \u0026\u0026 e.changedTouches[0];\n          if (!tch) return;\n          var dx = tch.clientX - startX;\n          lockUntil = 0;\n          if (Math.abs(dx) \u003c 36) show(startIdx);\n          else show(startIdx + (dx \u003c 0 ? 1 : -1));\n        }, { passive: true });\n\n        var drag = false, dStartX = 0, dStartLeft = 0, moved = false, dStartIdx = 0;\n        track.addEventListener(\"pointerdown\", function (e) {\n          if (e.pointerType !== \"mouse\" || e.button !== 0 || Date.now() \u003c lockUntil) return;\n          drag = true; moved = false;\n          dStartX = e.clientX; dStartLeft = track.scrollLeft; dStartIdx = idx;\n          track.classList.add(\"is-dragging\");\n          try { track.setPointerCapture(e.pointerId); } catch (err) {}\n        });\n        track.addEventListener(\"pointermove\", function (e) {\n          if (!drag) return;\n          var dx = e.clientX - dStartX;\n          if (Math.abs(dx) \u003e 3) moved = true;\n          var nextLeft = dStartLeft - dx;\n          var maxL = Math.max(0, track.scrollWidth - track.clientWidth);\n          if (nextLeft \u003c 0) nextLeft = 0;\n          if (nextLeft \u003e maxL) nextLeft = maxL;\n          track.scrollLeft = nextLeft;\n        });\n        track.addEventListener(\"pointerup\", function (e) {\n          if (!drag) return;\n          drag = false; track.classList.remove(\"is-dragging\");\n          if (!moved) return;\n          var dx = e.clientX - dStartX;\n          lockUntil = 0;\n          if (Math.abs(dx) \u003c 36) show(dStartIdx);\n          else show(dStartIdx + (dx \u003c 0 ? 1 : -1));\n        });\n        track.addEventListener(\"pointercancel\", function () {\n          drag = false; track.classList.remove(\"is-dragging\");\n        });\n        track.addEventListener(\"click\", function (e) {\n          if (moved) { e.preventDefault(); e.stopPropagation(); moved = false; }\n        }, true);\n\n        window.addEventListener(\"resize\", function () {\n          window.clearTimeout(track._sizeResizeT);\n          track._sizeResizeT = window.setTimeout(function () {\n            show(idx, true);\n          }, 80);\n        });\n\n        renderDots();\n        show(0, true);\n        window.setTimeout(function () { show(idx, true); }, 160);\n      }\n\n      function initRoot(root) {\n        if (root.getAttribute(\"data-convex-ready\") === \"1\") return;\n        root.setAttribute(\"data-convex-ready\", \"1\");\n        applyBleed(root);\n        window.addEventListener(\"resize\", function () { applyBleed(root); });\n        window.setTimeout(function () { applyBleed(root); }, 300);\n        document.addEventListener(\"click\", function () {\n          window.setTimeout(function () { applyBleed(root); }, 50);\n        }, true);\n        bindCarousels(root);\n        bindStyleToggle(root);\n      }\n\n      roots.forEach(initRoot);\n    })();\n\u003c\/script\u003e\n\u003c\/div\u003e","brand":"monulo","offers":[{"title":"Antique Gold \/ Spark","offer_id":67857570660510,"sku":"AITC26-ROC-ANTH-1025643","price":40.0,"currency_code":"USD","in_stock":true},{"title":"Antique Gold \/ Star","offer_id":67857570693278,"sku":"AITC26-ROC-ANTH-1025642","price":45.0,"currency_code":"USD","in_stock":true},{"title":"Antique Gold \/ Sun","offer_id":67857570726046,"sku":"AITC26-ROC-ANTH-1025641","price":50.0,"currency_code":"USD","in_stock":true},{"title":"Antique Gold \/ Convex Sun","offer_id":67857570758814,"sku":"AITC26-ROC-ANTH-1025640","price":130.0,"currency_code":"USD","in_stock":true},{"title":"Black \/ Black Floral","offer_id":67857570791582,"sku":"AITC26-ROC-ANTH-1025639","price":40.0,"currency_code":"USD","in_stock":true},{"title":"Black \/ Black Bobbin","offer_id":67857570824350,"sku":"AITC26-ROC-ANTH-1025638","price":49.0,"currency_code":"USD","in_stock":true},{"title":"Black \/ Black Starburst","offer_id":67857570857118,"sku":"AITC26-ROC-ANTH-1025637","price":61.0,"currency_code":"USD","in_stock":true},{"title":"Black \/ Black Deep Frame","offer_id":67857570889886,"sku":"AITC26-ROC-ANTH-1025636","price":45.0,"currency_code":"USD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0680\/6349\/4302\/files\/86c1de4c71e7f204c7589660821363d5.jpg?v=1793243646","url":"https:\/\/www.monulo.com\/de\/products\/decorative-convex-wall-mirror-collection-with-distinct-frame-styles","provider":"Monulo","version":"1.0","type":"link"}