Diff -- /var/www/vhosts/webstls.com/httpdocs/TEMPLATES/webstls_cart.html
Diff

/var/www/vhosts/webstls.com/httpdocs/TEMPLATES/webstls_cart.html

added on WebSTLs (webstls.com) at 2026-07-01 22:26:58

Added
+220
lines
Removed
-0
lines
Context
0
unchanged
Blobs
from
to 9974b53410cf
Restore this content →
Unified diff
Naive LCS-based line diff. Additions in emerald, deletions in rose. Both sides decompressed live from BLOB_STORE.
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <link rel="icon" type="image/svg+xml" href="/assets/images/favicon.svg">
7 <title>Cart &middot; $store_name</title>
8 <link rel="stylesheet" href="/assets/css/site.css">
9 <style>:root { $theme_css_vars }</style>
10 <style>
11 body { background: var(--col-bg); color: var(--col-text); font-family: var(--font-ui, sans-serif); margin: 0; }
12 .cart-page { max-width: 900px; margin: 0 auto; padding: 60px 24px 80px; }
13 .cart-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 28px; flex-wrap: wrap; gap: 14px; }
14 .cart-head h1 { font-size: 34px; margin: 0; color: var(--col-text); }
15 .cart-head a.back { color: var(--col-text-2); text-decoration: none; font-size: 13px; }
16 .cart-head a.back:hover { color: var(--col-accent-bright); }
17 .cart-row {
18 display: flex; align-items: center; gap: 16px;
19 padding: 14px;
20 background: var(--col-surface-1);
21 border: 1px solid var(--col-border);
22 border-radius: 12px;
23 margin-bottom: 10px;
24 transition: opacity 0.2s;
25 }
26 .cart-row.is-removing { opacity: 0.3; pointer-events: none; }
27 .cart-thumb { width: 90px; height: 90px; border-radius: 8px; background-size: cover; background-position: center; flex-shrink: 0; border: 1px solid var(--col-border); }
28 .cart-info { flex: 1; min-width: 0; }
29 .cart-title { font-size: 16px; font-weight: 600; color: var(--col-text); margin-bottom: 4px; }
30 .cart-meta { font-size: 12px; color: var(--col-text-3); }
31 .cart-line { font-size: 16px; font-weight: 700; color: var(--col-accent-bright); font-family: var(--font-mono, monospace); }
32 .cart-variant { display:inline-block; margin-top:4px; padding:2px 8px; font-size:11px; letter-spacing:0.5px; font-weight:600; border-radius:5px; background:rgba(255,255,255,0.06); color:var(--col-text-2); text-transform:none; }
33 .cart-variant.is-physical { background:rgba(217,119,6,0.15); color:#f59e0b; }
34 .cart-ship-note { margin-top:12px; padding:10px 14px; background:rgba(217,119,6,0.08); border:1px solid rgba(217,119,6,0.25); border-radius:10px; color:#f59e0b; font-size:13px; display:flex; align-items:center; gap:10px; }
35 .cart-x {
36 background: none; border: 1px solid var(--col-border);
37 color: var(--col-text-3);
38 width: 30px; height: 30px; border-radius: 50%;
39 cursor: pointer; flex-shrink: 0;
40 display: grid; place-items: center;
41 font-size: 16px;
42 transition: all 0.15s;
43 }
44 .cart-x:hover { background: rgba(239,68,68,0.18); color: #f87171; border-color: rgba(239,68,68,0.4); }
45 .cart-empty {
46 text-align: center; padding: 80px 24px;
47 border: 1px dashed var(--col-border-2);
48 border-radius: 14px;
49 color: var(--col-text-2);
50 }
51 .cart-empty h2 { color: var(--col-text); margin-bottom: 10px; }
52 .cart-summary {
53 margin-top: 26px; padding: 18px 22px;
54 background: var(--col-surface-1);
55 border: 1px solid var(--col-border-2);
56 border-radius: 12px;
57 display: flex; justify-content: space-between; align-items: center;
58 flex-wrap: wrap; gap: 14px;
59 }
60 .cart-summary-total { font-size: 22px; font-weight: 700; color: var(--col-text); }
61 .cart-summary-total .num { color: var(--col-accent-bright); font-family: var(--font-mono, monospace); }
62 .cart-checkout-btn {
63 background: linear-gradient(130deg, var(--col-accent), var(--col-accent-bright));
64 color: #fff; border: 0; padding: 12px 24px;
65 font-size: 14px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase;
66 border-radius: 10px; cursor: pointer; font-family: inherit;
67 transition: filter 0.15s;
68 text-decoration: none; display: inline-block;
69 }
70 .cart-checkout-btn:hover { filter: brightness(1.08); }
71 </style>
72</head>
73<body>
74
75$store_chrome_html
76
77<main class="cart-page">
78
79 <div class="cart-head">
80 <h1>Your cart</h1>
81 <a class="back" href="$back_href">&larr; Keep shopping at $store_name</a>
82 </div>
83
84 [if:$has_items]
85 <div id="cart-rows">
86 [loop:@items]
87 <div class="cart-row" data-cart-item-id="$loop1.cart_item_id">
88 <div class="cart-thumb" style="background-image:url('$loop1.hero');background-position:$loop1.hero_pos"></div>
89 <div class="cart-info">
90 <div class="cart-title">$loop1.title</div>
91 <div class="cart-meta">Qty $loop1.quantity &middot; $loop1.price each</div>
92 [if:$loop1.variant_pill]<span class="cart-variant[if:$loop1.is_physical] is-physical[/if]">$loop1.variant_pill</span>[/if]
93 </div>
94 <div class="cart-line">$loop1.line_total</div>
95 <button type="button" class="cart-x" data-rm="$loop1.cart_item_id" title="Remove">&times;</button>
96 </div>
97 [/loop]
98 </div>
99
100 [if:$needs_shipping]
101 <div class="cart-ship-note">
102 <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2"><rect x="1" y="3" width="15" height="13" rx="2"/><polygon points="16 8 20 8 23 11 23 16 16 16 16 8"/><circle cx="5.5" cy="18.5" r="2.5"/><circle cx="18.5" cy="18.5" r="2.5"/></svg>
103 <span>This order includes printed items &mdash; you'll enter a shipping address at checkout.</span>
104 </div>
105 [/if]
106
107 <!-- Promo code panel. Inline-styled so storefront themes inherit
108 theme_css_vars without us having to ship a separate per-theme
109 stylesheet. The discount line below is rendered only when
110 cart_promotions has an applied row. -->
111 <style>
112 .cart-promo { margin:18px 0 6px; padding:12px 14px; border-radius:10px; background:rgba(255,255,255,0.04); border:1px solid rgba(255,255,255,0.10); }
113 .cart-promo-flash { padding:8px 10px; margin-bottom:10px; border-radius:8px; font-size:13px; }
114 .cart-promo-flash.ok { background:rgba(34,197,94,0.10); border:1px solid rgba(34,197,94,0.35); color:#86efac; }
115 .cart-promo-flash.err { background:rgba(239,68,68,0.10); border:1px solid rgba(239,68,68,0.35); color:#fca5a5; }
116 .cart-promo-row { display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
117 .cart-promo-row input { flex:1; min-width:140px; padding:8px 12px; border-radius:8px; border:1px solid rgba(255,255,255,0.15); background:rgba(0,0,0,0.25); color:#fff; font:600 13px var(--font-mono, monospace); letter-spacing:1px; text-transform:uppercase; }
118 .cart-promo-row button { padding:9px 16px; border:0; border-radius:8px; background:linear-gradient(135deg,#3b82f6,#7c3aed); color:#fff; font-weight:700; cursor:pointer; }
119 .cart-promo-applied { display:flex; align-items:center; gap:10px; padding:10px 12px; border-radius:8px; background:rgba(34,197,94,0.10); border:1px solid rgba(34,197,94,0.30); color:#86efac; font-size:13px; flex-wrap:wrap; }
120 .cart-promo-applied code { background:rgba(255,255,255,0.10); padding:2px 7px; border-radius:5px; font-weight:700; }
121 .cart-promo-applied .grow { flex:1; }
122 .cart-promo-applied button { background:transparent; border:1px solid rgba(252,165,165,0.35); color:#fca5a5; padding:5px 12px; border-radius:6px; font-size:12px; cursor:pointer; }
123 .cart-summary-row { display:flex; justify-content:space-between; font-size:13px; color:rgba(255,255,255,0.75); margin-bottom:4px; }
124 .cart-summary-row.discount { color:#86efac; }
125 </style>
126 <div class="cart-promo">
127 [if:$has_promo_flash]
128 <div class="cart-promo-flash $promo_flash_kind">$promo_flash_msg</div>
129 [/if]
130 [if:$has_applied_promo]
131 <div class="cart-promo-applied">
132 <span>&#10003; <strong>$applied_label</strong> with code <code>$applied_code</code></span>
133 <span class="grow"></span>
134 <form method="POST" action="/cart_promo.cgi" style="margin:0">
135 <input type="hidden" name="action" value="remove">
136 <input type="hidden" name="storefront_id" value="$store_id">
137 <button type="submit">Remove</button>
138 </form>
139 </div>
140 [/if]
141 [if:!$has_applied_promo]
142 <form class="cart-promo-row" method="POST" action="/cart_promo.cgi">
143 <input type="hidden" name="action" value="apply">
144 <input type="hidden" name="storefront_id" value="$store_id">
145 <input type="text" name="code" placeholder="ENTER CODE" maxlength="64" autocomplete="off">
146 <button type="submit">Apply</button>
147 </form>
148 [/if]
149 </div>
150
151 <div class="cart-summary">
152 [if:$has_discount]
153 <div class="cart-summary-row"><span>Subtotal</span><span class="num">$subtotal_display</span></div>
154 <div class="cart-summary-row discount"><span>Discount ($applied_code)</span><span class="num">-$discount_display</span></div>
155 [/if]
156 [if:$has_credit]
157 <div class="cart-summary-row"><span>Subtotal</span><span class="num">$total_before_credit_display</span></div>
158 <div class="cart-summary-row discount"><span>Store credit applied</span><span class="num">-$credit_applied_display</span></div>
159 [/if]
160 <div class="cart-summary-total">Total <span class="num">$total_display</span></div>
161 [if:$has_credit_balance][if:!$has_credit]
162 <div style="font-size:11px;color:var(--col-text-3,#888);margin-top:8px;text-align:center">You have $credit_balance_display store credit available.</div>
163 [/if][/if]
164 <a class="cart-checkout-btn" href="/checkout.cgi?id=$store_id">Checkout &rarr;</a>
165 </div>
166 [/if]
167
168 [if:!$has_items]
169 <div class="cart-empty">
170 <h2>Your cart is empty</h2>
171 <p>Browse the store and tap <strong>Add to cart</strong> on anything you want to take with you.</p>
172 <a class="cart-checkout-btn" href="$back_href" style="margin-top:18px">Back to $store_name</a>
173 </div>
174 [/if]
175
176</main>
177
178<script>
179(function() {
180 /* Per-row remove. POSTs to /cart_remove.cgi, hides the row on
181 success. Reloads if the cart becomes empty so the empty state
182 renders correctly. */
183 document.addEventListener('click', function(e) {
184 var btn = e.target.closest('[data-rm]');
185 if (!btn) return;
186 var row = btn.closest('.cart-row');
187 var id = btn.getAttribute('data-rm');
188 if (!row || !id) return;
189 row.classList.add('is-removing');
190 var fd = new FormData();
191 fd.append('cart_item_id', id);
192 fetch('/cart_remove.cgi', { method: 'POST', body: fd, credentials: 'same-origin' })
193 .then(function(r){ return r.json(); })
194 .then(function(data){
195 if (!data || !data.success) throw new Error(data && data.error || 'remove failed');
196 row.style.height = row.offsetHeight + 'px';
197 requestAnimationFrame(function(){
198 row.style.transition = 'opacity 0.2s, height 0.25s, margin 0.25s, padding 0.25s';
199 row.style.opacity = '0';
200 row.style.height = '0';
201 row.style.marginBottom = '0';
202 row.style.padding = '0';
203 setTimeout(function(){
204 row.remove();
205 if (!document.querySelectorAll('.cart-row').length) {
206 window.location.reload();
207 }
208 }, 260);
209 });
210 })
211 .catch(function(err){
212 row.classList.remove('is-removing');
213 appToast({ message: 'Could not remove: ' + err.message, type: 'error' });
214 });
215 });
216})();
217</script>
218
219</body>
220</html>
Keyboard: j next diff k previous diff g top G bottom r restore c compile-check ? help