";margin-left:.25rem;opacity:0;transform:var(--tw-transform)}#menu nav>ul>li li a:after{content:"\2000\266F";margin-left:.25rem}#menu nav>ul>li>a.active:after,#menu nav>ul>li>a.active:before,#menu nav>ul>li>a:hover:after,#menu nav>ul>li>a:hover:before{--tw-translate-x:0px;opacity:1;transform:var(--tw-transform)}@font-face{font-display:swap;font-family:IBM Plex Mono;font-style:normal;font-weight:400;src:url(/static/ibm-plex-mono-v6-latin-regular-c708fd4f02694c48059ff599eaab6a33.woff2) format("woff2")}@font-face{font-display:swap;font-family:IBM Plex Mono;font-style:italic;font-weight:400;src:url(/static/ibm-plex-mono-v6-latin-italic-1c4b3c62369a45fdc78f4146f9b16417.woff2) format("woff2")}@font-face{font-display:swap;font-family:IBM Plex Mono;font-style:normal;font-weight:500;src:url(/static/ibm-plex-mono-v6-latin-500-1eeaa99b03ad926d0cd60abcc4ffb901.woff2) format("woff2")}@font-face{font-display:swap;font-family:IBM Plex Mono;font-style:italic;font-weight:500;src:url(/static/ibm-plex-mono-v6-latin-500italic-2f3ff4c87e1d23f6a7be79e61607dbc7.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:normal;font-weight:400;src:url(/static/ibm-plex-serif-v9-latin-regular-36d1794d9b478119b1b23f3314b20fc5.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:italic;font-weight:400;src:url(/static/ibm-plex-serif-v9-latin-italic-1736b2738313516b472e52013d0421bf.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:normal;font-weight:500;src:url(/static/ibm-plex-serif-v9-latin-500-a3db2c3279ad389f04960680d4d7ace4.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:italic;font-weight:500;src:url(/static/ibm-plex-serif-v9-latin-500italic-dfe083aeb3676418aeef628322e91a06.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:normal;font-weight:700;src:url(/static/ibm-plex-serif-v9-latin-700-455f367c7984c7d84297d04183e73a85.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:italic;font-weight:700;src:url(/static/ibm-plex-serif-v9-latin-700italic-0526086c877f65395725c48335ed63db.woff2) format("woff2")}.link,.link-primary{display:inline-block;font-weight:500}.link{cursor:pointer;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;text-decoration-thickness:from-font}.link-primary,.link:hover{color:var(--primary)}.link-primary{cursor:pointer}.link-primary:hover{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;text-decoration-thickness:from-font}.overflow-grad{background:linear-gradient(90deg,transparent 0,var(--secondary) 70%);bottom:0;display:block;position:absolute;right:0;width:15%}.icon{fill:currentColor;display:inline-block;font-style:normal;font-weight:400;text-transform:none}.icon,.icon~*{vertical-align:middle}.icon-spinner{-webkit-animation:rotate 2s linear infinite;animation:rotate 2s linear infinite}.icon-spinner>circle{fill:none;stroke:currentColor;stroke-width:5;-webkit-animation:dash 1.5s ease-in-out infinite;animation:dash 1.5s ease-in-out infinite}@-webkit-keyframes rotate{to{transform:rotate(1turn)}}@keyframes rotate{to{transform:rotate(1turn)}}@-webkit-keyframes dash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}to{stroke-dasharray:90,150;stroke-dashoffset:-124}}@keyframes dash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}to{stroke-dasharray:90,150;stroke-dashoffset:-124}}.btn{--tw-shadow:0 10px 15px -3px rgba(0,0,0,0.1),0 4px 6px -2px rgba(0,0,0,0.05);background-color:var(--accent);border-color:var(--accent);border-radius:.25rem;border-width:2px;box-shadow:0 0 transparent,0 0 transparent,var(--tw-shadow);box-shadow:var(--tw-ring-offset-shadow,0 0 transparent),var(--tw-ring-shadow,0 0 transparent),var(--tw-shadow);color:var(--typo-dim);cursor:pointer;display:inline-block;font-family:IBM Plex Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1rem;font-style:italic;font-weight:500;line-height:1.5rem;padding:.5rem 1.5rem;position:relative;text-shadow:none;transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;white-space:nowrap}.btn:focus{outline:2px solid transparent;outline-offset:2px}.btn.btn-mono,.btn.btn-tiny{--tw-shadow:0 4px 6px -1px rgba(0,0,0,0.1),0 2px 4px -1px rgba(0,0,0,0.06);box-shadow:0 0 transparent,0 0 transparent,var(--tw-shadow);box-shadow:var(--tw-ring-offset-shadow,0 0 transparent),var(--tw-ring-shadow,0 0 transparent),var(--tw-shadow);font-style:normal}.btn.btn-tiny{border-width:1px;font-size:.75rem;line-height:1rem;padding:0 .375rem}.btn.btn-mono,.btn.btn-tiny{font-family:"IBM Plex Serif",ui-serif,Georgia,Cambria,Times New Roman,Times,serif}.btn.btn-mono{line-height:1;padding:.5rem}.btn.btn-disabled{cursor:auto}.btn.btn-active:not(.btn-disabled),.btn:hover:not(.btn-disabled){background-color:var(--typo-dim);border-color:var(--typo-dim);color:var(--accent)}.btn.btn-outline{background-color:initial;color:var(--accent)}.btn.btn-outline.btn-active:not(.btn-disabled),.btn.btn-outline:hover:not(.btn-disabled){background-color:var(--accent);border-color:var(--accent);color:var(--typo-dim)}.btn.btn-alt{background-color:var(--typo-dim);border-color:var(--typo-dim);color:var(--accent)}.btn.btn-alt.btn-active:not(.btn-disabled),.btn.btn-alt:hover:not(.btn-disabled){background-color:var(--accent);border-color:var(--accent);color:var(--typo-dim)}.btn.btn-alt.btn-outline{background-color:initial;color:var(--typo-dim)}.btn.btn-alt.btn-outline.btn-active:not(.btn-disabled),.btn.btn-alt.btn-outline:hover:not(.btn-disabled){background-color:var(--typo-dim);border-color:var(--typo-dim);color:var(--accent)}.btn.btn-primary{background-color:var(--primary);border-color:var(--primary);color:var(--accent)}.btn.btn-primary.btn-active:not(.btn-disabled),.btn.btn-primary:hover:not(.btn-disabled){background-color:var(--typo-dim);border-color:var(--typo-dim);color:var(--accent)}.btn.btn-primary.btn-outline{background-color:initial;color:var(--primary)}.btn.btn-primary.btn-outline.btn-active:not(.btn-disabled),.btn.btn-primary.btn-outline:hover:not(.btn-disabled){background-color:var(--primary);border-color:var(--primary);color:var(--accent)}.btn-group>.btn:not(:last-child){margin-right:1rem}.btn-group>.btn:not(:last-child).btn-tiny{margin-right:.5rem}.btn-group.btn-group-glue>.btn:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:0}.btn-group.btn-group-glue>.btn:not(:last-child).btn-outline{border-right-width:0}.btn-group.btn-group-glue>.btn:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.typewriter .typewriter-cursor{-webkit-animation:blink .8s infinite;animation:blink .8s infinite}@-webkit-keyframes blink{0%{opacity:1}to{opacity:0}}@keyframes blink{0%{opacity:1}to{opacity:0}}.sep{background-color:var(--primary);border-width:0;width:100%}.sep.sep-gradient{background:linear-gradient(90deg,var(--primary) 0,transparent 85%)}.sep{height:1px}.sep.sep-2{height:2px}.typography{font-size:1.125rem;line-height:1.75rem}.typography>:first-child{margin-top:0}.typography>:last-child{margin-bottom:0}.typography p{margin-bottom:1.3em;margin-top:1.3em}.typography a{color:var(--primary);font-weight:500}.typography a:hover{text-decoration:underline}.typography strong{color:var(--typo-dim);font-weight:600}.typography blockquote{border-left-color:var(--primary);border-left-width:.25rem;color:var(--primary);font-style:italic;font-weight:500;margin-bottom:1.6em;margin-top:1.6em;padding-left:1em;quotes:"\201C" "\201D" "\2018" "\2019"}.typography blockquote p:first-of-type:before{content:open-quote}.typography blockquote p:last-of-type:after{content:close-quote}.typography h1{font-size:2.5em;line-height:1}.typography h1,.typography h2{color:var(--typo);font-style:italic;margin-bottom:1em}.typography h2{font-size:1.6em;line-height:1.3;margin-top:2em}.typography h3{color:var(--primary);font-size:1.3em;line-height:1.6;margin-bottom:.6em;margin-top:1.6em}.typography h4{color:var(--primary);font-size:1.15em;line-height:1.5;margin-bottom:.4em;margin-top:1.7em}.typography ul>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.25rem*var(--tw-space-y-reverse));margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))}.typography ul{list-style-type:"❖";padding-left:1.5rem}.typography ul>li{padding-left:.5rem}.typography img{margin-bottom:1.8em;margin-top:1.8em}.static{position:static}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.top-0{top:0}.right-0{right:0}.bottom-0{bottom:0}.-bottom-4{bottom:-1rem}.right-4{right:1rem}.-top-4{top:-1rem}.left-4{left:1rem}.z-20{z-index:20}.float-right{float:right}.my-4{margin-bottom:1rem;margin-top:1rem}.mx-auto{margin-left:auto;margin-right:auto}.mb-6{margin-bottom:1.5rem}.mb-12{margin-bottom:3rem}.mt-4{margin-top:1rem}.mb-10{margin-bottom:2.5rem}.mt-8{margin-top:2rem}.mb-4{margin-bottom:1rem}.mt-12{margin-top:3rem}.mr-1{margin-right:.25rem}.mr-4{margin-right:1rem}.ml-2{margin-left:.5rem}.mt-3{margin-top:.75rem}.mt-2{margin-top:.5rem}.mr-2{margin-right:.5rem}.-mb-8{margin-bottom:-2rem}.mb-8{margin-bottom:2rem}.ml-3{margin-left:.75rem}.mt-10{margin-top:2.5rem}.-mr-8{margin-right:-2rem}.-mr-6{margin-right:-1.5rem}.mr-6{margin-right:1.5rem}.-mr-56{margin-right:-14rem}.mt-16{margin-top:4rem}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.grid{display:grid}.hidden{display:none}.h-5{height:1.25rem}.h-8{height:2rem}.h-6{height:1.5rem}.h-16{height:4rem}.h-screen{height:100vh}.h-full{height:100%}.h-1\/2{height:50%}.max-h-12{max-height:3rem}.w-5{width:1.25rem}.w-8{width:2rem}.w-6{width:1.5rem}.w-16{width:4rem}.w-12{width:3rem}.w-9{width:2.25rem}.w-56{width:14rem}.w-0{width:0}.w-14{width:3.5rem}.max-w-3xl{max-width:48rem}.max-w-lg{max-width:32rem}.max-w-\[8\.5in\]{max-width:8.5in}.max-w-\[430px\]{max-width:430px}.flex-shrink-0{flex-shrink:0}.flex-grow{flex-grow:1}.resize{resize:both}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.gap-2{grid-gap:.5rem;gap:.5rem}.gap-8{grid-gap:2rem;gap:2rem}.gap-x-4{grid-column-gap:1rem;-moz-column-gap:1rem;column-gap:1rem}.gap-y-8{grid-row-gap:2rem;row-gap:2rem}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1rem*var(--tw-space-y-reverse));margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2rem*var(--tw-space-y-reverse));margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.25rem*var(--tw-space-y-reverse));margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.75rem*var(--tw-space-y-reverse));margin-top:calc(.75rem*(1 - var(--tw-space-y-reverse)))}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-md{border-radius:.375rem}.border-\[\.35rem\]{border-width:.35rem}.border-2{border-width:2px}.border-r-2{border-right-width:2px}.border-primary{border-color:var(--primary)}.\!border-primary{border-color:var(--primary)!important}.bg-accent{background-color:var(--accent)}.bg-typo{background-color:var(--typo)}.bg-secondary{background-color:var(--secondary)}.bg-cover{background-size:cover}.bg-center{background-position:50%}.px-10{padding-left:2.5rem;padding-right:2.5rem}.py-10{padding-bottom:2.5rem}.pt-10,.py-10{padding-top:2.5rem}.text-center{text-align:center}.text-right{text-align:right}.font-display{font-family:IBM Plex Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.font-body{font-family:"IBM Plex Serif",ui-serif,Georgia,Cambria,Times New Roman,Times,serif}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-xl{font-size:1.25rem}.text-lg,.text-xl{line-height:1.75rem}.text-lg{font-size:1.125rem}.text-base{font-size:1rem;line-height:1.5rem}.font-medium{font-weight:500}.uppercase{text-transform:uppercase}.italic{font-style:italic}.leading-normal{line-height:1.5}.leading-relaxed{line-height:1.625}.leading-6{line-height:1.5rem}.text-typo{color:var(--typo)}.text-typo-dim{color:var(--typo-dim)}.text-primary{color:var(--primary)}.opacity-90{opacity:.9}.shadow-2xl{--tw-shadow:0 25px 50px -12px rgba(0,0,0,0.25)}.shadow-2xl,.shadow-lg{box-shadow:0 0 transparent,0 0 transparent,var(--tw-shadow);box-shadow:var(--tw-ring-offset-shadow,0 0 transparent),var(--tw-ring-shadow,0 0 transparent),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,0.1),0 4px 6px -2px rgba(0,0,0,0.05)}.filter{filter:var(--tw-filter)}.transition-all{transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-box{transition-duration:.15s;transition-property:height,width,margin,padding;transition-timing-function:cubic-bezier(.4,0,.2,1)}.text-shadow{text-shadow:1px 1px 0 hsla(0,0%,100%,.25)}.dark .text-shadow{text-shadow:1px 1px 0 rgba(0,0,0,.5)}.cursor-zoom{cursor:zoom-in}.page-break{page-break-before:always}.page-break-avoid{-moz-column-break-inside:avoid;break-inside:avoid;page-break-inside:avoid}.columns-2{grid-column-gap:1rem;-moz-column-gap:1rem;column-gap:1rem;-moz-columns:2;column-count:2}.columns-2>*{display:inline-block}.list-style-diamond{list-style-type:"❖";padding-left:.65rem}.list-style-diamond>li{padding-left:.25rem}.ct-default{--primary:#b28e59;--secondary:#234e52;--accent:#222;--typo:#f7f3e3;--typo-dim:#9a937c}.ct-breeze{--primary:#ba6a6a;--secondary:#233e52;--accent:#222;--typo:#f7f3e3;--typo-dim:#7c8d9a}.ct-eclipse{--primary:#f98376;--secondary:#fff;--accent:#f7f6f3;--typo:#3d3d3d;--typo-dim:#928763}.ct-moonlight{--primary:#75a1fa;--secondary:#fff;--accent:#f3f5f7;--typo:#3d3d3d;--typo-dim:#73819d}.ct-trajan{--primary:#667a8d;--secondary:#f8f1e9;--accent:#e8e4e0;--typo:#342d26;--typo-dim:#969089}html[data-layout=print]{--primary:#bd3147;--secondary:#fff;--accent:#e7ebee;--typo:#304145;--typo-dim:#4f6b72}html[data-layout=print] .text-shadow{text-shadow:none}.et-xl .rounded-full{border-radius:1rem}.et-md .rounded-full{border-radius:.375rem}.et-md .rounded-md,.et-sm .rounded-full{border-radius:.125rem}.et-sm .rounded-md{border-radius:0}.after\:px-1:after{content:"";padding-left:.25rem;padding-right:.25rem}.after\:content-\[\"\|\"\]:after{content:"|"}.last\:after\:content-\[\"\"\]:last-child:after{content:""}.hover\:text-primary:hover{color:var(--primary)}.hover\:text-typo:hover{color:var(--typo)}@media print{.print\:hidden{display:none}.print\:shadow-none{--tw-shadow:0 0 transparent;box-shadow:0 0 transparent,0 0 transparent,var(--tw-shadow);box-shadow:var(--tw-ring-offset-shadow,0 0 transparent),var(--tw-ring-shadow,0 0 transparent),var(--tw-shadow)}}@media (min-width:410px){.xs\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.xs\:gap-x-1{grid-column-gap:.25rem;-moz-column-gap:.25rem;column-gap:.25rem}}@media (min-width:640px){.sm\:mb-6{margin-bottom:1.5rem}}@media (min-width:768px){.md\:mb-14{margin-bottom:3.5rem}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:gap-x-4{grid-column-gap:1rem;-moz-column-gap:1rem;column-gap:1rem}.md\:py-14{padding-bottom:3.5rem;padding-top:3.5rem}}@media (min-width:1024px){.lg\:mb-20{margin-bottom:5rem}.lg\:-mr-16{margin-right:-4rem}.lg\:inline{display:inline}.lg\:h-32{height:8rem}.lg\:w-32{width:8rem}.lg\:w-\[4\.375rem\]{width:4.375rem}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:border-r-4{border-right-width:4px}.lg\:px-14{padding-left:3.5rem;padding-right:3.5rem}.lg\:py-20{padding-bottom:5rem;padding-top:5rem}}@media (min-width:1280px){.xl\:-mr-0{margin-right:0}.xl\:hidden{display:none}.xl\:w-56{width:14rem}.xl\:w-auto{width:auto}.xl\:max-w-3xl{max-width:48rem}.xl\:max-w-4xl{max-width:56rem}.xl\:columns-2{grid-column-gap:1rem;-moz-column-gap:1rem;column-gap:1rem;-moz-columns:2;column-count:2}.xl\:columns-2>*{display:inline-block}}@media (min-width:1536px){.\32xl\:mt-24{margin-top:6rem}}@media (min-width:1680px){.\33xl\:w-64{width:16rem}.\33xl\:px-16{padding-left:4rem;padding-right:4rem}}@media (min-width:1920px){.\34xl\:px-20{padding-left:5rem;padding-right:5rem}}
<Project id="ge-cheese-app" />
Project Name Glen Echo Cheese App
About the client Glen Echo Fine Foods Inc. distributes a large selection of fine food products with an emphasis on cheese and related products for both
retail and food service. They carry over 400 different cheeses in stock and can deliver even more.
Project Description Responsive web app, custom-built to run on iPad and iPod Touch devices displayed in supermarkets throughout Canada and set up as interactive kiosks. Users are able to interact with the
app in order to learn more about featured cheeses and sign up for the Glen Echo newsletter for future updates.
I was the lead developer of the project, working alongside two other team members. My main responsibilities were:
Turning the designs mockups and UX flows provided by our designer into a fully functional/responsive web app based on Symfony framework. Building a simple recommendation engine that uses user input to present a list of the most recommended types of cheese, it is also used to display a list of related products on every cheese page. Development of an admin dashboard that allows managing the cheese database and other app configurations. Implementation of CI/CD pipelines.