/* Seals living in houses on /village.html (town-map.js homeSealHtml / roomHtml).
   Its own file rather than site.css so adding it doesn't mean bumping ?v= on every page —
   only village.html and preview.html load it.

   Three nested boxes, three transforms: the outer box paces (translateX, as a % of its own
   width — town-map.js works out --hs-range from the yard's width), .hs-turn faces the way it's
   going on the same 16s clock, .hs-waddle rocks. The art faces left, so walking right is the
   mirrored half. */
.gt-home-seal,
.gt-room-seal{
  position:absolute; aspect-ratio:500/332;
  animation:hs-pace 16s ease-in-out infinite;
}
.hs-turn{display:block; width:100%; height:100%; animation:hs-turn 16s linear infinite; animation-delay:inherit;}
.hs-waddle{
  display:block; width:100%; height:100%; transform-origin:50% 90%;
  animation:gt-seal-waddle .55s ease-in-out infinite;
}
.hs-waddle svg{display:block; width:100%; height:100%; overflow:visible;}
@keyframes hs-pace{
  0%,4%{transform:translateX(calc(var(--hs-range, 90%) * -1));}
  44%,54%{transform:translateX(var(--hs-range, 90%));}
  94%,100%{transform:translateX(calc(var(--hs-range, 90%) * -1));}
}
@keyframes hs-turn{
  0%,48.9%{transform:scaleX(-1);}
  49%,98.9%{transform:scaleX(1);}
  99%,100%{transform:scaleX(-1);}
}

/* On the map: standing on the stone path in front of the house, just over its bottom edge. */
.gt-home-seal{
  bottom:-6%; z-index:3; pointer-events:none;
  filter:drop-shadow(1px 2px 0 rgba(20,20,20,.22));
}
#page-content[data-daytime="night"] .gt-home-seal{filter:brightness(.85) drop-shadow(0 0 3px rgba(255,236,170,.6));}

/* ---- inside the house ---- */
.gt-room{
  position:relative; width:100%; max-width:380px; aspect-ratio:16/10;
  border-radius:18px; overflow:hidden; border:3px solid var(--line);
  background:#fde8d7; box-shadow:0 4px 0 rgba(20,20,20,.08);
}
.gt-room-scene{position:absolute; inset:0; width:100%; height:100%; display:block;}
#page-content[data-daytime="dusk"] .gt-room-sky{fill:#ffc6a8;}
#page-content[data-daytime="night"] .gt-room-sky{fill:#3d417e;}
#page-content[data-daytime="night"] .gt-room-sun{fill:#fff6c9; r:5;}
/* In the room she is moved by home-room.js (left/bottom with transitions), not the CSS pace
   loop — so every looping animation the map seal has is switched off here and put back only
   while she's walking (.walking) or doing something (data-act). */
.gt-room-seal{
  width:24%; margin-left:-12%; z-index:4; cursor:var(--cursor-pointer-url), pointer;
  animation:none;
}
.gt-room-seal.tucked{z-index:2;}
.gt-room-seal .hs-turn{animation:none; transition:transform .2s;}
.gt-room-seal.face-r .hs-turn{transform:scaleX(-1);}
.gt-room-seal .hs-waddle{animation:none; filter:drop-shadow(0 4px 2px rgba(120,80,120,.18));}
.gt-room-seal.walking .hs-waddle{animation:gt-seal-waddle .55s ease-in-out infinite;}
.gt-room-seal.poked .hs-waddle{animation:hs-hop .5s cubic-bezier(.3,1.6,.5,1);}

/* What she does at each piece. The art faces left, so "forward" is local -X and a positive
   rotate lifts her head — both stay right when .face-r mirrors her. */
