A visual guide to the pendant: where audio goes, what’s inside, what the light means, its limits, and how it fails.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Omi Developers","colors":{"primary":"#0D9373","light":"#55D799","dark":"#0D9373"},"favicon":"https://mintcdn.com/omi/kuqgaBKwHOGhyCBK/favicon.ico?fit=max\u0026auto=format\u0026n=kuqgaBKwHOGhyCBK\u0026q=85\u0026s=218cc921327f517a91e40d837c39d5c6","navbar":{"links":[{"href":"https://help.omi.me","label":"Support"},{"href":"https://github.com/BasedHardware/omi/blob/main/SECURITY.md","label":"Security"},{"href":"/doc/info/License","label":"License"}],"primary":{"type":"button","label":"Buy Now","href":"https://www.omi.me/cart/50230946562340:1"}},"footer":{"socials":{"github":"https://github.com/BasedHardware/omi","discord":"https://discord.gg/TdRNp5U7cy","x":"https://x.com/omedotme","linkedin":"https://www.linkedin.com/company/omi-ai","instagram":"https://www.instagram.com/based_hardware"}},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"omi","hasAudioNarration":false,"actualSubdomain":"omi","customDomains":["docs.omi.me"],"gitSource":{"type":"github","owner":"basedhardware","repo":"omi","deployBranch":"main","contentDirectory":"docs","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6aeb5eb0385381993c30d234","collectionId":"6336f15b-57d0-4596-954b-769bc357c38e","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6aeb5eb0385381993c30d234"},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6aeb6563b8882c034789d1c2","clientVersion":"0.0.4054","searchFilterCounts":[{"language":"default","tag":"Reference","count":67},{"language":"default","tag":"API reference","count":59},{"language":"default","tag":"Build","count":37},{"language":"default","tag":"Hardware","count":19},{"language":"default","tag":"Conversations","count":14},{"language":"default","tag":"Apps","count":14},{"language":"default","tag":"Get started","count":12},{"language":"default","tag":"Memories","count":11},{"language":"default","tag":"How Omi works","count":10},{"language":"default","tag":"Contribute","count":9}]},"assistantConfig":{},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"doc/hardware/how-the-pendant-works","slug":"/doc/hardware/how-the-pendant-works","pageMetadata":{"title":"How the Omi pendant works","description":"A visual guide to the pendant: where audio goes, what's inside, what the light means, its limits, and how it fails.","icon":"circle-play","mode":"wide","href":"/doc/hardware/how-the-pendant-works"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"A visual guide to the pendant: where audio goes, what’s inside, what the light means, its limits, and how it fails.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];const PendantGuide=()=>{const html=`\n\u003clink rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n\u003clink rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n\u003clink rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css2?family=Fredoka:wght@500;600;700\u0026family=Nunito+Sans:opsz,wght@6..12,400;6..12,600;6..12,700\u0026display=swap\">\n\u003cstyle>\n/* Layout: a visual guide. An animated \"watch it work\" scene up top, the real exploded view and\n board, then numbered behaviour cards that each tie back to the board. All rules are scoped\n under .pg so the guide can be embedded in the docs site without leaking styles.\n Colours always mean the same thing: green = live, teal = saved, red = lost, blue = the Bluetooth light. */\n.pg{\n --bg:#f4f6f8; --panel:#ffffff; --ink:#1b2430; --muted:#5b6675; --line:#d5dbe2; --sunk:#e9edf1;\n --yellow:#f2b705; --yellow-soft:#fdf3d0;\n --live:#2e9e5b; --live-soft:#dcf1e4; --saved:#1b8fa0; --saved-soft:#d7eff2; --lost:#d94338; --lost-soft:#fbe0dd;\n --blue:#2f6fde; --case:#c9ced6; --case-dark:#8d96a3; --screen:#eef2f6; --doze:#8b95a3;\n --f-display:\"Fredoka\",\"Arial Rounded MT Bold\",\"Trebuchet MS\",system-ui,sans-serif;\n --f-body:\"Nunito Sans\",-apple-system,\"Segoe UI\",system-ui,sans-serif;\n --r:14px;\n}\n\nhtml[data-theme=\"dark\"] .pg{\n --bg:#11161c; --panel:#18202a; --ink:#e7ecf2; --muted:#9aa6b4; --line:#2b3644; --sunk:#202a36;\n --yellow:#f5c431; --yellow-soft:#3a3115;\n --live:#5cc787; --live-soft:#173323; --saved:#4fc0cf; --saved-soft:#143139; --lost:#f07a70; --lost-soft:#3b1c1a;\n --blue:#6b9bf0; --case:#6c7684; --case-dark:#4a5360; --screen:#25303d; --doze:#7f8a98;\n color-scheme:dark}\nhtml.dark .pg{\n --bg:#11161c; --panel:#18202a; --ink:#e7ecf2; --muted:#9aa6b4; --line:#2b3644; --sunk:#202a36;\n --yellow:#f5c431; --yellow-soft:#3a3115;\n --live:#5cc787; --live-soft:#173323; --saved:#4fc0cf; --saved-soft:#143139; --lost:#f07a70; --lost-soft:#3b1c1a;\n --blue:#6b9bf0; --case:#6c7684; --case-dark:#4a5360; --screen:#25303d; --doze:#7f8a98;\n color-scheme:dark}\n.pg, .pg *{box-sizing:border-box}\n.pg{background:var(--bg);color:var(--ink);font-family:var(--f-body);font-size:1.05rem;line-height:1.55;margin:0}\n.pg .wrap{max-width:1000px;margin:0 auto;padding-inline:clamp(16px,4vw,36px);padding-block:0 5rem}\n.pg h1, .pg h2, .pg h3{font-family:var(--f-display);font-weight:600;line-height:1.1;text-wrap:balance;margin:0}\n.pg h1{font-size:clamp(2.3rem,6vw,3.6rem);font-weight:700}\n.pg h2{font-size:clamp(1.6rem,3.6vw,2.2rem);margin-bottom:.4rem}\n.pg h3{font-size:1.35rem}\n.pg p{margin:0 0 .8rem}\n.pg a{color:var(--blue)}\n.pg button:focus-visible, .pg input:focus-visible{outline:3px solid var(--yellow);outline-offset:2px}\n.pg .muted{color:var(--muted)}\n.pg .small{font-size:.88rem}\n.pg header{padding-block:2.6rem 1rem;display:grid;gap:.8rem}\n.pg .kicker{font-family:var(--f-display);font-weight:600;font-size:.95rem;color:var(--ink);background:var(--yellow);display:inline-block;padding:.15rem .7rem;border-radius:999px;justify-self:start}\n.pg .lede{font-size:1.2rem;color:var(--muted);max-width:56ch}\n.pg .chapter{padding-block:2.4rem .4rem}\n.pg .chapter>p{max-width:60ch;color:var(--muted)}\n\n/* scene */\n.pg .scene{background:var(--panel);border:2px solid var(--ink);border-radius:var(--r);overflow:hidden}\n.pg .scene svg{display:block;width:100%;height:auto}\n.pg .modes{display:flex;flex-wrap:wrap;gap:.45rem;padding:.8rem;border-top:2px solid var(--ink);background:var(--sunk)}\n.pg .mode{all:unset;cursor:pointer;font-family:var(--f-display);font-weight:600;font-size:.95rem;padding:.42rem .85rem;border-radius:999px;background:var(--panel);border:2px solid var(--line);color:var(--ink)}\n.pg .mode[aria-pressed=\"true\"]{border-color:var(--ink);background:var(--yellow);color:#1b2430}\n.pg .fixtg{display:inline-flex;align-items:center;gap:.5rem;font-size:.92rem;margin-left:auto;cursor:pointer;padding:.3rem .2rem}\n.pg .fixtg input{appearance:none;width:40px;height:22px;border-radius:999px;background:var(--line);position:relative;cursor:pointer;transition:background .15s;flex:none}\n.pg .fixtg input::after{content:\"\";position:absolute;top:3px;left:3px;width:16px;height:16px;border-radius:50%;background:var(--panel);transition:left .15s}\n.pg .fixtg input:checked{background:var(--saved)} .pg .fixtg input:checked::after{left:21px}\n.pg .caption{display:grid;grid-template-columns:auto minmax(0,1fr);gap:.8rem;align-items:center;padding:.9rem 1rem;border-top:2px solid var(--ink)}\n.pg .caption .badge{font-family:var(--f-display);font-weight:600;padding:.3rem .8rem;border-radius:8px;white-space:nowrap}\n.pg .b-live{background:var(--live-soft);color:var(--live)} .pg .b-saved{background:var(--saved-soft);color:var(--saved)} .pg .b-lost{background:var(--lost-soft);color:var(--lost)} .pg .b-doze{background:var(--sunk);color:var(--doze)}\n.pg .caption p{margin:0}\n@media (max-width:560px){.pg .caption{grid-template-columns:minmax(0,1fr)}.pg .fixtg{margin-left:0}}\n\n/* step panels */\n.pg .steps{display:grid;grid-template-columns:repeat(auto-fit,minmax(290px,1fr));gap:1rem;margin-top:1.2rem}\n.pg .step{background:var(--panel);border:2px solid var(--ink);border-radius:var(--r);padding:1rem 1rem 1.1rem;display:grid;grid-template-rows:auto auto 1fr;gap:.6rem;position:relative;min-width:0}\n.pg .step.wide{grid-column:1/-1}\n.pg .step .num{font-family:var(--f-display);font-weight:700;font-size:2.6rem;line-height:1;color:var(--ink)}\n.pg .step .head{display:flex;align-items:flex-start;gap:.7rem}\n.pg .step .head h3{padding-top:.35rem}\n.pg .step svg{width:100%;height:auto;display:block;background:var(--sunk);border-radius:10px}\n.pg .step p{margin:0;font-size:.98rem}\n.pg .step.warn .head{padding-right:6rem}\n.pg .step.warn{border-color:var(--lost);box-shadow:6px 6px 0 var(--lost-soft)}\n.pg .callout{position:absolute;top:.8rem;right:.8rem;font-size:.72rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;border:2px solid var(--ink);border-radius:6px;padding:.1rem .45rem;background:var(--yellow);color:#1b2430}\n.pg .callout.red{background:var(--lost);color:#fff;border-color:var(--lost)}\n\n/* parts tray */\n.pg .tray{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.6rem}\n@media (max-width:620px){.pg .tray{grid-template-columns:repeat(2,minmax(0,1fr))}}\n.pg .part{background:var(--sunk);border-radius:10px;padding:.6rem .4rem .7rem;text-align:center;min-width:0}\n.pg .part svg{width:64px;height:64px;background:none;margin:0 auto .3rem}\n.pg .part b{font-family:var(--f-display);font-weight:600;font-size:1rem;display:block}\n.pg .part span{font-size:.82rem;color:var(--muted);display:block;line-height:1.3}\n.pg .part .qty{display:inline-block;font-family:var(--f-display);font-weight:700;font-size:.8rem;background:var(--panel);border:1.5px solid var(--ink);border-radius:5px;padding:0 .35rem;margin-bottom:.2rem}\n\n/* lights */\n.pg .lights{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:.6rem}\n.pg .light{display:flex;gap:.65rem;align-items:flex-start;background:var(--sunk);border-radius:10px;padding:.65rem .7rem}\n.pg .light i{flex:none;width:26px;height:26px;border-radius:50%;box-shadow:0 0 0 4px var(--panel),0 0 14px 2px currentColor}\n.pg .light b{font-family:var(--f-display);font-weight:600;display:block}\n.pg .light span{font-size:.88rem;color:var(--muted)}\n@keyframes blink{50%{opacity:.15}} .pg .blink{animation:blink 1s steps(1) infinite}\n@keyframes alt{0%,49%{background:#2e9e5b;color:#2e9e5b}50%,100%{background:#2f6fde;color:#2f6fde}} .pg .alt{animation:alt 2s steps(1) infinite}\n\n/* gauges */\n.pg .gauges{display:grid;gap:.9rem}\n.pg .g{display:grid;grid-template-columns:7.5rem minmax(0,1fr);gap:.7rem;align-items:center}\n.pg .g b{font-family:var(--f-display);font-weight:600}\n.pg .track{height:28px;background:var(--sunk);border-radius:8px;position:relative;overflow:hidden;border:2px solid var(--ink)}\n.pg .fill{position:absolute;inset:0 auto 0 0;border-radius:5px;display:flex;align-items:center;padding-left:.5rem;font-weight:700;font-size:.82rem;color:#fff;white-space:nowrap}\n.pg .tick{position:absolute;top:-2px;bottom:-2px;width:2px;background:var(--ink)}\n.pg .ticklbl{position:absolute;top:30px;font-size:.72rem;color:var(--muted);transform:translateX(-50%)}\n\n/* day sim */\n.pg .sim{background:var(--panel);border:2px solid var(--ink);border-radius:var(--r);padding:1rem;margin-top:1rem}\n.pg .simtop{display:flex;flex-wrap:wrap;gap:.6rem;align-items:center;justify-content:space-between;margin-bottom:.8rem}\n.pg .tl{display:flex;height:58px;border-radius:10px;overflow:hidden;border:2px solid var(--ink)}\n.pg .blk{all:unset;cursor:pointer;display:flex;align-items:flex-end;padding:.3rem .35rem;font-weight:700;font-size:.7rem;min-width:0;overflow:hidden;border-right:2px solid var(--panel)}\n.pg .blk:last-child{border-right:0}\n.pg .blk.live{background:var(--live-soft);color:var(--live)} .pg .blk.saved{background:var(--saved-soft);color:var(--saved)} .pg .blk.lost{background:var(--lost-soft);color:var(--lost)}\n.pg .blk.doze{background:repeating-linear-gradient(135deg,var(--sunk) 0 6px,var(--panel) 6px 11px);color:var(--doze)} .pg .blk.off{background:var(--line);color:var(--muted)}\n.pg .blk[aria-pressed=\"true\"]{outline:3px solid var(--ink);outline-offset:-3px}\n.pg .daycard{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);gap:1rem;margin-top:.9rem}\n@media (max-width:640px){.pg .daycard{grid-template-columns:minmax(0,1fr)}.pg .blk{font-size:0}}\n.pg .daycard h3{font-size:1.25rem;margin:.1rem 0 .3rem}\n.pg .mini{background:var(--sunk);border-radius:10px;padding:.55rem .75rem;font-size:.92rem;margin-bottom:.45rem}\n.pg .mini b{display:block;font-size:.72rem;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}\n.pg .dot{display:inline-block;width:11px;height:11px;border-radius:50%;margin-right:.35rem;vertical-align:-1px}\n.pg .tot{display:grid;grid-template-columns:repeat(4,1fr);gap:.5rem;margin-top:.9rem}\n.pg .tot div{border-radius:10px;padding:.45rem .6rem;background:var(--sunk)}\n.pg .tot b{font-family:var(--f-display);font-size:1.4rem;display:block;font-variant-numeric:tabular-nums}\n.pg .tot span{font-size:.75rem;color:var(--muted);font-weight:700;text-transform:uppercase;letter-spacing:.04em}\n@media (max-width:520px){.pg .tot{grid-template-columns:repeat(2,1fr)}}\n\n/* trouble cards */\n.pg .trouble{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:.8rem;margin-top:1rem}\n.pg .t{background:var(--panel);border:2px solid var(--line);border-radius:var(--r);padding:.9rem 1rem;min-width:0}\n.pg .t .say{font-family:var(--f-display);font-weight:600;font-size:1.12rem;line-height:1.25;margin-bottom:.4rem}\n.pg .t .say::before{content:\"“\";color:var(--muted)} .pg .t .say::after{content:\"”\";color:var(--muted)}\n.pg .t p{font-size:.93rem;margin:0 0 .45rem}\n.pg .chips{display:flex;flex-wrap:wrap;gap:.3rem}\n.pg .chip{font-size:.74rem;font-weight:700;border-radius:999px;padding:.08rem .55rem;border:1.5px solid currentColor}\n.pg .c-no{color:var(--lost)} .pg .c-yes{color:var(--live)} .pg .c-some{color:#b07d00} .pg .c-fix{color:var(--muted)}\nhtml[data-theme=\"dark\"] .pg .c-some{color:var(--yellow)}\n\n\n/* rules */\n.pg .rules{display:grid;gap:.6rem;margin-top:1rem;counter-reset:q}\n.pg .rule{display:grid;grid-template-columns:2.4rem minmax(0,1fr);gap:.7rem;align-items:start;background:var(--panel);border:2px solid var(--line);border-radius:var(--r);padding:.8rem .9rem}\n.pg .rule::before{counter-increment:q;content:counter(q);font-family:var(--f-display);font-weight:700;font-size:1.3rem;width:2.2rem;height:2.2rem;border-radius:50%;background:var(--yellow);color:#1b2430;display:grid;place-items:center}\n.pg .rule b{font-family:var(--f-display);font-weight:600;font-size:1.1rem;display:block}\n.pg .rule span{font-size:.95rem;color:var(--muted)}\n.pg .big-rule{background:var(--yellow-soft);border:2px solid var(--yellow);border-radius:var(--r);padding:1rem 1.1rem;margin-top:1rem;display:grid;grid-template-columns:auto minmax(0,1fr);gap:1rem;align-items:center}\n.pg .big-rule svg{width:84px;height:84px}\n.pg .big-rule p{margin:0}\n.pg .big-rule b{font-family:var(--f-display);font-size:1.25rem;font-weight:600;display:block;margin-bottom:.2rem}\n@media (max-width:520px){.pg .big-rule{grid-template-columns:minmax(0,1fr)}}\n\n/* inside: exploded view + board */\n.pg .inside{display:grid;gap:1rem;margin-top:1rem}\n.pg .exploded{position:relative;background:#ececec;border:2px solid var(--ink);border-radius:var(--r);overflow:hidden}\n.pg .exploded img{display:block;width:100%;height:auto}\n.pg .pin{position:absolute;transform:translate(-50%,-50%);width:30px;height:30px;border-radius:50%;background:var(--yellow);border:2px solid #1b2430;color:#1b2430;font-family:var(--f-display);font-weight:700;display:grid;place-items:center;font-size:.95rem;box-shadow:0 2px 0 #1b2430}\n.pg .keys{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:.4rem .9rem;margin:.7rem 0 0;padding:0;list-style:none}\n.pg .keys li{display:flex;gap:.55rem;align-items:flex-start;font-size:.95rem}\n.pg .keys li b.k{flex:none;width:24px;height:24px;border-radius:50%;background:var(--yellow);border:2px solid var(--ink);display:grid;place-items:center;font-family:var(--f-display);font-size:.8rem;color:#1b2430}\n.pg .boardbox{display:grid;grid-template-columns:minmax(0,1fr);gap:1rem;background:var(--panel);border:2px solid var(--ink);border-radius:var(--r);padding:1rem}\n@media (min-width:760px){.pg .boardbox{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}\n.pg .boardstage{background:#1d3a2f;border-radius:12px;padding:.8rem;display:grid;gap:.6rem;justify-items:center}\n.pg .boardstage svg{width:100%;max-width:420px;height:auto}\n.pg .flip{display:inline-flex;border-radius:999px;overflow:hidden;border:2px solid #e8efe9}\n.pg .flip button{all:unset;cursor:pointer;font-family:var(--f-display);font-weight:600;font-size:.9rem;padding:.3rem .9rem;color:#e8efe9}\n.pg .flip button[aria-pressed=\"true\"]{background:#e8efe9;color:#1d3a2f}\n.pg .ly.mask{color:#16302a}.pg .ly.cu{color:#c88a4a;opacity:.38}.pg .ly.inner{display:none}.pg .ly.silk{color:#f4f1e4}.pg .ly.edge{color:#f4f1e4;opacity:.7}\n.pg{--pcb-hole:#1d3a2f}\n.pg .hs{cursor:pointer}\n.pg .hs circle{fill:rgba(242,183,5,.2);stroke:#f2b705;stroke-width:.22}\n.pg .hs text{font-family:var(--f-display);font-weight:700;font-size:.95px;fill:#1b2430}\n.pg .hs .tagbg{fill:#f2b705}\n.pg .hs.on circle{fill:rgba(242,183,5,.45);stroke-width:.3}\n.pg .hs:focus{outline:none}.pg .hs:focus circle{stroke:#fff}\n.pg .partcard h3{font-size:1.5rem;margin:.2rem 0 .4rem}\n.pg .partcard .eyebrow{font-size:.78rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}\n.pg .partlist{display:flex;flex-wrap:wrap;gap:.35rem;margin-top:.8rem}\n.pg .partlist button{all:unset;cursor:pointer;font-size:.84rem;font-weight:700;border:2px solid var(--line);border-radius:999px;padding:.15rem .6rem}\n.pg .partlist button[aria-pressed=\"true\"]{border-color:var(--ink);background:var(--yellow);color:#1b2430}\n.pg .where{display:flex;gap:.75rem;align-items:center;border-top:2px dashed var(--line);padding-top:.7rem;margin-top:.2rem}\n.pg .where svg.mini-board{flex:none;width:96px;height:96px;background:none!important;border-radius:50%}\n.pg .where span{font-size:.88rem;color:var(--muted);line-height:1.4}\n.pg .where b{display:block;color:var(--ink);font-size:.74rem;letter-spacing:.06em;text-transform:uppercase}\n.pg .mini-board .hl{fill:rgba(242,183,5,.55);stroke:#fff;stroke-width:.6}\n.pg footer{margin-top:3rem;padding-top:1rem;border-top:2px solid var(--line);font-size:.85rem;color:var(--muted)}\n\n/* small SVG animations */\n@keyframes wave{0%{opacity:0;transform:scale(.6)}40%{opacity:1}100%{opacity:0;transform:scale(1.25)}}\n.pg .wv{transform-box:fill-box;transform-origin:left center;animation:wave 1.6s ease-out infinite}\n.pg .wv.d1{animation-delay:.4s}.pg .wv.d2{animation-delay:.8s}\n@keyframes slide{0%{transform:translateX(0);opacity:0}10%{opacity:1}90%{opacity:1}100%{transform:translateX(var(--dx));opacity:0}}\n.pg .mv{animation:slide 2.2s linear infinite}\n@keyframes drop{0%{transform:translateY(0);opacity:0}15%{opacity:1}85%{opacity:1}100%{transform:translateY(var(--dy));opacity:0}}\n.pg .dr{animation:drop 1.8s ease-in infinite}\n@keyframes zz{0%{opacity:0;transform:translate(0,0)}30%{opacity:1}100%{opacity:0;transform:translate(14px,-22px)}}\n.pg .zz{animation:zz 2.4s ease-out infinite}.pg .zz.d1{animation-delay:.8s}.pg .zz.d2{animation-delay:1.6s}\n@keyframes grow{0%,10%{transform:scaleY(.2)}60%,100%{transform:scaleY(1)}}\n.pg .gr{transform-box:fill-box;transform-origin:bottom;animation:grow 3s ease-in-out infinite alternate}\n@keyframes shrink{0%,10%{transform:scaleY(1)}60%,100%{transform:scaleY(.15)}}\n.pg .sh{transform-box:fill-box;transform-origin:bottom;animation:shrink 3s ease-in-out infinite alternate}\n@keyframes pulse{50%{opacity:.35}} .pg .pl{animation:pulse 1.4s ease-in-out infinite}\n@media (prefers-reduced-motion:reduce){.pg, .pg *{animation:none!important;transition:none!important}}\n\n/* defend against host prose styles (Mintlify) */\n.pg .boardstage{align-content:start}\n.pg .boardbox{align-items:start}\n.pg .flip{align-self:start;height:auto;line-height:1.2}\n.pg .flip button{line-height:1.2;height:auto;margin:0}\n.pg ul.keys{padding-left:0;margin-left:0}\n.pg .keys li{padding-left:0;margin:0}\n.pg .keys li::before{display:none;content:none}\n.pg img{margin:0;border-radius:0}\n.pg button{min-height:0}\n\n\u003c/style>\n\n\u003c!-- shared drawings -->\n\u003csvg width=\"0\" height=\"0\" style=\"position:absolute\" aria-hidden=\"true\">\n \u003cdefs>\n \u003csymbol id=\"pendant\" viewBox=\"-40 -40 80 80\">\n \u003ccircle r=\"36\" fill=\"var(--case)\" stroke=\"var(--ink)\" stroke-width=\"3\"/>\n \u003ccircle r=\"27\" fill=\"none\" stroke=\"var(--case-dark)\" stroke-width=\"2\"/>\n \u003ccircle cx=\"-11\" r=\"4.5\" fill=\"currentColor\"/>\u003ccircle cx=\"11\" r=\"4.5\" fill=\"currentColor\"/>\n \u003ccircle r=\"6\" fill=\"var(--panel)\" stroke=\"var(--ink)\" stroke-width=\"2\"/>\n \u003c/symbol>\n \u003csymbol id=\"phone\" viewBox=\"0 0 50 90\">\n \u003crect x=\"2\" y=\"2\" width=\"46\" height=\"86\" rx=\"9\" fill=\"var(--panel)\" stroke=\"var(--ink)\" stroke-width=\"3\"/>\n \u003crect x=\"7\" y=\"11\" width=\"36\" height=\"64\" rx=\"3\" fill=\"var(--screen)\"/>\n \u003crect x=\"19\" y=\"80\" width=\"12\" height=\"3\" rx=\"1.5\" fill=\"var(--ink)\"/>\n \u003c/symbol>\n \u003csymbol id=\"box\" viewBox=\"0 0 90 70\">\n \u003cpath d=\"M5 18 L45 4 L85 18 L85 64 L5 64 Z\" fill=\"var(--panel)\" stroke=\"var(--ink)\" stroke-width=\"3\" stroke-linejoin=\"round\"/>\n \u003cpath d=\"M5 18 L45 30 L85 18 M45 30 L45 64\" fill=\"none\" stroke=\"var(--ink)\" stroke-width=\"2\"/>\n \u003c/symbol>\n \u003csymbol id=\"bin\" viewBox=\"0 0 60 70\">\n \u003cpath d=\"M8 16 H52 L47 66 H13 Z\" fill=\"var(--lost-soft)\" stroke=\"var(--lost)\" stroke-width=\"3\" stroke-linejoin=\"round\"/>\n \u003crect x=\"4\" y=\"8\" width=\"52\" height=\"8\" rx=\"3\" fill=\"var(--lost)\"/>\n \u003cpath d=\"M22 26 V58 M30 26 V58 M38 26 V58\" stroke=\"var(--lost)\" stroke-width=\"2.5\"/>\n \u003c/symbol>\n \u003csymbol id=\"cloud\" viewBox=\"0 0 90 56\">\n \u003cpath d=\"M22 50 H70 A16 16 0 0 0 68 18 A22 22 0 0 0 26 16 A17 17 0 0 0 22 50 Z\" fill=\"var(--panel)\" stroke=\"var(--ink)\" stroke-width=\"3\"/>\n \u003c/symbol>\n \u003csymbol id=\"chip\" viewBox=\"0 0 64 64\">\n \u003cg stroke=\"var(--ink)\" stroke-width=\"3\">\u003cpath d=\"M20 8v8M32 8v8M44 8v8M20 48v8M32 48v8M44 48v8M8 20h8M8 32h8M8 44h8M48 20h8M48 32h8M48 44h8\"/>\u003c/g>\n \u003crect x=\"15\" y=\"15\" width=\"34\" height=\"34\" rx=\"5\" fill=\"var(--ink)\"/>\n \u003ccircle cx=\"23\" cy=\"23\" r=\"3\" fill=\"var(--yellow)\"/>\n \u003c/symbol>\n \u003csymbol id=\"board-top\" viewBox=\"-0.3 -0.3 21.6 21.6\">\u003cimage href=\"/images/hardware/pendant-guide/board-front.svg\" x=\"-0.3\" y=\"-0.3\" width=\"21.6\" height=\"21.6\"/>\u003c/symbol>\n \u003csymbol id=\"board-bot\" viewBox=\"-0.3 -0.3 21.6 21.6\">\u003cimage href=\"/images/hardware/pendant-guide/board-back.svg\" x=\"-0.3\" y=\"-0.3\" width=\"21.6\" height=\"21.6\"/>\u003c/symbol>\n \u003c/defs>\n\u003c/svg>\n\n\u003cdiv class=\"pg\">\u003cdiv class=\"wrap\">\n\n\n\u003csection class=\"chapter\" aria-labelledby=\"watch\">\n \u003ch2 id=\"watch\">Watch it work\u003c/h2>\n \u003cp>Each little block is a slice of sound, 1/50th of a second. Pick a situation and follow the blocks.\u003c/p>\n \u003cdiv class=\"scene\">\n \u003csvg id=\"scene\" viewBox=\"0 0 820 330\" role=\"img\" aria-label=\"Animated scene: audio blocks travel from the pendant to the phone, into its memory, or into the bin\">\n \u003ctext x=\"410\" y=\"28\" text-anchor=\"middle\" font-family=\"var(--f-display)\" font-size=\"15\" fill=\"var(--muted)\" id=\"s-radio-lbl\">Bluetooth\u003c/text>\n \u003cline id=\"s-radio\" x1=\"185\" y1=\"140\" x2=\"650\" y2=\"140\" stroke=\"var(--blue)\" stroke-width=\"3\" stroke-dasharray=\"2 10\" stroke-linecap=\"round\"/>\n \u003cg id=\"s-waves\">\n \u003cpath class=\"wv\" d=\"M70 120 q-12 20 0 40\" fill=\"none\" stroke=\"var(--ink)\" stroke-width=\"3\" stroke-linecap=\"round\"/>\n \u003cpath class=\"wv d1\" d=\"M55 108 q-18 32 0 64\" fill=\"none\" stroke=\"var(--ink)\" stroke-width=\"3\" stroke-linecap=\"round\"/>\n \u003cpath class=\"wv d2\" d=\"M40 96 q-24 44 0 88\" fill=\"none\" stroke=\"var(--ink)\" stroke-width=\"3\" stroke-linecap=\"round\"/>\n \u003c/g>\n \u003cg id=\"s-zz\" font-family=\"var(--f-display)\" font-weight=\"700\" fill=\"var(--doze)\" style=\"display:none\">\n \u003ctext class=\"zz\" x=\"160\" y=\"90\" font-size=\"22\">z\u003c/text>\u003ctext class=\"zz d1\" x=\"172\" y=\"78\" font-size=\"18\">z\u003c/text>\u003ctext class=\"zz d2\" x=\"182\" y=\"66\" font-size=\"14\">z\u003c/text>\n \u003c/g>\n \u003cuse href=\"#pendant\" id=\"s-pendant\" x=\"80\" y=\"90\" width=\"100\" height=\"100\" style=\"color:var(--blue)\"/>\n \u003ctext x=\"130\" y=\"210\" text-anchor=\"middle\" font-family=\"var(--f-display)\" font-size=\"15\" fill=\"var(--ink)\">Pendant\u003c/text>\n \u003c!-- memory -->\n \u003cuse href=\"#box\" x=\"85\" y=\"240\" width=\"90\" height=\"70\"/>\n \u003cclipPath id=\"boxclip\">\u003crect x=\"91\" y=\"272\" width=\"78\" height=\"35\"/>\u003c/clipPath>\n \u003crect id=\"s-mem\" x=\"91\" y=\"307\" width=\"78\" height=\"0\" fill=\"var(--saved)\" opacity=\".85\" clip-path=\"url(#boxclip)\"/>\n \u003ctext x=\"190\" y=\"290\" font-family=\"var(--f-display)\" font-size=\"14\" fill=\"var(--muted)\">memory\u003c/text>\n \u003c!-- bin -->\n \u003cuse href=\"#bin\" id=\"s-bin\" x=\"385\" y=\"245\" width=\"52\" height=\"62\"/>\n \u003ctext x=\"446\" y=\"292\" font-family=\"var(--f-display)\" font-size=\"14\" fill=\"var(--lost)\" id=\"s-binlbl\">thrown away\u003c/text>\n \u003c!-- phone -->\n \u003cg id=\"s-phonegrp\">\n \u003ccircle id=\"s-range\" cx=\"690\" cy=\"140\" r=\"0\" fill=\"none\" stroke=\"var(--muted)\" stroke-dasharray=\"4 6\"/>\n \u003cuse href=\"#phone\" id=\"s-phone\" x=\"655\" y=\"80\" width=\"70\" height=\"126\"/>\n \u003cg id=\"s-lines\">\u003c/g>\n \u003ctext id=\"s-phonelbl\" x=\"690\" y=\"228\" text-anchor=\"middle\" font-family=\"var(--f-display)\" font-size=\"15\" fill=\"var(--ink)\">Phone\u003c/text>\n \u003c/g>\n \u003ctext id=\"s-phonenote\" x=\"690\" y=\"250\" text-anchor=\"middle\" font-family=\"var(--f-body)\" font-size=\"12.5\" fill=\"var(--muted)\">\u003c/text>\n \u003cg id=\"s-pk\">\u003c/g>\n \u003c/svg>\n \u003cdiv class=\"modes\" role=\"group\" aria-label=\"Situation\">\n \u003cbutton type=\"button\" class=\"mode\" data-m=\"live\" aria-pressed=\"true\">Talking, phone nearby\u003c/button>\n \u003cbutton type=\"button\" class=\"mode\" data-m=\"away\" aria-pressed=\"false\">Phone left behind\u003c/button>\n \u003cbutton type=\"button\" class=\"mode\" data-m=\"back\" aria-pressed=\"false\">Phone comes back\u003c/button>\n \u003cbutton type=\"button\" class=\"mode\" data-m=\"quiet\" aria-pressed=\"false\">Quiet room\u003c/button>\n \u003cbutton type=\"button\" class=\"mode\" data-m=\"deaf\" aria-pressed=\"false\">Phone stops listening\u003c/button>\n \u003clabel class=\"fixtg\">\u003cinput type=\"checkbox\" id=\"fix\"> With the planned fix\u003c/label>\n \u003c/div>\n \u003cdiv class=\"caption\">\u003cspan class=\"badge\" id=\"s-badge\">\u003c/span>\u003cp id=\"s-cap\">\u003c/p>\u003c/div>\n \u003c/div>\n\u003c/section>\n\n\u003csection class=\"chapter\" aria-labelledby=\"inside\">\n \u003ch2 id=\"inside\">What's inside\u003c/h2>\n \u003cp>Take it apart and you get a stack of layers about the size of a large coin. The parts that matter for behaviour are the circuit board and the battery.\u003c/p>\n \u003cdiv class=\"inside\">\n \u003cfigure style=\"margin:0\">\n \u003cdiv class=\"exploded\">\n \u003cimg src=\"/images/hardware/pendant-guide/exploded.jpg\" alt=\"Exploded 3D view of the pendant's parts laid out in a line: covers, shell, frame, circuit boards, buzzer, battery and lanyard.\">\n \u003cspan class=\"pin\" style=\"left:34.4%;top:38%\">1\u003c/span>\n \u003cspan class=\"pin\" style=\"left:13%;top:31%\">2\u003c/span>\n \u003cspan class=\"pin\" style=\"left:69.5%;top:47%\">3\u003c/span>\n \u003cspan class=\"pin\" style=\"left:63.5%;top:34%\">4\u003c/span>\n \u003cspan class=\"pin\" style=\"left:37.5%;top:50%\">5\u003c/span>\n \u003cspan class=\"pin\" style=\"left:22.5%;top:79%\">6\u003c/span>\n \u003c/div>\n \u003cul class=\"keys\">\n \u003cli>\u003cb class=\"k\">1\u003c/b>\u003cspan>\u003cb>Main circuit board.\u003c/b> The brain, microphones, memory and radio, all on a 21 mm disc. Explore it below.\u003c/span>\u003c/li>\n \u003cli>\u003cb class=\"k\">2\u003c/b>\u003cspan>\u003cb>Small boards.\u003c/b> A flex strip and the charging contacts.\u003c/span>\u003c/li>\n \u003cli>\u003cb class=\"k\">3\u003c/b>\u003cspan>\u003cb>Battery.\u003c/b> 150 mAh, soldered in, about a day of use.\u003c/span>\u003c/li>\n \u003cli>\u003cb class=\"k\">4\u003c/b>\u003cspan>\u003cb>Buzzer.\u003c/b> A tiny vibration motor for taps and replies.\u003c/span>\u003c/li>\n \u003cli>\u003cb class=\"k\">5\u003c/b>\u003cspan>\u003cb>Metal covers.\u003c/b> Machined aluminium. They also act as the radio antenna.\u003c/span>\u003c/li>\n \u003cli>\u003cb class=\"k\">6\u003c/b>\u003cspan>\u003cb>Shell.\u003c/b> The moulded outer ring. Glued and screwed shut, with no ports.\u003c/span>\u003c/li>\n \u003c/ul>\n \u003cp class=\"muted small\" style=\"margin-top:.5rem\">Image from the open-source hardware files. The small red labels name how each part is manufactured.\u003c/p>\n \u003c/figure>\n\n \u003cdiv class=\"boardbox\">\n \u003cdiv class=\"boardstage\">\n \u003cspan class=\"flip\" role=\"group\" aria-label=\"Board side\">\u003cbutton type=\"button\" id=\"bt\" aria-pressed=\"true\">Front\u003c/button>\u003cbutton type=\"button\" id=\"bb\" aria-pressed=\"false\">Back\u003c/button>\u003c/span>\n \u003csvg id=\"board\" viewBox=\"-0.3 -0.3 21.6 21.6\" role=\"img\" aria-label=\"The real circuit board, rendered from the design files\">\u003cuse id=\"boarduse\" href=\"#board-top\"/>\u003cg id=\"hs\">\u003c/g>\u003c/svg>\n \u003c/div>\n \u003cdiv class=\"partcard\" aria-live=\"polite\">\n \u003cdiv class=\"eyebrow\" id=\"pc-side\">Front of the board\u003c/div>\n \u003ch3 id=\"pc-name\">\u003c/h3>\n \u003cp id=\"pc-text\">\u003c/p>\n \u003cdiv class=\"partlist\" id=\"partlist\">\u003c/div>\n \u003cp class=\"muted small\" style=\"margin-top:.8rem\">This is the actual board, drawn from its design files. Copper is shown in orange and printed labels in white. Tap a highlighted part.\u003c/p>\n \u003c/div>\n \u003c/div>\n \u003c/div>\n\u003c/section>\n\n\u003csection class=\"chapter\" aria-labelledby=\"build\">\n \u003ch2 id=\"build\">How it works, one picture at a time\u003c/h2>\n \u003cp>Each card shows one behaviour, plus where it happens on the real board.\u003c/p>\n \u003cdiv class=\"steps\">\n\n \u003cdiv class=\"step\">\n \u003cdiv class=\"head\">\u003cspan class=\"num\">1\u003c/span>\u003ch3>Sound becomes blocks\u003c/h3>\u003c/div>\n \u003csvg viewBox=\"0 0 300 140\" aria-hidden=\"true\">\n \u003cpath class=\"wv\" d=\"M40 55 q-10 15 0 30\" fill=\"none\" stroke=\"var(--ink)\" stroke-width=\"3\" stroke-linecap=\"round\"/>\n \u003cpath class=\"wv d1\" d=\"M28 45 q-16 25 0 50\" fill=\"none\" stroke=\"var(--ink)\" stroke-width=\"3\" stroke-linecap=\"round\"/>\n \u003cuse href=\"#pendant\" x=\"60\" y=\"35\" width=\"70\" height=\"70\" style=\"color:var(--blue)\"/>\n \u003cg class=\"mv\" style=\"--dx:130px\">\u003crect x=\"140\" y=\"62\" width=\"16\" height=\"16\" rx=\"3\" fill=\"var(--live)\"/>\u003c/g>\n \u003cg class=\"mv\" style=\"--dx:130px;animation-delay:.55s\">\u003crect x=\"140\" y=\"62\" width=\"16\" height=\"16\" rx=\"3\" fill=\"var(--live)\"/>\u003c/g>\n \u003cg class=\"mv\" style=\"--dx:130px;animation-delay:1.1s\">\u003crect x=\"140\" y=\"62\" width=\"16\" height=\"16\" rx=\"3\" fill=\"var(--live)\"/>\u003c/g>\n \u003cg class=\"mv\" style=\"--dx:130px;animation-delay:1.65s\">\u003crect x=\"140\" y=\"62\" width=\"16\" height=\"16\" rx=\"3\" fill=\"var(--live)\"/>\u003c/g>\n \u003ctext x=\"215\" y=\"118\" text-anchor=\"middle\" font-family=\"var(--f-display)\" font-size=\"14\" fill=\"var(--muted)\">50 blocks every second\u003c/text>\n \u003c/svg>\n \u003cp>While awake, the microphones capture sound and the brain chops it into tiny compressed blocks, about the size of a text message each.\u003c/p>\n \u003cdiv class=\"where\">\u003csvg class=\"mini-board\" data-side=\"t\" data-refs=\"MIC1 MIC2 U1\" viewBox=\"-0.3 -0.3 21.6 21.6\" aria-hidden=\"true\">\u003c/svg>\u003cspan>\u003cb>On the board\u003c/b>The two microphones sit on opposite edges. The brain chip does the chopping.\u003c/span>\u003c/div>\n \u003c/div>\n\n \u003cdiv class=\"step\">\n \u003cdiv class=\"head\">\u003cspan class=\"num\">2\u003c/span>\u003ch3>Blocks fly to the phone\u003c/h3>\u003c/div>\n \u003csvg viewBox=\"0 0 300 140\" aria-hidden=\"true\">\n \u003cuse href=\"#pendant\" x=\"16\" y=\"40\" width=\"64\" height=\"64\" style=\"color:var(--blue)\"/>\n \u003cline x1=\"84\" y1=\"72\" x2=\"226\" y2=\"72\" stroke=\"var(--blue)\" stroke-width=\"3\" stroke-dasharray=\"2 9\" stroke-linecap=\"round\"/>\n \u003cg class=\"mv\" style=\"--dx:130px\">\u003crect x=\"88\" y=\"64\" width=\"16\" height=\"16\" rx=\"3\" fill=\"var(--live)\"/>\u003c/g>\n \u003cg class=\"mv\" style=\"--dx:130px;animation-delay:.7s\">\u003crect x=\"88\" y=\"64\" width=\"16\" height=\"16\" rx=\"3\" fill=\"var(--live)\"/>\u003c/g>\n \u003cg class=\"mv\" style=\"--dx:130px;animation-delay:1.4s\">\u003crect x=\"88\" y=\"64\" width=\"16\" height=\"16\" rx=\"3\" fill=\"var(--live)\"/>\u003c/g>\n \u003cuse href=\"#phone\" x=\"232\" y=\"28\" width=\"46\" height=\"84\"/>\n \u003crect x=\"241\" y=\"48\" width=\"26\" height=\"4\" rx=\"2\" fill=\"var(--live)\"/>\u003crect x=\"241\" y=\"57\" width=\"20\" height=\"4\" rx=\"2\" fill=\"var(--live)\"/>\u003crect x=\"241\" y=\"66\" width=\"24\" height=\"4\" rx=\"2\" fill=\"var(--live)\"/>\n \u003c/svg>\n \u003cp>Over Bluetooth, the blocks go to the Omi app. The app sends them to the cloud, which turns them into words. \u003cb>All the smart stuff happens there, not on the pendant.\u003c/b>\u003c/p>\n \u003cdiv class=\"where\">\u003csvg class=\"mini-board\" data-side=\"t\" data-refs=\"U1 PP1\" viewBox=\"-0.3 -0.3 21.6 21.6\" aria-hidden=\"true\">\u003c/svg>\u003cspan>\u003cb>On the board\u003c/b>The radio is built into the brain chip. A spring contact passes the signal to the metal case, which works as the antenna.\u003c/span>\u003c/div>\n \u003c/div>\n\n \u003cdiv class=\"step\">\n \u003cdiv class=\"head\">\u003cspan class=\"num\">3\u003c/span>\u003ch3>No phone? Save it for later\u003c/h3>\u003c/div>\n \u003csvg viewBox=\"0 0 300 140\" aria-hidden=\"true\">\n \u003cuse href=\"#pendant\" x=\"40\" y=\"10\" width=\"64\" height=\"64\" style=\"color:#d94338\"/>\n \u003cg class=\"dr\" style=\"--dy:40px\">\u003crect x=\"64\" y=\"76\" width=\"16\" height=\"16\" rx=\"3\" fill=\"var(--saved)\"/>\u003c/g>\n \u003cg class=\"dr\" style=\"--dy:40px;animation-delay:.6s\">\u003crect x=\"64\" y=\"76\" width=\"16\" height=\"16\" rx=\"3\" fill=\"var(--saved)\"/>\u003c/g>\n \u003cg class=\"dr\" style=\"--dy:40px;animation-delay:1.2s\">\u003crect x=\"64\" y=\"76\" width=\"16\" height=\"16\" rx=\"3\" fill=\"var(--saved)\"/>\u003c/g>\n \u003cuse href=\"#box\" x=\"35\" y=\"88\" width=\"74\" height=\"50\"/>\n \u003crect class=\"gr\" x=\"42\" y=\"112\" width=\"60\" height=\"22\" fill=\"var(--saved)\" opacity=\".8\"/>\n \u003cuse href=\"#phone\" x=\"220\" y=\"30\" width=\"44\" height=\"80\" opacity=\".3\"/>\n \u003cpath d=\"M200 40 L284 110 M284 40 L200 110\" stroke=\"var(--muted)\" stroke-width=\"3\" stroke-linecap=\"round\" opacity=\".6\"/>\n \u003ctext x=\"242\" y=\"130\" text-anchor=\"middle\" font-family=\"var(--f-display)\" font-size=\"13\" fill=\"var(--muted)\">out of range\u003c/text>\n \u003c/svg>\n \u003cp>When the phone is out of range, the pendant stores the blocks in its own memory instead, as long as its clock is set. The light turns \u003cb style=\"color:var(--lost)\">red\u003c/b>, but that's normal, nothing is wrong.\u003c/p>\n \u003cdiv class=\"where\">\u003csvg class=\"mini-board\" data-side=\"b\" data-refs=\"U7\" viewBox=\"-0.3 -0.3 21.6 21.6\" aria-hidden=\"true\">\u003c/svg>\u003cspan>\u003cb>On the board\u003c/b>The memory chip is on the underside of the board.\u003c/span>\u003c/div>\n \u003c/div>\n\n \u003cdiv class=\"step\">\n \u003cdiv class=\"head\">\u003cspan class=\"num\">4\u003c/span>\u003ch3>Phone's back: catch up\u003c/h3>\u003c/div>\n \u003csvg viewBox=\"0 0 300 140\" aria-hidden=\"true\">\n \u003cuse href=\"#box\" x=\"20\" y=\"70\" width=\"74\" height=\"50\"/>\n \u003crect class=\"sh\" x=\"27\" y=\"94\" width=\"60\" height=\"22\" fill=\"var(--saved)\" opacity=\".8\"/>\n \u003cpath d=\"M94 92 C140 92 150 72 220 72\" fill=\"none\" stroke=\"var(--blue)\" stroke-width=\"3\" stroke-dasharray=\"2 9\" stroke-linecap=\"round\"/>\n \u003cg class=\"mv\" style=\"--dx:120px\">\u003crect x=\"98\" y=\"70\" width=\"16\" height=\"16\" rx=\"3\" fill=\"var(--saved)\"/>\u003c/g>\n \u003cg class=\"mv\" style=\"--dx:120px;animation-delay:.7s\">\u003crect x=\"98\" y=\"70\" width=\"16\" height=\"16\" rx=\"3\" fill=\"var(--saved)\"/>\u003c/g>\n \u003cg class=\"mv\" style=\"--dx:120px;animation-delay:1.4s\">\u003crect x=\"98\" y=\"70\" width=\"16\" height=\"16\" rx=\"3\" fill=\"var(--saved)\"/>\u003c/g>\n \u003cuse href=\"#phone\" x=\"226\" y=\"30\" width=\"46\" height=\"84\"/>\n \u003cuse href=\"#pendant\" x=\"26\" y=\"6\" width=\"56\" height=\"56\" style=\"color:var(--blue)\"/>\n \u003c/svg>\n \u003cp>When the phone reconnects, the app quietly downloads what was saved. Those conversations show up \u003cb>later\u003c/b>, sometimes hours later. That's expected.\u003c/p>\n \u003cdiv class=\"where\">\u003csvg class=\"mini-board\" data-side=\"b\" data-refs=\"U7\" viewBox=\"-0.3 -0.3 21.6 21.6\" aria-hidden=\"true\">\u003c/svg>\u003cspan>\u003cb>On the board\u003c/b>The same memory chip, read back over Bluetooth.\u003c/span>\u003c/div>\n \u003c/div>\n\n \u003cdiv class=\"step\">\n \u003cdiv class=\"head\">\u003cspan class=\"num\">5\u003c/span>\u003ch3>Quiet room? Take a nap\u003c/h3>\u003c/div>\n \u003csvg viewBox=\"0 0 300 140\" aria-hidden=\"true\">\n \u003cuse href=\"#pendant\" x=\"100\" y=\"40\" width=\"74\" height=\"74\" style=\"color:var(--blue)\"/>\n \u003cg font-family=\"var(--f-display)\" font-weight=\"700\" fill=\"var(--doze)\">\u003ctext class=\"zz\" x=\"176\" y=\"50\" font-size=\"24\">z\u003c/text>\u003ctext class=\"zz d1\" x=\"190\" y=\"38\" font-size=\"19\">z\u003c/text>\u003ctext class=\"zz d2\" x=\"202\" y=\"26\" font-size=\"15\">z\u003c/text>\u003c/g>\n \u003ctext x=\"137\" y=\"132\" text-anchor=\"middle\" font-family=\"var(--f-display)\" font-size=\"13\" fill=\"var(--muted)\">after ~10 s of quiet\u003c/text>\n \u003c/svg>\n \u003cp>After about 10 seconds of silence, recording pauses to save battery, and the microphone's own low-power detector keeps listening. A loud enough sound restarts recording. Quiet sounds, and the first moment of speech, can be missed.\u003c/p>\n \u003cdiv class=\"where\">\u003csvg class=\"mini-board\" data-side=\"t\" data-refs=\"MIC1\" viewBox=\"-0.3 -0.3 21.6 21.6\" aria-hidden=\"true\">\u003c/svg>\u003cspan>\u003cb>On the board\u003c/b>The left microphone has a \"wake up\" wire back to the brain. It listens for sound on its own.\u003c/span>\u003c/div>\n \u003c/div>\n\n \u003cdiv class=\"step warn\">\n \u003cdiv class=\"head\">\u003cspan class=\"num\">6\u003c/span>\u003ch3>Connected but not listening\u003c/h3>\u003c/div>\n \u003csvg viewBox=\"0 0 300 140\" aria-hidden=\"true\">\n \u003cuse href=\"#pendant\" x=\"12\" y=\"22\" width=\"64\" height=\"64\" style=\"color:var(--blue)\"/>\n \u003cline x1=\"80\" y1=\"54\" x2=\"226\" y2=\"54\" stroke=\"var(--blue)\" stroke-width=\"3\" stroke-dasharray=\"2 9\" stroke-linecap=\"round\"/>\n \u003cuse href=\"#phone\" x=\"232\" y=\"12\" width=\"46\" height=\"84\"/>\n \u003ctext x=\"255\" y=\"58\" text-anchor=\"middle\" font-family=\"var(--f-display)\" font-size=\"10\" fill=\"var(--muted)\">zzz\u003c/text>\n \u003cg class=\"dr\" style=\"--dy:52px\">\u003crect x=\"94\" y=\"62\" width=\"16\" height=\"16\" rx=\"3\" fill=\"var(--lost)\"/>\u003c/g>\n \u003cg class=\"dr\" style=\"--dy:52px;animation-delay:.6s\">\u003crect x=\"94\" y=\"62\" width=\"16\" height=\"16\" rx=\"3\" fill=\"var(--lost)\"/>\u003c/g>\n \u003cg class=\"dr\" style=\"--dy:52px;animation-delay:1.2s\">\u003crect x=\"94\" y=\"62\" width=\"16\" height=\"16\" rx=\"3\" fill=\"var(--lost)\"/>\u003c/g>\n \u003cuse href=\"#bin\" x=\"80\" y=\"94\" width=\"44\" height=\"46\"/>\n \u003ctext x=\"140\" y=\"126\" font-family=\"var(--f-display)\" font-size=\"13\" fill=\"var(--lost)\">light still blue\u003c/text>\n \u003c/svg>\n \u003cp>Sometimes the phone stays connected but stops asking for audio. iPhones do this to apps in the background. The pendant \u003cb>throws the blocks away\u003c/b> and the light stays \u003cb style=\"color:var(--blue)\">blue\u003c/b>, so nobody notices. This is how a real meeting was lost. A fix is in progress.\u003c/p>\n \u003cdiv class=\"where\">\u003csvg class=\"mini-board\" data-side=\"t\" data-refs=\"U1\" viewBox=\"-0.3 -0.3 21.6 21.6\" aria-hidden=\"true\">\u003c/svg>\u003cspan>\u003cb>On the board\u003c/b>This happens in the brain chip's software, so the fix is a firmware update.\u003c/span>\u003c/div>\n \u003c/div>\n\n \u003cdiv class=\"step wide\">\n \u003cdiv class=\"head\">\u003cspan class=\"num\">7\u003c/span>\u003ch3>Read the light\u003c/h3>\u003c/div>\n \u003cdiv class=\"lights\">\n \u003cdiv class=\"light\">\u003ci style=\"background:#2f6fde;color:#2f6fde\">\u003c/i>\u003cdiv>\u003cb>Solid blue\u003c/b>\u003cspan>Connected. \u003cu>Not\u003c/u> proof that audio is reaching the phone.\u003c/span>\u003c/div>\u003c/div>\n \u003cdiv class=\"light\">\u003ci style=\"background:#d94338;color:#d94338\">\u003c/i>\u003cdiv>\u003cb>Solid red\u003c/b>\u003cspan>No phone. Saving to memory, which is fine.\u003c/span>\u003c/div>\u003c/div>\n \u003cdiv class=\"light\">\u003ci class=\"blink\" style=\"background:#d94338;color:#d94338\">\u003c/i>\u003cdiv>\u003cb>Blinking red\u003c/b>\u003cspan>Its clock isn't set, usually because it has never connected to the app. It can't save anything offline yet.\u003c/span>\u003c/div>\u003c/div>\n \u003cdiv class=\"light\">\u003ci class=\"alt\">\u003c/i>\u003cdiv>\u003cb>Green + blue/red\u003c/b>\u003cspan>Charging. The other colour shows connection.\u003c/span>\u003c/div>\u003c/div>\n \u003cdiv class=\"light\">\u003ci style=\"background:#2e9e5b;color:#2e9e5b\">\u003c/i>\u003cdiv>\u003cb>Solid green\u003c/b>\u003cspan>Charged.\u003c/span>\u003c/div>\u003c/div>\n \u003c/div>\n \u003cp class=\"muted small\">Users read blue as \"working\" and red as \"broken\". Both can be wrong. Making the light honest is on the list for the next firmware release.\u003c/p>\n \u003cdiv class=\"where\">\u003csvg class=\"mini-board\" data-side=\"t\" data-refs=\"D2 D7 K2\" viewBox=\"-0.3 -0.3 21.6 21.6\" aria-hidden=\"true\">\u003c/svg>\u003cspan>\u003cb>On the board\u003c/b>Two colour lights sit either side of the button, in the middle of the board.\u003c/span>\u003c/div>\n \u003c/div>\n\n \u003cdiv class=\"step wide\">\n \u003cdiv class=\"head\">\u003cspan class=\"num\">8\u003c/span>\u003ch3>Know the limits\u003c/h3>\u003c/div>\n \u003cdiv class=\"gauges\">\n \u003cdiv class=\"g\">\u003cb>Battery\u003c/b>\u003cdiv class=\"track\">\u003cdiv class=\"fill\" style=\"width:44%;background:var(--live)\">~17–20 h if it never naps\u003c/div>\u003cdiv class=\"tick\" style=\"left:66.6%\">\u003c/div>\u003cspan class=\"ticklbl\" style=\"left:66.6%\">1 day\u003c/span>\u003c/div>\u003c/div>\n \u003cdiv class=\"g\">\u003cb>Memory\u003c/b>\u003cdiv class=\"track\">\u003cdiv class=\"fill\" style=\"width:100%;background:var(--saved)\">~1.5 days of audio\u003c/div>\u003cdiv class=\"tick\" style=\"left:66.6%\">\u003c/div>\u003c/div>\u003c/div>\n \u003cdiv class=\"g\" style=\"margin-top:.6rem\">\u003cb>Field logs\u003c/b>\u003cdiv class=\"track\">\u003cdiv class=\"fill\" style=\"width:0\">\u003c/div>\u003cspan style=\"position:absolute;left:.6rem;top:3px;font-weight:700;font-size:.85rem\">none: the pendant doesn't report problems\u003c/span>\u003c/div>\u003c/div>\n \u003c/div>\n \u003cp class=\"muted small\" style=\"margin-top:.9rem\">Bars share one scale of 36 hours, and the tick marks one day. \u003cb>Battery runs out before memory does.\u003c/b> These are estimates from the design and past measurements, not field data.\u003c/p>\n \u003cdiv class=\"where\">\u003csvg class=\"mini-board\" data-side=\"t\" data-refs=\"U15\" viewBox=\"-0.3 -0.3 21.6 21.6\" aria-hidden=\"true\">\u003c/svg>\u003cspan>\u003cb>On the board\u003c/b>The battery isn't on the board. It is soldered to two pads, and this small chip charges it from the dock.\u003c/span>\u003c/div>\n \u003c/div>\n\n \u003cdiv class=\"step wide\">\n \u003cdiv class=\"head\">\u003cspan class=\"num\">9\u003c/span>\u003ch3>Getting a fix onto the pendant\u003c/h3>\u003c/div>\n \u003csvg viewBox=\"0 0 860 150\" aria-hidden=\"true\">\n \u003cg font-family=\"var(--f-display)\" font-size=\"14\" fill=\"var(--ink)\" text-anchor=\"middle\">\n \u003crect x=\"30\" y=\"40\" width=\"110\" height=\"64\" rx=\"10\" fill=\"var(--panel)\" stroke=\"var(--ink)\" stroke-width=\"3\"/>\u003ctext x=\"85\" y=\"78\">new firmware\u003c/text>\n \u003cuse href=\"#cloud\" x=\"215\" y=\"38\" width=\"110\" height=\"68\"/>\u003ctext x=\"270\" y=\"130\">release\u003c/text>\n \u003cuse href=\"#phone\" x=\"420\" y=\"30\" width=\"50\" height=\"90\"/>\u003ctext x=\"445\" y=\"140\">user taps \"Product Update\"\u003c/text>\n \u003cuse href=\"#pendant\" x=\"600\" y=\"38\" width=\"76\" height=\"76\" style=\"color:var(--blue)\"/>\u003ctext x=\"638\" y=\"140\">installed\u003c/text>\n \u003ctext x=\"780\" y=\"70\" fill=\"var(--muted)\">…if the user\u003c/text>\u003ctext x=\"780\" y=\"90\" fill=\"var(--muted)\">ever does\u003c/text>\n \u003c/g>\n \u003cg stroke=\"var(--muted)\" stroke-width=\"3\" fill=\"none\" stroke-linecap=\"round\">\u003cpath d=\"M148 72h56M338 72h70M482 72h104\"/>\u003c/g>\n \u003cg class=\"mv\" style=\"--dx:440px\">\u003crect x=\"150\" y=\"62\" width=\"22\" height=\"20\" rx=\"4\" fill=\"var(--yellow)\" stroke=\"var(--ink)\" stroke-width=\"2\"/>\u003c/g>\n \u003c/svg>\n \u003cp>The case is sealed, so normal updates arrive only through the app, and only when someone accepts them. Engineers can also reflash by wire, but that means opening the case. Many never do. \u003cb>Every old version stays out in the world\u003c/b>, and the app has to keep working with all of them. App and cloud fixes reach everyone within days. Firmware fixes trickle out.\u003c/p>\n \u003cdiv class=\"where\">\u003csvg class=\"mini-board\" data-side=\"b\" data-refs=\"U12\" viewBox=\"-0.3 -0.3 21.6 21.6\" aria-hidden=\"true\">\u003c/svg>\u003cspan>\u003cb>On the board\u003c/b>New firmware first downloads into this small separate chip. On restart, the pendant swaps it in.\u003c/span>\u003c/div>\n \u003c/div>\n \u003c/div>\n\n \u003cdiv class=\"big-rule\">\n \u003csvg viewBox=\"0 0 84 84\" aria-hidden=\"true\">\u003ccircle cx=\"42\" cy=\"42\" r=\"38\" fill=\"var(--yellow)\" stroke=\"var(--ink)\" stroke-width=\"3\"/>\u003cpath d=\"M26 44l11 11 22-26\" fill=\"none\" stroke=\"var(--ink)\" stroke-width=\"7\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\u003c/svg>\n \u003cp>\u003cb>The one rule: audio is never silently lost.\u003c/b>Every block must reach the phone or be saved for later, unless the user turned the pendant off or muted it on purpose. Saving phone battery can change \u003ci>when\u003c/i> blocks are sent, never \u003ci>whether\u003c/i> they survive. (Internally this is called INV-CAP-1.)\u003c/p>\n \u003c/div>\n\u003c/section>\n\n\u003csection class=\"chapter\" aria-labelledby=\"day\">\n \u003ch2 id=\"day\">Play through a day\u003c/h2>\n \u003cp>Tap a stretch of the day. Then flip on the planned fix and see what changes.\u003c/p>\n \u003cdiv class=\"sim\">\n \u003cdiv class=\"simtop\">\n \u003cspan class=\"modes\" style=\"padding:0;border:0;background:none\" role=\"group\" aria-label=\"Scenario\">\n \u003cbutton type=\"button\" class=\"mode\" id=\"sc-typ\" aria-pressed=\"true\">Typical day\u003c/button>\n \u003cbutton type=\"button\" class=\"mode\" id=\"sc-new\" aria-pressed=\"false\">Brand-new pendant\u003c/button>\n \u003c/span>\n \u003clabel class=\"fixtg\">\u003cinput type=\"checkbox\" id=\"dfix\"> With the planned fix\u003c/label>\n \u003c/div>\n \u003cdiv class=\"tl\" id=\"tl\" role=\"group\" aria-label=\"Timeline of the day\">\u003c/div>\n \u003cdiv class=\"daycard\" id=\"dcard\" aria-live=\"polite\">\u003c/div>\n \u003cdiv class=\"tot\" id=\"dtot\">\u003c/div>\n \u003c/div>\n\u003c/section>\n\n\u003csection class=\"chapter\" aria-labelledby=\"trouble\">\n \u003ch2 id=\"trouble\">When a user says…\u003c/h2>\n \u003cdiv class=\"trouble\">\n \u003cdiv class=\"t\">\u003cdiv class=\"say\">Half my meeting is missing.\u003c/div>\u003cp>The phone stopped listening while still connected (step 6). The blocks went in the bin.\u003c/p>\u003cdiv class=\"chips\">\u003cspan class=\"chip c-no\">Nobody is told\u003c/span>\u003cspan class=\"chip c-fix\">Fix: pendant firmware\u003c/span>\u003c/div>\u003c/div>\n \u003cdiv class=\"t\">\u003cdiv class=\"say\">It didn't record anything on day one.\u003c/div>\u003cp>It was worn before it was set up in the app. It won't save without a valid clock, and the app is what sets it.\u003c/p>\u003cdiv class=\"chips\">\u003cspan class=\"chip c-some\">Light blinks red\u003c/span>\u003cspan class=\"chip c-fix\">Fix: onboarding or firmware\u003c/span>\u003c/div>\u003c/div>\n \u003cdiv class=\"t\">\u003cdiv class=\"say\">My conversations showed up hours late.\u003c/div>\u003cp>The phone was away, so audio was saved and synced later (steps 3–4). It's working as designed.\u003c/p>\u003cdiv class=\"chips\">\u003cspan class=\"chip c-yes\">App shows syncing\u003c/span>\u003cspan class=\"chip c-fix\">Fix: clearer messaging\u003c/span>\u003c/div>\u003c/div>\n \u003cdiv class=\"t\">\u003cdiv class=\"say\">It died before dinner.\u003c/div>\u003cp>Battery. Talkative days drain it faster, and it switches itself off when low.\u003c/p>\u003cdiv class=\"chips\">\u003cspan class=\"chip c-some\">We see battery %, not why\u003c/span>\u003cspan class=\"chip c-fix\">Fix: firmware power work\u003c/span>\u003c/div>\u003c/div>\n \u003cdiv class=\"t\">\u003cdiv class=\"say\">It wouldn't charge or pair out of the box.\u003c/div>\u003cp>Often physical: the dock or cable isn't seated. How often this happens isn't known yet.\u003c/p>\u003cdiv class=\"chips\">\u003cspan class=\"chip c-some\">Support tickets only\u003c/span>\u003cspan class=\"chip c-fix\">Fix: packaging and setup\u003c/span>\u003c/div>\u003c/div>\n \u003cdiv class=\"t\">\u003cdiv class=\"say\">It cut off my first word.\u003c/div>\u003cp>Recording was paused in a quiet room and restarted only once the sound was loud enough (step 5).\u003c/p>\u003cdiv class=\"chips\">\u003cspan class=\"chip c-no\">Nobody is told\u003c/span>\u003cspan class=\"chip c-fix\">Fix: firmware (draft exists)\u003c/span>\u003c/div>\u003c/div>\n \u003c/div>\n\u003c/section>\n\n\u003csection class=\"chapter\" aria-labelledby=\"ask\">\n \u003ch2 id=\"ask\">Before you decide anything about the pendant\u003c/h2>\n \u003cdiv class=\"rules\">\n \u003cdiv class=\"rule\">\u003cdiv>\u003cb>Does it change when the phone stops listening?\u003c/b>\u003cspan>Then it must not open a gap where blocks go in the bin.\u003c/span>\u003c/div>\u003c/div>\n \u003cdiv class=\"rule\">\u003cdiv>\u003cb>Does it need new firmware?\u003c/b>\u003cspan>Expect a slow, partial rollout. If the app or cloud can solve it, start there.\u003c/span>\u003c/div>\u003c/div>\n \u003cdiv class=\"rule\">\u003cdiv>\u003cb>How will we know it worked?\u003c/b>\u003cspan>The pendant reports nothing by itself. Decide what to measure before you ship.\u003c/span>\u003c/div>\u003c/div>\n \u003cdiv class=\"rule\">\u003cdiv>\u003cb>What does the user see when it fails?\u003c/b>\u003cspan>An honest \"this part is missing\" beats a clean timeline with hidden holes.\u003c/span>\u003c/div>\u003c/div>\n \u003cdiv class=\"rule\">\u003cdiv>\u003cb>What does it cost in battery?\u003c/b>\u003cspan>A full day of battery is the hardest limit the device has.\u003c/span>\u003c/div>\u003c/div>\n \u003c/div>\n\u003c/section>\n\n\u003cfooter>\n Want the engineering detail? See \u003ca href=\"/doc/hardware/consumer/electronics\">the open-source electronics\u003c/a>, \u003ca href=\"/doc/developer/firmware/Compile_firmware\">compiling the firmware\u003c/a>, and the firmware source in \u003ccode>omi/firmware/omi/\u003c/code>. The board pictures are rendered from the KiCad files in \u003ccode>omi/hardware/consumer/\u003c/code>. Battery and memory figures are estimates from the design, not field measurements.\n\u003c/footer>\n\u003c/div>\u003c/div>\n\n\n`;useEffect(()=>{let stopped=false;const requestAnimationFrame=f=>stopped?0:window.requestAnimationFrame(f);const $=s=>document.querySelector(s),$$=s=>[...document.querySelectorAll(s)];const NS=`http://www.w3.org/2000/svg`;const reduce=matchMedia(`(prefers-reduced-motion: reduce)`).matches;const MODES={live:{badge:[`b-live`,`Live`],cap:`Each block goes straight to the phone, and words appear within seconds.`,led:`var(--blue)`,phone:`on`,note:`listening`},away:{badge:[`b-saved`,`Saved for later`],cap:`No phone in range, so blocks pile up in the pendant's memory. The light is red, and that is normal.`,led:`#d94338`,phone:`gone`,note:`out of range`},back:{badge:[`b-saved`,`Catching up`],cap:`The phone is back. New blocks go live while the saved pile empties to the phone in the background.`,led:`var(--blue)`,phone:`on`,note:`syncing saved audio`},quiet:{badge:[`b-doze`,`Napping`],cap:`Nobody is talking. Recording pauses to save battery, and a low-power detector restarts it when sound returns. Quiet sounds can slip through.`,led:`var(--blue)`,phone:`on`,note:`nothing new, which is correct`},deaf:{badge:[`b-lost`,`Lost`],cap:`Still connected, but the phone stopped asking for audio. The pendant throws every block away and the light stays blue. Nobody notices.`,led:`var(--blue)`,phone:`deaf`,note:`connected, not listening`},deafFix:{badge:[`b-saved`,`Saved for later`],cap:`Proposed behaviour (not shipped): \"connected but not listening\" is treated like \"no phone\". Blocks are saved, and they sync once the app wakes up.`,led:`var(--blue)`,phone:`deaf`,note:`connected, not listening`}};let mode=`live`,mem=0,lines=0,packets=[],lastSpawn=0;function effMode(){return mode===`deaf`\u0026\u0026$(`#fix`).checked?`deafFix`:mode}function setMode(m){mode=m;$$(`.mode[data-m]`).forEach(b=>b.setAttribute(`aria-pressed`,b.dataset.m===m));if(m===`live`||m===`back`)lines=Math.min(lines,2);drawStatic()}function drawStatic(){const M=MODES[effMode()];$(`#s-badge`).className=`badge `+M.badge[0];$(`#s-badge`).textContent=M.badge[1];$(`#s-cap`).textContent=M.cap;$(`#s-pendant`).style.color=M.led;$(`#s-waves`).style.display=mode===`quiet`?`none`:``;$(`#s-zz`).style.display=mode===`quiet`?``:`none`;const gone=M.phone===`gone`;$(`#s-phonegrp`).setAttribute(`opacity`,gone?.25:1);$(`#s-phonegrp`).setAttribute(`transform`,gone?`translate(60 0)`:``);$(`#s-radio`).setAttribute(`x2`,gone?420:650);$(`#s-radio`).setAttribute(`opacity`,gone?.35:1);$(`#s-radio-lbl`).textContent=gone?`Bluetooth: no phone in range`:`Bluetooth`;$(`#s-phonenote`).textContent=M.note;const deaf=M.phone===`deaf`;$(`#s-bin`).setAttribute(`opacity`,mode===`deaf`\u0026\u0026!$(`#fix`).checked?1:.35);$(`#s-binlbl`).setAttribute(`opacity`,mode===`deaf`\u0026\u0026!$(`#fix`).checked?1:.35);drawLines(deaf);drawMem()}function drawMem(){const h=Math.min(35,mem*.7);$(`#s-mem`).setAttribute(`y`,307-h);$(`#s-mem`).setAttribute(`height`,h)}function drawLines(deaf){const g=$(`#s-lines`);g.innerHTML=``;if(deaf){const t=document.createElementNS(NS,`text`);t.setAttribute(`x`,690);t.setAttribute(`y`,140);t.setAttribute(`text-anchor`,`middle`);t.setAttribute(`font-size`,`11`);t.setAttribute(`fill`,`var(--muted)`);t.textContent=`zzz`;g.appendChild(t);return}if(MODES[effMode()].phone===`gone`)return;for(let i=0;i\u003cMath.min(lines,9);i++){const r=document.createElementNS(NS,`rect`);r.setAttribute(`x`,668);r.setAttribute(`y`,98+i*9);r.setAttribute(`width`,[36,28,40,22,34,30,38,26,32][i]);r.setAttribute(`height`,4.5);r.setAttribute(`rx`,2);r.setAttribute(`fill`,i%3===2?`var(--saved)`:`var(--live)`);g.appendChild(r)}}function spawn(route,color){const el=document.createElementNS(NS,`rect`);el.setAttribute(`width`,16);el.setAttribute(`height`,16);el.setAttribute(`rx`,3);el.setAttribute(`fill`,color);$(`#s-pk`).appendChild(el);packets.push({el,route,t:0,len:route.reduce((a,s,i)=>i?a+Math.hypot(s[0]-route[i-1][0],s[1]-route[i-1][1]):0,0)})}const R={live:[[180,132],[648,132]],save:[[122,180],[122,262]],bin:[[180,132],[403,132],[403,262]],drain:[[175,282],[240,250],[420,150],[648,150]]};function tick(ts){const em=effMode();if(ts-lastSpawn>260){lastSpawn=ts;if(em===`live`)spawn(R.live,`var(--live)`);else if(em===`away`||em===`deafFix`)spawn(R.save,`var(--saved)`);else if(em===`deaf`)spawn(R.bin,`var(--lost)`);else if(em===`back`){spawn(R.live,`var(--live)`);if(mem>0){spawn(R.drain,`var(--saved)`);mem=Math.max(0,mem-1.2);drawMem()}}}const speed=.34;packets=packets.filter(p=>{p.t+=speed*16;let d=p.t,i=1;while(i\u003cp.route.length){const a=p.route[i-1],b=p.route[i],L=Math.hypot(b[0]-a[0],b[1]-a[1]);if(d\u003c=L){p.el.setAttribute(`x`,a[0]+(b[0]-a[0])*d/L-8);p.el.setAttribute(`y`,a[1]+(b[1]-a[1])*d/L-8);return true}d-=L;i++}p.el.remove();if(p.route===R.save){mem=Math.min(50,mem+1);drawMem()}if(p.route===R.live||p.route===R.drain){if(Math.random()\u003c.25){lines=(lines+1)%10;drawLines(false)}}return false});requestAnimationFrame(tick)}$$(`.mode[data-m]`).forEach(b=>b.onclick=()=>setMode(b.dataset.m));$(`#fix`).onchange=drawStatic;lines=4;drawStatic();if(reduce){const r={live:R.live};[.2,.45,.7].forEach(f=>{const a=R.live[0],b=R.live[1];const el=document.createElementNS(NS,`rect`);el.setAttribute(`x`,a[0]+(b[0]-a[0])*f-8);el.setAttribute(`y`,a[1]-8);el.setAttribute(`width`,16);el.setAttribute(`height`,16);el.setAttribute(`rx`,3);el.setAttribute(`fill`,`var(--live)`);$(`#s-pk`).appendChild(el)})}else requestAnimationFrame(tick);const PARTS={\"D3\":[7.576,16.006,`b`],\"D4\":[5.51,11.699,`b`],\"Q7\":[5.434,7.185,`b`],\"U5\":[14.164,12.637,`b`],\"U7\":[11.673,6.164,`b`],\"U9\":[5.948,9.64,`b`],\"U12\":[10.106,11.428,`b`],\"U14\":[6.227,15.989,`b`],\"D1\":[7.582,2.006,`t`],\"D2\":[11.934,10.494,`t`],\"D7\":[9.085,10.494,`t`],\"J1\":[8.519,15.857,`t`],\"K2\":[10.49,10.49,`t`],\"MIC1\":[2.889,10.489,`t`],\"MIC2\":[18.099,10.489,`t`],\"PP1\":[16.585,4.169,`t`],\"PP2\":[9.56,1.744,`t`],\"PP3\":[12.76,18.969,`t`],\"PP4\":[2.235,13.494,`t`],\"PP5\":[5.31,3.394,`t`],\"PP6\":[18.382,14.337,`t`],\"Q1\":[6.241,2.101,`t`],\"Q2\":[3.646,12.595,`t`],\"U1\":[12.335,15.694,`t`],\"U2\":[11.985,6.594,`t`],\"U3\":[14.982,9.357,`t`],\"U4\":[4.911,7.743,`t`],\"U6\":[5.31,5.169,`t`],\"U8\":[6.202,11.23,`t`],\"U10\":[13.36,9.544,`t`],\"U11\":[15.285,6.169,`t`],\"U13\":[6.38,13.935,`t`],\"U15\":[8.644,12.776,`t`],\"U16\":[7.003,3.373,`t`],\"X1\":[14.472,18.822,`t`],\"X2\":[15.066,12.549,`t`],\"X3\":[8.112,6.238,`t`]};const FRIENDLY=[{id:`brain`,name:`The brain`,refs:[`U1`],side:`t`,text:`One chip runs everything: it turns sound into blocks, decides where each block goes, and holds the Bluetooth radio. Its software is the \"firmware\".`},{id:`mics`,name:`Two microphones`,refs:[`MIC1`,`MIC2`],side:`t`,text:`One on each edge, listening through small holes. Their sound is mixed into one track. The left one can also wake the pendant from a nap.`},{id:`lights`,name:`Button and lights`,refs:[`K2`,`D2`,`D7`],side:`t`,text:`The button sits in the centre with a colour light on each side. Tap, double-tap, or hold for 3 seconds to turn it off.`},{id:`antenna`,name:`Antenna contact`,refs:[`PP1`],side:`t`,text:`A tiny spring pin that touches the metal cover, turning the whole case into the Bluetooth antenna.`},{id:`charge`,name:`Battery charger`,refs:[`U15`],side:`t`,text:`Charges the battery from the magnetic dock. The battery itself is wired to two pads on the edge.`},{id:`debug`,name:`Engineer's connector`,refs:[`J1`],side:`t`,text:`A tiny socket for loading firmware by wire. It's inside the sealed case, so regular updates go over Bluetooth instead.`},{id:`memory`,name:`Memory chip`,refs:[`U7`],side:`b`,text:`512 MB of storage, about a day and a half of audio. This is where blocks go when the phone is away.`},{id:`update`,name:`Update chip`,refs:[`U12`],side:`b`,text:`A small separate chip that holds a new firmware version while it downloads, so a failed update can't break the pendant.`},{id:`motion`,name:`Motion sensor`,refs:[`U5`],side:`b`,text:`Present, but motion features are switched off. Today it only helps the pendant keep track of time while it's off.`}];let bside=`t`,bsel=`brain`;function bxy(ref){const p=PARTS[ref];if(!p)return null;return[p[2]===`b`?20.98-p[0]:p[0],p[1]]}function boardRender(){$(`#boarduse`).setAttribute(`href`,bside===`t`?`#board-top`:`#board-bot`);$(`#bt`).setAttribute(`aria-pressed`,bside===`t`);$(`#bb`).setAttribute(`aria-pressed`,bside===`b`);const g=$(`#hs`);g.innerHTML=``;FRIENDLY.filter(f=>f.side===bside).forEach((f,idx)=>{const a=document.createElementNS(NS,`g`);a.setAttribute(`class`,`hs`+(f.id===bsel?` on`:``));a.setAttribute(`tabindex`,`0`);a.setAttribute(`role`,`button`);a.setAttribute(`aria-label`,f.name);let h=``;f.refs.forEach(r=>{const c=bxy(r);if(c)h+=`\u003ccircle cx=\"${c[0]}\" cy=\"${c[1]}\" r=\"${r===`U1`||r===`U7`?2:1.1}\"/>`});a.innerHTML=h;a.onclick=()=>{bsel=f.id;boardRender()};a.onkeydown=e=>{if(e.key===`Enter`||e.key===` `){e.preventDefault();bsel=f.id;boardRender()}};g.appendChild(a)});const f=FRIENDLY.find(x=>x.id===bsel);$(`#pc-side`).textContent=f.side===`t`?`Front of the board`:`Back of the board`;$(`#pc-name`).textContent=f.name;$(`#pc-text`).textContent=f.text;$(`#partlist`).innerHTML=FRIENDLY.map(x=>`\u003cbutton type=\"button\" data-id=\"${x.id}\" aria-pressed=\"${x.id===bsel}\">${x.name}\u003c/button>`).join(``);$$(`#partlist button`).forEach(b=>b.onclick=()=>{const x=FRIENDLY.find(y=>y.id===b.dataset.id);bsel=x.id;bside=x.side;boardRender()})}$(`#bt`).onclick=()=>{bside=`t`;bsel=`brain`;boardRender()};$(`#bb`).onclick=()=>{bside=`b`;bsel=`memory`;boardRender()};boardRender();$$(`.mini-board`).forEach(svg=>{const side=svg.dataset.side;let h=`\u003cuse href=\"${side===`t`?`#board-top`:`#board-bot`}\"/>`;svg.dataset.refs.split(` `).forEach(r=>{const c=bxy(r);if(c)h+=`\u003ccircle class=\"hl\" cx=\"${c[0]}\" cy=\"${c[1]}\" r=\"${r===`U1`||r===`U7`?2.6:1.8}\"/>`});svg.innerHTML=h});const LED={blue:`#2f6fde`,red:`#d94338`,green:`#2e9e5b`,off:`#777`};const DAYS={typ:[{t:`7am`,h:1,k:`live`,n:`Morning, phone in pocket`,w:`App running in the background. Blocks go straight to the phone.`,led:`blue`,app:`Live transcript.`},{t:`8am`,h:1,k:`doze`,n:`Quiet commute`,w:`Nobody is talking, so recording pauses and the mic's detector listens. Quiet sounds or the first words of speech can be missed.`,led:`blue`,app:`Nothing new, which is correct.`},{t:`9am`,h:1.5,k:`lost`,fk:`saved`,n:`Meeting, phone in bag`,w:`The iPhone quietly stops the app from asking for audio, but stays connected. The pendant bins every block. This is the real lost meeting.`,fw:`With the fix, the pendant saves the blocks instead, and they sync when the app wakes.`,led:`blue`,app:`No transcript, and no warning.`,fapp:`The meeting appears a bit later.`},{t:`10:30`,h:1.5,k:`live`,n:`User opens the app`,w:`Audio flows live again. The meeting does not come back.`,fw:`Audio flows live again, and the saved meeting syncs up behind it.`,led:`blue`,app:`Live again. The meeting is missing.`,fapp:`Live again. The meeting fills in.`},{t:`noon`,h:1,k:`saved`,n:`Lunch, phone on the desk`,w:`Out of range, so the pendant saves to memory.`,led:`red`,app:`Nothing yet.`},{t:`1pm`,h:4,k:`live`,n:`Back at the desk`,w:`Reconnects, goes live, and downloads the saved lunch audio in the background.`,led:`blue`,app:`Live, and lunch shows up later.`},{t:`5pm`,h:3,k:`doze`,n:`Quiet evening`,w:`Napping through the quiet, which is where the battery savings come from.`,led:`blue`,app:`Nothing new.`},{t:`8pm`,h:1.5,k:`live`,n:`Dinner`,w:`Streaming normally.`,led:`blue`,app:`Live transcript.`},{t:`9:30`,h:1.5,k:`off`,n:`Battery runs out`,w:`A talkative day can drain the small battery before bedtime. It switches itself off.`,led:`off`,app:`Shows as disconnected.`}],neu:[{t:`7am`,h:2,k:`lost`,fk:`lost`,n:`Worn before setting up the app`,w:`No phone, so it tries to save, but its clock has never been set and it won't save without a valid one. Everything is dropped.`,fw:`The planned fix doesn't cover this. It needs its own onboarding or firmware change.`,led:`redblink`,app:`Not set up yet.`},{t:`9am`,h:1,k:`live`,n:`Pairs with the app`,w:`Once connected, the app sets the clock and live audio starts. From then on saving works, as long as the clock stays valid and storage is healthy.`,led:`blue`,app:`First transcript.`},{t:`10am`,h:2,k:`saved`,n:`Phone left at home`,w:`Saved to memory.`,led:`red`,app:`Syncs later.`},{t:`noon`,h:4,k:`live`,n:`Normal use`,w:`Streaming normally.`,led:`blue`,app:`Live transcript.`},{t:`4pm`,h:2,k:`doze`,n:`Quiet afternoon`,w:`Napping.`,led:`blue`,app:`Nothing new.`},{t:`6pm`,h:5,k:`live`,n:`Evening, then on the dock`,w:`Works normally, even while charging. On the dock the light alternates green with blue, then goes solid green when full.`,led:`green`,app:`Live transcript.`}]};const LBL={live:`Live`,saved:`Saved for later`,lost:`Lost`,doze:`Napping`,off:`Off`};const COL={live:`var(--live)`,saved:`var(--saved)`,lost:`var(--lost)`,doze:`var(--doze)`,off:`var(--muted)`};let day=`typ`,sel=2;function kind(s){return $(`#dfix`).checked\u0026\u0026s.fk?s.fk:s.k}function led(l){if(l===`redblink`)return`\u003cspan class=\"dot blink\" style=\"background:${LED.red}\">\u003c/span>Blinking red`;if(l===`off`)return`\u003cspan class=\"dot\" style=\"background:${LED.off}\">\u003c/span>Dark`;return`\u003cspan class=\"dot\" style=\"background:${LED[l]}\">\u003c/span>${{blue:`Blue`,red:`Red`,green:`Green`}[l]}`}function dayRender(){const d=DAYS[day],fix=$(`#dfix`).checked;$(`#sc-typ`).setAttribute(`aria-pressed`,day===`typ`);$(`#sc-new`).setAttribute(`aria-pressed`,day===`neu`);$(`#tl`).innerHTML=d.map((s,i)=>`\u003cbutton type=\"button\" class=\"blk ${kind(s)}\" style=\"flex:${s.h}\" aria-pressed=\"${i===sel}\" data-i=\"${i}\" aria-label=\"${s.t}: ${s.n}, ${LBL[kind(s)]}\">${s.t}\u003c/button>`).join(``);$$(`#tl .blk`).forEach(b=>b.onclick=()=>{sel=+b.dataset.i;dayRender()});const s=d[sel],k=kind(s),ch=fix\u0026\u0026s.fw;$(`#dcard`).innerHTML=`\u003cdiv>\u003cspan class=\"badge\" style=\"font-family:var(--f-display);font-weight:600;color:${COL[k]}\">${LBL[k]}\u003c/span>\u003ch3>${s.n}\u003c/h3>\u003cp style=\"margin:0\">${ch?s.fw:s.w}\u003c/p>\u003c/div>\u003cdiv>\u003cdiv class=\"mini\">\u003cb>The light\u003c/b>${led(s.led)}\u003c/div>\u003cdiv class=\"mini\">\u003cb>In the app\u003c/b>${ch\u0026\u0026s.fapp?s.fapp:s.app}\u003c/div>\u003c/div>`;const tot={live:0,saved:0,lost:0,doze:0};d.forEach(x=>{const kk=kind(x);if(kk in tot)tot[kk]+=x.h});const f=h=>h%1?h.toFixed(1):h;$(`#dtot`).innerHTML=[`live`,`saved`,`lost`,`doze`].map(k=>`\u003cdiv>\u003cb style=\"color:${COL[k]}\">${f(tot[k])} h\u003c/b>\u003cspan>${LBL[k]}\u003c/span>\u003c/div>`).join(``)}$(`#sc-typ`).onclick=()=>{day=`typ`;sel=2;dayRender()};$(`#sc-new`).onclick=()=>{day=`neu`;sel=0;dayRender()};$(`#dfix`).onchange=dayRender;dayRender();return()=>{stopped=true}},[]);return _jsx(`div`,{dangerouslySetInnerHTML:{__html:html}})};function _createMdxContent(props){const{_MdxComponentBoundary}={..._provideComponents(),...props.components};if(!_MdxComponentBoundary)_missingMdxReference(`_MdxComponentBoundary`,true);return _jsx(_MdxComponentBoundary,{name:`PendantGuide`,children:_jsx(PendantGuide,{})})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{PendantGuide,default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"How the Omi pendant works","description":"A visual guide to the pendant: where audio goes, what's inside, what the light means, its limits, and how it fails.","icon":"circle-play","mode":"wide","href":"/doc/hardware/how-the-pendant-works"}}},"mdxSourceWithNoJs":null,"noJsSplices":[[121,59910,"null;function _creat"]]},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"subdomain":"omi","siteName":"Omi Developers","title":"How the Omi pendant works - Omi Developers","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-11-04T16:36:00.273Z","originalFileLocation":"doc/hardware/how-the-pendant-works.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"A visual guide to the pendant: where audio goes, what\u0026#x27;s inside, what the light means, its limits, and how it fails.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Omi Developers\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/omi/V7sJ0-MmKz9-hzsp/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/omi/V7sJ0-MmKz9-hzsp/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/omi/V7sJ0-MmKz9-hzsp/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/omi/V7sJ0-MmKz9-hzsp/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/omi/V7sJ0-MmKz9-hzsp/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/omi/V7sJ0-MmKz9-hzsp/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/omi/V7sJ0-MmKz9-hzsp/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/omi/V7sJ0-MmKz9-hzsp/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/omi/V7sJ0-MmKz9-hzsp/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"How the Omi pendant works - Omi Developers\">\u003cmeta data-mint-head property=\"og:description\" content=\"A visual guide to the pendant: where audio goes, what\u0026#x27;s inside, what the light means, its limits, and how it fails.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Omi Developers\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.omi.me/doc/hardware/how-the-pendant-works\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://omi.mintlify.app/_mintlify/api/og/v2?division=Omi+device\u0026amp;title=How+the+Omi+pendant+works\u0026amp;description=A+visual+guide+to+the+pendant%3A+where+audio+goes%2C+what%27s+inside%2C+what+the+light+means%2C+its+limits%2C+and+how+it+fails.\u0026amp;theme=08f71a11b2a1fddfe6ddd773\u0026amp;signature=34ba61ce8104fbaf7b9b1483905ec3c038f71958c3b251097df4cc5a513b3d2d\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"How the Omi pendant works - Omi Developers\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"A visual guide to the pendant: where audio goes, what\u0026#x27;s inside, what the light means, its limits, and how it fails.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://omi.mintlify.app/_mintlify/api/og/v2?division=Omi+device\u0026amp;title=How+the+Omi+pendant+works\u0026amp;description=A+visual+guide+to+the+pendant%3A+where+audio+goes%2C+what%27s+inside%2C+what+the+light+means%2C+its+limits%2C+and+how+it+fails.\u0026amp;theme=08f71a11b2a1fddfe6ddd773\u0026amp;signature=34ba61ce8104fbaf7b9b1483905ec3c038f71958c3b251097df4cc5a513b3d2d\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/omi/V7sJ0-MmKz9-hzsp/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Omi Developers\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#0D9373\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.omi.me/doc/hardware/how-the-pendant-works\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/doc/hardware/how-the-pendant-works.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.omi.me/#organization\",\"name\":\"Omi Developers\",\"url\":\"https://docs.omi.me\"},{\"@type\":\"WebSite\",\"@id\":\"https://docs.omi.me#website\",\"name\":\"Omi Developers\",\"url\":\"https://docs.omi.me\",\"publisher\":{\"@id\":\"https://docs.omi.me/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.omi.me/doc/hardware/how-the-pendant-works#webpage\",\"url\":\"https://docs.omi.me/doc/hardware/how-the-pendant-works\",\"name\":\"How the Omi pendant works\",\"description\":\"A visual guide to the pendant: where audio goes, what's inside, what the light means, its limits, and how it fails.\",\"dateModified\":\"2026-11-04T16:36:00.273Z\",\"isPartOf\":{\"@id\":\"https://docs.omi.me#website\"},\"breadcrumb\":{\"@id\":\"https://docs.omi.me/doc/hardware/how-the-pendant-works#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.omi.me/doc/hardware/how-the-pendant-works#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Omi Developers\",\"item\":\"https://docs.omi.me\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How the Omi pendant works\",\"item\":\"https://docs.omi.me/doc/hardware/how-the-pendant-works\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.omi.me/doc/hardware/how-the-pendant-works#article\",\"headline\":\"How the Omi pendant works\",\"name\":\"How the Omi pendant works\",\"description\":\"A visual guide to the pendant: where audio goes, what's inside, what the light means, its limits, and how it fails.\",\"url\":\"https://docs.omi.me/doc/hardware/how-the-pendant-works\",\"mainEntityOfPage\":{\"@id\":\"https://docs.omi.me/doc/hardware/how-the-pendant-works#webpage\"},\"dateModified\":\"2026-11-04T16:36:00.273Z\",\"publisher\":{\"@id\":\"https://docs.omi.me/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.omi.me#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Omi Developers\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Omi Developers","nav":{"global":null,"tabs":[{"tab":"Get started","icon":"rocket","pages":[{"title":"Get started","href":"/doc/get_started/what-is-omi"}]},{"tab":"Build","icon":"puzzle-piece","pages":[{"title":"Build","href":"/doc/developer/apps/Introduction"}]},{"tab":"Hardware","icon":"microchip","groups":[{"group":"Omi device","pages":[{"title":"How the Omi pendant works","icon":"circle-play","mode":"wide","href":"/doc/hardware/how-the-pendant-works"},{"title":"Omi","icon":"circle-dot","description":"Omi Consumer Version 1 (CV1), the current everyday wearable: specifications, firmware updates, and open-source design files.","href":"/doc/hardware/OmiConsumer"}]},{"group":"Flashing firmware","pages":[{"title":"Update Omi firmware","icon":"bolt","href":"/doc/get_started/Flash_device"},{"title":"Compile firmware","icon":"microchip","href":"/doc/developer/firmware/Compile_firmware"}]},{"group":"omiGlass","pages":[{"title":"omiGlass","icon":"glasses","href":"/doc/hardware/omiGlass"},{"title":"Flash firmware","icon":"bolt","href":"/doc/hardware/omiglass/flash-firmware"},{"title":"Monitoring and testing","icon":"chart-line","href":"/doc/hardware/omiglass/monitoring"}]},{"group":"Open hardware files","pages":[{"title":"Open source hardware","icon":"screwdriver-wrench","href":"/doc/hardware/consumer/index"},{"title":"Electronics","icon":"bolt","href":"/doc/hardware/consumer/electronics"},{"title":"Mechanical and packaging","icon":"gears","href":"/doc/hardware/consumer/mechanical"},{"title":"Assembly and BOM","icon":"hammer","href":"/doc/hardware/consumer/assembly"},{"title":"License","icon":"file-contract","href":"/doc/hardware/consumer/license"}]},{"group":"Legacy and community","pages":[{"title":"Omi DevKit 2","icon":"microchip","href":"/doc/hardware/DevKit2"},{"title":"Omi DevKit 1","icon":"circuit-board","href":"/doc/hardware/DevKit1"},{"title":"Build your own Omi device","icon":"book","href":"/doc/assembly/introduction"},{"title":"Parts list","icon":"cart-shopping","href":"/doc/assembly/Buying_Guide"},{"title":"Building the device","icon":"screwdriver","href":"/doc/assembly/Build_the_device"},{"title":"Adding a speaker to CV1 and DevKit 1","icon":"volume-2","href":"/doc/hardware/SpeakerMod"},{"title":"Painting your Omi device","icon":"paintbrush","href":"/doc/hardware/PaintingOMI"}]}]},{"tab":"How Omi works","icon":"sitemap","pages":[{"title":"How Omi works","href":"/doc/how-omi-works/architecture"}]},{"tab":"Contribute","icon":"code-pull-request","pages":[{"title":"Contribute","href":"/doc/developer/Contribution"}]},{"tab":"Reference","icon":"square-terminal","pages":[{"title":"Reference","href":"/api-reference/introduction"}]}]},"basePath":"","title":"How the Omi pendant works - Omi Developers","buildId":"dpl_345ReqzYaAjzS9QpeJemsKdb7KDj","deploymentId":"dpl_345ReqzYaAjzS9QpeJemsKdb7KDj","dynamics":[],"chunks":[]}