# Domain Switch: Dark Mode

> A landing page's theme toggle. Dark mode opens from the button as a domain and takes the page over, with a seam of stars at its edge; press again to draw it back in.

A shadcn/ui block from the [@keyframeui](https://keyframeui.com/?utm_source=shadcn.exchange) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/keyframeui/domain-switch-demo).

- Page, with a live preview: https://shadcn.exchange/r/keyframeui/domain-switch-demo
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/keyframeui/domain-switch-demo-light-0f27e15aef0dec9d.png
- Registry item: https://keyframeui.com/r/domain-switch-demo.json
- Categories: toggle, theme, transition, canvas
- Listed: 2026-10-23, source last changed 2026-10-23

## Install

```bash
npx shadcn@latest add https://shadcn.exchange/r/keyframeui/domain-switch-demo.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- Registry items: `https://keyframeui.com/r/domain-switch.json`

## Notes from the registry

Live preview, examples and props: https://keyframeui.com/components/domain-switch#domain-switch-demo

## Files

### `registry/demos/domain-switch-demo.tsx`

```tsx
"use client";

import * as React from "react";

import { cn } from "@/lib/utils";
import { DomainSwitch, DomainSwitchScope, DomainSwitchToggle } from "@/components/ui/domain-switch";

export function DomainSwitchDemo() {
  const [dark, setDark] = React.useState(false);

  return (
    <div className="w-full overflow-hidden rounded-xl border border-zinc-200 dark:border-zinc-800">
      <DomainSwitch checked={dark} onCheckedChange={setDark}>
        <DomainSwitchScope
          className="h-[var(--demo-height,560px)]"
          outside={<Landing dark={false} />}
          inside={<Landing dark />}
        />
      </DomainSwitch>
    </div>
  );
}

function Landing({ dark }: { dark: boolean }) {
  return (
    <div
      className={cn(
        "relative flex h-full flex-col overflow-hidden",
        dark ? "bg-[#09090c] text-zinc-100" : "bg-[#fbfbfa] text-zinc-900",
      )}
    >
      {dark && (
        <div
          aria-hidden
          className="pointer-events-none absolute inset-x-0 top-0 h-72 bg-[radial-gradient(60%_100%_at_50%_0%,rgba(129,140,248,0.16),transparent)]"
        />
      )}
      <nav className="relative flex items-center gap-6 px-5 py-4 sm:px-8">
        <span className="flex items-center gap-2 text-sm font-semibold tracking-tight">
          <span
            className={cn(
              "grid size-6 place-items-center rounded-md text-[11px] font-bold",
              dark ? "bg-indigo-400 text-[#09090c]" : "bg-zinc-900 text-white",
            )}
          >
            T
          </span>
          Tidal
        </span>
        <div className={cn("hidden gap-5 text-sm sm:flex", dark ? "text-zinc-400" : "text-zinc-500")}>
          <span>Product</span>
          <span>Pricing</span>
          <span>Docs</span>
        </div>
        <div className="ml-auto flex items-center gap-2">
          <DomainSwitchToggle
            aria-label="Dark mode"
            className={cn(
              "size-9 rounded-full border",
              dark
                ? "border-white/10 bg-white/5 text-indigo-200 hover:bg-white/10"
                : "border-zinc-200 bg-white text-zinc-700 shadow-xs hover:bg-zinc-50",
            )}
          >
            {dark ? <MoonIcon /> : <SunIcon />}
          </DomainSwitchToggle>
          <a
            href="#"
            className={cn(
              "hidden rounded-full px-4 py-2 text-sm font-medium sm:block",
              dark ? "bg-zinc-100 text-zinc-900" : "bg-zinc-900 text-white",
            )}
          >
            Sign in
          </a>
        </div>
      </nav>

      <section className="relative mx-auto flex max-w-2xl flex-col items-center px-5 pt-8 text-center sm:pt-12">
        <span
          className={cn(
            "rounded-full border px-3 py-1 text-xs",
            dark ? "border-indigo-400/25 bg-indigo-400/10 text-indigo-200" : "border-zinc-200 bg-white text-zinc-600",
          )}
        >
          New: answers in Slack
        </span>
        <h1 className="mt-5 text-3xl font-semibold tracking-tight text-balance sm:text-5xl/[1.05]">
          Analytics that answer back.
        </h1>
        <p className={cn("mt-4 max-w-md text-sm text-pretty sm:text-base", dark ? "text-zinc-400" : "text-zinc-600")}>
          Ask a question in plain words. Tidal writes the query, checks it and draws the chart.
        </p>
        <div className="mt-6 flex gap-2">
          <a
            href="#"
            className={cn(
              "rounded-full px-5 py-2.5 text-sm font-medium",
              dark ? "bg-indigo-400 text-[#09090c]" : "bg-zinc-900 text-white",
            )}
          >
            Start free
          </a>
          <a
            href="#"
            className={cn(
              "rounded-full border px-5 py-2.5 text-sm font-medium",
              dark ? "border-white/10 text-zinc-200" : "border-zinc-200 bg-white text-zinc-800",
            )}
          >
            Book a demo
          </a>
        </div>
      </section>

      <section className="relative mx-auto mt-10 grid w-full max-w-3xl grid-cols-1 gap-3 px-5 sm:grid-cols-2 sm:px-8">
        <Card dark={dark} title="Live queries" body="Weekly signups, by channel">
          <svg viewBox="0 0 200 48" className="h-12 w-full" aria-hidden>
            <path
              d="M0 40 L20 36 L40 38 L60 28 L80 30 L100 20 L120 24 L140 14 L160 16 L180 8 L200 10"
              fill="none"
              strokeWidth="2"
              strokeLinecap="round"
              strokeLinejoin="round"
              className={dark ? "stroke-indigo-300" : "stroke-zinc-900"}
            />
          </svg>
        </Card>
        <Card dark={dark} title="Shared boards" body="Three people are looking at Q3">
          <div className="flex h-12 items-center -space-x-2">
            {["bg-amber-300", "bg-sky-300", "bg-rose-300"].map((color) => (
              <span
                key={color}
                className={cn("size-8 rounded-full border-2", color, dark ? "border-[#121217]" : "border-white")}
              />
            ))}
          </div>
        </Card>
      </section>
    </div>
  );
}

function Card({
  dark,
  title,
  body,
  children,
}: {
  dark: boolean;
  title: string;
  body: string;
  children: React.ReactNode;
}) {
  return (
    <div
      className={cn(
        "rounded-2xl border p-4",
        dark ? "border-white/[0.07] bg-[#121217]" : "border-zinc-200 bg-white shadow-xs",
      )}
    >
      {children}
      <p className="mt-3 text-sm font-medium">{title}</p>
      <p className={cn("text-xs", dark ? "text-zinc-500" : "text-zinc-500")}>{body}</p>
    </div>
  );
}

function SunIcon() {
  return (
    <svg viewBox="0 0 24 24" className="size-4" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
      <circle cx="12" cy="12" r="4" />
      <path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4" />
    </svg>
  );
}

function MoonIcon() {
  return (
    <svg viewBox="0 0 24 24" className="size-4" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M20.5 14.1A8.5 8.5 0 1 1 9.9 3.5a7 7 0 0 0 10.6 10.6Z" />
    </svg>
  );
}
```
