1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <title>Our Story: Vietnamese Family Cooking in Chicago Since 2009 | Saigon Sisters</title> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"> 6 <meta charset="UTF-8"> 7 8 <meta name="description" content="Sisters Mary Nguyen Aregoni and Theresa Nguyen opened Saigon Sisters at Chicago's French Market in 2009, bringing Mama Suu's recipes to the West Loop." /> 9 <meta property="og:title" content="The Sisters Behind Saigon Sisters" /> 10 <meta property="og:description" content="From Mama Suu's pho station at the French Market in 2009 to a West Loop restaurant: the Vietnamese family story behind Saigon Sisters." /> 11 <meta property="og:image" content="https://res.cloudinary.com/targetable/image/upload/v1787255781/Customers/50070/Saigon%20Sisters/PICS/logo.svg" /> 12 <meta property="og:type" content="website" /> 13 <meta property="og:url" content="https://www.saigonsisters.com/about-us" /> 14 15 <link rel="icon" type="image/png" href="https://res.cloudinary.com/targetable/image/upload/v1787255780/Customers/50070/Saigon%20Sisters/PICS/favicon.png"> 16 <link rel="canonical" href="https://www.saigonsisters.com/about-us" /> 17 18 19 20 21 22 <link rel="stylesheet" href="/assets/site-fa6bd954239289997bc418875168ed5ab9c9013b19cc0c43e02d72d7ae77e155.css" data-turbo-track="reload" /> 23 <link rel="stylesheet" href="/assets/icons-8a8adf1b209dcf6019c445e5477d00b79192f6726b65fd7cf29cf43036ec3917.css" data-turbo-track="reload" /> 24 25
25<script type="importmap" data-turbo-track="reload">{ 26 "imports": { 27 "application": "/assets/application-4a1c1d27c11faa4dbac51fff4126422169b85739cdee3e8b89ea183bc17a2c23.js", 28 "@hotwired/turbo-rails": "/assets/turbo.min-f3765a09513ca1417099ce92257ef54b9d4cf3a7addc7dcbb1d6d848d307ee8a.js", 29 "@hotwired/stimulus": "/assets/stimulus.min-dd364f16ec9504dfb72672295637a1c8838773b01c0b441bd41008124c407894.js", 30 "@hotwired/stimulus-loading": "/assets/stimulus-loading-3576ce92b149ad5d6959438c6f291e2426c86df3b874c525b30faad51b0d96b3.js", 31 "site": "/assets/site-4b047adea2bfbedbd09cb582dd17c2c15e218d15c9dc17cfa26985c983bcea78.js", 32 "local-time": "/assets/local-time-821d43d4efe5c285055b57aea1a1f04a89a1019f689de214873d5af45a3ab3d7.js", 33 "jquery": "/assets/jquery-9292661fe0d8c5ef2ef35f5ca64d541d70c87e9f6d7f2716d646591a295b7f36.js", 34 "jquery-mask-plugin": "/assets/jquery-mask-plugin-12f491759485d6e50f909cf5fb641f245011016ab91b9043c057666fe07a99c0.js", 35 "alpinejs": "/assets/alpinejs-1330ff78f6252d676b60ac1291d71df4f04e542899717f8ee4d03a79dec27045.js", 36 "swiper": "/assets/swiper-2faaef3c8e00dc01e477390250b8d1e3950bde9bcacdc205a4a0265787e5c077.js", 37 "libraries/vidbg": "/assets/libraries/vidbg-ca103f7572673d0e7e3cc8a6a59b200f7ab3da61da78a43e532949d800635fa5.js", 38 "controllers/application": "/assets/controllers/application-368d98631bccbf2349e0d4f8269afb3fe9625118341966de054759d96ea86c7e.js", 39 "controllers/hello_controller": "/assets/controllers/hello_controller-549135e8e7c683a538c3d6d517339ba470fcfb79d62f738a0a089ba41851a554.js", 40 "controllers": "/assets/controllers/index-2db729dddcc5b979110e98de4b6720f83f91a123172e87281d5a58410fc43806.js", 41 "controllers/prompt_engineering_controller": "/assets/controllers/prompt_engineering_controller-c5abfd07f3f7b741f778d3070d18fd216b100840ef6cfdce4adb7c953a59d715.js" 42 } 43}</script>
43 44<link rel="modulepreload" href="/assets/site-4b047adea2bfbedbd09cb582dd17c2c15e218d15c9dc17cfa26985c983bcea78.js"> 45<link rel="modulepreload" href="/assets/jquery-9292661fe0d8c5ef2ef35f5ca64d541d70c87e9f6d7f2716d646591a295b7f36.js"> 46<link rel="modulepreload" href="/assets/jquery-mask-plugin-12f491759485d6e50f909cf5fb641f245011016ab91b9043c057666fe07a99c0.js"> 47<link rel="modulepreload" href="/assets/alpinejs-1330ff78f6252d676b60ac1291d71df4f04e542899717f8ee4d03a79dec27045.js"> 48<link rel="modulepreload" href="/assets/swiper-2faaef3c8e00dc01e477390250b8d1e3950bde9bcacdc205a4a0265787e5c077.js">
49<script type="module">import "site"</script>
49 50 51 <link rel="preconnect" href="https://fonts.googleapis.com"> 52 <link rel="preconnect" href="https://cdnjs.cloudflare.com"> 53 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 54 55 56 <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@48,700,0..1,0&icon_names=17mp,add_card,ads_click,app_promo,attach_money,award_star,bakery_dining,bookmark_star,breakfast_dining,brightness_alert,cake,cake_add,cleaning_bucket,coffee,credit_card,date_range,directions_bus,drag_click,emoji_food_beverage,explosion,fastfood,featured_seasonal_and_gifts,fiber_new,file_map,file_map_stack,fireplace,food_bank,fork_spoon,glass_cup,home_pin,kid_star,local_bar,local_dining,local_fire_department,local_pizza,location_on,lunch_dining,mail,mark_email_unread,motorcycle,online_prediction,open_in_phone,phone_enabled,pin_drop,potted_plant,priority,quick_reorder,ramen_dining,restaurant,rice_bowl,sell,sentiment_excited,set_meal,settings_cell,shopping_bag,skillet_cooktop,smartphone,soup_kitchen,sports_football,star,star_rate,stockpot,trophy,volunteer_activism,wifi_calling_bar_1,wine_bar&display=block" 57 rel="preload" as="style"> 58 <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@48,700,0..1,0&icon_names=17mp,add_card,ads_click,app_promo,attach_money,award_star,bakery_dining,bookmark_star,breakfast_dining,brightness_alert,cake,cake_add,cleaning_bucket,coffee,credit_card,date_range,directions_bus,drag_click,emoji_food_beverage,explosion,fastfood,featured_seasonal_and_gifts,fiber_new,file_map,file_map_stack,fireplace,food_bank,fork_spoon,glass_cup,home_pin,kid_star,local_bar,local_dining,local_fire_department,local_pizza,location_on,lunch_dining,mail,mark_email_unread,motorcycle,online_prediction,open_in_phone,phone_enabled,pin_drop,potted_plant,priority,quick_reorder,ramen_dining,restaurant,rice_bowl,sell,sentiment_excited,set_meal,settings_cell,shopping_bag,skillet_cooktop,smartphone,soup_kitchen,sports_football,star,star_rate,stockpot,trophy,volunteer_activism,wifi_calling_bar_1,wine_bar&display=block" 59 rel="stylesheet"> 60 61 <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/fontawesome.min.css" 62 rel="preload" as="style"> 63 <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/fontawesome.min.css" 64 rel="stylesheet"> 65 66 <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/brands.min.css" 67 rel="preload" as="style"> 68 <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/brands.min.css" 69 rel="stylesheet">
vendor: 75 bytes, lines 69-71
69 70 71 <script src="https://www.google.com/recaptcha/enterprise.js?render=
716LcsffgqAAAAANLXQa19TOl4LbE2V7eS6PfaYhiT
vendor: 21 bytes, lines 71-73
71" defer></script> 72 73
73<script> 74 if (!window.origin.includes('http://localhost')) { 75 window.heap=window.heap||[],heap.load=function(e,t){window.heap.appid=e,window.heap.config=t=t||{};var r=document.createElement("script");r.type="text/javascript",r.async=!0,r.src="https://cdn.heapanalytics.com/js/heap-"+e+".js";var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(r,a);for(var n=function(e){return function(){heap.push([e].concat(Array.prototype.slice.call(arguments,0)))}},p=["addEventProperties","addUserProperties","clearEventProperties","identify","resetIdentity","removeEventProperty","setEventProperties","track","unsetEventProperty"],o=0;o<p.length;o++)heap[p[o]]=n(p[o])}; 76 heap.load((window.origin.includes('chowly.dev') ? '3177339425' : '3745098455')); 77 } 78 </script>
78 79 80 <link href="https://fonts.googleapis.com/css2?family=Roboto Slab:wght@400;700&family=Roboto Slab:wght@400;700&display=swap" 81 rel="preload" as="style"> 82 <link href="https://fonts.googleapis.com/css2?family=Roboto Slab:wght@400;700&family=Roboto Slab:wght@400;700&display=swap" 83 rel="stylesheet"> 84 85 <style> 86 87 :root { 88 /* Light theme colors */ 89 --bg-primary: white; 90 --bg-secondary: #F2F2F2; 91 --bg-form: white; 92 --text-primary: #212121; 93 --text-secondary: #666; 94 --text-muted: #666666; 95 --border-primary: #6b953e; 96 --border-secondary: #D7D7D7; 97 --stroke-primary: #6b953e; 98 --stroke-secondary: currentColor; 99 --active-bg-opacity: 8%; 100 --active-text: #6b953e; 101 --hover-bg-opacity: 8%; 102 --hover-text: #6b953e; 103 --link-text: #666; 104 --link-hover: black; 105 --social-bg: #666; 106 --social-text: white; 107 --placeholder-text: #D7D7D7; 108 --focus-border: #777777; 109 --button-bg: transparent; 110 --button-text: #6b953e; 111 --button-border: #6b953e; 112 --button-hover-bg: transparent; 113 --button-hover-border: #6b953e; 114 --brand-primary: #6b953e; 115 --brand-secondary: #6b953e; 116 --brand-overlay: rgba(107,149,62,0.08); 117 --brand-overlay-heavy: rgba(107,149,62,0.80); 118 --dim-overlay: rgba(0,0,0,0.4); 119 } 120 121 body { 122 background: linear-gradient(180deg, rgba(107, 149, 62, 0.08) 0px, rgba(107, 149, 62, 0.00) 520px); 123 } 124 125 .grecaptcha-badge { visibility: hidden; } 126 </style> 127 128 <!-- ===== Saigon Sisters â elevated brand system (head_scripts) ===== --> 129<!-- 0) SEO head (additive â layout owns canonical/og-core/Restaurant JSON-LD) --> 130<meta name="twitter:card" content="summary_large_image"> 131<meta name="twitter:title" content="Vietnamese Restaurant in West Loop Chicago: Banh Mi & Pho"> 132<meta name="twitter:description" content="Family-run Vietnamese restaurant on W Lake St in Chicago's West Loop since 2009. Banh mi, pho, bao, spring rolls and catering for dine-in, takeout and delivery.">
133<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"Organization","name":"saigon-sisters","sameAs":["https://www.instagram.com/saigonsisters","https://www.facebook.com/225838153600","https://maps.google.com/?cid=16374601163417073777"]}]}</script>
133 134<link rel="preconnect" href="https://fonts.googleapis.com"> 135<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 136<link rel="preconnect" href="https://res.cloudinary.com"> 137<link href="https://fonts.googleapis.com/css2?family=Jost:wght@500;600;700&family=Montserrat:wght@400;500;600&display=swap" rel="stylesheet"> 138 139<style> 140/* ---------- 1. TOKEN REMAP (recolors the whole token-driven theme) ---------- */ 141:root{ 142 --display-font-stack:'Jost',Montserrat,system-ui,sans-serif; 143 --body-font-stack:'Montserrat',system-ui,-apple-system,sans-serif; 144 --bg-primary:#FFFFFF; 145 --bg-secondary:#F3F7EE; 146 --bg-form:#F3F7EE; 147 --text-primary:#311541; 148 --text-secondary:#5E4F63; 149 --text-muted:#5E4F63; 150 --brand-primary:#4D7A24; 151 --brand-overlay:rgba(77,122,36,0.07); 152 --brand-overlay-heavy:rgba(77,122,36,0.82); 153 --dim-overlay:rgba(28,12,36,0.42); 154 --review-star-color:#9e6b16; 155 --button-bg:#311541; --button-text:#FFFFFF; --button-border:#311541; 156 --button-hover-bg:#5A2D6E; --button-hover-border:#5A2D6E; 157 --button-hover-text:#FFFFFF; 158 --link-text:#311541; --link-hover:#311541; 159 --border-primary:#4D7A24; --border-secondary:rgba(49,21,65,0.14); 160 --stroke-primary:#4D7A24; 161 --active-text:#311541; --hover-text:#311541; 162 --social-bg:#4D7A24; --social-text:#FFFFFF; 163 --placeholder-text:#5e4f63; 164 --focus-border:#4D7A24; 165} 166/* overflow-x:clip, never `hidden` â `hidden` makes html/body a scroll container and kills the 167 sticky nav; `clip` stops the sideways scroll without one. Blanket guard so a full-bleed band or 168 a decorative element that overhangs the viewport can't give the page a real horizontal scroll. */ 169html,body{ background-color:var(--bg-primary)!important; color:var(--text-primary); overflow-x:clip; } 170 171/* ---------- 2. TYPOGRAPHY ---------- */ 172html body{ font-family:'Montserrat',system-ui,-apple-system,sans-serif; font-weight:400; } 173html body h1,html body h2,html body h3,html body h4,html body h5,html body h6{ 174 font-family:'Jost',Montserrat,system-ui,sans-serif!important; font-weight:600; letter-spacing:-0.01em; line-height:1.06; } 175html body h1{ font-weight:700; } 176/* eyebrows / small caps labels read warmer in the display face */ 177html body .uppercase,html body [class*="eyebrow"]{ letter-spacing:0.06em; } 178/* PROTECT glyph fonts â without these, icons render as literal text */ 179.material-symbols-outlined,.material-icons{ font-family:'Material Symbols Outlined','Material Icons'!important; } 180.fa,.fas,.far,.fal,.fab,[class^="fa-"],[class*=" fa-"]{ font-family:"Font Awesome 6 Free","Font Awesome 6 Brands"!important; } 181 182/* ---------- 3. PILL CTAs (rounded buttons) ---------- */ 183/* button-ness gate (#338): only pill-ify order links that already read as buttons 184 (carry a `bg-` theme class). Bare text-only order links like top_10_picks' 12px 185 "Add Item" (`text-[...]` only, no `bg-`) must NOT get the pill/lift/hover. */ 186html body a[class*="rounded"], html body button[class*="rounded"], 187html body a[href="/stores"][class*="bg-"], html body a[href*="/stores"]:not(section a){ 188 border-radius:999px!important; 189} 190/* primary CTAs: solid brand pills with a soft lift */ 191html body a[href="/stores"][class*="bg-"]{ 192 box-shadow:0 6px 0 0 rgba(49,21,65,0.16); transition:transform .15s ease, box-shadow .15s ease, background-color .15s ease; 193} 194html body a[href="/stores"][class*="bg-"]:hover{ transform:translateY(-2px); box-shadow:0 8px 0 0 rgba(49,21,65,0.22); } 195 196/* ---------- 4. BAND RHYTHM (base bg with alternating color blocks) ---------- */ 197/* image_left + image_right are FLEX rows â color only, never display:block */ 198#section-ONg7ndz-Mxo{ background-color:#EEF4E6!important; } 199#section-Ej3jxE4g{ background-color:#4D7A24!important; } 200#section-Ej3jxE4g, #section-Ej3jxE4g *{ color:#FFFFFF!important; } 201#section-986bFUi0{ background-color:#EEF4E6!important; } 202 203/* ---------- 4c. FULL-BLEED BANDS â color fills edge-to-edge + NO seams between sections ---------- */ 204@media(min-width:1280px){ #section-lJfwt4mDElw, #section-ONg7ndz-Mxo, #section-MnhqgiEX4wo, #section-Ej3jxE4g, #section-XGH-ZS4x, #section-986bFUi0, #section-wwehgrDj, #section-BaRHvt74, #section-y4bXQdGUH94, #section-FjzSonYwoGo, #section-sybu7lb2Ock, #section-u-ZwNrjt0WY, #section-V8ShQ5PR, #section-mBRLYquT, #section-_LdfZMObePA, #section-tkbbCTBJ, #section-NWjfUO3N, #section-owbCpW54, #section-f7TN9yUCwdw, #section-hhWazBR2, #section-s894dOsW, #section-CmRX1naS, #section-5j0fEFjq, #section-iT8CbAGH, #
204section-b5eea6TD, #section-ftFycDVW, #section-Rz9fntLF{ 205 width:100vw!important; max-width:100vw!important; 206 margin-left:calc(50% - 50vw)!important; margin-right:calc(50% - 50vw)!important; } } 207#section-lJfwt4mDElw, #section-ONg7ndz-Mxo, #section-MnhqgiEX4wo, #section-Ej3jxE4g, #section-XGH-ZS4x, #section-986bFUi0, #section-wwehgrDj, #section-BaRHvt74, #section-y4bXQdGUH94, #section-FjzSonYwoGo, #section-sybu7lb2Ock, #section-u-ZwNrjt0WY, #section-V8ShQ5PR, #section-mBRLYquT, #section-_LdfZMObePA, #section-tkbbCTBJ, #section-NWjfUO3N, #section-owbCpW54, #section-f7TN9yUCwdw, #section-hhWazBR2, #section-s894dOsW, #section-CmRX1naS, #section-5j0fEFjq, #section-iT8CbAGH, #section-b5eea6TD, #section-ftFycDVW, #section-Rz9fntLF{ 208 padding-left:max(24px, calc(50vw - 640px))!important; 209 padding-right:max(24px, calc(50vw - 640px))!important; } 210@media(max-width:1279px){ #section-lJfwt4mDElw, #section-ONg7ndz-Mxo, #section-MnhqgiEX4wo, #section-Ej3jxE4g, #section-XGH-ZS4x, #section-986bFUi0, #section-wwehgrDj, #section-BaRHvt74, #section-y4bXQdGUH94, #section-FjzSonYwoGo, #section-sybu7lb2Ock, #section-u-ZwNrjt0WY, #section-V8ShQ5PR, #section-mBRLYquT, #section-_LdfZMObePA, #section-tkbbCTBJ, #section-NWjfUO3N, #section-owbCpW54, #section-f7TN9yUCwdw, #section-hhWazBR2, #section-s894dOsW, #section-CmRX1naS, #section-5j0fEFjq, #section-iT8CbAGH, #section-b5eea6TD, #section-ftFycDVW, #section-Rz9fntLF{ grid-column:1 / -1!important; } } 211#section-FYU2eG76, #section-lJfwt4mDElw, #section-ONg7ndz-Mxo, #section-MnhqgiEX4wo, #section-Ej3jxE4g, #section-XGH-ZS4x, #section-986bFUi0, #section-wwehgrDj, #section-BaRHvt74, #section-y4bXQdGUH94, #section-FjzSonYwoGo, #section-sybu7lb2Ock, #section-u-ZwNrjt0WY, #section-V8ShQ5PR, #section-mBRLYquT, #section-_LdfZMObePA, #section-tkbbCTBJ, #section-NWjfUO3N, #section-owbCpW54, #section-f7TN9yUCwdw, #section-hhWazBR2, #section-s894dOsW, #section-CmRX1naS, #section-5j0fEFjq, #section-iT8CbAGH, #section-b5eea6TD, #section-ftFycDVW, #section-Rz9fntLF{ margin-top:0!important; margin-bottom:0!important; } 212#section-ONg7ndz-Mxo, #section-MnhqgiEX4wo, #section-Ej3jxE4g, #section-BaRHvt74, #section-y4bXQdGUH94, #section-FjzSonYwoGo, #section-sybu7lb2Ock, #section-u-ZwNrjt0WY, #section-V8ShQ5PR, #section-_LdfZMObePA, #section-tkbbCTBJ, #section-NWjfUO3N, #section-owbCpW54, #section-hhWazBR2, #section-s894dOsW, #section-CmRX1naS, #section-iT8CbAGH, #section-b5eea6TD, #section-ftFycDVW, #section-Rz9fntLF{ padding-top:clamp(32px,4vw,64px)!important; padding-bottom:clamp(32px,4vw,64px)!important; } 213@media(min-width:1280px){ #section-ONg7ndz-Mxo figure, #section-MnhqgiEX4wo figure, #section-Ej3jxE4g figure, #section-BaRHvt74 figure, #section-y4bXQdGUH94 figure, #section-FjzSonYwoGo figure, #section-sybu7lb2Ock figure, #section-u-ZwNrjt0WY figure, #section-V8ShQ5PR figure, #section-_LdfZMObePA figure, #section-tkbbCTBJ figure, #section-NWjfUO3N figure, #section-owbCpW54 figure, #section-hhWazBR2 figure, #section-s894dOsW figure, #section-CmRX1naS figure, #section-iT8CbAGH figure, #section-b5eea6TD figure, #section-ftFycDVW figure, #section-Rz9fntLF figure{ max-width:520px!important; } } 214@media(min-width:1280px){ #section-cwIG3a0886d6{ 215 padding-left:max(24px, calc(50vw - 640px))!important; 216 padding-right:max(24px, calc(50vw - 640px))!important; } } 217 218/* ---------- 4a. SITE-SCOPED FIXES (nav logo + notification are singletons the page-save drops) ---------- */ 219@media(max-width:767px){ #section-dDb0AMpP a[href="/"][aria-label]{ max-height:58px!important; } #section-dDb0AMpP a[href="/"][aria-label] img{ max-height:58px!important; width:auto!important; } } 220#section-FYU2eG76{ background-color:var(--brand-primary)!important; } 221#section-FYU2eG76, #section-FYU2eG76 *{ color:#FFFFFF!important; } 222/* platform FAQ keyword links inherit the theme accent â sub-AA on light brands (#398) */ 223#section-wwehgrDj a, #section-wwehgrDj a *{ color:#311541!important; text-decoration-color:#311541!important; } 224/* native IG-carousel CTA light-brand guard (#271) â id-independent, always-on */ 225#section-cwIG3a0886d6 a[data-maglev-id$=".cta_button_text"], #section-cwIG3a0886d6 a[data-maglev-id$=".cta_button_text"] span, section[class*="instagram_carousel"] a[data-maglev-id$=".cta_button_text"], section[class*="instagram_carousel"] a[data-maglev-id$=".cta_button_text"] span{ color:#FFFFFF!important; } 226/* hardcoded text-white pill idiom on brand fills â contrast-gated AA repaint (resting + hover) */ 227html:root body :is(a,button)[class*="text-[var(--button-text)]"], 228html:root body :is(a,button)[class*="text-[var(--button-text)]"] *, 229html:root body :is(#section-ONg7ndz-Mxo,#section-Ej3jxE4g,#section-986bFUi0,#section-lJfwt4mDElw,#section-MnhqgiEX4wo,#section-XGH-ZS4x,#section-wwehgrDj,#section-BaRHvt74,#section-y4bXQdGUH94,#section-FjzSonYwoGo,#section-sybu7lb2Ock,#section-u-ZwNrjt0WY,#section-V8ShQ5PR,#section-mBRLYquT,#section-_LdfZMObePA,#section-tkbbCTBJ,#section-NWjfUO3N,#section-owbCpW54,#section-f7TN9yUCwdw,#section-hhWazBR2,#section-s894dOsW,#section-CmRX1naS,#section-5j0fEFjq,#section-iT8CbAGH,#section-b5eea6TD,#section-ftFycDVW,#section-Rz9fntLF,#section-FYU2eG76,#section-cwIG3a0886d6,#section-dDb0AMpP,#section-M4aDtxB6egU,#section-DlCqLZcy,#section-KB7tNzVofEA,#section-cwSigffb51dfe) :is(a,button)[class*="text-[var(--button-text)]"], 230html:root body :is(#section-ONg7ndz-Mxo,#section-Ej3jxE4g,#section-986bFUi0,#section-lJfwt4mDElw,#section-MnhqgiEX4wo,#section-XGH-ZS4x,#section-wwehgrDj,#section-BaRHvt74,#section-y4bXQdGUH94,#section-FjzSonYwoGo,#section-sybu7lb2Ock,#section-u-ZwNrjt0WY,#section-V8ShQ5PR,#section-mBRLYquT,#section-_LdfZMObePA,#section-tkbbCTBJ,#section-NWjfUO3N,#section-owbCpW54,#section-f7TN9yUCwdw,#section-hhWazBR2,#section-s894dOsW,#section-CmRX1naS,#section-5j0fEFjq,#section-iT8CbAGH,#section-b5eea6TD,#section-ftFycDVW,#section-Rz9fntLF,#section-FYU2eG76,#section-cwIG3a0886d6,#section-dDb0AMpP,#section-M4aDtxB6egU,#section-DlCqLZcy,#section-KB7tNzVofEA,#section-cwSigffb51dfe) :is(a,button)[class*="text-[var(--button-text)]"] *{ color:var(--button-text)!important; } 231/* form controls: the theme paints Submit with an INLINE background that ignores --button-bg (#722) */ 232input[type="submit"], button[type="submit"]{ background-color:#311541!important; color:#FFFFFF!important; border-color:#311541!important; } 233 234/* ---------- 4b. HERO refinement (hierarchy, legibility, secondary CTA) ---------- */ 235#section-M4aDtxB6egU{ position:relative; } 236#section-M4aDtxB6egU::before{ content:""; position:absolute; inset:0; z-index:0; pointer-events:none; background:linear-gradient(90deg, rgba(28,12,36,0.6) 0%, rgba(28,12,36,0.6) 55%, rgba(28,12,36,0.6) 72%, rgba(28,12,36,0.0) 90%); } 237#section-M4aDtxB6egU > *{ position:relative; z-index:1; } 238#section-M4aDtxB6egU div[class*="bg-black"]{ background:linear-gradient(90deg, rgba(28,12,36,0.6) 0%, rgba(28,12,36,0.6) 55%, rgba(28,12,36,0.6) 72%, rgba(28,12,36,0.0) 90%)!important; } 239@media(max-width:767px){ 240 #section-M4aDtxB6egU::before{ background:linear-gradient(180deg, rgba(28,12,36,0.6) 0%, rgba(28,12,36,0.6) 88%, rgba(28,12,36,0.432) 100%); } 241 #section-M4aDtxB6egU div[class*="bg-black"]{ background:linear-gradient(180deg, rgba(28,12,36,0.6) 0%, rgba(28,12,36,0.6) 88%, rgba(28,12,36,0.432) 100%)!important; } } 242#section-M4aDtxB6egU h1, #section-M4aDtxB6egU p{ text-shadow:0 2px 16px rgba(0,0,0,.58), 0 1px 4px rgba(0,0,0,.55); } 243#section-M4aDtxB6egU a[href="/menu"]:where([class*="bg-"]){ background:#FFFFFF!important; color:#4D7A24!important; border:0!important; border-radius:999px!important; box-shadow:0 6px 0 0 rgba(0,0,0,.16); } 244#section-M4aDtxB6egU a[href="/menu"]:where([class*="bg-"]):hover{ transform:translateY(-2px); } 245#section-M4aDtxB6egU a[data-maglev-id$=".button"], #section-M4aDtxB6egU a[data-maglev-id$=".button"] span{ color:#FFFFFF!important; } 246#section-M4aDtxB6egU a[data-maglev-id$=".button"]{ box-shadow:0 0 0 1.5px rgba(255,255,255,.90), 0 6px 0 0 rgba(0,0,0,.16); } 247#section-M4aDtxB6egU a[data-maglev-id$=".button_2"]{ background:rgba(14,12,10,.82)!important; color:#FFFFFF!important; border:0!important; box-shadow:0 0 0 1.5px rgba(255,255,255,.90), 0 6px 0 0 rgba(0,0,0,.16); } 248#section-M4aDtxB6egU a[data-maglev-id$=".button_2"] span{ color:#FFFFFF!important; } 249html:root body #section-M4aDtxB6egU a[data-maglev-id$=".button_2"][class]{ color:#FFFFFF!important; } 250html:root body #section-M4aDtxB6egU a[data-maglev-id$=".button_2"] :is(span,*){ color:#FFFFFF!important; } 251#section-M4aDtxB6egU a[data-maglev-id$=".button_2"]:hover{ transform:translateY(-2px); } 252#section-DlCqLZcy{ position:relative; } 253#section-DlCqLZcy::before{ content:""; position:absolute; inset:0; z-index:0; pointer-events:none; background:linear-gradient(90deg, rgba(28,12,36,0.6) 0%, rgba(28,12,36,0.6) 55%, rgba(28,12,36,0.6) 72%, rgba(28,12,36,0.0) 90%); } 254#section-DlCqLZcy > *{ position:relative; z-index:1; } 255#section-DlCqLZcy div[class*="bg-black"]{ background:linear-gradient(90deg, rgba(28,12,36,0.6) 0%, rgba(28,12,36,0.6) 55%, rgba(28,12,36,0.6) 72%, rgba(28,12,36,0.0) 90%)!important; } 256@media(max-width:767px){ 257 #section-DlCqLZcy::before{ background:linear-gradient(180deg, rgba(28,12,36,0.6) 0%, rgba(28,12,36,0.6) 88%, rgba(28,12,36,0.432) 100%); } 258 #section-DlCqLZcy div[class*="bg-black"]{ background:linear-gradient(180deg, rgba(28,12,36,0.6) 0%, rgba(28,12,36,0.6) 88%, rgba(28,12,36,0.432) 100%)!important; } } 259#section-DlCqLZcy h1, #section-DlCqLZcy p{ text-shadow:0 2px 16px rgba(0,0,0,.58), 0 1px 4px rgba(0,0,0,.55); } 260#section-DlCqLZcy a[href="/menu"]:where([class*="bg-"]){ background:#FFFFFF!important; color:#4D7A24!important; border:0!important; border-radius:999px!important; box-shadow:0 6px 0 0 rgba(0,0,0,.16); } 261#section-DlCqLZcy a[href="/menu"]:where([class*="bg-"]):hover{ transform:translateY(-2px); } 262#section-DlCqLZcy a[data-maglev-id$=".button"], #section-DlCqLZcy a[data-maglev-id$=".button"] span{ color:#FFFFFF!important; } 263#section-DlCqLZcy a[data-maglev-id$=".button"]{ box-shadow:0 0 0 1.5px rgba(255,255,255,.90), 0 6px 0 0 rgba(0,0,0,.16); } 264#section-DlCqLZcy a[data-maglev-id$=".button_2"]{ background:rgba(14,12,10,.82)!important; color:#FFFFFF!important; border:0!important; box-shadow:0 0 0 1.5px rgba(255,255,255,.90), 0 6px 0 0 rgba(0,0,0,.16); } 265#section-DlCqLZcy a[data-maglev-id$=".button_2"] span{ color:#FFFFFF!important; } 266html:root body #section-DlCqLZcy a[data-maglev-id$=".button_2"][class]{ color:#FFFFFF!important; } 267html:root body #section-DlCqLZcy a[data-maglev-id$=".button_2"] :is(span,*){ color:#FFFFFF!important; } 268#section-DlCqLZcy a[data-maglev-id$=".button_2"]:hover{ transform:translateY(-2px); } 269#section-KB7tNzVofEA{ position:relative; } 270#section-KB7tNzVofEA::before{ content:""; position:absolute; inset:0; z-index:0; pointer-events:none; background:linear-gradient(90deg, rgba(28,12,36,0.6) 0%, rgba(28,12,36,0.6) 55%, rgba(28,12,36,0.6) 72%, rgba(28,12,36,0.0) 90%); } 271#section-KB7tNzVofEA > *{ position:relative; z-index:1; } 272#section-KB7tNzVofEA div[class*="bg-black"]{ background:linear-gradient(90deg, rgba(28,12,36,0.6) 0%, rgba(28,12,36,0.6) 55%, rgba(28,12,36,0.6) 72%, rgba(28,12,36,0.0) 90%)!important; } 273@media(max-width:767px){ 274 #section-KB7tNzVofEA::before{ background:linear-gradient(180deg, rgba(28,12,36,0.6) 0%, rgba(28,12,36,0.6) 88%, rgba(28,12,36,0.432) 100%); } 275 #section-KB7tNzVofEA div[class*="bg-black"]{ background:linear-gradient(180deg, rgba(28,12,36,0.6) 0%, rgba(28,12,36,0.6) 88%, rgba(28,12,36,0.432) 100%)!important; } } 276#section-KB7tNzVofEA h1, #section-KB7tNzVofEA p{ text-shadow:0 2px 16px rgba(0,0,0,.58), 0 1px 4px rgba(0,0,0,.55); } 277#section-KB7tNzVofEA a[href="/menu"]:where([class*="bg-"]){ background:#FFFFFF!important; color:#4D7A24!important; border:0!important; border-radius:999px!important; box-shadow:0 6px 0 0 rgba(0,0,0,.16); } 278#section-KB7tNzVofEA a[href="/menu"]:where([class*="bg-"]):hover{ transform:translateY(-2px); } 279#section-KB7tNzVofEA a[data-maglev-id$=".button"], #section-KB7tNzVofEA a[data-maglev-id$=".button"] span{ color:#FFFFFF!important; } 280#section-KB7tNzVofEA a[data-maglev-id$=".button"]{ box-shadow:0 0 0 1.5px rgba(255,255,255,.90), 0 6px 0 0 rgba(0,0,0,.16); } 281#section-KB7tNzVofEA a[data-maglev-id$=".button_2"]{ background:rgba(14,12,10,.82)!important; color:#FFFFFF!important; border:0!important; box-shadow:0 0 0 1.5px rgba(255,255,255,.90), 0 6px 0 0 rgba(0,0,0,.16); } 282#section-KB7tNzVofEA a[data-maglev-id$=".button_2"] span{ color:#FFFFFF!important; } 283html:root body #section-KB7tNzVofEA a[data-maglev-id$=".button_2"][class]{ color:#FFFFFF!important; } 284html:root body #section-KB7tNzVofEA a[data-maglev-id$=".button_2"] :is(span,*){ color:#FFFFFF!important; } 285#section-KB7tNzVofEA a[data-maglev-id$=".button_2"]:hover{ transform:translateY(-2px); } 286 287/* ---------- 4d. CTA HOVER LABEL (#620) ---------- */ 288/* the theme ships `hover:bg-` with no `hover:text-` pair â without this the label keeps its resting 289 colour while the fill swaps under it. NOT last: §6 (components + the brand's extra_css) is 290 substituted after this, so the guard cannot rely on source order and carries the specificity to 291 win outright instead (see `_cta_hover_css`). That is deliberate â an author who wants a different 292 hover label writes an equally-specific rule in `extra_css` and still wins on order. */ 293html:root body :is(a,button)[class*="hover:bg-[var(--button-hover-bg)]"]:hover, 294html:root body :is(a,button)[class*="hover:bg-[var(--button-hover-bg)]"]:hover *, 295html:root body :is(#section-ONg7ndz-Mxo,#section-Ej3jxE4g,#section-986bFUi0,#section-lJfwt4mDElw,#section-MnhqgiEX4wo,#section-XGH-ZS4x,#section-wwehgrDj,#section-BaRHvt74,#section-y4bXQdGUH94,#section-FjzSonYwoGo,#section-sybu7lb2Ock,#section-u-ZwNrjt0WY,#section-V8ShQ5PR,#section-mBRLYquT,#section-_LdfZMObePA,#section-tkbbCTBJ,#section-NWjfUO3N,#section-owbCpW54,#section-f7TN9yUCwdw,#section-hhWazBR2,#section-s894dOsW,#section-CmRX1naS,#section-5j0fEFjq,#section-iT8CbAGH,#section-b5eea6TD,#section-ftFycDVW,#section-Rz9fntLF,#section-FYU2eG76,#section-cwIG3a0886d6,#section-dDb0AMpP,#section-M4aDtxB6egU,#section-DlCqLZcy,#section-KB7tNzVofEA,#section-cwSigffb51dfe) :is(a,button)[class*="hover:bg-[var(--button-hover-bg)]"]:hover, 296html:root body :is(#section-ONg7ndz-Mxo,#section-Ej3jxE4g,#section-986bFUi0,#section-lJfwt4mDElw,#section-MnhqgiEX4wo,#section-XGH-ZS4x,#section-wwehgrDj,#section-BaRHvt74,#section-y4bXQdGUH94,#section-FjzSonYwoGo,#section-sybu7lb2Ock,#section-u-ZwNrjt0WY,#section-V8ShQ5PR,#section-mBRLYquT,#section-_LdfZMObePA,#section-tkbbCTBJ,#section-NWjfUO3N,#section-owbCpW54,#section-f7TN9yUCwdw,#section-hhWazBR2,#section-s894dOsW,#section-CmRX1naS,#section-5j0fEFjq,#section-iT8CbAGH,#section-b5eea6TD,#section-ftFycDVW,#section-Rz9fntLF,#section-FYU2eG76,#section-cwIG3a0886d6,#section-dDb0AMpP,#section-M4aDtxB6egU,#section-DlCqLZcy,#section-KB7tNzVofEA,#section-cwSigffb51dfe) :is(a,button)[class*="hover:bg-[var(--button-hover-bg)]"]:hover *{ color:var(--button-hover-text)!important; } 297 298/* ---------- 5. SCROLL-REVEAL (gated for reduced-motion; JS adds .cw-reveal) ---------- */ 299@media (prefers-reduced-motion:no-preference){ 300 /* transition lives on the .cw-in (revealed) state, NOT the base: setting the hidden state must be 301 INSTANT. If the base carried the transition, tagging a section .cw-reveal would fade it 1â0, and
302 a near-fold section (revealed a couple frames later) reverses to 1 before ever reaching 0 â so it 303 never visibly animates. Instant-hide + transition-on-reveal makes the first content section rise 304 in like the rest. */ 305 .cw-reveal{ opacity:0; transform:translateY(26px); } 306 .cw-reveal.cw-in{ opacity:1; transform:none; transition:opacity .7s ease, transform .7s cubic-bezier(.2,.7,.2,1); } 307} 308 309/* ---------- 6. SIGNATURE COMPONENTS (full-bleed bands, mascots â per chosen surprise) ---------- */ 310/* signature marquee band â cwSigffb51dfe */ 311/* full-bleed: the theme caps custom_html at 760/1440 inside a flex parent â force 100vw here. 312 display:block is SAFE on a custom_html section (it is NOT a native flex row). */ 313#section-cwSigffb51dfe{ width:100vw!important; max-width:100vw!important; margin-left:calc(50% - 50vw)!important; margin-right:calc(50% - 50vw)!important; display:block!important; } 314/* overflow:VISIBLE, deliberately (#752). The band used to carry `overflow:hidden`, which was 315 redundant â the scrolling ticker is clipped by `.cw-sig__marquee` below, the element that 316 actually holds the overflowing track â but it silently ate any ambient hosted on this element. 317 `house_edge` draws its seam as an `::after` at `top:calc(100% - 1px)`, i.e. wholly BELOW the 318 host box, so the clip erased it: measured 0.0px of bottom-edge variation across 40 x-samples at 319 both 1440 and 390, with every `getComputedStyle(el,'::after')` property still reading correct 320 (content/background/height/mask/opacity/z-index). That combination â correct computed style, 321 zero pixels â is what makes this class of bug expensive, so keep the clip on the row that needs 322 it and leave the band itself unclipped. */ 323.cw-sig{ background:#311541; color:#ffffff; overflow:visible; position:relative; width:100vw; margin-left:calc(50% - 50vw); margin-right:calc(50% - 50vw); } 324/* THE clip for the ticker: the track is `display:inline-block` and animates translateX(-50%), so 325 it runs past both edges of this row and must be cut here (never on the band â see above). */ 326.cw-sig__marquee{ border-top:2px solid rgba(255,255,255,0.25); border-bottom:2px solid rgba(255,255,255,0.25); padding:11px 0; overflow:hidden; white-space:nowrap; } 327/* #894 â the belt holds exactly TWO identical tracks, so translating IT by -50% advances 328 exactly one track and the loop is seamless. The animation used to sit on .cw-sig__track, 329 where -50% resolved against ONE track's width (half a period) and the ticker lurched 330 sideways once per cycle. Each track repeats the word list 4x so the belt covers wide 331 viewports â two tracks of one repetition left up to 56% of the band empty at 1920. */ 332.cw-sig__belt{ display:inline-block; will-change:transform; } 333.cw-sig__track{ display:inline-block; font-family:'Jost',Montserrat,system-ui,sans-serif; font-weight:600; font-size:clamp(18px,2.4vw,30px); letter-spacing:.05em; color:#FFFFFF; text-transform:uppercase; } 334.cw-sig__inner{ max-width:1200px; margin:0 auto; padding:clamp(40px,6vw,84px) 24px; display:flex; align-items:center; gap:clamp(24px,5vw,72px); } 335/* the mascot sits on a soft radial GLOW by default (bird_bg), never a hard opaque circle â a 336 solid disc reads as a broken white blob behind a transparent-PNG mascot (#454). No drop shadow 337 for the same reason. Override bird_bg with a solid hex for a deliberate solid-medallion look. 338 bird_ring_css is EMPTY unless the brand DECLARES a `mascot_disc` (artwork that bakes in its own 339 colored disc, e.g. a logo emblem) AND that disc would dissolve into this band (#405) â then it 340 adds a thin ring + soft shadow so the emblem reads as a medallion. A normal transparent-PNG 341 mascot declares no disc and is never rimmed, which is what keeps #454 fixed. */ 342.cw-sig__bird{ width:clamp(150px,20vw,260px); height:auto; border-radius:50%; flex:0 0 auto; background:radial-gradient(circle at 50% 45%,rgba(255,255,255,.16),rgba(255,255,255,0) 68%); } 343.cw-sig__copy{ flex:1 1 auto; } 344.cw-sig__eyebrow{ font-family:'Jost',Montserrat,system-ui,sans-serif; font-weight:600; text-transform:uppercase; letter-spacing:.14em; font-size:14px; color:#FFFFFF; margin:0 0 10px; } 345.cw-sig__head{ font-family:'Jost',Montserrat,system-ui,sans-serif!important; font-weight:700; color:#ffffff!important; font-size:clamp(38px,5.4vw,72px); line-height:.98; margin:0 0 16px; } 346.cw-sig__sub{ font-size:clamp(16px,1.5vw,20px); line-height:1.5; max-width:36ch; color:#FFFFFF; margin:0 0 24px; } 347.cw-sig__cta{ display:inline-block; text-decoration:none; background:#ffffff; color:#311541!important; font-family:'Jost',Montserrat,system-ui,sans-serif; font-weight:600; font-size:17px; padding:14px 30px; border-radius:999px; box-shadow:0 6px 0 0 rgba(0,0,0,.18); transition:transform .15s ease, box-shadow .15s ease; } 348.cw-sig__cta:hover{ transform:translateY(-2px); box-shadow:0 9px 0 0 rgba(0,0,0,.22); } 349@media (max-width:760px){ .cw-sig__inner{ flex-direction:column; text-align:center; } .cw-sig__sub{ margin-left:auto; margin-right:auto; } } 350/* motion â marquee scroll + a gentle stamp bob â gated for reduced-motion, NEVER outside the gate */ 351@media (prefers-reduced-motion:no-preference){ 352 @keyframes cw-sig-scroll{ from{transform:translateX(0)} to{transform:translateX(-50%)} } 353 @keyframes cw-sig-bob{ 0%,100%{transform:translateY(0) rotate(-1deg)} 50%{transform:translateY(-7px) rotate(1deg)} } 354 .cw-sig__belt{ animation:cw-sig-scroll 104s linear infinite; } 355 .cw-sig__bird{ animation:cw-sig-bob 5.6s cubic-bezier(.45,0,.55,1) infinite; transform-origin:50% 62%; } 356} 357 358#section-cwSigffb51dfe{ margin-top:0!important; margin-bottom:0!important; padding-top:0!important; padding-bottom:0!important; } 359 360/* botanical veil â faint herb-sprig linework over #section-Ej3jxE4g */ 361#section-Ej3jxE4g{ position:relative; } 362#section-Ej3jxE4g::after{ 363 content:""; position:absolute; inset:0; z-index:0; pointer-events:none; 364 opacity:0.08; background:#DCEBC8; 365 -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 220 220'%3E%3Cg fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M52 196 C58 146 70 96 96 50'/%3E%3Cpath d='M62 156 l-22 8 M70 126 l-20 4 M80 98 l-18 0 M88 72 l-16 -4 M62 156 l18 14 M70 126 l16 12 M80 98 l14 10 M88 72 l12 8'/%3E%3Cpath d='M170 30 C164 78 150 120 126 160' transform='rotate(6 148 95)'/%3E%3Cpath d='M160 70 l20 -8 M152 100 l18 -4 M142 128 l16 0 M134 152 l14 4 M160 70 l-16 -12 M152 100 l-16 -10 M142 128 l-14 -8'/%3E%3C/g%3E%3C/svg%3E") 0 0 / 240px 240px repeat; 366 mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 220 220'%3E%3Cg fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M52 196 C58 146 70 96 96 50'/%3E%3Cpath d='M62 156 l-22 8 M70 126 l-20 4 M80 98 l-18 0 M88 72 l-16 -4 M62 156 l18 14 M70 126 l16 12 M80 98 l14 10 M88 72 l12 8'/%3E%3Cpath d='M170 30 C164 78 150 120 126 160' transform='rotate(6 148 95)'/%3E%3Cpath d='M160 70 l20 -8 M152 100 l18 -4 M142 128 l16 0 M134 152 l14 4 M160 70 l-16 -12 M152 100 l-16 -10 M142 128 l-14 -8'/%3E%3C/g%3E%3C/svg%3E") 0 0 / 240px 240px repeat; 367} 368#section-Ej3jxE4g > *{ position:relative; z-index:1; } 369 370 371/* animated corner mascot (peek) */ 372/* a mascot that peeks in from the corner on scroll, with an order nudge. 373 NOTE: uses its OWN .cw-peek--in shown-state class so the scroll-reveal's .cw-in never toggles it. */ 374.cw-peek{ position:fixed; left:20px; bottom:20px; width:74px; height:74px; border-radius:50%; z-index:55; 375 background-image:url('https://res.cloudinary.com/targetable/image/upload/f_auto,q_auto,c_fill,ar_1:1,g_
375center,r_max,w_520/Customers/saigon-sisters/site/mascot-0b064062'); background-size:cover; background-position:center; border:2px solid #4D7A24; 376 box-shadow:0 6px 18px rgba(36,31,27,.22); filter:drop-shadow(0 1px 2px rgba(36,31,27,.12)); 377 transform:translateY(150%) rotate(8deg); transition:transform .5s cubic-bezier(.22,1,.36,1); cursor:pointer; } 378.cw-peek.cw-peek--in{ transform:translateY(0) rotate(0); } 379.cw-peek__tip{ position:absolute; left:88px; bottom:20px; white-space:nowrap; background:#4D7A24; color:#FFFFFF; 380 font-family:'Jost',Montserrat,system-ui,sans-serif; font-weight:600; font-size:13px; padding:6px 12px; border-radius:999px; 381 box-shadow:0 4px 12px rgba(0,0,0,.18); opacity:0; transform:translateX(-6px); transition:opacity .25s, transform .25s; pointer-events:none; } 382.cw-peek:hover .cw-peek__tip{ opacity:1; transform:translateX(0); } 383@media (prefers-reduced-motion:no-preference){ 384 @keyframes cw-peek-idle{ 0%,100%{transform:translateY(0)} 50%{transform:translateY(-3px)} } /* imperceptible idle */ 385 @keyframes cw-peek-hop{ 0%,100%{transform:translateY(0) rotate(0)} 45%{transform:translateY(-13px) rotate(-6deg)} } 386 .cw-peek.cw-peek--in{ animation:cw-peek-idle 4.3s cubic-bezier(.45,0,.55,1) .8s infinite; } /* desynced period */ 387 .cw-peek.cw-peek--in:hover{ animation:cw-peek-hop .5s ease; } /* flutter/hop reserved for hover only */ 388} 389@media (prefers-reduced-motion:reduce){ .cw-peek{ transition:none; transform:translateY(0) rotate(0); } } 390/* #455 â #539: the fixed 74px corner FAB is pinned at left:20px (`_CORNER["bottom-left"]` in 391 compose.py â a FIXED inset for every brand), so its right edge sits at ~x=98px on EVERY 392 viewport. A prior fix (#455/PR#448) shrunk it to 52px/10px below 600px, which only clears 393 phones â single-column content on tablet/small-laptop widths (roughly 601â1360px, confirmed 394 by an @design collision sweep on Alinea) still starts well inside that 98px band, so the 395 badge kept overlapping body copy AND stealing taps from real CTAs (e.g. a footer link) up to 396 ~1360px. There is no shrink threshold that clears both a 390px phone and a 1024px tablet at a 397 fixed left:20px inset, so below the desktop gutter the badge is not a corner FAB at all: it 398 becomes a full-width sticky bottom bar (Liv's Juice Bar's #chowly-floating-footer is the 399 reference). A bar can't collide with a single-column body â it OWNS the bottom edge, and 400 `body{padding-bottom}` below reserves that strip so no content (footer included) ever hides 401 under it. #539 replaced the previous "hide it entirely below 1399px" trade-off, which made 402 this SPINE order-nudge invisible to most mobile/tablet traffic. Same 1399px cutoff as that 403 fix (NOT Liv's own 768px, which leaves the 601â1360px band with no persistent CTA at all). 404 The bar is always-on, not scroll-gated: it's a utility, not a reveal. */ 405@media (max-width:1399px){ 406 /* ONE source of truth for the bar's height â the body reservation below reads the same var. */ 407 :root{ --cw-peek-bar-h:60px; 408 /* Both bottom corners are reserved on an elevated site (#421). Measured at 768px on live 409 sites: the Maglev a11y button (UserWay) is 44x44 docked 21px from the right edge â the 410 SAME geometry on two unrelated elevated customers, so it is platform-level, not per-brand; 411 a SpotHopper-style chat bubble on another site is 56x56 at 7px. Worst case the corner is 412 occupied out to 65px, so the bar pads BOTH ends by 76px and centres its content between 413 them â the label and mascot chip can never sit under a corner widget. Verified by injecting 414 this bar into those live pages: the widget still hit-tests on top of the bar 415 (elementFromPoint at its centre), so it is neither hidden nor tap-blocked â it just docks 416 on the bar's right end. */ 417 --cw-peek-a11y-reserve:76px; } 418 .cw-peek{ box-sizing:border-box; overflow:hidden; left:0; right:0; bottom:0; width:auto; 419 height:calc(var(--cw-peek-bar-h) + env(safe-area-inset-bottom,0px)); 420 padding:0 var(--cw-peek-a11y-reserve) env(safe-area-inset-bottom,0px); 421 display:flex; align-items:center; justify-content:center; gap:10px; 422 border:0; border-radius:0; background-image:none; background-color:#4D7A24; 423 box-shadow:0 -4px 14px rgba(36,31,27,.18); filter:none; text-decoration:none; 424 /* always-on: neutralise the scroll-in gate (.cw-peek--in) and the idle bob without touching 425 body.js.tmpl â !important because both live on higher-specificity selectors above. */ 426 transform:none !important; animation:none !important; } 427 .cw-peek::before{ content:''; flex:0 0 auto; width:34px; height:34px; border-radius:50%; 428 background-image:url('https://res.cloudinary.com/targetable/image/upload/f_auto,q_auto,c_fill,ar_1:1,g_
428center,r_max,w_520/Customers/saigon-sisters/site/mascot-0b064062'); background-size:cover; background-position:center; 429 border:2px solid #FFFFFF; } /* the mascot survives as the bar's leading chip */ 430 .cw-peek__tip{ position:static; background:none; box-shadow:none; padding:0; border-radius:0; 431 font-size:16px; opacity:1; transform:none; transition:none; max-width:100%; 432 overflow:hidden; text-overflow:ellipsis; } /* the tooltip becomes the bar's label */ 433 /* Reserve the strip the bar covers. Verified 0px on live elevated sites, so nothing to preserve; 434 !important because `body` is theme-owned and our <style> can be outranked by source order. */ 435 body{ padding-bottom:calc(var(--cw-peek-bar-h) + env(safe-area-inset-bottom,0px)) !important; } 436} 437 438</style> 439 440 441
441<script src="https://cdn.userway.org/widget.js" data-account="2RTD1qUW2F" data-position="3"></script>
441 442 443 <link rel="stylesheet" href="/assets/vidbg-59cd2b661e27143a4d41f154396b1fabc6ac9c0893f4d4b1623cbf033efc0130.css" /> 444 445
445<script src="/assets/libraries/vidbg-ca103f7572673d0e7e3cc8a6a59b200f7ab3da61da78a43e532949d800635fa5.js"></script>
445 446
446<script src="/assets/banner-component-730ab5752d6195daf2963c20c32c885c4d07215b1fbd2a76a52cd94622d82ef7.js"></script>
446 447 448
448<script async> 449 window.chowlyApiHost = 'https://api.chowlyinc.com'; 450 window.siteHost = 'https://sites.chowly.app'; 451 </script>
451 452 453
453<script type="application/ld+json"> 454 {"@type":"Restaurant","name":"Saigon Sisters","address":{"@type":"PostalAddress","streetAddress":"567 W Lake St","addressLocality":"Chicago","addressRegion":"IL","postalCode":"60661","addressCountry":"US"},"telephone":"8339986885","geo":{"@type":"GeoCoordinates","latitude":41.88553719999999,"longitude":-87.6425287},"url":"https://www.saigonsisters.com#location-49193","servesCuisine":["Asian","Bao","Southeast Asian","Vietnamese","Vietnamese Street Food","Vietnamese Restaurant","Banh Mi"],"priceRange":"$$","openingHoursSpecification":[{"@type":"OpeningHoursSpecification","dayOfWeek":"https://schema.org/Tuesday","opens":"11:00:00","closes":"21:00:00"},{"@type":"OpeningHoursSpecification","dayOfWeek":"https://schema.org/Wednesday","opens":"11:00:00","closes":"21:00:00"},{"@type":"OpeningHoursSpecification","dayOfWeek":"https://schema.org/Thursday","opens":"11:00:00","closes":"21:00:00"},{"@type":"OpeningHoursSpecification","dayOfWeek":"https://schema.org/Friday","opens":"11:00:00","closes":"22:00:00"},{"@type":"OpeningHoursSpecification","dayOfWeek":"https://schema.org/Saturday","opens":"12:00:00","closes":"22:00:00"}],"hasMenu":"https://www.saigonsisters.com/menu","areaServed":["Chicago","Fulton Market","Near West Side","West Loop","West Side","Chicago Loop","West Loop Gate","River West"],"@context":"https://schema.org"} 455 </script>
455 456</head> 457<body data-organization-id="50070" > 458 <a href="#main-content" class="sr-only focus:not-sr-only">Skip to main content</a> 459 <main id="main-content" role="main" data-maglev-dropzone> 460 <section class="grid grid-cols-2 gap-0 justify-center"> 461 <div class="bg-[var(--brand-primary)] w-full h-[40px] flex justify-center items-center px-4 col-span-2" role="banner" id="section-FYU2eG76" data-maglev-section-id="FYU2eG76" data-maglev-section-type="site_notification_01"> 462 <section class="flex items-center space-x-2 max-w-[1440px] w-full justify-center"> 463 <div class="w-[30px] h-[30px] overflow-hidden"> 464 <i class="text-white mds-food_bank" data-maglev-id="FYU2eG76.icon" aria-hidden="true"></i> 465 </div> 466 <span data-maglev-id="FYU2eG76.title" class="text-white text-[14px] font-normal leading-[24px] text-center line-clamp-2 overflow-hidden"><p><strong>Fresh Vietnamese Banh Mi and Bao Buns Crafted for the Heart of Chicago</strong></p></span> 467 </section> 468</div><header class="sticky top-0 z-50 bg-[var(--bg-primary)] py-[16px] xl:py-[12px] shadow-md w-full col-span-2" id="section-dDb0AMpP" data-maglev-section-id="dDb0AMpP" data-maglev-section-type="standard_nav_01"> 469 <div class="flex justify-between items-center px-4 xl:px-8 mx-auto w-full xl:max-w-[1440px]"> 470 <div class="flex items-center"> 471 <div class="max-w-[280px] max-h-[100px] rounded-lg flex-shrink-0 mr-4 xl:mr-8"> 472 <a href="/" aria-label="Saigon Sisters home"> 473 <img src="https://image-cdn.chowlyinc.com/300%2Cfit/https%3A%2F%2Fres.cloudinary.com%2Ftargetable%2Fimage%2Fupload%2Fv1787255781%2FCustomers%2F50070%2FSaigon%2520Sisters%2FPICS%2Flogo.svg" alt="Saigon Sisters logo" class="max-w-[280px] max-h-[100px] w-auto h-auto object-contain rounded-lg"> 474 </a> 475 </div> 476 477 <nav role="navigation" aria-label="Main navigation" class="hidden xl:block"> 478 <ul class="flex"> 479 480 481 <li> 482 <a data-maglev-id="bBXmgufkIJM.link" class="flex text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] items-center justify-center gap-2 py-2 px-3 text-sm font-semibold rounded-md mr-3" aria-current="false" href="/"><span data-maglev-id="bBXmgufkIJM.link.text">Home</span></a> 483 </li> 484 485 <li> 486 <a data-maglev-id="tnA8C-Kd2h8.link" class="flex text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] items-center justify-center gap-2 py-2 px-3 text-sm font-semibold rounded-md mr-3" aria-current="false" href="https://www.opentable.com/restref/client/?restref=62917&lang=en-US&corrid=cc94466e-a0ad-407e-91d2-3cc8acd3d527#"><span data-maglev-id="tnA8C-Kd2h8.link.text">Reservation</span></a> 487 </li> 488 489 <li> 490 <a data-maglev-id="7oUpvmUk55I.link" class="flex text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] items-center justify-center gap-2 py-2 px-3 text-sm font-semibold rounded-md mr-3" aria-current="false" href="/menu"><span data-maglev-id="7oUpvmUk55I.link.text">Menu</span></a> 491 </li> 492 493 <li> 494 <a data-maglev-id="udpPlZgdbig.link" class="flex text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] items-center justify-center gap-2 py-2 px-3 text-sm font-semibold rounded-md mr-3" aria-current="false" href="/cater"><span data-maglev-id="udpPlZgdbig.link.text">Catering</span></a> 495 </li> 496 497 <li class="relative"> 498 <button id="more-menu-button" class="flex text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] items-center justify-center gap-2 py-2 px-3 text-sm font-semibold rounded-md mr-3"> 499 More 500 <svg id="more-arrow" xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 transition-transform duration-300" fill="none" viewBox="0 0 24 24" stroke="currentColor"> 501 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" /> 502 </svg> 503 </button> 504 <div id="more-dropdown" class="hidden fixed left-0 right-0 w-full z-50 transition-all duration-300"> 505 <div class="mx-auto max-w-7xl bg-[var(--bg-secondary)] shadow-lg p-6 rounded-lg dropdown-top-shadow"> 506 <div class="grid grid-cols-3 gap-4"> 507 <div class="w-full mb-2"> 508 <a data-maglev-id="ri0eS2En9TA.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] inline-block py-2 px-4 text-sm font-medium rounded-md" aria-current="false" href="/parties"><span data-maglev-id="ri0eS2En9TA.link.text">Private Parties</span></a> 509 </div> 510 <div class="w-full mb-2"> 511 <a data-maglev-id="QEBa3HrV2t4.link" class="bg-[var(--brand-primary)]/[var(--active-bg-opacity)] text-[var(--active-text)] inline-block py-2 px-4 text-sm font-medium rounded-md" aria-current="page" href="/about-us"><span data-maglev-id="QEBa3HrV2t4.link.text">About Us</span></a> 512 </div> 513 <div class="w-full mb-2"> 514 <a data-maglev-id="lZW7rigoUEg.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] inline-block py-2 px-4 text-sm font-medium rounded-md" aria-current="false" href="https://www.toasttab.com/saigon-sisters-lake-street/giftcards?utm_source=undefined&utm_content=home&utm_medium=toast_sites&utm_term=nav&utm_campaign=giftcards"><span data-maglev-id="lZW7rigoUEg.link.text">Gift Cards</span></a> 515 </div> 516 <div class="w-full mb-2"> 517 <a data-maglev-id="FZX5iQ6aukg.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] inline-block py-2 px-4 text-sm font-medium rounded-md" aria-current="false" href="https://www.toasttab.com/saigon-sisters-lake-street/rewardsSignup"><span data-maglev-id="FZX5iQ6aukg.link.text">Loyalty</span></a> 518 </div> 519 <div class="w-full mb-2"> 520 <a data-maglev-id="gELXreZZzJ0.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] inline-block py-2 px-4 text-sm font-medium rounded-md" aria-current="false" href="/jobs"><span data-maglev-id="gELXreZZzJ0.link.text">Jobs</span></a> 521 </div> 522 <div class="w-full mb-2"> 523 <a data-maglev-id="o6dU1BZ3A4M.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] inline-block py-2 px-4 text-sm font-medium rounded-md" aria-current="false" href="/events"><span data-maglev-id="o6dU1BZ3A4M.link.text">Events</span></a> 524 </div> 525 <div class="w-full mb-2"> 526 <a data-maglev-id="fgu-6M0y1M4.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] inline-block py-2 px-4 text-sm font-medium rounded-md" aria-current="false" href="/press"><span data-maglev-id="fgu-6M0y1M4.link.text">Press</span></a> 527 </div> 528 <div class="w-full mb-2"> 529 <a data-maglev-id="kIOawxqXMeY.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] inline-block py-2 px-4 text-sm font-medium rounded-md" aria-current="false" href="/saigon-french-market"><span data-maglev-id="kIOawxqXMeY.link.text">Saigon Sisters (French Market)</span></a> 530 </div> 531 <div class="w-full mb-2"> 532 <a data-maglev-id="IFlb_wtMFs8.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] inline-block py-2 px-4 text-sm font-medium rounded-md" aria-current="false" href="/gallery"><span data-maglev-id="IFlb_wtMFs8.link.text">Gallery</span></a> 533 </div> 534 <div class="w-full mb-2"> 535 <a data-maglev-id="mJuDi32Bgek.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] inline-block py-2 px-4 text-sm font-medium rounded-md" aria-current="false" href="/recipe"><span data-maglev-id="mJuDi32Bgek.link.text">Recipe</span></a> 536 </div> 537 <div class="w-full mb-2"> 538 <a data-maglev-id="EjOpb3XcEGI.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] inline-block py-2 px-4 text-sm font-medium rounded-md" aria-current="false" href="/contact-us"><span data-maglev-id="EjOpb3XcEGI.link.text">Contact Us</span></a> 539 </div> 540 </div> 541 </div> 542 </div> 543 </li> 544 </ul> 545 </nav> 546 </div> 547 548 <!-- Right side: Mobile toggle + Desktop buttons --> 549 <div class="flex items-center gap-2"> 550 <!-- Mobile menu toggle --> 551 <div class="xl:hidden"> 552 <button id="menu-toggle" class="focus:outline-none" aria-expanded="false" aria-controls="mobile-menu" aria-label="Toggle menu"> 553 <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="var(--stroke-primary)"> 554 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" /> 555 </svg> 556 </button> 557 </div> 558 559 <!-- Desktop buttons (hidden on mobile) --> 560 <div class="hidden xl:flex items-center gap-2"> 561 <!-- Primary Order Now button --> 562 <a href="/stores" class="inline-flex items-center justify-center h-12 px-8 bg-[var(--brand-primary)] text-white text-base font-semibold rounded-md hover:brightness-90">Order Now</a> 563 564 <!-- Secondary button (optional, configurable) --> 565 </div> 566 </div> 567 </div> 568 569 <div id="mobile-menu" class="hidden fixed top-0 left-0 w-full h-full bg-[var(--bg-primary)] z-50 overflow-y-auto"> 570 <div class="flex justify-between items-center px-4 py-4 sticky top-0 bg-[var(--bg-primary)] z-10"> 571 <div class="max-w-[280px] max-h-[100px] rounded-lg flex-shrink-0 mr-4 xl:mr-8"> 572 <img src="https://image-cdn.chowlyinc.com/300%2Cfit/https%3A%2F%2Fres.cloudinary.com%2Ftargetable%2Fimage%2Fupload%2Fv1787255781%2FCustomers%2F50070%2FSaigon%2520Sisters%2FPICS%2Flogo.svg" alt="Saigon Sisters logo" class="max-w-[280px] max-h-[100px] w-auto h-auto object-contain rounded-lg"> 573 </div> 574 <button id="menu-close" class="focus:outline-none" aria-label="Close menu"> 575 <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="var(--stroke-primary)"> 576 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /> 577 </svg> 578 </button> 579 </div> 580 581 <nav role="navigation" aria-label="Mobile navigation" class="pb-32"> 582 <ul class="flex flex-col items-start px-5 space-y-6 mt-8"> 583 584 <li> 585 <a data-maglev-id="bBXmgufkIJM.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] py-2 px-4 text-sm font-semibold pl-3" aria-current="false" href="/"><span data-maglev-id="bBXmgufkIJM.link.text">Home</span></a> 586 </li> 587 588 <li> 589 <a data-maglev-id="tnA8C-Kd2h8.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] py-2 px-4 text-sm font-semibold pl-3" aria-current="false" href="https://www.opentable.com/restref/client/?restref=62917&lang=en-US&corrid=cc94466e-a0ad-407e-91d2-3cc8acd3d527#"><span data-maglev-id="tnA8C-Kd2h8.link.text">Reservation</span></a> 590 </li> 591 592 <li> 593 <a data-maglev-id="7oUpvmUk55I.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] py-2 px-4 text-sm font-semibold pl-3" aria-current="false" href="/menu"><span data-maglev-id="7oUpvmUk55I.link.text">Menu</span></a> 594 </li> 595 596 <li> 597 <a data-maglev-id="udpPlZgdbig.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] py-2 px-4 text-sm font-semibold pl-3" aria-current="false" href="/cater"><span data-maglev-id="udpPlZgdbig.link.text">Catering</span></a> 598 </li> 599 600 <li> 601 <a data-maglev-id="ri0eS2En9TA.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] py-2 px-4 text-sm font-semibold pl-3" aria-current="false" href="/parties"><span data-maglev-id="ri0eS2En9TA.link.text">Private Parties</span></a> 602 </li> 603 604 <li> 605 <a data-maglev-id="QEBa3HrV2t4.link" class="bg-[var(--brand-primary)]/[var(--active-bg-opacity)] text-[var(--active-text)] py-2 px-4 text-sm font-semibold pl-3" aria-current="page" href="/about-us"><span data-maglev-id="QEBa3HrV2t4.link.text">About Us</span></a> 606 </li> 607 608 <li> 609 <a data-maglev-id="lZW7rigoUEg.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] py-2 px-4 text-sm font-semibold pl-3" aria-current="false" href="https://www.toasttab.com/saigon-sisters-lake-street/giftcards?utm_source=undefined&utm_content=home&utm_medium=toast_sites&utm_term=nav&utm_campaign=giftcards"><span data-maglev-id="lZW7rigoUEg.link.text">Gift Cards</span></a> 610 </li> 611 612 <li> 613 <a data-maglev-id="FZX5iQ6aukg.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] py-2 px-4 text-sm font-semibold pl-3" aria-current="false" href="https://www.toasttab.com/saigon-sisters-lake-street/rewardsSignup"><span data-maglev-id="FZX5iQ6aukg.link.text">Loyalty</span></a> 614 </li> 615 616 <li> 617 <a data-maglev-id="gELXreZZzJ0.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] py-2 px-4 text-sm font-semibold pl-3" aria-current="false" href="/jobs"><span data-maglev-id="gELXreZZzJ0.link.text">Jobs</span></a> 618 </li> 619 620 <li> 621 <a data-maglev-id="o6dU1BZ3A4M.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] py-2 px-4 text-sm font-semibold pl-3" aria-current="false" href="/events"><span data-maglev-id="o6dU1BZ3A4M.link.text">Events</span></a> 622 </li> 623 624 <li> 625 <a data-maglev-id="fgu-6M0y1M4.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] py-2 px-4 text-sm font-semibold pl-3" aria-current="false" href="/press"><span data-maglev-id="fgu-6M0y1M4.link.text">Press</span></a> 626 </li> 627 628 <li> 629 <a data-maglev-id="kIOawxqXMeY.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] py-2 px-4 text-sm font-semibold pl-3" aria-current="false" href="/saigon-french-market"><span data-maglev-id="kIOawxqXMeY.link.text">Saigon Sisters (French Market)</span></a> 630 </li> 631 632 <li> 633 <a data-maglev-id="IFlb_wtMFs8.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] py-2 px-4 text-sm font-semibold pl-3" aria-current="false" href="/gallery"><span data-maglev-id="IFlb_wtMFs8.link.text">Gallery</span></a> 634 </li> 635 636 <li> 637 <a data-maglev-id="mJuDi32Bgek.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] py-2 px-4 text-sm font-semibold pl-3" ari
637a-current="false" href="/recipe"><span data-maglev-id="mJuDi32Bgek.link.text">Recipe</span></a> 638 </li> 639 640 <li> 641 <a data-maglev-id="EjOpb3XcEGI.link" class="text-[var(--text-muted)] hover:bg-[var(--brand-primary)]/[var(--hover-bg-opacity)] py-2 px-4 text-sm font-semibold pl-3" aria-current="false" href="/contact-us"><span data-maglev-id="EjOpb3XcEGI.link.text">Contact Us</span></a> 642 </li> 643 </ul> 644 </nav> 645 646 <div class="fixed bottom-0 left-0 w-full flex items-center justify-center gap-2 py-8 px-4 bg-[var(--bg-primary)] border-[var(--border-secondary)]"> 647 <!-- Primary Order Now button --> 648 <a href="/stores" class="inline-flex h-12 px-8 justify-center items-center gap-2 flex-shrink-0 rounded-[6px] bg-[var(--brand-primary)] text-white text-[15px] font-semibold leading-[150%] hover:brightness-90">Order Now</a> 649 650 <!-- Secondary button (optional, configurable) --> 651 </div> 652 </div> 653</header>
654<script> 655 const menuToggle = document.getElementById('menu-toggle'); 656 const menuClose = document.getElementById('menu-close'); 657 const mobileMenu = document.getElementById('mobile-menu'); 658 659 menuToggle.addEventListener('click', () => { 660 mobileMenu.classList.remove('hidden'); 661 mobileMenu.setAttribute('aria-hidden', 'false'); 662 menuToggle.setAttribute('aria-expanded', 'true'); 663 }); 664 665 menuClose.addEventListener('click', () => { 666 mobileMenu.classList.add('hidden'); 667 mobileMenu.setAttribute('aria-hidden', 'true'); 668 menuToggle.setAttribute('aria-expanded', 'false'); 669 }); 670 671 document.addEventListener('DOMContentLoaded', function() { 672 // More menu dropdown functionality 673 const moreButton = document.getElementById('more-menu-button'); 674 const moreDropdown = document.getElementById('more-dropdown'); 675 const moreArrow = document.getElementById('more-arrow'); 676 677 if (moreButton && moreDropdown && moreArrow) { 678 let isOpen = false; 679 let isHoveringButton = false; 680 let isHoveringDropdown = false; 681 let dropdownTimeout; 682 683 function showDropdown() { 684 clearTimeout(dropdownTimeout); 685 moreDropdown.classList.remove('hidden'); 686 moreDropdown.style.opacity = '1'; 687 moreArrow.classList.add('rotate-180'); 688 isOpen = true; 689 } 690 691 function hideDropdown() { 692 moreDropdown.style.opacity = '0'; 693 moreArrow.classList.remove('rotate-180'); 694 695 dropdownTimeout = setTimeout(() => { 696 moreDropdown.classList.add('hidden'); 697 isOpen = false; 698 }, 300); 699 } 700 701 function toggleDropdown() { 702 if (isOpen) { 703 hideDropdown(); 704 } else { 705 showDropdown(); 706 } 707 } 708 709 function updateDropdownVisibility() { 710 if (isHoveringButton || isHoveringDropdown) { 711 showDropdown(); 712 } else { 713 hideDropdown(); 714 } 715 } 716 717 moreButton.addEventListener('click', function(e) { 718 e.preventDefault(); 719 toggleDropdown(); 720 }); 721 722 moreButton.addEventListener('mouseenter', () => { 723 isHoveringButton = true; 724 updateDropdownVisibility(); 725 }); 726 727 moreButton.addEventListener('mouseleave', () => { 728 isHoveringButton = false; 729 toggleDropdown(); 730 }); 731 732 moreDropdown.addEventListener('mouseenter', () => { 733 isHoveringDropdown = true; 734 updateDropdownVisibility(); 735 }); 736 737 moreDropdown.addEventListener('mouseleave', () => { 738 isHoveringDropdown = false; 739 toggleDropdown(); 740 }); 741 742 document.addEventListener('click', function(e) { 743 if (isOpen && !moreButton.contains(e.target) && !moreDropdown.contains(e.target)) { 744 hideDropdown(); 745 } 746 }); 747 } 748 749 // Locations dropdown functionality (desktop main nav) 750 const locationsContainers = document.querySelectorAll('.locations-dropdown-container'); 751 locationsContainers.forEach(container => { 752 const button = container.querySelector('.locations-dropdown-button'); 753 const dropdown = container.querySelector('.locations-dropdown'); 754 const arrow = container.querySelector('.locations-arrow'); 755 756 if (button && dropdown && arrow) { 757 let isOpen = false; 758 let hoverTimeout; 759 760 function showLocationsDropdown() { 761 clearTimeout(hoverTimeout); 762 dropdown.classList.remove('hidden'); 763 arrow.classList.add('rotate-180'); 764 isOpen = true; 765 } 766 767 function hideLocationsDropdown() { 768 hoverTimeout = setTimeout(() => { 769 dropdown.classList.add('hidden'); 770 arrow.classList.remove('rotate-180'); 771 isOpen = false; 772 }, 150); 773 } 774 775 button.addEventListener('click', (e) => { 776 e.preventDefault(); 777 if (isOpen) { 778 hideLocationsDropdown(); 779 } else { 780 showLocationsDropdown(); 781 } 782 }); 783 784 container.addEventListener('mouseenter', showLocationsDropdown); 785 container.addEventListener('mouseleave', hideLocationsDropdown); 786 787 document.addEventListener('click', (e) => { 788 if (isOpen && !container.contains(e.target)) { 789 dropdown.classList.add('hidden'); 790 arrow.classList.remove('rotate-180'); 791 isOpen = false;
792 } 793 }); 794 } 795 }); 796 797 // Locations dropdown in "More" menu 798 const locationsMoreContainers = document.querySelectorAll('.locations-more-dropdown-container'); 799 locationsMoreContainers.forEach(container => { 800 const button = container.querySelector('.locations-more-button'); 801 const dropdown = container.querySelector('.locations-more-dropdown'); 802 const arrow = container.querySelector('.locations-more-arrow'); 803 804 if (button && dropdown && arrow) { 805 let isOpen = false; 806 807 button.addEventListener('click', (e) => { 808 e.preventDefault(); 809 e.stopPropagation(); 810 if (isOpen) { 811 dropdown.classList.add('hidden'); 812 arrow.classList.remove('rotate-180'); 813 isOpen = false; 814 } else { 815 dropdown.classList.remove('hidden'); 816 arrow.classList.add('rotate-180'); 817 isOpen = true; 818 } 819 }); 820 821 container.addEventListener('mouseenter', () => { 822 dropdown.classList.remove('hidden'); 823 arrow.classList.add('rotate-180'); 824 isOpen = true; 825 }); 826 827 container.addEventListener('mouseleave', () => { 828 dropdown.classList.add('hidden'); 829 arrow.classList.remove('rotate-180'); 830 isOpen = false; 831 }); 832 } 833 }); 834 835 // Mobile locations toggle 836 const mobileLocationsToggles = document.querySelectorAll('.mobile-locations-toggle'); 837 mobileLocationsToggles.forEach(toggle => { 838 const arrow = toggle.querySelector('.mobile-locations-arrow'); 839 const list = toggle.parentElement.querySelector('.mobile-locations-list'); 840 841 if (arrow && list) { 842 toggle.addEventListener('click', (e) => { 843 e.preventDefault(); 844 list.classList.toggle('hidden'); 845 arrow.classList.toggle('rotate-180'); 846 }); 847 } 848 }); 849 }); 850</script>
850 851 852<style> 853 .rotate-180 { 854 transform: rotate(180deg); 855 transition: transform 300ms; 856 } 857 858 #more-dropdown { 859 opacity: 0; 860 transition: opacity 300ms; 861 position: absolute; 862 top: 100%; 863 left: 50%; 864 right: 0; 865 width: 80vw; 866 margin-left: auto; 867 margin-right: auto; 868 z-index: 50; 869 transform: translateX(calc(-50% + 10vw)); 870 } 871 872 .dropdown-top-shadow { 873 box-shadow: 0 -4px 6px -1px rgba(0, 0, 0, 0.1), 0 -2px 4px -1px rgba(0, 0, 0, 0.06), 874 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); 875 } 876 877 .locations-dropdown { 878 box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); 879 } 880 881 .locations-more-dropdown { 882 box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); 883 } 884</style> 885<section class="w-full xl:max-w-[1440px] mx-auto h-auto flex-shrink-0 relative flex flex-col items-start justify-center px-10 xl:px-20 py-10 xl:py-20 col-span-2" id="section-ssH1aboutu" data-maglev-section-id="ssH1aboutu" data-maglev-section-type="custom_html_01"> 886 <div class="ss-root ssh"><p class="ssh-eye">Our Story</p><h1 class="ssh-h">Saigon Sisters: A Vietnamese Family Kitchen</h1></div> 887<style> 888.ss-root{width:100%;flex:1 1 100%;min-width:0;display:block} 889.ssh{text-align:center;padding:clamp(40px,6vw,72px) 16px clamp(8px,2vw,20px)} 890.ssh-eye{margin:0 0 10px;text-transform:uppercase;letter-spacing:.18em;font-size:.8rem;font-weight:700;color:var(--brand-primary,#4d7a24)} 891.ssh-h{margin:0 auto;max-width:900px;font-size:clamp(2rem,4.2vw,3.2rem);line-height:1.1;color:var(--text-primary,#311541)} 892</style> 893</section> 894<section class="flex flex-grow flex-col xl:flex-row items-center xl:justify-evenly gap-6 xl:gap-6 w-full xl:max-w-[1440px] mx-auto mt-10 xl:mt-20 px-4 xl:px-0 col-span-2 md:col-span-1 xl:col-span-2" id="section-y4bXQdGUH94" data-maglev-section-id="y4bXQdGUH94" data-maglev-section-type="image_left_01"> 895 <figure class="w-full xl:w-[500px] min-w-0 hidden xl:block order-1"> 896 <img src="/maglev/assets/a8b8d937-e5ae-4a1f-b6f9-44e97b415920-mary-20and-20theresa-20best-20pic.avif" alt="Two Sisters, One Family Legacy" data-maglev-id="y4bXQdGUH94.image" class="rounded-lg w-full h-auto object-cover" /> 897 </figure> 898 <article class="w-full xl:w-[480px] min-w-0 text-left order-2"> 899 <h2 data-maglev-id="y4bXQdGUH94.title" class="text-[var(--text-primary)] font-semibold text-[32px] xl:text-[48px] leading-none tracking-[-0.48px]" id="section-title-b9e3e06f1a62">Two Sisters, One Family Legacy</h2> 900 901 <figure class=" xl:hidden w-full mt-4"> 902 <img src="/maglev/assets/a8b8d937-e5ae-4a1f-b6f9-44e97b415920-mary-20and-20theresa-20best-20pic.avif" alt="Two Sisters, One Family Legacy" data-maglev-id="y4bXQdGUH94.image" class="rounded-lg w-full h-auto object-cover" /> 903 </figure> 904 905 <p data-maglev-id="y4bXQdGUH94.body" class="text-[var(--text-secondary)] text-[14px] xl:text-[16px] font-normal leading-[24px] mt-4">Saigon Sisters is led by Vietnamese sisters Mary Nguyen Aregoni and Theresa Nguyen, alongside the memory of their beloved mother, Mama Suu, who passed away on January 5, 2025. The family's story starts long before Chicago, with a grandmother who ran a food distribution business serving markets and embassies in Laos, and continues through their move to the United States in 1976. What began as a dream between a mother and her daughters is now a restaurant built on that same entrepreneurial spirit and love of feeding people well.</p> 906 907 </article> 908</section> 909<section class="flex flex-grow flex-col xl:flex-row items-center xl:justify-evenly gap-6 xl:gap-6 w-full xl:max-w-[1440px] mx-auto mt-10 xl:mt-20 px-4 xl:px-0 col-span-2 md:col-span-1 xl:col-span-2" id="section-FjzSonYwoGo" data-maglev-section-id="FjzSonYwoGo" data-maglev-section-type="image_right_01"> 910 <article class="w-full xl:w-[480px] min-w-0 text-left order-2 xl:order-1"> 911 <h2 data-maglev-id="FjzSonYwoGo.title" class="text-[var(--text-primary)] font-semibold text-[32px] xl:text-[48px] leading-none tracking-[-0.48px]" id="section-title-7ac56c9e7120">Southeast Asian Roots, French Influence</h2> 912 913 <figure class=" xl:hidden w-full mt-4"> 914 <img src="/maglev/assets/43c6adcb-eb81-4a53-b3b3-23223de988ec-lemongrass-20pork-20chop-20resize.avif" alt="Southeast Asian Roots, French Influence" data-maglev-id="FjzSonYwoGo.image" class="rounded-lg w-full h-auto object-cover" /> 915 </figure> 916 917 <p data-maglev-id="FjzSonYwoGo.body" class="text-[var(--text-secondary)] text-[14px] xl:text-[16
917px] font-normal leading-[24px] mt-4">Growing up between Southeast Asian and French cuisines gave this family a distinct way of cooking, one that shows up in every banh mi baguette and every bowl of curry we serve. Our kitchen blends traditional Vietnamese technique with dishes that reflect where this family has been and what they've learned along the way, from Laos to Chicago. Nothing on the menu is there by accident, it's all connected to where we come from.</p> 918 919 </article> 920 <figure class="w-full xl:w-[500px] min-w-0 hidden xl:block order-1 xl:order-2"> 921 <img src="/maglev/assets/43c6adcb-eb81-4a53-b3b3-23223de988ec-lemongrass-20pork-20chop-20resize.avif" alt="Southeast Asian Roots, French Influence" data-maglev-id="FjzSonYwoGo.image" class="rounded-lg w-full h-auto object-cover" /> 922 </figure> 923</section> 924<section class="flex flex-grow flex-col xl:flex-row items-center xl:justify-evenly gap-6 xl:gap-6 w-full xl:max-w-[1440px] mx-auto mt-10 xl:mt-20 px-4 xl:px-0 col-span-2 md:col-span-1 xl:col-span-2" id="section-sybu7lb2Ock" data-maglev-section-id="sybu7lb2Ock" data-maglev-section-type="image_left_01"> 925 <figure class="w-full xl:w-[500px] min-w-0 hidden xl:block order-1"> 926 <img src="/maglev/assets/3d5b9bea-3323-4833-aed3-54fea6b9010a-nems.avif" alt="Right in the Heart of the West Loop" data-maglev-id="sybu7lb2Ock.image" class="rounded-lg w-full h-auto object-cover" /> 927 </figure> 928 <article class="w-full xl:w-[480px] min-w-0 text-left order-2"> 929 <h2 data-maglev-id="sybu7lb2Ock.title" class="text-[var(--text-primary)] font-semibold text-[32px] xl:text-[48px] leading-none tracking-[-0.48px]" id="section-title-22a7a0c13c06">Right in the Heart of the West Loop</h2> 930 931 <figure class=" xl:hidden w-full mt-4"> 932 <img src="/maglev/assets/3d5b9bea-3323-4833-aed3-54fea6b9010a-nems.avif" alt="Right in the Heart of the West Loop" data-maglev-id="sybu7lb2Ock.image" class="rounded-lg w-full h-auto object-cover" /> 933 </figure> 934 935 <p data-maglev-id="sybu7lb2Ock.body" class="text-[var(--text-secondary)] text-[14px] xl:text-[16px] font-normal leading-[24px] mt-4">You'll find us at 567 W. Lake Street, in a West Loop dining room built for real conversation over a real meal, with limited indoor seating that fills up fast, so a reservation is a good idea. Our roots are also still at the Chicago French Market at 131 N. Clinton Street, the same spot where Mama Suu once served Banh Mis and Pho to the neighborhood. Two locations, one family, and a story you can taste in both.</p> 936 937 </article> 938</section> 939<section class="flex flex-grow flex-col xl:flex-row items-center xl:justify-evenly gap-6 xl:gap-6 w-full xl:max-w-[1440px] mx-auto mt-10 xl:mt-20 px-4 xl:px-0 col-span-2 md:col-span-1 xl:col-span-2" id="section-u-ZwNrjt0WY" data-maglev-section-id="u-ZwNrjt0WY" data-maglev-section-type="image_right_01"> 940 <article class="w-full xl:w-[480px] min-w-0 text-left order-2 xl:order-1"> 941 <h2 data-maglev-id="u-ZwNrjt0WY.title" class="text-[var(--text-primary)] font-semibold text-[32px] xl:text-[48px] leading-none tracking-[-0.48px]" id="section-title-a916efda5843">Bring the Family Recipes Home</h2> 942 943 <figure class=" xl:hidden w-full mt-4"> 944 <img src="/maglev/assets/27a8034b-4d32-4d5b-ad0c-7b08cf0eb673-beef-20khao-20soi.avif" alt="Bring the Family Recipes Home" data-maglev-id="u-ZwNrjt0WY.image" class="rounded-lg w-full h-auto object-cover" /> 945 </figure> 946 947 <p data-maglev-id="u-ZwNrjt0WY.body" class="text-[var(--text-secondary)] text-[14px] xl:text-[16px] font-normal leading-[24px] mt-4">Now that you know our story, come taste it for yourself. Order online from either location and enjoy the same banh mis, pho and baos that carried this family from a small market stall to a West Loop restaurant, all made the way Mama Suu would have wanted. We also cater offices, weddings, private events and cooking classes, so let us know how we can be part of your next gathering too.</p> 948 949 <a data-maglev-id="u-ZwNrjt0WY.button" class="inline-flex h-[48px] px-8 py-4 justify-center items-center gap-2 flex-shrink-0 bg-[var(--button-bg)] text-[var(--button-text)] border border-[var(--button-border)] hover:bg-[var(--button-hover-bg)] hover:border-[var(--button-hover-border)] text-[15px] font-semibold leading-[150%] rounded-[6px] mt-7" aria-label="Order Now â Bring the Family Recipes Home" href="/stores"><span data-maglev-id="u-ZwNrjt0WY.button.text">Order Now</span></a> 950 </article> 951 <figure class="w-full xl:w-[500px] min-w-0 hidden xl:block order-1 xl:order-2"> 952 <img src="/maglev/assets/27a8034b-4d32-4d5b-ad0c-7b08cf0eb673-beef-20khao-20soi.avif" alt="Bring the Family Recipes Home" data-maglev-id="u-ZwNrjt0WY.image" class="rounded-lg w-full h-auto object-cover" /> 953 </figure> 954</section><footer class="w-full mx-auto bg-[var(--bg-primary)] py-8 col-span-2" role="contentinfo" itemscope="itemscope" itemtype="https://schema.org/WPFooter" id="section-C803vDZW" data-maglev-section-id="C803vDZW" data-maglev-section-type="standard_footer_01"> 955 <div class="w-full px-4 xl:px-0 xl:w-[1200px] mx-auto flex flex-col space-y-3 xl:space-y-6"> 956 957 <div class="w-full grid grid-cols-1 xl:grid-cols-3 gap-4 xl:gap-4 mb-2 xl:mb-4"> 958 <nav class="col-span-1 flex flex-wrap justify-center xl:justify-start order-2 xl:order-1 xl:pl-0" aria-label="Footer navigation"> 959 <a data-maglev-id="uJRkXCzfEqs.link" class="mx-3 xl:mx-0 xl:mr-6 mb-2 text-[var(--link-text)] hover:text-[var(--link-hover)] text-sm" href="/events"><span data-maglev-id="uJRkXCzfEqs.link.text">Events</span></a> 960 <a data-maglev-id="VhznJc8Km1o.link" class="mx-3 xl:mx-0 xl:mr-6 mb-2 text-[var(--link-text)] hover:text-[var(--link-hover)] text-sm" href="/parties"><span data-maglev-id="VhznJc8Km1o.link.text">Parties</span></a> 961 <a data-maglev-id="BtM4YbIQy-c.link" class="mx-3 xl:mx-0 xl:mr-6 mb-2 text-[var(--link-text)] hover:text-[var(--link-hover)] text-sm" href="/press"><span data-maglev-id="BtM4YbIQy-c.link.text">Press</span></a> 962 <a data-maglev-id="6QCxcnQajQ4.link" class="mx-3 xl:mx-0 xl:mr-6 mb-2 text-[var(--link-text)] hover:text-[var(--link-hover)] text-sm" href="/contact-us"><span data-maglev-id="6QCxcnQajQ4.link.text">Contact Us</span></a> 963 </nav> 964 965 <nav class="col-span-1 flex justify-center space-x-6 xl:space-x-8 order-1 xl:order-2" aria-label="Social media links"> 966 <a data-maglev-id="oa00iH_yXwU.link" target="_blank" class="w-[32px] h-[32px] bg-[var(--social-bg)] rounded-lg text-[var(--social-text)] text-center" aria-label="fa-brands fa-facebook-f" href="https://www.instagram.com/saigonsisters"> 967 <i class="text-[24px] pt-[4px] fa-brands fa-facebook-f" data-maglev-id="oa00iH_yXwU.icon"></i> 968</a> <a data-maglev-id="FJ_JejxhY9s.link" target="_blank" class="w-[32px] h-[32px] bg-[var(--social-bg)] rounded-lg text-[var(--social-text)] text-center" aria-label="fa-brands fa-instagram" href="https://www.instagram.com/saigonsisters"> 969 <i class="text-[24px] pt-[4px] fa-brands fa-instagram" data-maglev-id="FJ_JejxhY9s.icon"></i> 970</a> </nav> 971 972 <div class="col-span-1 hidden xl:block order-3"></div> 973 </div> 974 975 <div class="w-full flex flex-col xl:flex-row justify-between items-center text-[var(--text-secondary)] text-sm font-normal leading-[142.857%] space-y-3 xl:space-y-0 mt-2 xl:mt-6"> 976 <nav class="flex flex-wrap justify-center xl:justify-start flex-grow
976space-x-4 xl:space-x-6 xl:pl-0" aria-label="Legal links"> 977 <a href="https://koala-configurations.s3.amazonaws.com/public/assets/Chowly-Terms-and-Conditions-b3cca027-acb6-42db-9d1f-11080e29b1e1.pdf" target="_blank" rel="noopener" class="mb-2">Terms of Use</a> 978 <a href="https://koala-configurations.s3.us-east-1.amazonaws.com/public/assets/Chowly-Privacy-Policy-202f4118-faeb-4593-8574-57dc447ae203.pdf" target="_blank" rel="noopener" class="mb-2">Privacy Policy</a> 979 </nav> 980 981 <p class="relative text-center xl:flex-grow xl:left-[-200px]" itemscope itemtype="https://schema.org/Organization"> 982 <span>Saigon Sisters</span>⢠<span itemprop="copyrightYear">2026</span> All Rights Reserved 983 </p> 984 <p class="text-center xl:text-right">Made by <a href="https://www.chowly.com" class="font-bold" rel="noopener">Chowly</a></p> 985 </div> 986 </div> 987</footer> 988 </section> 989 </main> 990 <!-- ===== Saigon Sisters â scroll reveal (body_scripts) ===== -->
991<script> 992(function(){ 993 // Signal that this reveal script mounted, so a host's belt-and-suspenders "force-reveal if JS 994 // didn't load" fallback can NO-OP when scroll-reveal is actually running (otherwise that fallback 995 // reveals every section on a timer, defeating the on-scroll animation). Set before the 996 // reduced-motion return so it's true whenever body_scripts executed at all. 997 window.cwRevealMounted = true; 998 if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) return; 999 // tag content sections for reveal â skip notification, nav, hero, footer (by id/role, NOT ordinal) 1000 var SKIP = {'section-FYU2eG76':1,'section-dDb0AMpP':1,'section-M4aDtxB6egU':1,'section-C803vDZW':1}; 1001 function tag(){ 1002 document.querySelectorAll('[id^="section-"]').forEach(function(el){ 1003 if (!SKIP[el.id]) el.classList.add('cw-reveal'); 1004 }); 1005 } 1006 function reveal(){ 1007 var vh = window.innerHeight || document.documentElement.clientHeight; 1008 document.querySelectorAll('.cw-reveal').forEach(function(el){ 1009 if (el.classList.contains('cw-in')) return; 1010 // scroll-position check (NOT IntersectionObserver â survives fast-scroll / jump-links / restored scroll) 1011 if (el.getBoundingClientRect().top < vh * 0.88) el.classList.add('cw-in'); 1012 }); 1013 } 1014 function armReveal(){ 1015 window.addEventListener('scroll', reveal, {passive:true}); 1016 window.addEventListener('resize', reveal, {passive:true}); 1017 // Defer the first reveal one paint so the opacity:0 state renders before .cw-in is added â a 1018 // section at the fold then animates in instead of snapping visible. 1019 if (window.requestAnimationFrame) 1020 requestAnimationFrame(function(){ requestAnimationFrame(reveal); }); 1021 else reveal(); 1022 } 1023 // Tag sections hidden SYNCHRONOUSLY now, before first paint. This inline script sits at the end of 1024 // <body>, so every content section above it is already parsed â hiding them here means a near-fold 1025 // section can't flash visible-then-hidden (tagging at DOMContentLoaded can paint once first, then 1026 // hide â a blink). No-JS never runs this and reduced-motion returned above, so content is only ever 1027 // hidden with JS + motion on; .cw-in (added post-paint) animates it in. Re-tag at DCL is a 1028 // belt-and-suspenders no-op catch for any section parsed after this script. 1029 tag(); 1030 if (document.readyState === 'loading') 1031 document.addEventListener('DOMContentLoaded', function(){ tag(); armReveal(); }); 1032 else armReveal(); 1033})(); 1034</script>
vendor: 2 bytes, line 1034
1034
1035<script> 1036/* shared motion utility (#177) â the ONE IntersectionObserver helper every library element 1037 rides: cwOnView(selector, class[, once=true]). Reduced-motion contract: callers gate their 1038 ANIMATION in CSS via prefers-reduced-motion; the class-add itself always runs so the 1039 finished state is the no-motion state (content never hidden without JS or motion). */ 1040(function(){ 1041 window.cwOnView = window.cwOnView || function (sel, cls, once) { 1042 var els = document.querySelectorAll(sel); 1043 if (!els.length) return; 1044 if (!('IntersectionObserver' in window)) { 1045 els.forEach(function (el) { el.classList.add(cls); }); 1046 return; 1047 } 1048 var io = new IntersectionObserver(function (entries) { 1049 entries.forEach(function (e) { 1050 if (e.isIntersecting) { 1051 e.target.classList.add(cls); 1052 if (once !== false) io.unobserve(e.target); 1053 } 1054 }); 1055 }, {threshold: 0.15}); 1056 els.forEach(function (el) { io.observe(el); }); 1057 }; 1058})(); 1059</script>
vendor: 2 bytes, line 1059
1059
1060<script> 1061/* shared editor-preview re-mount utility (#536) â the ONE MutationObserver every DOM-injecting 1062 element rides: cwRemount(mountFn). The Maglev editor's live preview re-renders a section's DOM 1063 AFTER body scripts run, so any JS-injected children are wiped (the published static site never 1064 does this). cwRemount runs mountFn once now, then re-runs it whenever a burst of body mutations 1065 settles. Per-node idempotency stays the CALLER's job â its own mount function must no-op on a 1066 node it already mounted (e.g. a `host.dataset.cwXx` guard); a guard key shared across components 1067 would let two of them clobber each other's mounted-state tracking. One observer serves every 1068 caller, so the second DOM-injecting element costs nothing beyond its callback. */ 1069(function(){ 1070 if (window.cwRemount) return; 1071 var mounts = [], timer = null, watching = false; 1072 function remountAll() { 1073 timer = null; // cleared BEFORE the callbacks, so a throwing caller can't wedge the debounce 1074 mounts.forEac
1074h(function (fn) { 1075 // one caller must never starve its siblings: surface the error asynchronously (it still 1076 // reaches the console with its stack) and carry on down the list 1077 try { fn(); } catch (err) { setTimeout(function () { throw err; }, 0); } 1078 }); 1079 } 1080 window.cwRemount = function (mountFn) { 1081 mountFn(); // mount now â on the published static site this is the only pass needed 1082 mounts.push(mountFn); 1083 if (watching || !window.MutationObserver) return; 1084 watching = true; 1085 new MutationObserver(function () { 1086 if (timer) return; // debounce the burst â one re-mount pass per 120ms of churn 1087 timer = setTimeout(remountAll, 120); 1088 }).observe(document.body, {childList: true, subtree: true}); 1089 }; 1090})(); 1091</script>
1091 1092<!-- ===== corner mascot (peek) ===== -->
1093<script> 1094(function(){ 1095 function init(){ 1096 if (document.querySelector('.cw-peek')) return; 1097 var a = document.createElement('a'); 1098 a.className = 'cw-peek'; 1099 a.href = '/stores'; 1100 a.setAttribute('aria-label', 'Order Saigon Sisters online for pickup or delivery'); 1101 a.innerHTML = '<span class="cw-peek__tip">Order Online</span>'; 1102 document.body.appendChild(a); 1103 function onScroll(){ 1104 var vh = window.innerHeight || document.documentElement.clientHeight; 1105 if (window.scrollY > vh * 0.75) a.classList.add('cw-peek--in'); 1106 else a.classList.remove('cw-peek--in'); 1107 } 1108 window.addEventListener('scroll', onScroll, {passive:true}); 1109 onScroll(); 1110 } 1111 if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init); 1112 else init(); 1113})(); 1114</script>
1114 1115 1116 1117</body> 1118</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.