doodle-duel / style.css
Doodle Duel Deploy
Deploy Doodle Duel to HF Space
eae6e07
Raw
History Blame Contribute Delete
26.3 kB
/* ═══════════════════════════════════════════════
Doodle Duel β€” SOTA dark gaming UI
Libraries injected via app.py:
- GSAP (animations)
- canvas-confetti (win explosion)
- Custom particle canvas (background)
═══════════════════════════════════════════════ */
@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;700;800&family=Space+Mono:wght@700&display=swap');
/* ── Tokens ──────────────────────────────────── */
:root {
--c-bg: #07061a;
--c-surface: rgba(255,255,255,0.04);
--c-glass: rgba(255,255,255,0.07);
--c-border: rgba(255,255,255,0.10);
--c-glow: #7c3aed;
--c-pink: #f472b6;
--c-cyan: #22d3ee;
--c-gold: #fbbf24;
--c-green: #34d399;
--c-red: #f87171;
--c-text: #f1f0ff;
--c-muted: #6b6a8a;
--c-purple: #a78bfa;
--blur: blur(18px);
--radius: 18px;
--glow-sm: 0 0 12px rgba(124,58,237,0.5);
--glow-md: 0 0 24px rgba(124,58,237,0.6), 0 0 48px rgba(124,58,237,0.2);
--glow-pink: 0 0 20px rgba(244,114,182,0.5);
--glow-cyan: 0 0 20px rgba(34,211,238,0.5);
}
/* ── Reset / Base ────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
/* Always reserve the vertical scrollbar's space. Without this, the first model
prediction fills the side panel and pushes the page tall enough to spawn a
scrollbar; that scrollbar steals ~15px of viewport width, reflows the centered
layout, and makes the Sketchpad re-fit to a new zoom % β€” mid-stroke, which
remaps the pen and leaves a stray diagonal. Reserving the gutter up front keeps
the canvas width (and its zoom) constant, so the layout never shifts. */
html { overflow-y: scroll; scrollbar-gutter: stable; }
/* Particle canvas lives behind everything */
#dd-particles {
position: fixed;
inset: 0;
z-index: 0;
pointer-events: none;
}
.gradio-container {
position: relative;
z-index: 1;
max-width: 1040px !important;
margin: 0 auto !important;
background: transparent !important;
font-family: 'Space Grotesk', system-ui, sans-serif !important;
color: var(--c-text) !important;
min-height: 100vh;
}
/* ── Force dark background β€” override EVERYTHING ─ */
* { box-sizing: border-box; }
/* Gradio 5/6 CSS custom properties β€” override at :root so theme tokens resolve dark */
:root {
--body-background-fill: #07061a !important;
--background-fill-primary: rgba(255,255,255,0.04) !important;
--background-fill-secondary: rgba(255,255,255,0.07) !important;
--border-color-primary: rgba(255,255,255,0.10) !important;
--border-color-accent: rgba(124,58,237,0.5) !important;
--color-accent: #7c3aed !important;
--color-accent-soft: rgba(124,58,237,0.2) !important;
--button-primary-background-fill: linear-gradient(135deg,#7c3aed,#a855f7,#ec4899) !important;
--button-primary-background-fill-hover: linear-gradient(135deg,#6d28d9,#9333ea,#db2777) !important;
--button-primary-text-color: #fff !important;
--button-secondary-background-fill: rgba(255,255,255,0.04) !important;
--button-secondary-border-color: rgba(255,255,255,0.1) !important;
--button-secondary-text-color: #eae8ff !important;
--input-background-fill: rgba(255,255,255,0.04) !important;
--input-border-color: rgba(255,255,255,0.10) !important;
--input-placeholder-color: #6b6a8a !important;
--block-background-fill: transparent !important;
--block-border-color: rgba(255,255,255,0.08) !important;
--block-title-text-color: #9491bc !important;
--panel-background-fill: transparent !important;
--panel-border-color: transparent !important;
--section-header-text-color: #9491bc !important;
--body-text-color: #eae8ff !important;
--body-text-color-subdued: #6b6a8a !important;
--link-text-color: #a78bfa !important;
--link-text-color-hover: #c4b5fd !important;
--shadow-drop: none !important;
--shadow-drop-lg: none !important;
}
html, body { background: #07061a !important; background-color: #07061a !important; }
.gradio-container, .main, .wrap, .contain, #root, #app,
[class*="gradio"], [data-testid] > div { background: transparent !important; }
/* Kill all white/light panel backgrounds */
.block, .form, .gap, .panel, .gr-group, .gr-box, .gr-form,
.prose, section.mt-4, .app, .svelte-1b6s6s, .svelte-vt1mxs {
background: transparent !important;
box-shadow: none !important;
border: none !important;
}
footer, .built-with, footer.svelte-mpyp48, [class*="footer"] { display: none !important; }
/* ── Glassmorphism helper ────────────────────── */
.glass {
background: var(--c-glass);
backdrop-filter: var(--blur);
-webkit-backdrop-filter: var(--blur);
border: 1px solid var(--c-border);
border-radius: var(--radius);
}
/* ── Title ───────────────────────────────────── */
#title {
text-align: center;
font-size: 2.4rem;
font-weight: 800;
letter-spacing: -1px;
margin: 0.7rem 0 0;
background: linear-gradient(135deg, #a78bfa 0%, #f472b6 50%, #22d3ee 100%);
background-size: 200% 200%;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
animation: titleShimmer 4s ease-in-out infinite;
filter: drop-shadow(0 0 30px rgba(167,139,250,0.4));
}
@keyframes titleShimmer {
0%,100% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
}
#blurb {
text-align: center;
color: var(--c-muted);
font-size: 0.88rem;
margin-bottom: 0.5rem;
letter-spacing: 0.02em;
}
/* ── Topbar ──────────────────────────────────── */
.topbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 14px;
background: var(--c-glass);
backdrop-filter: var(--blur);
-webkit-backdrop-filter: var(--blur);
border: 1px solid var(--c-border);
border-radius: var(--radius);
padding: 12px 20px;
box-shadow: var(--glow-sm), inset 0 1px 0 rgba(255,255,255,0.08);
position: relative;
overflow: hidden;
}
.topbar::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0;
height: 1px;
background: linear-gradient(90deg, transparent, var(--c-purple), var(--c-pink), transparent);
opacity: 0.6;
}
.topbar .prompt {
color: var(--c-text);
font-size: 1rem;
font-weight: 700;
text-align: center;
width: 100%;
}
.draw-card { display: flex; flex-direction: column; gap: 3px; min-width: 140px; }
.draw-card .dl {
font-size: 0.62rem;
color: var(--c-muted);
letter-spacing: 0.18em;
text-transform: uppercase;
font-weight: 700;
}
.draw-card .word {
font-family: 'Space Mono', monospace;
font-size: 1.5rem;
font-weight: 700;
color: var(--c-purple);
text-shadow: 0 0 20px rgba(167,139,250,0.6);
letter-spacing: -0.5px;
}
.cat {
display: inline-block;
font-size: 0.6rem;
background: rgba(167,139,250,0.12);
color: var(--c-purple);
border: 1px solid rgba(167,139,250,0.3);
border-radius: 6px;
padding: 2px 8px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
}
/* Timer ring */
.ring-t {
font-family: 'Space Mono', monospace;
font-size: 0.9rem;
font-weight: 700;
fill: var(--c-text);
}
.score-card {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 4px;
min-width: 110px;
}
.scores { display: flex; align-items: center; gap: 10px; }
.score-card > span {
color: var(--c-muted);
font-size: 0.78rem;
font-weight: 700;
}
.score-card .score {
font-family: 'Space Mono', monospace;
font-size: 1.3rem;
font-weight: 700;
color: var(--c-gold);
text-shadow: 0 0 16px rgba(251,191,36,0.5);
}
.best {
font-size: 0.82rem;
font-weight: 700;
color: var(--c-pink);
text-shadow: var(--glow-pink);
}
/* ── Word choice buttons ─────────────────────── */
#word-choices { gap: 10px; }
#word-choices button {
border-radius: 14px !important;
font-family: 'Space Grotesk', sans-serif !important;
font-weight: 800 !important;
font-size: 1.1rem !important;
padding: 0.7rem 0.5rem !important;
text-transform: capitalize;
background: var(--c-glass) !important;
backdrop-filter: var(--blur) !important;
border: 1px solid rgba(167,139,250,0.35) !important;
color: var(--c-purple) !important;
box-shadow: var(--glow-sm), inset 0 1px 0 rgba(255,255,255,0.06) !important;
transition: all 0.2s cubic-bezier(0.34,1.56,0.64,1) !important;
position: relative !important;
overflow: hidden !important;
}
#word-choices button::after {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(135deg, rgba(167,139,250,0.15), transparent);
opacity: 0;
transition: opacity 0.2s;
}
#word-choices button:hover {
transform: translateY(-5px) scale(1.04) !important;
border-color: var(--c-purple) !important;
box-shadow: var(--glow-md), inset 0 1px 0 rgba(255,255,255,0.1) !important;
color: #fff !important;
}
#word-choices button:hover::after { opacity: 1; }
/* ── AI Robot area ───────────────────────────── */
.ai-area {
display: flex;
align-items: center;
gap: 14px;
margin: 0.8rem 0;
}
.robot {
font-size: 3.2rem;
filter: drop-shadow(0 0 16px rgba(167,139,250,0.6));
flex-shrink: 0;
transition: filter 0.3s;
}
.robot.think {
animation: robotWobble 0.9s ease-in-out infinite;
filter: drop-shadow(0 0 20px rgba(244,114,182,0.7));
}
.robot.win {
animation: robotPop 0.6s cubic-bezier(0.34,1.56,0.64,1);
filter: drop-shadow(0 0 28px rgba(52,211,153,0.8));
}
@keyframes robotWobble {
0%,100% { transform: rotate(-8deg) translateY(0); }
50% { transform: rotate(8deg) translateY(-6px); }
}
@keyframes robotPop {
0% { transform: scale(0.3) rotate(-20deg); }
60% { transform: scale(1.35) rotate(10deg); }
100% { transform: scale(1) rotate(0deg); }
}
.ai-bubble {
position: relative;
background: var(--c-glass);
backdrop-filter: var(--blur);
-webkit-backdrop-filter: var(--blur);
border: 1px solid rgba(167,139,250,0.4);
border-radius: var(--radius);
padding: 0.9rem 1.2rem;
color: var(--c-text);
font-size: 1.05rem;
font-weight: 700;
flex: 1;
box-shadow: var(--glow-sm), inset 0 1px 0 rgba(255,255,255,0.07);
line-height: 1.5;
overflow: hidden;
}
.ai-bubble::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0;
height: 1px;
background: linear-gradient(90deg, transparent, var(--c-purple), transparent);
opacity: 0.7;
}
/* Animated border glow on bubble */
.ai-bubble::after {
content: '';
position: absolute;
inset: -1px;
border-radius: var(--radius);
background: linear-gradient(135deg, rgba(167,139,250,0.3), transparent 60%, rgba(244,114,182,0.2));
z-index: -1;
opacity: 0;
transition: opacity 0.3s;
}
.robot.think ~ .ai-bubble::after { opacity: 1; animation: borderPulse 2s ease-in-out infinite; }
@keyframes borderPulse {
0%,100% { opacity: 0.3; }
50% { opacity: 0.8; }
}
/* Tail of bubble */
.ai-bubble:before {
content: '';
position: absolute;
left: -8px;
top: 22px;
width: 0; height: 0;
border: 7px solid transparent;
border-right-color: rgba(167,139,250,0.4);
}
/* Guess chips */
.chip {
display: inline-block;
background: rgba(167,139,250,0.15);
color: var(--c-purple);
border: 1px solid rgba(167,139,250,0.4);
border-radius: 8px;
padding: 2px 10px;
margin: 0 3px;
font-weight: 800;
font-size: 0.95em;
animation: chipPop 0.3s cubic-bezier(0.34,1.56,0.64,1);
box-shadow: var(--glow-sm);
}
@keyframes chipPop {
0% { transform: scale(0.5) translateY(8px); opacity: 0; }
100% { transform: scale(1) translateY(0); opacity: 1; }
}
/* ── Stage layout ── everything here is frozen so the canvas never moves ── */
/* Decouple the two columns' heights (no stretch) and never wrap, so the canvas
column's geometry is independent of the thoughts column. */
#stage {
align-items: flex-start !important;
flex-wrap: nowrap !important;
justify-content: center !important;
}
/* FIXED pixel widths (not %): a percentage depends on the container width, which
the scrollbar appearing/disappearing changes β€” that is what recalculated the
Sketchpad zoom (71%↔83%) mid-stroke. A fixed px width is immune, so the zoom
is computed once and frozen. Totals 580+360 = 940px, comfortably inside the
1040px container so the columns never wrap. */
#canvas-col {
flex: 0 0 580px !important;
min-width: 580px !important;
max-width: 580px !important;
}
#thoughts-col {
flex: 0 0 360px !important;
min-width: 360px !important;
max-width: 360px !important;
}
/* The thoughts panel is a FIXED-SIZE box: new reasoning scrolls inside tp-body
instead of growing (or shrinking) the panel. Height matches the canvas so the
row looks balanced and its height never changes. */
#thoughts-col .think-panel {
min-height: 384px !important;
height: 384px !important;
max-height: 384px !important;
}
#thoughts-col .tp-body {
max-height: 300px !important;
}
/* ── Canvas ──────────────────────────────────── */
.gradio-container .gr-sketchpad,
.gradio-container [data-testid="sketchpad"],
.gradio-container canvas:not(#dd-particles) {
border-radius: 16px !important;
}
/* White drawing surface */
.gradio-container .sketchpad-container {
background: #fff !important;
border-radius: 16px !important;
border: 1px solid var(--c-border) !important;
box-shadow: 0 0 0 1px rgba(167,139,250,0.2), 0 8px 32px rgba(0,0,0,0.4) !important;
/* Promote the drawing surface to its own compositor layer and contain its
paints, so a sibling re-render (e.g. the guess landing in the right panel)
can't force the canvas to repaint mid-stroke and drop a pointer event. */
transform: translateZ(0);
contain: layout paint;
}
/* ── Control buttons ─────────────────────────── */
#controls button {
border-radius: 14px !important;
font-family: 'Space Grotesk', sans-serif !important;
font-weight: 800 !important;
font-size: 0.95rem !important;
letter-spacing: 0.02em !important;
transition: all 0.2s cubic-bezier(0.34,1.56,0.64,1) !important;
position: relative !important;
overflow: hidden !important;
}
/* Ripple effect */
#controls button::after {
content: '';
position: absolute;
width: 100px; height: 100px;
background: rgba(255,255,255,0.15);
border-radius: 50%;
transform: scale(0);
top: 50%; left: 50%;
margin: -50px 0 0 -50px;
transition: transform 0.4s, opacity 0.4s;
opacity: 0;
}
#controls button:active::after {
transform: scale(3);
opacity: 0;
transition: 0s;
}
/* Start / Next */
#controls button:first-child {
background: linear-gradient(135deg, #7c3aed, #a855f7, #ec4899) !important;
background-size: 200% 200% !important;
color: #fff !important;
border: none !important;
box-shadow: var(--glow-md) !important;
animation: btnGradient 3s ease infinite !important;
}
@keyframes btnGradient {
0%,100% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
}
#controls button:first-child:hover {
transform: translateY(-3px) scale(1.03) !important;
box-shadow: 0 0 32px rgba(124,58,237,0.8), 0 0 64px rgba(124,58,237,0.3) !important;
}
/* Hint */
#controls button:nth-child(2) {
background: rgba(251,191,36,0.08) !important;
color: var(--c-gold) !important;
border: 1px solid rgba(251,191,36,0.3) !important;
}
#controls button:nth-child(2):hover {
background: rgba(251,191,36,0.15) !important;
box-shadow: 0 0 20px rgba(251,191,36,0.4) !important;
transform: translateY(-2px) !important;
}
/* Clear */
#controls button:nth-child(3) {
background: var(--c-glass) !important;
color: var(--c-muted) !important;
border: 1px solid var(--c-border) !important;
}
#controls button:nth-child(3):hover {
color: var(--c-text) !important;
transform: translateY(-2px) !important;
}
/* ── Right panel: Robot thoughts ─────────────── */
.think-panel {
height: 100%;
display: flex;
flex-direction: column;
background: var(--c-glass);
backdrop-filter: var(--blur);
-webkit-backdrop-filter: var(--blur);
border: 1px solid var(--c-border);
border-radius: var(--radius);
padding: 14px 16px;
box-shadow: var(--glow-sm), inset 0 1px 0 rgba(255,255,255,0.05);
min-height: 360px;
position: relative;
overflow: hidden;
}
.think-panel::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0;
height: 1px;
background: linear-gradient(90deg, transparent, var(--c-cyan), transparent);
opacity: 0.5;
}
.tp-title {
font-weight: 800;
color: var(--c-text);
font-size: 0.95rem;
margin-bottom: 12px;
display: flex;
align-items: center;
gap: 7px;
letter-spacing: 0.01em;
}
.tp-sub {
font-family: 'Space Mono', monospace;
font-size: 0.65rem;
font-weight: 700;
color: var(--c-cyan);
background: rgba(34,211,238,0.1);
border: 1px solid rgba(34,211,238,0.25);
border-radius: 6px;
padding: 2px 8px;
margin-left: 4px;
box-shadow: var(--glow-cyan);
}
.tp-body {
display: flex;
flex-direction: column;
gap: 8px;
overflow-y: auto;
max-height: 360px;
padding-right: 4px;
scrollbar-width: thin;
scrollbar-color: rgba(167,139,250,0.3) transparent;
}
.tp-body::-webkit-scrollbar { width: 4px; }
.tp-body::-webkit-scrollbar-track { background: transparent; }
.tp-body::-webkit-scrollbar-thumb { background: rgba(167,139,250,0.3); border-radius: 4px; }
.tp-empty {
color: var(--c-muted);
font-size: 0.88rem;
font-weight: 600;
font-style: italic;
line-height: 1.6;
}
.thought {
background: rgba(255,255,255,0.03);
border: 1px solid var(--c-border);
border-left: 3px solid rgba(167,139,250,0.4);
border-radius: 10px;
padding: 8px 12px;
color: var(--c-text);
font-size: 0.88rem;
font-weight: 600;
line-height: 1.45;
animation: thoughtSlide 0.35s cubic-bezier(0.34,1.56,0.64,1);
}
@keyframes thoughtSlide {
0% { transform: translateX(20px) scale(0.95); opacity: 0; }
100% { transform: translateX(0) scale(1); opacity: 1; }
}
.thought.latest {
background: rgba(124,58,237,0.1);
border-color: rgba(167,139,250,0.5);
border-left-color: var(--c-purple);
color: #e8e4ff;
font-weight: 700;
box-shadow: var(--glow-sm);
}
.thought.analyzing {
background: rgba(251,191,36,0.06);
border-left-color: var(--c-gold);
border-color: rgba(251,191,36,0.2);
color: #fde68a;
font-weight: 700;
animation: analyzePulse 1.6s ease-in-out infinite;
}
@keyframes analyzePulse {
0%,100% { opacity: 0.55; transform: scale(1); }
50% { opacity: 1; transform: scale(1.01); }
}
/* Spinner for analyzing */
.analyzing-spinner {
display: inline-block;
width: 12px; height: 12px;
border: 2px solid rgba(251,191,36,0.3);
border-top-color: var(--c-gold);
border-radius: 50%;
animation: spin 0.8s linear infinite;
margin-right: 6px;
vertical-align: middle;
}
@keyframes spin { to { transform: rotate(360deg); } }
/* ── Result banner ───────────────────────────── */
.result {
position: relative;
overflow: hidden;
margin-top: 0.8rem;
padding: 1.1rem 1.4rem;
border-radius: var(--radius);
text-align: center;
animation: resultAppear 0.5s cubic-bezier(0.34,1.56,0.64,1);
}
@keyframes resultAppear {
0% { transform: scale(0.8) translateY(20px); opacity: 0; }
100% { transform: scale(1) translateY(0); opacity: 1; }
}
.result.win {
background: linear-gradient(135deg, rgba(52,211,153,0.08), rgba(16,185,129,0.05));
border: 1px solid rgba(52,211,153,0.4);
box-shadow: 0 0 40px rgba(52,211,153,0.15), inset 0 1px 0 rgba(52,211,153,0.2);
}
.result.lose {
background: linear-gradient(135deg, rgba(248,113,113,0.08), rgba(239,68,68,0.05));
border: 1px solid rgba(248,113,113,0.35);
box-shadow: 0 0 30px rgba(248,113,113,0.1), inset 0 1px 0 rgba(248,113,113,0.15);
}
.r-title {
font-size: 1.4rem;
font-weight: 800;
color: var(--c-text);
letter-spacing: -0.3px;
}
.r-sub {
color: var(--c-muted);
margin-top: 4px;
font-weight: 600;
font-size: 0.93rem;
line-height: 1.5;
}
/* CSS confetti fallback (animated before JS confetti fires) */
.confetti i {
position: absolute;
top: -12px;
width: 8px; height: 14px;
border-radius: 3px;
animation: fallDown 1.8s linear infinite;
}
@keyframes fallDown {
to { transform: translateY(260px) rotate(720deg); opacity: 0; }
}
/* ── AI-turn topbar variant ──────────────────── */
.topbar.ai-turn-bar {
border-color: rgba(34,211,238,0.35);
box-shadow: var(--glow-cyan), inset 0 1px 0 rgba(255,255,255,0.06);
}
.topbar.ai-turn-bar::before {
background: linear-gradient(90deg, transparent, var(--c-cyan), transparent);
}
.topbar.generating {
animation: generatePulse 1.4s ease-in-out infinite;
}
@keyframes generatePulse {
0%,100% { box-shadow: var(--glow-cyan); }
50% { box-shadow: 0 0 40px rgba(34,211,238,0.5), 0 0 80px rgba(34,211,238,0.15); }
}
/* Dot loader for generating state */
.dot-loader span {
display: inline-block;
animation: dotBounce 1.4s ease-in-out infinite;
font-size: 1.4rem;
line-height: 1;
}
.dot-loader span:nth-child(2) { animation-delay: 0.2s; }
.dot-loader span:nth-child(3) { animation-delay: 0.4s; }
@keyframes dotBounce {
0%,80%,100% { transform: translateY(0); opacity: 0.4; }
40% { transform: translateY(-8px); opacity: 1; }
}
/* ── AI canvas display area ──────────────────── */
.ai-canvas-area {
width: 100%;
aspect-ratio: 500 / 360;
border-radius: 16px;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
position: relative;
background: var(--c-glass);
backdrop-filter: var(--blur);
border: 1px solid var(--c-border);
box-shadow: 0 0 0 1px rgba(34,211,238,0.15), 0 8px 32px rgba(0,0,0,0.4);
min-height: 300px;
}
.ai-canvas-area.svg-reveal {
border-color: rgba(34,211,238,0.4);
box-shadow: var(--glow-cyan), 0 8px 32px rgba(0,0,0,0.4);
}
.svg-wrapper {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background: #fff;
border-radius: 16px;
overflow: hidden;
}
.svg-wrapper svg {
width: 100% !important;
height: 100% !important;
max-width: 100%;
max-height: 100%;
background: #ffffff !important;
}
.canvas-placeholder {
text-align: center;
color: var(--c-muted);
font-size: 1rem;
font-weight: 700;
line-height: 1.8;
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
}
.canvas-placeholder span { color: var(--c-text); font-size: 1.1rem; }
.canvas-placeholder small { color: var(--c-muted); font-size: 0.82rem; }
/* Brush loader animation */
.brush-loader {
font-size: 2.8rem;
animation: brushDraw 1.2s ease-in-out infinite;
filter: drop-shadow(0 0 12px rgba(34,211,238,0.6));
}
@keyframes brushDraw {
0% { transform: translate(-30px, -20px) rotate(-30deg); }
25% { transform: translate(30px, -10px) rotate(10deg); }
50% { transform: translate(-10px, 20px) rotate(-15deg); }
75% { transform: translate(20px, 10px) rotate(20deg); }
100% { transform: translate(-30px, -20px) rotate(-30deg); }
}
.drawing-anim {
gap: 16px;
}
/* ── Player guess input ──────────────────────── */
#ai-guess-row { margin-top: 0.6rem; }
#ai-guess-input input, #ai-guess-input textarea {
background: var(--c-glass) !important;
backdrop-filter: var(--blur) !important;
border: 1px solid rgba(34,211,238,0.35) !important;
border-radius: 14px !important;
color: var(--c-text) !important;
font-family: 'Space Grotesk', sans-serif !important;
font-size: 1.1rem !important;
font-weight: 700 !important;
padding: 0.7rem 1rem !important;
box-shadow: var(--glow-cyan) !important;
transition: all 0.2s !important;
}
#ai-guess-input input:focus, #ai-guess-input textarea:focus {
border-color: var(--c-cyan) !important;
box-shadow: 0 0 24px rgba(34,211,238,0.5) !important;
outline: none !important;
}
#ai-guess-btn button {
border-radius: 14px !important;
font-family: 'Space Grotesk', sans-serif !important;
font-weight: 800 !important;
font-size: 1rem !important;
background: linear-gradient(135deg, #0891b2, #22d3ee) !important;
color: #fff !important;
border: none !important;
box-shadow: var(--glow-cyan) !important;
transition: all 0.2s cubic-bezier(0.34,1.56,0.64,1) !important;
}
#ai-guess-btn button:hover {
transform: translateY(-2px) scale(1.03) !important;
box-shadow: 0 0 30px rgba(34,211,238,0.7) !important;
}
/* Wrong guess chip */
.wrong-chip {
background: rgba(248,113,113,0.1) !important;
color: var(--c-red) !important;
border-color: rgba(248,113,113,0.3) !important;
}
.thought.wrong-guess {
background: rgba(248,113,113,0.05);
border-left-color: var(--c-red);
border-color: rgba(248,113,113,0.2);
color: #fca5a5;
}
/* AI word mask display */
.ai-word-mask {
font-family: 'Space Mono', monospace !important;
color: var(--c-cyan) !important;
text-shadow: 0 0 20px rgba(34,211,238,0.6) !important;
}
/* ── Gradio overrides ────────────────────────── */
.gradio-container .label-wrap,
.gradio-container label {
color: var(--c-muted) !important;
font-family: 'Space Grotesk', sans-serif !important;
}
/* Remove Gradio's default white card backgrounds */
.gradio-container .gr-group,
.gradio-container .gr-form,
.gradio-container .gr-box,
.gradio-container .block {
background: transparent !important;
border: none !important;
box-shadow: none !important;
padding: 0 !important;
}
.gradio-container .gap { background: transparent !important; }