228 lines
7.5 KiB
HTML
228 lines
7.5 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<title>Motion</title>
|
|
<link rel="stylesheet" href="../colors_and_type.css" />
|
|
<style>
|
|
:root {
|
|
--ease: cubic-bezier(0.2, 0, 0, 1);
|
|
}
|
|
html, body { margin: 0; background: var(--background); font-family: var(--font-sans); }
|
|
.card { padding: 20px 24px; box-sizing: border-box; display: grid; grid-template-columns: repeat(2, 1fr); grid-auto-rows: 150px; gap: 14px; }
|
|
.tile {
|
|
position: relative;
|
|
background: var(--surface-container);
|
|
border-radius: 12px;
|
|
padding: 14px 16px;
|
|
overflow: hidden;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: space-between;
|
|
}
|
|
.k { font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--on-surface-variant); }
|
|
.v { font-family: var(--font-serif); font-style: italic; color: var(--on-surface); font-size: 13px; }
|
|
.stage {
|
|
flex: 1;
|
|
position: relative;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin: 4px 0;
|
|
}
|
|
.note { font-size: 10px; color: #9a8679; }
|
|
|
|
/* Easing demo — a block slides left→right on loop, one easing only */
|
|
.ease-track {
|
|
position: relative;
|
|
width: 100%;
|
|
height: 2px;
|
|
background: rgba(186,186,176,0.4);
|
|
border-radius: 2px;
|
|
}
|
|
.ease-dot {
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 0;
|
|
width: 12px; height: 12px;
|
|
margin-top: -6px; margin-left: -6px;
|
|
background: #785f53;
|
|
border-radius: 999px;
|
|
animation: easeMove 2.4s var(--ease) infinite;
|
|
}
|
|
@keyframes easeMove {
|
|
0% { left: 0%; }
|
|
45% { left: 100%; }
|
|
55% { left: 100%; }
|
|
100% { left: 0%; }
|
|
}
|
|
|
|
/* Durations — three bars of 140 / 240 / 420 ms */
|
|
.bars { display: flex; flex-direction: column; gap: 8px; width: 100%; }
|
|
.bar { position: relative; height: 6px; border-radius: 3px; background: rgba(186,186,176,0.3); }
|
|
.bar::before {
|
|
content: "";
|
|
position: absolute;
|
|
left: 0; top: 0; bottom: 0;
|
|
border-radius: 3px;
|
|
background: #785f53;
|
|
animation-iteration-count: infinite;
|
|
animation-timing-function: var(--ease);
|
|
}
|
|
.bar-140::before { animation-name: fillOnce; animation-duration: 1.4s; }
|
|
.bar-240::before { animation-name: fillOnce; animation-duration: 1.8s; }
|
|
.bar-420::before { animation-name: fillOnce; animation-duration: 2.4s; }
|
|
@keyframes fillOnce {
|
|
0% { width: 0%; }
|
|
28% { width: 100%; }
|
|
72% { width: 100%; }
|
|
100% { width: 0%; }
|
|
}
|
|
.bar-row { display: flex; align-items: center; gap: 8px; }
|
|
.bar-row .tag { font-size: 10px; color: var(--on-surface-variant); width: 58px; letter-spacing: 0.04em; }
|
|
.bar-row .bar { flex: 1; }
|
|
|
|
/* Entrance — fade + 4px translate up, repeating */
|
|
.entrance {
|
|
display: flex; gap: 10px; align-items: flex-end; justify-content: center;
|
|
}
|
|
.entrance .chip {
|
|
background: #fffcf7;
|
|
border-radius: 8px;
|
|
padding: 10px 12px;
|
|
font-family: var(--font-serif);
|
|
font-size: 12px;
|
|
color: var(--on-surface);
|
|
box-shadow: 0 6px 14px -10px rgba(56,56,49,0.25);
|
|
opacity: 0;
|
|
transform: translateY(4px);
|
|
animation: enter 2.8s var(--ease) infinite;
|
|
}
|
|
.entrance .chip:nth-child(2) { animation-delay: 0.15s; }
|
|
.entrance .chip:nth-child(3) { animation-delay: 0.30s; }
|
|
@keyframes enter {
|
|
0%, 15% { opacity: 0; transform: translateY(4px); }
|
|
35%, 75% { opacity: 1; transform: translateY(0); }
|
|
90%, 100% { opacity: 0; transform: translateY(4px); }
|
|
}
|
|
|
|
/* Press — button dips 1px translateY, no scale */
|
|
.press-btn {
|
|
background: #785f53;
|
|
color: #fffcf7;
|
|
font: 500 13px/1 var(--font-sans);
|
|
border-radius: 10px;
|
|
padding: 11px 18px;
|
|
border: 0;
|
|
animation: press 2s var(--ease) infinite;
|
|
}
|
|
@keyframes press {
|
|
0%, 35% { transform: translateY(0); background: #785f53; }
|
|
45%, 60% { transform: translateY(1px); background: #6b5348; }
|
|
70%, 100% { transform: translateY(0); background: #785f53; }
|
|
}
|
|
|
|
/* Focus ring — 2px secondary @ 40% with 3px offset, appears and fades */
|
|
.focus-stage {
|
|
display: flex; align-items: center; justify-content: center; width: 100%;
|
|
}
|
|
.focus-field {
|
|
background: #e7e1d0;
|
|
border-radius: 10px;
|
|
padding: 10px 14px;
|
|
font-family: var(--font-serif);
|
|
font-size: 13px;
|
|
color: var(--on-surface-variant);
|
|
position: relative;
|
|
animation: focusBlink 3.4s var(--ease) infinite;
|
|
}
|
|
@keyframes focusBlink {
|
|
0%, 40% { box-shadow: 0 0 0 0 rgba(120,95,83,0), 0 0 0 0 rgba(120,95,83,0); }
|
|
50%, 75% { box-shadow: 0 0 0 3px var(--background), 0 0 0 5px rgba(120,95,83,0.4); }
|
|
85%, 100% { box-shadow: 0 0 0 0 rgba(120,95,83,0), 0 0 0 0 rgba(120,95,83,0); }
|
|
}
|
|
|
|
/* Tonal shift — surface tier animates through the scale */
|
|
.tonal-shift {
|
|
width: 72px; height: 52px; border-radius: 10px;
|
|
animation: tonalShift 4s var(--ease) infinite;
|
|
}
|
|
@keyframes tonalShift {
|
|
0%, 100% { background: #fffcf7; }
|
|
25% { background: #faf6ee; }
|
|
50% { background: #efeadc; }
|
|
75% { background: #ddd6c3; }
|
|
}
|
|
|
|
.stat { display: flex; align-items: baseline; gap: 6px; }
|
|
.stat b { font-family: var(--font-serif); font-style: italic; color: var(--on-surface); font-size: 13px; font-weight: 400; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="card">
|
|
|
|
<!-- Easing -->
|
|
<div class="tile">
|
|
<div><div class="k">Standard ease</div><div class="v">cubic-bezier(0.2, 0, 0, 1)</div></div>
|
|
<div class="stage">
|
|
<div class="ease-track"><span class="ease-dot"></span></div>
|
|
</div>
|
|
<div class="note">One curve for the entire system. No bounces, no springs.</div>
|
|
</div>
|
|
|
|
<!-- Durations -->
|
|
<div class="tile">
|
|
<div><div class="k">Durations</div><div class="v">140 · 240 · 420 ms</div></div>
|
|
<div class="stage">
|
|
<div class="bars">
|
|
<div class="bar-row"><span class="tag">140 · micro</span><div class="bar bar-140"></div></div>
|
|
<div class="bar-row"><span class="tag">240 · default</span><div class="bar bar-240"></div></div>
|
|
<div class="bar-row"><span class="tag">420 · layout</span><div class="bar bar-420"></div></div>
|
|
</div>
|
|
</div>
|
|
<div class="note">Fades and tonal shifts only.</div>
|
|
</div>
|
|
|
|
<!-- Entrance -->
|
|
<div class="tile">
|
|
<div><div class="k">Entrance</div><div class="v">Fade + 4px translate-up</div></div>
|
|
<div class="stage">
|
|
<div class="entrance">
|
|
<div class="chip">§ 1</div>
|
|
<div class="chip">§ 2</div>
|
|
<div class="chip">§ 3</div>
|
|
</div>
|
|
</div>
|
|
<div class="note">Staggered. Never scale. Never off-screen.</div>
|
|
</div>
|
|
|
|
<!-- Press -->
|
|
<div class="tile">
|
|
<div><div class="k">Press</div><div class="v">1px translateY, no scale</div></div>
|
|
<div class="stage">
|
|
<button class="press-btn" type="button">Open the archive</button>
|
|
</div>
|
|
<div class="note">Fill darkens one step on press.</div>
|
|
</div>
|
|
|
|
<!-- Focus -->
|
|
<div class="tile">
|
|
<div><div class="k">Focus</div><div class="v">2px ring · 3px offset</div></div>
|
|
<div class="stage">
|
|
<div class="focus-stage"><div class="focus-field">Search the archive</div></div>
|
|
</div>
|
|
<div class="note">Secondary brown at 40% opacity. Never a solid border.</div>
|
|
</div>
|
|
|
|
<!-- Tonal shift -->
|
|
<div class="tile">
|
|
<div><div class="k">Tonal shift</div><div class="v">Background tier, not shadow</div></div>
|
|
<div class="stage">
|
|
<div class="tonal-shift"></div>
|
|
</div>
|
|
<div class="note">Depth is a paper tier. Elevation is never a box-shadow first.</div>
|
|
</div>
|
|
|
|
</div>
|
|
</body>
|
|
</html>
|