/* ─────────────────────────────────────────────
   Product Showcase — styles aligned with the
   sse theme (homepage) design system.
   Falls back gracefully when theme vars are absent.
   ───────────────────────────────────────────── */

/* The old plugin code used a token set the theme does not define (--font-*, --fs-sm), so var() failed
   at computed-value time: font-size did nothing and the Georgia fallbacks rendered a serif face - the
   only extra typeface on the site. Remapping to the theme tokens here fixed 120+ usages in one place.
*/
:root {
    --font-display: var(--display, 'Anton', Impact, sans-serif);
    --font-mono: var(--mono, 'Space Mono', 'Courier New', monospace);
    --fs-sm: 13px;
}

body.tax-product_cat .wp-block-post-title,
body.tax-product_cat .entry-header,
body.single-product .wp-block-post-title,
body.single-product .entry-header,
body.single-product .wp-block-post-author,
body.single-product .wp-block-post-date,
body.single-product .wp-block-post-author-name,
body.single-product .wp-block-post-author-biography,
body.single-product .post-author,
body.single-product .byline,
body.single-product .posted-on,
body.single-product .wp-block-group:has(.wp-block-post-author),
body.single-product .wp-block-group:has(.wp-block-post-date),
body.single-product .wp-block-group.has-small-font-size {
    display: none !important;
}

/* ── Container ── */
.ps-container {
    width: 100%;
    max-width: var(--container, 1440px);
    margin: 0 auto;
    padding: clamp(28px, 5vw, 56px) var(--gutter, 32px);
    box-sizing: border-box;
}
.ps-container > :first-child {
    margin-top: 0;
}
.ps-container > :last-child {
    margin-bottom: 0;
}

