176 lines
5.6 KiB
HTML
176 lines
5.6 KiB
HTML
|
|
<!doctype html>
|
|||
|
|
<!--
|
|||
|
|
Shared frame: iPhone 15 Pro (390 × 844).
|
|||
|
|
Usage: <iframe src="iphone-15-pro.html?screen=path/to/screen.html"></iframe>
|
|||
|
|
Renders: the bezel + Dynamic Island + status bar + home indicator,
|
|||
|
|
with the ?screen content embedded as an iframe in the screen area.
|
|||
|
|
-->
|
|||
|
|
<html lang="en">
|
|||
|
|
<head>
|
|||
|
|
<meta charset="utf-8" />
|
|||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|||
|
|
<title>iPhone 15 Pro frame</title>
|
|||
|
|
<style>
|
|||
|
|
*, *::before, *::after { box-sizing: border-box; }
|
|||
|
|
html, body { margin: 0; padding: 0; height: 100%; background: transparent; }
|
|||
|
|
body {
|
|||
|
|
display: grid;
|
|||
|
|
place-items: center;
|
|||
|
|
font: 15px/1.4 -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
|
|||
|
|
color: #1a1916;
|
|||
|
|
-webkit-font-smoothing: antialiased;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.device {
|
|||
|
|
position: relative;
|
|||
|
|
width: 390px;
|
|||
|
|
height: 844px;
|
|||
|
|
border-radius: 56px;
|
|||
|
|
padding: 12px;
|
|||
|
|
background:
|
|||
|
|
linear-gradient(160deg, #2a2a2c 0%, #1a1a1c 50%, #0e0e10 100%);
|
|||
|
|
box-shadow:
|
|||
|
|
0 0 0 1px rgba(255,255,255,0.04) inset,
|
|||
|
|
0 0 0 2px #000 inset,
|
|||
|
|
0 28px 60px -12px rgba(0,0,0,0.45),
|
|||
|
|
0 8px 20px -8px rgba(0,0,0,0.35);
|
|||
|
|
isolation: isolate;
|
|||
|
|
}
|
|||
|
|
.device::before, .device::after {
|
|||
|
|
content: '';
|
|||
|
|
position: absolute;
|
|||
|
|
width: 3px;
|
|||
|
|
background: linear-gradient(to bottom, transparent 0%, rgba(255,255,255,0.06) 8%, transparent 16%, transparent 84%, rgba(255,255,255,0.04) 92%, transparent 100%);
|
|||
|
|
top: 100px;
|
|||
|
|
bottom: 100px;
|
|||
|
|
pointer-events: none;
|
|||
|
|
}
|
|||
|
|
.device::before { left: -1px; }
|
|||
|
|
.device::after { right: -1px; }
|
|||
|
|
|
|||
|
|
.island {
|
|||
|
|
position: absolute;
|
|||
|
|
top: 22px;
|
|||
|
|
left: 50%;
|
|||
|
|
transform: translateX(-50%);
|
|||
|
|
width: 124px;
|
|||
|
|
height: 36px;
|
|||
|
|
background: #000;
|
|||
|
|
border-radius: 999px;
|
|||
|
|
z-index: 5;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.btn-rail {
|
|||
|
|
position: absolute;
|
|||
|
|
width: 4px;
|
|||
|
|
background: #0a0a0c;
|
|||
|
|
border-radius: 2px;
|
|||
|
|
}
|
|||
|
|
.btn-rail.left-1 { left: -3px; top: 174px; height: 32px; }
|
|||
|
|
.btn-rail.left-2 { left: -3px; top: 220px; height: 60px; }
|
|||
|
|
.btn-rail.left-3 { left: -3px; top: 290px; height: 60px; }
|
|||
|
|
.btn-rail.right-1 { right: -3px; top: 250px; height: 100px; }
|
|||
|
|
|
|||
|
|
.screen {
|
|||
|
|
position: relative;
|
|||
|
|
width: 100%; height: 100%;
|
|||
|
|
background: #fafaf7;
|
|||
|
|
border-radius: 44px;
|
|||
|
|
overflow: hidden;
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.statusbar {
|
|||
|
|
flex: 0 0 47px;
|
|||
|
|
padding: 18px 26px 0;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: flex-start;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
font-size: 15px;
|
|||
|
|
font-weight: 600;
|
|||
|
|
letter-spacing: -0.01em;
|
|||
|
|
color: var(--statusbar-fg, #1a1916);
|
|||
|
|
pointer-events: none;
|
|||
|
|
}
|
|||
|
|
.statusbar .right { display: inline-flex; align-items: center; gap: 6px; }
|
|||
|
|
.statusbar svg { width: 17px; height: 11px; fill: currentColor; }
|
|||
|
|
.statusbar .battery { width: 25px; }
|
|||
|
|
|
|||
|
|
.inner {
|
|||
|
|
flex: 1 1 auto;
|
|||
|
|
width: 100%;
|
|||
|
|
border: 0;
|
|||
|
|
background: #fafaf7;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.home-indicator {
|
|||
|
|
flex: 0 0 28px;
|
|||
|
|
position: relative;
|
|||
|
|
pointer-events: none;
|
|||
|
|
}
|
|||
|
|
.home-indicator::after {
|
|||
|
|
content: '';
|
|||
|
|
position: absolute;
|
|||
|
|
left: 50%; bottom: 8px;
|
|||
|
|
transform: translateX(-50%);
|
|||
|
|
width: 134px; height: 5px;
|
|||
|
|
background: var(--home-fg, #1a1916);
|
|||
|
|
border-radius: 999px;
|
|||
|
|
opacity: 0.85;
|
|||
|
|
}
|
|||
|
|
</style>
|
|||
|
|
</head>
|
|||
|
|
<body>
|
|||
|
|
<div class="device">
|
|||
|
|
<span class="btn-rail left-1" aria-hidden></span>
|
|||
|
|
<span class="btn-rail left-2" aria-hidden></span>
|
|||
|
|
<span class="btn-rail left-3" aria-hidden></span>
|
|||
|
|
<span class="btn-rail right-1" aria-hidden></span>
|
|||
|
|
<span class="island" aria-hidden></span>
|
|||
|
|
|
|||
|
|
<div class="screen">
|
|||
|
|
<div class="statusbar">
|
|||
|
|
<span>9:41</span>
|
|||
|
|
<span class="right">
|
|||
|
|
<svg viewBox="0 0 17 11" aria-hidden>
|
|||
|
|
<rect x="0" y="7" width="3" height="4" rx="0.6"/>
|
|||
|
|
<rect x="4" y="5" width="3" height="6" rx="0.6"/>
|
|||
|
|
<rect x="8" y="3" width="3" height="8" rx="0.6"/>
|
|||
|
|
<rect x="12" y="0" width="3" height="11" rx="0.6"/>
|
|||
|
|
</svg>
|
|||
|
|
<svg viewBox="0 0 17 11" aria-hidden>
|
|||
|
|
<path d="M8.5 1.5C5.5 1.5 2.7 2.6 0.5 4.6L2 6.1C3.8 4.5 6.1 3.6 8.5 3.6c2.4 0 4.7 0.9 6.5 2.5l1.5-1.5c-2.2-2-5-3.1-8-3.1zM3.5 7.6L5 9.1c1-0.9 2.2-1.4 3.5-1.4 1.3 0 2.5 0.5 3.5 1.4l1.5-1.5c-1.4-1.3-3.1-2-5-2-1.9 0-3.6 0.7-5 2zM6.5 10.6l2 2 2-2c-0.5-0.5-1.2-0.8-2-0.8s-1.5 0.3-2 0.8z"/>
|
|||
|
|
</svg>
|
|||
|
|
<svg class="battery" viewBox="0 0 25 11" aria-hidden>
|
|||
|
|
<rect x="0.5" y="0.5" width="21" height="10" rx="2.5" fill="none" stroke="currentColor" stroke-opacity="0.45"/>
|
|||
|
|
<rect x="22" y="3.5" width="1.5" height="4" rx="0.4" fill="currentColor" fill-opacity="0.45"/>
|
|||
|
|
<rect x="2" y="2" width="18" height="7" rx="1.4"/>
|
|||
|
|
</svg>
|
|||
|
|
</span>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<iframe
|
|||
|
|
class="inner"
|
|||
|
|
id="screen"
|
|||
|
|
title="Inner screen"
|
|||
|
|
sandbox="allow-scripts allow-same-origin"
|
|||
|
|
loading="lazy"
|
|||
|
|
src="about:blank"
|
|||
|
|
></iframe>
|
|||
|
|
|
|||
|
|
<div class="home-indicator" aria-hidden></div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
(function () {
|
|||
|
|
var qs = new URLSearchParams(location.search);
|
|||
|
|
var src = qs.get('screen');
|
|||
|
|
var iframe = document.getElementById('screen');
|
|||
|
|
if (src) iframe.src = src;
|
|||
|
|
})();
|
|||
|
|
</script>
|
|||
|
|
</body>
|
|||
|
|
</html>
|