Sunlight streams down through blue water onto a coral reef, where jellyfish drift and garden eels peek out of the sand.
Buy tickets

Open daily, 9:30–17:30

The ocean, lit from within.

Drift past glowing jellies, a three-story kelp forest and one very clever octopus. Six living worlds on Harborview’s waterfront, and an axolotl called Gilly to show you around.

Today at Tidelight

Feedings, talks and a penguin parade

Every talk is free with your ticket. Come a few minutes early for a spot by the glass.

First up

10:30

Otter breakfast

Otter Cove · 15 min

  1. Otter breakfast

    Pip and Marlo crack their clams while floating on their backs, and a keeper explains how otters stay warm without any blubber.

    Otter Cove · 15 min

  2. Jelly glow talk

    The lights go down in the jelly gallery: how moon jellies pulse, glow and get by without a brain.

    Jellyfish Lanterns · 20 min

  3. Octopus enrichment

    Juniper gets a brand-new puzzle box. Last week she had it open in four minutes flat.

    Octopus Den · 20 min

  4. Penguin parade

    Twenty-two little penguins waddle a lap of the Main Hall. Wave; they love an audience.

    Penguin Point to the Main Hall · 15 min

  5. Kelp forest dive

    A diver feeds the garibaldi and answers your questions through the glass.

    Kelp Cathedral · 20 min

  6. Axolotl Lagoon meet-up

    Meet Gilly’s real-life cousins and find out how an axolotl grows back a lost leg.

    Axolotl Lagoon · 20 min

  7. Quiet glow

    Ten calm minutes before closing: lights low, music off, just the jellies.

    Jellyfish Lanterns · 10 min

Exhibits

Six worlds under one roof

From sunlit kelp to the quiet glow of the deep, every gallery is built around the animals who live in it. Most visits take about two and a half hours. The otters make it hard to leave.

  • Level 1 · Blue Hall

    Jellyfish Lanterns

    A dark, hushed gallery of pulsing moon jellies, sea nettles and tiny comb jellies that shimmer like rainbows.

    Glow talk

  • Levels 1–3 · Atrium

    Kelp Cathedral

    A three-story kelp forest that sways in real surf. Look up through the canopy, or watch the garibaldi guard their patch.

    Forest dive

  • Level 2 · Rock Pools

    Octopus Den

    Juniper, our giant Pacific octopus, opens jars, changes color when she’s curious and knows exactly which keeper brings the crab.

    Enrichment

  • Level 1 · Harbor Deck

    Otter Cove

    Pip and Marlo, two rescued sea otters, with a rocky pool built for rolling, cracking shells and napping paw in paw.

    Breakfast

  • Level 2 · Penguin Point

    Penguin Point

    A pebble beach and a deep, clear pool for a colony of twenty-two little penguins, the smallest penguins in the world.

    Parade

  • Level 3 · Freshwater

    Axolotl Lagoon

    Smiling salamanders from the lakes of Mexico, with frilly gills and a talent for regrowing just about anything.

    Meet-up

Gilly, a pink cartoon axolotl

Meet Gilly

Questions? Ask the axolotl.

Gilly is Tidelight’s resident axolotl. Well, the cartoon one: the real ones are napping in Axolotl Lagoon. Gilly knows every feeding time, the step-free routes and the quietest hour for the jellies, and loves to talk about all of it.

  • Tap to chat

    Gilly lives in the corner of every page. Tap and ask anything about your visit.

  • Talk out loud

    Ask with your voice. Gilly answers aloud, with speech bubbles so you can read along.

  • Meet Gilly in your room

    On Apple Vision Pro or iPhone, Gilly swims off the page and into your space.

Tickets & hours

Come for the jellies. Stay all day.

Pick an entry time, then stay as long as you like. Book online and skip the ticket line.

Adult 13 and up
$32
Child 3 to 12
$18
Under 3 On a grown-up’s ticket
Free
Members Unlimited visits for a year, from $89
Free
  • Every talk, feeding and the penguin parade
  • Same-day re-entry, so you can lunch on the Quay
  • Free lockers, stroller parking and wheelchairs

Opening hours

Monday to Wednesday9:30–17:30
Thursday9:30–21:00
Friday to Sunday9:30–17:30

Last entry one hour before closing. Open every day of the year except December 25.

Plan your visit

On the waterfront, a tram ride from anywhere

Tidelight Aquarium, 2 Lantern Quay, Harborview. Everything below is step-free, and every question you have, Gilly has probably heard before.

Map of Harborview’s waterfront: Tidelight Aquarium stands at the end of Lantern Quay, next to the tram stop, with Quayside Garage across Harbor Street and Harborview Central station a short walk along the boardwalk.
  • Tidelight Aquarium
  • Lantern Quay, tram 3
  • Quayside Garage
  • Harborview Central

Getting here

