:root { --ink: #e8e6df; --muted: #98a0b3; --yellow: #ffd84d; --blue: #6ecbff; --panel: rgba(10, 12, 22, 0.62); --panel-strong: rgba(10, 12, 22, 0.82); --line: rgba(255, 255, 255, 0.09); } * { box-sizing: border-box; } html, body, #app { height: 100%; } @supports (height: 100dvh) { html, body, #app { height: 100dvh; } } body { margin: 0; background: #05060c; color: var(--ink); font-family: system-ui, -apple-system, "Segoe UI", sans-serif; overflow: hidden; } #app { position: relative; } #stage { position: absolute; inset: 0; width: 100%; height: 100%; display: block; } .overlay { position: absolute; inset: 0; display: flex; flex-direction: column; pointer-events: none; } .overlay header { display: flex; align-items: baseline; justify-content: space-between; padding: 16px 22px 0; } .brand { display: flex; flex-direction: column; gap: 3px; } .byline { margin: 0; font-size: 0.72rem; color: var(--muted); letter-spacing: 0.03em; text-shadow: 0 1px 8px rgba(0, 0, 0, 0.7); } .byline a { pointer-events: auto; color: var(--ink); text-decoration: none; } .byline a:hover { color: var(--blue); } .credit { position: absolute; left: 18px; bottom: 12px; margin: 0; font-size: 0.72rem; color: #2e3644; font-weight: 600; text-shadow: 0 1px 6px rgba(255, 255, 255, 0.4); } .credit a { pointer-events: auto; color: #2e3644; } .overlay h1 { margin: 0; font-size: 1rem; font-weight: 700; letter-spacing: 0.24em; text-transform: uppercase; text-shadow: 0 1px 10px rgba(0, 0, 0, 0.7); } .overlay a { pointer-events: auto; color: var(--muted); } .header-actions { display: flex; align-items: center; flex-wrap: wrap; justify-content: flex-end; gap: 8px; } #share, #customize { pointer-events: auto; display: inline-flex; align-items: center; gap: 7px; font: inherit; font-size: 0.8rem; font-weight: 600; line-height: 1; white-space: nowrap; color: var(--ink); background: var(--panel-strong); border: 1px solid var(--line); border-radius: 999px; padding: 9px 16px; cursor: pointer; } #share:hover, #customize:hover { border-color: var(--yellow); } .gh { pointer-events: auto; display: inline-flex; align-items: center; gap: 7px; color: var(--ink); font-size: 0.76rem; font-weight: 600; line-height: 1; white-space: nowrap; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; text-decoration: none; background: var(--panel-strong); border: 1px solid var(--line); border-radius: 999px; padding: 9px 14px; } .gh:hover { border-color: var(--yellow); } .creator[hidden] { display: none; } .creator { position: absolute; inset: 0; z-index: 6; pointer-events: none; } .creator-top { position: absolute; top: 52px; left: 50%; transform: translateX(-50%); display: flex; flex-direction: column; align-items: center; gap: 10px; pointer-events: auto; } .creator-top h2 { margin: 0; font-size: 1rem; letter-spacing: 0.18em; text-transform: uppercase; text-shadow: 0 2px 12px rgba(0, 0, 0, 0.8); } .creator-top input { font: inherit; font-size: 1rem; text-align: center; color: var(--ink); background: var(--panel-strong); border: 1px solid var(--line); border-radius: 999px; padding: 9px 18px; width: 240px; } .creator-presets { display: flex; gap: 7px; } .colorway { display: flex; flex-direction: column; align-items: center; gap: 5px; min-width: 76px; padding: 7px 9px; color: var(--ink); background: var(--panel-strong); border: 1px solid var(--line); border-radius: 10px; font: inherit; font-size: 0.68rem; font-weight: 700; cursor: pointer; } .colorway:hover { border-color: var(--yellow); } .colorway-swatches { display: flex; overflow: hidden; width: 58px; height: 10px; border-radius: 999px; box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.16); } .colorway-swatches span { flex: 1; } .creator-side { position: absolute; top: 50%; transform: translateY(-50%); display: flex; flex-direction: column; gap: 18px; pointer-events: auto; } .creator-side.left { left: max(24px, 8vw); } .creator-side.right { right: max(24px, 8vw); align-items: flex-end; } .creator-side .fld { background: var(--panel-strong); border: 1px solid var(--line); border-radius: 12px; padding: 10px 14px; gap: 14px; font-size: 0.85rem; color: var(--ink); } .creator-bottom { position: absolute; bottom: 26px; left: 50%; transform: translateX(-50%); display: flex; flex-direction: column; align-items: center; gap: 10px; pointer-events: auto; } .creator-actions { display: flex; justify-content: center; flex-wrap: wrap; gap: 12px; max-width: calc(100vw - 20px); } .creator-actions button { font: inherit; font-size: 0.9rem; font-weight: 700; border-radius: 999px; border: 1px solid var(--line); padding: 11px 22px; cursor: pointer; color: var(--ink); background: var(--panel-strong); } #duck-share { background: var(--yellow); color: #171300; border: none; } /* character creation hides the chat stage */ .customizing .chat, .customizing .credit, .customizing .tap-hint, .customizing .radial, .customizing #share { display: none; } .chat { pointer-events: auto; /* The panel is anchored by its composer. New history can only consume space above it, inside the scrolling feed. */ position: absolute; right: 18px; bottom: max(18px, env(safe-area-inset-bottom, 0px)); width: min(390px, calc(100vw - 36px)); max-height: calc(100dvh - 102px - env(safe-area-inset-bottom, 0px)); display: flex; flex-direction: column; justify-content: flex-end; gap: 10px; } .feed { display: flex; flex-direction: column; gap: 8px; flex: 0 1 auto; min-height: 0; max-height: 42vh; overflow-y: auto; scrollbar-width: thin; padding: 4px; } .chips, #composer { flex: 0 0 auto; } .bubble { max-width: 88%; padding: 9px 13px; border-radius: 15px; border: 1px solid var(--line); backdrop-filter: blur(8px); font-size: 0.9rem; line-height: 1.35; animation: rise 220ms ease-out; } .bubble.user { align-self: flex-end; background: rgba(255, 216, 77, 0.34); border-bottom-right-radius: 4px; } .bubble.duck { align-self: flex-start; background: rgba(10, 12, 22, 0.46); border-bottom-left-radius: 4px; display: flex; flex-direction: column; gap: 3px; } .bubble .droid { color: var(--blue); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.86rem; } .bubble .gloss { color: var(--ink); } .decode-pending { visibility: hidden; } .bubble .tag { color: var(--muted); font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.08em; } @keyframes rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } } @media (prefers-reduced-motion: reduce) { .bubble { animation: none; } } .chips { display: flex; flex-wrap: wrap; gap: 6px; } .chip { font: inherit; font-size: 0.78rem; color: var(--ink); background: var(--panel); border: 1px solid var(--line); border-radius: 999px; padding: 5px 12px; cursor: pointer; backdrop-filter: blur(8px); } .chip:hover:not(:disabled) { border-color: var(--blue); } .chip:disabled { opacity: 0.4; cursor: default; } #composer { display: flex; gap: 8px; } #input { flex: 1; font: inherit; font-size: 0.9rem; color: var(--ink); background: var(--panel-strong); border: 1px solid var(--line); border-radius: 999px; padding: 10px 16px; backdrop-filter: blur(8px); } #input:disabled { opacity: 0.5; } #input:focus-visible, .chip:focus-visible, #send:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; } #send { font: inherit; font-weight: 700; border: none; border-radius: 999px; cursor: pointer; color: #171300; background: var(--yellow); padding: 10px 20px; } #send:disabled { opacity: 0.4; cursor: default; } .sound-overlay { position: absolute; inset: 0; z-index: 10; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; background: rgba(4, 6, 12, 0.66); backdrop-filter: blur(3px); color: var(--ink); cursor: pointer; pointer-events: auto; opacity: 1; transition: opacity 450ms ease; text-align: center; padding: 24px; } .sound-overlay[hidden] { display: none; } .sound-overlay.gone { opacity: 0; pointer-events: none; } .sound-overlay svg { color: var(--yellow); filter: drop-shadow(0 0 24px rgba(255, 216, 77, 0.35)); animation: pulse 1.8s ease-in-out infinite; } .sound-overlay p { margin: 0; font-size: 1.4rem; font-weight: 700; letter-spacing: 0.04em; text-shadow: 0 2px 14px rgba(0, 0, 0, 0.8); } .sound-overlay span { color: var(--muted); font-size: 0.9rem; } @keyframes pulse { 0%, 100% { transform: scale(1); opacity: 0.9; } 50% { transform: scale(1.08); opacity: 1; } } @media (prefers-reduced-motion: reduce) { .sound-overlay svg { animation: none; } .sound-overlay { transition: none; } } @media (max-width: 640px) { .credit, .byline { display: none; } .gh { font-size: 0; gap: 0; padding: 8px 10px; } #customize, #share { font-size: 0.72rem; padding: 8px 12px; } .creator-side { gap: 10px; } .creator-side.left { left: 10px; } .creator-side.right { right: 10px; } } /* Touch devices stay compact. Removing blur saves compositor memory, but chat items must remain in normal flex flow so history grows upward. */ @media (pointer: coarse) { .chat { width: min(340px, calc(100vw - 20px)); gap: 7px; } .feed { max-height: min(30dvh, 260px); } .bubble { font-size: 0.8rem; padding: 7px 11px; backdrop-filter: none; } .bubble .droid { font-size: 0.74rem; } .bubble.duck { background: rgba(10, 12, 22, 0.72); } .chip { font-size: 0.7rem; padding: 4px 10px; } .chip, #input { background: rgba(10, 12, 22, 0.88); backdrop-filter: none; } .sound-overlay { background: rgba(4, 6, 12, 0.8); backdrop-filter: none; } } /* ── chat collapse: slim vertical arrow on the panel's left edge ── */ #chat-toggle { pointer-events: auto; position: absolute; left: -25px; bottom: 8px; width: 24px; height: 76px; display: flex; align-items: center; justify-content: center; font-size: 0.72rem; line-height: 1; color: var(--muted); background: var(--panel-strong); border: 1px solid var(--line); border-right: none; border-radius: 9px 0 0 9px; cursor: pointer; padding: 0; } #chat-toggle:hover { color: var(--ink); border-color: var(--yellow); } .chat.collapsed .feed, .chat.collapsed .chips, .chat.collapsed #composer { display: none; } .chat.collapsed { right: 0; width: 0; min-height: 92px; min-width: 0; } /* ── Sims-style ring of actions around the duck ── */ .radial { position: absolute; top: 0; left: 0; z-index: 7; pointer-events: none; } .radial[hidden] { display: none; } .radial-btn { pointer-events: auto; position: absolute; transform: translate(calc(var(--dx) - 50%), calc(var(--dy) - 50%)); width: 66px; height: 66px; border-radius: 50%; border: 2px solid rgba(255, 255, 255, 0.55); background: rgba(12, 16, 28, 0.85); color: var(--ink); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; cursor: pointer; box-shadow: 0 4px 18px rgba(0, 0, 0, 0.45); animation: ring-pop 170ms ease-out; } .radial-btn:hover { border-color: var(--yellow); background: rgba(22, 28, 46, 0.95); } .radial-icon { font-size: 1.3rem; line-height: 1; } .radial-label { font-size: 0.52rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); } @keyframes ring-pop { from { transform: translate(-50%, -50%) scale(0.4); opacity: 0; } } /* ── glowing "you can click the duck" hint ── */ .tap-hint { position: absolute; top: 0; left: 0; z-index: 5; font-size: 2rem; pointer-events: none; filter: drop-shadow(0 0 14px rgba(255, 216, 77, 0.9)); animation: tap-pulse 1.1s ease-in-out infinite; } .tap-hint[hidden] { display: none; } @keyframes tap-pulse { 0%, 100% { scale: 1; opacity: 0.85; } 50% { scale: 1.25; opacity: 1; } } @media (prefers-reduced-motion: reduce) { .tap-hint, .radial-btn { animation: none; } } /* phones: chat pinned bottom-right, toggle tucked above it */ @media (max-width: 640px) { .chat { right: max(10px, env(safe-area-inset-right, 0px)); bottom: max(10px, env(safe-area-inset-bottom, 0px)); width: min( 390px, calc(100vw - 20px - env(safe-area-inset-left, 0px) - env(safe-area-inset-right, 0px)) ); max-height: calc(100dvh - 76px - env(safe-area-inset-bottom, 0px)); margin: 0; } .feed { max-height: min(30dvh, 260px); } .chat.collapsed { min-height: 0; height: 0; } #chat-toggle { left: auto; right: 0; top: -26px; bottom: auto; width: 68px; height: 24px; border: 1px solid var(--line); border-bottom: none; border-radius: 9px 9px 0 0; } .chat.collapsed #chat-toggle { left: auto; right: 0; top: auto; bottom: 8px; width: 24px; height: 76px; border: 1px solid var(--line); border-radius: 9px 0 0 9px; } .radial-btn { width: 56px; height: 56px; } }