{"id":12,"date":"2026-07-08T01:56:56","date_gmt":"2026-07-08T08:56:56","guid":{"rendered":"https:\/\/llccraft.com\/?page_id=12"},"modified":"2026-07-08T01:56:56","modified_gmt":"2026-07-08T08:56:56","slug":"pdp","status":"publish","type":"page","link":"https:\/\/llccraft.com\/?page_id=12","title":{"rendered":"PDP \u00b7 \u5668\u7269\u8be6\u60c5"},"content":{"rendered":"<p><!DOCTYPE html><br \/>\n<html lang=\"zh-CN\"><br \/>\n<head><br \/>\n<meta charset=\"UTF-8\"><br \/>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><br \/>\n<title>LLCCRAFT \u00b7 P-02 PDP \u00b7 v0.5.0<\/title><br \/>\n<meta name=\"description\" content=\"LLCCRAFT P-02 Product Detail Page skeleton. v0.5.0. Inherits P-01 v0.4.1.5 constitution (Helvetica Regular, Lumina footer, Impeccable A11Y).\"><\/p>\n<p><!--\n  ============================================================================\n  P-02 PDP \u00b7 v0.5.0 \u00b7 STATIC SKELETON \u00b7 2026-07-06\n  ============================================================================\n  Inherits from P-01 v0.4.1.5 (LOCKED 2026-07-06, MD5 a4f0934dbf7e96605ccaa74dc0651340):\n    - Helvetica Regular @font-face (5 formats)\n    - Impeccable A11Y \/ WCAG 2.1 AA \/ reduced-motion \/ skiplink\n    - Lumina 14-line CSS (footer 100% \u590d\u7528 verbatim)\n    - \u5546\u4e1a\u62a4\u57ce\u6cb3: NO countdown, NO red strikethrough, NO sale badge\n  New for P-02 (Tenmokus \u5bf9\u6807):\n    [G] Gallery      :  left multi-image vertical scroll\n    [S] Sticky info  :  right column position:sticky (below nav)\n    [V] Variant pill :  custom radios (NOT native select)  + arrow-key nav\n    [Q] Quantity     :  custom -\/+ buttons (NOT native input) + 1-99 clamp\n    [D] Drawer cart  :  right slide-in, NO page refresh + Esc close + focus mgmt\n  ============================================================================\n--><\/p>\n<p><!-- Tailwind Play CDN : self-contained skeleton render --><br \/>\n<script src=\"https:\/\/cdn.tailwindcss.com\"><\/script><br \/>\n<script>\n  tailwind.config = {\n    theme: {\n      extend: {\n        colors: {\n          'gallery':  'oklch(0.97 0.012 90)',\n          'ink':      'oklch(0.20 0.010 28)',\n          'ink-soft': 'oklch(0.55 0.008 28)',\n          'rule':     'oklch(0.88 0.005 28)',\n        },\n        fontFamily: {\n          serif: ['\"Cormorant Garamond\"', 'Georgia', 'serif'],\n          sans:  ['\"Helvetica Regular\"', '\"Inter\"', 'system-ui', 'sans-serif'],\n        },\n        maxWidth: { 'wide': '1320px' },\n      }\n    }\n  }\n<\/script><\/p>\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Cormorant+Garamond:ital,wght@0,400;0,500;0,700;1,400&#038;family=Inter:wght@400;500&#038;display=swap\" rel=\"stylesheet\">\n<style>\n  \/* ==========================================================================\n     P-02 PDP v0.5.0  -  Product Detail Page\n     ==========================================================================\n     Constitution carry-overs (P-01 v0.4.1.5 \u590d\u7528):\n       - Helvetica Regular @font-face  (5 \u683c\u5f0f CDN)\n       - Impeccable \u5baa\u6cd5 :  A11Y skiplink \/ focus-visible \/ reduced-motion\n       - WCAG 2.1 AA  :  contrast \/ keyboard \/ aria\n       - Lumina 14-line CSS  :  \u00a76 \u590d\u7528 verbatim\n       - \u5546\u4e1a\u62a4\u57ce\u6cb3  :  NO countdown \/ NO red strikethrough \/ NO sale badge\n     ========================================================================== *\/<\/p>\n<p>  \/* ---------- F1 : Helvetica Regular @font-face (inherited, ACTIVE) ---------- *\/\n  @font-face {\n    font-family: \"Helvetica Regular\";\n    font-style: normal;\n    font-weight: 400;\n    font-display: swap;\n    src: url(\"https:\/\/db.onlinewebfonts.com\/t\/a64ff11d2c24584c767f6257e880dc65.eot\");\n    src: url(\"https:\/\/db.onlinewebfonts.com\/t\/a64ff11d2c24584c767f6257e880dc65.eot?#iefix\")format(\"embedded-opentype\"),\n         url(\"https:\/\/db.onlinewebfonts.com\/t\/a64ff11d2c24584c767f6257e880dc65.woff2\")format(\"woff2\"),\n         url(\"https:\/\/db.onlinewebfonts.com\/t\/a64ff11d2c24584c767f6257e880dc65.woff\")format(\"woff\"),\n         url(\"https:\/\/db.onlinewebfonts.com\/t\/a64ff11d2c24584c767f6257e880dc65.ttf\")format(\"truetype\"),\n         url(\"https:\/\/db.onlinewebfonts.com\/t\/a64ff11d2c24584c767f6257e880dc65.svg#Helvetica Regular\")format(\"svg\");\n  }<\/p>\n<p>  *, *::before, *::after { box-sizing: border-box; }\n  html, body { margin: 0; padding: 0; }\n  body {\n    background: oklch(0.97 0.012 90);\n    color: oklch(0.20 0.010 28);\n    font-family: \"Helvetica Regular\", \"Inter\", system-ui, -apple-system, sans-serif;\n    font-size: 16px; line-height: 1.5;\n    -webkit-font-smoothing: antialiased;\n  }<\/p>\n<p>  \/* ---------- A11Y ---------- *\/\n  .skiplink {\n    position: fixed; top: -100px; left: 12px; z-index: 200;\n    padding: 8px 24px; background: #000; color: #fff;\n    font-size: 12px; letter-spacing: 0.18em; text-transform: uppercase;\n    border-radius: 2px; text-decoration: none; font-weight: 500;\n    transition: top 240ms cubic-bezier(0.16, 1, 0.3, 1);\n  }\n  .skiplink:focus { top: 12px; }\n  :focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }<\/p>\n<p>  @media (prefers-reduced-motion: reduce) {\n    *, *::before, *::after {\n      animation-duration: 0.01ms !important;\n      transition-duration: 0.01ms !important;\n    }\n  }<\/p>\n<p>  \/* ====================================================================\n     1.  Global Sticky Header  (v0.5.1 chassis - PHASE 3.5)\n     ==================================================================== *\/\n  .global-header {\n    position: fixed; top: 0; left: 0; right: 0;\n    z-index: 100;\n    background: transparent;\n    border-bottom: 1px solid transparent;\n    transition: background 320ms ease, backdrop-filter 320ms ease,\n                border-color 320ms ease;\n  }\n  .global-header.is-scrolled-down {\n    background: rgba(15, 15, 15, 0.5);\n    backdrop-filter: blur(20px) saturate(140%);\n    -webkit-backdrop-filter: blur(20px) saturate(140%);\n    border-bottom-color: rgba(255, 255, 255, 0.08);\n  }\n  .global-header.is-scrolled-up {\n    background: transparent;\n    backdrop-filter: none;\n    border-bottom-color: transparent;\n  }\n  .global-header__inner {\n    max-width: 1320px; margin: 0 auto;\n    padding: 18px 24px;\n    display: flex; align-items: center; justify-content: space-between;\n    gap: 32px;\n  }\n  .global-header__brand {\n    font-family: 'Cormorant Garamond', Georgia, serif;\n    font-size: 22px; font-weight: 500;\n    color: #fff; text-decoration: none;\n    letter-spacing: -0.005em; flex-shrink: 0;\n  }\n  .global-header__actions { display: flex; align-items: center; gap: 24px; }\n  .global-header__lang { position: relative; }\n  .global-header__lang-btn {\n    display: inline-flex; align-items: center; gap: 4px;\n    background: transparent; border: none; padding: 6px 8px;\n    color: #fff; cursor: pointer;\n    font-family: \"Helvetica Regular\", \"Inter\", sans-serif;\n    font-size: 12px; letter-spacing: 0.05em;\n    border-radius: 4px; transition: background 200ms ease;\n  }\n  .global-header__lang-btn:hover { background: rgba(255, 255, 255, 0.08); }\n  .global-header__lang-caret { width: 10px; height: 10px; fill: currentColor; }\n  .global-header__lang-menu {\n    position: absolute; top: calc(100% + 8px); right: 0;\n    background: oklch(0.18 0.012 28 \/ 0.95);\n    backdrop-filter: blur(12px);\n    border: 1px solid rgba(255, 255, 255, 0.08);\n    border-radius: 4px; padding: 4px 0;\n    min-width: 100px; list-style: none; margin: 0;\n    opacity: 0; visibility: hidden; transform: translateY(-4px);\n    transition: opacity 200ms ease, transform 200ms ease, visibility 200ms ease;\n    z-index: 110;\n  }\n  .global-header__lang-menu.is-open { opacity: 1; visibility: visible; transform: translateY(0); }\n  .global-header__lang-menu button {\n    display: block; width: 100%; padding: 8px 16px;\n    background: transparent; border: none;\n    color: rgba(255, 255, 255, 0.7);\n    font-family: \"Helvetica Regular\", \"Inter\", sans-serif;\n    font-size: 12px; letter-spacing: 0.05em;\n    text-align: left; cursor: pointer;\n    transition: background 200ms ease, color 200ms ease;\n  }\n  .global-header__lang-menu button:hover,\n  .global-header__lang-menu button.is-active {\n    background: rgba(255, 255, 255, 0.08); color: #fff;\n  }\n  .global-header__social {\n    display: flex; align-items: center; gap: 12px;\n    list-style: none; padding: 0; margin: 0;\n  }\n  .global-header__social a {\n    display: flex; align-items: center; justify-content: center;\n    width: 28px; height: 28px;\n    color: #fff; opacity: 0.7;\n    text-decoration: none; transition: opacity 200ms ease;\n  }\n  .global-header__social a:hover { opacity: 1; }\n  .global-header__social svg { width: 16px; height: 16px; fill: currentColor; }\n  .global-header__icons { display: flex; align-items: center; gap: 4px; }\n  .global-header__icon-btn,\n  .global-header__icon-link {\n    position: relative;\n    display: flex; align-items: center; justify-content: center;\n    width: 40px; height: 40px;\n    background: transparent; border: none;\n    color: #fff; opacity: 0.85;\n    text-decoration: none; cursor: pointer; border-radius: 50%;\n    transition: opacity 200ms ease, background 200ms ease;\n  }\n  .global-header__icon-btn:hover,\n  .global-header__icon-link:hover { opacity: 1; background: rgba(255, 255, 255, 0.08); }\n  .global-header__icon-btn svg,\n  .global-header__icon-link svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.5; }\n  .global-header__cart-badge {\n    position: absolute; top: 4px; right: 4px;\n    min-width: 16px; height: 16px; padding: 0 4px;\n    display: flex; align-items: center; justify-content: center;\n    background: oklch(0.42 0.165 27);\n    color: #fff;\n    font-family: \"Helvetica Regular\", \"Inter\", sans-serif;\n    font-size: 10px; font-weight: 500;\n    border-radius: 999px; line-height: 1;\n  }<\/p>\n<p>  \/* ====================================================================\n     2.  PDP layout  -  gallery (left) + sticky info (right)\n     ==================================================================== *\/\n  .pdp {\n    display: grid;\n    grid-template-columns: minmax(0, 1fr) 480px;\n    gap: 64px;\n    max-width: 1320px;\n    margin: 0 auto;\n    padding: 120px 24px 80px;  \/* 120 top = nav clearance *\/\n  }\n  @media (max-width: 960px) {\n    .pdp {\n      grid-template-columns: 1fr;\n      gap: 48px;\n      padding: 96px 16px 64px;\n    }\n  }<\/p>\n<p>  \/* [G] Gallery :  multi-image vertical scroll *\/\n  .pdp__gallery {\n    display: flex;\n    flex-direction: column;\n    gap: 16px;\n  }\n  .pdp__image {\n    width: 100%;\n    aspect-ratio: 1 \/ 1;\n    background: oklch(0.93 0.005 28);\n    overflow: hidden;\n  }\n  .pdp__image img {\n    width: 100%; height: 100%;\n    object-fit: cover; display: block;\n    transition: transform 0.8s cubic-bezier(0.16, 1, 0.3, 1);\n  }\n  .pdp__image:hover img { transform: scale(1.02); }<\/p>\n<p>  \/* [S] Sticky info column *\/\n  .pdp__info {\n    position: sticky;\n    top: 96px;  \/* below nav *\/\n    align-self: start;\n    display: flex;\n    flex-direction: column;\n    gap: 28px;\n    max-height: calc(100vh - 120px);\n    overflow-y: auto;\n    padding-right: 8px;\n    \/* hide scrollbar visually but keep functional *\/\n    scrollbar-width: thin;\n    scrollbar-color: oklch(0.85 0.005 28) transparent;\n  }\n  @media (max-width: 960px) {\n    .pdp__info { position: static; max-height: none; }\n  }<\/p>\n<p>  .pdp__breadcrumb {\n    font-family: \"Helvetica Regular\", \"Inter\", sans-serif;\n    font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;\n    color: oklch(0.55 0.008 28); margin: 0;\n  }\n  .pdp__title {\n    font-family: 'Cormorant Garamond', Georgia, serif;\n    font-size: clamp(1.75rem, 2.5vw, 2.5rem);\n    font-weight: 500; line-height: 1.1;\n    margin: 0; color: oklch(0.20 0.010 28);\n    letter-spacing: -0.01em;\n  }\n  .pdp__subtitle {\n    font-family: 'Cormorant Garamond', Georgia, serif;\n    font-style: italic;\n    font-size: 16px; color: oklch(0.55 0.008 28);\n    margin: -16px 0 0;\n  }<\/p>\n<p>  .pdp__rating {\n    display: flex; align-items: center; gap: 2px;\n    font-family: \"Helvetica Regular\", \"Inter\", sans-serif;\n  }\n  .pdp__rating .star { color: oklch(0.72 0.025 85); font-size: 14px; line-height: 1; }\n  .pdp__rating .rating-count {\n    margin-left: 10px; color: oklch(0.55 0.008 28);\n    font-size: 12px; letter-spacing: 0.02em;\n  }<\/p>\n<p>  .pdp__price {\n    font-family: \"Helvetica Regular\", \"Inter\", sans-serif;\n    font-size: 24px; font-weight: 500;\n    color: oklch(0.20 0.010 28); margin: 0;\n    letter-spacing: -0.005em;\n    \/* v0.5.0 : single-color premium, NO red\/black discount contrast *\/\n  }<\/p>\n<p>  .pdp__specs {\n    display: flex; justify-content: space-between;\n    padding: 16px 0;\n    border-top: 1px solid oklch(0.88 0.005 28);\n    border-bottom: 1px solid oklch(0.88 0.005 28);\n    font-family: \"Helvetica Regular\", \"Inter\", sans-serif;\n    font-size: 12px; color: oklch(0.55 0.008 28);\n  }\n  .spec {\n    display: flex; align-items: center; gap: 6px;\n  }\n  .spec__icon {\n    display: flex; align-items: center; justify-content: center;\n    width: 18px; height: 18px;\n    color: oklch(0.42 0.012 28); flex-shrink: 0;\n  }\n  .spec__icon svg { display: block; }\n  .spec__label { font-weight: 500; }<\/p>\n<p>  \/* ====================================================================\n     3.  [V] Variant pill selector  -  custom radios, NOT native select\n     ==================================================================== *\/\n  .pdp__variant-group {\n    display: flex; flex-direction: column; gap: 12px;\n  }\n  .pdp__variant-label {\n    font-family: \"Helvetica Regular\", \"Inter\", sans-serif;\n    font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;\n    color: oklch(0.55 0.008 28); margin: 0; font-weight: 500;\n  }\n  .pdp__variant-options {\n    display: flex; flex-wrap: wrap; gap: 8px;\n  }\n  .pdp__pill {\n    display: inline-flex; align-items: center; justify-content: center;\n    padding: 10px 18px;\n    background: transparent;\n    color: oklch(0.20 0.010 28);\n    border: 1px solid oklch(0.20 0.010 28 \/ 0.4);\n    border-radius: 999px;\n    font-family: \"Helvetica Regular\", \"Inter\", sans-serif;\n    font-size: 13px; font-weight: 500;\n    letter-spacing: 0.02em;\n    cursor: pointer;\n    transition: background 200ms ease, color 200ms ease, border-color 200ms ease;\n  }\n  .pdp__pill:hover {\n    background: oklch(0.20 0.010 28 \/ 0.06);\n    border-color: oklch(0.20 0.010 28 \/ 0.8);\n  }\n  .pdp__pill.is-active {\n    background: oklch(0.20 0.010 28);\n    color: oklch(0.97 0.012 90);\n    border-color: oklch(0.20 0.010 28);\n  }\n  .pdp__pill:focus-visible {\n    outline: 2px solid oklch(0.42 0.165 27);\n    outline-offset: 2px;\n  }<\/p>\n<p>  \/* ====================================================================\n     4.  [Q] Quantity stepper  -  custom -\/+, NOT native input\n     ==================================================================== *\/\n  .pdp__qty {\n    display: inline-flex; align-items: stretch;\n    border: 1px solid oklch(0.20 0.010 28 \/ 0.4);\n    border-radius: 999px;\n    overflow: hidden;\n    width: fit-content;\n  }\n  .pdp__qty-btn {\n    display: flex; align-items: center; justify-content: center;\n    width: 44px; height: 44px;\n    background: transparent; border: none;\n    color: oklch(0.20 0.010 28);\n    font-family: \"Helvetica Regular\", \"Inter\", sans-serif;\n    font-size: 18px; cursor: pointer;\n    transition: background 200ms ease, color 200ms ease;\n  }\n  .pdp__qty-btn:hover {\n    background: oklch(0.20 0.010 28 \/ 0.08);\n  }\n  .pdp__qty-btn:disabled {\n    color: oklch(0.55 0.008 28);\n    cursor: not-allowed;\n  }\n  .pdp__qty-value {\n    display: flex; align-items: center; justify-content: center;\n    min-width: 48px; padding: 0 8px;\n    font-family: \"Helvetica Regular\", \"Inter\", sans-serif;\n    font-size: 14px; font-weight: 500;\n    color: oklch(0.20 0.010 28);\n    border-left: 1px solid oklch(0.20 0.010 28 \/ 0.2);\n    border-right: 1px solid oklch(0.20 0.010 28 \/ 0.2);\n  }<\/p>\n<p>  \/* ====================================================================\n     5.  Acquisition CTA  -  opens drawer (NO page refresh)\n     ==================================================================== *\/\n  .pdp__cta {\n    display: block; width: 100%;\n    padding: 20px 32px;\n    background: oklch(0.20 0.010 28);\n    color: oklch(0.97 0.012 90);\n    border: none; border-radius: 999px;\n    font-family: \"Helvetica Regular\", \"Inter\", sans-serif;\n    font-size: 13px; font-weight: 500;\n    letter-spacing: 0.18em; text-transform: uppercase;\n    cursor: pointer;\n    transition: background 240ms ease, transform 100ms ease;\n  }\n  .pdp__cta:hover { background: oklch(0.42 0.165 27); }\n  .pdp__cta:active { transform: scale(0.99); }<\/p>\n<p>  .pdp__note {\n    font-family: \"Helvetica Regular\", \"Inter\", sans-serif;\n    font-size: 11px; letter-spacing: 0.05em;\n    color: oklch(0.55 0.008 28); margin: 0; text-align: center;\n  }<\/p>\n<p>  \/* ====================================================================\n     6.  [D] Drawer Cart  -  right slide-in, NO page refresh\n     ==================================================================== *\/\n  .drawer-backdrop {\n    position: fixed; inset: 0; z-index: 199;\n    background: rgba(0, 0, 0, 0.4);\n    opacity: 0; visibility: hidden;\n    transition: opacity 280ms ease, visibility 280ms ease;\n  }\n  .drawer-backdrop.is-open { opacity: 1; visibility: visible; }<\/p>\n<p>  .drawer {\n    position: fixed; top: 0; right: 0; bottom: 0;\n    z-index: 200;\n    width: 480px; max-width: 100vw;\n    background: oklch(0.97 0.012 90);\n    transform: translateX(100%);\n    transition: transform 360ms cubic-bezier(0.16, 1, 0.3, 1);\n    display: flex; flex-direction: column;\n    box-shadow: -4px 0 24px rgba(0, 0, 0, 0.08);\n  }\n  .drawer.is-open { transform: translateX(0); }<\/p>\n<p>  .drawer__header {\n    display: flex; align-items: center; justify-content: space-between;\n    padding: 24px;\n    border-bottom: 1px solid oklch(0.88 0.005 28);\n  }\n  .drawer__title {\n    font-family: 'Cormorant Garamond', Georgia, serif;\n    font-size: 22px; font-weight: 500;\n    margin: 0; color: oklch(0.20 0.010 28);\n    letter-spacing: -0.005em;\n  }\n  .drawer__close {\n    width: 36px; height: 36px;\n    background: transparent; border: none;\n    color: oklch(0.20 0.010 28);\n    font-size: 22px; line-height: 1;\n    cursor: pointer; border-radius: 50%;\n    transition: background 200ms ease;\n  }\n  .drawer__close:hover { background: oklch(0.20 0.010 28 \/ 0.08); }<\/p>\n<p>  .drawer__body {\n    flex: 1; overflow-y: auto;\n    padding: 24px;\n  }\n  .drawer__empty {\n    text-align: center; padding: 64px 16px;\n    color: oklch(0.55 0.008 28);\n    font-family: \"Helvetica Regular\", \"Inter\", sans-serif;\n    font-size: 13px;\n  }<\/p>\n<p>  .drawer__item {\n    display: grid; grid-template-columns: 80px 1fr;\n    gap: 16px;\n    padding: 16px 0;\n    border-bottom: 1px solid oklch(0.88 0.005 28);\n  }\n  .drawer__item:last-child { border-bottom: none; }\n  .drawer__item-image {\n    width: 80px; height: 80px;\n    background: oklch(0.93 0.005 28);\n    overflow: hidden;\n  }\n  .drawer__item-image img {\n    width: 100%; height: 100%; object-fit: cover; display: block;\n  }\n  .drawer__item-meta {\n    display: flex; flex-direction: column; gap: 4px;\n  }\n  .drawer__item-title {\n    font-family: 'Cormorant Garamond', Georgia, serif;\n    font-size: 16px; font-weight: 500;\n    margin: 0; color: oklch(0.20 0.010 28);\n    letter-spacing: -0.005em;\n  }\n  .drawer__item-variant {\n    font-family: \"Helvetica Regular\", \"Inter\", sans-serif;\n    font-size: 11px; color: oklch(0.55 0.008 28); margin: 0;\n    letter-spacing: 0.02em;\n  }\n  .drawer__item-qty {\n    font-family: \"Helvetica Regular\", \"Inter\", sans-serif;\n    font-size: 11px; color: oklch(0.55 0.008 28); margin: 0;\n    letter-spacing: 0.02em;\n  }\n  .drawer__item-price {\n    font-family: \"Helvetica Regular\", \"Inter\", sans-serif;\n    font-size: 13px; font-weight: 500;\n    color: oklch(0.20 0.010 28); margin: 4px 0 0;\n  }\n  .drawer__item-remove {\n    align-self: flex-start;\n    background: transparent; border: none; padding: 0;\n    color: oklch(0.55 0.008 28);\n    font-family: \"Helvetica Regular\", \"Inter\", sans-serif;\n    font-size: 11px; letter-spacing: 0.05em; text-transform: uppercase;\n    cursor: pointer; margin-top: 6px;\n    text-decoration: underline;\n  }\n  .drawer__item-remove:hover { color: oklch(0.42 0.165 27); }<\/p>\n<p>  .drawer__footer {\n    padding: 24px;\n    border-top: 1px solid oklch(0.88 0.005 28);\n    background: oklch(0.97 0.012 90);\n  }\n  .drawer__subtotal {\n    display: flex; align-items: baseline; justify-content: space-between;\n    margin-bottom: 8px;\n  }\n  .drawer__subtotal-label {\n    font-family: \"Helvetica Regular\", \"Inter\", sans-serif;\n    font-size: 12px; letter-spacing: 0.05em; text-transform: uppercase;\n    color: oklch(0.55 0.008 28);\n  }\n  .drawer__subtotal-value {\n    font-family: 'Cormorant Garamond', Georgia, serif;\n    font-size: 24px; font-weight: 500;\n    color: oklch(0.20 0.010 28);\n  }\n  .drawer__shipping {\n    font-family: \"Helvetica Regular\", \"Inter\", sans-serif;\n    font-size: 11px; color: oklch(0.55 0.008 28);\n    margin: 0 0 16px;\n  }\n  .drawer__checkout {\n    display: block; width: 100%;\n    padding: 16px 32px;\n    background: oklch(0.20 0.010 28);\n    color: oklch(0.97 0.012 90);\n    border: none; border-radius: 999px;\n    font-family: \"Helvetica Regular\", \"Inter\", sans-serif;\n    font-size: 13px; font-weight: 500;\n    letter-spacing: 0.18em; text-transform: uppercase;\n    cursor: pointer;\n    transition: background 240ms ease;\n  }\n  .drawer__checkout:hover { background: oklch(0.42 0.165 27); }\n  .drawer__continue {\n    display: block; width: 100%;\n    padding: 12px 32px;\n    background: transparent;\n    color: oklch(0.55 0.008 28);\n    border: none;\n    font-family: \"Helvetica Regular\", \"Inter\", sans-serif;\n    font-size: 12px; letter-spacing: 0.05em; text-transform: uppercase;\n    cursor: pointer; margin-top: 8px;\n  }\n  .drawer__continue:hover { color: oklch(0.20 0.010 28); }<\/p>\n<p>  \/* ====================================================================\n     7.  Lumina Liquid Glass footer  -  14-line CSS verbatim (LOCKED)\n         + video bg + glass overlay + content stack\n     ==================================================================== *\/\n  .liquid-glass {\n    background: rgba(255, 255, 255, 0.01);\n    background-blend-mode: luminosity;\n    backdrop-filter: blur(4px);\n    -webkit-backdrop-filter: blur(4px);\n    border: none;\n    box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.1);\n    position: relative;\n    overflow: hidden;\n  }\n  .liquid-glass::before {\n    content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 1.4px;\n    background: linear-gradient(180deg, rgba(255,255,255,0.45) 0%, rgba(255,255,255,0.15) 20%, rgba(255,255,255,0) 40%, rgba(255,255,255,0) 60%, rgba(255,255,255,0.15) 80%, rgba(255,255,255,0.45) 100%);\n    -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);\n    -webkit-mask-composite: xor; mask-composite: exclude; pointer-events: none;\n  }\n  .footer__bg {\n    position: absolute; inset: 0; z-index: 0;\n    width: 100%; height: 100%; object-fit: cover;\n    opacity: 0.55;\n  }\n  .footer__glass {\n    position: absolute; inset: 0; z-index: 0;\n  }\n  .footer__content {\n    position: relative; z-index: 1;\n  }\n<\/style>\n<p><\/head><br \/>\n<body><\/p>\n<p><!-- A11Y skiplink --><br \/>\n<a href=\"#main\" class=\"skiplink\">Skip to main content<\/a><\/p>\n<p><!-- 1. Global Sticky Header  (PHASE 3.5 chassis) --><\/p>\n<header class=\"global-header\" data-state=\"top\" id=\"global-header\">\n<div class=\"global-header__inner\">\n<p>    <a href=\"p01-home.html\" class=\"global-header__brand\">LLCCRAFT<\/a><\/p>\n<div class=\"global-header__actions\">\n<div class=\"global-header__lang\">\n        <button class=\"global-header__lang-btn\" id=\"lang-btn\" type=\"button\"\n                aria-haspopup=\"true\" aria-expanded=\"false\" aria-controls=\"lang-menu\"><br \/>\n          <span data-current-lang>EN<\/span><br \/>\n          <svg class=\"global-header__lang-caret\" viewBox=\"0 0 10 10\" aria-hidden=\"true\">\n            <path d=\"M2 4l3 3 3-3\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"\/>\n          <\/svg><br \/>\n        <\/button><\/p>\n<ul class=\"global-header__lang-menu\" id=\"lang-menu\" role=\"menu\" aria-label=\"Language\">\n<li role=\"none\"><button role=\"menuitem\" data-lang=\"en\" class=\"is-active\">EN<\/button><\/li>\n<li role=\"none\"><button role=\"menuitem\" data-lang=\"zh\">\u4e2d\u6587<\/button><\/li>\n<li role=\"none\"><button role=\"menuitem\" data-lang=\"fr\">FR<\/button><\/li>\n<li role=\"none\"><button role=\"menuitem\" data-lang=\"ja\">\u65e5\u672c\u8a9e<\/button><\/li>\n<\/ul><\/div>\n<ul class=\"global-header__social\" aria-label=\"Social\">\n<li><a href=\"#\" aria-label=\"Instagram\"><br \/>\n          <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n            <rect x=\"2\" y=\"2\" width=\"12\" height=\"12\" rx=\"3\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.2\"\/>\n            <circle cx=\"8\" cy=\"8\" r=\"2.6\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.2\"\/>\n            <circle cx=\"11.6\" cy=\"4.4\" r=\"0.7\" fill=\"currentColor\"\/>\n          <\/svg><br \/>\n        <\/a><\/li>\n<li><a href=\"#\" aria-label=\"WeChat\"><br \/>\n          <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n            <ellipse cx=\"6\" cy=\"7\" rx=\"5\" ry=\"4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.2\"\/>\n            <ellipse cx=\"11\" cy=\"10\" rx=\"3.5\" ry=\"3\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.2\"\/>\n            <circle cx=\"4.7\" cy=\"6\" r=\"0.45\" fill=\"currentColor\"\/>\n            <circle cx=\"7.3\" cy=\"6\" r=\"0.45\" fill=\"currentColor\"\/>\n            <circle cx=\"10.4\" cy=\"9.5\" r=\"0.35\" fill=\"currentColor\"\/>\n          <\/svg><br \/>\n        <\/a><\/li>\n<li><a href=\"#\" aria-label=\"Weibo\"><br \/>\n          <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n            <ellipse cx=\"8\" cy=\"8.5\" rx=\"6\" ry=\"4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.2\"\/>\n            <circle cx=\"6\" cy=\"9\" r=\"0.4\" fill=\"currentColor\"\/>\n            <circle cx=\"9\" cy=\"8\" r=\"0.4\" fill=\"currentColor\"\/>\n          <\/svg><br \/>\n        <\/a><\/li>\n<\/ul>\n<div class=\"global-header__icons\">\n        <button class=\"global-header__icon-btn\" id=\"search-btn\" type=\"button\" aria-label=\"Search\"><br \/>\n          <svg viewBox=\"0 0 18 18\" aria-hidden=\"true\">\n            <circle cx=\"8\" cy=\"8\" r=\"5.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"\/>\n            <path d=\"M12 12l4 4\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"\/>\n          <\/svg><br \/>\n        <\/button><br \/>\n        <a href=\"p05-auth.html\" class=\"global-header__icon-link\" aria-label=\"Account\"><br \/>\n          <svg viewBox=\"0 0 18 18\" aria-hidden=\"true\">\n            <circle cx=\"9\" cy=\"6.5\" r=\"3\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"\/>\n            <path d=\"M3 16c0-3 3-5 6-5s6 2 6 5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"\/>\n          <\/svg><br \/>\n        <\/a><br \/>\n        <button class=\"global-header__icon-btn global-header__cart\" id=\"cart-btn\" type=\"button\" aria-label=\"Cart\"><br \/>\n          <svg viewBox=\"0 0 18 18\" aria-hidden=\"true\">\n            <path d=\"M3 5h2l1.5 8h7l1.5-6H6\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linejoin=\"round\"\/>\n            <circle cx=\"7.5\" cy=\"15.5\" r=\"1\" fill=\"currentColor\"\/>\n            <circle cx=\"12.5\" cy=\"15.5\" r=\"1\" fill=\"currentColor\"\/>\n          <\/svg><\/p>\n<p>        <\/button>\n      <\/div>\n<\/p><\/div>\n<\/p><\/div>\n<\/header>\n<p><main id=\"main\"><\/p>\n<p><!-- ====================================================================\n     2.  PDP main  -  [G] gallery (left) + [S] sticky info (right)\n     ==================================================================== --><\/p>\n<section class=\"pdp\" aria-label=\"Product detail\">\n<p>  <!-- LEFT : Gallery (5 multi-image, vertical scroll) --><\/p>\n<div class=\"pdp__gallery\" aria-label=\"Piece gallery\">\n<div class=\"pdp__image\"><img decoding=\"async\" src=\"https:\/\/picsum.photos\/800\/800?random=20\" alt=\"Lorem ipsum piece - view 1 of 5\" loading=\"lazy\"><\/div>\n<div class=\"pdp__image\"><img decoding=\"async\" src=\"https:\/\/picsum.photos\/800\/800?random=21\" alt=\"Lorem ipsum piece - view 2 of 5\" loading=\"lazy\"><\/div>\n<div class=\"pdp__image\"><img decoding=\"async\" src=\"https:\/\/picsum.photos\/800\/800?random=22\" alt=\"Lorem ipsum piece - view 3 of 5\" loading=\"lazy\"><\/div>\n<div class=\"pdp__image\"><img decoding=\"async\" src=\"https:\/\/picsum.photos\/800\/800?random=23\" alt=\"Lorem ipsum piece - view 4 of 5\" loading=\"lazy\"><\/div>\n<div class=\"pdp__image\"><img decoding=\"async\" src=\"https:\/\/picsum.photos\/800\/800?random=24\" alt=\"Lorem ipsum piece - view 5 of 5\" loading=\"lazy\"><\/div>\n<\/p><\/div>\n<p>  <!-- RIGHT : Sticky info column --><\/p>\n<aside class=\"pdp__info\" aria-label=\"Piece details and purchase options\">\n<p class=\"pdp__breadcrumb\">Lorem ipsum \u00b7 Lot 014 \u00b7 Contemporary Ru ware<\/p>\n<div>\n<h1 class=\"pdp__title\">Lorem ipsum sky-blue Mei vase<\/h1>\n<p class=\"pdp__subtitle\">Hand-thrown reduction fired, signed by maker<\/p>\n<\/p><\/div>\n<div class=\"pdp__rating\" aria-label=\"5 out of 5 stars from 24 reviews\">\n      <span class=\"star\" aria-hidden=\"true\">&#9733;<\/span><br \/>\n      <span class=\"star\" aria-hidden=\"true\">&#9733;<\/span><br \/>\n      <span class=\"star\" aria-hidden=\"true\">&#9733;<\/span><br \/>\n      <span class=\"star\" aria-hidden=\"true\">&#9733;<\/span><br \/>\n      <span class=\"star\" aria-hidden=\"true\">&#9733;<\/span><br \/>\n      <span class=\"rating-count\">(24 reviews)<\/span>\n    <\/div>\n<p class=\"pdp__price\">USD 1,200<\/p>\n<div class=\"pdp__specs\">\n<div class=\"spec\">\n        <span class=\"spec__icon\" aria-label=\"Capacity\"><br \/>\n          <svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.2\" aria-hidden=\"true\">\n            <path d=\"M5 2v3M11 2v3M3 5h10v3a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4V5z\"\/>\n          <\/svg><br \/>\n        <\/span><br \/>\n        <span class=\"spec__label\">280 ml<\/span>\n      <\/div>\n<div class=\"spec\">\n        <span class=\"spec__icon\" aria-label=\"Diameter\"><br \/>\n          <svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.2\" aria-hidden=\"true\">\n            <circle cx=\"8\" cy=\"8\" r=\"6\"\/>\n            <path d=\"M2 8h12\"\/>\n          <\/svg><br \/>\n        <\/span><br \/>\n        <span class=\"spec__label\">12.5 cm<\/span>\n      <\/div>\n<div class=\"spec\">\n        <span class=\"spec__icon\" aria-label=\"Depth\"><br \/>\n          <svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.2\" aria-hidden=\"true\">\n            <path d=\"M3 2h10v9l-5 3-5-3V2z\"\/>\n          <\/svg><br \/>\n        <\/span><br \/>\n        <span class=\"spec__label\">8.0 cm<\/span>\n      <\/div>\n<\/p><\/div>\n<p>    <!-- [V] Variant 1 : Size --><\/p>\n<div class=\"pdp__variant-group\">\n<p class=\"pdp__variant-label\" id=\"variant-size-label\">Size<\/p>\n<div class=\"pdp__variant-options\" role=\"radiogroup\" aria-labelledby=\"variant-size-label\" data-variant-group=\"size\">\n        <button class=\"pdp__pill\" role=\"radio\" aria-checked=\"false\" tabindex=\"-1\" data-value=\"S\">Small &middot; S<\/button><br \/>\n        <button class=\"pdp__pill is-active\" role=\"radio\" aria-checked=\"true\" tabindex=\"0\" data-value=\"M\">Medium &middot; M<\/button><br \/>\n        <button class=\"pdp__pill\" role=\"radio\" aria-checked=\"false\" tabindex=\"-1\" data-value=\"L\">Large &middot; L<\/button>\n      <\/div>\n<\/p><\/div>\n<p>    <!-- [V] Variant 2 : Glaze --><\/p>\n<div class=\"pdp__variant-group\">\n<p class=\"pdp__variant-label\" id=\"variant-glaze-label\">Glaze<\/p>\n<div class=\"pdp__variant-options\" role=\"radiogroup\" aria-labelledby=\"variant-glaze-label\" data-variant-group=\"glaze\">\n        <button class=\"pdp__pill\" role=\"radio\" aria-checked=\"false\" tabindex=\"-1\" data-value=\"sky\">Sky-blue<\/button><br \/>\n        <button class=\"pdp__pill is-active\" role=\"radio\" aria-checked=\"true\" tabindex=\"0\" data-value=\"moon\">Moon-white<\/button><br \/>\n        <button class=\"pdp__pill\" role=\"radio\" aria-checked=\"false\" tabindex=\"-1\" data-value=\"sunset\">Sunset-amber<\/button>\n      <\/div>\n<\/p><\/div>\n<p>    <!-- [Q] Quantity --><\/p>\n<div class=\"pdp__variant-group\">\n<p class=\"pdp__variant-label\" id=\"qty-label\">Quantity<\/p>\n<div class=\"pdp__qty\" role=\"group\" aria-labelledby=\"qty-label\">\n        <button class=\"pdp__qty-btn\" id=\"qty-decrement\" type=\"button\" aria-label=\"Decrease quantity\">&minus;<\/button><br \/>\n        <span class=\"pdp__qty-value\" id=\"qty-value\" aria-live=\"polite\">1<\/span><br \/>\n        <button class=\"pdp__qty-btn\" id=\"qty-increment\" type=\"button\" aria-label=\"Increase quantity\">&plus;<\/button>\n      <\/div>\n<\/p><\/div>\n<p>    <!-- 5. Acquisition CTA :  opens drawer (NO page refresh) --><br \/>\n    <button id=\"pdp-add\" class=\"pdp__cta\" type=\"button\">\u52a0\u5165\u672c\u6b21\u76f4\u7ed3 \/ Add to acquisition<\/button><\/p>\n<p class=\"pdp__note\">Free white-glove delivery &middot; 14-day authenticity review<\/p>\n<\/aside>\n<\/section>\n<p><\/main><\/p>\n<p><!-- ====================================================================\n     [D] Drawer Cart  -  right slide-in, NO page refresh\n     ==================================================================== --><\/p>\n<div class=\"drawer-backdrop\" id=\"drawer-backdrop\" aria-hidden=\"true\"><\/div>\n<aside class=\"drawer\" id=\"drawer\" aria-label=\"Acquisition cart\" aria-hidden=\"true\">\n<header class=\"drawer__header\">\n<h2 class=\"drawer__title\">Acquisition<\/h2>\n<p>    <button class=\"drawer__close\" id=\"drawer-close\" type=\"button\" aria-label=\"Close cart\">&times;<\/button><br \/>\n  <\/header>\n<div class=\"drawer__body\" id=\"drawer-body\">\n    <!-- items injected by JS -->\n  <\/div>\n<footer class=\"drawer__footer\">\n<div class=\"drawer__subtotal\">\n      <span class=\"drawer__subtotal-label\">Subtotal<\/span><br \/>\n      <span class=\"drawer__subtotal-value\" id=\"drawer-subtotal\">USD 0<\/span>\n    <\/div>\n<p class=\"drawer__shipping\">Shipping &amp; provenance review calculated at next step<\/p>\n<p>    <button class=\"drawer__checkout\" id=\"drawer-checkout\" type=\"button\">Proceed to acquisition<\/button><br \/>\n    <button class=\"drawer__continue\" id=\"drawer-continue\" type=\"button\">Continue browsing<\/button><br \/>\n  <\/footer>\n<\/aside>\n<p><!-- ====================================================================\n     Lumina Liquid Glass footer  (P-01 v0.4.1.5 100% \u590d\u7528 verbatim)\n     ==================================================================== --><\/p>\n<footer class=\"relative overflow-hidden\" style=\"isolation: isolate; border-radius: 0; margin-top: 96px; min-height: 480px;\">\n<p>  <video class=\"footer__bg\" autoplay loop muted playsinline><source src=\"{{hero.video.url}}\" data-placeholder=\"hero-video.mp4\" type=\"video\/mp4\"><\/video><\/p>\n<div class=\"liquid-glass footer__glass\"><\/div>\n<div class=\"footer__content\" style=\"padding: 96px 24px 32px;\">\n<div class=\"max-w-wide mx-auto\" style=\"display: grid; grid-template-columns: repeat(4, 1fr); gap: 48px;\">\n<div>\n<h3 class=\"font-serif text-2xl mb-4\" style=\"font-family: 'Cormorant Garamond', serif; font-weight: 500;\">LLCCRAFT<\/h3>\n<p class=\"text-sm\" style=\"color: oklch(0.20 0.010 28); opacity: 0.7;\">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor.<\/p>\n<\/p><\/div>\n<div>\n<h4 class=\"text-xs uppercase mb-4\" style=\"letter-spacing: 0.18em; color: oklch(0.55 0.008 28);\">Collections<\/h4>\n<ul style=\"list-style: none; padding: 0; margin: 0;\">\n<li style=\"margin-bottom: 8px;\"><a href=\"#\" style=\"color: oklch(0.20 0.010 28); text-decoration: none; font-size: 14px;\">Contemporary Ru ware<\/a><\/li>\n<li style=\"margin-bottom: 8px;\"><a href=\"#\" style=\"color: oklch(0.20 0.010 28); text-decoration: none; font-size: 14px;\">Jingdezhen blue-and-white<\/a><\/li>\n<li style=\"margin-bottom: 8px;\"><a href=\"#\" style=\"color: oklch(0.20 0.010 28); text-decoration: none; font-size: 14px;\">Reserved &#038; Commission<\/a><\/li>\n<\/ul><\/div>\n<div>\n<h4 class=\"text-xs uppercase mb-4\" style=\"letter-spacing: 0.18em; color: oklch(0.55 0.008 28);\">Atelier<\/h4>\n<ul style=\"list-style: none; padding: 0; margin: 0;\">\n<li style=\"margin-bottom: 8px;\"><a href=\"#\" style=\"color: oklch(0.20 0.010 28); text-decoration: none; font-size: 14px;\">Master Liu<\/a><\/li>\n<li style=\"margin-bottom: 8px;\"><a href=\"#\" style=\"color: oklch(0.20 0.010 28); text-decoration: none; font-size: 14px;\">Master Chen<\/a><\/li>\n<li style=\"margin-bottom: 8px;\"><a href=\"#\" style=\"color: oklch(0.20 0.010 28); text-decoration: none; font-size: 14px;\">Provenance<\/a><\/li>\n<\/ul><\/div>\n<div>\n<h4 class=\"text-xs uppercase mb-4\" style=\"letter-spacing: 0.18em; color: oklch(0.55 0.008 28);\">Acquisition<\/h4>\n<ul style=\"list-style: none; padding: 0; margin: 0;\">\n<li style=\"margin-bottom: 8px;\"><a href=\"#\" style=\"color: oklch(0.20 0.010 28); text-decoration: none; font-size: 14px;\">Direct purchase<\/a><\/li>\n<li style=\"margin-bottom: 8px;\"><a href=\"#\" style=\"color: oklch(0.20 0.010 28); text-decoration: none; font-size: 14px;\">Private inquiry<\/a><\/li>\n<li style=\"margin-bottom: 8px;\"><a href=\"#\" style=\"color: oklch(0.20 0.010 28); text-decoration: none; font-size: 14px;\">Contact<\/a><\/li>\n<\/ul><\/div>\n<\/p><\/div>\n<div class=\"max-w-wide mx-auto\" style=\"margin-top: 64px; padding-top: 24px; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 16px; border-top: 1px solid oklch(0.20 0.010 28 \/ 0.1);\">\n<p class=\"text-xs\" style=\"color: oklch(0.55 0.008 28);\">&copy; 2026 LLCCRAFT &middot; Lorem ipsum<\/p>\n<p class=\"text-xs\" style=\"color: oklch(0.55 0.008 28);\">Privacy &middot; Terms &middot; Contact<\/p>\n<\/p><\/div>\n<\/p><\/div>\n<\/footer>\n<p><script>\n  \/* ==========================================================================\n     P-02 PDP JS  v0.5.0\n     ==========================================================================\n     Modules (all custom, no page refresh):\n       1. Sticky nav scroll effect\n       2. Variant pill roving-tabindex + arrow-key navigation\n       3. Quantity stepper  (1-99 clamp)\n       4. Drawer open\/close  (slide-in + Esc + focus mgmt)\n       5. Add-to-cart  (in-memory state, render into drawer)\n       6. Remove-from-cart\n     ========================================================================== *\/<\/p>\n<p>  (function () {\n    \/* ---------- 1. Global Sticky Header  (PHASE 3.5 chassis) ---------- *\/\n    const header = document.getElementById('global-header');\n    if (header) {\n      let lastY = 0;\n      const onScroll = () => {\n        const y = window.scrollY;\n        const dir = y > lastY ? 'down' : 'up';\n        lastY = y;\n        if (y < 80) {\n          header.dataset.state = 'top';\n          header.classList.remove('is-scrolled-down', 'is-scrolled-up');\n        } else {\n          header.dataset.state = dir;\n          header.classList.toggle('is-scrolled-down', dir === 'down');\n          header.classList.toggle('is-scrolled-up', dir === 'up');\n        }\n      };\n      window.addEventListener('scroll', onScroll, { passive: true });\n      onScroll();\n    }\n\n    \/* ---------- 1b. Lang dropdown ---------- *\/\n    const langBtn  = document.getElementById('lang-btn');\n    const langMenu = document.getElementById('lang-menu');\n    if (langBtn &#038;&#038; langMenu) {\n      const toggle = (open) => {\n        const isOpen = open ?? !langMenu.classList.contains('is-open');\n        langMenu.classList.toggle('is-open', isOpen);\n        langBtn.setAttribute('aria-expanded', isOpen ? 'true' : 'false');\n      };\n      langBtn.addEventListener('click', (e) => { e.stopPropagation(); toggle(); });\n      langMenu.addEventListener('click', (e) => {\n        const item = e.target.closest('[data-lang]');\n        if (item) {\n          langMenu.querySelectorAll('button').forEach((b) => b.classList.remove('is-active'));\n          item.classList.add('is-active');\n          const cur = langBtn.querySelector('[data-current-lang]');\n          if (cur) cur.textContent = item.textContent;\n          toggle(false);\n        }\n      });\n      document.addEventListener('click', (e) => {\n        if (!e.target.closest('.global-header__lang')) toggle(false);\n      });\n      document.addEventListener('keydown', (e) => {\n        if (e.key === 'Escape' && langMenu.classList.contains('is-open')) {\n          toggle(false);\n          langBtn.focus();\n        }\n      });\n    }\n  })();<\/p>\n<p>  \/* ---------- 2. Variant pill roving-tabindex + arrow-key nav ---------- *\/\n  (function () {\n    const groups = document.querySelectorAll('[data-variant-group]');\n    groups.forEach((group) => {\n      const pills = Array.from(group.querySelectorAll('.pdp__pill'));\n      const setActive = (pill) => {\n        pills.forEach((p) => {\n          const active = p === pill;\n          p.classList.toggle('is-active', active);\n          p.setAttribute('aria-checked', active ? 'true' : 'false');\n          p.tabIndex = active ? 0 : -1;\n        });\n      };\n      pills.forEach((pill) => {\n        pill.addEventListener('click', () => setActive(pill));\n        pill.addEventListener('keydown', (e) => {\n          const idx = pills.indexOf(pill);\n          if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {\n            e.preventDefault();\n            const next = pills[(idx + 1) % pills.length];\n            setActive(next); next.focus();\n          } else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {\n            e.preventDefault();\n            const prev = pills[(idx - 1 + pills.length) % pills.length];\n            setActive(prev); prev.focus();\n          } else if (e.key === 'Home') {\n            e.preventDefault(); setActive(pills[0]); pills[0].focus();\n          } else if (e.key === 'End') {\n            e.preventDefault(); setActive(pills[pills.length - 1]); pills[pills.length - 1].focus();\n          }\n        });\n      });\n    });\n  })();<\/p>\n<p>  \/* ---------- 3. Quantity stepper ---------- *\/\n  (function () {\n    const MIN = 1, MAX = 99;\n    const dec = document.getElementById('qty-decrement');\n    const inc = document.getElementById('qty-increment');\n    const val = document.getElementById('qty-value');\n    if (!dec || !inc || !val) return;\n    const clamp = (n) => Math.max(MIN, Math.min(MAX, n));\n    const setQty = (n) => {\n      const v = clamp(n);\n      val.textContent = v;\n      dec.disabled = v <= MIN;\n      inc.disabled = v >= MAX;\n      state.qty = v;\n    };\n    dec.addEventListener('click', () => setQty(parseInt(val.textContent, 10) - 1));\n    inc.addEventListener('click', () => setQty(parseInt(val.textContent, 10) + 1));\n    setQty(1);\n  })();<\/p>\n<p>  \/* ---------- 4-6. Drawer + Cart state ---------- *\/\n  const state = { qty: 1, items: [] };<\/p>\n<p>  const VARIANT_LABELS = { size: 'Size', glaze: 'Glaze' };<\/p>\n<p>  function getSelectedVariants() {\n    const out = {};\n    document.querySelectorAll('[data-variant-group]').forEach((g) => {\n      const group = g.dataset.variantGroup;\n      const active = g.querySelector('.pdp__pill.is-active');\n      if (active) out[group] = active.dataset.value;\n    });\n    return out;\n  }<\/p>\n<p>  const drawer       = document.getElementById('drawer');\n  const backdrop     = document.getElementById('drawer-backdrop');\n  const drawerBody   = document.getElementById('drawer-body');\n  const drawerSub    = document.getElementById('drawer-subtotal');\n  const openBtn      = document.getElementById('cart-btn');\n  const addBtn       = document.getElementById('pdp-add');\n  const closeBtn     = document.getElementById('drawer-close');\n  const continueBtn  = document.getElementById('drawer-continue');\n  const checkoutBtn  = document.getElementById('drawer-checkout');<\/p>\n<p>  function openDrawer() {\n    drawer.classList.add('is-open');\n    backdrop.classList.add('is-open');\n    drawer.setAttribute('aria-hidden', 'false');\n    backdrop.setAttribute('aria-hidden', 'false');\n    document.body.style.overflow = 'hidden';\n    setTimeout(() => closeBtn && closeBtn.focus(), 360);\n  }\n  function closeDrawer() {\n    drawer.classList.remove('is-open');\n    backdrop.classList.remove('is-open');\n    drawer.setAttribute('aria-hidden', 'true');\n    backdrop.setAttribute('aria-hidden', 'true');\n    document.body.style.overflow = '';\n  }<\/p>\n<p>  function formatUSD(n) {\n    return 'USD ' + n.toLocaleString('en-US');\n  }<\/p>\n<p>  function renderDrawer() {\n    if (state.items.length === 0) {\n      drawerBody.innerHTML = '<\/p>\n<p class=\"drawer__empty\">No pieces selected yet.<\/p>\n<p>';\n    } else {\n      drawerBody.innerHTML = state.items.map((it) => {\n        const variantsHTML = Object.keys(it.variants)\n          .map((k) => VARIANT_LABELS[k] + ': ' + it.variants[k])\n          .join(' &middot; ');\n        return [\n          '<\/p>\n<article class=\"drawer__item\" data-item-id=\"', it.id, '\">',\n            '<\/p>\n<div class=\"drawer__item-image\"><img decoding=\"async\" src=\"', it.image, '\" alt=\"\"><\/div>\n<p>',\n            '<\/p>\n<div class=\"drawer__item-meta\">',\n              '<\/p>\n<p class=\"drawer__item-title\">', it.title, '<\/p>\n<p>',\n              '<\/p>\n<p class=\"drawer__item-variant\">', variantsHTML, '<\/p>\n<p>',\n              '<\/p>\n<p class=\"drawer__item-qty\">Qty ', it.qty, '<\/p>\n<p>',\n              '<\/p>\n<p class=\"drawer__item-price\">', formatUSD(it.subtotal), '<\/p>\n<p>',\n              '<button class=\"drawer__item-remove\" data-remove-id=\"', it.id, '\" type=\"button\">Remove<\/button>',\n            '<\/div>\n<p>',\n          '<\/article>\n<p>'\n        ].join('');\n      }).join('');\n    }\n    const total = state.items.reduce((s, it) => s + it.subtotal, 0);\n    drawerSub.textContent = formatUSD(total);\n  }<\/p>\n<p>  function addToCart() {\n    const variants = getSelectedVariants();\n    const item = {\n      id: 'i_' + Date.now(),\n      title: 'Lorem ipsum sky-blue Mei vase',\n      image: 'https:\/\/picsum.photos\/seed\/pdp-main\/200\/200.jpg',\n      price: 1200,\n      qty: state.qty,\n      variants: variants,\n      subtotal: 1200 * state.qty,\n    };\n    state.items.push(item);\n    renderDrawer();\n    openDrawer();\n  }<\/p>\n<p>  function removeFromCart(id) {\n    state.items = state.items.filter((it) => it.id !== id);\n    renderDrawer();\n  }<\/p>\n<p>  \/* event wiring *\/\n  if (openBtn)     openBtn.addEventListener('click', openDrawer);\n  if (addBtn)      addBtn.addEventListener('click', addToCart);\n  if (closeBtn)    closeBtn.addEventListener('click', closeDrawer);\n  if (continueBtn) continueBtn.addEventListener('click', closeDrawer);\n  if (backdrop)    backdrop.addEventListener('click', closeDrawer);\n  if (drawerBody) {\n    drawerBody.addEventListener('click', (e) => {\n      const btn = e.target.closest('[data-remove-id]');\n      if (btn) removeFromCart(btn.dataset.removeId);\n    });\n  }\n  document.addEventListener('keydown', (e) => {\n    if (e.key === 'Escape' && drawer.classList.contains('is-open')) {\n      closeDrawer();\n    }\n  });\n  if (checkoutBtn) {\n    checkoutBtn.addEventListener('click', () => {\n      \/* skeleton : no real checkout - drawer just acknowledges *\/\n      alert('Skeleton: checkout would proceed to P-03 (Acquisition flow).\\nCart has ' + state.items.length + ' item(s).');\n    });\n  }<\/p>\n<p>  \/* initial render *\/\n  renderDrawer();\n<\/script><\/p>\n<p><\/body><br \/>\n<\/html><\/p>\n","protected":false},"excerpt":{"rendered":"<p>LLCCRAFT \u00b7 P-02 PDP \u00b7 v0.5.0 Skip to main content LLCCRAFT EN EN \u4e2d\u6587 FR \u65e5\u672c\u8a9e Lorem ipsum \u00b7 Lot 014 \u00b7 Contemporary Ru ware Lorem ipsum sky-blue Mei vase Hand-thrown reduction fired, signed by maker &#9733; &#9733; &#9733; &#9733; &#9733; (24 reviews) USD 1,200 280 ml 12.5 cm 8.0 cm Size Small &middot; S [&hellip;]<\/p>\n","protected":false},"author":0,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-12","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/llccraft.com\/index.php?rest_route=\/wp\/v2\/pages\/12","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/llccraft.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/llccraft.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"replies":[{"embeddable":true,"href":"https:\/\/llccraft.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=12"}],"version-history":[{"count":0,"href":"https:\/\/llccraft.com\/index.php?rest_route=\/wp\/v2\/pages\/12\/revisions"}],"wp:attachment":[{"href":"https:\/\/llccraft.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=12"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}