Tram 3 stops right outside at Lantern Quay. From Harborview Central it’s a ten-minute walk along the boardwalk. Quayside Garage is $9 for three hours with your ticket, and there are bike racks by the main doors.

Accessibility

Step-free throughout, with lifts to all three levels. Borrow a wheelchair or a sensory backpack at the front desk. Every talk is captioned, and Calm Mornings on the first Sunday of the month open at 8:30 with low lights and no music.

With little ones

Strollers are welcome everywhere, with stroller parking outside Otter Cove and Penguin Point. Baby changing on every level, and a quiet feeding room beside the jellies.

Food & drink

The Driftwood Café on Level 2 looks out over the harbor: chowder, grilled cheese, big salads and good coffee, 9:30–17:00. Picnics are welcome on the Quay deck.

How it works

A 3D character as the whole chat UI

There is no chat button and no chat window. Gilly is the interface: an animated axolotl who idles in the corner, answers out loud with a speech bubble that keeps pace with the voice, and listens when you talk back. The conversation behind the character is real: it runs on Stand's custom chat UI API, so an AI Stand-in answers, a person on the team can take over, and the history stays in Stand.

Try it

  1. Leave Gilly alone for a minute. Gilly gets bored: glances around, sighs, checks the time, blows bubbles, does a flip, sits down to wait, and finally dozes off.
  2. Move your pointer close and Gilly perks up and watches it. Click Gilly, or tab to Gilly and press Enter.
  3. Gilly startles awake, waves and says hello, lighting up each word as it's spoken. Ask something like When do the otters eat? Gilly leans in while you type, thinks while the answer is being written, then answers out loud.
  4. Tap the microphone to ask out loud (Chrome, Edge and Safari). The speaker button turns the voice off; everything still works as text.
  5. Close the bubble, or reload the page: the conversation picks up where it left off.
  6. On iPhone or iPad, choose See Gilly in your room in the chat's ⋯ menu or the Meet Gilly section. On Apple Vision Pro, Gilly is a real 3D model with depth, standing in a soft window into the page: pinch and drag Gilly out of the page into your room.
This page uses siteId: 'demo', Stand Chat's shared demo site, which works on any domain. Its demo Stand-in follows the page's private context but won't pretend to be a real aquarium. With your own Site ID, your own Stand-ins and team answer.

The pieces

1. Discover now, start on the first message

Discovery asks Stand who can answer; it's free and creates nothing. The conversation starts when the visitor sends a first message, together with the greeting Gilly already spoke and private context for whoever answers.

const api = 'https://api.stand.chat';
const query = new URLSearchParams({ siteId: 'demo', page: location.href, greetingsEnabled: 'false' });
const offer = await (await fetch(`${api}/v1/reps/find?${query}`, { credentials: 'omit' })).json();
// offer.available, offer.responderType ('standin' or 'rep'), offer.poweredByUrl…

// Later, on the visitor's first message:
const session = await (await fetch(`${api}/v1/sessions`, {
  method: 'POST',
  credentials: 'omit',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    siteId: 'demo',
    page: location.href,
    standinProfileId: offer.standinProfileId, // or repId for a person
    initialMessage: 'When do the otters eat?',
    includeOpeningGreeting: true,
    openingMessage: "Oh! Hi there! I'm Gilly…", // what Gilly already said
    prompt: 'Your replies are spoken aloud by Gilly, a cartoon axolotl… Today: …', // privateContext()
  }),
})).json();
// Keep session.sessionId and session.visitorToken for this conversation.

2. Replies arrive over a WebSocket

Messages go out over HTTP and come back over a socket. Canonical messages merge by messageId; live events let Gilly look thoughtful while an AI reply is being written.

const url = new URL(`wss://api.stand.chat/ws/sessions/${session.sessionId}`);
url.searchParams.set('token', session.visitorToken);
const socket = new WebSocket(url);
socket.onmessage = (event) => {
  const data = JSON.parse(event.data);
  if (data.type === 'standin.status' || data.type === 'typing') gilly.setState('thinking');
  else if (data.type === 'session.closed') showEnded();
  else if (data.event === 'message') mergeByMessageId(data); // then Gilly says it
};

Reconnects, reload recovery, retries that never send twice, and closing versus ending a chat are all in stand-client.js. They're the unglamorous half of a custom UI: read the guide's recovery chapter before shipping your own.

3. Speak, and keep the bubble in step

for (const sentence of splitSentences(text)) {  // Chrome cuts off long utterances
  const u = new SpeechSynthesisUtterance(sentence.text);
  u.pitch = 1.18; // a little higher: Gilly is small
  u.onboundary = (e) => onProgress(sentence.start + e.charIndex); // exact, where voices report words
  speechSynthesis.speak(u);
}
// Voices without word events: progress is estimated from the speaking rate.
// The same character index lights up the bubble and shapes Gilly's mouth.

