Navigation · Component reference

Sticky navigation

Keep important destinations reachable as a page grows.

Published and reviewed · Starlit’s implementation notes

Try the live example

Research and our take

We explored the InstaLanding Sticky navigation reference as part of our template research. Its composition was a starting point for Starlit’s palette, system typography, sample content and local interaction treatment. This is an adapted study, not a claim that Starlit invented the underlying pattern.

Our take is described in the reasoning and tradeoffs below. Examples use fictional content and keep their actions local. Read the provenance and reuse notes.

Design reasoning

Keep important destinations reachable as a page grows.

  1. Start with the person’s task and the barrier they may encounter.
  2. Use a compact sticky header when it helps repeated navigation. Keep a readable opaque fallback and a usable narrow layout.
  3. Keep the ordinary content and action usable before adding enhancement.
  4. Open and close the narrow menu, follow an anchor and Tab to content near the sticky edge. Check the focused item is visible.

Usage pattern

Use a compact sticky header when it helps repeated navigation. Keep a readable opaque fallback and a usable narrow layout.

Impact and tradeoffs

Persistent navigation saves travel but consumes reading space and can cover focused content.

Accessibility solutions

Expose menu expansion, preserve visible focus, and provide anchor offsets. Transparency must not lower text contrast.

Build accessible source content first. Personal preferences supplement semantic HTML, useful names, keyboard access and visible focus.

HTML

A concrete usage example. Host these assets on your own origin if you adapt the pattern. Read the source and credits before reuse.

Read the html implementation (139 lines)
<link rel="stylesheet" href="/open-ui/examples/sticky-glass-navbar.css">
<!-- Load these files from the document head. -->
<link rel="stylesheet" href="/open-ui/brand/tokens.css">
<link rel="stylesheet" href="/open-ui/brand/system.css">
<link rel="stylesheet" href="/open-ui/brand/components.css">
<script defer src="/open-ui/brand/components.js?v=sdou20261029"></script>
<!-- Set data-sd-theme="dark" on the html element. -->
<!-- Place this markup in the document body. -->
<div class="sdou-study-intro">
        <span class="sdou-kicker">The details make the difference</span>
        <h1>A clear way through the work.</h1>
        <p>
          Navigation that stays close without taking over. Scroll the study to
          see the bar settle into its compact state.
        </p>
      </div>
      <div class="sdou-stage">
        <div class="sdou-demo-navbar" id="demo-nav">
          <a href="#nav-0">Starlit</a
          ><button
            class="sdou-button secondary sdou-menu-toggle"
            aria-expanded="false"
            aria-controls="sample-nav"
          >
            Menu
          </button>
          <nav id="sample-nav" aria-label="Sample navigation">
            <a href="#nav-0">Overview</a><a href="#nav-1">Tools</a
            ><a href="#nav-2">Process</a><a href="#nav-3">Notes</a
            ><a href="#nav-4">Studio</a>
          </nav>
          <a class="sdou-button" href="#nav-4">Explore</a>
        </div>
        <section class="sdou-navbar-body" id="nav-0">
          <div>
            <span class="sdou-kicker">01 / Overview</span>
            <h2>Keep the important things close.</h2>
          </div>
          <div>
            <p>
              Clear navigation leaves more attention for the content people came
              to see.
            </p>
            <div class="sdou-mini" aria-hidden="true">
              <span class="example-style-0"></span
              ><span class="example-style-1"></span
              ><span class="example-style-2"></span
              ><span class="example-style-3"></span
              ><span class="example-style-4"></span
              ><span class="example-style-5"></span
              ><span class="example-style-6"></span>
            </div>
          </div>
        </section>
        <section class="sdou-navbar-body" id="nav-1">
          <div>
            <span class="sdou-kicker">02 / Tools</span>
            <h2>Useful ideas, thoughtfully made.</h2>
          </div>
          <div>
            <p>
              A consistent place for each action makes the whole experience
              easier to learn.
            </p>
            <div class="sdou-mini" aria-hidden="true">
              <span class="example-style-7"></span
              ><span class="example-style-8"></span
              ><span class="example-style-9"></span
              ><span class="example-style-10"></span
              ><span class="example-style-11"></span
              ><span class="example-style-12"></span
              ><span class="example-style-13"></span>
            </div>
          </div>
        </section>
        <section class="sdou-navbar-body" id="nav-2">
          <div>
            <span class="sdou-kicker">03 / Process</span>
            <h2>Give the next step a clear shape.</h2>
          </div>
          <div>
            <p>
              Every part of the page should help someone understand where they
              are and what comes next.
            </p>
            <div class="sdou-mini" aria-hidden="true">
              <span class="example-style-14"></span
              ><span class="example-style-15"></span
              ><span class="example-style-16"></span
              ><span class="example-style-17"></span
              ><span class="example-style-18"></span
              ><span class="example-style-19"></span
              ><span class="example-style-20"></span>
            </div>
          </div>
        </section>
        <section class="sdou-navbar-body" id="nav-3">
          <div>
            <span class="sdou-kicker">04 / Notes</span>
            <h2>Leave a readable record.</h2>
          </div>
          <div>
            <p>
              Good work becomes easier to revisit when the useful details stay
              in view.
            </p>
            <div class="sdou-mini" aria-hidden="true">
              <span class="example-style-21"></span
              ><span class="example-style-22"></span
              ><span class="example-style-23"></span
              ><span class="example-style-24"></span
              ><span class="example-style-25"></span
              ><span class="example-style-26"></span
              ><span class="example-style-27"></span>
            </div>
          </div>
        </section>
        <section class="sdou-navbar-body" id="nav-4">
          <div>
            <span class="sdou-kicker">05 / Studio</span>
            <h2>Independent thinking. Shared care.</h2>
          </div>
          <div>
            <p>
              A small studio with a considered approach to the work and the
              people who use it.
            </p>
            <div class="sdou-mini" aria-hidden="true">
              <span class="example-style-28"></span
              ><span class="example-style-29"></span
              ><span class="example-style-30"></span
              ><span class="example-style-31"></span
              ><span class="example-style-32"></span
              ><span class="example-style-33"></span
              ><span class="example-style-34"></span>
            </div>
          </div>
        </section>
      </div>