/* ── Breadcrumb (homepage meta style) ── */
.ps-breadcrumb {
    font-family: var(--font-mono, ui-monospace, Menlo, monospace);
    font-size: 12px;
    letter-spacing: 0.02em;
    color: var(--muted, #777);
    padding: 0;
    margin: 0 0 clamp(24px, 4vw, 48px);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
}
.ps-breadcrumb a {
    color: var(--muted, #777);
    text-decoration: none;
    transition: color 0.15s;
}
.ps-breadcrumb a:hover {
    color: var(--accent, #7a6ce0);
}
.ps-sep {
    color: var(--border, #e8e6ee);
    font-size: 12px;
}
.ps-current {
    color: var(--fg, #222);
    font-weight: 500;
}

/* ── Titles (Anton, same as homepage headings) ── */
.ps-single-title,
.ps-archive-title {
    font-family: var(--font-display, 'Anton', Impact, sans-serif);
    font-weight: 600;
    letter-spacing: -0.015em;
    line-height: 1.1;
    color: var(--fg, #222);
    margin: 0;
}
.ps-single-title {
    font-size: clamp(28px, 3vw, 38px);
    margin-bottom: var(--gap-md, 20px);
}
.ps-archive-title {
    font-size: clamp(30px, 3.6vw, 44px);
    margin-bottom: var(--gap-lg, 32px);
}

/* ── Product detail layout ── */
.ps-detail {
    display: flex;
    gap: clamp(28px, 5vw, 64px);
    margin: 0;
    align-items: flex-start;
}
.ps-detail-images {
    flex: 0 0 420px;
    max-width: 100%;
}
.ps-main-img-wrap {
    position: relative;
}
.ps-main-img-wrap img {
    width: 100%;
    border-radius: var(--radius-lg, 16px);
    display: block;
    border: 1px solid var(--border, #e8e6ee);
    box-shadow: 0 12px 48px color-mix(in oklch, var(--fg, #222) 10%, transparent);
    background: var(--surface, #fff);
}
.ps-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 36px;
    height: 36px;
    border: none;
    border-radius: 50%;
    background: color-mix(in oklch, var(--fg, #222) 55%, transparent);
    color: #fff;
    font-size: 20px;
    cursor: pointer;
    line-height: 36px;
    text-align: center;
    opacity: 0;
    transition: opacity 0.25s, background 0.2s;
    z-index: 2;
    padding: 0;
}
.ps-main-img-wrap:hover .ps-nav {
    opacity: 1;
}
.ps-nav:hover {
    background: color-mix(in oklch, var(--fg, #222) 80%, transparent);
}
.ps-nav-left { left: 10px; }
.ps-nav-right { right: 10px; }

.ps-lightbox {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.85);
    z-index: 99999;
    align-items: center;
    justify-content: center;
    padding: 40px;
}
.ps-lb-image {
    max-width: 90vw;
    max-height: 90vh;
    object-fit: contain;
    border-radius: 6px;
}
.ps-lb-close {
    position: absolute;
    top: 16px;
    right: 24px;
    color: #fff;
    font-size: 36px;
    cursor: pointer;
    line-height: 1;
    opacity: 0.7;
}
.ps-lb-close:hover { opacity: 1; }
.ps-lb-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background: rgba(0, 0, 0, 0.45);
    border: 1px solid rgba(255, 255, 255, 0.2);
    color: #fff;
    font-size: 40px;
    width: 50px;
    height: 60px;
    cursor: pointer;
    border-radius: 8px;
    line-height: 60px;
    text-align: center;
    transition: background 0.2s, border-color 0.2s;
    padding: 0;
    box-shadow: 0 2px 8px rgba(0,0,0,0.2);
}
.ps-lb-nav:hover { background: rgba(0, 0, 0, 0.6); border-color: rgba(255,255,255,0.4); }
.ps-lb-prev { left: 16px; }
.ps-lb-next { right: 16px; }

/* Product gallery: a vertical thumbnail rail left of the main image, 4 visible at a time.
   Structure: .ps-gallery > (.ps-thumb-strip + .ps-main-img-wrap); .ps-thumb-strip > (.ps-thumb-viewport
   > .ps-thumb-track > .ps-thumb*n) + two absolutely-positioned .ps-thumb-nav.
   The rail's total height must equal the main image's, which varies with the viewport (aspect-ratio),
   so script.js syncRailHeight writes that height into --ps-gallery-h and the per-cell size is derived
   from it. The nav arrows overlay the track ends and appear on hover, so the end cells keep no gap.
*/
.ps-gallery {
    display: flex;
    align-items: flex-start;
    gap: 14px;
}
.ps-gallery .ps-main-img-wrap {
    flex: 1 1 auto;
    min-width: 0;
}

/* Colour variants: one button per colour, each swapping that colour's images (images only, never the
   spec table). Not rendered for products with no variants configured.
*/
.ps-colors {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 12px;
}
.ps-color {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 5px 11px 5px 7px;
    background: transparent;
    border: 1px solid var(--border, #e4e4e7);
    border-radius: 999px;
    font: inherit;
    font-size: 13px;
    line-height: 1.3;
    color: inherit;
    cursor: pointer;
    transition: border-color .18s ease, background-color .18s ease;
}
.ps-color:hover {
    border-color: var(--ps-accent, #c8102e);
}
.ps-color.active {
    border-color: var(--ps-accent, #c8102e);
    box-shadow: inset 0 0 0 1px var(--ps-accent, #c8102e);
}
.ps-color-dot {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: #ccc;
    /* White and pale swatches have no visible edge on a light ground, so they get an inset border. */
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .18);
    flex: 0 0 auto;
}
.ps-color-name {
    white-space: nowrap;
}

@media (max-width: 640px) {
    .ps-color-name {
        display: none;   /* Narrow screens keep the swatch only, saving a line of width. */
    }
}

.ps-thumb-strip {
    --ps-thumb-size: 80px;
    --ps-thumb-gap: 10px;
    --ps-thumb-visible: 4;

    /* The main image height is written to --ps-gallery-h by script.js, falling back to the old 4x80
       algorithm. Three gaps are subtracted and the remainder split into four cells.
    */
    --ps-thumb-auto: calc(
        (var(--ps-gallery-h, calc(var(--ps-thumb-visible) * var(--ps-thumb-size) + (var(--ps-thumb-visible) - 1) * var(--ps-thumb-gap)))
         - (var(--ps-thumb-visible) - 1) * var(--ps-thumb-gap)) / var(--ps-thumb-visible));

    position: relative;                 /* positioning context for the arrows */
    flex: 0 0 auto;
    width: var(--ps-thumb-auto, var(--ps-thumb-size));  /* column width = cell size */
}
.ps-thumb-viewport {
    overflow: hidden;
    /* 4 cells + 3 gaps exactly fill the main image height */
    height: calc(var(--ps-thumb-visible) * var(--ps-thumb-auto, var(--ps-thumb-size)) + (var(--ps-thumb-visible) - 1) * var(--ps-thumb-gap));
}
.ps-thumb-track {
    display: flex;
    flex-direction: column;
    gap: var(--ps-thumb-gap);
    transition: transform 0.42s cubic-bezier(0.33, 0, 0.2, 1);
    will-change: transform;
}
.ps-thumb {
    /* flex-shrink:0 is required: the track's height is dictated by the viewport and it would be squashed otherwise. */
    flex: 0 0 auto;
    width: var(--ps-thumb-auto, var(--ps-thumb-size));
    height: var(--ps-thumb-auto, var(--ps-thumb-size));
    object-fit: cover;
    border-radius: var(--radius, 10px);
    cursor: pointer;
    border: 2px solid transparent;
    opacity: 0.75;
    transition: border-color 0.2s, opacity 0.2s;
    box-sizing: border-box;
}
.ps-thumb.active,
.ps-thumb:hover {
    border-color: var(--accent, #7a6ce0);
    opacity: 1;
}

/* Up/down buttons, same treatment as the main image's .ps-nav: transparent ground, dimmed text,
   overlaying the end thumbnails. Hidden until the pointer enters the rail.
*/
.ps-thumb-nav {
    position: absolute;
    left: 0;
    right: 0;
    z-index: 2;
    height: 34px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: color-mix(in oklch, var(--fg, #222) 55%, transparent);
    color: #fff;
    font-size: 18px;
    line-height: 34px;
    text-align: center;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.25s, background 0.2s;
}
.ps-thumb-up   { top: 0; }
.ps-thumb-down { bottom: 0; }

/* Shown on rail hover, or on keyboard focus of the arrows. */
.ps-thumb-strip:hover .ps-thumb-nav,
.ps-thumb-nav:focus-visible {
    opacity: 1;
}
.ps-thumb-nav:hover {
    background: color-mix(in oklch, var(--fg, #222) 80%, transparent);
}

/* Cross-fade: a ghost layer overlaps #ps-main-image. On switch the ghost fades in and the main fades
   out, and only then is src written - setting src directly flashes white.
*/
.ps-main-ghost {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.42s ease;
}
.ps-main-ghost.is-active {
    opacity: 1;
}
#ps-main-image {
    transition: opacity 0.42s ease;
}
#ps-main-image.is-fading {
    opacity: 0;
}
@media (prefers-reduced-motion: reduce) {
    .ps-main-ghost,
    #ps-main-image,
    .ps-thumb-track {
        transition: none;
    }
}
@media (max-width: 480px) {
    .ps-gallery { gap: 8px; }
    .ps-thumb-strip {
        --ps-thumb-gap: 6px;
        --ps-thumb-size: 62px;
    }
    .ps-thumb-nav {
        height: 24px;
        font-size: 9px;
    }
}

/* ── Info column (title sits here, next to gallery) ── */
.ps-detail-info {
    flex: 1;
    min-width: 0;
    padding-top: 4px;
}
.ps-detail-desc {
    font-size: var(--fs-body, 16px);
    line-height: 1.7;
    color: var(--fg, #222);
    max-width: 60ch;
}
.ps-detail-desc p {
    margin: 0 0 1em;
}
.ps-detail-desc p:last-child {
    margin-bottom: 0;
}

/* Share bar, kept identical to parts-inquiry's .pi-share (sizes, square, ground, label tracking).
   This is one bar in two places - change one and change the other.
*/
.ps-share {
    display: flex;
    align-items: center;
    /* Narrow screens (the <=320px tier): label plus five icons wrap instead of overflowing. */
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 28px;
    padding-top: 20px;
    border-top: 1px solid var(--line, rgba(20, 22, 42, .14));
}
.ps-share-label {
    font-family: var(--mono, 'Space Mono', 'Courier New', monospace);
    font-size: 11px;
    color: var(--muted, #6C6F7B);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .18em;
    margin-right: 6px;
}
.ps-share-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border-radius: 0;
    color: var(--muted, #6C6F7B);
    background: var(--paper-2, #E9E6DD);
    text-decoration: none;
    transition: background .2s, color .2s;
    border: none;
    cursor: pointer;
    padding: 0;
    position: relative;
}
.ps-share-link:hover {
    color: #fff;
}
.ps-share-facebook:hover { background: #1877f2; }
.ps-share-twitter:hover { background: #000; }
.ps-share-linkedin:hover { background: #0a66c2; }
.ps-share-whatsapp:hover { background: #25d366; }
.ps-share-copy:hover { background: #666; }
.ps-share-copy.copied { background: #22c55e; color: #fff; }
.ps-share-copy-tooltip {
    position: absolute;
    bottom: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%);
    background: #333;
    color: #fff;
    font-size: 11px;
    padding: 3px 8px;
    border-radius: 4px;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s;
}
.ps-share-copy.copied .ps-share-copy-tooltip {
    opacity: 1;
}

/* Detail module, aligned with the parts-inquiry detail page (parts use .pi-single-*, products use
   .ps-detail-*; every value here was measured off the .pi-* set, so change both).
   Almost every var() in this file is a fallback: --fg / --accent / --font-display / --radius-lg /
   --surface are undefined by the theme, so what rendered was the hardcoded fallback - Georgia
   headings, purple accent, a 16px-radius white card with a shadow. Only the detail module is overridden
   here; the rest of the plugin (archive, cards, carousel) is untouched.
   Scoped to the single product page: the archive's .ps-container already gets --hh spacing from the
   theme template, and a global rule would stack a second copy on it.
*/

/* Measure and side padding, matching .wrap / .pi-container (the original used 1440 width with 32px
   insets, reading 80px narrower than the rest of the site).
*/
body.single-product .ps-container {
    max-width: var(--max, 1480px);
    /* The fixed header overlays the content (68px + 1px border on non-front pages), so the top padding has
       to include its height - the original 56px was entirely swallowed and the breadcrumb sat under the header.
    */
    padding: calc(var(--hh, 74px) + clamp(32px, 3vw, 44px)) var(--pad, clamp(20px, 5vw, 72px)) clamp(48px, 6vw, 96px);
}

/* Breadcrumb, same layout as .pi-breadcrumb (mono, uppercase, wide tracking).
   与 parts-inquiry 的 .pi-breadcrumb / .pi-bc-sep 必须像素一致：11px/700/.18em/uppercase + margin 0 0 18px，
   父级 flex + gap 6px，sep 12px 无 margin（.pi-bc-sep 就是照 .ps-sep 改的）；改一处要同步另一处。 */
body.single-product .ps-breadcrumb {
    font-family: var(--mono, 'Space Mono', 'Courier New', monospace);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--muted, #6C6F7B);
    margin: 0 0 18px;
}
body.single-product .ps-breadcrumb a { color: var(--muted, #6C6F7B); }
body.single-product .ps-breadcrumb a:hover { color: var(--orange, #F0950A); }
body.single-product .ps-breadcrumb .ps-current { color: var(--ink, #14162A); font-weight: 700; }
body.single-product .ps-breadcrumb .ps-sep { color: var(--line, rgba(20,22,42,.14)); }

/* Two equal columns. The image column used to be a fixed 420px with the info column taking the
   remaining 892px. flex:1 1 0 splits evenly with the gap subtracted, since flex-basis:50% would
   overflow; align-items:stretch lets the info column match the image height.
*/
body.single-product .ps-detail {
    gap: clamp(32px, 4vw, 64px);
    align-items: stretch;
}
body.single-product .ps-detail-images,
body.single-product .ps-detail-info {
    flex: 1 1 0;
    min-width: 0;
    max-width: 100%;
}

/* The thumbnail rail takes ~74px off the image column, so an even split would shrink the product
   image. Weighted 1.1 / 0.9 (~55:45): the main image minus the rail is about the same size as before
   (676 -> ~670) and the text column is still a comfortable ~608.
*/
body.single-product .ps-detail-images { flex: 1.1 1 0; }
body.single-product .ps-detail-info { flex: 0.9 1 0; }

/* Images: right angles, no shadow site-wide (originally 16px radius, white ground, large shadow). */
body.single-product .ps-main-img-wrap img {
    border-radius: 0;
    box-shadow: none;
    border: 0;
    background: transparent;
}

/* Title: Anton uppercase, exactly as .pi-single-title (the original fell back to Georgia serif at 38px -
   the only place on the site not set in Anton).
*/
body.single-product .ps-single-title {
    font-family: var(--display, 'Anton', Impact, sans-serif);
    font-weight: 400;
    font-size: clamp(1.6rem, 3.2vw, 2.6rem);
    line-height: 1;
    letter-spacing: .01em;
    text-transform: uppercase;
    color: var(--ink, #14162A);
    margin: 0 0 16px;
}
body.single-product .ps-detail-desc {
    color: var(--muted, #6C6F7B);
}

/* Info column: top padding so the title is not flush against the image (it was 4px), and the share bar
   pushed to the column's bottom so its rule lines up with the image's bottom edge (auto once the copy
   is longer than the image).
*/
body.single-product .ps-detail-info {
    padding-top: 50px;
    display: flex;
    flex-direction: column;
}
body.single-product .ps-detail-info > .ps-share { margin-top: auto; }

/* The product page's two action buttons: inquire (opens the modal like the header CTA) and view parts
   (new window). Same height, size and tracking so they read as a pair.
*/
body.single-product .ps-actions {
    display: flex;
    gap: 12px;
    align-items: center;
    flex-wrap: wrap;
    margin: 24px 0 0;
}

/* These two buttons are aligned item by item with the parts page's .pi-add-btn / .pi-inquire-now:
   padding 16/32, 13.5px, weight 800, right angles, uppercase. line-height must be normal - the theme
   gives <a> an inherited 1.6 (13.5 x 1.6 ~ 22px) against the parts page's <button> at ~15px, so
   hardcoding 20px made the two pages render 54px against 49px.
*/
body.single-product .ps-action-inquire,
body.single-product .ps-action-parts {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 16px 32px;
    border: 1px solid transparent;
    font-family: var(--sans, 'Archivo', sans-serif);
    font-weight: 800;
    font-size: 13.5px;
    line-height: normal;
    text-transform: uppercase;
    text-decoration: none;
    white-space: nowrap;
    box-sizing: border-box;
    cursor: pointer;
    transition: background .25s, color .25s, border-color .25s;
}

/* Primary = the parts page's .pi-add-btn: orange ground, white text, .06em tracking, darkens on hover. */
body.single-product .ps-action-inquire {
    background: var(--orange, #F0950A);
    border-color: transparent;
    color: #fff;
    letter-spacing: .06em;
}
body.single-product .ps-action-inquire:hover {
    background: var(--ink, #14162A);
    border-color: transparent;
    color: #fff;
}

/* Secondary = the parts page's .pi-inquire-now: dark outline, .08em tracking, orange ground on hover.
   Opens a new window.
*/
body.single-product .ps-action-parts {
    background: transparent;
    border-color: var(--ink, #14162A);
    color: var(--ink, #14162A);
    letter-spacing: .08em;
}
body.single-product .ps-action-parts:hover {
    background: var(--orange, #F0950A);
    border-color: var(--orange, #F0950A);
    color: #fff;
}

/* The share bar's appearance moved up into the base .ps-share rule (aligned with .pi-share); only the
   detail page's push-to-bottom behaviour is left here.
*/

/* When stacked, the gap above comes from .ps-detail's gap, so the info column needs no extra top padding. */
@media (max-width: 768px) {
    body.single-product .ps-detail-info { padding-top: 0; }
}

/* Key-spec icon strip under the detail image: icon + value + caption, four per row. Data is maintained
   in the product's _ps_key_specs field and rendered by PS_Sections::render_key_specs() as .ps-key-specs.
*/
.ps-key-specs {
    display: grid;
    /* Four per row; narrow screens go to 2x2 and only below 380px to a single column. Not auto-fit: with
       four items auto-fit resolves to three columns and orphans the fourth.
    */
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 32px 24px;
    margin: clamp(40px, 6vw, 72px) 0 0;
    padding: clamp(32px, 4vw, 56px) clamp(20px, 3vw, 40px);
    background: var(--paper-2, #E9E6DD);
}
@media (max-width: 1024px) {
    .ps-key-specs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 380px) {
    .ps-key-specs { grid-template-columns: minmax(0, 1fr); }
}
.ps-key-spec {
    text-align: center;
    color: var(--ink, #14162A);
}
.ps-key-spec svg {
    display: block;
    width: 52px;
    height: 52px;
    margin: 0 auto 20px;
}
/* Value and caption are italic as in the reference. Only Archivo regular is loaded, so the browser
   synthesises the oblique - visually identical, and no extra weight is downloaded.
*/
.ps-key-spec-value {
    font-family: var(--sans, 'Archivo', -apple-system, 'Segoe UI', Roboto, sans-serif);
    font-style: italic;
    font-weight: 800;
    font-size: clamp(1.5rem, 2.2vw, 1.9rem);
    line-height: 1.1;
    letter-spacing: -.01em;
}
.ps-key-spec-label {
    margin-top: 8px;
    font-style: italic;
    font-size: 15px;
    line-height: 1.4;
    color: var(--muted, #6C6F7B);
}

/* ── Category nav (archive) ── */
.ps-cat-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0 0 var(--gap-lg, 32px);
    padding: 0;
    border-top: 1px solid var(--border, #e8e6ee);
    border-bottom: 1px solid var(--border, #e8e6ee);
    padding-block: 4px;
}
.ps-cat-nav a {
    display: block;
    padding: 7px 18px;
    border: 1px solid var(--border, #e8e6ee);
    border-radius: 999px;
    color: var(--muted, #777);
    text-decoration: none;
    font-size: 13px;
    transition: all 0.2s;
}
.ps-cat-nav a:hover {
    border-color: var(--accent, #7a6ce0);
    color: var(--accent, #7a6ce0);
}
.ps-cat-nav a.active {
    background: var(--accent, #7a6ce0);
    color: var(--surface, #fff);
    border-color: var(--accent, #7a6ce0);
}

.ps-cat-desc {
    margin: 0 0 var(--gap-lg, 32px);
    padding: var(--gap-md, 20px) var(--gap-lg, 32px);
    background: var(--surface, #fff);
    border: 1px solid var(--border, #e8e6ee);
    border-left: 3px solid var(--accent, #7a6ce0);
    border-radius: var(--radius, 10px);
    line-height: 1.7;
    color: var(--fg, #222);
    max-width: 72ch;
}
.ps-cat-desc p:last-child {
    margin-bottom: 0;
}

.ps-search {
    display: flex;
    gap: 8px;
    margin: 0 0 var(--gap-lg, 32px);
    max-width: 400px;
}
.ps-search input {
    flex: 1;
    padding: 10px 14px;
    border: 1px solid var(--border, #e8e6ee);
    border-radius: var(--radius, 10px);
    font-size: 14px;
    font-family: inherit;
    color: var(--fg, #222);
    background: var(--surface, #fff);
    outline: none;
    transition: border-color 0.2s;
}
.ps-search input:focus {
    border-color: var(--accent, #7a6ce0);
}
.ps-search button {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: 1px solid var(--accent, #7a6ce0);
    background: var(--accent, #7a6ce0);
    color: var(--surface, #fff);
    border-radius: var(--radius, 10px);
    cursor: pointer;
    transition: background 0.2s;
}
.ps-search button:hover {
    background: color-mix(in oklch, var(--accent, #7a6ce0) 88%, var(--fg, #222));
}

/* ── Archive grid / cards ── */
.ps-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: var(--gap-lg, 32px);
    margin: 0;
}
.ps-card {
    border: 1px solid var(--border, #e8e6ee);
    border-radius: var(--radius-lg, 16px);
    overflow: hidden;
    background: var(--surface, #fff);
    transition: box-shadow 0.2s, transform 0.2s;
}
.ps-card:hover {
    box-shadow: 0 12px 48px color-mix(in oklch, var(--fg, #222) 12%, transparent);
    transform: translateY(-2px);
}
.ps-card-img-link {
    display: block;
}
.ps-card-img img {
    width: 100%;
    height: 220px;
    object-fit: cover;
    display: block;
}
.ps-card h3 {
    margin: var(--gap-md, 20px) var(--gap-md, 20px) 6px;
    font-family: var(--font-display, 'Anton', Impact, sans-serif);
    font-size: 18px;
    font-weight: 600;
    letter-spacing: -0.01em;
}
.ps-card h3 a {
    text-decoration: none;
    color: var(--fg, #222);
}
.ps-card h3 a:hover {
    color: var(--accent, #7a6ce0);
}
.ps-excerpt {
    margin: 8px var(--gap-md, 20px) var(--gap-md, 20px);
    font-size: 14px;
    color: var(--muted, #777);
    line-height: 1.6;
}
.ps-excerpt p {
    margin: 0;
}

/* ── Pagination ── */
.ps-pagination {
    margin: var(--gap-xl, 56px) 0 var(--gap-md, 20px);
    text-align: center;
}
.ps-pagination ul {
    display: inline-flex;
    gap: 6px;
    list-style: none;
    margin: 0;
    padding: 0;
}
.ps-pagination li {
    margin: 0;
}
.ps-pagination a,
.ps-pagination span {
    display: block;
    padding: 7px 13px;
    border: 1px solid var(--border, #e8e6ee);
    border-radius: var(--radius, 10px);
    font-size: 13px;
    text-decoration: none;
    color: var(--muted, #777);
    min-width: 30px;
    box-sizing: border-box;
    transition: all 0.15s;
}
.ps-pagination a:hover {
    background: var(--accent-soft, #efeafb);
    border-color: var(--accent, #7a6ce0);
    color: var(--accent, #7a6ce0);
}
.ps-pagination .current {
    background: var(--accent, #7a6ce0);
    color: var(--surface, #fff);
    border-color: var(--accent, #7a6ce0);
}
.ps-pagination .dots {
    border: none;
    color: var(--muted, #777);
}

/* ── Section titles (below the fold, homepage h2 rhythm) ── */
.ps-section-title {
    font-family: var(--font-display, 'Anton', Impact, sans-serif);
    font-size: clamp(24px, 2.6vw, 32px);
    font-weight: 600;
    letter-spacing: -0.015em;
    line-height: 1.15;
    color: var(--fg, #222);
    margin: clamp(40px, 6vw, 72px) 0 var(--gap-md, 20px);
}

/* ── Carousel (compact card style) ── */
.ps-carousel-section {
    margin: var(--gap-lg, 32px) 0;
}
.ps-carousel {
    position: relative;
    overflow: hidden;
}
.ps-carousel-track {
    display: flex;
    gap: var(--gap-lg, 32px);
    transition: transform 0.35s ease;
}
.ps-carousel-card {
    flex: 0 0 calc((100% - 64px) / 3);
    border: 1px solid var(--border, #e8e6ee);
    border-radius: var(--radius-lg, 16px);
    overflow: hidden;
    background: var(--surface, #fff);
    transition: box-shadow 0.2s;
}
.ps-carousel-card:hover {
    box-shadow: 0 12px 48px color-mix(in oklch, var(--fg, #222) 10%, transparent);
}
.ps-carousel-img img {
    width: 100%;
    height: 180px;
    object-fit: cover;
    display: block;
}
.ps-carousel-text {
    padding: var(--gap-md, 20px);
}
.ps-carousel-text h4 {
    margin: 0 0 6px;
    font-family: var(--font-display, 'Anton', Impact, sans-serif);
    font-size: 16px;
    font-weight: 600;
    color: var(--fg, #222);
}
.ps-carousel-text p {
    margin: 0;
    font-size: 13px;
    color: var(--muted, #777);
    line-height: 1.6;
}
.ps-carousel-prev,
.ps-carousel-next {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 3;
    background: var(--surface, #fff);
    border: 1px solid var(--border, #e8e6ee);
    color: var(--fg, #222);
    font-size: 24px;
    width: 36px;
    height: 48px;
    cursor: pointer;
    border-radius: var(--radius, 10px);
    line-height: 48px;
    text-align: center;
    transition: background 0.2s, box-shadow 0.2s;
    padding: 0;
    box-shadow: 0 4px 16px color-mix(in oklch, var(--fg, #222) 10%, transparent);
    opacity: 0.9;
}
.ps-carousel-prev:hover,
.ps-carousel-next:hover {
    background: var(--fg-soft, #f0eef4);
    opacity: 1;
}
.ps-carousel-prev { left: 8px; }
.ps-carousel-next { right: 8px; }

/* ── Videos (full width) ── */
.ps-video-section {
    margin-bottom: var(--gap-lg, 32px);
}
.ps-video-embed {
    width: 100%;
    aspect-ratio: 16 / 9;
    display: block;
    border-radius: var(--radius-lg, 16px);
    margin-bottom: var(--gap-md, 20px);
}
.ps-video-embed:last-child {
    margin-bottom: 0;
}
.ps-video-embed iframe {
    width: 100%;
    height: 100%;
    border: none;
    border-radius: var(--radius-lg, 16px);
}
.ps-video-embed video {
    width: 100%;
    height: 100%;
    border-radius: var(--radius-lg, 16px);
    display: block;
}

/* ── Alternating Sections ── */
.ps-alt-sections {
    display: flex;
    flex-direction: column;
    gap: var(--gap-xl, 56px);
    margin: 0;
}
.ps-alt-row {
    display: flex;
    gap: clamp(28px, 5vw, 64px);
    align-items: center;
}
.ps-alt-row.ps-alt-reverse {
    flex-direction: row-reverse;
}
.ps-alt-image {
    flex: 0 0 45%;
}
.ps-alt-image img {
    width: 100%;
    border-radius: var(--radius-lg, 16px);
    display: block;
    border: 1px solid var(--border, #e8e6ee);
}
.ps-alt-text {
    flex: 1;
}
.ps-alt-text h3 {
    font-family: var(--font-display, 'Anton', Impact, sans-serif);
    font-size: clamp(20px, 2vw, 26px);
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--fg, #222);
    margin: 0 0 var(--gap-sm, 12px);
}
.ps-alt-desc {
    font-size: var(--fs-body, 16px);
    line-height: 1.7;
    color: var(--muted, #777);
}

/* ── Specifications Table ── */
.ps-specs-section {
    margin: var(--gap-lg, 32px) 0;
}
.ps-specs-wrap {
    overflow-x: auto;
    border: 1px solid var(--border, #e8e6ee);
    border-radius: var(--radius, 10px);
    background: var(--surface, #fff);
}
.ps-specs-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
    color: var(--fg, #222);
}
.ps-specs-table th {
    background: var(--fg-soft, #f0eef4);
    border: 1px solid var(--border, #e8e6ee);
    padding: 12px 16px;
    text-align: left;
    font-weight: 600;
    white-space: nowrap;
    font-family: var(--font-mono, ui-monospace, Menlo, monospace);
    font-size: 11px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--muted, #777);
}
.ps-specs-table td {
    border: 1px solid var(--border, #e8e6ee);
    padding: 10px 16px;
    line-height: 1.6;
}
.ps-specs-table tbody tr:nth-child(odd) {
    background: color-mix(in oklch, var(--fg, #222) 2%, transparent);
}
.ps-specs-table tbody tr:hover {
    background: var(--accent-soft, #efeafb);
}

/* ── Related products ── */
.ps-related {
    margin: clamp(40px, 6vw, 72px) 0 0;
}
.ps-related .ps-section-title {
    margin-top: 0;
}
.ps-related-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: var(--gap-lg, 32px);
}
.ps-related-card {
    border: 1px solid var(--border, #e8e6ee);
    border-radius: var(--radius-lg, 16px);
    overflow: hidden;
    background: var(--surface, #fff);
    transition: box-shadow 0.2s, transform 0.2s;
}
.ps-related-card:hover {
    box-shadow: 0 12px 48px color-mix(in oklch, var(--fg, #222) 12%, transparent);
    transform: translateY(-2px);
}
.ps-related-card img {
    width: 100%;
    height: 180px;
    object-fit: cover;
    display: block;
}
.ps-related-card h3 {
    margin: var(--gap-md, 20px) var(--gap-md, 20px) 4px;
    font-family: var(--font-display, 'Anton', Impact, sans-serif);
    font-size: 16px;
    font-weight: 600;
    letter-spacing: -0.01em;
}
.ps-related-card h3 a {
    text-decoration: none;
    color: var(--fg, #222);
}
.ps-related-card h3 a:hover {
    color: var(--accent, #7a6ce0);
}
/* ── Responsive ── */
@media (max-width: 768px) {
    .ps-detail {
        flex-direction: column;
        align-items: stretch;
    }
    .ps-detail-images {
        flex: none;
        max-width: 100%;
    }
    /* The two flex:none rules above lose to the same-named body.single-product rules, so this equal-weight
       rule clears flex-basis:0 for the stacked layout and restores the 55:45 weights.
    */
    body.single-product .ps-detail-images,
    body.single-product .ps-detail-info {
        flex: 0 0 auto;
    }
    /* On narrow screens the image column is clipped by the thumbnail rail, so the rail steps down too. */
    .ps-gallery { gap: 10px; }
    .ps-thumb-strip {
        --ps-thumb-gap: 8px;
        --ps-thumb-size: 68px;
    }
    .ps-container {
        padding-inline: 20px;
    }
    .ps-carousel-card {
        flex: 0 0 calc((100% - 32px) / 2);
    }
    .ps-alt-row {
        flex-direction: column;
        align-items: flex-start;
    }
    .ps-alt-row.ps-alt-reverse {
        flex-direction: column;
    }
    .ps-alt-image {
        flex: none;
        width: 100%;
    }
    .ps-lb-prev { left: 8px; }
    .ps-lb-next { right: 8px; }
    .ps-lb-nav {
        font-size: 28px;
        width: 40px;
        height: 52px;
        line-height: 52px;
        background: rgba(0, 0, 0, 0.5);
    }
    .ps-lightbox {
        padding: 10px;
    }
}

/* Product page: spec table + related products restyled into this site's design language. Both blocks
   come from the plugin's earliest styling (Georgia headings, pale purple table header, a 16px-radius
   white card with a shadow). Scoped to the single product page because the archive also uses
   .ps-section-title.
*/

body.single-product .ps-section-title {
    font-family: var(--display, 'Anton', Impact, sans-serif);
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: .005em;
    font-size: clamp(1.6rem, 3.2vw, 2.6rem);
    line-height: 1;
    color: var(--ink, #14162A);
    margin: clamp(48px, 6vw, 88px) 0 clamp(20px, 2.4vw, 32px);
}

/* Spec table: right angles, hairlines, no outer frame and no zebra striping. */
body.single-product .ps-specs-section {
    margin: 0;
    padding: clamp(48px, 6vw, 88px) 0 0;
}
body.single-product .ps-specs-wrap {
    overflow-x: auto;
    border: 0;
    border-top: 1px solid var(--line, rgba(20, 22, 42, .14));
    border-radius: 0;
    background: transparent;
    margin-top: clamp(20px, 2.4vw, 32px);
}
body.single-product .ps-specs-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
    font-size: var(--fs-body, 16px);
    color: var(--ink, #14162A);
}
/* Multi-column spec table (versions of one model compared sideways). Two things had to be fixed:
   1) The first column was too wide. A `tbody th { width: 34% }` rule never matched, because the front
      end renders the first cell as <td> (render_specs() emits td throughout tbody), so
      table-layout:fixed split evenly and the parameter names wasted half the table.
   2) Narrow screens could not scroll. With table-layout:fixed + width:100% the table always fills its
      container and never overflows, so .ps-specs-wrap's overflow-x:auto never fired: at 390px four
      columns compressed to 88px each and rows reached 200px. Tables of 3+ columns now get a min-width.
   The selectors use :has() on the header cells to detect the column count, so no class is needed.
   (A plugin upgrade overwrites this file - re-apply.)
*/
body.single-product .ps-specs-table:has(thead th:nth-child(3)) td:first-child,
body.single-product .ps-specs-table:has(thead th:nth-child(3)) th:first-child {
    width: 22%;
}
@media (max-width: 720px) {
    body.single-product .ps-specs-table:has(thead th:nth-child(3)) { min-width: 520px; }
    body.single-product .ps-specs-table:has(thead th:nth-child(4)) { min-width: 660px; }
}
body.single-product .ps-specs-table th,
body.single-product .ps-specs-table td {
    border: 0;
    border-bottom: 1px solid var(--line, rgba(20, 22, 42, .14));
    padding: clamp(13px, 1.5vw, 20px) clamp(12px, 1.5vw, 26px);
    text-align: left;
    vertical-align: top;
    line-height: 1.6;
}
body.single-product .ps-specs-table thead th {
    font-family: var(--mono, 'Space Mono', 'Courier New', monospace);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--muted, #6C6F7B);
    border-bottom-color: var(--ink, #14162A);
    background: transparent;
}
body.single-product .ps-specs-table tbody th {
    width: 34%;
    font-family: var(--mono, 'Space Mono', 'Courier New', monospace);
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--muted, #6C6F7B);
    background: transparent;
    white-space: normal;
}
body.single-product .ps-specs-table tbody td {
    font-weight: 600;
    color: var(--ink, #14162A);
}
body.single-product .ps-specs-table tbody tr:nth-child(odd) { background: transparent; }
body.single-product .ps-specs-table tbody tr:hover { background: var(--paper-2, #E9E6DD); }

/* Related products: right-angle paper cards with an orange outline. */
body.single-product .ps-related {
    margin: 0;
    padding: clamp(48px, 6vw, 88px) 0 0;
}
body.single-product .ps-related-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: clamp(16px, 2vw, 28px);
}
body.single-product .ps-related-card {
    border: 1px solid var(--line, rgba(20, 22, 42, .14));
    border-radius: 0;
    background: var(--paper, #F3F1EA);
    transition: border-color .18s ease, transform .18s ease;
}
body.single-product .ps-related-card:hover {
    border-color: var(--orange, #F0950A);
    box-shadow: none;
    transform: translateY(-2px);
}
body.single-product .ps-related-card img {
    width: 100%;
    height: auto;
    aspect-ratio: 1 / 1;
    object-fit: contain;
    /* White-ground product photos sit on paper without showing a white box. */
    mix-blend-mode: multiply;
    background: var(--paper, #F3F1EA);
    border-bottom: 1px solid var(--line, rgba(20, 22, 42, .14));
    transition: transform .3s ease;
}
body.single-product .ps-related-card:hover img { transform: scale(1.04); }
body.single-product .ps-related-card h3 {
    margin: 16px 18px 20px;
    font-family: var(--sans, 'Archivo', system-ui, sans-serif);
    font-size: 16px;
    font-weight: 700;
    line-height: 1.35;
    letter-spacing: -.01em;
}
body.single-product .ps-related-card h3 a { color: var(--ink, #14162A); }
body.single-product .ps-related-card h3 a:hover { color: var(--orange, #F0950A); }

@media (max-width: 1024px) {
    body.single-product .ps-related-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 820px) {
    body.single-product .ps-related-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    body.single-product .ps-specs-table tbody th { width: 42%; }
}

/* 「可定制/升级」的一句话说明（模板里写死，不是每产品单独填）—— 跟站点其它脚注同一套：
   mono 小字、--muted、不上色，落在两个按钮下面一行。 */
body.single-product .ps-oem-note {
    margin: 14px 0 0;
    max-width: 62ch;
    font-family: var(--mono, 'Space Mono', monospace);
    font-size: var(--fs-label, 12px);
    line-height: 1.85;
    letter-spacing: .02em;
    color: var(--muted, #6C6F7B);
}
