Skip to content

Instantly share code, notes, and snippets.

@kazzohikaru
Created February 13, 2026 01:49
Show Gist options
  • Select an option

  • Save kazzohikaru/0fc556c981e3cf524cdd433706564866 to your computer and use it in GitHub Desktop.

Select an option

Save kazzohikaru/0fc556c981e3cf524cdd433706564866 to your computer and use it in GitHub Desktop.
CSS-Scroll-Focus-Text
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MÅNE | Architecture of Silence</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@300;600;800&display=swap" rel="stylesheet">
</head>
<body>
<!-- Mobile Progress Widget -->
<div class="mobile-progress">
<svg viewBox="0 0 100 100">
<circle class="track-circle" cx="50" cy="50" r="40" />
<circle class="progress-circle" cx="50" cy="50" r="40" pathLength="1" />
</svg>
</div>
<!-- Visuals Container -->
<div class="sticky-visual">
<div class="desktop-progress"></div>
<div class="shape-container shape-1">
<div class="circle-outline"></div>
</div>
<div class="shape-container shape-2">
<div class="stone-block"></div>
</div>
<div class="shape-container shape-3">
<div class="grid-lines">
<div class="grid-box"></div>
<div class="grid-box"></div>
<div class="grid-box"></div>
<div class="grid-box"></div>
</div>
</div>
<div class="shape-container shape-4">
<div class="balance">
<div class="b-circle b-1"></div>
<div class="b-circle b-2"></div>
</div>
</div>
<div class="shape-container shape-5">
<div class="light-orb"></div>
</div>
<div class="shape-container shape-6">
<div class="end-line"></div>
</div>
</div>
<!-- Scroll Content -->
<div class="content">
<header>
<div>
<h1>MÅNE Studio</h1>
<span class="title-large">Architecture<br>of Silence.</span>
</div>
</header>
<section class="scroll-section s1">
<p class="focus-text">We don't just fill space. We shape the void.</p>
<p class="description">True luxury is the absence of noise. Our design philosophy centers on negative space as the primary material of construction.</p>
</section>
<section class="scroll-section s2">
<p class="focus-text">Honest materials that age, but never break.</p>
<p class="description">Raw oak. Brushed steel. Travertine stone. We select materials that develop a patina, telling the story of their use over decades.</p>
</section>
<section class="scroll-section s3">
<p class="focus-text">Rigorous structure. Fluid living.</p>
<p class="description">The grid is our foundation, but life is organic. We create systems that bring order to chaos without constraining the human spirit.</p>
</section>
<section class="scroll-section s4">
<p class="focus-text">Objects that don't scream for attention.</p>
<p class="description">In a world of constant demand, we create calm. Furniture and spaces that exist with quiet confidence and absolute purpose.</p>
</section>
<section class="scroll-section s5">
<p class="focus-text">Light as the fourth dimension.</p>
<p class="description">We sculpt light like a physical material. It guides the eye, reveals texture, and marks the passage of time throughout the day.</p>
</section>
<section class="scroll-section s6">
<p class="focus-text">Sustainability is not a feature.</p>
<p class="description">It is the default. We build for permanence. The most sustainable building is the one that never needs to be torn down.</p>
</section>
<div class="closing-section">
<div class="closer">
<strong>Start the conversation.</strong>
[email protected]<br>
Copenhagen / Tokyo / New York
</div>
</div>
</div>
</body>
/* Config & Variables */
:root {
/* Palette */
--bg: #080808;
--text-muted: #444;
--text-light: #e5e5e5;
--accent: #d4c5a3;
/* Timeline Scopes */
timeline-scope: --s1, --s2, --s3, --s4, --s5, --s6;
}
/* Base / Reset */
body {
margin: 0;
background: var(--bg);
color: var(--text-light);
font-family: "Manrope", sans-serif;
overflow-x: hidden;
-webkit-font-smoothing: antialiased;
}
/* Layout: Sticky Visuals (Right) */
.sticky-visual {
position: fixed;
top: 0;
right: 0;
width: 50%;
height: 100vh;
display: grid;
place-items: center;
z-index: 10;
pointer-events: none;
border-left: 1px solid rgba(255, 255, 255, 0.05);
}
.shape-container {
position: absolute;
width: 400px;
height: 400px;
display: grid;
place-items: center;
opacity: 0;
/* Entry/Exit Animation */
animation-name: shape-fade;
animation-fill-mode: both;
animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}
/* Timeline Linkages */
.shape-1 {
animation-timeline: --s1;
}
.shape-2 {
animation-timeline: --s2;
}
.shape-3 {
animation-timeline: --s3;
}
.shape-4 {
animation-timeline: --s4;
}
.shape-5 {
animation-timeline: --s5;
}
.shape-6 {
animation-timeline: --s6;
}
/* Layout: Content (Left) */
.content {
width: 50%;
padding-bottom: 20vh;
position: relative;
z-index: 20;
}
header {
height: 90vh;
display: flex;
align-items: center;
padding-left: 10vw;
}
.scroll-section {
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
padding-left: 10vw;
padding-right: 2rem;
/* View Timeline Source */
view-timeline-axis: block;
view-timeline-inset: 40% 40%;
}
/* Section IDs */
.s1 {
view-timeline-name: --s1;
}
.s2 {
view-timeline-name: --s2;
}
.s3 {
view-timeline-name: --s3;
}
.s4 {
view-timeline-name: --s4;
}
.s5 {
view-timeline-name: --s5;
}
.s6 {
view-timeline-name: --s6;
}
.closing-section {
height: 60vh;
display: flex;
align-items: center;
padding-left: 10vw;
border-top: 1px solid rgba(255, 255, 255, 0.1);
margin-top: 10vh;
}
/* Components: Typography */
h1 {
font-size: 1.5rem;
letter-spacing: 0.2em;
text-transform: uppercase;
font-weight: 300;
margin: 0;
color: var(--accent);
opacity: 0.8;
}
.title-large {
display: block;
font-size: 5rem;
font-weight: 800;
letter-spacing: -0.02em;
color: var(--text-light);
margin-top: 1rem;
line-height: 1;
}
.focus-text {
font-size: 3.5rem;
font-weight: 600;
line-height: 1.1;
color: var(--text-muted);
margin: 0;
max-width: 500px;
letter-spacing: -0.02em;
/* Magnify Effect */
animation: content-focus linear both;
animation-timeline: view();
animation-range: cover 0% cover 100%;
}
.description {
font-size: 1.1rem;
color: #666;
margin-top: 1.5rem;
max-width: 420px;
line-height: 1.7;
font-weight: 300;
border-left: 2px solid var(--accent);
padding-left: 1.5rem;
/* Sync with Header */
animation: content-focus linear both;
animation-timeline: view();
animation-range: cover 0% cover 100%;
}
.closer {
font-size: 1.2rem;
font-weight: 300;
color: var(--text-muted);
}
.closer strong {
display: block;
font-size: 2rem;
color: var(--text-light);
margin-bottom: 1rem;
}
/* Components: Shapes (CSS Art) */
/* 1. Circle Outline */
.circle-outline {
width: 300px;
height: 300px;
border: 2px solid var(--text-light);
border-radius: 50%;
box-shadow: 0 0 60px rgba(255, 255, 255, 0.05);
}
/* 2. Textured Stone */
.stone-block {
width: 250px;
height: 350px;
background: linear-gradient(135deg, #333, #111);
border-radius: 4px;
position: relative;
overflow: hidden;
}
.stone-block::after {
content: "";
position: absolute;
inset: 0;
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)' opacity='0.4'/%3E%3C/svg%3E");
mix-blend-mode: overlay;
}
/* 3. Grid */
.grid-lines {
width: 300px;
height: 300px;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 20px;
}
.grid-box {
border: 1px solid rgba(255, 255, 255, 0.2);
}
.grid-box:nth-child(1) {
border-top: 0;
border-left: 0;
}
.grid-box:nth-child(4) {
border-bottom: 0;
border-right: 0;
}
/* 4. Balance */
.balance {
width: 300px;
height: 300px;
position: relative;
}
.b-circle {
position: absolute;
width: 150px;
height: 150px;
border-radius: 50%;
mix-blend-mode: exclusion;
}
.b-1 {
background: #fff;
top: 20%;
left: 20%;
}
.b-2 {
background: #666;
bottom: 20%;
right: 20%;
}
/* 5. Light Orb */
.light-orb {
width: 300px;
height: 300px;
border-radius: 50%;
background: radial-gradient(
circle at 30% 30%,
var(--accent),
transparent 60%
);
filter: blur(40px);
opacity: 0.6;
}
/* 6. End Line */
.end-line {
width: 2px;
height: 300px;
background: var(--text-light);
position: relative;
}
.end-line::before {
content: "";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 40px;
height: 1px;
background: var(--text-light);
}
/* Components: Progress Indicators */
/* Desktop: Vertical Line on Border */
.desktop-progress {
position: absolute;
left: -1px;
top: 0;
width: 3px;
height: 100%;
background: var(--accent);
transform-origin: top;
transform: scaleY(0);
animation: progress-grow linear;
animation-timeline: scroll();
z-index: 20;
}
/* Mobile: Circular Widget */
.mobile-progress {
display: none;
position: fixed;
bottom: 30px;
right: 30px;
width: 60px;
height: 60px;
z-index: 100;
background: rgba(0, 0, 0, 0.8);
border-radius: 50%;
padding: 5px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
backdrop-filter: blur(10px);
}
.mobile-progress svg {
width: 100%;
height: 100%;
transform: rotate(-90deg);
}
.progress-circle {
fill: none;
stroke: var(--accent);
stroke-width: 8;
stroke-linecap: round;
stroke-dasharray: 1;
stroke-dashoffset: 1;
animation: circle-grow linear;
animation-timeline: scroll();
}
.track-circle {
fill: none;
stroke: rgba(255, 255, 255, 0.1);
stroke-width: 8;
}
/* Keyframes */
@keyframes shape-fade {
entry 0% {
opacity: 0;
transform: translateY(40px) scale(0.9);
}
entry 100% {
opacity: 1;
transform: translateY(0) scale(1);
}
exit 0% {
opacity: 1;
transform: translateY(0) scale(1);
}
exit 100% {
opacity: 0;
transform: translateY(-40px) scale(1.1);
}
}
@keyframes content-focus {
0% {
filter: blur(12px);
opacity: 0;
transform: scale(0.8) translateY(40px);
border-color: transparent;
}
45%,
55% {
filter: blur(0);
opacity: 1;
transform: scale(1) translateY(0);
color: var(--text-light);
border-color: var(--accent);
}
100% {
filter: blur(12px);
opacity: 0;
transform: scale(0.95) translateY(-40px);
border-color: transparent;
}
}
@keyframes progress-grow {
to {
transform: scaleY(1);
}
}
@keyframes circle-grow {
to {
stroke-dashoffset: 0;
}
}
/* Responsive Design */
@media (max-width: 768px) {
.sticky-visual {
opacity: 0.1;
width: 100%;
z-index: -1;
border-left: none;
}
.content {
width: 100%;
}
.scroll-section {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
header {
padding-left: 1.5rem;
}
/* Adjust Typography */
.focus-text {
font-size: 2rem;
}
.title-large {
font-size: 3.5rem;
}
/* Toggle Progress Indicators */
.desktop-progress {
display: none;
}
.mobile-progress {
display: block;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment