PageSourceSearch

https://phootime.com/cart

html phootime.com collected 2026-10-03 22:35:23 UTC 235,578 bytes, 4,950 lines download raw bytes

1<!doctype html>
2<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" class="zh_tw ">
3<head>
4<meta content="width=device-width, user-scalable=yes" name="viewport">
5<meta name="theme-color" content="#E4ACCD">
6<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7<meta http-equiv="x-dns-prefetch-control" content="on">
8<meta name="robots" content="noindex, follow" />
9<meta name="google-play-app" content="app-id=com.phootime.android">
10<meta name="description" content="無框畫第一品牌,用頂級藝術微噴把精彩的照片印成油畫布無框畫、木框畫與各式照片禮物,還能把照片變成AI似顏繪,留下每一次難忘的回憶,更是生日、紀念日送禮最暖心的禮物"/>
11<meta property="fb:app_id" content="475464309255043">
12<meta property="og:locale" content="zh_TW"/>
13<meta property="og:locale:alternate" content="en_US"/>
14<meta property="og:site_name" content="Phootime無框畫"/>
15<meta property="og:title" content="畫布無框畫 - 結帳 | Phootime無框畫第一品牌"/>
16<meta property="og:type" content="website"/>
17<meta property="og:description" content="無框畫第一品牌,用頂級藝術微噴把精彩的照片印成油畫布無框畫、木框畫與各式照片禮物,還能把照片變成AI似顏繪,留下每一次難忘的回憶,更是生日、紀念日送禮最暖心的禮物"/>
18
19<script type='application/ld+json'>{"@context":"http:\/\/schema.org","@type":"WebSite","url":"https:\/\/www.phootime.com\/","name":"Phootime無框畫","alternateName": "Phootime藝術微噴","potentialAction":{"@type":"SearchAction","target":"https:\/\/shop.phootime.com\/search?q={search_term_string}","query-input":"required name=search_term_string"}}</script>
vendor: 1 bytes, line 19
19
20<script type='application/ld+json'>{"@context":"http:\/\/schema.org","@type":"Organization","url":"https:\/\/www.phootime.com","sameAs":["https:\/\/www.facebook.com\/phootime","https:\/\/instagram.com\/phootime","https:\/\/twitter.com\/bestphootime"],"name":"Phootime","logo":"https:\/\/gcdn.phootime.com\/www\/images\/v6\/phootime_logo.svg"}</script>
vendor: 1 bytes, line 20
20
21<script type="application/ld+json">
22{
23    "@context":"http:\/\/schema.org",
24    "@type":"ProfessionalService",
25    "@id":"https:\/\/www.phootime.com\/",
26    "name": "Phootime客製化禮物",
27    "address":{
28        "@type":"PostalAddress",
29        "streetAddress":"台北市信義區和平東路三段225號",
30        "addressLocality":"台北市信義區",
31        "postalCode":"11061",
32        "addressCountry":"TW"
33    },
34    "url": "https:\/\/www.phootime.com\/",
35    "logo": "https:\/\/gcdn.phootime.com\/www\/images\/v6\/phootime_logo.svg",
36    "image": "https:\/\/gcdn.phootime.com\/www\/images\/v6\/phootime_logo.svg",
37    "description": "無框畫第一品牌,用頂級藝術微噴把精彩的婚紗照或生活照印成油畫布無框畫,留下每一份難忘的回憶。照片輸出在亮面或是消光面的油畫布上製作成無框畫,更是生日節日送禮最暖心的禮物",
38    "award": "Red Herring 亞洲創新100強",
39    "email": "[email protected]",
40    "priceRange": "$$",
41    "telephone":  "+886223456698"
42}
43</script>
vendor: 1 bytes, line 43
43
44<script type="application/ld+json">
45[
46{
47  "@context" : "http://schema.org",
48  "@type" : "QAPage",
49  "mainEntity" : {
50    "@type" : "Question",
51    "name" : "什麼是藝術微噴?",
52    "text" : "什麼是藝術微噴?藝術微噴是什麼樣的數位輸出與藝術品複製技術?",
53    "answerCount" : "1",
54    "author" : "Phootime",
55    "dateCreated" : "2018-06-11",
56    "acceptedAnswer" : {
57      "@type" : "Answer",
58      "text" : "藝術微噴是一種數位輸出技術,可稱為數位版畫或 Giclée,是由日本 EPSON 公司研發而成的一種藝術品複製工法,可於各式不同質料的畫布或畫紙上印製博物館典藏等級的高解析度數位圖像。藝術微噴數位輸出技術能呈現出高飽和度的顏色,且保留極細緻的色彩變化,細膩地顯示出色彩的濃淡、融合和各種細節,充分展現出原作的精髓,尤其是在藝術品製作方面,完全取代了傳統印製模式。藝術微噴現已成為藝術家、畫廊和出版商較歡迎和推崇的藝術品複製模式。全球各大美術館博物館大部分複製品均採用藝術微噴數位複製技術製作,國內比較為人所知的常玉藝術微噴複製畫、齊柏林紀念攝影展、日本知名攝影師杉本博司攝影展、斯洛伐克的新銳攝影師瑪麗亞斯拉波娃 Maria Svarbova 來台亞洲首展等都是使用藝術微噴方式印製展覽作品。藝術微噴有別一般大量 4 色或 6 色的印刷,使用至少 9 色以上抗褪色顏料及 44吋以上大尺寸高解析噴墨印表機製作出幾可亂真的分身藝術作品,並且具有專業的色彩管理能力。",
59      "upvoteCount" : "9999",
60      "author" : "Phootime",
61        "dateCreated" : "2018-06-11",
62      "url" : "https://www.phootime.com/epson"
63    }
64  }
65}
66]
67</script>
67
68
69<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-v2.png">
70<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
71<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
72<link rel="manifest" href="/manifest.json">
73<meta name="apple-mobile-web-app-title" content="Phootime">
74<meta name="application-name" content="Phootime">
75<script>
76if ('serviceWorker' in navigator) {
77    window.addEventListener('load', function () {
78        navigator.serviceWorker.register('/sw.js');
79    });
80}
81/* iOS PWA 從背景喚醒不會重載頁面,badge 要在回前景時也清 */
82(function () {
83    function ptClearBadge() {
84        if ('clearAppBadge' in navigator) navigator.clearAppBadge().catch(function () {});
85    }
86    ptClearBadge();
87    document.addEventListener('visibilitychange', function () { if (!document.hidden) ptClearBadge(); });
88    window.addEventListener('pageshow', ptClearBadge);
89})();
90</script>
90
91<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
92<meta name="theme-color" content="#ffffff">
93<title>畫布無框畫 - 結帳 | Phootime無框畫第一品牌</title>
94<meta property="og:image" content="https://gcdn.phootime.com/static/images/shop/fb_canvas_logo_tw.png"/>
95<!-- preconnect: gcdn1 是 min server,供應 jQuery / jQuery UI / Bootstrap / 所有 bundle,是最關鍵的 host;字型走 Google。 -->
96<link rel="preconnect" href="https://gcdn1.phootime.com" crossorigin>
97<link rel="preconnect" href="https://fonts.googleapis.com">
98<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
99<script src="https://gcdn1.phootime.com/min/f=js/jquery-3.6.1.min.js?v=1788505984" crossorigin="anonymous"></script>
99
100<link href='//fonts.googleapis.com/css?family=Noto+Serif|Josefin+Sans:300|Roboto:400,100,300,500|Raleway:400,500,700&display=swap' rel='stylesheet' type='text/css'>
101
102
103
104<link type="text/css" rel="stylesheet" crossorigin="anonymous" href="https://gcdn1.phootime.com/min/g=shop-checkout-noma-css?v=1788505984" />
105<script crossorigin="anonymous" src="https://gcdn1.phootime.com/min/g=shop-checkout-js?v=1788505984"></script>
vendor: 1 bytes, line 105
105
106<script type="text/javascript">
107//document.domain = 'phootime.com';
108var enable_sticky = true; // ($('body#upload').length == 0);
109
110function toggle_submenu(css_class) {
111  if ($('.header_mainmenu li.'+css_class).hasClass('open'))
112    $('.header_mainmenu li.'+css_class).removeClass('open');
113  else
114    $('.header_mainmenu li.'+css_class).addClass('open');
115}
116
117function click_buy() {
118    if (window.innerWidth < 1024) {
119        toggle_submenu('buy');
120    } else {
121        window.location.href = 'https://shop.phootime.com';
122    }
123}
124
125var cookie_key = '20250218';
126function popup_banner() {
127
128    if (typeof Cookies == 'undefined')
129        return;
130
131    if (Swal.isVisible()) {
132        setTimeout(popup_banner, 1000 * 30);
133        return;
134    }
135
136    Cookies.set(cookie_key, 'yes', { expires: 10 });
137    Swal.fire({
138        title: '',
139        imageUrl: 'https://gcdn3.phootime.com/static/images/shop/banner_20250218.jpg',
140        imageWidth: 600,
141        customClass: {
142            container: 'tiny',
143        },
144        showClass: {
145            popup: 'no_padding animate__animated animate__fadeInDown animate__fast'
146        },
147        hideClass: {
148            popup: 'no_padding animate__animated animate__fadeOutUp animate__fast'
149        },
150        reverseButtons: false,
151        showCancelButton: false,
152        confirmButtonText:  '我知道了',
153        }).then(function(result) {
154            if (result.isConfirmed) {
155            }
156        });
157}
158$( document ).ready(function() {
159
160    $('.search').click(function(event) {
161        if ($(this).hasClass('click')) {
162            // $(this).removeClass('click');
163            // $(this).addClass('clear');
164        } else {
165            $(this).removeClass('clear');
166            $(this).addClass('click');
167            $(this).find('.searchbar').focus();
168        }
169    });
170
171    if (window.innerWidth < 1024) {
172        $('.search_click').click(function() {
173            if ($('.searchbar').val().length > 0)
174                window.location.href = 'https://shop.phootime.com/search?q=' + encodeURIComponent($('.searchbar').val());
175        });
176    }
177
178    $('#drawer-btn').click(function() {
179        $('#new_header').addClass('act');
180        $('html').addClass('no-scroll');
181        // document.ontouchmove = function(e){ e.preventDefault(); }
182    });
183
184    $('#close-wrap, .PageOverlay').click(function(event) {
185        event.preventDefault();
186        $('#new_header').removeClass('act');
187        $('html').removeClass('no-scroll');
188        // document.ontouchmove = function(e){ return true; }
189        return false;
190    });
191
192    var header = $('header');
193    var container = $('#container');
194    var full_width_slider = $('#full-width-slider');
195    // embed=1 時 header 被隱藏,沒有 offset 可讀,略過 sticky 邏輯
196    var sticky = header.length ? header.offset().top : 0;
197    // if (enable_sticky) {
198    //     $('#shipping').addClass('sticky');
199    // }
200
201    $(window).scroll(function(event) {
202
203        enable_sticky_header();
204
205    });
206    if (header.length) enable_sticky_header();
207
208    
209    $('.header_submenu_CAT_item > li').hover(function() {
210        $(this).addClass("select").siblings().removeClass("select");
211    }, function() {
212        $(this).siblings().removeClass("select");
213    });
214
215
216function enable_sticky_header() {
217    if (!header || header.length === 0) return; // embed 模式沒有 header
218    if (enable_sticky) {
219        var bar_offset = 7;
220        // if (window.innerWidth >= 1024) {
221        //     bar_offset = 37;
222        // }
223        if (window.pageYOffset > sticky - bar_offset) {
224          header.addClass("sticky");
225          container.addClass('sticky');
226          if (full_width_slider)
227            full_width_slider.addClass('sticky');
228        } else {
229          header.removeClass("sticky");
230          container.removeClass('sticky');
231          if (full_width_slider)
232            full_width_slider.removeClass('sticky');
233        }
234    }
235}
236
237    if (typeof Cookies !== 'undefined') {
238        var visited = Cookies.get(cookie_key);
239        if (visited != 'yes') {
240            // setTimeout(popup_banner, 1000 * 3);
241        }
242    }
243
244});
245
246
247function setLog(log) {
248    
249}
250
251function clickCart(url) {
252    setLog('click to cart');
253    window.location.href = url;
254}
255</script>
255
256<!-- OpenAI Ads Pixel -->
257<script>!function(w,d,s,u){if(w.oaiq)return;var q=function(){q.q.push(arguments)};q.q=[];w.oaiq=q;var j=d.createElement(s);j.async=1;j.src=u;var f=d.getElementsByTagName(s)[0];f.parentNode.insertBefore(j,f)}(window,document,"script","https://bzrcdn.openai.com/sdk/oaiq.min.js");oaiq("init",{pixelId:"RGZQ5uFo7hbie3rQTtvBxz",debug:true});</script>
vendor: 1 bytes, line 257
257
258<script>
259  // OpenAI 轉換事件 helper:amount 要用 ISO 4217 最小單位整數(TWD/USD… ×100,JPY/KRW 沒有小數位);
260  // eventId 只給 checkout_started / order_created(= 訂單 id,重整不重複計)。oaiq 不存在時靜默。
261  window.pt_oai = function (name, value, currency, contents, eventId) {
262    try {
263      if (typeof oaiq !== 'function' || !name) return;
264      var d = { type: 'contents' };
265      var n = parseFloat(String(value == null ? '' : value).replace(/[^0-9.]/g, ''));
266      if (currency && isFinite(n) && n > 0) {
267        d.amount = Math.round(n * (/^(JPY|KRW)$/i.test(currency) ? 1 : 100));
268        d.currency = String(currency).toUpperCase();
269      }
270      if (contents && contents.length) d.contents = contents;
271      if (eventId) oaiq('measure', name, d, { event_id: String(eventId) });
272      else oaiq('measure', name, d);
273    } catch (e) {}
274  };
275</script>
275
276<!-- Global site tag (gtag.js) - Google Analytics -->
vendor: 64 bytes, lines 276-277
276
277<script async src="https://www.googletagmanager.com/gtag/js?id=
277G-JB21QF5RV5
vendor: 12 bytes, line 277
277"></script>
278<script>
279  
vendor: 134 bytes, lines 279-283
279window.dataLayer = window.dataLayer || [];
280  function gtag(){dataLayer.push(arguments);}
281  gtag('js', new Date());
282
283  gtag('config', '
283G-JB21QF5RV5
vendor: 8 bytes, lines 283-284
283');
284    
284// Global site tag (gtag.js) - Google Ads: 855948583
285  gtag('config','AW-11096059240', {'allow_enhanced_conversions':true});
286  gtag('config', 'AW-10928790878', {'allow_enhanced_conversions':true});
287</script>
287
288<!-- Google 再营销代码 -->
289<script type="text/javascript">
290/* <![CDATA[ */
291var google_conversion_id = 855948583;
292var google_custom_params = window.google_tag_params;
293var google_remarketing_only = true;
294/* ]]> */
295</script>
295
296<div style="display:none">
296<script type="text/javascript" src="//www.googleadservices.com/pagead/conversion.js">
297</script>
297
298<noscript>
299<div style="display:inline;">
300<img height="1" width="1" style="border-style:none;" alt="" src="//googleads.g.doubleclick.net/pagead/viewthroughconversion/855948583/?guid=ON&amp;script=0"/>
301</div>
302</noscript></div>
303<!-- Facebook Pixel Code -->
304<script>
vendor: 417 bytes, lines 304-313
304
305  !function(f,b,e,v,n,t,s)
306  {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
307  n.callMethod.apply(n,arguments):n.queue.push(arguments)};
308  if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
309  n.queue=[];t=b.createElement(e);t.async=!0;
310  t.src=v;s=b.getElementsByTagName(e)[0];
311  s.parentNode.insertBefore(t,s)}(window, document,'script',
312  'https://connect.facebook.net/en_US/fbevents.js');
313  fbq('init', '
313342691330851806
vendor: 6 bytes, lines 313-314
313');
314  
314fbq('init', '764962923516514');
315</script>
315
316<noscript><img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=342691330851806&ev=PageView&noscript=1" /><img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=764962923516514&ev=PageView&noscript=1" /></noscript>
317<!-- End Facebook Pixel Code -->
317<script>
318  gtag('event','view_item', {
319    'items': [
320      {
321        'id': 'pt-canvas',
322        'google_business_vertical': 'retail'
323      }]
324  });
325  // GA4 微漏斗事件 helper(/create 上傳/選項/提示/彈窗…):gtag 不存在時靜默;params 只放小型 scalar。
326  // 事件名對照:upload_start / upload_done / upload_error / product_select / size_select / low_res_warning_shown /
327  // ai_upsell_shown / ai_upsell_accepted / draft_saved / popup_shown / popup_closed / custom_size_suggested / paper_border_select
328  window.pt_track = function (name, params) {
329    try {
330      if (typeof gtag !== 'function' || !name) return;
331      var p = { page_path: location.pathname };
332      if (params) { for (var k in params) { if (params.hasOwnProperty(k) && params[k] !== undefined && params[k] !== null) p[k] = params[k]; } }
333      gtag('event', name, p);
334    } catch (e) {}
335  };
336</script>
336
337<!-- Facebook Pixel Code -->
338<script>
339fbq('track', "PageView", {}, {eventID: '6ac1832a4feeb'});
340</script>
340
341<!-- End Facebook Pixel Code -->
342<!-- LINE Tag Base Code -->
343<!-- Do Not Modify -->
344<script>
345(function(g,d,o){
346  g._ltq=g._ltq||[];g._lt=g._lt||function(){g._ltq.push(arguments)};
347  var h=location.protocol==='https:'?'https://d.line-scdn.net':'http://d.line-cdn.net';
348  var s=d.createElement('script');s.async=1;
349  s.src=o||h+'/n/line_tag/public/release/v1/lt.js';
350  var t=d.getElementsByTagName('script')[0];t.parentNode.insertBefore(s,t);
351    })(window, document);
352_lt('init', {
353  customerType: 'lap',
354  tagId: '04dcc8bf-15ed-4375-addd-900f5d9d5e21'
355});
356_lt('send', 'pv', ['04dcc8bf-15ed-4375-addd-900f5d9d5e21']);
357</script>
357
358<noscript>
359  <img height="1" width="1" style="display:none"
360       src="https://tr.line.me/tag.gif?c_t=lap&t_id=04dcc8bf-15ed-4375-addd-900f5d9d5e21&e=pv&noscript=1" />
361</noscript>
362<!-- End LINE Tag Base Code -->
363</head>
364<body id="checkout">
365<script type="text/javascript">
366$(document).keydown(function(e){
367    if ($('#canvas_text').is(":focus")) {
368        return;
369    }
370        });
371</script>
371
372<style type="text/css">
373.is_new::after {
374    content: "";
375    position: absolute;
376    margin-top: -3px;
377    margin-left: -3px;
378    line-height: 0px;
379    width: 6px;
380    height: 6px;
381    border-radius: 50%;
382    background-color: rgb(250, 50, 18);
383}
384button.swiper-button-next, button.swiper-button-prev {
385    display: none;
386}
387#full-width-slider.sticky {
388    margin-top: 77px;
389}
390
391@media (min-width: 1024px) {
392    .header_mainmenu li ul li._swiper-slide_ {
393        padding-right: 0;
394        padding-left: 0;
395    }
396    button.swiper-button-next, button.swiper-button-prev {
397        display: flex;
398        color: #999;
399        border: 0;
400        background: transparent;
401    }
402    button.swiper-button-next {
403        right: calc( (100% - 860px) / 2 );
404    }
405    button.swiper-button-prev {
406        left: calc( (100% - 860px) / 2 );
407    }
408    button.swiper-button-disabled {
409        display: none;
410    }
411
412    #container.sticky, #full-width-slider.sticky {
413        margin-top: 80px;
414    }
415}
416
417header.sticky {
418    position: fixed;
419    top: 0;
420    width: 100%;
421    margin-top: 6px;
422    box-shadow: 0px 1px 5px #cecece;
423}
424
425#shipping .topbar {
426    background-color: #FF708B;
427    z-index: 9998;
428}
429
430#shipping.sticky {
431    position: fixed;
432}
433
434.header_mainmenu li ul {
435    background: #fbf2f9;
436}
437
438#shipping a {
439    border-radius: 10px;
440    background-color: #fff4f3;
441    padding: 0px 5px;
442}
443  .tab li, .btn-picframes, .btn-collage-toolbar, #collage_upload, .collage.view_in_room, .collage.back_view_in_room, .back.back_to_upload, .back.back_to_collage, .re-upload, .center_image, .fill_image, .reupload_btn .view_in_room, .reupload_btn .back_view_in_room, .btn-collage {
444    color: #353535;
445  }
446  .noUi-connect,.noUi-horizontal .noUi-handle, .noUi-vertical .noUi-handle {
447    background-color: #353535;
448  }
449
450  .tab li.select {
451    color: #ff7372;
452  }
453
454  .mobile-menu .price_info, #mobile-shopping-checkout .price_info .price.sale .on_sale, #mobile-shopping-checkout .price_info .currency, #mobile-shopping-checkout .price_info .number,
455  .price_info .currency, .price_info .number,
456  .total .unit_price sub, .total .unit_price .number, .total .owner {
457    color: #f85153;
458  }
459
460  .total .owner {
461    /* background-color: #f26591; */
462    color: #fff;
463    width: 40px;
464    padding-left: 4px;
465    padding-right: 4px;
466    font-size: 14px;
467    padding: 0;
468    margin: 0;
469    padding-top: 2px;
470    padding-bottom: 2px;
471    height: 18px;
472  }
473
474  .shape li.select, .value .all-value li.select, .shape li.show, .size .all-size li.select, .shape li.select:hover, .size .all-size li.select:hover, #Bt li.select, .AddToCart.select, .edge .canvas_layouts li.type_glossy.select, .edge .canvas_layouts li.type_matte.select, .edge .canvas_layouts li.type_glossy.select:hover, .edge .canvas_layouts li.type_matte.select:hover {
475    background-color: rgb(255, 135, 135);
476    border: 1px solid; /* do not assign color to fix inner space */
477  }
478
479  .total span.discount_label, .discount_label, .discount_label2 {
480    background: linear-gradient(to bottom, #D4AF37 0%, #C5A028 100%);
481    border-radius: 4px;
482    color: #fff;
483    font-weight: bold;
484  }
485
486  .products li, .products li:nth-child(4n) {
487    margin-right: 25px;
488  }
489</style>
490<div id="wrap">
491        <div id="shipping">
492        <div class="topbar v-center">台灣本島滿 $1500 免運        </div>
493        <div class="topbar v-center">台灣本島滿 $1500 免運</div>
494    </div>
495    <header>
496        <a href="https://www.phootime.com"><div class="header_logo"></div></a>
497        <nav id="new_header">
498            <div id="drawer-btn">
499                <div id="drawer-wrap">
500                    <div class="hambarg"></div>
501                    <div class="hambarg"></div>
502                    <div class="hambarg"></div>
503                </div>
504                <div id="close-wrap">
505                    <div class="hambarg"></div>
506                    <div class="hambarg"></div>
507                </div>
508            </div>
509            <div class="checkout mobile">
510                <a href="https://phootime.com/cart">購物車<span class="cart_count" style="display:none"></span></a>
511            </div>
512                        <div class="member_wrap mobile">
513                                    <a href="/member/login?next=%2Fcart" rel="nofollow" title="會員登入">
514                        <span class="mh-icon-guest" aria-hidden="true">
515                            <svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="10" r="3.2"/><path d="M6.5 19.2c1.2-2.5 3.2-3.8 5.5-3.8s4.3 1.3 5.5 3.8"/></svg>
516                        </span>
517                    </a>
518                            </div>
519                                    <div class="header_upload">
520                <a href="https://shop.phootime.com/create" original-title="客製">
521                    <span class="web">客製</span><span class="mobile">客製</span>
522                </a>
523            </div>
524                        <div class="header_mainmenu">
525                <ul class="item" itemscope itemtype="http://www.schema.org/SiteNavigationElement">
526                    <li class="upload" itemprop="name">
527                      <a class="is_new" href="https://shop.phootime.com/create" title="客製" itemprop="url">客製</a>
528                    </li>
529                    <li class="intro pv-host">
530                        <a href="javascript:;" onclick="toggle_submenu('intro')">產品介紹</a>
531                        <!-- ===== 產品介紹 影像化 mega-menu(桌機 hover 顯示;手機隱藏,沿用下方 header_submenu_CAT) ===== -->
532                        <div class="pv-mega" role="menu" aria-label="產品介紹">
533                          <div class="pv-mega-inner">
534                            <div class="pv-cols">
535
536                              <div class="pv-col">
537                                <div class="pv-col-head">無框系列</div>
538                                <a class="pv-card" href="https://www.phootime.com/canvas">
539                                  <img class="pv-thumb" src="https://gcdn.phootime.com/static/www/images/canvas_bg_01_3_s.jpg" alt="無框畫" loading="lazy">
540                                  <span class="pv-txt"><span class="pv-name">無框畫</span></span>
541                                </a>
542                                <a class="pv-card" href="https://www.phootime.com/canvasair">
543                                  <img class="pv-thumb" src="https://gcdn.phootime.com/static/www/images/gatorfoam_bg_01_s.jpg" alt="磁吸霧柔無框畫" loading="lazy">
544                                  <span class="pv-txt"><span class="pv-name">磁吸霧柔無框畫</span></span>
545                                </a>
546                                <a class="pv-card" href="https://www.phootime.com/silkcanvas">
547                                  <img class="pv-thumb" src="https://gcdn.phootime.com/static/www/images/silkcanvas_bg_02_s.jpg" alt="細絹無框畫" loading="lazy">
548                                  <span class="pv-txt"><span class="pv-name">細絹無框畫</span></span>
549                                </a>
550                              </div>
551
552                              <div class="pv-col">
553                                <div class="pv-col-head">有框系列</div>
554                                <a class="pv-card" href="https://www.phootime.com/framed">
555                                  <img class="pv-thumb" src="https://gcdn.phootime.com/works/IMG_1140_logo.jpg" alt="木框畫" loading="lazy">
556                                  <span class="pv-txt"><span class="pv-name">木框畫</span></span>
557                                </a>
558                                <a class="pv-card" href="https://www.phootime.com/metal">
559                                  <img class="pv-thumb" src="https://gcdn.phootime.com/works/IMG_0407_logo.jpg" alt="金屬鋁框畫" loading="lazy">
560                                  <span class="pv-txt"><span class="pv-name">金屬鋁框畫</span></span>
561                                </a>
562                                <a class="pv-card" href="https://www.phootime.com/frameneo">
563                                  <img class="pv-thumb" src="https://gcdn.phootime.com/static/images/shop/color_acrylic_tile.jpg" alt="霓彩懸浮相框" loading="lazy">
564                                  <span class="pv-txt"><span class="pv-name">霓彩懸浮相框</span><span class="pv-new">NEW</span></span>
565                                </a>
566                                <a class="pv-card" href="https://www.phootime.com/lightbox">
567                                  <img class="pv-thumb" src="https://gcdn.phootime.com/static/www/images/lightbox_bg_01_s.jpg" alt="藝術燈箱" loading="lazy">
568                                  <span class="pv-txt"><span class="pv-name">藝術燈箱</span><span class="pv-soldout">已停售</span></span>
569                                </a>
570                                <a class="pv-card" href="https://www.phootime.com/hinoki">
571                                  <img class="pv-thumb" src="https://gcdn.phootime.com/static/www/images/wood_design_print_bg_07_1_s.jpg" alt="日本檜木相框" loading="lazy">
572                                  <span class="pv-txt"><span class="pv-name">日本檜木相框</span><span class="pv-soldout">已停售</span></span>
573                                </a>
574                              </div>
575
576                              <div class="pv-col">
577                                <div class="pv-col-head">年曆、相紙、卡片</div>
578                                <a class="pv-card" href="https://www.phootime.com/photostrip">
579                                  <img class="pv-thumb" src="https://gcdn.phootime.com/works/IMG_4748_logo.jpg" alt="年曆、海報" loading="lazy">
580                                  <span class="pv-txt"><span class="pv-name">年曆、海報</span></span>
581                                </a>
582                                <a class="pv-card" href="https://www.phootime.com/premiumpaper">
583                                  <img class="pv-thumb" src="https://gcdn.phootime.com/static/www/images/develop_bg_01_s.jpg" alt="頂級相紙" loading="lazy">
584                                  <span class="pv-txt"><span class="pv-name">頂級相紙</span></span>
585                                </a>
586                                <a class="pv-card" href="https://www.phootime.com/squarecard">
587                                  <img class="pv-thumb" src="https://gcdn.phootime.com/static/www/images/square_cards_bg_01_s.jpg" alt="小桌卡、月曆" loading="lazy">
588                                  <span class="pv-txt"><span class="pv-name">小桌卡、月曆</span><span class="pv-soldout">已停售</span></span>
589                                </a>
590                                <a class="pv-card" href="https://www.phootime.com/miniphotostrip">
591                                  <img class="pv-thumb" src="https://gcdn.phootime.com/static/www/images/mini_photostrip_bg_01_s.jpg" alt="四連拍拍卡" loading="lazy">
592                                  <span class="pv-txt"><span class="pv-name">四連拍拍卡</span><span class="pv-soldout">已停售</span></span>
593                                </a>
594                              </div>
595
596                            </div><!-- /.pv-cols -->
597
598                            <a class="pv-featured" href="https://shop.phootime.com/create">
599                              <span class="pv-featured-img" style="background-image:url('https://gcdn.phootime.com/static/www/images/featured.jpg');"></span>
600                              <span class="pv-featured-body">
601                                <span class="pv-featured-label">FEATURED</span>
602                                <span class="pv-featured-title">把回憶<br>裱成一幅作品</span>
603                                <span class="pv-featured-cta">線上製作 &rarr;</span>
604                              </span>
605                            </a>
606
607                          </div><!-- /.pv-mega-inner -->
608                        </div><!-- /.pv-mega -->
609                        <!-- ===== /產品介紹 影像化 mega-menu ===== -->
610                        <ul class="header_submenu_CAT">
611                          <div class="header_submenu_CAT_item">
612                            <li class="frameless select"><a href="javascript:;" onclick="toggle_submenu('frameless')">無框系列</a>
613                              <ul class="header_submenu header_products">
614                                <div>
615                                  <li itemprop="name">
616                                      <a href="https://www.phootime.com/canvas"><i class="icon-canvas-print"></i></a>
617                                      <a href="https://www.phootime.com/canvas" title="畫布無框畫" itemprop="url">畫布無框畫</a>
618                                  </li>
619                                  <li itemprop="name">
620                                      <a href="https://www.phootime.com/canvasair"><i class="icon-gatorfoam"></i></a>
621                                      <a href="https://www.phootime.com/canvasair" title="磁吸霧柔無框畫" itemprop="url">磁吸霧柔無框畫</a>
622                                  </li>
623                                  <li itemprop="name">
624                                      <a href="https://www.phootime.com/silkcanvas"><i class="icon-silkcanvas-print"></i></a>
625                                      <a href="https://www.phootime.com/silkcanvas" title="細絹無框畫" itemprop="url">細絹無框畫</a>
626                                  </li>
627                                </div>
628                              </ul>
629                            </li>
630                            <li class="framed"><a href="javascript:;" onclick="toggle_submenu('framed')">有框系列</a>
631                              <ul class="header_submenu header_products">
632                                <div>
633                                  <li itemprop="name">
634                                      <a href="https://www.phootime.com/framed"><i class="icon_wooden_framed_print"></i></a>
635                                      <a href="https://www.phootime.com/framed" title="木框畫" itemprop="url">木框畫</a>
636                                  </li>
637                                  <li itemprop="name">
638                                      <a href="https://www.phootime.com/metal"><i class="icon-framed-print"></i></a>
639                                      <a href="https://www.phootime.com/metal" title="金屬鋁框畫" itemprop="url">金屬鋁框畫</a>
640                                  </li>
641                                  <li itemprop="name">
642                                      <a href="https://www.phootime.com/frameneo"><i class="icon-acrylic-frame"></i></a>
643                                      <a href="https://www.phootime.com/frameneo" title="霓彩懸浮相框" itemprop="url">霓彩懸浮相框</a>
644                                  </li>
645                                  <li itemprop="name">
646                                      <a href="https://www.phootime.com/lightbox"><i class="icon-lightbox"></i></a>
647                                      <a href="https://www.phootime.com/lightbox" title="藝術燈箱" itemprop="url">藝術燈箱</a>
648                                  </li>
649                                  <li itemprop="name">
650                                      <a href="https://www.phootime.com/hinoki"><i class="icon-wood-design"></i></a>
651                                      <a href="https://www.phootime.com/hinoki" title="日本檜木相框" itemprop="url">日本檜木相框</a>
652                                  </li>
653                                                                  </div>
654                              </ul>
655                            </li>
656                            <li class="calendar"><a href="javascript:;" onclick="toggle_submenu('calendar')">年月曆、海報</a>
657                              <ul class="header_submenu header_products">
658                                <div>
659                                  <li itemprop="name">
660                                    <a href="https://www.phootime.com/photostrip"><i class="icon-photostrip"></i></a>
661                                    <a href="https://www.phootime.com/photostrip" title="年曆、海報" itemprop="url">年曆、海報</a>
662                                  </li>
663                                  <li itemprop="name">
664                                    <a href="https://www.phootime.com/squarecard"><i class="icon-square-cards"></i></a>
665                                    <a href="https://www.phootime.com/squarecard" title="小桌卡、月曆" itemprop="url">小桌卡、月曆</a>
666                                  </li>
667                                </div>
668                              </ul>
669                            </li>
670                            <li class="paper"><a href="javascript:;" onclick="toggle_submenu('paper')">頂級相紙、卡片</a>
671                              <ul class="header_submenu header_products">
672                                <div>
673                                  <li itemprop="name">
674                                    <a href="https://www.phootime.com/premiumpaper"><i class="icon-photo"></i></a>
675                                    <a href="https://www.phootime.com/premiumpaper" title="頂級相紙" itemprop="url">頂級相紙</a>
676                                  </li>
677                                  <li itemprop="name">
678                                    <a href="https://www.phootime.com/squarecard"><i class="icon-square-cards"></i></a>
679                                    <a href="https://www.phootime.com/squarecard" title="小桌卡/月曆" itemprop="url">小桌卡</a>
680                                  </li>
681                                  <li itemprop="name">
682                                    <a href="https://www.phootime.com/miniphotostrip"><i class="icon-mini-photostrip"></i></a>
683                                    <a href="https://www.phootime.com/miniphotostrip" title="四連拍拍卡" itemprop="url">四連拍拍卡</a>
684                                  </li>
685                                </div>
686                              </ul>
687                            </li>
688                          </div>
689                        </ul>
690                                            </li>
691                    <li class="buy pv-host">
692                        <a href="javascript:;" onclick="click_buy()">買設計</a>
693                        <!-- ===== 買設計 影像化 mega-menu ===== -->
694                        <div class="pv-mega" role="menu" aria-label="買設計">
695                          <div class="pv-mega-head">精選設計藝廊</div>
696                          <div class="pv-grid">
697                          <a class="pv-card" href="https://shop.phootime.com/?cat=10">
698                            <span class="pv-thumb" style="background-image:url('https://cdn.phootime.com/1/mnhw5h/omacw4/150/DSC_1555_01-2_5.jpg?1407162604');"></span>
699                            <span class="pv-txt"><span class="pv-name">台灣之美</span></span>
700                          </a>
701                          <a class="pv-card" href="https://shop.phootime.com/?cat=36">
702                            <span class="pv-thumb" style="background-image:url('https://cdn4.phootime.com/1/260bku/znh77q/150/The-Starry-Night.jpg?1674220179');"></span>
703                            <span class="pv-txt"><span class="pv-name">名畫複製畫</span></span>
704                          </a>
705                          <a class="pv-card" href="https://shop.phootime.com/?cat=1">
706                            <span class="pv-thumb" style="background-image:url('https://cdn3.phootime.com/1/m5u6c2/p7vnse/150/Aurora-2_Full-resolution_5304x6630_U_100.jpg?1654754579');"></span>
707                            <span class="pv-txt"><span class="pv-name">風景</span></span>
708                          </a>
709                          <a class="pv-card" href="https://shop.phootime.com/?cat=5">
710                            <span class="pv-thumb" style="background-image:url('https://cdn.phootime.com/1/4chv2w/j4skfq/150/DSC_5101.jpg?1548920661');"></span>
711                            <span class="pv-txt"><span class="pv-name">自然</span></span>
712                          </a>
713                                                    <a class="pv-card" href="https://shop.phootime.com/?cat=32">
714                            <span class="pv-thumb" style="background-image:url('https://cdn.phootime.com/1/260bku/znh77q/320/%E7%8E%8B%E7%BE%B2%E4%B9%8B_%E5%B9%B3%E5%AE%89_%E6%B7%B1%E7%B4%85.png?1782336103');"></span>
715                            <span class="pv-txt"><span class="pv-name">開運祝福</span></span>
716                          </a>
717                          <a class="pv-card" href="https://shop.phootime.com/?cat=29">
718                            <span class="pv-thumb" style="background-image:url('https://cdn.phootime.com/1/e9ci2w/pvy2eq/150/20180318_124844.jpg?1597044424');"></span>
719                            <span class="pv-txt"><span class="pv-name">美術</span></span>
720                          </a>
721                          </div>
722                        </div>
723                        <ul class="header_submenu header_products no_item">
724                          <div>
725                            <li itemprop="name">
726                                <a href="https://shop.phootime.com/">全部</a>
727                            </li>
728                            <li itemprop="name">
729                                <a href="https://shop.phootime.com/?cat=10"><i style="background-image:url(https://cdn.phootime.com/1/mnhw5h/omacw4/150/DSC_1555_01-2_5.jpg?1407162604);"></i></a>
730                                <a href="https://shop.phootime.com/?cat=10">台灣之美</a>
731                            </li>
732                            <li itemprop="name">
733                                <a href="https://shop.phootime.com/?cat=36"><i style="background-image:url(https://cdn4.phootime.com/1/260bku/znh77q/150/The-Starry-Night.jpg?1674220179);"></i></a>
734                                <a href="https://shop.phootime.com/?cat=36">名畫複製畫</a>
735                            </li>
736                            <li itemprop="name">
737                                <a href="https://shop.phootime.com/?cat=1"><i style="background-image:url(https://cdn3.phootime.com/1/m5u6c2/p7vnse/150/Aurora-2_Full-resolution_5304x6630_U_100.jpg?1654754579);"></i></a>
738                                <a href="https://shop.phootime.com/?cat=1">風景</a>
739                            </li>
740                            <li itemprop="name">
741                                <a href="https://shop.phootime.com/?cat=5"><i style="background-image:url(https://cdn.phootime.com/1/4chv2w/j4skfq/150/DSC_5101.jpg?1548920661);"></i></a>
742                                <a href="https://shop.phootime.com/?cat=5">自然</a>
743                            </li>
744                            <li itemprop="name">
745                                                                <a href="https://shop.phootime.com/?cat=32"><i style="background-image:url(https://cdn.phootime.com/1/260bku/znh77q/320/%E7%8E%8B%E7%BE%B2%E4%B9%8B_%E5%B9%B3%E5%AE%89_%E6%B7%B1%E7%B4%85.png?1782336103);"></i></a>
746                                <a href="https://shop.phootime.com/?cat=32">開運祝福</a>
747                            </li>
748                            <li itemprop="name">
749                                <a href="https://shop.phootime.com/?cat=29"><i style="background-image:url(https://cdn.phootime.com/1/e9ci2w/pvy2eq/150/20180318_124844.jpg?1597044424);"></i></a>
750                                <a href="https://shop.phootime.com/?cat=29">美術</a>
751                            </li>
752                          </div>
753                        </ul>
754                    </li>
755                    <li class="gifts pv-host" itemprop="name">
756                        <a href="https://www.phootime.com/gifts" onclick="if(window.innerWidth<1024){toggle_submenu('gifts');return false;}" title="禮物專區" itemprop="url">禮物專區</a>
757                        <!-- ===== 禮物專區 影像化 mega-menu ===== -->
758                        <div class="pv-mega" role="menu" aria-label="禮物專區">
759                          <div class="pv-mega-head">依場合挑禮物</div>
760                          <div class="pv-grid">
761                          <a class="pv-card" href="https://www.phootime.com/graduation">
762                            <span class="pv-thumb" style="background-image:url('https://gcdn.phootime.com/static/images/shop/graduate_1920x490.jpg');"></span>
763                            <span class="pv-txt"><span class="pv-name">畢業禮物</span></span>
764                          </a>
765                          <a class="pv-card" href="https://www.phootime.com/gifts/birthday">
766                            <span class="pv-thumb" style="background-image:url('https://gcdn.phootime.com/static/images/shop/birthday_01_600x380.jpg');"></span>
767                            <span class="pv-txt"><span class="pv-name">生日禮物</span></span>
768                          </a>
769                          <a class="pv-card" href="https://www.phootime.com/gifts/mothersday">
770                            <span class="pv-thumb" style="background-image:url('https://gcdn.phootime.com/static/images/shop/mother_01_600x380.jpg');"></span>
771                            <span class="pv-txt"><span class="pv-name">母親節禮物</span></span>
772                          </a>
773                          <a class="pv-card" href="https://www.phootime.com/gifts/valentinesday">
774                            <span class="pv-thumb" style="background-image:url('https://gcdn.phootime.com/static/images/shop/valentinesday_01_600x380.jpg');"></span>
775                            <span class="pv-txt"><span class="pv-name">情人節禮物</span></span>
776                          </a>
777                          <a class="pv-card" href="https://www.phootime.com/gifts/fathersday">
778                            <span class="pv-thumb" style="background-image:url('https://gcdn.phootime.com/static/images/shop/fathersday_01_600x380.jpg');"></span>
779                            <span class="pv-txt"><span class="pv-name">父親節禮物</span></span>
780                          </a>
781                          <a class="pv-card" href="https://www.phootime.com/gifts/xmas">
782                            <span class="pv-thumb" style="background-image:url('https://gcdn.phootime.com/static/images/shop/xmas_01_600x380.jpg');"></span>
783                            <span class="pv-txt"><span class="pv-name">聖誕禮物</span></span>
784                          </a>
785                          </div>
786                          <a class="pv-allgifts" href="https://www.phootime.com/gifts">看全部送禮 &rarr;</a>
787                        </div>
788                        <ul class="header_submenu header_products no_item">
789                          <div>
790                            <li itemprop="name">
791                                <a href="https://www.phootime.com/graduation"><i style="background-image:url(https://gcdn1.phootime.com/static/images/shop/icon_graduation.jpg);"></i></a>
792                                <a href="https://www.phootime.com/graduation" title="畢業禮物" itemprop="url">畢業禮物</a>
793                            </li>
794                            <li itemprop="name">
795                                <a href="https://www.phootime.com/gifts/birthday"><i class="icon-birthday"></i></a>
796                                <a href="https://www.phootime.com/gifts/birthday" title="生日禮物" itemprop="url">生日禮物</a>
797                            </li>
798                            <li itemprop="name">
799                                <a href="https://www.phootime.com/gifts/mothersday"><i class="icon-mothersday"></i></a>
800                                <a href="https://www.phootime.com/gifts/mothersday" title="母親節禮物" itemprop="url">母親節禮物</a>
801                            </li>
802                            <li itemprop="name">
803                                <a href="https://www.phootime.com/gifts/valentinesday"><i class="icon-valentinesday"></i></a>
804                                <a href="https://www.phootime.com/gifts/valentinesday" title="情人節禮物" itemprop="url">情人節禮物</a>
805                            </li>
806                            <li itemprop="name">
807                                <a href="https://www.phootime.com/gifts/fathersday"><i class="icon-fathersday"></i></a>
808                                <a href="https://www.phootime.com/gifts/fathersday" title="父親節禮物" itemprop="url">父親節禮物</a>
809                            </li>
810                             <li itemprop="name">
811                                <a href="https://www.phootime.com/gifts/xmas"><i class="icon-xmas"></i></a>
812                                <a href="https://www.phootime.com/gifts/xmas" title="聖誕禮物" itemprop="url">聖誕禮物</a>
813                            </li>
814                          </div>
815                        </ul>
816                    </li>
817                                        <li itemprop="name">
818                        <a href="https://www.phootime.com/epson" title="藝術微噴介紹" itemprop="url">藝術微噴介紹</a>
819                    </li>
820                    <li itemprop="name">
821                        <a href="https://www.phootime.com/caricature" title="AI 似顏繪" itemprop="url">AI 似顏繪</a>
822                    </li>
823                                        <li class="checkout desktop">
824                        <a href="https://phootime.com/cart" title="購物車">
825                            <span class="mh-icon-cart" aria-hidden="true">
826                                <svg viewBox="0 0 24 24"><path d="M4.5 8.5h15l-1 12a2 2 0 01-2 1.8H7.5a2 2 0 01-2-1.8l-1-12z"/><path d="M8.5 8.5V6a3.5 3.5 0 017 0v2.5"/></svg>
827                            </span>
828                            <span class="sr-only">購物車</span>
829                            <span class="cart_count" style="display:none"></span>
830                        </a>
831                    </li>
832                                        <style>
833                    /* match .header_mainmenu li.checkout positioning exactly */
834                    .header_mainmenu li.member_wrap { position: relative; vertical-align: middle; margin: -14px 10px 0 25px; line-height: 1; }
835                    .header_mainmenu li.member_wrap > a { display: flex !important; align-items: center; justify-content: center; width: 30px; height: 30px; margin-top: 3px; padding: 0; color: #333; text-decoration: none; line-height: 1; }
836                    /* narrow bridge that only covers the 8px gap directly below icon,
837                       so passing cursor toward 選項 tab doesn't trigger menu by accident */
838                    .header_mainmenu li.member_wrap::after { content: ''; position: absolute; top: 100%; left: 0; right: 0; height: 8px; background: transparent; }
839                    .header_mainmenu li.member_wrap > a { transition: color .2s; }
840                    .header_mainmenu li.member_wrap > a:hover { color: #ed6884; text-decoration: none; }
841                    .header_mainmenu li.member_wrap .mh-icon-guest { display: block; width: 28px; height: 28px; color: #333; transition: color .2s; }
842                    .header_mainmenu li.member_wrap > a:hover .mh-icon-guest { color: #ed6884; }
843                    .header_mainmenu li.member_wrap .mh-icon-guest svg { width: 100%; height: 100%; display: block; stroke: currentColor; fill: none; stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; }
844                    /* visibility-based hide so we can transition-delay show (hover intent) */
845                    .member_menu { display: block; visibility: hidden; opacity: 0; pointer-events: none; position: absolute; top: 100%; right: -80px; min-width: 200px; padding: 6px 0; margin-top: 8px; background: #ffffff; border: 1px solid #ececec; border-radius: 10px; box-shadow: 0 8px 24px rgba(0,0,0,.10); list-style: none; z-index: 9999; font-size: 13px; text-align: left; line-height: 1.4; transition: opacity .12s linear, visibility 0s linear .12s; }
846                    .member_menu::before { content: ''; position: absolute; top: -8px; left: 0; right: 0; height: 8px; background: transparent; }
847                    .header_mainmenu li.member_wrap:hover .member_menu,
848                    .header_mainmenu li.member_wrap:focus-within .member_menu { visibility: visible; opacity: 1; pointer-events: auto; transition: opacity .12s linear .25s, visibility 0s linear .25s; }
849                    /* 注意:selector 一律帶 .header_mainmenu 祖先,蓋過 shop-css / w-css 裡
850                       `.header_mainmenu li ul li a { display:block; font-size:12px }`(0,1,4) */
851                    .header_mainmenu .member_menu li { display: block; margin: 0; padding: 0; line-height: 1.4; font-size: 13px; background: transparent; }
852                    .header_mainmenu .member_menu li a { display: flex; align-items: center; gap: 10px; padding: 9px 18px; color: #333 !important; text-decoration: none !important; line-height: 1.4; white-space: nowrap; font-size: 13px; transition: background-color .15s ease, color .15s ease; }
853                    .header_mainmenu .member_menu li a:hover { background: #fdf2f5 !important; color: #ed6884 !important; }
854                    .header_mainmenu .member_menu .mm-icon { width: 16px; height: 16px; flex-shrink: 0; color: #999; stroke: currentColor; fill: none; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; transition: color .15s ease; }
855                    .header_mainmenu .member_menu li a:hover .mm-icon { color: #ed6884; }
856                    .header_mainmenu .member_menu .mm-sep { height: 1px; background: #ececec; margin: 4px 0; padding: 0; }
857
858                    /* mobile header member icon (sibling of .checkout.mobile) */
859                    .member_wrap.mobile { display: none; position: absolute; top: 0; right: 96px; width: 40px; height: 47px; padding: 8px 5px 15px 5px; box-sizing: border-box; }
860                    .member_wrap.mobile a { display: block; width: 30px; height: 30px; color: #ed6884; text-decoration: none; }
861                    .member_wrap.mobile .mh-icon-guest { display: block; width: 28px; height: 28px; margin: 1px; color: #ed6884; }
862                    .member_wrap.mobile .mh-icon-guest svg { width: 100%; height: 100%; display: block; stroke: currentColor; fill: none; stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; }
863
864                    /* desktop header cart icon: inline svg, follows text color (same pattern as member icon) */
865                    .header_mainmenu li.checkout.desktop > a {
866                        background-image: none !important;
867                        text-indent: 0;
868                        color: #555;
869                        transition: color .2s;
870                        position: relative;
871                    }
872                    .header_mainmenu li.checkout.desktop > a:hover { color: #ed6884; text-decoration: none; }
873                    .header_mainmenu li.checkout.desktop .mh-icon-cart { display: block; width: 28px; height: 28px; margin: 2px 1px 0; color: inherit; }
874                    .header_mainmenu li.checkout.desktop .mh-icon-cart svg { width: 100%; height: 100%; display: block; stroke: currentColor; fill: none; stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; }
875                    .header_mainmenu li.checkout.desktop .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
876                    .header_mainmenu li.checkout.desktop .cart_count { color: #fff; }
877
878                    @media (max-width: 1023px) {
879                        .member_wrap.mobile { display: block; }
880                        .header_mainmenu li.member_wrap.desktop { display: none; }
881                        /* push 客製 button further left so it doesn't overlap member icon */
882                        .header_upload a { margin-right: 150px !important; }
883                    }
884                    @media (min-width: 1024px) {
885                        .member_wrap.mobile { display: none !important; }
886                    }
887                    @media (min-width: 1300px) {
888                        .header_mainmenu li.checkout.desktop { margin: -14px 5px 0 10px; left: 80px; }
889                        .header_mainmenu li.member_wrap.desktop { margin: -14px 0 0 20px; left: 80px; }
890                    }
891                    </style>
892                    <li class="member_wrap desktop" itemprop="name">
893                                                    <a href="/member/login?next=%2Fcart" rel="nofollow" title="會員登入">
894                                <span class="mh-icon-guest" aria-hidden="true">
895                                    <svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="10" r="3.2"/><path d="M6.5 19.2c1.2-2.5 3.2-3.8 5.5-3.8s4.3 1.3 5.5 3.8"/></svg>
896                                </span>
897                            </a>
898                                            </li>
899                                    </ul>
900            </div>
901            <div class="PageOverlay"></div>
902        </nav>
903    </header>
904                                <div id="container" class="">    <div class="loading-overlay"><img src="https://gcdn4.phootime.com/static/images/loading.gif" /></div>
905    
906<script>
907
908window.__twConfig = {
909  corePlugins: { preflight: false },
910  important: true,
911  theme: {
912    extend: {
913      colors: {
914        brand: {
915          50:  '#fff5f5',
916          100: '#ffe6e6',
917          200: '#ffc4c4',
918          300: '#ff9d9c',
919          400: '#ff7372',
920          500: '#ff5957',
921          600: '#e04948',
922          700: '#b73838',
923          DEFAULT: '#ff7372',
924        },
925        accent: { DEFAULT: '#E4ACCD' }
926      },
927      fontFamily: {
928        sans: ['"Noto Sans TC"', '"PingFang TC"', '"Microsoft JhengHei"', 'sans-serif'],
929      }
930    }
931  }
932};
933</script>
vendor: 1 bytes, line 933
933
934<script src="https://cdn.tailwindcss.com/3.4.17"></script>
vendor: 1 bytes, line 934
934
935<script>tailwind.config = window.__twConfig;</script>
935
936<style>
937
938#tw-checkout-root { font-family: "Noto Sans TC","PingFang TC","Microsoft JhengHei",sans-serif; color: #1f2937; line-height: 1.6; letter-spacing: 0.02em; }
939#tw-checkout-root, #tw-checkout-root *, #tw-checkout-root *::before, #tw-checkout-root *::after { box-sizing: border-box !important; }
940#tw-checkout-root ul, #tw-checkout-root ol { list-style: none !important; padding: 0 !important; margin: 0 !important; }
941#tw-checkout-root li { list-style: none !important; }
942
943#tw-checkout-root [style*="display:none"],
944#tw-checkout-root [style*="display: none"] {
945    display: none !important;
946}
947
948#tw-checkout-root h1, #tw-checkout-root h2, #tw-checkout-root h3,
949#tw-checkout-root h4, #tw-checkout-root h5, #tw-checkout-root h6,
950#tw-checkout-root dl, #tw-checkout-root dd {
951    margin-top: 0 !important;
952    margin-bottom: 0;
953}
954
955#tw-checkout-root p {
956    margin-top: 0;
957    margin-bottom: 0;
958}
959
960#tw-checkout-root .tw-help-text {
961    margin-top: 8px !important;
962    font-size: 13px !important;
963    line-height: 1.5 !important;
964    color: #6b7280 !important;
965    margin-left: 0 !important;
966}
967#tw-checkout-root .tw-help-text.tw-help-mute { color: #9ca3af !important; }
968
969#tw-checkout-root section .grid,
970#tw-checkout-root section .grid > div:not(.tw-radio-card):not(.tw-radio-dot),
971#tw-checkout-root section > form,
972#tw-checkout-root section > form > div:not(.tw-radio-card),
973#tw-checkout-root .tw-inv-panel,
974#tw-checkout-root .tw-inv-panel > div,
975#tw-checkout-root #tw-inv-addr-wrap {
976    padding-left: 0 !important;
977    margin-left: 0 !important;
978}
979
980#tw-checkout-root section label:not(.tw-radio-card) {
981    padding-left: 0 !important;
982    margin-left: 0 !important;
983}
984
985#tw-checkout-root section > h3:first-child,
986#tw-checkout-root section > div:first-child > h3,
987#tw-checkout-root .bg-white.rounded-2xl > h3:first-child,
988#tw-checkout-root .bg-white.rounded-2xl > h3 {
989    margin-bottom: 1.5rem !important;
990    padding-bottom: 0;
991}
992
993#tw-checkout-root .sticky-summary > .bg-white.rounded-2xl:not(.flex) > * + * {
994    margin-top: 1rem !important;
995}
996#tw-checkout-root .sticky-summary dl > * + * {
997    margin-top: 0.5rem !important;
998}
999
1000#tw-checkout-root #js-summary-edd .tcat-note,
1001#tw-checkout-root #js-summary-esd .tcat-note {
1002    display: block;
1003    margin-top: 4px;
1004    font-size: 11px;
1005    font-weight: 400;
1006    color: #9ca3af;
1007    line-height: 1.5;
1008}
1009#tw-checkout-root #js-summary-edd .tcat-note a,
1010#tw-checkout-root #js-summary-esd .tcat-note a {
1011    color: #ff7372;
1012    text-decoration: underline;
1013}
1014#tw-checkout-root #js-summary-edd .tcat-note a:hover,
1015#tw-checkout-root #js-summary-esd .tcat-note a:hover {
1016    color: #ff5957;
1017}
1018
1019#tw-checkout-root #js-summary-edd-row,
1020#tw-checkout-root #js-summary-esd-row {
1021    align-items: flex-start !important;
1022}
1023
1024#tw-checkout-root .sticky-summary dl,
1025#tw-checkout-root .sticky-summary dl > div,
1026#tw-checkout-root .sticky-summary dl dt,
1027#tw-checkout-root .sticky-summary dl dd,
1028#tw-checkout-root .sticky-summary dl dd > div,
1029#tw-checkout-root .sticky-summary .tw-discount-amt {
1030    font-size: 0.875rem !important;
1031    font-weight: 500 !important;
1032    line-height: 1.5 !important;
1033}
1034#tw-checkout-root .sticky-summary dl dd,
1035#tw-checkout-root .sticky-summary dl dd > div,
1036#tw-checkout-root .sticky-summary .tw-discount-amt {
1037    
1038    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", "Courier New", monospace !important;
1039    font-variant-numeric: tabular-nums !important;
1040    font-feature-settings: "tnum" !important;
1041    letter-spacing: -0.01em !important;
1042}
1043
1044#tw-checkout-root .sticky-summary dl dt {
1045    font-weight: 400 !important;
1046}
1047#tw-checkout-root img { max-width: 100%; height: auto; display: block; }
1048#tw-checkout-root a { text-decoration: none; }
1049
1050#tw-checkout-root,
1051#tw-checkout-root *,
1052#tw-checkout-root *::before,
1053#tw-checkout-root *::after {
1054    -webkit-tap-highlight-color: rgba(255, 115, 114, .18) !important;
1055}
1056
1057::selection { background-color: rgba(255, 115, 114, .28) !important; color: inherit !important; }
1058::-moz-selection { background-color: rgba(255, 115, 114, .28) !important; color: inherit !important; }
1059*::selection { background-color: rgba(255, 115, 114, .28) !important; color: inherit !important; }
1060*::-moz-selection { background-color: rgba(255, 115, 114, .28) !important; color: inherit !important; }
1061#tw-checkout-root *::selection { background-color: rgba(255, 115, 114, .28) !important; color: inherit !important; }
1062#tw-checkout-root *::-moz-selection { background-color: rgba(255, 115, 114, .28) !important; color: inherit !important; }
1063
1064#tw-checkout-root button,
1065#tw-checkout-root button *,
1066#tw-checkout-root a,
1067#tw-checkout-root a *,
1068#tw-checkout-root .tw-cta-primary,
1069#tw-checkout-root .tw-cta-line,
1070#tw-checkout-root .tw-cta-paypal,
1071#tw-checkout-root .tw-mobile-cta,
1072#tw-checkout-root .tw-mobile-cta-line,
1073#tw-checkout-root .tw-radio-card,
1074#tw-checkout-root .tw-radio-card * {
1075    -webkit-user-select: none !important;
1076    -moz-user-select: none !important;
1077    user-select: none !important;
1078    -webkit-tap-highlight-color: transparent !important;
1079}
1080
1081#tw-checkout-root input[type="text"].tw-field-error.tw-field-error,
1082#tw-checkout-root input[type="email"].tw-field-error.tw-field-error,
1083#tw-checkout-root input[type="tel"].tw-field-error.tw-field-error,
1084#tw-checkout-root input[type="number"].tw-field-error.tw-field-error,
1085#tw-checkout-root input[type="password"].tw-field-error.tw-field-error,
1086#tw-checkout-root input:not([type]).tw-field-error.tw-field-error,
1087#tw-checkout-root textarea.tw-field-error.tw-field-error,
1088#tw-checkout-root select.tw-field-error.tw-field-error,
1089#tw-checkout-root input[type="text"].tw-field-error.tw-field-error:focus,
1090#tw-checkout-root input[type="email"].tw-field-error.tw-field-error:focus,
1091#tw-checkout-root input[type="tel"].tw-field-error.tw-field-error:focus,
1092#tw-checkout-root input[type="number"].tw-field-error.tw-field-error:focus,
1093#tw-checkout-root input[type="password"].tw-field-error.tw-field-error:focus,
1094#tw-checkout-root input:not([type]).tw-field-error.tw-field-error:focus,
1095#tw-checkout-root textarea.tw-field-error.tw-field-error:focus,
1096#tw-checkout-root select.tw-field-error.tw-field-error:focus,
1097#tw-checkout-root .tw-field-error.tw-field-error {
1098    border: 1.5px solid #ef4444 !important;
1099    box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.18) !important;
1100    animation: tw-field-shake .35s ease-in-out 1;
1101}
1102@keyframes tw-field-shake {
1103    0%, 100% { transform: translateX(0); }
1104    25%       { transform: translateX(-4px); }
1105    50%       { transform: translateX(4px); }
1106    75%       { transform: translateX(-2px); }
1107}
1108
1109#tw-checkout-root .cb-boost-bar {
1110    position: relative;
1111    padding: 14px 20px;
1112    
1113    border-radius: 16px;
1114    background: linear-gradient(135deg, #FF6B9D 0%, #FF8E53 60%, #FFC857 100%);
1115    box-shadow: 0 6px 16px -4px rgba(255, 107, 157, 0.28);
1116    color: #fff;
1117    overflow: hidden;
1118    font-family: 'Noto Sans TC', '微軟正黑體', 'PingFang TC', sans-serif;
1119}
1120#tw-checkout-root .cb-boost-bar::before {
1121    content: '';
1122    position: absolute; top: 0; left: -60%; height: 100%; width: 50%;
1123    background: linear-gradient(120deg, transparent, rgba(255, 255, 255, 0.35), transparent);
1124    transform: skewX(-20deg);
1125    animation: cb-shimmer 3.2s ease-in-out infinite;
1126    pointer-events: none;
1127}
1128#tw-checkout-root .cb-row { position: relative; z-index: 1; display: flex; align-items: center; gap: 12px; }
1129#tw-checkout-root .cb-icon {
1130    flex-shrink: 0;
1131    width: 40px; height: 40px;
1132    display: inline-flex; align-items: center; justify-content: center;
1133    background: rgba(255, 255, 255, 0.22);
1134    border-radius: 50%;
1135    animation: cb-bounce 1.6s ease-in-out infinite;
1136    color: #fff;
1137}
1138#tw-checkout-root .cb-text { flex: 1; min-width: 0; line-height: 1.45; }
1139#tw-checkout-root .cb-headline { display: inline-block; font-size: 15px; font-weight: 800; letter-spacing: 0.5px; margin-right: 12px; vertical-align: middle; }
1140#tw-checkout-root .cb-detail { display: inline-block; font-size: 13.5px; font-weight: 500; white-space: nowrap; vertical-align: middle; }
1141#tw-checkout-root .cb-pct {
1142    background: #fff; color: #FF5C8A;
1143    padding: 1px 9px; border-radius: 999px;
1144    font-weight: 800; font-size: 14.5px;
1145    margin: 0 2px; display: inline-block;
1146}
1147#tw-checkout-root .cb-strike { text-decoration: line-through; opacity: 0.85; font-size: 12.5px; margin: 0 6px 0 2px; }
1148#tw-checkout-root .cb-end {
1149    display: inline-block;
1150    padding-left: 10px; margin-left: 4px;
1151    border-left: 1px solid rgba(255, 255, 255, 0.45);
1152    font-size: 12.5px; opacity: 0.95; white-space: nowrap;
1153}
1154@keyframes cb-bounce { 0%, 100% { transform: scale(1) rotate(0); } 50% { transform: scale(1.12) rotate(-10deg); } }
1155@keyframes cb-shimmer { 0% { left: -60%; } 60%, 100% { left: 120%; } }
1156@media (max-width: 1023px) {
1157    #tw-checkout-root .cb-boost-bar { padding: 12px 14px; border-radius: 14px; }
1158    #tw-checkout-root .cb-row { gap: 10px; }
1159    #tw-checkout-root .cb-icon { width: 32px; height: 32px; }
1160    #tw-checkout-root .cb-text { line-height: 1.4; }
1161    #tw-checkout-root .cb-headline { display: block; font-size: 13.5px; margin-right: 0; }
1162    #tw-checkout-root .cb-detail { display: block; font-size: 12px; margin-top: 2px; white-space: normal; }
1163    #tw-checkout-root .cb-pct { font-size: 12.5px; padding: 1px 7px; }
1164    #tw-checkout-root .cb-strike { font-size: 11px; margin: 0 4px 0 1px; }
1165    #tw-checkout-root .cb-end { font-size: 11px; padding-left: 8px; margin-left: 2px; }
1166}
1167
1168#container.sticky { position: static !important; }
1169
1170.member_menu { line-height: 1.4 !important; padding: 6px 0 !important; }
1171.member_menu li { display: block !important; padding: 0 !important; margin: 0 !important; line-height: 1.4 !important; font-size: 13px !important; }
1172.member_menu li a { display: flex !important; align-items: center !important; gap: 10px !important; padding: 9px 18px !important; line-height: 1.4 !important; font-size: 13px !important; height: auto !important; }
1173.member_menu .mm-icon { width: 16px !important; height: 16px !important; flex-shrink: 0 !important; display: inline-block !important; vertical-align: middle !important; }
1174.member_menu .mm-sep { height: 1px !important; margin: 4px 0 !important; padding: 0 !important; }
1175
1176#tw-checkout-root button:focus,
1177#tw-checkout-root a:focus { outline: none; }
1178#tw-checkout-root button:focus-visible,
1179#tw-checkout-root a:focus-visible {
1180    outline: 2px solid rgba(255, 115, 114, .55);
1181    outline-offset: 2px;
1182}
1183
1184#tw-checkout-root svg {
1185    display: inline-block;
1186    vertical-align: middle;
1187    max-width: 100%;
1188}
1189#tw-checkout-root svg:not([class*="w-"]) { width: 1em; }
1190#tw-checkout-root svg:not([class*="h-"]) { height: 1em; }
1191
1192#tw-checkout-root button {
1193  font-family: inherit !important;
1194  cursor: pointer !important;
1195  text-transform: none !important;
1196  letter-spacing: normal !important;
1197  line-height: normal !important;
1198  -webkit-appearance: none !important;
1199  appearance: none !important;
1200  border-width: 0;
1201  border-style: solid;
1202  border-color: #e5e7eb;
1203  box-shadow: none;
1204}
1205
1206#tw-checkout-root input[type="text"]:not(.qty-input):not(.tw-discount-input),
1207#tw-checkout-root input[type="email"]:not(.qty-input),
1208#tw-checkout-root input[type="tel"]:not(.qty-input),
1209#tw-checkout-root input[type="number"]:not(.qty-input),
1210#tw-checkout-root input[type="password"]:not(.qty-input),
1211#tw-checkout-root input:not([type]):not(.qty-input),
1212#tw-checkout-root textarea,
1213#tw-checkout-root select {
1214    font-family: inherit !important;
1215    font-size: 0.875rem !important;
1216    color: #1f2937 !important;
1217    background-color: #fff !important;
1218    border: 1px solid #d1d5db !important;
1219    border-radius: 0.5rem !important;
1220    outline: none !important;
1221    box-shadow: none !important;
1222    margin: 0 !important;
1223    box-sizing: border-box !important;
1224    height: 2.75rem !important;
1225    padding: 0 1rem !important;
1226    width: 100% !important;
1227    transition: border-color .15s, box-shadow .15s !important;
1228    -webkit-appearance: none !important;
1229    appearance: none !important;
1230}
1231#tw-checkout-root textarea {
1232    height: auto !important;
1233    min-height: 4rem !important;
1234    padding: 0.75rem 1rem !important;
1235}
1236#tw-checkout-root input[type="text"]:not(.qty-input):not(.tw-discount-input):focus,
1237#tw-checkout-root input[type="email"]:not(.qty-input):focus,
1238#tw-checkout-root input[type="tel"]:not(.qty-input):focus,
1239#tw-checkout-root input[type="number"]:not(.qty-input):focus,
1240#tw-checkout-root textarea:focus,
1241#tw-checkout-root select:focus {
1242    border-color: #ff7372 !important;
1243    box-shadow: 0 0 0 3px rgba(255,115,114,.15) !important;
1244}
1245
1246#tw-checkout-root input[type="radio"],
1247#tw-checkout-root input[type="checkbox"] {
1248    margin: 0 !important;
1249    padding: 0 !important;
1250    border: 0 !important;
1251    background: transparent !important;
1252    -webkit-appearance: auto !important;
1253    appearance: auto !important;
1254}
1255
1256#tw-checkout-root .tw-cb-wrap {
1257    position: relative !important;
1258}
1259
1260#tw-checkout-root input.tw-cb[type="checkbox"] {
1261    position: absolute !important;
1262    left: 0 !important;
1263    top: 0 !important;
1264    width: 14px !important;
1265    height: 14px !important;
1266    min-width: 0 !important;
1267    min-height: 0 !important;
1268    opacity: 0 !important;
1269    margin: 0 !important;
1270    padding: 0 !important;
1271    border: 0 !important;
1272    outline: none !important;
1273    box-shadow: none !important;
1274    z-index: 1 !important;
1275}
1276#tw-checkout-root .tw-cb-box {
1277    display: inline-block !important;
1278    box-sizing: border-box !important;
1279    width: 14px !important;
1280    height: 14px !important;
1281    min-width: 14px !important;
1282    min-height: 14px !important;
1283    flex-shrink: 0 !important;
1284    border: 1.5px solid #d1d5db !important;
1285    border-radius: 3px !important;
1286    background: #fff !important;
1287    box-shadow: none !important;
1288    cursor: pointer !important;
1289    vertical-align: middle !important;
1290    transition: background-color .12s, border-color .12s;
1291}
1292#tw-checkout-root input.tw-cb[type="checkbox"]:checked + .tw-cb-box {
1293    border-color: #ff7372 !important;
1294    background-color: #ff7372 !important;
1295    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='white' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round' d='M3.5 8.5l3 3 6-7'/%3E%3C/svg%3E") !important;
1296    background-repeat: no-repeat !important;
1297    background-position: center !important;
1298    background-size: 11px 11px !important;
1299}
1300#tw-checkout-root input.tw-cb[type="checkbox"]:focus-visible + .tw-cb-box {
1301    border-color: #ff7372 !important;
1302    box-shadow: 0 0 0 3px rgba(255,115,114,.25) !important;
1303}
1304
1305#tw-checkout-root input.qty-input,
1306#tw-checkout-root input[type="text"].qty-input {
1307    flex: 0 0 3rem !important;
1308    width: 3rem !important;
1309    min-width: 3rem !important;
1310    height: 2.25rem !important;
1311    line-height: 2.25rem !important;
1312    border: 0 !important;
1313    border-radius: 0 !important;
1314    text-align: center !important;
1315    background: transparent !important;
1316    padding: 0 !important;
1317    box-shadow: none !important;
1318    outline: 0 !important;
1319    vertical-align: middle !important;
1320    display: inline-block !important;
1321    box-sizing: border-box !important;
1322    font-size: 0.9375rem !important;
1323    font-weight: 500 !important;
1324    font-variant-numeric: tabular-nums !important;
1325    -moz-font-feature-settings: "tnum" !important;
1326    -webkit-font-feature-settings: "tnum" !important;
1327    font-feature-settings: "tnum" !important;
1328    transform: translateY(2px) !important;
1329}
1330#tw-checkout-root input.qty-input:focus,
1331#tw-checkout-root input[type="text"].qty-input:focus {
1332    border: 0 !important;
1333    box-shadow: none !important;
1334    outline: 0 !important;
1335}
1336
1337#tw-checkout-root input.qty-input.qty-input-sm,
1338#tw-checkout-root input[type="text"].qty-input.qty-input-sm {
1339    flex: 0 0 2.25rem !important;
1340    width: 2.25rem !important;
1341    min-width: 2.25rem !important;
1342    height: 1.75rem !important;
1343    line-height: 1.75rem !important;
1344    font-size: 0.8125rem !important;
1345    transform: translateY(3px) !important;
1346}
1347#tw-checkout-root .qty-btn-sm {
1348    user-select: none;
1349    background: transparent !important;
1350    border: 0 !important;
1351    width: 1.75rem !important;
1352    height: 1.75rem !important;
1353    padding: 0 !important;
1354    font-size: 1rem !important;
1355    
1356    line-height: 1.75rem !important;
1357    cursor: pointer !important;
1358    display: inline-flex !important;
1359    align-items: center !important;
1360    justify-content: center !important;
1361    font-feature-settings: "tnum" !important;
1362}
1363
1364#tw-checkout-root .qty-btn-sm[data-qty-op="-"],
1365#tw-checkout-root .qty-btn-sm[data-qty-op="+"] {
1366    position: relative;
1367    color: transparent !important;
1368}
1369#tw-checkout-root .qty-btn-sm[data-qty-op]::before,
1370#tw-checkout-root .qty-btn-sm[data-qty-op="+"]::after {
1371    content: '';
1372    position: absolute;
1373    background: #6b7280;
1374    border-radius: 1px;
1375}
1376#tw-checkout-root .qty-btn-sm[data-qty-op]::before {
1377    width: 10px; height: 1.5px;
1378    top: 50%; left: 50%;
1379    transform: translate(-50%, -50%);
1380}
1381#tw-checkout-root .qty-btn-sm[data-qty-op="+"]::after {
1382    width: 1.5px; height: 10px;
1383    top: 50%; left: 50%;
1384    transform: translate(-50%, -50%);
1385}
1386#tw-checkout-root .qty-btn-sm:hover[data-qty-op]::before,
1387#tw-checkout-root .qty-btn-sm:hover[data-qty-op="+"]::after { background: #1f2937; }
1388#tw-checkout-root .qty-btn {
1389    user-select:none;
1390    background: transparent !important;
1391    border: 0 !important;
1392    height: 2.25rem !important;
1393    padding: 0 !important;
1394}
1395
1396#tw-checkout-root .product-thumb { background-color: transparent; border-radius: 0; overflow: visible; }
1397
1398#tw-checkout-root .tw-addr-select,
1399#tw-checkout-root .tw-addr-zip {
1400    height: 2.75rem !important;
1401    padding: 0 0.875rem !important;
1402    border: 1px solid #d1d5db !important;
1403    border-radius: 0.5rem !important;
1404    background: #fff !important;
1405    color: #1f2937 !important;
1406    font-size: 0.875rem !important;
1407    width: 100% !important;
1408    box-sizing: border-box !important;
1409    -webkit-appearance: none !important;
1410    appearance: none !important;
1411    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2'><polyline points='6 9 12 15 18 9'/></svg>") !important;
1412    background-repeat: no-repeat !important;
1413    background-position: right 0.75rem center !important;
1414    padding-right: 2rem !important;
1415    cursor: pointer !important;
1416    margin: 0 !important;
1417    box-shadow: none !important;
1418    outline: none !important;
1419}
1420#tw-checkout-root .tw-addr-zip {
1421    background-image: none !important;
1422    padding-right: 0.875rem !important;
1423    cursor: default !important;
1424    background-color: #f9fafb !important;
1425}
1426#tw-checkout-root .tw-addr-select:focus {
1427    border-color: #ff7372 !important;
1428    box-shadow: 0 0 0 3px rgba(255,115,114,.15) !important;
1429}
1430
1431#tw-checkout-root .grid > .md\:col-span-2 > section + section,
1432#tw-checkout-root .grid > div:first-child > section + section,
1433#tw-checkout-root section ~ section {
1434    margin-top: 1.75rem !important;
1435}
1436@media (min-width: 768px) {
1437    #tw-checkout-root section ~ section {
1438        margin-top: 2.5rem !important;
1439    }
1440}
1441
1442#tw-checkout-root .tw-cta-primary {
1443    background-color: #ff7372 !important;
1444    color: #fff !important;
1445    width: 100% !important;
1446    height: 3rem !important;
1447    border-radius: 9999px !important;
1448    font-weight: 600 !important;
1449    font-size: 1rem !important;
1450    box-shadow: 0 4px 12px rgba(255,115,114,.3) !important;
1451    display: inline-flex !important;
1452    align-items: center !important;
1453    justify-content: center !important;
1454    gap: 0.5rem !important;
1455    border: 0 !important;
1456    transition: background-color .15s !important;
1457}
1458#tw-checkout-root .tw-cta-primary:hover { background-color: #ff5957 !important; }
1459#tw-checkout-root .tw-cta-stack {
1460    flex-direction: column !important;
1461    gap: 0.125rem !important;
1462    height: 3.5rem !important;
1463}
1464#tw-checkout-root .tw-cta-stack .tw-cta-title { font-size: 1rem; font-weight: 600; line-height: 1.2; }
1465#tw-checkout-root .tw-cta-stack .tw-cta-sub { font-size: 0.7rem; font-weight: 400; opacity: 0.9; line-height: 1.2; }
1466
1467#tw-checkout-root .tw-cta-stack .tw-cta-pay-icons {
1468    display: inline-flex; align-items: center; justify-content: center;
1469    gap: 10px; opacity: 0.92; margin-top: 4px;
1470}
1471#tw-checkout-root .tw-cta-stack .tw-cta-pay-icons svg {
1472    width: 20px; height: 20px; flex-shrink: 0; display: inline-block;
1473}
1474#tw-checkout-root .tw-cta-stack .tw-cta-pay-icons .tw-cta-pay-text {
1475    display: inline-flex; align-items: center; justify-content: center;
1476    height: 18px; padding: 0 5px;
1477    font-size: 10px; font-weight: 700; line-height: 1;
1478    letter-spacing: 0.3px;
1479    border: 1px solid currentColor; border-radius: 4px;
1480    flex-shrink: 0; font-family: -apple-system, "Helvetica Neue", Arial, sans-serif;
1481}
1482#tw-checkout-root .tw-cta-line {
1483    background-color: #06c755 !important;
1484    color: #fff !important;
1485    width: 100% !important;
1486    height: 2.75rem !important;
1487    border-radius: 9999px !important;
1488    font-weight: 500 !important;
1489    box-shadow: none !important;
1490    display: inline-flex !important;
1491    align-items: center !important;
1492    justify-content: center !important;
1493    gap: 0.5rem !important;
1494    border: 0 !important;
1495    margin-top: 0.5rem !important;
1496}
1497#tw-checkout-root .tw-cta-line:hover { background-color: #05b349 !important; }
1498#tw-checkout-root .tw-cta-paypal {
1499    background-color: #003087 !important;
1500    color: #fff !important;
1501    width: 100% !important;
1502    height: 2.75rem !important;
1503    border-radius: 9999px !important;
1504    font-weight: 500 !important;
1505    display: inline-flex !important;
1506    align-items: center !important;
1507    justify-content: center !important;
1508    gap: 0.5rem !important;
1509    border: 0 !important;
1510    margin-top: 0.5rem !important;
1511}
1512#tw-checkout-root .tw-cta-paypal:hover { background-color: #002870 !important; }
1513
1514#tw-checkout-root .tw-radio-card {
1515    cursor: pointer;
1516    display: flex;
1517    flex-direction: column;
1518    gap: 0.5rem;
1519    padding: 1rem;
1520    border-radius: 0.75rem;
1521    border: 2px solid #e5e7eb !important;
1522    background: #fff;
1523    transition: border-color .15s, background-color .15s;
1524}
1525#tw-checkout-root .tw-radio-card:hover { border-color: #ff9d9c !important; }
1526#tw-checkout-root .tw-radio-card.tw-selected {
1527    border-color: #ff7372 !important;
1528    background-color: #fff5f5 !important;
1529}
1530#tw-checkout-root .tw-radio-card .tw-radio-input { display: none !important; }
1531#tw-checkout-root .tw-radio-card .tw-radio-dot {
1532    flex-shrink: 0;
1533    width: 1.25rem;
1534    height: 1.25rem;
1535    border-radius: 9999px;
1536    border: 2px solid #d1d5db;
1537    background: #fff;
1538    color: transparent;
1539    display: inline-flex;
1540    align-items: center;
1541    justify-content: center;
1542    font-size: 0.75rem;
1543    font-weight: bold;
1544    transition: all .15s;
1545}
1546#tw-checkout-root .tw-radio-card.tw-selected .tw-radio-dot {
1547    border-color: #ff7372;
1548    background-color: #ff7372;
1549    color: #fff;
1550}
1551
1552#tw-checkout-root .tw-discount-input {
1553    flex: 1 1 auto !important;
1554    min-width: 0 !important;
1555    height: 2.5rem !important;
1556    padding: 0 0.75rem !important;
1557    border: 1px solid #d1d5db !important;
1558    border-radius: 0.5rem !important;
1559    background: #fff !important;
1560    color: #1f2937 !important;
1561    font-size: 0.875rem !important;
1562    outline: 0 !important;
1563    box-shadow: none !important;
1564    box-sizing: border-box !important;
1565}
1566#tw-checkout-root .tw-discount-input:focus {
1567    border-color: #ff7372 !important;
1568    box-shadow: 0 0 0 2px rgba(255,115,114,.15) !important;
1569}
1570#tw-checkout-root .tw-discount-btn {
1571    flex: 0 0 auto !important;
1572    height: 2.5rem !important;
1573    padding: 0 1rem !important;
1574    background: #ff7372 !important;
1575    color: #fff !important;
1576    font-size: 0.75rem !important;
1577    font-weight: 500 !important;
1578    border-radius: 0.5rem !important;
1579    border: 0 !important;
1580    box-shadow: none !important;
1581    white-space: nowrap !important;
1582}
1583#tw-checkout-root .tw-discount-btn:hover { background: #e04948 !important; }
1584
1585#tw-checkout-root .tw-mp-toggle {
1586    position: relative !important; display: inline-block !important;
1587    width: 36px !important; height: 20px !important;
1588    background-color: #d1d5db !important; border: 0 !important;
1589    padding: 0 !important; margin: 0 !important;
1590    border-radius: 9999px !important; cursor: pointer !important;
1591    box-shadow: none !important; outline: 0 !important;
1592    transition: background-color .2s ease-in-out !important;
1593}
1594#tw-checkout-root .tw-mp-toggle:hover,
1595#tw-checkout-root .tw-mp-toggle:focus,
1596#tw-checkout-root .tw-mp-toggle:active { background-color: #d1d5db !important; box-shadow: none !important; }
1597#tw-checkout-root .tw-mp-toggle[data-state="1"],
1598#tw-checkout-root .tw-mp-toggle[data-state="1"]:hover,
1599#tw-checkout-root .tw-mp-toggle[data-state="1"]:focus,
1600#tw-checkout-root .tw-mp-toggle[data-state="1"]:active { background-color: #10b981 !important; }
1601#tw-checkout-root .tw-mp-toggle[disabled] { opacity: .5 !important; cursor: not-allowed !important; }
1602#tw-checkout-root .tw-mp-toggle .tw-mp-thumb {
1603    position: absolute !important; top: 2px !important; left: 2px !important;
1604    width: 16px !important; height: 16px !important; background: #fff !important;
1605    border-radius: 9999px !important; box-shadow: 0 1px 2px rgba(0,0,0,.2) !important;
1606    transition: transform .2s ease-in-out !important;
1607}
1608#tw-checkout-root .tw-mp-toggle[data-state="1"] .tw-mp-thumb { transform: translateX(16px) !important; }
1609
1610#tw-checkout-root .tw-mp-redeem-amt { color: #b45309; font-weight: 500; }
1611
1612#tw-checkout-root .tw-discount-toggle-btn {
1613    display: flex !important;
1614    align-items: center !important;
1615    gap: 0.5rem !important;
1616    width: 100% !important;
1617    min-height: 2.75rem !important;
1618    padding: 0.625rem 0.875rem !important;
1619    font-size: 0.875rem !important;
1620    font-weight: 500 !important;
1621    line-height: 1.2 !important;
1622    color: #6b7280 !important;
1623    background: #fafafa !important;
1624    border: 1px dashed #d1d5db !important;
1625    border-radius: 0.5rem !important;
1626    transition: background-color .15s, border-color .15s, color .15s !important;
1627    box-shadow: none !important;
1628    cursor: pointer !important;
1629}
1630#tw-checkout-root .tw-discount-toggle-btn:hover {
1631    color: #4b5563 !important;
1632    background: #f3f4f6 !important;
1633    border-color: #9ca3af !important;
1634}
1635#tw-checkout-root .tw-discount-toggle-btn .tw-discount-toggle-chev {
1636    color: #9ca3af !important;
1637    transition: transform .2s !important;
1638}
1639#tw-checkout-root .tw-discount-toggle-btn:hover .tw-discount-toggle-chev { color: #6b7280 !important; }
1640
1641#tw-checkout-root .tw-free-card-btn {
1642    display: flex !important;
1643    align-items: center !important;
1644    gap: 0.5rem !important;
1645    width: 100% !important;
1646    min-height: 2.75rem !important;
1647    padding: 0.625rem 0.875rem !important;
1648    font-size: 0.875rem !important;
1649    font-weight: 500 !important;
1650    line-height: 1.2 !important;
1651    color: #c73a3a !important;
1652    background: #fff5f5 !important;
1653    border: 1px solid #ffd9d8 !important;
1654    border-radius: 0.5rem !important;
1655    transition: background-color .15s, border-color .15s !important;
1656    box-shadow: none !important;
1657    cursor: pointer !important;
1658    flex-wrap: wrap !important;
1659}
1660#tw-checkout-root .tw-free-card-btn:hover {
1661    background: #ffeded !important;
1662    border-color: #ffc4c4 !important;
1663}
1664#tw-checkout-root .tw-free-card-btn svg { color: #e98a86 !important; }
1665#tw-checkout-root .tw-free-card-btn .tw-free-card-label { white-space: nowrap !important; }
1666#tw-checkout-root .tw-free-card-btn .tw-card-selected-badge {
1667    display: inline-flex !important; align-items: center !important;
1668    font-size: 0.75rem !important; font-weight: 500 !important;
1669    padding: 0.125rem 0.5rem !important;
1670    border-radius: 9999px !important;
1671    
1672    background: #ffd9d8; color: #a23030;
1673    white-space: nowrap !important;
1674}
1675
1676#tw-checkout-root .tw-seg {
1677    display: flex;
1678    flex-wrap: wrap;
1679    gap: 0;
1680    padding: 3px;
1681    background: #f5f5f4;
1682    border-radius: 10px;
1683    margin-bottom: 16px;
1684}
1685#tw-checkout-root .tw-seg label {
1686    position: relative;
1687    cursor: pointer;
1688    margin: 0;
1689    flex: 1 1 auto;
1690    min-width: 0;
1691}
1692#tw-checkout-root .tw-seg input.tw-seg-radio,
1693#tw-checkout-root .tw-seg label input[type="radio"] {
1694    display: none !important;
1695    visibility: hidden !important;
1696    width: 0 !important;
1697    height: 0 !important;
1698    position: absolute !important;
1699    opacity: 0 !important;
1700    pointer-events: none !important;
1701    -webkit-appearance: none !important;
1702    appearance: none !important;
1703}
1704#tw-checkout-root .tw-seg .tw-seg-lbl {
1705    display: block !important;
1706    padding: 7px 10px !important;
1707    font-size: 12px !important;
1708    border-radius: 7px !important;
1709    color: #57534e !important;
1710    transition: all .15s !important;
1711    white-space: nowrap !important;
1712    text-align: center !important;
1713    height: auto !important;
1714    line-height: 1.2 !important;
1715    user-select: none !important;
1716    position: relative !important;
1717}
1718#tw-checkout-root .tw-seg input.tw-seg-radio:checked + .tw-seg-lbl {
1719    background: #fff !important;
1720    color: #ff7372 !important;
1721    font-weight: 600 !important;
1722    box-shadow: 0 1px 2px rgba(0,0,0,.06) !important;
1723}
1724
1725#tw-checkout-root .tw-inv-panel { display: none; }
1726#tw-checkout-root .tw-inv-panel.active { display: block; }
1727
1728.tw-mobile-bar {
1729    position: fixed !important;
1730    bottom: 0 !important;
1731    left: 0 !important;
1732    right: 0 !important;
1733    background: #fff !important;
1734    border-top: 1px solid #e5e7eb !important;
1735    box-shadow: 0 -4px 20px rgba(0,0,0,.08) !important;
1736    
1737    z-index: 100 !important;
1738    
1739    padding: 0.75rem 0 calc(0.75rem + env(safe-area-inset-bottom)) 0 !important;
1740}
1741.tw-mobile-bar-total {
1742    display: flex !important;
1743    align-items: baseline !important;
1744    justify-content: space-between !important;
1745    gap: 0.5rem !important;
1746    margin-bottom: 0.5rem !important;
1747}
1748.tw-mobile-bar-label { font-size: 12px !important; color: #6b7280 !important; line-height: 1.2 !important; }
1749.tw-mobile-bar-value { font-size: 22px !important; font-weight: 700 !important; color: #ff7372 !important; line-height: 1.2 !important; white-space: nowrap !important; }
1750.tw-mobile-bar-pay {
1751    display: flex !important;
1752    align-items: stretch !important;
1753    gap: 0.5rem !important;
1754}
1755#tw-checkout-root .tw-mobile-cta,
1756.tw-mobile-bar .tw-mobile-cta {
1757    height: 2.75rem !important;
1758    padding: 0 1rem !important;
1759    border-radius: 9999px !important;
1760    background: #ff7372 !important;
1761    color: #fff !important;
1762    font-weight: 600 !important;
1763    font-size: 0.9375rem !important;
1764    border: 0 !important;
1765    box-shadow: 0 4px 12px rgba(255,115,114,.3) !important;
1766    white-space: nowrap !important;
1767    display: inline-flex !important;
1768    align-items: center !important;
1769    justify-content: center !important;
1770    gap: 0.375rem !important;
1771    cursor: pointer !important;
1772    text-decoration: none !important;
1773}
1774.tw-mobile-bar .tw-mobile-cta:hover { background: #ff5957 !important; }
1775.tw-mobile-bar .tw-mobile-cta-full { width: 100% !important; }
1776.tw-mobile-bar .tw-mobile-cta-half { flex: 1 1 0 !important; min-width: 0 !important; padding: 0 0.5rem !important; box-shadow: none !important; }
1777
1778.tw-mobile-bar .tw-mobile-cta-wide { flex: 2 1 0 !important; min-width: 0 !important; padding: 0 0.75rem !important; box-shadow: none !important; }
1779.tw-mobile-bar .tw-mobile-cta-narrow { flex: 1 1 0 !important; min-width: 0 !important; padding: 0 0.5rem !important; }
1780.tw-mobile-bar .tw-mobile-cta-line {
1781    height: 2.75rem !important;
1782    border-radius: 9999px !important;
1783    background: #06c755 !important;
1784    color: #fff !important;
1785    font-weight: 600 !important;
1786    font-size: 0.9375rem !important;
1787    border: 0 !important;
1788    cursor: pointer !important;
1789    display: inline-flex !important;
1790    align-items: center !important;
1791    justify-content: center !important;
1792}
1793.tw-mobile-bar .tw-mobile-cta-line:hover { background: #05b349 !important; }
1794
1795.tw-mobile-bar .tw-mobile-cta-inline {
1796    flex-direction: row !important;
1797    align-items: center !important;
1798    justify-content: center !important;
1799    gap: 8px !important;
1800    height: 2.75rem !important;
1801    padding: 0 12px !important;
1802}
1803.tw-mobile-bar .tw-mobile-cta-inline .tw-mobile-cta-title {
1804    font-size: 0.9rem !important;
1805    font-weight: 700 !important;
1806    line-height: 1 !important;
1807}
1808.tw-mobile-bar .tw-mobile-cta-inline .tw-mobile-cta-icons {
1809    display: inline-flex !important;
1810    align-items: center !important;
1811    gap: 6px !important;
1812    opacity: .92 !important;
1813    flex-shrink: 1 !important;
1814    min-width: 0 !important;
1815    overflow: hidden !important;
1816}
1817.tw-mobile-bar .tw-mobile-cta-inline .tw-mobile-cta-icons svg {
1818    width: 18px !important; height: 18px !important;
1819    flex-shrink: 0 !important;
1820    display: inline-block !important;
1821}
1822.tw-mobile-bar .tw-mobile-cta-inline .tw-mobile-cta-icons .tw-mobile-pay-text,
1823.tw-mobile-bar .tw-mobile-cta-stack .tw-mobile-cta-icons .tw-mobile-pay-text {
1824    display: inline-flex !important; align-items: center !important; justify-content: center !important;
1825    height: 16px !important; padding: 0 4px !important;
1826    font-size: 9px !important; font-weight: 700 !important; line-height: 1 !important;
1827    letter-spacing: 0.2px !important;
1828    border: 1px solid currentColor !important; border-radius: 3px !important;
1829    flex-shrink: 0 !important;
1830    font-family: -apple-system, "Helvetica Neue", Arial, sans-serif !important;
1831}
1832
1833.tw-mobile-bar .tw-mobile-cta-stack {
1834    flex-direction: column !important;
1835    gap: 3px !important;
1836    padding: 6px 8px !important;
1837    height: 3.25rem !important;
1838    line-height: 1.2 !important;
1839}
1840.tw-mobile-bar .tw-mobile-cta-stack .tw-mobile-cta-title {
1841    font-size: 0.9rem !important;
1842    font-weight: 700 !important;
1843    line-height: 1.15 !important;
1844}
1845.tw-mobile-bar .tw-mobile-cta-stack .tw-mobile-cta-icons {
1846    display: inline-flex !important;
1847    align-items: center !important;
1848    justify-content: center !important;
1849    gap: 7px !important;
1850    opacity: .92 !important;
1851}
1852.tw-mobile-bar .tw-mobile-cta-stack .tw-mobile-cta-icons svg {
1853    width: 18px !important; height: 18px !important;
1854    flex-shrink: 0 !important;
1855    display: inline-block !important;
1856}
1857
1858.tw-mobile-bar .tw-mobile-cta-stack .tw-mobile-cta-sub {
1859    font-size: 0.6875rem !important; font-weight: 400 !important; line-height: 1.2 !important;
1860    opacity: .9 !important; white-space: nowrap !important; overflow: hidden !important;
1861    text-overflow: ellipsis !important; max-width: 100% !important;
1862}
1863
1864.tw-mobile-bar-inner {
1865    max-width: 72rem;       
1866    margin: 0 auto;
1867    padding-left: 1rem;     
1868    padding-right: 1rem;
1869}
1870
1871@media (max-width: 767px) {
1872    .tw-mobile-bar-split .tw-mobile-bar-inner {
1873        display: flex !important;
1874        flex-direction: row !important;
1875        align-items: center !important;
1876        justify-content: space-between !important;
1877        gap: 1rem !important;
1878    }
1879    .tw-mobile-bar-split .tw-mobile-bar-total {
1880        flex: 0 0 auto !important;
1881        flex-direction: column !important;
1882        align-items: flex-start !important;
1883        justify-content: center !important;
1884        gap: 0.25rem !important;
1885        margin-bottom: 0 !important;
1886    }
1887    .tw-mobile-bar-split .tw-mobile-bar-label { font-size: 13px !important; }
1888    .tw-mobile-bar-split .tw-mobile-bar-value { font-size: 25px !important; }
1889    .tw-mobile-bar-split .tw-mobile-cta-full {
1890        width: auto !important;
1891        flex: 1 1 auto !important;
1892        min-width: 0 !important;
1893        max-width: 58% !important;
1894        height: 3rem !important;
1895        font-size: 1rem !important;
1896    }
1897}
1898
1899@media (min-width: 768px) {
1900    .tw-mobile-bar {
1901        padding: 0.875rem 0 calc(0.875rem + env(safe-area-inset-bottom)) 0 !important;
1902    }
1903    .tw-mobile-bar-inner {
1904        display: flex !important;
1905        flex-direction: row !important;
1906        align-items: center !important;
1907        justify-content: flex-end !important;
1908        gap: 1.5rem !important;
1909    }
1910    .tw-mobile-bar-inner > * { max-width: none !important; }
1911    .tw-mobile-bar-total {
1912        margin-bottom: 0 !important;
1913        flex-direction: row !important;
1914        align-items: baseline !important;
1915        gap: 0.5rem !important;
1916        flex-shrink: 0 !important;
1917    }
1918    .tw-mobile-bar-label { font-size: 14px !important; }
1919    .tw-mobile-bar-value { font-size: 26px !important; }
1920    .tw-mobile-bar-pay {
1921        flex: 0 1 auto !important;
1922        gap: 0.5rem !important;
1923    }
1924    .tw-mobile-bar .tw-mobile-cta-full {
1925        width: auto !important;
1926        min-width: 220px !important;
1927    }
1928    .tw-mobile-bar .tw-mobile-cta-wide,
1929    .tw-mobile-bar .tw-mobile-cta-narrow {
1930        flex: 0 1 auto !important;
1931    }
1932    .tw-mobile-bar .tw-mobile-cta-wide { min-width: 220px !important; }
1933    .tw-mobile-bar .tw-mobile-cta-narrow { min-width: 120px !important; }
1934}
1935
1936.tw-card-modal {
1937    position: fixed; inset: 0; z-index: 99999;
1938    display: flex; align-items: center; justify-content: center;
1939    padding: calc(16px + env(safe-area-inset-top)) 16px calc(16px + env(safe-area-inset-bottom));
1940    overflow-y: auto;
1941}
1942.tw-card-modal-backdrop {
1943    position: absolute; inset: 0;
1944    background: rgba(15, 23, 42, .55);
1945    backdrop-filter: blur(2px);
1946}
1947.tw-card-modal-panel {
1948    position: relative;
1949    width: 100%; max-width: 720px;
1950    
1951    max-height: calc(100vh - 32px - env(safe-area-inset-top) - env(safe-area-inset-bottom));
1952    max-height: calc(100dvh - 32px - env(safe-area-inset-top) - env(safe-area-inset-bottom));
1953    background: #fff; border-radius: 16px;
1954    box-shadow: 0 25px 50px -12px rgba(0, 0, 0, .35);
1955    display: flex; flex-direction: column; overflow: hidden;
1956    animation: twCardIn .18s ease-out both;
1957}
1958@keyframes twCardIn {
1959    from { opacity: 0; transform: translateY(8px) scale(.98); }
1960    to   { opacity: 1; transform: none; }
1961}
1962.tw-card-modal-close {
1963    position: absolute; top: 12px; right: 12px;
1964    width: 36px; height: 36px;
1965    border: 0; border-radius: 9999px;
1966    background: rgba(0, 0, 0, .04); color: #6b7280;
1967    display: inline-flex; align-items: center; justify-content: center;
1968    cursor: pointer; transition: background .15s, color .15s; z-index: 2;
1969}
1970.tw-card-modal-close:hover { background: rgba(0, 0, 0, .08); color: #1f2937; }
1971.tw-card-modal-close svg { width: 18px; height: 18px; }
1972.tw-card-modal-header { padding: 20px 24px 12px; border-bottom: 1px solid #f3f4f6; }
1973.tw-card-modal-header h3 { margin: 0 !important; font-size: 18px; font-weight: 600; color: #111827; }
1974.tw-card-modal-header p { margin: 4px 0 0; font-size: 13px; color: #6b7280; }
1975.tw-card-step { padding: 0; overflow-y: auto; }
1976.tw-card-grid {
1977    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px;
1978    padding: 16px 24px 24px;
1979}
1980@media (min-width: 480px) { .tw-card-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
1981@media (min-width: 720px) { .tw-card-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
1982.tw-card-tile {
1983    display: flex; flex-direction: column; gap: 6px;
1984    padding: 8px; border: 1.5px solid #e5e7eb; border-radius: 12px;
1985    background: #fafafa; cursor: pointer;
1986    transition: border-color .15s, transform .12s, box-shadow .15s;
1987    text-align: center;
1988}
1989.tw-card-tile:hover {
1990    border-color: #ff7372; background: #fff;
1991    transform: translateY(-2px);
1992    box-shadow: 0 8px 16px -8px rgba(255, 115, 114, .35);
1993}
1994.tw-card-tile.is-selected {
1995    border-color: #ff7372; background: #fff5f5;
1996    box-shadow: 0 0 0 2px rgba(255, 115, 114, .25);
1997}
1998.tw-card-tile-img {
1999    width: 100%; aspect-ratio: 3 / 4;
2000    background-size: cover; background-position: center; background-repeat: no-repeat;
2001    border-radius: 8px; background-color: #f3f4f6;
2002}
2003.tw-card-tile-label { font-size: 12px; color: #4b5563; line-height: 1.3; }
2004#tw-card-step-2 .tw-card-modal-header { display: flex; align-items: center; gap: 12px; }
2005.tw-card-back {
2006    display: inline-flex; align-items: center; gap: 4px;
2007    padding: 6px 10px; background: transparent; border: 0; border-radius: 9999px;
2008    color: #6b7280; font-size: 13px; cursor: pointer;
2009    transition: background .15s, color .15s;
2010}
2011.tw-card-back:hover { background: rgba(0, 0, 0, .04); color: #1f2937; }
2012.tw-card-back svg { width: 14px; height: 14px; }
2013.tw-card-preview-wrap { padding: 20px 24px 0; display: flex; justify-content: center; }
2014.tw-card-preview {
2015    width: 100%; max-width: 280px; aspect-ratio: 3 / 4;
2016    background-size: cover; background-position: center; background-repeat: no-repeat;
2017    border-radius: 12px;
2018    box-shadow: 0 12px 24px -12px rgba(0, 0, 0, .2);
2019    background-color: #f3f4f6;
2020}
2021.tw-card-msg-wrap { padding: 16px 24px 0; }
2022.tw-card-msg-label { display: block; font-size: 13px; font-weight: 500; color: #374151; margin-bottom: 6px; }
2023.tw-card-msg-input {
2024    width: 100%; padding: 10px 12px;
2025    border: 1.5px solid #d1d5db; border-radius: 8px;
2026    font-size: 14px; line-height: 1.5; color: #1f2937;
2027    resize: none; outline: none; box-sizing: border-box;
2028    transition: border-color .15s, box-shadow .15s;
2029    min-height: 80px; font-family: inherit;
2030}
2031.tw-card-msg-input:focus { border-color: #ff7372; box-shadow: 0 0 0 3px rgba(255, 115, 114, .15); }
2032.tw-card-msg-meta {
2033    display: flex; justify-content: space-between; align-items: center;
2034    margin-top: 6px; font-size: 11px; color: #9ca3af;
2035}
2036.tw-card-actions {
2037    display: flex; gap: 8px;
2038    padding: 16px 24px 20px; margin-top: 12px;
2039    border-top: 1px solid #f3f4f6;
2040}
2041.tw-card-btn-secondary, .tw-card-btn-primary {
2042    flex: 1; height: 44px; border-radius: 9999px;
2043    font-size: 14px; font-weight: 600; cursor: pointer; border: 0;
2044    transition: background .15s, border-color .15s;
2045}
2046.tw-card-btn-secondary { background: #fff; color: #6b7280; border: 1.5px solid #e5e7eb; }
2047.tw-card-btn-secondary:hover { border-color: #d1d5db; color: #374151; }
2048.tw-card-btn-primary { background: #ff7372; color: #fff; box-shadow: 0 4px 12px rgba(255, 115, 114, .3); }
2049.tw-card-btn-primary:hover { background: #ff5957; }
2050.tw-card-btn-primary:disabled { opacity: .5; cursor: not-allowed; }
2051.tw-card-modal[data-stage="1"] #tw-card-step-2 { display: none !important; }
2052.tw-card-modal[data-stage="2"] #tw-card-step-1 { display: none !important; }
2053.tw-card-modal[data-stage="2"] #tw-card-step-2 { display: block !important; }
2054
2055.tw-savecart-main { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; min-height: 0; }
2056.tw-savecart-main > .tw-card-modal-body { padding: 18px 22px 22px; overflow-y: auto; min-height: 0; }
2057.tw-savecart-oauth { display: flex; flex-direction: column; gap: 8px; margin: 4px 0 14px; }
2058#tw-checkout-root .tw-savecart-oauth-btn { display: flex; align-items: center; justify-content: center; gap: 10px; padding: 11px 14px; border-radius: 10px; text-decoration: none; font-weight: 600; font-size: 14px; }
2059#tw-checkout-root .tw-savecart-oauth-btn.is-line { background: #06c755; color: #fff; }
2060#tw-checkout-root .tw-savecart-oauth-btn.is-facebook { background: #1877f2; color: #fff; }
2061#tw-checkout-root .tw-savecart-oauth-btn.is-google { background: #fff; color: #3c4043; border: 1px solid #dadce0; }
2062.tw-savecart-or { display: flex; align-items: center; gap: 10px; margin: 6px 0 12px; font-size: 12px; color: #999; }
2063.tw-savecart-field { display: flex; gap: 6px; align-items: center; }
2064.tw-savecart-actions { display: flex; gap: 8px; margin-top: 14px; justify-content: flex-end; }
2065.tw-savecart-short, .tw-savecart-perks, .tw-savecart-sub, .tw-savecart-hint, .tw-savecart-save-inline { display: none; }
2066
2067.tw-savecart-has-promo { max-width: 380px; }
2068.tw-savecart-promo { position: relative; flex: none; }
2069
2070.tw-savecart-promo-backdrop { position: absolute; inset: 0; overflow: hidden; background: #efe6da; }
2071#tw-checkout-root .tw-savecart-promo-backdrop img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; object-fit: cover; filter: blur(40px) saturate(1.1); transform: scale(1.5); }
2072.tw-savecart-promo-backdrop::after { content: ""; position: absolute; inset: 0; background: rgba(255, 255, 255, .14); }
2073.tw-savecart-promo-inner { position: relative; display: flex; flex-direction: column; align-items: center; }
2074#tw-checkout-root .tw-savecart-promo-img { min-width: 0; min-height: 0; width: auto; }
2075.tw-savecart-promo-tag {
2076    display: inline-flex; align-items: center; gap: 6px; padding: 6px 16px 6px 14px; border-radius: 9999px;
2077    background: linear-gradient(135deg, #ff7372, #f64600); color: #fff;
2078    font-size: 15px; font-weight: 800; letter-spacing: .14em; line-height: 1.5; white-space: nowrap;
2079    box-shadow: 0 6px 16px -4px rgba(246, 70, 0, .55);
2080}
2081.tw-savecart-promo-tag svg { width: 17px; height: 17px; flex: none; }
2082.tw-savecart-promo-note { font-size: 13px; font-weight: 600; color: #44403c; background: rgba(255, 255, 255, .78); padding: 5px 14px; border-radius: 9999px; white-space: nowrap; }
2083.tw-savecart-perk { background: #fff7ed; border: 1px solid #fed7aa; border-radius: 10px; padding: 7px 4px 6px; text-align: center; }
2084.tw-savecart-perk b { display: block; font-size: 15px; font-weight: 800; color: #c2410c; line-height: 1.3; }
2085.tw-savecart-perk span { display: block; font-size: 11px; color: #78716c; line-height: 1.4; margin-top: 2px; }
2086.tw-savecart-perk.is-hot { background: linear-gradient(135deg, #ff7372, #f64600); border-color: transparent; }
2087.tw-savecart-perk.is-hot b, .tw-savecart-perk.is-hot span { color: #fff; }
2088
2089@media (min-width: 900px) {
2090    .tw-savecart-has-promo { max-width: 840px; flex-direction: row; }
2091    .tw-savecart-has-promo .tw-savecart-promo { flex: 0 0 460px; }
2092    .tw-savecart-has-promo .tw-savecart-promo-inner { position: absolute; inset: 0; justify-content: center; gap: 14px; padding: 22px; }
2093    #tw-checkout-root .tw-savecart-has-promo .tw-savecart-promo-img {
2094        flex: 0 1 auto; max-height: 100%; object-fit: contain; border-radius: 12px;
2095        box-shadow: 0 22px 44px -16px rgba(0, 0, 0, .55), 0 0 0 1px rgba(255, 255, 255, .35);
2096    }
2097    .tw-savecart-has-promo .tw-savecart-promo-tag,
2098    .tw-savecart-has-promo .tw-savecart-promo-note { flex: none; }
2099}
2100@media (max-width: 899px) {
2101    
2102    .tw-savecart-has-promo { overflow-y: auto; }
2103    .tw-savecart-has-promo .tw-savecart-main { flex: none; }
2104    .tw-savecart-has-promo .tw-savecart-main > .tw-card-modal-body { padding: 0 16px 16px; overflow: visible; }
2105    #tw-checkout-root .tw-savecart-has-promo .tw-savecart-promo-img { max-height: 40vh; max-height: 40dvh; }
2106    .tw-savecart-has-promo .tw-savecart-promo-tag {
2107        position: absolute; left: 12px; top: 12px; z-index: 2;
2108        font-size: 13px; padding: 5px 12px 5px 10px; box-shadow: 0 4px 12px rgba(0, 0, 0, .28);
2109    }
2110    .tw-savecart-has-promo .tw-savecart-promo-note { display: none; }
2111    .tw-savecart-has-promo .tw-card-modal-close {
2112        top: 10px; right: 10px; width: 34px; height: 34px;
2113        background: rgba(255, 255, 255, .88); color: #374151; box-shadow: 0 2px 8px rgba(0, 0, 0, .18);
2114    }
2115    .tw-savecart-has-promo .tw-card-modal-header { padding: 16px 16px 10px; border-bottom: 0; }
2116    .tw-savecart-has-promo .tw-card-modal-header h3 { font-size: 17px; }
2117    
2118    .tw-savecart-has-promo .tw-savecart-full { display: none; }
2119    .tw-savecart-has-promo .tw-savecart-perks { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; margin: 0 0 14px; }
2120    .tw-savecart-has-promo .tw-savecart-sub { display: block; font-size: 12px; color: #6b7280; margin: 0 0 6px; }
2121    .tw-savecart-has-promo .tw-savecart-oauth { flex-direction: row; gap: 6px; margin: 0; }
2122    #tw-checkout-root .tw-savecart-has-promo .tw-savecart-oauth-btn { flex: 1 1 0; min-width: 0; height: 42px; padding: 0 4px; gap: 6px; font-size: 13px; letter-spacing: 0; }
2123    .tw-savecart-has-promo .tw-savecart-oauth-btn svg { width: 16px; height: 16px; flex: none; }
2124    .tw-savecart-has-promo .tw-savecart-long { display: none; }
2125    .tw-savecart-has-promo .tw-savecart-short { display: inline; }
2126    .tw-savecart-has-promo .tw-savecart-or { margin: 12px 0 10px; }
2127    .tw-savecart-has-promo .tw-savecart-save-inline { display: block; flex: none; width: 76px; height: 40px; border-radius: 10px; box-shadow: none; }
2128    
2129    .tw-savecart-has-promo .tw-savecart-field .tw-discount-input { margin: 0; }
2130    .tw-savecart-has-promo .tw-savecart-hint { display: block; font-size: 11.5px; color: #9ca3af; margin-top: 6px; }
2131}
2132
2133.event_card_mom          { background-image: url("//gcdn.phootime.com/static/images/shop/2025_card_mom.jpg"); }
2134.event_card_dad          { background-image: url("//gcdn.phootime.com/static/images/shop/2024_card_dad.jpg"); }
2135.event_card_teacher      { background-image: url("//gcdn.phootime.com/static/images/shop/2025_card_teacher.jpg"); }
2136.event_card_lover        { background-image: url("//gcdn.phootime.com/static/images/shop/2020_card_lover.jpg"); }
2137.event_card_valentine    { background-image: url("//gcdn.phootime.com/static/images/shop/2024_card_valentine.jpg"); }
2138.event_card_valentine_02 { background-image: url("//gcdn.phootime.com/static/images/shop/2023_card_lover.jpg"); }
2139.event_card_valentine_03 { background-image: url("//gcdn.phootime.com/static/images/shop/2024_card_valentine3.jpg"); }
2140.event_card_xmas_01      { background-image: url("//gcdn.phootime.com/static/images/shop/2025_card_xmas.jpg"); }
2141.event_card_xmas_02      { background-image: url("//gcdn.phootime.com/static/images/shop/2025_card_xmas2.jpg"); }
2142.event_card_bday         { background-image: url("//gcdn.phootime.com/static/images/shop/2023_card_bday.jpg"); }
2143.event_card_graduation   { background-image: url("//gcdn.phootime.com/static/images/shop/2023_card_graduation.jpg"); }
2144.event_card_thankyou     { background-image: url("//gcdn.phootime.com/static/images/shop/2023_card_thankyou.jpg"); }
2145.event_card_horoscope_01 { background-image: url("//gcdn.phootime.com/static/images/shop/horoscope_card_01.jpg"); }
2146.event_card_horoscope_02 { background-image: url("//gcdn.phootime.com/static/images/shop/horoscope_card_02.jpg"); }
2147.event_card_horoscope_03 { background-image: url("//gcdn.phootime.com/static/images/shop/horoscope_card_03.jpg"); }
2148.event_card_horoscope_04 { background-image: url("//gcdn.phootime.com/static/images/shop/horoscope_card_04.jpg"); }
2149.event_card_horoscope_05 { background-image: url("//gcdn.phootime.com/static/images/shop/horoscope_card_05.jpg"); }
2150.event_card_horoscope_06 { background-image: url("//gcdn.phootime.com/static/images/shop/horoscope_card_06.jpg"); }
2151.event_card_horoscope_07 { background-image: url("//gcdn.phootime.com/static/images/shop/horoscope_card_07.jpg"); }
2152.event_card_horoscope_08 { background-image: url("//gcdn.phootime.com/static/images/shop/horoscope_card_08.jpg"); }
2153.event_card_horoscope_09 { background-image: url("//gcdn.phootime.com/static/images/shop/horoscope_card_09.jpg"); }
2154.event_card_horoscope_10 { background-image: url("//gcdn.phootime.com/static/images/shop/horoscope_card_10.jpg"); }
2155.event_card_horoscope_11 { background-image: url("//gcdn.phootime.com/static/images/shop/horoscope_card_11.jpg"); }
2156.event_card_horoscope_12 { background-image: url("//gcdn.phootime.com/static/images/shop/horoscope_card_12.jpg"); }
2157
2158html, body {
2159    overflow-x: clip !important;
2160}
2161
2162body {
2163    background-color: #f7f7f9 !important;
2164}
2165
2166@media (max-width: 1024px) {
2167    body { min-width: 0 !important; }
2168}
2169
2170#tw-checkout-root [class*="col-span"],
2171#tw-checkout-root [class*="span"] {
2172    float: none !important;
2173    margin-left: 0 !important;
2174}
2175
2176@media (min-width: 768px) {
2177    #wrap {
2178        overflow: clip !important;
2179    }
2180}
2181#tw-checkout-root,
2182#tw-checkout-root > div,
2183#tw-checkout-root .grid,
2184#tw-checkout-root aside {
2185    overflow: visible !important;
2186}
2187@media (min-width: 768px) {
2188  
2189  #tw-checkout-root .sticky-summary {
2190      position: -webkit-sticky !important;
2191      position: sticky !important;
2192      top: 5rem !important;
2193  }
2194}
2195
2196@media (max-width: 767px) {
2197    footer .web-footer .link .col > h4 {
2198        cursor: pointer !important;
2199        position: relative !important;
2200        padding-right: 30px !important;
2201        margin-bottom: 0 !important;
2202    }
2203    footer .web-footer .link .col > h4::after {
2204        content: '+';
2205        position: absolute;
2206        right: 0.5em;
2207        top: 50%;
2208        transform: translateY(-50%);
2209        font-size: 1.4em;
2210        font-weight: 300;
2211        color: #9ca3af;
2212        line-height: 1;
2213        transition: transform .15s;
2214    }
2215    footer .web-footer .link .col.tw-fc-open > h4::after {
2216        content: '−';
2217    }
2218    footer .web-footer .link .col > ul {
2219        display: none !important;
2220    }
2221    footer .web-footer .link .col.tw-fc-open > ul {
2222        display: block !important;
2223    }
2224}
2225
2226footer .web-footer .col img.icon {
2227    display: inline-block !important;
2228    vertical-align: middle !important;
2229    width: auto !important;
2230    height: 18px !important;
2231    max-width: none !important;
2232}
2233
2234@media (min-width: 1200px) {
2235    footer .container.web-footer {
2236        width: auto !important;
2237        max-width: 72rem !important;
2238        padding-left: 1rem !important;
2239        padding-right: 1rem !important;
2240    }
2241}
2242
2243#tw-toast-stack {
2244    position: fixed; top: 1rem; right: 1rem; z-index: 100000;
2245    display: flex; flex-direction: column; gap: 0.5rem;
2246    pointer-events: none;
2247}
2248@media (max-width: 640px) {
2249    #tw-toast-stack { left: 1rem; right: 1rem; align-items: stretch; top: 0.75rem; }
2250}
2251.tw-toast {
2252    pointer-events: auto;
2253    background: #fff;
2254    border: 1px solid #e5e7eb;
2255    border-left-width: 4px;
2256    border-radius: 0.625rem;
2257    box-shadow: 0 6px 16px rgba(15, 23, 42, .08), 0 2px 4px rgba(15, 23, 42, .04);
2258    padding: 0.75rem 0.875rem;
2259    display: flex; align-items: flex-start; gap: 0.625rem;
2260    min-width: 280px; max-width: 380px;
2261    font-size: 0.875rem; line-height: 1.55; color: #1f2937;
2262    animation: tw-toast-in .25s cubic-bezier(.16,1,.3,1);
2263}
2264@media (max-width: 640px) {
2265    .tw-toast { min-width: 0; max-width: none; }
2266}
2267.tw-toast.tw-toast-leaving { animation: tw-toast-out .2s ease-in forwards; }
2268@keyframes tw-toast-in {
2269    from { opacity: 0; transform: translateX(20px) scale(.95); }
2270    to   { opacity: 1; transform: translateX(0) scale(1); }
2271}
2272@keyframes tw-toast-out {
2273    from { opacity: 1; transform: translateX(0); max-height: 200px; margin-bottom: .5rem; padding-top: .75rem; padding-bottom: .75rem; }
2274    to   { opacity: 0; transform: translateX(20px); max-height: 0; margin-bottom: 0; padding-top: 0; padding-bottom: 0; }
2275}
2276.tw-toast-icon { width: 18px; height: 18px; flex-shrink: 0; margin-top: 2px; }
2277.tw-toast-msg  { flex: 1; min-width: 0; word-wrap: break-word; }
2278.tw-toast-close {
2279    flex-shrink: 0; padding: 0; margin: -2px -4px 0 4px;
2280    background: transparent !important; border: 0 !important;
2281    color: #9ca3af !important; cursor: pointer;
2282    width: 22px; height: 22px;
2283    display: inline-flex; align-items: center; justify-content: center;
2284    border-radius: 4px;
2285}
2286.tw-toast-close:hover { color: #4b5563 !important; background: rgba(0,0,0,.04) !important; }
2287.tw-toast-close svg { width: 14px; height: 14px; }
2288.tw-toast-error   { border-left-color: #dc2626; }
2289.tw-toast-error   .tw-toast-icon { color: #dc2626; }
2290.tw-toast-success { border-left-color: #10b981; }
2291.tw-toast-success .tw-toast-icon { color: #10b981; }
2292.tw-toast-info    { border-left-color: #3b82f6; }
2293.tw-toast-info    .tw-toast-icon { color: #3b82f6; }
2294.tw-toast-warning { border-left-color: #f59e0b; }
2295.tw-toast-warning .tw-toast-icon { color: #f59e0b; }
2296
2297#tw-alert-modal {
2298    position: fixed; inset: 0; z-index: 100001;
2299    display: none; align-items: center; justify-content: center;
2300    padding: 1rem;
2301}
2302#tw-alert-modal.tw-alert-open { display: flex; }
2303.tw-alert-backdrop {
2304    position: absolute; inset: 0; background: rgba(15, 23, 42, .55);
2305    animation: tw-alert-fade .15s ease-out;
2306}
2307.tw-alert-panel {
2308    position: relative; background: #fff; border-radius: 1rem;
2309    width: 100%; max-width: 360px;
2310    box-shadow: 0 20px 50px rgba(0, 0, 0, .25);
2311    padding: 1.5rem; text-align: center;
2312    animation: tw-alert-pop .22s cubic-bezier(.16,1,.3,1);
2313}
2314@keyframes tw-alert-fade { from { opacity: 0; } to { opacity: 1; } }
2315@keyframes tw-alert-pop {
2316    from { opacity: 0; transform: scale(.92); }
2317    to   { opacity: 1; transform: scale(1); }
2318}
2319.tw-alert-icon {
2320    width: 48px; height: 48px; margin: 0 auto 0.875rem;
2321    display: flex; align-items: center; justify-content: center;
2322    border-radius: 9999px;
2323}
2324.tw-alert-icon svg { width: 28px; height: 28px; }
2325.tw-alert-icon-info     { background: #eff6ff; color: #3b82f6; }
2326.tw-alert-icon-question { background: #fef3c7; color: #d97706; }
2327.tw-alert-icon-warning  { background: #fee2e2; color: #dc2626; }
2328.tw-alert-icon-success  { background: #ecfdf5; color: #10b981; }
2329.tw-alert-msg {
2330    color: #1f2937; font-size: 0.95rem; line-height: 1.65;
2331    margin-bottom: 1.25rem; word-wrap: break-word; white-space: pre-wrap;
2332}
2333.tw-alert-actions { display: flex; gap: 0.5rem; justify-content: center; }
2334.tw-alert-btn {
2335    min-width: 88px;
2336    padding: 0.5rem 1rem;
2337    border-radius: 0.5rem;
2338    font-size: 0.875rem;
2339    font-weight: 500;
2340    cursor: pointer;
2341    border: 0;
2342    transition: background-color .15s;
2343}
2344.tw-alert-btn-primary {
2345    background: #ff7372 !important; color: #fff !important;
2346}
2347.tw-alert-btn-primary:hover { background: #ff5957 !important; }
2348.tw-alert-btn-secondary {
2349    background: #f3f4f6 !important; color: #4b5563 !important;
2350}
2351.tw-alert-btn-secondary:hover { background: #e5e7eb !important; }
2352</style>
2353
2354
2355<div id="tw-checkout-root" class="min-h-screen pb-32 md:pb-28" style="background:#f7f7f9;">
2356  <div class="max-w-6xl mx-auto px-4 py-6 md:py-10">
2357
2358    
2359
2360    
2361        <div class="mb-4 md:mb-8">
2362      <ol class="flex items-center justify-center gap-2 md:gap-4 text-xs md:text-sm">
2363                <li class="flex items-center gap-2">
2364          <span class="w-7 h-7 md:w-8 md:h-8 rounded-full flex items-center justify-center font-semibold" style="background:#ff7372;color:#fff;">1</span>
2365          <span style="color:#111827;font-weight:500;">前往購物車</span>
2366        </li>
2367                <li class="w-8 md:w-12 h-px" style="background:#d1d5db;"></li>
2368        <li class="flex items-center gap-2">
2369          <span class="w-7 h-7 md:w-8 md:h-8 rounded-full flex items-center justify-center font-semibold" style="background:#e5e7eb;color:#6b7280;">2</span>
2370          <span style="color:#9ca3af;">結帳</span>
2371        </li>
2372        <li class="w-8 md:w-12 h-px" style="background:#d1d5db;"></li>
2373        <li class="flex items-center gap-2">
2374          <span class="w-7 h-7 md:w-8 md:h-8 rounded-full flex items-center justify-center font-semibold" style="background:#e5e7eb;color:#6b7280;">3</span>
2375          <span style="color:#9ca3af;">付款完成</span>
2376        </li>
2377      </ol>
2378    </div>
2379
2380    
2381    
2382    
2383    <div class="bg-white rounded-2xl shadow-sm p-12 md:p-20 text-center">
2384      <svg class="mx-auto mb-6 w-24 h-24" viewBox="0 0 96 96" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
2385        <path d="M18 30 H78 L73 82 C72.7 85 70.5 87 67.5 87 H28.5 C25.5 87 23.3 85 23 82 Z" fill="#ffe1e1"/>
2386        <path d="M18 30 H78 L73 82 C72.7 85 70.5 87 67.5 87 H28.5 C25.5 87 23.3 85 23 82 Z" stroke="#ff7372" stroke-width="3" stroke-linejoin="round"/>
2387        <path d="M34 30 V22 C34 14.5 40.3 9 48 9 C55.7 9 62 14.5 62 22 V30" stroke="#ff7372" stroke-width="3.5" stroke-linecap="round" fill="none"/>
2388        <circle cx="40" cy="50" r="2" fill="#ff7372"/>
2389        <circle cx="56" cy="50" r="2" fill="#ff7372"/>
2390        <path d="M40 60 Q48 67 56 60" stroke="#ff7372" stroke-width="2.5" stroke-linecap="round" fill="none"/>
2391      </svg>
2392      <h2 class="text-xl md:text-2xl font-medium text-gray-700">你的購物車中沒有商品</h2>
2393      <div class="flex flex-wrap justify-center gap-x-3 gap-y-4" style="margin-top: 40px !important;">
2394        <a href="/" class="inline-flex items-center justify-center px-8 h-12 rounded-full font-medium transition"
2395           style="background:#ff7372; color:#fff; box-shadow:0 4px 12px rgba(255,115,114,.3);"
2396           onmouseover="this.style.background='#ff5957'" onmouseout="this.style.background='#ff7372'">
2397          繼續選購          <span style="margin-left:6px;">→</span>
2398        </a>
2399                <a href="/member/login?next=%2Fcart"
2400           class="inline-flex items-center justify-center px-8 h-12 rounded-full font-medium transition"
2401           style="background:#fff; color:#ff7372; border:1.5px solid #ff7372;"
2402           onmouseover="this.style.background='#fff5f5'" onmouseout="this.style.background='#fff'">
2403          登入查看購物車        </a>
2404              </div>
2405    </div>
2406
2407  </div>
2408
2409  
2410    <div id="tw-card-modal" class="tw-card-modal" style="display:none;">
2411    <div class="tw-card-modal-backdrop" onclick="twCardModalClose()"></div>
2412    <div class="tw-card-modal-panel" role="dialog" aria-modal="true" aria-label="免費兌換卡片一張">
2413      <button type="button" class="tw-card-modal-close" onclick="twCardModalClose()" aria-label="Close">
2414        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"/></svg>
2415      </button>
2416
2417      
2418      <div id="tw-card-step-1" class="tw-card-step">
2419        <div class="tw-card-modal-header">
2420          <h3>免費兌換卡片一張</h3>
2421          <p>請選擇一張您想要的卡片</p>
2422        </div>
2423        <div class="tw-card-grid">
2424                    <button type="button" class="tw-card-tile" data-card-type="3" data-card-label="母親節卡" data-card-css="event_card_mom" onclick="twCardPick(this)">
2425            <div class="tw-card-tile-img event_card_mom"></div>
2426            <div class="tw-card-tile-label">母親節卡</div>
2427          </button>
2428                    <button type="button" class="tw-card-tile" data-card-type="25" data-card-label="情人卡" data-card-css="event_card_valentine_03" onclick="twCardPick(this)">
2429            <div class="tw-card-tile-img event_card_valentine_03"></div>
2430            <div class="tw-card-tile-label">情人卡</div>
2431          </button>
2432                    <button type="button" class="tw-card-tile" data-card-type="24" data-card-label="情人卡" data-card-css="event_card_valentine" onclick="twCardPick(this)">
2433            <div class="tw-card-tile-img event_card_valentine"></div>
2434            <div class="tw-card-tile-label">情人卡</div>
2435          </button>
2436                    <button type="button" class="tw-card-tile" data-card-type="2" data-card-label="情人卡" data-card-css="event_card_valentine_02" onclick="twCardPick(this)">
2437            <div class="tw-card-tile-img event_card_valentine_02"></div>
2438            <div class="tw-card-tile-label">情人卡</div>
2439          </button>
2440                    <button type="button" class="tw-card-tile" data-card-type="20" data-card-label="聖誕卡" data-card-css="event_card_xmas_01" onclick="twCardPick(this)">
2441            <div class="tw-card-tile-img event_card_xmas_01"></div>
2442            <div class="tw-card-tile-label">聖誕卡</div>
2443          </button>
2444                    <button type="button" class="tw-card-tile" data-card-type="21" data-card-label="聖誕卡" data-card-css="event_card_xmas_02" onclick="twCardPick(this)">
2445            <div class="tw-card-tile-img event_card_xmas_02"></div>
2446            <div class="tw-card-tile-label">聖誕卡</div>
2447          </button>
2448                    <button type="button" class="tw-card-tile" data-card-type="26" data-card-label="教師節卡" data-card-css="event_card_teacher" onclick="twCardPick(this)">
2449            <div class="tw-card-tile-img event_card_teacher"></div>
2450            <div class="tw-card-tile-label">教師節卡</div>
2451          </button>
2452                    <button type="button" class="tw-card-tile" data-card-type="5" data-card-label="父親節卡" data-card-css="event_card_dad" onclick="twCardPick(this)">
2453            <div class="tw-card-tile-img event_card_dad"></div>
2454            <div class="tw-card-tile-label">父親節卡</div>
2455          </button>
2456                    <button type="button" class="tw-card-tile" data-card-type="23" data-card-label="畢業卡" data-card-css="event_card_graduation" onclick="twCardPick(this)">
2457            <div class="tw-card-tile-img event_card_graduation"></div>
2458            <div class="tw-card-tile-label">畢業卡</div>
2459          </button>
2460                    <button type="button" class="tw-card-tile" data-card-type="4" data-card-label="情人卡" data-card-css="event_card_lover" onclick="twCardPick(this)">
2461            <div class="tw-card-tile-img event_card_lover"></div>
2462            <div class="tw-card-tile-label">情人卡</div>
2463          </button>
2464                    <button type="button" class="tw-card-tile" data-card-type="22" data-card-label="感謝卡" data-card-css="event_card_thankyou" onclick="twCardPick(this)">
2465            <div class="tw-card-tile-img event_card_thankyou"></div>
2466            <div class="tw-card-tile-label">感謝卡</div>
2467          </button>
2468                    <button type="button" class="tw-card-tile" data-card-type="6" data-card-label="生日卡" data-card-css="event_card_bday" onclick="twCardPick(this)">
2469            <div class="tw-card-tile-img event_card_bday"></div>
2470            <div class="tw-card-tile-label">生日卡</div>
2471          </button>
2472                    <button type="button" class="tw-card-tile" data-card-type="7" data-card-label="摩羯卡" data-card-css="event_card_horoscope_10" onclick="twCardPick(this)">
2473            <div class="tw-card-tile-img event_card_horoscope_10"></div>
2474            <div class="tw-card-tile-label">摩羯卡</div>
2475          </button>
2476                    <button type="button" class="tw-card-tile" data-card-type="8" data-card-label="水瓶卡" data-card-css="event_card_horoscope_11" onclick="twCardPick(this)">
2477            <div class="tw-card-tile-img event_card_horoscope_11"></div>
2478            <div class="tw-card-tile-label">水瓶卡</div>
2479          </button>
2480                    <button type="button" class="tw-card-tile" data-card-type="9" data-card-label="雙魚卡" data-card-css="event_card_horoscope_12" onclick="twCardPick(this)">
2481            <div class="tw-card-tile-img event_card_horoscope_12"></div>
2482            <div class="tw-card-tile-label">雙魚卡</div>
2483          </button>
2484                    <button type="button" class="tw-card-tile" data-card-type="10" data-card-label="牡羊卡" data-card-css="event_card_horoscope_01" onclick="twCardPick(this)">
2485            <div class="tw-card-tile-img event_card_horoscope_01"></div>
2486            <div class="tw-card-tile-label">牡羊卡</div>
2487          </button>
2488                    <button type="button" class="tw-card-tile" data-card-type="11" data-card-label="金牛卡" data-card-css="event_card_horoscope_02" onclick="twCardPick(this)">
2489            <div class="tw-card-tile-img event_card_horoscope_02"></div>
2490            <div class="tw-card-tile-label">金牛卡</div>
2491          </button>
2492                    <button type="button" class="tw-card-tile" data-card-type="12" data-card-label="雙子卡" data-card-css="event_card_horoscope_03" onclick="twCardPick(this)">
2493            <div class="tw-card-tile-img event_card_horoscope_03"></div>
2494            <div class="tw-card-tile-label">雙子卡</div>
2495          </button>
2496                    <button type="button" class="tw-card-tile" data-card-type="13" data-card-label="巨蟹卡" data-card-css="event_card_horoscope_04" onclick="twCardPick(this)">
2497            <div class="tw-card-tile-img event_card_horoscope_04"></div>
2498            <div class="tw-card-tile-label">巨蟹卡</div>
2499          </button>
2500                    <button type="button" class="tw-card-tile" data-card-type="14" data-card-label="獅子卡" data-card-css="event_card_horoscope_05" onclick="twCardPick(this)">
2501            <div class="tw-card-tile-img event_card_horoscope_05"></div>
2502            <div class="tw-card-tile-label">獅子卡</div>
2503          </button>
2504                    <button type="button" class="tw-card-tile" data-card-type="15" data-card-label="處女卡" data-card-css="event_card_horoscope_06" onclick="twCardPick(this)">
2505            <div class="tw-card-tile-img event_card_horoscope_06"></div>
2506            <div class="tw-card-tile-label">處女卡</div>
2507          </button>
2508                    <button type="button" class="tw-card-tile" data-card-type="16" data-card-label="天秤卡" data-card-css="event_card_horoscope_07" onclick="twCardPick(this)">
2509            <div class="tw-card-tile-img event_card_horoscope_07"></div>
2510            <div class="tw-card-tile-label">天秤卡</div>
2511          </button>
2512                    <button type="button" class="tw-card-tile" data-card-type="17" data-card-label="天蠍卡" data-card-css="event_card_horoscope_08" onclick="twCardPick(this)">
2513            <div class="tw-card-tile-img event_card_horoscope_08"></div>
2514            <div class="tw-card-tile-label">天蠍卡</div>
2515          </button>
2516                    <button type="button" class="tw-card-tile" data-card-type="18" data-card-label="射手卡" data-card-css="event_card_horoscope_09" onclick="twCardPick(this)">
2517            <div class="tw-card-tile-img event_card_horoscope_09"></div>
2518            <div class="tw-card-tile-label">射手卡</div>
2519          </button>
2520                  </div>
2521      </div>
2522
2523      
2524      <div id="tw-card-step-2" class="tw-card-step" style="display:none;">
2525        <div class="tw-card-modal-header">
2526          <button type="button" class="tw-card-back" onclick="twCardBack()" aria-label="Back">
2527            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7"/></svg>
2528            <span>返回挑選</span>
2529          </button>
2530          <h3 id="tw-card-picked-label">寫卡片</h3>
2531        </div>
2532        <div class="tw-card-preview-wrap">
2533          <div id="tw-card-preview" class="tw-card-preview"></div>
2534        </div>
2535        <div class="tw-card-msg-wrap">
2536          <label for="tw-card-msg-input" class="tw-card-msg-label">想對對方說的話</label>
2537          <textarea id="tw-card-msg-input" class="tw-card-msg-input" rows="3" maxlength="55" placeholder="請在這裡輸入想說的話"></textarea>
2538          <div class="tw-card-msg-meta">
2539            <span class="tw-card-msg-hint">最多 3 行,55 字內,請勿使用表情符號</span>
2540            <span class="tw-card-msg-count"><span id="tw-card-msg-count-num">0</span>/55</span>
2541          </div>
2542        </div>
2543        <div class="tw-card-actions">
2544          <button type="button" class="tw-card-btn-secondary" onclick="twCardCancelRedeem()">取消兌換</button>
2545          <button type="button" class="tw-card-btn-primary" onclick="twCardSave()">儲存卡片</button>
2546        </div>
2547      </div>
2548    </div>
2549  </div>
2550  
2551  
2552  
2553  
2554  </div>
2555
2556<script>
2557(function(){
2558  var CSRF_NAME = "CSRF_TOKEN";
2559  var CSRF_VAL  = "aff6f94ebfb88b50587cbbdc0d8f3a8703775ab7";
2560  var ORDER_ID  = null;
2561
2562  var URLS = {
2563    deleteitem:           "\/shopping\/deleteitem",
2564    addonadd:             "\/shopping\/add",
2565    changequantity:       "\/shopping\/changequantity",
2566    discount:             "\/shopping\/discount",
2567    removediscount:       "\/shopping\/removediscount",
2568    savepreviewopt:       "\/shopping\/savepreviewopt",
2569    savehaslogo:          "\/shopping\/savehaslogo",
2570    saveshippingcountry:  "\/shopping\/saveshippingcountry",
2571    shippingfee:          "\/shopping\/shippingfee",
2572    savecity:             "\/shopping\/savecity",
2573    savezipcode:          "\/shopping\/savezipcode",
2574    saveemail:            "\/shopping\/saveemail",
2575    savephone:            "\/shopping\/savephone",
2576    savebuyername:        "\/shopping\/savebuyername",
2577    saverecipientname:    "\/shopping\/saverecipientname",
2578    saverecipientphone:   "\/shopping\/saverecipientphone",
2579    saveaddress:          "\/shopping\/saveaddress",
2580    savenote:             "\/shopping\/savenote",
2581    savevatnumber:        "\/shopping\/savevatnumber",
2582    savevattitle:         "\/shopping\/savevattitle",
2583    savemomcard:          "\/shopping\/savemomcard",
2584    sendemailverify:      "\/shopping\/sendemailverification",
2585    verifyemail:          "\/shopping\/verifyemail",
2586    checkmobilebarcode:   "\/shopping\/checkmobilebarcode",
2587    redeemmemberpoints:   "\/shopping\/redeemMemberPoints",
2588    refundmemberpoints:   "\/shopping\/refundMemberPoints",
2589    saveoutputmode:       "\/shopping\/saveoutputmode"  };
2590
2591  
2592  var TW_FUNNEL_BASE = {
2593    step:          "1",
2594    items:         0,
2595    amount:        0,
2596    deliver_by:    1,
2597    is_member:     0,
2598    freeship:      "short_0",
2599    has_esd:       0  };
2600  function _twFunnel(name, params) {
2601    try {
2602      if (typeof window.pt_track !== 'function') return;
2603      var p = {};
2604      for (var k in TW_FUNNEL_BASE) if (TW_FUNNEL_BASE.hasOwnProperty(k)) p[k] = TW_FUNNEL_BASE[k];
2605      p.device = (window.innerWidth < 1024) ? 'mobile' : 'desktop';
2606      if (params) for (var j in params) if (params.hasOwnProperty(j)) p[j] = params[j];
2607      pt_track(name, p);
2608    } catch (e) {}
2609  }
2610  window._twFunnel = _twFunnel;
2611
2612  _twFunnel('checkout_funnel_view');
2613
2614  document.addEventListener('click', function(e){
2615    var a = e.target && e.target.closest && e.target.closest('a[href]');
2616    if (!a) return;
2617    var href = a.getAttribute('href') || '';
2618    if (/step[\/=]2(\b|$)/.test(href))       _twFunnel('checkout_to_step2');
2619    else if (href.indexOf('/cvsmap/') > -1)  _twFunnel('checkout_cvs_open');
2620  }, true);
2621
2622  try {
2623    if (typeof IntersectionObserver === 'function') {
2624      var esdEl = document.getElementById('js-summary-shipping-dates');
2625      if (esdEl) {
2626        var esdSeen = false;
2627        var esdObs = new IntersectionObserver(function(entries){
2628          for (var i = 0; i < entries.length; i++) {
2629            if (entries[i].isIntersecting && !esdSeen) {
2630              esdSeen = true;
2631              _twFunnel('checkout_esd_seen');
2632              esdObs.disconnect();
2633            }
2634          }
2635        }, { threshold: 0.6 });
2636        esdObs.observe(esdEl);
2637      }
2638    }
2639  } catch (e) {}
2640
2641  
2642  function _twEnsureToastStack() {
2643    var stack = document.getElementById('tw-toast-stack');
2644    if (!stack) { stack = document.createElement('div'); stack.id = 'tw-toast-stack'; document.body.appendChild(stack); }
2645    return stack;
2646  }
2647  window.twToast = function(msg, type, opts) {
2648    type = type || 'info';
2649    opts = opts || {};
2650
2651    if (type === 'error' && typeof _twFunnel === 'function')
2652      _twFunnel('checkout_error', { reason: String(msg || '').replace(/<[^>]*>/g, '').slice(0, 60) });
2653    var duration = opts.duration != null ? opts.duration : (type === 'error' || type === 'warning' ? 5000 : 3500);
2654    var icons = {
2655      error:   '<path d="M12 9v3.75m0 3.75h.008m-.008-7.5L4.07 19.5a1.5 1.5 0 0 0 1.302 2.25h13.256a1.5 1.5 0 0 0 1.302-2.25L13.06 5.25a1.5 1.5 0 0 0-2.6 0L8.65 8.625"/>',
2656      success: '<path d="m4.5 12.75 6 6 9-13.5"/>',
2657      info:    '<path d="M11.25 11.25l.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z"/>',
2658      warning: '<path d="M12 9v3.75m9-.75a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 3.75h.008v.008H12v-.008Z"/>'
2659    };
2660    var t = document.createElement('div');
2661    t.className = 'tw-toast tw-toast-' + type;
2662    t.innerHTML =
2663      '<svg class="tw-toast-icon" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24">' + (icons[type] || icons.info) + '</svg>' +
2664      '<div class="tw-toast-msg"></div>' +
2665      '<button type="button" class="tw-toast-close" aria-label="Close"><svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"/></svg></button>';
2666    t.querySelector('.tw-toast-msg').textContent = msg;
2667    var dismiss = function(){
2668      if (t._dismissed) return; t._dismissed = true;
2669      t.classList.add('tw-toast-leaving');
2670      setTimeout(function(){ if (t.parentNode) t.parentNode.removeChild(t); }, 200);
2671    };
2672    t.querySelector('.tw-toast-close').addEventListener('click', dismiss);
2673    if (duration > 0) setTimeout(dismiss, duration);
2674    _twEnsureToastStack().appendChild(t);
2675    return dismiss;
2676  };
2677
2678  
2679  function _twAlertEnsure() {
2680    var m = document.getElementById('tw-alert-modal');
2681    if (m) return m;
2682    m = document.createElement('div');
2683    m.id = 'tw-alert-modal';
2684    m.innerHTML =
2685      '<div class="tw-alert-backdrop"></div>' +
2686      '<div class="tw-alert-panel" role="alertdialog" aria-modal="true">' +
2687        '<div class="tw-alert-icon" id="tw-alert-icon-wrap"></div>' +
2688        '<div class="tw-alert-msg" id="tw-alert-msg"></div>' +
2689        '<div class="tw-alert-actions" id="tw-alert-actions"></div>' +
2690      '</div>';
2691    document.body.appendChild(m);
2692    return m;
2693  }
2694  function _twAlertOpen(opts) {
2695    return new Promise(function(resolve){
2696      var m = _twAlertEnsure();
2697      var iconWrap = m.querySelector('#tw-alert-icon-wrap');
2698      var msgEl    = m.querySelector('#tw-alert-msg');
2699      var actions  = m.querySelector('#tw-alert-actions');
2700      var iconSvg = {
2701        info:     '<svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M11.25 11.25l.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z"/></svg>',
2702        question: '<svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 5.25h.008v.008H12v-.008Z"/></svg>',
2703        warning:  '<svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.008v.008H12v-.008Z"/></svg>',
2704        success:  '<svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/></svg>'
2705      };
2706      var iconType = opts.icon || (opts.confirm ? 'question' : 'warning');
2707      iconWrap.className = 'tw-alert-icon tw-alert-icon-' + iconType;
2708      iconWrap.innerHTML = iconSvg[iconType] || iconSvg.info;
2709      msgEl.textContent = opts.msg || '';
2710      actions.innerHTML = '';
2711      function close(result){
2712        m.classList.remove('tw-alert-open');
2713        twUnlockScroll();
2714        document.removeEventListener('keydown', onKey);
2715        resolve(result);
2716      }
2717      function onKey(e){
2718        if (e.key === 'Escape') { e.preventDefault(); close(opts.confirm ? false : undefined); }
2719        else if (e.key === 'Enter') { e.preventDefault(); close(opts.confirm ? true : undefined); }
2720      }
2721      if (opts.confirm) {
2722        var cancelBtn = document.createElement('button');
2723        cancelBtn.type = 'button';
2724        cancelBtn.className = 'tw-alert-btn tw-alert-btn-secondary';
2725        cancelBtn.textContent = opts.cancelText || '取消';
2726        cancelBtn.addEventListener('click', function(){ close(false); });
2727        actions.appendChild(cancelBtn);
2728      }
2729      var okBtn = document.createElement('button');
2730      okBtn.type = 'button';
2731      okBtn.className = 'tw-alert-btn tw-alert-btn-primary';
2732      okBtn.textContent = opts.okText || 'OK';
2733      okBtn.addEventListener('click', function(){ close(opts.confirm ? true : undefined); });
2734      actions.appendChild(okBtn);
2735      m.classList.add('tw-alert-open');
2736      twLockScroll();
2737      document.addEventListener('keydown', onKey);
2738      setTimeout(function(){ try { okBtn.focus(); } catch(e){} }, 50);
2739    });
2740  }
2741  window.twAlert   = function(msg, opts) { opts = opts || {}; return _twAlertOpen({ msg: msg, confirm: false, icon: opts.icon, okText: opts.okText }); };
2742  window.twConfirm = function(msg, opts) { opts = opts || {}; return _twAlertOpen({ msg: msg, confirm: true,  icon: opts.icon || 'question', okText: opts.okText, cancelText: opts.cancelText }); };
2743
2744  
2745  var __twSessionExpiredShown = false;
2746  function _twHandleSessionExpired() {
2747    if (__twSessionExpiredShown) return;
2748    __twSessionExpiredShown = true;
2749    twAlert('您的畫面停留太久已逾時,請重新整理頁面再試一次。', { icon: 'warning' })
2750      .then(function(){ try { location.reload(); } catch(e){} });
2751  }
2752  function postForm(url, data, onSuccess, onError) {
2753    data = data || {};
2754    data[CSRF_NAME] = CSRF_VAL;
2755    var fd = new FormData();
2756    Object.keys(data).forEach(function(k){ fd.append(k, data[k]); });
2757
2758    var safeUrl = url;
2759    try {
2760      var u = new URL(url, window.location.href);
2761      if (u.origin !== window.location.origin) {
2762        safeUrl = u.pathname + u.search;
2763      }
2764    } catch (e) {  }
2765    fetch(safeUrl, {
2766      method: 'POST',
2767      body: fd,
2768      credentials: 'same-origin',
2769      headers: { 'X-Requested-With': 'XMLHttpRequest' }  // Yii::isAjaxRequest 判斷依據
2770    })
2771      .then(function(r){
2772        return r.text().then(function(t){
2773          var parsed;
2774          try { parsed = JSON.parse(t); } catch(e){ parsed = { _raw: t, ok: r.ok, _httpStatus: r.status }; }
2775
2776          if (r.status === 401 || r.status === 403 || (r.status === 400 && /CSRF|csrf|X-CSRF/.test(t))) {
2777            _twHandleSessionExpired();
2778            return null;
2779          }
2780
2781          if (!r.ok && r.status >= 500) {
2782            console.warn('server error', r.status, safeUrl);
2783          }
2784
2785          if (parsed && parsed._raw && /<html|<!doctype|sign in|login/i.test(parsed._raw) && parsed._raw.length > 100) {
2786            _twHandleSessionExpired();
2787            return null;
2788          }
2789          return parsed;
2790        });
2791      })
2792      .then(function(d){ if (d == null) return; if (onSuccess) onSuccess(d); })
2793      .catch(function(e){
2794        console.error('postForm failed:', safeUrl, e);
2795        if (onError) onError(e);
2796        else { twToast('網路錯誤,請重試 (' + safeUrl + ')', 'error'); }
2797      });
2798  }
2799
2800  window.twDeleteItem = async function(itemId) {
2801    if (!(await twConfirm('確認刪除?'))) return;
2802    postForm(URLS.deleteitem, { id: itemId }, function(d){
2803
2804      location.reload();
2805    });
2806  };
2807
2808  
2809  var CURRENCY_PREFIX = "$";
2810  function fmtMoney(n) {
2811    var v = Math.round(parseFloat(n) || 0);
2812    return CURRENCY_PREFIX + v.toLocaleString('en-US');
2813  }
2814
2815  
2816  function isOk(d) { return d && (d.status === 1 || d.status === '1' || d.status === true); }
2817
2818  
2819  
2820  function _twUpdateFeeRow(rowId, amtId, value) {
2821    var row = document.getElementById(rowId);
2822    var amt = document.getElementById(amtId);
2823    if (!row || !amt) return;
2824    var n = parseFloat(value) || 0;
2825    if (n > 0) {
2826      amt.textContent = fmtMoney(n);
2827      row.style.display = '';
2828    } else {
2829      row.style.display = 'none';
2830    }
2831  }
2832  
2833  var FREE_SHIP_DELIVER_OPTS = [1,7,102,103];
2834  var _twFreeShipSubtotal = 0;
2835
2836  var _twMinFreeShipOverride = null;
2837  function _twUpdateFreeShipBanner(subtotal) {
2838    var banner = document.getElementById('js-summary-free-ship-banner');
2839    if (!banner) return;
2840    if (banner.getAttribute('data-eligible') !== '1') return;
2841    if (subtotal !== undefined && subtotal !== null) _twFreeShipSubtotal = parseFloat(subtotal) || 0;
2842    if (_twMinFreeShipOverride !== null) banner.setAttribute('data-min-free-ship', _twMinFreeShipOverride);
2843    var curDeliver = parseInt((document.getElementById('delivery_options') || {}).value, 10);
2844    if (FREE_SHIP_DELIVER_OPTS.indexOf(curDeliver) === -1) {
2845      banner.style.display = 'none';
2846      return;
2847    }
2848    var minAmt = parseInt(banner.getAttribute('data-min-free-ship'), 10) || 0;
2849    var sub = _twFreeShipSubtotal;
2850    var need = document.getElementById('js-freeship-need');
2851    var done = document.getElementById('js-freeship-done');
2852    var diff = document.getElementById('js-freeship-diff');
2853    var fill = document.getElementById('js-freeship-fill');
2854    var link = document.getElementById('js-freeship-addon-link');
2855    var reached = (minAmt > 0 && sub >= minAmt);
2856    banner.style.display = '';
2857    banner.style.background = reached ? '#ecfdf5' : '#fffbeb';
2858    if (fill) {
2859      fill.style.width = (minAmt > 0 ? Math.min(100, sub / minAmt * 100) : 100) + '%';
2860      fill.style.background = reached ? '#34d399' : '#f59e0b';
2861    }
2862    if (need) need.style.display = reached ? 'none' : '';
2863    if (done) done.style.display = reached ? '' : 'none';
2864    if (link) link.style.display = reached ? 'none' : '';
2865    if (diff && !reached) diff.textContent = Math.ceil(minAmt - sub).toLocaleString('en-US');
2866  }
2867  function applyTotals(d) {
2868    if (!isOk(d)) return;
2869    var $ = function(id){ return document.getElementById(id); };
2870    if (d.subtotal_amount != null && $('js-summary-subtotal'))
2871      $('js-summary-subtotal').textContent = fmtMoney(d.subtotal_amount);
2872    if (d.shipping_fee != null && $('js-summary-shipping')) {
2873      var shipEl = $('js-summary-shipping');
2874      var fee = parseFloat(d.shipping_fee) || 0;
2875      if (fee > 0) shipEl.textContent = fmtMoney(fee);
2876      else shipEl.innerHTML = '<span class="text-emerald-600">免運</span>';
2877    }
2878    if (d.total_amount != null) {
2879      var t = Math.round(parseFloat(d.total_amount) || 0).toLocaleString('en-US');
2880      if ($('js-summary-total')) $('js-summary-total').textContent = t;
2881      if ($('js-mobile-total')) $('js-mobile-total').textContent = CURRENCY_PREFIX + t;
2882    }
2883
2884    if (d.promotion_lines !== undefined) {
2885      var promoWrap = $('js-summary-promotion-wrap');
2886      if (promoWrap) {
2887        promoWrap.innerHTML = '';
2888        (d.promotion_lines || []).forEach(function(line){
2889          var row = document.createElement('div');
2890          row.className = 'flex justify-between text-amber-700';
2891          var dt = document.createElement('dt');
2892          dt.appendChild(document.createTextNode("\u512a\u60e0\u6298\u62b5"));
2893          var sub = document.createElement('span');
2894          sub.className = 'block text-gray-400 text-[11px]';
2895          sub.textContent = line.title || '';
2896          dt.appendChild(sub);
2897          var dd = document.createElement('dd');
2898          dd.textContent = '−' + fmtMoney(line.discount);
2899          row.appendChild(dt);
2900          row.appendChild(dd);
2901          promoWrap.appendChild(row);
2902        });
2903      }
2904    }
2905
2906    if (d.engraving_amount !== undefined) _twUpdateFeeRow('js-summary-engraving-row', 'js-summary-engraving', d.engraving_amount);
2907    if (d.qrcode_amount    !== undefined) _twUpdateFeeRow('js-summary-qrcode-row',    'js-summary-qrcode',    d.qrcode_amount);
2908    if (d.ai_amount        !== undefined) _twUpdateFeeRow('js-summary-ai-row',        'js-summary-ai',        d.ai_amount);
2909
2910    if (d.min_free_ship_amount !== undefined && d.min_free_ship_amount !== null)
2911      _twMinFreeShipOverride = parseInt(d.min_free_ship_amount, 10) || 0;
2912    if (d.subtotal_amount !== undefined) _twUpdateFreeShipBanner(d.subtotal_amount);
2913    else if (d.min_free_ship_amount !== undefined) _twUpdateFreeShipBanner();
2914
2915    if (d.redeem_points !== undefined) {
2916      var redeemNum  = document.querySelector('#tw-mp-row .tw-mp-redeem-amt-num');
2917      var redeemWrap = document.querySelector('#tw-mp-row .tw-mp-redeem-amt');
2918      if (redeemNum && redeemWrap) {
2919        var rp = parseFloat(d.redeem_points) || 0;
2920        if (rp > 0) {
2921          redeemNum.textContent = Math.round(rp).toLocaleString('en-US');
2922          redeemWrap.classList.remove('hidden');
2923          var btn = document.getElementById('tw-mp-toggle');
2924          if (btn) { btn.setAttribute('data-state', '1'); btn.setAttribute('aria-pressed', 'true'); }
2925        } else {
2926          redeemWrap.classList.add('hidden');
2927          var btn0 = document.getElementById('tw-mp-toggle');
2928          if (btn0) { btn0.setAttribute('data-state', '0'); btn0.setAttribute('aria-pressed', 'false'); }
2929        }
2930      }
2931    }
2932
2933    if (d.member_points_redeemable !== undefined) {
2934      document.querySelectorAll('#tw-mp-row .member_points_redeemable').forEach(function(el){
2935        el.textContent = (parseInt(d.member_points_redeemable, 10) || 0).toLocaleString('en-US');
2936      });
2937    }
2938    if (d.member_points_balance !== undefined) {
2939      var bal = document.getElementById('tw-member-points-balance');
2940      if (bal) bal.value = d.member_points_balance;
2941    }
2942
2943  }
2944
2945  window.twChangeQty = function(itemId, delta) {
2946    var inp = document.getElementById(itemId + '_q');
2947    if (!inp) return;
2948    var v = parseInt(inp.value, 10) || 1;
2949    v += delta;
2950    if (v < 1) v = 1;
2951    inp.value = v;
2952    twChangeQtyInput(inp, itemId);
2953  };
2954
2955  window.twChangeQtyInput = function(inp, itemId) {
2956    var q = parseInt(inp.value, 10) || 1;
2957    if (q < 1) q = 1;
2958    inp.value = q;
2959    postForm(URLS.changequantity, { id: itemId, quantity: q }, function(d){
2960      if (!isOk(d)) {
2961        var em = (d && (d.error || d.msg)) || 'Network error, please retry.';
2962        twToast(em, 'error');
2963        if (inp.dataset.oldvalue) inp.value = inp.dataset.oldvalue;
2964        return;
2965      }
2966
2967      if (d.item_amount != null) {
2968        var line = document.querySelector('.js-line-total[data-item-id="' + itemId + '"]');
2969        if (line) line.textContent = fmtMoney(d.item_amount);
2970      }
2971      inp.dataset.oldvalue = q;
2972      applyTotals(d);
2973
2974      _twHandleGiftDiscount(d.refund_gifts, d.change_gifts);
2975      _twHandleSetGift(d);
2976      if (d.campaign_discount_amount !== undefined) _twUpdateCampaignDiscount(d.campaign_discount_amount);
2977
2978      if (d.wood_sold_out) {
2979        twToast('部分商品庫存不足,請調整訂購數量', 'warning');
2980      }
2981    });
2982  };
2983
2984  window.twSamePhone = function() {
2985    var p = document.getElementById('phone');
2986    var rp = document.getElementById('recipient_phone');
2987    if (p && rp) rp.value = p.value;
2988  };
2989
2990  function _twSyncRecipientPhone() {
2991    var p = document.getElementById('phone');
2992    var rp = document.getElementById('recipient_phone');
2993    if (p && rp) rp.value = p.value;
2994  }
2995  window.twToggleSamePhone = function(cb) {
2996    var p = document.getElementById('phone');
2997    var rp = document.getElementById('recipient_phone');
2998    if (!p || !rp) return;
2999    if (cb.checked) {
3000      rp.dataset.prevValue = rp.value;
3001      rp.value = p.value;
3002      rp.readOnly = true;
3003      rp.style.background = '#f3f4f6';
3004
3005      p.addEventListener('input', _twSyncRecipientPhone);
3006      p.addEventListener('change', _twSyncRecipientPhone);
3007
3008      var v = (rp.value || '').trim();
3009      if (v) postForm(URLS.saverecipientphone, { order_id: ORDER_ID, recipient_phone: v }, function(){});
3010    } else {
3011      rp.value = rp.dataset.prevValue || rp.value;
3012      rp.readOnly = false;
3013      rp.style.background = '';
3014      p.removeEventListener('input', _twSyncRecipientPhone);
3015      p.removeEventListener('change', _twSyncRecipientPhone);
3016    }
3017  };
3018
3019  
3020  function _twEscapeHtml(s) {
3021    return String(s == null ? '' : s).replace(/[&<>"']/g, function(c){
3022      return ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'})[c];
3023    });
3024  }
3025  function _twInsertOrUpdateDiscountRow(d) {
3026    var wrap = document.getElementById('js-summary-discounts');
3027    if (!wrap) return;
3028    var code = d.discount_code || d.gift_code;
3029    if (!code) return;
3030
3031    var existing = wrap.querySelector('[data-discount-code="' + code.replace(/"/g, '\\"') + '"]');
3032    var label = d.is_free_shipping ? '免運' : '優惠活動折扣';
3033    var amount = d.discount_amount || d.gift_discount_amount || 0;
3034    var amtText = d.is_free_shipping ? '' : ('−' + fmtMoney(amount));
3035    var expireAt = d.expire_at || '';
3036    var minAmt = parseFloat(d.min_order_amount || 0);
3037    var isVip = d.gift_is_vip == 1 || d.gift_is_vip === '1';
3038    if (existing) {
3039      var amtEl = existing.querySelector('.tw-discount-amt');
3040      if (amtEl) amtEl.textContent = amtText;
3041      return;
3042    }
3043    var btnHtml = isVip ? '' : '<button type="button" onclick="twRemoveDiscount(\'' + code.replace(/'/g, "\\'") + '\')" class="text-base text-gray-400 hover:text-red-500 leading-none px-1" title="取消" aria-label="取消">×</button>';
3044
3045    var expireDateOnly = expireAt ? expireAt.split(' ')[0] : '';
3046    var validUntilTxt = expireDateOnly ? '使用期限至 ' + _twEscapeHtml(expireDateOnly) : '';
3047    var minTxt = minAmt > 0 ? '商品金額須滿 ' + CURRENCY_PREFIX + Math.round(minAmt).toLocaleString('en-US') : '';
3048    var metaTxt = '';
3049    if (validUntilTxt && minTxt) metaTxt = validUntilTxt + ' · ' + minTxt;
3050    else metaTxt = validUntilTxt || minTxt;
3051    var metaHtml = metaTxt ? '<span class="text-[11px] text-gray-400 leading-snug">' + metaTxt + '</span>' : '';
3052    var row = document.createElement('div');
3053    row.className = 'tw-discount-row flex justify-between text-amber-700 items-start gap-3';
3054    row.setAttribute('data-discount-code', code);
3055    row.innerHTML =
3056      '<dt class="flex flex-col gap-1 min-w-0 flex-1">' +
3057        '<span class="flex items-center gap-1.5 leading-tight">' +
3058          '<span class="text-amber-700">' + _twEscapeHtml(label) + '</span>' +
3059          '<span class="font-mono text-xs px-1.5 py-0.5 rounded bg-amber-100 text-amber-900 truncate">' + _twEscapeHtml(code) + '</span>' +
3060          btnHtml +
3061        '</span>' + metaHtml +
3062      '</dt>' +
3063      '<dd class="text-right whitespace-nowrap">' +
3064        '<div class="tw-discount-amt font-medium">' + amtText + '</div>' +
3065      '</dd>';
3066    wrap.appendChild(row);
3067  }
3068  function _twRemoveDiscountRow(code) {
3069    var wrap = document.getElementById('js-summary-discounts');
3070    if (!wrap) return;
3071    var row = wrap.querySelector('[data-discount-code="' + code.replace(/"/g, '\\"') + '"]');
3072    if (row) row.remove();
3073  }
3074  
3075  function _twHandleGiftDiscount(refundGifts, changeGifts) {
3076    if (refundGifts && refundGifts.length) {
3077      refundGifts.forEach(function(g){
3078        if (g && g.code) _twRemoveDiscountRow(g.code);
3079      });
3080    }
3081    if (changeGifts) {
3082
3083      var keys = Object.keys(changeGifts);
3084      keys.forEach(function(k){
3085        var v = changeGifts[k];
3086        if (!v || !v.code) return;
3087        _twInsertOrUpdateDiscountRow({
3088          gift_code: v.code,
3089          gift_discount_amount: Math.abs(parseFloat(v.discount_amount) || 0),
3090          gift_is_vip: v.is_vip || true, // gift 預設不可手動移除
3091          expire_at: v.expire_at || '',
3092          min_order_amount: v.min_order_amount || 0
3093        });
3094      });
3095    }
3096  }
3097  
3098  function _twHandleSetGift(d) {
3099    if (!d || !d.gift_code) return;
3100    if (d.gift_discount_amount && d.gift_discount_amount != '-1' && d.gift_discount_amount != '0') {
3101      _twInsertOrUpdateDiscountRow(d);
3102    } else {
3103      _twRemoveDiscountRow(d.gift_code);
3104    }
3105  }
3106
3107  function _twUpdateCampaignDiscount(amount) {
3108    var wrap = document.getElementById('js-summary-campaign-wrap');
3109    var span = document.getElementById('js-summary-campaign');
3110    var n = parseFloat(amount) || 0;
3111    if (wrap) wrap.style.display = (n > 0) ? '' : 'none';
3112    if (span && n > 0) span.textContent = Math.round(n).toLocaleString('en-US');
3113  }
3114
3115  window.twApplyDiscount = function() {
3116    var inp = document.getElementById('tw_discount_code');
3117    var v = inp ? (inp.value || '').trim() : '';
3118    var msg = document.getElementById('tw_discount_msg');
3119    if (msg) msg.classList.add('hidden');
3120    if (!v) return;
3121    postForm(URLS.discount, { order: ORDER_ID, code: v }, function(d){
3122      if (!isOk(d)) {
3123        if (msg) {
3124          msg.textContent = (d && (d.error || d.msg)) || '無效的折扣碼';
3125          msg.className = 'mt-2 text-sm text-red-600';
3126        } else {
3127          twToast((d && (d.error || d.msg)) || '無效的折扣碼', 'error');
3128        }
3129        return;
3130      }
3131
3132      if (inp) inp.value = '';
3133      if (msg) msg.classList.add('hidden');
3134      _twInsertOrUpdateDiscountRow(d);
3135      _twUpdateCampaignDiscount(d.campaign_discount_amount);
3136      applyTotals(d);
3137
3138      if (d.show_discount_msg == '1' && d.discount_msg) {
3139        twToast(d.discount_msg, 'error');
3140      } else if (d.show_campaign_msg == '1') {
3141        twToast('使用折扣代碼即無法享有其他優惠', 'warning');
3142      }
3143    });
3144  };
3145
3146  window.twRemoveDiscount = async function(code) {
3147    if (!(await twConfirm('取消這個折扣嗎?'))) return;
3148
3149    postForm(URLS.removediscount, { order: ORDER_ID, code: code }, function(d){
3150      if (!isOk(d)) {
3151        twToast((d && (d.error || d.msg)) || 'Network error, please retry.', 'error');
3152        return;
3153      }
3154
3155      _twRemoveDiscountRow(code);
3156      _twUpdateCampaignDiscount(d.campaign_discount_amount);
3157      applyTotals(d);
3158    });
3159  };
3160
3161  
3162  window.twAddonAdd = function(btn) {
3163    if (btn.disabled) return;
3164    btn.disabled = true;
3165    var ov = document.querySelector('.loading-overlay');
3166    if (ov) ov.classList.add('active');
3167    postForm(URLS.addonadd, {
3168      photo_id: btn.getAttribute('data-photo-id'),
3169      size: btn.getAttribute('data-size'),
3170      product_type: btn.getAttribute('data-product-type'),
3171      material: btn.getAttribute('data-material'),
3172      board: btn.getAttribute('data-board'),
3173      wrap_type: btn.getAttribute('data-wrap-type'),
3174      add_more: 1
3175    }, function(d){
3176      if (!isOk(d)) {
3177        if (ov) ov.classList.remove('active');
3178        btn.disabled = false;
3179        twToast((d && (d.error || d.msg)) || 'Network error, please retry.', 'error');
3180        return;
3181      }
3182      window.location.reload();
3183    }, function(){
3184      if (ov) ov.classList.remove('active');
3185      btn.disabled = false;
3186      twToast('Network error, please retry.', 'error');
3187    });
3188  };
3189
3190  
3191  var PENDING_COUPON = "";
3192  function twAutoApplyPendingCoupon() {
3193    if (!PENDING_COUPON) return;
3194    var inp = document.getElementById('tw_discount_code');
3195    if (!inp || typeof window.twApplyDiscount !== 'function') return;
3196
3197    if (document.querySelector('.tw-discount-row')) return;
3198    inp.value = PENDING_COUPON;
3199    window.twApplyDiscount();
3200  }
3201  if (document.readyState === 'loading') {
3202    document.addEventListener('DOMContentLoaded', twAutoApplyPendingCoupon);
3203  } else {
3204    twAutoApplyPendingCoupon();
3205  }
3206
3207  
3208
3209  window.twSetInvoiceType = function(t, skipSave) {
3210    t = parseInt(t, 10);
3211    var hid = document.getElementById('invoice_type');
3212    if (hid) hid.value = t;
3213
3214    document.querySelectorAll('.tw-inv-panel').forEach(function(p){
3215      p.classList.toggle('active', parseInt(p.getAttribute('data-inv'), 10) === t);
3216    });
3217
3218    var segR = document.querySelector('input[name="tw_inv_seg"][value="' + t + '"]');
3219    if (segR) segR.checked = true;
3220
3221    var vn = document.getElementById('vat_no');
3222    var vt = document.getElementById('vat_name');
3223    if (vn && vt) {
3224      if (t === 2) {
3225        vn.value = (document.getElementById('vat_number') || {}).value || '';
3226        vt.value = (document.getElementById('vat_title')  || {}).value || '';
3227      } else if (t === 3) {
3228        vn.value = (document.getElementById('barcode_mobile') || {}).value || '';
3229        vt.value = '';
3230      } else if (t === 4) {
3231        vn.value = (document.getElementById('barcode_natural') || {}).value || '';
3232        vt.value = '';
3233      } else if (t === 5) {
3234        vn.value = (document.getElementById('love_code') || {}).value || '0';
3235        vt.value = '';
3236      } else {
3237        vn.value = '';
3238        vt.value = '';
3239      }
3240    }
3241
3242    twRefreshInvoiceAddrVisibility();
3243
3244    if (t === 1 && !skipSave) {
3245      postForm(URLS.savevatnumber, {
3246        order_id: ORDER_ID,
3247        vat_number: '',
3248        invoice_type: 1
3249      }, function(){});
3250    }
3251  };
3252
3253  
3254  function twRefreshInvoiceAddrVisibility() {
3255    var addrWrap = document.getElementById('tw-inv-addr-wrap');
3256    if (!addrWrap) return;
3257    var invType = parseInt((document.getElementById('invoice_type') || {}).value || '1', 10);
3258    var hasVat  = ((document.getElementById('vat_number') || {}).value || '').trim().length === 8;
3259    var deliver = parseInt((document.getElementById('delivery_options') || {}).value || '0', 10);
3260    var isCvs   = CVS_DELIVER_OPTS.indexOf(deliver) !== -1;
3261    addrWrap.style.display = (invType === 2 && hasVat && isCvs) ? '' : 'none';
3262  }
3263  window.twRefreshInvoiceAddrVisibility = twRefreshInvoiceAddrVisibility;
3264
3265  document.addEventListener('change', function(e){
3266    if (e.target && e.target.matches && e.target.matches('input[name="tw_inv_seg"]')) {
3267      twSetInvoiceType(e.target.value);
3268    }
3269  });
3270
3271  window.twOnVatNumberInput = function() {
3272    var v = (document.getElementById('vat_number').value || '').trim();
3273    var vn = document.getElementById('vat_no');
3274    if (vn) vn.value = v;
3275
3276    if (v.length === 8 && window._twIsValidGUI(v)) twSetInvoiceType(2);
3277
3278    if (typeof twRefreshInvoiceAddrVisibility === 'function') twRefreshInvoiceAddrVisibility();
3279  };
3280
3281  
3282  document.addEventListener('change', function(e){
3283    var t = e.target;
3284    if (!t || t.type !== 'radio') return;
3285    if (!t.classList.contains('tw-radio-input')) return;
3286    if (!t.name) return;
3287    document.querySelectorAll('input.tw-radio-input[name="' + t.name + '"]').forEach(function(inp){
3288      var card = inp.closest('.tw-radio-card');
3289      if (!card) return;
3290      if (inp === t || inp.checked) card.classList.add('tw-selected');
3291      else card.classList.remove('tw-selected');
3292    });
3293
3294    if (t.name === 'tw_deliver_by') {
3295      var hid = document.getElementById('delivery_options');
3296      if (hid) hid.value = t.value;
3297      _twFunnel('checkout_ship_change', { to_deliver_by: parseInt(t.value, 10) || 0 });
3298      twChangeDeliverBy(t.value);
3299    }
3300
3301    if (t.name === 'preview_status') {
3302      postForm(URLS.savepreviewopt, { order_id: ORDER_ID, preview_status: t.value }, function(){});
3303    }
3304
3305    if (t.name === 'tw_output_mode') {
3306      var hidOM = document.getElementById('output_mode');
3307      if (hidOM) hidOM.value = t.value;
3308      postForm(URLS.saveoutputmode, { order_id: ORDER_ID, output_mode: t.value }, function(){});
3309    }
3310
3311    if (t.name === 'has_logo') {
3312      postForm(URLS.savehaslogo, { order_id: ORDER_ID, has_logo: t.value }, function(){});
3313      var fcWrap = document.getElementById('tw-free-card-wrap');
3314      if (fcWrap) fcWrap.style.display = (t.value === '1') ? '' : 'none';
3315    }
3316  });
3317
3318  
3319  
3320  var FIELD_SAVE_MAP = [
3321    { sel: '#email',           url: URLS.saveemail,          param: 'email' },
3322    { sel: '#phone',           url: URLS.savephone,          param: 'phone' },
3323    { sel: '#buyer_name',      url: URLS.savebuyername,      param: 'buyer_name' },
3324    { sel: '#recipient_name',  url: URLS.saverecipientname,  param: 'recipient_name' },
3325    { sel: '#recipient_phone', url: URLS.saverecipientphone, param: 'recipient_phone' },
3326    { sel: '#address',         url: URLS.saveaddress,        param: 'address' },
3327
3328    { sel: 'input[type="text"]#city',    url: URLS.savecity,    param: 'city' },
3329    { sel: 'input[type="text"]#zipcode', url: URLS.savezipcode, param: 'zipcode' },
3330    { sel: '#note',            url: URLS.savenote,           param: 'note' },
3331    { sel: '#vat_number',      url: URLS.savevatnumber,      param: 'vat_number' },
3332    { sel: '#vat_title',       url: URLS.savevattitle,       param: 'vat_title' },
3333    { sel: '#invoice_address', url: URLS.saveaddress,        param: 'address' },
3334    { sel: '#barcode_mobile',  url: URLS.savevatnumber,      param: 'vat_number', forceInvoiceType: 3 },
3335    { sel: '#barcode_natural', url: URLS.savevatnumber,      param: 'vat_number', forceInvoiceType: 4 },
3336    { sel: '#love_code',       url: URLS.savevatnumber,      param: 'vat_number', forceInvoiceType: 5 }
3337  ];
3338  var _saveTimers = {};
3339  function bindAutoSave(map) {
3340    var el = document.querySelector(map.sel);
3341    if (!el) return;
3342    var key = map.sel;
3343    function send() {
3344
3345      if (map.sel === '#email' && _twIsUnsupportedEmail(el.value)) {
3346        _twSyncEmailDomainHint();
3347        return;
3348      }
3349      var data = { order_id: ORDER_ID };
3350      data[map.param] = el.value;
3351
3352      if (map.param === 'vat_number') {
3353        if (map.forceInvoiceType) {
3354
3355          var raw = (el.value || '').trim();
3356          if (raw === '' || raw === '0') return;
3357          data.invoice_type = map.forceInvoiceType;
3358        } else {
3359          var invType = document.getElementById('invoice_type');
3360          if (invType) data.invoice_type = invType.value;
3361
3362          if (map.sel === '#vat_number') {
3363            var v = (el.value || '').trim();
3364
3365            if (v.length > 0 && v.length < 8) return;
3366            if (v.length === 8 && !window._twIsValidGUI(v)) return;
3367          }
3368        }
3369      }
3370      postForm(map.url, data, function(){});
3371    }
3372    function schedule() {
3373      clearTimeout(_saveTimers[key]);
3374      _saveTimers[key] = setTimeout(send, 600);
3375    }
3376
3377    el.addEventListener('input', schedule);
3378    el.addEventListener('change', function(){
3379      clearTimeout(_saveTimers[key]);
3380      send();
3381
3382      if (map.sel === '#email' || map.sel === '#phone') _twTrackBeginCheckout();
3383    });
3384    el.addEventListener('blur', function(){ clearTimeout(_saveTimers[key]); send(); });
3385
3386    if (map.sel === '#email') {
3387      el.addEventListener('blur', function(){
3388        var v = (el.value || '').trim();
3389        var fixed = _twAutoFixEmail(v);
3390        if (fixed && fixed !== v) {
3391          el.value = fixed;
3392
3393          clearTimeout(_saveTimers[key]);
3394          send();
3395        }
3396      });
3397
3398      el.addEventListener('input', function(){
3399        var badge = document.getElementById('email-verified-badge');
3400        if (badge) badge.style.display = 'none';
3401      });
3402    }
3403
3404    if (map.sel === '#recipient_name') {
3405      el.addEventListener('blur', function(){
3406        var cvsBlock = document.getElementById('tw-addr-cvs');
3407        var isCvs = cvsBlock && cvsBlock.style.display !== 'none';
3408        if (!isCvs) return;
3409        var v = (el.value || '').trim();
3410        if (!v) return;
3411        if (/^[A-Za-z0-9 ]*$/.test(v)) {
3412          el.classList.add('tw-field-error');
3413          twToast('請輸入中文姓名', 'error');
3414          setTimeout(function(){ try { el.focus(); } catch(e){} }, 30);
3415        } else {
3416          el.classList.remove('tw-field-error');
3417        }
3418      });
3419    }
3420  }
3421
3422  
3423  function _twAutoFixEmail(emailVal) {
3424    if (!emailVal) return emailVal;
3425    var atIdx = emailVal.lastIndexOf('@');
3426    if (atIdx <= 0) return emailVal;
3427    var localPart = emailVal.substring(0, atIdx);
3428    var domainPart = emailVal.substring(atIdx + 1).toLowerCase();
3429
3430    domainPart = domainPart.replace(/^\d+(yahoo|gmail|hotmail|outlook)/i, '$1');
3431
3432    var domainFixes = {
3433      'gamil': 'gmail', 'gmali': 'gmail', 'gmial': 'gmail', 'gmsil': 'gmail',
3434      'gamail': 'gmail', 'gmil': 'gmail', 'gmai': 'gmail', 'ganil': 'gmail',
3435      'yhaoo': 'yahoo', 'yshoo': 'yahoo', 'uahoo': 'yahoo', 'tahoo': 'yahoo', 'yahho': 'yahoo',
3436      'hotmoal': 'hotmail', 'hotmaim': 'hotmail', 'hotmial': 'hotmail', 'hoymail': 'hotmail',
3437      'hotamil': 'hotmail', 'hotmali': 'hotmail', 'hotmailc': 'hotmail',
3438      'licould': 'icloud', 'icolud': 'icloud', 'icould': 'icloud',
3439      'outllok': 'outlook', 'outlok': 'outlook',
3440      'hibix': 'hibox'
3441    };
3442    var domainName = domainPart.split('.')[0];
3443    if (domainFixes[domainName]) {
3444      domainPart = domainPart.replace(domainName, domainFixes[domainName]);
3445    }
3446
3447    var suffixFixes = [
3448      [/^gmail\.(com\.tw|com\.hk|co\.tw|cmo\.tw|com\.te)$/, 'gmail.com'],
3449      [/^(gmail|hotmail|outlook|icloud|msn)\.(con|vom|cmo|come|comp|coom|comm|ocm|cim|xom|c0m|om|cm|co|comn)$/, '$1.com'],
3450      [/^(gmail|hotmail|outlook|icloud|msn),(com)$/, '$1.$2'],
3451      [/^hotmailc\.om$/, 'hotmail.com'],
3452      [/^yahoo\.(con\.tw|cpm\.tw|ocm\.tw|vom\.tw|cm\.tw|co\.tw|com\.te|com\.yw)$/, 'yahoo.com.tw'],
3453      [/^yahoo\.(con\.hk|vom\.hk)$/, 'yahoo.com.hk']
3454    ];
3455    for (var i = 0; i < suffixFixes.length; i++) {
3456      domainPart = domainPart.replace(suffixFixes[i][0], suffixFixes[i][1]);
3457    }
3458    return localPart + '@' + domainPart;
3459  }
3460  window._twAutoFixEmail = _twAutoFixEmail;
3461  function initAutoSave() { FIELD_SAVE_MAP.forEach(bindAutoSave); }
3462
3463  
3464  function initVatNumberValidation() {
3465    var input = document.getElementById('vat_number');
3466    var errEl = document.getElementById('vat_number_err');
3467    if (!input || !errEl) return;
3468    function showErr() { input.classList.add('tw-field-error'); errEl.style.display = ''; }
3469    function clearErr() { input.classList.remove('tw-field-error'); errEl.style.display = 'none'; }
3470    input.addEventListener('blur', function() {
3471      var v = (input.value || '').trim();
3472      if (v.length === 0) { clearErr(); return; }
3473      if (v.length < 8 || !window._twIsValidGUI(v)) showErr();
3474      else clearErr();
3475    });
3476    input.addEventListener('input', clearErr);
3477  }
3478  function initFieldBindings() { initAutoSave(); initVatNumberValidation(); }
3479  if (document.readyState === 'loading') {
3480    document.addEventListener('DOMContentLoaded', initFieldBindings);
3481  } else {
3482    initFieldBindings();
3483  }
3484
3485  
3486  window.twSetShippingCountry = function(country) {
3487    if (!country) return;
3488    var curDeliver = (document.getElementById('delivery_options') || {}).value || '1';
3489    postForm(URLS.shippingfee, { id: ORDER_ID, country_code: country, deliver_by: curDeliver }, function(d){
3490      if (!isOk(d)) {
3491        twToast((d && (d.error || d.msg)) || 'Network error, please retry.', 'error');
3492        return;
3493      }
3494      location.reload();
3495    });
3496  };
3497
3498  
3499  
3500  (function relocateMobileBar(){
3501    function move(){
3502      var bar = document.querySelector('.tw-mobile-bar');
3503      if (bar && bar.parentElement !== document.body) {
3504        document.body.appendChild(bar);
3505      }
3506    }
3507    if (document.readyState === 'loading') {
3508      document.addEventListener('DOMContentLoaded', move);
3509    } else {
3510      move();
3511    }
3512  })();
3513
3514  var CVS_DELIVER_OPTS = [7, 18, 102, 103]; // DELIVERY_OPT_CVS / NEXT_DAY_CVS / HOLIDAY_CVS / HOLIDAY2_CVS
3515
3516  
3517  function setCvsMode(showCvs) {
3518    var normal = document.getElementById('tw-addr-normal');
3519    var cvs    = document.getElementById('tw-addr-cvs');
3520    if (normal) {
3521      normal.style.display = showCvs ? 'none' : '';
3522      normal.querySelectorAll('input, select, textarea').forEach(function(el){
3523        if (showCvs) {
3524          if (el.required) { el.dataset._required = '1'; el.required = false; }
3525          el.disabled = true;
3526        } else {
3527          el.disabled = false;
3528          if (el.dataset._required === '1') { el.required = true; delete el.dataset._required; }
3529        }
3530      });
3531    }
3532    if (cvs) cvs.style.display = showCvs ? '' : 'none';
3533  }
3534
3535  window.twChangeDeliverBy = function(deliverBy) {
3536    var curCountry = (document.getElementById('shipping_country_real') || {}).value || 'TW';
3537    var willBeCvs = CVS_DELIVER_OPTS.indexOf(parseInt(deliverBy, 10)) !== -1;
3538
3539    var hidden = document.getElementById('delivery_options');
3540    if (hidden) hidden.value = deliverBy;
3541    document.querySelectorAll('.tw-deliver-card').forEach(function(c){
3542      c.classList.toggle('tw-selected', c.getAttribute('data-opt') === String(deliverBy));
3543    });
3544
3545    setCvsMode(willBeCvs);
3546
3547    _twUpdateFreeShipBanner();
3548
3549    if (typeof twRefreshInvoiceAddrVisibility === 'function') twRefreshInvoiceAddrVisibility();
3550
3551    postForm(URLS.shippingfee, { id: ORDER_ID, country_code: curCountry, deliver_by: deliverBy }, function(d){
3552      if (!isOk(d)) {
3553        twToast((d && (d.error || d.msg)) || 'Network error, please retry.', 'error');
3554        return;
3555      }
3556      applyTotals(d);
3557      var nameEl = document.getElementById('js-summary-deliver-name');
3558      var card = document.querySelector('.tw-deliver-card[data-opt="' + deliverBy + '"]');
3559      if (nameEl && card) {
3560        var titleEl = card.querySelector('.font-medium');
3561        if (titleEl) nameEl.textContent = titleEl.textContent.trim();
3562      }
3563
3564      _twUpdateShippingDates(d);
3565
3566      _twUpdateFreeShipBanner();
3567    });
3568  };
3569
3570  
3571  function _twUpdateShippingDates(d) {
3572    if (!d) return;
3573    var esd = '';
3574    var edd = '';
3575    if (d.esd_full !== undefined && d.esd_full !== null) esd = String(d.esd_full).trim();
3576    else if (d.esd !== undefined && d.esd !== null) esd = String(d.esd).trim();
3577    if (d.edd_full !== undefined && d.edd_full !== null) edd = String(d.edd_full).trim();
3578    else if (d.edd !== undefined && d.edd !== null) edd = String(d.edd).trim();
3579
3580    if (d.esd_full === undefined && d.edd_full === undefined && d.esd === undefined && d.edd === undefined) return;
3581    var esdRow = document.getElementById('js-summary-esd-row');
3582    var eddRow = document.getElementById('js-summary-edd-row');
3583    var esdEl  = document.getElementById('js-summary-esd');
3584    var eddEl  = document.getElementById('js-summary-edd');
3585
3586    if (esdEl) esdEl.innerHTML = esd;
3587    if (eddEl) eddEl.innerHTML = edd;
3588    if (esdRow) esdRow.style.display = esd ? '' : 'none';
3589    if (eddRow) eddRow.style.display = edd ? '' : 'none';
3590  }
3591  window._twUpdateShippingDates = _twUpdateShippingDates;
3592
3593  
3594  window.twSendEmailVerification = function() {
3595    var emailEl = document.getElementById('email');
3596    if (!emailEl) return;
3597    var email = (emailEl.value || '').trim();
3598    var emailReg = /^[A-Za-z0-9._%+\-]+@[A-Za-z0-9.\-]+\.[A-Za-z]{2,}$/;
3599    if (!emailReg.test(email)) {
3600      twToast('無效的電子郵件地址', 'error');
3601      emailEl.focus();
3602      return;
3603    }
3604    if (_twIsUnsupportedEmail(email)) {
3605      _twSyncEmailDomainHint();
3606      twToast(TW_UNSUPPORTED_EMAIL_MSG, 'error');
3607      emailEl.focus();
3608      return;
3609    }
3610    var btn = document.getElementById('btn-send-verify');
3611    var originalText = btn ? btn.textContent : '';
3612    if (btn) { btn.disabled = true; btn.textContent = '發送中...'; }
3613    postForm(URLS.sendemailverify, { order_id: ORDER_ID }, function(d){
3614      if (isOk(d)) {
3615        if (btn) btn.style.display = 'none';
3616        var sent = document.getElementById('verify-code-sent-msg');
3617        var row = document.getElementById('row-email-code');
3618        if (sent) sent.style.display = 'block';
3619        if (row) { row.style.display = 'flex'; setTimeout(function(){ var c = document.getElementById('email_verify_code'); if (c) c.focus(); }, 100); }
3620      } else {
3621        if (btn) { btn.disabled = false; btn.textContent = originalText; }
3622        var msg = (d && d.error === 'rate_limit')
3623          ? '發送次數已達上限,請明天再試'
3624          : '發送失敗,請稍後再試';
3625        twToast(msg, 'error');
3626      }
3627    });
3628  };
3629
3630  window.twVerifyEmailCode = function() {
3631    var c = document.getElementById('email_verify_code');
3632    if (!c) return;
3633    var code = (c.value || '').trim();
3634    if (!/^\d{6}$/.test(code)) {
3635      twToast('請輸入 6 位數驗證碼', 'error');
3636      c.focus();
3637      return;
3638    }
3639    postForm(URLS.verifyemail, { order_id: ORDER_ID, code: code }, function(d){
3640      if (isOk(d)) {
3641        var row = document.getElementById('row-email-code');
3642        var sent = document.getElementById('verify-code-sent-msg');
3643        var badge = document.getElementById('email-verified-badge');
3644        var btn = document.getElementById('btn-send-verify');
3645        if (row) row.style.display = 'none';
3646        if (sent) sent.style.display = 'none';
3647        if (badge) badge.style.display = 'inline-flex';
3648        if (btn) btn.style.display = 'none';
3649      } else {
3650        twToast('驗證碼錯誤,請重新輸入', 'error');
3651        c.value = '';
3652        c.focus();
3653      }
3654    });
3655  };
3656
3657  
3658  var _twCardState = {
3659    type: 0,
3660    cssClass: '',
3661    label: '',
3662    initContent: ""  };
3663
3664  
3665  var _twScrollLockCount = 0, _twScrollLockPrev = null;
3666  function twLockScroll() {
3667    if (++_twScrollLockCount > 1) return;
3668    var body = document.body;
3669    var y = window.pageYOffset || document.documentElement.scrollTop || 0;
3670    _twScrollLockPrev = { y: y, position: body.style.position, top: body.style.top,
3671                          left: body.style.left, right: body.style.right, width: body.style.width };
3672    body.style.position = 'fixed';
3673    body.style.top   = (-y) + 'px';
3674    body.style.left  = '0';
3675    body.style.right = '0';
3676    body.style.width = '100%';
3677  }
3678  function twUnlockScroll() {
3679    if (_twScrollLockCount === 0) return;
3680    if (--_twScrollLockCount > 0) return;
3681    if (!_twScrollLockPrev) return;
3682    var body = document.body, p = _twScrollLockPrev;
3683    body.style.position = p.position;
3684    body.style.top      = p.top;
3685    body.style.left     = p.left;
3686    body.style.right    = p.right;
3687    body.style.width    = p.width;
3688    window.scrollTo(0, p.y);
3689    _twScrollLockPrev = null;
3690  }
3691
3692  function twCardModalOpen() {
3693    var modal = document.getElementById('tw-card-modal');
3694    if (!modal) return;
3695    modal.style.display = 'flex';
3696    modal.setAttribute('data-stage', '1');
3697    twLockScroll();
3698    var current = _twCardState.type;
3699    modal.querySelectorAll('.tw-card-tile').forEach(function(t){
3700      t.classList.toggle('is-selected', parseInt(t.getAttribute('data-card-type'), 10) === current);
3701    });
3702  }
3703  function twCardModalCloseFn() {
3704    var modal = document.getElementById('tw-card-modal');
3705    if (!modal) return;
3706    if (modal.style.display === 'none') return;   // 重複呼叫不可以重複解鎖
3707    modal.style.display = 'none';
3708    twUnlockScroll();
3709  }
3710  window.twCardModalClose = twCardModalCloseFn;
3711
3712  window.twCardPick = function(tile) {
3713    if (!tile) return;
3714    _twCardState.type     = parseInt(tile.getAttribute('data-card-type'), 10) || 0;
3715    _twCardState.cssClass = tile.getAttribute('data-card-css') || '';
3716    _twCardState.label    = tile.getAttribute('data-card-label') || '';
3717    var modal   = document.getElementById('tw-card-modal');
3718    var preview = document.getElementById('tw-card-preview');
3719    var label   = document.getElementById('tw-card-picked-label');
3720    var input   = document.getElementById('tw-card-msg-input');
3721    var count   = document.getElementById('tw-card-msg-count-num');
3722    if (preview) preview.className = 'tw-card-preview ' + _twCardState.cssClass;
3723    if (label)   label.textContent = _twCardState.label;
3724    if (input)   input.value = _twCardState.initContent || '';
3725    if (count)   count.textContent = (input && input.value ? input.value.length : 0);
3726    if (modal)   modal.setAttribute('data-stage', '2');
3727    setTimeout(function(){ if (input) input.focus(); }, 50);
3728  };
3729
3730  window.twCardBack = function() {
3731    var modal = document.getElementById('tw-card-modal');
3732    if (modal) modal.setAttribute('data-stage', '1');
3733  };
3734
3735  window.twCardCancelRedeem = async function() {
3736    if (!(await twConfirm('確定要取消兌換嗎?'))) return;
3737    postForm(URLS.savemomcard, {
3738      order_id: ORDER_ID, mom_card: '', card_type: _twCardState.type || 0
3739    }, function(){
3740      _twCardState.initContent = '';
3741
3742      var sel = document.querySelector('#tw-free-card-wrap .tw-card-selected-badge');
3743      if (sel) {
3744        sel.textContent = '未兌換';
3745        sel.style.background = '#f3f4f6';
3746        sel.style.color = '#6b7280';
3747      }
3748      twCardModalCloseFn();
3749    });
3750  };
3751
3752  window.twCardSave = function() {
3753    var input = document.getElementById('tw-card-msg-input');
3754    var content = input ? (input.value || '').trim() : '';
3755    if (!content) {
3756      twToast('請輸入想說的話', 'error');
3757      if (input) input.focus();
3758      return;
3759    }
3760    postForm(URLS.savemomcard, {
3761      order_id: ORDER_ID, mom_card: content, card_type: _twCardState.type
3762    }, function(d){
3763      if (!isOk(d)) {
3764        twToast((d && (d.error || d.msg)) || 'Network error, please retry.', 'error');
3765        return;
3766      }
3767      _twCardState.initContent = content;
3768
3769      var btn = document.querySelector('#tw-free-card-wrap button');
3770      if (btn) {
3771        var span = btn.querySelector('.tw-card-selected-badge');
3772        if (!span) {
3773          span = document.createElement('span');
3774          span.className = 'tw-card-selected-badge';
3775          span.style.marginLeft = 'auto';
3776          btn.appendChild(span);
3777        }
3778
3779        span.style.background = '';
3780        span.style.color = '';
3781        var labelText = '已選擇';
3782        if (_twCardState.label) labelText += ':' + _twCardState.label;
3783        span.textContent = labelText;
3784      }
3785      twCardModalCloseFn();
3786    });
3787  };
3788
3789  window.twOpenFreeCard = function() { twCardModalOpen(); };
3790
3791  
3792  document.addEventListener('input', function(e){
3793    if (!e.target || e.target.id !== 'tw-card-msg-input') return;
3794    var lines = (e.target.value || '').split('\n');
3795    if (lines.length > 3) e.target.value = lines.slice(0, 3).join('\n');
3796    var count = document.getElementById('tw-card-msg-count-num');
3797    if (count) count.textContent = e.target.value.length;
3798  });
3799  document.addEventListener('keydown', function(e){
3800    if (e.target && e.target.id === 'tw-card-msg-input' && (e.key === 'Enter' || e.keyCode === 13)) {
3801      var lines = (e.target.value || '').split('\n');
3802      if (lines.length >= 3) e.preventDefault();
3803    }
3804    if (e.key === 'Escape') {
3805      var modal = document.getElementById('tw-card-modal');
3806      if (modal && modal.style.display !== 'none') twCardModalCloseFn();
3807    }
3808  });
3809
3810  
3811  function _twFlagRequired(el) {
3812    if (!el) return;
3813    el.classList.add('tw-field-error');
3814    var clear = function(){ el.classList.remove('tw-field-error'); el.removeEventListener('input', clear); el.removeEventListener('change', clear); };
3815    el.addEventListener('input', clear);
3816    el.addEventListener('change', clear);
3817    try { el.scrollIntoView({ behavior: 'smooth', block: 'center' }); } catch(e) { try { el.scrollIntoView(); } catch(_){} }
3818    setTimeout(function(){ try { el.focus({ preventScroll: true }); } catch(e) { try { el.focus(); } catch(_){} } }, 320);
3819  }
3820
3821  
3822  function _twIsActiveField(el) {
3823    if (!el) return false;
3824    if (el.disabled) return false;
3825    if (el.type === 'hidden') {
3826
3827      var addrNormal = document.getElementById('tw-addr-normal');
3828      if (addrNormal && addrNormal.contains(el) && addrNormal.style.display === 'none') return false;
3829      return true;
3830    }
3831
3832    if (el.offsetParent === null) return false;
3833    return true;
3834  }
3835
3836  
3837  function _twVisualEl(el) {
3838    if (!el) return null;
3839    if (el.type !== 'hidden') return el;
3840    if (el.id === 'city') {
3841      var county   = document.querySelector('#tw-addr-normal .county');
3842      var district = document.querySelector('#tw-addr-normal .district');
3843      if (county && !(county.value || '').trim()) return county;
3844      if (district && !(district.value || '').trim()) return district;
3845      return county || el;
3846    }
3847    if (el.id === 'zipcode') return document.querySelector('#tw-addr-normal .zipcode') || el;
3848    return el;
3849  }
3850
3851  
3852  function _twIsValidGUI(taxId) {
3853    taxId = (taxId || '').trim();
3854    var invalidList = ['00000000', '11111111'];
3855    if (!/^\d{8}$/.test(taxId) || invalidList.indexOf(taxId) !== -1) return false;
3856    var op = [1, 2, 1, 2, 1, 2, 4, 1], sum = 0;
3857    var calc = function(p) { var ones = p % 10; return ones + ((p - ones) / 10); };
3858    for (var i = 0; i < op.length; i++) sum += calc(taxId.charAt(i) * op[i]);
3859    return sum % 5 === 0 || (taxId.charAt(6) === '7' && (sum + 1) % 5 === 0);
3860  }
3861  window._twIsValidGUI = _twIsValidGUI;
3862
3863  
3864  function _twIsValidPhone(raw) {
3865    var phone = (raw || '').replace(/ /g, '');
3866    var re = /^[0-9\-()+ ]+$/;
3867    if (phone.length < 6) return false;
3868    if (!re.test(phone)) return false;
3869    if (phone.indexOf('09') === 0 && phone.length < 10) return false;
3870    return true;
3871  }
3872
3873  
3874  function _twIsValidEmail(raw) {
3875    var email = (raw || '').trim();
3876    var re = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
3877    return re.test(email);
3878  }
3879
3880  
3881  var TW_UNSUPPORTED_EMAIL_MSG = "\u4e0d\u652f\u63f4 Hotmail \u4fe1\u7bb1\uff08\u6211\u5011\u5bc4\u51fa\u7684\u9a57\u8b49\u78bc\u8207\u8a02\u55ae\u901a\u77e5\u7d93\u5e38\u7121\u6cd5\u9001\u9054\uff09\uff0c\u8acb\u6539\u7528\u5176\u4ed6 Email\uff0c\u4f8b\u5982 Gmail\u3001Yahoo\u3002";
3882  function _twIsUnsupportedEmail(raw) {
3883    return /@hotmail(\.|$)/i.test((raw || '').trim());
3884  }
3885
3886  function _twSyncEmailDomainHint() {
3887    var el = document.getElementById('email');
3888    var box = document.getElementById('tw-email-domain-err');
3889    var bad = !!(el && _twIsUnsupportedEmail(el.value));
3890    if (box) {
3891      box.textContent = bad ? TW_UNSUPPORTED_EMAIL_MSG : '';
3892      box.style.display = bad ? 'block' : 'none';
3893    }
3894    return bad;
3895  }
3896  (function bindEmailDomainHint(){
3897    var el = document.getElementById('email');
3898    if (!el) return;
3899    el.addEventListener('input', _twSyncEmailDomainHint);
3900    el.addEventListener('change', _twSyncEmailDomainHint);
3901
3902    _twSyncEmailDomainHint();
3903  })();
3904
3905  
3906
3907  
3908  function _twMpSetState(on) {
3909    var btn = document.getElementById('tw-mp-toggle');
3910    if (!btn) return;
3911    btn.setAttribute('data-state', on ? '1' : '0');
3912    btn.setAttribute('aria-pressed', on ? 'true' : 'false');
3913  }
3914  function _twMpUpdateAmt(redeemPts) {
3915    var wrap = document.querySelector('#tw-mp-row .tw-mp-redeem-amt');
3916    var num  = document.querySelector('#tw-mp-row .tw-mp-redeem-amt-num');
3917    if (!wrap || !num) return;
3918    if (redeemPts && redeemPts > 0) {
3919
3920      num.textContent = (typeof redeemPts === 'number' ? redeemPts : parseFloat(redeemPts) || 0).toLocaleString('en-US');
3921      wrap.classList.remove('hidden');
3922    } else {
3923      wrap.classList.add('hidden');
3924    }
3925  }
3926  function _twMpUpdateBalance(bal) {
3927
3928    var inp = document.getElementById('tw-member-points-balance');
3929    if (inp) inp.value = bal;
3930  }
3931  window.twMpRedeem = function() {
3932    _twMpSetState(true);
3933    postForm(URLS.redeemmemberpoints, { order: ORDER_ID }, function(d){
3934      if (!isOk(d)) {
3935        _twMpSetState(false);
3936        twToast((d && d.error) || '兌換失敗', 'error');
3937        return;
3938      }
3939      applyTotals(d);
3940      if (d.campaign_discount_amount !== undefined) _twUpdateCampaignDiscount(d.campaign_discount_amount);
3941      _twMpUpdateAmt(d.redeem_points);
3942      if (d.member_points_balance !== undefined) _twMpUpdateBalance(d.member_points_balance);
3943    }, function(){ _twMpSetState(false); });
3944  };
3945  window.twMpRefund = function() {
3946    _twMpSetState(false);
3947    postForm(URLS.refundmemberpoints, { order: ORDER_ID }, function(d){
3948      if (!isOk(d)) {
3949        _twMpSetState(true);
3950        twToast((d && d.error) || '取消兌換失敗', 'error');
3951        return;
3952      }
3953      applyTotals(d);
3954      if (d.campaign_discount_amount !== undefined) _twUpdateCampaignDiscount(d.campaign_discount_amount);
3955      _twMpUpdateAmt(0);
3956      if (d.member_points_balance !== undefined) _twMpUpdateBalance(d.member_points_balance);
3957    }, function(){ _twMpSetState(true); });
3958  };
3959  document.addEventListener('click', function(e){
3960    var btn = e.target && e.target.closest && e.target.closest('#tw-mp-toggle');
3961    if (!btn) return;
3962    if (btn.hasAttribute('disabled')) return;
3963    if (btn.getAttribute('data-state') === '1') twMpRefund();
3964    else twMpRedeem();
3965  });
3966
3967  
3968  var _twBeganCheckout = false;
3969  function _twTrackBeginCheckout() {
3970    if (_twBeganCheckout) return;
3971    var totalEl = document.getElementById('js-summary-total');
3972    var fb_value = totalEl ? (totalEl.textContent || '').replace(/,/g, '').trim() : '0';
3973    var fb_currency = "TWD";
3974    try {
3975      if (typeof fbq === 'function') {
3976        fbq('track', 'InitiateCheckout', { value: fb_value, currency: fb_currency }, { eventID: "" });
3977      }
3978      if (typeof pt_oai === 'function') {
3979        pt_oai('checkout_started', fb_value, fb_currency, null, "");
3980      }
3981      if (typeof gtag === 'function') {
3982        var emEl = document.getElementById('email');
3983        var phEl = document.getElementById('phone');
3984        if (emEl && (emEl.value || '').length > 0) gtag('set', 'user_data', { 'email': emEl.value });
3985        if (phEl && (phEl.value || '').length > 0) gtag('set', 'user_data', { 'phone_number': phEl.value });
3986        gtag('event', 'begin_checkout', { currency: fb_currency, value: fb_value });
3987        gtag('event', 'conversion', {
3988          'send_to': 'AW-10928790878/idYNCO3s3r0YEN66oNso',
3989          'value': fb_value,
3990          'currency': fb_currency
3991        });
3992      }
3993      if (typeof _lt === 'function') {
3994        _lt('send', 'cv', { type: 'InitiateCheckout' }, ['04dcc8bf-15ed-4375-addd-900f5d9d5e21']);
3995      }
3996    } catch (e) { console.warn('track_begin_checkout failed', e); }
3997    _twBeganCheckout = true;
3998  }
3999  window._twTrackBeginCheckout = _twTrackBeginCheckout;
4000
4001  
4002  function _twTrackCheckoutSubmit() {
4003    var totalEl = document.getElementById('js-summary-total');
4004    var fb_value = totalEl ? (totalEl.textContent || '').replace(/,/g, '').trim() : '0';
4005    var fb_currency = "TWD";
4006    try {
4007      if (typeof gtag === 'function') {
4008        gtag('event', 'conversion', {
4009          'send_to': 'AW-11096059240/JP1UCInVz40YEOjagasp',
4010          'value': fb_value,
4011          'currency': fb_currency,
4012          'transaction_id': ""        });
4013      }
4014    } catch (e) { console.warn('track checkout submit failed', e); }
4015  }
4016
4017  
4018  function _twCheckMobileBarcodeSync(code) {
4019    try {
4020      var xhr = new XMLHttpRequest();
4021      xhr.open('POST', URLS.checkmobilebarcode, false); // sync
4022      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
4023      xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
4024      var body = 'order_id=' + encodeURIComponent(ORDER_ID)
4025               + '&code=' + encodeURIComponent(code)
4026               + '&' + encodeURIComponent(CSRF_NAME) + '=' + encodeURIComponent(CSRF_VAL);
4027      xhr.send(body);
4028      if (xhr.status >= 200 && xhr.status < 300) {
4029        try {
4030          var d = JSON.parse(xhr.responseText);
4031
4032          return (d && (d.status === '1' || d.status === 1));
4033        } catch(e) { return false; }
4034      }
4035      return false;
4036    } catch (e) {
4037
4038      console.warn('checkmobilebarcode failed', e);
4039      return true;
4040    }
4041  }
4042
4043  async function _twSubmitCheckoutBody(payWith) {
4044    var f = document.getElementById('shopping-checkout-form-tw');
4045    if (!f) return;
4046    var fillMsg = '請填寫所有必填欄位';
4047
4048    var required = ['email','phone','recipient_name','recipient_phone','city','address'];
4049    for (var i = 0; i < required.length; i++) {
4050      var el = document.getElementById(required[i]);
4051      if (!_twIsActiveField(el)) continue;
4052      if (!(el.value || '').trim()) {
4053        twToast(fillMsg, 'error');
4054        _twFlagRequired(_twVisualEl(el));
4055        return;
4056      }
4057    }
4058
4059    var emailEl = document.getElementById('email');
4060    if (_twIsActiveField(emailEl) && !_twIsValidEmail(emailEl.value)) {
4061      twToast('無效的電子郵件地址', 'error');
4062      _twFlagRequired(emailEl);
4063      return;
4064    }
4065
4066    if (_twIsActiveField(emailEl) && _twIsUnsupportedEmail(emailEl.value)) {
4067      _twSyncEmailDomainHint();
4068      twToast(TW_UNSUPPORTED_EMAIL_MSG, 'error');
4069      _twFlagRequired(emailEl);
4070      return;
4071    }
4072
4073    var phoneEl = document.getElementById('phone');
4074    if (_twIsActiveField(phoneEl) && !_twIsValidPhone(phoneEl.value)) {
4075      twToast('無效的電話號碼', 'error');
4076      _twFlagRequired(phoneEl);
4077      return;
4078    }
4079
4080    var recPhoneEl = document.getElementById('recipient_phone');
4081    if (_twIsActiveField(recPhoneEl) && !_twIsValidPhone(recPhoneEl.value)) {
4082      twToast('無效的電話號碼', 'error');
4083      _twFlagRequired(recPhoneEl);
4084      return;
4085    }
4086
4087    var cvsBlock = document.getElementById('tw-addr-cvs');
4088    var isCvsMode = cvsBlock && cvsBlock.style.display !== 'none';
4089    if (isCvsMode && cvsBlock.getAttribute('data-has-store') !== '1') {
4090      twToast('請選擇門市', 'error');
4091      try { cvsBlock.scrollIntoView({ behavior: 'smooth', block: 'center' }); } catch(e){ try { cvsBlock.scrollIntoView(); } catch(_){} }
4092
4093      var card = cvsBlock.querySelector('.rounded-xl');
4094      if (card) {
4095        card.classList.add('tw-field-error');
4096        setTimeout(function(){ card.classList.remove('tw-field-error'); }, 1800);
4097      }
4098      return;
4099    }
4100
4101    if (isCvsMode) {
4102      var recNameEl = document.getElementById('recipient_name');
4103      if (_twIsActiveField(recNameEl) && /^[A-Za-z0-9 ]*$/.test((recNameEl.value || '').trim())) {
4104        twToast('請輸入中文姓名', 'error');
4105        _twFlagRequired(recNameEl);
4106        return;
4107      }
4108    }
4109
4110    if (!isCvsMode) {
4111      var addrEl = document.getElementById('address');
4112      if (_twIsActiveField(addrEl) && (addrEl.value || '').trim().length < 5) {
4113        twToast('請確認地址是否填寫完整', 'error');
4114        _twFlagRequired(addrEl);
4115        return;
4116      }
4117    }
4118
4119    var curShipCountry = (document.getElementById('shipping_country_real') || {}).value || '';
4120    if (curShipCountry === 'TW') {
4121      var zipEl = document.getElementById('zipcode');
4122      var zipVal = zipEl ? (zipEl.value || '').trim() : '';
4123      if (zipVal) {
4124        var TW_SURROUNDING_ZIP = ['817','819','290','209','210','211','212','880','881','882','883','884','885','890','891','892','893','894','896','951','952','929'];
4125        for (var zi = 0; zi < TW_SURROUNDING_ZIP.length; zi++) {
4126          if (zipVal.indexOf(TW_SURROUNDING_ZIP[zi]) > -1) {
4127            twToast('您輸入的是台灣離島的郵遞區號,請確認您的運費選擇是否正確!', 'warning');
4128            return;
4129          }
4130        }
4131      }
4132    }
4133
4134    var invTypeEl = document.getElementById('invoice_type');
4135    var curInvType = invTypeEl ? parseInt(invTypeEl.value || '1', 10) : 1;
4136    if (curInvType === 2) {
4137      var vn = document.getElementById('vat_number');
4138      var vt = document.getElementById('vat_title');
4139      if (_twIsActiveField(vn) && !(vn.value || '').trim()) { twToast(fillMsg, 'error'); _twFlagRequired(vn); return; }
4140      if (_twIsActiveField(vt) && !(vt.value || '').trim()) { twToast(fillMsg, 'error'); _twFlagRequired(vt); return; }
4141
4142      if (_twIsActiveField(vn) && !_twIsValidGUI(vn.value)) {
4143        twToast('統一編號錯誤', 'error');
4144        _twFlagRequired(vn);
4145        return;
4146      }
4147    }
4148
4149    if (curInvType === 3) {
4150      var bm = document.getElementById('barcode_mobile');
4151      if (_twIsActiveField(bm)) {
4152        var bmVal = (bm.value || '').trim();
4153        if (!bmVal) { twToast('請輸入手機條碼', 'error'); _twFlagRequired(bm); return; }
4154        if (!/^\/.+$/.test(bmVal)) { twToast('手機條碼錯誤', 'error'); _twFlagRequired(bm); return; }
4155
4156        var bmOk = _twCheckMobileBarcodeSync(bmVal);
4157        if (!bmOk) {
4158          twToast('手機條碼錯誤', 'error');
4159          _twFlagRequired(bm);
4160          return;
4161        }
4162      }
4163    }
4164
4165    if (curInvType === 4) {
4166      var bn = document.getElementById('barcode_natural');
4167      if (_twIsActiveField(bn)) {
4168        var bnVal = (bn.value || '').trim();
4169        if (!bnVal) { twToast('請輸入自然人憑證條碼', 'error'); _twFlagRequired(bn); return; }
4170        if (!/^[A-Za-z]{2}\d{14}$/.test(bnVal)) { twToast('請輸入自然人憑證條碼', 'error'); _twFlagRequired(bn); return; }
4171      }
4172    }
4173
4174    if (curInvType === 5) {
4175      var lc = document.getElementById('love_code');
4176      if (_twIsActiveField(lc) && (!(lc.value || '').trim() || (lc.value || '').trim() === '0')) {
4177        twToast('請選擇發票捐贈單位', 'error');
4178        _twFlagRequired(lc);
4179        return;
4180      }
4181    }
4182
4183    var invAddrWrap = document.getElementById('tw-inv-addr-wrap');
4184    if (invAddrWrap && invAddrWrap.style.display !== 'none') {
4185      var ia = document.getElementById('invoice_address');
4186      if (_twIsActiveField(ia) && !(ia.value || '').trim()) { twToast(fillMsg, 'error'); _twFlagRequired(ia); return; }
4187    }
4188
4189    var verifiedBadge = document.getElementById('email-verified-badge');
4190    var isVerified = verifiedBadge && verifiedBadge.style.display !== 'none';
4191    if (!isVerified) {
4192
4193      if (!window._twSkipEmailVerify) {
4194        var msg = '您的 Email 尚未驗證,可能會無法收到重要的訂單後續通知。確定要繼續前往付款嗎?';
4195        if (await twConfirm(msg)) {
4196
4197          window._twSkipEmailVerify = true;
4198        } else {
4199
4200          var emEl = document.getElementById('email');
4201          if (emEl) {
4202            try { emEl.scrollIntoView({ behavior: 'smooth', block: 'center' }); } catch(e){}
4203            setTimeout(function(){ try { emEl.focus({ preventScroll: true }); } catch(e) { try { emEl.focus(); } catch(_){} } }, 320);
4204          }
4205          return;
4206        }
4207      }
4208    }
4209
4210    var invType = parseInt(document.getElementById('invoice_type').value, 10);
4211    twSetInvoiceType(invType, true);
4212
4213    var pw = f.querySelector('input[name="pay_with"]');
4214    if (pw) pw.value = payWith;
4215
4216    _twTrackCheckoutSubmit();
4217
4218    var __btns = document.querySelectorAll('[onclick*="twSubmitCheckout"]');
4219    for (var __i = 0; __i < __btns.length; __i++) {
4220      __btns[__i].disabled = true;
4221      __btns[__i].style.opacity = '0.6';
4222      __btns[__i].style.cursor = 'not-allowed';
4223    }
4224    f.submit();
4225    return true;
4226  }
4227
4228  window.twSubmitCheckout = async function(payWith) {
4229    if (window._twCheckoutInFlight) return;
4230    window._twCheckoutInFlight = true;
4231    var ok = false;
4232    try {
4233      _twFunnel('checkout_pay_click', { pay_with: payWith });
4234      ok = await _twSubmitCheckoutBody(payWith);
4235    } finally {
4236      if (!ok) {
4237        window._twCheckoutInFlight = false;
4238
4239        _twFunnel('checkout_blocked', { pay_with: payWith });
4240      }
4241    }
4242  };
4243
4244  
4245  function initTwCitySelector() {
4246    if (typeof TwCitySelector !== 'function') return;
4247    var rootEl = document.querySelector('#tw-checkout-root .tw-city-selector');
4248    if (!rootEl) return;
4249    if (rootEl.dataset.twcsInited) return;
4250    rootEl.dataset.twcsInited = '1';
4251
4252    var rawCity = (document.getElementById('city') || {}).value || '';
4253    var rawArea = (document.getElementById('area_name') || {}).value || '';
4254    var countyVal = rawCity;
4255    var districtVal = rawArea;
4256
4257    if (rawCity && !rawArea) {
4258      var m = rawCity.match(/^(.{2,3}?[市縣])(.+)$/);
4259      if (m) { countyVal = m[1]; districtVal = m[2]; }
4260    }
4261
4262    var curCountry = (document.getElementById('shipping_country_real') || {}).value || 'TW';
4263    var tcsConfig = {
4264      el: '.tw-city-selector',
4265      elCounty: '.county',
4266      elDistrict: '.district',
4267      elZipcode: '.zipcode',
4268      countyValue: countyVal || null,
4269      districtValue: districtVal || null,
4270      hasZipcode: true,
4271      standardWords: true
4272    };
4273    if (curCountry === 'TW_SURROUNDING') {
4274      tcsConfig.only = [
4275        '臺東縣@綠島鄉|蘭嶼鄉',
4276        '屏東縣@琉球鄉',
4277        '澎湖縣',
4278        '金門縣',
4279        '連江縣',
4280        '高雄市@東沙群島|南沙群島'
4281      ];
4282    }
4283    try {
4284      new TwCitySelector(tcsConfig);
4285    } catch (e) { console.warn('TwCitySelector init failed', e); return; }
4286
4287    var $ = window.jQuery;
4288    if ($) {
4289
4290      $('#tw-checkout-root .tw-city-selector .county').on('change', function(){
4291        var county = $(this).val() || '';
4292        if ($('#city').val() === county) return;
4293        $('#city').val(county);
4294
4295        $('#area_name').val('');
4296        $('#zipcode').val('');
4297        postForm(URLS.savecity, { order_id: ORDER_ID, city: county }, function(){});
4298      });
4299      $('#tw-checkout-root .tw-city-selector .district').on('change', function(){
4300        var district = $(this).val() || '';
4301
4302        var zip = $(this).find('option:selected').attr('data-zipcode') || '';
4303        var $zipDisplay = $('#tw-checkout-root .tw-city-selector .zipcode');
4304        if ($zipDisplay.length) $zipDisplay.val(zip);
4305
4306        if ($('#area_name').val() === district && $('#zipcode').val() === zip) return;
4307        $('#area_name').val(district);
4308        $('#zipcode').val(zip);
4309        postForm(URLS.savezipcode, {
4310          order_id: ORDER_ID,
4311          zipcode: zip,
4312          area_name: district
4313        }, function(){});
4314      });
4315    }
4316  }
4317  if (document.readyState === 'loading') {
4318    document.addEventListener('DOMContentLoaded', initTwCitySelector);
4319  } else {
4320    setTimeout(initTwCitySelector, 0);
4321  }
4322
4323  
4324
4325  
4326  function _twInitFooterAccordion() {
4327    document.querySelectorAll('footer .web-footer .link .col').forEach(function(col){
4328      var h4 = col.querySelector(':scope > h4');
4329      if (!h4 || h4.dataset.twFcInited) return;
4330      h4.dataset.twFcInited = '1';
4331      h4.addEventListener('click', function(){ col.classList.toggle('tw-fc-open'); });
4332    });
4333  }
4334  if (document.readyState === 'loading') {
4335    document.addEventListener('DOMContentLoaded', _twInitFooterAccordion);
4336  } else {
4337    _twInitFooterAccordion();
4338  }
4339})();
4340</script>
4340
4341    </div> <!-- end of container -->
4342        
4343                    </div>  <!-- end of id="wrap" -->
4344    <footer>
4345        <div class="footnotes">
4346          購物須知          <ol>
4347                        <li>商品與包裝皆印有本品牌 Logo 與商品生產 QRcode 以作為識別。</li>
4348            <li>電腦或手機螢幕與印刷品成像原理不同,呈現的顏色又會因螢幕不同而有所差異,不可能完全無色差,本公司有專業色彩管理之國際認證,實際印製完成的顏色會接近經過專業校色過的螢幕成色。</li>
4349            <li>印刷品的顏色呈現取決於光線,因此不同亮度或色溫的光線照射在同一件作品上會顯示出不同的顏色。印刷品的標準光源是 D50,相當於中午的太陽光。如果擺放作品的環境光源無法提供符合標準的亮度或色溫,會導致觀看時顏色顯得較暗沉。建議事先微調檔案的亮度來避免這種情況。</li>
4350            <li>墨水抗光年限參考來源為 EPSON 原廠所述新一代 UltraChrome HDX 墨水系統抗光效果可達 60 年之久,惟此數據所測試之環境與一般室內環境會有差異,故僅供參考並非絕對保證,正常情況下仍大幅優於它種墨水的抗光年限。</li>
4351            <li>所有商品皆無現貨庫存,付款完成後才會進行製作,開始製作即無法修改和退換貨。在尚未完成付款前,本站保留取消訂單之權利。</li>
4352            <li>使用超商取貨必須填寫收件人中文真實姓名,若因故無法取貨或未取貨,買方必須負擔重新寄出之費用。</li>
4353          </ol>
4354        </div>
4355        <div class="container web-footer">
4356            <div class="link row-fluid">
4357                <div class="col">
4358                    <h4>聯絡我們</h2>
4359                    <ul>
4360                        <li><a href="https://line.me/R/ti/p/@zbo0771t" rel="noopener" target="_blank">LINE 官方帳號</a></li>
4361                        <li><a href="http://m.me/phootime" rel="noopener" target="_blank">Messenger</a></li>
4362                        <li><i class="fa fa-phone"></i> (02) 2345-6698 (上班時間)</li>
4363                        <li><i class="fa fa-envelope"></i> <a href="mailto:[email protected]">[email protected]</a></li>
4364                    </ul>
4365                </div>
4366                <div class="col desktop">
4367                    <h4>產品</h2>
4368                    <ul>
4369                        <li><a itemscope="" itemtype="http://schema.org/Product" href="//www.phootime.com/canvas"><span itemprop="name">畫布無框畫</span>
4370                            <meta itemprop="description" content="無框畫第一品牌,照片禮物最推薦無框畫,把照片輸出成無框畫,絕對是生日節日送禮最暖心的禮物。生活照或婚紗照以頂級藝術微噴印成畫布無框畫,60年以上不褪色,留下每一次難忘的回憶。" />
4371                            <meta itemprop="image" content="https://gcdn.phootime.com/static/images/shop/landing/canvas18.jpg" />
4372                            <div itemprop="brand" itemtype="http://schema.org/Brand" itemscope>
4373                                <meta itemprop="name" content="Phootime無框畫第一品牌">
4374                                <meta itemprop="logo" content="https://gcdn.phootime.com/static/www/images/phootime_logo.svg">
4375                            </div>
4376                            <div itemprop="offers" itemtype="http://schema.org/Offer" itemscope>
4377                                  <link itemprop="url" href="https://www.phootime.com/canvas" />
4378                                  <meta itemprop="availability" content="http://schema.org/InStock" />
4379                                  <meta itemprop="priceCurrency" content="TWD" />
4380                                  <meta itemprop="price" content="920" />
4381                                  <meta itemprop="priceValidUntil" content="2030-11-15" />
4382                            </div>
4383                        </a></li>
4384                                                <li><a itemtype="http://schema.org/Product" itemscope itemtype="http://schema.org/Product" href="/silkcanvas"><span itemprop="name">細絹無框畫</span>
4385                            <meta itemprop="description" content="細絹無框畫,超越畫布的細緻,如絹布般細緻,照片禮物最推薦無框畫,把照片輸出成無框畫,絕對是生日節日送禮最暖心的禮物。生活照或婚紗照以頂級藝術微噴印成畫布無框畫,60年以上不褪色,留下每一次難忘的回憶。" />
4386                            <meta itemprop="image" content="https://gcdn1.phootime.com/static/www/images/2022/silkcanvas_01.jpg" />
4387                            <div itemprop="brand" itemtype="http://schema.org/Brand" itemscope>
4388                                <meta itemprop="name" content="Phootime無框畫第一品牌">
4389                                <meta itemprop="logo" content="https://gcdn.phootime.com/static/www/images/phootime_logo.svg">
4390                            </div>
4391                            <div itemprop="offers" itemtype="http://schema.org/Offer" itemscope>
4392                                  <link itemprop="url" href="/silkcanvas" />
4393                                  <meta itemprop="availability" content="http://schema.org/InStock" />
4394                                  <meta itemprop="priceCurrency" content="TWD" />
4395                                  <meta itemprop="price" content="700" />
4396                                  <meta itemprop="priceValidUntil" content="2030-11-15" />
4397                            </div>
4398                        </a></li>
4399                        <li><a itemscope="" itemtype="http://schema.org/Product" href="//www.phootime.com/framed"><span itemprop="name">木框畫</span>
4400                            <meta itemprop="description" content="木框畫多款框色,可自由組合出特色的拼貼照片牆!木框畫用頂級的藝術微噴讓作品更細緻,可長久保存不褪色。豪華版木框畫選用世界頂級品牌 Canson® Infinity 的頂級博物館專業油畫布印製照片,晉身藝術典藏等級。" />
4401                            <meta itemprop="image" content="https://gcdn.phootime.com/static/images/shop/landing/wood.jpg" />
4402                            <div itemprop="brand" itemtype="http://schema.org/Brand" itemscope>
4403                                <meta itemprop="name" content="Phootime無框畫第一品牌">
4404                                <meta itemprop="logo" content="https://gcdn.phootime.com/static/www/images/phootime_logo.svg">
4405                            </div>
4406                            <div itemprop="offers" itemtype="http://schema.org/Offer" itemscope>
4407                                  <link itemprop="url" href="https://www.phootime.com/framed" />
4408                                  <meta itemprop="availability" content="http://schema.org/InStock" />
4409                                  <meta itemprop="priceCurrency" content="TWD" />
4410                                  <meta itemprop="price" content="490" />
4411                                  <meta itemprop="priceValidUntil" content="2030-11-15" />
4412                            </div>
4413                        </a></li>
4414                        <li><a itemscope="" itemtype="http://schema.org/Product" href="//www.phootime.com/metal"><span itemprop="name">金屬鋁框畫</span>
4415                            <meta itemprop="description" content="頂級藝術微噴金屬鋁框畫,展覽等級製作,為您的照片創造再一次的感動顛峰" />
4416                            <meta itemprop="image" content="https://gcdn.phootime.com/static/www/images/framed_print_bg_06_s.jpg" />
4417                            <div itemprop="brand" itemtype="http://schema.org/Brand" itemscope>
4418                                <meta itemprop="name" content="Phootime無框畫第一品牌">
4419                                <meta itemprop="logo" content="https://gcdn.phootime.com/static/www/images/phootime_logo.svg">
4420                            </div>
4421                            <div itemprop="offers" itemtype="http://schema.org/Offer" itemscope>
4422                                  <link itemprop="url" href="https://www.phootime.com/metal" />
4423                                  <meta itemprop="availability" content="http://schema.org/InStock" />
4424                                  <meta itemprop="priceCurrency" content="TWD" />
4425                                  <meta itemprop="price" content="1790" />
4426                                  <meta itemprop="priceValidUntil" content="2030-11-15" />
4427                            </div>
4428                        </a></li>
4429                        <li><a itemscope="" itemtype="http://schema.org/Product" href="//www.phootime.com/gatorfoam"><span itemprop="name">磁吸霧柔無框畫</span>
4430                            <meta itemprop="description" content="僅 5 個 10 元硬幣重,
4430附贈雙面膠片,可免用掛鉤、免用黏土,直接貼牆輕鬆搞定。" />
4431                            <meta itemprop="image" content="https://gcdn3.phootime.com/static/www/images/2022/gatorfoam_01.jpg" />
4432                            <div itemprop="brand" itemtype="http://schema.org/Brand" itemscope>
4433                                <meta itemprop="name" content="Phootime無框畫第一品牌">
4434                                <meta itemprop="logo" content="https://gcdn.phootime.com/static/www/images/phootime_logo.svg">
4435                            </div>
4436                            <div itemprop="offers" itemtype="http://schema.org/Offer" itemscope>
4437                                  <link itemprop="url" href="https://www.phootime.com/gatorfoam" />
4438                                  <meta itemprop="availability" content="http://schema.org/InStock" />
4439                                  <meta itemprop="priceCurrency" content="TWD" />
4440                                  <meta itemprop="price" content="399" />
4441                                  <meta itemprop="priceValidUntil" content="2030-11-15" />
4442                            </div>
4443                        </a></li>
4444                        <li><a itemscope="" itemtype="http://schema.org/Product" href="//www.phootime.com/frameneo"><span itemprop="name">霓彩懸浮相框</span>
4445                            <meta itemprop="description" content="Frame Neo 霓彩懸浮相框,照片懸浮於雙層透明壓克力之間,四款霓彩框色沿邊緣發光,手工製作、可立可掛。" />
4446                            <meta itemprop="image" content="https://gcdn.phootime.com/static/images/shop/color_acrylic_tile.jpg" />
4447                            <div itemprop="brand" itemtype="http://schema.org/Brand" itemscope>
4448                                <meta itemprop="name" content="Phootime無框畫第一品牌">
4449                                <meta itemprop="logo" content="https://gcdn.phootime.com/static/www/images/phootime_logo.svg">
4450                            </div>
4451                            <div itemprop="offers" itemtype="http://schema.org/Offer" itemscope>
4452                                  <link itemprop="url" href="https://www.phootime.com/frameneo" />
4453                                  <meta itemprop="availability" content="http://schema.org/InStock" />
4454                                  <meta itemprop="priceCurrency" content="TWD" />
4455                                  <meta itemprop="price" content="890" />
4456                                  <meta itemprop="priceValidUntil" content="2030-11-15" />
4457                            </div>
4458                        </a></li>
4459                        <li><a itemscope="" itemtype="http://schema.org/Product" href="//www.phootime.com/squarecard"><span itemprop="name">小桌卡、月曆</span><span style="margin-left:6px;padding:0 5px;font-size:11px;line-height:1.6;color:#9a9097;background:#f1ebee;border-radius:4px;white-space:nowrap;">已停售</span>
4460                            <meta itemprop="description" content="小桌卡,特選厚磅歐洲進口頂級藝術紙,絕佳手感,原木木座擺設,桌面佈置小幫手" />
4461                            <meta itemprop="image" content="https://gcdn.phootime.com/static/www/images/square_cards_bg_01_s.jpg" />
4462                            <div itemprop="brand" itemtype="http://schema.org/Brand" itemscope>
4463                                <meta itemprop="name" content="Phootime無框畫第一品牌">
4464                                <meta itemprop="logo" content="https://gcdn.phootime.com/static/www/images/phootime_logo.svg">
4465                            </div>
4466                            <div itemprop="offers" itemtype="http://schema.org/Offer" itemscope>
4467                                  <link itemprop="url" href="https://www.phootime.com/squarecard" />
4468                                  <meta itemprop="availability" content="http://schema.org/Discontinued" />
4469                                  <meta itemprop="priceCurrency" content="TWD" />
4470                                  <meta itemprop="price" content="350" />
4471                                  <meta itemprop="priceValidUntil" content="2030-11-15" />
4472                            </div>
4473                        </a></li>
4474                        <li><a itemscope="" itemtype="http://schema.org/Product" href="//www.phootime.com/miniphotostrip"><span itemprop="name">四連拍拍卡</span><span style="margin-left:6px;padding:0 5px;font-size:11px;line-height:1.6;color:#9a9097;background:#f1ebee;border-radius:4px;white-space:nowrap;">已停售</span>
4475                            <meta itemprop="description" content="重現經典四連拍趣味,特選進口厚磅典藏級藝術紙給你絕佳手感,頂級藝術微噴讓你的照片長久不褪色,原木木座擺設,桌面佈置小幫手" />
4476                            <meta itemprop="image" content="https://gcdn.phootime.com/static/www/images/mini_photostrip_bg_02_s.jpg" />
4477                            <div itemprop="brand" itemtype="http://schema.org/Brand" itemscope>
4478                                <meta itemprop="name" content="Phootime無框畫第一品牌">
4479                                <meta itemprop="logo" content="https://gcdn.phootime.com/static/www/images/phootime_logo.svg">
4480                            </div>
4481                            <div itemprop="offers" itemtype="http://schema.org/Offer" itemscope>
4482                                  <link itemprop="url" href="https://www.phootime.com/miniphotostrip" />
4483                                  <meta itemprop="availability" content="http://schema.org/Discontinued" />
4484                                  <meta itemprop="priceCurrency" content="TWD" />
4485                                  <meta itemprop="price" content="350" />
4486                                  <meta itemprop="priceValidUntil" content="2030-11-15" />
4487                            </div>
4488                        </a></li>
4489                        <li><a itemscope="" itemtype="http://schema.org/Product" href="//www.phootime.com/photostrip"><span itemprop="name">海報掛條</span>
4490                            <meta itemprop="description" content="2024 年曆,客製化照片掛曆,北歐風格磁鐵掛畫器,精選平滑藝術紙,生日節日送禮最暖心的禮物" />
4491                            <meta itemprop="image" content="https://gcdn.phootime.com/static/images/shop/landing/photostrip2.
4491jpg" />
4492                            <div itemprop="brand" itemtype="http://schema.org/Brand" itemscope>
4493                                <meta itemprop="name" content="Phootime無框畫第一品牌">
4494                                <meta itemprop="logo" content="https://gcdn.phootime.com/static/www/images/phootime_logo.svg">
4495                            </div>
4496                            <div itemprop="offers" itemtype="http://schema.org/Offer" itemscope>
4497                                  <link itemprop="url" href="https://www.phootime.com/photostrip" />
4498                                  <meta itemprop="availability" content="http://schema.org/InStock" />
4499                                  <meta itemprop="priceCurrency" content="TWD" />
4500                                  <meta itemprop="price" content="850" />
4501                                  <meta itemprop="priceValidUntil" content="2030-11-15" />
4502                            </div>
4503                        </a></li>
4504                        <li><a itemscope="" itemtype="http://schema.org/Product" href="//www.phootime.com/hinoki"><span itemprop="name">日本檜木相框</span><span style="margin-left:6px;padding:0 5px;font-size:11px;line-height:1.6;color:#9a9097;background:#f1ebee;border-radius:4px;white-space:nowrap;">已停售</span>
4505                            <meta itemprop="description" content="Phootime 與一郎木創聯名合作,以 11 色藝術微噴的頂級技術印製您的照片,再放入一郎木創的日本檜木相框,與天然原木處理的日本檜木完美地融入您的生活。" />
4506                            <meta itemprop="image" content="https://gcdn.phootime.com/static/www/images/wood_design_print_bg_07_1_parallax.jpg" />
4507                            <div itemprop="brand" itemtype="http://schema.org/Brand" itemscope>
4508                                <meta itemprop="name" content="Phootime無框畫第一品牌">
4509                                <meta itemprop="logo" content="https://gcdn.phootime.com/static/www/images/phootime_logo.svg">
4510                            </div>
4511                            <div itemprop="offers" itemtype="http://schema.org/Offer" itemscope>
4512                                  <link itemprop="url" href="https://www.phootime.com/hinoki" />
4513                                  <meta itemprop="availability" content="http://schema.org/Discontinued" />
4514                                  <meta itemprop="priceCurrency" content="TWD" />
4515                                  <meta itemprop="price" content="1150" />
4516                                  <meta itemprop="priceValidUntil" content="2030-11-15" />
4517                            </div>
4518                        </a></li>
4519                                                <li><a itemscope="" itemtype="http://schema.org/Product" href="//www.phootime.com/lightbox"><span itemprop="name">藝術燈箱</span><span style="margin-left:6px;padding:0 5px;font-size:11px;line-height:1.6;color:#9a9097;background:#f1ebee;border-radius:4px;white-space:nowrap;">已停售</span>
4520                            <meta itemprop="description" content="藝術燈箱,實木手工框,可輕鬆更換藝術微噴照片燈片,燈箱可調整不同亮度,也可當夜燈,點亮幸福的照片燈箱。二代照片燈箱採全新獨家設計一體成型 LED 燈板,發光均勻穩定,業界第一。" />
4521                            <meta itemprop="image" content="https://gcdn.phootime.com/static/www/images/lightbox_bg_01_s.jpg" />
4522                            <div itemprop="brand" itemtype="http://schema.org/Brand" itemscope>
4523                                <meta itemprop="name" content="Phootime無框畫第一品牌">
4524                                <meta itemprop="logo" content="https://gcdn.phootime.com/static/www/images/phootime_logo.svg">
4525                            </div>
4526                            <div itemprop="offers" itemtype="http://schema.org/Offer" itemscope>
4527                                  <link itemprop="url" href="https://www.phootime.com/lightbox" />
4528                                  <meta itemprop="availability" content="http://schema.org/Discontinued" />
4529                                  <meta itemprop="priceCurrency" content="TWD" />
4530                                  <meta itemprop="price" content="1699" />
4531                                  <meta itemprop="priceValidUntil" content="2030-11-15" />
4532                            </div>
4533                        </a></li>
4534                        <li><a itemscope="" itemtype="http://schema.org/Product" href="//www.phootime.com/premiumpaper"><span itemprop="name">頂級相紙</span>
4535                            <meta itemprop="description" content="頂級藝術微噴輸出,選用法國 Canson 頂級無酸純棉平光藝術紙與 EPSON 頂級半光面相紙,支援高色域,能呈現鮮豔色彩,皆為專業攝影師展覽作品專用紙材,且足以與傳統銀鹽相片沖洗所產生的效果相媲美,讓您重現眼見感受的溫度。" />
4536                            <meta itemprop="image" content="https://gcdn.phootime.com/static/www/images/photo_bg_01_s.jpg" />
4537                            <div itemprop="brand" itemtype="http://schema.org/Brand" itemscope>
4538                                <meta itemprop="name" content="Phootime無框畫第一品牌">
4539                                <meta itemprop="logo" content="https://gcdn.phootime.com/static/www/images/phootime_logo.svg">
4540                            </div>
4541                            <div itemprop="offers" itemtype="http://schema.org/Offer" itemscope>
4542                                  <link itemprop="url" href="https://www.phootime.com/premiumpaper" />
4543                                  <meta itemprop="availability" content="http://schema.org/InStock" />
4544                                  <meta itemprop="priceCurrency" content="TWD" />
4545                                  <meta itemprop="price" content="290" />
4546                                  <meta itemprop="priceValidUntil" content="2030-11-15" />
4547                            </div>
4548                        </a></li>
4549                    </ul>
4550                </div>
4551                <div class="col">
4552                    <h4>服務相關</h2>
4553                    <ul>
4554                        <li><a href="https://www.phootime.com/epson">EPSON 藝術微噴</a></li>
4555                        <li><a href="https://www.phootime.com/notice/">商品注意事項</a></li>
4556                        <li><a href="https://www.phootime.com/coloring">光線的影響</a></li>
4557                        <li><a href="https://www.phootime.com/monitorcheck">螢幕校正</a></li>
4558                        <li><a href="https://www.phootime.com/hanging">掛畫掛勾選擇指南</a></li>
4559                        <li><a href="https://shop.phootime.com/shopping/shipping">
4559訂單狀態查詢</a></li>
4560                        <li><a href="https://www.phootime.com/faq/">常見問題</a></li>
4561                        <li><a href="https://www.phootime.com/largeorder">企業大量訂購與文創周邊商品代工服務</a></li>
4562                        <li><a href="http://phootime.com/user/login?next=%2F">販售作品登入</a></li>
4563                        <li><a href="//www.phootime.com/sell">創作募集</a></li>
4564                    </ul>
4565                </div>
4566                <div class="col hot-topics">
4567                    <h4>主題專區</h2>
4568                    <ul>
4569                    <li><a href="https://shop.phootime.com/brothers">中信兄弟聯名商品</a></li>
4570                        <li><a href="https://shop.phootime.com/uni-lions">統一獅聯名商品</a></li>
4571                        <li><a href="https://shop.phootime.com/wdragons">味全龍聯名商品</a></li>
4572                        <li><a href="https://shop.phootime.com/lioneers">新竹攻城獅聯名商品</a></li>
4573                        <li><a href="https://www.phootime.com/wedding">婚禮企劃 <img class="icon" src="https://gcdn3.phootime.com/static/images/shop/wedding-ring.png" alt="婚禮企劃"></a></li>
4574                        <li><a href="https://www.phootime.com/baby">寶寶成長紀錄 <img class="icon" src="https://gcdn2.phootime.com/static/images/shop/rubber-duck.png" alt="寶寶成長紀錄"></a></li>
4575                        <li><a href="https://www.phootime.com/graduation">畢業禮物 <img class="icon" src="https://gcdn1.phootime.com/static/images/shop/graduate.png" alt="畢業禮物"></a></li>
4576                        <li><a href="https://www.phootime.com/pets">寵愛毛孩 <img class="icon" src="https://gcdn4.phootime.com/static/images/shop/dog.png" alt="寵愛毛孩"></a></li>
4577                        <li><a href="https://www.phootime.com/gifts/mothersday">母親節禮物</a></li>
4578                        <li><a href="https://www.phootime.com/gifts/birthday">生日禮物</a></li>
4579                        <li><a href="https://www.phootime.com/gifts/fathersday">父親節禮物</a></li>
4580                        <li><a href="https://www.phootime.com/gifts/valentinesday">情人節禮物</a></li>
4581                        <li><a href="https://www.phootime.com/gifts/xmas">聖誕禮物</a></li>
4582                        <li><a href="https://www.phootime.com/caricature">AI 似顏繪</a></li>
4583                        <li><a href="https://www.phootime.com/nft">NFT 作品印製</a></li>
4584                    </ul>
4585                </div>
4586                <div class="col desktop awards">
4587                    <a href="https://www.phootime.com/epson" rel="noopener" class="red_herring"><img loading="lazy" src="https://gcdn3.phootime.com/static/images/shop/epson.jpg" alt="Epson 官方認證藝術微噴輸出中心" title="Epson 官方認證藝術微噴輸出中心"></a>
4588                    <a href="javascript:void(0);" rel="noopener" class="pantone"><img loading="lazy" src="https://gcdn1.phootime.com/static/images/shop/logo_pantone.jpg" alt="phootime 取得 X-Rite PANTONE 國際認證色彩控制達人" title="phootime 取得 X-Rite PANTONE 國際認證色彩控制達人"></a>
4589                                                            <p><div class="fb-like" data-href="https://www.facebook.com/phootime/" data-layout="button_count" data-action="like" data-size="small" data-show-faces="false" data-share="false"></div>
4590                    
4590<script async defer crossorigin="anonymous" src="https://connect.facebook.net/zh_TW/sdk.js#xfbml=1&version=v17.0" nonce="JfKqWeH5"></script>
4590
4591                                    </div>
4592            </div>
4593            <ul class="navi">
4594                <li><a href="//www.phootime.com/store_terms">使用條款</a></li>
4595                <li><a href="//www.phootime.com/store_terms#return_policy">退換政策</a></li>
4596                <li><a href="https://facebook.com/phootime" rel="noopener" target="_blank"><i class="fa fa-facebook"></i></a></li>
4597                <li><a href="https://instagram.com/phootime" rel="noopener" target="_blank"><i class="fa fa-instagram"></i></a></li>
4598                <li class="lang-cur">
4599                    <select id="lang" class="lang drop-up" name="lang" style="display:none;">
4600                        <option value="en"  >English</option>
4601                        <option value="zh_tw" selected="selected">中文(台灣)</option>
4602                    </select>
4603                    <div id="cur">
4604                        <select class="cur" name="currency">
4605                            <option value="TWD" selected="">NT$ - TWD - 新台幣</option>
4606                            <option value="HKD" >HK$ - HKD - 港幣</option>
4607                            <option value="MOP" >MOP - 澳門幣</option>
4608                            <option value="USD" >US$ - USD - 美元</option>
4609                            <option value="CNY" >CN¥ - CNY - 中國人民幣</option>
4610                            <option value="SGD" >SGD - 新加坡幣</option>
4611                            <option value="JPY" >¥ - JPY - 日圓</option>
4612                            <option value="KRW" >₩ - KRW - 韓圜</option>
4613                            <option value="MYR" >MYR - 馬來西亞令吉</option>
4614                            <option value="EUR" >€ - EUR - 歐元</option>
4615                            <option value="GBP" >£ - GBP - 磅</option>
4616                            <option value="AUD" >A$ - AUD - 澳幣</option>
4617                        </select>
4618                    </div>
4619                </li>
4620                <li class="copyright">Copyright &copy; 2026 Phootime 無框畫第一品牌<br/>光時創新股份有限公司54540433 Made in Taiwan</li>
4621            </ul>
4622        </div>
4623    </footer>
4624<div class="modal fade" id="popupImage" tabindex="-1" aria-labelledby="popupImageLabel" aria-hidden="true">
4625  <div class="modal-dialog modal-dialog-centered modal-mobile">
4626    <div class="modal-content position-relative">
4627      <button type="button" class="position-absolute top-0 end-0 border-0"
4628              data-bs-dismiss="modal" aria-label="Close"
4629              style="background-color: #eb8686; color: white; width: 40px; height: 40px; border-radius: 50%; transform: translate(20%, -20%); display: flex; justify-content: center; align-items: center; font-weight: bold; padding: 0; z-index: 1080;">
4630        <span style="font-size: 24px; padding-bottom: 4px;">×</span>
4631      </button>
4632
4633      <div class="modal-body p-0">
4634                <img src="https://gcdn.phootime.com/static/images/popups/1790926038_6abf5cd6879cb.jpg"
4635             class="img-fluid popup-image"
4636             alt="Popup Image"
4637             data-popup-id="wb39yk"
4638             data-link-url=""
4639             data-has-valid-link="false">
4640              </div>
4641    </div>
4642  </div>
4643</div>
4644<style>
4645.popup-image {
4646  cursor: pointer;
4647}
4648#popupImage .modal-dialog.modal-mobile {
4649    max-width: 720px;
4650    margin: 1.75rem auto;
4651}
4652#popupImage .modal-content {
4653    border-radius: 12px;
4654    background: transparent;
4655    border: 0;
4656}
4657#popupImage .modal-body {
4658    border-radius: 12px;
4659    overflow: hidden;
4660    line-height: 0;
4661}
4662#popupImage .popup-image {
4663    display: block;
4664    width: 100%;
4665    height: auto;
4666    max-height: 88vh;
4667    object-fit: contain;
4668    border-radius: 12px;
4669}
4670@media (max-width: 767px) {
4671    #popupImage .modal-dialog.modal-mobile {
4672        max-width: 92%;
4673        margin: 1rem auto;
4674    }
4675    #popupImage .popup-image {
4676        max-height: 82vh;
4677    }
4678}
4679/* HTML 內容彈窗:覆蓋圖片用的 line-height:0,並裁切圓角 */
4680#popupImage .modal-body .popup-html {
4681    line-height: normal;
4682    border-radius: 12px;
4683    overflow: hidden;
4684    max-height: 88vh;
4685    overflow-y: auto;
4686}
4687#popupImage .popup-html img { max-width: 100%; height: auto; }
4688@media (max-width: 767px) {
4689    #popupImage .modal-body .popup-html { max-height: 82vh; }
4690}
4691</style>
4692<script>
4693(function () {
4694    var POPUP_DEFER = false;
4695    var POPUP_ID = "wb39yk";
4696    var SEEN_VALUE = "";
4697    var SEEN_DAYS = 60;
4698    // A/B(只在 /create 延後頁):cookie pt_popab=on|off,沒有就擲一次 50/50 並存 30 天,使用者跨天回來仍在同一組
4699    var POPUP_AB = false;
4700    var POPUP_VARIANT = 'on';
4701    if (POPUP_AB) {
4702        try {
4703            var abm = document.cookie.match(/(?:^|;\s*)pt_popab=(on|off)(?:;|$)/);
4704            POPUP_VARIANT = abm ? abm[1] : (Math.random() < 0.5 ? 'off' : 'on');
4705            if (!abm) document.cookie = 'pt_popab=' + POPUP_VARIANT + '; path=/; max-age=' + (30 * 86400) + '; SameSite=Lax';
4706        } catch (e) {}
4707    }
4708    var shown = false;
4709    function markSeen() {
4710        if (POPUP_DEFER && SEEN_VALUE) {   // 真的顯示了才算「看過」(server 端在延後頁不寫 seen cookie)
4711            document.cookie = 'popup_seen=' + encodeURIComponent(SEEN_VALUE) + '; path=/; max-age=' + (SEEN_DAYS * 86400) + '; SameSite=Lax';
4712        }
4713    }
4714    function showPopup(reason) {
4715        if (shown) return;
4716        shown = true;
4717        if (POPUP_AB && POPUP_VARIANT === 'off') {
4718            // 對照組:/create 不跳,但「本來會跳的那一刻」照樣記 seen cookie 並發 popup_suppressed。
4719            // 兩組必須以同樣的節奏消耗促銷清單,否則 on 組看過的 banner 下次不再渲染(連 popup_ab_on 都不發),
4720            // off 組卻每 4 小時重新入組一次 → off 組回訪者比例偏高、轉換被高估。
4721            // popup_suppressed(reason) 與 popup_shown(reason) 觸發條件完全相同,是最乾淨的一對比較基準。
4722            markSeen();
4723            if (window.pt_track) pt_track('popup_suppressed', { popup_id: POPUP_ID, reason: reason || 'load' });
4724            return;
4725        }
4726        var el = document.getElementById('popupImage');
4727        if (!el) return;
4728        if (typeof bootstrap === 'undefined') { el.style.display = 'none'; return; }
4729        markSeen();
4730        var popupModal = new bootstrap.Modal(el, { backdrop: true, keyboard: true, focus: true });
4731        popupModal.show();
4732        if (window.pt_track) pt_track('popup_shown', { popup_id: POPUP_ID, reason: reason || 'load' });
4733        el.addEventListener('hidden.bs.modal', function () { if (window.pt_track) pt_track('popup_closed', { popup_id: POPUP_ID }); }, { once: true });
4734    }
4735    window.pt_popup_show = showPopup;   // /create:上傳完成後由 showUploadFile 延遲呼叫
4736    document.addEventListener('DOMContentLoaded', function () {
4737        if (!POPUP_DEFER) { showPopup('load'); return; }
4738        // 重編模式(寄預覽圖後回來改圖、iframe 內)不跳任何彈窗
4739        if (document.body.classList.contains('c26-reedit') || window.pt_reedit_embed) return;
4740        // A/B 分組事件:每次進頁發一次,GA 漏斗以 popup_ab_on / popup_ab_off 為第一步比較後續 upload_start / add_to_cart
4741        if (POPUP_AB && window.pt_track) pt_track('popup_ab_' + POPUP_VARIANT, { popup_id: POPUP_ID });
4742        // off 組不在這裡 return:計時器照跑,到點由 showPopup 決定「跳」或「記 seen + popup_suppressed」
4743        // 30 秒仍未開始上傳才跳;一旦開始上傳就改走「上傳完成後」那條路
4744        setTimeout(function () { if (!window._ptUploadStarted) showPopup('idle30s'); }, 30000);
4745    });
4746})();
4747$(document).ready(function() {
4748  // Popup click handler
4749  $('.popup-image').on('click', function() {
4750    var $img = $(this);
4751    var popupId = $img.data('popup-id');
4752    var linkUrl = $img.data('link-url');
4753    var hasValidLink = $img.data('has-valid-link');
4754
4755    if (!popupId) {
4756      console.error('Popup ID is required');
4757      return;
4758    }
4759
4760    // Add clicking effect
4761    $img.addClass('clicking');
4762
4763    // Record click
4764    recordPopupClick(popupId)
4765      .done(function(response) {
4766        if (response.success) {
4767          // Check if has valid link
4768          if (hasValidLink === false || hasValidLink === 'false' || !linkUrl) {
4769            // No valid link, just close modal
4770            $('#popupImage').modal('hide');
4771          } else if (isSameUrl(linkUrl, window.location.href)) {
4772            // Same URL, just close modal
4773            $('#popupImage').modal('hide');
4774          } else {
4775            // Different URL, navigate to it
4776            window.location.href = linkUrl;
4777          }
4778        } else {
4779          console.error('Failed to record click:', response.message);
4780        }
4781      })
4782      .fail(function(xhr, status, error) {
4783        console.error('AJAX error:', error);
4784      })
4785      .always(function() {
4786        // Remove clicking effect
4787        setTimeout(function() {
4788          $img.removeClass('clicking');
4789        }, 200);
4790      });
4791  });
4792});
4793
4794// Function to check if two URLs are the same
4795function isSameUrl(url1, url2) {
4796  try {
4797    // Handle relative URLs
4798    var link1 = new URL(url1, window.location.origin);
4799    var link2 = new URL(url2, window.location.origin);
4800
4801    // Compare the full URLs (excluding hash fragments)
4802    return link1.origin + link1.pathname + link1.search ===
4803           link2.origin + link2.pathname + link2.search;
4804  } catch (e) {
4805    // Fallback: simple string comparison
4806    return url1 === url2;
4807  }
4808}
4809
4810// AJAX function to record popup click using jQuery
4811function recordPopupClick(popupId) {
4812  return $.ajax({
4813    url: '/recordClick',
4814    type: 'POST',
4815    dataType: 'json',
4816    data: {
4817      id: popupId,
4818      'CSRF_TOKEN':'aff6f94ebfb88b50587cbbdc0d8f3a8703775ab7'
4819    },
4820    timeout: 5000 // 5 seconds timeout
4821  });
4822}
4823</script>
4823
4824
4825<script type="text/javascript">
4826
4827function listAddFav(photo_id) {
4828    $.ajax({
4829        type: 'POST',
4830        url: '/shop/itemfaves',
4831        data: {'photo_id':photo_id, 'return_url': window.location.href, 'CSRF_TOKEN':'aff6f94ebfb88b50587cbbdc0d8f3a8703775ab7'},
4832        dataType: 'json',
4833        async: true,
4834        success: function(data) {
4835
4836            if('0' == data.status) {
4837                if (data.login_required && data.login_url) {
4838                    window.location.href = data.login_url;
4839                    return;
4840                }
4841                toastr.info(data.error);
4842            } else if ('1' == data.status) {
4843
4844                if (data.fave == '1') {
4845                    $('#' + photo_id + ' .fav-icon').addClass('fa-heart').removeClass('fa-heart-o');
4846                } else {
4847                    $('#' + photo_id + ' .fav-icon').addClass('fa-heart-o').removeClass('fa-heart');
4848                }
4849            }
4850        }
4851    });
4852}
4853
4854$(document).ready(function() {
4855
4856    $('select.lang').niceSelect();
4857
4858    
4859    
4860    if ($('#customer-showcases').length) {
4861        var mySwiper_showcases = new Swiper ('#customer-showcases', {
4862            // Optional parameters
4863            direction: 'horizontal',
4864            slidesPerView: 1.2,
4865            centeredSlides: true,
4866            loop: true,
4867            spaceBetween: 5,
4868            // Disable preloading of all images
4869            preloadImages: true,
4870            autoplay: {
4871                delay: 3500,
4872            },
4873            lazy: true,
4874            lazyPreloadPrevNext: 2,
4875            // lazy: {
4876            //     loadPrevNext: true,
4877            // },
4878            breakpoints: {
4879                415: {
4880                  spaceBetween: 10,
4881                  slidesPerView: 2.2,
4882                },
4883                1315: {
4884                  spaceBetween: 10,
4885                  slidesPerView: 3.2,
4886                },
4887            }
4888        });
4889    }
4890    $('select.lang').change(function() {
4891        var lang = $(this).val();
4892        $.ajax({
4893            type: 'POST',
4894            url: '/home/locale',
4895            data: {'_lang': lang },
4896            async: true,
4897            complete: function(data) {
4898                var a = window.location.href;
4899                if (a.indexOf("#") != -1)
4900                    window.location.href = a.substring(0, a.indexOf("#"));
4901                else
4902                    window.location.href = window.location.href;
4903            }
4904        })
4905    });
4906
4907    $('select.cur').change(function() {
4908        var currency = $(this).val();
4909        $.ajax({
4910            type: 'POST',
4911            url: '/home/currency',
4912            data: {'_currency': currency },
4913            async: true,
4914            complete: function(data) {
4915                var a = window.location.href;
4916                if (a.indexOf("#") != -1)
4917                    window.location.href = a.substring(0, a.indexOf("#"));
4918                else
4919                    window.location.href = window.location.href;
4920            }
4921        })
4922    });
4923
4924    
4925    if (typeof LazyLoad != "undefined") {
4926        var myLazyLoad = new LazyLoad({
4927            elements_selector: ".lazyload",
4928            callback_loaded: function(el) {
4929                // AOS.refresh();
4930            },
4931        });
4932    }
4933
4934    if ($.isFunction($('.ba-slider').beforeAfter))
4935        $('.ba-slider').beforeAfter();
4936
4937});
4938
4939</script>
vendor: 1 bytes, line 4939
4939
4940<script type="text/javascript">
4941    (function() {
4942        var css = document.createElement('link');
4943        css.href = 'https://gcdn3.phootime.com/static/css/font-awesome.min.css';
4944        css.rel = 'stylesheet';
4945        css.type = 'text/css';
4946        document.getElementsByTagName('head')[0].appendChild(css);
4947    })();
4948</script>
4948
4949</body>
4950</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.