Each letter maps to a mouth shape (open, wide or round) that blends into Gilly's face, so the lips move with the words, even with the voice muted. The first utterance has to start inside a tap on iOS, which is why Gilly greets you when you click.

4. Listen

const Recognition = window.SpeechRecognition || window.webkitSpeechRecognition;
const rec = new Recognition();
rec.interimResults = true; // words appear in the bubble as you speak
rec.onresult = (e) => (input.value = [...e.results].map((r) => r[0].transcript).join(''));
rec.onend = () => input.value && send(input.value);
rec.start();

Chrome sends the audio to Google to transcribe it, Safari to Apple, and Safari on Mac needs Siri turned on. Firefox has no speech recognition, so there the microphone button isn't shown.

5. Step out of the page

On iPhone and iPad, AR Quick Look puts gilly.usdz on your table. On Vision Pro, Safari's <model> element shows the same file with real depth, right in the page, and you can pinch and drag it into your room.

<a rel="ar" href="gilly.usdz"><img src="gilly.png" alt="See Gilly in your room"></a>

<model src="gilly.usdz"><img src="gilly.png" alt="Gilly"></model>

A USDZ holds a single animation timeline, so every mood Gilly has in the page (idle, waving, talking, listening, thinking, sighing…) was recorded from the web engine into one 46-second reel, with each clip starting and ending on the same pose. In the page, ar.js plays one clip at a time by seeking model.currentTime; Quick Look plays the whole reel as a loop. Serve USDZ as model/vnd.usdz+zip.

On Vision Pro, a <model> is drawn behind the page surface in an opaque box, and anything that comes in front of the surface is sliced off. So Gilly stands back from the surface by as far as each mood ever reaches, measured when the USDZ is built, and backs up before a flip. A CSS mask-image fades the box's edges into the page, like a spatial photo.

6. Make a character feel alive

Good to know

How this was made

This example is nearly a one-shot. Claude Opus 5.5, with max effort, in Claude Code, built it in one session from the prompt below, plus one follow-up asking for this box. It modeled and rigged Gilly with headless Blender scripts, wrote the animation engine and the chat, held real conversations with Stand's demo site in headless Chrome, judged the animation from filmstrips, and tested on the iOS and visionOS simulators. A sub-agent designed and illustrated the aquarium website in parallel, from a written brief.

A chat doesn't have to be a box in the corner. With AI writing the front end, it can be a character who lives on your site, while Stand's custom chat UI API keeps the conversation, the AI Stand-in and your team behind it.

The prompt, lightly edited

Let's add a super fancy example: an animated AR chat mascot, inspired by Meta's Muse avatars. [Two example images] Develop a unique, cute, animated avatar in Blender (its MCP server is available on this Mac). Create a custom chat UI: https://stand.chat/guide/custom-chat-ui - It's available through a 3D avatar sitting in the bottom-right corner of the page, replacing the chat button. - The avatar feels alive, but bored when not active: moving around, sitting, looking around… Draw inspiration from this meme. [The "waiting" meme] - When the avatar is tapped or clicked, it smiles and speaks out using the browser's built-in speech synthesis. - There is a speech bubble synced with this. - Another bubble lets you type your responses. If the platform easily exposes built-in speech recognition, make that available. All in all, this should feel playful. Be creative and add a suitable website for it to live in. Find a fun use case where such an avatar would feel at home. Now the hard part. We want to support AR-capable browsers, notably Apple Vision Pro, making the avatar actually 3D, and if web standards allow, letting you place it outside the page in the real environment. But it should also be usable on iPhone, Mac and Windows. On computers, we should support Safari and Chrome. Iterate this to top quality: character animations should feel natural, almost like watching a Pixar character. The UX should be polished, reliable and usable. Blender is probably in use by another chat, "Vintage Terminal chat UI". Coordinate with it to avoid conflicts.

The follow-up

This seems mostly a one-shot. Include the original prompt (clean it up as you choose) and the model used on the page, as a subtle expandable "How this was made" box. The intent is to help people create high-fidelity experiences like this on top of Stand Chat, now that AI is able to generate the front end.

If you try this yourself

  • Point the agent at the custom chat UI guide. It's written for coding agents.
  • Build on the demo Site ID, so every test is a real conversation, then switch to yours.
  • Have the character built by a script instead of by hand, so the agent can change a number and rebuild. Here, blender/ rebuilds Gilly in about 20 seconds.
  • Ask the agent to judge motion from filmstrips and to test in simulators, then try the AR yourself on a real device: simulators can't pinch, or place anything in a room.

Copy this example

npx degit standchat/examples/chat-mascot my-mascot

Set SITE_ID in chat.js to your Site ID and rewrite privateContext() with facts about your business. To make a character of your own, start from blender/gilly.py: every shape is a few numbers in blender/anatomy.py.