Open the HTML usage source

CSS

Actual shared component stylesheet. Rules for this example sit alongside the other interface studies. tokens.css and system.css provide the foundation. Any example specific stylesheet is linked in the HTML above.

Read the css implementation (861 lines)
/* Starlit component resources. Layouts share tokens and controls with the full studies. */
.sdou-component {
  overflow-x: clip;
}
.sdou-component .sdou-stage {
  min-height: 380px;
}
.sdou-component h2 {
  font-size: clamp(28px, 4vw, 44px);
}
.sdou-component .sdou-card h3 {
  font-size: 26px;
  margin: 0 0 12px;
}
.sdou-component .sdou-card p {
  color: var(--sdou-muted);
  margin: 0 0 20px;
}
.sdou-example-note {
  font-size: 13px !important;
  color: var(--sdou-muted) !important;
  max-width: 70ch;
}
.sdou-label {
  display: block;
  font-weight: 600;
  font-size: 14px;
  margin: 0 0 8px;
}
.sdou-status {
  min-height: 28px;
  color: var(--sdou-secondary);
  font-size: 14px;
  margin-top: 12px;
}
.sdou-actions {
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
}
.sdou-marquee {
  overflow: hidden;
  mask-image: linear-gradient(
    90deg,
    transparent,
    #000 12%,
    #000 88%,
    transparent
  );
  padding: 48px 0;
  border-block: 1px solid var(--sdou-line);
}
.sdou-marquee-track {
  display: flex;
  width: max-content;
  animation: sdou-marquee 30s linear infinite;
  align-items: center;
}
.sdou-marquee-group {
  display: flex;
  align-items: center;
  gap: 40px;
  padding-right: 40px;
}
.sdou-marquee span {
  font: 32px var(--sdou-font-display);
  color: var(--sdou-muted);
  white-space: nowrap;
}
.sdou-marquee:hover .sdou-marquee-track,
.sdou-marquee:focus-within .sdou-marquee-track,
.sdou-marquee[data-paused="true"] .sdou-marquee-track {
  animation-play-state: paused;
}
@keyframes sdou-marquee {
  to {
    transform: translateX(-50%);
  }
}
.sdou-pricing-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 24px;
  margin-bottom: 32px;
  flex-wrap: wrap;
}
.sdou-switch {
  display: inline-flex;
  gap: 4px;
  padding: 5px;
  border: 1px solid var(--sdou-line);
  border-radius: 14px;
  background: var(--sdou-panel);
}
.sdou-switch button {
  border: 0;
  border-radius: 9px;
  min-height: 44px;
  padding: 8px 16px;
  color: var(--sdou-muted);
  background: none;
  cursor: pointer;
}
.sdou-switch button[aria-pressed="true"] {
  background: var(--sdou-accent);
  color: var(--sdou-on-accent);
}
.sdou-plan {
  display: flex;
  flex-direction: column;
  position: relative;
}
.sdou-plan.featured {
  border-color: var(--sdou-gold);
  background: var(--sdou-navy-800);
  color: var(--sdou-cream);
  transform: translateY(-12px);
}
.sdou-plan.featured p {
  color: var(--sdou-muted-dark);
}
.sdou-plan ul {
  padding: 0;
  list-style: none;
  margin: 24px 0 32px;
  flex: 1;
}
.sdou-plan li {
  padding: 8px 0;
}
.sdou-plan li::before {
  content: "✓";
  color: var(--sdou-secondary);
  margin-right: 10px;
}
.sdou-price {
  font: 52px var(--sdou-font-display);
  margin-top: 16px;
}
.sdou-price small {
  font: 14px var(--sdou-font-body);
  color: var(--sdou-muted);
}
.sdou-pill {
  display: inline-flex;
  align-self: start;
  border: 1px solid var(--sdou-line);
  border-radius: 999px;
  font: 11px var(--sdou-font-body);
  padding: 6px 10px;
  color: var(--sdou-accent);
}
.sdou-demo-navbar {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 16px 24px;
  min-height: 72px;
  border-radius: 18px;
  border: 1px solid transparent;
  background: color-mix(in srgb, var(--sdou-panel) 88%, transparent);
  backdrop-filter: blur(18px);
  transition:
    padding 0.2s,
    min-height 0.2s;
}
.sdou-demo-navbar.compact {
  min-height: 56px;
  padding-block: 8px;
  border-color: var(--sdou-line);
}
.sdou-demo-navbar > a {
  font: 24px var(--sdou-font-display);
  color: var(--sdou-ink);
  text-decoration: none;
}
.sdou-demo-navbar nav {
  display: flex;
  gap: 20px;
  margin-left: auto;
}
.sdou-demo-navbar nav a {
  color: var(--sdou-muted);
  font-size: 13px;
  min-height: 44px;
  display: flex;
  align-items: center;
  text-decoration: none;
}
.sdou-menu-toggle {
  display: none;
}
.sdou-navbar-body {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  gap: 40px;
  padding: 96px 0;
  min-height: 500px;
}
.sdou-navbar-body p {
  color: var(--sdou-muted);
}
.sdou-magnetic-stage {
  display: grid;
  place-items: center;
  min-height: 360px;
  border: 1px solid var(--sdou-line);
  border-radius: 28px;
  background: radial-gradient(
    ellipse at 50% 80%,
    var(--sdou-raised),
    var(--sdou-bg)
  );
}
.sdou-magnetic {
  position: relative;
  padding: 20px 34px;
  overflow: hidden;
  will-change: transform;
}
.sdou-magnetic span {
  position: relative;
  z-index: 1;
  display: inline-block;
}
.sdou-magnetic::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(
    circle at var(--x, 50%) var(--y, 50%),
    #fff8,
    transparent 60%
  );
  opacity: 0;
  transition: opacity 0.2s;
}
.sdou-magnetic:hover::before {
  opacity: 1;
}
.sdou-form-card {
  max-width: 660px;
  margin-inline: auto;
  padding: clamp(24px, 5vw, 56px);
}
.sdou-email-row {
  display: flex;
  gap: 12px;
}
.sdou-email-row .sdou-input {
  flex: 1;
  min-width: 0;
}
.sdou-error {
  color: var(--sdou-error);
  min-height: 24px;
  font-size: 14px;
}
.sdou-success-icon {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--sdou-raised);
  color: var(--sdou-secondary);
  font-size: 28px;
}
.sdou-loading::after {
  content: "";
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid currentColor;
  border-right-color: transparent;
  animation: sdou-spin 0.8s linear infinite;
}
@keyframes sdou-spin {
  to {
    transform: rotate(360deg);
  }
}
.sdou-bento {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 24px;
}
.sdou-bento .sdou-card {
  min-height: 240px;
  position: relative;
  overflow: hidden;
  transition:
    transform 0.2s,
    box-shadow 0.2s;
}
.sdou-bento .sdou-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 18px 40px #09151f22;
}
.sdou-bento .sdou-card:first-child {
  grid-column: span 2;
  grid-row: span 2;
}
.sdou-bento .sdou-card:nth-child(2) {
  grid-column: span 2;
}
.sdou-bento .sdou-card:first-child h3 {
  font-size: 42px;
  max-width: 10ch;
}
.sdou-bento .sdou-card:nth-child(3) {
  background: var(--sdou-navy-800);
  color: var(--sdou-cream);
}
.sdou-bento .sdou-card:nth-child(3) p {
  color: var(--sdou-muted-dark);
}
.sdou-mini {
  height: 100px;
  margin-top: 32px;
  display: flex;
  gap: 8px;
  align-items: flex-end;
}
.sdou-mini span {
  flex: 1;
  border: 1px solid var(--sdou-line);
  border-radius: 7px;
  background: var(--sdou-raised);
}
.sdou-mini span:nth-child(2n) {
  background: var(--sdou-secondary);
}
.sdou-mini span:nth-child(3n) {
  background: var(--sdou-accent);
}
.sdou-reveal-section {
  padding-block: 72px;
  border-top: 1px solid var(--sdou-line);
}
.sdou-reveal-section h2 {
  max-width: 16ch;
}
.sdou-motion-ready [data-reveal] {
  opacity: 0;
  transform: translateY(24px);
  transition:
    opacity 0.6s ease-out,
    transform 0.6s ease-out;
}
.sdou-motion-ready [data-reveal].visible {
  opacity: 1;
  transform: translateY(0);
}
.sdou-mega {
  padding: 48px;
  border-radius: 28px;
  background: var(--sdou-panel);
  border: 1px solid var(--sdou-line);
}
.sdou-newsletter {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 40px;
  align-items: center;
  border-bottom: 1px solid var(--sdou-line);
  padding-bottom: 40px;
}
.sdou-footer-cols {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 24px;
  padding-top: 40px;
}
.sdou-footer-cols strong {
  display: block;
  color: var(--sdou-accent);
  font-size: 13px;
  margin-bottom: 16px;
}
.sdou-footer-cols a {
  display: block;
  color: var(--sdou-muted);
  min-height: 36px;
  text-decoration: none;
}
.sdou-outline-word {
  font: clamp(40px, 11vw, 144px)/1.1 var(--sdou-font-display);
  color: transparent;
  -webkit-text-stroke: 1px var(--sdou-muted);
  margin: 60px 0 20px;
  transition: color 0.2s;
}
.sdou-outline-word:hover {
  color: var(--sdou-accent);
}
.sdou-quote {
  position: relative;
}
.sdou-quote::before {
  content: "“";
  position: absolute;
  right: 20px;
  top: 0;
  font: 120px var(--sdou-font-display);
  opacity: 0.1;
}
.sdou-stars {
  color: var(--sdou-accent);
  letter-spacing: 0.2em;
  font-size: 14px;
}
.sdou-quote blockquote {
  font: italic 24px/1.5 var(--sdou-font-display);
  margin: 28px 0;
}
.sdou-quote:nth-child(2) {
  transform: translateY(-12px);
  background: var(--sdou-raised);
}
.sdou-avatar {
  display: flex;
  align-items: center;
  gap: 12px;
}
.sdou-avatar > span {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border: 1px solid var(--sdou-line);
  background: var(--sdou-bg);
  border-radius: 50%;
  color: var(--sdou-accent);
}
.sdou-avatar small {
  display: block;
  color: var(--sdou-muted);
}
.sdou-dashboard {
  max-width: 900px;
  margin: auto;
}
.sdou-dashboard-head {
  display: flex;
  justify-content: space-between;
  gap: 20px;
  align-items: start;
}
.sdou-dashboard-head .sdou-select {
  width: auto;
  min-width: 150px;
}
.sdou-metrics {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
  margin-top: 32px;
}
.sdou-metric {
  padding: 18px;
  border: 1px solid var(--sdou-line);
  border-radius: 12px;
}
.sdou-metric small {
  color: var(--sdou-muted);
  font-size: 11px;
}
.sdou-metric strong {
  display: block;
  font: 34px var(--sdou-font-display);
  margin: 12px 0;
}
.sdou-delta {
  font-size: 12px;
  color: var(--sdou-secondary);
}
.sdou-chart {
  display: flex;
  align-items: end;
  gap: 12px;
  height: 180px;
  margin-top: 40px;
  border-bottom: 1px solid var(--sdou-line);
}
.sdou-bar {
  flex: 1;
  border: 0;
  position: relative;
  height: var(--height);
  background: var(--sdou-line);
  border-radius: 6px 6px 0 0;
  cursor: pointer;
  padding: 0;
  min-width: 0;
}
.sdou-bar.active,
.sdou-bar:hover,
.sdou-bar:focus {
  background: var(--sdou-accent);
}
.sdou-bar::after {
  content: attr(data-value);
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  color: var(--sdou-ink);
  background: var(--sdou-bg);
  padding: 4px 8px;
  border: 1px solid var(--sdou-line);
  border-radius: 5px;
  font-size: 11px;
  opacity: 0;
  white-space: nowrap;
}
.sdou-bar:hover::after,
.sdou-bar:focus::after {
  opacity: 1;
}
.sdou-dashboard.skeleton .sdou-metric strong {
  color: transparent;
  background: var(--sdou-line);
  border-radius: 6px;
  animation: sdou-skeleton 1s alternate infinite;
}
@keyframes sdou-skeleton {
  to {
    opacity: 0.35;
  }
}
.sdou-sidebar-frame {
  display: grid;
  grid-template-columns: 240px 1fr;
  min-height: 640px;
  border: 1px solid var(--sdou-line);
  border-radius: 24px;
  overflow: hidden;
}
.sdou-sidebar {
  display: flex;
  flex-direction: column;
  padding: 28px 20px;
  background: var(--sdou-panel);
  border-right: 1px solid var(--sdou-line);
}
.sdou-sidebar img {
  width: 48px;
  height: 48px;
  margin-bottom: 36px;
}
.sdou-sidebar nav {
  display: grid;
  gap: 4px;
}
.sdou-sidebar a {
  min-height: 48px;
  display: flex;
  align-items: center;
  color: var(--sdou-muted);
  text-decoration: none;
  font: 12px var(--sdou-font-body);
  letter-spacing: 0.1em;
  padding: 12px;
  border-left: 2px solid transparent;
}
.sdou-sidebar a[aria-current="page"] {
  color: var(--sdou-ink);
  border-left-color: var(--sdou-accent);
  background: var(--sdou-raised);
}
.sdou-sidebar a:hover {
  color: var(--sdou-ink);
}
.sdou-sidebar-bottom {
  margin-top: auto;
  padding-top: 40px;
}
.sdou-sidebar-content {
  padding: 48px;
  min-width: 0;
}
.sdou-sidebar-mobile {
  display: none;
}
.sdou-command-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 48px;
  width: min(100%, 560px);
  padding: 20px 24px;
  background: var(--sdou-panel);
  color: var(--sdou-muted);
  border: 1px solid var(--sdou-line);
  border-radius: 14px;
  cursor: pointer;
  font-size: 16px;
}
.sdou-command-trigger kbd {
  font: 12px var(--sdou-font-mono);
  padding: 4px 8px;
  border: 1px solid var(--sdou-line);
  border-radius: 6px;
}
.sdou-dialog {
  background: var(--sdou-panel);
  color: var(--sdou-ink);
  border: 1px solid var(--sdou-line);
  border-radius: 20px;
  width: min(640px, calc(100% - 32px));
  max-height: 80dvh;
  padding: 24px;
}
.sdou-dialog::backdrop {
  background: #09151fcc;
  backdrop-filter: blur(5px);
}
.sdou-command-results {
  list-style: none;
  padding: 0;
  margin: 16px 0;
  max-height: 360px;
  overflow: auto;
}
.sdou-command-results button {
  display: flex;
  justify-content: space-between;
  width: 100%;
  min-height: 52px;
  padding: 12px 16px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--sdou-ink);
  text-align: left;
  cursor: pointer;
}
.sdou-command-results button[aria-selected="true"] {
  background: var(--sdou-raised);
  color: var(--sdou-accent);
}
.sdou-command-results small {
  color: var(--sdou-muted);
}
.sdou-command-results mark {
  background: var(--sdou-gold);
  color: var(--sdou-navy-950);
}
.sdou-masonry {
  columns: 3;
  column-gap: 12px;
}
.sdou-masonry figure {
  break-inside: avoid;
  margin: 0 0 12px;
  position: relative;
  border-radius: 14px;
  overflow: hidden;
  background: var(--sdou-panel);
}
.sdou-masonry img {
  display: block;
  width: 100%;
  transition: transform 0.35s;
}
.sdou-masonry figure:hover img {
  transform: scale(1.03);
}
.sdou-masonry figcaption {
  position: absolute;
  inset: auto 0 0;
  padding: 18px;
  background: linear-gradient(transparent, #09151ff2);
  color: var(--sdou-cream);
  transform: translateY(8px);
  transition: transform 0.2s;
}
.sdou-masonry figure:hover figcaption {
  transform: translateY(0);
}
.sdou-masonry small {
  display: block;
  color: var(--sdou-gold);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.sdou-crt {
  padding: clamp(20px, 4vw, 48px);
  background: var(--sdou-navy-950);
  border-radius: 28px;
  border: 1px solid var(--sdou-navy-600);
  box-shadow:
    inset 0 1px 0 #ffffff20,
    0 28px 60px #09151f44;
}
.sdou-crt canvas {
  display: block;
  width: 100%;
  aspect-ratio: 16/9;
  background: #09151f;
  border-radius: 40%/8%;
  border: 12px solid var(--sdou-navy-900);
  box-shadow:
    0 0 0 2px var(--sdou-navy-600),
    inset 0 0 100px #000;
}
.sdou-crt-controls {
  display: flex;
  gap: 20px;
  align-items: center;
  margin-top: 32px;
  color: var(--sdou-cream);
}
.sdou-crt-controls input {
  flex: 1;
  min-width: 0;
  accent-color: var(--sdou-gold);
}
@media (max-width: 900px) {
  .sdou-bento {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .sdou-bento .sdou-card:first-child {
    grid-row: auto;
  }
  .sdou-bento .sdou-card:nth-child(2) {
    grid-column: auto;
  }
  .sdou-masonry {
    columns: 2;
  }
  .sdou-grid.sdou-quotes {
    grid-template-columns: 1fr;
  }
  .sdou-quote:nth-child(2) {
    transform: none;
  }
}
@media (max-width: 760px) {
  .sdou-plan.featured {
    transform: none;
  }
  .sdou-newsletter,
  .sdou-navbar-body {
    grid-template-columns: 1fr;
  }
  .sdou-footer-cols {
    grid-template-columns: repeat(2, 1fr);
  }
  .sdou-mega {
    padding: 24px;
  }
  .sdou-metrics {
    grid-template-columns: repeat(2, 1fr);
  }
  .sdou-dashboard-head {
    flex-wrap: wrap;
  }
  .sdou-chart {
    gap: 6px;
  }
  .sdou-sidebar-frame {
    grid-template-columns: 1fr;
  }
  .sdou-sidebar {
    display: none;
    border: 0;
  }
  .sdou-sidebar.open {
    display: flex;
  }
  .sdou-sidebar-mobile {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 20px;
    background: var(--sdou-panel);
    border-bottom: 1px solid var(--sdou-line);
  }
  .sdou-sidebar-content {
    padding: 24px;
  }
  .sdou-menu-toggle {
    display: inline-flex;
    margin-left: auto;
  }
  .sdou-demo-navbar {
    flex-wrap: wrap;
    padding: 12px 16px;
  }
  .sdou-demo-navbar nav {
    display: none;
    flex-basis: 100%;
    margin: 0;
  }
  .sdou-demo-navbar nav.open {
    display: flex;
    flex-direction: column;
    gap: 0;
  }
  .sdou-demo-navbar > .sdou-button:not(.sdou-menu-toggle) {
    display: none;
  }
}
@media (max-width: 520px) {
  .sdou-bento {
    grid-template-columns: 1fr;
  }
  .sdou-bento .sdou-card:first-child,
  .sdou-bento .sdou-card:nth-child(2) {
    grid-column: auto;
  }
  .sdou-email-row {
    flex-direction: column;
  }
  .sdou-masonry {
    columns: 1;
  }
  .sdou-footer-cols {
    gap: 24px;
  }
  .sdou-crt-controls {
    gap: 10px;
  }
  .sdou-crt-controls .sdou-button {
    padding: 10px;
  }
  .sdou-study-intro {
    padding-top: 48px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .sdou-marquee-track {
    animation: none;
  }
  .sdou-motion-ready [data-reveal] {
    opacity: 1;
    transform: none;
  }
  .sdou-magnetic {
    transform: none !important;
  }
  .sdou-bento .sdou-card:hover,
  .sdou-masonry figure:hover img {
    transform: none;
  }
}
figure.sdou-card {
  margin: 0;
}
.sdou-marquee-track > div {
  flex-shrink: 0;
}

JavaScript

Actual shared example controller. Each block activates only when its matching element exists. Layout only components need no custom JavaScript; the bundled file also supports the interactive studies.

Read the javascript implementation (472 lines)
/* Starlit resource interactions. All examples run locally and send no data. */
(() => {
  const $ = (s, r = document) => r.querySelector(s),
    $$ = (s, r = document) => [...r.querySelectorAll(s)];
  const reduced = matchMedia("(prefers-reduced-motion: reduce)");
  const toggle = $("#marquee-toggle");
  if (toggle)
    toggle.onclick = () => {
      const paused = toggle.getAttribute("aria-pressed") !== "true";
      $(".sdou-marquee").dataset.paused = paused;
      toggle.setAttribute("aria-pressed", paused);
      toggle.textContent = paused ? "Resume motion" : "Pause motion";
    };
  $$("[data-billing]").forEach(
    (button) =>
      (button.onclick = () => {
        const period = button.dataset.billing;
        $$("[data-billing]").forEach((b) =>
          b.setAttribute("aria-pressed", b === button),
        );
        $$("[data-monthly]").forEach(
          (p) => (p.textContent = p.dataset[period]),
        );
        $$(".sdou-saving").forEach((b) => (b.hidden = period !== "annual"));
      }),
  );
  $$("[data-plan]").forEach(
    (button) =>
      (button.onclick = () =>
        ($("#plan-status").textContent =
          button.dataset.plan +
          " selected in this example. No purchase or account was created.")),
  );
  const demoNav = $("#demo-nav");
  if (demoNav) {
    const y = demoNav.getBoundingClientRect().top + scrollY;
    const update = () => demoNav.classList.toggle("compact", scrollY > y + 80);
    addEventListener("scroll", update, { passive: true });
    update();
    $(".sdou-menu-toggle").onclick = (e) => {
      const open = e.currentTarget.getAttribute("aria-expanded") !== "true";
      e.currentTarget.setAttribute("aria-expanded", open);
      $("#sample-nav").classList.toggle("open", open);
    };
    $$("#sample-nav a").forEach(
      (a) =>
        (a.onclick = () => {
          $("#sample-nav").classList.remove("open");
          $(".sdou-menu-toggle").setAttribute("aria-expanded", "false");
        }),
    );
  }
  const magnetic = $("#magnetic");
  if (magnetic) {
    let tx = 0,
      ty = 0,
      x = 0,
      y = 0,
      frame = 0;
    const tick = () => {
      x += (tx - x) * 0.16;
      y += (ty - y) * 0.16;
      magnetic.style.transform = `translate(${x}px,${y}px)`;
      $("span", magnetic).style.transform =
        `translate(${x * 0.5}px,${y * 0.5}px)`;
      if (Math.abs(tx - x) + Math.abs(ty - y) > 0.02)
        frame = requestAnimationFrame(tick);
      else frame = 0;
    };
    const go = () => {
      if (!frame) frame = requestAnimationFrame(tick);
    };
    magnetic.parentElement.onpointermove = (e) => {
      if (e.pointerType === "touch" || reduced.matches) return;
      const r = magnetic.parentElement.getBoundingClientRect(),
        dx = e.clientX - r.left - r.width / 2,
        dy = e.clientY - r.top - r.height / 2,
        d = Math.hypot(dx, dy);
      tx = d < 120 ? Math.max(-12, Math.min(12, dx * 0.1)) : 0;
      ty = d < 120 ? Math.max(-12, Math.min(12, dy * 0.1)) : 0;
      magnetic.style.setProperty("--x", 50 + dx * 0.4 + "%");
      magnetic.style.setProperty("--y", 50 + dy * 0.4 + "%");
      go();
    };
    magnetic.parentElement.onpointerleave = () => {
      tx = ty = 0;
      go();
    };
    magnetic.onclick = () =>
      ($("#magnetic-status").textContent =
        "A clear action, with a small moment of delight.");
  }
  $$(".sdou-local-form").forEach(
    (form) =>
      (form.onsubmit = async (e) => {
        e.preventDefault();
        const input = $("input[type=email]", form),
          error = $(".sdou-error", form),
          button = $("button[type=submit]", form);
        if (!input.validity.valid) {
          input.setAttribute("aria-invalid", "true");
          error.textContent =
            "Enter an email address in the form name@example.com.";
          input.focus();
          return;
        }
        input.removeAttribute("aria-invalid");
        error.textContent = "";
        button.disabled = true;
        button.classList.add("sdou-loading");
        button.textContent = "Checking…";
        await new Promise((r) => setTimeout(r, 600));
        const result = form.nextElementSibling;
        result.hidden = false;
        result.innerHTML =
          '<div class="sdou-success-icon" aria-hidden="true">✓</div><h3>A clear next step.</h3><p>The sample form is complete. Your address stayed in this page and was not submitted.</p><button class="sdou-button secondary" type="button">Try again</button>';
        form.hidden = true;
        $("button", result).onclick = () => {
          result.hidden = true;
          form.hidden = false;
          form.reset();
          button.disabled = false;
          button.classList.remove("sdou-loading");
          button.textContent = "Keep me posted";
          input.focus();
        };
      }),
  );
  window.sdou_useReveal = (root = document) => {
    const nodes = $$("[data-reveal]", root);
    if (reduced.matches || !("IntersectionObserver" in window)) {
      nodes.forEach((n) => n.classList.add("visible"));
      return () => {};
    }
    document.documentElement.classList.add("sdou-motion-ready");
    const observer = new IntersectionObserver(
      (entries) =>
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            entry.target.classList.add("visible");
            observer.unobserve(entry.target);
          }
        }),
      { threshold: 0.15 },
    );
    $$("[data-stagger]", root).forEach((parent) =>
      $$("[data-reveal]", parent).forEach(
        (el, i) => (el.style.transitionDelay = i * 80 + "ms"),
      ),
    );
    nodes.forEach((n) => observer.observe(n));
    return () => observer.disconnect();
  };
  if ($("[data-reveal]")) window.sdou_useReveal();
  const loading = $("#show-loading");
  if (loading) {
    let timer;
    const preview = () => {
      clearTimeout(timer);
      $(".sdou-dashboard").classList.add("skeleton");
      $(".sdou-dashboard").setAttribute("aria-busy", "true");
      timer = setTimeout(() => {
        $(".sdou-dashboard").classList.remove("skeleton");
        $(".sdou-dashboard").setAttribute("aria-busy", "false");
      }, 700);
    };
    loading.onclick = preview;
    $("#date-range").onchange = (e) => {
      preview();
      $("#chart-status").textContent =
        "Showing illustrative activity for " +
        e.target.value.toLowerCase() +
        ".";
      $$(".sdou-bar").forEach((b, i) => {
        const value = e.target.selectedIndex
          ? ((i * 17) % 68) + 25
          : ((i * 13) % 70) + 22;
        b.style.setProperty("--height", value + "%");
        b.dataset.value =
          (e.target.selectedIndex ? "Month " : "Week ") +
          (i + 1) +
          ": " +
          value * 12;
        b.setAttribute("aria-label", b.dataset.value + " sample sessions");
      });
    };
    $$(".sdou-bar").forEach(
      (b) =>
        (b.onclick = () => {
          $$(".sdou-bar").forEach((x) => x.classList.toggle("active", x === b));
          $("#chart-status").textContent =
            b.dataset.value + " sample sessions.";
        }),
    );
  }
  const sideToggle = $("#sidebar-toggle");
  if (sideToggle) {
    sideToggle.onclick = () => {
      const open = sideToggle.getAttribute("aria-expanded") !== "true";
      sideToggle.setAttribute("aria-expanded", open);
      $("#sample-sidebar").classList.toggle("open", open);
    };
    $$("[data-panel]").forEach(
      (a) =>
        (a.onclick = (e) => {
          e.preventDefault();
          $$("[data-panel]").forEach((x) =>
            x === a
              ? x.setAttribute("aria-current", "page")
              : x.removeAttribute("aria-current"),
          );
          $("#panel-title").textContent = a.dataset.panel;
          $("#panel-copy").textContent = {
            Overview:
              "Bring the work together, keep the useful context close and make the next step clear.",
            Projects:
              "A place for work in progress, clear checkpoints and useful next actions.",
            Library:
              "Keep reusable patterns, considered details and useful examples within reach.",
            Notes:
              "A readable record of ideas, observations and decisions worth coming back to.",
            Settings:
              "A clear place for the choices that make a workspace feel comfortable.",
          }[a.dataset.panel];
          if (innerWidth < 761) {
            $("#sample-sidebar").classList.remove("open");
            sideToggle.setAttribute("aria-expanded", "false");
          }
        }),
    );
  }
  const command = $("#command-dialog");
  if (command) {
    let index = 0;
    const choices = [
      ["Studio overview", "Recent", "/open-ui/"],
      ["Bento feature grid", "Components", "bento-feature-grid.html"],
      ["A considered invitation", "Components", "email-waitlist-form.html"],
      ["Useful signals", "Components", "stats-dashboard-card.html"],
      ["Studio compositions", "Components", "masonry-gallery.html"],
      ["Source notes", "Pages", "/open-ui/sources/"],
      ["Tool library", "Pages", "/open-ui/components/"],
      ["Design system", "Pages", "/open-ui/guidance/"],
    ];
    let results = choices;
    const fuzzy = (query, value) => {
      let i = 0;
      for (const ch of value.toLowerCase()) if (ch === query[i]) i++;
      return i === query.length;
    };
    const render = () => {
      const query = $("#command-input").value.trim().toLowerCase();
      results = choices.filter((c) => fuzzy(query, c[0] + " " + c[1]));
      index = 0;
      $("#command-results").replaceChildren();
      $("#command-input").removeAttribute("aria-activedescendant");
      $("#command-status").textContent = results.length + " matching resources.";
      if (!results.length) {
        $("#command-status").textContent = "No matching resources. Try another word.";
        return;
      }
      results.forEach((item, i) => {
        const li = document.createElement("li"),
          button = document.createElement("button");
        button.type = "button";
        li.setAttribute("role", "presentation");
        button.setAttribute("role", "option");
        button.tabIndex = -1;
        button.setAttribute("aria-selected", i === index);
        button.id = "command-result-" + i;
        const title = document.createElement("span");
        let q = 0;
        for (const ch of item[0]) {
          const node = document.createElement(
            ch.toLowerCase() === query[q] ? "mark" : "span",
          );
          if (ch.toLowerCase() === query[q]) q++;
          node.textContent = ch;
          title.append(node);
        }
        button.append(title);
        const small = document.createElement("small");
        small.textContent = item[1];
        button.append(small);
        button.onclick = () => (location.href = item[2]);
        li.append(button);
        $("#command-results").append(li);
      });
      $("#command-input").setAttribute(
        "aria-activedescendant",
        "command-result-0",
      );
    };
    let commandTrigger;
    command.addEventListener("close", () => {
      $("#command-input").setAttribute("aria-expanded", "false");
      if (commandTrigger?.isConnected) commandTrigger.focus();
    });
    const open = () => {
      if (!command.open) {
        commandTrigger = document.activeElement;
        $("#command-input").setAttribute("aria-expanded", "true");
        render();
        command.showModal();
        $("#command-input").focus();
      }
    };
    $("#command-open").onclick = open;
    $("#command-close").onclick = () => command.close();
    command.onclick = (e) => {
      if (e.target === command) {
        const r = command.getBoundingClientRect();
        if (
          e.clientX < r.left ||
          e.clientX > r.right ||
          e.clientY < r.top ||
          e.clientY > r.bottom
        )
          command.close();
      }
    };
    addEventListener("keydown", (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
        e.preventDefault();
        command.open ? command.close() : open();
      }
    });
    $("#command-input").oninput = render;
    $("#command-input").onkeydown = (e) => {
      if (["ArrowDown", "ArrowUp"].includes(e.key) && results.length) {
        e.preventDefault();
        index =
          (index + (e.key === "ArrowDown" ? 1 : -1) + results.length) %
          results.length;
        $$("#command-results button").forEach((b, i) =>
          b.setAttribute("aria-selected", i === index),
        );
        $("#command-input").setAttribute(
          "aria-activedescendant",
          "command-result-" + index,
        );
        $("#command-result-" + index).scrollIntoView({ block: "nearest" });
      }
      if (e.key === "Enter" && results[index]) {
        e.preventDefault();
        location.href = results[index][2];
      }
    };
  }
  const crt = $("#crt-container");
  if (crt) {
    window.sdou_createScene = ({
      width = 1280,
      height = 720,
      container,
      captions = [
        { text: "Thoughtful tools.", start: 0, end: 5 },
        { text: "Made for people.", start: 5, end: 10 },
        { text: "Starlit Digital.", start: 10, end: 16 },
      ],
      duration = 18,
    } = {}) => {
      const canvas = document.createElement("canvas");
      canvas.width = width;
      canvas.height = height;
      canvas.setAttribute("role", "img");
      canvas.setAttribute(
        "aria-label",
        "A Starlit caption rendered as phosphor contours",
      );
      container.append(canvas);
      const ctx = canvas.getContext("2d");
      const seek = (t) => {
        t = Math.max(0, Math.min(duration, t));
        ctx.clearRect(0, 0, width, height);
        ctx.fillStyle = "#09151f";
        ctx.fillRect(0, 0, width, height);
        const caption = captions.find((c) => t >= c.start && t < c.end);
        for (let i = 0; i < 32; i++) {
          ctx.beginPath();
          ctx.strokeStyle = `rgba(121,183,181,${0.03 + (i % 3) * 0.012})`;
          for (let x = 0; x <= width; x += 10) {
            const y =
              height * 0.5 +
              Math.sin(x * 0.006 + t * 0.3 + i * 0.13) * height * 0.2 +
              i * 4;
            x ? ctx.lineTo(x, y) : ctx.moveTo(x, y);
          }
          ctx.stroke();
        }
        if (caption) {
          const age = t - caption.start,
            remaining = caption.end - t,
            fade = Math.min(1, age / 0.7, remaining / 0.6),
            z = Math.sin((Math.min(1, age / 1.5) * Math.PI) / 2);
          ctx.save();
          ctx.textAlign = "center";
          ctx.textBaseline = "middle";
          const size = width / (caption.text.length * 0.64);
          ctx.font = `500 ${size}px Georgia`;
          ctx.translate(width * 0.5, height * 0.48);
          ctx.scale(0.94 + z * 0.06, 0.94 + z * 0.06);
          for (let i = 18; i >= 0; i--) {
            ctx.lineWidth = 0.5;
            ctx.strokeStyle = `rgba(121,183,181,${fade * (0.02 + (18 - i) * 0.004)})`;
            ctx.strokeText(caption.text, i * 0.8, -i * 0.6);
          }
          ctx.shadowColor = "#79b7b5";
          ctx.shadowBlur = 20;
          ctx.fillStyle = `rgba(242,231,212,${fade})`;
          ctx.fillText(caption.text, 0, 0);
          ctx.restore();
          canvas.setAttribute("aria-label", caption.text);
        }
        const vignette = ctx.createRadialGradient(
          width / 2,
          height / 2,
          0,
          width / 2,
          height / 2,
          width * 0.6,
        );
        vignette.addColorStop(0, "transparent");
        vignette.addColorStop(1, "#000b");
        ctx.fillStyle = vignette;
        ctx.fillRect(0, 0, width, height);
        for (let y = 0; y < height; y += 4) {
          ctx.fillStyle = "#0003";
          ctx.fillRect(0, y, width, 1);
        }
        ctx.fillStyle = "#e8c58e";
        ctx.font = "14px monospace";
        ctx.fillText("STARLIT / PHOSPHOR NOTES", width * 0.06, height * 0.9);
      };
      seek(0);
      return { duration, width, height, canvas, seek };
    };
    window.sdou_scene = window.sdou_createScene({ container: crt });
    let playing = false,
      origin = 0,
      at = 0,
      frame;
    const seek = (t) => {
      at = t;
      window.sdou_scene.seek(t);
      $("#crt-seek").value = t;
      $("#crt-time").value = t.toFixed(1) + "s";
    };
    const tick = (now) => {
      if (!playing) return;
      seek(((now - origin) / 1000) % window.sdou_scene.duration);
      frame = requestAnimationFrame(tick);
    };
    $("#crt-play").onclick = () => {
      playing = !playing;
      $("#crt-play").textContent = playing ? "Pause" : "Play";
      $("#crt-play").setAttribute("aria-pressed", playing);
      if (playing) {
        origin = performance.now() - at * 1000;
        frame = requestAnimationFrame(tick);
      } else cancelAnimationFrame(frame);
    };
    $("#crt-seek").oninput = (e) => {
      playing = false;
      cancelAnimationFrame(frame);
      $("#crt-play").textContent = "Play";
      $("#crt-play").setAttribute("aria-pressed", "false");
      seek(+e.target.value);
    };
    if (new URLSearchParams(location.search).has("paused")) seek(0);
  }
})();

