Apple put the Singapore store behind a cover page for the iPhone 18 Pro pre-order, and for a while the whole thing was one blue rectangle. An Apple logo glowing like a sun in a clear sky, and four words underneath it: Be right back.
It is a beautiful page. It is also a piece of stagecraft, and once you see the rigging you cannot unsee it.
I pressed Cmd-A.
The sky has a seam
Select all on that page and the sky breaks. A selection rectangle snaps around a box in the middle of the screen — not around the whole background, just a box. The landscape you thought you were looking at is a file called aos_covers_image.jpg, and it is exactly 1200 by 1200 pixels. A square. Everything outside that square is not a photograph at all. It is one line of CSS.
Here is the whole trick:
.rs-covers-preorder { background-color: #5c8dc7; min-height: 100vh }
.rs-covers-preorder:has(.rs-covers-media-image) .rs-covers-media-wrapper {
width: min(90vw, 60vh, 680px);
margin-inline: auto;
height: auto;
}
The page background is #5c8dc7. I sampled every pixel around the perimeter of that JPEG — all 4,800 of them. Not "close to" #5c8dc7: 4,728 are that value exactly, and the remaining 72 are off by at most 2 out of 255, which is ordinary JPEG ringing and invisible to anything with eyes. Walking inward from the left edge at mid-height, the colour does not change at all for the first 19 pixels.
So it is a square of sky, dropped onto an infinite field of identical sky. No blend mode, no gradient mask, no feathered edge, no clever compositing. The seam is invisible because arithmetically there is no seam. Two numbers agree, and your brain fills in a photograph that was never taken.
Then they cheat once more. The headline is pulled up into the image:
.rs-covers-preorder:has(.rs-covers-media-image) .rs-covers-content-container {
margin-top: -80px; /* -56px and -24px at narrower breakpoints */
}
"Be right back." sits over the bottom of the square. The one place your eye might go hunting for an edge is occupied by text.
One more thing hiding in that CSS: :has(). Apple is branching the entire cover layout on whether this campaign shipped a still image or a video, in CSS, with no class toggling from JavaScript at all. That is a relational selector doing load-bearing work in production.
The 503 that is not an error
Fetch the page from a terminal and the first surprise is the status line:
HTTP/2 503
server: Apple
content-type: text/html;charset=utf-8
cache-control: private, no-cache, no-store, must-revalidate, proxy-revalidate
503 Service Unavailable, with a complete page in the body and no Retry-After header. That omission is deliberate. A Retry-After is a promise made in a header, where every proxy and crawler between Cupertino and you can read it, act on it, and hold Apple to it. Instead the retry interval ships inside the document, in a bootstrap object in the head:
data = {
"disableVideo" : "true",
"cv" : "preorder",
"version" : "2",
"refreshInterval" : "65000",
"shldUrl" : "",
"cctx" : "full"
};
Six fields. That is the entire waiting room protocol.
The cache headers are the other half of the design. Nothing about this page may be stored anywhere, by anyone, ever. Every poll from every waiting browser goes all the way to origin. When you are deliberately holding a few million people on a page, the page has to be worthless to cache — otherwise half your audience would sit staring at a CDN copy of a door that opened ten minutes ago.
cv and cctx
cv is the cover variant. cctx is the cover context. Both are enumerated in the bundle:
W = { dfull: "default_full", dpartial: "default_partial",
afull: "announce_full", apartial: "announce_partial",
pfull: "preorder_full", ppartial: "preorder_partial" }
Z = "live" // cctx
G = "partial" // cctx
$ = "full" // cctx
K = "default" // cv
J = "announce" // cv
Y = "preorder" // cv
Three campaigns crossed with three gate states. full means the door is shut. partial means the door is open a crack and people are being let through. live means you are inside. What I captured was preorder and full: pre-order campaign, store completely closed. Every /shop/goto/ deep link I tried answered 503, and so did the shopping bag. The browse page for the phone itself stayed up. They covered the checkout, not the catalogue.
A 65-second heartbeat
No WebSocket. No Server-Sent Events. No long poll. A setInterval:
const g = parseInt(o.refreshInterval, 10) || 0; // 65000
const v = setInterval(() => { ba() }, g);
ba() re-fetches the page's own URL with one extra query parameter — the bundle calls it ajaxUrlParams: { qbaaropc: 1 } — and races the fetch against a 30-second abort. The same URL that served HTML to your browser answers the poll with JSON:
$ curl -sSL 'https://www.apple.com/sg/shop/goto/buy_iphone/iphone_18_pro?qbaaropc=1'
{ "disableVideo" : "true", "cv" : "preorder",
"version" : "2", "cctx" : "full",
"refreshInterval" : "65000", "shldUrl" : "" }
Content type application/json, status still 503. One URL, content-negotiated by query string: a page for eyes, a state object for the loop.
The five-second gap
There is a hop before that JSON. The first request to ?qbaaropc=1 does not answer at all. It returns a 302 redirect to itself, and plants a cookie on the way out:
HTTP/2 302
location: /sg/shop/goto/buy_iphone/iphone_18_pro?qbaaropc=1
set-cookie: aos_baaropc=1VixnV1I87ljba3noB3_BkgjaVp-jP; Max-Age=60; Secure; HttpOnly
Follow the redirect, get the JSON. A client that does not follow redirects or does not keep cookies simply never receives an answer, which filters out the laziest tier of scraper before a single byte of state is spent on it.
Now put the two numbers side by side. The cookie lives 60 seconds. The client polls every 65. The token you were just handed is dead five seconds before you are permitted to ask again.
That gap is the point. A well-behaved client always comes back with an expired token. A client that comes back early arrives holding one that is still valid — and that is trivially detectable at the edge, with no counters, no Redis, no per-visitor state anywhere. A rate limiter made out of nothing but a cookie lifetime and a redirect.
How the doors open
The release logic is one line, and minification has not hidden it well:
(n = u).cctx !== Z && t.version === n.version
|| (xl("coversmode"), window.location.reload(!0))
In words: if the new payload is not live and the version still matches what you were holding, keep waiting. Otherwise drop the stored mode and hard-reload the page.
So there are two levers. Flip cctx to live and everyone holding that page walks in on their next heartbeat. Or bump version — it is "2" today — and every client reloads, which is how you push new copy, new artwork or a new build to a few million people who are all parked on a stale document. Apple can redecorate the waiting room without anybody having to leave it.
The message ladder
This is my favourite part, because it is the part that is purely about feelings. All of the strings sit in the bundle in plain text:
full_heading: "Be right back."
partial_heading: "Almost there."
msg1_heading: "It's a bit crowded right now."
msg2_heading: "Magic is just moments away."
msg3_heading: "Ready...set..."
msgA_heading: "This is taking longer than expected."
msg4_heading: "Message 4 heading."
msg5_heading: "Message 5 heading."
msgB_heading: "Message B heading."
Read the render branch and something clicks: the msg strings are only reachable in partial mode. While the store is fully closed you get one flat, honest line — "Be right back. We're making updates to the Apple Store. Check back soon." No progress bar, no queue position, no countdown, because at that moment there is nothing true to say and Apple declines to invent something.
The instant the door cracks open, the page starts talking to you. "It's a bit crowded right now. Please stay on this page until we can bring you into the store. Thanks." Then "Magic is just moments away. The wait is almost over." Then "Ready...set..." — an unfinished sentence, and a genuinely good piece of writing. It implies the word "go" without ever promising it.
And when it all goes wrong there is the apology track: "This is taking longer than expected. Sorry about that. For now, you can try the Apple Store app on iPhone and iPad to visit the store." A real apology, and a fallback route into an entirely different capacity pool.
Which message you see is not decided by a timer in your browser. The payload carries a msg field and the server chooses. The escalation is centrally conducted, so the emotional temperature of a million tabs can be raised or lowered from one place.
One more detail I enjoy more than I should: msg_4, msg_5 and msg_B still read "Message 4 heading." They shipped the slots to production without writing the words. Somebody wanted room to improvise on launch day.
as_abacus, or: your CPU pays rent
Buried in the poll handler is the thing I did not expect to find:
if (u.challenge && !document.cookie.includes("as_abacus")) {
const { complexity, iterations } = u.challenge;
const start = performance.now();
const input = response.headers.get("aos-covers-input");
const answer = await Al(input, complexity, iterations);
document.cookie = `as_abacus=${JSON.stringify({
answer, durationMS: performance.now() - start
})}; domain=.apple.com; SameSite=None; Secure; max-age=86400`;
}
Al is a proof of work. It SHA-256 hashes a seed the server sends down in a response header, treats the 32-byte digest as a counter, and grinds:
hash the counter
if the digest starts with `complexity` zero bits, keep that counter value
stop once you have collected `iterations` winners
otherwise increment the counter and go again
Hashcash, in crypto.subtle, with both the difficulty and the number of required answers set by the server per request — and the seed delivered in a header, so nothing can be precomputed. The answer is cached in a cookie for 24 hours, which means a real person pays once a day and never notices. A bot farm pays per identity, per day, in CPU that cannot be faked or borrowed.
And it reports durationMS: how long your machine took. You do not need that number to check the answer. You need it to know what kind of machine is answering.
They named the cookie as_abacus. Someone enjoyed themselves.
The shield
There is one more layer, and it is the most operationally interesting. If the payload carries a shldUrl, the client injects it:
const e = document.createElement("script");
e.setAttribute("src", shldUrl);
e.setAttribute("type", "module");
e.setAttribute("crossorigin", "anonymous");
e.id = "shldVerify";
document.head.appendChild(e);
Then the heartbeat is held hostage behind it. The page waits for a shld_bt_ck cookie to appear, retrying ten times at 100 ms intervals, and listens for a shldDone event. If the shield reports back with the id shld-no-ck, the page waits 500 ms and re-runs the whole shield.
Read that as an architecture and it is rather elegant: the bot-detection module is named by the server, at runtime, per response. It can be swapped, hardened or retargeted in the middle of an incident without shipping a build, and until it is satisfied nobody's poll goes through. When I looked, shldUrl was empty — which tells you it is armed on demand rather than always on.
What is worth stealing
The invisible seam. You do not need a mask or a gradient to make an image dissolve into a page. You need the image's edge pixels and the page background colour to be the same number. That is the entire technique. It costs nothing, survives every viewport, and works in a browser from 2011.
Six fields of JSON. The whole waiting room is a polled document with six keys. No socket to keep alive, no per-waiter connection state, and it sails through every corporate proxy on earth.
Version as the release signal. One integer that means "everybody reload, now". It is the cheapest push channel in existence when your clients are already polling.
A rate limiter made of a cookie. Sixty-second cookie, sixty-five-second poll. The gap is the enforcement.
Cost instead of a CAPTCHA. Nobody was asked to identify a bicycle. The machine quietly paid, once, for the day.
And one thing not worth stealing. Every cover mode shares a single alt-text string: "Apple logo, transparent and outlined with a glowing neon effect in blue, green, yellow, orange and pink hues". That describes the old rainbow-outline cover, a 520 by 632 image on black. It does not describe the blue sun that was actually on the screen. If you could not see the page, the page told you about a different page.
See it for yourself
# the cover, with headers
curl -sS -D - 'https://www.apple.com/sg/shop/goto/buy_iphone/iphone_18_pro' | head -40
# the heartbeat the page polls every 65 seconds
curl -sSL 'https://www.apple.com/sg/shop/goto/buy_iphone/iphone_18_pro?qbaaropc=1'
# the sun
curl -sS -o cover.jpg \
https://store.storeimages.cdn-apple.com/2/store.apple.com/shop/rs-covers/2/dist/images/aos_covers_image.jpg
Open that last file and look at the corners. It is the same blue as the sky, because it is the sky, because there was never a sky at all. Just one square, and a background colour that agreed with it.
Quantum Responses