.gt-room-seal[data-act="sleep"] .hs-waddle{transform-origin:50% 100%; animation:hr-breathe 2.6s ease-in-out infinite;}
@keyframes hr-breathe{0%,100%{transform:scale(.86,.84) rotate(-3deg);} 50%{transform:scale(.88,.87) rotate(-3deg);}}
.gt-room-seal[data-act="piano"] .hs-waddle{animation:hr-bop .38s ease-in-out infinite;}
@keyframes hr-bop{0%,100%{transform:translateY(0) rotate(0);} 50%{transform:translateY(-7%) rotate(-4deg);}}
.gt-room-seal[data-act="fish"] .hs-waddle{transform-origin:70% 100%; animation:hr-gaze 1.6s ease-in-out infinite;}
@keyframes hr-gaze{0%,100%{transform:rotate(9deg);} 50%{transform:rotate(12deg) translateY(-3%);}}
.gt-room-seal[data-act="bath"] .hs-waddle{transform-origin:50% 100%; animation:hr-soak 2s ease-in-out infinite;}
@keyframes hr-soak{0%,100%{transform:scale(.86) rotate(-4deg);} 50%{transform:scale(.86) rotate(4deg) translateY(2%);}}
.gt-room-seal[data-act="ball"] .hs-waddle{animation:hr-nudge 2s ease-in-out infinite;}
@keyframes hr-nudge{0%,8%,40%,100%{transform:translateX(0);} 16%{transform:translateX(-14%) rotate(-6deg);} 26%{transform:translateX(0) rotate(0);}}

