diff --git a/cli-windows/build-images.ps1 b/cli-windows/build-images.ps1 new file mode 100644 index 000000000..d454f3a14 --- /dev/null +++ b/cli-windows/build-images.ps1 @@ -0,0 +1,11 @@ +Param([string] $imageTag) + +$scriptPath = Split-Path $script:MyInvocation.MyCommand.Path + +if ([string]::IsNullOrEmpty($imageTag)) { + $imageTag = $(git rev-parse --abbrev-ref HEAD) +} + +Write-Host "Building images with tag $imageTag" -ForegroundColor Yellow +$env:TAG=$imageTag +docker-compose -f "$scriptPath\..\docker-compose.yml" build \ No newline at end of file diff --git a/docker-compose-windows.yml b/docker-compose-windows.yml index f281d855a..5a7e3ff16 100644 --- a/docker-compose-windows.yml +++ b/docker-compose-windows.yml @@ -2,7 +2,7 @@ version: '2.1' services: basket.api: - image: eshop/basket.api-win + image: eshop/basket.api-win:${TAG:-latest} build: context: ./src/Services/Basket/Basket.API dockerfile: Dockerfile.nanowin @@ -11,7 +11,7 @@ services: - identity.api catalog.api: - image: eshop/catalog.api-win + image: eshop/catalog.api-win:${TAG:-latest} build: context: ./src/Services/Catalog/Catalog.API dockerfile: Dockerfile.nanowin @@ -19,7 +19,7 @@ services: - sql.data identity.api: - image: eshop/identity.api-win + image: eshop/identity.api-win:${TAG:-latest} build: context: ./src/Services/Identity/Identity.API dockerfile: Dockerfile.nanowin @@ -27,7 +27,7 @@ services: - sql.data ordering.api: - image: eshop/ordering.api-win + image: eshop/ordering.api-win:${TAG:-latest} build: context: ./src/Services/Ordering/Ordering.API dockerfile: Dockerfile.nanowin @@ -35,7 +35,7 @@ services: - sql.data webspa: - image: eshop/webspa-win + image: eshop/webspa-win:${TAG:-latest} build: context: ./src/Web/WebSPA dockerfile: Dockerfile.nanowin @@ -44,7 +44,7 @@ services: - basket.api webmvc: - image: eshop/webmvc-win + image: eshop/webmvc-win:${TAG:-latest} build: context: ./src/Web/WebMVC dockerfile: Dockerfile.nanowin @@ -55,7 +55,7 @@ services: - basket.api locations.api: - image: locations.api + image: eshop/locations.api:${TAG:-latest} build: context: ./src/Services/Location/Locations.API dockerfile: Dockerfile @@ -64,7 +64,7 @@ services: - rabbitmq marketing.api: - image: eshop/marketing.api + image: eshop/marketing.api:${TAG:-latest} build: context: ./src/Services/Marketing/Marketing.API dockerfile: Dockerfile diff --git a/docker-compose.yml b/docker-compose.yml index 4b9a52cdb..898bb1f61 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,9 +1,8 @@ -version: '2' - +version: '3' services: graceperiodmanager: - image: eshop/graceperiodmanager + image: eshop/graceperiodmanager:${TAG:-latest} build: context: ./src/Services/GracePeriod/GracePeriodManager dockerfile: Dockerfile @@ -12,7 +11,7 @@ services: - rabbitmq basket.api: - image: eshop/basket.api + image: eshop/basket.api:${TAG:-latest} build: context: ./src/Services/Basket/Basket.API dockerfile: Dockerfile @@ -21,7 +20,7 @@ services: - identity.api catalog.api: - image: eshop/catalog.api + image: eshop/catalog.api:${TAG:-latest} build: context: ./src/Services/Catalog/Catalog.API dockerfile: Dockerfile @@ -30,7 +29,7 @@ services: - rabbitmq identity.api: - image: eshop/identity.api + image: eshop/identity.api:${TAG:-latest} build: context: ./src/Services/Identity/Identity.API dockerfile: Dockerfile @@ -38,7 +37,7 @@ services: - sql.data ordering.api: - image: eshop/ordering.api + image: eshop/ordering.api:${TAG:-latest} build: context: ./src/Services/Ordering/Ordering.API dockerfile: Dockerfile @@ -47,7 +46,7 @@ services: - rabbitmq marketing.api: - image: eshop/marketing.api + image: eshop/marketing.api:${TAG:-latest} build: context: ./src/Services/Marketing/Marketing.API dockerfile: Dockerfile @@ -58,7 +57,7 @@ services: - rabbitmq webspa: - image: eshop/webspa + image: eshop/webspa:${TAG:-latest} build: context: ./src/Web/WebSPA dockerfile: Dockerfile @@ -67,7 +66,7 @@ services: - basket.api webmvc: - image: eshop/webmvc + image: eshop/webmvc:${TAG:-latest} build: context: ./src/Web/WebMVC dockerfile: Dockerfile @@ -94,13 +93,13 @@ services: - "5672:5672" webstatus: - image: eshop/webstatus + image: eshop/webstatus:${TAG:-latest} build: context: ./src/Web/WebStatus dockerfile: Dockerfile payment.api: - image: eshop/payment.api + image: eshop/payment.api:${TAG:-latest} build: context: ./src/Services/Payment/Payment.API dockerfile: Dockerfile @@ -108,7 +107,7 @@ services: - rabbitmq locations.api: - image: eshop/locations.api + image: eshop/locations.api:${TAG:-latest} build: context: ./src/Services/Location/Locations.API dockerfile: Dockerfile diff --git a/k8s/deploy.ps1 b/k8s/deploy.ps1 index cf5df8d18..24f6ec3e1 100644 --- a/k8s/deploy.ps1 +++ b/k8s/deploy.ps1 @@ -7,10 +7,17 @@ Param( [parameter(Mandatory=$false)][string]$execPath, [parameter(Mandatory=$false)][string]$kubeconfigPath, [parameter(Mandatory=$true)][string]$configFile, + [parameter(Mandatory=$false)][string]$imageTag, [parameter(Mandatory=$false)][bool]$deployInfrastructure=$true ) $debugMode = $PSCmdlet.MyInvocation.BoundParameters["Debug"].IsPresent +if ([string]::IsNullOrEmpty($imageTag)) { + $imageTag = $(git rev-parse --abbrev-ref HEAD) +} + +Write-Host "Docker image Tag: $imageTag" -ForegroundColor Yellow + function ExecKube($cmd) { if($deployCI) { $kubeconfig = $kubeconfigPath + 'config'; @@ -27,10 +34,10 @@ function ExecKube($cmd) { $config = Get-Content -Raw -Path $configFile | ConvertFrom-Json if ($debugMode) { -Write-Host "Using following JSON config: " +Write-Host "Using following JSON config: " -ForegroundColor Yellow $json = ConvertTo-Json $config -Depth 5 -Write-Host $json -Write-Host "Press a key " +Write-Host $json +Write-Host "Press a key " -ForegroundColor Yellow [System.Console]::Read() } @@ -90,14 +97,15 @@ if(-not $deployCI) { dotnet restore ../eShopOnContainers-ServicesAndWebApps.sln dotnet publish -c Release -o obj/Docker/publish ../eShopOnContainers-ServicesAndWebApps.sln - Write-Host "Building Docker images..." -ForegroundColor Yellow + Write-Host "Building Docker images." -ForegroundColor Yellow + $env:TAG=$imageTag docker-compose -p .. -f ../docker-compose.yml build Write-Host "Pushing images to $registry..." -ForegroundColor Yellow - $services = ("basket.api", "catalog.api", "identity.api", "ordering.api", "webmvc", "webspa", "webstatus") + $services = ("basket.api", "catalog.api", "identity.api", "ordering.api", "marketing.api","payment.api","locations.api", "webmvc", "webspa", "webstatus") foreach ($service in $services) { - docker tag eshop/$service $registry/eshop/$service - docker push $registry/eshop/$service + docker tag eshop/${service}:$imageTag $registry/eshop/${service}:$imageTag + docker push $registry/eshop/${service}:$imageTag } } @@ -142,7 +150,7 @@ ExecKube -cmd 'create configmap externalcfg ` --from-literal=MarketingSqlDb=$($config.sql.marketing) ` --from-literal=LocationsNoSqlDb=$($config.nosql.locations.constr) ` --from-literal=LocationsNoSqlDbName=$($config.nosql.locations.db) ` - --from-literal=MarketingsNoSqlDb=$($config.nosql.marketing.constr) ` + --from-literal=MarketingNoSqlDb=$($config.nosql.marketing.constr) ` --from-literal=MarketingNoSqlDbName=$($config.nosql.marketing.db) ` --from-literal=BasketRedisConStr=$($config.redis.basket) ` --from-literal=LocationsBus=$($config.servicebus.locations) ` @@ -150,7 +158,9 @@ ExecKube -cmd 'create configmap externalcfg ` --from-literal=BasketBus=$($config.servicebus.basket) ` --from-literal=OrderingBus=$($config.servicebus.ordering) ` --from-literal=CatalogBus=$($config.servicebus.catalog) ` - --from-literal=PaymentBus=$($config.servicebus.payment) ' + --from-literal=PaymentBus=$($config.servicebus.payment) ` + --from-literal=UseAzureServiceBus=$($config.servicebus.use_azure) ` + --from-literal=keystore=$($config.redis.keystore) ' ExecKube -cmd 'label configmap externalcfg app=eshop' @@ -164,13 +174,16 @@ if(-not $deployCI) { # update deployments with the private registry before k8s tries to pull images # (deployment templating, or Helm, would obviate this) Write-Host "Update Image containers..." -ForegroundColor Yellow - ExecKube -cmd 'set image deployments/basket basket=$registry/eshop/basket.api' - ExecKube -cmd 'set image deployments/catalog catalog=$registry/eshop/catalog.api' - ExecKube -cmd 'set image deployments/identity identity=$registry/eshop/identity.api' - ExecKube -cmd 'set image deployments/ordering ordering=$registry/eshop/ordering.api' - ExecKube -cmd 'set image deployments/webmvc webmvc=$registry/eshop/webmvc' - ExecKube -cmd 'set image deployments/webstatus webstatus=$registry/eshop/webstatus' - ExecKube -cmd 'set image deployments/webspa webspa=$registry/eshop/webspa' + ExecKube -cmd 'set image deployments/basket basket=$registry/eshop/basket.api:$imageTag' + ExecKube -cmd 'set image deployments/catalog catalog=$registry/eshop/catalog.api:$imageTag' + ExecKube -cmd 'set image deployments/identity identity=$registry/eshop/identity.api:$imageTag' + ExecKube -cmd 'set image deployments/ordering ordering=$registry/eshop/ordering.api:$imageTag' + ExecKube -cmd 'set image deployments/marketing marketing=$registry/eshop/marketing.api:$imageTag' + ExecKube -cmd 'set image deployments/locations locations=$registry/eshop/locations.api:$imageTag' + ExecKube -cmd 'set image deployments/payment payment=$registry/eshop/payment.api:$imageTag' + ExecKube -cmd 'set image deployments/webmvc webmvc=$registry/eshop/webmvc:$imageTag' + ExecKube -cmd 'set image deployments/webstatus webstatus=$registry/eshop/webstatus:$imageTag' + ExecKube -cmd 'set image deployments/webspa webspa=$registry/eshop/webspa:$imageTag' } Write-Host "Execute rollout..." -ForegroundColor Yellow @@ -178,6 +191,9 @@ ExecKube -cmd 'rollout resume deployments/basket' ExecKube -cmd 'rollout resume deployments/catalog' ExecKube -cmd 'rollout resume deployments/identity' ExecKube -cmd 'rollout resume deployments/ordering' +ExecKube -cmd 'rollout resume deployments/marketing' +ExecKube -cmd 'rollout resume deployments/locations' +ExecKube -cmd 'rollout resume deployments/payment' ExecKube -cmd 'rollout resume deployments/webmvc' ExecKube -cmd 'rollout resume deployments/webstatus' ExecKube -cmd 'rollout resume deployments/webspa' diff --git a/k8s/deployments.yaml b/k8s/deployments.yaml index 20d0a3971..0a42f573d 100644 --- a/k8s/deployments.yaml +++ b/k8s/deployments.yaml @@ -28,7 +28,10 @@ spec: name: externalcfg key: BasketBus - name: AzureServiceBusEnabled - value: "true" + valueFrom: + configMapKeyRef: + name: externalcfg + key: UseAzureServiceBus - name: IdentityUrl valueFrom: configMapKeyRef: @@ -103,7 +106,10 @@ spec: name: externalcfg key: IdentitySqlDb - name: DPConnectionString - value: keystore-data + valueFrom: + configMapKeyRef: + name: externalcfg + key: keystore - name: IsClusterEnv value: 'True' - name: MvcClient @@ -151,7 +157,10 @@ spec: name: externalcfg key: OrderingBus - name: AzureServiceBusEnabled - value: "true" + valueFrom: + configMapKeyRef: + name: externalcfg + key: UseAzureServiceBus - name: IdentityUrl valueFrom: configMapKeyRef: @@ -192,7 +201,10 @@ spec: name: externalcfg key: LocationsNoSqlDbName - name: AzureServiceBusEnabled - value: "true" + valueFrom: + configMapKeyRef: + name: externalcfg + key: UseAzureServiceBus - name: EventBusConnection valueFrom: configMapKeyRef: @@ -243,7 +255,10 @@ spec: name: externalcfg key: MarketingNoSqlDbName - name: AzureServiceBusEnabled - value: "true" + valueFrom: + configMapKeyRef: + name: externalcfg + key: UseAzureServiceBus - name: EventBusConnection valueFrom: configMapKeyRef: @@ -279,7 +294,10 @@ spec: - name: ASPNETCORE_URLS value: http://0.0.0.0:80/payment-api - name: AzureServiceBusEnabled - value: ·true" + valueFrom: + configMapKeyRef: + name: externalcfg + key: UseAzureServiceBus - name: EventBusConnection valueFrom: configMapKeyRef: @@ -310,7 +328,10 @@ spec: - name: ASPNETCORE_URLS value: http://0.0.0.0:80/webmvc - name: DPConnectionString - value: keystore-data + valueFrom: + configMapKeyRef: + name: externalcfg + key: keystore - name: IsClusterEnv value: 'True' - name: BasketUrl @@ -417,7 +438,10 @@ spec: - name: ASPNETCORE_URLS value: http://0.0.0.0:80 - name: DPConnectionString - value: keystore-data + valueFrom: + configMapKeyRef: + name: externalcfg + key: keystore - name: IsClusterEnv value: 'True' - name: BasketUrl diff --git a/k8s/local.json b/k8s/local.json index 4a4638463..9f3fef102 100644 --- a/k8s/local.json +++ b/k8s/local.json @@ -3,22 +3,24 @@ "catalog": "Server=sql-data;Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word;", "identity":"Server=sql-data;Initial Catalog=Microsoft.eShopOnContainers.Services.IdentityDb;User Id=sa;Password=Pass@word;", "ordering":"Server=sql-data;Initial Catalog=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;", - "marketing":"Server=sql.data;Initial Catalog=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word;" + "marketing":"Server=sql-data;Initial Catalog=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word;" }, "nosql": { "locations": { - "constr": "mongodb://nosql.data", + "constr": "mongodb://nosql-data", "db": "LocationsDb" }, "marketing": { - "constr": "mongodb://nosql.data", + "constr": "mongodb://nosql-data", "db": "MarketingDb" } }, "redis": { - "basket" : "basket.data" + "basket" : "basket-data", + "keystore": "keystore-data" }, "servicebus": { + "use_azure": false, "ordering": "rabbitmq", "marketing": "rabbitmq", "locations": "rabbitmq", diff --git a/k8s/nosql-data.yaml b/k8s/nosql-data.yaml index 84e60993b..5dfb67c6e 100644 --- a/k8s/nosql-data.yaml +++ b/k8s/nosql-data.yaml @@ -24,7 +24,7 @@ spec: component: nosql-data spec: containers: - - name: nosql.data + - name: nosql-data image: mongo ports: - containerPort: 27017 diff --git a/src/Web/WebMVC/wwwroot/css/site.min.css b/src/Web/WebMVC/wwwroot/css/site.min.css index 4d03fa783..a928a84ae 100644 --- a/src/Web/WebMVC/wwwroot/css/site.min.css +++ b/src/Web/WebMVC/wwwroot/css/site.min.css @@ -1 +1 @@ -.esh-app-footer{background-color:#000;border-top:1px solid #eee;margin-top:2.5rem;padding-bottom:2.5rem;padding-top:2.5rem;width:100%}.esh-app-footer-brand{height:50px;width:230px}.esh-app-footer-text{color:#83d01b;line-height:50px;text-align:right;width:100%}@font-face{font-family:Montserrat;font-weight:400;src:url("../fonts/Montserrat-Regular.eot?") format("eot"),url("../fonts/Montserrat-Regular.woff") format("woff"),url("../fonts/Montserrat-Regular.ttf") format("truetype"),url("../fonts/Montserrat-Regular.svg#Montserrat") format("svg")}@font-face{font-family:Montserrat;font-weight:700;src:url("../fonts/Montserrat-Bold.eot?") format("eot"),url("../fonts/Montserrat-Bold.woff") format("woff"),url("../fonts/Montserrat-Bold.ttf") format("truetype"),url("../fonts/Montserrat-Bold.svg#Montserrat") format("svg")}html,body{font-family:Montserrat,sans-serif;font-size:16px;font-weight:400;z-index:10}*,*::after,*::before{box-sizing:border-box}.preloading{color:#00a69c;display:block;font-size:1.5rem;left:50%;position:fixed;top:50%;transform:translate(-50%,-50%)}select::-ms-expand{display:none}@media screen and (min-width:992px){.form-input{max-width:360px;width:360px}}.form-input{border-radius:0;height:45px;padding:10px}.form-input-small{max-width:100px !important}.form-input-medium{width:150px !important}.alert{padding-left:0}.alert-danger{background-color:transparent;border:0;color:#fb0d0d;font-size:12px}a,a:active,a:hover,a:visited{color:#000;text-decoration:none;transition:color .35s}a:hover,a:active{color:#75b918;transition:color .35s}.esh-basket{min-height:80vh}.esh-basket-titles{padding-bottom:1rem;padding-top:2rem}.esh-basket-titles--clean{padding-bottom:0;padding-top:0}.esh-basket-title{text-transform:uppercase}.esh-basket-items--border{border-bottom:1px solid #eee;padding:.5rem 0}.esh-basket-items--border:last-of-type{border-color:transparent}.esh-basket-item{font-size:1rem;font-weight:300}.esh-basket-item--middle{line-height:8rem}@media screen and (max-width:1024px){.esh-basket-item--middle{line-height:1rem}}.esh-basket-item--mark{color:#00a69c}.esh-basket-image{height:8rem}.esh-basket-input{line-height:1rem;width:100%}.esh-basket-checkout{border:none;border-radius:0;background-color:#83d01b;color:#fff;display:inline-block;font-size:1rem;font-weight:400;margin-top:1rem;padding:1rem 1.5rem;text-align:center;text-transform:uppercase;transition:all .35s}.esh-basket-checkout:hover{background-color:#4a760f;transition:all .35s}.esh-basket-margin12{margin-left:12px}.esh-basketstatus{cursor:pointer;display:inline-block;float:right;position:relative;transition:all .35s}.esh-basketstatus.is-disabled{opacity:.5;pointer-events:none}.esh-basketstatus-image{height:36px;margin-top:.5rem}.esh-basketstatus-badge{background-color:#83d01b;border-radius:50%;color:#fff;display:block;height:1.5rem;left:50%;position:absolute;text-align:center;top:0;transform:translateX(-38%);transition:all .35s;width:1.5rem}.esh-basketstatus:hover .esh-basketstatus-badge{background-color:transparent;color:#75b918;transition:all .35s}.esh-catalog-hero{background-image:url("../images/main_banner.png");background-size:cover;height:260px;width:100%}.esh-catalog-title{position:relative;top:74.28571px}.esh-catalog-filters{background-color:#00a69c;height:65px}.esh-catalog-filter{background-color:transparent;border-color:#00d9cc;color:#fff;cursor:pointer;margin-right:1rem;margin-top:.5rem;outline-color:#83d01b;padding-bottom:0;padding-left:.5rem;padding-right:.5rem;padding-top:1.5rem;min-width:140px;-webkit-appearance:none}.esh-catalog-filter option{background-color:#00a69c}.esh-catalog-label{display:inline-block;position:relative;z-index:0}.esh-catalog-label::before{color:rgba(255,255,255,.5);content:attr(data-title);font-size:.65rem;margin-top:.65rem;margin-left:.5rem;position:absolute;text-transform:uppercase;z-index:1}.esh-catalog-label::after{background-image:url("../images/arrow-down.png");height:7px;content:'';position:absolute;right:1.5rem;top:2.5rem;width:10px;z-index:1}.esh-catalog-send{background-color:#83d01b;color:#fff;cursor:pointer;font-size:1rem;transform:translateY(.5rem);padding:.5rem;transition:all .35s}.esh-catalog-send:hover{background-color:#4a760f;transition:all .35s}.esh-catalog-items{margin-top:1rem}.esh-catalog-item{text-align:center;margin-bottom:1.5rem;width:33%;display:inline-block;float:none !important}@media screen and (max-width:1024px){.esh-catalog-item{width:50%}}@media screen and (max-width:768px){.esh-catalog-item{width:100%}}.esh-catalog-thumbnail{max-width:370px;width:100%}.esh-catalog-button{background-color:#83d01b;border:none;color:#fff;cursor:pointer;font-size:1rem;height:3rem;margin-top:1rem;transition:all .35s;width:80%}.esh-catalog-button.is-disabled{opacity:.5;pointer-events:none}.esh-catalog-button:hover{background-color:#4a760f;transition:all .35s}.esh-catalog-name{font-size:1rem;font-weight:300;margin-top:.5rem;text-align:center;text-transform:uppercase}.esh-catalog-price{text-align:center;font-weight:900;font-size:28px}.esh-catalog-price::before{content:'$'}.esh-orders{min-height:80vh;overflow-x:hidden}.esh-orders-header{background-color:#00a69c;height:4rem}.esh-orders-back{color:rgba(255,255,255,.4);line-height:4rem;text-transform:uppercase;text-decoration:none;transition:color .35s}.esh-orders-back:hover{color:#fff;transition:color .35s}.esh-orders-titles{padding-bottom:1rem;padding-top:2rem}.esh-orders-title{text-transform:uppercase}.esh-orders-items{height:2rem;line-height:2rem;position:relative}.esh-orders-items:nth-of-type(2n+1):before{background-color:#eef;content:'';height:100%;left:0;margin-left:-100vw;position:absolute;top:0;width:200vw;z-index:-1}.esh-orders-item{font-weight:300}.esh-orders-item--hover{opacity:0;pointer-events:none}.esh-orders-items:hover .esh-orders-item--hover{opacity:1;pointer-events:all}.esh-orders-link{color:#83d01b;text-decoration:none;transition:color .35s}.esh-orders-link:hover{color:#75b918;transition:color .35s}.esh-orders_detail{min-height:80vh}.esh-orders_detail-section{padding:1rem 0}.esh-orders_detail-section--right{text-align:right}.esh-orders_detail-titles{padding-bottom:1rem;padding-top:2rem}.esh-orders_detail-title{text-transform:uppercase}.esh-orders_detail-items--border{border-bottom:1px solid #eee;padding:.5rem 0}.esh-orders_detail-items--border:last-of-type{border-color:transparent}.esh-orders_detail-item{font-size:1rem;font-weight:300}.esh-orders_detail-item--middle{line-height:8rem}@media screen and (max-width:768px){.esh-orders_detail-item--middle{line-height:1rem}}.esh-orders_detail-item--mark{color:#83d01b}.esh-orders_detail-image{height:8rem}.esh-orders_new{min-height:80vh}.esh-orders_new-header{background-color:#00a69c;height:4rem}.esh-orders_new-back{color:rgba(255,255,255,.4);line-height:4rem;text-decoration:none;text-transform:uppercase;transition:color .35s}.esh-orders_new-back:hover{color:#fff;transition:color .35s}.esh-orders_new-section{padding:1rem 0}.esh-orders_new-section--right{text-align:right}.esh-orders_new-placeOrder{background-color:#83d01b;border:0;border-radius:0;color:#fff;display:inline-block;font-size:1rem;font-weight:400;margin-top:1rem;padding:1rem 1.5rem;text-align:center;text-transform:uppercase;transition:all .35s}.esh-orders_new-placeOrder:hover{background-color:#4a760f;transition:all .35s}.esh-orders_new-titles{padding-bottom:1rem;padding-top:2rem}.esh-orders_new-title{font-size:1.25rem;text-transform:uppercase}.esh-orders_new-items--border{border-bottom:1px solid #eee;padding:.5rem 0}.esh-orders_new-items--border:last-of-type{border-color:transparent}.esh-orders_new-item{font-size:1rem;font-weight:300}.esh-orders_new-item--middle{line-height:8rem}@media screen and (max-width:768px){.esh-orders_new-item--middle{line-height:1rem}}.esh-orders_new-item--mark{color:#83d01b}.esh-orders_new-image{height:8rem}.esh-header{background-color:#00a69c;height:4rem}.esh-header-back{color:rgba(255,255,255,.5) !important;line-height:4rem;text-transform:uppercase;text-decoration:none;transition:color .35s}.esh-header-back:hover{color:#fff !important;transition:color .35s}.esh-identity{line-height:3rem;position:relative;text-align:right}.esh-identity-section{display:inline-block;width:100%}.esh-identity-name{display:inline-block}.esh-identity-name--upper{text-transform:uppercase}@media screen and (max-width:768px){.esh-identity-name{font-size:.85rem}}.esh-identity-image{display:inline-block}.esh-identity-drop{background:#fff;height:0;min-width:14rem;right:0;overflow:hidden;padding:.5rem;position:absolute;top:2.5rem;transition:height .35s}.esh-identity:hover .esh-identity-drop{border:1px solid #eee;height:7rem;transition:height .35s}.esh-identity-item{cursor:pointer;display:block;transition:color .35s}.esh-identity-item:hover{color:#75b918;transition:color .35s}.esh-pager-wrapper{padding-top:1rem;text-align:center}.esh-pager-item{margin:0 5vw}.esh-pager-item--navigable{display:inline-block;cursor:pointer}.esh-pager-item--navigable.is-disabled{opacity:0;pointer-events:none}.esh-pager-item--navigable:hover{color:#83d01b}@media screen and (max-width:1280px){.esh-pager-item{font-size:.85rem}}@media screen and (max-width:1024px){.esh-pager-item{margin:0 4vw}} \ No newline at end of file +.esh-app-footer{background-color:#000;border-top:1px solid #eee;margin-top:2.5rem;padding-bottom:2.5rem;padding-top:2.5rem;width:100%}.esh-app-footer-brand{height:50px;width:230px}.esh-app-footer-text{color:#83d01b;line-height:50px;text-align:right;width:100%}@font-face{font-family:Montserrat;font-weight:400;src:url("../fonts/Montserrat-Regular.eot?") format("eot"),url("../fonts/Montserrat-Regular.woff") format("woff"),url("../fonts/Montserrat-Regular.ttf") format("truetype"),url("../fonts/Montserrat-Regular.svg#Montserrat") format("svg")}@font-face{font-family:Montserrat;font-weight:700;src:url("../fonts/Montserrat-Bold.eot?") format("eot"),url("../fonts/Montserrat-Bold.woff") format("woff"),url("../fonts/Montserrat-Bold.ttf") format("truetype"),url("../fonts/Montserrat-Bold.svg#Montserrat") format("svg")}html,body{font-family:Montserrat,sans-serif;font-size:16px;font-weight:400;z-index:10}*,*::after,*::before{box-sizing:border-box}.preloading{color:#00a69c;display:block;font-size:1.5rem;left:50%;position:fixed;top:50%;transform:translate(-50%,-50%)}select::-ms-expand{display:none}@media screen and (min-width:992px){.form-input{max-width:360px;width:360px}}.form-input{border-radius:0;height:45px;padding:10px}.form-input-small{max-width:100px !important}.form-input-medium{width:150px !important}.alert{padding-left:0}.alert-danger{background-color:transparent;border:0;color:#fb0d0d;font-size:12px}a,a:active,a:hover,a:visited{color:#000;text-decoration:none;transition:color .35s}a:hover,a:active{color:#75b918;transition:color .35s}.esh-basket{min-height:80vh}.esh-basket-titles{padding-bottom:1rem;padding-top:2rem}.esh-basket-titles--clean{padding-bottom:0;padding-top:0}.esh-basket-title{text-transform:uppercase}.esh-basket-items--border{border-bottom:1px solid #eee;padding:.5rem 0}.esh-basket-items--border:last-of-type{border-color:transparent}.esh-basket-item{font-size:1rem;font-weight:300}.esh-basket-item--middle{line-height:8rem}@media screen and (max-width:1024px){.esh-basket-item--middle{line-height:1rem}}.esh-basket-item--mark{color:#00a69c}.esh-basket-image{height:8rem}.esh-basket-input{line-height:1rem;width:100%}.esh-basket-checkout{border:none;border-radius:0;background-color:#83d01b;color:#fff;display:inline-block;font-size:1rem;font-weight:400;margin-top:1rem;padding:1rem 1.5rem;text-align:center;text-transform:uppercase;transition:all .35s}.esh-basket-checkout:hover{background-color:#4a760f;transition:all .35s}.esh-basket-margin12{margin-left:12px}.esh-basketstatus{cursor:pointer;display:inline-block;float:right;position:relative;transition:all .35s}.esh-basketstatus.is-disabled{opacity:.5;pointer-events:none}.esh-basketstatus-image{height:36px;margin-top:.5rem}.esh-basketstatus-badge{background-color:#83d01b;border-radius:50%;color:#fff;display:block;height:1.5rem;left:50%;position:absolute;text-align:center;top:0;transform:translateX(-38%);transition:all .35s;width:1.5rem}.esh-basketstatus:hover .esh-basketstatus-badge{background-color:transparent;color:#75b918;transition:all .35s}.esh-catalog-hero{background-image:url("../images/main_banner.png");background-size:cover;height:260px;width:100%}.esh-catalog-title{position:relative;top:74.28571px}.esh-catalog-filters{background-color:#00a69c;height:65px}.esh-catalog-filter{background-color:transparent;border-color:#00d9cc;color:#fff;cursor:pointer;margin-right:1rem;margin-top:.5rem;outline-color:#83d01b;padding-bottom:0;padding-left:.5rem;padding-right:.5rem;padding-top:1.5rem;min-width:140px;-webkit-appearance:none}.esh-catalog-filter option{background-color:#00a69c}.esh-catalog-label{display:inline-block;position:relative;z-index:0}.esh-catalog-label::before{color:rgba(255,255,255,.5);content:attr(data-title);font-size:.65rem;margin-top:.65rem;margin-left:.5rem;position:absolute;text-transform:uppercase;z-index:1}.esh-catalog-label::after{background-image:url("../images/arrow-down.png");height:7px;content:'';position:absolute;right:1.5rem;top:2.5rem;width:10px;z-index:1}.esh-catalog-send{background-color:#83d01b;color:#fff;cursor:pointer;font-size:1rem;transform:translateY(.5rem);padding:.5rem;transition:all .35s}.esh-catalog-send:hover{background-color:#4a760f;transition:all .35s}.esh-catalog-items{margin-top:1rem}.esh-catalog-item{text-align:center;margin-bottom:1.5rem;width:33%;display:inline-block;float:none !important}@media screen and (max-width:1024px){.esh-catalog-item{width:50%}}@media screen and (max-width:768px){.esh-catalog-item{width:100%}}.esh-catalog-thumbnail{max-width:370px;width:100%}.esh-catalog-button{background-color:#83d01b;border:none;color:#fff;cursor:pointer;font-size:1rem;height:3rem;margin-top:1rem;transition:all .35s;width:80%}.esh-catalog-button.is-disabled{opacity:.5;pointer-events:none}.esh-catalog-button:hover{background-color:#4a760f;transition:all .35s}.esh-catalog-name{font-size:1rem;font-weight:300;margin-top:.5rem;text-align:center;text-transform:uppercase}.esh-catalog-price{text-align:center;font-weight:900;font-size:28px}.esh-catalog-price::before{content:'$'}.esh-orders{min-height:80vh;overflow-x:hidden}.esh-orders-header{background-color:#00a69c;height:4rem}.esh-orders-back{color:rgba(255,255,255,.4);line-height:4rem;text-transform:uppercase;text-decoration:none;transition:color .35s}.esh-orders-back:hover{color:#fff;transition:color .35s}.esh-orders-titles{padding-bottom:1rem;padding-top:2rem}.esh-orders-title{text-transform:uppercase}.esh-orders-items{height:2rem;line-height:2rem;position:relative}.esh-orders-items:nth-of-type(2n+1):before{background-color:#eef;content:'';height:100%;left:0;margin-left:-100vw;position:absolute;top:0;width:200vw;z-index:-1}.esh-orders-item{font-weight:300}.esh-orders-item--hover{opacity:0;pointer-events:none}.esh-orders-items:hover .esh-orders-item--hover{opacity:1;pointer-events:all}.esh-orders-link{color:#83d01b;text-decoration:none;transition:color .35s}.esh-orders-link:hover{color:#75b918;transition:color .35s}.esh-orders_detail{min-height:80vh}.esh-orders_detail-section{padding:1rem 0}.esh-orders_detail-section--right{text-align:right}.esh-orders_detail-titles{padding-bottom:1rem;padding-top:2rem}.esh-orders_detail-title{text-transform:uppercase}.esh-orders_detail-items--border{border-bottom:1px solid #eee;padding:.5rem 0}.esh-orders_detail-items--border:last-of-type{border-color:transparent}.esh-orders_detail-item{font-size:1rem;font-weight:300}.esh-orders_detail-item--middle{line-height:8rem}@media screen and (max-width:768px){.esh-orders_detail-item--middle{line-height:1rem}}.esh-orders_detail-item--mark{color:#83d01b}.esh-orders_detail-image{height:8rem}.esh-orders_new{min-height:80vh}.esh-orders_new-header{background-color:#00a69c;height:4rem}.esh-orders_new-back{color:rgba(255,255,255,.4);line-height:4rem;text-decoration:none;text-transform:uppercase;transition:color .35s}.esh-orders_new-back:hover{color:#fff;transition:color .35s}.esh-orders_new-section{padding:1rem 0}.esh-orders_new-section--right{text-align:right}.esh-orders_new-placeOrder{background-color:#83d01b;border:0;border-radius:0;color:#fff;display:inline-block;font-size:1rem;font-weight:400;margin-top:1rem;padding:1rem 1.5rem;text-align:center;text-transform:uppercase;transition:all .35s}.esh-orders_new-placeOrder:hover{background-color:#4a760f;transition:all .35s}.esh-orders_new-titles{padding-bottom:1rem;padding-top:2rem}.esh-orders_new-title{font-size:1.25rem;text-transform:uppercase}.esh-orders_new-items--border{border-bottom:1px solid #eee;padding:.5rem 0}.esh-orders_new-items--border:last-of-type{border-color:transparent}.esh-orders_new-item{font-size:1rem;font-weight:300}.esh-orders_new-item--middle{line-height:8rem}@media screen and (max-width:768px){.esh-orders_new-item--middle{line-height:1rem}}.esh-orders_new-item--mark{color:#83d01b}.esh-orders_new-image{height:8rem}.esh-header{background-color:#00a69c;height:4rem}.esh-header-title{color:rgba(255,255,255,.5) !important;line-height:4rem;text-transform:uppercase;text-decoration:none;transition:color .35s;margin-right:15px}.esh-header-title:hover{color:#fff !important;transition:color .35s}.esh-header-back{color:rgba(255,255,255,.5) !important;line-height:4rem;text-transform:uppercase;text-decoration:none;transition:color .35s}.esh-header-back:hover{color:#fff !important;transition:color .35s}.esh-identity{line-height:3rem;position:relative;text-align:right}.esh-identity-section{display:inline-block;width:100%}.esh-identity-name{display:inline-block}.esh-identity-name--upper{text-transform:uppercase}@media screen and (max-width:768px){.esh-identity-name{font-size:.85rem}}.esh-identity-image{display:inline-block}.esh-identity-drop{background:#fff;height:0;min-width:14rem;right:0;overflow:hidden;padding:.5rem;position:absolute;top:2.5rem;transition:height .35s}.esh-identity:hover .esh-identity-drop{border:1px solid #eee;height:7rem;transition:height .35s}.esh-identity-item{cursor:pointer;display:block;transition:color .35s}.esh-identity-item:hover{color:#75b918;transition:color .35s}.esh-pager-wrapper{padding-top:1rem;text-align:center}.esh-pager-item{margin:0 5vw}.esh-pager-item--navigable{display:inline-block;cursor:pointer}.esh-pager-item--navigable.is-disabled{opacity:0;pointer-events:none}.esh-pager-item--navigable:hover{color:#83d01b}@media screen and (max-width:1280px){.esh-pager-item{font-size:.85rem}}@media screen and (max-width:1024px){.esh-pager-item{margin:0 4vw}} \ No newline at end of file