<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>TopView</title>
	<atom:link href="https://topvieweg.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://topvieweg.com/</link>
	<description>نقدم حلول التحول الرقمي، بناء التطبيقات، وأنظمة eCommerce لتسريع نمو علامتك التجارية وبأسعار تنافسية.</description>
	<lastBuildDate>Thu, 22 Oct 2026 11:32:19 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://topvieweg.com/wp-content/uploads/2024/08/cropped-final-logo-3-1-32x32.png</url>
	<title>TopView</title>
	<link>https://topvieweg.com/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Your own app or delivery apps? What changes for a multi-branch brand</title>
		<link>https://topvieweg.com/own-app-vs-delivery-apps/</link>
		
		<dc:creator><![CDATA[Amr Bendary]]></dc:creator>
		<pubDate>Wed, 14 Oct 2026 10:00:00 +0000</pubDate>
				<category><![CDATA[Insights]]></category>
		<guid isPermaLink="false">https://topvieweg.com/own-app-vs-delivery-apps/</guid>

					<description><![CDATA[<p>Delivery apps bring orders, but they keep the customer and take a share of every sale. Here is what changes when a multi-branch brand runs its own app and online store, and how to start without losing the orders you already have.</p>
<p>The post <a href="https://topvieweg.com/own-app-vs-delivery-apps/">Your own app or delivery apps? What changes for a multi-branch brand</a> appeared first on <a href="https://topvieweg.com">TopView</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="5571" class="elementor elementor-5571" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-tvb5571c e-con-full e-flex e-con e-parent" data-id="tvb5571c" data-element_type="container" data-e-type="container">
				<div class="elementor-element elementor-element-tvb5571w elementor-widget elementor-widget-html" data-id="tvb5571w" data-element_type="widget" data-e-type="widget" data-widget_type="html.default">
				<div class="elementor-widget-container">
					<!-- TopView blog: article own-app-vs-delivery-apps. Generated by live-site/blog/build.js from articles.js; edit there and rebuild. -->
<style>
/* Shared base for the TopView platform (.tvpf) and discount-system (.tvdm) sections.
   The izeetak theme styles every <button> (70px line height, 60px side padding, uppercase, wide tracking),
   sets body line height to 2 and decorates lists, so each section resets those inside itself. */
.tvx {
  --x-ink: #1B1825;
  --x-muted: #5A6475;
  --x-line: #E3E8EF;
  --x-paper: #FFFFFF;
  --x-mist: #F4F7FB;
  --x-blue: #086AD9;
  --x-blue-ink: #0757B3;
  --x-blue-tint: #E7F0FC;
  --x-beige: #D2A88F;
  --x-beige-lite: #E7C7B2;
  --x-navy: #06142B;
  --x-navy-2: #0B2A55;
  --x-ease: cubic-bezier(.2, .8, .2, 1);
  container: tvx / inline-size;
  position: relative;
  width: 100%;
  font-family: "Barlow", "Segoe UI", system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.5;
  color: var(--x-ink);
  text-align: left;
}
.elementor-widget:has(> .elementor-widget-container > .tvx) { width: 100%; min-width: 0; }
.tvx *, .tvx *::before, .tvx *::after { box-sizing: border-box; }
/* Element-weight resets (0,0,1): they still beat the theme (same weight, later in the page) but lose to every
   class rule, even when a second section on the page repeats this file after the first section’s rules. */
:where(.tvx) :is(h2, h3, h4, p, ul, ol, li, dl, dt, dd, figure) { margin: 0; padding: 0; }
:where(.tvx) :is(ul, ol) { list-style: none; }
:where(.tvx) li::before, :where(.tvx) li::after { content: none; }
:where(.tvx) img { display: block; max-width: 100%; height: auto; }
.tvx button { min-width: 0; min-height: 0; margin: 0; padding: 0; border: 0; background: none; color: inherit; font: inherit; line-height: inherit; letter-spacing: normal; text-transform: none; cursor: pointer; }
.tvx button:hover, .tvx button:focus { background: none; color: inherit; }
.tvx :focus-visible { outline: 3px solid var(--x-blue); outline-offset: 3px; }

.tvx__inner { max-width: 1200px; margin: 0 auto; padding-inline: clamp(16px, 4cqi, 32px); padding-block: clamp(56px, 7cqi, 96px); }
.tvx__head { max-width: 720px; margin-bottom: clamp(28px, 4cqi, 48px); }
.tvx__title { font-weight: 800; font-size: clamp(30px, 2.4cqi + 14px, 46px); line-height: 1.08; letter-spacing: -.01em; color: var(--x-ink); text-wrap: balance; margin-bottom: 14px; }
.tvx__lede { font-size: clamp(16px, .5cqi + 12px, 19px); line-height: 1.65; font-weight: 500; color: var(--x-muted); text-wrap: pretty; }
.tvx__h3 { font-weight: 800; font-size: clamp(21px, .8cqi + 15px, 26px); line-height: 1.2; color: var(--x-ink); margin-bottom: 18px; text-wrap: balance; }

.tvx__icon { flex: none; width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center; background: var(--x-blue-tint); color: var(--x-blue); }
.tvx__icon svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

.tvx__chips { display: flex; flex-wrap: wrap; gap: 8px; }
.tvx__chips li { padding: 7px 13px; border: 1px solid var(--x-line); border-radius: 20px; background: var(--x-paper); font-size: 14px; font-weight: 600; line-height: 1.3; color: var(--x-ink); }

/* closing call to action */
.tvx__cta { margin-top: clamp(40px, 5cqi, 64px); border-radius: 14px; padding: clamp(28px, 4cqi, 44px); display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 24px 40px; color: #fff; background: radial-gradient(60% 120% at 85% 0%, rgba(8, 106, 217, .55), transparent 70%), linear-gradient(160deg, var(--x-navy-2), var(--x-navy)); }
.tvx__cta-text { min-width: 0; max-width: 560px; }
.tvx__cta-title { font-weight: 800; font-size: clamp(22px, 1cqi + 15px, 30px); line-height: 1.2; color: #fff; text-wrap: balance; }
.tvx__cta-body { margin-top: 8px; font-size: 16px; line-height: 1.6; color: rgba(255, 255, 255, .82); }
.tvx__cta-actions { display: flex; flex-wrap: wrap; gap: 12px; }
.tvx__btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 52px; padding: 0 22px; border-radius: 8px; font-weight: 700; font-size: 14px; line-height: 1; letter-spacing: .1em; text-transform: uppercase; text-decoration: none; white-space: nowrap; transition: background-color .2s ease, border-color .2s ease, transform .2s ease; }
.tvx__btn svg { width: 18px; height: 18px; flex: none; }
.tvx__btn--primary { background: var(--x-beige); color: var(--x-ink); }
.tvx__btn--primary:hover, .tvx__btn--primary:focus { background: var(--x-beige-lite); color: var(--x-ink); }
.tvx__btn--ghost { color: #fff; border: 1.5px solid rgba(255, 255, 255, .34); }
.tvx__btn--ghost:hover, .tvx__btn--ghost:focus { color: #fff; border-color: #fff; background: rgba(255, 255, 255, .06); }
.tvx__btn:active { transform: translateY(1px); }
.tvx__btn:focus-visible { outline-color: var(--x-beige-lite); }

/* scroll reveal: only armed by JS, so content is visible without it */
.tvx.is-armed [data-reveal] { opacity: 0; transform: translateY(16px); transition: opacity .7s var(--x-ease), transform .7s var(--x-ease); transition-delay: calc(var(--i, 0) * 70ms); }
.tvx.is-armed [data-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .tvx *, .tvx *::before, .tvx *::after { animation: none !important; transition: none !important; }
  .tvx.is-armed [data-reveal] { opacity: 1; transform: none; }
}
@container tvx (max-width: 560px) {
  .tvx__cta-actions { width: 100%; flex-direction: column; }
  .tvx__btn { width: 100%; padding: 14px 16px; letter-spacing: .07em; white-space: normal; text-align: center; line-height: 1.3; }
}

/* ===== Blog (.tvbl): home "News & Articles" section, the News page and the article page. Builds on ../platform/tv-shared.css ===== */
.tvbl { background: var(--x-paper); }
.tvbl__band { width: 100%; }
.tvbl__band--mist { background: var(--x-mist); }

/* section head (home + news page) */
.tvbl__head { max-width: 760px; margin-bottom: clamp(28px, 4cqi, 44px); }
.tvbl__head--center { margin-inline: auto; text-align: center; }
.tvbl__eyebrow { display: inline-flex; align-items: center; gap: 10px; margin-bottom: 10px; font-size: 16px; font-weight: 600; color: var(--x-muted); }
.tvbl__eyebrow::before { content: ""; width: 14px; height: 2px; background: var(--x-beige); }
.tvbl__head--center .tvx__title { margin-inline: auto; }
.tvbl__head--center .tvx__lede { margin-inline: auto; max-width: 640px; }

/* cards */
.tvbl__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.tvbl__card { position: relative; display: flex; flex-direction: column; border-radius: 16px; overflow: hidden; background: var(--x-paper); border: 1px solid var(--x-line); transition: border-color .25s ease, box-shadow .25s ease, transform .25s ease; }
.tvbl__card:hover { border-color: #C9D3E0; box-shadow: 0 22px 40px -28px rgba(6, 20, 43, .45); transform: translateY(-3px); }
.tvbl__card-img { display: block; aspect-ratio: 16 / 9; overflow: hidden; background: var(--x-navy); }
.tvbl__card-img img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--x-ease); }
.tvbl__card:hover .tvbl__card-img img { transform: scale(1.03); }
.tvbl__card-body { display: flex; flex-direction: column; gap: 10px; flex: 1; padding: 20px 22px 22px; }
.tvbl__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; font-size: 13.5px; font-weight: 600; line-height: 1.3; color: var(--x-muted); }
.tvbl__meta > span + span::before { content: ""; display: inline-block; width: 4px; height: 4px; margin: 0 10px 2px 0; border-radius: 50%; background: #C3CBD8; vertical-align: middle; }
.tvbl__cat { display: inline-block; padding: 4px 10px; border-radius: 20px; background: var(--x-blue-tint); color: var(--x-blue-ink); font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; text-decoration: none; }
.tvbl__cat[data-cat="case-studies"] { background: #F8EEE7; color: #8A5A3E; }
.tvbl__cat[data-cat="guides"] { background: #E6F6EE; color: #0E7A47; }
a.tvbl__cat:hover { filter: brightness(.96); }
.tvbl__card-title { font-weight: 700; font-size: 20px; line-height: 1.3; color: var(--x-ink); text-wrap: balance; }
.tvbl__card-title a { color: inherit; text-decoration: none; }
.tvbl__card-title a::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.tvbl__card-title a:focus-visible { outline: none; }
.tvbl__card:has(.tvbl__card-title a:focus-visible) { outline: 3px solid var(--x-blue); outline-offset: 3px; }
.tvbl__card-ex { font-size: 15px; line-height: 1.6; color: var(--x-muted); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.tvbl__more { margin-top: auto; padding-top: 6px; display: inline-flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--x-blue); }
.tvbl__more svg { width: 16px; height: 16px; transition: transform .2s ease; }
.tvbl__card:hover .tvbl__more svg { transform: translateX(4px); }

/* featured (first) card on the news page */
.tvbl__card--feature { grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.tvbl__card--feature .tvbl__card-img { aspect-ratio: auto; min-height: 100%; }
.tvbl__card--feature .tvbl__card-body { justify-content: center; gap: 14px; padding: clamp(24px, 3.4cqi, 44px); }
.tvbl__card--feature .tvbl__card-title { font-size: clamp(24px, 1.2cqi + 14px, 32px); line-height: 1.2; }
.tvbl__card--feature .tvbl__card-ex { font-size: 16.5px; -webkit-line-clamp: 4; }

/* filter chips (news page) */
.tvbl__filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 26px; }
.tvx .tvbl__filter { padding: 9px 16px; border-radius: 30px; border: 1px solid var(--x-line); background: var(--x-paper); font-size: 14.5px; font-weight: 700; line-height: 1.2; color: var(--x-ink); transition: background-color .2s ease, color .2s ease, border-color .2s ease; }
.tvx .tvbl__filter:hover { border-color: #C9D3E0; background: var(--x-paper); color: var(--x-ink); }
.tvx .tvbl__filter[aria-pressed="true"] { background: var(--x-ink); border-color: var(--x-ink); color: #fff; }
.tvbl__card[hidden] { display: none; }
.tvbl__empty { padding: 40px; text-align: center; color: var(--x-muted); }

.tvbl__all { display: flex; justify-content: center; margin-top: clamp(28px, 4cqi, 40px); }
.tvbl .tvx__btn--outline { color: var(--x-ink); border: 1.5px solid #C9D3E0; }
.tvbl .tvx__btn--outline:hover, .tvbl .tvx__btn--outline:focus { color: var(--x-ink); border-color: var(--x-ink); }
.tvbl .tvx__btn--outline:focus-visible { outline-color: var(--x-blue); }

/* ---------- article page ---------- */
.tvbl__article { max-width: 960px; margin: 0 auto; padding-inline: clamp(16px, 4cqi, 32px); padding-block: clamp(40px, 6cqi, 72px) clamp(48px, 6cqi, 80px); }
.tvbl__article > :not(.tvbl__cover) { max-width: 720px; margin-inline: auto; }
.tvbl__meta--top { margin-bottom: 18px; font-size: 14.5px; }
.tvbl__lede { font-size: clamp(19px, .6cqi + 15px, 22px); line-height: 1.6; font-weight: 500; color: #3A4252; text-wrap: pretty; }
.tvbl__cover { margin: clamp(28px, 4cqi, 40px) 0; border-radius: 18px; overflow: hidden; background: var(--x-navy); box-shadow: 0 30px 60px -40px rgba(6, 20, 43, .55); }
.tvbl__cover img { width: 100%; height: auto; }

.tvbl__glance { margin-bottom: 36px; padding: 22px 24px; border-radius: 14px; background: var(--x-mist); border: 1px solid var(--x-line); }
.tvbl__glance-client { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; margin-bottom: 16px; }
.tvbl__glance-client b { font-size: 17px; font-weight: 800; color: var(--x-ink); }
.tvbl__glance-client span { font-size: 14px; font-weight: 600; color: var(--x-muted); }
.tvbl__glance dl { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
.tvbl__glance dl > div { display: flex; flex-direction: column-reverse; gap: 4px; padding-left: 14px; border-left: 2px solid #D9E2EE; }
.tvbl__glance dd { font-size: clamp(22px, .8cqi + 16px, 28px); font-weight: 800; line-height: 1.05; color: var(--x-blue); font-variant-numeric: tabular-nums; }
.tvbl__glance dt { font-size: 13.5px; font-weight: 600; line-height: 1.35; color: var(--x-muted); }

.tvbl__body { font-size: 18px; line-height: 1.75; color: #2E3442; }
.tvbl__body > * + * { margin-top: 18px; }
.tvbl__body h2 { margin-top: 46px; font-weight: 800; font-size: clamp(24px, .8cqi + 18px, 30px); line-height: 1.2; letter-spacing: -.005em; color: var(--x-ink); text-wrap: balance; }
.tvbl__body h3 { margin-top: 30px; font-weight: 700; font-size: 21px; line-height: 1.3; color: var(--x-ink); }
.tvbl__body h2 + *, .tvbl__body h3 + * { margin-top: 12px; }
.tvbl__body strong { font-weight: 700; color: var(--x-ink); }
.tvbl__body a { color: var(--x-blue); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: rgba(8, 106, 217, .35); }
.tvbl__body a:hover { color: var(--x-blue-ink); text-decoration-color: currentColor; }
.tvbl__body ul, .tvbl__body ol { display: grid; gap: 10px; }
.tvbl__body ul > li { position: relative; padding-left: 26px; }
.tvbl__body ul > li::before { content: ""; position: absolute; left: 4px; top: .7em; width: 8px; height: 8px; border-radius: 50%; background: var(--x-beige); }
.tvbl__body ol:not(.tvbl__steps) { counter-reset: tvbl; }
.tvbl__body ol:not(.tvbl__steps) > li { position: relative; padding-left: 42px; counter-increment: tvbl; }
.tvbl__body ol:not(.tvbl__steps) > li::before { content: counter(tvbl); position: absolute; left: 0; top: .1em; width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; background: var(--x-blue-tint); color: var(--x-blue); font-size: 14px; font-weight: 800; line-height: 1; }
.tvbl__fig { margin-block: 32px; }
.tvbl__fig img { width: 100%; height: auto; border-radius: 14px; border: 1px solid var(--x-line); background: var(--x-mist); }
.tvbl__fig figcaption { margin-top: 10px; font-size: 14.5px; line-height: 1.5; color: var(--x-muted); }
.tvbl__note { margin-top: 32px; padding: 18px 20px; border-radius: 12px; background: var(--x-mist); border-left: 3px solid var(--x-blue); font-size: 16.5px; line-height: 1.6; }
.tvbl__steps { display: grid; gap: 12px; }
.tvbl__steps li { position: relative; padding: 16px 18px 16px 60px; border-radius: 12px; border: 1px solid var(--x-line); background: var(--x-paper); font-size: 17px; line-height: 1.6; }
.tvbl__steps li::before { content: ""; position: absolute; left: 18px; top: 18px; width: 26px; height: 26px; border-radius: 50%; background: var(--x-blue) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / 15px no-repeat; }
.tvbl__steps li.is-now::before { background: var(--x-paper); box-shadow: inset 0 0 0 3px var(--x-beige); }
.tvbl__steps li > span { display: inline-block; margin: 0 8px 4px 0; padding: 2px 9px; border-radius: 20px; font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; background: #E6F6EE; color: #0E7A47; vertical-align: 2px; }
.tvbl__steps li.is-now > span { background: #F8EEE7; color: #8A5A3E; }

/* author box under every article; the byline links to it */
.tvbl__meta .tvbl__by { color: inherit; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: #C3CBD8; }
.tvbl__meta .tvbl__by:hover { color: var(--x-ink); text-decoration-color: currentColor; }
.tvbl__author { display: flex; align-items: flex-start; gap: 18px; margin-top: 44px; padding: 22px 24px; border-radius: 14px; background: var(--x-mist); border: 1px solid var(--x-line); scroll-margin-top: 110px; }
.tvbl__author-mark { flex: none; width: 56px; height: 56px; border-radius: 50%; display: grid; place-items: center; background: var(--x-navy); color: #fff; font-size: 18px; font-weight: 800; letter-spacing: .04em; box-shadow: inset 0 0 0 2px var(--x-beige); }
.tvbl__author-kicker { font-size: 12.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--x-muted); }
.tvbl__author-name { margin-top: 4px; font-size: 19px; font-weight: 800; line-height: 1.3; color: var(--x-ink); }
.tvbl__author-role { margin-top: 2px; font-size: 14.5px; font-weight: 600; color: var(--x-blue-ink); }
.tvbl__author-bio { margin-top: 10px; font-size: 16px; line-height: 1.65; color: #3A4252; text-wrap: pretty; }
.tvbl__author + .tvbl__share { margin-top: 28px; }
.tvbl__share { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 44px; padding-top: 24px; border-top: 1px solid var(--x-line); }
.tvbl__share > span { margin-right: 6px; font-size: 14px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--x-muted); }
.tvx .tvbl__sh { width: 42px; height: 42px; border-radius: 50%; display: inline-grid; place-items: center; border: 1px solid var(--x-line); background: var(--x-paper); color: var(--x-ink); text-decoration: none; transition: background-color .2s ease, color .2s ease, border-color .2s ease; }
.tvx .tvbl__sh:hover { background: var(--x-ink); border-color: var(--x-ink); color: #fff; }
.tvbl__sh svg { width: 18px; height: 18px; }
.tvbl__copied { font-size: 14px; font-weight: 600; color: #0E7A47; opacity: 0; transition: opacity .2s ease; }
.tvbl__copied.is-on { opacity: 1; }
.tvbl .tvx__cta { margin-top: 0; }

@container tvx (max-width: 1020px) {
  .tvbl__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tvbl__grid--home > :nth-child(3) { display: none; }
}
@container tvx (max-width: 900px) {
  .tvbl__card--feature { grid-template-columns: minmax(0, 1fr); }
  .tvbl__card--feature .tvbl__card-img { aspect-ratio: 16 / 9; min-height: 0; }
  .tvbl__glance dl { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@container tvx (max-width: 640px) {
  .tvbl__author { flex-direction: column; gap: 12px; padding: 18px; }
  .tvbl__grid { grid-template-columns: minmax(0, 1fr); }
  .tvbl__grid--home > :nth-child(3) { display: flex; }
  .tvbl__body { font-size: 17px; }
  .tvbl__cover { border-radius: 12px; margin-inline: calc(-1 * clamp(0px, 2cqi, 8px)); }
}

.tvbl .tvx__inner--tight { padding-block: clamp(40px, 5cqi, 64px); }

</style>
<section class="tvx tvbl tvbl--post" aria-label="Your own app or delivery apps? What changes for a multi-branch brand">
  <div class="tvbl__article">
    <div class="tvbl__meta tvbl__meta--top"><a class="tvbl__cat" data-cat="insights" href="https://topvieweg.com/blog/?cat=insights">Insight</a><span>14 October 2026</span><span>3 min read</span><span>By <a class="tvbl__by" href="#tvbl-author">Amr Bendary</a></span></div>
    <p class="tvbl__lede">Delivery apps bring orders, but they keep the customer and take a share of every sale. Here is what changes when a multi-branch brand runs its own app and online store, and how to start without losing the orders you already have.</p>
    <figure class="tvbl__cover"><img fetchpriority="high" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-own-app.jpg" width="1200" height="675" alt="Etoile Egypt ordering app on a phone, next to the points it wins over delivery apps" decoding="async"></figure>
    <div class="tvbl__body">
<h2>Where most multi-branch brands sell online today</h2>
<p>For most restaurant, sweets and retail chains, online orders arrive through two doors: the delivery apps and the call centre. Both work, up to a point. Both also carry costs that grow with every order.</p>

<h2>What delivery apps cost you, beyond the commission</h2>
<ul>
  <li><strong>A commission on every order.</strong> The more you sell through them, the more you pay.</li>
  <li><strong>The customer belongs to the app.</strong> You rarely get the contact details or the order history, so you cannot reach that customer again directly.</li>
  <li><strong>Your brand sits next to your competitors.</strong> The customer is one tap away from ordering somewhere else.</li>
  <li><strong>Offers run on their terms.</strong> Visibility, discounts and campaigns are decided inside someone else’s platform.</li>
</ul>

<h2>And what the call centre costs</h2>
<p>Every phone order needs staff, lines, space and training, and customers wait on hold at the busiest times. Orders are typed in by hand, so mistakes travel to the branch and to the customer.</p>

<h2>What your own channel changes</h2>
<p>An app and website in your brand’s name turn online ordering into something you own:</p>
<ul>
  <li><strong>Direct orders, with no commission on each one.</strong></li>
  <li><strong>Customer data that is yours:</strong> who buys, what they buy and when, so you can plan instead of guess.</li>
  <li><strong>Loyalty that works everywhere:</strong> points on every purchase, in the app and in the branch, in one account per customer.</li>
  <li><strong>Offers you control:</strong> coupons for occasions, for new customers and for customers who stopped ordering, plus targeted notifications.</li>
</ul>
<figure class="tvbl__fig"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/platform-customer-app.jpg" width="960" height="720" alt="Etoile Egypt customer app: product, home and delivery map screens" loading="lazy" decoding="async"><figcaption>Etoile Egypt’s own app: the order goes straight to the branch that covers the customer’s address.</figcaption></figure>

<h2>It only works if it is connected</h2>
<p>Many apps stall because one part is missing: a system that is not connected to the branches, branches that do not follow the orders, or an app with no offers to bring customers back. That is why we work on three things together.</p>
<ul>
  <li><strong>Technology.</strong> An app and website connected to online payment, delivery, ERP and POS, so orders arrive without errors and prices and stock are right in every branch.</li>
  <li><strong>Operations.</strong> A dashboard for management and a screen for every branch to follow orders, drivers and customers.</li>
  <li><strong>Marketing.</strong> Points, coupons and notifications, with reports that show who buys and what they buy.</li>
</ul>

<h2>What it looks like in practice</h2>
<p>Etoile Egypt used to take a large share of its orders through the call centre. Today its own app has more than 520,000 users, in March 2025 it reached #2 in the Food &amp; Drink chart on the App Store and Google Play in Egypt, and the app and website take 1,500 to 4,500 orders a day, connected to Microsoft Dynamics 365 Business Central and LS Central. <a href="https://topvieweg.com/etoile-egypt-app-case-study/">Read the Etoile Egypt story</a>.</p>

<h2>Do you have to leave the delivery apps?</h2>
<p>No. Delivery apps are useful for reach, especially in new areas. The point is balance: keep them as one channel, and build your own channel next to them, so every customer who finds you through a delivery app has a reason to order from you directly next time.</p>

<h2>How to start</h2>
<ol>
  <li><strong>Map how orders flow today:</strong> the channels, the branches, the call centre and the systems behind them.</li>
  <li><strong>Decide what the first version must do:</strong> delivery zones, payment methods, loyalty, and the link to ERP and POS.</li>
  <li><strong>See it before it is built:</strong> a live prototype of the app before the final proposal.</li>
  <li><strong>Build and connect in stages,</strong> with a defined timeline and your approval at each stage.</li>
  <li><strong>Launch with your branch teams:</strong> testing, publishing on the App Store and Google Play, and staff training.</li>
</ol>
<p class="tvbl__note">Planning your own app or online store? See how we build them on our <a href="https://topvieweg.com/service/mobile-app-development/">mobile app</a> and <a href="https://topvieweg.com/service/ecommerce-solutions/">e&#8209;commerce</a> pages.</p>
    </div>
    <aside class="tvbl__author" id="tvbl-author" aria-labelledby="tvbl-author-name">
      <span class="tvbl__author-mark" aria-hidden="true">AB</span>
      <div>
        <p class="tvbl__author-kicker">About the author</p>
        <p class="tvbl__author-name" id="tvbl-author-name">Amr Bendary</p>
        <p class="tvbl__author-role">Founder, Top View · CTO, Etoile</p>
        <p class="tvbl__author-bio">Founder of Top View and CTO at Etoile, Amr Bendary brings over 20 years of experience in digital transformation, mobile apps, e-commerce, and ERP integration. He holds an MBA in Digital Transformation and helps businesses connect technology with growth and operational efficiency.</p>
      </div>
    </aside>
    <div class="tvbl__share"><span>Share</span>
      <a class="tvbl__sh" href="https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Ftopvieweg.com%2Fown-app-vs-delivery-apps%2F" target="_blank" rel="noopener" aria-label="Share on LinkedIn"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M6.94 8.5H3.56V20h3.38V8.5ZM5.25 3a1.96 1.96 0 1 0 0 3.92 1.96 1.96 0 0 0 0-3.92ZM20.44 13.4c0-3.1-1.65-4.55-3.86-4.55-1.78 0-2.58.98-3.02 1.67V8.5h-3.38c.04.95 0 11.5 0 11.5h3.38v-6.42c0-.34.02-.69.13-.93.27-.69.9-1.4 1.95-1.4 1.38 0 1.93 1.05 1.93 2.59V20h3.37v-6.6Z"/></svg></a>
      <a class="tvbl__sh" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Ftopvieweg.com%2Fown-app-vs-delivery-apps%2F" target="_blank" rel="noopener" aria-label="Share on Facebook"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M13.5 21v-7.5h2.53l.38-2.93H13.5V8.7c0-.85.24-1.43 1.45-1.43h1.55V4.65a20.8 20.8 0 0 0-2.26-.12c-2.24 0-3.77 1.37-3.77 3.88v2.16H7.94v2.93h2.53V21h3.03Z"/></svg></a>
      <a class="tvbl__sh" href="https://wa.me/?text=Your%20own%20app%20or%20delivery%20apps%3F%20What%20changes%20for%20a%20multi-branch%20brand%20https%3A%2F%2Ftopvieweg.com%2Fown-app-vs-delivery-apps%2F" target="_blank" rel="noopener" aria-label="Share on WhatsApp"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M17.47 14.38c-.3-.15-1.76-.87-2.03-.97-.27-.1-.47-.15-.67.15-.2.3-.77.97-.94 1.16-.17.2-.35.22-.64.07-.3-.15-1.26-.46-2.39-1.47-.88-.79-1.48-1.76-1.65-2.06-.17-.3-.02-.46.13-.61.13-.13.3-.35.45-.52.15-.17.2-.3.3-.5.1-.2.05-.37-.03-.52-.07-.15-.67-1.61-.92-2.21-.24-.58-.49-.5-.67-.51h-.57c-.2 0-.52.07-.79.37-.27.3-1.04 1.02-1.04 2.48 0 1.46 1.07 2.88 1.21 3.07.15.2 2.1 3.2 5.08 4.49.71.31 1.26.49 1.69.63.71.23 1.36.2 1.87.12.57-.09 1.76-.72 2-1.41.25-.7.25-1.29.18-1.41-.08-.13-.27-.2-.57-.35ZM12.05 21.79h-.01a9.87 9.87 0 0 1-5.03-1.38l-.36-.21-3.74.98 1-3.65-.24-.37a9.86 9.86 0 0 1-1.51-5.26c0-5.45 4.44-9.88 9.89-9.88a9.83 9.83 0 0 1 9.88 9.89c0 5.45-4.44 9.88-9.88 9.88Zm8.41-18.3A11.82 11.82 0 0 0 12.05 0C5.5 0 .16 5.34.16 11.89c0 2.1.55 4.14 1.59 5.95L.06 24l6.3-1.65a11.88 11.88 0 0 0 5.68 1.45h.01c6.55 0 11.89-5.34 11.89-11.89 0-3.18-1.24-6.17-3.48-8.42Z"/></svg></a>
      <a class="tvbl__sh" href="https://topvieweg.com/own-app-vs-delivery-apps/" data-copy aria-label="Copy link"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1"/><path d="M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1"/></svg></a><span class="tvbl__copied" aria-live="polite">Link copied</span>
    </div>
  </div>
  <div class="tvbl__band">
    <div class="tvx__inner tvx__inner--tight">
      <div class="tvx__cta" data-reveal>
        <div class="tvx__cta-text"><h3 class="tvx__cta-title">Planning something similar?</h3><p class="tvx__cta-body">Book a free meeting with our team. We will review how your branches work and suggest the right setup.</p></div>
        <div class="tvx__cta-actions">
          <a class="tvx__btn tvx__btn--primary" href="https://topvieweg.com/contact/" data-tvx="consultation" data-where="blog_own-app-vs-delivery-apps">Get a Free Consultation <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          <a class="tvx__btn tvx__btn--ghost" href="https://wa.me/201114000096?text=Hello%20TopView%2C%20I'm%20contacting%20you%20from%20your%20website%20(News%20article).%20I'd%20like%20to%20discuss%20a%20project." target="_blank" rel="noopener" data-tvx="whatsapp"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M17.47 14.38c-.3-.15-1.76-.87-2.03-.97-.27-.1-.47-.15-.67.15-.2.3-.77.97-.94 1.16-.17.2-.35.22-.64.07-.3-.15-1.26-.46-2.39-1.47-.88-.79-1.48-1.76-1.65-2.06-.17-.3-.02-.46.13-.61.13-.13.3-.35.45-.52.15-.17.2-.3.3-.5.1-.2.05-.37-.03-.52-.07-.15-.67-1.61-.92-2.21-.24-.58-.49-.5-.67-.51h-.57c-.2 0-.52.07-.79.37-.27.3-1.04 1.02-1.04 2.48 0 1.46 1.07 2.88 1.21 3.07.15.2 2.1 3.2 5.08 4.49.71.31 1.26.49 1.69.63.71.23 1.36.2 1.87.12.57-.09 1.76-.72 2-1.41.25-.7.25-1.29.18-1.41-.08-.13-.27-.2-.57-.35ZM12.05 21.79h-.01a9.87 9.87 0 0 1-5.03-1.38l-.36-.21-3.74.98 1-3.65-.24-.37a9.86 9.86 0 0 1-1.51-5.26c0-5.45 4.44-9.88 9.89-9.88a9.83 9.83 0 0 1 9.88 9.89c0 5.45-4.44 9.88-9.88 9.88Zm8.41-18.3A11.82 11.82 0 0 0 12.05 0C5.5 0 .16 5.34.16 11.89c0 2.1.55 4.14 1.59 5.95L.06 24l6.3-1.65a11.88 11.88 0 0 0 5.68 1.45h.01c6.55 0 11.89-5.34 11.89-11.89 0-3.18-1.24-6.17-3.48-8.42Z"/></svg> Chat on WhatsApp</a>
        </div>
      </div>
    </div>
  </div>
  <div class="tvbl__band tvbl__band--mist">
    <div class="tvx__inner">
      <div class="tvbl__head" data-reveal><h2 class="tvx__title">More articles</h2></div>
      <div class="tvbl__grid" data-tvbl-feed data-count="3" data-exclude="5571" data-reveal>
        <article class="tvbl__card" data-id="5575" data-cat="guides">
          <a class="tvbl__card-img" href="https://topvieweg.com/what-is-ecommerce/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-g-what.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="guides">Guide</span><span>14 Oct 2026</span><span>2 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/what-is-ecommerce/">What is e-commerce? A plain guide for business owners</a></h3>
            <p class="tvbl__card-ex">E-commerce is more than a website with a cart. Here is what it really means for a restaurant, shop or brand, the channels it covers, and the parts that have to work together behind every online order.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
        <article class="tvbl__card" data-id="5572" data-cat="case-studies">
          <a class="tvbl__card-img" href="https://topvieweg.com/etoile-egypt-app-case-study/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-etoile.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="case-studies">Case study</span><span>14 Oct 2026</span><span>2 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/etoile-egypt-app-case-study/">How Etoile Egypt went from a call centre to 520,000+ app users</a></h3>
            <p class="tvbl__card-ex">Etoile Egypt moved its online orders from a busy call centre to its own app and website. Today the app has more than 520,000 users and takes thousands of orders a day, connected to the branches, ERP and POS.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
        <article class="tvbl__card" data-id="3197" data-cat="guides">
          <a class="tvbl__card-img" href="https://topvieweg.com/ecommerce-benefits/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-g-benefits.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="guides">Guide</span><span>14 Oct 2026</span><span>2 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/ecommerce-benefits/">7 ways e-commerce helps a business grow</a></h3>
            <p class="tvbl__card-ex">Selling online is not only about a new sales channel. Here are seven practical ways e-commerce helps restaurants, sweets brands and retailers grow, from more ordering hours to better decisions.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
      </div>
      <div class="tvbl__all"><a class="tvx__btn tvx__btn--outline" href="https://topvieweg.com/blog/">View all articles <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a></div>
    </div>
  </div>
</section>
<script>
(function () {
  var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  function fmt(n) { return Math.round(n).toLocaleString('en-US'); }
  function countUp(el) {
    var to = Number(el.getAttribute('data-n'));
    if (reduce || !to) return;
    var dur = 1200, t0 = null;
    el.textContent = fmt(0);
    requestAnimationFrame(function step(t) {
      if (t0 === null) t0 = t;
      var p = Math.min(1, (t - t0) / dur);
      el.textContent = fmt(to * (1 - Math.pow(1 - p, 3)));
      if (p < 1) requestAnimationFrame(step);
    });
    // always land on the real value, even if frames stall
    setTimeout(function () { el.textContent = fmt(to); }, dur + 400);
  }

  function init(root) {
    root.setAttribute('data-ready', '');
    root.classList.add('is-js');

    // scroll reveal (armed only here, so the section is complete without JS)
    var items = [].slice.call(root.querySelectorAll('[data-reveal]'));
    var drawTarget = root.querySelector('[data-draw]');
    if (!reduce && 'IntersectionObserver' in window) {
      root.classList.add('is-armed');
      var io = new IntersectionObserver(function (entries) {
        entries.forEach(function (e) {
          if (!e.isIntersecting) return;
          io.unobserve(e.target);
          if (e.target === drawTarget) {
            root.classList.add('is-drawn');
            [].slice.call(root.querySelectorAll('[data-n]')).forEach(countUp);
          } else {
            e.target.classList.add('is-in');
          }
        });
      }, { threshold: 0.15, rootMargin: '0px 0px -40px 0px' });
      items.forEach(function (el) { io.observe(el); });
      if (drawTarget) io.observe(drawTarget);
      // safety net: never leave content hidden
      setTimeout(function () { items.forEach(function (el) { el.classList.add('is-in'); }); root.classList.add('is-drawn'); }, 4000);
    } else {
      root.classList.add('is-drawn');
    }
    // looping decorations pause while the section is off screen
    if ('IntersectionObserver' in window) {
      new IntersectionObserver(function (entries) { root.classList.toggle('is-off', !entries[entries.length - 1].isIntersecting); }).observe(root);
    }

    // looping motion ([data-loop]) starts when first seen, so it opens on its first scene, and pauses off screen
    [].slice.call(root.querySelectorAll('[data-loop]')).forEach(function (el) {
      if (reduce || !('IntersectionObserver' in window)) return;
      new IntersectionObserver(function (entries) {
        var on = entries[entries.length - 1].isIntersecting; // several entries can queue up during a fast scroll; the last one is current
        if (on) el.classList.add('is-playing');
        el.classList.toggle('is-paused', !on);
      }, { threshold: 0.3 }).observe(el);
    });

    // tabs with a sliding highlight
    var tabs = [].slice.call(root.querySelectorAll('[role="tab"]'));
    if (!tabs.length) return;
    var panels = tabs.map(function (t) { return root.querySelector('#' + t.getAttribute('aria-controls')); });
    var ink = root.querySelector('.tvpf__ink');
    var list = tabs[0].parentNode;
    var current = Math.max(0, tabs.findIndex(function (t) { return t.getAttribute('aria-selected') === 'true'; }));
    function moveInk() {
      if (!ink) return;
      var t = tabs[current];
      ink.style.width = t.offsetWidth + 'px';
      ink.style.transform = 'translateX(' + t.offsetLeft + 'px)';
    }
    function show(n, focus) {
      if (n === current) return;
      current = (n + tabs.length) % tabs.length;
      tabs.forEach(function (t, k) {
        var on = k === current;
        t.classList.toggle('is-active', on);
        t.setAttribute('aria-selected', on ? 'true' : 'false');
        t.tabIndex = on ? 0 : -1;
      });
      panels.forEach(function (p, k) {
        var on = k === current;
        p.hidden = !on;
        p.classList.toggle('is-active', on);
        p.classList.remove('is-entering');
        if (on && !reduce) { void p.offsetWidth; p.classList.add('is-entering'); }
      });
      moveInk();
      var t = tabs[current];
      if (list.scrollWidth > list.clientWidth) list.scrollTo({ left: t.offsetLeft - (list.clientWidth - t.offsetWidth) / 2, behavior: reduce ? 'auto' : 'smooth' });
      if (focus) t.focus();
    }
    tabs.forEach(function (t, k) {
      t.addEventListener('click', function () { show(k); });
      t.addEventListener('keydown', function (e) {
        if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') { e.preventDefault(); show(current + (e.key === 'ArrowRight' ? 1 : -1), true); }
      });
    });
    moveInk();
    if (window.ResizeObserver) new ResizeObserver(moveInk).observe(list);
    window.addEventListener('load', moveInk);
  }

  [].slice.call(document.querySelectorAll('.tvx:not([data-ready])')).forEach(init);

  // calls to action: same tracking as the floating WhatsApp button and the home CTA
  // (each section ships this script, so register the listener only once per page)
  if (window.__tvxCtaTracking) return;
  window.__tvxCtaTracking = true;
  document.addEventListener('click', function (e) {
    var a = e.target.closest && e.target.closest('.tvx a[data-tvx]');
    if (!a) return;
    if (a.getAttribute('data-tvx') === 'whatsapp') {
      if (typeof gtag === 'function') { gtag('event', 'contact', { method: 'WhatsApp', link_url: a.href }); }
      if (typeof fbq === 'function') { fbq('track', 'Contact', { content_name: 'WhatsApp' }); }
      if (typeof window.lintrk === 'function') { window.lintrk('track', { conversion_id: 31200418 }); }
    } else if (typeof gtag === 'function') {
      gtag('event', 'cta_click', { cta: 'free_consultation', location: a.getAttribute('data-where') || 'section' });
    }
  });
})();

(function () {
  if (window.__tvblReady) return;
  window.__tvblReady = true;

  var CAT = { guides: 'Guide', 'case-studies': 'Case study', insights: 'Insight' };
  var arrow = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg>';
  var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

  function text(html, sel) {
    var d = document.createElement('div'); d.innerHTML = html || '';
    [].slice.call(d.querySelectorAll('style,script')).forEach(function (n) { n.remove(); });
    var part = sel && d.querySelector(sel);
    return ((part || d).textContent || '').replace(/\s+/g, ' ').trim();
  }
  function esc(s) { return String(s).replace(/[&<>"]/g, function (c) { return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c]; }); }

  // the same card markup the build script prints, rebuilt from the REST API so new posts show up on their own
  // mins comes from the card the build printed for that post; a post published later shows no reading time
  // p.tv_card = { img, cat, cat_name } is a small REST field added by the "TopView speed & SEO tweaks" snippet
  function card(p, feature, mins) {
    var tc = p.tv_card || {};
    var img = tc.img || '';
    var term = { slug: tc.cat || '', name: tc.cat_name || '' };
    var d = new Date(p.date);
    return '<article class="tvbl__card' + (feature ? ' tvbl__card--feature' : '') + '" data-id="' + p.id + '" data-cat="' + esc(term.slug || '') + '">' +
      (img ? '<a class="tvbl__card-img" href="' + esc(p.link) + '" tabindex="-1" aria-hidden="true"><img loading="lazy" src="' + esc(img) + '" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>' : '') +
      '<div class="tvbl__card-body"><div class="tvbl__meta">' + (term.slug ? '<span class="tvbl__cat" data-cat="' + esc(term.slug) + '">' + esc(CAT[term.slug] || term.name) + '</span>' : '') +
      '<span>' + d.getDate() + ' ' + months[d.getMonth()] + ' ' + d.getFullYear() + '</span>' + (mins ? '<span>' + mins + ' min read</span>' : '') + '</div>' +
      '<h3 class="tvbl__card-title"><a href="' + esc(p.link) + '">' + p.title.rendered + '</a></h3>' +
      '<p class="tvbl__card-ex">' + esc(text(p.excerpt && p.excerpt.rendered)) + '</p>' +
      '<span class="tvbl__more" aria-hidden="true">Read article ' + arrow + '</span></div></article>';
  }

  function applyFilter(root, cat) {
    var cards = [].slice.call(root.querySelectorAll('.tvbl__card'));
    var shown = 0;
    cards.forEach(function (c) { var on = !cat || c.getAttribute('data-cat') === cat; c.hidden = !on; if (on) shown++; });
    [].slice.call(root.querySelectorAll('.tvbl__filter')).forEach(function (b) { b.setAttribute('aria-pressed', String((b.getAttribute('data-cat') || '') === (cat || ''))); });
    var empty = root.querySelector('.tvbl__empty');
    if (empty) empty.hidden = shown > 0;
  }

  function initFilters() {
    [].slice.call(document.querySelectorAll('.tvbl [data-tvbl-filters]')).forEach(function (bar) {
      var root = bar.closest('.tvbl');
      if (bar.getAttribute('data-ready')) { var cur = bar.querySelector('[aria-pressed="true"]'); applyFilter(root, cur ? cur.getAttribute('data-cat') || '' : ''); return; }
      bar.setAttribute('data-ready', '1');
      bar.addEventListener('click', function (e) {
        var b = e.target.closest('.tvbl__filter');
        if (!b) return;
        applyFilter(root, b.getAttribute('data-cat') || '');
      });
      var m = location.search.match(/[?&]cat=([a-z-]+)/);
      applyFilter(root, m ? m[1] : '');
    });
  }

  // copy link
  document.addEventListener('click', function (e) {
    var b = e.target.closest && e.target.closest('.tvbl [data-copy]');
    if (!b) return;
    e.preventDefault();
    var done = function () { var t = b.parentNode.querySelector('.tvbl__copied'); if (t) { t.classList.add('is-on'); setTimeout(function () { t.classList.remove('is-on'); }, 1800); } };
    if (navigator.clipboard) navigator.clipboard.writeText(location.href.split('#')[0]).then(done, function () {}); else done();
  });

  var feeds = [].slice.call(document.querySelectorAll('[data-tvbl-feed]'));
  initFilters();
  if (!feeds.length || !window.fetch) return;

  // Only the fields a card shows (the full post content made this ~600 KB), and only once a feed
  // comes near the screen, so the request never competes with the page's first paint.
  var loaded = false;
  function refresh() {
    if (loaded) return;
    loaded = true;
    var mins = {};
    [].forEach.call(document.querySelectorAll('.tvbl__card[data-id]'), function (c) {
      var m = (c.textContent || '').match(/(\d+) min read/);
      if (m) mins[c.getAttribute('data-id')] = m[1];
    });
    fetch('/wp-json/wp/v2/posts?per_page=12&_fields=id,date,link,title,excerpt,tv_card', { credentials: 'omit' })
      .then(function (r) { return r.ok ? r.json() : Promise.reject(r.status); })
      .then(function (posts) {
        if (!Array.isArray(posts) || !posts.length || !posts[0].tv_card) return; // keep the printed cards if the field is missing
        feeds.forEach(function (feed) {
          var max = Number(feed.getAttribute('data-count')) || posts.length;
          var skip = Number(feed.getAttribute('data-exclude')) || 0;
          var list = posts.filter(function (p) { return p.id !== skip; }).slice(0, max);
          var have = [].map.call(feed.querySelectorAll('.tvbl__card'), function (el) { return el.getAttribute('data-id'); }).join();
          if (have === list.map(function (p) { return String(p.id); }).join()) return; // the printed cards are already current
          var feature = feed.hasAttribute('data-feature');
          feed.innerHTML = list.map(function (p, i) { return card(p, feature && i === 0, mins[p.id]); }).join('');
        });
        initFilters();
      })
      .catch(function () {});
  }
  if ('IntersectionObserver' in window) {
    var io = new IntersectionObserver(function (entries) {
      if (entries.some(function (e) { return e.isIntersecting; })) { io.disconnect(); refresh(); }
    }, { rootMargin: '600px 0px' });
    feeds.forEach(function (f) { io.observe(f); });
  } else {
    window.addEventListener('load', refresh);
  }
})();

</script>
				</div>
				</div>
				</div>
				</div>
		<p>The post <a href="https://topvieweg.com/own-app-vs-delivery-apps/">Your own app or delivery apps? What changes for a multi-branch brand</a> appeared first on <a href="https://topvieweg.com">TopView</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>What is e-commerce? A plain guide for business owners</title>
		<link>https://topvieweg.com/what-is-ecommerce/</link>
		
		<dc:creator><![CDATA[Amr Bendary]]></dc:creator>
		<pubDate>Wed, 14 Oct 2026 09:30:00 +0000</pubDate>
				<category><![CDATA[Guides]]></category>
		<guid isPermaLink="false">https://topvieweg.com/what-is-ecommerce/</guid>

					<description><![CDATA[<p>E-commerce is more than a website with a cart. Here is what it really means for a restaurant, shop or brand, the channels it covers, and the parts that have to work together behind every online order.</p>
<p>The post <a href="https://topvieweg.com/what-is-ecommerce/">What is e-commerce? A plain guide for business owners</a> appeared first on <a href="https://topvieweg.com">TopView</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="5575" class="elementor elementor-5575" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-tvb5575c e-con-full e-flex e-con e-parent" data-id="tvb5575c" data-element_type="container" data-e-type="container">
				<div class="elementor-element elementor-element-tvb5575w elementor-widget elementor-widget-html" data-id="tvb5575w" data-element_type="widget" data-e-type="widget" data-widget_type="html.default">
				<div class="elementor-widget-container">
					<!-- TopView blog: article what-is-ecommerce. Generated by live-site/blog/build.js from articles.js; edit there and rebuild. -->
<style>
/* Shared base for the TopView platform (.tvpf) and discount-system (.tvdm) sections.
   The izeetak theme styles every <button> (70px line height, 60px side padding, uppercase, wide tracking),
   sets body line height to 2 and decorates lists, so each section resets those inside itself. */
.tvx {
  --x-ink: #1B1825;
  --x-muted: #5A6475;
  --x-line: #E3E8EF;
  --x-paper: #FFFFFF;
  --x-mist: #F4F7FB;
  --x-blue: #086AD9;
  --x-blue-ink: #0757B3;
  --x-blue-tint: #E7F0FC;
  --x-beige: #D2A88F;
  --x-beige-lite: #E7C7B2;
  --x-navy: #06142B;
  --x-navy-2: #0B2A55;
  --x-ease: cubic-bezier(.2, .8, .2, 1);
  container: tvx / inline-size;
  position: relative;
  width: 100%;
  font-family: "Barlow", "Segoe UI", system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.5;
  color: var(--x-ink);
  text-align: left;
}
.elementor-widget:has(> .elementor-widget-container > .tvx) { width: 100%; min-width: 0; }
.tvx *, .tvx *::before, .tvx *::after { box-sizing: border-box; }
/* Element-weight resets (0,0,1): they still beat the theme (same weight, later in the page) but lose to every
   class rule, even when a second section on the page repeats this file after the first section’s rules. */
:where(.tvx) :is(h2, h3, h4, p, ul, ol, li, dl, dt, dd, figure) { margin: 0; padding: 0; }
:where(.tvx) :is(ul, ol) { list-style: none; }
:where(.tvx) li::before, :where(.tvx) li::after { content: none; }
:where(.tvx) img { display: block; max-width: 100%; height: auto; }
.tvx button { min-width: 0; min-height: 0; margin: 0; padding: 0; border: 0; background: none; color: inherit; font: inherit; line-height: inherit; letter-spacing: normal; text-transform: none; cursor: pointer; }
.tvx button:hover, .tvx button:focus { background: none; color: inherit; }
.tvx :focus-visible { outline: 3px solid var(--x-blue); outline-offset: 3px; }

.tvx__inner { max-width: 1200px; margin: 0 auto; padding-inline: clamp(16px, 4cqi, 32px); padding-block: clamp(56px, 7cqi, 96px); }
.tvx__head { max-width: 720px; margin-bottom: clamp(28px, 4cqi, 48px); }
.tvx__title { font-weight: 800; font-size: clamp(30px, 2.4cqi + 14px, 46px); line-height: 1.08; letter-spacing: -.01em; color: var(--x-ink); text-wrap: balance; margin-bottom: 14px; }
.tvx__lede { font-size: clamp(16px, .5cqi + 12px, 19px); line-height: 1.65; font-weight: 500; color: var(--x-muted); text-wrap: pretty; }
.tvx__h3 { font-weight: 800; font-size: clamp(21px, .8cqi + 15px, 26px); line-height: 1.2; color: var(--x-ink); margin-bottom: 18px; text-wrap: balance; }

.tvx__icon { flex: none; width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center; background: var(--x-blue-tint); color: var(--x-blue); }
.tvx__icon svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

.tvx__chips { display: flex; flex-wrap: wrap; gap: 8px; }
.tvx__chips li { padding: 7px 13px; border: 1px solid var(--x-line); border-radius: 20px; background: var(--x-paper); font-size: 14px; font-weight: 600; line-height: 1.3; color: var(--x-ink); }

/* closing call to action */
.tvx__cta { margin-top: clamp(40px, 5cqi, 64px); border-radius: 14px; padding: clamp(28px, 4cqi, 44px); display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 24px 40px; color: #fff; background: radial-gradient(60% 120% at 85% 0%, rgba(8, 106, 217, .55), transparent 70%), linear-gradient(160deg, var(--x-navy-2), var(--x-navy)); }
.tvx__cta-text { min-width: 0; max-width: 560px; }
.tvx__cta-title { font-weight: 800; font-size: clamp(22px, 1cqi + 15px, 30px); line-height: 1.2; color: #fff; text-wrap: balance; }
.tvx__cta-body { margin-top: 8px; font-size: 16px; line-height: 1.6; color: rgba(255, 255, 255, .82); }
.tvx__cta-actions { display: flex; flex-wrap: wrap; gap: 12px; }
.tvx__btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 52px; padding: 0 22px; border-radius: 8px; font-weight: 700; font-size: 14px; line-height: 1; letter-spacing: .1em; text-transform: uppercase; text-decoration: none; white-space: nowrap; transition: background-color .2s ease, border-color .2s ease, transform .2s ease; }
.tvx__btn svg { width: 18px; height: 18px; flex: none; }
.tvx__btn--primary { background: var(--x-beige); color: var(--x-ink); }
.tvx__btn--primary:hover, .tvx__btn--primary:focus { background: var(--x-beige-lite); color: var(--x-ink); }
.tvx__btn--ghost { color: #fff; border: 1.5px solid rgba(255, 255, 255, .34); }
.tvx__btn--ghost:hover, .tvx__btn--ghost:focus { color: #fff; border-color: #fff; background: rgba(255, 255, 255, .06); }
.tvx__btn:active { transform: translateY(1px); }
.tvx__btn:focus-visible { outline-color: var(--x-beige-lite); }

/* scroll reveal: only armed by JS, so content is visible without it */
.tvx.is-armed [data-reveal] { opacity: 0; transform: translateY(16px); transition: opacity .7s var(--x-ease), transform .7s var(--x-ease); transition-delay: calc(var(--i, 0) * 70ms); }
.tvx.is-armed [data-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .tvx *, .tvx *::before, .tvx *::after { animation: none !important; transition: none !important; }
  .tvx.is-armed [data-reveal] { opacity: 1; transform: none; }
}
@container tvx (max-width: 560px) {
  .tvx__cta-actions { width: 100%; flex-direction: column; }
  .tvx__btn { width: 100%; padding: 14px 16px; letter-spacing: .07em; white-space: normal; text-align: center; line-height: 1.3; }
}

/* ===== Blog (.tvbl): home "News & Articles" section, the News page and the article page. Builds on ../platform/tv-shared.css ===== */
.tvbl { background: var(--x-paper); }
.tvbl__band { width: 100%; }
.tvbl__band--mist { background: var(--x-mist); }

/* section head (home + news page) */
.tvbl__head { max-width: 760px; margin-bottom: clamp(28px, 4cqi, 44px); }
.tvbl__head--center { margin-inline: auto; text-align: center; }
.tvbl__eyebrow { display: inline-flex; align-items: center; gap: 10px; margin-bottom: 10px; font-size: 16px; font-weight: 600; color: var(--x-muted); }
.tvbl__eyebrow::before { content: ""; width: 14px; height: 2px; background: var(--x-beige); }
.tvbl__head--center .tvx__title { margin-inline: auto; }
.tvbl__head--center .tvx__lede { margin-inline: auto; max-width: 640px; }

/* cards */
.tvbl__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.tvbl__card { position: relative; display: flex; flex-direction: column; border-radius: 16px; overflow: hidden; background: var(--x-paper); border: 1px solid var(--x-line); transition: border-color .25s ease, box-shadow .25s ease, transform .25s ease; }
.tvbl__card:hover { border-color: #C9D3E0; box-shadow: 0 22px 40px -28px rgba(6, 20, 43, .45); transform: translateY(-3px); }
.tvbl__card-img { display: block; aspect-ratio: 16 / 9; overflow: hidden; background: var(--x-navy); }
.tvbl__card-img img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--x-ease); }
.tvbl__card:hover .tvbl__card-img img { transform: scale(1.03); }
.tvbl__card-body { display: flex; flex-direction: column; gap: 10px; flex: 1; padding: 20px 22px 22px; }
.tvbl__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; font-size: 13.5px; font-weight: 600; line-height: 1.3; color: var(--x-muted); }
.tvbl__meta > span + span::before { content: ""; display: inline-block; width: 4px; height: 4px; margin: 0 10px 2px 0; border-radius: 50%; background: #C3CBD8; vertical-align: middle; }
.tvbl__cat { display: inline-block; padding: 4px 10px; border-radius: 20px; background: var(--x-blue-tint); color: var(--x-blue-ink); font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; text-decoration: none; }
.tvbl__cat[data-cat="case-studies"] { background: #F8EEE7; color: #8A5A3E; }
.tvbl__cat[data-cat="guides"] { background: #E6F6EE; color: #0E7A47; }
a.tvbl__cat:hover { filter: brightness(.96); }
.tvbl__card-title { font-weight: 700; font-size: 20px; line-height: 1.3; color: var(--x-ink); text-wrap: balance; }
.tvbl__card-title a { color: inherit; text-decoration: none; }
.tvbl__card-title a::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.tvbl__card-title a:focus-visible { outline: none; }
.tvbl__card:has(.tvbl__card-title a:focus-visible) { outline: 3px solid var(--x-blue); outline-offset: 3px; }
.tvbl__card-ex { font-size: 15px; line-height: 1.6; color: var(--x-muted); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.tvbl__more { margin-top: auto; padding-top: 6px; display: inline-flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--x-blue); }
.tvbl__more svg { width: 16px; height: 16px; transition: transform .2s ease; }
.tvbl__card:hover .tvbl__more svg { transform: translateX(4px); }

/* featured (first) card on the news page */
.tvbl__card--feature { grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.tvbl__card--feature .tvbl__card-img { aspect-ratio: auto; min-height: 100%; }
.tvbl__card--feature .tvbl__card-body { justify-content: center; gap: 14px; padding: clamp(24px, 3.4cqi, 44px); }
.tvbl__card--feature .tvbl__card-title { font-size: clamp(24px, 1.2cqi + 14px, 32px); line-height: 1.2; }
.tvbl__card--feature .tvbl__card-ex { font-size: 16.5px; -webkit-line-clamp: 4; }

/* filter chips (news page) */
.tvbl__filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 26px; }
.tvx .tvbl__filter { padding: 9px 16px; border-radius: 30px; border: 1px solid var(--x-line); background: var(--x-paper); font-size: 14.5px; font-weight: 700; line-height: 1.2; color: var(--x-ink); transition: background-color .2s ease, color .2s ease, border-color .2s ease; }
.tvx .tvbl__filter:hover { border-color: #C9D3E0; background: var(--x-paper); color: var(--x-ink); }
.tvx .tvbl__filter[aria-pressed="true"] { background: var(--x-ink); border-color: var(--x-ink); color: #fff; }
.tvbl__card[hidden] { display: none; }
.tvbl__empty { padding: 40px; text-align: center; color: var(--x-muted); }

.tvbl__all { display: flex; justify-content: center; margin-top: clamp(28px, 4cqi, 40px); }
.tvbl .tvx__btn--outline { color: var(--x-ink); border: 1.5px solid #C9D3E0; }
.tvbl .tvx__btn--outline:hover, .tvbl .tvx__btn--outline:focus { color: var(--x-ink); border-color: var(--x-ink); }
.tvbl .tvx__btn--outline:focus-visible { outline-color: var(--x-blue); }

/* ---------- article page ---------- */
.tvbl__article { max-width: 960px; margin: 0 auto; padding-inline: clamp(16px, 4cqi, 32px); padding-block: clamp(40px, 6cqi, 72px) clamp(48px, 6cqi, 80px); }
.tvbl__article > :not(.tvbl__cover) { max-width: 720px; margin-inline: auto; }
.tvbl__meta--top { margin-bottom: 18px; font-size: 14.5px; }
.tvbl__lede { font-size: clamp(19px, .6cqi + 15px, 22px); line-height: 1.6; font-weight: 500; color: #3A4252; text-wrap: pretty; }
.tvbl__cover { margin: clamp(28px, 4cqi, 40px) 0; border-radius: 18px; overflow: hidden; background: var(--x-navy); box-shadow: 0 30px 60px -40px rgba(6, 20, 43, .55); }
.tvbl__cover img { width: 100%; height: auto; }

.tvbl__glance { margin-bottom: 36px; padding: 22px 24px; border-radius: 14px; background: var(--x-mist); border: 1px solid var(--x-line); }
.tvbl__glance-client { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; margin-bottom: 16px; }
.tvbl__glance-client b { font-size: 17px; font-weight: 800; color: var(--x-ink); }
.tvbl__glance-client span { font-size: 14px; font-weight: 600; color: var(--x-muted); }
.tvbl__glance dl { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
.tvbl__glance dl > div { display: flex; flex-direction: column-reverse; gap: 4px; padding-left: 14px; border-left: 2px solid #D9E2EE; }
.tvbl__glance dd { font-size: clamp(22px, .8cqi + 16px, 28px); font-weight: 800; line-height: 1.05; color: var(--x-blue); font-variant-numeric: tabular-nums; }
.tvbl__glance dt { font-size: 13.5px; font-weight: 600; line-height: 1.35; color: var(--x-muted); }

.tvbl__body { font-size: 18px; line-height: 1.75; color: #2E3442; }
.tvbl__body > * + * { margin-top: 18px; }
.tvbl__body h2 { margin-top: 46px; font-weight: 800; font-size: clamp(24px, .8cqi + 18px, 30px); line-height: 1.2; letter-spacing: -.005em; color: var(--x-ink); text-wrap: balance; }
.tvbl__body h3 { margin-top: 30px; font-weight: 700; font-size: 21px; line-height: 1.3; color: var(--x-ink); }
.tvbl__body h2 + *, .tvbl__body h3 + * { margin-top: 12px; }
.tvbl__body strong { font-weight: 700; color: var(--x-ink); }
.tvbl__body a { color: var(--x-blue); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: rgba(8, 106, 217, .35); }
.tvbl__body a:hover { color: var(--x-blue-ink); text-decoration-color: currentColor; }
.tvbl__body ul, .tvbl__body ol { display: grid; gap: 10px; }
.tvbl__body ul > li { position: relative; padding-left: 26px; }
.tvbl__body ul > li::before { content: ""; position: absolute; left: 4px; top: .7em; width: 8px; height: 8px; border-radius: 50%; background: var(--x-beige); }
.tvbl__body ol:not(.tvbl__steps) { counter-reset: tvbl; }
.tvbl__body ol:not(.tvbl__steps) > li { position: relative; padding-left: 42px; counter-increment: tvbl; }
.tvbl__body ol:not(.tvbl__steps) > li::before { content: counter(tvbl); position: absolute; left: 0; top: .1em; width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; background: var(--x-blue-tint); color: var(--x-blue); font-size: 14px; font-weight: 800; line-height: 1; }
.tvbl__fig { margin-block: 32px; }
.tvbl__fig img { width: 100%; height: auto; border-radius: 14px; border: 1px solid var(--x-line); background: var(--x-mist); }
.tvbl__fig figcaption { margin-top: 10px; font-size: 14.5px; line-height: 1.5; color: var(--x-muted); }
.tvbl__note { margin-top: 32px; padding: 18px 20px; border-radius: 12px; background: var(--x-mist); border-left: 3px solid var(--x-blue); font-size: 16.5px; line-height: 1.6; }
.tvbl__steps { display: grid; gap: 12px; }
.tvbl__steps li { position: relative; padding: 16px 18px 16px 60px; border-radius: 12px; border: 1px solid var(--x-line); background: var(--x-paper); font-size: 17px; line-height: 1.6; }
.tvbl__steps li::before { content: ""; position: absolute; left: 18px; top: 18px; width: 26px; height: 26px; border-radius: 50%; background: var(--x-blue) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / 15px no-repeat; }
.tvbl__steps li.is-now::before { background: var(--x-paper); box-shadow: inset 0 0 0 3px var(--x-beige); }
.tvbl__steps li > span { display: inline-block; margin: 0 8px 4px 0; padding: 2px 9px; border-radius: 20px; font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; background: #E6F6EE; color: #0E7A47; vertical-align: 2px; }
.tvbl__steps li.is-now > span { background: #F8EEE7; color: #8A5A3E; }

/* author box under every article; the byline links to it */
.tvbl__meta .tvbl__by { color: inherit; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: #C3CBD8; }
.tvbl__meta .tvbl__by:hover { color: var(--x-ink); text-decoration-color: currentColor; }
.tvbl__author { display: flex; align-items: flex-start; gap: 18px; margin-top: 44px; padding: 22px 24px; border-radius: 14px; background: var(--x-mist); border: 1px solid var(--x-line); scroll-margin-top: 110px; }
.tvbl__author-mark { flex: none; width: 56px; height: 56px; border-radius: 50%; display: grid; place-items: center; background: var(--x-navy); color: #fff; font-size: 18px; font-weight: 800; letter-spacing: .04em; box-shadow: inset 0 0 0 2px var(--x-beige); }
.tvbl__author-kicker { font-size: 12.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--x-muted); }
.tvbl__author-name { margin-top: 4px; font-size: 19px; font-weight: 800; line-height: 1.3; color: var(--x-ink); }
.tvbl__author-role { margin-top: 2px; font-size: 14.5px; font-weight: 600; color: var(--x-blue-ink); }
.tvbl__author-bio { margin-top: 10px; font-size: 16px; line-height: 1.65; color: #3A4252; text-wrap: pretty; }
.tvbl__author + .tvbl__share { margin-top: 28px; }
.tvbl__share { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 44px; padding-top: 24px; border-top: 1px solid var(--x-line); }
.tvbl__share > span { margin-right: 6px; font-size: 14px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--x-muted); }
.tvx .tvbl__sh { width: 42px; height: 42px; border-radius: 50%; display: inline-grid; place-items: center; border: 1px solid var(--x-line); background: var(--x-paper); color: var(--x-ink); text-decoration: none; transition: background-color .2s ease, color .2s ease, border-color .2s ease; }
.tvx .tvbl__sh:hover { background: var(--x-ink); border-color: var(--x-ink); color: #fff; }
.tvbl__sh svg { width: 18px; height: 18px; }
.tvbl__copied { font-size: 14px; font-weight: 600; color: #0E7A47; opacity: 0; transition: opacity .2s ease; }
.tvbl__copied.is-on { opacity: 1; }
.tvbl .tvx__cta { margin-top: 0; }

@container tvx (max-width: 1020px) {
  .tvbl__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tvbl__grid--home > :nth-child(3) { display: none; }
}
@container tvx (max-width: 900px) {
  .tvbl__card--feature { grid-template-columns: minmax(0, 1fr); }
  .tvbl__card--feature .tvbl__card-img { aspect-ratio: 16 / 9; min-height: 0; }
  .tvbl__glance dl { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@container tvx (max-width: 640px) {
  .tvbl__author { flex-direction: column; gap: 12px; padding: 18px; }
  .tvbl__grid { grid-template-columns: minmax(0, 1fr); }
  .tvbl__grid--home > :nth-child(3) { display: flex; }
  .tvbl__body { font-size: 17px; }
  .tvbl__cover { border-radius: 12px; margin-inline: calc(-1 * clamp(0px, 2cqi, 8px)); }
}

.tvbl .tvx__inner--tight { padding-block: clamp(40px, 5cqi, 64px); }

</style>
<section class="tvx tvbl tvbl--post" aria-label="What is e-commerce? A plain guide for business owners">
  <div class="tvbl__article">
    <div class="tvbl__meta tvbl__meta--top"><a class="tvbl__cat" data-cat="guides" href="https://topvieweg.com/blog/?cat=guides">Guide</a><span>14 October 2026</span><span>2 min read</span><span>By <a class="tvbl__by" href="#tvbl-author">Amr Bendary</a></span></div>
    <p class="tvbl__lede">E-commerce is more than a website with a cart. Here is what it really means for a restaurant, shop or brand, the channels it covers, and the parts that have to work together behind every online order.</p>
    <figure class="tvbl__cover"><img src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-g-what.jpg" width="1200" height="675" alt="What is e-commerce? The parts of an online order: catalogue, payment, delivery and customer" decoding="async"></figure>
    <div class="tvbl__body">
<h2>E-commerce in one sentence</h2>
<p>E-commerce means selling your products online: the customer finds what they want, orders it and pays on a website or an app, and you deliver it or prepare it for pickup.</p>

<h2>It is more than a website</h2>
<p>Many owners picture e-commerce as a nice-looking website. In practice, every online sale has five parts, and each one has to work:</p>
<ul>
  <li><strong>The catalogue:</strong> your products, prices, photos and offers, kept up to date.</li>
  <li><strong>Ordering:</strong> a cart and checkout that are quick and easy on a phone.</li>
  <li><strong>Payment:</strong> cards, wallets or cash on delivery.</li>
  <li><strong>Fulfilment:</strong> the order reaches the right branch, gets prepared, then delivered or picked up.</li>
  <li><strong>After the sale:</strong> order tracking, customer service, and a reason to order again.</li>
</ul>
<p>If one part is weak, customers feel it: a wrong price, a late order, a payment that fails. That is why e-commerce is as much about operations as it is about design.</p>

<h2>The channels you can sell through</h2>
<ul>
  <li><strong>Your own website:</strong> an online store in your brand’s name that anyone can open from Google or a link.</li>
  <li><strong>Your own app:</strong> on your customers’ phones, with notifications, saved addresses and loyalty points.</li>
  <li><strong>Delivery apps and marketplaces:</strong> they bring their own customers, on their own terms.</li>
  <li><strong>Social media and WhatsApp:</strong> conversations that often end in a phone order.</li>
</ul>
<p>Most brands use a mix. The real question is which channels you own and which you rent. We compare the two in <a href="https://topvieweg.com/own-app-vs-delivery-apps/">Your own app or delivery apps?</a></p>

<h2>What e-commerce is not</h2>
<ul>
  <li><strong>Not a replacement for your branches.</strong> For multi-branch brands, online orders are usually prepared in the branches you already have.</li>
  <li><strong>Not “build it and forget it”.</strong> An online store needs updated products, offers and follow-up, just like a shop.</li>
  <li><strong>Not only for big companies.</strong> What matters is clear products, a way to deliver, and someone responsible for online orders.</li>
</ul>

<h2>Where to start</h2>
<p>Write down how customers order from you today, and where they get stuck: busy phone lines, missed calls, wrong orders, no way to pay online. That simple map usually shows which part of e-commerce will make the biggest difference first.</p>
<p class="tvbl__note">Next: <a href="https://topvieweg.com/ecommerce-benefits/">7 ways e-commerce helps a business grow</a>, and <a href="https://topvieweg.com/ready-to-sell-online/">8 signs your business is ready to sell online</a>.</p>
    </div>
    <aside class="tvbl__author" id="tvbl-author" aria-labelledby="tvbl-author-name">
      <span class="tvbl__author-mark" aria-hidden="true">AB</span>
      <div>
        <p class="tvbl__author-kicker">About the author</p>
        <p class="tvbl__author-name" id="tvbl-author-name">Amr Bendary</p>
        <p class="tvbl__author-role">Founder, Top View · CTO, Etoile</p>
        <p class="tvbl__author-bio">Founder of Top View and CTO at Etoile, Amr Bendary brings over 20 years of experience in digital transformation, mobile apps, e-commerce, and ERP integration. He holds an MBA in Digital Transformation and helps businesses connect technology with growth and operational efficiency.</p>
      </div>
    </aside>
    <div class="tvbl__share"><span>Share</span>
      <a class="tvbl__sh" href="https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Ftopvieweg.com%2Fwhat-is-ecommerce%2F" target="_blank" rel="noopener" aria-label="Share on LinkedIn"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M6.94 8.5H3.56V20h3.38V8.5ZM5.25 3a1.96 1.96 0 1 0 0 3.92 1.96 1.96 0 0 0 0-3.92ZM20.44 13.4c0-3.1-1.65-4.55-3.86-4.55-1.78 0-2.58.98-3.02 1.67V8.5h-3.38c.04.95 0 11.5 0 11.5h3.38v-6.42c0-.34.02-.69.13-.93.27-.69.9-1.4 1.95-1.4 1.38 0 1.93 1.05 1.93 2.59V20h3.37v-6.6Z"/></svg></a>
      <a class="tvbl__sh" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Ftopvieweg.com%2Fwhat-is-ecommerce%2F" target="_blank" rel="noopener" aria-label="Share on Facebook"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M13.5 21v-7.5h2.53l.38-2.93H13.5V8.7c0-.85.24-1.43 1.45-1.43h1.55V4.65a20.8 20.8 0 0 0-2.26-.12c-2.24 0-3.77 1.37-3.77 3.88v2.16H7.94v2.93h2.53V21h3.03Z"/></svg></a>
      <a class="tvbl__sh" href="https://wa.me/?text=What%20is%20e-commerce%3F%20A%20plain%20guide%20for%20business%20owners%20https%3A%2F%2Ftopvieweg.com%2Fwhat-is-ecommerce%2F" target="_blank" rel="noopener" aria-label="Share on WhatsApp"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M17.47 14.38c-.3-.15-1.76-.87-2.03-.97-.27-.1-.47-.15-.67.15-.2.3-.77.97-.94 1.16-.17.2-.35.22-.64.07-.3-.15-1.26-.46-2.39-1.47-.88-.79-1.48-1.76-1.65-2.06-.17-.3-.02-.46.13-.61.13-.13.3-.35.45-.52.15-.17.2-.3.3-.5.1-.2.05-.37-.03-.52-.07-.15-.67-1.61-.92-2.21-.24-.58-.49-.5-.67-.51h-.57c-.2 0-.52.07-.79.37-.27.3-1.04 1.02-1.04 2.48 0 1.46 1.07 2.88 1.21 3.07.15.2 2.1 3.2 5.08 4.49.71.31 1.26.49 1.69.63.71.23 1.36.2 1.87.12.57-.09 1.76-.72 2-1.41.25-.7.25-1.29.18-1.41-.08-.13-.27-.2-.57-.35ZM12.05 21.79h-.01a9.87 9.87 0 0 1-5.03-1.38l-.36-.21-3.74.98 1-3.65-.24-.37a9.86 9.86 0 0 1-1.51-5.26c0-5.45 4.44-9.88 9.89-9.88a9.83 9.83 0 0 1 9.88 9.89c0 5.45-4.44 9.88-9.88 9.88Zm8.41-18.3A11.82 11.82 0 0 0 12.05 0C5.5 0 .16 5.34.16 11.89c0 2.1.55 4.14 1.59 5.95L.06 24l6.3-1.65a11.88 11.88 0 0 0 5.68 1.45h.01c6.55 0 11.89-5.34 11.89-11.89 0-3.18-1.24-6.17-3.48-8.42Z"/></svg></a>
      <a class="tvbl__sh" href="https://topvieweg.com/what-is-ecommerce/" data-copy aria-label="Copy link"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1"/><path d="M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1"/></svg></a><span class="tvbl__copied" aria-live="polite">Link copied</span>
    </div>
  </div>
  <div class="tvbl__band">
    <div class="tvx__inner tvx__inner--tight">
      <div class="tvx__cta" data-reveal>
        <div class="tvx__cta-text"><h3 class="tvx__cta-title">Planning something similar?</h3><p class="tvx__cta-body">Book a free meeting with our team. We will review how your branches work and suggest the right setup.</p></div>
        <div class="tvx__cta-actions">
          <a class="tvx__btn tvx__btn--primary" href="https://topvieweg.com/contact/" data-tvx="consultation" data-where="blog_what-is-ecommerce">Get a Free Consultation <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          <a class="tvx__btn tvx__btn--ghost" href="https://wa.me/201114000096?text=Hello%20TopView%2C%20I'm%20contacting%20you%20from%20your%20website%20(News%20article).%20I'd%20like%20to%20discuss%20a%20project." target="_blank" rel="noopener" data-tvx="whatsapp"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M17.47 14.38c-.3-.15-1.76-.87-2.03-.97-.27-.1-.47-.15-.67.15-.2.3-.77.97-.94 1.16-.17.2-.35.22-.64.07-.3-.15-1.26-.46-2.39-1.47-.88-.79-1.48-1.76-1.65-2.06-.17-.3-.02-.46.13-.61.13-.13.3-.35.45-.52.15-.17.2-.3.3-.5.1-.2.05-.37-.03-.52-.07-.15-.67-1.61-.92-2.21-.24-.58-.49-.5-.67-.51h-.57c-.2 0-.52.07-.79.37-.27.3-1.04 1.02-1.04 2.48 0 1.46 1.07 2.88 1.21 3.07.15.2 2.1 3.2 5.08 4.49.71.31 1.26.49 1.69.63.71.23 1.36.2 1.87.12.57-.09 1.76-.72 2-1.41.25-.7.25-1.29.18-1.41-.08-.13-.27-.2-.57-.35ZM12.05 21.79h-.01a9.87 9.87 0 0 1-5.03-1.38l-.36-.21-3.74.98 1-3.65-.24-.37a9.86 9.86 0 0 1-1.51-5.26c0-5.45 4.44-9.88 9.89-9.88a9.83 9.83 0 0 1 9.88 9.89c0 5.45-4.44 9.88-9.88 9.88Zm8.41-18.3A11.82 11.82 0 0 0 12.05 0C5.5 0 .16 5.34.16 11.89c0 2.1.55 4.14 1.59 5.95L.06 24l6.3-1.65a11.88 11.88 0 0 0 5.68 1.45h.01c6.55 0 11.89-5.34 11.89-11.89 0-3.18-1.24-6.17-3.48-8.42Z"/></svg> Chat on WhatsApp</a>
        </div>
      </div>
    </div>
  </div>
  <div class="tvbl__band tvbl__band--mist">
    <div class="tvx__inner">
      <div class="tvbl__head" data-reveal><h2 class="tvx__title">More articles</h2></div>
      <div class="tvbl__grid" data-tvbl-feed data-count="3" data-exclude="5575" data-reveal>
        <article class="tvbl__card" data-id="5571" data-cat="insights">
          <a class="tvbl__card-img" href="https://topvieweg.com/own-app-vs-delivery-apps/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-own-app.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="insights">Insight</span><span>14 Oct 2026</span><span>3 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/own-app-vs-delivery-apps/">Your own app or delivery apps? What changes for a multi-branch brand</a></h3>
            <p class="tvbl__card-ex">Delivery apps bring orders, but they keep the customer and take a share of every sale. Here is what changes when a multi-branch brand runs its own app and online store, and how to start without losing the orders you already have.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
        <article class="tvbl__card" data-id="5572" data-cat="case-studies">
          <a class="tvbl__card-img" href="https://topvieweg.com/etoile-egypt-app-case-study/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-etoile.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="case-studies">Case study</span><span>14 Oct 2026</span><span>2 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/etoile-egypt-app-case-study/">How Etoile Egypt went from a call centre to 520,000+ app users</a></h3>
            <p class="tvbl__card-ex">Etoile Egypt moved its online orders from a busy call centre to its own app and website. Today the app has more than 520,000 users and takes thousands of orders a day, connected to the branches, ERP and POS.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
        <article class="tvbl__card" data-id="3197" data-cat="guides">
          <a class="tvbl__card-img" href="https://topvieweg.com/ecommerce-benefits/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-g-benefits.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="guides">Guide</span><span>14 Oct 2026</span><span>2 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/ecommerce-benefits/">7 ways e-commerce helps a business grow</a></h3>
            <p class="tvbl__card-ex">Selling online is not only about a new sales channel. Here are seven practical ways e-commerce helps restaurants, sweets brands and retailers grow, from more ordering hours to better decisions.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
      </div>
      <div class="tvbl__all"><a class="tvx__btn tvx__btn--outline" href="https://topvieweg.com/blog/">View all articles <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a></div>
    </div>
  </div>
</section>
<script>
(function () {
  var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  function fmt(n) { return Math.round(n).toLocaleString('en-US'); }
  function countUp(el) {
    var to = Number(el.getAttribute('data-n'));
    if (reduce || !to) return;
    var dur = 1200, t0 = null;
    el.textContent = fmt(0);
    requestAnimationFrame(function step(t) {
      if (t0 === null) t0 = t;
      var p = Math.min(1, (t - t0) / dur);
      el.textContent = fmt(to * (1 - Math.pow(1 - p, 3)));
      if (p < 1) requestAnimationFrame(step);
    });
    // always land on the real value, even if frames stall
    setTimeout(function () { el.textContent = fmt(to); }, dur + 400);
  }

  function init(root) {
    root.setAttribute('data-ready', '');
    root.classList.add('is-js');

    // scroll reveal (armed only here, so the section is complete without JS)
    var items = [].slice.call(root.querySelectorAll('[data-reveal]'));
    var drawTarget = root.querySelector('[data-draw]');
    if (!reduce && 'IntersectionObserver' in window) {
      root.classList.add('is-armed');
      var io = new IntersectionObserver(function (entries) {
        entries.forEach(function (e) {
          if (!e.isIntersecting) return;
          io.unobserve(e.target);
          if (e.target === drawTarget) {
            root.classList.add('is-drawn');
            [].slice.call(root.querySelectorAll('[data-n]')).forEach(countUp);
          } else {
            e.target.classList.add('is-in');
          }
        });
      }, { threshold: 0.15, rootMargin: '0px 0px -40px 0px' });
      items.forEach(function (el) { io.observe(el); });
      if (drawTarget) io.observe(drawTarget);
      // safety net: never leave content hidden
      setTimeout(function () { items.forEach(function (el) { el.classList.add('is-in'); }); root.classList.add('is-drawn'); }, 4000);
    } else {
      root.classList.add('is-drawn');
    }
    // looping decorations pause while the section is off screen
    if ('IntersectionObserver' in window) {
      new IntersectionObserver(function (entries) { root.classList.toggle('is-off', !entries[entries.length - 1].isIntersecting); }).observe(root);
    }

    // looping motion ([data-loop]) starts when first seen, so it opens on its first scene, and pauses off screen
    [].slice.call(root.querySelectorAll('[data-loop]')).forEach(function (el) {
      if (reduce || !('IntersectionObserver' in window)) return;
      new IntersectionObserver(function (entries) {
        var on = entries[entries.length - 1].isIntersecting; // several entries can queue up during a fast scroll; the last one is current
        if (on) el.classList.add('is-playing');
        el.classList.toggle('is-paused', !on);
      }, { threshold: 0.3 }).observe(el);
    });

    // tabs with a sliding highlight
    var tabs = [].slice.call(root.querySelectorAll('[role="tab"]'));
    if (!tabs.length) return;
    var panels = tabs.map(function (t) { return root.querySelector('#' + t.getAttribute('aria-controls')); });
    var ink = root.querySelector('.tvpf__ink');
    var list = tabs[0].parentNode;
    var current = Math.max(0, tabs.findIndex(function (t) { return t.getAttribute('aria-selected') === 'true'; }));
    function moveInk() {
      if (!ink) return;
      var t = tabs[current];
      ink.style.width = t.offsetWidth + 'px';
      ink.style.transform = 'translateX(' + t.offsetLeft + 'px)';
    }
    function show(n, focus) {
      if (n === current) return;
      current = (n + tabs.length) % tabs.length;
      tabs.forEach(function (t, k) {
        var on = k === current;
        t.classList.toggle('is-active', on);
        t.setAttribute('aria-selected', on ? 'true' : 'false');
        t.tabIndex = on ? 0 : -1;
      });
      panels.forEach(function (p, k) {
        var on = k === current;
        p.hidden = !on;
        p.classList.toggle('is-active', on);
        p.classList.remove('is-entering');
        if (on && !reduce) { void p.offsetWidth; p.classList.add('is-entering'); }
      });
      moveInk();
      var t = tabs[current];
      if (list.scrollWidth > list.clientWidth) list.scrollTo({ left: t.offsetLeft - (list.clientWidth - t.offsetWidth) / 2, behavior: reduce ? 'auto' : 'smooth' });
      if (focus) t.focus();
    }
    tabs.forEach(function (t, k) {
      t.addEventListener('click', function () { show(k); });
      t.addEventListener('keydown', function (e) {
        if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') { e.preventDefault(); show(current + (e.key === 'ArrowRight' ? 1 : -1), true); }
      });
    });
    moveInk();
    if (window.ResizeObserver) new ResizeObserver(moveInk).observe(list);
    window.addEventListener('load', moveInk);
  }

  [].slice.call(document.querySelectorAll('.tvx:not([data-ready])')).forEach(init);

  // calls to action: same tracking as the floating WhatsApp button and the home CTA
  // (each section ships this script, so register the listener only once per page)
  if (window.__tvxCtaTracking) return;
  window.__tvxCtaTracking = true;
  document.addEventListener('click', function (e) {
    var a = e.target.closest && e.target.closest('.tvx a[data-tvx]');
    if (!a) return;
    if (a.getAttribute('data-tvx') === 'whatsapp') {
      if (typeof gtag === 'function') { gtag('event', 'contact', { method: 'WhatsApp', link_url: a.href }); }
      if (typeof fbq === 'function') { fbq('track', 'Contact', { content_name: 'WhatsApp' }); }
      if (typeof window.lintrk === 'function') { window.lintrk('track', { conversion_id: 31200418 }); }
    } else if (typeof gtag === 'function') {
      gtag('event', 'cta_click', { cta: 'free_consultation', location: a.getAttribute('data-where') || 'section' });
    }
  });
})();

(function () {
  if (window.__tvblReady) return;
  window.__tvblReady = true;

  var CAT = { guides: 'Guide', 'case-studies': 'Case study', insights: 'Insight' };
  var arrow = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg>';
  var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

  function text(html, sel) {
    var d = document.createElement('div'); d.innerHTML = html || '';
    [].slice.call(d.querySelectorAll('style,script')).forEach(function (n) { n.remove(); });
    var part = sel && d.querySelector(sel);
    return ((part || d).textContent || '').replace(/\s+/g, ' ').trim();
  }
  function esc(s) { return String(s).replace(/[&<>"]/g, function (c) { return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c]; }); }

  // the same card markup the build script prints, rebuilt from the REST API so new posts show up on their own
  // mins comes from the card the build printed for that post; a post published later shows no reading time
  // p.tv_card = { img, cat, cat_name } is a small REST field added by the "TopView speed & SEO tweaks" snippet
  function card(p, feature, mins) {
    var tc = p.tv_card || {};
    var img = tc.img || '';
    var term = { slug: tc.cat || '', name: tc.cat_name || '' };
    var d = new Date(p.date);
    return '<article class="tvbl__card' + (feature ? ' tvbl__card--feature' : '') + '" data-id="' + p.id + '" data-cat="' + esc(term.slug || '') + '">' +
      (img ? '<a class="tvbl__card-img" href="' + esc(p.link) + '" tabindex="-1" aria-hidden="true"><img loading="lazy" src="' + esc(img) + '" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>' : '') +
      '<div class="tvbl__card-body"><div class="tvbl__meta">' + (term.slug ? '<span class="tvbl__cat" data-cat="' + esc(term.slug) + '">' + esc(CAT[term.slug] || term.name) + '</span>' : '') +
      '<span>' + d.getDate() + ' ' + months[d.getMonth()] + ' ' + d.getFullYear() + '</span>' + (mins ? '<span>' + mins + ' min read</span>' : '') + '</div>' +
      '<h3 class="tvbl__card-title"><a href="' + esc(p.link) + '">' + p.title.rendered + '</a></h3>' +
      '<p class="tvbl__card-ex">' + esc(text(p.excerpt && p.excerpt.rendered)) + '</p>' +
      '<span class="tvbl__more" aria-hidden="true">Read article ' + arrow + '</span></div></article>';
  }

  function applyFilter(root, cat) {
    var cards = [].slice.call(root.querySelectorAll('.tvbl__card'));
    var shown = 0;
    cards.forEach(function (c) { var on = !cat || c.getAttribute('data-cat') === cat; c.hidden = !on; if (on) shown++; });
    [].slice.call(root.querySelectorAll('.tvbl__filter')).forEach(function (b) { b.setAttribute('aria-pressed', String((b.getAttribute('data-cat') || '') === (cat || ''))); });
    var empty = root.querySelector('.tvbl__empty');
    if (empty) empty.hidden = shown > 0;
  }

  function initFilters() {
    [].slice.call(document.querySelectorAll('.tvbl [data-tvbl-filters]')).forEach(function (bar) {
      var root = bar.closest('.tvbl');
      if (bar.getAttribute('data-ready')) { var cur = bar.querySelector('[aria-pressed="true"]'); applyFilter(root, cur ? cur.getAttribute('data-cat') || '' : ''); return; }
      bar.setAttribute('data-ready', '1');
      bar.addEventListener('click', function (e) {
        var b = e.target.closest('.tvbl__filter');
        if (!b) return;
        applyFilter(root, b.getAttribute('data-cat') || '');
      });
      var m = location.search.match(/[?&]cat=([a-z-]+)/);
      applyFilter(root, m ? m[1] : '');
    });
  }

  // copy link
  document.addEventListener('click', function (e) {
    var b = e.target.closest && e.target.closest('.tvbl [data-copy]');
    if (!b) return;
    e.preventDefault();
    var done = function () { var t = b.parentNode.querySelector('.tvbl__copied'); if (t) { t.classList.add('is-on'); setTimeout(function () { t.classList.remove('is-on'); }, 1800); } };
    if (navigator.clipboard) navigator.clipboard.writeText(location.href.split('#')[0]).then(done, function () {}); else done();
  });

  var feeds = [].slice.call(document.querySelectorAll('[data-tvbl-feed]'));
  initFilters();
  if (!feeds.length || !window.fetch) return;

  // Only the fields a card shows (the full post content made this ~600 KB), and only once a feed
  // comes near the screen, so the request never competes with the page's first paint.
  var loaded = false;
  function refresh() {
    if (loaded) return;
    loaded = true;
    var mins = {};
    [].forEach.call(document.querySelectorAll('.tvbl__card[data-id]'), function (c) {
      var m = (c.textContent || '').match(/(\d+) min read/);
      if (m) mins[c.getAttribute('data-id')] = m[1];
    });
    fetch('/wp-json/wp/v2/posts?per_page=12&_fields=id,date,link,title,excerpt,tv_card', { credentials: 'omit' })
      .then(function (r) { return r.ok ? r.json() : Promise.reject(r.status); })
      .then(function (posts) {
        if (!Array.isArray(posts) || !posts.length || !posts[0].tv_card) return; // keep the printed cards if the field is missing
        feeds.forEach(function (feed) {
          var max = Number(feed.getAttribute('data-count')) || posts.length;
          var skip = Number(feed.getAttribute('data-exclude')) || 0;
          var list = posts.filter(function (p) { return p.id !== skip; }).slice(0, max);
          var have = [].map.call(feed.querySelectorAll('.tvbl__card'), function (el) { return el.getAttribute('data-id'); }).join();
          if (have === list.map(function (p) { return String(p.id); }).join()) return; // the printed cards are already current
          var feature = feed.hasAttribute('data-feature');
          feed.innerHTML = list.map(function (p, i) { return card(p, feature && i === 0, mins[p.id]); }).join('');
        });
        initFilters();
      })
      .catch(function () {});
  }
  if ('IntersectionObserver' in window) {
    var io = new IntersectionObserver(function (entries) {
      if (entries.some(function (e) { return e.isIntersecting; })) { io.disconnect(); refresh(); }
    }, { rootMargin: '600px 0px' });
    feeds.forEach(function (f) { io.observe(f); });
  } else {
    window.addEventListener('load', refresh);
  }
})();

</script>
				</div>
				</div>
				</div>
				</div>
		<p>The post <a href="https://topvieweg.com/what-is-ecommerce/">What is e-commerce? A plain guide for business owners</a> appeared first on <a href="https://topvieweg.com">TopView</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How Etoile Egypt went from a call centre to 520,000+ app users</title>
		<link>https://topvieweg.com/etoile-egypt-app-case-study/</link>
		
		<dc:creator><![CDATA[Amr Bendary]]></dc:creator>
		<pubDate>Wed, 14 Oct 2026 09:00:00 +0000</pubDate>
				<category><![CDATA[Case Studies]]></category>
		<guid isPermaLink="false">https://topvieweg.com/etoile-egypt-app-case-study/</guid>

					<description><![CDATA[<p>Etoile Egypt moved its online orders from a busy call centre to its own app and website. Today the app has more than 520,000 users and takes thousands of orders a day, connected to the branches, ERP and POS.</p>
<p>The post <a href="https://topvieweg.com/etoile-egypt-app-case-study/">How Etoile Egypt went from a call centre to 520,000+ app users</a> appeared first on <a href="https://topvieweg.com">TopView</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="5572" class="elementor elementor-5572" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-tvb5572c e-con-full e-flex e-con e-parent" data-id="tvb5572c" data-element_type="container" data-e-type="container">
				<div class="elementor-element elementor-element-tvb5572w elementor-widget elementor-widget-html" data-id="tvb5572w" data-element_type="widget" data-e-type="widget" data-widget_type="html.default">
				<div class="elementor-widget-container">
					<!-- TopView blog: article etoile-egypt-app-case-study. Generated by live-site/blog/build.js from articles.js; edit there and rebuild. -->
<style>
/* Shared base for the TopView platform (.tvpf) and discount-system (.tvdm) sections.
   The izeetak theme styles every <button> (70px line height, 60px side padding, uppercase, wide tracking),
   sets body line height to 2 and decorates lists, so each section resets those inside itself. */
.tvx {
  --x-ink: #1B1825;
  --x-muted: #5A6475;
  --x-line: #E3E8EF;
  --x-paper: #FFFFFF;
  --x-mist: #F4F7FB;
  --x-blue: #086AD9;
  --x-blue-ink: #0757B3;
  --x-blue-tint: #E7F0FC;
  --x-beige: #D2A88F;
  --x-beige-lite: #E7C7B2;
  --x-navy: #06142B;
  --x-navy-2: #0B2A55;
  --x-ease: cubic-bezier(.2, .8, .2, 1);
  container: tvx / inline-size;
  position: relative;
  width: 100%;
  font-family: "Barlow", "Segoe UI", system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.5;
  color: var(--x-ink);
  text-align: left;
}
.elementor-widget:has(> .elementor-widget-container > .tvx) { width: 100%; min-width: 0; }
.tvx *, .tvx *::before, .tvx *::after { box-sizing: border-box; }
/* Element-weight resets (0,0,1): they still beat the theme (same weight, later in the page) but lose to every
   class rule, even when a second section on the page repeats this file after the first section’s rules. */
:where(.tvx) :is(h2, h3, h4, p, ul, ol, li, dl, dt, dd, figure) { margin: 0; padding: 0; }
:where(.tvx) :is(ul, ol) { list-style: none; }
:where(.tvx) li::before, :where(.tvx) li::after { content: none; }
:where(.tvx) img { display: block; max-width: 100%; height: auto; }
.tvx button { min-width: 0; min-height: 0; margin: 0; padding: 0; border: 0; background: none; color: inherit; font: inherit; line-height: inherit; letter-spacing: normal; text-transform: none; cursor: pointer; }
.tvx button:hover, .tvx button:focus { background: none; color: inherit; }
.tvx :focus-visible { outline: 3px solid var(--x-blue); outline-offset: 3px; }

.tvx__inner { max-width: 1200px; margin: 0 auto; padding-inline: clamp(16px, 4cqi, 32px); padding-block: clamp(56px, 7cqi, 96px); }
.tvx__head { max-width: 720px; margin-bottom: clamp(28px, 4cqi, 48px); }
.tvx__title { font-weight: 800; font-size: clamp(30px, 2.4cqi + 14px, 46px); line-height: 1.08; letter-spacing: -.01em; color: var(--x-ink); text-wrap: balance; margin-bottom: 14px; }
.tvx__lede { font-size: clamp(16px, .5cqi + 12px, 19px); line-height: 1.65; font-weight: 500; color: var(--x-muted); text-wrap: pretty; }
.tvx__h3 { font-weight: 800; font-size: clamp(21px, .8cqi + 15px, 26px); line-height: 1.2; color: var(--x-ink); margin-bottom: 18px; text-wrap: balance; }

.tvx__icon { flex: none; width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center; background: var(--x-blue-tint); color: var(--x-blue); }
.tvx__icon svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

.tvx__chips { display: flex; flex-wrap: wrap; gap: 8px; }
.tvx__chips li { padding: 7px 13px; border: 1px solid var(--x-line); border-radius: 20px; background: var(--x-paper); font-size: 14px; font-weight: 600; line-height: 1.3; color: var(--x-ink); }

/* closing call to action */
.tvx__cta { margin-top: clamp(40px, 5cqi, 64px); border-radius: 14px; padding: clamp(28px, 4cqi, 44px); display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 24px 40px; color: #fff; background: radial-gradient(60% 120% at 85% 0%, rgba(8, 106, 217, .55), transparent 70%), linear-gradient(160deg, var(--x-navy-2), var(--x-navy)); }
.tvx__cta-text { min-width: 0; max-width: 560px; }
.tvx__cta-title { font-weight: 800; font-size: clamp(22px, 1cqi + 15px, 30px); line-height: 1.2; color: #fff; text-wrap: balance; }
.tvx__cta-body { margin-top: 8px; font-size: 16px; line-height: 1.6; color: rgba(255, 255, 255, .82); }
.tvx__cta-actions { display: flex; flex-wrap: wrap; gap: 12px; }
.tvx__btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 52px; padding: 0 22px; border-radius: 8px; font-weight: 700; font-size: 14px; line-height: 1; letter-spacing: .1em; text-transform: uppercase; text-decoration: none; white-space: nowrap; transition: background-color .2s ease, border-color .2s ease, transform .2s ease; }
.tvx__btn svg { width: 18px; height: 18px; flex: none; }
.tvx__btn--primary { background: var(--x-beige); color: var(--x-ink); }
.tvx__btn--primary:hover, .tvx__btn--primary:focus { background: var(--x-beige-lite); color: var(--x-ink); }
.tvx__btn--ghost { color: #fff; border: 1.5px solid rgba(255, 255, 255, .34); }
.tvx__btn--ghost:hover, .tvx__btn--ghost:focus { color: #fff; border-color: #fff; background: rgba(255, 255, 255, .06); }
.tvx__btn:active { transform: translateY(1px); }
.tvx__btn:focus-visible { outline-color: var(--x-beige-lite); }

/* scroll reveal: only armed by JS, so content is visible without it */
.tvx.is-armed [data-reveal] { opacity: 0; transform: translateY(16px); transition: opacity .7s var(--x-ease), transform .7s var(--x-ease); transition-delay: calc(var(--i, 0) * 70ms); }
.tvx.is-armed [data-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .tvx *, .tvx *::before, .tvx *::after { animation: none !important; transition: none !important; }
  .tvx.is-armed [data-reveal] { opacity: 1; transform: none; }
}
@container tvx (max-width: 560px) {
  .tvx__cta-actions { width: 100%; flex-direction: column; }
  .tvx__btn { width: 100%; padding: 14px 16px; letter-spacing: .07em; white-space: normal; text-align: center; line-height: 1.3; }
}

/* ===== Blog (.tvbl): home "News & Articles" section, the News page and the article page. Builds on ../platform/tv-shared.css ===== */
.tvbl { background: var(--x-paper); }
.tvbl__band { width: 100%; }
.tvbl__band--mist { background: var(--x-mist); }

/* section head (home + news page) */
.tvbl__head { max-width: 760px; margin-bottom: clamp(28px, 4cqi, 44px); }
.tvbl__head--center { margin-inline: auto; text-align: center; }
.tvbl__eyebrow { display: inline-flex; align-items: center; gap: 10px; margin-bottom: 10px; font-size: 16px; font-weight: 600; color: var(--x-muted); }
.tvbl__eyebrow::before { content: ""; width: 14px; height: 2px; background: var(--x-beige); }
.tvbl__head--center .tvx__title { margin-inline: auto; }
.tvbl__head--center .tvx__lede { margin-inline: auto; max-width: 640px; }

/* cards */
.tvbl__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.tvbl__card { position: relative; display: flex; flex-direction: column; border-radius: 16px; overflow: hidden; background: var(--x-paper); border: 1px solid var(--x-line); transition: border-color .25s ease, box-shadow .25s ease, transform .25s ease; }
.tvbl__card:hover { border-color: #C9D3E0; box-shadow: 0 22px 40px -28px rgba(6, 20, 43, .45); transform: translateY(-3px); }
.tvbl__card-img { display: block; aspect-ratio: 16 / 9; overflow: hidden; background: var(--x-navy); }
.tvbl__card-img img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--x-ease); }
.tvbl__card:hover .tvbl__card-img img { transform: scale(1.03); }
.tvbl__card-body { display: flex; flex-direction: column; gap: 10px; flex: 1; padding: 20px 22px 22px; }
.tvbl__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; font-size: 13.5px; font-weight: 600; line-height: 1.3; color: var(--x-muted); }
.tvbl__meta > span + span::before { content: ""; display: inline-block; width: 4px; height: 4px; margin: 0 10px 2px 0; border-radius: 50%; background: #C3CBD8; vertical-align: middle; }
.tvbl__cat { display: inline-block; padding: 4px 10px; border-radius: 20px; background: var(--x-blue-tint); color: var(--x-blue-ink); font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; text-decoration: none; }
.tvbl__cat[data-cat="case-studies"] { background: #F8EEE7; color: #8A5A3E; }
.tvbl__cat[data-cat="guides"] { background: #E6F6EE; color: #0E7A47; }
a.tvbl__cat:hover { filter: brightness(.96); }
.tvbl__card-title { font-weight: 700; font-size: 20px; line-height: 1.3; color: var(--x-ink); text-wrap: balance; }
.tvbl__card-title a { color: inherit; text-decoration: none; }
.tvbl__card-title a::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.tvbl__card-title a:focus-visible { outline: none; }
.tvbl__card:has(.tvbl__card-title a:focus-visible) { outline: 3px solid var(--x-blue); outline-offset: 3px; }
.tvbl__card-ex { font-size: 15px; line-height: 1.6; color: var(--x-muted); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.tvbl__more { margin-top: auto; padding-top: 6px; display: inline-flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--x-blue); }
.tvbl__more svg { width: 16px; height: 16px; transition: transform .2s ease; }
.tvbl__card:hover .tvbl__more svg { transform: translateX(4px); }

/* featured (first) card on the news page */
.tvbl__card--feature { grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.tvbl__card--feature .tvbl__card-img { aspect-ratio: auto; min-height: 100%; }
.tvbl__card--feature .tvbl__card-body { justify-content: center; gap: 14px; padding: clamp(24px, 3.4cqi, 44px); }
.tvbl__card--feature .tvbl__card-title { font-size: clamp(24px, 1.2cqi + 14px, 32px); line-height: 1.2; }
.tvbl__card--feature .tvbl__card-ex { font-size: 16.5px; -webkit-line-clamp: 4; }

/* filter chips (news page) */
.tvbl__filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 26px; }
.tvx .tvbl__filter { padding: 9px 16px; border-radius: 30px; border: 1px solid var(--x-line); background: var(--x-paper); font-size: 14.5px; font-weight: 700; line-height: 1.2; color: var(--x-ink); transition: background-color .2s ease, color .2s ease, border-color .2s ease; }
.tvx .tvbl__filter:hover { border-color: #C9D3E0; background: var(--x-paper); color: var(--x-ink); }
.tvx .tvbl__filter[aria-pressed="true"] { background: var(--x-ink); border-color: var(--x-ink); color: #fff; }
.tvbl__card[hidden] { display: none; }
.tvbl__empty { padding: 40px; text-align: center; color: var(--x-muted); }

.tvbl__all { display: flex; justify-content: center; margin-top: clamp(28px, 4cqi, 40px); }
.tvbl .tvx__btn--outline { color: var(--x-ink); border: 1.5px solid #C9D3E0; }
.tvbl .tvx__btn--outline:hover, .tvbl .tvx__btn--outline:focus { color: var(--x-ink); border-color: var(--x-ink); }
.tvbl .tvx__btn--outline:focus-visible { outline-color: var(--x-blue); }

/* ---------- article page ---------- */
.tvbl__article { max-width: 960px; margin: 0 auto; padding-inline: clamp(16px, 4cqi, 32px); padding-block: clamp(40px, 6cqi, 72px) clamp(48px, 6cqi, 80px); }
.tvbl__article > :not(.tvbl__cover) { max-width: 720px; margin-inline: auto; }
.tvbl__meta--top { margin-bottom: 18px; font-size: 14.5px; }
.tvbl__lede { font-size: clamp(19px, .6cqi + 15px, 22px); line-height: 1.6; font-weight: 500; color: #3A4252; text-wrap: pretty; }
.tvbl__cover { margin: clamp(28px, 4cqi, 40px) 0; border-radius: 18px; overflow: hidden; background: var(--x-navy); box-shadow: 0 30px 60px -40px rgba(6, 20, 43, .55); }
.tvbl__cover img { width: 100%; height: auto; }

.tvbl__glance { margin-bottom: 36px; padding: 22px 24px; border-radius: 14px; background: var(--x-mist); border: 1px solid var(--x-line); }
.tvbl__glance-client { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; margin-bottom: 16px; }
.tvbl__glance-client b { font-size: 17px; font-weight: 800; color: var(--x-ink); }
.tvbl__glance-client span { font-size: 14px; font-weight: 600; color: var(--x-muted); }
.tvbl__glance dl { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
.tvbl__glance dl > div { display: flex; flex-direction: column-reverse; gap: 4px; padding-left: 14px; border-left: 2px solid #D9E2EE; }
.tvbl__glance dd { font-size: clamp(22px, .8cqi + 16px, 28px); font-weight: 800; line-height: 1.05; color: var(--x-blue); font-variant-numeric: tabular-nums; }
.tvbl__glance dt { font-size: 13.5px; font-weight: 600; line-height: 1.35; color: var(--x-muted); }

.tvbl__body { font-size: 18px; line-height: 1.75; color: #2E3442; }
.tvbl__body > * + * { margin-top: 18px; }
.tvbl__body h2 { margin-top: 46px; font-weight: 800; font-size: clamp(24px, .8cqi + 18px, 30px); line-height: 1.2; letter-spacing: -.005em; color: var(--x-ink); text-wrap: balance; }
.tvbl__body h3 { margin-top: 30px; font-weight: 700; font-size: 21px; line-height: 1.3; color: var(--x-ink); }
.tvbl__body h2 + *, .tvbl__body h3 + * { margin-top: 12px; }
.tvbl__body strong { font-weight: 700; color: var(--x-ink); }
.tvbl__body a { color: var(--x-blue); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: rgba(8, 106, 217, .35); }
.tvbl__body a:hover { color: var(--x-blue-ink); text-decoration-color: currentColor; }
.tvbl__body ul, .tvbl__body ol { display: grid; gap: 10px; }
.tvbl__body ul > li { position: relative; padding-left: 26px; }
.tvbl__body ul > li::before { content: ""; position: absolute; left: 4px; top: .7em; width: 8px; height: 8px; border-radius: 50%; background: var(--x-beige); }
.tvbl__body ol:not(.tvbl__steps) { counter-reset: tvbl; }
.tvbl__body ol:not(.tvbl__steps) > li { position: relative; padding-left: 42px; counter-increment: tvbl; }
.tvbl__body ol:not(.tvbl__steps) > li::before { content: counter(tvbl); position: absolute; left: 0; top: .1em; width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; background: var(--x-blue-tint); color: var(--x-blue); font-size: 14px; font-weight: 800; line-height: 1; }
.tvbl__fig { margin-block: 32px; }
.tvbl__fig img { width: 100%; height: auto; border-radius: 14px; border: 1px solid var(--x-line); background: var(--x-mist); }
.tvbl__fig figcaption { margin-top: 10px; font-size: 14.5px; line-height: 1.5; color: var(--x-muted); }
.tvbl__note { margin-top: 32px; padding: 18px 20px; border-radius: 12px; background: var(--x-mist); border-left: 3px solid var(--x-blue); font-size: 16.5px; line-height: 1.6; }
.tvbl__steps { display: grid; gap: 12px; }
.tvbl__steps li { position: relative; padding: 16px 18px 16px 60px; border-radius: 12px; border: 1px solid var(--x-line); background: var(--x-paper); font-size: 17px; line-height: 1.6; }
.tvbl__steps li::before { content: ""; position: absolute; left: 18px; top: 18px; width: 26px; height: 26px; border-radius: 50%; background: var(--x-blue) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / 15px no-repeat; }
.tvbl__steps li.is-now::before { background: var(--x-paper); box-shadow: inset 0 0 0 3px var(--x-beige); }
.tvbl__steps li > span { display: inline-block; margin: 0 8px 4px 0; padding: 2px 9px; border-radius: 20px; font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; background: #E6F6EE; color: #0E7A47; vertical-align: 2px; }
.tvbl__steps li.is-now > span { background: #F8EEE7; color: #8A5A3E; }

/* author box under every article; the byline links to it */
.tvbl__meta .tvbl__by { color: inherit; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: #C3CBD8; }
.tvbl__meta .tvbl__by:hover { color: var(--x-ink); text-decoration-color: currentColor; }
.tvbl__author { display: flex; align-items: flex-start; gap: 18px; margin-top: 44px; padding: 22px 24px; border-radius: 14px; background: var(--x-mist); border: 1px solid var(--x-line); scroll-margin-top: 110px; }
.tvbl__author-mark { flex: none; width: 56px; height: 56px; border-radius: 50%; display: grid; place-items: center; background: var(--x-navy); color: #fff; font-size: 18px; font-weight: 800; letter-spacing: .04em; box-shadow: inset 0 0 0 2px var(--x-beige); }
.tvbl__author-kicker { font-size: 12.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--x-muted); }
.tvbl__author-name { margin-top: 4px; font-size: 19px; font-weight: 800; line-height: 1.3; color: var(--x-ink); }
.tvbl__author-role { margin-top: 2px; font-size: 14.5px; font-weight: 600; color: var(--x-blue-ink); }
.tvbl__author-bio { margin-top: 10px; font-size: 16px; line-height: 1.65; color: #3A4252; text-wrap: pretty; }
.tvbl__author + .tvbl__share { margin-top: 28px; }
.tvbl__share { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 44px; padding-top: 24px; border-top: 1px solid var(--x-line); }
.tvbl__share > span { margin-right: 6px; font-size: 14px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--x-muted); }
.tvx .tvbl__sh { width: 42px; height: 42px; border-radius: 50%; display: inline-grid; place-items: center; border: 1px solid var(--x-line); background: var(--x-paper); color: var(--x-ink); text-decoration: none; transition: background-color .2s ease, color .2s ease, border-color .2s ease; }
.tvx .tvbl__sh:hover { background: var(--x-ink); border-color: var(--x-ink); color: #fff; }
.tvbl__sh svg { width: 18px; height: 18px; }
.tvbl__copied { font-size: 14px; font-weight: 600; color: #0E7A47; opacity: 0; transition: opacity .2s ease; }
.tvbl__copied.is-on { opacity: 1; }
.tvbl .tvx__cta { margin-top: 0; }

@container tvx (max-width: 1020px) {
  .tvbl__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tvbl__grid--home > :nth-child(3) { display: none; }
}
@container tvx (max-width: 900px) {
  .tvbl__card--feature { grid-template-columns: minmax(0, 1fr); }
  .tvbl__card--feature .tvbl__card-img { aspect-ratio: 16 / 9; min-height: 0; }
  .tvbl__glance dl { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@container tvx (max-width: 640px) {
  .tvbl__author { flex-direction: column; gap: 12px; padding: 18px; }
  .tvbl__grid { grid-template-columns: minmax(0, 1fr); }
  .tvbl__grid--home > :nth-child(3) { display: flex; }
  .tvbl__body { font-size: 17px; }
  .tvbl__cover { border-radius: 12px; margin-inline: calc(-1 * clamp(0px, 2cqi, 8px)); }
}

.tvbl .tvx__inner--tight { padding-block: clamp(40px, 5cqi, 64px); }

</style>
<section class="tvx tvbl tvbl--post" aria-label="How Etoile Egypt went from a call centre to 520,000+ app users">
  <div class="tvbl__article">
    <div class="tvbl__meta tvbl__meta--top"><a class="tvbl__cat" data-cat="case-studies" href="https://topvieweg.com/blog/?cat=case-studies">Case study</a><span>14 October 2026</span><span>2 min read</span><span>By <a class="tvbl__by" href="#tvbl-author">Amr Bendary</a></span></div>
    <p class="tvbl__lede">Etoile Egypt moved its online orders from a busy call centre to its own app and website. Today the app has more than 520,000 users and takes thousands of orders a day, connected to the branches, ERP and POS.</p>
    <figure class="tvbl__cover"><img src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-etoile.jpg" width="1200" height="675" alt="Etoile Egypt app screens with the 520,000+ app users figure" decoding="async"></figure>
    <aside class="tvbl__glance" aria-label="At a glance"><div class="tvbl__glance-client"><b>Etoile Egypt</b><span>Patisserie chain · Egypt</span></div>
      <dl><div><dt>App users since January 2025</dt><dd>520K+</dd></div><div><dt>Food &amp; Drink chart, Egypt, March 2025</dt><dd>#2</dd></div><div><dt>Website visitors a month</dt><dd>350K+</dd></div><div><dt>Orders a day, app &amp; website</dt><dd>1.5K–4.5K</dd></div></dl>
    </aside>
    <div class="tvbl__body">
<h2>The challenge</h2>
<p>Etoile is a patisserie chain with dozens of branches in Egypt. A large share of its orders came through the call centre: every order needed an agent, a phone line and manual entry, and customers waited at the busiest times. The brand wanted a direct digital channel of its own, connected to the branches and to its systems.</p>

<h2>What we built</h2>
<ul>
  <li><strong>An app and website in Etoile’s name,</strong> for delivery and branch pickup.</li>
  <li><strong>The nearest branch, automatically.</strong> Customers pin their address on the map; the app checks coverage and sends the order to the branch that serves the area.</li>
  <li><strong>Online payment</strong> with cards and wallets, plus cash on delivery.</li>
  <li><strong>Etoile Stars,</strong> one loyalty account in the app and in the branch: stars on every purchase, a rewards menu, and a clear balance and expiry date.</li>
  <li><strong>Coupons, home-screen offers and targeted notifications.</strong></li>
  <li><strong>A central dashboard</strong> for orders, menu, prices and offers.</li>
  <li><strong>Integration with Microsoft Dynamics 365 Business Central and LS Central,</strong> so prices, stock and orders stay in sync with the branches.</li>
</ul>
<figure class="tvbl__fig"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/platform-loyalty.jpg" width="960" height="720" alt="Etoile Egypt rewards screens: stars balance and rewards menu" loading="lazy" decoding="async"><figcaption>Etoile Stars: customers see their balance at the top of the screen and swap stars for products.</figcaption></figure>

<h2>Listening to customers at scale</h2>
<p>The app includes short in-app surveys: star ratings, multiple choice and written feedback, five questions with a progress indicator. <strong>63,000 Etoile customers answered a single survey,</strong> and the results appear live in the dashboard: the average score for each question, the share of each answer, and every written comment in one place.</p>
<figure class="tvbl__fig"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/platform-dashboard.jpg" width="960" height="720" alt="In-app customer survey and the survey results dashboard" loading="lazy" decoding="async"><figcaption>The in-app survey and its live results in the dashboard.</figcaption></figure>

<h2>The results</h2>
<ul>
  <li><strong>520,000+ app users</strong> since January 2025.</li>
  <li><strong>#2 in the Food &amp; Drink chart</strong> on the App Store and Google Play in Egypt, in March 2025.</li>
  <li><strong>350,000+ website visitors</strong> a month.</li>
  <li><strong>1,500 to 4,500 orders a day</strong> through the app and the website.</li>
</ul>
<p>Above all, Etoile now has a direct sales channel it owns: it reaches customers with offers and takes thousands of orders a day, with no middleman.</p>

<h2>From Egypt to Saudi Arabia</h2>
<p>The same approach went to Saudi Arabia, with an app designed for the Saudi market and its own management for branches, orders and offers. Since March 2024, Etoile KSA has reached <strong>51,675 active users</strong>, <strong>13,200 website visitors a month</strong> and <strong>200 to 1,100 orders a day</strong>.</p>

<h2>What other brands can take from it</h2>
<ul>
  <li><strong>Connect before you launch.</strong> An app that is not linked to the branches and the ERP creates more calls, not fewer.</li>
  <li><strong>Make loyalty work everywhere.</strong> One account in the app and the branch gives customers a reason to order directly.</li>
  <li><strong>Ask your customers.</strong> A five-question survey can tell you more than months of guessing.</li>
  <li><strong>Treat the app as a channel, not a project.</strong> Offers, notifications and reports keep it growing after launch.</li>
</ul>
<p class="tvbl__note">Thinking about your own app? See <a href="https://topvieweg.com/service/mobile-app-development/">how we build mobile apps</a> for multi-branch brands.</p>
    </div>
    <aside class="tvbl__author" id="tvbl-author" aria-labelledby="tvbl-author-name">
      <span class="tvbl__author-mark" aria-hidden="true">AB</span>
      <div>
        <p class="tvbl__author-kicker">About the author</p>
        <p class="tvbl__author-name" id="tvbl-author-name">Amr Bendary</p>
        <p class="tvbl__author-role">Founder, Top View · CTO, Etoile</p>
        <p class="tvbl__author-bio">Founder of Top View and CTO at Etoile, Amr Bendary brings over 20 years of experience in digital transformation, mobile apps, e-commerce, and ERP integration. He holds an MBA in Digital Transformation and helps businesses connect technology with growth and operational efficiency.</p>
      </div>
    </aside>
    <div class="tvbl__share"><span>Share</span>
      <a class="tvbl__sh" href="https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Ftopvieweg.com%2Fetoile-egypt-app-case-study%2F" target="_blank" rel="noopener" aria-label="Share on LinkedIn"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M6.94 8.5H3.56V20h3.38V8.5ZM5.25 3a1.96 1.96 0 1 0 0 3.92 1.96 1.96 0 0 0 0-3.92ZM20.44 13.4c0-3.1-1.65-4.55-3.86-4.55-1.78 0-2.58.98-3.02 1.67V8.5h-3.38c.04.95 0 11.5 0 11.5h3.38v-6.42c0-.34.02-.69.13-.93.27-.69.9-1.4 1.95-1.4 1.38 0 1.93 1.05 1.93 2.59V20h3.37v-6.6Z"/></svg></a>
      <a class="tvbl__sh" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Ftopvieweg.com%2Fetoile-egypt-app-case-study%2F" target="_blank" rel="noopener" aria-label="Share on Facebook"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M13.5 21v-7.5h2.53l.38-2.93H13.5V8.7c0-.85.24-1.43 1.45-1.43h1.55V4.65a20.8 20.8 0 0 0-2.26-.12c-2.24 0-3.77 1.37-3.77 3.88v2.16H7.94v2.93h2.53V21h3.03Z"/></svg></a>
      <a class="tvbl__sh" href="https://wa.me/?text=How%20Etoile%20Egypt%20went%20from%20a%20call%20centre%20to%20520%2C000%2B%20app%20users%20https%3A%2F%2Ftopvieweg.com%2Fetoile-egypt-app-case-study%2F" target="_blank" rel="noopener" aria-label="Share on WhatsApp"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M17.47 14.38c-.3-.15-1.76-.87-2.03-.97-.27-.1-.47-.15-.67.15-.2.3-.77.97-.94 1.16-.17.2-.35.22-.64.07-.3-.15-1.26-.46-2.39-1.47-.88-.79-1.48-1.76-1.65-2.06-.17-.3-.02-.46.13-.61.13-.13.3-.35.45-.52.15-.17.2-.3.3-.5.1-.2.05-.37-.03-.52-.07-.15-.67-1.61-.92-2.21-.24-.58-.49-.5-.67-.51h-.57c-.2 0-.52.07-.79.37-.27.3-1.04 1.02-1.04 2.48 0 1.46 1.07 2.88 1.21 3.07.15.2 2.1 3.2 5.08 4.49.71.31 1.26.49 1.69.63.71.23 1.36.2 1.87.12.57-.09 1.76-.72 2-1.41.25-.7.25-1.29.18-1.41-.08-.13-.27-.2-.57-.35ZM12.05 21.79h-.01a9.87 9.87 0 0 1-5.03-1.38l-.36-.21-3.74.98 1-3.65-.24-.37a9.86 9.86 0 0 1-1.51-5.26c0-5.45 4.44-9.88 9.89-9.88a9.83 9.83 0 0 1 9.88 9.89c0 5.45-4.44 9.88-9.88 9.88Zm8.41-18.3A11.82 11.82 0 0 0 12.05 0C5.5 0 .16 5.34.16 11.89c0 2.1.55 4.14 1.59 5.95L.06 24l6.3-1.65a11.88 11.88 0 0 0 5.68 1.45h.01c6.55 0 11.89-5.34 11.89-11.89 0-3.18-1.24-6.17-3.48-8.42Z"/></svg></a>
      <a class="tvbl__sh" href="https://topvieweg.com/etoile-egypt-app-case-study/" data-copy aria-label="Copy link"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1"/><path d="M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1"/></svg></a><span class="tvbl__copied" aria-live="polite">Link copied</span>
    </div>
  </div>
  <div class="tvbl__band">
    <div class="tvx__inner tvx__inner--tight">
      <div class="tvx__cta" data-reveal>
        <div class="tvx__cta-text"><h3 class="tvx__cta-title">Planning something similar?</h3><p class="tvx__cta-body">Book a free meeting with our team. We will review how your branches work and suggest the right setup.</p></div>
        <div class="tvx__cta-actions">
          <a class="tvx__btn tvx__btn--primary" href="https://topvieweg.com/contact/" data-tvx="consultation" data-where="blog_etoile-egypt-app-case-study">Get a Free Consultation <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          <a class="tvx__btn tvx__btn--ghost" href="https://wa.me/201114000096?text=Hello%20TopView%2C%20I'm%20contacting%20you%20from%20your%20website%20(News%20article).%20I'd%20like%20to%20discuss%20a%20project." target="_blank" rel="noopener" data-tvx="whatsapp"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M17.47 14.38c-.3-.15-1.76-.87-2.03-.97-.27-.1-.47-.15-.67.15-.2.3-.77.97-.94 1.16-.17.2-.35.22-.64.07-.3-.15-1.26-.46-2.39-1.47-.88-.79-1.48-1.76-1.65-2.06-.17-.3-.02-.46.13-.61.13-.13.3-.35.45-.52.15-.17.2-.3.3-.5.1-.2.05-.37-.03-.52-.07-.15-.67-1.61-.92-2.21-.24-.58-.49-.5-.67-.51h-.57c-.2 0-.52.07-.79.37-.27.3-1.04 1.02-1.04 2.48 0 1.46 1.07 2.88 1.21 3.07.15.2 2.1 3.2 5.08 4.49.71.31 1.26.49 1.69.63.71.23 1.36.2 1.87.12.57-.09 1.76-.72 2-1.41.25-.7.25-1.29.18-1.41-.08-.13-.27-.2-.57-.35ZM12.05 21.79h-.01a9.87 9.87 0 0 1-5.03-1.38l-.36-.21-3.74.98 1-3.65-.24-.37a9.86 9.86 0 0 1-1.51-5.26c0-5.45 4.44-9.88 9.89-9.88a9.83 9.83 0 0 1 9.88 9.89c0 5.45-4.44 9.88-9.88 9.88Zm8.41-18.3A11.82 11.82 0 0 0 12.05 0C5.5 0 .16 5.34.16 11.89c0 2.1.55 4.14 1.59 5.95L.06 24l6.3-1.65a11.88 11.88 0 0 0 5.68 1.45h.01c6.55 0 11.89-5.34 11.89-11.89 0-3.18-1.24-6.17-3.48-8.42Z"/></svg> Chat on WhatsApp</a>
        </div>
      </div>
    </div>
  </div>
  <div class="tvbl__band tvbl__band--mist">
    <div class="tvx__inner">
      <div class="tvbl__head" data-reveal><h2 class="tvx__title">More articles</h2></div>
      <div class="tvbl__grid" data-tvbl-feed data-count="3" data-exclude="5572" data-reveal>
        <article class="tvbl__card" data-id="5571" data-cat="insights">
          <a class="tvbl__card-img" href="https://topvieweg.com/own-app-vs-delivery-apps/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-own-app.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="insights">Insight</span><span>14 Oct 2026</span><span>3 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/own-app-vs-delivery-apps/">Your own app or delivery apps? What changes for a multi-branch brand</a></h3>
            <p class="tvbl__card-ex">Delivery apps bring orders, but they keep the customer and take a share of every sale. Here is what changes when a multi-branch brand runs its own app and online store, and how to start without losing the orders you already have.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
        <article class="tvbl__card" data-id="5575" data-cat="guides">
          <a class="tvbl__card-img" href="https://topvieweg.com/what-is-ecommerce/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-g-what.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="guides">Guide</span><span>14 Oct 2026</span><span>2 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/what-is-ecommerce/">What is e-commerce? A plain guide for business owners</a></h3>
            <p class="tvbl__card-ex">E-commerce is more than a website with a cart. Here is what it really means for a restaurant, shop or brand, the channels it covers, and the parts that have to work together behind every online order.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
        <article class="tvbl__card" data-id="3197" data-cat="guides">
          <a class="tvbl__card-img" href="https://topvieweg.com/ecommerce-benefits/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-g-benefits.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="guides">Guide</span><span>14 Oct 2026</span><span>2 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/ecommerce-benefits/">7 ways e-commerce helps a business grow</a></h3>
            <p class="tvbl__card-ex">Selling online is not only about a new sales channel. Here are seven practical ways e-commerce helps restaurants, sweets brands and retailers grow, from more ordering hours to better decisions.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
      </div>
      <div class="tvbl__all"><a class="tvx__btn tvx__btn--outline" href="https://topvieweg.com/blog/">View all articles <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a></div>
    </div>
  </div>
</section>
<script>
(function () {
  var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  function fmt(n) { return Math.round(n).toLocaleString('en-US'); }
  function countUp(el) {
    var to = Number(el.getAttribute('data-n'));
    if (reduce || !to) return;
    var dur = 1200, t0 = null;
    el.textContent = fmt(0);
    requestAnimationFrame(function step(t) {
      if (t0 === null) t0 = t;
      var p = Math.min(1, (t - t0) / dur);
      el.textContent = fmt(to * (1 - Math.pow(1 - p, 3)));
      if (p < 1) requestAnimationFrame(step);
    });
    // always land on the real value, even if frames stall
    setTimeout(function () { el.textContent = fmt(to); }, dur + 400);
  }

  function init(root) {
    root.setAttribute('data-ready', '');
    root.classList.add('is-js');

    // scroll reveal (armed only here, so the section is complete without JS)
    var items = [].slice.call(root.querySelectorAll('[data-reveal]'));
    var drawTarget = root.querySelector('[data-draw]');
    if (!reduce && 'IntersectionObserver' in window) {
      root.classList.add('is-armed');
      var io = new IntersectionObserver(function (entries) {
        entries.forEach(function (e) {
          if (!e.isIntersecting) return;
          io.unobserve(e.target);
          if (e.target === drawTarget) {
            root.classList.add('is-drawn');
            [].slice.call(root.querySelectorAll('[data-n]')).forEach(countUp);
          } else {
            e.target.classList.add('is-in');
          }
        });
      }, { threshold: 0.15, rootMargin: '0px 0px -40px 0px' });
      items.forEach(function (el) { io.observe(el); });
      if (drawTarget) io.observe(drawTarget);
      // safety net: never leave content hidden
      setTimeout(function () { items.forEach(function (el) { el.classList.add('is-in'); }); root.classList.add('is-drawn'); }, 4000);
    } else {
      root.classList.add('is-drawn');
    }
    // looping decorations pause while the section is off screen
    if ('IntersectionObserver' in window) {
      new IntersectionObserver(function (entries) { root.classList.toggle('is-off', !entries[entries.length - 1].isIntersecting); }).observe(root);
    }

    // looping motion ([data-loop]) starts when first seen, so it opens on its first scene, and pauses off screen
    [].slice.call(root.querySelectorAll('[data-loop]')).forEach(function (el) {
      if (reduce || !('IntersectionObserver' in window)) return;
      new IntersectionObserver(function (entries) {
        var on = entries[entries.length - 1].isIntersecting; // several entries can queue up during a fast scroll; the last one is current
        if (on) el.classList.add('is-playing');
        el.classList.toggle('is-paused', !on);
      }, { threshold: 0.3 }).observe(el);
    });

    // tabs with a sliding highlight
    var tabs = [].slice.call(root.querySelectorAll('[role="tab"]'));
    if (!tabs.length) return;
    var panels = tabs.map(function (t) { return root.querySelector('#' + t.getAttribute('aria-controls')); });
    var ink = root.querySelector('.tvpf__ink');
    var list = tabs[0].parentNode;
    var current = Math.max(0, tabs.findIndex(function (t) { return t.getAttribute('aria-selected') === 'true'; }));
    function moveInk() {
      if (!ink) return;
      var t = tabs[current];
      ink.style.width = t.offsetWidth + 'px';
      ink.style.transform = 'translateX(' + t.offsetLeft + 'px)';
    }
    function show(n, focus) {
      if (n === current) return;
      current = (n + tabs.length) % tabs.length;
      tabs.forEach(function (t, k) {
        var on = k === current;
        t.classList.toggle('is-active', on);
        t.setAttribute('aria-selected', on ? 'true' : 'false');
        t.tabIndex = on ? 0 : -1;
      });
      panels.forEach(function (p, k) {
        var on = k === current;
        p.hidden = !on;
        p.classList.toggle('is-active', on);
        p.classList.remove('is-entering');
        if (on && !reduce) { void p.offsetWidth; p.classList.add('is-entering'); }
      });
      moveInk();
      var t = tabs[current];
      if (list.scrollWidth > list.clientWidth) list.scrollTo({ left: t.offsetLeft - (list.clientWidth - t.offsetWidth) / 2, behavior: reduce ? 'auto' : 'smooth' });
      if (focus) t.focus();
    }
    tabs.forEach(function (t, k) {
      t.addEventListener('click', function () { show(k); });
      t.addEventListener('keydown', function (e) {
        if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') { e.preventDefault(); show(current + (e.key === 'ArrowRight' ? 1 : -1), true); }
      });
    });
    moveInk();
    if (window.ResizeObserver) new ResizeObserver(moveInk).observe(list);
    window.addEventListener('load', moveInk);
  }

  [].slice.call(document.querySelectorAll('.tvx:not([data-ready])')).forEach(init);

  // calls to action: same tracking as the floating WhatsApp button and the home CTA
  // (each section ships this script, so register the listener only once per page)
  if (window.__tvxCtaTracking) return;
  window.__tvxCtaTracking = true;
  document.addEventListener('click', function (e) {
    var a = e.target.closest && e.target.closest('.tvx a[data-tvx]');
    if (!a) return;
    if (a.getAttribute('data-tvx') === 'whatsapp') {
      if (typeof gtag === 'function') { gtag('event', 'contact', { method: 'WhatsApp', link_url: a.href }); }
      if (typeof fbq === 'function') { fbq('track', 'Contact', { content_name: 'WhatsApp' }); }
      if (typeof window.lintrk === 'function') { window.lintrk('track', { conversion_id: 31200418 }); }
    } else if (typeof gtag === 'function') {
      gtag('event', 'cta_click', { cta: 'free_consultation', location: a.getAttribute('data-where') || 'section' });
    }
  });
})();

(function () {
  if (window.__tvblReady) return;
  window.__tvblReady = true;

  var CAT = { guides: 'Guide', 'case-studies': 'Case study', insights: 'Insight' };
  var arrow = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg>';
  var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

  function text(html, sel) {
    var d = document.createElement('div'); d.innerHTML = html || '';
    [].slice.call(d.querySelectorAll('style,script')).forEach(function (n) { n.remove(); });
    var part = sel && d.querySelector(sel);
    return ((part || d).textContent || '').replace(/\s+/g, ' ').trim();
  }
  function esc(s) { return String(s).replace(/[&<>"]/g, function (c) { return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c]; }); }

  // the same card markup the build script prints, rebuilt from the REST API so new posts show up on their own
  // mins comes from the card the build printed for that post; a post published later shows no reading time
  // p.tv_card = { img, cat, cat_name } is a small REST field added by the "TopView speed & SEO tweaks" snippet
  function card(p, feature, mins) {
    var tc = p.tv_card || {};
    var img = tc.img || '';
    var term = { slug: tc.cat || '', name: tc.cat_name || '' };
    var d = new Date(p.date);
    return '<article class="tvbl__card' + (feature ? ' tvbl__card--feature' : '') + '" data-id="' + p.id + '" data-cat="' + esc(term.slug || '') + '">' +
      (img ? '<a class="tvbl__card-img" href="' + esc(p.link) + '" tabindex="-1" aria-hidden="true"><img loading="lazy" src="' + esc(img) + '" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>' : '') +
      '<div class="tvbl__card-body"><div class="tvbl__meta">' + (term.slug ? '<span class="tvbl__cat" data-cat="' + esc(term.slug) + '">' + esc(CAT[term.slug] || term.name) + '</span>' : '') +
      '<span>' + d.getDate() + ' ' + months[d.getMonth()] + ' ' + d.getFullYear() + '</span>' + (mins ? '<span>' + mins + ' min read</span>' : '') + '</div>' +
      '<h3 class="tvbl__card-title"><a href="' + esc(p.link) + '">' + p.title.rendered + '</a></h3>' +
      '<p class="tvbl__card-ex">' + esc(text(p.excerpt && p.excerpt.rendered)) + '</p>' +
      '<span class="tvbl__more" aria-hidden="true">Read article ' + arrow + '</span></div></article>';
  }

  function applyFilter(root, cat) {
    var cards = [].slice.call(root.querySelectorAll('.tvbl__card'));
    var shown = 0;
    cards.forEach(function (c) { var on = !cat || c.getAttribute('data-cat') === cat; c.hidden = !on; if (on) shown++; });
    [].slice.call(root.querySelectorAll('.tvbl__filter')).forEach(function (b) { b.setAttribute('aria-pressed', String((b.getAttribute('data-cat') || '') === (cat || ''))); });
    var empty = root.querySelector('.tvbl__empty');
    if (empty) empty.hidden = shown > 0;
  }

  function initFilters() {
    [].slice.call(document.querySelectorAll('.tvbl [data-tvbl-filters]')).forEach(function (bar) {
      var root = bar.closest('.tvbl');
      if (bar.getAttribute('data-ready')) { var cur = bar.querySelector('[aria-pressed="true"]'); applyFilter(root, cur ? cur.getAttribute('data-cat') || '' : ''); return; }
      bar.setAttribute('data-ready', '1');
      bar.addEventListener('click', function (e) {
        var b = e.target.closest('.tvbl__filter');
        if (!b) return;
        applyFilter(root, b.getAttribute('data-cat') || '');
      });
      var m = location.search.match(/[?&]cat=([a-z-]+)/);
      applyFilter(root, m ? m[1] : '');
    });
  }

  // copy link
  document.addEventListener('click', function (e) {
    var b = e.target.closest && e.target.closest('.tvbl [data-copy]');
    if (!b) return;
    e.preventDefault();
    var done = function () { var t = b.parentNode.querySelector('.tvbl__copied'); if (t) { t.classList.add('is-on'); setTimeout(function () { t.classList.remove('is-on'); }, 1800); } };
    if (navigator.clipboard) navigator.clipboard.writeText(location.href.split('#')[0]).then(done, function () {}); else done();
  });

  var feeds = [].slice.call(document.querySelectorAll('[data-tvbl-feed]'));
  initFilters();
  if (!feeds.length || !window.fetch) return;

  // Only the fields a card shows (the full post content made this ~600 KB), and only once a feed
  // comes near the screen, so the request never competes with the page's first paint.
  var loaded = false;
  function refresh() {
    if (loaded) return;
    loaded = true;
    var mins = {};
    [].forEach.call(document.querySelectorAll('.tvbl__card[data-id]'), function (c) {
      var m = (c.textContent || '').match(/(\d+) min read/);
      if (m) mins[c.getAttribute('data-id')] = m[1];
    });
    fetch('/wp-json/wp/v2/posts?per_page=12&_fields=id,date,link,title,excerpt,tv_card', { credentials: 'omit' })
      .then(function (r) { return r.ok ? r.json() : Promise.reject(r.status); })
      .then(function (posts) {
        if (!Array.isArray(posts) || !posts.length || !posts[0].tv_card) return; // keep the printed cards if the field is missing
        feeds.forEach(function (feed) {
          var max = Number(feed.getAttribute('data-count')) || posts.length;
          var skip = Number(feed.getAttribute('data-exclude')) || 0;
          var list = posts.filter(function (p) { return p.id !== skip; }).slice(0, max);
          var have = [].map.call(feed.querySelectorAll('.tvbl__card'), function (el) { return el.getAttribute('data-id'); }).join();
          if (have === list.map(function (p) { return String(p.id); }).join()) return; // the printed cards are already current
          var feature = feed.hasAttribute('data-feature');
          feed.innerHTML = list.map(function (p, i) { return card(p, feature && i === 0, mins[p.id]); }).join('');
        });
        initFilters();
      })
      .catch(function () {});
  }
  if ('IntersectionObserver' in window) {
    var io = new IntersectionObserver(function (entries) {
      if (entries.some(function (e) { return e.isIntersecting; })) { io.disconnect(); refresh(); }
    }, { rootMargin: '600px 0px' });
    feeds.forEach(function (f) { io.observe(f); });
  } else {
    window.addEventListener('load', refresh);
  }
})();

</script>
				</div>
				</div>
				</div>
				</div>
		<p>The post <a href="https://topvieweg.com/etoile-egypt-app-case-study/">How Etoile Egypt went from a call centre to 520,000+ app users</a> appeared first on <a href="https://topvieweg.com">TopView</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>7 ways e-commerce helps a business grow</title>
		<link>https://topvieweg.com/ecommerce-benefits/</link>
		
		<dc:creator><![CDATA[TopView Team]]></dc:creator>
		<pubDate>Wed, 14 Oct 2026 08:30:00 +0000</pubDate>
				<category><![CDATA[Guides]]></category>
		<guid isPermaLink="false">https://tplabs.co/izeetak/?p=3197</guid>

					<description><![CDATA[<p>Selling online is not only about a new sales channel. Here are seven practical ways e-commerce helps restaurants, sweets brands and retailers grow, from more ordering hours to better decisions.</p>
<p>The post <a href="https://topvieweg.com/ecommerce-benefits/">7 ways e-commerce helps a business grow</a> appeared first on <a href="https://topvieweg.com">TopView</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="3197" class="elementor elementor-3197" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-tvb3197c e-con-full e-flex e-con e-parent" data-id="tvb3197c" data-element_type="container" data-e-type="container">
				<div class="elementor-element elementor-element-tvb3197w elementor-widget elementor-widget-html" data-id="tvb3197w" data-element_type="widget" data-e-type="widget" data-widget_type="html.default">
				<div class="elementor-widget-container">
					<!-- TopView blog: article ecommerce-benefits. Generated by live-site/blog/build.js from articles.js; edit there and rebuild. -->
<style>
/* Shared base for the TopView platform (.tvpf) and discount-system (.tvdm) sections.
   The izeetak theme styles every <button> (70px line height, 60px side padding, uppercase, wide tracking),
   sets body line height to 2 and decorates lists, so each section resets those inside itself. */
.tvx {
  --x-ink: #1B1825;
  --x-muted: #5A6475;
  --x-line: #E3E8EF;
  --x-paper: #FFFFFF;
  --x-mist: #F4F7FB;
  --x-blue: #086AD9;
  --x-blue-ink: #0757B3;
  --x-blue-tint: #E7F0FC;
  --x-beige: #D2A88F;
  --x-beige-lite: #E7C7B2;
  --x-navy: #06142B;
  --x-navy-2: #0B2A55;
  --x-ease: cubic-bezier(.2, .8, .2, 1);
  container: tvx / inline-size;
  position: relative;
  width: 100%;
  font-family: "Barlow", "Segoe UI", system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.5;
  color: var(--x-ink);
  text-align: left;
}
.elementor-widget:has(> .elementor-widget-container > .tvx) { width: 100%; min-width: 0; }
.tvx *, .tvx *::before, .tvx *::after { box-sizing: border-box; }
/* Element-weight resets (0,0,1): they still beat the theme (same weight, later in the page) but lose to every
   class rule, even when a second section on the page repeats this file after the first section’s rules. */
:where(.tvx) :is(h2, h3, h4, p, ul, ol, li, dl, dt, dd, figure) { margin: 0; padding: 0; }
:where(.tvx) :is(ul, ol) { list-style: none; }
:where(.tvx) li::before, :where(.tvx) li::after { content: none; }
:where(.tvx) img { display: block; max-width: 100%; height: auto; }
.tvx button { min-width: 0; min-height: 0; margin: 0; padding: 0; border: 0; background: none; color: inherit; font: inherit; line-height: inherit; letter-spacing: normal; text-transform: none; cursor: pointer; }
.tvx button:hover, .tvx button:focus { background: none; color: inherit; }
.tvx :focus-visible { outline: 3px solid var(--x-blue); outline-offset: 3px; }

.tvx__inner { max-width: 1200px; margin: 0 auto; padding-inline: clamp(16px, 4cqi, 32px); padding-block: clamp(56px, 7cqi, 96px); }
.tvx__head { max-width: 720px; margin-bottom: clamp(28px, 4cqi, 48px); }
.tvx__title { font-weight: 800; font-size: clamp(30px, 2.4cqi + 14px, 46px); line-height: 1.08; letter-spacing: -.01em; color: var(--x-ink); text-wrap: balance; margin-bottom: 14px; }
.tvx__lede { font-size: clamp(16px, .5cqi + 12px, 19px); line-height: 1.65; font-weight: 500; color: var(--x-muted); text-wrap: pretty; }
.tvx__h3 { font-weight: 800; font-size: clamp(21px, .8cqi + 15px, 26px); line-height: 1.2; color: var(--x-ink); margin-bottom: 18px; text-wrap: balance; }

.tvx__icon { flex: none; width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center; background: var(--x-blue-tint); color: var(--x-blue); }
.tvx__icon svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

.tvx__chips { display: flex; flex-wrap: wrap; gap: 8px; }
.tvx__chips li { padding: 7px 13px; border: 1px solid var(--x-line); border-radius: 20px; background: var(--x-paper); font-size: 14px; font-weight: 600; line-height: 1.3; color: var(--x-ink); }

/* closing call to action */
.tvx__cta { margin-top: clamp(40px, 5cqi, 64px); border-radius: 14px; padding: clamp(28px, 4cqi, 44px); display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 24px 40px; color: #fff; background: radial-gradient(60% 120% at 85% 0%, rgba(8, 106, 217, .55), transparent 70%), linear-gradient(160deg, var(--x-navy-2), var(--x-navy)); }
.tvx__cta-text { min-width: 0; max-width: 560px; }
.tvx__cta-title { font-weight: 800; font-size: clamp(22px, 1cqi + 15px, 30px); line-height: 1.2; color: #fff; text-wrap: balance; }
.tvx__cta-body { margin-top: 8px; font-size: 16px; line-height: 1.6; color: rgba(255, 255, 255, .82); }
.tvx__cta-actions { display: flex; flex-wrap: wrap; gap: 12px; }
.tvx__btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 52px; padding: 0 22px; border-radius: 8px; font-weight: 700; font-size: 14px; line-height: 1; letter-spacing: .1em; text-transform: uppercase; text-decoration: none; white-space: nowrap; transition: background-color .2s ease, border-color .2s ease, transform .2s ease; }
.tvx__btn svg { width: 18px; height: 18px; flex: none; }
.tvx__btn--primary { background: var(--x-beige); color: var(--x-ink); }
.tvx__btn--primary:hover, .tvx__btn--primary:focus { background: var(--x-beige-lite); color: var(--x-ink); }
.tvx__btn--ghost { color: #fff; border: 1.5px solid rgba(255, 255, 255, .34); }
.tvx__btn--ghost:hover, .tvx__btn--ghost:focus { color: #fff; border-color: #fff; background: rgba(255, 255, 255, .06); }
.tvx__btn:active { transform: translateY(1px); }
.tvx__btn:focus-visible { outline-color: var(--x-beige-lite); }

/* scroll reveal: only armed by JS, so content is visible without it */
.tvx.is-armed [data-reveal] { opacity: 0; transform: translateY(16px); transition: opacity .7s var(--x-ease), transform .7s var(--x-ease); transition-delay: calc(var(--i, 0) * 70ms); }
.tvx.is-armed [data-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .tvx *, .tvx *::before, .tvx *::after { animation: none !important; transition: none !important; }
  .tvx.is-armed [data-reveal] { opacity: 1; transform: none; }
}
@container tvx (max-width: 560px) {
  .tvx__cta-actions { width: 100%; flex-direction: column; }
  .tvx__btn { width: 100%; padding: 14px 16px; letter-spacing: .07em; white-space: normal; text-align: center; line-height: 1.3; }
}

/* ===== Blog (.tvbl): home "News & Articles" section, the News page and the article page. Builds on ../platform/tv-shared.css ===== */
.tvbl { background: var(--x-paper); }
.tvbl__band { width: 100%; }
.tvbl__band--mist { background: var(--x-mist); }

/* section head (home + news page) */
.tvbl__head { max-width: 760px; margin-bottom: clamp(28px, 4cqi, 44px); }
.tvbl__head--center { margin-inline: auto; text-align: center; }
.tvbl__eyebrow { display: inline-flex; align-items: center; gap: 10px; margin-bottom: 10px; font-size: 16px; font-weight: 600; color: var(--x-muted); }
.tvbl__eyebrow::before { content: ""; width: 14px; height: 2px; background: var(--x-beige); }
.tvbl__head--center .tvx__title { margin-inline: auto; }
.tvbl__head--center .tvx__lede { margin-inline: auto; max-width: 640px; }

/* cards */
.tvbl__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.tvbl__card { position: relative; display: flex; flex-direction: column; border-radius: 16px; overflow: hidden; background: var(--x-paper); border: 1px solid var(--x-line); transition: border-color .25s ease, box-shadow .25s ease, transform .25s ease; }
.tvbl__card:hover { border-color: #C9D3E0; box-shadow: 0 22px 40px -28px rgba(6, 20, 43, .45); transform: translateY(-3px); }
.tvbl__card-img { display: block; aspect-ratio: 16 / 9; overflow: hidden; background: var(--x-navy); }
.tvbl__card-img img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--x-ease); }
.tvbl__card:hover .tvbl__card-img img { transform: scale(1.03); }
.tvbl__card-body { display: flex; flex-direction: column; gap: 10px; flex: 1; padding: 20px 22px 22px; }
.tvbl__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; font-size: 13.5px; font-weight: 600; line-height: 1.3; color: var(--x-muted); }
.tvbl__meta > span + span::before { content: ""; display: inline-block; width: 4px; height: 4px; margin: 0 10px 2px 0; border-radius: 50%; background: #C3CBD8; vertical-align: middle; }
.tvbl__cat { display: inline-block; padding: 4px 10px; border-radius: 20px; background: var(--x-blue-tint); color: var(--x-blue-ink); font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; text-decoration: none; }
.tvbl__cat[data-cat="case-studies"] { background: #F8EEE7; color: #8A5A3E; }
.tvbl__cat[data-cat="guides"] { background: #E6F6EE; color: #0E7A47; }
a.tvbl__cat:hover { filter: brightness(.96); }
.tvbl__card-title { font-weight: 700; font-size: 20px; line-height: 1.3; color: var(--x-ink); text-wrap: balance; }
.tvbl__card-title a { color: inherit; text-decoration: none; }
.tvbl__card-title a::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.tvbl__card-title a:focus-visible { outline: none; }
.tvbl__card:has(.tvbl__card-title a:focus-visible) { outline: 3px solid var(--x-blue); outline-offset: 3px; }
.tvbl__card-ex { font-size: 15px; line-height: 1.6; color: var(--x-muted); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.tvbl__more { margin-top: auto; padding-top: 6px; display: inline-flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--x-blue); }
.tvbl__more svg { width: 16px; height: 16px; transition: transform .2s ease; }
.tvbl__card:hover .tvbl__more svg { transform: translateX(4px); }

/* featured (first) card on the news page */
.tvbl__card--feature { grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.tvbl__card--feature .tvbl__card-img { aspect-ratio: auto; min-height: 100%; }
.tvbl__card--feature .tvbl__card-body { justify-content: center; gap: 14px; padding: clamp(24px, 3.4cqi, 44px); }
.tvbl__card--feature .tvbl__card-title { font-size: clamp(24px, 1.2cqi + 14px, 32px); line-height: 1.2; }
.tvbl__card--feature .tvbl__card-ex { font-size: 16.5px; -webkit-line-clamp: 4; }

/* filter chips (news page) */
.tvbl__filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 26px; }
.tvx .tvbl__filter { padding: 9px 16px; border-radius: 30px; border: 1px solid var(--x-line); background: var(--x-paper); font-size: 14.5px; font-weight: 700; line-height: 1.2; color: var(--x-ink); transition: background-color .2s ease, color .2s ease, border-color .2s ease; }
.tvx .tvbl__filter:hover { border-color: #C9D3E0; background: var(--x-paper); color: var(--x-ink); }
.tvx .tvbl__filter[aria-pressed="true"] { background: var(--x-ink); border-color: var(--x-ink); color: #fff; }
.tvbl__card[hidden] { display: none; }
.tvbl__empty { padding: 40px; text-align: center; color: var(--x-muted); }

.tvbl__all { display: flex; justify-content: center; margin-top: clamp(28px, 4cqi, 40px); }
.tvbl .tvx__btn--outline { color: var(--x-ink); border: 1.5px solid #C9D3E0; }
.tvbl .tvx__btn--outline:hover, .tvbl .tvx__btn--outline:focus { color: var(--x-ink); border-color: var(--x-ink); }
.tvbl .tvx__btn--outline:focus-visible { outline-color: var(--x-blue); }

/* ---------- article page ---------- */
.tvbl__article { max-width: 960px; margin: 0 auto; padding-inline: clamp(16px, 4cqi, 32px); padding-block: clamp(40px, 6cqi, 72px) clamp(48px, 6cqi, 80px); }
.tvbl__article > :not(.tvbl__cover) { max-width: 720px; margin-inline: auto; }
.tvbl__meta--top { margin-bottom: 18px; font-size: 14.5px; }
.tvbl__lede { font-size: clamp(19px, .6cqi + 15px, 22px); line-height: 1.6; font-weight: 500; color: #3A4252; text-wrap: pretty; }
.tvbl__cover { margin: clamp(28px, 4cqi, 40px) 0; border-radius: 18px; overflow: hidden; background: var(--x-navy); box-shadow: 0 30px 60px -40px rgba(6, 20, 43, .55); }
.tvbl__cover img { width: 100%; height: auto; }

.tvbl__glance { margin-bottom: 36px; padding: 22px 24px; border-radius: 14px; background: var(--x-mist); border: 1px solid var(--x-line); }
.tvbl__glance-client { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; margin-bottom: 16px; }
.tvbl__glance-client b { font-size: 17px; font-weight: 800; color: var(--x-ink); }
.tvbl__glance-client span { font-size: 14px; font-weight: 600; color: var(--x-muted); }
.tvbl__glance dl { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
.tvbl__glance dl > div { display: flex; flex-direction: column-reverse; gap: 4px; padding-left: 14px; border-left: 2px solid #D9E2EE; }
.tvbl__glance dd { font-size: clamp(22px, .8cqi + 16px, 28px); font-weight: 800; line-height: 1.05; color: var(--x-blue); font-variant-numeric: tabular-nums; }
.tvbl__glance dt { font-size: 13.5px; font-weight: 600; line-height: 1.35; color: var(--x-muted); }

.tvbl__body { font-size: 18px; line-height: 1.75; color: #2E3442; }
.tvbl__body > * + * { margin-top: 18px; }
.tvbl__body h2 { margin-top: 46px; font-weight: 800; font-size: clamp(24px, .8cqi + 18px, 30px); line-height: 1.2; letter-spacing: -.005em; color: var(--x-ink); text-wrap: balance; }
.tvbl__body h3 { margin-top: 30px; font-weight: 700; font-size: 21px; line-height: 1.3; color: var(--x-ink); }
.tvbl__body h2 + *, .tvbl__body h3 + * { margin-top: 12px; }
.tvbl__body strong { font-weight: 700; color: var(--x-ink); }
.tvbl__body a { color: var(--x-blue); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: rgba(8, 106, 217, .35); }
.tvbl__body a:hover { color: var(--x-blue-ink); text-decoration-color: currentColor; }
.tvbl__body ul, .tvbl__body ol { display: grid; gap: 10px; }
.tvbl__body ul > li { position: relative; padding-left: 26px; }
.tvbl__body ul > li::before { content: ""; position: absolute; left: 4px; top: .7em; width: 8px; height: 8px; border-radius: 50%; background: var(--x-beige); }
.tvbl__body ol:not(.tvbl__steps) { counter-reset: tvbl; }
.tvbl__body ol:not(.tvbl__steps) > li { position: relative; padding-left: 42px; counter-increment: tvbl; }
.tvbl__body ol:not(.tvbl__steps) > li::before { content: counter(tvbl); position: absolute; left: 0; top: .1em; width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; background: var(--x-blue-tint); color: var(--x-blue); font-size: 14px; font-weight: 800; line-height: 1; }
.tvbl__fig { margin-block: 32px; }
.tvbl__fig img { width: 100%; height: auto; border-radius: 14px; border: 1px solid var(--x-line); background: var(--x-mist); }
.tvbl__fig figcaption { margin-top: 10px; font-size: 14.5px; line-height: 1.5; color: var(--x-muted); }
.tvbl__note { margin-top: 32px; padding: 18px 20px; border-radius: 12px; background: var(--x-mist); border-left: 3px solid var(--x-blue); font-size: 16.5px; line-height: 1.6; }
.tvbl__steps { display: grid; gap: 12px; }
.tvbl__steps li { position: relative; padding: 16px 18px 16px 60px; border-radius: 12px; border: 1px solid var(--x-line); background: var(--x-paper); font-size: 17px; line-height: 1.6; }
.tvbl__steps li::before { content: ""; position: absolute; left: 18px; top: 18px; width: 26px; height: 26px; border-radius: 50%; background: var(--x-blue) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / 15px no-repeat; }
.tvbl__steps li.is-now::before { background: var(--x-paper); box-shadow: inset 0 0 0 3px var(--x-beige); }
.tvbl__steps li > span { display: inline-block; margin: 0 8px 4px 0; padding: 2px 9px; border-radius: 20px; font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; background: #E6F6EE; color: #0E7A47; vertical-align: 2px; }
.tvbl__steps li.is-now > span { background: #F8EEE7; color: #8A5A3E; }

/* author box under every article; the byline links to it */
.tvbl__meta .tvbl__by { color: inherit; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: #C3CBD8; }
.tvbl__meta .tvbl__by:hover { color: var(--x-ink); text-decoration-color: currentColor; }
.tvbl__author { display: flex; align-items: flex-start; gap: 18px; margin-top: 44px; padding: 22px 24px; border-radius: 14px; background: var(--x-mist); border: 1px solid var(--x-line); scroll-margin-top: 110px; }
.tvbl__author-mark { flex: none; width: 56px; height: 56px; border-radius: 50%; display: grid; place-items: center; background: var(--x-navy); color: #fff; font-size: 18px; font-weight: 800; letter-spacing: .04em; box-shadow: inset 0 0 0 2px var(--x-beige); }
.tvbl__author-kicker { font-size: 12.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--x-muted); }
.tvbl__author-name { margin-top: 4px; font-size: 19px; font-weight: 800; line-height: 1.3; color: var(--x-ink); }
.tvbl__author-role { margin-top: 2px; font-size: 14.5px; font-weight: 600; color: var(--x-blue-ink); }
.tvbl__author-bio { margin-top: 10px; font-size: 16px; line-height: 1.65; color: #3A4252; text-wrap: pretty; }
.tvbl__author + .tvbl__share { margin-top: 28px; }
.tvbl__share { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 44px; padding-top: 24px; border-top: 1px solid var(--x-line); }
.tvbl__share > span { margin-right: 6px; font-size: 14px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--x-muted); }
.tvx .tvbl__sh { width: 42px; height: 42px; border-radius: 50%; display: inline-grid; place-items: center; border: 1px solid var(--x-line); background: var(--x-paper); color: var(--x-ink); text-decoration: none; transition: background-color .2s ease, color .2s ease, border-color .2s ease; }
.tvx .tvbl__sh:hover { background: var(--x-ink); border-color: var(--x-ink); color: #fff; }
.tvbl__sh svg { width: 18px; height: 18px; }
.tvbl__copied { font-size: 14px; font-weight: 600; color: #0E7A47; opacity: 0; transition: opacity .2s ease; }
.tvbl__copied.is-on { opacity: 1; }
.tvbl .tvx__cta { margin-top: 0; }

@container tvx (max-width: 1020px) {
  .tvbl__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tvbl__grid--home > :nth-child(3) { display: none; }
}
@container tvx (max-width: 900px) {
  .tvbl__card--feature { grid-template-columns: minmax(0, 1fr); }
  .tvbl__card--feature .tvbl__card-img { aspect-ratio: 16 / 9; min-height: 0; }
  .tvbl__glance dl { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@container tvx (max-width: 640px) {
  .tvbl__author { flex-direction: column; gap: 12px; padding: 18px; }
  .tvbl__grid { grid-template-columns: minmax(0, 1fr); }
  .tvbl__grid--home > :nth-child(3) { display: flex; }
  .tvbl__body { font-size: 17px; }
  .tvbl__cover { border-radius: 12px; margin-inline: calc(-1 * clamp(0px, 2cqi, 8px)); }
}

.tvbl .tvx__inner--tight { padding-block: clamp(40px, 5cqi, 64px); }

</style>
<section class="tvx tvbl tvbl--post" aria-label="7 ways e-commerce helps a business grow">
  <div class="tvbl__article">
    <div class="tvbl__meta tvbl__meta--top"><a class="tvbl__cat" data-cat="guides" href="https://topvieweg.com/blog/?cat=guides">Guide</a><span>14 October 2026</span><span>2 min read</span><span>By <a class="tvbl__by" href="#tvbl-author">Amr Bendary</a></span></div>
    <p class="tvbl__lede">Selling online is not only about a new sales channel. Here are seven practical ways e-commerce helps restaurants, sweets brands and retailers grow, from more ordering hours to better decisions.</p>
    <figure class="tvbl__cover"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-g-benefits.jpg" width="1200" height="675" alt="7 ways e-commerce helps a business grow, shown as a rising chart" decoding="async"></figure>
    <div class="tvbl__body">
<p>E-commerce is often sold as “more sales”. The real benefits are more specific, and they add up over time. Here are seven we see again and again with multi-branch brands.</p>

<h2>1. Customers can order when it suits them</h2>
<p>Your phone line has opening hours; an online store does not. Customers can browse late at night, schedule an order for tomorrow, or order for pickup on the way home.</p>

<h2>2. You reach customers across all your branches</h2>
<p>With delivery zones for each branch, a customer anywhere in your coverage can order, and the order goes to the branch that serves their address.</p>

<h2>3. Fewer phone calls, fewer mistakes</h2>
<p>When the customer types the order, nobody has to copy it by hand. When the store is connected to your POS or ERP, the order reaches the branch exactly as placed, with the right prices and items.</p>

<h2>4. You get to know your customers</h2>
<p>Every online order tells you who bought what, when and where. Over time that shows your best products, your busiest hours and the customers who have stopped ordering.</p>

<h2>5. Customers come back</h2>
<p>Points on every purchase, coupons for occasions and notifications about new products give customers a reason to order from you again, instead of from whoever is first on a delivery app.</p>

<h2>6. Your brand stays in your hands</h2>
<p>On your own website or app, there are no competitors on the page. You decide how products look, which offers run and what the customer sees first.</p>

<h2>7. Decisions based on numbers</h2>
<p>A dashboard with sales by branch and by channel replaces guesswork. You can see which offer worked, which branch needs help, and where orders get stuck.</p>

<h2>What it can look like</h2>
<p>Abo Mehram, a new sweets brand, reached 30,000 active users in its first two months online, with up to 1,800 orders a day. Etoile Egypt’s app reached #2 in the Food &amp; Drink chart on the App Store and Google Play in Egypt in March 2025. <a href="https://topvieweg.com/etoile-egypt-app-case-study/">Read how Etoile did it</a>.</p>

<h2>A fair warning</h2>
<p>None of this happens by itself. The benefits come when the store is connected to your branches and someone keeps the products, prices and offers alive. That is the difference between an online store that grows and one that is quietly forgotten.</p>
<p class="tvbl__note">Wondering if the timing is right? Read <a href="https://topvieweg.com/ready-to-sell-online/">8 signs your business is ready to sell online</a>.</p>
    </div>
    <aside class="tvbl__author" id="tvbl-author" aria-labelledby="tvbl-author-name">
      <span class="tvbl__author-mark" aria-hidden="true">AB</span>
      <div>
        <p class="tvbl__author-kicker">About the author</p>
        <p class="tvbl__author-name" id="tvbl-author-name">Amr Bendary</p>
        <p class="tvbl__author-role">Founder, Top View · CTO, Etoile</p>
        <p class="tvbl__author-bio">Founder of Top View and CTO at Etoile, Amr Bendary brings over 20 years of experience in digital transformation, mobile apps, e-commerce, and ERP integration. He holds an MBA in Digital Transformation and helps businesses connect technology with growth and operational efficiency.</p>
      </div>
    </aside>
    <div class="tvbl__share"><span>Share</span>
      <a class="tvbl__sh" href="https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Ftopvieweg.com%2Fecommerce-benefits%2F" target="_blank" rel="noopener" aria-label="Share on LinkedIn"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M6.94 8.5H3.56V20h3.38V8.5ZM5.25 3a1.96 1.96 0 1 0 0 3.92 1.96 1.96 0 0 0 0-3.92ZM20.44 13.4c0-3.1-1.65-4.55-3.86-4.55-1.78 0-2.58.98-3.02 1.67V8.5h-3.38c.04.95 0 11.5 0 11.5h3.38v-6.42c0-.34.02-.69.13-.93.27-.69.9-1.4 1.95-1.4 1.38 0 1.93 1.05 1.93 2.59V20h3.37v-6.6Z"/></svg></a>
      <a class="tvbl__sh" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Ftopvieweg.com%2Fecommerce-benefits%2F" target="_blank" rel="noopener" aria-label="Share on Facebook"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M13.5 21v-7.5h2.53l.38-2.93H13.5V8.7c0-.85.24-1.43 1.45-1.43h1.55V4.65a20.8 20.8 0 0 0-2.26-.12c-2.24 0-3.77 1.37-3.77 3.88v2.16H7.94v2.93h2.53V21h3.03Z"/></svg></a>
      <a class="tvbl__sh" href="https://wa.me/?text=7%20ways%20e-commerce%20helps%20a%20business%20grow%20https%3A%2F%2Ftopvieweg.com%2Fecommerce-benefits%2F" target="_blank" rel="noopener" aria-label="Share on WhatsApp"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M17.47 14.38c-.3-.15-1.76-.87-2.03-.97-.27-.1-.47-.15-.67.15-.2.3-.77.97-.94 1.16-.17.2-.35.22-.64.07-.3-.15-1.26-.46-2.39-1.47-.88-.79-1.48-1.76-1.65-2.06-.17-.3-.02-.46.13-.61.13-.13.3-.35.45-.52.15-.17.2-.3.3-.5.1-.2.05-.37-.03-.52-.07-.15-.67-1.61-.92-2.21-.24-.58-.49-.5-.67-.51h-.57c-.2 0-.52.07-.79.37-.27.3-1.04 1.02-1.04 2.48 0 1.46 1.07 2.88 1.21 3.07.15.2 2.1 3.2 5.08 4.49.71.31 1.26.49 1.69.63.71.23 1.36.2 1.87.12.57-.09 1.76-.72 2-1.41.25-.7.25-1.29.18-1.41-.08-.13-.27-.2-.57-.35ZM12.05 21.79h-.01a9.87 9.87 0 0 1-5.03-1.38l-.36-.21-3.74.98 1-3.65-.24-.37a9.86 9.86 0 0 1-1.51-5.26c0-5.45 4.44-9.88 9.89-9.88a9.83 9.83 0 0 1 9.88 9.89c0 5.45-4.44 9.88-9.88 9.88Zm8.41-18.3A11.82 11.82 0 0 0 12.05 0C5.5 0 .16 5.34.16 11.89c0 2.1.55 4.14 1.59 5.95L.06 24l6.3-1.65a11.88 11.88 0 0 0 5.68 1.45h.01c6.55 0 11.89-5.34 11.89-11.89 0-3.18-1.24-6.17-3.48-8.42Z"/></svg></a>
      <a class="tvbl__sh" href="https://topvieweg.com/ecommerce-benefits/" data-copy aria-label="Copy link"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1"/><path d="M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1"/></svg></a><span class="tvbl__copied" aria-live="polite">Link copied</span>
    </div>
  </div>
  <div class="tvbl__band">
    <div class="tvx__inner tvx__inner--tight">
      <div class="tvx__cta" data-reveal>
        <div class="tvx__cta-text"><h3 class="tvx__cta-title">Planning something similar?</h3><p class="tvx__cta-body">Book a free meeting with our team. We will review how your branches work and suggest the right setup.</p></div>
        <div class="tvx__cta-actions">
          <a class="tvx__btn tvx__btn--primary" href="https://topvieweg.com/contact/" data-tvx="consultation" data-where="blog_ecommerce-benefits">Get a Free Consultation <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          <a class="tvx__btn tvx__btn--ghost" href="https://wa.me/201114000096?text=Hello%20TopView%2C%20I'm%20contacting%20you%20from%20your%20website%20(News%20article).%20I'd%20like%20to%20discuss%20a%20project." target="_blank" rel="noopener" data-tvx="whatsapp"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M17.47 14.38c-.3-.15-1.76-.87-2.03-.97-.27-.1-.47-.15-.67.15-.2.3-.77.97-.94 1.16-.17.2-.35.22-.64.07-.3-.15-1.26-.46-2.39-1.47-.88-.79-1.48-1.76-1.65-2.06-.17-.3-.02-.46.13-.61.13-.13.3-.35.45-.52.15-.17.2-.3.3-.5.1-.2.05-.37-.03-.52-.07-.15-.67-1.61-.92-2.21-.24-.58-.49-.5-.67-.51h-.57c-.2 0-.52.07-.79.37-.27.3-1.04 1.02-1.04 2.48 0 1.46 1.07 2.88 1.21 3.07.15.2 2.1 3.2 5.08 4.49.71.31 1.26.49 1.69.63.71.23 1.36.2 1.87.12.57-.09 1.76-.72 2-1.41.25-.7.25-1.29.18-1.41-.08-.13-.27-.2-.57-.35ZM12.05 21.79h-.01a9.87 9.87 0 0 1-5.03-1.38l-.36-.21-3.74.98 1-3.65-.24-.37a9.86 9.86 0 0 1-1.51-5.26c0-5.45 4.44-9.88 9.89-9.88a9.83 9.83 0 0 1 9.88 9.89c0 5.45-4.44 9.88-9.88 9.88Zm8.41-18.3A11.82 11.82 0 0 0 12.05 0C5.5 0 .16 5.34.16 11.89c0 2.1.55 4.14 1.59 5.95L.06 24l6.3-1.65a11.88 11.88 0 0 0 5.68 1.45h.01c6.55 0 11.89-5.34 11.89-11.89 0-3.18-1.24-6.17-3.48-8.42Z"/></svg> Chat on WhatsApp</a>
        </div>
      </div>
    </div>
  </div>
  <div class="tvbl__band tvbl__band--mist">
    <div class="tvx__inner">
      <div class="tvbl__head" data-reveal><h2 class="tvx__title">More articles</h2></div>
      <div class="tvbl__grid" data-tvbl-feed data-count="3" data-exclude="3197" data-reveal>
        <article class="tvbl__card" data-id="5571" data-cat="insights">
          <a class="tvbl__card-img" href="https://topvieweg.com/own-app-vs-delivery-apps/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-own-app.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="insights">Insight</span><span>14 Oct 2026</span><span>3 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/own-app-vs-delivery-apps/">Your own app or delivery apps? What changes for a multi-branch brand</a></h3>
            <p class="tvbl__card-ex">Delivery apps bring orders, but they keep the customer and take a share of every sale. Here is what changes when a multi-branch brand runs its own app and online store, and how to start without losing the orders you already have.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
        <article class="tvbl__card" data-id="5575" data-cat="guides">
          <a class="tvbl__card-img" href="https://topvieweg.com/what-is-ecommerce/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-g-what.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="guides">Guide</span><span>14 Oct 2026</span><span>2 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/what-is-ecommerce/">What is e-commerce? A plain guide for business owners</a></h3>
            <p class="tvbl__card-ex">E-commerce is more than a website with a cart. Here is what it really means for a restaurant, shop or brand, the channels it covers, and the parts that have to work together behind every online order.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
        <article class="tvbl__card" data-id="5572" data-cat="case-studies">
          <a class="tvbl__card-img" href="https://topvieweg.com/etoile-egypt-app-case-study/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-etoile.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="case-studies">Case study</span><span>14 Oct 2026</span><span>2 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/etoile-egypt-app-case-study/">How Etoile Egypt went from a call centre to 520,000+ app users</a></h3>
            <p class="tvbl__card-ex">Etoile Egypt moved its online orders from a busy call centre to its own app and website. Today the app has more than 520,000 users and takes thousands of orders a day, connected to the branches, ERP and POS.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
      </div>
      <div class="tvbl__all"><a class="tvx__btn tvx__btn--outline" href="https://topvieweg.com/blog/">View all articles <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a></div>
    </div>
  </div>
</section>
<script>
(function () {
  var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  function fmt(n) { return Math.round(n).toLocaleString('en-US'); }
  function countUp(el) {
    var to = Number(el.getAttribute('data-n'));
    if (reduce || !to) return;
    var dur = 1200, t0 = null;
    el.textContent = fmt(0);
    requestAnimationFrame(function step(t) {
      if (t0 === null) t0 = t;
      var p = Math.min(1, (t - t0) / dur);
      el.textContent = fmt(to * (1 - Math.pow(1 - p, 3)));
      if (p < 1) requestAnimationFrame(step);
    });
    // always land on the real value, even if frames stall
    setTimeout(function () { el.textContent = fmt(to); }, dur + 400);
  }

  function init(root) {
    root.setAttribute('data-ready', '');
    root.classList.add('is-js');

    // scroll reveal (armed only here, so the section is complete without JS)
    var items = [].slice.call(root.querySelectorAll('[data-reveal]'));
    var drawTarget = root.querySelector('[data-draw]');
    if (!reduce && 'IntersectionObserver' in window) {
      root.classList.add('is-armed');
      var io = new IntersectionObserver(function (entries) {
        entries.forEach(function (e) {
          if (!e.isIntersecting) return;
          io.unobserve(e.target);
          if (e.target === drawTarget) {
            root.classList.add('is-drawn');
            [].slice.call(root.querySelectorAll('[data-n]')).forEach(countUp);
          } else {
            e.target.classList.add('is-in');
          }
        });
      }, { threshold: 0.15, rootMargin: '0px 0px -40px 0px' });
      items.forEach(function (el) { io.observe(el); });
      if (drawTarget) io.observe(drawTarget);
      // safety net: never leave content hidden
      setTimeout(function () { items.forEach(function (el) { el.classList.add('is-in'); }); root.classList.add('is-drawn'); }, 4000);
    } else {
      root.classList.add('is-drawn');
    }
    // looping decorations pause while the section is off screen
    if ('IntersectionObserver' in window) {
      new IntersectionObserver(function (entries) { root.classList.toggle('is-off', !entries[entries.length - 1].isIntersecting); }).observe(root);
    }

    // looping motion ([data-loop]) starts when first seen, so it opens on its first scene, and pauses off screen
    [].slice.call(root.querySelectorAll('[data-loop]')).forEach(function (el) {
      if (reduce || !('IntersectionObserver' in window)) return;
      new IntersectionObserver(function (entries) {
        var on = entries[entries.length - 1].isIntersecting; // several entries can queue up during a fast scroll; the last one is current
        if (on) el.classList.add('is-playing');
        el.classList.toggle('is-paused', !on);
      }, { threshold: 0.3 }).observe(el);
    });

    // tabs with a sliding highlight
    var tabs = [].slice.call(root.querySelectorAll('[role="tab"]'));
    if (!tabs.length) return;
    var panels = tabs.map(function (t) { return root.querySelector('#' + t.getAttribute('aria-controls')); });
    var ink = root.querySelector('.tvpf__ink');
    var list = tabs[0].parentNode;
    var current = Math.max(0, tabs.findIndex(function (t) { return t.getAttribute('aria-selected') === 'true'; }));
    function moveInk() {
      if (!ink) return;
      var t = tabs[current];
      ink.style.width = t.offsetWidth + 'px';
      ink.style.transform = 'translateX(' + t.offsetLeft + 'px)';
    }
    function show(n, focus) {
      if (n === current) return;
      current = (n + tabs.length) % tabs.length;
      tabs.forEach(function (t, k) {
        var on = k === current;
        t.classList.toggle('is-active', on);
        t.setAttribute('aria-selected', on ? 'true' : 'false');
        t.tabIndex = on ? 0 : -1;
      });
      panels.forEach(function (p, k) {
        var on = k === current;
        p.hidden = !on;
        p.classList.toggle('is-active', on);
        p.classList.remove('is-entering');
        if (on && !reduce) { void p.offsetWidth; p.classList.add('is-entering'); }
      });
      moveInk();
      var t = tabs[current];
      if (list.scrollWidth > list.clientWidth) list.scrollTo({ left: t.offsetLeft - (list.clientWidth - t.offsetWidth) / 2, behavior: reduce ? 'auto' : 'smooth' });
      if (focus) t.focus();
    }
    tabs.forEach(function (t, k) {
      t.addEventListener('click', function () { show(k); });
      t.addEventListener('keydown', function (e) {
        if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') { e.preventDefault(); show(current + (e.key === 'ArrowRight' ? 1 : -1), true); }
      });
    });
    moveInk();
    if (window.ResizeObserver) new ResizeObserver(moveInk).observe(list);
    window.addEventListener('load', moveInk);
  }

  [].slice.call(document.querySelectorAll('.tvx:not([data-ready])')).forEach(init);

  // calls to action: same tracking as the floating WhatsApp button and the home CTA
  // (each section ships this script, so register the listener only once per page)
  if (window.__tvxCtaTracking) return;
  window.__tvxCtaTracking = true;
  document.addEventListener('click', function (e) {
    var a = e.target.closest && e.target.closest('.tvx a[data-tvx]');
    if (!a) return;
    if (a.getAttribute('data-tvx') === 'whatsapp') {
      if (typeof gtag === 'function') { gtag('event', 'contact', { method: 'WhatsApp', link_url: a.href }); }
      if (typeof fbq === 'function') { fbq('track', 'Contact', { content_name: 'WhatsApp' }); }
      if (typeof window.lintrk === 'function') { window.lintrk('track', { conversion_id: 31200418 }); }
    } else if (typeof gtag === 'function') {
      gtag('event', 'cta_click', { cta: 'free_consultation', location: a.getAttribute('data-where') || 'section' });
    }
  });
})();

(function () {
  if (window.__tvblReady) return;
  window.__tvblReady = true;

  var CAT = { guides: 'Guide', 'case-studies': 'Case study', insights: 'Insight' };
  var arrow = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg>';
  var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

  function text(html, sel) {
    var d = document.createElement('div'); d.innerHTML = html || '';
    [].slice.call(d.querySelectorAll('style,script')).forEach(function (n) { n.remove(); });
    var part = sel && d.querySelector(sel);
    return ((part || d).textContent || '').replace(/\s+/g, ' ').trim();
  }
  function esc(s) { return String(s).replace(/[&<>"]/g, function (c) { return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c]; }); }

  // the same card markup the build script prints, rebuilt from the REST API so new posts show up on their own
  // mins comes from the card the build printed for that post; a post published later shows no reading time
  // p.tv_card = { img, cat, cat_name } is a small REST field added by the "TopView speed & SEO tweaks" snippet
  function card(p, feature, mins) {
    var tc = p.tv_card || {};
    var img = tc.img || '';
    var term = { slug: tc.cat || '', name: tc.cat_name || '' };
    var d = new Date(p.date);
    return '<article class="tvbl__card' + (feature ? ' tvbl__card--feature' : '') + '" data-id="' + p.id + '" data-cat="' + esc(term.slug || '') + '">' +
      (img ? '<a class="tvbl__card-img" href="' + esc(p.link) + '" tabindex="-1" aria-hidden="true"><img loading="lazy" src="' + esc(img) + '" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>' : '') +
      '<div class="tvbl__card-body"><div class="tvbl__meta">' + (term.slug ? '<span class="tvbl__cat" data-cat="' + esc(term.slug) + '">' + esc(CAT[term.slug] || term.name) + '</span>' : '') +
      '<span>' + d.getDate() + ' ' + months[d.getMonth()] + ' ' + d.getFullYear() + '</span>' + (mins ? '<span>' + mins + ' min read</span>' : '') + '</div>' +
      '<h3 class="tvbl__card-title"><a href="' + esc(p.link) + '">' + p.title.rendered + '</a></h3>' +
      '<p class="tvbl__card-ex">' + esc(text(p.excerpt && p.excerpt.rendered)) + '</p>' +
      '<span class="tvbl__more" aria-hidden="true">Read article ' + arrow + '</span></div></article>';
  }

  function applyFilter(root, cat) {
    var cards = [].slice.call(root.querySelectorAll('.tvbl__card'));
    var shown = 0;
    cards.forEach(function (c) { var on = !cat || c.getAttribute('data-cat') === cat; c.hidden = !on; if (on) shown++; });
    [].slice.call(root.querySelectorAll('.tvbl__filter')).forEach(function (b) { b.setAttribute('aria-pressed', String((b.getAttribute('data-cat') || '') === (cat || ''))); });
    var empty = root.querySelector('.tvbl__empty');
    if (empty) empty.hidden = shown > 0;
  }

  function initFilters() {
    [].slice.call(document.querySelectorAll('.tvbl [data-tvbl-filters]')).forEach(function (bar) {
      var root = bar.closest('.tvbl');
      if (bar.getAttribute('data-ready')) { var cur = bar.querySelector('[aria-pressed="true"]'); applyFilter(root, cur ? cur.getAttribute('data-cat') || '' : ''); return; }
      bar.setAttribute('data-ready', '1');
      bar.addEventListener('click', function (e) {
        var b = e.target.closest('.tvbl__filter');
        if (!b) return;
        applyFilter(root, b.getAttribute('data-cat') || '');
      });
      var m = location.search.match(/[?&]cat=([a-z-]+)/);
      applyFilter(root, m ? m[1] : '');
    });
  }

  // copy link
  document.addEventListener('click', function (e) {
    var b = e.target.closest && e.target.closest('.tvbl [data-copy]');
    if (!b) return;
    e.preventDefault();
    var done = function () { var t = b.parentNode.querySelector('.tvbl__copied'); if (t) { t.classList.add('is-on'); setTimeout(function () { t.classList.remove('is-on'); }, 1800); } };
    if (navigator.clipboard) navigator.clipboard.writeText(location.href.split('#')[0]).then(done, function () {}); else done();
  });

  var feeds = [].slice.call(document.querySelectorAll('[data-tvbl-feed]'));
  initFilters();
  if (!feeds.length || !window.fetch) return;

  // Only the fields a card shows (the full post content made this ~600 KB), and only once a feed
  // comes near the screen, so the request never competes with the page's first paint.
  var loaded = false;
  function refresh() {
    if (loaded) return;
    loaded = true;
    var mins = {};
    [].forEach.call(document.querySelectorAll('.tvbl__card[data-id]'), function (c) {
      var m = (c.textContent || '').match(/(\d+) min read/);
      if (m) mins[c.getAttribute('data-id')] = m[1];
    });
    fetch('/wp-json/wp/v2/posts?per_page=12&_fields=id,date,link,title,excerpt,tv_card', { credentials: 'omit' })
      .then(function (r) { return r.ok ? r.json() : Promise.reject(r.status); })
      .then(function (posts) {
        if (!Array.isArray(posts) || !posts.length || !posts[0].tv_card) return; // keep the printed cards if the field is missing
        feeds.forEach(function (feed) {
          var max = Number(feed.getAttribute('data-count')) || posts.length;
          var skip = Number(feed.getAttribute('data-exclude')) || 0;
          var list = posts.filter(function (p) { return p.id !== skip; }).slice(0, max);
          var have = [].map.call(feed.querySelectorAll('.tvbl__card'), function (el) { return el.getAttribute('data-id'); }).join();
          if (have === list.map(function (p) { return String(p.id); }).join()) return; // the printed cards are already current
          var feature = feed.hasAttribute('data-feature');
          feed.innerHTML = list.map(function (p, i) { return card(p, feature && i === 0, mins[p.id]); }).join('');
        });
        initFilters();
      })
      .catch(function () {});
  }
  if ('IntersectionObserver' in window) {
    var io = new IntersectionObserver(function (entries) {
      if (entries.some(function (e) { return e.isIntersecting; })) { io.disconnect(); refresh(); }
    }, { rootMargin: '600px 0px' });
    feeds.forEach(function (f) { io.observe(f); });
  } else {
    window.addEventListener('load', refresh);
  }
})();

</script>
				</div>
				</div>
				</div>
				</div>
		<p>The post <a href="https://topvieweg.com/ecommerce-benefits/">7 ways e-commerce helps a business grow</a> appeared first on <a href="https://topvieweg.com">TopView</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Zahran Market: a shopping app and a picking app in 45 working days</title>
		<link>https://topvieweg.com/zahran-market-apps-case-study/</link>
		
		<dc:creator><![CDATA[Amr Bendary]]></dc:creator>
		<pubDate>Wed, 14 Oct 2026 08:00:00 +0000</pubDate>
				<category><![CDATA[Case Studies]]></category>
		<guid isPermaLink="false">https://topvieweg.com/zahran-market-apps-case-study/</guid>

					<description><![CDATA[<p>A supermarket with 24 branches and more than 23,000 products needed a customer app and an organised way to pick and deliver orders. We built the shopping and picking apps in 45 working days, with a delivery app for drivers.</p>
<p>The post <a href="https://topvieweg.com/zahran-market-apps-case-study/">Zahran Market: a shopping app and a picking app in 45 working days</a> appeared first on <a href="https://topvieweg.com">TopView</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="5573" class="elementor elementor-5573" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-tvb5573c e-con-full e-flex e-con e-parent" data-id="tvb5573c" data-element_type="container" data-e-type="container">
				<div class="elementor-element elementor-element-tvb5573w elementor-widget elementor-widget-html" data-id="tvb5573w" data-element_type="widget" data-e-type="widget" data-widget_type="html.default">
				<div class="elementor-widget-container">
					<!-- TopView blog: article zahran-market-apps-case-study. Generated by live-site/blog/build.js from articles.js; edit there and rebuild. -->
<style>
/* Shared base for the TopView platform (.tvpf) and discount-system (.tvdm) sections.
   The izeetak theme styles every <button> (70px line height, 60px side padding, uppercase, wide tracking),
   sets body line height to 2 and decorates lists, so each section resets those inside itself. */
.tvx {
  --x-ink: #1B1825;
  --x-muted: #5A6475;
  --x-line: #E3E8EF;
  --x-paper: #FFFFFF;
  --x-mist: #F4F7FB;
  --x-blue: #086AD9;
  --x-blue-ink: #0757B3;
  --x-blue-tint: #E7F0FC;
  --x-beige: #D2A88F;
  --x-beige-lite: #E7C7B2;
  --x-navy: #06142B;
  --x-navy-2: #0B2A55;
  --x-ease: cubic-bezier(.2, .8, .2, 1);
  container: tvx / inline-size;
  position: relative;
  width: 100%;
  font-family: "Barlow", "Segoe UI", system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.5;
  color: var(--x-ink);
  text-align: left;
}
.elementor-widget:has(> .elementor-widget-container > .tvx) { width: 100%; min-width: 0; }
.tvx *, .tvx *::before, .tvx *::after { box-sizing: border-box; }
/* Element-weight resets (0,0,1): they still beat the theme (same weight, later in the page) but lose to every
   class rule, even when a second section on the page repeats this file after the first section’s rules. */
:where(.tvx) :is(h2, h3, h4, p, ul, ol, li, dl, dt, dd, figure) { margin: 0; padding: 0; }
:where(.tvx) :is(ul, ol) { list-style: none; }
:where(.tvx) li::before, :where(.tvx) li::after { content: none; }
:where(.tvx) img { display: block; max-width: 100%; height: auto; }
.tvx button { min-width: 0; min-height: 0; margin: 0; padding: 0; border: 0; background: none; color: inherit; font: inherit; line-height: inherit; letter-spacing: normal; text-transform: none; cursor: pointer; }
.tvx button:hover, .tvx button:focus { background: none; color: inherit; }
.tvx :focus-visible { outline: 3px solid var(--x-blue); outline-offset: 3px; }

.tvx__inner { max-width: 1200px; margin: 0 auto; padding-inline: clamp(16px, 4cqi, 32px); padding-block: clamp(56px, 7cqi, 96px); }
.tvx__head { max-width: 720px; margin-bottom: clamp(28px, 4cqi, 48px); }
.tvx__title { font-weight: 800; font-size: clamp(30px, 2.4cqi + 14px, 46px); line-height: 1.08; letter-spacing: -.01em; color: var(--x-ink); text-wrap: balance; margin-bottom: 14px; }
.tvx__lede { font-size: clamp(16px, .5cqi + 12px, 19px); line-height: 1.65; font-weight: 500; color: var(--x-muted); text-wrap: pretty; }
.tvx__h3 { font-weight: 800; font-size: clamp(21px, .8cqi + 15px, 26px); line-height: 1.2; color: var(--x-ink); margin-bottom: 18px; text-wrap: balance; }

.tvx__icon { flex: none; width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center; background: var(--x-blue-tint); color: var(--x-blue); }
.tvx__icon svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

.tvx__chips { display: flex; flex-wrap: wrap; gap: 8px; }
.tvx__chips li { padding: 7px 13px; border: 1px solid var(--x-line); border-radius: 20px; background: var(--x-paper); font-size: 14px; font-weight: 600; line-height: 1.3; color: var(--x-ink); }

/* closing call to action */
.tvx__cta { margin-top: clamp(40px, 5cqi, 64px); border-radius: 14px; padding: clamp(28px, 4cqi, 44px); display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 24px 40px; color: #fff; background: radial-gradient(60% 120% at 85% 0%, rgba(8, 106, 217, .55), transparent 70%), linear-gradient(160deg, var(--x-navy-2), var(--x-navy)); }
.tvx__cta-text { min-width: 0; max-width: 560px; }
.tvx__cta-title { font-weight: 800; font-size: clamp(22px, 1cqi + 15px, 30px); line-height: 1.2; color: #fff; text-wrap: balance; }
.tvx__cta-body { margin-top: 8px; font-size: 16px; line-height: 1.6; color: rgba(255, 255, 255, .82); }
.tvx__cta-actions { display: flex; flex-wrap: wrap; gap: 12px; }
.tvx__btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 52px; padding: 0 22px; border-radius: 8px; font-weight: 700; font-size: 14px; line-height: 1; letter-spacing: .1em; text-transform: uppercase; text-decoration: none; white-space: nowrap; transition: background-color .2s ease, border-color .2s ease, transform .2s ease; }
.tvx__btn svg { width: 18px; height: 18px; flex: none; }
.tvx__btn--primary { background: var(--x-beige); color: var(--x-ink); }
.tvx__btn--primary:hover, .tvx__btn--primary:focus { background: var(--x-beige-lite); color: var(--x-ink); }
.tvx__btn--ghost { color: #fff; border: 1.5px solid rgba(255, 255, 255, .34); }
.tvx__btn--ghost:hover, .tvx__btn--ghost:focus { color: #fff; border-color: #fff; background: rgba(255, 255, 255, .06); }
.tvx__btn:active { transform: translateY(1px); }
.tvx__btn:focus-visible { outline-color: var(--x-beige-lite); }

/* scroll reveal: only armed by JS, so content is visible without it */
.tvx.is-armed [data-reveal] { opacity: 0; transform: translateY(16px); transition: opacity .7s var(--x-ease), transform .7s var(--x-ease); transition-delay: calc(var(--i, 0) * 70ms); }
.tvx.is-armed [data-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .tvx *, .tvx *::before, .tvx *::after { animation: none !important; transition: none !important; }
  .tvx.is-armed [data-reveal] { opacity: 1; transform: none; }
}
@container tvx (max-width: 560px) {
  .tvx__cta-actions { width: 100%; flex-direction: column; }
  .tvx__btn { width: 100%; padding: 14px 16px; letter-spacing: .07em; white-space: normal; text-align: center; line-height: 1.3; }
}

/* ===== Blog (.tvbl): home "News & Articles" section, the News page and the article page. Builds on ../platform/tv-shared.css ===== */
.tvbl { background: var(--x-paper); }
.tvbl__band { width: 100%; }
.tvbl__band--mist { background: var(--x-mist); }

/* section head (home + news page) */
.tvbl__head { max-width: 760px; margin-bottom: clamp(28px, 4cqi, 44px); }
.tvbl__head--center { margin-inline: auto; text-align: center; }
.tvbl__eyebrow { display: inline-flex; align-items: center; gap: 10px; margin-bottom: 10px; font-size: 16px; font-weight: 600; color: var(--x-muted); }
.tvbl__eyebrow::before { content: ""; width: 14px; height: 2px; background: var(--x-beige); }
.tvbl__head--center .tvx__title { margin-inline: auto; }
.tvbl__head--center .tvx__lede { margin-inline: auto; max-width: 640px; }

/* cards */
.tvbl__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.tvbl__card { position: relative; display: flex; flex-direction: column; border-radius: 16px; overflow: hidden; background: var(--x-paper); border: 1px solid var(--x-line); transition: border-color .25s ease, box-shadow .25s ease, transform .25s ease; }
.tvbl__card:hover { border-color: #C9D3E0; box-shadow: 0 22px 40px -28px rgba(6, 20, 43, .45); transform: translateY(-3px); }
.tvbl__card-img { display: block; aspect-ratio: 16 / 9; overflow: hidden; background: var(--x-navy); }
.tvbl__card-img img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--x-ease); }
.tvbl__card:hover .tvbl__card-img img { transform: scale(1.03); }
.tvbl__card-body { display: flex; flex-direction: column; gap: 10px; flex: 1; padding: 20px 22px 22px; }
.tvbl__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; font-size: 13.5px; font-weight: 600; line-height: 1.3; color: var(--x-muted); }
.tvbl__meta > span + span::before { content: ""; display: inline-block; width: 4px; height: 4px; margin: 0 10px 2px 0; border-radius: 50%; background: #C3CBD8; vertical-align: middle; }
.tvbl__cat { display: inline-block; padding: 4px 10px; border-radius: 20px; background: var(--x-blue-tint); color: var(--x-blue-ink); font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; text-decoration: none; }
.tvbl__cat[data-cat="case-studies"] { background: #F8EEE7; color: #8A5A3E; }
.tvbl__cat[data-cat="guides"] { background: #E6F6EE; color: #0E7A47; }
a.tvbl__cat:hover { filter: brightness(.96); }
.tvbl__card-title { font-weight: 700; font-size: 20px; line-height: 1.3; color: var(--x-ink); text-wrap: balance; }
.tvbl__card-title a { color: inherit; text-decoration: none; }
.tvbl__card-title a::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.tvbl__card-title a:focus-visible { outline: none; }
.tvbl__card:has(.tvbl__card-title a:focus-visible) { outline: 3px solid var(--x-blue); outline-offset: 3px; }
.tvbl__card-ex { font-size: 15px; line-height: 1.6; color: var(--x-muted); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.tvbl__more { margin-top: auto; padding-top: 6px; display: inline-flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--x-blue); }
.tvbl__more svg { width: 16px; height: 16px; transition: transform .2s ease; }
.tvbl__card:hover .tvbl__more svg { transform: translateX(4px); }

/* featured (first) card on the news page */
.tvbl__card--feature { grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.tvbl__card--feature .tvbl__card-img { aspect-ratio: auto; min-height: 100%; }
.tvbl__card--feature .tvbl__card-body { justify-content: center; gap: 14px; padding: clamp(24px, 3.4cqi, 44px); }
.tvbl__card--feature .tvbl__card-title { font-size: clamp(24px, 1.2cqi + 14px, 32px); line-height: 1.2; }
.tvbl__card--feature .tvbl__card-ex { font-size: 16.5px; -webkit-line-clamp: 4; }

/* filter chips (news page) */
.tvbl__filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 26px; }
.tvx .tvbl__filter { padding: 9px 16px; border-radius: 30px; border: 1px solid var(--x-line); background: var(--x-paper); font-size: 14.5px; font-weight: 700; line-height: 1.2; color: var(--x-ink); transition: background-color .2s ease, color .2s ease, border-color .2s ease; }
.tvx .tvbl__filter:hover { border-color: #C9D3E0; background: var(--x-paper); color: var(--x-ink); }
.tvx .tvbl__filter[aria-pressed="true"] { background: var(--x-ink); border-color: var(--x-ink); color: #fff; }
.tvbl__card[hidden] { display: none; }
.tvbl__empty { padding: 40px; text-align: center; color: var(--x-muted); }

.tvbl__all { display: flex; justify-content: center; margin-top: clamp(28px, 4cqi, 40px); }
.tvbl .tvx__btn--outline { color: var(--x-ink); border: 1.5px solid #C9D3E0; }
.tvbl .tvx__btn--outline:hover, .tvbl .tvx__btn--outline:focus { color: var(--x-ink); border-color: var(--x-ink); }
.tvbl .tvx__btn--outline:focus-visible { outline-color: var(--x-blue); }

/* ---------- article page ---------- */
.tvbl__article { max-width: 960px; margin: 0 auto; padding-inline: clamp(16px, 4cqi, 32px); padding-block: clamp(40px, 6cqi, 72px) clamp(48px, 6cqi, 80px); }
.tvbl__article > :not(.tvbl__cover) { max-width: 720px; margin-inline: auto; }
.tvbl__meta--top { margin-bottom: 18px; font-size: 14.5px; }
.tvbl__lede { font-size: clamp(19px, .6cqi + 15px, 22px); line-height: 1.6; font-weight: 500; color: #3A4252; text-wrap: pretty; }
.tvbl__cover { margin: clamp(28px, 4cqi, 40px) 0; border-radius: 18px; overflow: hidden; background: var(--x-navy); box-shadow: 0 30px 60px -40px rgba(6, 20, 43, .55); }
.tvbl__cover img { width: 100%; height: auto; }

.tvbl__glance { margin-bottom: 36px; padding: 22px 24px; border-radius: 14px; background: var(--x-mist); border: 1px solid var(--x-line); }
.tvbl__glance-client { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; margin-bottom: 16px; }
.tvbl__glance-client b { font-size: 17px; font-weight: 800; color: var(--x-ink); }
.tvbl__glance-client span { font-size: 14px; font-weight: 600; color: var(--x-muted); }
.tvbl__glance dl { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
.tvbl__glance dl > div { display: flex; flex-direction: column-reverse; gap: 4px; padding-left: 14px; border-left: 2px solid #D9E2EE; }
.tvbl__glance dd { font-size: clamp(22px, .8cqi + 16px, 28px); font-weight: 800; line-height: 1.05; color: var(--x-blue); font-variant-numeric: tabular-nums; }
.tvbl__glance dt { font-size: 13.5px; font-weight: 600; line-height: 1.35; color: var(--x-muted); }

.tvbl__body { font-size: 18px; line-height: 1.75; color: #2E3442; }
.tvbl__body > * + * { margin-top: 18px; }
.tvbl__body h2 { margin-top: 46px; font-weight: 800; font-size: clamp(24px, .8cqi + 18px, 30px); line-height: 1.2; letter-spacing: -.005em; color: var(--x-ink); text-wrap: balance; }
.tvbl__body h3 { margin-top: 30px; font-weight: 700; font-size: 21px; line-height: 1.3; color: var(--x-ink); }
.tvbl__body h2 + *, .tvbl__body h3 + * { margin-top: 12px; }
.tvbl__body strong { font-weight: 700; color: var(--x-ink); }
.tvbl__body a { color: var(--x-blue); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: rgba(8, 106, 217, .35); }
.tvbl__body a:hover { color: var(--x-blue-ink); text-decoration-color: currentColor; }
.tvbl__body ul, .tvbl__body ol { display: grid; gap: 10px; }
.tvbl__body ul > li { position: relative; padding-left: 26px; }
.tvbl__body ul > li::before { content: ""; position: absolute; left: 4px; top: .7em; width: 8px; height: 8px; border-radius: 50%; background: var(--x-beige); }
.tvbl__body ol:not(.tvbl__steps) { counter-reset: tvbl; }
.tvbl__body ol:not(.tvbl__steps) > li { position: relative; padding-left: 42px; counter-increment: tvbl; }
.tvbl__body ol:not(.tvbl__steps) > li::before { content: counter(tvbl); position: absolute; left: 0; top: .1em; width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; background: var(--x-blue-tint); color: var(--x-blue); font-size: 14px; font-weight: 800; line-height: 1; }
.tvbl__fig { margin-block: 32px; }
.tvbl__fig img { width: 100%; height: auto; border-radius: 14px; border: 1px solid var(--x-line); background: var(--x-mist); }
.tvbl__fig figcaption { margin-top: 10px; font-size: 14.5px; line-height: 1.5; color: var(--x-muted); }
.tvbl__note { margin-top: 32px; padding: 18px 20px; border-radius: 12px; background: var(--x-mist); border-left: 3px solid var(--x-blue); font-size: 16.5px; line-height: 1.6; }
.tvbl__steps { display: grid; gap: 12px; }
.tvbl__steps li { position: relative; padding: 16px 18px 16px 60px; border-radius: 12px; border: 1px solid var(--x-line); background: var(--x-paper); font-size: 17px; line-height: 1.6; }
.tvbl__steps li::before { content: ""; position: absolute; left: 18px; top: 18px; width: 26px; height: 26px; border-radius: 50%; background: var(--x-blue) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / 15px no-repeat; }
.tvbl__steps li.is-now::before { background: var(--x-paper); box-shadow: inset 0 0 0 3px var(--x-beige); }
.tvbl__steps li > span { display: inline-block; margin: 0 8px 4px 0; padding: 2px 9px; border-radius: 20px; font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; background: #E6F6EE; color: #0E7A47; vertical-align: 2px; }
.tvbl__steps li.is-now > span { background: #F8EEE7; color: #8A5A3E; }

/* author box under every article; the byline links to it */
.tvbl__meta .tvbl__by { color: inherit; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: #C3CBD8; }
.tvbl__meta .tvbl__by:hover { color: var(--x-ink); text-decoration-color: currentColor; }
.tvbl__author { display: flex; align-items: flex-start; gap: 18px; margin-top: 44px; padding: 22px 24px; border-radius: 14px; background: var(--x-mist); border: 1px solid var(--x-line); scroll-margin-top: 110px; }
.tvbl__author-mark { flex: none; width: 56px; height: 56px; border-radius: 50%; display: grid; place-items: center; background: var(--x-navy); color: #fff; font-size: 18px; font-weight: 800; letter-spacing: .04em; box-shadow: inset 0 0 0 2px var(--x-beige); }
.tvbl__author-kicker { font-size: 12.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--x-muted); }
.tvbl__author-name { margin-top: 4px; font-size: 19px; font-weight: 800; line-height: 1.3; color: var(--x-ink); }
.tvbl__author-role { margin-top: 2px; font-size: 14.5px; font-weight: 600; color: var(--x-blue-ink); }
.tvbl__author-bio { margin-top: 10px; font-size: 16px; line-height: 1.65; color: #3A4252; text-wrap: pretty; }
.tvbl__author + .tvbl__share { margin-top: 28px; }
.tvbl__share { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 44px; padding-top: 24px; border-top: 1px solid var(--x-line); }
.tvbl__share > span { margin-right: 6px; font-size: 14px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--x-muted); }
.tvx .tvbl__sh { width: 42px; height: 42px; border-radius: 50%; display: inline-grid; place-items: center; border: 1px solid var(--x-line); background: var(--x-paper); color: var(--x-ink); text-decoration: none; transition: background-color .2s ease, color .2s ease, border-color .2s ease; }
.tvx .tvbl__sh:hover { background: var(--x-ink); border-color: var(--x-ink); color: #fff; }
.tvbl__sh svg { width: 18px; height: 18px; }
.tvbl__copied { font-size: 14px; font-weight: 600; color: #0E7A47; opacity: 0; transition: opacity .2s ease; }
.tvbl__copied.is-on { opacity: 1; }
.tvbl .tvx__cta { margin-top: 0; }

@container tvx (max-width: 1020px) {
  .tvbl__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tvbl__grid--home > :nth-child(3) { display: none; }
}
@container tvx (max-width: 900px) {
  .tvbl__card--feature { grid-template-columns: minmax(0, 1fr); }
  .tvbl__card--feature .tvbl__card-img { aspect-ratio: 16 / 9; min-height: 0; }
  .tvbl__glance dl { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@container tvx (max-width: 640px) {
  .tvbl__author { flex-direction: column; gap: 12px; padding: 18px; }
  .tvbl__grid { grid-template-columns: minmax(0, 1fr); }
  .tvbl__grid--home > :nth-child(3) { display: flex; }
  .tvbl__body { font-size: 17px; }
  .tvbl__cover { border-radius: 12px; margin-inline: calc(-1 * clamp(0px, 2cqi, 8px)); }
}

.tvbl .tvx__inner--tight { padding-block: clamp(40px, 5cqi, 64px); }

</style>
<section class="tvx tvbl tvbl--post" aria-label="Zahran Market: a shopping app and a picking app in 45 working days">
  <div class="tvbl__article">
    <div class="tvbl__meta tvbl__meta--top"><a class="tvbl__cat" data-cat="case-studies" href="https://topvieweg.com/blog/?cat=case-studies">Case study</a><span>14 October 2026</span><span>2 min read</span><span>By <a class="tvbl__by" href="#tvbl-author">Amr Bendary</a></span></div>
    <p class="tvbl__lede">A supermarket with 24 branches and more than 23,000 products needed a customer app and an organised way to pick and deliver orders. We built the shopping and picking apps in 45 working days, with a delivery app for drivers.</p>
    <figure class="tvbl__cover"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-zahran.jpg" width="1200" height="675" alt="Zahran Market shopping and picking apps, built in 45 working days" decoding="async"></figure>
    <aside class="tvbl__glance" aria-label="At a glance"><div class="tvbl__glance-client"><b>Zahran Market</b><span>Supermarket chain · 24 branches · Egypt</span></div>
      <dl><div><dt>Working days for the shopping and picking apps</dt><dd>45</dd></div><div><dt>Active users in the first 4 months</dt><dd>10,291</dd></div><div><dt>Orders a day</dt><dd>200–1,300</dd></div><div><dt>Products in the catalogue</dt><dd>23K+</dd></div></dl>
    </aside>
    <div class="tvbl__body">
<h2>The challenge</h2>
<p>Zahran Market runs 24 supermarket branches with more than 23,000 products. Groceries are harder than a menu: big baskets, items that run out, substitutions, and orders that must be picked accurately in the branch and tracked on the way to the customer. Zahran needed a customer app, and an organised way for branch teams and drivers to handle every order.</p>

<h2>Three apps, one flow</h2>
<h3>The shopping app, for customers</h3>
<ul>
  <li><strong>The nearest branch, automatically:</strong> customers set their location and the app picks the right branch.</li>
  <li><strong>Shopping by department,</strong> from vegetables, dairy and bakery to offers, with search and barcode scanning.</li>
  <li><strong>Flexible checkout:</strong> delivery or branch pickup, with discount coupons.</li>
</ul>
<h3>The picking app, for branch teams</h3>
<ul>
  <li><strong>New orders appear instantly</strong> for the branch team, with every product and customer detail.</li>
  <li><strong>Picking by barcode:</strong> each item is scanned, with an option to mark a substitute or an out-of-stock item.</li>
  <li><strong>A summary before handover:</strong> the team reviews everything picked, then confirms the order is ready in one tap.</li>
</ul>
<figure class="tvbl__fig"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/platform-branch-picking.jpg" width="960" height="720" alt="Zahran Market picking app: order list, barcode picking and picking summary" loading="lazy" decoding="async"><figcaption>The picking app: from the new order to barcode picking and the summary before handover.</figcaption></figure>
<h3>The delivery app, for drivers</h3>
<p>A delivery app for drivers completes the flow, so every order is tracked on its way to the customer. All three apps are published on the App Store and Google Play.</p>

<h2>Built in 45 working days</h2>
<p>The shopping app and the picking app were built in 45 working days.</p>

<h2>The results</h2>
<ul>
  <li><strong>Sales started in June 2026.</strong></li>
  <li><strong>1,700 customers in the first week,</strong> from just three branches.</li>
  <li><strong>10,291 active users</strong> in the first four months.</li>
  <li><strong>200 to 1,300 orders a day.</strong></li>
</ul>

<h2>What made it work</h2>
<ul>
  <li><strong>Designing for the branch, not only the customer.</strong> A grocery app is only as good as the picking behind it.</li>
  <li><strong>Planning for what is not on the shelf.</strong> Substitutes and out-of-stock items are part of the flow, not an exception.</li>
  <li><strong>A check before every handover,</strong> so mistakes are caught in the branch, not at the customer’s door.</li>
  <li><strong>Launching in stages.</strong> The first week ran from three branches.</li>
</ul>
<p class="tvbl__note">Running a supermarket or retail chain? See <a href="https://topvieweg.com/service/mobile-app-development/">how we build apps</a> for branches with large catalogues.</p>
    </div>
    <aside class="tvbl__author" id="tvbl-author" aria-labelledby="tvbl-author-name">
      <span class="tvbl__author-mark" aria-hidden="true">AB</span>
      <div>
        <p class="tvbl__author-kicker">About the author</p>
        <p class="tvbl__author-name" id="tvbl-author-name">Amr Bendary</p>
        <p class="tvbl__author-role">Founder, Top View · CTO, Etoile</p>
        <p class="tvbl__author-bio">Founder of Top View and CTO at Etoile, Amr Bendary brings over 20 years of experience in digital transformation, mobile apps, e-commerce, and ERP integration. He holds an MBA in Digital Transformation and helps businesses connect technology with growth and operational efficiency.</p>
      </div>
    </aside>
    <div class="tvbl__share"><span>Share</span>
      <a class="tvbl__sh" href="https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Ftopvieweg.com%2Fzahran-market-apps-case-study%2F" target="_blank" rel="noopener" aria-label="Share on LinkedIn"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M6.94 8.5H3.56V20h3.38V8.5ZM5.25 3a1.96 1.96 0 1 0 0 3.92 1.96 1.96 0 0 0 0-3.92ZM20.44 13.4c0-3.1-1.65-4.55-3.86-4.55-1.78 0-2.58.98-3.02 1.67V8.5h-3.38c.04.95 0 11.5 0 11.5h3.38v-6.42c0-.34.02-.69.13-.93.27-.69.9-1.4 1.95-1.4 1.38 0 1.93 1.05 1.93 2.59V20h3.37v-6.6Z"/></svg></a>
      <a class="tvbl__sh" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Ftopvieweg.com%2Fzahran-market-apps-case-study%2F" target="_blank" rel="noopener" aria-label="Share on Facebook"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M13.5 21v-7.5h2.53l.38-2.93H13.5V8.7c0-.85.24-1.43 1.45-1.43h1.55V4.65a20.8 20.8 0 0 0-2.26-.12c-2.24 0-3.77 1.37-3.77 3.88v2.16H7.94v2.93h2.53V21h3.03Z"/></svg></a>
      <a class="tvbl__sh" href="https://wa.me/?text=Zahran%20Market%3A%20a%20shopping%20app%20and%20a%20picking%20app%20in%2045%20working%20days%20https%3A%2F%2Ftopvieweg.com%2Fzahran-market-apps-case-study%2F" target="_blank" rel="noopener" aria-label="Share on WhatsApp"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M17.47 14.38c-.3-.15-1.76-.87-2.03-.97-.27-.1-.47-.15-.67.15-.2.3-.77.97-.94 1.16-.17.2-.35.22-.64.07-.3-.15-1.26-.46-2.39-1.47-.88-.79-1.48-1.76-1.65-2.06-.17-.3-.02-.46.13-.61.13-.13.3-.35.45-.52.15-.17.2-.3.3-.5.1-.2.05-.37-.03-.52-.07-.15-.67-1.61-.92-2.21-.24-.58-.49-.5-.67-.51h-.57c-.2 0-.52.07-.79.37-.27.3-1.04 1.02-1.04 2.48 0 1.46 1.07 2.88 1.21 3.07.15.2 2.1 3.2 5.08 4.49.71.31 1.26.49 1.69.63.71.23 1.36.2 1.87.12.57-.09 1.76-.72 2-1.41.25-.7.25-1.29.18-1.41-.08-.13-.27-.2-.57-.35ZM12.05 21.79h-.01a9.87 9.87 0 0 1-5.03-1.38l-.36-.21-3.74.98 1-3.65-.24-.37a9.86 9.86 0 0 1-1.51-5.26c0-5.45 4.44-9.88 9.89-9.88a9.83 9.83 0 0 1 9.88 9.89c0 5.45-4.44 9.88-9.88 9.88Zm8.41-18.3A11.82 11.82 0 0 0 12.05 0C5.5 0 .16 5.34.16 11.89c0 2.1.55 4.14 1.59 5.95L.06 24l6.3-1.65a11.88 11.88 0 0 0 5.68 1.45h.01c6.55 0 11.89-5.34 11.89-11.89 0-3.18-1.24-6.17-3.48-8.42Z"/></svg></a>
      <a class="tvbl__sh" href="https://topvieweg.com/zahran-market-apps-case-study/" data-copy aria-label="Copy link"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1"/><path d="M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1"/></svg></a><span class="tvbl__copied" aria-live="polite">Link copied</span>
    </div>
  </div>
  <div class="tvbl__band">
    <div class="tvx__inner tvx__inner--tight">
      <div class="tvx__cta" data-reveal>
        <div class="tvx__cta-text"><h3 class="tvx__cta-title">Planning something similar?</h3><p class="tvx__cta-body">Book a free meeting with our team. We will review how your branches work and suggest the right setup.</p></div>
        <div class="tvx__cta-actions">
          <a class="tvx__btn tvx__btn--primary" href="https://topvieweg.com/contact/" data-tvx="consultation" data-where="blog_zahran-market-apps-case-study">Get a Free Consultation <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          <a class="tvx__btn tvx__btn--ghost" href="https://wa.me/201114000096?text=Hello%20TopView%2C%20I'm%20contacting%20you%20from%20your%20website%20(News%20article).%20I'd%20like%20to%20discuss%20a%20project." target="_blank" rel="noopener" data-tvx="whatsapp"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M17.47 14.38c-.3-.15-1.76-.87-2.03-.97-.27-.1-.47-.15-.67.15-.2.3-.77.97-.94 1.16-.17.2-.35.22-.64.07-.3-.15-1.26-.46-2.39-1.47-.88-.79-1.48-1.76-1.65-2.06-.17-.3-.02-.46.13-.61.13-.13.3-.35.45-.52.15-.17.2-.3.3-.5.1-.2.05-.37-.03-.52-.07-.15-.67-1.61-.92-2.21-.24-.58-.49-.5-.67-.51h-.57c-.2 0-.52.07-.79.37-.27.3-1.04 1.02-1.04 2.48 0 1.46 1.07 2.88 1.21 3.07.15.2 2.1 3.2 5.08 4.49.71.31 1.26.49 1.69.63.71.23 1.36.2 1.87.12.57-.09 1.76-.72 2-1.41.25-.7.25-1.29.18-1.41-.08-.13-.27-.2-.57-.35ZM12.05 21.79h-.01a9.87 9.87 0 0 1-5.03-1.38l-.36-.21-3.74.98 1-3.65-.24-.37a9.86 9.86 0 0 1-1.51-5.26c0-5.45 4.44-9.88 9.89-9.88a9.83 9.83 0 0 1 9.88 9.89c0 5.45-4.44 9.88-9.88 9.88Zm8.41-18.3A11.82 11.82 0 0 0 12.05 0C5.5 0 .16 5.34.16 11.89c0 2.1.55 4.14 1.59 5.95L.06 24l6.3-1.65a11.88 11.88 0 0 0 5.68 1.45h.01c6.55 0 11.89-5.34 11.89-11.89 0-3.18-1.24-6.17-3.48-8.42Z"/></svg> Chat on WhatsApp</a>
        </div>
      </div>
    </div>
  </div>
  <div class="tvbl__band tvbl__band--mist">
    <div class="tvx__inner">
      <div class="tvbl__head" data-reveal><h2 class="tvx__title">More articles</h2></div>
      <div class="tvbl__grid" data-tvbl-feed data-count="3" data-exclude="5573" data-reveal>
        <article class="tvbl__card" data-id="5571" data-cat="insights">
          <a class="tvbl__card-img" href="https://topvieweg.com/own-app-vs-delivery-apps/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-own-app.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="insights">Insight</span><span>14 Oct 2026</span><span>3 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/own-app-vs-delivery-apps/">Your own app or delivery apps? What changes for a multi-branch brand</a></h3>
            <p class="tvbl__card-ex">Delivery apps bring orders, but they keep the customer and take a share of every sale. Here is what changes when a multi-branch brand runs its own app and online store, and how to start without losing the orders you already have.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
        <article class="tvbl__card" data-id="5575" data-cat="guides">
          <a class="tvbl__card-img" href="https://topvieweg.com/what-is-ecommerce/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-g-what.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="guides">Guide</span><span>14 Oct 2026</span><span>2 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/what-is-ecommerce/">What is e-commerce? A plain guide for business owners</a></h3>
            <p class="tvbl__card-ex">E-commerce is more than a website with a cart. Here is what it really means for a restaurant, shop or brand, the channels it covers, and the parts that have to work together behind every online order.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
        <article class="tvbl__card" data-id="5572" data-cat="case-studies">
          <a class="tvbl__card-img" href="https://topvieweg.com/etoile-egypt-app-case-study/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-etoile.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="case-studies">Case study</span><span>14 Oct 2026</span><span>2 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/etoile-egypt-app-case-study/">How Etoile Egypt went from a call centre to 520,000+ app users</a></h3>
            <p class="tvbl__card-ex">Etoile Egypt moved its online orders from a busy call centre to its own app and website. Today the app has more than 520,000 users and takes thousands of orders a day, connected to the branches, ERP and POS.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
      </div>
      <div class="tvbl__all"><a class="tvx__btn tvx__btn--outline" href="https://topvieweg.com/blog/">View all articles <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a></div>
    </div>
  </div>
</section>
<script>
(function () {
  var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  function fmt(n) { return Math.round(n).toLocaleString('en-US'); }
  function countUp(el) {
    var to = Number(el.getAttribute('data-n'));
    if (reduce || !to) return;
    var dur = 1200, t0 = null;
    el.textContent = fmt(0);
    requestAnimationFrame(function step(t) {
      if (t0 === null) t0 = t;
      var p = Math.min(1, (t - t0) / dur);
      el.textContent = fmt(to * (1 - Math.pow(1 - p, 3)));
      if (p < 1) requestAnimationFrame(step);
    });
    // always land on the real value, even if frames stall
    setTimeout(function () { el.textContent = fmt(to); }, dur + 400);
  }

  function init(root) {
    root.setAttribute('data-ready', '');
    root.classList.add('is-js');

    // scroll reveal (armed only here, so the section is complete without JS)
    var items = [].slice.call(root.querySelectorAll('[data-reveal]'));
    var drawTarget = root.querySelector('[data-draw]');
    if (!reduce && 'IntersectionObserver' in window) {
      root.classList.add('is-armed');
      var io = new IntersectionObserver(function (entries) {
        entries.forEach(function (e) {
          if (!e.isIntersecting) return;
          io.unobserve(e.target);
          if (e.target === drawTarget) {
            root.classList.add('is-drawn');
            [].slice.call(root.querySelectorAll('[data-n]')).forEach(countUp);
          } else {
            e.target.classList.add('is-in');
          }
        });
      }, { threshold: 0.15, rootMargin: '0px 0px -40px 0px' });
      items.forEach(function (el) { io.observe(el); });
      if (drawTarget) io.observe(drawTarget);
      // safety net: never leave content hidden
      setTimeout(function () { items.forEach(function (el) { el.classList.add('is-in'); }); root.classList.add('is-drawn'); }, 4000);
    } else {
      root.classList.add('is-drawn');
    }
    // looping decorations pause while the section is off screen
    if ('IntersectionObserver' in window) {
      new IntersectionObserver(function (entries) { root.classList.toggle('is-off', !entries[entries.length - 1].isIntersecting); }).observe(root);
    }

    // looping motion ([data-loop]) starts when first seen, so it opens on its first scene, and pauses off screen
    [].slice.call(root.querySelectorAll('[data-loop]')).forEach(function (el) {
      if (reduce || !('IntersectionObserver' in window)) return;
      new IntersectionObserver(function (entries) {
        var on = entries[entries.length - 1].isIntersecting; // several entries can queue up during a fast scroll; the last one is current
        if (on) el.classList.add('is-playing');
        el.classList.toggle('is-paused', !on);
      }, { threshold: 0.3 }).observe(el);
    });

    // tabs with a sliding highlight
    var tabs = [].slice.call(root.querySelectorAll('[role="tab"]'));
    if (!tabs.length) return;
    var panels = tabs.map(function (t) { return root.querySelector('#' + t.getAttribute('aria-controls')); });
    var ink = root.querySelector('.tvpf__ink');
    var list = tabs[0].parentNode;
    var current = Math.max(0, tabs.findIndex(function (t) { return t.getAttribute('aria-selected') === 'true'; }));
    function moveInk() {
      if (!ink) return;
      var t = tabs[current];
      ink.style.width = t.offsetWidth + 'px';
      ink.style.transform = 'translateX(' + t.offsetLeft + 'px)';
    }
    function show(n, focus) {
      if (n === current) return;
      current = (n + tabs.length) % tabs.length;
      tabs.forEach(function (t, k) {
        var on = k === current;
        t.classList.toggle('is-active', on);
        t.setAttribute('aria-selected', on ? 'true' : 'false');
        t.tabIndex = on ? 0 : -1;
      });
      panels.forEach(function (p, k) {
        var on = k === current;
        p.hidden = !on;
        p.classList.toggle('is-active', on);
        p.classList.remove('is-entering');
        if (on && !reduce) { void p.offsetWidth; p.classList.add('is-entering'); }
      });
      moveInk();
      var t = tabs[current];
      if (list.scrollWidth > list.clientWidth) list.scrollTo({ left: t.offsetLeft - (list.clientWidth - t.offsetWidth) / 2, behavior: reduce ? 'auto' : 'smooth' });
      if (focus) t.focus();
    }
    tabs.forEach(function (t, k) {
      t.addEventListener('click', function () { show(k); });
      t.addEventListener('keydown', function (e) {
        if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') { e.preventDefault(); show(current + (e.key === 'ArrowRight' ? 1 : -1), true); }
      });
    });
    moveInk();
    if (window.ResizeObserver) new ResizeObserver(moveInk).observe(list);
    window.addEventListener('load', moveInk);
  }

  [].slice.call(document.querySelectorAll('.tvx:not([data-ready])')).forEach(init);

  // calls to action: same tracking as the floating WhatsApp button and the home CTA
  // (each section ships this script, so register the listener only once per page)
  if (window.__tvxCtaTracking) return;
  window.__tvxCtaTracking = true;
  document.addEventListener('click', function (e) {
    var a = e.target.closest && e.target.closest('.tvx a[data-tvx]');
    if (!a) return;
    if (a.getAttribute('data-tvx') === 'whatsapp') {
      if (typeof gtag === 'function') { gtag('event', 'contact', { method: 'WhatsApp', link_url: a.href }); }
      if (typeof fbq === 'function') { fbq('track', 'Contact', { content_name: 'WhatsApp' }); }
      if (typeof window.lintrk === 'function') { window.lintrk('track', { conversion_id: 31200418 }); }
    } else if (typeof gtag === 'function') {
      gtag('event', 'cta_click', { cta: 'free_consultation', location: a.getAttribute('data-where') || 'section' });
    }
  });
})();

(function () {
  if (window.__tvblReady) return;
  window.__tvblReady = true;

  var CAT = { guides: 'Guide', 'case-studies': 'Case study', insights: 'Insight' };
  var arrow = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg>';
  var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

  function text(html, sel) {
    var d = document.createElement('div'); d.innerHTML = html || '';
    [].slice.call(d.querySelectorAll('style,script')).forEach(function (n) { n.remove(); });
    var part = sel && d.querySelector(sel);
    return ((part || d).textContent || '').replace(/\s+/g, ' ').trim();
  }
  function esc(s) { return String(s).replace(/[&<>"]/g, function (c) { return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c]; }); }

  // the same card markup the build script prints, rebuilt from the REST API so new posts show up on their own
  // mins comes from the card the build printed for that post; a post published later shows no reading time
  // p.tv_card = { img, cat, cat_name } is a small REST field added by the "TopView speed & SEO tweaks" snippet
  function card(p, feature, mins) {
    var tc = p.tv_card || {};
    var img = tc.img || '';
    var term = { slug: tc.cat || '', name: tc.cat_name || '' };
    var d = new Date(p.date);
    return '<article class="tvbl__card' + (feature ? ' tvbl__card--feature' : '') + '" data-id="' + p.id + '" data-cat="' + esc(term.slug || '') + '">' +
      (img ? '<a class="tvbl__card-img" href="' + esc(p.link) + '" tabindex="-1" aria-hidden="true"><img loading="lazy" src="' + esc(img) + '" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>' : '') +
      '<div class="tvbl__card-body"><div class="tvbl__meta">' + (term.slug ? '<span class="tvbl__cat" data-cat="' + esc(term.slug) + '">' + esc(CAT[term.slug] || term.name) + '</span>' : '') +
      '<span>' + d.getDate() + ' ' + months[d.getMonth()] + ' ' + d.getFullYear() + '</span>' + (mins ? '<span>' + mins + ' min read</span>' : '') + '</div>' +
      '<h3 class="tvbl__card-title"><a href="' + esc(p.link) + '">' + p.title.rendered + '</a></h3>' +
      '<p class="tvbl__card-ex">' + esc(text(p.excerpt && p.excerpt.rendered)) + '</p>' +
      '<span class="tvbl__more" aria-hidden="true">Read article ' + arrow + '</span></div></article>';
  }

  function applyFilter(root, cat) {
    var cards = [].slice.call(root.querySelectorAll('.tvbl__card'));
    var shown = 0;
    cards.forEach(function (c) { var on = !cat || c.getAttribute('data-cat') === cat; c.hidden = !on; if (on) shown++; });
    [].slice.call(root.querySelectorAll('.tvbl__filter')).forEach(function (b) { b.setAttribute('aria-pressed', String((b.getAttribute('data-cat') || '') === (cat || ''))); });
    var empty = root.querySelector('.tvbl__empty');
    if (empty) empty.hidden = shown > 0;
  }

  function initFilters() {
    [].slice.call(document.querySelectorAll('.tvbl [data-tvbl-filters]')).forEach(function (bar) {
      var root = bar.closest('.tvbl');
      if (bar.getAttribute('data-ready')) { var cur = bar.querySelector('[aria-pressed="true"]'); applyFilter(root, cur ? cur.getAttribute('data-cat') || '' : ''); return; }
      bar.setAttribute('data-ready', '1');
      bar.addEventListener('click', function (e) {
        var b = e.target.closest('.tvbl__filter');
        if (!b) return;
        applyFilter(root, b.getAttribute('data-cat') || '');
      });
      var m = location.search.match(/[?&]cat=([a-z-]+)/);
      applyFilter(root, m ? m[1] : '');
    });
  }

  // copy link
  document.addEventListener('click', function (e) {
    var b = e.target.closest && e.target.closest('.tvbl [data-copy]');
    if (!b) return;
    e.preventDefault();
    var done = function () { var t = b.parentNode.querySelector('.tvbl__copied'); if (t) { t.classList.add('is-on'); setTimeout(function () { t.classList.remove('is-on'); }, 1800); } };
    if (navigator.clipboard) navigator.clipboard.writeText(location.href.split('#')[0]).then(done, function () {}); else done();
  });

  var feeds = [].slice.call(document.querySelectorAll('[data-tvbl-feed]'));
  initFilters();
  if (!feeds.length || !window.fetch) return;

  // Only the fields a card shows (the full post content made this ~600 KB), and only once a feed
  // comes near the screen, so the request never competes with the page's first paint.
  var loaded = false;
  function refresh() {
    if (loaded) return;
    loaded = true;
    var mins = {};
    [].forEach.call(document.querySelectorAll('.tvbl__card[data-id]'), function (c) {
      var m = (c.textContent || '').match(/(\d+) min read/);
      if (m) mins[c.getAttribute('data-id')] = m[1];
    });
    fetch('/wp-json/wp/v2/posts?per_page=12&_fields=id,date,link,title,excerpt,tv_card', { credentials: 'omit' })
      .then(function (r) { return r.ok ? r.json() : Promise.reject(r.status); })
      .then(function (posts) {
        if (!Array.isArray(posts) || !posts.length || !posts[0].tv_card) return; // keep the printed cards if the field is missing
        feeds.forEach(function (feed) {
          var max = Number(feed.getAttribute('data-count')) || posts.length;
          var skip = Number(feed.getAttribute('data-exclude')) || 0;
          var list = posts.filter(function (p) { return p.id !== skip; }).slice(0, max);
          var have = [].map.call(feed.querySelectorAll('.tvbl__card'), function (el) { return el.getAttribute('data-id'); }).join();
          if (have === list.map(function (p) { return String(p.id); }).join()) return; // the printed cards are already current
          var feature = feed.hasAttribute('data-feature');
          feed.innerHTML = list.map(function (p, i) { return card(p, feature && i === 0, mins[p.id]); }).join('');
        });
        initFilters();
      })
      .catch(function () {});
  }
  if ('IntersectionObserver' in window) {
    var io = new IntersectionObserver(function (entries) {
      if (entries.some(function (e) { return e.isIntersecting; })) { io.disconnect(); refresh(); }
    }, { rootMargin: '600px 0px' });
    feeds.forEach(function (f) { io.observe(f); });
  } else {
    window.addEventListener('load', refresh);
  }
})();

</script>
				</div>
				</div>
				</div>
				</div>
		<p>The post <a href="https://topvieweg.com/zahran-market-apps-case-study/">Zahran Market: a shopping app and a picking app in 45 working days</a> appeared first on <a href="https://topvieweg.com">TopView</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Is your business ready to sell online? 8 signs</title>
		<link>https://topvieweg.com/ready-to-sell-online/</link>
		
		<dc:creator><![CDATA[Amr Bendary]]></dc:creator>
		<pubDate>Wed, 14 Oct 2026 07:30:00 +0000</pubDate>
				<category><![CDATA[Guides]]></category>
		<guid isPermaLink="false">https://topvieweg.com/ready-to-sell-online/</guid>

					<description><![CDATA[<p>How do you know it is time for your own online store or app? Here are eight signs we see in businesses that are ready, and what to have in place before you start.</p>
<p>The post <a href="https://topvieweg.com/ready-to-sell-online/">Is your business ready to sell online? 8 signs</a> appeared first on <a href="https://topvieweg.com">TopView</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="5577" class="elementor elementor-5577" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-tvb5577c e-con-full e-flex e-con e-parent" data-id="tvb5577c" data-element_type="container" data-e-type="container">
				<div class="elementor-element elementor-element-tvb5577w elementor-widget elementor-widget-html" data-id="tvb5577w" data-element_type="widget" data-e-type="widget" data-widget_type="html.default">
				<div class="elementor-widget-container">
					<!-- TopView blog: article ready-to-sell-online. Generated by live-site/blog/build.js from articles.js; edit there and rebuild. -->
<style>
/* Shared base for the TopView platform (.tvpf) and discount-system (.tvdm) sections.
   The izeetak theme styles every <button> (70px line height, 60px side padding, uppercase, wide tracking),
   sets body line height to 2 and decorates lists, so each section resets those inside itself. */
.tvx {
  --x-ink: #1B1825;
  --x-muted: #5A6475;
  --x-line: #E3E8EF;
  --x-paper: #FFFFFF;
  --x-mist: #F4F7FB;
  --x-blue: #086AD9;
  --x-blue-ink: #0757B3;
  --x-blue-tint: #E7F0FC;
  --x-beige: #D2A88F;
  --x-beige-lite: #E7C7B2;
  --x-navy: #06142B;
  --x-navy-2: #0B2A55;
  --x-ease: cubic-bezier(.2, .8, .2, 1);
  container: tvx / inline-size;
  position: relative;
  width: 100%;
  font-family: "Barlow", "Segoe UI", system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.5;
  color: var(--x-ink);
  text-align: left;
}
.elementor-widget:has(> .elementor-widget-container > .tvx) { width: 100%; min-width: 0; }
.tvx *, .tvx *::before, .tvx *::after { box-sizing: border-box; }
/* Element-weight resets (0,0,1): they still beat the theme (same weight, later in the page) but lose to every
   class rule, even when a second section on the page repeats this file after the first section’s rules. */
:where(.tvx) :is(h2, h3, h4, p, ul, ol, li, dl, dt, dd, figure) { margin: 0; padding: 0; }
:where(.tvx) :is(ul, ol) { list-style: none; }
:where(.tvx) li::before, :where(.tvx) li::after { content: none; }
:where(.tvx) img { display: block; max-width: 100%; height: auto; }
.tvx button { min-width: 0; min-height: 0; margin: 0; padding: 0; border: 0; background: none; color: inherit; font: inherit; line-height: inherit; letter-spacing: normal; text-transform: none; cursor: pointer; }
.tvx button:hover, .tvx button:focus { background: none; color: inherit; }
.tvx :focus-visible { outline: 3px solid var(--x-blue); outline-offset: 3px; }

.tvx__inner { max-width: 1200px; margin: 0 auto; padding-inline: clamp(16px, 4cqi, 32px); padding-block: clamp(56px, 7cqi, 96px); }
.tvx__head { max-width: 720px; margin-bottom: clamp(28px, 4cqi, 48px); }
.tvx__title { font-weight: 800; font-size: clamp(30px, 2.4cqi + 14px, 46px); line-height: 1.08; letter-spacing: -.01em; color: var(--x-ink); text-wrap: balance; margin-bottom: 14px; }
.tvx__lede { font-size: clamp(16px, .5cqi + 12px, 19px); line-height: 1.65; font-weight: 500; color: var(--x-muted); text-wrap: pretty; }
.tvx__h3 { font-weight: 800; font-size: clamp(21px, .8cqi + 15px, 26px); line-height: 1.2; color: var(--x-ink); margin-bottom: 18px; text-wrap: balance; }

.tvx__icon { flex: none; width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center; background: var(--x-blue-tint); color: var(--x-blue); }
.tvx__icon svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

.tvx__chips { display: flex; flex-wrap: wrap; gap: 8px; }
.tvx__chips li { padding: 7px 13px; border: 1px solid var(--x-line); border-radius: 20px; background: var(--x-paper); font-size: 14px; font-weight: 600; line-height: 1.3; color: var(--x-ink); }

/* closing call to action */
.tvx__cta { margin-top: clamp(40px, 5cqi, 64px); border-radius: 14px; padding: clamp(28px, 4cqi, 44px); display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 24px 40px; color: #fff; background: radial-gradient(60% 120% at 85% 0%, rgba(8, 106, 217, .55), transparent 70%), linear-gradient(160deg, var(--x-navy-2), var(--x-navy)); }
.tvx__cta-text { min-width: 0; max-width: 560px; }
.tvx__cta-title { font-weight: 800; font-size: clamp(22px, 1cqi + 15px, 30px); line-height: 1.2; color: #fff; text-wrap: balance; }
.tvx__cta-body { margin-top: 8px; font-size: 16px; line-height: 1.6; color: rgba(255, 255, 255, .82); }
.tvx__cta-actions { display: flex; flex-wrap: wrap; gap: 12px; }
.tvx__btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 52px; padding: 0 22px; border-radius: 8px; font-weight: 700; font-size: 14px; line-height: 1; letter-spacing: .1em; text-transform: uppercase; text-decoration: none; white-space: nowrap; transition: background-color .2s ease, border-color .2s ease, transform .2s ease; }
.tvx__btn svg { width: 18px; height: 18px; flex: none; }
.tvx__btn--primary { background: var(--x-beige); color: var(--x-ink); }
.tvx__btn--primary:hover, .tvx__btn--primary:focus { background: var(--x-beige-lite); color: var(--x-ink); }
.tvx__btn--ghost { color: #fff; border: 1.5px solid rgba(255, 255, 255, .34); }
.tvx__btn--ghost:hover, .tvx__btn--ghost:focus { color: #fff; border-color: #fff; background: rgba(255, 255, 255, .06); }
.tvx__btn:active { transform: translateY(1px); }
.tvx__btn:focus-visible { outline-color: var(--x-beige-lite); }

/* scroll reveal: only armed by JS, so content is visible without it */
.tvx.is-armed [data-reveal] { opacity: 0; transform: translateY(16px); transition: opacity .7s var(--x-ease), transform .7s var(--x-ease); transition-delay: calc(var(--i, 0) * 70ms); }
.tvx.is-armed [data-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .tvx *, .tvx *::before, .tvx *::after { animation: none !important; transition: none !important; }
  .tvx.is-armed [data-reveal] { opacity: 1; transform: none; }
}
@container tvx (max-width: 560px) {
  .tvx__cta-actions { width: 100%; flex-direction: column; }
  .tvx__btn { width: 100%; padding: 14px 16px; letter-spacing: .07em; white-space: normal; text-align: center; line-height: 1.3; }
}

/* ===== Blog (.tvbl): home "News & Articles" section, the News page and the article page. Builds on ../platform/tv-shared.css ===== */
.tvbl { background: var(--x-paper); }
.tvbl__band { width: 100%; }
.tvbl__band--mist { background: var(--x-mist); }

/* section head (home + news page) */
.tvbl__head { max-width: 760px; margin-bottom: clamp(28px, 4cqi, 44px); }
.tvbl__head--center { margin-inline: auto; text-align: center; }
.tvbl__eyebrow { display: inline-flex; align-items: center; gap: 10px; margin-bottom: 10px; font-size: 16px; font-weight: 600; color: var(--x-muted); }
.tvbl__eyebrow::before { content: ""; width: 14px; height: 2px; background: var(--x-beige); }
.tvbl__head--center .tvx__title { margin-inline: auto; }
.tvbl__head--center .tvx__lede { margin-inline: auto; max-width: 640px; }

/* cards */
.tvbl__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.tvbl__card { position: relative; display: flex; flex-direction: column; border-radius: 16px; overflow: hidden; background: var(--x-paper); border: 1px solid var(--x-line); transition: border-color .25s ease, box-shadow .25s ease, transform .25s ease; }
.tvbl__card:hover { border-color: #C9D3E0; box-shadow: 0 22px 40px -28px rgba(6, 20, 43, .45); transform: translateY(-3px); }
.tvbl__card-img { display: block; aspect-ratio: 16 / 9; overflow: hidden; background: var(--x-navy); }
.tvbl__card-img img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--x-ease); }
.tvbl__card:hover .tvbl__card-img img { transform: scale(1.03); }
.tvbl__card-body { display: flex; flex-direction: column; gap: 10px; flex: 1; padding: 20px 22px 22px; }
.tvbl__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; font-size: 13.5px; font-weight: 600; line-height: 1.3; color: var(--x-muted); }
.tvbl__meta > span + span::before { content: ""; display: inline-block; width: 4px; height: 4px; margin: 0 10px 2px 0; border-radius: 50%; background: #C3CBD8; vertical-align: middle; }
.tvbl__cat { display: inline-block; padding: 4px 10px; border-radius: 20px; background: var(--x-blue-tint); color: var(--x-blue-ink); font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; text-decoration: none; }
.tvbl__cat[data-cat="case-studies"] { background: #F8EEE7; color: #8A5A3E; }
.tvbl__cat[data-cat="guides"] { background: #E6F6EE; color: #0E7A47; }
a.tvbl__cat:hover { filter: brightness(.96); }
.tvbl__card-title { font-weight: 700; font-size: 20px; line-height: 1.3; color: var(--x-ink); text-wrap: balance; }
.tvbl__card-title a { color: inherit; text-decoration: none; }
.tvbl__card-title a::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.tvbl__card-title a:focus-visible { outline: none; }
.tvbl__card:has(.tvbl__card-title a:focus-visible) { outline: 3px solid var(--x-blue); outline-offset: 3px; }
.tvbl__card-ex { font-size: 15px; line-height: 1.6; color: var(--x-muted); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.tvbl__more { margin-top: auto; padding-top: 6px; display: inline-flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--x-blue); }
.tvbl__more svg { width: 16px; height: 16px; transition: transform .2s ease; }
.tvbl__card:hover .tvbl__more svg { transform: translateX(4px); }

/* featured (first) card on the news page */
.tvbl__card--feature { grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.tvbl__card--feature .tvbl__card-img { aspect-ratio: auto; min-height: 100%; }
.tvbl__card--feature .tvbl__card-body { justify-content: center; gap: 14px; padding: clamp(24px, 3.4cqi, 44px); }
.tvbl__card--feature .tvbl__card-title { font-size: clamp(24px, 1.2cqi + 14px, 32px); line-height: 1.2; }
.tvbl__card--feature .tvbl__card-ex { font-size: 16.5px; -webkit-line-clamp: 4; }

/* filter chips (news page) */
.tvbl__filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 26px; }
.tvx .tvbl__filter { padding: 9px 16px; border-radius: 30px; border: 1px solid var(--x-line); background: var(--x-paper); font-size: 14.5px; font-weight: 700; line-height: 1.2; color: var(--x-ink); transition: background-color .2s ease, color .2s ease, border-color .2s ease; }
.tvx .tvbl__filter:hover { border-color: #C9D3E0; background: var(--x-paper); color: var(--x-ink); }
.tvx .tvbl__filter[aria-pressed="true"] { background: var(--x-ink); border-color: var(--x-ink); color: #fff; }
.tvbl__card[hidden] { display: none; }
.tvbl__empty { padding: 40px; text-align: center; color: var(--x-muted); }

.tvbl__all { display: flex; justify-content: center; margin-top: clamp(28px, 4cqi, 40px); }
.tvbl .tvx__btn--outline { color: var(--x-ink); border: 1.5px solid #C9D3E0; }
.tvbl .tvx__btn--outline:hover, .tvbl .tvx__btn--outline:focus { color: var(--x-ink); border-color: var(--x-ink); }
.tvbl .tvx__btn--outline:focus-visible { outline-color: var(--x-blue); }

/* ---------- article page ---------- */
.tvbl__article { max-width: 960px; margin: 0 auto; padding-inline: clamp(16px, 4cqi, 32px); padding-block: clamp(40px, 6cqi, 72px) clamp(48px, 6cqi, 80px); }
.tvbl__article > :not(.tvbl__cover) { max-width: 720px; margin-inline: auto; }
.tvbl__meta--top { margin-bottom: 18px; font-size: 14.5px; }
.tvbl__lede { font-size: clamp(19px, .6cqi + 15px, 22px); line-height: 1.6; font-weight: 500; color: #3A4252; text-wrap: pretty; }
.tvbl__cover { margin: clamp(28px, 4cqi, 40px) 0; border-radius: 18px; overflow: hidden; background: var(--x-navy); box-shadow: 0 30px 60px -40px rgba(6, 20, 43, .55); }
.tvbl__cover img { width: 100%; height: auto; }

.tvbl__glance { margin-bottom: 36px; padding: 22px 24px; border-radius: 14px; background: var(--x-mist); border: 1px solid var(--x-line); }
.tvbl__glance-client { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; margin-bottom: 16px; }
.tvbl__glance-client b { font-size: 17px; font-weight: 800; color: var(--x-ink); }
.tvbl__glance-client span { font-size: 14px; font-weight: 600; color: var(--x-muted); }
.tvbl__glance dl { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
.tvbl__glance dl > div { display: flex; flex-direction: column-reverse; gap: 4px; padding-left: 14px; border-left: 2px solid #D9E2EE; }
.tvbl__glance dd { font-size: clamp(22px, .8cqi + 16px, 28px); font-weight: 800; line-height: 1.05; color: var(--x-blue); font-variant-numeric: tabular-nums; }
.tvbl__glance dt { font-size: 13.5px; font-weight: 600; line-height: 1.35; color: var(--x-muted); }

.tvbl__body { font-size: 18px; line-height: 1.75; color: #2E3442; }
.tvbl__body > * + * { margin-top: 18px; }
.tvbl__body h2 { margin-top: 46px; font-weight: 800; font-size: clamp(24px, .8cqi + 18px, 30px); line-height: 1.2; letter-spacing: -.005em; color: var(--x-ink); text-wrap: balance; }
.tvbl__body h3 { margin-top: 30px; font-weight: 700; font-size: 21px; line-height: 1.3; color: var(--x-ink); }
.tvbl__body h2 + *, .tvbl__body h3 + * { margin-top: 12px; }
.tvbl__body strong { font-weight: 700; color: var(--x-ink); }
.tvbl__body a { color: var(--x-blue); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: rgba(8, 106, 217, .35); }
.tvbl__body a:hover { color: var(--x-blue-ink); text-decoration-color: currentColor; }
.tvbl__body ul, .tvbl__body ol { display: grid; gap: 10px; }
.tvbl__body ul > li { position: relative; padding-left: 26px; }
.tvbl__body ul > li::before { content: ""; position: absolute; left: 4px; top: .7em; width: 8px; height: 8px; border-radius: 50%; background: var(--x-beige); }
.tvbl__body ol:not(.tvbl__steps) { counter-reset: tvbl; }
.tvbl__body ol:not(.tvbl__steps) > li { position: relative; padding-left: 42px; counter-increment: tvbl; }
.tvbl__body ol:not(.tvbl__steps) > li::before { content: counter(tvbl); position: absolute; left: 0; top: .1em; width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; background: var(--x-blue-tint); color: var(--x-blue); font-size: 14px; font-weight: 800; line-height: 1; }
.tvbl__fig { margin-block: 32px; }
.tvbl__fig img { width: 100%; height: auto; border-radius: 14px; border: 1px solid var(--x-line); background: var(--x-mist); }
.tvbl__fig figcaption { margin-top: 10px; font-size: 14.5px; line-height: 1.5; color: var(--x-muted); }
.tvbl__note { margin-top: 32px; padding: 18px 20px; border-radius: 12px; background: var(--x-mist); border-left: 3px solid var(--x-blue); font-size: 16.5px; line-height: 1.6; }
.tvbl__steps { display: grid; gap: 12px; }
.tvbl__steps li { position: relative; padding: 16px 18px 16px 60px; border-radius: 12px; border: 1px solid var(--x-line); background: var(--x-paper); font-size: 17px; line-height: 1.6; }
.tvbl__steps li::before { content: ""; position: absolute; left: 18px; top: 18px; width: 26px; height: 26px; border-radius: 50%; background: var(--x-blue) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / 15px no-repeat; }
.tvbl__steps li.is-now::before { background: var(--x-paper); box-shadow: inset 0 0 0 3px var(--x-beige); }
.tvbl__steps li > span { display: inline-block; margin: 0 8px 4px 0; padding: 2px 9px; border-radius: 20px; font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; background: #E6F6EE; color: #0E7A47; vertical-align: 2px; }
.tvbl__steps li.is-now > span { background: #F8EEE7; color: #8A5A3E; }

/* author box under every article; the byline links to it */
.tvbl__meta .tvbl__by { color: inherit; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: #C3CBD8; }
.tvbl__meta .tvbl__by:hover { color: var(--x-ink); text-decoration-color: currentColor; }
.tvbl__author { display: flex; align-items: flex-start; gap: 18px; margin-top: 44px; padding: 22px 24px; border-radius: 14px; background: var(--x-mist); border: 1px solid var(--x-line); scroll-margin-top: 110px; }
.tvbl__author-mark { flex: none; width: 56px; height: 56px; border-radius: 50%; display: grid; place-items: center; background: var(--x-navy); color: #fff; font-size: 18px; font-weight: 800; letter-spacing: .04em; box-shadow: inset 0 0 0 2px var(--x-beige); }
.tvbl__author-kicker { font-size: 12.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--x-muted); }
.tvbl__author-name { margin-top: 4px; font-size: 19px; font-weight: 800; line-height: 1.3; color: var(--x-ink); }
.tvbl__author-role { margin-top: 2px; font-size: 14.5px; font-weight: 600; color: var(--x-blue-ink); }
.tvbl__author-bio { margin-top: 10px; font-size: 16px; line-height: 1.65; color: #3A4252; text-wrap: pretty; }
.tvbl__author + .tvbl__share { margin-top: 28px; }
.tvbl__share { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 44px; padding-top: 24px; border-top: 1px solid var(--x-line); }
.tvbl__share > span { margin-right: 6px; font-size: 14px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--x-muted); }
.tvx .tvbl__sh { width: 42px; height: 42px; border-radius: 50%; display: inline-grid; place-items: center; border: 1px solid var(--x-line); background: var(--x-paper); color: var(--x-ink); text-decoration: none; transition: background-color .2s ease, color .2s ease, border-color .2s ease; }
.tvx .tvbl__sh:hover { background: var(--x-ink); border-color: var(--x-ink); color: #fff; }
.tvbl__sh svg { width: 18px; height: 18px; }
.tvbl__copied { font-size: 14px; font-weight: 600; color: #0E7A47; opacity: 0; transition: opacity .2s ease; }
.tvbl__copied.is-on { opacity: 1; }
.tvbl .tvx__cta { margin-top: 0; }

@container tvx (max-width: 1020px) {
  .tvbl__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tvbl__grid--home > :nth-child(3) { display: none; }
}
@container tvx (max-width: 900px) {
  .tvbl__card--feature { grid-template-columns: minmax(0, 1fr); }
  .tvbl__card--feature .tvbl__card-img { aspect-ratio: 16 / 9; min-height: 0; }
  .tvbl__glance dl { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@container tvx (max-width: 640px) {
  .tvbl__author { flex-direction: column; gap: 12px; padding: 18px; }
  .tvbl__grid { grid-template-columns: minmax(0, 1fr); }
  .tvbl__grid--home > :nth-child(3) { display: flex; }
  .tvbl__body { font-size: 17px; }
  .tvbl__cover { border-radius: 12px; margin-inline: calc(-1 * clamp(0px, 2cqi, 8px)); }
}

.tvbl .tvx__inner--tight { padding-block: clamp(40px, 5cqi, 64px); }

</style>
<section class="tvx tvbl tvbl--post" aria-label="Is your business ready to sell online? 8 signs">
  <div class="tvbl__article">
    <div class="tvbl__meta tvbl__meta--top"><a class="tvbl__cat" data-cat="guides" href="https://topvieweg.com/blog/?cat=guides">Guide</a><span>14 October 2026</span><span>2 min read</span><span>By <a class="tvbl__by" href="#tvbl-author">Amr Bendary</a></span></div>
    <p class="tvbl__lede">How do you know it is time for your own online store or app? Here are eight signs we see in businesses that are ready, and what to have in place before you start.</p>
    <figure class="tvbl__cover"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-g-ready.jpg" width="1200" height="675" alt="A checklist of signs a business is ready to sell online" decoding="async"></figure>
    <div class="tvbl__body">
<p>There is no perfect moment to start selling online, but there are clear signs. If several of these sound familiar, your customers are already asking for it.</p>

<h2>The signs</h2>
<ol>
  <li><strong>Customers already order by phone or WhatsApp.</strong> The demand is there; it is just arriving through the slowest channel.</li>
  <li><strong>Your phone lines are busy at peak times.</strong> Every missed call is a missed order.</li>
  <li><strong>Delivery apps take a growing share of your sales.</strong> More of your orders, and your customers, live on someone else’s platform.</li>
  <li><strong>You have loyal customers you cannot reach.</strong> They come back often, but you have no way to tell them about a new product or offer.</li>
  <li><strong>You run more than one branch, or plan to.</strong> Online ordering helps send each order to the right branch automatically.</li>
  <li><strong>Customers ask to pay by card or wallet.</strong> Cash only is starting to cost you orders.</li>
  <li><strong>You run offers but cannot measure them.</strong> You do not know which promotion actually brought orders.</li>
  <li><strong>Competitors near you already have an app or store.</strong> Your customers are getting used to ordering that way.</li>
</ol>

<h2>What to have in place first</h2>
<ul>
  <li><strong>A clear product list</strong> with prices and good photos.</li>
  <li><strong>A delivery plan:</strong> your own drivers, a partner, branch pickup, or a mix.</li>
  <li><strong>Someone who owns online orders</strong> in each branch, so no order is left waiting.</li>
  <li><strong>A system for prices and stock,</strong> such as your POS or ERP, so what customers see online is true.</li>
</ul>

<h2>Not ready yet?</h2>
<p>That is fine. Start by fixing the basics above: organise your product list, decide how delivery will work, and agree who handles online orders. When those are clear, building the store goes much faster.</p>

<h2>Ready?</h2>
<p>The next decision is where to start: a website, an app, or both. We cover that in <a href="https://topvieweg.com/website-app-or-both/">Website, app or both?</a></p>
<p class="tvbl__note">Want a second opinion on your situation? <a href="https://topvieweg.com/contact/">Book a free meeting</a> and we will look at how your branches work today.</p>
    </div>
    <aside class="tvbl__author" id="tvbl-author" aria-labelledby="tvbl-author-name">
      <span class="tvbl__author-mark" aria-hidden="true">AB</span>
      <div>
        <p class="tvbl__author-kicker">About the author</p>
        <p class="tvbl__author-name" id="tvbl-author-name">Amr Bendary</p>
        <p class="tvbl__author-role">Founder, Top View · CTO, Etoile</p>
        <p class="tvbl__author-bio">Founder of Top View and CTO at Etoile, Amr Bendary brings over 20 years of experience in digital transformation, mobile apps, e-commerce, and ERP integration. He holds an MBA in Digital Transformation and helps businesses connect technology with growth and operational efficiency.</p>
      </div>
    </aside>
    <div class="tvbl__share"><span>Share</span>
      <a class="tvbl__sh" href="https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Ftopvieweg.com%2Fready-to-sell-online%2F" target="_blank" rel="noopener" aria-label="Share on LinkedIn"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M6.94 8.5H3.56V20h3.38V8.5ZM5.25 3a1.96 1.96 0 1 0 0 3.92 1.96 1.96 0 0 0 0-3.92ZM20.44 13.4c0-3.1-1.65-4.55-3.86-4.55-1.78 0-2.58.98-3.02 1.67V8.5h-3.38c.04.95 0 11.5 0 11.5h3.38v-6.42c0-.34.02-.69.13-.93.27-.69.9-1.4 1.95-1.4 1.38 0 1.93 1.05 1.93 2.59V20h3.37v-6.6Z"/></svg></a>
      <a class="tvbl__sh" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Ftopvieweg.com%2Fready-to-sell-online%2F" target="_blank" rel="noopener" aria-label="Share on Facebook"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M13.5 21v-7.5h2.53l.38-2.93H13.5V8.7c0-.85.24-1.43 1.45-1.43h1.55V4.65a20.8 20.8 0 0 0-2.26-.12c-2.24 0-3.77 1.37-3.77 3.88v2.16H7.94v2.93h2.53V21h3.03Z"/></svg></a>
      <a class="tvbl__sh" href="https://wa.me/?text=Is%20your%20business%20ready%20to%20sell%20online%3F%208%20signs%20https%3A%2F%2Ftopvieweg.com%2Fready-to-sell-online%2F" target="_blank" rel="noopener" aria-label="Share on WhatsApp"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M17.47 14.38c-.3-.15-1.76-.87-2.03-.97-.27-.1-.47-.15-.67.15-.2.3-.77.97-.94 1.16-.17.2-.35.22-.64.07-.3-.15-1.26-.46-2.39-1.47-.88-.79-1.48-1.76-1.65-2.06-.17-.3-.02-.46.13-.61.13-.13.3-.35.45-.52.15-.17.2-.3.3-.5.1-.2.05-.37-.03-.52-.07-.15-.67-1.61-.92-2.21-.24-.58-.49-.5-.67-.51h-.57c-.2 0-.52.07-.79.37-.27.3-1.04 1.02-1.04 2.48 0 1.46 1.07 2.88 1.21 3.07.15.2 2.1 3.2 5.08 4.49.71.31 1.26.49 1.69.63.71.23 1.36.2 1.87.12.57-.09 1.76-.72 2-1.41.25-.7.25-1.29.18-1.41-.08-.13-.27-.2-.57-.35ZM12.05 21.79h-.01a9.87 9.87 0 0 1-5.03-1.38l-.36-.21-3.74.98 1-3.65-.24-.37a9.86 9.86 0 0 1-1.51-5.26c0-5.45 4.44-9.88 9.89-9.88a9.83 9.83 0 0 1 9.88 9.89c0 5.45-4.44 9.88-9.88 9.88Zm8.41-18.3A11.82 11.82 0 0 0 12.05 0C5.5 0 .16 5.34.16 11.89c0 2.1.55 4.14 1.59 5.95L.06 24l6.3-1.65a11.88 11.88 0 0 0 5.68 1.45h.01c6.55 0 11.89-5.34 11.89-11.89 0-3.18-1.24-6.17-3.48-8.42Z"/></svg></a>
      <a class="tvbl__sh" href="https://topvieweg.com/ready-to-sell-online/" data-copy aria-label="Copy link"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1"/><path d="M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1"/></svg></a><span class="tvbl__copied" aria-live="polite">Link copied</span>
    </div>
  </div>
  <div class="tvbl__band">
    <div class="tvx__inner tvx__inner--tight">
      <div class="tvx__cta" data-reveal>
        <div class="tvx__cta-text"><h3 class="tvx__cta-title">Planning something similar?</h3><p class="tvx__cta-body">Book a free meeting with our team. We will review how your branches work and suggest the right setup.</p></div>
        <div class="tvx__cta-actions">
          <a class="tvx__btn tvx__btn--primary" href="https://topvieweg.com/contact/" data-tvx="consultation" data-where="blog_ready-to-sell-online">Get a Free Consultation <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          <a class="tvx__btn tvx__btn--ghost" href="https://wa.me/201114000096?text=Hello%20TopView%2C%20I'm%20contacting%20you%20from%20your%20website%20(News%20article).%20I'd%20like%20to%20discuss%20a%20project." target="_blank" rel="noopener" data-tvx="whatsapp"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M17.47 14.38c-.3-.15-1.76-.87-2.03-.97-.27-.1-.47-.15-.67.15-.2.3-.77.97-.94 1.16-.17.2-.35.22-.64.07-.3-.15-1.26-.46-2.39-1.47-.88-.79-1.48-1.76-1.65-2.06-.17-.3-.02-.46.13-.61.13-.13.3-.35.45-.52.15-.17.2-.3.3-.5.1-.2.05-.37-.03-.52-.07-.15-.67-1.61-.92-2.21-.24-.58-.49-.5-.67-.51h-.57c-.2 0-.52.07-.79.37-.27.3-1.04 1.02-1.04 2.48 0 1.46 1.07 2.88 1.21 3.07.15.2 2.1 3.2 5.08 4.49.71.31 1.26.49 1.69.63.71.23 1.36.2 1.87.12.57-.09 1.76-.72 2-1.41.25-.7.25-1.29.18-1.41-.08-.13-.27-.2-.57-.35ZM12.05 21.79h-.01a9.87 9.87 0 0 1-5.03-1.38l-.36-.21-3.74.98 1-3.65-.24-.37a9.86 9.86 0 0 1-1.51-5.26c0-5.45 4.44-9.88 9.89-9.88a9.83 9.83 0 0 1 9.88 9.89c0 5.45-4.44 9.88-9.88 9.88Zm8.41-18.3A11.82 11.82 0 0 0 12.05 0C5.5 0 .16 5.34.16 11.89c0 2.1.55 4.14 1.59 5.95L.06 24l6.3-1.65a11.88 11.88 0 0 0 5.68 1.45h.01c6.55 0 11.89-5.34 11.89-11.89 0-3.18-1.24-6.17-3.48-8.42Z"/></svg> Chat on WhatsApp</a>
        </div>
      </div>
    </div>
  </div>
  <div class="tvbl__band tvbl__band--mist">
    <div class="tvx__inner">
      <div class="tvbl__head" data-reveal><h2 class="tvx__title">More articles</h2></div>
      <div class="tvbl__grid" data-tvbl-feed data-count="3" data-exclude="5577" data-reveal>
        <article class="tvbl__card" data-id="5571" data-cat="insights">
          <a class="tvbl__card-img" href="https://topvieweg.com/own-app-vs-delivery-apps/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-own-app.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="insights">Insight</span><span>14 Oct 2026</span><span>3 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/own-app-vs-delivery-apps/">Your own app or delivery apps? What changes for a multi-branch brand</a></h3>
            <p class="tvbl__card-ex">Delivery apps bring orders, but they keep the customer and take a share of every sale. Here is what changes when a multi-branch brand runs its own app and online store, and how to start without losing the orders you already have.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
        <article class="tvbl__card" data-id="5575" data-cat="guides">
          <a class="tvbl__card-img" href="https://topvieweg.com/what-is-ecommerce/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-g-what.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="guides">Guide</span><span>14 Oct 2026</span><span>2 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/what-is-ecommerce/">What is e-commerce? A plain guide for business owners</a></h3>
            <p class="tvbl__card-ex">E-commerce is more than a website with a cart. Here is what it really means for a restaurant, shop or brand, the channels it covers, and the parts that have to work together behind every online order.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
        <article class="tvbl__card" data-id="5572" data-cat="case-studies">
          <a class="tvbl__card-img" href="https://topvieweg.com/etoile-egypt-app-case-study/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-etoile.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="case-studies">Case study</span><span>14 Oct 2026</span><span>2 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/etoile-egypt-app-case-study/">How Etoile Egypt went from a call centre to 520,000+ app users</a></h3>
            <p class="tvbl__card-ex">Etoile Egypt moved its online orders from a busy call centre to its own app and website. Today the app has more than 520,000 users and takes thousands of orders a day, connected to the branches, ERP and POS.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
      </div>
      <div class="tvbl__all"><a class="tvx__btn tvx__btn--outline" href="https://topvieweg.com/blog/">View all articles <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a></div>
    </div>
  </div>
</section>
<script>
(function () {
  var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  function fmt(n) { return Math.round(n).toLocaleString('en-US'); }
  function countUp(el) {
    var to = Number(el.getAttribute('data-n'));
    if (reduce || !to) return;
    var dur = 1200, t0 = null;
    el.textContent = fmt(0);
    requestAnimationFrame(function step(t) {
      if (t0 === null) t0 = t;
      var p = Math.min(1, (t - t0) / dur);
      el.textContent = fmt(to * (1 - Math.pow(1 - p, 3)));
      if (p < 1) requestAnimationFrame(step);
    });
    // always land on the real value, even if frames stall
    setTimeout(function () { el.textContent = fmt(to); }, dur + 400);
  }

  function init(root) {
    root.setAttribute('data-ready', '');
    root.classList.add('is-js');

    // scroll reveal (armed only here, so the section is complete without JS)
    var items = [].slice.call(root.querySelectorAll('[data-reveal]'));
    var drawTarget = root.querySelector('[data-draw]');
    if (!reduce && 'IntersectionObserver' in window) {
      root.classList.add('is-armed');
      var io = new IntersectionObserver(function (entries) {
        entries.forEach(function (e) {
          if (!e.isIntersecting) return;
          io.unobserve(e.target);
          if (e.target === drawTarget) {
            root.classList.add('is-drawn');
            [].slice.call(root.querySelectorAll('[data-n]')).forEach(countUp);
          } else {
            e.target.classList.add('is-in');
          }
        });
      }, { threshold: 0.15, rootMargin: '0px 0px -40px 0px' });
      items.forEach(function (el) { io.observe(el); });
      if (drawTarget) io.observe(drawTarget);
      // safety net: never leave content hidden
      setTimeout(function () { items.forEach(function (el) { el.classList.add('is-in'); }); root.classList.add('is-drawn'); }, 4000);
    } else {
      root.classList.add('is-drawn');
    }
    // looping decorations pause while the section is off screen
    if ('IntersectionObserver' in window) {
      new IntersectionObserver(function (entries) { root.classList.toggle('is-off', !entries[entries.length - 1].isIntersecting); }).observe(root);
    }

    // looping motion ([data-loop]) starts when first seen, so it opens on its first scene, and pauses off screen
    [].slice.call(root.querySelectorAll('[data-loop]')).forEach(function (el) {
      if (reduce || !('IntersectionObserver' in window)) return;
      new IntersectionObserver(function (entries) {
        var on = entries[entries.length - 1].isIntersecting; // several entries can queue up during a fast scroll; the last one is current
        if (on) el.classList.add('is-playing');
        el.classList.toggle('is-paused', !on);
      }, { threshold: 0.3 }).observe(el);
    });

    // tabs with a sliding highlight
    var tabs = [].slice.call(root.querySelectorAll('[role="tab"]'));
    if (!tabs.length) return;
    var panels = tabs.map(function (t) { return root.querySelector('#' + t.getAttribute('aria-controls')); });
    var ink = root.querySelector('.tvpf__ink');
    var list = tabs[0].parentNode;
    var current = Math.max(0, tabs.findIndex(function (t) { return t.getAttribute('aria-selected') === 'true'; }));
    function moveInk() {
      if (!ink) return;
      var t = tabs[current];
      ink.style.width = t.offsetWidth + 'px';
      ink.style.transform = 'translateX(' + t.offsetLeft + 'px)';
    }
    function show(n, focus) {
      if (n === current) return;
      current = (n + tabs.length) % tabs.length;
      tabs.forEach(function (t, k) {
        var on = k === current;
        t.classList.toggle('is-active', on);
        t.setAttribute('aria-selected', on ? 'true' : 'false');
        t.tabIndex = on ? 0 : -1;
      });
      panels.forEach(function (p, k) {
        var on = k === current;
        p.hidden = !on;
        p.classList.toggle('is-active', on);
        p.classList.remove('is-entering');
        if (on && !reduce) { void p.offsetWidth; p.classList.add('is-entering'); }
      });
      moveInk();
      var t = tabs[current];
      if (list.scrollWidth > list.clientWidth) list.scrollTo({ left: t.offsetLeft - (list.clientWidth - t.offsetWidth) / 2, behavior: reduce ? 'auto' : 'smooth' });
      if (focus) t.focus();
    }
    tabs.forEach(function (t, k) {
      t.addEventListener('click', function () { show(k); });
      t.addEventListener('keydown', function (e) {
        if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') { e.preventDefault(); show(current + (e.key === 'ArrowRight' ? 1 : -1), true); }
      });
    });
    moveInk();
    if (window.ResizeObserver) new ResizeObserver(moveInk).observe(list);
    window.addEventListener('load', moveInk);
  }

  [].slice.call(document.querySelectorAll('.tvx:not([data-ready])')).forEach(init);

  // calls to action: same tracking as the floating WhatsApp button and the home CTA
  // (each section ships this script, so register the listener only once per page)
  if (window.__tvxCtaTracking) return;
  window.__tvxCtaTracking = true;
  document.addEventListener('click', function (e) {
    var a = e.target.closest && e.target.closest('.tvx a[data-tvx]');
    if (!a) return;
    if (a.getAttribute('data-tvx') === 'whatsapp') {
      if (typeof gtag === 'function') { gtag('event', 'contact', { method: 'WhatsApp', link_url: a.href }); }
      if (typeof fbq === 'function') { fbq('track', 'Contact', { content_name: 'WhatsApp' }); }
      if (typeof window.lintrk === 'function') { window.lintrk('track', { conversion_id: 31200418 }); }
    } else if (typeof gtag === 'function') {
      gtag('event', 'cta_click', { cta: 'free_consultation', location: a.getAttribute('data-where') || 'section' });
    }
  });
})();

(function () {
  if (window.__tvblReady) return;
  window.__tvblReady = true;

  var CAT = { guides: 'Guide', 'case-studies': 'Case study', insights: 'Insight' };
  var arrow = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg>';
  var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

  function text(html, sel) {
    var d = document.createElement('div'); d.innerHTML = html || '';
    [].slice.call(d.querySelectorAll('style,script')).forEach(function (n) { n.remove(); });
    var part = sel && d.querySelector(sel);
    return ((part || d).textContent || '').replace(/\s+/g, ' ').trim();
  }
  function esc(s) { return String(s).replace(/[&<>"]/g, function (c) { return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c]; }); }

  // the same card markup the build script prints, rebuilt from the REST API so new posts show up on their own
  // mins comes from the card the build printed for that post; a post published later shows no reading time
  // p.tv_card = { img, cat, cat_name } is a small REST field added by the "TopView speed & SEO tweaks" snippet
  function card(p, feature, mins) {
    var tc = p.tv_card || {};
    var img = tc.img || '';
    var term = { slug: tc.cat || '', name: tc.cat_name || '' };
    var d = new Date(p.date);
    return '<article class="tvbl__card' + (feature ? ' tvbl__card--feature' : '') + '" data-id="' + p.id + '" data-cat="' + esc(term.slug || '') + '">' +
      (img ? '<a class="tvbl__card-img" href="' + esc(p.link) + '" tabindex="-1" aria-hidden="true"><img loading="lazy" src="' + esc(img) + '" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>' : '') +
      '<div class="tvbl__card-body"><div class="tvbl__meta">' + (term.slug ? '<span class="tvbl__cat" data-cat="' + esc(term.slug) + '">' + esc(CAT[term.slug] || term.name) + '</span>' : '') +
      '<span>' + d.getDate() + ' ' + months[d.getMonth()] + ' ' + d.getFullYear() + '</span>' + (mins ? '<span>' + mins + ' min read</span>' : '') + '</div>' +
      '<h3 class="tvbl__card-title"><a href="' + esc(p.link) + '">' + p.title.rendered + '</a></h3>' +
      '<p class="tvbl__card-ex">' + esc(text(p.excerpt && p.excerpt.rendered)) + '</p>' +
      '<span class="tvbl__more" aria-hidden="true">Read article ' + arrow + '</span></div></article>';
  }

  function applyFilter(root, cat) {
    var cards = [].slice.call(root.querySelectorAll('.tvbl__card'));
    var shown = 0;
    cards.forEach(function (c) { var on = !cat || c.getAttribute('data-cat') === cat; c.hidden = !on; if (on) shown++; });
    [].slice.call(root.querySelectorAll('.tvbl__filter')).forEach(function (b) { b.setAttribute('aria-pressed', String((b.getAttribute('data-cat') || '') === (cat || ''))); });
    var empty = root.querySelector('.tvbl__empty');
    if (empty) empty.hidden = shown > 0;
  }

  function initFilters() {
    [].slice.call(document.querySelectorAll('.tvbl [data-tvbl-filters]')).forEach(function (bar) {
      var root = bar.closest('.tvbl');
      if (bar.getAttribute('data-ready')) { var cur = bar.querySelector('[aria-pressed="true"]'); applyFilter(root, cur ? cur.getAttribute('data-cat') || '' : ''); return; }
      bar.setAttribute('data-ready', '1');
      bar.addEventListener('click', function (e) {
        var b = e.target.closest('.tvbl__filter');
        if (!b) return;
        applyFilter(root, b.getAttribute('data-cat') || '');
      });
      var m = location.search.match(/[?&]cat=([a-z-]+)/);
      applyFilter(root, m ? m[1] : '');
    });
  }

  // copy link
  document.addEventListener('click', function (e) {
    var b = e.target.closest && e.target.closest('.tvbl [data-copy]');
    if (!b) return;
    e.preventDefault();
    var done = function () { var t = b.parentNode.querySelector('.tvbl__copied'); if (t) { t.classList.add('is-on'); setTimeout(function () { t.classList.remove('is-on'); }, 1800); } };
    if (navigator.clipboard) navigator.clipboard.writeText(location.href.split('#')[0]).then(done, function () {}); else done();
  });

  var feeds = [].slice.call(document.querySelectorAll('[data-tvbl-feed]'));
  initFilters();
  if (!feeds.length || !window.fetch) return;

  // Only the fields a card shows (the full post content made this ~600 KB), and only once a feed
  // comes near the screen, so the request never competes with the page's first paint.
  var loaded = false;
  function refresh() {
    if (loaded) return;
    loaded = true;
    var mins = {};
    [].forEach.call(document.querySelectorAll('.tvbl__card[data-id]'), function (c) {
      var m = (c.textContent || '').match(/(\d+) min read/);
      if (m) mins[c.getAttribute('data-id')] = m[1];
    });
    fetch('/wp-json/wp/v2/posts?per_page=12&_fields=id,date,link,title,excerpt,tv_card', { credentials: 'omit' })
      .then(function (r) { return r.ok ? r.json() : Promise.reject(r.status); })
      .then(function (posts) {
        if (!Array.isArray(posts) || !posts.length || !posts[0].tv_card) return; // keep the printed cards if the field is missing
        feeds.forEach(function (feed) {
          var max = Number(feed.getAttribute('data-count')) || posts.length;
          var skip = Number(feed.getAttribute('data-exclude')) || 0;
          var list = posts.filter(function (p) { return p.id !== skip; }).slice(0, max);
          var have = [].map.call(feed.querySelectorAll('.tvbl__card'), function (el) { return el.getAttribute('data-id'); }).join();
          if (have === list.map(function (p) { return String(p.id); }).join()) return; // the printed cards are already current
          var feature = feed.hasAttribute('data-feature');
          feed.innerHTML = list.map(function (p, i) { return card(p, feature && i === 0, mins[p.id]); }).join('');
        });
        initFilters();
      })
      .catch(function () {});
  }
  if ('IntersectionObserver' in window) {
    var io = new IntersectionObserver(function (entries) {
      if (entries.some(function (e) { return e.isIntersecting; })) { io.disconnect(); refresh(); }
    }, { rootMargin: '600px 0px' });
    feeds.forEach(function (f) { io.observe(f); });
  } else {
    window.addEventListener('load', refresh);
  }
})();

</script>
				</div>
				</div>
				</div>
				</div>
		<p>The post <a href="https://topvieweg.com/ready-to-sell-online/">Is your business ready to sell online? 8 signs</a> appeared first on <a href="https://topvieweg.com">TopView</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Bringing a stalled ERP project back on track: lessons from Al Mohamady Group</title>
		<link>https://topvieweg.com/stalled-erp-project-lessons/</link>
		
		<dc:creator><![CDATA[TopView Team]]></dc:creator>
		<pubDate>Wed, 14 Oct 2026 07:00:00 +0000</pubDate>
				<category><![CDATA[Insights]]></category>
		<guid isPermaLink="false">https://tplabs.co/izeetak/?p=2011</guid>

					<description><![CDATA[<p>Al Mohamady Group’s Microsoft Dynamics 365 project had been stalled for a long time. As the client’s technical representative, we helped bring it back on track. Here is what we did, and what any ERP project can learn from it.</p>
<p>The post <a href="https://topvieweg.com/stalled-erp-project-lessons/">Bringing a stalled ERP project back on track: lessons from Al Mohamady Group</a> appeared first on <a href="https://topvieweg.com">TopView</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="2011" class="elementor elementor-2011" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-tvb2011c e-con-full e-flex e-con e-parent" data-id="tvb2011c" data-element_type="container" data-e-type="container">
				<div class="elementor-element elementor-element-tvb2011w elementor-widget elementor-widget-html" data-id="tvb2011w" data-element_type="widget" data-e-type="widget" data-widget_type="html.default">
				<div class="elementor-widget-container">
					<!-- TopView blog: article stalled-erp-project-lessons. Generated by live-site/blog/build.js from articles.js; edit there and rebuild. -->
<style>
/* Shared base for the TopView platform (.tvpf) and discount-system (.tvdm) sections.
   The izeetak theme styles every <button> (70px line height, 60px side padding, uppercase, wide tracking),
   sets body line height to 2 and decorates lists, so each section resets those inside itself. */
.tvx {
  --x-ink: #1B1825;
  --x-muted: #5A6475;
  --x-line: #E3E8EF;
  --x-paper: #FFFFFF;
  --x-mist: #F4F7FB;
  --x-blue: #086AD9;
  --x-blue-ink: #0757B3;
  --x-blue-tint: #E7F0FC;
  --x-beige: #D2A88F;
  --x-beige-lite: #E7C7B2;
  --x-navy: #06142B;
  --x-navy-2: #0B2A55;
  --x-ease: cubic-bezier(.2, .8, .2, 1);
  container: tvx / inline-size;
  position: relative;
  width: 100%;
  font-family: "Barlow", "Segoe UI", system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.5;
  color: var(--x-ink);
  text-align: left;
}
.elementor-widget:has(> .elementor-widget-container > .tvx) { width: 100%; min-width: 0; }
.tvx *, .tvx *::before, .tvx *::after { box-sizing: border-box; }
/* Element-weight resets (0,0,1): they still beat the theme (same weight, later in the page) but lose to every
   class rule, even when a second section on the page repeats this file after the first section’s rules. */
:where(.tvx) :is(h2, h3, h4, p, ul, ol, li, dl, dt, dd, figure) { margin: 0; padding: 0; }
:where(.tvx) :is(ul, ol) { list-style: none; }
:where(.tvx) li::before, :where(.tvx) li::after { content: none; }
:where(.tvx) img { display: block; max-width: 100%; height: auto; }
.tvx button { min-width: 0; min-height: 0; margin: 0; padding: 0; border: 0; background: none; color: inherit; font: inherit; line-height: inherit; letter-spacing: normal; text-transform: none; cursor: pointer; }
.tvx button:hover, .tvx button:focus { background: none; color: inherit; }
.tvx :focus-visible { outline: 3px solid var(--x-blue); outline-offset: 3px; }

.tvx__inner { max-width: 1200px; margin: 0 auto; padding-inline: clamp(16px, 4cqi, 32px); padding-block: clamp(56px, 7cqi, 96px); }
.tvx__head { max-width: 720px; margin-bottom: clamp(28px, 4cqi, 48px); }
.tvx__title { font-weight: 800; font-size: clamp(30px, 2.4cqi + 14px, 46px); line-height: 1.08; letter-spacing: -.01em; color: var(--x-ink); text-wrap: balance; margin-bottom: 14px; }
.tvx__lede { font-size: clamp(16px, .5cqi + 12px, 19px); line-height: 1.65; font-weight: 500; color: var(--x-muted); text-wrap: pretty; }
.tvx__h3 { font-weight: 800; font-size: clamp(21px, .8cqi + 15px, 26px); line-height: 1.2; color: var(--x-ink); margin-bottom: 18px; text-wrap: balance; }

.tvx__icon { flex: none; width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center; background: var(--x-blue-tint); color: var(--x-blue); }
.tvx__icon svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

.tvx__chips { display: flex; flex-wrap: wrap; gap: 8px; }
.tvx__chips li { padding: 7px 13px; border: 1px solid var(--x-line); border-radius: 20px; background: var(--x-paper); font-size: 14px; font-weight: 600; line-height: 1.3; color: var(--x-ink); }

/* closing call to action */
.tvx__cta { margin-top: clamp(40px, 5cqi, 64px); border-radius: 14px; padding: clamp(28px, 4cqi, 44px); display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 24px 40px; color: #fff; background: radial-gradient(60% 120% at 85% 0%, rgba(8, 106, 217, .55), transparent 70%), linear-gradient(160deg, var(--x-navy-2), var(--x-navy)); }
.tvx__cta-text { min-width: 0; max-width: 560px; }
.tvx__cta-title { font-weight: 800; font-size: clamp(22px, 1cqi + 15px, 30px); line-height: 1.2; color: #fff; text-wrap: balance; }
.tvx__cta-body { margin-top: 8px; font-size: 16px; line-height: 1.6; color: rgba(255, 255, 255, .82); }
.tvx__cta-actions { display: flex; flex-wrap: wrap; gap: 12px; }
.tvx__btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 52px; padding: 0 22px; border-radius: 8px; font-weight: 700; font-size: 14px; line-height: 1; letter-spacing: .1em; text-transform: uppercase; text-decoration: none; white-space: nowrap; transition: background-color .2s ease, border-color .2s ease, transform .2s ease; }
.tvx__btn svg { width: 18px; height: 18px; flex: none; }
.tvx__btn--primary { background: var(--x-beige); color: var(--x-ink); }
.tvx__btn--primary:hover, .tvx__btn--primary:focus { background: var(--x-beige-lite); color: var(--x-ink); }
.tvx__btn--ghost { color: #fff; border: 1.5px solid rgba(255, 255, 255, .34); }
.tvx__btn--ghost:hover, .tvx__btn--ghost:focus { color: #fff; border-color: #fff; background: rgba(255, 255, 255, .06); }
.tvx__btn:active { transform: translateY(1px); }
.tvx__btn:focus-visible { outline-color: var(--x-beige-lite); }

/* scroll reveal: only armed by JS, so content is visible without it */
.tvx.is-armed [data-reveal] { opacity: 0; transform: translateY(16px); transition: opacity .7s var(--x-ease), transform .7s var(--x-ease); transition-delay: calc(var(--i, 0) * 70ms); }
.tvx.is-armed [data-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .tvx *, .tvx *::before, .tvx *::after { animation: none !important; transition: none !important; }
  .tvx.is-armed [data-reveal] { opacity: 1; transform: none; }
}
@container tvx (max-width: 560px) {
  .tvx__cta-actions { width: 100%; flex-direction: column; }
  .tvx__btn { width: 100%; padding: 14px 16px; letter-spacing: .07em; white-space: normal; text-align: center; line-height: 1.3; }
}

/* ===== Blog (.tvbl): home "News & Articles" section, the News page and the article page. Builds on ../platform/tv-shared.css ===== */
.tvbl { background: var(--x-paper); }
.tvbl__band { width: 100%; }
.tvbl__band--mist { background: var(--x-mist); }

/* section head (home + news page) */
.tvbl__head { max-width: 760px; margin-bottom: clamp(28px, 4cqi, 44px); }
.tvbl__head--center { margin-inline: auto; text-align: center; }
.tvbl__eyebrow { display: inline-flex; align-items: center; gap: 10px; margin-bottom: 10px; font-size: 16px; font-weight: 600; color: var(--x-muted); }
.tvbl__eyebrow::before { content: ""; width: 14px; height: 2px; background: var(--x-beige); }
.tvbl__head--center .tvx__title { margin-inline: auto; }
.tvbl__head--center .tvx__lede { margin-inline: auto; max-width: 640px; }

/* cards */
.tvbl__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.tvbl__card { position: relative; display: flex; flex-direction: column; border-radius: 16px; overflow: hidden; background: var(--x-paper); border: 1px solid var(--x-line); transition: border-color .25s ease, box-shadow .25s ease, transform .25s ease; }
.tvbl__card:hover { border-color: #C9D3E0; box-shadow: 0 22px 40px -28px rgba(6, 20, 43, .45); transform: translateY(-3px); }
.tvbl__card-img { display: block; aspect-ratio: 16 / 9; overflow: hidden; background: var(--x-navy); }
.tvbl__card-img img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--x-ease); }
.tvbl__card:hover .tvbl__card-img img { transform: scale(1.03); }
.tvbl__card-body { display: flex; flex-direction: column; gap: 10px; flex: 1; padding: 20px 22px 22px; }
.tvbl__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; font-size: 13.5px; font-weight: 600; line-height: 1.3; color: var(--x-muted); }
.tvbl__meta > span + span::before { content: ""; display: inline-block; width: 4px; height: 4px; margin: 0 10px 2px 0; border-radius: 50%; background: #C3CBD8; vertical-align: middle; }
.tvbl__cat { display: inline-block; padding: 4px 10px; border-radius: 20px; background: var(--x-blue-tint); color: var(--x-blue-ink); font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; text-decoration: none; }
.tvbl__cat[data-cat="case-studies"] { background: #F8EEE7; color: #8A5A3E; }
.tvbl__cat[data-cat="guides"] { background: #E6F6EE; color: #0E7A47; }
a.tvbl__cat:hover { filter: brightness(.96); }
.tvbl__card-title { font-weight: 700; font-size: 20px; line-height: 1.3; color: var(--x-ink); text-wrap: balance; }
.tvbl__card-title a { color: inherit; text-decoration: none; }
.tvbl__card-title a::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.tvbl__card-title a:focus-visible { outline: none; }
.tvbl__card:has(.tvbl__card-title a:focus-visible) { outline: 3px solid var(--x-blue); outline-offset: 3px; }
.tvbl__card-ex { font-size: 15px; line-height: 1.6; color: var(--x-muted); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.tvbl__more { margin-top: auto; padding-top: 6px; display: inline-flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--x-blue); }
.tvbl__more svg { width: 16px; height: 16px; transition: transform .2s ease; }
.tvbl__card:hover .tvbl__more svg { transform: translateX(4px); }

/* featured (first) card on the news page */
.tvbl__card--feature { grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.tvbl__card--feature .tvbl__card-img { aspect-ratio: auto; min-height: 100%; }
.tvbl__card--feature .tvbl__card-body { justify-content: center; gap: 14px; padding: clamp(24px, 3.4cqi, 44px); }
.tvbl__card--feature .tvbl__card-title { font-size: clamp(24px, 1.2cqi + 14px, 32px); line-height: 1.2; }
.tvbl__card--feature .tvbl__card-ex { font-size: 16.5px; -webkit-line-clamp: 4; }

/* filter chips (news page) */
.tvbl__filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 26px; }
.tvx .tvbl__filter { padding: 9px 16px; border-radius: 30px; border: 1px solid var(--x-line); background: var(--x-paper); font-size: 14.5px; font-weight: 700; line-height: 1.2; color: var(--x-ink); transition: background-color .2s ease, color .2s ease, border-color .2s ease; }
.tvx .tvbl__filter:hover { border-color: #C9D3E0; background: var(--x-paper); color: var(--x-ink); }
.tvx .tvbl__filter[aria-pressed="true"] { background: var(--x-ink); border-color: var(--x-ink); color: #fff; }
.tvbl__card[hidden] { display: none; }
.tvbl__empty { padding: 40px; text-align: center; color: var(--x-muted); }

.tvbl__all { display: flex; justify-content: center; margin-top: clamp(28px, 4cqi, 40px); }
.tvbl .tvx__btn--outline { color: var(--x-ink); border: 1.5px solid #C9D3E0; }
.tvbl .tvx__btn--outline:hover, .tvbl .tvx__btn--outline:focus { color: var(--x-ink); border-color: var(--x-ink); }
.tvbl .tvx__btn--outline:focus-visible { outline-color: var(--x-blue); }

/* ---------- article page ---------- */
.tvbl__article { max-width: 960px; margin: 0 auto; padding-inline: clamp(16px, 4cqi, 32px); padding-block: clamp(40px, 6cqi, 72px) clamp(48px, 6cqi, 80px); }
.tvbl__article > :not(.tvbl__cover) { max-width: 720px; margin-inline: auto; }
.tvbl__meta--top { margin-bottom: 18px; font-size: 14.5px; }
.tvbl__lede { font-size: clamp(19px, .6cqi + 15px, 22px); line-height: 1.6; font-weight: 500; color: #3A4252; text-wrap: pretty; }
.tvbl__cover { margin: clamp(28px, 4cqi, 40px) 0; border-radius: 18px; overflow: hidden; background: var(--x-navy); box-shadow: 0 30px 60px -40px rgba(6, 20, 43, .55); }
.tvbl__cover img { width: 100%; height: auto; }

.tvbl__glance { margin-bottom: 36px; padding: 22px 24px; border-radius: 14px; background: var(--x-mist); border: 1px solid var(--x-line); }
.tvbl__glance-client { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; margin-bottom: 16px; }
.tvbl__glance-client b { font-size: 17px; font-weight: 800; color: var(--x-ink); }
.tvbl__glance-client span { font-size: 14px; font-weight: 600; color: var(--x-muted); }
.tvbl__glance dl { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
.tvbl__glance dl > div { display: flex; flex-direction: column-reverse; gap: 4px; padding-left: 14px; border-left: 2px solid #D9E2EE; }
.tvbl__glance dd { font-size: clamp(22px, .8cqi + 16px, 28px); font-weight: 800; line-height: 1.05; color: var(--x-blue); font-variant-numeric: tabular-nums; }
.tvbl__glance dt { font-size: 13.5px; font-weight: 600; line-height: 1.35; color: var(--x-muted); }

.tvbl__body { font-size: 18px; line-height: 1.75; color: #2E3442; }
.tvbl__body > * + * { margin-top: 18px; }
.tvbl__body h2 { margin-top: 46px; font-weight: 800; font-size: clamp(24px, .8cqi + 18px, 30px); line-height: 1.2; letter-spacing: -.005em; color: var(--x-ink); text-wrap: balance; }
.tvbl__body h3 { margin-top: 30px; font-weight: 700; font-size: 21px; line-height: 1.3; color: var(--x-ink); }
.tvbl__body h2 + *, .tvbl__body h3 + * { margin-top: 12px; }
.tvbl__body strong { font-weight: 700; color: var(--x-ink); }
.tvbl__body a { color: var(--x-blue); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: rgba(8, 106, 217, .35); }
.tvbl__body a:hover { color: var(--x-blue-ink); text-decoration-color: currentColor; }
.tvbl__body ul, .tvbl__body ol { display: grid; gap: 10px; }
.tvbl__body ul > li { position: relative; padding-left: 26px; }
.tvbl__body ul > li::before { content: ""; position: absolute; left: 4px; top: .7em; width: 8px; height: 8px; border-radius: 50%; background: var(--x-beige); }
.tvbl__body ol:not(.tvbl__steps) { counter-reset: tvbl; }
.tvbl__body ol:not(.tvbl__steps) > li { position: relative; padding-left: 42px; counter-increment: tvbl; }
.tvbl__body ol:not(.tvbl__steps) > li::before { content: counter(tvbl); position: absolute; left: 0; top: .1em; width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; background: var(--x-blue-tint); color: var(--x-blue); font-size: 14px; font-weight: 800; line-height: 1; }
.tvbl__fig { margin-block: 32px; }
.tvbl__fig img { width: 100%; height: auto; border-radius: 14px; border: 1px solid var(--x-line); background: var(--x-mist); }
.tvbl__fig figcaption { margin-top: 10px; font-size: 14.5px; line-height: 1.5; color: var(--x-muted); }
.tvbl__note { margin-top: 32px; padding: 18px 20px; border-radius: 12px; background: var(--x-mist); border-left: 3px solid var(--x-blue); font-size: 16.5px; line-height: 1.6; }
.tvbl__steps { display: grid; gap: 12px; }
.tvbl__steps li { position: relative; padding: 16px 18px 16px 60px; border-radius: 12px; border: 1px solid var(--x-line); background: var(--x-paper); font-size: 17px; line-height: 1.6; }
.tvbl__steps li::before { content: ""; position: absolute; left: 18px; top: 18px; width: 26px; height: 26px; border-radius: 50%; background: var(--x-blue) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / 15px no-repeat; }
.tvbl__steps li.is-now::before { background: var(--x-paper); box-shadow: inset 0 0 0 3px var(--x-beige); }
.tvbl__steps li > span { display: inline-block; margin: 0 8px 4px 0; padding: 2px 9px; border-radius: 20px; font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; background: #E6F6EE; color: #0E7A47; vertical-align: 2px; }
.tvbl__steps li.is-now > span { background: #F8EEE7; color: #8A5A3E; }

/* author box under every article; the byline links to it */
.tvbl__meta .tvbl__by { color: inherit; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: #C3CBD8; }
.tvbl__meta .tvbl__by:hover { color: var(--x-ink); text-decoration-color: currentColor; }
.tvbl__author { display: flex; align-items: flex-start; gap: 18px; margin-top: 44px; padding: 22px 24px; border-radius: 14px; background: var(--x-mist); border: 1px solid var(--x-line); scroll-margin-top: 110px; }
.tvbl__author-mark { flex: none; width: 56px; height: 56px; border-radius: 50%; display: grid; place-items: center; background: var(--x-navy); color: #fff; font-size: 18px; font-weight: 800; letter-spacing: .04em; box-shadow: inset 0 0 0 2px var(--x-beige); }
.tvbl__author-kicker { font-size: 12.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--x-muted); }
.tvbl__author-name { margin-top: 4px; font-size: 19px; font-weight: 800; line-height: 1.3; color: var(--x-ink); }
.tvbl__author-role { margin-top: 2px; font-size: 14.5px; font-weight: 600; color: var(--x-blue-ink); }
.tvbl__author-bio { margin-top: 10px; font-size: 16px; line-height: 1.65; color: #3A4252; text-wrap: pretty; }
.tvbl__author + .tvbl__share { margin-top: 28px; }
.tvbl__share { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 44px; padding-top: 24px; border-top: 1px solid var(--x-line); }
.tvbl__share > span { margin-right: 6px; font-size: 14px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--x-muted); }
.tvx .tvbl__sh { width: 42px; height: 42px; border-radius: 50%; display: inline-grid; place-items: center; border: 1px solid var(--x-line); background: var(--x-paper); color: var(--x-ink); text-decoration: none; transition: background-color .2s ease, color .2s ease, border-color .2s ease; }
.tvx .tvbl__sh:hover { background: var(--x-ink); border-color: var(--x-ink); color: #fff; }
.tvbl__sh svg { width: 18px; height: 18px; }
.tvbl__copied { font-size: 14px; font-weight: 600; color: #0E7A47; opacity: 0; transition: opacity .2s ease; }
.tvbl__copied.is-on { opacity: 1; }
.tvbl .tvx__cta { margin-top: 0; }

@container tvx (max-width: 1020px) {
  .tvbl__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tvbl__grid--home > :nth-child(3) { display: none; }
}
@container tvx (max-width: 900px) {
  .tvbl__card--feature { grid-template-columns: minmax(0, 1fr); }
  .tvbl__card--feature .tvbl__card-img { aspect-ratio: 16 / 9; min-height: 0; }
  .tvbl__glance dl { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@container tvx (max-width: 640px) {
  .tvbl__author { flex-direction: column; gap: 12px; padding: 18px; }
  .tvbl__grid { grid-template-columns: minmax(0, 1fr); }
  .tvbl__grid--home > :nth-child(3) { display: flex; }
  .tvbl__body { font-size: 17px; }
  .tvbl__cover { border-radius: 12px; margin-inline: calc(-1 * clamp(0px, 2cqi, 8px)); }
}

.tvbl .tvx__inner--tight { padding-block: clamp(40px, 5cqi, 64px); }

</style>
<section class="tvx tvbl tvbl--post" aria-label="Bringing a stalled ERP project back on track: lessons from Al Mohamady Group">
  <div class="tvbl__article">
    <div class="tvbl__meta tvbl__meta--top"><a class="tvbl__cat" data-cat="insights" href="https://topvieweg.com/blog/?cat=insights">Insight</a><span>14 October 2026</span><span>2 min read</span><span>By <a class="tvbl__by" href="#tvbl-author">Amr Bendary</a></span></div>
    <p class="tvbl__lede">Al Mohamady Group’s Microsoft Dynamics 365 project had been stalled for a long time. As the client’s technical representative, we helped bring it back on track. Here is what we did, and what any ERP project can learn from it.</p>
    <figure class="tvbl__cover"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-erp.jpg" width="1200" height="675" alt="ERP project status: scope and contracts done, setup done, training and go-live in progress" decoding="async"></figure>
    <aside class="tvbl__glance" aria-label="At a glance"><div class="tvbl__glance-client"><b>Al Mohamady Group</b><span>Restaurants and factories · Egypt</span></div>
      <dl><div><dt>Factories</dt><dd>2</dd></div><div><dt>Branches</dt><dd>9</dd></div><div><dt>With LS Central</dt><dd>D365 BC</dd></div><div><dt>Training and go-live</dt><dd>In progress</dd></div></dl>
    </aside>
    <div class="tvbl__body">
<h2>Why ERP projects stall</h2>
<p>ERP projects rarely stall for one reason. In our experience the scope was never fully written down, the contract does not say clearly who delivers what, master data arrives late, and the people who will use the system join too late. Each gap adds weeks, and after a while nobody is sure what “done” means.</p>

<h2>Our role: an independent representative</h2>
<p>When we joined Al Mohamady Group, a restaurant and food manufacturing group, its ERP project on Microsoft Dynamics 365 Business Central and LS Central had been stalled for a long time. We represent the client in front of the implementation company, and we follow every stage until go-live across two factories and nine branches.</p>

<h2>What we did, step by step</h2>
<ol class="tvbl__steps">
  <li class="is-done"><span>Done</span><strong>Clear scope and complete contracts.</strong> We reviewed the project from the start, and completed the requirements document and the agreements with the implementation company.</li>
  <li class="is-done"><span>Done</span><strong>Setup stages finished.</strong> Development, testing, master data and configuration are complete and reviewed.</li>
  <li class="is-now"><span>In progress</span><strong>Training and go-live.</strong> Training is under way in the Mansoura and Cairo branches, ahead of full go-live.</li>
</ol>

<h2>Lessons for any ERP project</h2>
<ul>
  <li><strong>Write the scope down before anything else.</strong> A requirements document both sides sign is the cheapest way to save months.</li>
  <li><strong>Have someone on your side who speaks the vendor’s language.</strong> An independent technical representative keeps delivery tied to what was agreed.</li>
  <li><strong>Treat master data as its own workstream.</strong> Items, prices, recipes and branches have to be ready before testing means anything.</li>
  <li><strong>Train branch by branch, with real scenarios.</strong> People adopt a system when they have used it on their own daily work.</li>
  <li><strong>Approve each stage before the next one starts.</strong> Clear checkpoints stop small delays from turning into a stalled project.</li>
</ul>

<h2>When to ask for help</h2>
<p>If your ERP or POS project has slipped, the scope keeps changing, or you are not sure what you are paying for, an independent review is a good first step. We also set up IT and ERP from scratch for Mini Melts, and advise Etoile on IT and digital transformation.</p>
<p class="tvbl__note">See how our <a href="https://topvieweg.com/service/it-consulting/">IT consulting</a> service works, from the first review to go-live.</p>
    </div>
    <aside class="tvbl__author" id="tvbl-author" aria-labelledby="tvbl-author-name">
      <span class="tvbl__author-mark" aria-hidden="true">AB</span>
      <div>
        <p class="tvbl__author-kicker">About the author</p>
        <p class="tvbl__author-name" id="tvbl-author-name">Amr Bendary</p>
        <p class="tvbl__author-role">Founder, Top View · CTO, Etoile</p>
        <p class="tvbl__author-bio">Founder of Top View and CTO at Etoile, Amr Bendary brings over 20 years of experience in digital transformation, mobile apps, e-commerce, and ERP integration. He holds an MBA in Digital Transformation and helps businesses connect technology with growth and operational efficiency.</p>
      </div>
    </aside>
    <div class="tvbl__share"><span>Share</span>
      <a class="tvbl__sh" href="https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Ftopvieweg.com%2Fstalled-erp-project-lessons%2F" target="_blank" rel="noopener" aria-label="Share on LinkedIn"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M6.94 8.5H3.56V20h3.38V8.5ZM5.25 3a1.96 1.96 0 1 0 0 3.92 1.96 1.96 0 0 0 0-3.92ZM20.44 13.4c0-3.1-1.65-4.55-3.86-4.55-1.78 0-2.58.98-3.02 1.67V8.5h-3.38c.04.95 0 11.5 0 11.5h3.38v-6.42c0-.34.02-.69.13-.93.27-.69.9-1.4 1.95-1.4 1.38 0 1.93 1.05 1.93 2.59V20h3.37v-6.6Z"/></svg></a>
      <a class="tvbl__sh" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Ftopvieweg.com%2Fstalled-erp-project-lessons%2F" target="_blank" rel="noopener" aria-label="Share on Facebook"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M13.5 21v-7.5h2.53l.38-2.93H13.5V8.7c0-.85.24-1.43 1.45-1.43h1.55V4.65a20.8 20.8 0 0 0-2.26-.12c-2.24 0-3.77 1.37-3.77 3.88v2.16H7.94v2.93h2.53V21h3.03Z"/></svg></a>
      <a class="tvbl__sh" href="https://wa.me/?text=Bringing%20a%20stalled%20ERP%20project%20back%20on%20track%3A%20lessons%20from%20Al%20Mohamady%20Group%20https%3A%2F%2Ftopvieweg.com%2Fstalled-erp-project-lessons%2F" target="_blank" rel="noopener" aria-label="Share on WhatsApp"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M17.47 14.38c-.3-.15-1.76-.87-2.03-.97-.27-.1-.47-.15-.67.15-.2.3-.77.97-.94 1.16-.17.2-.35.22-.64.07-.3-.15-1.26-.46-2.39-1.47-.88-.79-1.48-1.76-1.65-2.06-.17-.3-.02-.46.13-.61.13-.13.3-.35.45-.52.15-.17.2-.3.3-.5.1-.2.05-.37-.03-.52-.07-.15-.67-1.61-.92-2.21-.24-.58-.49-.5-.67-.51h-.57c-.2 0-.52.07-.79.37-.27.3-1.04 1.02-1.04 2.48 0 1.46 1.07 2.88 1.21 3.07.15.2 2.1 3.2 5.08 4.49.71.31 1.26.49 1.69.63.71.23 1.36.2 1.87.12.57-.09 1.76-.72 2-1.41.25-.7.25-1.29.18-1.41-.08-.13-.27-.2-.57-.35ZM12.05 21.79h-.01a9.87 9.87 0 0 1-5.03-1.38l-.36-.21-3.74.98 1-3.65-.24-.37a9.86 9.86 0 0 1-1.51-5.26c0-5.45 4.44-9.88 9.89-9.88a9.83 9.83 0 0 1 9.88 9.89c0 5.45-4.44 9.88-9.88 9.88Zm8.41-18.3A11.82 11.82 0 0 0 12.05 0C5.5 0 .16 5.34.16 11.89c0 2.1.55 4.14 1.59 5.95L.06 24l6.3-1.65a11.88 11.88 0 0 0 5.68 1.45h.01c6.55 0 11.89-5.34 11.89-11.89 0-3.18-1.24-6.17-3.48-8.42Z"/></svg></a>
      <a class="tvbl__sh" href="https://topvieweg.com/stalled-erp-project-lessons/" data-copy aria-label="Copy link"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1"/><path d="M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1"/></svg></a><span class="tvbl__copied" aria-live="polite">Link copied</span>
    </div>
  </div>
  <div class="tvbl__band">
    <div class="tvx__inner tvx__inner--tight">
      <div class="tvx__cta" data-reveal>
        <div class="tvx__cta-text"><h3 class="tvx__cta-title">Planning something similar?</h3><p class="tvx__cta-body">Book a free meeting with our team. We will review how your branches work and suggest the right setup.</p></div>
        <div class="tvx__cta-actions">
          <a class="tvx__btn tvx__btn--primary" href="https://topvieweg.com/contact/" data-tvx="consultation" data-where="blog_stalled-erp-project-lessons">Get a Free Consultation <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          <a class="tvx__btn tvx__btn--ghost" href="https://wa.me/201114000096?text=Hello%20TopView%2C%20I'm%20contacting%20you%20from%20your%20website%20(News%20article).%20I'd%20like%20to%20discuss%20a%20project." target="_blank" rel="noopener" data-tvx="whatsapp"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M17.47 14.38c-.3-.15-1.76-.87-2.03-.97-.27-.1-.47-.15-.67.15-.2.3-.77.97-.94 1.16-.17.2-.35.22-.64.07-.3-.15-1.26-.46-2.39-1.47-.88-.79-1.48-1.76-1.65-2.06-.17-.3-.02-.46.13-.61.13-.13.3-.35.45-.52.15-.17.2-.3.3-.5.1-.2.05-.37-.03-.52-.07-.15-.67-1.61-.92-2.21-.24-.58-.49-.5-.67-.51h-.57c-.2 0-.52.07-.79.37-.27.3-1.04 1.02-1.04 2.48 0 1.46 1.07 2.88 1.21 3.07.15.2 2.1 3.2 5.08 4.49.71.31 1.26.49 1.69.63.71.23 1.36.2 1.87.12.57-.09 1.76-.72 2-1.41.25-.7.25-1.29.18-1.41-.08-.13-.27-.2-.57-.35ZM12.05 21.79h-.01a9.87 9.87 0 0 1-5.03-1.38l-.36-.21-3.74.98 1-3.65-.24-.37a9.86 9.86 0 0 1-1.51-5.26c0-5.45 4.44-9.88 9.89-9.88a9.83 9.83 0 0 1 9.88 9.89c0 5.45-4.44 9.88-9.88 9.88Zm8.41-18.3A11.82 11.82 0 0 0 12.05 0C5.5 0 .16 5.34.16 11.89c0 2.1.55 4.14 1.59 5.95L.06 24l6.3-1.65a11.88 11.88 0 0 0 5.68 1.45h.01c6.55 0 11.89-5.34 11.89-11.89 0-3.18-1.24-6.17-3.48-8.42Z"/></svg> Chat on WhatsApp</a>
        </div>
      </div>
    </div>
  </div>
  <div class="tvbl__band tvbl__band--mist">
    <div class="tvx__inner">
      <div class="tvbl__head" data-reveal><h2 class="tvx__title">More articles</h2></div>
      <div class="tvbl__grid" data-tvbl-feed data-count="3" data-exclude="2011" data-reveal>
        <article class="tvbl__card" data-id="5571" data-cat="insights">
          <a class="tvbl__card-img" href="https://topvieweg.com/own-app-vs-delivery-apps/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-own-app.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="insights">Insight</span><span>14 Oct 2026</span><span>3 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/own-app-vs-delivery-apps/">Your own app or delivery apps? What changes for a multi-branch brand</a></h3>
            <p class="tvbl__card-ex">Delivery apps bring orders, but they keep the customer and take a share of every sale. Here is what changes when a multi-branch brand runs its own app and online store, and how to start without losing the orders you already have.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
        <article class="tvbl__card" data-id="5575" data-cat="guides">
          <a class="tvbl__card-img" href="https://topvieweg.com/what-is-ecommerce/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-g-what.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="guides">Guide</span><span>14 Oct 2026</span><span>2 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/what-is-ecommerce/">What is e-commerce? A plain guide for business owners</a></h3>
            <p class="tvbl__card-ex">E-commerce is more than a website with a cart. Here is what it really means for a restaurant, shop or brand, the channels it covers, and the parts that have to work together behind every online order.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
        <article class="tvbl__card" data-id="5572" data-cat="case-studies">
          <a class="tvbl__card-img" href="https://topvieweg.com/etoile-egypt-app-case-study/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-etoile.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="case-studies">Case study</span><span>14 Oct 2026</span><span>2 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/etoile-egypt-app-case-study/">How Etoile Egypt went from a call centre to 520,000+ app users</a></h3>
            <p class="tvbl__card-ex">Etoile Egypt moved its online orders from a busy call centre to its own app and website. Today the app has more than 520,000 users and takes thousands of orders a day, connected to the branches, ERP and POS.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
      </div>
      <div class="tvbl__all"><a class="tvx__btn tvx__btn--outline" href="https://topvieweg.com/blog/">View all articles <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a></div>
    </div>
  </div>
</section>
<script>
(function () {
  var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  function fmt(n) { return Math.round(n).toLocaleString('en-US'); }
  function countUp(el) {
    var to = Number(el.getAttribute('data-n'));
    if (reduce || !to) return;
    var dur = 1200, t0 = null;
    el.textContent = fmt(0);
    requestAnimationFrame(function step(t) {
      if (t0 === null) t0 = t;
      var p = Math.min(1, (t - t0) / dur);
      el.textContent = fmt(to * (1 - Math.pow(1 - p, 3)));
      if (p < 1) requestAnimationFrame(step);
    });
    // always land on the real value, even if frames stall
    setTimeout(function () { el.textContent = fmt(to); }, dur + 400);
  }

  function init(root) {
    root.setAttribute('data-ready', '');
    root.classList.add('is-js');

    // scroll reveal (armed only here, so the section is complete without JS)
    var items = [].slice.call(root.querySelectorAll('[data-reveal]'));
    var drawTarget = root.querySelector('[data-draw]');
    if (!reduce && 'IntersectionObserver' in window) {
      root.classList.add('is-armed');
      var io = new IntersectionObserver(function (entries) {
        entries.forEach(function (e) {
          if (!e.isIntersecting) return;
          io.unobserve(e.target);
          if (e.target === drawTarget) {
            root.classList.add('is-drawn');
            [].slice.call(root.querySelectorAll('[data-n]')).forEach(countUp);
          } else {
            e.target.classList.add('is-in');
          }
        });
      }, { threshold: 0.15, rootMargin: '0px 0px -40px 0px' });
      items.forEach(function (el) { io.observe(el); });
      if (drawTarget) io.observe(drawTarget);
      // safety net: never leave content hidden
      setTimeout(function () { items.forEach(function (el) { el.classList.add('is-in'); }); root.classList.add('is-drawn'); }, 4000);
    } else {
      root.classList.add('is-drawn');
    }
    // looping decorations pause while the section is off screen
    if ('IntersectionObserver' in window) {
      new IntersectionObserver(function (entries) { root.classList.toggle('is-off', !entries[entries.length - 1].isIntersecting); }).observe(root);
    }

    // looping motion ([data-loop]) starts when first seen, so it opens on its first scene, and pauses off screen
    [].slice.call(root.querySelectorAll('[data-loop]')).forEach(function (el) {
      if (reduce || !('IntersectionObserver' in window)) return;
      new IntersectionObserver(function (entries) {
        var on = entries[entries.length - 1].isIntersecting; // several entries can queue up during a fast scroll; the last one is current
        if (on) el.classList.add('is-playing');
        el.classList.toggle('is-paused', !on);
      }, { threshold: 0.3 }).observe(el);
    });

    // tabs with a sliding highlight
    var tabs = [].slice.call(root.querySelectorAll('[role="tab"]'));
    if (!tabs.length) return;
    var panels = tabs.map(function (t) { return root.querySelector('#' + t.getAttribute('aria-controls')); });
    var ink = root.querySelector('.tvpf__ink');
    var list = tabs[0].parentNode;
    var current = Math.max(0, tabs.findIndex(function (t) { return t.getAttribute('aria-selected') === 'true'; }));
    function moveInk() {
      if (!ink) return;
      var t = tabs[current];
      ink.style.width = t.offsetWidth + 'px';
      ink.style.transform = 'translateX(' + t.offsetLeft + 'px)';
    }
    function show(n, focus) {
      if (n === current) return;
      current = (n + tabs.length) % tabs.length;
      tabs.forEach(function (t, k) {
        var on = k === current;
        t.classList.toggle('is-active', on);
        t.setAttribute('aria-selected', on ? 'true' : 'false');
        t.tabIndex = on ? 0 : -1;
      });
      panels.forEach(function (p, k) {
        var on = k === current;
        p.hidden = !on;
        p.classList.toggle('is-active', on);
        p.classList.remove('is-entering');
        if (on && !reduce) { void p.offsetWidth; p.classList.add('is-entering'); }
      });
      moveInk();
      var t = tabs[current];
      if (list.scrollWidth > list.clientWidth) list.scrollTo({ left: t.offsetLeft - (list.clientWidth - t.offsetWidth) / 2, behavior: reduce ? 'auto' : 'smooth' });
      if (focus) t.focus();
    }
    tabs.forEach(function (t, k) {
      t.addEventListener('click', function () { show(k); });
      t.addEventListener('keydown', function (e) {
        if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') { e.preventDefault(); show(current + (e.key === 'ArrowRight' ? 1 : -1), true); }
      });
    });
    moveInk();
    if (window.ResizeObserver) new ResizeObserver(moveInk).observe(list);
    window.addEventListener('load', moveInk);
  }

  [].slice.call(document.querySelectorAll('.tvx:not([data-ready])')).forEach(init);

  // calls to action: same tracking as the floating WhatsApp button and the home CTA
  // (each section ships this script, so register the listener only once per page)
  if (window.__tvxCtaTracking) return;
  window.__tvxCtaTracking = true;
  document.addEventListener('click', function (e) {
    var a = e.target.closest && e.target.closest('.tvx a[data-tvx]');
    if (!a) return;
    if (a.getAttribute('data-tvx') === 'whatsapp') {
      if (typeof gtag === 'function') { gtag('event', 'contact', { method: 'WhatsApp', link_url: a.href }); }
      if (typeof fbq === 'function') { fbq('track', 'Contact', { content_name: 'WhatsApp' }); }
      if (typeof window.lintrk === 'function') { window.lintrk('track', { conversion_id: 31200418 }); }
    } else if (typeof gtag === 'function') {
      gtag('event', 'cta_click', { cta: 'free_consultation', location: a.getAttribute('data-where') || 'section' });
    }
  });
})();

(function () {
  if (window.__tvblReady) return;
  window.__tvblReady = true;

  var CAT = { guides: 'Guide', 'case-studies': 'Case study', insights: 'Insight' };
  var arrow = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg>';
  var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

  function text(html, sel) {
    var d = document.createElement('div'); d.innerHTML = html || '';
    [].slice.call(d.querySelectorAll('style,script')).forEach(function (n) { n.remove(); });
    var part = sel && d.querySelector(sel);
    return ((part || d).textContent || '').replace(/\s+/g, ' ').trim();
  }
  function esc(s) { return String(s).replace(/[&<>"]/g, function (c) { return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c]; }); }

  // the same card markup the build script prints, rebuilt from the REST API so new posts show up on their own
  // mins comes from the card the build printed for that post; a post published later shows no reading time
  // p.tv_card = { img, cat, cat_name } is a small REST field added by the "TopView speed & SEO tweaks" snippet
  function card(p, feature, mins) {
    var tc = p.tv_card || {};
    var img = tc.img || '';
    var term = { slug: tc.cat || '', name: tc.cat_name || '' };
    var d = new Date(p.date);
    return '<article class="tvbl__card' + (feature ? ' tvbl__card--feature' : '') + '" data-id="' + p.id + '" data-cat="' + esc(term.slug || '') + '">' +
      (img ? '<a class="tvbl__card-img" href="' + esc(p.link) + '" tabindex="-1" aria-hidden="true"><img loading="lazy" src="' + esc(img) + '" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>' : '') +
      '<div class="tvbl__card-body"><div class="tvbl__meta">' + (term.slug ? '<span class="tvbl__cat" data-cat="' + esc(term.slug) + '">' + esc(CAT[term.slug] || term.name) + '</span>' : '') +
      '<span>' + d.getDate() + ' ' + months[d.getMonth()] + ' ' + d.getFullYear() + '</span>' + (mins ? '<span>' + mins + ' min read</span>' : '') + '</div>' +
      '<h3 class="tvbl__card-title"><a href="' + esc(p.link) + '">' + p.title.rendered + '</a></h3>' +
      '<p class="tvbl__card-ex">' + esc(text(p.excerpt && p.excerpt.rendered)) + '</p>' +
      '<span class="tvbl__more" aria-hidden="true">Read article ' + arrow + '</span></div></article>';
  }

  function applyFilter(root, cat) {
    var cards = [].slice.call(root.querySelectorAll('.tvbl__card'));
    var shown = 0;
    cards.forEach(function (c) { var on = !cat || c.getAttribute('data-cat') === cat; c.hidden = !on; if (on) shown++; });
    [].slice.call(root.querySelectorAll('.tvbl__filter')).forEach(function (b) { b.setAttribute('aria-pressed', String((b.getAttribute('data-cat') || '') === (cat || ''))); });
    var empty = root.querySelector('.tvbl__empty');
    if (empty) empty.hidden = shown > 0;
  }

  function initFilters() {
    [].slice.call(document.querySelectorAll('.tvbl [data-tvbl-filters]')).forEach(function (bar) {
      var root = bar.closest('.tvbl');
      if (bar.getAttribute('data-ready')) { var cur = bar.querySelector('[aria-pressed="true"]'); applyFilter(root, cur ? cur.getAttribute('data-cat') || '' : ''); return; }
      bar.setAttribute('data-ready', '1');
      bar.addEventListener('click', function (e) {
        var b = e.target.closest('.tvbl__filter');
        if (!b) return;
        applyFilter(root, b.getAttribute('data-cat') || '');
      });
      var m = location.search.match(/[?&]cat=([a-z-]+)/);
      applyFilter(root, m ? m[1] : '');
    });
  }

  // copy link
  document.addEventListener('click', function (e) {
    var b = e.target.closest && e.target.closest('.tvbl [data-copy]');
    if (!b) return;
    e.preventDefault();
    var done = function () { var t = b.parentNode.querySelector('.tvbl__copied'); if (t) { t.classList.add('is-on'); setTimeout(function () { t.classList.remove('is-on'); }, 1800); } };
    if (navigator.clipboard) navigator.clipboard.writeText(location.href.split('#')[0]).then(done, function () {}); else done();
  });

  var feeds = [].slice.call(document.querySelectorAll('[data-tvbl-feed]'));
  initFilters();
  if (!feeds.length || !window.fetch) return;

  // Only the fields a card shows (the full post content made this ~600 KB), and only once a feed
  // comes near the screen, so the request never competes with the page's first paint.
  var loaded = false;
  function refresh() {
    if (loaded) return;
    loaded = true;
    var mins = {};
    [].forEach.call(document.querySelectorAll('.tvbl__card[data-id]'), function (c) {
      var m = (c.textContent || '').match(/(\d+) min read/);
      if (m) mins[c.getAttribute('data-id')] = m[1];
    });
    fetch('/wp-json/wp/v2/posts?per_page=12&_fields=id,date,link,title,excerpt,tv_card', { credentials: 'omit' })
      .then(function (r) { return r.ok ? r.json() : Promise.reject(r.status); })
      .then(function (posts) {
        if (!Array.isArray(posts) || !posts.length || !posts[0].tv_card) return; // keep the printed cards if the field is missing
        feeds.forEach(function (feed) {
          var max = Number(feed.getAttribute('data-count')) || posts.length;
          var skip = Number(feed.getAttribute('data-exclude')) || 0;
          var list = posts.filter(function (p) { return p.id !== skip; }).slice(0, max);
          var have = [].map.call(feed.querySelectorAll('.tvbl__card'), function (el) { return el.getAttribute('data-id'); }).join();
          if (have === list.map(function (p) { return String(p.id); }).join()) return; // the printed cards are already current
          var feature = feed.hasAttribute('data-feature');
          feed.innerHTML = list.map(function (p, i) { return card(p, feature && i === 0, mins[p.id]); }).join('');
        });
        initFilters();
      })
      .catch(function () {});
  }
  if ('IntersectionObserver' in window) {
    var io = new IntersectionObserver(function (entries) {
      if (entries.some(function (e) { return e.isIntersecting; })) { io.disconnect(); refresh(); }
    }, { rootMargin: '600px 0px' });
    feeds.forEach(function (f) { io.observe(f); });
  } else {
    window.addEventListener('load', refresh);
  }
})();

</script>
				</div>
				</div>
				</div>
				</div>
		<p>The post <a href="https://topvieweg.com/stalled-erp-project-lessons/">Bringing a stalled ERP project back on track: lessons from Al Mohamady Group</a> appeared first on <a href="https://topvieweg.com">TopView</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Website, app or both? How to choose your first online channel</title>
		<link>https://topvieweg.com/website-app-or-both/</link>
		
		<dc:creator><![CDATA[TopView Team]]></dc:creator>
		<pubDate>Wed, 14 Oct 2026 06:30:00 +0000</pubDate>
				<category><![CDATA[Guides]]></category>
		<guid isPermaLink="false">https://tplabs.co/izeetak/?p=1355</guid>

					<description><![CDATA[<p>A website and an app do different jobs. Here is what each one does best, the questions that help you choose, and why many brands end up running both from one dashboard.</p>
<p>The post <a href="https://topvieweg.com/website-app-or-both/">Website, app or both? How to choose your first online channel</a> appeared first on <a href="https://topvieweg.com">TopView</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="1355" class="elementor elementor-1355" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-tvb1355c e-con-full e-flex e-con e-parent" data-id="tvb1355c" data-element_type="container" data-e-type="container">
				<div class="elementor-element elementor-element-tvb1355w elementor-widget elementor-widget-html" data-id="tvb1355w" data-element_type="widget" data-e-type="widget" data-widget_type="html.default">
				<div class="elementor-widget-container">
					<!-- TopView blog: article website-app-or-both. Generated by live-site/blog/build.js from articles.js; edit there and rebuild. -->
<style>
/* Shared base for the TopView platform (.tvpf) and discount-system (.tvdm) sections.
   The izeetak theme styles every <button> (70px line height, 60px side padding, uppercase, wide tracking),
   sets body line height to 2 and decorates lists, so each section resets those inside itself. */
.tvx {
  --x-ink: #1B1825;
  --x-muted: #5A6475;
  --x-line: #E3E8EF;
  --x-paper: #FFFFFF;
  --x-mist: #F4F7FB;
  --x-blue: #086AD9;
  --x-blue-ink: #0757B3;
  --x-blue-tint: #E7F0FC;
  --x-beige: #D2A88F;
  --x-beige-lite: #E7C7B2;
  --x-navy: #06142B;
  --x-navy-2: #0B2A55;
  --x-ease: cubic-bezier(.2, .8, .2, 1);
  container: tvx / inline-size;
  position: relative;
  width: 100%;
  font-family: "Barlow", "Segoe UI", system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.5;
  color: var(--x-ink);
  text-align: left;
}
.elementor-widget:has(> .elementor-widget-container > .tvx) { width: 100%; min-width: 0; }
.tvx *, .tvx *::before, .tvx *::after { box-sizing: border-box; }
/* Element-weight resets (0,0,1): they still beat the theme (same weight, later in the page) but lose to every
   class rule, even when a second section on the page repeats this file after the first section’s rules. */
:where(.tvx) :is(h2, h3, h4, p, ul, ol, li, dl, dt, dd, figure) { margin: 0; padding: 0; }
:where(.tvx) :is(ul, ol) { list-style: none; }
:where(.tvx) li::before, :where(.tvx) li::after { content: none; }
:where(.tvx) img { display: block; max-width: 100%; height: auto; }
.tvx button { min-width: 0; min-height: 0; margin: 0; padding: 0; border: 0; background: none; color: inherit; font: inherit; line-height: inherit; letter-spacing: normal; text-transform: none; cursor: pointer; }
.tvx button:hover, .tvx button:focus { background: none; color: inherit; }
.tvx :focus-visible { outline: 3px solid var(--x-blue); outline-offset: 3px; }

.tvx__inner { max-width: 1200px; margin: 0 auto; padding-inline: clamp(16px, 4cqi, 32px); padding-block: clamp(56px, 7cqi, 96px); }
.tvx__head { max-width: 720px; margin-bottom: clamp(28px, 4cqi, 48px); }
.tvx__title { font-weight: 800; font-size: clamp(30px, 2.4cqi + 14px, 46px); line-height: 1.08; letter-spacing: -.01em; color: var(--x-ink); text-wrap: balance; margin-bottom: 14px; }
.tvx__lede { font-size: clamp(16px, .5cqi + 12px, 19px); line-height: 1.65; font-weight: 500; color: var(--x-muted); text-wrap: pretty; }
.tvx__h3 { font-weight: 800; font-size: clamp(21px, .8cqi + 15px, 26px); line-height: 1.2; color: var(--x-ink); margin-bottom: 18px; text-wrap: balance; }

.tvx__icon { flex: none; width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center; background: var(--x-blue-tint); color: var(--x-blue); }
.tvx__icon svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

.tvx__chips { display: flex; flex-wrap: wrap; gap: 8px; }
.tvx__chips li { padding: 7px 13px; border: 1px solid var(--x-line); border-radius: 20px; background: var(--x-paper); font-size: 14px; font-weight: 600; line-height: 1.3; color: var(--x-ink); }

/* closing call to action */
.tvx__cta { margin-top: clamp(40px, 5cqi, 64px); border-radius: 14px; padding: clamp(28px, 4cqi, 44px); display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 24px 40px; color: #fff; background: radial-gradient(60% 120% at 85% 0%, rgba(8, 106, 217, .55), transparent 70%), linear-gradient(160deg, var(--x-navy-2), var(--x-navy)); }
.tvx__cta-text { min-width: 0; max-width: 560px; }
.tvx__cta-title { font-weight: 800; font-size: clamp(22px, 1cqi + 15px, 30px); line-height: 1.2; color: #fff; text-wrap: balance; }
.tvx__cta-body { margin-top: 8px; font-size: 16px; line-height: 1.6; color: rgba(255, 255, 255, .82); }
.tvx__cta-actions { display: flex; flex-wrap: wrap; gap: 12px; }
.tvx__btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 52px; padding: 0 22px; border-radius: 8px; font-weight: 700; font-size: 14px; line-height: 1; letter-spacing: .1em; text-transform: uppercase; text-decoration: none; white-space: nowrap; transition: background-color .2s ease, border-color .2s ease, transform .2s ease; }
.tvx__btn svg { width: 18px; height: 18px; flex: none; }
.tvx__btn--primary { background: var(--x-beige); color: var(--x-ink); }
.tvx__btn--primary:hover, .tvx__btn--primary:focus { background: var(--x-beige-lite); color: var(--x-ink); }
.tvx__btn--ghost { color: #fff; border: 1.5px solid rgba(255, 255, 255, .34); }
.tvx__btn--ghost:hover, .tvx__btn--ghost:focus { color: #fff; border-color: #fff; background: rgba(255, 255, 255, .06); }
.tvx__btn:active { transform: translateY(1px); }
.tvx__btn:focus-visible { outline-color: var(--x-beige-lite); }

/* scroll reveal: only armed by JS, so content is visible without it */
.tvx.is-armed [data-reveal] { opacity: 0; transform: translateY(16px); transition: opacity .7s var(--x-ease), transform .7s var(--x-ease); transition-delay: calc(var(--i, 0) * 70ms); }
.tvx.is-armed [data-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .tvx *, .tvx *::before, .tvx *::after { animation: none !important; transition: none !important; }
  .tvx.is-armed [data-reveal] { opacity: 1; transform: none; }
}
@container tvx (max-width: 560px) {
  .tvx__cta-actions { width: 100%; flex-direction: column; }
  .tvx__btn { width: 100%; padding: 14px 16px; letter-spacing: .07em; white-space: normal; text-align: center; line-height: 1.3; }
}

/* ===== Blog (.tvbl): home "News & Articles" section, the News page and the article page. Builds on ../platform/tv-shared.css ===== */
.tvbl { background: var(--x-paper); }
.tvbl__band { width: 100%; }
.tvbl__band--mist { background: var(--x-mist); }

/* section head (home + news page) */
.tvbl__head { max-width: 760px; margin-bottom: clamp(28px, 4cqi, 44px); }
.tvbl__head--center { margin-inline: auto; text-align: center; }
.tvbl__eyebrow { display: inline-flex; align-items: center; gap: 10px; margin-bottom: 10px; font-size: 16px; font-weight: 600; color: var(--x-muted); }
.tvbl__eyebrow::before { content: ""; width: 14px; height: 2px; background: var(--x-beige); }
.tvbl__head--center .tvx__title { margin-inline: auto; }
.tvbl__head--center .tvx__lede { margin-inline: auto; max-width: 640px; }

/* cards */
.tvbl__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.tvbl__card { position: relative; display: flex; flex-direction: column; border-radius: 16px; overflow: hidden; background: var(--x-paper); border: 1px solid var(--x-line); transition: border-color .25s ease, box-shadow .25s ease, transform .25s ease; }
.tvbl__card:hover { border-color: #C9D3E0; box-shadow: 0 22px 40px -28px rgba(6, 20, 43, .45); transform: translateY(-3px); }
.tvbl__card-img { display: block; aspect-ratio: 16 / 9; overflow: hidden; background: var(--x-navy); }
.tvbl__card-img img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--x-ease); }
.tvbl__card:hover .tvbl__card-img img { transform: scale(1.03); }
.tvbl__card-body { display: flex; flex-direction: column; gap: 10px; flex: 1; padding: 20px 22px 22px; }
.tvbl__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; font-size: 13.5px; font-weight: 600; line-height: 1.3; color: var(--x-muted); }
.tvbl__meta > span + span::before { content: ""; display: inline-block; width: 4px; height: 4px; margin: 0 10px 2px 0; border-radius: 50%; background: #C3CBD8; vertical-align: middle; }
.tvbl__cat { display: inline-block; padding: 4px 10px; border-radius: 20px; background: var(--x-blue-tint); color: var(--x-blue-ink); font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; text-decoration: none; }
.tvbl__cat[data-cat="case-studies"] { background: #F8EEE7; color: #8A5A3E; }
.tvbl__cat[data-cat="guides"] { background: #E6F6EE; color: #0E7A47; }
a.tvbl__cat:hover { filter: brightness(.96); }
.tvbl__card-title { font-weight: 700; font-size: 20px; line-height: 1.3; color: var(--x-ink); text-wrap: balance; }
.tvbl__card-title a { color: inherit; text-decoration: none; }
.tvbl__card-title a::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.tvbl__card-title a:focus-visible { outline: none; }
.tvbl__card:has(.tvbl__card-title a:focus-visible) { outline: 3px solid var(--x-blue); outline-offset: 3px; }
.tvbl__card-ex { font-size: 15px; line-height: 1.6; color: var(--x-muted); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.tvbl__more { margin-top: auto; padding-top: 6px; display: inline-flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--x-blue); }
.tvbl__more svg { width: 16px; height: 16px; transition: transform .2s ease; }
.tvbl__card:hover .tvbl__more svg { transform: translateX(4px); }

/* featured (first) card on the news page */
.tvbl__card--feature { grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.tvbl__card--feature .tvbl__card-img { aspect-ratio: auto; min-height: 100%; }
.tvbl__card--feature .tvbl__card-body { justify-content: center; gap: 14px; padding: clamp(24px, 3.4cqi, 44px); }
.tvbl__card--feature .tvbl__card-title { font-size: clamp(24px, 1.2cqi + 14px, 32px); line-height: 1.2; }
.tvbl__card--feature .tvbl__card-ex { font-size: 16.5px; -webkit-line-clamp: 4; }

/* filter chips (news page) */
.tvbl__filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 26px; }
.tvx .tvbl__filter { padding: 9px 16px; border-radius: 30px; border: 1px solid var(--x-line); background: var(--x-paper); font-size: 14.5px; font-weight: 700; line-height: 1.2; color: var(--x-ink); transition: background-color .2s ease, color .2s ease, border-color .2s ease; }
.tvx .tvbl__filter:hover { border-color: #C9D3E0; background: var(--x-paper); color: var(--x-ink); }
.tvx .tvbl__filter[aria-pressed="true"] { background: var(--x-ink); border-color: var(--x-ink); color: #fff; }
.tvbl__card[hidden] { display: none; }
.tvbl__empty { padding: 40px; text-align: center; color: var(--x-muted); }

.tvbl__all { display: flex; justify-content: center; margin-top: clamp(28px, 4cqi, 40px); }
.tvbl .tvx__btn--outline { color: var(--x-ink); border: 1.5px solid #C9D3E0; }
.tvbl .tvx__btn--outline:hover, .tvbl .tvx__btn--outline:focus { color: var(--x-ink); border-color: var(--x-ink); }
.tvbl .tvx__btn--outline:focus-visible { outline-color: var(--x-blue); }

/* ---------- article page ---------- */
.tvbl__article { max-width: 960px; margin: 0 auto; padding-inline: clamp(16px, 4cqi, 32px); padding-block: clamp(40px, 6cqi, 72px) clamp(48px, 6cqi, 80px); }
.tvbl__article > :not(.tvbl__cover) { max-width: 720px; margin-inline: auto; }
.tvbl__meta--top { margin-bottom: 18px; font-size: 14.5px; }
.tvbl__lede { font-size: clamp(19px, .6cqi + 15px, 22px); line-height: 1.6; font-weight: 500; color: #3A4252; text-wrap: pretty; }
.tvbl__cover { margin: clamp(28px, 4cqi, 40px) 0; border-radius: 18px; overflow: hidden; background: var(--x-navy); box-shadow: 0 30px 60px -40px rgba(6, 20, 43, .55); }
.tvbl__cover img { width: 100%; height: auto; }

.tvbl__glance { margin-bottom: 36px; padding: 22px 24px; border-radius: 14px; background: var(--x-mist); border: 1px solid var(--x-line); }
.tvbl__glance-client { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; margin-bottom: 16px; }
.tvbl__glance-client b { font-size: 17px; font-weight: 800; color: var(--x-ink); }
.tvbl__glance-client span { font-size: 14px; font-weight: 600; color: var(--x-muted); }
.tvbl__glance dl { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
.tvbl__glance dl > div { display: flex; flex-direction: column-reverse; gap: 4px; padding-left: 14px; border-left: 2px solid #D9E2EE; }
.tvbl__glance dd { font-size: clamp(22px, .8cqi + 16px, 28px); font-weight: 800; line-height: 1.05; color: var(--x-blue); font-variant-numeric: tabular-nums; }
.tvbl__glance dt { font-size: 13.5px; font-weight: 600; line-height: 1.35; color: var(--x-muted); }

.tvbl__body { font-size: 18px; line-height: 1.75; color: #2E3442; }
.tvbl__body > * + * { margin-top: 18px; }
.tvbl__body h2 { margin-top: 46px; font-weight: 800; font-size: clamp(24px, .8cqi + 18px, 30px); line-height: 1.2; letter-spacing: -.005em; color: var(--x-ink); text-wrap: balance; }
.tvbl__body h3 { margin-top: 30px; font-weight: 700; font-size: 21px; line-height: 1.3; color: var(--x-ink); }
.tvbl__body h2 + *, .tvbl__body h3 + * { margin-top: 12px; }
.tvbl__body strong { font-weight: 700; color: var(--x-ink); }
.tvbl__body a { color: var(--x-blue); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: rgba(8, 106, 217, .35); }
.tvbl__body a:hover { color: var(--x-blue-ink); text-decoration-color: currentColor; }
.tvbl__body ul, .tvbl__body ol { display: grid; gap: 10px; }
.tvbl__body ul > li { position: relative; padding-left: 26px; }
.tvbl__body ul > li::before { content: ""; position: absolute; left: 4px; top: .7em; width: 8px; height: 8px; border-radius: 50%; background: var(--x-beige); }
.tvbl__body ol:not(.tvbl__steps) { counter-reset: tvbl; }
.tvbl__body ol:not(.tvbl__steps) > li { position: relative; padding-left: 42px; counter-increment: tvbl; }
.tvbl__body ol:not(.tvbl__steps) > li::before { content: counter(tvbl); position: absolute; left: 0; top: .1em; width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; background: var(--x-blue-tint); color: var(--x-blue); font-size: 14px; font-weight: 800; line-height: 1; }
.tvbl__fig { margin-block: 32px; }
.tvbl__fig img { width: 100%; height: auto; border-radius: 14px; border: 1px solid var(--x-line); background: var(--x-mist); }
.tvbl__fig figcaption { margin-top: 10px; font-size: 14.5px; line-height: 1.5; color: var(--x-muted); }
.tvbl__note { margin-top: 32px; padding: 18px 20px; border-radius: 12px; background: var(--x-mist); border-left: 3px solid var(--x-blue); font-size: 16.5px; line-height: 1.6; }
.tvbl__steps { display: grid; gap: 12px; }
.tvbl__steps li { position: relative; padding: 16px 18px 16px 60px; border-radius: 12px; border: 1px solid var(--x-line); background: var(--x-paper); font-size: 17px; line-height: 1.6; }
.tvbl__steps li::before { content: ""; position: absolute; left: 18px; top: 18px; width: 26px; height: 26px; border-radius: 50%; background: var(--x-blue) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / 15px no-repeat; }
.tvbl__steps li.is-now::before { background: var(--x-paper); box-shadow: inset 0 0 0 3px var(--x-beige); }
.tvbl__steps li > span { display: inline-block; margin: 0 8px 4px 0; padding: 2px 9px; border-radius: 20px; font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; background: #E6F6EE; color: #0E7A47; vertical-align: 2px; }
.tvbl__steps li.is-now > span { background: #F8EEE7; color: #8A5A3E; }

/* author box under every article; the byline links to it */
.tvbl__meta .tvbl__by { color: inherit; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: #C3CBD8; }
.tvbl__meta .tvbl__by:hover { color: var(--x-ink); text-decoration-color: currentColor; }
.tvbl__author { display: flex; align-items: flex-start; gap: 18px; margin-top: 44px; padding: 22px 24px; border-radius: 14px; background: var(--x-mist); border: 1px solid var(--x-line); scroll-margin-top: 110px; }
.tvbl__author-mark { flex: none; width: 56px; height: 56px; border-radius: 50%; display: grid; place-items: center; background: var(--x-navy); color: #fff; font-size: 18px; font-weight: 800; letter-spacing: .04em; box-shadow: inset 0 0 0 2px var(--x-beige); }
.tvbl__author-kicker { font-size: 12.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--x-muted); }
.tvbl__author-name { margin-top: 4px; font-size: 19px; font-weight: 800; line-height: 1.3; color: var(--x-ink); }
.tvbl__author-role { margin-top: 2px; font-size: 14.5px; font-weight: 600; color: var(--x-blue-ink); }
.tvbl__author-bio { margin-top: 10px; font-size: 16px; line-height: 1.65; color: #3A4252; text-wrap: pretty; }
.tvbl__author + .tvbl__share { margin-top: 28px; }
.tvbl__share { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 44px; padding-top: 24px; border-top: 1px solid var(--x-line); }
.tvbl__share > span { margin-right: 6px; font-size: 14px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--x-muted); }
.tvx .tvbl__sh { width: 42px; height: 42px; border-radius: 50%; display: inline-grid; place-items: center; border: 1px solid var(--x-line); background: var(--x-paper); color: var(--x-ink); text-decoration: none; transition: background-color .2s ease, color .2s ease, border-color .2s ease; }
.tvx .tvbl__sh:hover { background: var(--x-ink); border-color: var(--x-ink); color: #fff; }
.tvbl__sh svg { width: 18px; height: 18px; }
.tvbl__copied { font-size: 14px; font-weight: 600; color: #0E7A47; opacity: 0; transition: opacity .2s ease; }
.tvbl__copied.is-on { opacity: 1; }
.tvbl .tvx__cta { margin-top: 0; }

@container tvx (max-width: 1020px) {
  .tvbl__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tvbl__grid--home > :nth-child(3) { display: none; }
}
@container tvx (max-width: 900px) {
  .tvbl__card--feature { grid-template-columns: minmax(0, 1fr); }
  .tvbl__card--feature .tvbl__card-img { aspect-ratio: 16 / 9; min-height: 0; }
  .tvbl__glance dl { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@container tvx (max-width: 640px) {
  .tvbl__author { flex-direction: column; gap: 12px; padding: 18px; }
  .tvbl__grid { grid-template-columns: minmax(0, 1fr); }
  .tvbl__grid--home > :nth-child(3) { display: flex; }
  .tvbl__body { font-size: 17px; }
  .tvbl__cover { border-radius: 12px; margin-inline: calc(-1 * clamp(0px, 2cqi, 8px)); }
}

.tvbl .tvx__inner--tight { padding-block: clamp(40px, 5cqi, 64px); }

</style>
<section class="tvx tvbl tvbl--post" aria-label="Website, app or both? How to choose your first online channel">
  <div class="tvbl__article">
    <div class="tvbl__meta tvbl__meta--top"><a class="tvbl__cat" data-cat="guides" href="https://topvieweg.com/blog/?cat=guides">Guide</a><span>14 October 2026</span><span>2 min read</span><span>By <a class="tvbl__by" href="#tvbl-author">Amr Bendary</a></span></div>
    <p class="tvbl__lede">A website and an app do different jobs. Here is what each one does best, the questions that help you choose, and why many brands end up running both from one dashboard.</p>
    <figure class="tvbl__cover"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-g-channel.jpg" width="1200" height="675" alt="A laptop and a phone: choosing between a website, an app or both" decoding="async"></figure>
    <div class="tvbl__body">
<p>“Do we need an app, or is a website enough?” is one of the first questions owners ask us. The honest answer: they do different jobs.</p>

<h2>What a website does best</h2>
<ul>
  <li><strong>Being found.</strong> Customers reach it from Google, ads and shared links, with nothing to download.</li>
  <li><strong>The first order.</strong> A new customer can order in a few taps from any browser.</li>
  <li><strong>Every screen.</strong> It works on phones, tablets and computers.</li>
</ul>

<h2>What an app does best</h2>
<ul>
  <li><strong>Repeat orders.</strong> It sits on the customer’s home screen, with saved addresses and one-tap reorder.</li>
  <li><strong>Notifications.</strong> You can tell customers about new products and offers directly.</li>
  <li><strong>Loyalty.</strong> Points, rewards and a customer account feel natural in an app.</li>
</ul>

<h2>Questions that help you choose</h2>
<ul>
  <li><strong>How often do customers order?</strong> Weekly or more often points to an app. Occasional orders point to a website first.</li>
  <li><strong>Where will new customers come from?</strong> If you rely on Google and ads, start with a website.</li>
  <li><strong>Do you want a loyalty programme?</strong> An app makes it far more visible.</li>
  <li><strong>How many products do you sell?</strong> Large catalogues need good search and filters on either channel.</li>
</ul>

<h2>Why many brands run both</h2>
<p>The website brings new customers; the app keeps them. When both share the same catalogue, offers and dashboard, you manage one system, not two. Etoile Egypt runs both: more than 350,000 website visitors a month and more than 520,000 app users. Abo Mehram runs both too, and reached 30,000 active users in its first two months.</p>

<h2>A simple rule of thumb</h2>
<p>If customers order from you often and you want them to come back, plan for an app. If you need to be found and win first orders, start with a website. If you can, plan both from the beginning, so adding the second one later is simple.</p>
<p class="tvbl__note">See how we build both: <a href="https://topvieweg.com/service/ecommerce-solutions/">online stores</a> and <a href="https://topvieweg.com/service/mobile-app-development/">mobile apps</a>.</p>
    </div>
    <aside class="tvbl__author" id="tvbl-author" aria-labelledby="tvbl-author-name">
      <span class="tvbl__author-mark" aria-hidden="true">AB</span>
      <div>
        <p class="tvbl__author-kicker">About the author</p>
        <p class="tvbl__author-name" id="tvbl-author-name">Amr Bendary</p>
        <p class="tvbl__author-role">Founder, Top View · CTO, Etoile</p>
        <p class="tvbl__author-bio">Founder of Top View and CTO at Etoile, Amr Bendary brings over 20 years of experience in digital transformation, mobile apps, e-commerce, and ERP integration. He holds an MBA in Digital Transformation and helps businesses connect technology with growth and operational efficiency.</p>
      </div>
    </aside>
    <div class="tvbl__share"><span>Share</span>
      <a class="tvbl__sh" href="https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Ftopvieweg.com%2Fwebsite-app-or-both%2F" target="_blank" rel="noopener" aria-label="Share on LinkedIn"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M6.94 8.5H3.56V20h3.38V8.5ZM5.25 3a1.96 1.96 0 1 0 0 3.92 1.96 1.96 0 0 0 0-3.92ZM20.44 13.4c0-3.1-1.65-4.55-3.86-4.55-1.78 0-2.58.98-3.02 1.67V8.5h-3.38c.04.95 0 11.5 0 11.5h3.38v-6.42c0-.34.02-.69.13-.93.27-.69.9-1.4 1.95-1.4 1.38 0 1.93 1.05 1.93 2.59V20h3.37v-6.6Z"/></svg></a>
      <a class="tvbl__sh" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Ftopvieweg.com%2Fwebsite-app-or-both%2F" target="_blank" rel="noopener" aria-label="Share on Facebook"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M13.5 21v-7.5h2.53l.38-2.93H13.5V8.7c0-.85.24-1.43 1.45-1.43h1.55V4.65a20.8 20.8 0 0 0-2.26-.12c-2.24 0-3.77 1.37-3.77 3.88v2.16H7.94v2.93h2.53V21h3.03Z"/></svg></a>
      <a class="tvbl__sh" href="https://wa.me/?text=Website%2C%20app%20or%20both%3F%20How%20to%20choose%20your%20first%20online%20channel%20https%3A%2F%2Ftopvieweg.com%2Fwebsite-app-or-both%2F" target="_blank" rel="noopener" aria-label="Share on WhatsApp"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M17.47 14.38c-.3-.15-1.76-.87-2.03-.97-.27-.1-.47-.15-.67.15-.2.3-.77.97-.94 1.16-.17.2-.35.22-.64.07-.3-.15-1.26-.46-2.39-1.47-.88-.79-1.48-1.76-1.65-2.06-.17-.3-.02-.46.13-.61.13-.13.3-.35.45-.52.15-.17.2-.3.3-.5.1-.2.05-.37-.03-.52-.07-.15-.67-1.61-.92-2.21-.24-.58-.49-.5-.67-.51h-.57c-.2 0-.52.07-.79.37-.27.3-1.04 1.02-1.04 2.48 0 1.46 1.07 2.88 1.21 3.07.15.2 2.1 3.2 5.08 4.49.71.31 1.26.49 1.69.63.71.23 1.36.2 1.87.12.57-.09 1.76-.72 2-1.41.25-.7.25-1.29.18-1.41-.08-.13-.27-.2-.57-.35ZM12.05 21.79h-.01a9.87 9.87 0 0 1-5.03-1.38l-.36-.21-3.74.98 1-3.65-.24-.37a9.86 9.86 0 0 1-1.51-5.26c0-5.45 4.44-9.88 9.89-9.88a9.83 9.83 0 0 1 9.88 9.89c0 5.45-4.44 9.88-9.88 9.88Zm8.41-18.3A11.82 11.82 0 0 0 12.05 0C5.5 0 .16 5.34.16 11.89c0 2.1.55 4.14 1.59 5.95L.06 24l6.3-1.65a11.88 11.88 0 0 0 5.68 1.45h.01c6.55 0 11.89-5.34 11.89-11.89 0-3.18-1.24-6.17-3.48-8.42Z"/></svg></a>
      <a class="tvbl__sh" href="https://topvieweg.com/website-app-or-both/" data-copy aria-label="Copy link"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1"/><path d="M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1"/></svg></a><span class="tvbl__copied" aria-live="polite">Link copied</span>
    </div>
  </div>
  <div class="tvbl__band">
    <div class="tvx__inner tvx__inner--tight">
      <div class="tvx__cta" data-reveal>
        <div class="tvx__cta-text"><h3 class="tvx__cta-title">Planning something similar?</h3><p class="tvx__cta-body">Book a free meeting with our team. We will review how your branches work and suggest the right setup.</p></div>
        <div class="tvx__cta-actions">
          <a class="tvx__btn tvx__btn--primary" href="https://topvieweg.com/contact/" data-tvx="consultation" data-where="blog_website-app-or-both">Get a Free Consultation <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          <a class="tvx__btn tvx__btn--ghost" href="https://wa.me/201114000096?text=Hello%20TopView%2C%20I'm%20contacting%20you%20from%20your%20website%20(News%20article).%20I'd%20like%20to%20discuss%20a%20project." target="_blank" rel="noopener" data-tvx="whatsapp"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M17.47 14.38c-.3-.15-1.76-.87-2.03-.97-.27-.1-.47-.15-.67.15-.2.3-.77.97-.94 1.16-.17.2-.35.22-.64.07-.3-.15-1.26-.46-2.39-1.47-.88-.79-1.48-1.76-1.65-2.06-.17-.3-.02-.46.13-.61.13-.13.3-.35.45-.52.15-.17.2-.3.3-.5.1-.2.05-.37-.03-.52-.07-.15-.67-1.61-.92-2.21-.24-.58-.49-.5-.67-.51h-.57c-.2 0-.52.07-.79.37-.27.3-1.04 1.02-1.04 2.48 0 1.46 1.07 2.88 1.21 3.07.15.2 2.1 3.2 5.08 4.49.71.31 1.26.49 1.69.63.71.23 1.36.2 1.87.12.57-.09 1.76-.72 2-1.41.25-.7.25-1.29.18-1.41-.08-.13-.27-.2-.57-.35ZM12.05 21.79h-.01a9.87 9.87 0 0 1-5.03-1.38l-.36-.21-3.74.98 1-3.65-.24-.37a9.86 9.86 0 0 1-1.51-5.26c0-5.45 4.44-9.88 9.89-9.88a9.83 9.83 0 0 1 9.88 9.89c0 5.45-4.44 9.88-9.88 9.88Zm8.41-18.3A11.82 11.82 0 0 0 12.05 0C5.5 0 .16 5.34.16 11.89c0 2.1.55 4.14 1.59 5.95L.06 24l6.3-1.65a11.88 11.88 0 0 0 5.68 1.45h.01c6.55 0 11.89-5.34 11.89-11.89 0-3.18-1.24-6.17-3.48-8.42Z"/></svg> Chat on WhatsApp</a>
        </div>
      </div>
    </div>
  </div>
  <div class="tvbl__band tvbl__band--mist">
    <div class="tvx__inner">
      <div class="tvbl__head" data-reveal><h2 class="tvx__title">More articles</h2></div>
      <div class="tvbl__grid" data-tvbl-feed data-count="3" data-exclude="1355" data-reveal>
        <article class="tvbl__card" data-id="5571" data-cat="insights">
          <a class="tvbl__card-img" href="https://topvieweg.com/own-app-vs-delivery-apps/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-own-app.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="insights">Insight</span><span>14 Oct 2026</span><span>3 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/own-app-vs-delivery-apps/">Your own app or delivery apps? What changes for a multi-branch brand</a></h3>
            <p class="tvbl__card-ex">Delivery apps bring orders, but they keep the customer and take a share of every sale. Here is what changes when a multi-branch brand runs its own app and online store, and how to start without losing the orders you already have.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
        <article class="tvbl__card" data-id="5575" data-cat="guides">
          <a class="tvbl__card-img" href="https://topvieweg.com/what-is-ecommerce/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-g-what.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="guides">Guide</span><span>14 Oct 2026</span><span>2 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/what-is-ecommerce/">What is e-commerce? A plain guide for business owners</a></h3>
            <p class="tvbl__card-ex">E-commerce is more than a website with a cart. Here is what it really means for a restaurant, shop or brand, the channels it covers, and the parts that have to work together behind every online order.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
        <article class="tvbl__card" data-id="5572" data-cat="case-studies">
          <a class="tvbl__card-img" href="https://topvieweg.com/etoile-egypt-app-case-study/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-etoile.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="case-studies">Case study</span><span>14 Oct 2026</span><span>2 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/etoile-egypt-app-case-study/">How Etoile Egypt went from a call centre to 520,000+ app users</a></h3>
            <p class="tvbl__card-ex">Etoile Egypt moved its online orders from a busy call centre to its own app and website. Today the app has more than 520,000 users and takes thousands of orders a day, connected to the branches, ERP and POS.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
      </div>
      <div class="tvbl__all"><a class="tvx__btn tvx__btn--outline" href="https://topvieweg.com/blog/">View all articles <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a></div>
    </div>
  </div>
</section>
<script>
(function () {
  var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  function fmt(n) { return Math.round(n).toLocaleString('en-US'); }
  function countUp(el) {
    var to = Number(el.getAttribute('data-n'));
    if (reduce || !to) return;
    var dur = 1200, t0 = null;
    el.textContent = fmt(0);
    requestAnimationFrame(function step(t) {
      if (t0 === null) t0 = t;
      var p = Math.min(1, (t - t0) / dur);
      el.textContent = fmt(to * (1 - Math.pow(1 - p, 3)));
      if (p < 1) requestAnimationFrame(step);
    });
    // always land on the real value, even if frames stall
    setTimeout(function () { el.textContent = fmt(to); }, dur + 400);
  }

  function init(root) {
    root.setAttribute('data-ready', '');
    root.classList.add('is-js');

    // scroll reveal (armed only here, so the section is complete without JS)
    var items = [].slice.call(root.querySelectorAll('[data-reveal]'));
    var drawTarget = root.querySelector('[data-draw]');
    if (!reduce && 'IntersectionObserver' in window) {
      root.classList.add('is-armed');
      var io = new IntersectionObserver(function (entries) {
        entries.forEach(function (e) {
          if (!e.isIntersecting) return;
          io.unobserve(e.target);
          if (e.target === drawTarget) {
            root.classList.add('is-drawn');
            [].slice.call(root.querySelectorAll('[data-n]')).forEach(countUp);
          } else {
            e.target.classList.add('is-in');
          }
        });
      }, { threshold: 0.15, rootMargin: '0px 0px -40px 0px' });
      items.forEach(function (el) { io.observe(el); });
      if (drawTarget) io.observe(drawTarget);
      // safety net: never leave content hidden
      setTimeout(function () { items.forEach(function (el) { el.classList.add('is-in'); }); root.classList.add('is-drawn'); }, 4000);
    } else {
      root.classList.add('is-drawn');
    }
    // looping decorations pause while the section is off screen
    if ('IntersectionObserver' in window) {
      new IntersectionObserver(function (entries) { root.classList.toggle('is-off', !entries[entries.length - 1].isIntersecting); }).observe(root);
    }

    // looping motion ([data-loop]) starts when first seen, so it opens on its first scene, and pauses off screen
    [].slice.call(root.querySelectorAll('[data-loop]')).forEach(function (el) {
      if (reduce || !('IntersectionObserver' in window)) return;
      new IntersectionObserver(function (entries) {
        var on = entries[entries.length - 1].isIntersecting; // several entries can queue up during a fast scroll; the last one is current
        if (on) el.classList.add('is-playing');
        el.classList.toggle('is-paused', !on);
      }, { threshold: 0.3 }).observe(el);
    });

    // tabs with a sliding highlight
    var tabs = [].slice.call(root.querySelectorAll('[role="tab"]'));
    if (!tabs.length) return;
    var panels = tabs.map(function (t) { return root.querySelector('#' + t.getAttribute('aria-controls')); });
    var ink = root.querySelector('.tvpf__ink');
    var list = tabs[0].parentNode;
    var current = Math.max(0, tabs.findIndex(function (t) { return t.getAttribute('aria-selected') === 'true'; }));
    function moveInk() {
      if (!ink) return;
      var t = tabs[current];
      ink.style.width = t.offsetWidth + 'px';
      ink.style.transform = 'translateX(' + t.offsetLeft + 'px)';
    }
    function show(n, focus) {
      if (n === current) return;
      current = (n + tabs.length) % tabs.length;
      tabs.forEach(function (t, k) {
        var on = k === current;
        t.classList.toggle('is-active', on);
        t.setAttribute('aria-selected', on ? 'true' : 'false');
        t.tabIndex = on ? 0 : -1;
      });
      panels.forEach(function (p, k) {
        var on = k === current;
        p.hidden = !on;
        p.classList.toggle('is-active', on);
        p.classList.remove('is-entering');
        if (on && !reduce) { void p.offsetWidth; p.classList.add('is-entering'); }
      });
      moveInk();
      var t = tabs[current];
      if (list.scrollWidth > list.clientWidth) list.scrollTo({ left: t.offsetLeft - (list.clientWidth - t.offsetWidth) / 2, behavior: reduce ? 'auto' : 'smooth' });
      if (focus) t.focus();
    }
    tabs.forEach(function (t, k) {
      t.addEventListener('click', function () { show(k); });
      t.addEventListener('keydown', function (e) {
        if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') { e.preventDefault(); show(current + (e.key === 'ArrowRight' ? 1 : -1), true); }
      });
    });
    moveInk();
    if (window.ResizeObserver) new ResizeObserver(moveInk).observe(list);
    window.addEventListener('load', moveInk);
  }

  [].slice.call(document.querySelectorAll('.tvx:not([data-ready])')).forEach(init);

  // calls to action: same tracking as the floating WhatsApp button and the home CTA
  // (each section ships this script, so register the listener only once per page)
  if (window.__tvxCtaTracking) return;
  window.__tvxCtaTracking = true;
  document.addEventListener('click', function (e) {
    var a = e.target.closest && e.target.closest('.tvx a[data-tvx]');
    if (!a) return;
    if (a.getAttribute('data-tvx') === 'whatsapp') {
      if (typeof gtag === 'function') { gtag('event', 'contact', { method: 'WhatsApp', link_url: a.href }); }
      if (typeof fbq === 'function') { fbq('track', 'Contact', { content_name: 'WhatsApp' }); }
      if (typeof window.lintrk === 'function') { window.lintrk('track', { conversion_id: 31200418 }); }
    } else if (typeof gtag === 'function') {
      gtag('event', 'cta_click', { cta: 'free_consultation', location: a.getAttribute('data-where') || 'section' });
    }
  });
})();

(function () {
  if (window.__tvblReady) return;
  window.__tvblReady = true;

  var CAT = { guides: 'Guide', 'case-studies': 'Case study', insights: 'Insight' };
  var arrow = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg>';
  var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

  function text(html, sel) {
    var d = document.createElement('div'); d.innerHTML = html || '';
    [].slice.call(d.querySelectorAll('style,script')).forEach(function (n) { n.remove(); });
    var part = sel && d.querySelector(sel);
    return ((part || d).textContent || '').replace(/\s+/g, ' ').trim();
  }
  function esc(s) { return String(s).replace(/[&<>"]/g, function (c) { return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c]; }); }

  // the same card markup the build script prints, rebuilt from the REST API so new posts show up on their own
  // mins comes from the card the build printed for that post; a post published later shows no reading time
  // p.tv_card = { img, cat, cat_name } is a small REST field added by the "TopView speed & SEO tweaks" snippet
  function card(p, feature, mins) {
    var tc = p.tv_card || {};
    var img = tc.img || '';
    var term = { slug: tc.cat || '', name: tc.cat_name || '' };
    var d = new Date(p.date);
    return '<article class="tvbl__card' + (feature ? ' tvbl__card--feature' : '') + '" data-id="' + p.id + '" data-cat="' + esc(term.slug || '') + '">' +
      (img ? '<a class="tvbl__card-img" href="' + esc(p.link) + '" tabindex="-1" aria-hidden="true"><img loading="lazy" src="' + esc(img) + '" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>' : '') +
      '<div class="tvbl__card-body"><div class="tvbl__meta">' + (term.slug ? '<span class="tvbl__cat" data-cat="' + esc(term.slug) + '">' + esc(CAT[term.slug] || term.name) + '</span>' : '') +
      '<span>' + d.getDate() + ' ' + months[d.getMonth()] + ' ' + d.getFullYear() + '</span>' + (mins ? '<span>' + mins + ' min read</span>' : '') + '</div>' +
      '<h3 class="tvbl__card-title"><a href="' + esc(p.link) + '">' + p.title.rendered + '</a></h3>' +
      '<p class="tvbl__card-ex">' + esc(text(p.excerpt && p.excerpt.rendered)) + '</p>' +
      '<span class="tvbl__more" aria-hidden="true">Read article ' + arrow + '</span></div></article>';
  }

  function applyFilter(root, cat) {
    var cards = [].slice.call(root.querySelectorAll('.tvbl__card'));
    var shown = 0;
    cards.forEach(function (c) { var on = !cat || c.getAttribute('data-cat') === cat; c.hidden = !on; if (on) shown++; });
    [].slice.call(root.querySelectorAll('.tvbl__filter')).forEach(function (b) { b.setAttribute('aria-pressed', String((b.getAttribute('data-cat') || '') === (cat || ''))); });
    var empty = root.querySelector('.tvbl__empty');
    if (empty) empty.hidden = shown > 0;
  }

  function initFilters() {
    [].slice.call(document.querySelectorAll('.tvbl [data-tvbl-filters]')).forEach(function (bar) {
      var root = bar.closest('.tvbl');
      if (bar.getAttribute('data-ready')) { var cur = bar.querySelector('[aria-pressed="true"]'); applyFilter(root, cur ? cur.getAttribute('data-cat') || '' : ''); return; }
      bar.setAttribute('data-ready', '1');
      bar.addEventListener('click', function (e) {
        var b = e.target.closest('.tvbl__filter');
        if (!b) return;
        applyFilter(root, b.getAttribute('data-cat') || '');
      });
      var m = location.search.match(/[?&]cat=([a-z-]+)/);
      applyFilter(root, m ? m[1] : '');
    });
  }

  // copy link
  document.addEventListener('click', function (e) {
    var b = e.target.closest && e.target.closest('.tvbl [data-copy]');
    if (!b) return;
    e.preventDefault();
    var done = function () { var t = b.parentNode.querySelector('.tvbl__copied'); if (t) { t.classList.add('is-on'); setTimeout(function () { t.classList.remove('is-on'); }, 1800); } };
    if (navigator.clipboard) navigator.clipboard.writeText(location.href.split('#')[0]).then(done, function () {}); else done();
  });

  var feeds = [].slice.call(document.querySelectorAll('[data-tvbl-feed]'));
  initFilters();
  if (!feeds.length || !window.fetch) return;

  // Only the fields a card shows (the full post content made this ~600 KB), and only once a feed
  // comes near the screen, so the request never competes with the page's first paint.
  var loaded = false;
  function refresh() {
    if (loaded) return;
    loaded = true;
    var mins = {};
    [].forEach.call(document.querySelectorAll('.tvbl__card[data-id]'), function (c) {
      var m = (c.textContent || '').match(/(\d+) min read/);
      if (m) mins[c.getAttribute('data-id')] = m[1];
    });
    fetch('/wp-json/wp/v2/posts?per_page=12&_fields=id,date,link,title,excerpt,tv_card', { credentials: 'omit' })
      .then(function (r) { return r.ok ? r.json() : Promise.reject(r.status); })
      .then(function (posts) {
        if (!Array.isArray(posts) || !posts.length || !posts[0].tv_card) return; // keep the printed cards if the field is missing
        feeds.forEach(function (feed) {
          var max = Number(feed.getAttribute('data-count')) || posts.length;
          var skip = Number(feed.getAttribute('data-exclude')) || 0;
          var list = posts.filter(function (p) { return p.id !== skip; }).slice(0, max);
          var have = [].map.call(feed.querySelectorAll('.tvbl__card'), function (el) { return el.getAttribute('data-id'); }).join();
          if (have === list.map(function (p) { return String(p.id); }).join()) return; // the printed cards are already current
          var feature = feed.hasAttribute('data-feature');
          feed.innerHTML = list.map(function (p, i) { return card(p, feature && i === 0, mins[p.id]); }).join('');
        });
        initFilters();
      })
      .catch(function () {});
  }
  if ('IntersectionObserver' in window) {
    var io = new IntersectionObserver(function (entries) {
      if (entries.some(function (e) { return e.isIntersecting; })) { io.disconnect(); refresh(); }
    }, { rootMargin: '600px 0px' });
    feeds.forEach(function (f) { io.observe(f); });
  } else {
    window.addEventListener('load', refresh);
  }
})();

</script>
				</div>
				</div>
				</div>
				</div>
		<p>The post <a href="https://topvieweg.com/website-app-or-both/">Website, app or both? How to choose your first online channel</a> appeared first on <a href="https://topvieweg.com">TopView</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>What customers expect when they order online, and how to deliver it</title>
		<link>https://topvieweg.com/what-customers-expect-online/</link>
		
		<dc:creator><![CDATA[TopView Team]]></dc:creator>
		<pubDate>Wed, 14 Oct 2026 06:00:00 +0000</pubDate>
				<category><![CDATA[Guides]]></category>
		<guid isPermaLink="false">https://tplabs.co/izeetak/?p=2007</guid>

					<description><![CDATA[<p>Customers compare every online order with the best app on their phone. Here are eight things they expect, and what has to work behind the scenes to deliver each one.</p>
<p>The post <a href="https://topvieweg.com/what-customers-expect-online/">What customers expect when they order online, and how to deliver it</a> appeared first on <a href="https://topvieweg.com">TopView</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="2007" class="elementor elementor-2007" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-tvb2007c e-con-full e-flex e-con e-parent" data-id="tvb2007c" data-element_type="container" data-e-type="container">
				<div class="elementor-element elementor-element-tvb2007w elementor-widget elementor-widget-html" data-id="tvb2007w" data-element_type="widget" data-e-type="widget" data-widget_type="html.default">
				<div class="elementor-widget-container">
					<!-- TopView blog: article what-customers-expect-online. Generated by live-site/blog/build.js from articles.js; edit there and rebuild. -->
<style>
/* Shared base for the TopView platform (.tvpf) and discount-system (.tvdm) sections.
   The izeetak theme styles every <button> (70px line height, 60px side padding, uppercase, wide tracking),
   sets body line height to 2 and decorates lists, so each section resets those inside itself. */
.tvx {
  --x-ink: #1B1825;
  --x-muted: #5A6475;
  --x-line: #E3E8EF;
  --x-paper: #FFFFFF;
  --x-mist: #F4F7FB;
  --x-blue: #086AD9;
  --x-blue-ink: #0757B3;
  --x-blue-tint: #E7F0FC;
  --x-beige: #D2A88F;
  --x-beige-lite: #E7C7B2;
  --x-navy: #06142B;
  --x-navy-2: #0B2A55;
  --x-ease: cubic-bezier(.2, .8, .2, 1);
  container: tvx / inline-size;
  position: relative;
  width: 100%;
  font-family: "Barlow", "Segoe UI", system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.5;
  color: var(--x-ink);
  text-align: left;
}
.elementor-widget:has(> .elementor-widget-container > .tvx) { width: 100%; min-width: 0; }
.tvx *, .tvx *::before, .tvx *::after { box-sizing: border-box; }
/* Element-weight resets (0,0,1): they still beat the theme (same weight, later in the page) but lose to every
   class rule, even when a second section on the page repeats this file after the first section’s rules. */
:where(.tvx) :is(h2, h3, h4, p, ul, ol, li, dl, dt, dd, figure) { margin: 0; padding: 0; }
:where(.tvx) :is(ul, ol) { list-style: none; }
:where(.tvx) li::before, :where(.tvx) li::after { content: none; }
:where(.tvx) img { display: block; max-width: 100%; height: auto; }
.tvx button { min-width: 0; min-height: 0; margin: 0; padding: 0; border: 0; background: none; color: inherit; font: inherit; line-height: inherit; letter-spacing: normal; text-transform: none; cursor: pointer; }
.tvx button:hover, .tvx button:focus { background: none; color: inherit; }
.tvx :focus-visible { outline: 3px solid var(--x-blue); outline-offset: 3px; }

.tvx__inner { max-width: 1200px; margin: 0 auto; padding-inline: clamp(16px, 4cqi, 32px); padding-block: clamp(56px, 7cqi, 96px); }
.tvx__head { max-width: 720px; margin-bottom: clamp(28px, 4cqi, 48px); }
.tvx__title { font-weight: 800; font-size: clamp(30px, 2.4cqi + 14px, 46px); line-height: 1.08; letter-spacing: -.01em; color: var(--x-ink); text-wrap: balance; margin-bottom: 14px; }
.tvx__lede { font-size: clamp(16px, .5cqi + 12px, 19px); line-height: 1.65; font-weight: 500; color: var(--x-muted); text-wrap: pretty; }
.tvx__h3 { font-weight: 800; font-size: clamp(21px, .8cqi + 15px, 26px); line-height: 1.2; color: var(--x-ink); margin-bottom: 18px; text-wrap: balance; }

.tvx__icon { flex: none; width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center; background: var(--x-blue-tint); color: var(--x-blue); }
.tvx__icon svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

.tvx__chips { display: flex; flex-wrap: wrap; gap: 8px; }
.tvx__chips li { padding: 7px 13px; border: 1px solid var(--x-line); border-radius: 20px; background: var(--x-paper); font-size: 14px; font-weight: 600; line-height: 1.3; color: var(--x-ink); }

/* closing call to action */
.tvx__cta { margin-top: clamp(40px, 5cqi, 64px); border-radius: 14px; padding: clamp(28px, 4cqi, 44px); display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 24px 40px; color: #fff; background: radial-gradient(60% 120% at 85% 0%, rgba(8, 106, 217, .55), transparent 70%), linear-gradient(160deg, var(--x-navy-2), var(--x-navy)); }
.tvx__cta-text { min-width: 0; max-width: 560px; }
.tvx__cta-title { font-weight: 800; font-size: clamp(22px, 1cqi + 15px, 30px); line-height: 1.2; color: #fff; text-wrap: balance; }
.tvx__cta-body { margin-top: 8px; font-size: 16px; line-height: 1.6; color: rgba(255, 255, 255, .82); }
.tvx__cta-actions { display: flex; flex-wrap: wrap; gap: 12px; }
.tvx__btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 52px; padding: 0 22px; border-radius: 8px; font-weight: 700; font-size: 14px; line-height: 1; letter-spacing: .1em; text-transform: uppercase; text-decoration: none; white-space: nowrap; transition: background-color .2s ease, border-color .2s ease, transform .2s ease; }
.tvx__btn svg { width: 18px; height: 18px; flex: none; }
.tvx__btn--primary { background: var(--x-beige); color: var(--x-ink); }
.tvx__btn--primary:hover, .tvx__btn--primary:focus { background: var(--x-beige-lite); color: var(--x-ink); }
.tvx__btn--ghost { color: #fff; border: 1.5px solid rgba(255, 255, 255, .34); }
.tvx__btn--ghost:hover, .tvx__btn--ghost:focus { color: #fff; border-color: #fff; background: rgba(255, 255, 255, .06); }
.tvx__btn:active { transform: translateY(1px); }
.tvx__btn:focus-visible { outline-color: var(--x-beige-lite); }

/* scroll reveal: only armed by JS, so content is visible without it */
.tvx.is-armed [data-reveal] { opacity: 0; transform: translateY(16px); transition: opacity .7s var(--x-ease), transform .7s var(--x-ease); transition-delay: calc(var(--i, 0) * 70ms); }
.tvx.is-armed [data-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .tvx *, .tvx *::before, .tvx *::after { animation: none !important; transition: none !important; }
  .tvx.is-armed [data-reveal] { opacity: 1; transform: none; }
}
@container tvx (max-width: 560px) {
  .tvx__cta-actions { width: 100%; flex-direction: column; }
  .tvx__btn { width: 100%; padding: 14px 16px; letter-spacing: .07em; white-space: normal; text-align: center; line-height: 1.3; }
}

/* ===== Blog (.tvbl): home "News & Articles" section, the News page and the article page. Builds on ../platform/tv-shared.css ===== */
.tvbl { background: var(--x-paper); }
.tvbl__band { width: 100%; }
.tvbl__band--mist { background: var(--x-mist); }

/* section head (home + news page) */
.tvbl__head { max-width: 760px; margin-bottom: clamp(28px, 4cqi, 44px); }
.tvbl__head--center { margin-inline: auto; text-align: center; }
.tvbl__eyebrow { display: inline-flex; align-items: center; gap: 10px; margin-bottom: 10px; font-size: 16px; font-weight: 600; color: var(--x-muted); }
.tvbl__eyebrow::before { content: ""; width: 14px; height: 2px; background: var(--x-beige); }
.tvbl__head--center .tvx__title { margin-inline: auto; }
.tvbl__head--center .tvx__lede { margin-inline: auto; max-width: 640px; }

/* cards */
.tvbl__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.tvbl__card { position: relative; display: flex; flex-direction: column; border-radius: 16px; overflow: hidden; background: var(--x-paper); border: 1px solid var(--x-line); transition: border-color .25s ease, box-shadow .25s ease, transform .25s ease; }
.tvbl__card:hover { border-color: #C9D3E0; box-shadow: 0 22px 40px -28px rgba(6, 20, 43, .45); transform: translateY(-3px); }
.tvbl__card-img { display: block; aspect-ratio: 16 / 9; overflow: hidden; background: var(--x-navy); }
.tvbl__card-img img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--x-ease); }
.tvbl__card:hover .tvbl__card-img img { transform: scale(1.03); }
.tvbl__card-body { display: flex; flex-direction: column; gap: 10px; flex: 1; padding: 20px 22px 22px; }
.tvbl__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; font-size: 13.5px; font-weight: 600; line-height: 1.3; color: var(--x-muted); }
.tvbl__meta > span + span::before { content: ""; display: inline-block; width: 4px; height: 4px; margin: 0 10px 2px 0; border-radius: 50%; background: #C3CBD8; vertical-align: middle; }
.tvbl__cat { display: inline-block; padding: 4px 10px; border-radius: 20px; background: var(--x-blue-tint); color: var(--x-blue-ink); font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; text-decoration: none; }
.tvbl__cat[data-cat="case-studies"] { background: #F8EEE7; color: #8A5A3E; }
.tvbl__cat[data-cat="guides"] { background: #E6F6EE; color: #0E7A47; }
a.tvbl__cat:hover { filter: brightness(.96); }
.tvbl__card-title { font-weight: 700; font-size: 20px; line-height: 1.3; color: var(--x-ink); text-wrap: balance; }
.tvbl__card-title a { color: inherit; text-decoration: none; }
.tvbl__card-title a::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.tvbl__card-title a:focus-visible { outline: none; }
.tvbl__card:has(.tvbl__card-title a:focus-visible) { outline: 3px solid var(--x-blue); outline-offset: 3px; }
.tvbl__card-ex { font-size: 15px; line-height: 1.6; color: var(--x-muted); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.tvbl__more { margin-top: auto; padding-top: 6px; display: inline-flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--x-blue); }
.tvbl__more svg { width: 16px; height: 16px; transition: transform .2s ease; }
.tvbl__card:hover .tvbl__more svg { transform: translateX(4px); }

/* featured (first) card on the news page */
.tvbl__card--feature { grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.tvbl__card--feature .tvbl__card-img { aspect-ratio: auto; min-height: 100%; }
.tvbl__card--feature .tvbl__card-body { justify-content: center; gap: 14px; padding: clamp(24px, 3.4cqi, 44px); }
.tvbl__card--feature .tvbl__card-title { font-size: clamp(24px, 1.2cqi + 14px, 32px); line-height: 1.2; }
.tvbl__card--feature .tvbl__card-ex { font-size: 16.5px; -webkit-line-clamp: 4; }

/* filter chips (news page) */
.tvbl__filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 26px; }
.tvx .tvbl__filter { padding: 9px 16px; border-radius: 30px; border: 1px solid var(--x-line); background: var(--x-paper); font-size: 14.5px; font-weight: 700; line-height: 1.2; color: var(--x-ink); transition: background-color .2s ease, color .2s ease, border-color .2s ease; }
.tvx .tvbl__filter:hover { border-color: #C9D3E0; background: var(--x-paper); color: var(--x-ink); }
.tvx .tvbl__filter[aria-pressed="true"] { background: var(--x-ink); border-color: var(--x-ink); color: #fff; }
.tvbl__card[hidden] { display: none; }
.tvbl__empty { padding: 40px; text-align: center; color: var(--x-muted); }

.tvbl__all { display: flex; justify-content: center; margin-top: clamp(28px, 4cqi, 40px); }
.tvbl .tvx__btn--outline { color: var(--x-ink); border: 1.5px solid #C9D3E0; }
.tvbl .tvx__btn--outline:hover, .tvbl .tvx__btn--outline:focus { color: var(--x-ink); border-color: var(--x-ink); }
.tvbl .tvx__btn--outline:focus-visible { outline-color: var(--x-blue); }

/* ---------- article page ---------- */
.tvbl__article { max-width: 960px; margin: 0 auto; padding-inline: clamp(16px, 4cqi, 32px); padding-block: clamp(40px, 6cqi, 72px) clamp(48px, 6cqi, 80px); }
.tvbl__article > :not(.tvbl__cover) { max-width: 720px; margin-inline: auto; }
.tvbl__meta--top { margin-bottom: 18px; font-size: 14.5px; }
.tvbl__lede { font-size: clamp(19px, .6cqi + 15px, 22px); line-height: 1.6; font-weight: 500; color: #3A4252; text-wrap: pretty; }
.tvbl__cover { margin: clamp(28px, 4cqi, 40px) 0; border-radius: 18px; overflow: hidden; background: var(--x-navy); box-shadow: 0 30px 60px -40px rgba(6, 20, 43, .55); }
.tvbl__cover img { width: 100%; height: auto; }

.tvbl__glance { margin-bottom: 36px; padding: 22px 24px; border-radius: 14px; background: var(--x-mist); border: 1px solid var(--x-line); }
.tvbl__glance-client { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; margin-bottom: 16px; }
.tvbl__glance-client b { font-size: 17px; font-weight: 800; color: var(--x-ink); }
.tvbl__glance-client span { font-size: 14px; font-weight: 600; color: var(--x-muted); }
.tvbl__glance dl { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
.tvbl__glance dl > div { display: flex; flex-direction: column-reverse; gap: 4px; padding-left: 14px; border-left: 2px solid #D9E2EE; }
.tvbl__glance dd { font-size: clamp(22px, .8cqi + 16px, 28px); font-weight: 800; line-height: 1.05; color: var(--x-blue); font-variant-numeric: tabular-nums; }
.tvbl__glance dt { font-size: 13.5px; font-weight: 600; line-height: 1.35; color: var(--x-muted); }

.tvbl__body { font-size: 18px; line-height: 1.75; color: #2E3442; }
.tvbl__body > * + * { margin-top: 18px; }
.tvbl__body h2 { margin-top: 46px; font-weight: 800; font-size: clamp(24px, .8cqi + 18px, 30px); line-height: 1.2; letter-spacing: -.005em; color: var(--x-ink); text-wrap: balance; }
.tvbl__body h3 { margin-top: 30px; font-weight: 700; font-size: 21px; line-height: 1.3; color: var(--x-ink); }
.tvbl__body h2 + *, .tvbl__body h3 + * { margin-top: 12px; }
.tvbl__body strong { font-weight: 700; color: var(--x-ink); }
.tvbl__body a { color: var(--x-blue); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: rgba(8, 106, 217, .35); }
.tvbl__body a:hover { color: var(--x-blue-ink); text-decoration-color: currentColor; }
.tvbl__body ul, .tvbl__body ol { display: grid; gap: 10px; }
.tvbl__body ul > li { position: relative; padding-left: 26px; }
.tvbl__body ul > li::before { content: ""; position: absolute; left: 4px; top: .7em; width: 8px; height: 8px; border-radius: 50%; background: var(--x-beige); }
.tvbl__body ol:not(.tvbl__steps) { counter-reset: tvbl; }
.tvbl__body ol:not(.tvbl__steps) > li { position: relative; padding-left: 42px; counter-increment: tvbl; }
.tvbl__body ol:not(.tvbl__steps) > li::before { content: counter(tvbl); position: absolute; left: 0; top: .1em; width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; background: var(--x-blue-tint); color: var(--x-blue); font-size: 14px; font-weight: 800; line-height: 1; }
.tvbl__fig { margin-block: 32px; }
.tvbl__fig img { width: 100%; height: auto; border-radius: 14px; border: 1px solid var(--x-line); background: var(--x-mist); }
.tvbl__fig figcaption { margin-top: 10px; font-size: 14.5px; line-height: 1.5; color: var(--x-muted); }
.tvbl__note { margin-top: 32px; padding: 18px 20px; border-radius: 12px; background: var(--x-mist); border-left: 3px solid var(--x-blue); font-size: 16.5px; line-height: 1.6; }
.tvbl__steps { display: grid; gap: 12px; }
.tvbl__steps li { position: relative; padding: 16px 18px 16px 60px; border-radius: 12px; border: 1px solid var(--x-line); background: var(--x-paper); font-size: 17px; line-height: 1.6; }
.tvbl__steps li::before { content: ""; position: absolute; left: 18px; top: 18px; width: 26px; height: 26px; border-radius: 50%; background: var(--x-blue) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / 15px no-repeat; }
.tvbl__steps li.is-now::before { background: var(--x-paper); box-shadow: inset 0 0 0 3px var(--x-beige); }
.tvbl__steps li > span { display: inline-block; margin: 0 8px 4px 0; padding: 2px 9px; border-radius: 20px; font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; background: #E6F6EE; color: #0E7A47; vertical-align: 2px; }
.tvbl__steps li.is-now > span { background: #F8EEE7; color: #8A5A3E; }

/* author box under every article; the byline links to it */
.tvbl__meta .tvbl__by { color: inherit; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: #C3CBD8; }
.tvbl__meta .tvbl__by:hover { color: var(--x-ink); text-decoration-color: currentColor; }
.tvbl__author { display: flex; align-items: flex-start; gap: 18px; margin-top: 44px; padding: 22px 24px; border-radius: 14px; background: var(--x-mist); border: 1px solid var(--x-line); scroll-margin-top: 110px; }
.tvbl__author-mark { flex: none; width: 56px; height: 56px; border-radius: 50%; display: grid; place-items: center; background: var(--x-navy); color: #fff; font-size: 18px; font-weight: 800; letter-spacing: .04em; box-shadow: inset 0 0 0 2px var(--x-beige); }
.tvbl__author-kicker { font-size: 12.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--x-muted); }
.tvbl__author-name { margin-top: 4px; font-size: 19px; font-weight: 800; line-height: 1.3; color: var(--x-ink); }
.tvbl__author-role { margin-top: 2px; font-size: 14.5px; font-weight: 600; color: var(--x-blue-ink); }
.tvbl__author-bio { margin-top: 10px; font-size: 16px; line-height: 1.65; color: #3A4252; text-wrap: pretty; }
.tvbl__author + .tvbl__share { margin-top: 28px; }
.tvbl__share { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 44px; padding-top: 24px; border-top: 1px solid var(--x-line); }
.tvbl__share > span { margin-right: 6px; font-size: 14px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--x-muted); }
.tvx .tvbl__sh { width: 42px; height: 42px; border-radius: 50%; display: inline-grid; place-items: center; border: 1px solid var(--x-line); background: var(--x-paper); color: var(--x-ink); text-decoration: none; transition: background-color .2s ease, color .2s ease, border-color .2s ease; }
.tvx .tvbl__sh:hover { background: var(--x-ink); border-color: var(--x-ink); color: #fff; }
.tvbl__sh svg { width: 18px; height: 18px; }
.tvbl__copied { font-size: 14px; font-weight: 600; color: #0E7A47; opacity: 0; transition: opacity .2s ease; }
.tvbl__copied.is-on { opacity: 1; }
.tvbl .tvx__cta { margin-top: 0; }

@container tvx (max-width: 1020px) {
  .tvbl__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tvbl__grid--home > :nth-child(3) { display: none; }
}
@container tvx (max-width: 900px) {
  .tvbl__card--feature { grid-template-columns: minmax(0, 1fr); }
  .tvbl__card--feature .tvbl__card-img { aspect-ratio: 16 / 9; min-height: 0; }
  .tvbl__glance dl { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@container tvx (max-width: 640px) {
  .tvbl__author { flex-direction: column; gap: 12px; padding: 18px; }
  .tvbl__grid { grid-template-columns: minmax(0, 1fr); }
  .tvbl__grid--home > :nth-child(3) { display: flex; }
  .tvbl__body { font-size: 17px; }
  .tvbl__cover { border-radius: 12px; margin-inline: calc(-1 * clamp(0px, 2cqi, 8px)); }
}

.tvbl .tvx__inner--tight { padding-block: clamp(40px, 5cqi, 64px); }

</style>
<section class="tvx tvbl tvbl--post" aria-label="What customers expect when they order online, and how to deliver it">
  <div class="tvbl__article">
    <div class="tvbl__meta tvbl__meta--top"><a class="tvbl__cat" data-cat="guides" href="https://topvieweg.com/blog/?cat=guides">Guide</a><span>14 October 2026</span><span>1 min read</span><span>By <a class="tvbl__by" href="#tvbl-author">Amr Bendary</a></span></div>
    <p class="tvbl__lede">Customers compare every online order with the best app on their phone. Here are eight things they expect, and what has to work behind the scenes to deliver each one.</p>
    <figure class="tvbl__cover"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-g-expect.jpg" width="1200" height="675" alt="An order tracking card: placed, paid, on the way, delivered" decoding="async"></figure>
    <div class="tvbl__body">
<p>Your customers already use apps that are fast and clear. When they order from you online, they expect the same. Here are eight expectations, and what makes each one possible.</p>

<h2>1. Find it fast</h2>
<p>Clear categories, search, and filters by price or size. The bigger your catalogue, the more this matters.</p>

<h2>2. Know the full price up front</h2>
<p>Prices, delivery fees and offers should be clear before checkout, not a surprise at the end.</p>

<h2>3. Pay their way</h2>
<p>Cards, wallets or cash on delivery. When customers can pay the way that suits them, fewer orders are cancelled.</p>

<h2>4. Get the right order</h2>
<p>This depends on what happens after the click. When the store is connected to the branch’s POS or ERP, prices and stock are correct and nobody types the order twice.</p>

<h2>5. Know where the order is</h2>
<p>A status for every step, the expected delivery time, and a notification when something changes. Customers who can see their order call less.</p>

<h2>6. Order again in seconds</h2>
<p>Saved addresses and past orders ready to repeat turn a good first order into a habit.</p>

<h2>7. Reach someone when something goes wrong</h2>
<p>Easy customer service from inside the app or website, so a problem is solved quickly instead of turning into a bad review.</p>

<h2>8. A reason to come back</h2>
<p>Points on every purchase, rewards and offers made for them. Small rewards add up to loyal customers.</p>

<h2>Behind the scenes</h2>
<p>Most of these expectations are not about design; they are about connected systems: payment, delivery zones, the branch screen, ERP and POS, and a dashboard that shows what is happening. That is why we build the app, the website and the operation together.</p>
<p class="tvbl__note">See it in a real grocery operation: <a href="https://topvieweg.com/zahran-market-apps-case-study/">Zahran Market’s shopping and picking apps</a>.</p>
    </div>
    <aside class="tvbl__author" id="tvbl-author" aria-labelledby="tvbl-author-name">
      <span class="tvbl__author-mark" aria-hidden="true">AB</span>
      <div>
        <p class="tvbl__author-kicker">About the author</p>
        <p class="tvbl__author-name" id="tvbl-author-name">Amr Bendary</p>
        <p class="tvbl__author-role">Founder, Top View · CTO, Etoile</p>
        <p class="tvbl__author-bio">Founder of Top View and CTO at Etoile, Amr Bendary brings over 20 years of experience in digital transformation, mobile apps, e-commerce, and ERP integration. He holds an MBA in Digital Transformation and helps businesses connect technology with growth and operational efficiency.</p>
      </div>
    </aside>
    <div class="tvbl__share"><span>Share</span>
      <a class="tvbl__sh" href="https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Ftopvieweg.com%2Fwhat-customers-expect-online%2F" target="_blank" rel="noopener" aria-label="Share on LinkedIn"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M6.94 8.5H3.56V20h3.38V8.5ZM5.25 3a1.96 1.96 0 1 0 0 3.92 1.96 1.96 0 0 0 0-3.92ZM20.44 13.4c0-3.1-1.65-4.55-3.86-4.55-1.78 0-2.58.98-3.02 1.67V8.5h-3.38c.04.95 0 11.5 0 11.5h3.38v-6.42c0-.34.02-.69.13-.93.27-.69.9-1.4 1.95-1.4 1.38 0 1.93 1.05 1.93 2.59V20h3.37v-6.6Z"/></svg></a>
      <a class="tvbl__sh" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Ftopvieweg.com%2Fwhat-customers-expect-online%2F" target="_blank" rel="noopener" aria-label="Share on Facebook"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M13.5 21v-7.5h2.53l.38-2.93H13.5V8.7c0-.85.24-1.43 1.45-1.43h1.55V4.65a20.8 20.8 0 0 0-2.26-.12c-2.24 0-3.77 1.37-3.77 3.88v2.16H7.94v2.93h2.53V21h3.03Z"/></svg></a>
      <a class="tvbl__sh" href="https://wa.me/?text=What%20customers%20expect%20when%20they%20order%20online%2C%20and%20how%20to%20deliver%20it%20https%3A%2F%2Ftopvieweg.com%2Fwhat-customers-expect-online%2F" target="_blank" rel="noopener" aria-label="Share on WhatsApp"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M17.47 14.38c-.3-.15-1.76-.87-2.03-.97-.27-.1-.47-.15-.67.15-.2.3-.77.97-.94 1.16-.17.2-.35.22-.64.07-.3-.15-1.26-.46-2.39-1.47-.88-.79-1.48-1.76-1.65-2.06-.17-.3-.02-.46.13-.61.13-.13.3-.35.45-.52.15-.17.2-.3.3-.5.1-.2.05-.37-.03-.52-.07-.15-.67-1.61-.92-2.21-.24-.58-.49-.5-.67-.51h-.57c-.2 0-.52.07-.79.37-.27.3-1.04 1.02-1.04 2.48 0 1.46 1.07 2.88 1.21 3.07.15.2 2.1 3.2 5.08 4.49.71.31 1.26.49 1.69.63.71.23 1.36.2 1.87.12.57-.09 1.76-.72 2-1.41.25-.7.25-1.29.18-1.41-.08-.13-.27-.2-.57-.35ZM12.05 21.79h-.01a9.87 9.87 0 0 1-5.03-1.38l-.36-.21-3.74.98 1-3.65-.24-.37a9.86 9.86 0 0 1-1.51-5.26c0-5.45 4.44-9.88 9.89-9.88a9.83 9.83 0 0 1 9.88 9.89c0 5.45-4.44 9.88-9.88 9.88Zm8.41-18.3A11.82 11.82 0 0 0 12.05 0C5.5 0 .16 5.34.16 11.89c0 2.1.55 4.14 1.59 5.95L.06 24l6.3-1.65a11.88 11.88 0 0 0 5.68 1.45h.01c6.55 0 11.89-5.34 11.89-11.89 0-3.18-1.24-6.17-3.48-8.42Z"/></svg></a>
      <a class="tvbl__sh" href="https://topvieweg.com/what-customers-expect-online/" data-copy aria-label="Copy link"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1"/><path d="M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1"/></svg></a><span class="tvbl__copied" aria-live="polite">Link copied</span>
    </div>
  </div>
  <div class="tvbl__band">
    <div class="tvx__inner tvx__inner--tight">
      <div class="tvx__cta" data-reveal>
        <div class="tvx__cta-text"><h3 class="tvx__cta-title">Planning something similar?</h3><p class="tvx__cta-body">Book a free meeting with our team. We will review how your branches work and suggest the right setup.</p></div>
        <div class="tvx__cta-actions">
          <a class="tvx__btn tvx__btn--primary" href="https://topvieweg.com/contact/" data-tvx="consultation" data-where="blog_what-customers-expect-online">Get a Free Consultation <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          <a class="tvx__btn tvx__btn--ghost" href="https://wa.me/201114000096?text=Hello%20TopView%2C%20I'm%20contacting%20you%20from%20your%20website%20(News%20article).%20I'd%20like%20to%20discuss%20a%20project." target="_blank" rel="noopener" data-tvx="whatsapp"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M17.47 14.38c-.3-.15-1.76-.87-2.03-.97-.27-.1-.47-.15-.67.15-.2.3-.77.97-.94 1.16-.17.2-.35.22-.64.07-.3-.15-1.26-.46-2.39-1.47-.88-.79-1.48-1.76-1.65-2.06-.17-.3-.02-.46.13-.61.13-.13.3-.35.45-.52.15-.17.2-.3.3-.5.1-.2.05-.37-.03-.52-.07-.15-.67-1.61-.92-2.21-.24-.58-.49-.5-.67-.51h-.57c-.2 0-.52.07-.79.37-.27.3-1.04 1.02-1.04 2.48 0 1.46 1.07 2.88 1.21 3.07.15.2 2.1 3.2 5.08 4.49.71.31 1.26.49 1.69.63.71.23 1.36.2 1.87.12.57-.09 1.76-.72 2-1.41.25-.7.25-1.29.18-1.41-.08-.13-.27-.2-.57-.35ZM12.05 21.79h-.01a9.87 9.87 0 0 1-5.03-1.38l-.36-.21-3.74.98 1-3.65-.24-.37a9.86 9.86 0 0 1-1.51-5.26c0-5.45 4.44-9.88 9.89-9.88a9.83 9.83 0 0 1 9.88 9.89c0 5.45-4.44 9.88-9.88 9.88Zm8.41-18.3A11.82 11.82 0 0 0 12.05 0C5.5 0 .16 5.34.16 11.89c0 2.1.55 4.14 1.59 5.95L.06 24l6.3-1.65a11.88 11.88 0 0 0 5.68 1.45h.01c6.55 0 11.89-5.34 11.89-11.89 0-3.18-1.24-6.17-3.48-8.42Z"/></svg> Chat on WhatsApp</a>
        </div>
      </div>
    </div>
  </div>
  <div class="tvbl__band tvbl__band--mist">
    <div class="tvx__inner">
      <div class="tvbl__head" data-reveal><h2 class="tvx__title">More articles</h2></div>
      <div class="tvbl__grid" data-tvbl-feed data-count="3" data-exclude="2007" data-reveal>
        <article class="tvbl__card" data-id="5571" data-cat="insights">
          <a class="tvbl__card-img" href="https://topvieweg.com/own-app-vs-delivery-apps/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-own-app.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="insights">Insight</span><span>14 Oct 2026</span><span>3 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/own-app-vs-delivery-apps/">Your own app or delivery apps? What changes for a multi-branch brand</a></h3>
            <p class="tvbl__card-ex">Delivery apps bring orders, but they keep the customer and take a share of every sale. Here is what changes when a multi-branch brand runs its own app and online store, and how to start without losing the orders you already have.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
        <article class="tvbl__card" data-id="5575" data-cat="guides">
          <a class="tvbl__card-img" href="https://topvieweg.com/what-is-ecommerce/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-g-what.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="guides">Guide</span><span>14 Oct 2026</span><span>2 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/what-is-ecommerce/">What is e-commerce? A plain guide for business owners</a></h3>
            <p class="tvbl__card-ex">E-commerce is more than a website with a cart. Here is what it really means for a restaurant, shop or brand, the channels it covers, and the parts that have to work together behind every online order.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
        <article class="tvbl__card" data-id="5572" data-cat="case-studies">
          <a class="tvbl__card-img" href="https://topvieweg.com/etoile-egypt-app-case-study/" tabindex="-1" aria-hidden="true"><img loading="lazy" src="https://topvieweg.com/wp-content/uploads/2026/10/topview-cover-etoile.jpg" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>
          <div class="tvbl__card-body">
            <div class="tvbl__meta"><span class="tvbl__cat" data-cat="case-studies">Case study</span><span>14 Oct 2026</span><span>2 min read</span></div>
            <h3 class="tvbl__card-title"><a href="https://topvieweg.com/etoile-egypt-app-case-study/">How Etoile Egypt went from a call centre to 520,000+ app users</a></h3>
            <p class="tvbl__card-ex">Etoile Egypt moved its online orders from a busy call centre to its own app and website. Today the app has more than 520,000 users and takes thousands of orders a day, connected to the branches, ERP and POS.</p>
            <span class="tvbl__more" aria-hidden="true">Read article <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
          </div>
        </article>
      </div>
      <div class="tvbl__all"><a class="tvx__btn tvx__btn--outline" href="https://topvieweg.com/blog/">View all articles <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a></div>
    </div>
  </div>
</section>
<script>
(function () {
  var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  function fmt(n) { return Math.round(n).toLocaleString('en-US'); }
  function countUp(el) {
    var to = Number(el.getAttribute('data-n'));
    if (reduce || !to) return;
    var dur = 1200, t0 = null;
    el.textContent = fmt(0);
    requestAnimationFrame(function step(t) {
      if (t0 === null) t0 = t;
      var p = Math.min(1, (t - t0) / dur);
      el.textContent = fmt(to * (1 - Math.pow(1 - p, 3)));
      if (p < 1) requestAnimationFrame(step);
    });
    // always land on the real value, even if frames stall
    setTimeout(function () { el.textContent = fmt(to); }, dur + 400);
  }

  function init(root) {
    root.setAttribute('data-ready', '');
    root.classList.add('is-js');

    // scroll reveal (armed only here, so the section is complete without JS)
    var items = [].slice.call(root.querySelectorAll('[data-reveal]'));
    var drawTarget = root.querySelector('[data-draw]');
    if (!reduce && 'IntersectionObserver' in window) {
      root.classList.add('is-armed');
      var io = new IntersectionObserver(function (entries) {
        entries.forEach(function (e) {
          if (!e.isIntersecting) return;
          io.unobserve(e.target);
          if (e.target === drawTarget) {
            root.classList.add('is-drawn');
            [].slice.call(root.querySelectorAll('[data-n]')).forEach(countUp);
          } else {
            e.target.classList.add('is-in');
          }
        });
      }, { threshold: 0.15, rootMargin: '0px 0px -40px 0px' });
      items.forEach(function (el) { io.observe(el); });
      if (drawTarget) io.observe(drawTarget);
      // safety net: never leave content hidden
      setTimeout(function () { items.forEach(function (el) { el.classList.add('is-in'); }); root.classList.add('is-drawn'); }, 4000);
    } else {
      root.classList.add('is-drawn');
    }
    // looping decorations pause while the section is off screen
    if ('IntersectionObserver' in window) {
      new IntersectionObserver(function (entries) { root.classList.toggle('is-off', !entries[entries.length - 1].isIntersecting); }).observe(root);
    }

    // looping motion ([data-loop]) starts when first seen, so it opens on its first scene, and pauses off screen
    [].slice.call(root.querySelectorAll('[data-loop]')).forEach(function (el) {
      if (reduce || !('IntersectionObserver' in window)) return;
      new IntersectionObserver(function (entries) {
        var on = entries[entries.length - 1].isIntersecting; // several entries can queue up during a fast scroll; the last one is current
        if (on) el.classList.add('is-playing');
        el.classList.toggle('is-paused', !on);
      }, { threshold: 0.3 }).observe(el);
    });

    // tabs with a sliding highlight
    var tabs = [].slice.call(root.querySelectorAll('[role="tab"]'));
    if (!tabs.length) return;
    var panels = tabs.map(function (t) { return root.querySelector('#' + t.getAttribute('aria-controls')); });
    var ink = root.querySelector('.tvpf__ink');
    var list = tabs[0].parentNode;
    var current = Math.max(0, tabs.findIndex(function (t) { return t.getAttribute('aria-selected') === 'true'; }));
    function moveInk() {
      if (!ink) return;
      var t = tabs[current];
      ink.style.width = t.offsetWidth + 'px';
      ink.style.transform = 'translateX(' + t.offsetLeft + 'px)';
    }
    function show(n, focus) {
      if (n === current) return;
      current = (n + tabs.length) % tabs.length;
      tabs.forEach(function (t, k) {
        var on = k === current;
        t.classList.toggle('is-active', on);
        t.setAttribute('aria-selected', on ? 'true' : 'false');
        t.tabIndex = on ? 0 : -1;
      });
      panels.forEach(function (p, k) {
        var on = k === current;
        p.hidden = !on;
        p.classList.toggle('is-active', on);
        p.classList.remove('is-entering');
        if (on && !reduce) { void p.offsetWidth; p.classList.add('is-entering'); }
      });
      moveInk();
      var t = tabs[current];
      if (list.scrollWidth > list.clientWidth) list.scrollTo({ left: t.offsetLeft - (list.clientWidth - t.offsetWidth) / 2, behavior: reduce ? 'auto' : 'smooth' });
      if (focus) t.focus();
    }
    tabs.forEach(function (t, k) {
      t.addEventListener('click', function () { show(k); });
      t.addEventListener('keydown', function (e) {
        if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') { e.preventDefault(); show(current + (e.key === 'ArrowRight' ? 1 : -1), true); }
      });
    });
    moveInk();
    if (window.ResizeObserver) new ResizeObserver(moveInk).observe(list);
    window.addEventListener('load', moveInk);
  }

  [].slice.call(document.querySelectorAll('.tvx:not([data-ready])')).forEach(init);

  // calls to action: same tracking as the floating WhatsApp button and the home CTA
  // (each section ships this script, so register the listener only once per page)
  if (window.__tvxCtaTracking) return;
  window.__tvxCtaTracking = true;
  document.addEventListener('click', function (e) {
    var a = e.target.closest && e.target.closest('.tvx a[data-tvx]');
    if (!a) return;
    if (a.getAttribute('data-tvx') === 'whatsapp') {
      if (typeof gtag === 'function') { gtag('event', 'contact', { method: 'WhatsApp', link_url: a.href }); }
      if (typeof fbq === 'function') { fbq('track', 'Contact', { content_name: 'WhatsApp' }); }
      if (typeof window.lintrk === 'function') { window.lintrk('track', { conversion_id: 31200418 }); }
    } else if (typeof gtag === 'function') {
      gtag('event', 'cta_click', { cta: 'free_consultation', location: a.getAttribute('data-where') || 'section' });
    }
  });
})();

(function () {
  if (window.__tvblReady) return;
  window.__tvblReady = true;

  var CAT = { guides: 'Guide', 'case-studies': 'Case study', insights: 'Insight' };
  var arrow = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg>';
  var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

  function text(html, sel) {
    var d = document.createElement('div'); d.innerHTML = html || '';
    [].slice.call(d.querySelectorAll('style,script')).forEach(function (n) { n.remove(); });
    var part = sel && d.querySelector(sel);
    return ((part || d).textContent || '').replace(/\s+/g, ' ').trim();
  }
  function esc(s) { return String(s).replace(/[&<>"]/g, function (c) { return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c]; }); }

  // the same card markup the build script prints, rebuilt from the REST API so new posts show up on their own
  // mins comes from the card the build printed for that post; a post published later shows no reading time
  // p.tv_card = { img, cat, cat_name } is a small REST field added by the "TopView speed & SEO tweaks" snippet
  function card(p, feature, mins) {
    var tc = p.tv_card || {};
    var img = tc.img || '';
    var term = { slug: tc.cat || '', name: tc.cat_name || '' };
    var d = new Date(p.date);
    return '<article class="tvbl__card' + (feature ? ' tvbl__card--feature' : '') + '" data-id="' + p.id + '" data-cat="' + esc(term.slug || '') + '">' +
      (img ? '<a class="tvbl__card-img" href="' + esc(p.link) + '" tabindex="-1" aria-hidden="true"><img loading="lazy" src="' + esc(img) + '" width="1200" height="675" alt="" loading="lazy" decoding="async"></a>' : '') +
      '<div class="tvbl__card-body"><div class="tvbl__meta">' + (term.slug ? '<span class="tvbl__cat" data-cat="' + esc(term.slug) + '">' + esc(CAT[term.slug] || term.name) + '</span>' : '') +
      '<span>' + d.getDate() + ' ' + months[d.getMonth()] + ' ' + d.getFullYear() + '</span>' + (mins ? '<span>' + mins + ' min read</span>' : '') + '</div>' +
      '<h3 class="tvbl__card-title"><a href="' + esc(p.link) + '">' + p.title.rendered + '</a></h3>' +
      '<p class="tvbl__card-ex">' + esc(text(p.excerpt && p.excerpt.rendered)) + '</p>' +
      '<span class="tvbl__more" aria-hidden="true">Read article ' + arrow + '</span></div></article>';
  }

  function applyFilter(root, cat) {
    var cards = [].slice.call(root.querySelectorAll('.tvbl__card'));
    var shown = 0;
    cards.forEach(function (c) { var on = !cat || c.getAttribute('data-cat') === cat; c.hidden = !on; if (on) shown++; });
    [].slice.call(root.querySelectorAll('.tvbl__filter')).forEach(function (b) { b.setAttribute('aria-pressed', String((b.getAttribute('data-cat') || '') === (cat || ''))); });
    var empty = root.querySelector('.tvbl__empty');
    if (empty) empty.hidden = shown > 0;
  }

  function initFilters() {
    [].slice.call(document.querySelectorAll('.tvbl [data-tvbl-filters]')).forEach(function (bar) {
      var root = bar.closest('.tvbl');
      if (bar.getAttribute('data-ready')) { var cur = bar.querySelector('[aria-pressed="true"]'); applyFilter(root, cur ? cur.getAttribute('data-cat') || '' : ''); return; }
      bar.setAttribute('data-ready', '1');
      bar.addEventListener('click', function (e) {
        var b = e.target.closest('.tvbl__filter');
        if (!b) return;
        applyFilter(root, b.getAttribute('data-cat') || '');
      });
      var m = location.search.match(/[?&]cat=([a-z-]+)/);
      applyFilter(root, m ? m[1] : '');
    });
  }

  // copy link
  document.addEventListener('click', function (e) {
    var b = e.target.closest && e.target.closest('.tvbl [data-copy]');
    if (!b) return;
    e.preventDefault();
    var done = function () { var t = b.parentNode.querySelector('.tvbl__copied'); if (t) { t.classList.add('is-on'); setTimeout(function () { t.classList.remove('is-on'); }, 1800); } };
    if (navigator.clipboard) navigator.clipboard.writeText(location.href.split('#')[0]).then(done, function () {}); else done();
  });

  var feeds = [].slice.call(document.querySelectorAll('[data-tvbl-feed]'));
  initFilters();
  if (!feeds.length || !window.fetch) return;

  // Only the fields a card shows (the full post content made this ~600 KB), and only once a feed
  // comes near the screen, so the request never competes with the page's first paint.
  var loaded = false;
  function refresh() {
    if (loaded) return;
    loaded = true;
    var mins = {};
    [].forEach.call(document.querySelectorAll('.tvbl__card[data-id]'), function (c) {
      var m = (c.textContent || '').match(/(\d+) min read/);
      if (m) mins[c.getAttribute('data-id')] = m[1];
    });
    fetch('/wp-json/wp/v2/posts?per_page=12&_fields=id,date,link,title,excerpt,tv_card', { credentials: 'omit' })
      .then(function (r) { return r.ok ? r.json() : Promise.reject(r.status); })
      .then(function (posts) {
        if (!Array.isArray(posts) || !posts.length || !posts[0].tv_card) return; // keep the printed cards if the field is missing
        feeds.forEach(function (feed) {
          var max = Number(feed.getAttribute('data-count')) || posts.length;
          var skip = Number(feed.getAttribute('data-exclude')) || 0;
          var list = posts.filter(function (p) { return p.id !== skip; }).slice(0, max);
          var have = [].map.call(feed.querySelectorAll('.tvbl__card'), function (el) { return el.getAttribute('data-id'); }).join();
          if (have === list.map(function (p) { return String(p.id); }).join()) return; // the printed cards are already current
          var feature = feed.hasAttribute('data-feature');
          feed.innerHTML = list.map(function (p, i) { return card(p, feature && i === 0, mins[p.id]); }).join('');
        });
        initFilters();
      })
      .catch(function () {});
  }
  if ('IntersectionObserver' in window) {
    var io = new IntersectionObserver(function (entries) {
      if (entries.some(function (e) { return e.isIntersecting; })) { io.disconnect(); refresh(); }
    }, { rootMargin: '600px 0px' });
    feeds.forEach(function (f) { io.observe(f); });
  } else {
    window.addEventListener('load', refresh);
  }
})();

</script>
				</div>
				</div>
				</div>
				</div>
		<p>The post <a href="https://topvieweg.com/what-customers-expect-online/">What customers expect when they order online, and how to deliver it</a> appeared first on <a href="https://topvieweg.com">TopView</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
