/* chat.saiden.dev * * Default look: clean, generic, neutral chat. Inter, soft grey, no cursive. * Personality is the result of calibration, not the starting point. * * Once calibrated, the body gets data-* attributes: * data-palette = default | rose | morning | evening | sage | paper | ink * data-typography = sans | serif-warm | serif-formal | mixed-modern | mono * data-density = airy | normal | dense * data-labels = block | cursive | none | prefix * * Each combination is a different room. */ /* ===================== DEFAULT TOKENS (neutral) ===================== */ :root { /* surfaces */ --bg: #f4f4f3; --bg-soft: #ececea; --surface: #e3e3e1; /* text */ --ink: #1f2024; --ink-muted: #6a6a6f; --ink-faint: #a8a8ac; /* accents (low-saturation by default) */ --coral: #6a6a6f; /* default accent is neutral grey */ --red: #8a4a3e; --gold: #9a8460; /* lines */ --line: #d6d6d3; /* font stacks (default = sans-only) */ --serif: 'Source Serif Pro', Georgia, serif; --serif-warm: 'Cormorant Garamond', Georgia, serif; --hand: 'Caveat', 'Brush Script MT', cursive; --sans: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; --mono: 'JetBrains Mono', Menlo, monospace; /* derived families — overridden by data-typography */ --font-body: var(--sans); --font-label: var(--sans); /* spacing scale — overridden by data-density */ --msg-gap: 1.5rem; --max-col: 36rem; --body-size: 1rem; --label-size: 0.72rem; --bt-size: 1.05rem; /* prompt baseline */ --line-thickness: 1px; } /* ===================== PALETTES ===================== */ body[data-palette="rose"] { --bg: #f5ebe0; --bg-soft: #f8e8db; --surface: #f0d9c7; --ink: #3d2820; --ink-muted: #8b6f60; --ink-faint: #b89a87; --coral: #e07856; --red: #c54f3d; --line: #e8d4c0; } body[data-palette="morning"] { --bg: #faf3e3; --bg-soft: #f4ead0; --surface: #ecdfb8; --ink: #3a2f1a; --ink-muted: #7a6a4a; --ink-faint: #b6a684; --coral: #d99b4a; --red: #b5703a; --line: #e7d6a8; } body[data-palette="evening"] { --bg: #ece1de; --bg-soft: #e4d2cd; --surface: #d8bdb6; --ink: #2e1b1d; --ink-muted: #7d5a59; --ink-faint: #b08c8a; --coral: #b04a55; --red: #84313e; --line: #d6bbb6; } body[data-palette="sage"] { --bg: #ecede4; --bg-soft: #e1e3d4; --surface: #cdd1bd; --ink: #25291e; --ink-muted: #5d6451; --ink-faint: #97a085; --coral: #6f8861; --red: #58683f; --line: #cfd4be; } body[data-palette="paper"] { --bg: #f7f4ed; --bg-soft: #efeada; --surface: #e1d9c2; --ink: #1d1c19; --ink-muted: #6b6759; --ink-faint: #a8a292; --coral: #8b5d2f; --red: #6a3f1b; --line: #d8cfb6; } body[data-palette="ink"] { --bg: #1d1d1f; --bg-soft: #26262a; --surface: #2f2f34; --ink: #e8e6df; --ink-muted: #9d9a90; --ink-faint: #65635c; --coral: #d8a572; --red: #b87653; --line: #353539; } /* ===================== TYPOGRAPHY SETS ===================== */ body[data-typography="sans"] { --font-body: var(--sans); --font-label: var(--sans); } body[data-typography="serif-warm"] { --font-body: var(--serif-warm); --font-label: var(--hand); --bt-size: 1.25rem; } body[data-typography="serif-formal"] { --font-body: var(--serif); --font-label: var(--sans); --bt-size: 1.15rem; } body[data-typography="mixed-modern"] { --font-body: var(--sans); --font-label: var(--hand); } body[data-typography="mono"] { --font-body: var(--mono); --font-label: var(--mono); --bt-size: 0.95rem; } /* ===================== DENSITY ===================== */ body[data-density="airy"] { --msg-gap: 2.3rem; --max-col: 38rem; --body-size: 1.05rem; } body[data-density="normal"] { --msg-gap: 1.5rem; --max-col: 36rem; --body-size: 1rem; } body[data-density="dense"] { --msg-gap: 1rem; --max-col: 34rem; --body-size: 0.95rem; } /* ===================== RESET ===================== */ *, *::before, *::after { box-sizing: border-box; } html, body { margin: 0; padding: 0; } html { font-size: 16px; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; } body { background: var(--bg); color: var(--ink); font-family: var(--font-body); font-weight: 400; font-size: var(--body-size); line-height: 1.55; min-height: 100vh; } /* ===================== LAYOUT ===================== */ .page { max-width: var(--max-col); margin: 0 auto; padding: 3rem 1.5rem 0 1.5rem; position: relative; min-height: 100vh; display: flex; flex-direction: column; } /* ---------- top-nav strip (recalibrate · sign out · sigil) ---------- */ .topnav { position: fixed; top: 1.25rem; right: 1.25rem; display: flex; align-items: center; gap: 0.75rem; z-index: 10; } .topnav__link { font-family: var(--sans); font-size: 0.62rem; font-weight: 400; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-faint); text-decoration: none; background: transparent; border: none; padding: 0; cursor: pointer; opacity: 0.45; transition: opacity 400ms ease, color 400ms ease; } .topnav__link:hover, .topnav__link:focus-visible { opacity: 1; color: var(--ink); outline: none; } .topnav__link:disabled { opacity: 0.25; cursor: progress; } .topnav__sep { color: var(--ink-faint); opacity: 0.35; font-size: 0.7rem; } .sigil { width: 14px; height: 14px; opacity: 0.35; transition: opacity 600ms ease; user-select: none; margin-left: 0.4rem; } .sigil:hover { opacity: 0.85; } .sigil img { width: 100%; height: 100%; display: block; } /* ===================== CONVERSATION ===================== */ .conversation { flex: 1 0 auto; padding-bottom: 2rem; } .msg { margin: var(--msg-gap) 0; opacity: 0; transform: translateY(6px); animation: appear 500ms cubic-bezier(0.16, 1, 0.3, 1) forwards; } .msg__label { font-family: var(--font-label); font-weight: 400; color: var(--ink-muted); font-size: var(--label-size); letter-spacing: 0.14em; text-transform: uppercase; margin-bottom: 0.45rem; user-select: none; } /* Cursive label override */ body[data-labels="cursive"] .msg__label { font-family: var(--hand); font-size: 1rem; letter-spacing: 0.01em; text-transform: none; } body[data-labels="none"] .msg__label { display: none; } body[data-labels="prefix"] .msg__label { display: inline; margin-right: 0.5em; font-weight: 600; text-transform: none; } .msg__body { color: var(--ink); font-size: var(--bt-size); line-height: 1.6; white-space: pre-wrap; word-wrap: break-word; } .msg--user .msg__body { color: var(--ink-muted); font-size: var(--body-size); line-height: 1.55; } .msg--system .msg__body { color: var(--ink-faint); font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.16em; font-family: var(--sans); font-weight: 300; } .msg--system .msg__label { display: none; } .msg--calibration .msg__body { color: var(--ink); font-size: calc(var(--bt-size) * 1.02); font-style: italic; line-height: 1.65; } .msg--calibration .msg__label { display: none; } .msg--calibration { margin: 1.5rem 0; } /* repeat-label hide */ .msg[data-hide-label="true"] .msg__label { display: none; } .msg[data-hide-label="true"] { margin-top: 0.8rem; } /* ===================== THINKING ===================== */ .thinking { color: var(--coral); font-size: 0.65rem; margin: 1.5rem 0; user-select: none; animation: pulse 1.8s ease-in-out infinite; } .thinking::before { content: "●"; } @keyframes pulse { 0%, 100% { opacity: 0.30; } 50% { opacity: 1.0; } } @keyframes appear { to { opacity: 1; transform: translateY(0); } } /* typewriter cursor */ .caret { display: inline-block; width: 0.5ch; margin-left: 0.05ch; color: var(--coral); animation: caret 800ms ease-out forwards; } .caret::after { content: "▍"; } @keyframes caret { 0% { opacity: 1; } 100% { opacity: 0; } } /* ===================== PROMPT ===================== */ .prompt { position: sticky; bottom: 0; background: var(--bg); padding: 1.5rem 0 2.5rem 0; z-index: 5; } .prompt__line { border: none; border-top: var(--line-thickness) solid var(--line); margin: 0 0 0.85rem 0; } .prompt__row { display: flex; align-items: center; gap: 0.75rem; } .prompt__input { flex: 1; border: none; background: transparent; outline: none; font-family: var(--font-body); font-weight: 400; font-size: var(--body-size); color: var(--ink); padding: 0; min-width: 0; } .prompt__input::placeholder { color: var(--ink-faint); font-style: italic; } .prompt__input:focus { caret-color: var(--coral); } /* ===================== MIC ===================== */ .prompt__mic { background: transparent; border: none; cursor: pointer; color: var(--ink-faint); padding: 0.4rem; display: flex; align-items: center; justify-content: center; border-radius: 50%; transition: color 200ms ease, background 200ms ease, transform 200ms ease; } .prompt__mic:hover { color: var(--ink-muted); } .prompt__mic:active { transform: scale(0.95); } .prompt__mic.recording { color: var(--coral); background: rgba(0, 0, 0, 0.04); animation: mic-pulse 1.2s ease-in-out infinite; } .prompt__mic.transcribing { color: var(--gold); animation: mic-spin 1.2s linear infinite; } .prompt__mic.empty { color: var(--red); animation: mic-empty 0.7s ease; } @keyframes mic-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(0, 0, 0, 0.18); } 50% { box-shadow: 0 0 0 8px rgba(0, 0, 0, 0); } } @keyframes mic-spin { to { transform: rotate(360deg); } } @keyframes mic-empty { 0% { transform: translateX(0); } 20% { transform: translateX(-2px); } 40% { transform: translateX(2px); } 60% { transform: translateX(-2px); } 80% { transform: translateX(2px); } 100% { transform: translateX(0); } } /* ===================== CHOICE TILES ===================== */ .choices { display: flex; flex-wrap: wrap; gap: 0.55rem; margin: 1rem 0 0.25rem 0; } .choice { background: var(--bg-soft); border: 1px solid var(--line); color: var(--ink); font-family: var(--font-body); font-size: 0.95rem; font-style: normal; padding: 0.5rem 0.95rem; border-radius: 999px; cursor: pointer; display: inline-flex; align-items: center; gap: 0.45rem; transition: background 220ms ease, color 220ms ease, border-color 220ms ease, transform 220ms ease, opacity 220ms ease; } .choice:hover { background: var(--surface); border-color: var(--coral); } .choice:active { transform: scale(0.97); } .choice:disabled { cursor: default; opacity: 0.45; } .choice--selected { background: var(--coral); color: var(--bg); border-color: var(--coral); opacity: 1 !important; } .choice--other { font-style: italic; color: var(--ink-muted); background: transparent; } .choice__icon { font-size: 1.05rem; line-height: 1; display: inline-flex; } .choice__label { line-height: 1; } /* ===================== DENIED PAGE ===================== */ .denied { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; padding: 2rem; text-align: center; } .denied__title { font-family: var(--font-body); font-size: 1.7rem; color: var(--ink); font-weight: 500; margin: 0 0 1rem 0; } .denied__body { font-family: var(--font-body); font-size: 1rem; color: var(--ink-muted); max-width: 28rem; line-height: 1.6; } .denied__link { font-family: var(--sans); font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.14em; color: var(--red); text-decoration: none; margin-top: 3rem; display: inline-block; border-bottom: 1px solid var(--line); padding-bottom: 0.15rem; } .denied__link:hover { border-color: var(--red); }