/* Homepage cleanup (2026-10-05): one support ask, fewer badges, plainer copy, no mascots. */
/* The header "Support us" button duplicated the support strip; it stays in the DOM because app.js binds it. */
.header-support { display: none !important; }
/* The "NEW" sticker on Queue links (added by link-queue.js). */
.link-queue-new { display: none !important; }
/* Service line in the normal UI font instead of small monospace. */
.convert-footer, .convert-footer * { font-family: inherit !important; letter-spacing: normal !important; text-transform: none !important; }
/* Bookmark reminder shows Woofer (bookmark-helper.js) instead of the old megaphone cartoon. */
.footer-maker { font-weight: 600; color: var(--text, inherit); }

/* Converter layout rules that used to live in coffee-mascot.css. */
.converter-dock { row-gap: 12px; padding-bottom: 10px; }
.converter-dock .convert-btn { min-height: 48px !important; height: 48px; }
.converter-dock .free-limit-notice {
  grid-column: 1 / -1; grid-row: 3; width: 100%; margin: 0; padding: 0;
  border: 0; background: transparent; box-shadow: none; justify-content: center;
  gap: 4px 10px; flex-wrap: wrap; color: var(--muted); font-size: 11px;
}
.converter-dock .free-limit-copy { display: flex; flex-wrap: wrap; justify-content: center; gap: 3px 6px; flex: 0 1 auto; }
.converter-dock .free-limit-copy strong { font-size: inherit; font-weight: 500; color: inherit; }
.converter-dock #btn-limit-upgrade { margin: 0; padding: 2px 0; min-height: 24px; font-size: 11px; color: var(--muted); text-decoration: underline; text-underline-offset: 3px; }
.converter-dock #btn-limit-upgrade:hover { color: var(--primary); }
.converter-dock .conversion-options-content { grid-row: 4; }
@media (max-width: 1100px) {
  .converter-dock .free-limit-notice { grid-row: 5; }
  .converter-dock .conversion-options-content { grid-row: 6; }
}

/* Woofer, the retriever mascot ("Fetch" in class names). app.js sets #living-signal[data-state] to idle/found/fetching/complete/error;
   the dog switches pose with it. The wrapper has no height, so it never pushes the converter down. */