/* ---- furniture ---- */
.hr-item, .hr-front{position:absolute; display:block; padding:0; margin:0; border:0; background:none;}
.hr-item{z-index:1; cursor:var(--cursor-pointer-url), pointer; transform-origin:50% 100%;}
.hr-front{z-index:3; pointer-events:none;}
.hr-item svg, .hr-front svg{display:block; width:100%; height:100%; overflow:visible;}
.hr-item:focus-visible{outline:2px dashed #b58cff; outline-offset:2px; border-radius:6px;}
.hr-ball{z-index:3;}
.hr-item.ghost, .hr-front.ghost{opacity:.3; filter:grayscale(.6);}
.hr-item.ghost::after{
  content:'+'; position:absolute; right:-4px; top:-4px; width:16px; height:16px; border-radius:50%;
  background:#fff; color:#e0609a; font:800 12px/16px sans-serif; text-align:center;
  box-shadow:0 1px 3px rgba(0,0,0,.2); opacity:1;
}
.hr-item.wiggle{animation:hr-wiggle .45s ease-in-out;}
@keyframes hr-wiggle{0%,100%{transform:rotate(0);} 25%{transform:rotate(-4deg);} 75%{transform:rotate(4deg);}}
.hr-fish{animation:hr-swim 5s ease-in-out infinite; transform-box:fill-box;}
.hr-fish-b{animation-duration:6.5s; animation-delay:-2s;}
@keyframes hr-swim{0%,100%{transform:translateX(0);} 50%{transform:translateX(-14px);}}
.gt-room[data-act="fish"] .hr-fish{animation-duration:1.6s;}
.hr-ball.kick{animation:hr-kick 1.6s ease-in-out;}
@keyframes hr-kick{
  0%{transform:translate(0,0) rotate(0);}
  30%{transform:translate(90%,-40%) rotate(160deg);}
  50%{transform:translate(160%,0) rotate(300deg);}
  100%{transform:translate(0,0) rotate(0);}
}

/* particles: zzz, notes, bubbles, hearts */
.hr-fx{
  position:absolute; z-index:5; pointer-events:none; line-height:1; font-weight:800;
  animation:hr-float 1.8s ease-out both; opacity:0;
}
.hr-fx.zz{color:#9b8cff; font-size:1rem;}
.hr-fx.note{color:#e877b0; font-size:1.05rem;}
.hr-fx.heart{color:#ff8fb8; font-size:.95rem;}
.hr-fx.bub{
  color:transparent; font-size:0; width:11px; height:11px; border-radius:50%;
  border:2px solid #9fd6ff; background:rgba(255,255,255,.75);
}
.hr-fx.spark{color:#ffc94a; font-size:.9rem;}
.hr-fx.drool{font-size:.7rem; animation:hr-drip 1.4s ease-in both;}
@keyframes hr-float{
  0%{opacity:0; transform:translate(0,0) scale(.6);}
  20%{opacity:1;}
  100%{opacity:0; transform:translate(10px,-38px) scale(1.1);}
}
@keyframes hr-drip{0%{opacity:0; transform:translateY(0);} 20%{opacity:1;} 100%{opacity:0; transform:translateY(16px);}}

/* the price bubble a not-yet-owned piece pops up */
.hr-tip{
  position:absolute; z-index:6; transform:translate(-50%,-100%);
  background:#fff; border:2px solid var(--line); border-radius:12px; padding:5px 10px;
  font-size:.74rem; text-align:center; white-space:nowrap; box-shadow:0 3px 0 rgba(20,20,20,.1);
}
.hr-tip small{display:block; font-size:.66rem; color:var(--ink-soft);}
.hr-shop-hint{margin:0 !important; font-size:.72rem; color:var(--ink-soft); text-align:center;}

/* furniture list in the side panel */
.gv-card-furn .gv-card-body{width:100%;}
.gv-furn-list{display:flex; flex-direction:column; gap:4px; margin:4px 0 2px;}
.gv-furn{display:flex; align-items:center; gap:8px; font-size:.78rem;}
.gv-furn > span:nth-child(2){flex:1 1 auto;}
.hr-thumb{width:34px; height:26px; flex:none;}
@keyframes hs-hop{
  0%{transform:translateY(0) scale(1,1);}
  30%{transform:translateY(-22%) scale(.95,1.07);}
  70%{transform:translateY(0) scale(1.08,.92);}
  100%{transform:translateY(0) scale(1,1);}
}
.gt-room-heart{
  position:absolute; z-index:3; color:#ff8fb8; font-size:1.1rem; line-height:1; pointer-events:none;
  animation:hs-heart 1.2s ease-out forwards; opacity:0;
}
@keyframes hs-heart{
  0%{opacity:0; transform:translateY(0) scale(.5);}
  20%{opacity:1; transform:translateY(-8px) scale(1.1);}
  100%{opacity:0; transform:translateY(-46px) scale(.9);}
}
.gt-room-cap{margin:0 !important; font-size:.8rem; color:var(--ink-soft); text-align:center;}

/* No seal yet: a dotted seal-shaped outline waits on the cushion. */
.gt-room.empty .gt-room-scene{filter:saturate(.8);}
.gt-room-ghost{
  position:absolute; right:6%; bottom:9%; width:22%; aspect-ratio:3/2; z-index:2;
  border:3px dashed #e5a9c6; border-radius:50% 50% 45% 45% / 60% 60% 40% 40%;
  display:flex; align-items:center; justify-content:center;
  color:#e5a9c6; font-weight:800; font-size:1.2rem;
  animation:hs-ghost 2.4s ease-in-out infinite;
}
@keyframes hs-ghost{0%,100%{opacity:.55;} 50%{opacity:1;}}
.gt-room-offer{
  width:100%; max-width:380px; display:flex; flex-direction:column; align-items:center; gap:3px;
  padding:10px 12px; border-radius:14px; text-align:center;
  background:var(--paper-2); border:2px dashed var(--line);
}
.gt-room-offer > span{font-size:.82rem;}
.gt-room-offer small{font-size:.72rem; color:var(--ink-soft);}
.gt-room-offer .gt-price{opacity:1; color:#e0609a; font-size:.9rem;}

/* The add-on's card at the end of the side panel's price list. */
.gv-card-seal{border-style:dashed !important;}
.gv-seal-art{display:block; width:62px; aspect-ratio:500/332;}
.gv-seal-art svg{display:block; width:100%; height:100%;}

/* ============================================================ yards and premium spots
   (2026-10-17) Two boxes per pad, both exactly the pad's size (town-map.js padGround()):
   .gt-pad-under below the plot buttons, .gt-pad-over above them. Neither takes pointer events,
   so a tap anywhere on the pad still reaches the house button. Sizes are in map px set inline
   by the scripts; --gt-scale is the zoom (1-4), used to keep the ribbon text in proportion. */
.gt-pad-under, .gt-pad-over{position:absolute; pointer-events:none; transition:opacity .2s ease, filter .2s ease;}
.gt-pad-under{z-index:1;}
.gt-pad-over{z-index:3;}
.gt-pad-under.gt-dim, .gt-pad-over.gt-dim{opacity:.25; filter:grayscale(1);}

.gt-yard-piece{position:absolute; display:block; image-rendering:pixelated;
  filter:drop-shadow(1px 2px 0 rgba(20,20,20,.25));}
.gt-yard-piece.back{filter:drop-shadow(2px 3px 0 rgba(20,20,20,.22));}
/* The lamp and the string lights come on after dark, like the houses' own windows. */
#page-content[data-daytime="dusk"] .gt-yard-piece.glow{filter:drop-shadow(0 0 3px rgba(255,214,120,.7));}
#page-content[data-daytime="night"] .gt-yard-piece.glow,
:root[data-theme="dark"] .gt-yard-piece.glow{
  filter:drop-shadow(0 0 4px rgba(255,214,120,.95)) brightness(1.15);
}
.gt-yard-lights{animation:gtYardLights 2.4s steps(1) infinite;}
@keyframes gtYardLights{
  0%,100%{opacity:1;}
  50%{opacity:.72;}
}
/* The fish pond's water catches the light now and then. */
.gt-yard-pond{animation:gtYardPond 3.2s ease-in-out infinite;}
@keyframes gtYardPond{0%,100%{filter:drop-shadow(1px 2px 0 rgba(20,20,20,.25));} 50%{filter:drop-shadow(1px 2px 0 rgba(20,20,20,.25)) brightness(1.12);}}
.gt-yard-sakura, .gt-yard-grapevine{transform-origin:50% 100%; animation:gtYardSway 5.5s ease-in-out infinite;}
.gt-yard-grapevine{animation-delay:-2.2s;}
@keyframes gtYardSway{0%,100%{transform:rotate(0deg);} 50%{transform:rotate(1.4deg);}}

/* Premium spot: a gold ring just inside the fence that slowly breathes, plus a ribbon over the
   back fence naming the spot. Shown sold or not — the street always shows where the good land is. */
.gt-spot-ring::before{
  content:''; position:absolute; inset:2%; border-radius:6px; pointer-events:none;
  box-shadow:0 0 0 2px rgba(255,212,94,.95), 0 0 calc(var(--gt-scale,2) * 6px) rgba(255,200,70,.75),
             inset 0 0 calc(var(--gt-scale,2) * 8px) rgba(255,220,120,.45);
  background:linear-gradient(180deg, rgba(255,236,170,.18), rgba(255,214,94,.08));
  animation:gtSpotGlow 2.8s ease-in-out infinite;
}
@keyframes gtSpotGlow{0%,100%{opacity:.75;} 50%{opacity:1;}}
.gt-spot-ribbon{
  position:absolute; left:50%; top:0; transform:translate(-50%,-75%);
  white-space:nowrap; font-weight:800; line-height:1.3;
  font-size:calc(.42rem + var(--gt-scale,2) * .16rem);
  padding:1px calc(var(--gt-scale,2) * 3px); border-radius:999px;
  background:var(--yellow); color:#3b3140; border:2px solid var(--line);
  box-shadow:0 2px 0 rgba(20,20,20,.25);
}
/* A vacant spot plot's for-sale tag carries the spot's surcharge on a third line. */
.gt-tag.gt-tag-spot{background:#fff4c4; border-color:#c99a1e;}
.gt-tag.gt-tag-spot em{font-style:normal; font-weight:800; font-size:var(--fs-plotTagNo, .58rem); color:#a8740a; letter-spacing:0;}

/* In the house window. */
.gt-spot-badge{
  display:inline-block; font-weight:800; font-size:.78rem; padding:3px 12px; border-radius:999px;
  background:var(--yellow); border:2px solid var(--line); color:#3b3140;
}
.gt-spot-box{
  width:100%; max-width:380px; display:flex; flex-direction:column; align-items:center; gap:2px;
  padding:9px 12px; border-radius:14px; text-align:center;
  background:#fff4c4; border:2px solid #c99a1e; color:#3b3140;
}
.gt-spot-box > span{font-size:.82rem;}
.gt-spot-box small{font-size:.72rem; opacity:.75;}
.gt-spot-box .gt-price{opacity:1; color:#a8740a; font-size:.9rem;}
.gt-price-split{display:block; font-size:.64rem; font-weight:700; opacity:.7; text-align:right;}
.gt-yard-box{
  width:100%; max-width:380px; display:flex; flex-direction:column; align-items:center; gap:6px;
  padding:10px 12px; border-radius:14px; background:var(--paper-2); border:2px dashed var(--line);
}
.gt-yard-head{font-size:.86rem;}
.gt-yard-chips{display:flex; flex-wrap:wrap; justify-content:center; gap:6px;}
.gt-yard-chip{
  display:flex; flex-direction:column; align-items:center; gap:2px; min-width:72px;
  padding:6px 8px; border-radius:12px; border:2px dashed var(--line); font-size:.72rem; opacity:.85;
}
.gt-yard-chip.have{border-style:solid; opacity:1; background:#eaf7e6;}
:root[data-theme="dark"] .gt-yard-chip.have{background:#1f3324;}
.gt-yard-chip small{font-size:.64rem; color:var(--ink-soft);}
.gt-yard-chip .gt-price{opacity:1; color:#e0609a;}
.gt-yard-note{font-size:.7rem; color:var(--ink-soft); text-align:center;}
.gt-yard-thumb{display:block; flex:none; image-rendering:pixelated; background-repeat:no-repeat; background-size:100% 100%;}
.gv-furn .gt-yard-thumb{max-width:40px; max-height:28px; background-size:contain; background-position:center;}
/* Side panel. */
.gv-card-spot{border-color:#c99a1e !important; background:#fff8dc !important;}
:root[data-theme="dark"] .gv-card-spot{background:#2b2612 !important;}
.gv-card-spot .gv-card-body{width:100%;}
.gv-spot-list{display:flex; flex-direction:column; gap:4px; margin:4px 0 2px;}
.gv-spot-line{display:flex; align-items:baseline; flex-wrap:wrap; gap:4px 8px; font-size:.8rem;}
.gv-spot-line > span:first-child{flex:1 1 auto; font-weight:700;}
.gv-spot-line small{flex:1 0 100%; font-size:.7rem; color:var(--ink-soft);}

/* ============================================================ roof paint (2026-10-18)
   The colour chips (town-paint.js swatch()) and the one colour with an effect of its own: a gold
   roof catches a sweep of light now and then, so it reads as gold rather than plain yellow. */
.gt-paint-swatch{display:inline-block; flex:none; border-radius:50%; border:2px solid var(--line); box-shadow:inset -2px -2px 0 rgba(0,0,0,.12);}
.gt-paint-swatch.shine{background-image:linear-gradient(135deg, rgba(255,255,255,.75) 0 22%, transparent 40%) !important;}
.gt-house.gt-paint-gold img{filter:drop-shadow(0 0 3px rgba(255,212,94,.75)) saturate(1.1);}
.gt-house.gt-paint-gold::after{
  content:''; position:absolute; inset:0 0 55% 0; pointer-events:none; z-index:2;
  background:linear-gradient(105deg, transparent 35%, rgba(255,255,255,.55) 50%, transparent 65%);
  background-size:250% 100%; background-repeat:no-repeat;
  mix-blend-mode:soft-light; animation:gtGoldSweep 4.5s ease-in-out infinite;
}
@keyframes gtGoldSweep{0%,55%{background-position:120% 0;} 100%{background-position:-120% 0;}}
.gt-paint-chip .gt-paint-swatch{margin-bottom:2px;}

@media (prefers-reduced-motion:reduce){
  .gt-house.gt-paint-gold::after{animation:none; display:none;}
  .gt-home-seal, .gt-room-seal, .hs-turn, .hs-waddle, .gt-room-ghost{animation:none !important;}
  .gt-yard-lights, .gt-yard-pond, .gt-yard-sakura, .gt-yard-grapevine, .gt-spot-ring::before{animation:none !important;}
}
