@font-face {
  font-family: 'Circular Std';
  src: url('media/CircularStd-Book.woff2') format('woff2');
  font-weight: 400;
  /* Preloaded and cached, so it is almost always ready on first paint; brief
     invisible text beats a visible jump from the fallback font. */
  font-display: block;
}

:root {
  --bg: #7BCFE3;
  --ink: #16161a;
  --font: 'Circular Std', -apple-system, BlinkMacSystemFont, 'Helvetica Neue', sans-serif;
  --gutter: clamp(1.25rem, 5vw, 3rem);
  --max: 1200px;
  /* Öi palette */
  --cyan: #7BCFE3; --peach: #FCC172; --green: #8CDD81; --pink: #FF92BB;
  --purple: #A771D1; --coral: #EA4B5F; --blue: #3D7DC9;
}

* { box-sizing: border-box; }
html { background: var(--bg); scroll-behavior: smooth; }
/* Nav links land each section just below the sticky header. "How to play" lands
   exactly at its top, where its sticky stage locks in place and the demo starts. */
.video, .characters { scroll-margin-top: 5rem; }
.how { scroll-margin-top: 0; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 1.125rem;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  transition: background-color 0.9s ease, color 0.9s ease;
}
body.playing { transition: none; }

h1, h2, h3, p { font-weight: 400; margin: 0; text-wrap: pretty; }
a { color: inherit; }
img { display: block; max-width: 100%; height: auto; }

a:focus-visible, button:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 4px;
  border-radius: 6px;
}

.badge { display: inline-block; text-decoration: none; }
.badge img { height: 56px; width: auto; }
.badge-small img { height: 40px; }

/* ---- Nav ---------------------------------------------------------------- */
.nav {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 2rem;
  /* Full-width background; the contents line up with the page's max width. */
  padding: 1rem max(var(--gutter), (100% - var(--max)) / 2 + var(--gutter));
  background: var(--bg);
  transition: inherit;
}
.brand { display: flex; align-items: center; gap: 0.6rem; text-decoration: none; font-size: 1.6rem; }
.brand img { width: 40px; height: 40px; border-radius: 10px; }
.nav nav { display: flex; gap: 1.75rem; margin-left: auto; }
.nav nav a { text-decoration: none; }
.nav nav a:hover { text-decoration: underline; text-underline-offset: 4px; }

/* ---- Hero --------------------------------------------------------------- */
.hero {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  align-items: center;
  gap: clamp(2rem, 6vw, 5rem);
  max-width: var(--max);
  margin: 0 auto;
  padding: clamp(2rem, 5vw, 4rem) var(--gutter) clamp(4rem, 8vw, 7rem);
}
.hero h1 { font-size: clamp(3rem, 7.5vw, 6.25rem); line-height: 1; letter-spacing: -0.03em; }
.hero .sub { font-size: clamp(1.25rem, 2.2vw, 1.6rem); line-height: 1.35; margin: 1.5rem 0 2.25rem; max-width: 30rem; }
.hero-phone { display: flex; justify-content: center; }

/* ---- Phone frame: one bevel for every phone on the site ------------------
   A 390 x 844 pt screen with 55 pt corners, a 12 pt bezel (so 67 pt outer
   corners) and a 126 x 37 pt Dynamic Island 11 pt from the top. Everything is
   a percentage of the frame itself, so the bevel looks the same at any size. */
.device, .phone {
  position: relative;
  aspect-ratio: 414 / 868;
  padding: 0;
  border-radius: 16.18% / 7.72%;
  background: #fff;
}
.device > img, .device > .phone-screen, .phone > .phone-screen {
  position: absolute;
  left: 2.9%; top: 1.38%;
  width: 94.2%; height: 97.24%; /* set explicitly: images don't stretch between insets */
  aspect-ratio: auto;
  border-radius: 14.1% / 6.52%;
  overflow: hidden;
}
.device::after, .phone::after {
  content: '';
  position: absolute;
  left: 34.78%; width: 30.43%;
  top: 2.65%; height: 4.26%;
  border-radius: 99px;
  background: #16161a;
}

.device { width: min(100%, 300px); box-shadow: 0 30px 60px rgb(0 0 0 / 0.18); }