.fetch-buddy { position: relative; z-index: 3; width: min(100%, var(--content-max, 1040px)); height: 0; margin: 0 auto; pointer-events: none; }
.fetch-dog { position: absolute; right: 30px; bottom: -14px; width: 84px; height: 100px; }
.fetch-pose { position: absolute; left: 50%; bottom: 0; width: auto; height: 96px; opacity: 0; transform: translateX(-50%); transform-origin: 50% 100%; transition: opacity .18s ease; }
.fetch-pose-run { height: 64px; bottom: 6px; }
.fetch-pose-error { height: 100px; }
.fetch-bubble { position: absolute; right: 14px; bottom: 116px; max-width: 220px; padding: 6px 12px; border: 1px solid var(--border, #dfe5e3); border-radius: 14px; background: var(--surface, #fff); color: var(--text, #17201e); font-size: 13px; font-weight: 600; line-height: 1.3; white-space: nowrap; box-shadow: 0 6px 18px rgba(23,32,30,.07); }
.fetch-bubble::after { content: ""; position: absolute; right: 34px; bottom: -6px; width: 10px; height: 10px; border-right: 1px solid var(--border, #dfe5e3); border-bottom: 1px solid var(--border, #dfe5e3); background: inherit; transform: rotate(45deg); }
html[dir="rtl"] .fetch-dog { right: auto; left: 30px; }
html[dir="rtl"] .fetch-bubble { right: auto; left: 14px; }
html[dir="rtl"] .fetch-bubble::after { right: auto; left: 34px; }
.fetch-buddy:is([data-state="idle"], [data-state="found"], [data-state="reset"]) .fetch-pose-idle,
.fetch-buddy[data-state="fetching"] .fetch-pose-run,
.fetch-buddy[data-state="complete"] .fetch-pose-done,
.fetch-buddy[data-state="error"] .fetch-pose-error { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  /* While waiting Woofer breathes, and now and then tilts his head or hops. */
  .fetch-buddy[data-state="idle"] .fetch-pose-idle { animation: fetch-idle-life 16s ease-in-out 2s infinite; }
  .fetch-buddy[data-state="found"] .fetch-pose-idle { animation: fetch-hop .6s ease-out; }
  .fetch-buddy[data-state="fetching"] .fetch-pose-run { animation: fetch-run .42s ease-in-out infinite alternate; }
  .fetch-buddy[data-state="complete"] .fetch-pose-done { animation: fetch-hop .7s ease-out, fetch-breathe 3.4s ease-in-out .7s infinite; }
  .fetch-buddy[data-state="error"] .fetch-pose-error { animation: fetch-tilt .9s ease-out; }
}
@keyframes fetch-breathe { 0%, 100% { transform: translateX(-50%) scale(1, 1); } 50% { transform: translateX(-50%) scale(1.02, .985); } }
@keyframes fetch-hop { 0% { transform: translateX(-50%) translateY(0); } 30% { transform: translateX(-50%) translateY(-14px); } 55% { transform: translateX(-50%) translateY(0); } 72% { transform: translateX(-50%) translateY(-4px); } 100% { transform: translateX(-50%) translateY(0); } }
@keyframes fetch-run { from { transform: translateX(-54%) translateY(0); } to { transform: translateX(-46%) translateY(-5px); } }
@keyframes fetch-tilt { 0% { transform: translateX(-50%) rotate(0); } 35% { transform: translateX(-50%) rotate(-5deg); } 70% { transform: translateX(-50%) rotate(2deg); } 100% { transform: translateX(-50%) rotate(0); } }
/* Phones: reserve a little room above the converter so Fetch never sits on the intro text. */
@media (max-width: 700px) {
  .fetch-buddy { height: 58px; }
  .fetch-dog { right: 14px; bottom: -12px; width: 64px; height: 76px; }
  .fetch-pose { height: 72px; }
  .fetch-pose-run { height: 48px; bottom: 4px; }
  .fetch-pose-error { height: 74px; }
  .fetch-bubble { right: 86px; bottom: 18px; font-size: 12px; }
}

/* Header logo: Fetch's head (icons/icon128.png) instead of the animated bars, same as every other page. */
.brand .brand-signal { display: none !important; }
.brand .brand-mark-fallback { position: static; width: 38px; height: 38px; opacity: 1; pointer-events: auto; }
@media (max-width: 760px) { .brand .brand-mark-fallback { width: 34px; height: 34px; } }

/* Hovering Woofer shows his name; the rest of the wrapper stays click-through. */
.fetch-dog { pointer-events: auto; cursor: default; }

@keyframes fetch-idle-life {
  0%, 8%, 16%, 24% { transform: translateX(-50%) scale(1, 1); }
  4%, 12%, 20% { transform: translateX(-50%) scale(1.02, .985); }
  30% { transform: translateX(-50%) rotate(0); }
  34%, 42% { transform: translateX(-50%) rotate(-7deg); }
  46% { transform: translateX(-50%) rotate(0); }
  58% { transform: translateX(-50%) translateY(0); }
  61% { transform: translateX(-50%) translateY(-13px); }
  64% { transform: translateX(-50%) translateY(0); }
  66% { transform: translateX(-50%) translateY(-4px); }
  68% { transform: translateX(-50%) translateY(0); }
  80%, 100% { transform: translateX(-50%) scale(1, 1); }
}

/* Nap: woofer.js sets data-mood="asleep" after 30 s without interaction (only while idle). */
.fetch-pose-sleep { height: 40px; bottom: 0; }
.fetch-zzz { position: absolute; right: 2px; bottom: 34px; display: none; color: var(--muted, #5d6b68); font-weight: 800; line-height: 1; }
.fetch-zzz i { position: absolute; right: 0; bottom: 0; font-style: normal; opacity: 0; }
.fetch-zzz i:nth-child(1) { font-size: 11px; }
.fetch-zzz i:nth-child(2) { font-size: 14px; }
.fetch-zzz i:nth-child(3) { font-size: 17px; }
.fetch-bubble { transition: opacity .3s ease; }
.fetch-buddy[data-mood="asleep"] .fetch-pose { opacity: 0 !important; }
.fetch-buddy[data-mood="asleep"] .fetch-pose-sleep { opacity: 1 !important; }
.fetch-buddy[data-mood="asleep"] .fetch-bubble { opacity: 0; }
.fetch-buddy[data-mood="asleep"] .fetch-zzz { display: block; }
@media (prefers-reduced-motion: no-preference) {
  .fetch-buddy[data-mood="asleep"] .fetch-pose-sleep { animation: fetch-snooze 3.6s ease-in-out infinite; }
  .fetch-buddy[data-mood="asleep"] .fetch-zzz i { animation: fetch-z 3.6s ease-out infinite; }
  .fetch-buddy[data-mood="asleep"] .fetch-zzz i:nth-child(2) { animation-delay: 1.2s; }
  .fetch-buddy[data-mood="asleep"] .fetch-zzz i:nth-child(3) { animation-delay: 2.4s; }
  .fetch-buddy[data-mood="waking"][data-state="idle"] .fetch-pose-idle { animation: fetch-hop .6s ease-out; }
}
@media (prefers-reduced-motion: reduce) {
  .fetch-buddy[data-mood="asleep"] .fetch-zzz i { opacity: .8; }
  .fetch-buddy[data-mood="asleep"] .fetch-zzz i:nth-child(2) { right: 9px; bottom: 10px; }
  .fetch-buddy[data-mood="asleep"] .fetch-zzz i:nth-child(3) { right: 20px; bottom: 22px; }
}
@keyframes fetch-snooze { 0%, 100% { transform: translateX(-50%) scale(1, 1); } 50% { transform: translateX(-50%) scale(1.015, 1.05); } }
@keyframes fetch-z { 0% { opacity: 0; transform: translate(0, 0); } 20% { opacity: .9; } 100% { opacity: 0; transform: translate(-14px, -30px); } }
@media (max-width: 700px) { .fetch-pose-sleep { height: 32px; } .fetch-zzz { bottom: 26px; } }

/* Layered idle pose: the tail wags around its root and the eyelids blink (cut from waiting.webp). */
span.fetch-pose-idle { display: block; aspect-ratio: 240 / 344; }
.fetch-layer { position: absolute; inset: 0; width: 100%; height: 100%; }
.fetch-tail { transform-origin: 23.6% 81.8%; }
.fetch-blink { opacity: 0; }
/* Costumes (woofer.js): same layers, own art. The witch hat makes the Halloween pose taller, so it gets
   extra height to keep the dog the same size, and its tail root sits in a slightly different spot. */
.fetch-buddy[data-costume="halloween"] span.fetch-pose-idle { aspect-ratio: 240 / 384; height: 107px; }
.fetch-buddy[data-costume="halloween"] .fetch-tail { transform-origin: 22.7% 78.5%; }
@media (max-width: 700px) { .fetch-buddy[data-costume="halloween"] span.fetch-pose-idle { height: 80px; } }
/* Animated idle clip (woofer.js places it: a little larger than the layers for the tail swing and ear flop). */
.fetch-live { display: none; right: auto; bottom: auto; }
.fetch-buddy[data-live] .fetch-live { display: block; }
.fetch-buddy[data-live] .fetch-pose-idle .fetch-layer:not(.fetch-live) { visibility: hidden; }
.fetch-dog { cursor: pointer; }
.fetch-heart { position: absolute; left: 46%; top: 0; color: #e0475c; font-size: 20px; line-height: 1; pointer-events: none; opacity: 0; }
@media (prefers-reduced-motion: no-preference) {
  .fetch-tail { animation: fetch-wag 4.2s ease-in-out infinite; }
  .fetch-blink { animation: fetch-blink 5.8s steps(1, end) 1.5s infinite; }
  .fetch-buddy[data-mood="petted"] .fetch-tail { animation: fetch-wag-happy .26s ease-in-out 0s 5 alternate; }
  .fetch-buddy[data-mood="petted"] span.fetch-pose-idle { animation: fetch-hop .6s ease-out; }
  .fetch-buddy[data-mood="petted"] .fetch-blink { animation: none; opacity: 1; }
  .fetch-heart { animation: fetch-heart 1.2s ease-out forwards; }
}
@keyframes fetch-wag {
  0%, 30%, 100% { transform: rotate(0); }
  4%, 12%, 20% { transform: rotate(10deg); }
  8%, 16%, 24% { transform: rotate(-3deg); }
}
@keyframes fetch-wag-happy { from { transform: rotate(-4deg); } to { transform: rotate(12deg); } }
@keyframes fetch-blink { 0% { opacity: 0; } 96% { opacity: 1; } 98.5% { opacity: 0; } }
@keyframes fetch-heart { 0% { opacity: 0; transform: translateY(0) scale(.6); } 20% { opacity: 1; transform: translateY(-8px) scale(1.1); } 100% { opacity: 0; transform: translateY(-34px) scale(1); } }

/* Animated pose clips (woofer.js swaps the still for the clip and adds .is-live). Each canvas is a little
   larger than its still (paws, ears, tail reach further), so the pose grows by the factor the converter
   printed and keeps its feet where they were. The clip's own motion replaces the CSS bob and tilt. */
.fetch-pose-run.is-live { height: calc(64px * 1.1738); bottom: calc(6px - 64px * .0366); }
.fetch-pose-done.is-live { height: calc(96px * 1.0137); }
.fetch-pose-error.is-live { height: calc(100px * 1.0053); }
.fetch-pose-sleep.is-live { height: calc(40px * 1.0618); }
@media (max-width: 700px) {
  .fetch-pose-run.is-live { height: calc(48px * 1.1738); bottom: calc(4px - 48px * .0366); }
  .fetch-pose-done.is-live { height: calc(72px * 1.0137); }
  .fetch-pose-error.is-live { height: calc(74px * 1.0053); }
  .fetch-pose-sleep.is-live { height: calc(32px * 1.0618); }
}
.fetch-buddy .fetch-pose.is-live { animation: none !important; }

/* Following along (woofer.js sets data-float): when his spot has scrolled away mid-conversion, Woofer and his
   bubble wait in the side margin, keeping the same spacing as in his usual spot. */
.fetch-buddy[data-float] .fetch-dog { position: fixed; right: var(--float-x, 24px); bottom: 24px; }
.fetch-buddy[data-float] .fetch-bubble { position: fixed; right: calc(var(--float-x, 24px) - 16px); bottom: 154px; }
html[dir="rtl"] .fetch-buddy[data-float] .fetch-dog { right: auto; left: var(--float-x, 24px); }
html[dir="rtl"] .fetch-buddy[data-float] .fetch-bubble { right: auto; left: calc(var(--float-x, 24px) - 16px); }
@media (prefers-reduced-motion: no-preference) {
  .fetch-buddy[data-float] .fetch-dog, .fetch-buddy[data-float] .fetch-bubble { animation: fetch-float-in .3s ease-out; }
}
@keyframes fetch-float-in { from { opacity: 0; translate: 0 14px; } to { opacity: 1; translate: 0 0; } }
/* Petting while he's busy (running, waving, puzzled): the whole dog gives a little hop. */
@media (prefers-reduced-motion: no-preference) {
  .fetch-buddy[data-mood="petted"]:not([data-state="idle"]) .fetch-dog { animation: fetch-pet-hop .5s ease-out; }
}
@keyframes fetch-pet-hop { 0%, 100% { translate: 0 0; } 35% { translate: 0 -10px; } 65% { translate: 0 0; } 80% { translate: 0 -3px; } }
