Files
initiative/apps/web/src/index.css
Lukas e161645228
All checks were successful
CI / check (push) Successful in 2m31s
CI / build-image (push) Successful in 26s
Add PF2e spell description popovers in stat blocks
Clicking a spell name in a PF2e creature's stat block now opens a
popover (desktop) or bottom sheet (mobile) showing full spell details:
description, traits, rank, range, target, area, duration, defense,
action cost icons, and heightening rules. All data is sourced from
the embedded Foundry VTT spell items already in the bestiary cache.

- Add SpellReference type replacing bare string spell arrays
- Extract full spell data in pf2e-bestiary-adapter (description,
  traits, traditions, range, target, area, duration, defense,
  action cost, heightening, overlays)
- Strip inline heightening text from descriptions to avoid duplication
- Bold save outcome labels (Critical Success/Failure) in descriptions
- Bump DB_VERSION to 6 for cache invalidation
- Add useSwipeToDismissDown hook for mobile bottom sheet
- Portal popover to document.body to escape transformed ancestors

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 16:18:08 +02:00

272 lines
5.4 KiB
CSS

@import "tailwindcss";
@theme {
--color-background: #0e1a2e;
--color-foreground: #e2e8f0;
--color-muted: #7a8ba4;
--color-muted-foreground: #94a3b8;
--color-card: #1a2e4a;
--color-card-foreground: #e2e8f0;
--color-border: #2a5088;
--color-input: #2a5088;
--color-primary: #3b82f6;
--color-primary-foreground: #ffffff;
--color-accent: #3b82f6;
--color-destructive: #ef4444;
--color-hover-neutral: var(--color-primary);
--color-hover-action: var(--color-primary);
--color-hover-destructive: var(--color-destructive);
--color-hover-neutral-bg: oklch(0.623 0.214 259 / 0.15);
--color-hover-action-bg: var(--color-muted);
--color-hover-destructive-bg: transparent;
--color-stat-heading: #fbbf24;
--color-stat-divider-from: oklch(0.5 0.1 65 / 0.6);
--color-stat-divider-via: oklch(0.5 0.1 65 / 0.4);
--color-hp-damage-hover-bg: oklch(0.25 0.05 25);
--color-hp-heal-hover-bg: oklch(0.25 0.05 155);
--color-active-row-bg: oklch(0.623 0.214 259 / 0.1);
--color-active-row-border: oklch(0.623 0.214 259 / 0.4);
--radius-sm: 0.25rem;
--radius-md: 0.5rem;
--radius-lg: 0.75rem;
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
}
[data-theme="light"] {
--color-background: #eeecea;
--color-foreground: #374151;
--color-muted: #e0ddd9;
--color-muted-foreground: #6b7280;
--color-card: #f7f6f4;
--color-card-foreground: #374151;
--color-border: #ddd9d5;
--color-input: #cdc8c3;
--color-primary: #2563eb;
--color-primary-foreground: #ffffff;
--color-accent: #2563eb;
--color-destructive: #dc2626;
--color-hover-neutral: var(--color-primary);
--color-hover-action: var(--color-primary);
--color-hover-destructive: var(--color-destructive);
--color-hover-neutral-bg: oklch(0.623 0.214 259 / 0.08);
--color-hover-action-bg: var(--color-muted);
--color-hover-destructive-bg: transparent;
--color-stat-heading: #92400e;
--color-stat-divider-from: oklch(0.55 0.1 65 / 0.5);
--color-stat-divider-via: oklch(0.55 0.1 65 / 0.25);
--color-hp-damage-hover-bg: #fef2f2;
--color-hp-heal-hover-bg: #ecfdf5;
--color-active-row-bg: oklch(0.623 0.214 259 / 0.08);
--color-active-row-border: oklch(0.623 0.214 259 / 0.25);
}
@keyframes concentration-shake {
0% {
translate: 0;
}
20% {
translate: -3px;
}
40% {
translate: 3px;
}
60% {
translate: -2px;
}
80% {
translate: 1px;
}
100% {
translate: 0;
}
}
@keyframes concentration-glow {
0% {
box-shadow: 0 0 4px 2px #c084fc;
}
100% {
box-shadow: 0 0 0 0 transparent;
}
}
@keyframes slide-in-right {
from {
translate: 100%;
}
to {
translate: 0;
}
}
@utility animate-slide-in-right {
animation: slide-in-right 200ms ease-out;
}
@keyframes slide-in-bottom {
from {
transform: translateY(100%);
}
to {
transform: translateY(0);
}
}
@utility animate-slide-in-bottom {
animation: slide-in-bottom 200ms ease-out;
}
@keyframes confirm-pulse {
0% {
scale: 1;
}
50% {
scale: 1.15;
}
100% {
scale: 1;
}
}
@keyframes settle-to-bottom {
from {
transform: translateY(-40vh);
opacity: 0;
}
40% {
opacity: 1;
}
to {
transform: translateY(0);
opacity: 1;
}
}
@utility animate-settle-to-bottom {
animation: settle-to-bottom 700ms cubic-bezier(0.22, 1, 0.36, 1) backwards;
}
@keyframes rise-to-center {
from {
transform: translateY(40vh);
opacity: 0;
}
40% {
opacity: 1;
}
to {
transform: translateY(0);
opacity: 1;
}
}
@utility animate-rise-to-center {
animation: rise-to-center 700ms cubic-bezier(0.22, 1, 0.36, 1) backwards;
}
@keyframes slide-down-in {
from {
transform: translateY(-100%);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
@utility animate-slide-down-in {
animation: slide-down-in 700ms cubic-bezier(0.22, 1, 0.36, 1) backwards;
}
@keyframes slide-up-out {
from {
transform: translateY(0);
opacity: 1;
}
60% {
opacity: 0;
}
to {
transform: translateY(-100%);
opacity: 0;
}
}
@utility animate-slide-up-out {
animation: slide-up-out 700ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
}
@custom-variant pointer-coarse (@media (pointer: coarse));
@utility animate-confirm-pulse {
animation: confirm-pulse 300ms ease-out;
}
@utility transition-slide-panel {
transition: translate 200ms ease-out;
}
@utility writing-vertical-rl {
writing-mode: vertical-rl;
}
@utility animate-concentration-pulse {
animation:
concentration-shake 450ms ease-out,
concentration-glow 1200ms ease-out;
}
@utility card-glow {
background-image: radial-gradient(
ellipse at 50% 50%,
oklch(0.35 0.05 250 / 0.5) 0%,
transparent 70%
);
box-shadow:
0 0 15px -2px oklch(0.623 0.214 259 / 0.2),
inset 0 1px 0 0 oklch(0.7 0.15 259 / 0.1);
[data-theme="light"] & {
background-image: none;
box-shadow: 0 1px 3px 0 oklch(0 0 0 / 0.08);
}
}
@utility panel-glow {
background-image: linear-gradient(
to bottom,
oklch(0.35 0.05 250 / 0.4) 0%,
transparent 40%
);
box-shadow:
0 0 20px -2px oklch(0.623 0.214 259 / 0.15),
inset 0 1px 0 0 oklch(0.7 0.15 259 / 0.1);
[data-theme="light"] & {
background-image: none;
box-shadow: -1px 0 6px 0 oklch(0 0 0 / 0.1);
}
}
* {
scrollbar-color: var(--color-border) transparent;
scrollbar-width: thin;
}
body {
background-color: var(--color-background);
background-image: radial-gradient(
ellipse at 50% 40%,
oklch(0.26 0.055 250) 0%,
var(--color-background) 70%
);
background-attachment: fixed;
color: var(--color-foreground);
font-family: var(--font-sans);
}
[data-theme="light"] body {
background-image: none;
}