<div class="knobs">
<select name="hue" id="hue">
<option>green</option>
<option>lime</option>
<option>yellow</option>
<option>orange</option>
<option>red</option>
<option>pink</option>
<option>purple</option>
<option>violet</option>
<option>indigo</option>
<option>blue</option>
<option>cyan</option>
<option>teal</option>
</select>
<input id="chroma" type="range" min="0" max=".15" step="0.01" value="0.05">
</div>
<div class="android-homescreen snap-x">
<section class="news">
<header>
<h2>News</h2>
</header>
<div class="card-list">
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
</div>
</section>
<main>
<div class="status-bar"></div>
<div class="snap-x">
<section>
<div class="datetime-widget">
<time>7:20</time>
<date>Monday, Sept 12</date>
</div>
</section>
<section>
<nav class="app-grid">
<div class="app"></div>
<div class="app"></div>
<div class="app"></div>
<div class="app"></div>
<div class="app"></div>
</nav>
</section>
<section>
<nav class="app-grid" style="align-content: start">
<div class="app"></div>
<div class="app"></div>
<div class="app"></div>
<div class="app"></div>
<div class="app"></div>
<div class="app"></div>
<div class="app"></div>
<div class="app"></div>
<div class="app"></div>
<div class="app"></div>
<div class="app"></div>
<div class="app"></div>
<div class="app"></div>
<div class="app"></div>
<div class="app"></div>
</nav>
</section>
</div>
<footer>
<nav>
<div class="app"></div>
<div class="app"></div>
<div class="app"></div>
<div class="app"></div>
<div class="app"></div>
</nav>
<input type="search" placeholder="Ask Google..">
</footer>
</main>
</div>
@use postcss-nested;
@import "https://unpkg.com/open-props" layer(base);
@import "https://unpkg.com/open-props/normalize.min.css" layer(base);
@import "https://unpkg.com/open-props/oklch-hues.min.css" layer(base);
@import "https://unpkg.com/open-props/gray-oklch.min.css" layer(base);
/* these will be overwritten by the HTML controls and JS */
* {
--gray-hue: var(--hue-green);
--gray-chroma: .05;
/* bring the color to focus and stuff */
accent-color: var(--surface-4);
outline-color: var(--surface-4);
}
/* this maps the 12 stable Open Props normalize adaptive vars to use the extended 15 vars from this okLCH beta pack */
html {
--surface-1: var(--gray-14);
--surface-2: var(--gray-12);
--surface-3: var(--gray-10);
--surface-4: var(--gray-9);
--text-1: var(--gray-1);
--text-2: var(--gray-3);
}
@media (prefers-color-scheme: light) {
html {
--surface-1: var(--gray-0);
--surface-2: var(--gray-1);
--surface-3: var(--gray-2);
--surface-4: var(--gray-3);
--text-1: var(--gray-14);
--text-2: var(--gray-11);
}
}
@layer android-homescreen {
.snap-x {
display: flex;
flex-wrap: nowrap;
overflow-x: auto;
scroll-snap-type: x mandatory;
}
.android-homescreen {
scrollbar-width: none;
overscroll-behavior-x: contain;
&::-webkit-scrollbar {
display: none;
}
}
.android-homescreen,
.android-homescreen :is(section, main) {
scroll-snap-align: center;
flex-shrink: 0;
inline-size: 100%;
block-size: 100%;
}
main {
scroll-snap-stop: always;
}
.android-homescreen > section {
animation: scroll-start 2ms;
}
.knobs {
position: fixed;
inset-block-start: var(--size-3);
inset-inline-end: var(--size-3);
display: grid;
gap: var(--size-3);
}
}
@keyframes scroll-start {
from {
scroll-snap-align: unset;
}
to {
scroll-snap-align: center;
}
}
@layer support {
body {
display: flex;
align-items: center;
justify-content: center;
}
.android-homescreen {
background: var(--surface-2);
border: var(--border-size-3) solid black;
aspect-ratio: 9/16;
inline-size: auto;
max-inline-size: 95vw;
max-block-size: 80vh;
box-shadow: var(--shadow-6);
border-radius: var(--radius-4);
}
.android-homescreen > section {
background: var(--surface-1);
}
.status-bar {
block-size: var(--size-5);
background: var(--surface-3);
}
main {
display: grid;
grid-template-rows: auto 1fr auto;
}
nav {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: var(--size-3);
padding-inline: var(--size-3);
padding-block: var(--size-3);
}
section {
display: grid;
}
.app-grid {
align-content: end;
}
.app {
aspect-ratio: 1;
border-radius: var(--radius-round);
background: var(--surface-4);
}
footer {
position: relative;
display: grid;
}
footer::after {
content: "";
background: black;
height: 3px;
border-radius: 3px;
position: absolute;
inset-block-end: 3px;
inline-size: 30%;
inset-inline-start: 35%;
}
input[type="search"] {
margin: var(--size-3);
background: var(--surface-4);
border-radius: var(--radius-round);
justify-self: stretch;
}
input[type="search"]::placeholder {
color: var(--text-2);
}
.news {
overflow-y: auto;
}
.news > header {
padding: var(--size-3);
}
.card-list {
display: grid;
gap: 1px;
grid-auto-rows: var(--size-content-1);
}
.card {
background: var(--surface-3);
}
.card-list > .card:first-child {
border-radius: var(--radius-4) var(--radius-4) 0 0;
}
.datetime-widget {
display: grid;
align-content: start;
padding: var(--size-3);
}
.datetime-widget > time {
font-size: var(--font-size-6);
font-weight: var(--font-weight-1);
line-height: var(--font-lineheight-00);
}
.datetime-widget > date {
font-size: var(--font-size-0);
}
}
View Compiled
const state = {
hue: 'green',
chroma: 0.05,
}
hue.oninput = e => {
state.hue = e.target.value
update()
}
chroma.oninput = e => {
state.chroma = parseFloat(e.target.value)
update()
}
function update() {
sheet.replaceSync(`* {
--gray-hue: var(--hue-${state.hue});
--gray-chroma: ${state.chroma};
}`, 0)
}
const sheet = new CSSStyleSheet()
document.adoptedStyleSheets = [document.adoptedStyleSheets, sheet]
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.