/* Bacteria Forever 1 — neon on black (the « Bacteria Forever » mockups of 2026-10-11). Phone first, 320 px and up. */
:root {
  --bg: #04060c;
  --panel: #0a1020;
  --line: #1b2a44;
  --ink: #e9fbff;
  --muted: #7f93ad;
  --cyan: #22f0ff;
  --magenta: #ff3df2;
  --green: #6dff5a;
  --good: #6dff5a;
  --bad: #ff5a6e;
  --flat: #9fb3c8;
  color-scheme: dark;
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; background: var(--bg); color: var(--ink); font: 16px/1.4 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
body { min-height: 100dvh; background: radial-gradient(120% 70% at 50% 0%, #0b1730 0%, var(--bg) 60%) fixed; }
#app { max-width: 560px; margin: 0 auto; padding: 12px 16px calc(24px + env(safe-area-inset-bottom)); }
button { font: inherit; color: inherit; }
small { color: var(--muted); }

.screen { display: flex; flex-direction: column; gap: 12px; }
.brand { text-align: center; margin: 36px 0 12px; }
.brand h1, .victory h1 { font-size: 46px; line-height: 1.02; margin: 0; letter-spacing: 1px; text-transform: uppercase; color: #dffcff;
  text-shadow: 0 0 6px var(--cyan), 0 0 18px var(--cyan), 0 0 40px rgba(34, 240, 255, .5); }
.brand p { color: var(--muted); }
h2 { margin: 8px 0; color: #dffcff; text-shadow: 0 0 10px rgba(34, 240, 255, .6); }
h3 { margin: 6px 0; font-size: 15px; color: #cfe9ff; }
.hint { color: var(--muted); font-size: 14px; margin: 0; }
.notice { background: rgba(255, 90, 110, .12); border: 1px solid rgba(255, 90, 110, .4); padding: 8px 10px; border-radius: 12px; }
.field { display: flex; flex-direction: column; gap: 6px; }
.field input { background: var(--panel); border: 1px solid var(--line); color: var(--ink); border-radius: 14px; padding: 12px 14px; font-size: 17px; }
.field input:focus { outline: none; border-color: var(--cyan); box-shadow: 0 0 0 3px rgba(34, 240, 255, .2); }

.neon { background: rgba(34, 240, 255, .06); border: 1.5px solid var(--cyan); color: #dffcff; border-radius: 16px; padding: 14px 16px; font-size: 18px; font-weight: 700;
  box-shadow: 0 0 10px rgba(34, 240, 255, .35), inset 0 0 10px rgba(34, 240, 255, .15); text-shadow: 0 0 8px rgba(34, 240, 255, .7); cursor: pointer; }
.neon:disabled { opacity: .45; box-shadow: none; }
.neon.ghost { border-color: var(--magenta); box-shadow: 0 0 10px rgba(255, 61, 242, .3); }
.neon.small { font-size: 14px; padding: 10px 8px; }
.link { background: none; border: none; color: var(--muted); text-decoration: underline; padding: 6px; cursor: pointer; }
.chip { background: var(--panel); border: 1px solid var(--line); border-radius: 999px; padding: 6px 12px; cursor: pointer; }
.chip.on { border-color: var(--cyan); box-shadow: 0 0 8px rgba(34, 240, 255, .4); }
.row { display: flex; gap: 8px; align-items: center; }
.row3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.qr { background: #e9fbff; border-radius: 18px; padding: 12px; width: min(260px, 80vw); margin: 0 auto; box-shadow: 0 0 24px rgba(34, 240, 255, .35); }
.qr svg { display: block; width: 100%; height: auto; }
.players { list-style: none; padding: 0; margin: 0; display: grid; gap: 6px; }
.players li { background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px; }
.players li.away { opacity: .5; }

/* ---- game ---- */
.top { display: flex; justify-content: space-between; align-items: center; background: var(--panel); border: 1px solid var(--line); border-radius: 999px; padding: 8px 14px; }
.res b { color: var(--cyan); text-shadow: 0 0 8px var(--cyan); }
.turnno { color: var(--green); text-shadow: 0 0 8px rgba(109, 255, 90, .6); font-weight: 700; }
.timer { min-width: 42px; text-align: right; font-variant-numeric: tabular-nums; }
.timer.low { color: var(--bad); text-shadow: 0 0 8px var(--bad); }
.meta { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; font-size: 13px; }
.meta .lbl { color: var(--muted); margin-left: 4px; }
.nat { display: inline-flex; align-items: center; gap: 5px; border-radius: 999px; padding: 3px 9px; background: var(--panel); border: 1px solid var(--line); }
.nat i { width: 10px; height: 10px; border-radius: 50%; display: inline-block; box-shadow: 0 0 6px currentColor; }
.nat.food { border-color: rgba(109, 255, 90, .5); }
.nat.poison { border-color: rgba(255, 90, 110, .6); }

.dish { display: block; width: 100%; height: auto; }
.dish.petri { max-width: 360px; margin: 0 auto; }
.glass { fill: rgba(180, 230, 255, .05); stroke: rgba(170, 225, 255, .55); stroke-width: 3; filter: drop-shadow(0 0 10px rgba(34, 240, 255, .35)); }
.agar { stroke: rgba(170, 225, 255, .18); stroke-width: 1; }
.shine { fill: none; stroke: rgba(255, 255, 255, .22); stroke-width: 4; stroke-linecap: round; }
.contact { text-align: center; font-size: 13px; color: var(--muted); margin: -4px 0 0; }
.contact.on { color: var(--magenta); text-shadow: 0 0 6px rgba(255, 61, 242, .6); }
.hex { fill: rgba(16, 32, 60, .55); stroke: #1e3a63; stroke-width: 1.2; }
.hex.empty { fill: rgba(16, 32, 60, .35); }
.hex.own { fill: color-mix(in srgb, var(--c) 22%, transparent); stroke: var(--c); stroke-width: 2; filter: drop-shadow(0 0 4px var(--c)); }
.gate { fill: none; stroke: var(--c); stroke-width: 1.5; stroke-dasharray: 4 3; opacity: .8; }
.dot { opacity: .9; }
.nat, text.nat { font-weight: 800; }
text.nat { fill: #05070d; text-anchor: middle; dominant-baseline: middle; }
text.eff { fill: #e9fbff; text-anchor: middle; dominant-baseline: middle; opacity: .85; }
.hex.m-new { animation: pop 1.2s ease-out 2; }
.hex.m-taken { stroke: #fff; stroke-width: 3; animation: pop 1.2s ease-out 2; }
.hex.m-lysed, .hex.m-eaten { stroke: var(--bad); stroke-width: 3; stroke-dasharray: 3 2; }
@keyframes pop { 0% { filter: drop-shadow(0 0 14px #fff); } 100% { filter: drop-shadow(0 0 4px var(--c, #fff)); } }

.colonies { display: flex; gap: 6px; overflow-x: auto; }
.col { flex: 1 0 auto; min-width: 72px; background: var(--panel); border: 1px solid color-mix(in srgb, var(--c) 60%, transparent); border-radius: 12px; padding: 6px 8px; display: flex; flex-direction: column; font-size: 13px; }
.col b { color: var(--c); text-shadow: 0 0 6px var(--c); }
.col.me { box-shadow: 0 0 10px color-mix(in srgb, var(--c) 50%, transparent); }
.who { color: var(--c); text-shadow: 0 0 6px var(--c); }

.stage { background: var(--panel); border: 1px solid var(--line); border-radius: 18px; padding: 12px; display: flex; flex-direction: column; gap: 10px; }
.say { margin: 0; }
.say.ok { color: var(--good); }
.drop { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.drop.back { display: flex; justify-content: center; align-items: center; height: 84px; border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%; background: radial-gradient(circle at 40% 35%, rgba(34, 240, 255, .25), rgba(10, 16, 32, .9)); border: 1.5px solid var(--cyan); width: 84px; margin: 0 auto; font-size: 30px; }
.slot { background: rgba(4, 6, 12, .6); border: 1.5px solid #234; border-radius: 14px; padding: 8px 4px; display: flex; flex-direction: column; align-items: center; gap: 2px; text-align: center; min-height: 82px; justify-content: center; }
.slot b { font-size: 14px; }
.slot.hidden { border-style: dashed; border-color: var(--magenta); box-shadow: inset 0 0 12px rgba(255, 61, 242, .25); }
.slot.hidden b { font-size: 28px; color: var(--magenta); text-shadow: 0 0 10px var(--magenta); }
.slot.was { border-color: var(--magenta); }
.ndot { width: 22px; height: 22px; border-radius: 50%; box-shadow: 0 0 10px currentColor; }
.eicon { font-style: normal; font-size: 22px; color: var(--cyan); text-shadow: 0 0 8px var(--cyan); }
.sz { font-style: normal; font-size: 24px; font-weight: 800; color: var(--green); text-shadow: 0 0 8px var(--green); }
.verdict { margin: 0; font-size: 15px; }
.good { color: var(--good); text-shadow: 0 0 6px rgba(109, 255, 90, .5); }
.bad { color: var(--bad); text-shadow: 0 0 6px rgba(255, 90, 110, .5); }
.flat { color: var(--flat); }

.holds { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.hold { position: relative; overflow: hidden; height: 112px; border-radius: 24px; border: 2px solid var(--c); background: rgba(4, 6, 12, .7); color: #fff; display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 2px;
  box-shadow: 0 0 16px color-mix(in srgb, var(--c) 45%, transparent); touch-action: none; user-select: none; -webkit-user-select: none; cursor: pointer; }
.hold.take { --c: var(--green); }
.hold.avoid { --c: var(--cyan); }
.hold b { font-size: 20px; z-index: 1; text-shadow: 0 0 8px var(--c); }
.hold small, .hold em { z-index: 1; }
.hold em { font-style: normal; font-size: 22px; font-weight: 800; font-variant-numeric: tabular-nums; }
.hold .gauge { position: absolute; left: 0; right: 0; bottom: 0; height: 0; background: linear-gradient(0deg, color-mix(in srgb, var(--c) 55%, transparent), color-mix(in srgb, var(--c) 15%, transparent)); }
.hold.pressed { transform: scale(.98); box-shadow: 0 0 28px var(--c); }
.hold:disabled { opacity: .4; }
.who-row { display: flex; flex-wrap: wrap; gap: 6px; font-size: 13px; }
.who-row span { border: 1px solid color-mix(in srgb, var(--c) 50%, transparent); border-radius: 999px; padding: 2px 8px; color: var(--muted); }
.who-row span.done { color: var(--c); }

.banner { font-size: 18px; font-weight: 700; text-align: center; }
.bars { display: grid; gap: 6px; }
.bar { display: grid; grid-template-columns: 64px 1fr auto; gap: 8px; align-items: center; font-size: 13px; }
.bar .nm { color: var(--c); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar .track { height: 10px; border-radius: 999px; background: #0e1a2e; overflow: hidden; }
.bar .fill { display: block; height: 100%; background: var(--c); box-shadow: 0 0 8px var(--c); animation: grow .9s ease-out; }
.bar.avoid .fill { background: repeating-linear-gradient(90deg, var(--c) 0 6px, transparent 6px 9px); }
@keyframes grow { from { width: 0; } }
.conflicts { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; font-size: 14px; }
.conflicts li { background: rgba(4, 6, 12, .6); border-radius: 10px; padding: 6px 8px; border-left: 3px solid var(--line); }
.k-capture { border-left-color: var(--magenta) !important; }
.k-perte { border-left-color: var(--bad) !important; }
.k-statu { border-left-color: var(--cyan) !important; }
.dock { display: flex; justify-content: center; }
.dock .neon { width: 100%; }
.mine { background: var(--panel); border: 1px solid var(--line); border-radius: 18px; padding: 8px 12px 12px; }
.tabs { display: flex; justify-content: center; }
.tabs button { background: none; border: 1px solid var(--line); border-radius: 999px; padding: 6px 14px; color: var(--muted); }

/* ---- end ---- */
.victory { text-align: center; margin-top: 16px; }
.victory h1.win { color: #e9ffe5; text-shadow: 0 0 6px var(--green), 0 0 22px var(--green); }
.victory h1.over { color: #ffe5ea; text-shadow: 0 0 6px var(--bad), 0 0 22px var(--bad); }
.ranks { display: grid; gap: 6px; }
.rank { display: grid; grid-template-columns: 26px 1fr auto; gap: 4px 8px; align-items: center; background: var(--panel); border: 1px solid color-mix(in srgb, var(--c) 55%, transparent); border-radius: 14px; padding: 8px 10px; }
.rank b { color: var(--c); text-shadow: 0 0 6px var(--c); }
.rank .cov { grid-column: 2 / 4; color: var(--muted); font-size: 13px; }
.rank small { grid-column: 2 / 4; }
.rank.win { box-shadow: 0 0 14px color-mix(in srgb, var(--c) 55%, transparent); }
.rk { font-weight: 800; color: var(--muted); }
.rules p { margin: 0 0 6px; }

.netbar { position: sticky; top: 0; z-index: 5; background: #2a1d05; border: 1px solid #6b4a10; color: #ffd27a; border-radius: 10px; padding: 6px 10px; font-size: 14px; margin-bottom: 8px; }
.netbar.bad { background: #2a0c12; border-color: #6b1a2a; color: #ffb3c0; }
.toast { position: fixed; left: 50%; bottom: calc(18px + env(safe-area-inset-bottom)); transform: translateX(-50%); background: #0e1a2e; border: 1px solid var(--cyan); border-radius: 12px; padding: 10px 14px; box-shadow: 0 0 16px rgba(34, 240, 255, .35); max-width: 90vw; z-index: 9; }
.news { background: rgba(255, 61, 242, .08); border: 1px solid rgba(255, 61, 242, .5); border-radius: 14px; padding: 8px 12px; box-shadow: 0 0 12px rgba(255, 61, 242, .25); font-size: 14px; }
.ndot.inline { display: inline-block; width: 10px; height: 10px; border-radius: 50%; vertical-align: middle; }
/* Bacteria Forever 2 « chimie » (src/bf/chimie.js) */
.drop.chem { grid-template-columns: repeat(4, 1fr); gap: 6px; }
.drop.chem .slot { min-height: 74px; }
.drop.chem .slot b { font-size: 14px; }
.chem-id { flex-wrap: wrap; row-gap: 4px; }
.chem-id .ideal { font-size: 13px; opacity: .9; margin-right: 8px; }
.hint.invite { font-size: 11px; word-break: break-all; user-select: all; opacity: .6; }
.neon.small.ghost { background: transparent; }
/* compact game screen: dish and colonies side by side, the hold buttons above the fold */
.game.chem { gap: 8px; }
.game.chem .top { padding: 6px 12px; }
.game.chem .board { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); gap: 8px; align-items: center; }
.game.chem .dish.petri { max-width: 240px; width: 100%; }
.cols { display: flex; flex-direction: column; gap: 4px; }
.cl { display: grid; grid-template-columns: 1fr auto; align-items: center; column-gap: 6px; background: var(--panel); border: 1px solid color-mix(in srgb, var(--c) 55%, transparent); border-radius: 10px; padding: 3px 8px; font-size: 12px; line-height: 1.25; }
.cl b { color: var(--c); text-shadow: 0 0 6px var(--c); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cl .n { grid-row: span 2; font-size: 20px; font-weight: 800; color: var(--c); font-variant-numeric: tabular-nums; }
.cl small { color: var(--muted); font-size: 11px; }
.cl.me { box-shadow: 0 0 10px color-mix(in srgb, var(--c) 45%, transparent); }
.chem-id { display: flex; flex-direction: column; gap: 4px; font-size: 12px; }
.chem-id div { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.chem-id .lbl { color: var(--muted); margin-left: 4px; }
.chem-id .nat { padding: 1px 7px; font-size: 12px; }
.game.chem .stage { padding: 10px; gap: 8px; }
.game.chem .drop.chem .slot { min-height: 56px; padding: 4px 2px; }
.game.chem .drop.chem .slot i { font-size: 16px; }
.game.chem .drop.chem .slot small { font-size: 10px; }
.game.chem .hold { height: 78px; border-radius: 18px; }
.game.chem .hold b { font-size: 17px; }
.game.chem .hold em { font-size: 18px; }
.game.chem .verdict { font-size: 14px; }
.game.chem .hint { font-size: 12px; }
.link.inline { display: inline; padding: 0; margin-left: 4px; font-size: 12px; }
.game.chem .news { font-size: 12px; padding: 6px 10px; }
.ideal-grid { display: grid !important; grid-template-columns: auto auto auto 1fr; column-gap: 14px; row-gap: 2px; align-items: baseline; font-size: 13px; }
.ideal-grid .lbl { margin-left: 0 !important; font-size: 11px; letter-spacing: .06em; }
.ideal-grid .ok b { color: #6dff5a; }
.ideal-grid .near b, .ideal-grid .near { color: #ffb52e; }
.ideal-grid .far b, .ideal-grid .far { color: #ff5a6e; }
.chem-id .sym { font-size: 16px; line-height: 1; margin: 0 2px 0 4px; }
.chem-id .sym.poison { color: #ff5a6e; text-shadow: 0 0 6px #ff5a6e; }
/* the 🌱 and ☠ symbols take the same width, so that the first food and the first poison line up */
.chem-id .sym { display: inline-block; width: 22px; text-align: center; margin: 0 4px 0 0; flex: 0 0 22px; }
/* reduced colony cards: a tap opens the medium */
button.cl { font: inherit; color: inherit; text-align: left; cursor: pointer; }
.cl .spg { grid-column: 1; height: 5px; border-radius: 999px; background: #0e1a2e; overflow: hidden; margin: 2px 0; }
.cl .spg i { display: block; height: 100%; background: linear-gradient(90deg, #9d7bff, #e9fbff); box-shadow: 0 0 6px #9d7bff; }
.cl .inh { font-size: 10px; opacity: .45; letter-spacing: -2px; }
.cl .inh.on { opacity: 1; filter: drop-shadow(0 0 4px #ff5a6e); }
.cl.masker { border-width: 2px; }
.cl .medium { grid-column: 1 / -1; color: var(--muted); }
.note-inhib { margin: 0; font-size: 12px; color: #ffb3bd; background: rgba(255, 90, 110, .08); border: 1px solid rgba(255, 90, 110, .45); border-radius: 10px; padding: 6px 8px; }
.inhib-box { border: 1.5px solid #ff5a6e; border-radius: 14px; padding: 8px; box-shadow: 0 0 14px rgba(255, 90, 110, .35); display: flex; flex-direction: column; gap: 8px; }
.neon.small.inhib { border-color: #ff5a6e; box-shadow: 0 0 10px rgba(255, 90, 110, .5); }
.neon.small.inhib small { display: block; font-size: 10px; opacity: .8; }
/* births hatch slowly, one after the other; deaths burst at once */
.hex.born { transform-box: fill-box; transform-origin: center; animation: hatch 1.4s cubic-bezier(.2, .8, .3, 1.2) both; }
@keyframes hatch {
  0% { transform: scale(.05); opacity: 0; filter: drop-shadow(0 0 0 var(--c)); }
  45% { transform: scale(.55); opacity: .7; filter: drop-shadow(0 0 3px var(--c)); }
  75% { transform: scale(1.18); opacity: 1; filter: drop-shadow(0 0 14px var(--c)); }
  100% { transform: scale(1); opacity: 1; filter: drop-shadow(0 0 4px var(--c)); }
}
.hex.dead { transform-box: fill-box; transform-origin: center; animation: burst .32s cubic-bezier(.6, 0, 1, .4) forwards; }
@keyframes burst {
  0% { transform: scale(1.3); opacity: 1; fill: #fff; stroke: #ff5a6e; filter: drop-shadow(0 0 16px #ff5a6e); }
  35% { transform: scale(1.1); opacity: 1; fill: #ff5a6e; }
  100% { transform: scale(0); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .hex.born, .hex.dead { animation-duration: .01s; } }
/* the fine dish (7 small cells for one cell of the score): thinner strokes, a softer glow */
.dish.fine .hex { stroke-width: .6; }
.dish.fine .hex.own { stroke-width: .9; filter: drop-shadow(0 0 2px var(--c)); }
.dish.fine .gate { stroke-width: 1.2; }
/* stress (currency 'stress'): a red gauge falling back live, a green one for the masker's energy */
.cl .stg { grid-column: 1; height: 5px; border-radius: 999px; background: #0e1a2e; overflow: hidden; margin: 2px 0; display: flex; }
.cl .stg i { display: block; height: 100%; background: linear-gradient(90deg, #ffb52e, #ff5a6e); box-shadow: 0 0 6px #ff5a6e; transition: width .25s linear; }
.cl .stg i.boost { background: linear-gradient(90deg, #6dff5a, #22f0ff); box-shadow: 0 0 6px #6dff5a; }
.stress-live { color: #ffb3bd; }
.hold .proj { z-index: 1; font-size: 11px; opacity: .85; }
/* the stress curve between the hold buttons */
.holds.with-curve { grid-template-columns: 1fr minmax(96px, .95fr) 1fr; gap: 8px; align-items: center; }
.scurve { width: 100%; height: auto; display: block; }
.scurve .ax { stroke: #4a5d78; stroke-width: 1; }
.scurve .grid { stroke: #24324a; stroke-width: .6; stroke-dasharray: 2 2; }
.scurve .lb { fill: #7f93ad; font-size: 7px; }
.scurve .str { fill: none; stroke: #ff5a6e; stroke-width: 2; filter: drop-shadow(0 0 3px #ff5a6e); }
.scurve .eff { fill: none; stroke: #6dff5a; stroke-width: 1.4; stroke-dasharray: 3 2; }
.scurve .dot { fill: #fff; stroke: #ff5a6e; stroke-width: 1.5; }
.scurve .lg { font-size: 7px; }
.scurve .str-t { fill: #ff8a99; }
.scurve .eff-t { fill: #9dff8c; }
.holds.with-curve { grid-template-columns: .9fr minmax(120px, 1.2fr) .9fr; }
.curvebox { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.curvebox .legend { font-size: 10px; color: var(--muted); display: flex; gap: 4px; align-items: center; }
.curvebox .legend i { display: inline-block; width: 12px; height: 0; border-top: 2px solid #ff5a6e; margin-left: 4px; }
.curvebox .legend i.eff-k { border-top: 2px dashed #6dff5a; }
.scurve .lb { font-size: 8px; }
.holds.with-curve .hold { height: 96px; padding: 4px; }
.holds.with-curve .hold b { font-size: 15px; }
.holds.with-curve .hold small { font-size: 10px; line-height: 1.15; }
.holds.with-curve .hold em { font-size: 16px; }
/* the title's heart (home): two cells that come together, divide into a heart, and part again (proposal 2) */
.title-heart { width: 1.1em; height: .9em; display: block; margin: 4px auto; overflow: visible; }
.title-heart circle { fill: rgba(109, 255, 90, .18); stroke: #6dff5a; stroke-width: 2.4; filter: drop-shadow(0 0 6px #6dff5a); transform-origin: 50% 50%; }
.title-heart .l { animation: th-l 3.2s ease-in-out infinite; }
.title-heart .r { animation: th-r 3.2s ease-in-out infinite; }
.title-heart path { fill: rgba(255, 61, 242, .2); stroke: #ff3df2; stroke-width: 2.4; filter: drop-shadow(0 0 7px #ff3df2); transform-origin: 50% 55%; animation: th-join 3.2s ease-in-out infinite; }
@keyframes th-l { 0%, 25% { transform: translateX(6px); opacity: 1; } 50%, 85% { transform: translateX(0); opacity: 0; } 100% { transform: translateX(6px); opacity: 1; } }
@keyframes th-r { 0%, 25% { transform: translateX(-6px); opacity: 1; } 50%, 85% { transform: translateX(0); opacity: 0; } 100% { transform: translateX(-6px); opacity: 1; } }
@keyframes th-join { 0%, 30% { opacity: 0; transform: scale(.8); } 50%, 85% { opacity: 1; transform: scale(1); } 100% { opacity: 0; transform: scale(.8); } }
@media (prefers-reduced-motion: reduce) { .title-heart circle { opacity: 0; animation: none; } .title-heart path { opacity: 1; animation: none; } }
