helva-robot/face/var/www/html/style.css

287 lines
6.1 KiB
CSS
Executable File

:root {
--bg: #0b0f14;
--panel: #121925;
--fg: #d7e3f2;
/* Glow / Stimmung */
--glow: rgba(0, 255, 180, 0.22);
/* Pupillen-Offset (wird via JS verändert) */
--pupil-x: 0px;
--pupil-y: 0px;
/* Mund-Parameter (Default = neutral) */
--mouth-w: 38vw;
--mouth-h: 10vh;
--mouth-radius: 999px;
--mouth-line-y: 50%;
--mouth-line-h: 10px;
--mouth-line-opacity: 0.85;
/* „Smile“-Bogen (0 = aus) */
--smile: 0;
/* „Frown“-Bogen (0 = aus) */
--frown: 0;
/* „O“-Mund (0 = aus, sonst Größe) */
--omouth: 0;
}
html, body {
height: 100%;
margin: 0;
background: var(--bg);
overflow: hidden;
font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
}
#face {
height: 100%;
display: grid;
place-items: center;
gap: 3.5vh;
}
.eyes {
display: flex;
gap: 8vw;
align-items: center;
}
.eye {
width: 14vw;
height: 14vw;
max-width: 220px;
max-height: 220px;
border-radius: 999px;
background: var(--panel);
box-shadow: 0 0 40px var(--glow);
position: relative;
overflow: hidden;
transition: border-radius 220ms ease, transform 220ms ease, height 220ms ease;
}
/* Pupille */
.eye::after {
content: "";
position: absolute;
inset: 28%;
border-radius: 999px;
background: var(--fg);
opacity: 0.9;
transform: translate(var(--pupil-x), var(--pupil-y));
transition: transform 180ms ease;
}
/* Blinzeln: wir "quetschen" das Auge kurz */
.eye.blink {
transform: scaleY(0.12);
}
/* Mund-Container */
.mouth {
width: var(--mouth-w);
height: var(--mouth-h);
max-width: 600px;
max-height: 120px;
border-radius: var(--mouth-radius);
background: var(--panel);
box-shadow: 0 0 40px var(--glow);
position: relative;
overflow: hidden;
transition: width 220ms ease, height 220ms ease, border-radius 220ms ease;
}
/* Mund-Shape (Linie + Bögen + O-Mund) */
.mouth-shape {
position: absolute;
inset: 0;
}
/* Mund-Linie */
.mouth-shape::after {
content: "";
position: absolute;
left: 12%;
right: 12%;
top: var(--mouth-line-y);
height: var(--mouth-line-h);
transform: translateY(-50%);
background: var(--fg);
border-radius: 999px;
opacity: var(--mouth-line-opacity);
transition: all 220ms ease;
}
/* Smile-Bogen */
.mouth-shape::before {
content: "";
position: absolute;
left: 16%;
right: 16%;
top: 38%;
height: 55%;
border: calc(6px + 6px * var(--smile)) solid rgba(215,227,242,0.85);
border-top: none;
border-left-color: transparent;
border-right-color: transparent;
border-bottom-left-radius: 999px;
border-bottom-right-radius: 999px;
opacity: calc(0.10 + 0.60 * var(--smile));
transition: opacity 220ms ease, border-width 220ms ease;
}
/* Frown-Bogen als extra Element über box-shadow Trick */
.mouth-shape {
filter: drop-shadow(0 0 0 rgba(0,0,0,0));
}
.mouth-shape.frown::before {
content: "";
position: absolute;
left: 16%;
right: 16%;
bottom: 38%;
height: 55%;
border: calc(6px + 6px * var(--frown)) solid rgba(215,227,242,0.85);
border-bottom: none;
border-left-color: transparent;
border-right-color: transparent;
border-top-left-radius: 999px;
border-top-right-radius: 999px;
opacity: calc(0.10 + 0.60 * var(--frown));
}
/* O-Mund: wir machen aus dem Mund-Container einen Kreis und verstecken Linie */
body.has-omouth .mouth {
width: calc(18vw + 8vw * var(--omouth));
height: calc(18vw + 8vw * var(--omouth));
max-width: 260px;
max-height: 260px;
border-radius: 999px;
}
body.has-omouth .mouth-shape::after {
left: 28%;
right: 28%;
top: 50%;
height: 42%;
border-radius: 999px;
opacity: 0.9;
}
body.has-omouth .mouth-shape::before {
opacity: 0; /* Smile aus */
}
/* Label */
.label {
position: fixed;
bottom: 18px;
left: 18px;
padding: 10px 14px;
background: rgba(18, 25, 37, 0.75);
color: var(--fg);
border-radius: 14px;
backdrop-filter: blur(8px);
border: 1px solid rgba(255,255,255,0.08);
letter-spacing: 0.5px;
}
/* ===== Emotionen über Variablen ===== */
body.emotion-neutral {
--glow: rgba(0, 255, 180, 0.22);
--smile: 0;
--frown: 0;
--omouth: 0;
--mouth-line-opacity: 0.85;
--mouth-line-h: 10px;
}
body.emotion-neutral .mouth-shape { }
body.emotion-neutral .mouth-shape.frown { } /* no-op */
body.emotion-happy {
--glow: rgba(0, 255, 120, 0.32);
--smile: 1;
--frown: 0;
--omouth: 0;
--mouth-line-y: 58%;
--mouth-line-h: 12px;
--mouth-line-opacity: 0;
}
body.emotion-happy .mouth-shape { }
body.emotion-happy .mouth-shape.frown { } /* no-op */
body.emotion-happy .mouth-shape::before {
top: -20%; /* war 38% -> kleiner = weiter nach oben */
height: 62%; /* etwas größer, damit der Bogen schön wirkt */
}
body.emotion-sad {
--glow: rgba(120, 180, 255, 0.32);
--smile: 0;
--frown: 1;
--omouth: 0;
--mouth-line-y: 42%;
--mouth-line-h: 12px;
--mouth-line-opacity: 0;
}
body.emotion-sad .mouth-shape { }
body.emotion-sad .mouth-shape.frown { } /* no-op */
body.emotion-angry {
--glow: rgba(255, 70, 70, 0.32);
--smile: 0;
--frown: 0.35;
--omouth: 0;
--mouth-line-opacity: 0.95;
--mouth-line-h: 16px;
}
body.emotion-angry .eye {
border-radius: 26% 74% 60% 40% / 55% 45% 55% 45%;
transform: rotate(-2deg);
}
body.emotion-surprised {
--glow: rgba(255, 220, 90, 0.34);
--smile: 0;
--frown: 0;
--omouth: 1;
--mouth-line-opacity: 0.95;
}
body.emotion-surprised { }
body.emotion-surprised.has-omouth { } /* marker in JS */
body.emotion-sleepy {
--glow: rgba(180, 180, 255, 0.22);
--smile: 0;
--frown: 0;
--omouth: 0;
--mouth-line-opacity: 0.55;
--mouth-line-h: 8px;
}
body.emotion-sleepy .eye {
height: 6vw;
max-height: 90px;
}
/* Smooth transition for everything */
* { box-sizing: border-box; }
:root{
--intensity: 0.7; /* 0..1 */
--mouth-open: 0; /* 0..1 */
}
/* Glow stärker je nach Intensität */
.eye, .mouth {
box-shadow: 0 0 calc(26px + 30px * var(--intensity)) var(--glow);
}
/* Mund-Linie “öffnet”: wird dicker und etwas tiefer */
.mouth-shape::after {
height: calc(var(--mouth-line-h) + 26px * var(--mouth-open));
top: calc(var(--mouth-line-y) + 6% * var(--mouth-open));
opacity: calc(var(--mouth-line-opacity) + 0.10 * var(--mouth-open));
}