/* ---- Video -------------------------------------------------------------- */
.video { max-width: var(--max); margin: 0 auto; padding: 0 var(--gutter) clamp(4rem, 8vw, 7rem); } /* the sticky stage above already leaves space */
.video-frame { position: relative; aspect-ratio: 16 / 9; }
.video-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* ---- Character screen: the app's colour bands with the character on top --- */
.screen {
  position: relative;
  container-type: inline-size;
  aspect-ratio: 390 / 844;
  overflow: hidden;
  background: linear-gradient(to bottom,
    var(--b1) 0 25.36%, var(--b2) 25.36% 41.79%, var(--b3) 41.79% 58.21%,
    var(--b4) 58.21% 74.64%, #000 74.64% 100%);
  color: #fff;
}
.screen .sprite {
  position: absolute;
  left: var(--spr-left);
  top: var(--spr-top);
  width: var(--spr-w);
  height: var(--spr-h);
  background-repeat: no-repeat;
}
.screen .label {
  position: absolute;
  left: 0; right: 0;
  top: 74.64%; bottom: 0;
  display: grid;
  place-items: center;
  font-size: 9cqw;
}
.screen .top-text {
  position: absolute;
  left: 6%; right: 6%;
  top: 9%;
  color: #16161a;
  font-size: 6.2cqw;
}
.screen .bottom-text {
  position: absolute;
  left: 10%; right: 10%;
  top: 74.64%; bottom: 0;
  display: grid;
  place-items: center;
  text-align: center;
  font-size: 4.1cqw;
  line-height: 1.35;
}
.screen .mouth {
  position: absolute;
  left: 39%; width: 22%;
  top: 34%;
  transform-origin: 50% 70%;
}

/* ---- Characters carousel ------------------------------------------------ */
.characters {
  /* Fills the screen below the nav, with the strip as big as the height allows. */
  --tile-h: clamp(325px, calc(100svh - 19rem), 700px);
  min-height: calc(100svh - 5rem);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 1.5rem 0 clamp(3rem, 6vw, 5rem);
}
.section-head { width: 100%; max-width: var(--max); margin: 0 auto; padding: 0 var(--gutter); }
.characters h2, .how h2 { font-size: clamp(2.25rem, 5vw, 3.75rem); line-height: 1.05; letter-spacing: -0.02em; }
.section-sub { margin: 0.75rem 0 2.5rem; font-size: 1.25rem; }

.carousel { overflow: hidden; }
.track {
  display: flex;
  width: max-content;
  margin: 0;
  padding: 0;
  list-style: none;
  animation: marquee 48s linear infinite;
}
.carousel:hover .track, .carousel:focus-within .track { animation-play-state: paused; }
@keyframes marquee { to { transform: translateX(-50%); } }

/* Each character is a bare app screen; the tiles butt up against each other. */
.character {
  display: block;
  width: calc(var(--tile-h) * 390 / 844);
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  cursor: pointer;
}
.character:focus-visible { outline: 4px solid #fff; outline-offset: -4px; }
.character .screen { display: block; }
/* Overlap each tile by 1px so no hairline of page colour shows between them
   while the track moves by fractions of a pixel. */
.track li { margin-right: -1px; }

/* ---- How to play: scroll-driven demo ------------------------------------ */
.how { position: relative; height: 465vh; }
.how-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  align-items: center;
  gap: clamp(2rem, 5vw, 4rem);
  max-width: var(--max);
  margin: 0 auto;
  padding: 5rem var(--gutter) 2rem;
}
.how-steps { list-style: none; margin: 2rem 0 0; padding: 0; display: grid; gap: 1.25rem; counter-reset: step; }
.how-steps li { opacity: 0.35; transition: opacity 0.3s ease; }
.how-steps li.active { opacity: 1; }
/* Numbered explicitly: on small screens the inactive steps are display:none and would not count. */
.how-steps li:nth-child(1) { counter-set: step 1; }
.how-steps li:nth-child(2) { counter-set: step 2; }
.how-steps li:nth-child(3) { counter-set: step 3; }
.how-steps li:nth-child(4) { counter-set: step 4; }
.how-steps h3 { font-size: clamp(1.4rem, 2.4vw, 1.9rem); line-height: 1.2; }
.how-steps h3::before { content: counter(step) '  '; }
.how-steps p { margin-top: 0.2rem; }

/* The stage: a square scene with rounded corners. */
.room {
  position: relative;
  aspect-ratio: 1;
  max-height: calc(100vh - 7rem);
  justify-self: center;
  width: 100%;
  border-radius: 36px;
  overflow: hidden;
}

/* The demo phone, in modern iPhone proportions (390 x 844 points). */
.phone {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 34%;
  box-shadow: 0 10px 30px rgb(0 0 0 / 0.15);
  translate: -50% -50%;
  will-change: transform;
}
.phone-screen .screen { position: absolute; inset: 0; width: 100%; height: 100%; }
.phone-strip { position: absolute; inset: 0; display: flex; will-change: transform; }
.phone-strip .screen { position: relative; flex: 0 0 100%; }

.rings { position: absolute; left: 50%; top: 72%; width: 0; height: 0; opacity: 0; }
.rings span {
  position: absolute;
  left: -40px; top: -40px;
  width: 80px; height: 80px;
  border: 4px solid #fff;
  border-radius: 50%;
  opacity: 0;
}
.room.listening .rings { opacity: 1; }
.room.listening .rings span { animation: ring 1.8s ease-out infinite; }
.room.listening .rings span:nth-child(2) { animation-delay: 0.6s; }
.room.listening .rings span:nth-child(3) { animation-delay: 1.2s; }
@keyframes ring { from { transform: scale(0.4); opacity: 0.9; } to { transform: scale(3.2); opacity: 0; } }

.call {
  position: absolute;
  padding: 0.35em 0.7em;
  border-radius: 999px;
  background: #fff;
  color: #16161a;
  font-size: clamp(1.1rem, 2.4vw, 1.8rem);
  line-height: 1;
  opacity: 0;
  scale: 0.4;
  transition: opacity 0.25s ease, scale 0.35s cubic-bezier(0.3, 1.6, 0.5, 1);
}
.call.on { opacity: 1; scale: 1; }

/* ---- The dollhouse: a cut-away house in the Öi palette. The phone hides in
   the toy box, its calls ripple through the rooms, and a torch searches the
   fridge and the sofa before finding it. Driven by how.js. */
.house-stage { background: var(--blue); }

.sun { position: absolute; left: 7%; top: 7%; width: 13%; aspect-ratio: 1; border-radius: 50%; background: var(--peach); }
.ground { position: absolute; left: 0; right: 0; bottom: 0; height: 11%; background: var(--green); }
.roof {
  position: absolute;
  left: 9%; right: 9%; top: 9%; height: 24%;
  background: var(--coral);
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}
.chimney { position: absolute; z-index: 0; left: 68%; top: 12%; width: 6%; height: 12%; background: var(--coral); filter: brightness(0.85); }
.roof { z-index: 1; }
.house {
  position: absolute;
  z-index: 1;
  left: 14%; right: 14%; top: 32.5%; bottom: 10.5%;
  display: grid;
  grid-template: 1fr 1fr / 1fr 1fr;
  gap: 2.2%;
  padding: 2.2%;
  background: #fff;
}
.rm { position: relative; overflow: hidden; border-radius: 8px; }
.rm > div { position: absolute; }
.bedroom { background: var(--cyan); }
.kitchen { background: var(--green); }
.living { background: var(--peach); }
.playroom { background: var(--pink); }

/* Bedroom */
.window { left: 12%; top: 14%; width: 22%; height: 32%; border-radius: 6px; background:
  linear-gradient(#fff, #fff) 50% 0 / 8% 100% no-repeat,
  linear-gradient(#fff, #fff) 0 50% / 100% 8% no-repeat, var(--blue); border: 4px solid #fff; }
.headboard { left: 8%; bottom: 0; width: 7%; height: 52%; border-radius: 8px 8px 0 0; background: var(--coral); }
.bed { left: 8%; bottom: 0; width: 80%; height: 20%; background: var(--coral); }
.pillow { left: 16%; bottom: 20%; width: 17%; height: 13%; border-radius: 999px; background: #fff; }
.duvet { left: 31%; bottom: 14%; width: 57%; height: 18%; border-radius: 12px 12px 4px 4px; background: var(--purple); }

/* Kitchen */
.shelf { left: 8%; top: 30%; width: 38%; height: 4%; background: #fff; }
.jar { bottom: 70%; width: 9%; height: 13%; border-radius: 4px 4px 6px 6px; background: var(--peach); }
.j1 { left: 13%; } .j2 { left: 27%; background: var(--coral); height: 10%; }
.counter { left: 0; bottom: 0; width: 52%; height: 34%; background: var(--blue); border-top: 6px solid #fff; }
.fridge { right: 8%; bottom: 0; width: 28%; height: 78%; border-radius: 8px 8px 0 0; background:
  repeating-linear-gradient(to bottom, transparent 0 22%, rgb(0 0 0 / 0.12) 22% 25%), #f4f1ea; }
.fridge-door { position: absolute; inset: 0; border-radius: 8px 8px 0 0; background: #fff; transform-origin: 100% 50%; will-change: transform; }
.fridge-door::after { content: ''; position: absolute; left: 12%; top: 30%; width: 8%; height: 18%; border-radius: 99px; background: #16161a; }

/* Living room */
.picture { left: 40%; top: 13%; width: 20%; height: 24%; border: 4px solid #fff; background: var(--green); }
.lamp { right: 4%; bottom: 0; width: 3%; height: 56%; background: #16161a; }
.lamp::before { content: ''; position: absolute; left: -200%; top: -12%; width: 500%; height: 22%; border-radius: 4px 4px 0 0; background: var(--cyan); clip-path: polygon(20% 0, 80% 0, 100% 100%, 0 100%); }
.sofa-b { left: 12%; bottom: 8%; width: 74%; height: 42%; border-radius: 16px 16px 6px 6px; background: var(--blue); }
.arm { bottom: 8%; width: 11%; height: 28%; border-radius: 12px; background: var(--blue); filter: brightness(0.9); }
.arm-l { left: 6%; } .arm-r { left: 81%; }
.sofa-seat { left: 17%; bottom: 8%; width: 64%; height: 17%; border-radius: 10px; background: var(--purple); transform-origin: 90% 100%; will-change: transform; }

/* Playroom */
.ball { left: 10%; bottom: 0; width: 17%; aspect-ratio: 1; border-radius: 50%; background:
  linear-gradient(to bottom, transparent 42%, #fff 42% 58%, transparent 58%), var(--blue); }
.toybox, .box-front { border-radius: 6px 6px 0 0; background:
  linear-gradient(to bottom, transparent 40%, var(--peach) 40% 52%, transparent 52%), var(--coral); }
.toybox { right: 10%; bottom: 0; width: 46%; height: 40%; }
/* A copy of the toy box drawn over the phone, so it can drop inside. Placed by how.js. */
.box-front { position: absolute; z-index: 5; pointer-events: none; }
.lid { position: absolute; left: -5%; right: -5%; top: -20%; height: 20%; border-radius: 6px; background: var(--peach); transform-origin: 0 100%; will-change: transform; }

/* Search and sound */
/* Night falls for the search: a moon over the sun and a few stars, drawn above the dark. */
.night { position: absolute; inset: 0; z-index: 3; pointer-events: none; opacity: 0; }
.moon { position: absolute; left: 6.7%; top: 6.7%; width: 13.6%; /* a touch bigger than the sun it covers */ aspect-ratio: 1; border-radius: 50%; background: #fff4d6;
  /* Cut the crescent with a mask rather than painting a dark disc over it, which left a hairline of moon on its edge. */
  -webkit-mask-image: radial-gradient(50% 50% at 84% 36%, transparent 98%, #000 100%);
  mask-image: radial-gradient(50% 50% at 84% 36%, transparent 98%, #000 100%); }
.night i { position: absolute; width: 1.1%; aspect-ratio: 1; border-radius: 50%; background: #fff; animation: twinkle 1.6s ease-in-out infinite alternate; }
.night i:nth-of-type(1) { left: 29%; top: 8%; }
.night i:nth-of-type(2) { left: 41%; top: 3.5%; animation-delay: 0.4s; }
.night i:nth-of-type(3) { left: 61%; top: 5%; animation-delay: 0.9s; }
.night i:nth-of-type(4) { left: 82%; top: 9%; animation-delay: 0.2s; }
.night i:nth-of-type(5) { left: 91%; top: 20%; animation-delay: 1.2s; }
.night i:nth-of-type(6) { left: 6%; top: 27%; animation-delay: 0.7s; }
@keyframes twinkle { from { opacity: 1; } to { opacity: 0.35; } }
/* The dollhouse rings burst once per call (how.js) instead of pulsing. */
.house-stage.listening .rings span { animation: none; }
.torch {
  position: absolute; inset: 0; z-index: 2; pointer-events: none; opacity: 0;
  background: radial-gradient(circle at var(--tx, 50%) var(--ty, 50%), transparent 0 var(--tr, 80px), rgb(12 14 32 / 0.74) calc(var(--tr, 80px) + 1.5px));
}
.house-stage .rings { z-index: 3; }
.peek {
  position: absolute; z-index: 5;
  translate: -50% -100%;
  padding: 0.2em 0.6em;
  border-radius: 999px;
  background: #fff;
  font-size: clamp(1.2rem, 2.4vw, 1.8rem);
  line-height: 1;
  opacity: 0; scale: 0.4;
  transition: opacity 0.2s ease, scale 0.3s cubic-bezier(0.3, 1.6, 0.5, 1);
}
.peek.on { opacity: 1; scale: 1; }
.scrim { position: absolute; inset: 0; z-index: 3; background: rgb(255 255 255 / 0.55); pointer-events: none; }
.house-stage .phone { z-index: 4; transform-origin: 50% 50%; }
.house-stage .call { z-index: 6; translate: -50% -50%; }

/* ---- Footer ------------------------------------------------------------- */
.footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.5rem 2rem;
  max-width: var(--max);
  margin: 0 auto;
  padding: 2.5rem var(--gutter) max(2.5rem, env(safe-area-inset-bottom));
}
.footer nav { display: flex; gap: 1.5rem; }
.footer span { margin-left: auto; opacity: 0.75; }

/* Sub-pages */
.page { max-width: 44rem; margin: 0 auto; padding: clamp(2rem, 5vw, 4rem) var(--gutter) clamp(3rem, 6vw, 5rem); }
.page h1 { font-size: clamp(2.5rem, 7vw, 4rem); line-height: 1.05; letter-spacing: -0.02em; margin-bottom: 1rem; }
.prose { font-size: 1.15rem; line-height: 1.55; }
.prose .lede { font-size: 1.35rem; line-height: 1.4; }
.prose h2 { font-size: 1.6rem; line-height: 1.2; margin: 2.5rem 0 0.75rem; }
.prose p + p, .prose ol + p { margin-top: 1rem; }
.prose ol { margin: 0; padding-left: 1.4rem; }
.prose li + li { margin-top: 0.4rem; }
.prose strong { font-weight: inherit; } /* app button names; the font has one weight */
.nav a[aria-current], .footer a[aria-current] { text-decoration-thickness: 3px; }

/* Support form */
.contact { display: grid; gap: 1.25rem; margin-top: 2rem; }
.contact label { display: grid; gap: 0.4rem; }
.contact .opt { opacity: 0.7; }
.contact input, .contact textarea {
  width: 100%;
  padding: 0.8rem 1rem;
  border: 0;
  border-radius: 14px;
  background: #fff;
  color: #16161a;
  font: inherit;
}
.contact textarea { resize: vertical; min-height: 9rem; }
.contact input:focus-visible, .contact textarea:focus-visible, .contact button:focus-visible { outline: 3px solid #16161a; outline-offset: 2px; }
.contact .hp { position: absolute; left: -9999px; }
.contact .note { font-size: 1rem; opacity: 0.85; }
.contact button {
  justify-self: start;
  padding: 0.85rem 1.6rem;
  border: 0;
  border-radius: 999px;
  background: #16161a;
  color: #fff;
  font: inherit;
  cursor: pointer;
}
.contact button:disabled { opacity: 0.6; cursor: progress; }
.contact .status:empty { display: none; }
.contact .status.err { padding: 0.8rem 1rem; border-radius: 14px; background: #fff; color: #b3261e; }


@media (max-width: 860px) {
  .nav nav { display: none; }
  .nav .badge-small { margin-left: auto; }
  .hero { grid-template-columns: 1fr; text-align: center; }
  .hero .sub { margin-left: auto; margin-right: auto; }
  .device { width: min(64%, 260px); }
  .how-stage { grid-template-columns: 1fr; align-content: center; gap: 1rem; padding-top: 4.5rem; }
  .how-steps { margin-top: 0.75rem; }
  .how-steps li { display: none; }
  .how-steps li.active { display: block; }
  .room { width: min(100%, 56vh); max-height: none; }
  .footer span { margin-left: 0; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  body, .nav, .how-steps li, .call, .peek { transition: none; }
  .track { animation: none; }
  .carousel { overflow-x: auto; scroll-snap-type: x mandatory; }
  .track li { scroll-snap-align: start; }
  .room.listening .rings span { animation: none; opacity: 0.6; transform: scale(1.6); }
  .night i { animation: none; }
}