PHP integration

In your own application, PHP can render this HTML on the server. Here, the example is escaped text only. The library has no PHP runner or execution endpoint. The browser owns the interaction.

<?php
// Server rendering example, not a payment or mailing endpoint.
declare(strict_types=1);
$heading = 'Sticky navigation';
$e = static fn (string $value): string =>
    htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
?>
<section aria-labelledby="example-heading">
  <h2 id="example-heading"><?= $e($heading) ?></h2>
  <?php
  // Include the trusted component HTML shown above from your own file.
  // Never build this path from a request parameter.
  require __DIR__ . '/partials/sticky-glass-navbar.html';
  ?>
</section>

Open the PHP rendering source

API and dependencies

The HTML section lists the actual selectors, IDs, classes and data attributes used by the example. Preserve IDs referenced by labels and JavaScript, and make them unique when composing a page. The shared controller is a demonstration bundle, not a backend service.

For PHP, save the body markup above in the fixed partial path shown, and load its linked CSS and scripts once in your page head. Escape dynamic text at output. Never insert untrusted HTML, URLs or script fragments into the partial.

Form, plan and dashboard outcomes are local simulations. A production submission needs its own validated endpoint, abuse controls and honest delivery result. Decorative studies need integration specific review before production use.

Testing and limitations

Open and close the narrow menu, follow an anchor and Tab to content near the sticky edge. Check the focused item is visible.

These visual studies are learning examples. Their presence here is not a claim that each is deployed across Starlit products or fully audited. Check motion changes, keyboard focus, status announcements and content equivalents in the final host.

Production review still needs assistive technology, touch, zoom, custom styles and representative content. See our testing scope and known gaps. Report a barrier to Starlit.