diff --git a/web/src/styles.css b/web/src/styles.css index 5c2f66b..f735b4d 100644 --- a/web/src/styles.css +++ b/web/src/styles.css @@ -1,26 +1,52 @@ /* ============================================================ - Super Auto Pets: The Board Game — cozy tabletop theme. - Deep felt table, cream cards with cocoa borders, chunky type. + Super Auto Pets: The Board Game — cozy tabletop, elevated. + + The whole app is one lamp-lit game table: a warm spotlight over + deep felt, walnut rails, and thick printed cards that cast real + shadows. Panels read as recessed felt trays, not floating boxes. + Palette stays warm end-to-end — pine, walnut, parchment, honey, + coral — so nothing feels generic or cold. ============================================================ */ :root { - --felt-900: #12351f; - --felt-800: #1a4a2b; - --felt-700: #226038; - --wood: #5b3a1e; - --wood-light: #7a5230; - --cream: #fdf3dc; - --cream-dark: #f3e3bd; + /* Felt — a lamp-lit pine table, warm in the middle, dark at the rim. */ + --felt-900: #0f2c20; + --felt-800: #163a2a; + --felt-700: #1d4c35; + --felt-600: #266145; + --felt-lit: #2c6f4d; + + /* Walnut rails and trays. */ + --wood: #5a3a20; + --wood-light: #815129; + --wood-dark: #3d2614; + + /* Printed parchment cards. */ + --cream: #fbf1d7; + --cream-dark: #efdcac; --cocoa: #4a2c14; - --ink: #33230f; - --coral: #ff8a3d; - --coral-dark: #e06a1b; - --gold: #ffcf5c; + --cocoa-soft: #6b4426; + --ink: #35240f; + --ink-soft: rgba(53, 36, 15, 0.66); + + /* Warm accents. */ + --coral: #f4884a; + --coral-dark: #d9611a; + --gold: #f6c94e; + --gold-deep: #e0a52f; + --honey: #f0b64a; + --sage: #4f9d78; + --sage-dark: #327a58; --red: #d94a38; - --teal: #2f9c8a; + --red-soft: #ffb3a7; + --font-display: 'Lilita One', system-ui, sans-serif; --font-body: 'Nunito', system-ui, sans-serif; - --card-radius: 12px; + --card-radius: 14px; + + /* Reusable warm shadows so depth stays consistent everywhere. */ + --shadow-card: 0 10px 20px -6px rgba(20, 12, 4, 0.55), 0 2px 4px rgba(20, 12, 4, 0.4); + --tray-inset: inset 0 2px 5px rgba(0, 0, 0, 0.45), inset 0 -1px 0 rgba(255, 255, 255, 0.05); } * { @@ -39,11 +65,18 @@ body { font-family: var(--font-body); color: var(--cream); background-color: var(--felt-900); + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + /* A warm overhead lamp, a soft felt weave, fine grain, and a dark rim. */ background-image: - radial-gradient(ellipse at 50% -20%, rgba(255, 255, 255, 0.09), transparent 60%), - radial-gradient(ellipse at 50% 120%, rgba(0, 0, 0, 0.45), transparent 60%), - url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E"), - linear-gradient(160deg, var(--felt-800), var(--felt-900) 70%); + radial-gradient(ellipse 90% 60% at 50% -8%, rgba(255, 214, 138, 0.16), transparent 60%), + radial-gradient(ellipse 70% 55% at 50% 32%, rgba(64, 150, 104, 0.22), transparent 70%), + radial-gradient(ellipse at 50% 116%, rgba(0, 0, 0, 0.55), transparent 62%), + repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.012) 0 2px, transparent 2px 4px), + repeating-linear-gradient(-45deg, rgba(0, 0, 0, 0.03) 0 2px, transparent 2px 4px), + url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.045'/%3E%3C/svg%3E"), + linear-gradient(165deg, var(--felt-700), var(--felt-900) 78%); + background-attachment: fixed; } h1, @@ -51,11 +84,11 @@ h2, h3 { font-family: var(--font-display); font-weight: 400; - letter-spacing: 0.02em; + letter-spacing: 0.01em; } .muted { - color: rgba(253, 243, 220, 0.55); + color: rgba(253, 243, 220, 0.52); } .centered { @@ -70,70 +103,130 @@ h3 { .hint { font-size: 0.9rem; - color: rgba(253, 243, 220, 0.65); + color: rgba(253, 243, 220, 0.62); text-align: center; } .warn-text { color: var(--gold); - font-weight: 700; + font-weight: 800; } /* ---------- buttons ---------- */ +/* Tactile printed tokens: a soft top sheen, a pressed edge underneath, and a + satisfying travel on click — like pushing a wooden meeple down. */ .btn { + position: relative; font-family: var(--font-display); font-size: 1rem; letter-spacing: 0.03em; color: var(--cream); - background: var(--wood); - border: 3px solid rgba(0, 0, 0, 0.25); + background: linear-gradient(180deg, var(--wood-light), var(--wood)); + border: none; border-radius: 12px; - padding: 10px 18px; + padding: 11px 20px; cursor: pointer; - box-shadow: 0 4px 0 rgba(0, 0, 0, 0.35); - transition: transform 80ms ease, box-shadow 80ms ease, filter 120ms ease; + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.22), + inset 0 -2px 3px rgba(0, 0, 0, 0.28), + 0 4px 0 var(--wood-dark), + 0 6px 10px rgba(0, 0, 0, 0.35); + transition: transform 90ms ease, box-shadow 90ms ease, filter 140ms ease; } .btn:hover:not(:disabled) { - filter: brightness(1.1); + filter: brightness(1.07) saturate(1.05); } .btn:active:not(:disabled) { transform: translateY(3px); - box-shadow: 0 1px 0 rgba(0, 0, 0, 0.35); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.18), + inset 0 -1px 2px rgba(0, 0, 0, 0.3), + 0 1px 0 var(--wood-dark), + 0 2px 4px rgba(0, 0, 0, 0.35); } .btn:disabled { - opacity: 0.4; + opacity: 0.42; cursor: not-allowed; + filter: saturate(0.6); } .btn-primary { - background: linear-gradient(180deg, var(--coral), var(--coral-dark)); + background: linear-gradient(180deg, #ffa257, var(--coral-dark)); color: #fff; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); + text-shadow: 0 1px 2px rgba(120, 45, 5, 0.55); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.35), + inset 0 -2px 3px rgba(150, 55, 0, 0.4), + 0 4px 0 #ab4a13, + 0 7px 12px rgba(120, 45, 5, 0.4); +} + +.btn-primary:active:not(:disabled) { + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.3), + inset 0 -1px 2px rgba(150, 55, 0, 0.4), + 0 1px 0 #ab4a13, + 0 2px 5px rgba(120, 45, 5, 0.4); } .btn-secondary { - background: linear-gradient(180deg, var(--teal), #227465); + background: linear-gradient(180deg, #5cb68c, var(--sage-dark)); + color: #f4fff8; + text-shadow: 0 1px 2px rgba(15, 60, 40, 0.5); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.3), + inset 0 -2px 3px rgba(15, 60, 40, 0.35), + 0 4px 0 #245840, + 0 7px 12px rgba(15, 60, 40, 0.35); +} + +.btn-secondary:active:not(:disabled) { + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.25), + inset 0 -1px 2px rgba(15, 60, 40, 0.35), + 0 1px 0 #245840, + 0 2px 5px rgba(15, 60, 40, 0.35); } .btn-ghost { - background: transparent; - border-color: rgba(253, 243, 220, 0.3); + background: rgba(253, 243, 220, 0.06); + border: 2px solid rgba(253, 243, 220, 0.22); + color: var(--cream); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08); +} + +.btn-ghost:hover:not(:disabled) { + background: rgba(253, 243, 220, 0.12); + filter: none; +} + +.btn-ghost:active:not(:disabled) { + transform: translateY(2px); box-shadow: none; } .btn-big { - font-size: 1.25rem; - padding: 14px 28px; + font-size: 1.3rem; + padding: 15px 32px; + letter-spacing: 0.02em; } .btn-sm { font-size: 0.8rem; - padding: 4px 10px; - border-width: 2px; + padding: 6px 11px; + border-radius: 9px; + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.18), + 0 3px 0 var(--wood-dark), + 0 4px 6px rgba(0, 0, 0, 0.3); +} + +.btn-ghost.btn-sm { + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08); } /* ---------- home ---------- */ @@ -144,13 +237,15 @@ h3 { flex-direction: column; align-items: center; justify-content: center; - gap: 20px; + gap: 22px; padding: 24px; } .home-pets { - font-size: 2.6rem; - letter-spacing: 0.3em; + font-size: 2.8rem; + letter-spacing: 0.28em; + padding-left: 0.28em; + filter: drop-shadow(0 6px 8px rgba(0, 0, 0, 0.45)); animation: float 3s ease-in-out infinite; } @@ -165,39 +260,54 @@ h3 { } .home-title { - font-size: clamp(2.2rem, 6vw, 3.6rem); + font-size: clamp(2.4rem, 6.5vw, 3.9rem); text-align: center; color: var(--gold); - text-shadow: 0 4px 0 rgba(0, 0, 0, 0.35); + text-shadow: + 0 2px 0 var(--gold-deep), + 0 5px 0 rgba(90, 58, 32, 0.5), + 0 8px 14px rgba(0, 0, 0, 0.4); display: flex; flex-direction: column; - line-height: 1.05; + line-height: 1.02; } .home-subtitle { - font-size: 0.42em; + font-size: 0.4em; color: var(--cream); - letter-spacing: 0.25em; + letter-spacing: 0.34em; + padding-left: 0.34em; text-transform: uppercase; + text-shadow: 0 2px 3px rgba(0, 0, 0, 0.4); + margin-top: 0.15em; } +/* The home card is a little parchment sign-in slip pinned to the felt. */ .home-card { - background: rgba(0, 0, 0, 0.25); - border: 2px solid rgba(253, 243, 220, 0.15); + position: relative; + background: + linear-gradient(180deg, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.22)); + border: 1px solid rgba(253, 243, 220, 0.14); border-radius: 20px; - padding: 28px; + padding: 30px; display: flex; flex-direction: column; gap: 16px; - width: min(380px, 92vw); + width: min(384px, 92vw); + box-shadow: + var(--tray-inset), + 0 18px 40px -12px rgba(0, 0, 0, 0.6); } .field { display: flex; flex-direction: column; - gap: 6px; - font-weight: 700; - font-size: 0.9rem; + gap: 7px; + font-weight: 800; + font-size: 0.82rem; + letter-spacing: 0.04em; + text-transform: uppercase; + color: rgba(253, 243, 220, 0.7); } .field input, @@ -206,28 +316,46 @@ h3 { font-size: 1.1rem; font-weight: 700; color: var(--ink); - background: var(--cream); - border: 3px solid var(--cocoa); - border-radius: 10px; - padding: 10px 12px; + background: linear-gradient(180deg, #fff8e8, var(--cream)); + border: 2px solid var(--cocoa-soft); + border-radius: 11px; + padding: 11px 13px; outline: none; width: 100%; + box-shadow: inset 0 2px 4px rgba(74, 44, 20, 0.18); + transition: border-color 120ms ease, box-shadow 120ms ease; +} + +.field input::placeholder { + color: rgba(53, 36, 15, 0.38); + font-weight: 600; +} + +.field input:focus, +.code-input:focus { + border-color: var(--coral); + box-shadow: + inset 0 2px 4px rgba(74, 44, 20, 0.18), + 0 0 0 3px rgba(244, 136, 74, 0.28); } .code-input { font-family: var(--font-display); letter-spacing: 0.35em; + padding-left: calc(13px + 0.35em); text-transform: uppercase; text-align: center; } .home-divider { text-align: center; - font-size: 0.85rem; + font-size: 0.82rem; color: rgba(253, 243, 220, 0.5); display: flex; align-items: center; - gap: 10px; + gap: 12px; + text-transform: uppercase; + letter-spacing: 0.08em; } .home-divider::before, @@ -235,7 +363,7 @@ h3 { content: ''; flex: 1; height: 1px; - background: rgba(253, 243, 220, 0.2); + background: linear-gradient(90deg, transparent, rgba(253, 243, 220, 0.28), transparent); } .home-join { @@ -244,7 +372,7 @@ h3 { } .home-error { - color: #ffb3a7; + color: var(--red-soft); font-weight: 700; text-align: center; } @@ -257,53 +385,81 @@ h3 { flex-direction: column; } +/* A solid walnut rail across the top of the table, with grain and a worn + highlight along its top edge. */ .topbar { display: flex; align-items: center; gap: 16px; - padding: 10px 16px; - background: linear-gradient(180deg, var(--wood-light), var(--wood)); - border-bottom: 4px solid rgba(0, 0, 0, 0.35); + padding: 11px 18px; + background: + repeating-linear-gradient(92deg, rgba(0, 0, 0, 0.05) 0 3px, transparent 3px 7px), + linear-gradient(180deg, var(--wood-light), var(--wood) 65%, var(--wood-dark)); + border-bottom: 3px solid var(--wood-dark); + box-shadow: + inset 0 1px 0 rgba(255, 220, 170, 0.25), + 0 4px 14px rgba(0, 0, 0, 0.4); flex-wrap: wrap; + position: relative; + z-index: 10; } .topbar-brand { + display: flex; + align-items: center; + gap: 7px; font-family: var(--font-display); - font-size: 1.2rem; + font-size: 1.3rem; color: var(--gold); + text-shadow: 0 2px 2px rgba(0, 0, 0, 0.45); + letter-spacing: 0.04em; } .topbar-round { font-size: 0.95rem; + font-weight: 700; + color: rgba(255, 245, 225, 0.9); +} + +.topbar-round strong { + color: var(--gold); } .topbar-players { display: flex; - gap: 14px; + gap: 12px; flex: 1; flex-wrap: wrap; } +/* Player tags read like enamel pins clipped to the rail. */ .topbar-player { display: flex; align-items: center; - gap: 6px; - background: rgba(0, 0, 0, 0.2); + gap: 7px; + background: linear-gradient(180deg, rgba(0, 0, 0, 0.18), rgba(0, 0, 0, 0.3)); border-radius: 999px; - padding: 4px 12px; + padding: 5px 13px; font-size: 0.9rem; + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.08), + 0 1px 2px rgba(0, 0, 0, 0.3); } .topbar-player.is-you { - outline: 2px solid var(--gold); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.1), + 0 0 0 2px var(--gold), + 0 1px 3px rgba(0, 0, 0, 0.35); } .topbar-name { - font-weight: 900; + font-weight: 800; } .chip { font-size: 0.85rem; + font-weight: 700; } .conn-dot { @@ -311,23 +467,27 @@ h3 { height: 8px; border-radius: 50%; display: inline-block; + box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.25); } .conn-dot.on { background: #6fe08b; + box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.25), 0 0 6px rgba(111, 224, 139, 0.7); } .conn-dot.off { background: var(--red); } +/* The room code, stamped like a label on a card tray. */ .topbar-code { font-family: var(--font-display); - letter-spacing: 0.25em; - background: rgba(0, 0, 0, 0.25); - border: 2px dashed rgba(253, 243, 220, 0.4); + letter-spacing: 0.28em; + padding: 5px 10px 5px calc(10px + 0.28em); + color: var(--gold); + background: rgba(0, 0, 0, 0.28); + border: 2px dashed rgba(246, 201, 78, 0.5); border-radius: 8px; - padding: 4px 10px; } .table-body { @@ -339,13 +499,14 @@ h3 { .table-main { flex: 1; - padding: 20px 16px 40px; + padding: 26px 20px 48px; max-width: 1100px; width: 100%; margin: 0 auto; } /* ---------- event log ---------- */ +/* A pinned-up ledger of what happened, paper-warm against the felt. */ .event-log { width: 300px; @@ -353,11 +514,13 @@ h3 { align-self: stretch; position: sticky; top: 0; - max-height: calc(100vh - 58px); + max-height: calc(100vh - 60px); display: flex; flex-direction: column; - background: rgba(0, 0, 0, 0.28); - border-left: 3px solid rgba(0, 0, 0, 0.35); + background: + linear-gradient(180deg, rgba(0, 0, 0, 0.22), rgba(0, 0, 0, 0.34)); + border-left: 1px solid rgba(0, 0, 0, 0.4); + box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.04); } .event-log.is-collapsed { @@ -369,12 +532,13 @@ h3 { align-items: center; justify-content: space-between; gap: 6px; - padding: 8px 10px; + padding: 10px 12px; font-family: var(--font-display); - font-size: 0.9rem; + font-size: 0.92rem; color: var(--gold); - background: rgba(0, 0, 0, 0.25); - border-bottom: 2px solid rgba(0, 0, 0, 0.3); + background: linear-gradient(180deg, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.15)); + border-bottom: 1px solid rgba(0, 0, 0, 0.35); + box-shadow: inset 0 -1px 0 rgba(255, 255, 255, 0.05); white-space: nowrap; } @@ -393,12 +557,12 @@ h3 { .event-log-body { flex: 1; overflow-y: auto; - padding: 8px 10px 12px; + padding: 10px 10px 14px; display: flex; flex-direction: column; gap: 5px; font-size: 0.82rem; - line-height: 1.25; + line-height: 1.3; } .log-empty { @@ -408,12 +572,12 @@ h3 { .log-line { display: flex; - gap: 6px; + gap: 7px; align-items: baseline; - padding: 3px 6px; - border-radius: 6px; + padding: 4px 8px; + border-radius: 7px; border-left: 3px solid transparent; - background: rgba(255, 255, 255, 0.03); + background: rgba(255, 255, 255, 0.035); } .log-icon { @@ -439,6 +603,7 @@ h3 { justify-content: center; font-family: var(--font-display); font-size: 0.8rem; + letter-spacing: 0.06em; opacity: 0.85; margin-top: 4px; } @@ -450,8 +615,8 @@ h3 { } .log-line.log-current { - background: rgba(255, 207, 92, 0.18); - outline: 1px solid rgba(255, 207, 92, 0.4); + background: rgba(246, 201, 78, 0.18); + box-shadow: inset 0 0 0 1px rgba(246, 201, 78, 0.45); } @media (max-width: 860px) { @@ -482,12 +647,13 @@ h3 { flex-direction: column; align-items: center; justify-content: center; - gap: 14px; + gap: 16px; text-align: center; } .lobby-bounce { - font-size: 3rem; + font-size: 3.2rem; + filter: drop-shadow(0 6px 8px rgba(0, 0, 0, 0.45)); animation: float 2s ease-in-out infinite; } @@ -495,36 +661,54 @@ h3 { font-family: var(--font-display); font-size: 3rem; letter-spacing: 0.35em; + padding: 14px 30px 14px calc(30px + 0.35em); color: var(--gold); background: rgba(0, 0, 0, 0.25); - border: 3px dashed rgba(255, 207, 92, 0.5); + border: 3px dashed rgba(246, 201, 78, 0.5); border-radius: 16px; - padding: 12px 28px 12px 40px; + text-shadow: 0 2px 4px rgba(0, 0, 0, 0.4); + box-shadow: var(--tray-inset); } /* ---------- cards ---------- */ +/* Thick printed stock: a warm parchment face, a soft ink border with an inner + keyline, a physical shadow, and a lit sheen along the top. */ .card { position: relative; width: 108px; height: 148px; - background: linear-gradient(180deg, var(--cream), var(--cream-dark)); - border: 3px solid var(--cocoa); + background: linear-gradient(168deg, #fdf6e3, var(--cream) 45%, var(--cream-dark)); + border: 2px solid var(--cocoa); border-radius: var(--card-radius); color: var(--ink); display: flex; flex-direction: column; align-items: center; - padding: 6px; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.35); + padding: 7px 6px; + box-shadow: + inset 0 0 0 1.5px rgba(255, 255, 255, 0.55), + inset 0 -8px 14px rgba(180, 140, 80, 0.22), + var(--shadow-card); flex-shrink: 0; - transition: transform 120ms ease, box-shadow 120ms ease; + transition: transform 130ms cubic-bezier(0.34, 1.4, 0.5, 1), box-shadow 130ms ease; user-select: none; } +/* A faint printed sheen sweeping across the top of every card. */ +.card::before { + content: ''; + position: absolute; + inset: 1.5px 1.5px auto 1.5px; + height: 42%; + border-radius: 11px 11px 40% 40%; + background: linear-gradient(180deg, rgba(255, 255, 255, 0.5), transparent); + pointer-events: none; +} + .card-lg { - width: 128px; - height: 176px; + width: 132px; + height: 180px; } .card-sm { @@ -537,17 +721,26 @@ h3 { } .card.is-clickable:hover { - transform: translateY(-6px) rotate(-1deg); - box-shadow: 0 10px 16px rgba(0, 0, 0, 0.4); + transform: translateY(-8px) rotate(-1.2deg); + box-shadow: + inset 0 0 0 1.5px rgba(255, 255, 255, 0.6), + inset 0 -8px 14px rgba(180, 140, 80, 0.22), + 0 18px 30px -8px rgba(20, 12, 4, 0.6), + 0 4px 8px rgba(20, 12, 4, 0.4); } .card.is-selected { - outline: 4px solid var(--gold); - transform: translateY(-6px); + outline: 3px solid var(--gold); + outline-offset: 1px; + transform: translateY(-8px); + box-shadow: + inset 0 0 0 1.5px rgba(255, 255, 255, 0.6), + 0 0 20px rgba(246, 201, 78, 0.45), + var(--shadow-card); } .card.is-disabled { - filter: saturate(0.6) brightness(0.85); + filter: saturate(0.55) brightness(0.86); } .card.is-dead { @@ -560,47 +753,73 @@ h3 { justify-content: space-between; align-items: center; font-size: 0.72rem; + z-index: 1; } .card-tier { - font-weight: 900; - color: rgba(51, 35, 15, 0.55); + font-family: var(--font-display); + font-size: 0.68rem; + color: rgba(74, 44, 20, 0.5); } .card-suit { font-size: 0.95rem; } +/* The art sits in a soft printed halo so it reads as the card's hero. */ .card-art { - font-size: 1.8rem; + position: relative; + font-size: 2rem; line-height: 1; flex: 0 0 auto; - filter: drop-shadow(0 3px 2px rgba(0, 0, 0, 0.25)); + margin-top: 1px; + z-index: 1; + filter: drop-shadow(0 3px 3px rgba(0, 0, 0, 0.28)); +} + +.card-art::before { + content: ''; + position: absolute; + left: 50%; + top: 52%; + width: 2.5em; + height: 2.5em; + transform: translate(-50%, -50%); + border-radius: 50%; + background: radial-gradient(circle, rgba(246, 201, 78, 0.32), transparent 68%); + z-index: -1; } .card-lg .card-art { - font-size: 2.5rem; + font-size: 2.7rem; } .card-sm .card-art { - font-size: 1.8rem; + font-size: 1.9rem; } .card-name { font-family: var(--font-display); - font-size: 0.8rem; - line-height: 1.1; - margin-top: 1px; + font-size: 0.84rem; + line-height: 1.05; + margin-top: 3px; flex: 0 0 auto; + z-index: 1; + color: var(--cocoa); +} + +.card-lg .card-name { + font-size: 0.94rem; } .card-effect { - font-size: 0.53rem; - line-height: 1.15; + font-size: 0.55rem; + line-height: 1.2; font-weight: 700; - color: rgba(51, 35, 15, 0.75); + color: var(--ink-soft); text-align: center; - padding: 1px 2px 0; + padding: 2px 3px 0; + z-index: 1; /* Grow into the space between the name and the power badge and center the text there, so long effects use the whole middle band instead of being clipped just under the name. */ @@ -614,7 +833,7 @@ h3 { } .card-lg .card-effect { - font-size: 0.62rem; + font-size: 0.63rem; } .card-sm .card-effect { @@ -626,86 +845,120 @@ h3 { gap: 6px; align-items: center; margin-top: auto; + z-index: 1; } +/* Suit markers as glossy enamel dots. */ .suit-dot { display: inline-block; - width: 13px; - height: 13px; + width: 14px; + height: 14px; border-radius: 50%; - border: 2px solid rgba(0, 0, 0, 0.35); + border: 1.5px solid rgba(0, 0, 0, 0.3); vertical-align: middle; + box-shadow: + inset 0 1.5px 1px rgba(255, 255, 255, 0.6), + inset 0 -2px 2px rgba(0, 0, 0, 0.25); } .suit-red { - background: #e2483d; + background: radial-gradient(circle at 35% 28%, #ff6b5f, #d23124); } .suit-blue { - background: #3d7de2; + background: radial-gradient(circle at 35% 28%, #6ba6f5, #2f6bd0); } .suit-yellow { - background: #f4c430; + background: radial-gradient(circle at 35% 28%, #ffdd6b, #e6ac1f); } +/* The power badge is a stamped honey coin with a raised rim. */ .card-power { font-family: var(--font-display); - background: radial-gradient(circle at 35% 30%, #ffb347, var(--coral-dark)); + background: radial-gradient(circle at 35% 28%, #ffcf6b, var(--coral-dark)); color: #fff; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4); - border: 2px solid rgba(0, 0, 0, 0.25); + text-shadow: 0 1px 2px rgba(120, 45, 5, 0.55); + border: 2px solid rgba(120, 45, 5, 0.35); border-radius: 50%; - width: 30px; - height: 30px; + width: 31px; + height: 31px; display: grid; place-items: center; - font-size: 0.95rem; + font-size: 0.98rem; + box-shadow: + inset 0 1.5px 1px rgba(255, 255, 255, 0.55), + inset 0 -2px 3px rgba(120, 45, 5, 0.4), + 0 2px 3px rgba(0, 0, 0, 0.3); } .card-power.is-buffed { - background: radial-gradient(circle at 35% 30%, #7be495, #1f9e55); + background: radial-gradient(circle at 35% 28%, #9ff0af, #1f9e55); + border-color: rgba(15, 80, 40, 0.4); + text-shadow: 0 1px 2px rgba(15, 60, 30, 0.55); + box-shadow: + inset 0 1.5px 1px rgba(255, 255, 255, 0.55), + inset 0 -2px 3px rgba(15, 80, 40, 0.4), + 0 0 8px rgba(80, 220, 120, 0.5); } .card-damage { font-family: var(--font-display); color: #fff; - background: var(--red); - border: 2px solid rgba(0, 0, 0, 0.25); + background: linear-gradient(180deg, #e85c49, var(--red)); + border: 1.5px solid rgba(120, 20, 10, 0.4); border-radius: 8px; - padding: 1px 6px; + padding: 2px 7px; font-size: 0.8rem; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3); } +/* Food cards get a rosy stock so they read apart from pets at a glance. */ .card-food { - background: linear-gradient(180deg, #ffe9e0, #ffd4c2); + background: linear-gradient(168deg, #fff0ea, #ffe0d1 55%, #ffceba); +} + +.card-food::before { + background: linear-gradient(180deg, rgba(255, 255, 255, 0.6), transparent); } .card-food .card-effect { - color: #7a2e1e; + color: #8a3320; +} + +.card-food .card-name { + color: #8a3320; +} + +.card-food .card-art::before { + background: radial-gradient(circle, rgba(255, 140, 100, 0.28), transparent 68%); } .card-check { position: absolute; top: -10px; right: -10px; - background: var(--gold); - color: var(--ink); + background: radial-gradient(circle at 35% 28%, #ffe08a, var(--gold-deep)); + color: var(--cocoa); font-weight: 900; border: 2px solid var(--cocoa); border-radius: 50%; - width: 26px; - height: 26px; + width: 27px; + height: 27px; display: grid; place-items: center; + z-index: 2; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.4); } .card-slot-empty { - width: 128px; - height: 176px; - border: 3px dashed rgba(253, 243, 220, 0.25); + width: 132px; + height: 180px; + border: 2px dashed rgba(253, 243, 220, 0.22); border-radius: var(--card-radius); flex-shrink: 0; + background: rgba(0, 0, 0, 0.12); + box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.25); } /* ---------- shop ---------- */ @@ -713,18 +966,19 @@ h3 { .shop { display: flex; flex-direction: column; - gap: 22px; + gap: 24px; } .shop-status { text-align: center; - font-size: 1.15rem; + font-size: 1.2rem; font-weight: 900; min-height: 1.6em; } .status-hot { color: var(--gold); + text-shadow: 0 1px 6px rgba(246, 201, 78, 0.4); animation: pulse 1.6s ease-in-out infinite; } @@ -734,36 +988,53 @@ h3 { opacity: 1; } 50% { - opacity: 0.65; + opacity: 0.62; } } .section-label { font-family: var(--font-display); - font-size: 1rem; - margin-bottom: 10px; - color: rgba(253, 243, 220, 0.9); + font-size: 1.02rem; + margin-bottom: 12px; + color: var(--gold); + letter-spacing: 0.02em; + display: flex; + align-items: baseline; + gap: 4px; } +.section-label .muted { + font-family: var(--font-body); + font-size: 0.82rem; + font-weight: 700; +} + +/* Recessed felt trays: a darker inset well with a stitched edge, so cards + look like they're laid into the mat rather than floating on it. */ .shop-row-wrap, .deck-wrap { - background: rgba(0, 0, 0, 0.18); - border: 2px solid rgba(253, 243, 220, 0.1); + background: + radial-gradient(ellipse 80% 120% at 50% 0%, rgba(255, 255, 255, 0.04), transparent 70%), + rgba(0, 0, 0, 0.24); + border: 1px solid rgba(0, 0, 0, 0.3); border-radius: 18px; - padding: 14px 16px; + padding: 16px 18px 18px; + box-shadow: + var(--tray-inset), + inset 0 0 0 1px rgba(246, 201, 78, 0.06); } .shop-row, .deck-row { display: flex; - gap: 14px; + gap: 16px; flex-wrap: wrap; justify-content: center; } .deck-empty { text-align: center; - padding: 20px 0; + padding: 22px 0; } .actions { @@ -778,27 +1049,34 @@ h3 { .modal-backdrop { position: fixed; inset: 0; - background: rgba(0, 0, 0, 0.6); + background: rgba(10, 20, 14, 0.72); + backdrop-filter: blur(3px); display: grid; place-items: center; z-index: 50; + animation: result-in 200ms ease; } .modal { - background: linear-gradient(180deg, var(--felt-700), var(--felt-800)); - border: 3px solid rgba(253, 243, 220, 0.25); + background: + radial-gradient(ellipse 80% 60% at 50% 0%, rgba(255, 214, 138, 0.1), transparent 70%), + linear-gradient(180deg, var(--felt-600), var(--felt-800)); + border: 1px solid rgba(253, 243, 220, 0.2); border-radius: 20px; - padding: 24px; + padding: 28px; text-align: center; display: flex; flex-direction: column; - gap: 18px; + gap: 20px; max-width: 92vw; + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.1), + 0 24px 60px -12px rgba(0, 0, 0, 0.7); } .modal-cards { display: flex; - gap: 18px; + gap: 20px; justify-content: center; } @@ -807,20 +1085,23 @@ h3 { .arrange { display: flex; flex-direction: column; - gap: 18px; + gap: 20px; } .arrange-row { display: flex; - gap: 12px; + gap: 14px; align-items: center; flex-wrap: wrap; justify-content: center; - background: rgba(0, 0, 0, 0.18); - border: 2px solid rgba(253, 243, 220, 0.1); + background: + radial-gradient(ellipse 80% 120% at 50% 0%, rgba(255, 255, 255, 0.04), transparent 70%), + rgba(0, 0, 0, 0.24); + border: 1px solid rgba(0, 0, 0, 0.3); border-radius: 18px; - padding: 18px 16px; - min-height: 220px; + padding: 20px 18px; + min-height: 224px; + box-shadow: var(--tray-inset); } .arrange-marker { @@ -828,15 +1109,16 @@ h3 { color: var(--gold); writing-mode: vertical-rl; transform: rotate(180deg); - font-size: 0.9rem; - opacity: 0.8; + font-size: 0.95rem; + letter-spacing: 0.04em; + opacity: 0.85; } .arrange-card { display: flex; flex-direction: column; align-items: center; - gap: 6px; + gap: 8px; cursor: grab; } @@ -846,7 +1128,7 @@ h3 { .arrange-arrows { display: flex; - gap: 4px; + gap: 5px; } /* ---------- battle ---------- */ @@ -854,21 +1136,31 @@ h3 { .battle { display: flex; flex-direction: column; - gap: 16px; + gap: 18px; } .battle-header { display: flex; justify-content: center; align-items: center; - gap: 14px; + gap: 16px; flex-wrap: wrap; } +.battle-header h2 { + font-size: 1.5rem; + color: var(--gold); + text-shadow: 0 2px 3px rgba(0, 0, 0, 0.4); +} + .battle-controls { display: flex; align-items: center; gap: 6px; + background: rgba(0, 0, 0, 0.22); + border-radius: 12px; + padding: 5px 8px; + box-shadow: var(--tray-inset); } .battle-step { @@ -883,7 +1175,8 @@ h3 { display: flex; justify-content: center; gap: 18px; - font-weight: 900; + font-weight: 800; + font-size: 1.05rem; } .battle-vs { @@ -891,32 +1184,49 @@ h3 { color: var(--gold); } +/* The battlefield is the lit heart of the table — a spotlit arena inset into + the felt, with a faint centre line where the two sides meet. */ .battlefield { display: flex; align-items: center; justify-content: center; gap: 8px; background: - radial-gradient(ellipse at center, rgba(255, 207, 92, 0.07), transparent 65%), - rgba(0, 0, 0, 0.2); - border: 2px solid rgba(253, 243, 220, 0.1); - border-radius: 18px; - padding: 26px 12px; - min-height: 240px; + radial-gradient(ellipse 55% 80% at center, rgba(246, 201, 78, 0.12), transparent 66%), + linear-gradient(180deg, rgba(0, 0, 0, 0.28), rgba(0, 0, 0, 0.18)); + border: 1px solid rgba(0, 0, 0, 0.3); + border-radius: 20px; + padding: 30px 14px; + min-height: 244px; overflow-x: auto; + box-shadow: + var(--tray-inset), + inset 0 0 60px rgba(0, 0, 0, 0.25); } .battle-center { position: relative; - font-size: 1.6rem; + font-size: 1.7rem; flex-shrink: 0; display: grid; place-items: center; - min-width: 2rem; + min-width: 2.4rem; + align-self: stretch; +} + +/* A soft seam down the middle of the arena. */ +.battle-center::before { + content: ''; + position: absolute; + top: 8%; + bottom: 8%; + width: 2px; + background: linear-gradient(180deg, transparent, rgba(246, 201, 78, 0.25), transparent); } .battle-center-bolt { - opacity: 0.45; + opacity: 0.5; + filter: drop-shadow(0 0 8px rgba(246, 201, 78, 0.5)); } .battle-side { @@ -935,20 +1245,23 @@ h3 { flex-shrink: 0; } +/* The face-down deck: a walnut-backed card with a woven diamond pattern and a + little stacked-depth shadow beneath it. */ .card-back { width: 84px; height: 116px; border-radius: var(--card-radius); - border: 3px solid var(--cocoa); + border: 2px solid var(--cocoa); background: - repeating-linear-gradient( - 45deg, - #b3552b 0 10px, - #a34a22 10px 20px - ); + repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.06) 0 6px, transparent 6px 12px), + repeating-linear-gradient(-45deg, rgba(0, 0, 0, 0.12) 0 6px, transparent 6px 12px), + linear-gradient(160deg, #c25f31, #a2451f); box-shadow: - 2px 2px 0 rgba(0, 0, 0, 0.25), - 4px 4px 0 rgba(0, 0, 0, 0.15); + inset 0 0 0 3px rgba(255, 230, 200, 0.18), + inset 0 2px 4px rgba(255, 255, 255, 0.15), + 3px 3px 0 rgba(0, 0, 0, 0.22), + 6px 6px 0 rgba(0, 0, 0, 0.12), + 0 8px 12px rgba(0, 0, 0, 0.35); display: grid; place-items: center; } @@ -957,12 +1270,13 @@ h3 { font-family: var(--font-display); font-size: 1.3rem; color: var(--cream); - background: rgba(0, 0, 0, 0.35); + background: rgba(0, 0, 0, 0.4); border-radius: 50%; - width: 38px; - height: 38px; + width: 40px; + height: 40px; display: grid; place-items: center; + box-shadow: inset 0 0 0 2px rgba(255, 230, 200, 0.25); } .stack-empty { @@ -1372,8 +1686,9 @@ h3 { text-align: center; display: flex; flex-direction: column; - gap: 10px; + gap: 12px; align-items: center; + padding: 8px 0; animation: result-in 400ms ease; } @@ -1390,7 +1705,8 @@ h3 { .battle-result-title { font-family: var(--font-display); - font-size: 2.4rem; + font-size: 2.6rem; + text-shadow: 0 3px 0 rgba(0, 0, 0, 0.3), 0 6px 14px rgba(0, 0, 0, 0.4); } .battle-result.is-win .battle-result-title { @@ -1402,7 +1718,7 @@ h3 { } .battle-result.is-draw .battle-result-title { - color: var(--teal); + color: #6fd6c2; } .battle-result-sub { @@ -1418,28 +1734,34 @@ h3 { flex-direction: column; align-items: center; justify-content: center; - gap: 18px; + gap: 20px; text-align: center; } .gameover-emoji { - font-size: 4rem; + font-size: 4.4rem; + filter: drop-shadow(0 8px 10px rgba(0, 0, 0, 0.45)); + animation: float 3s ease-in-out infinite; } .gameover-title { - font-size: 3rem; + font-size: 3.2rem; color: var(--gold); - text-shadow: 0 4px 0 rgba(0, 0, 0, 0.35); + text-shadow: + 0 2px 0 var(--gold-deep), + 0 5px 0 rgba(90, 58, 32, 0.5), + 0 8px 16px rgba(0, 0, 0, 0.4); } .gameover-scores { display: flex; flex-direction: column; gap: 8px; - background: rgba(0, 0, 0, 0.22); + background: rgba(0, 0, 0, 0.24); border-radius: 16px; - padding: 18px 26px; + padding: 20px 28px; min-width: min(360px, 90vw); + box-shadow: var(--tray-inset); } .score-line { @@ -1447,6 +1769,8 @@ h3 { justify-content: space-between; gap: 24px; font-size: 1.1rem; + font-weight: 700; + padding: 4px 0; } .score-line.is-you .score-name { @@ -1461,30 +1785,33 @@ h3 { bottom: 24px; left: 50%; transform: translateX(-50%); - background: var(--red); + background: linear-gradient(180deg, #e85c49, var(--red)); color: #fff; font-weight: 700; border-radius: 12px; - padding: 10px 20px; - box-shadow: 0 6px 14px rgba(0, 0, 0, 0.4); + padding: 11px 22px; + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.25), + 0 8px 18px rgba(0, 0, 0, 0.45); animation: result-in 200ms ease; z-index: 100; } .banner { position: fixed; - top: 64px; + top: 66px; left: 50%; transform: translateX(-50%); border-radius: 10px; - padding: 6px 16px; + padding: 7px 18px; font-size: 0.9rem; font-weight: 700; z-index: 90; + box-shadow: 0 6px 14px rgba(0, 0, 0, 0.4); } .banner-warn { - background: rgba(217, 74, 56, 0.9); + background: rgba(217, 74, 56, 0.92); } @media (max-width: 600px) { @@ -1506,7 +1833,7 @@ h3 { .debug-panel { position: fixed; - top: 64px; + top: 66px; right: 0; z-index: 120; display: flex; @@ -1581,7 +1908,7 @@ h3 { full effect text instead of clipping like a fixed-height card. */ .card-magnify .card { height: auto; - min-height: 176px; + min-height: 180px; padding-bottom: 10px; } @@ -1618,10 +1945,12 @@ h3 { width: max-content; max-width: 60vw; background: rgba(18, 53, 31, 0.98); - border: 2px solid var(--cocoa); - border-radius: 10px; - padding: 8px 10px; - box-shadow: 0 8px 20px rgba(0, 0, 0, 0.5); + border: 1px solid var(--cocoa); + border-radius: 12px; + padding: 10px 12px; + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.08), + 0 10px 24px rgba(0, 0, 0, 0.55); pointer-events: none; }