talking-pixel / src /app.css
cfahlgren1's picture
cfahlgren1 HF Staff
convert talking pixel to a sveltekit app that runs pivo-1.4m tts in the browser
3ec6b9e
Raw History Blame Contribute Delete
10.2 kB
:root {
--yellow: #ffd21e;
--bg: #0b0b0f;
--text: #fff;
--muted: #b9b9c9;
--meta: #8e8ea3;
--panel: #15151c;
--panel-line: #2a2a36;
--panel-shadow: none;
--field: #0f0f15;
--field-line: #2f2f3c;
--chip-bg: #1d1d26;
--chip-line: transparent;
--ex-bg: transparent;
--ex-line: #33333f;
--ex-text: #d3d3e0;
--voice-bg: #1d1d26;
--voice-on-bg: #1d1d26;
--voice-on-line: var(--yellow);
--avatar-bg: #1d1d26;
--big-text: var(--yellow);
--marker: none;
--accent-text: var(--yellow);
--focus: var(--yellow);
--on-yellow: #0b0b0f;
--wave-on: var(--yellow);
--wave-off: #2c2c38;
--loader-fill: var(--yellow);
--err-text: #ffb4a3;
--err-bg: #2a1712;
--info-bg: #1d1d26;
color-scheme: dark;
}
/* Light theme: explicit choice, or the system preference when no choice is stored. */
:root[data-theme="light"] {
--bg: #faf8f2;
--text: #121212;
--muted: #5f5d57;
--meta: #77746c;
--panel: #fff;
--panel-line: #e7e3d8;
--panel-shadow: 0 20px 40px -24px rgba(60, 50, 20, .25);
--field: #fbfaf6;
--field-line: #e4e0d4;
--chip-bg: #fff;
--chip-line: #e4e0d4;
--ex-bg: #fff;
--ex-line: #e0dccf;
--ex-text: #3d3b36;
--voice-bg: #f2efe6;
--voice-on-bg: #fff;
--voice-on-line: #121212;
--avatar-bg: #f2efe6;
--big-text: #121212;
--marker: linear-gradient(transparent 58%, var(--yellow) 58%, var(--yellow) 92%, transparent 92%);
--accent-text: #121212;
--focus: #121212;
--on-yellow: #121212;
--wave-on: #121212;
--wave-off: #e6e2d6;
--loader-fill: #121212;
--err-text: #8a1c0a;
--err-bg: #fdecea;
--info-bg: #f2efe6;
color-scheme: light;
}
@media (prefers-color-scheme: light) {
:root:not([data-theme="dark"]) {
--bg: #faf8f2;
--text: #121212;
--muted: #5f5d57;
--meta: #77746c;
--panel: #fff;
--panel-line: #e7e3d8;
--panel-shadow: 0 20px 40px -24px rgba(60, 50, 20, .25);
--field: #fbfaf6;
--field-line: #e4e0d4;
--chip-bg: #fff;
--chip-line: #e4e0d4;
--ex-bg: #fff;
--ex-line: #e0dccf;
--ex-text: #3d3b36;
--voice-bg: #f2efe6;
--voice-on-bg: #fff;
--voice-on-line: #121212;
--avatar-bg: #f2efe6;
--big-text: #121212;
--marker: linear-gradient(transparent 58%, var(--yellow) 58%, var(--yellow) 92%, transparent 92%);
--accent-text: #121212;
--focus: #121212;
--on-yellow: #121212;
--wave-on: #121212;
--wave-off: #e6e2d6;
--loader-fill: #121212;
--err-text: #8a1c0a;
--err-bg: #fdecea;
--info-bg: #f2efe6;
color-scheme: light;
}
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
margin: 0;
min-height: 100vh;
background: var(--bg);
color: var(--text);
font-family: 'Archivo', system-ui, -apple-system, sans-serif;
}
button { font: inherit; color: inherit; touch-action: manipulation; }
.mono, .facts, .wmeta { font-family: 'JetBrains Mono', ui-monospace, monospace; font-weight: 500; font-variant-numeric: tabular-nums; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* Desktop: the 1200x675 composition, scaled to the viewport height. */
.root {
min-height: 100vh;
max-width: 1440px;
margin: 0 auto;
padding: 40px 48px;
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 560px);
grid-template-rows: auto minmax(0, 1fr);
gap: 20px 48px;
}
.hero { min-width: 0; }
.big {
margin: -4px 0 0;
font-weight: 900;
font-stretch: 62%;
font-size: clamp(140px, 32.6vh, 260px);
line-height: .82;
letter-spacing: -.03em;
color: var(--big-text);
}
.big-num, .big-unit { display: block; width: fit-content; padding: 0 4px; margin-left: -4px; background: var(--marker); }
.topbar { grid-column: 1 / -1; display: flex; align-items: center; gap: 16px; min-width: 0; }
.theme-btn {
flex: none;
margin-left: auto;
width: 44px;
height: 44px;
display: grid;
place-items: center;
border-radius: 999px;
border: 1px solid var(--chip-line);
background: var(--chip-bg);
color: var(--text);
cursor: pointer;
}
.theme-btn svg { width: 20px; height: 20px; }
.theme-btn:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.big small {
display: block;
margin-top: 14px;
font-size: clamp(26px, 5.3vh, 40px);
font-stretch: 100%;
font-weight: 700;
letter-spacing: -.01em;
line-height: 1.1;
color: var(--text);
}
.facts { min-width: 0; font-size: 15px; color: var(--muted); }
.chip {
display: inline-flex;
align-items: center;
gap: 10px;
min-height: 44px;
padding: 8px 16px 8px 10px;
border-radius: 999px;
border: 1px solid var(--chip-line);
background: var(--chip-bg);
color: var(--text);
text-decoration: none;
font: inherit;
cursor: pointer;
}
.chip .hf { font-size: 20px; }
.app {
align-self: stretch;
min-width: 0;
background: var(--panel);
border: 1px solid var(--panel-line);
box-shadow: var(--panel-shadow);
border-radius: 24px;
padding: 24px;
display: flex;
flex-direction: column;
gap: 16px;
}
.quote { margin: 0; font-size: 30px; font-weight: 700; line-height: 1.12; overflow-wrap: anywhere; min-height: 1.12em; }
.quote .on { color: var(--on-yellow); background: var(--yellow); padding: 0 4px; margin: 0 -4px; border-radius: 2px; box-decoration-break: clone; -webkit-box-decoration-break: clone; }
.quote.long { font-size: 22px; }
.quote.longer { font-size: 17px; line-height: 1.25; }
.wavebox { position: relative; }
canvas.w { display: block; width: 100%; height: 76px; }
.loader {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
justify-content: center;
gap: 10px;
background: var(--panel);
font: 500 13px 'JetBrains Mono', monospace;
color: var(--muted);
}
.loader[hidden] { display: none; }
.loader-track { height: 6px; border-radius: 3px; background: var(--wave-off); overflow: hidden; }
.loader-fill { display: block; width: 0; height: 100%; background: var(--loader-fill); transition: width .15s linear; }
.wmeta { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 4px 12px; margin: -10px 0 -8px; font-size: 12px; color: var(--meta); }
.meta-right { display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.meta-btn {
min-height: 44px;
padding: 0 8px;
margin: 0 -8px;
border: 0;
background: transparent;
color: var(--meta);
font: inherit;
cursor: pointer;
border-radius: 8px;
}
.meta-right .meta-btn { margin-right: -8px; }
.meta-btn:disabled { cursor: default; opacity: .55; }
.meta-btn:not(:disabled) { color: var(--ex-text); }
textarea {
min-height: 76px;
border-radius: 14px;
border: 1.5px solid var(--field-line);
background: var(--field);
color: var(--text);
font: 500 17px/1.35 'Archivo', sans-serif;
padding: 12px 14px;
resize: none;
outline: none;
}
textarea:focus-visible { border-color: var(--focus); }
.examples { display: flex; gap: 6px; flex-wrap: wrap; margin-top: -4px; }
.ex {
min-height: 32px;
padding: 0 11px;
border-radius: 999px;
border: 1px solid var(--ex-line);
background: var(--ex-bg);
color: var(--ex-text);
font: 500 13px 'Archivo', sans-serif;
cursor: pointer;
text-align: left;
}
.notice { margin: 0; font-size: 13px; line-height: 1.45; color: var(--err-text); background: var(--err-bg); border-radius: 10px; padding: 8px 12px; overflow-wrap: anywhere; }
.notice.info { color: var(--muted); background: var(--info-bg); }
.row { display: flex; align-items: center; gap: 8px; margin-top: auto; flex-wrap: wrap; }
.voices { display: flex; gap: 8px; }
.voice {
display: flex;
align-items: center;
gap: 8px;
min-height: 48px;
padding: 0 15px 0 5px;
border-radius: 999px;
background: var(--voice-bg);
color: var(--text);
font: 700 16px 'Archivo', sans-serif;
border: 2px solid transparent;
cursor: pointer;
}
.voice.on { border-color: var(--voice-on-line); background: var(--voice-on-bg); }
.voice canvas { width: 36px; height: 36px; border-radius: 50%; image-rendering: pixelated; }
.speak {
margin-left: auto;
min-height: 48px;
padding: 0 24px;
border-radius: 999px;
border: 0;
background: var(--yellow);
color: var(--on-yellow);
font: 900 17px 'Archivo', sans-serif;
cursor: pointer;
}
.speak:disabled { opacity: .6; cursor: progress; }
.speak:active { transform: translateY(1px); }
:is(.speak, .voice, .ex, .chip, .meta-btn):focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
@media (hover: hover) {
.ex:hover, .chip:hover { border-color: var(--focus); }
.voice:not(.on):hover { border-color: var(--ex-line); }
.meta-btn:not(:disabled):hover { color: var(--accent-text); text-decoration: underline; }
}
/* Short desktop windows: keep the composition from overflowing. */
@media (min-width: 901px) and (max-height: 620px) {
.big { font-size: 140px; }
}
/* Mobile: the giant number becomes a header line, then the panel. */
@media (max-width: 900px) {
.root { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; gap: 20px; padding: 20px 16px 24px; max-width: 640px; }
.topbar { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: 'chip theme' 'facts facts'; gap: 8px 12px; }
.chip { grid-area: chip; justify-self: start; max-width: 100%; }
.topbar .facts { grid-area: facts; }
.theme-btn { grid-area: theme; margin-left: 0; }
.big { margin: 0; font-size: 64px; line-height: .9; display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 12px; }
.big-num, .big-unit { display: inline-block; }
.big small { flex-basis: 100%; font-size: 20px; margin-top: 6px; }
.desk { display: none; }
.facts { font-size: 13px; }
.app { padding: 18px; gap: 14px; border-radius: 20px; }
.quote { font-size: 24px; }
.quote.long { font-size: 19px; }
.quote.longer { font-size: 16px; }
.ex { min-height: 44px; font-size: 14px; }
textarea { font-size: 17px; }
.speak { flex: 1 0 auto; }
}
@media (max-width: 380px) {
.big { font-size: 54px; }
.row { gap: 6px; }
.voice { padding-right: 12px; }
.speak { padding: 0 16px; }
}
@media (prefers-reduced-motion: reduce) {
.loader-fill { transition: none; }
}