/* The shop's card and quick-view styles, copied from shop.html by
   tools/related_patterns.py for the similar-pattern cards on pattern pages.
   Do not edit here: edit shop.html and run the tool again. */
/* ============================================================
           SHOP PAGE — editorial catalog layer
           ------------------------------------------------------------
           Same token values as pattern-page.css (paper / ink / clay /
           near-black CTA / radius & shadow scale), namespaced --shop-*
           here rather than imported, since pattern-page.css is scoped
           to the product page's own layout offsets. Keeping the same
           values is what makes the shop feel like it belongs to the
           same catalogue as the pattern pages, not a different site.
           ============================================================ */
        :root {
            --shop-paper: #FAF7F2;
            --shop-paper-alt: #F2EDE4;
            --shop-ink: #211D1A;
            --shop-ink-soft: #5A534C;
            --shop-ink-faint: #8C837A;
            --shop-line: #E2D9CC;
            --shop-clay: #B5563A;
            --shop-clay-deep: #8F3F28;
            --shop-clay-tint: #F6E7E0;
            --shop-black: #1A1714;
            --shop-sage: #5F6B52;
            --shop-sage-tint: #E8EBE1;
            --shop-r-s: 6px;
            --shop-r-m: 12px;
            --shop-r-l: 18px;
            --shop-shadow: 0 1px 2px rgba(33,29,26,.05), 0 8px 24px -14px rgba(33,29,26,.22);
            --shop-shadow-lift: 0 2px 6px rgba(33,29,26,.06), 0 18px 40px -20px rgba(33,29,26,.30);
        }

        .shop-hero {
            padding: 132px 0 44px 0;
            background:
                linear-gradient(180deg, rgba(250, 247, 242, 0.96) 0%, rgba(250, 247, 242, 0.90) 100%),
                url('assets/fashion_sewing_bg.png') center/cover no-repeat;
            text-align: center;
            border-bottom: 1px solid var(--shop-line);
        }

        .shop-hero-eyebrow {
            display: inline-block;
            font-family: var(--font-data);
            font-size: 0.72rem;
            font-weight: 500;
            letter-spacing: 0.12em;
            text-transform: uppercase;
            color: var(--shop-clay-deep);
            margin-bottom: 14px;
        }

        .shop-hero h1 {
            font-family: var(--font-heading);
            font-weight: 600;
            font-size: clamp(2.2rem, 3.6vw, 3.1rem);
            letter-spacing: -0.01em;
            line-height: 1.15;
            margin-bottom: 14px;
            color: var(--shop-ink);
        }

        .shop-hero p {
            font-size: 1.05rem;
            line-height: 1.6;
            color: var(--shop-ink-soft);
            max-width: 620px;
            margin: 0 auto 28px auto;
        }

        .shop-hero p strong { color: var(--shop-ink); }

        /* The one big offer, as a button that reads as the way forward: near-black
           like the product page's buy button, with the price set apart inside it
           so what you are agreeing to is visible before you click. The a-prefixed
           selectors are there because the site-wide link rules would otherwise
           win on colour and underline. */
        .shop-hero a.shop-hero-cta {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            gap: 14px;
            min-height: 54px;
            padding: 0 26px 0 30px;
            background: var(--shop-black);
            color: #FFFFFF;
            border-radius: var(--shop-r-m);
            font-family: var(--font-body);
            font-size: 1rem;
            font-weight: 700;
            letter-spacing: 0.01em;
            text-decoration: none;
            box-shadow: var(--shop-shadow);
            transition: background-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
        }
        .shop-hero a.shop-hero-cta:hover,
        .shop-hero a.shop-hero-cta:focus-visible {
            background: var(--shop-clay-deep);
            color: #FFFFFF;
            transform: translateY(-1px);
            box-shadow: var(--shop-shadow-lift);
        }
        .shop-hero a.shop-hero-cta:active { transform: none; }
        .shop-hero a.shop-hero-cta:focus-visible {
            outline: 2px solid var(--shop-clay);
            outline-offset: 3px;
        }
        .shop-hero-cta-price {
            padding-left: 14px;
            border-left: 1px solid rgba(255, 255, 255, 0.3);
            font-weight: 600;
        }
        .shop-hero-cta-arrow { flex: none; transition: transform 0.2s ease; }
        .shop-hero a.shop-hero-cta:hover .shop-hero-cta-arrow { transform: translateX(3px); }
        .shop-hero-assurance {
            display: block;
            margin-top: 14px;
            font-size: 0.84rem;
            letter-spacing: 0.02em;
            color: var(--shop-ink-faint);
        }
        .shop-hero-cta-label { white-space: nowrap; }
        @media (max-width: 480px) {
            .shop-hero a.shop-hero-cta {
                width: 100%;
                max-width: 360px;
                gap: 12px;
                padding: 0 20px;
                font-size: 0.95rem;
            }
        }
        @media (max-width: 360px) {
            .shop-hero a.shop-hero-cta {
                gap: 10px;
                padding: 0 14px;
                font-size: 0.86rem;
            }
            .shop-hero-cta-price { padding-left: 10px; }
        }
        @media (prefers-reduced-motion: reduce) {
            .shop-hero a.shop-hero-cta,
            .shop-hero-cta-arrow { transition: none; }
            .shop-hero a.shop-hero-cta:hover { transform: none; }
        }

        /* Shop Main 2-Column Layout */
        .shop-layout {
            display: flex;
            gap: 40px;
            align-items: flex-start;
            margin-top: 44px;
            margin-bottom: 60px;
            padding-top: 10px;
        }

        /* Sidebar Styling — plain editorial filter rail, not boxed widgets */
        /* Sticks to the BOTTOM of the viewport, not the top. A top-sticky
           sidebar pins immediately on scroll, and since its own content is
           taller than most laptop viewports, everything past that first
           screenful stayed rendered off-screen and unreachable. Anchoring
           from the bottom instead lets it scroll past naturally in full
           view first, and only "catches" once you've scrolled far enough
           that its own bottom edge would leave the viewport — from then on
           it rides along at the bottom instead of leaving the left column
           empty for the rest of the (much taller) product grid. */
        .shop-sidebar {
            width: 232px;
            flex-shrink: 0;
            position: sticky;
            bottom: 24px;
            display: flex;
            flex-direction: column;
            gap: 30px;
            transition: all 0.3s ease;
        }

        .shop-sidebar-widget {
            padding-bottom: 26px;
            border-bottom: 1px solid var(--shop-line);
        }

        .shop-sidebar-widget:last-child,
        .shop-sidebar-widget.is-last-filter {
            border-bottom: none;
            padding-bottom: 0;
        }

        .shop-sidebar-drawer-footer { display: none; }

        .shop-sidebar-drawer-header {
            display: none;
        }

        .widget-title {
            font-family: var(--font-data);
            font-size: 0.72rem;
            font-weight: 500;
            letter-spacing: 0.1em;
            text-transform: uppercase;
            color: var(--shop-ink-faint);
            margin-bottom: 14px;
            display: flex;
            align-items: center;
            justify-content: space-between;
        }

        .widget-reset-btn {
            font-family: var(--font-body);
            font-size: 0.76rem;
            font-weight: 600;
            text-transform: none;
            letter-spacing: 0;
            color: var(--shop-clay-deep) !important;
            background: none;
            border: none;
            cursor: pointer;
            padding: 0;
            transition: opacity 0.2s ease;
        }

        .widget-reset-btn:hover {
            opacity: 0.65;
        }

        /* No max-height/overflow here on purpose: this used to be its own
           460px scroll box with a wheel handler trapping scroll input over
           it, so hovering the filter and scrolling moved only this small
           box instead of the page, and the categories below the fold were
           unreachable without discovering that separate scrollbar. It's now
           part of the sidebar's normal flow, scrolling with the page like
           every other widget. */
        .sidebar-category-list {
            display: flex;
            flex-direction: column;
            gap: 1px;
            list-style: none;
            padding: 0;
            margin: 0;
        }

        /* Checkbox-style filter rows — a square keyline box per row (checked
           = filled ink square with a tick) instead of a tinted active row.
           Category stays single-select under the hood (picking one clears
           the last), but reads as the familiar shop-filter checkbox list
           rather than a plain link list. */
        .filter-checkbox {
            flex: 0 0 16px;
            width: 16px;
            height: 16px;
            border: 1.5px solid var(--shop-line);
            background: #FFFFFF;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            transition: background-color 0.15s ease, border-color 0.15s ease;
        }

        .filter-checkbox svg {
            width: 10px;
            height: 10px;
            stroke: #FFFFFF;
            opacity: 0;
            transform: scale(0.5);
            transition: opacity 0.15s ease, transform 0.15s ease;
        }

        .sidebar-cat-btn,
        .sidebar-skill-btn {
            width: 100%;
            display: flex;
            align-items: center;
            gap: 10px;
            padding: 7px 4px;
            border-radius: 0;
            background: transparent;
            border: none;
            font-family: var(--font-body);
            font-size: 0.9rem;
            font-weight: 500;
            color: var(--shop-ink-soft);
            cursor: pointer;
            text-align: left;
            transition: color 0.15s ease;
        }

        .sidebar-cat-btn span:not(.filter-checkbox):not(.sidebar-cat-count) {
            flex: 1;
            min-width: 0;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        .sidebar-cat-btn:hover,
        .sidebar-skill-btn:hover {
            color: var(--shop-ink) !important;
        }

        .sidebar-cat-btn:hover .filter-checkbox,
        .sidebar-skill-btn:hover .filter-checkbox {
            border-color: var(--shop-ink);
        }

        .sidebar-cat-btn.active,
        .sidebar-skill-btn.active {
            color: var(--shop-ink);
            font-weight: 700;
        }

        .sidebar-cat-btn.active .filter-checkbox,
        .sidebar-skill-btn.active .filter-checkbox {
            background: var(--shop-ink);
            border-color: var(--shop-ink);
        }

        .sidebar-cat-btn.active .filter-checkbox svg,
        .sidebar-skill-btn.active .filter-checkbox svg {
            opacity: 1;
            transform: scale(1);
        }

        .sidebar-cat-count {
            font-family: var(--font-data);
            font-size: 0.72rem;
            font-weight: 500;
            color: var(--shop-ink-faint);
            flex-shrink: 0;
        }

        .sidebar-skill-btn .sidebar-cat-count {
            margin-left: auto;
        }

        /* Skill Level filter list */
        .sidebar-skill-list {
            display: flex;
            flex-direction: column;
            gap: 2px;
        }

        /* ============================================================
           CLOSING BAND - why sewists love us / sewing guides
           ------------------------------------------------------------
           These two used to sit at the foot of the filter rail, which put
           reassurance and a blog link inside the tool for narrowing the
           catalogue, and on phones made the filter drawer longer than the
           filters. They close the page instead, after the grid.
           ============================================================ */
        .shop-closing {
            padding: 60px 0 64px;
            background: var(--shop-paper-alt);
            border-top: 1px solid var(--shop-line);
        }
        .shop-closing-grid {
            display: grid;
            grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
            gap: 64px;
            align-items: start;
        }
        .shop-closing-title {
            margin: 0 0 24px;
            font-family: var(--font-heading);
            font-size: clamp(1.5rem, 2.4vw, 1.9rem);
            font-weight: 600;
            line-height: 1.2;
            letter-spacing: -0.01em;
            color: var(--shop-ink);
        }
        .shop-perks {
            list-style: none;
            margin: 0;
            padding: 0;
            display: grid;
            grid-template-columns: repeat(2, minmax(0, 1fr));
            gap: 20px 32px;
        }
        .shop-perks li {
            display: flex;
            align-items: center;
            gap: 14px;
            color: var(--shop-ink);
            font-size: 1rem;
            line-height: 1.35;
        }
        .shop-perk-icon {
            flex: none;
            width: 42px;
            height: 42px;
            display: grid;
            place-items: center;
            border: 1px solid var(--shop-line-strong);
            border-radius: var(--shop-r-s);
            background: #FFFFFF;
            color: var(--shop-clay-deep);
        }
        .shop-closing-guides { padding-left: 56px; border-left: 1px solid var(--shop-line-strong); }
        .shop-closing-guides p {
            margin: 0 0 22px;
            max-width: 380px;
            color: var(--shop-ink-soft);
            font-size: 1rem;
            line-height: 1.6;
        }
        .shop-closing a.shop-closing-link {
            display: inline-flex;
            align-items: center;
            gap: 10px;
            min-height: 48px;
            padding: 0 22px;
            border: 1px solid var(--shop-ink);
            border-radius: var(--shop-r-m);
            background: transparent;
            color: var(--shop-ink);
            font-family: var(--font-body);
            font-size: 0.95rem;
            font-weight: 700;
            text-decoration: none;
            transition: background-color 0.2s ease, color 0.2s ease;
        }
        .shop-closing a.shop-closing-link:hover {
            background: var(--shop-black);
            color: #FFFFFF;
        }
        @media (max-width: 992px) {
            .shop-closing { padding: 44px 0 48px; }
            .shop-closing-grid { grid-template-columns: minmax(0, 1fr); gap: 36px; }
            .shop-closing-guides { padding-left: 0; padding-top: 32px; border-left: 0; border-top: 1px solid var(--shop-line-strong); }
        }
        @media (max-width: 600px) {
            .shop-perks { grid-template-columns: minmax(0, 1fr); gap: 16px; }
        }
        @media (prefers-reduced-motion: reduce) {
            .shop-closing a.shop-closing-link { transition: none; }
        }

        /* Main Content Container */
        .shop-main-content {
            flex: 1;
            min-width: 0; /* Prevents flex overflow */
        }

        /* ============================================================
           TOOLBAR - search, filters, sort, what is applied, how many
           ------------------------------------------------------------
           One row of controls that share a height (48px, above the 44px
           touch minimum), a hairline darker than a card's so an empty
           field still reads as a field, and the same 12px corner as the
           site's buttons. Below 993px the filters open a drawer, so the toolbar
           becomes search on its own row with Filters and Sort as two
           equal halves beneath it. What is applied is written out as
           removable chips, because on a phone the drawer is closed and
           nothing else says why the grid is short.
           ============================================================ */
        :root { --shop-line-strong: #C9BCA9; }

        .shop-toolbar {
            display: grid;
            grid-template-columns: minmax(0, 1fr) auto;
            grid-template-areas: "search sort";
            gap: 12px;
            margin-bottom: 18px;
        }
        .shop-search { grid-area: search; position: relative; }
        .shop-sort { grid-area: sort; position: relative; }
        .shop-filter-btn { grid-area: filter; display: none; }

        .shop-search-icon {
            position: absolute;
            left: 16px;
            top: 50%;
            transform: translateY(-50%);
            display: flex;
            color: var(--shop-ink-faint);
            pointer-events: none;
            transition: color 0.2s ease;
        }
        .shop-search:focus-within .shop-search-icon { color: var(--shop-ink); }

        .shop-search-input {
            width: 100%;
            height: 48px;
            padding: 0 78px 0 46px;
            border: 1px solid var(--shop-line-strong);
            border-radius: var(--shop-r-m);
            background: #FFFFFF;
            color: var(--shop-ink);
            /* 16px: anything smaller makes iOS zoom the page when the field is focused */
            font-family: var(--font-body);
            font-size: 1rem;
            outline: none;
            -webkit-appearance: none;
            appearance: none;
            transition: border-color 0.2s ease, box-shadow 0.2s ease;
        }
        .shop-search-input::placeholder { color: var(--shop-ink-faint); }
        .shop-search-input::-webkit-search-cancel-button,
        .shop-search-input::-webkit-search-decoration { -webkit-appearance: none; display: none; }
        .shop-search-input:hover { border-color: var(--shop-ink-faint); }
        .shop-search-input:focus {
            border-color: var(--shop-ink);
            box-shadow: 0 0 0 3px var(--shop-clay-tint);
        }

        .shop-search-clear {
            position: absolute;
            right: 6px;
            top: 50%;
            transform: translateY(-50%);
            width: 36px;
            height: 36px;
            display: none;
            place-items: center;
            padding: 0;
            border: 0;
            border-radius: 4px;
            background: transparent;
            color: var(--shop-ink-soft);
            cursor: pointer;
            transition: background-color 0.15s ease, color 0.15s ease;
        }
        .shop-search.has-value .shop-search-clear { display: grid; }
        .shop-search-clear:hover { background: var(--shop-paper-alt); color: var(--shop-ink); }

        /* the "/" shortcut hint: only where there is a keyboard to press it on */
        .shop-search-kbd {
            position: absolute;
            right: 14px;
            top: 50%;
            transform: translateY(-50%);
            padding: 1px 8px;
            border: 1px solid var(--shop-line-strong);
            border-radius: 4px;
            background: var(--shop-paper);
            color: var(--shop-ink-faint);
            font-family: var(--font-body);
            font-size: 0.78rem;
            font-weight: 600;
            pointer-events: none;
        }
        .shop-search.has-value .shop-search-kbd,
        .shop-search:focus-within .shop-search-kbd { display: none; }

        .shop-sort-label {
            position: absolute;
            left: 16px;
            top: 50%;
            transform: translateY(-50%);
            font-family: var(--font-data);
            font-size: 0.68rem;
            font-weight: 500;
            letter-spacing: 0.1em;
            text-transform: uppercase;
            color: var(--shop-ink-faint);
            pointer-events: none;
        }
        .shop-sort-select {
            height: 48px;
            min-width: 220px;
            padding: 0 40px 0 64px;
            border: 1px solid var(--shop-line-strong);
            border-radius: var(--shop-r-m);
            background: #FFFFFF url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="%235A534C" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>') no-repeat right 14px center;
            color: var(--shop-ink);
            font-family: var(--font-body);
            font-size: 0.95rem;
            font-weight: 600;
            outline: none;
            cursor: pointer;
            -webkit-appearance: none;
            appearance: none;
            transition: border-color 0.2s ease, box-shadow 0.2s ease;
        }
        .shop-sort-select:hover { border-color: var(--shop-ink-faint); }
        .shop-sort-select:focus {
            border-color: var(--shop-ink);
            box-shadow: 0 0 0 3px var(--shop-clay-tint);
        }

        .shop-filter-btn {
            align-items: center;
            justify-content: center;
            gap: 10px;
            height: 48px;
            padding: 0 16px;
            border: 1px solid var(--shop-line-strong);
            border-radius: var(--shop-r-m);
            background: #FFFFFF;
            color: var(--shop-ink);
            font-family: var(--font-body);
            font-size: 0.95rem;
            font-weight: 600;
            cursor: pointer;
            transition: border-color 0.2s ease, box-shadow 0.2s ease;
        }
        .shop-filter-btn:hover { border-color: var(--shop-ink-faint); }
        .shop-filter-btn.has-filters { border-color: var(--shop-ink); }
        .shop-filter-count {
            min-width: 20px;
            height: 20px;
            padding: 0 6px;
            display: inline-grid;
            place-items: center;
            border-radius: 10px;
            background: var(--shop-black);
            color: #FFFFFF;
            font-size: 0.72rem;
            font-weight: 700;
            line-height: 1;
        }
        .shop-filter-count[hidden] { display: none; }

        .shop-search-input:focus-visible,
        .shop-sort-select:focus-visible,
        .shop-filter-btn:focus-visible,
        .shop-search-clear:focus-visible,
        .shop-chip:focus-visible,
        .shop-clear-all:focus-visible,
        .shop-drawer-apply:focus-visible,
        .shop-drawer-reset:focus-visible,
        .shop-empty-btn:focus-visible,
        .shop-empty-chip:focus-visible,
        .shop-closing-link:focus-visible {
            outline: 2px solid var(--shop-clay);
            outline-offset: 2px;
        }
        .shop-search-input:focus-visible,
        .shop-sort-select:focus-visible { outline-offset: 0; }

        /* results line + applied filters */
        .shop-results-bar {
            display: flex;
            flex-wrap: wrap;
            align-items: center;
            gap: 8px 14px;
            min-height: 36px;
            margin-bottom: 20px;
        }
        .shop-results-meta {
            margin: 0;
            font-size: 0.9rem;
            font-weight: 500;
            color: var(--shop-ink-soft);
        }
        .shop-results-meta strong { color: var(--shop-ink); font-weight: 700; }
        .shop-active-filters {
            display: flex;
            flex-wrap: wrap;
            align-items: center;
            gap: 8px;
        }
        .shop-active-filters[hidden] { display: none; }
        .shop-chip {
            display: inline-flex;
            align-items: center;
            gap: 8px;
            height: 34px;
            padding: 0 8px 0 12px;
            border: 1px solid var(--shop-line-strong);
            border-radius: var(--shop-r-s);
            background: #FFFFFF;
            color: var(--shop-ink);
            font-family: var(--font-body);
            font-size: 0.84rem;
            font-weight: 600;
            cursor: pointer;
            transition: border-color 0.15s ease;
        }
        .shop-chip svg { flex: none; color: var(--shop-ink-faint); transition: color 0.15s ease; }
        .shop-chip:hover { border-color: var(--shop-ink); }
        .shop-chip:hover svg { color: var(--shop-ink); }
        .shop-clear-all {
            height: 34px;
            padding: 0 4px;
            border: 0;
            background: none;
            color: var(--shop-clay-deep);
            font-family: var(--font-body);
            font-size: 0.84rem;
            font-weight: 700;
            text-decoration: underline;
            text-decoration-color: transparent;
            text-underline-offset: 3px;
            cursor: pointer;
            transition: text-decoration-color 0.15s ease;
        }
        .shop-clear-all:hover { text-decoration-color: currentColor; }

        /* nothing matched: say why and offer a way out, never a dead end */
        .shop-empty {
            grid-column: 1 / -1;
            padding: 56px 24px;
            text-align: center;
            border: 1px dashed var(--shop-line-strong);
            border-radius: var(--shop-r-m);
            background: rgba(255, 255, 255, 0.6);
        }
        .shop-empty h3 {
            margin: 0 0 8px;
            font-family: var(--font-heading);
            font-size: 1.5rem;
            font-weight: 600;
            color: var(--shop-ink);
        }
        .shop-empty p {
            max-width: 440px;
            margin: 0 auto 22px;
            color: var(--shop-ink-soft);
            line-height: 1.55;
        }
        .shop-empty-btn {
            height: 46px;
            padding: 0 24px;
            border: 0;
            border-radius: var(--shop-r-m);
            background: var(--shop-black);
            color: #FFFFFF;
            font-family: var(--font-body);
            font-size: 0.95rem;
            font-weight: 700;
            cursor: pointer;
            transition: background-color 0.2s ease;
        }
        .shop-empty-btn:hover { background: var(--shop-clay-deep); }
        .shop-empty-suggest {
            margin-top: 28px;
            font-size: 0.82rem;
            color: var(--shop-ink-faint);
        }
        .shop-empty-list {
            display: flex;
            flex-wrap: wrap;
            justify-content: center;
            gap: 8px;
            margin-top: 10px;
        }
        .shop-empty-chip {
            height: 36px;
            padding: 0 14px;
            border: 1px solid var(--shop-line-strong);
            border-radius: var(--shop-r-s);
            background: #FFFFFF;
            color: var(--shop-ink);
            font-family: var(--font-body);
            font-size: 0.86rem;
            font-weight: 600;
            cursor: pointer;
            transition: border-color 0.15s ease;
        }
        .shop-empty-chip:hover { border-color: var(--shop-ink); }

        /* page numbers: square like every other control here, the current one filled */
        #shop-pagination-container .shop-pagination-btn {
            width: 44px;
            height: 44px;
            border-radius: var(--shop-r-m);
            background: #FFFFFF;
            color: var(--shop-ink);
            border: 1px solid var(--shop-line-strong);
            font-family: var(--font-body);
            font-size: 0.95rem;
            font-weight: 600;
            box-shadow: none;
            transform: none;
        }
        #shop-pagination-container .shop-pagination-btn:hover:not(:disabled) {
            background: var(--shop-paper-alt);
            border-color: var(--shop-ink);
            box-shadow: none;
            transform: none;
        }
        #shop-pagination-container .shop-pagination-btn.active {
            background: var(--shop-black) !important;
            border: 1px solid var(--shop-black) !important;
            color: #FFFFFF !important;
            font-weight: 700 !important;
            box-shadow: none !important;
            transform: none !important;
        }
        #shop-pagination-container .shop-pagination-btn:disabled {
            opacity: 0.4;
            background: #FFFFFF;
            cursor: not-allowed;
        }
        #shop-pagination-container .shop-pagination-btn:focus-visible {
            outline: 2px solid var(--shop-clay);
            outline-offset: 2px;
        }

        @media (hover: none), (max-width: 992px) {
            .shop-search-kbd { display: none; }
        }
        @media (prefers-reduced-motion: reduce) {
            .shop-search-input, .shop-sort-select, .shop-filter-btn, .shop-chip,
            .shop-clear-all, .shop-search-clear, .shop-empty-btn, .shop-empty-chip { transition: none; }
        }

        /* Shop Grid: 3 cards per row on desktop/laptop screens */
        .shop-grid {
            display: grid !important;
            grid-template-columns: repeat(3, 1fr) !important;
            gap: 28px 24px !important;
            margin-bottom: 50px;
            width: 100%;
        }

        @media (max-width: 992px) {
            .shop-layout {
                flex-direction: column;
                gap: 0;
            }
            .shop-toolbar {
                grid-template-columns: repeat(2, minmax(0, 1fr));
                grid-template-areas:
                    "search search"
                    "filter sort";
            }
            .shop-filter-btn { display: inline-flex; }
            .shop-sort-select { width: 100%; min-width: 0; }

            /* The filter panel becomes a full-screen drawer rather than inline
               content the page scrolls past. Inline content that tall (13
               categories + skill level + promo + guides) meant, on a real phone,
               rows kept scrolling underneath the fixed chat bubble, back-to-top
               button and bottom nav bar — all higher z-index than anything on
               this page — so taps landed on those instead of the filter. A
               full-screen drawer has its own scroll and sits above all of them. */
            .shop-sidebar {
                width: 100%;
                position: fixed;
                inset: 0;
                z-index: 2600;
                display: none;
                flex-direction: column;
                gap: 0;
                background: #FFFFFF;
                border: none;
                border-radius: 0;
                padding: 0;
                margin-bottom: 0;
            }
            .shop-sidebar.mobile-visible {
                display: flex;
                overflow-y: auto;
                -webkit-overflow-scrolling: touch;
            }
            .shop-sidebar-drawer-header {
                display: flex;
                align-items: center;
                justify-content: space-between;
                flex-shrink: 0;
                position: sticky;
                top: 0;
                z-index: 1;
                padding: 18px 20px;
                background: #FFFFFF;
                border-bottom: 1px solid var(--shop-line);
                font-family: var(--font-heading);
                font-size: 1.1rem;
                font-weight: 600;
                color: var(--shop-ink);
            }
            .shop-sidebar-drawer-close {
                width: 34px;
                height: 34px;
                border-radius: 50%;
                border: none;
                background: var(--shop-paper-alt);
                color: var(--shop-ink);
                font-size: 1.5rem;
                line-height: 1;
                cursor: pointer;
            }
            /* the widgets that used to be the whole sidebar are now the drawer's
               scrollable body, below the fixed header */
            .shop-sidebar > .shop-sidebar-widget {
                flex-shrink: 0;
                margin: 0 20px;
            }
            .shop-sidebar > .shop-sidebar-widget:first-of-type {
                margin-top: 20px;
            }
            /* Filters are chosen together and the drawer stays open while they are.
               Its own footer closes it, and says what the choice will do first
               ("Show 54 patterns") instead of closing on the first tap. */
            .shop-sidebar > .shop-sidebar-widget.is-last-filter { margin-bottom: 24px; }
            .shop-sidebar .widget-reset-btn { display: none; }
            .shop-sidebar-drawer-footer {
                display: flex;
                gap: 10px;
                flex-shrink: 0;
                position: sticky;
                bottom: 0;
                margin-top: auto;
                padding: 14px 20px calc(14px + env(safe-area-inset-bottom, 0px));
                background: #FFFFFF;
                border-top: 1px solid var(--shop-line);
                z-index: 1;
            }
            .shop-drawer-reset {
                height: 50px;
                padding: 0 20px;
                border: 1px solid var(--shop-line-strong);
                border-radius: var(--shop-r-m);
                background: #FFFFFF;
                color: var(--shop-ink);
                font-family: var(--font-body);
                font-size: 0.95rem;
                font-weight: 600;
                cursor: pointer;
            }
            .shop-drawer-apply {
                flex: 1;
                height: 50px;
                border: 0;
                border-radius: var(--shop-r-m);
                background: var(--shop-black);
                color: #FFFFFF;
                font-family: var(--font-body);
                font-size: 1rem;
                font-weight: 700;
                cursor: pointer;
            }
            /* Hidden while the drawer covers the screen, so they can't sit on
               top of it and steal taps meant for a filter row underneath them. */
            body.shop-filters-open #crisp-chatbox,
            body.shop-filters-open #back-to-top-btn,
            body.shop-filters-open .bottom-nav {
                display: none !important;
            }

            .shop-grid {
                grid-template-columns: repeat(3, 1fr) !important;
                gap: 16px 12px !important;
            }
            .shop-hero h1 { font-size: 2.2rem; }
        }

        @media (max-width: 768px) {
            .shop-grid {
                grid-template-columns: repeat(2, 1fr) !important;
                gap: 14px 10px !important;
            }
        }

        @media (max-width: 480px) {
            .shop-grid {
                grid-template-columns: repeat(2, 1fr) !important;
                gap: 12px 8px !important;
            }
        }

        /* chic-responsive.css sets the title to 0.88rem !important below
           600px, which still reads too large on a ~170px-wide 2-up mobile
           card — sized down further here, matched at the same breakpoint. */
        @media (max-width: 600px) {
            .shop-card-title {
                font-size: 0.82rem !important;
                line-height: 1.3 !important;
            }
        }

        /* Editorial Pattern Card — near-square, hairline border. Just enough
           radius (4px) to take the point off the corner without reading as
           a rounded UI box; a boutique catalogue is sharp rectangles of
           photography with a thin keyline, not the 18px radius used
           elsewhere on the site (buttons, sidebar cards). */
        .shop-card {
            background-color: #FFFFFF;
            border: 1px solid var(--shop-line);
            border-radius: 4px;
            overflow: hidden;
            display: flex;
            flex-direction: column;
            transition: transform 0.3s cubic-bezier(0.165, 0.84, 0.44, 1), box-shadow 0.3s ease, border-color 0.3s ease;
            box-shadow: none;
            position: relative;
        }

        .shop-card:hover {
            transform: translateY(-3px);
            box-shadow: 0 10px 24px rgba(33, 29, 26, 0.12);
            border-color: var(--shop-ink);
        }

        .shop-card-img-wrapper {
            position: relative;
            width: 100%;
            aspect-ratio: 3/4;
            max-height: none;
            background-color: var(--shop-paper-alt);
            overflow: hidden;
            padding: 0;
            display: block;
            cursor: pointer;
        }

        .shop-card-img-wrapper img {
            width: 100%;
            height: 100%;
            object-fit: cover;
            border-radius: 0;
            transition: transform 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
        }

        .shop-card:hover .shop-card-img-wrapper img {
            transform: scale(1.04);
        }

        /* Landscape photographs (bags) are shown whole on the paper tone, as the
           product page does - cropping them to 3:4 cut the bag itself off. */
        .shop-card-img-wrapper img.is-wide {
            object-fit: contain;
            background: var(--shop-paper-alt);
        }


        /* Sits directly on the photo, no fill or keyline — white text reads
           clearly against any pattern photo the way a printed corner stamp
           would, without needing a box behind it. */
        .shop-card-badge {
            position: absolute;
            top: 10px;
            left: 10px;
            background: none;
            color: #FFFFFF;
            padding: 0;
            font-family: var(--font-data);
            font-size: 0.72rem;
            font-weight: 600;
            letter-spacing: 0.02em;
            text-shadow: 0 1px 3px rgba(0, 0, 0, 0.55), 0 1px 8px rgba(0, 0, 0, 0.3);
            z-index: 2;
        }

        /* Favorite toggle — no box, no fill: a plain icon on the photo, white
           at rest, red once favorited. The drop-shadow on the svg is what
           keeps a white outline legible on a light or white pattern photo
           without needing a background plate behind it. */
        /* !important throughout: style.min.css and chic-responsive.css both
           ship an older circular .favorite-heart-btn (one of them via a
           "& .favorite-heart-btn" selector, which nesting syntax gives extra
           specificity over a plain class), and this component needs to win
           outright rather than compete on specificity with either. */
        .favorite-heart-btn {
            position: absolute !important;
            top: 0 !important;
            right: 0 !important;
            width: 44px !important;
            height: 44px !important;
            min-width: 44px !important;
            min-height: 44px !important;
            border-radius: 0 !important;
            background: none !important;
            border: 0 !important;
            display: inline-flex !important;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            z-index: 25;
            box-shadow: none !important;
            backdrop-filter: none !important;
            transition: transform 0.15s ease;
        }

        .favorite-heart-btn svg {
            filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.55)) drop-shadow(0 1px 6px rgba(0, 0, 0, 0.25));
        }

        .favorite-heart-btn:hover {
            background: none !important;
            border-color: transparent !important;
            transform: scale(1.1) !important;
        }

        .favorite-heart-btn.active {
            background: none !important;
            border-color: transparent !important;
        }

        .favorite-heart-btn:active {
            transform: scale(0.9) !important;
        }

        /* Quick View — a solid label strip flush with the bottom edge of the
           photo, like a caption bar, rather than a floating pill button. */
        .shop-card-hover-overlay {
            position: absolute;
            bottom: 0;
            left: 0;
            width: 100%;
            padding: 0;
            background: none;
            opacity: 0;
            transform: translateY(100%);
            transition: opacity 0.25s ease, transform 0.25s ease;
            display: flex;
            justify-content: center;
            z-index: 2;
        }

        .shop-card:hover .shop-card-hover-overlay {
            opacity: 1;
            transform: translateY(0);
        }

        .shop-card-quickview-btn {
            width: 100%;
            background: var(--shop-black);
            color: #FFFFFF;
            border: none;
            border-radius: 0;
            padding: 11px 20px;
            font-family: var(--font-body);
            font-size: 0.72rem;
            font-weight: 700;
            text-transform: uppercase;
            letter-spacing: 0.12em;
            cursor: pointer;
            transition: background-color 0.2s ease;
        }

        .shop-card-quickview-btn:hover {
            background: var(--shop-clay);
        }

        .shop-card-body {
            padding: 15px 16px 16px 16px;
            display: flex;
            flex-direction: column;
            flex: 1;
        }

        .shop-card-header-row {
            display: flex;
            flex-wrap: wrap;
            align-items: center;
            margin-bottom: 6px;
            gap: 4px 8px;
        }

        .shop-card-category {
            max-width: 100%;
            font-size: 0.68rem;
            font-weight: 600;
            color: var(--shop-ink-faint);
            text-transform: uppercase;
            letter-spacing: 0.07em;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        .shop-card-skill {
            flex-shrink: 0;
            font-family: var(--font-data);
            font-size: 0.66rem;
            font-weight: 600;
            padding: 0;
            border: none;
            background: none;
            color: var(--shop-sage);
            text-transform: uppercase;
            letter-spacing: 0.04em;
            white-space: nowrap;
        }

        .shop-card-skill::before {
            content: "";
            display: inline-block;
            width: 5px;
            height: 5px;
            margin-right: 5px;
            border-radius: 50%;
            background: var(--shop-sage);
            vertical-align: middle;
        }

        .shop-card-title {
            font-family: var(--font-heading);
            font-size: 1.05rem;
            font-weight: 600;
            color: var(--shop-ink);
            margin: 0 0 14px 0;
            line-height: 1.28;
            display: -webkit-box;
            -webkit-line-clamp: 2;
            -webkit-box-orient: vertical;
            overflow: hidden;
        }

        /* !important: chic-responsive.css stacks this column below 600px
           (price above the cart button) — this stays a row, price and the
           cart button side by side, at every width. */
        .shop-card-footer {
            margin-top: auto;
            padding-top: 12px;
            border-top: 1px solid var(--shop-line);
            display: flex !important;
            flex-direction: row !important;
            align-items: center !important;
            justify-content: space-between;
        }

        .shop-card-price {
            font-family: var(--font-data);
            font-size: 1.05rem;
            font-weight: 500;
            color: var(--shop-ink) !important;
            line-height: 1;
        }

        .shop-card-cart-btn {
            background: transparent;
            color: var(--shop-ink-soft);
            border: 1px solid var(--shop-line);
            border-radius: 0;
            padding: 6px 9px;
            cursor: pointer;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            gap: 4px;
            transition: all 0.2s ease;
            flex-shrink: 0;
            outline: none;
        }

        .shop-card-cart-btn:hover {
            color: #FFFFFF;
            background: var(--shop-black);
            border-color: var(--shop-black);
        }

        .shop-card-cart-btn:active {
            transform: scale(0.94);
        }

        /* Modal Quick View */
        .modal-overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(44, 26, 17, 0.6);
            backdrop-filter: blur(8px);
            z-index: 2000;
            display: flex;
            align-items: center;
            justify-content: center;
            opacity: 0;
            pointer-events: none;
            transition: opacity 0.3s ease;
            padding: 20px;
        }

        .modal-overlay.active {
            opacity: 1;
            pointer-events: auto;
        }

        .modal-card {
            background: #FFFFFF;
            border-radius: var(--border-radius-lg);
            max-width: 850px;
            width: 100%;
            max-height: 90vh;
            overflow-y: auto;
            box-shadow: 0 25px 60px rgba(44, 26, 17, 0.3);
            position: relative;
            transform: scale(0.95);
            transition: transform 0.3s ease;
        }

        .modal-overlay.active .modal-card {
            transform: scale(1);
        }

        #cart-drawer-overlay.active #cart-drawer-card {
            transform: translateX(0) !important;
        }

        .modal-close {
            position: absolute;
            top: 16px;
            right: 20px;
            font-size: 2rem;
            background: none;
            border: none;
            color: var(--color-text-secondary);
            cursor: pointer;
            z-index: 10;
            line-height: 1;
        }

        /* ============================================================
           QUICK VIEW
           ------------------------------------------------------------
           Built from the product page's own components. pattern-page.css
           is linked in <head>, so the gallery and its thumbnail rail
           (.pp-gallery), the eyebrow, price row, meta rows and buttons
           (.pp-eyebrow, .pp-pricerow, .pp-meta, .pp-btn), the drawers
           (.pp-drawer) and the file cards (.pp-file) all come from there
           and look exactly as they do on a pattern page. Only the shell
           - where things sit inside a modal - is set here.
           ============================================================ */
        #quickview-modal {
            padding: 16px;
            visibility: hidden;
            transition: opacity 0.3s ease, visibility 0s linear 0.3s;
        }
        #quickview-modal.active {
            visibility: visible;
            transition: opacity 0.3s ease, visibility 0s;
        }

        .shop-qv {
            position: relative;
            display: flex;
            flex-direction: column;
            width: 100%;
            max-width: 1040px;
            max-height: min(900px, calc(100vh - 32px));
            background: var(--pp-paper);
            color: var(--pp-ink-soft);
            border: 1px solid var(--pp-line);
            border-radius: var(--pp-r-l);
            box-shadow: 0 30px 80px -30px rgba(26, 23, 20, 0.55);
            overflow: hidden;
            outline: none;
            transform: translateY(12px);
            transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.3, 1);
        }
        #quickview-modal.active .shop-qv { transform: none; }
        .shop-qv [hidden] { display: none !important; }

        .shop-qv-scroll {
            flex: 1 1 auto;
            min-height: 0;
            overflow-y: auto;
            overscroll-behavior: contain;
            -webkit-overflow-scrolling: touch;
        }

        .shop-qv-close {
            position: absolute;
            top: 12px;
            right: 12px;
            z-index: 40;
            width: 44px;
            height: 44px;
            padding: 0;
            display: grid;
            place-items: center;
            cursor: pointer;
            border-radius: 50%;
            color: var(--pp-ink);
            background: rgba(255, 255, 255, 0.94);
            border: 1px solid var(--pp-line-strong);
            box-shadow: 0 4px 14px rgba(26, 23, 20, 0.14);
            transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease;
        }
        .shop-qv-close:hover,
        .shop-qv-close:focus-visible {
            background: var(--pp-black);
            color: #FFFFFF;
            border-color: var(--pp-black);
        }

        .shop-qv-grid {
            display: grid;
            grid-template-columns: minmax(0, 1fr);
            gap: 22px;
            padding: 22px 18px 26px;
        }
        .shop-qv-media,
        .shop-qv-info { min-width: 0; }

        /* the eyebrow's hairline runs to the edge, which is where the close
           button sits on desktop */
        .shop-qv-info .pp-eyebrow { padding-right: 52px; }

        .shop-qv-title {
            margin: 10px 0 0;
            font-family: var(--pp-font-display);
            font-weight: 600;
            font-size: 1.5rem;
            line-height: 1.18;
            letter-spacing: -0.012em;
            color: var(--pp-ink);
            text-wrap: balance;
        }

        /* the page sets these two roles on a .pp-page ancestor, which a modal
           is not; the site-wide type rules would otherwise win on dt / td / th */
        .shop-qv .pp-metalabel,
        .shop-qv .pp-metaval.is-data,
        .shop-qv .pp-file-meta,
        .shop-qv .pp-drawer-title,
        .shop-qv .pp-table thead th,
        .shop-qv .pp-table tbody td,
        .shop-qv .pp-size-cell {
            font-family: var(--pp-font-data);
        }

        /* photo: same tone the page letterboxes on, so a slow image is a calm
           paper-coloured box rather than a white flash */
        .shop-qv .pp-gallery-main { background: var(--pp-paper-alt); }
        .shop-qv .pp-gallery-main .pp-mainimg { cursor: default; }
        .shop-qv .pp-gcount:empty { display: none; }

        /* below the page's two-column breakpoint the modal is one column, and
           the page's own tablet rule (a 16:11 landscape crop) would cut the
           garment off, so the frame stays portrait, sized by height */
        @media (max-width: 1023px) {
            .shop-qv .pp-gallery-main {
                width: min(100%, calc(52vh * 0.75));
                margin-inline: auto;
            }
            .shop-qv .pp-gallery-main .pp-mainimg {
                aspect-ratio: 3 / 4;
                height: auto;
                max-height: none;
                object-position: center 22%;
            }
            .shop-qv .pp-gallery-main .pp-mainimg.is-wide { object-position: center center; }
            .shop-qv .pp-rail { justify-content: center; }
        }

        @media (min-width: 768px) and (max-width: 1023px) {
            .shop-qv { max-width: 680px; }
            .shop-qv-grid { padding: 30px 30px 34px; gap: 26px; }
            .shop-qv-title { font-size: 1.7rem; }
        }

        @media (min-width: 1024px) {
            .shop-qv-grid {
                grid-template-columns: minmax(0, 49fr) minmax(0, 51fr);
                gap: 40px;
                padding: 40px 40px 36px;
                align-items: start;
            }
            /* the photo stays put while a long info column scrolls past it */
            .shop-qv-media { position: sticky; top: 20px; }
            .shop-qv-title { font-size: 1.75rem; }
        }

        /* phones: a sheet rising from the bottom edge */
        @media (max-width: 767px) {
            #quickview-modal { padding: 0; align-items: flex-end; }
            .shop-qv {
                max-width: none;
                max-height: 94vh;
                border-radius: var(--pp-r-l) var(--pp-r-l) 0 0;
                border-bottom: 0;
                transform: translateY(48px);
            }
            .shop-qv-grid { padding-bottom: calc(26px + env(safe-area-inset-bottom)); }
        }

        .shop-qv-links {
            display: flex;
            flex-wrap: wrap;
            align-items: center;
            justify-content: space-between;
            gap: 2px 20px;
            margin-top: 10px;
        }
        .shop-qv-link {
            display: inline-flex;
            align-items: center;
            gap: 8px;
            min-height: 44px;
            padding: 0;
            background: none;
            border: 0;
            cursor: pointer;
            font-family: var(--pp-font-body);
            font-weight: 600;
            font-size: 0.92rem;
            color: var(--pp-ink);
            text-decoration: none;
            transition: color 0.18s ease;
        }
        .shop-qv-link:hover,
        .shop-qv-link:focus { color: var(--pp-clay-deep); }
        .shop-qv-link-arrow::after { content: "\2192"; font-size: 1.05em; line-height: 1; }
        .shop-qv-link svg { flex: none; fill: none; stroke: currentColor; }
        /* the same red the heart on a card turns */
        #modal-add-planner-btn.is-saved { color: #E0263F; }
        #modal-add-planner-btn.is-saved svg { fill: currentColor; }

        .shop-qv-drawers { margin-top: 12px; border-top: 1px solid var(--pp-line-strong); }
        .shop-qv .pp-drawer { border-top: 0; border-bottom: 1px solid var(--pp-line-strong); }
        .shop-qv .pp-drawer-head { padding: 15px 2px; min-height: 52px; }
        .shop-qv .pp-drawer-body { padding: 2px 0 var(--pp-s4); }
        .shop-qv .pp-drawer-body p { max-width: none; }
        .shop-qv .pp-delivery { margin-top: 16px; }

        .shop-qv a:focus-visible,
        .shop-qv button:focus-visible,
        .shop-qv summary:focus-visible {
            outline: 2px solid var(--pp-clay);
            outline-offset: 3px;
            border-radius: 4px;
        }

        /* the fixed chat bubble, back-to-top and bottom nav all sit at a
           z-index the modal cannot beat, so they are put away while it is open */
        body.shop-qv-open #crisp-chatbox,
        body.shop-qv-open #back-to-top-btn,
        body.shop-qv-open .bottom-nav { display: none !important; }

        @media (prefers-reduced-motion: reduce) {
            .shop-qv,
            #quickview-modal { transition: none; }
        }

        /* Load More Button */
        .load-more-container {
            text-align: center;
            margin-bottom: 80px;
        }

/* Pattern pages: the similar-pattern grid reads exactly like the shop */
.pp-page .pp-relshop{color:rgb(30, 27, 24); line-height:1.6;}
.pp-page .pp-relshop .shop-card-badge,
.pp-page .pp-relshop .shop-card-skill,
.pp-page .pp-relshop .shop-card-price{font-family:'IBM Plex Mono', ui-monospace, monospace;}
.pp-page .pp-relshop .shop-card-title{font-family:var(--font-heading); font-weight:600; margin:0 0 14px 0; line-height:1.28;}
.pp-page .pp-relshop .shop-card-img-wrapper img{display:inline;}
