/*
 * Snitch on the website (public/v2/snitch.js). Plain CSS outside the Vite
 * build, themed on the html.dark class the site toggle writes.
 */
:root {
    --dfs-say-bg: #1A1D23;
    --dfs-say-text: #FFF7EE;
    --dfs-muted: #5B6170;
    --dfs-drop-bg: #FFF4E8;
    --dfs-drop-edge: #F6D9BC;
    /* His sticker (owner pick "C", 2026-10-11): cream with an ember edge. */
    --dfs-stk-bg: #FFF3E2; --dfs-stk-text: #3A1A12; --dfs-stk-edge: #FF8A3D; --dfs-stk-shadow: rgba(232, 101, 10, .25); --dfs-stk-link: #C2410C;
    /* The companion's panel: the page's own surface. */
    --dfs-pan-bg: #FFFDF9; --dfs-pan-text: #1E2430; --dfs-pan-muted: #666C77; --dfs-pan-edge: #E6E0D6; --dfs-pan-sunk: #F4F1EC; --dfs-pan-hot: #C7362A;
}
html.dark {
    --dfs-say-bg: #FFF7EE;
    --dfs-say-text: #1A1D23;
    --dfs-muted: #A7AEBD;
    --dfs-drop-bg: #2B2019;
    --dfs-drop-edge: rgba(255, 138, 61, .28);
    --dfs-stk-bg: #2A1B12; --dfs-stk-text: #FFE6CC; --dfs-stk-edge: #E8762F; --dfs-stk-shadow: rgba(0, 0, 0, .35); --dfs-stk-link: #FF9A57;
    --dfs-pan-bg: #171B23; --dfs-pan-text: #E9EDF4; --dfs-pan-muted: #97A0B0; --dfs-pan-edge: #262C37; --dfs-pan-sunk: #0E1117; --dfs-pan-hot: #FF7A6B;
}

/* A slot keeps its ordinary content until Snitch moves in. */
.df-snitch-slot { position: relative; display: inline-flex; align-items: center; justify-content: center; vertical-align: middle; }
.df-snitch-slot.is-snitch > :not(.df-snitch):not(.df-snitch-say) { display: none !important; }
/* Only one Snitch on screen: the others step aside and show their fallback. */
.df-snitch-slot.is-snitch.is-yield > .df-snitch { display: none !important; }
.df-snitch-slot.is-snitch.is-yield > :not(.df-snitch):not(.df-snitch-say) { display: revert !important; }

.df-snitch {
    position: relative; display: inline-block; flex: none; line-height: 0;
    -webkit-tap-highlight-color: transparent; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;
    transition: opacity .3s ease, transform .3s ease;
}
.df-snitch[role="button"] { cursor: pointer; border-radius: 40%; transition: transform .18s ease; }
/* He looks pokeable: a little lean and lift under the pointer. */
@media (hover: hover) { .df-snitch[role="button"]:hover { transform: rotate(-6deg) translateY(-2px) scale(1.06); } }
@media (prefers-reduced-motion: reduce) { .df-snitch[role="button"]:hover { transform: none; } }
.df-snitch[role="button"]:focus-visible { outline: 2px solid #FF8A3D; outline-offset: 3px; }
.df-snitch__still, .df-snitch__live { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.df-snitch__live { opacity: 0; transition: opacity .2s ease; }
.df-snitch.is-live .df-snitch__live { opacity: 1; }
.df-snitch.is-live .df-snitch__still { opacity: 0; transition: opacity .2s ease .1s; }
.df-snitch.is-away { opacity: 0; transform: translateY(30%) scale(.6); pointer-events: none; }

/* The still drawing's stand-ins for the animated file's triggers. */
.df-snitch.is-giggle { animation: dfs-giggle .55s ease; }
.df-snitch.is-hop { animation: dfs-hop .7s cubic-bezier(.3, 1.6, .5, 1); }
.df-snitch.is-spin { animation: dfs-spin .7s ease; }
.df-snitch.is-shake { animation: dfs-shake .5s ease; }
.df-snitch.is-flop { animation: dfs-flop .9s ease; }
@keyframes dfs-giggle { 0%, 100% { transform: none; } 25% { transform: scale(1.08, .92) rotate(-4deg); } 50% { transform: translateY(-12%) scale(.95, 1.06); } 75% { transform: rotate(4deg); } }
@keyframes dfs-hop { 0%, 100% { transform: none; } 40% { transform: translateY(-22%) scale(.96, 1.05); } 70% { transform: translateY(0) scale(1.06, .94); } }
@keyframes dfs-spin { to { transform: rotateY(360deg); } }
@keyframes dfs-shake { 0%, 100% { transform: none; } 20%, 60% { transform: translateX(-6%) rotate(-3deg); } 40%, 80% { transform: translateX(6%) rotate(3deg); } }
@keyframes dfs-flop { 0%, 100% { transform: none; } 30%, 70% { transform: rotate(-80deg) translateY(10%); } }

/* His one line, beside him: his own sticker (owner pick "C", 2026-10-11),
   cream with an ember edge in his display face, tilted a touch, the sharp
   corner pointing at him. */
.df-snitch-say {
    position: absolute; z-index: 30; left: calc(100% + 6px); top: 50%;
    transform: translate(-4px, -50%) rotate(-2deg); opacity: 0;
    max-width: min(230px, 60vw); width: max-content;
    padding: 4px 10px 5px; border-radius: 14px 14px 14px 4px;
    background: var(--dfs-stk-bg); color: var(--dfs-stk-text); border: 1.5px solid var(--dfs-stk-edge);
    font: 800 13.5px/1.25 "Bricolage Grotesque", Figtree, system-ui, sans-serif; letter-spacing: -.01em;
    white-space: normal; text-align: left; pointer-events: none;
    box-shadow: 2px 2px 0 var(--dfs-stk-shadow);
    transition: opacity .2s ease, transform .2s ease;
}
.df-snitch-say.is-left { left: auto; right: calc(100% + 6px); transform: translate(4px, -50%) rotate(2deg); border-radius: 14px 14px 4px 14px; }
.df-snitch-say.is-on { opacity: 1; transform: translate(0, -50%) rotate(-2deg); }
.df-snitch-say.is-left.is-on { transform: translate(0, -50%) rotate(2deg); }

/* The homepage drop-in: floats over the top edge of the feed for a moment and
   fades away. Positioned, never in the flow: opening a gap pushed every deal
   down (layout shift, a Core Web Vitals cost; owner, 2026-10-11). */
.hv2-feedwrap__in { position: relative; }
.df-snitch-drop {
    position: absolute; left: 50%; top: -10px; z-index: 6;
    display: flex; align-items: center; gap: 6px; width: max-content; max-width: calc(100% - 32px);
    opacity: 0; transform: translate(-50%, -8px); pointer-events: none;
    transition: opacity .3s ease, transform .35s ease;
}
.df-snitch-drop.is-open { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
.df-snitch-drop__line { font: 800 15px/1.25 "Bricolage Grotesque", Figtree, system-ui, sans-serif; letter-spacing: -.01em; padding: 4px 12px 5px;
    background: var(--dfs-stk-bg); color: var(--dfs-stk-text); border: 1.5px solid var(--dfs-stk-edge); border-radius: 14px 14px 14px 4px;
    box-shadow: 2px 2px 0 var(--dfs-stk-shadow); transform: rotate(-1deg); }

/* The logo egg: anchored on the lens, above everything nearby. */
.df-snitch-egg { position: fixed; z-index: 9990; pointer-events: none; opacity: 0; transition: opacity .25s ease; }
.df-snitch-egg.is-on { opacity: 1; }
.df-snitch-egg .df-snitch-say { pointer-events: none; }
.hv2-logo { -webkit-touch-callout: none; }

/* Search: a digging Snitch beside "searching", then a hop, then gone. */
.sr2-snitch { display: flex; align-items: center; gap: 10px; margin: 6px 0 10px; color: var(--dfs-muted); font: 600 14px/1.3 Figtree, system-ui, sans-serif; opacity: 0; transition: opacity .3s ease; }
.sr2-snitch.is-on { opacity: 1; }

/* Homepage load more: Snitch digs in the spinner's place. */
.hv2-more__snitch { margin: -6px 0; }
/* Feed end: sleepy Snitch over "You've seen it all". */
.hv2-caughtup__snitch { display: flex; justify-content: center; margin-bottom: 6px; }
.hv2-caughtup__snitch .df-snitch-slot:not(.is-snitch) { display: none; }

/* Comments drawer empty state: he takes the speech-bubble icon's place. */
.dfc-state__icon.df-snitch-slot { display: flex; }
.dfc-state__icon.is-snitch { background: none !important; border: 0 !important; width: auto !important; height: auto !important; }

/* Aura: on the streak tile in the flame's place, and peeking from behind the coin. */
.aura2-streak-snitch { margin: -4px 2px -4px 0; vertical-align: -6px; }
/* The showcase: Snitch stands where the coin spins and the coins come out of
   him. The coin and its hint show only when he is off or yields. */
.aura2-coin-snitch { position: absolute; left: 50%; bottom: 22px; z-index: 1; transform: translateX(-50%); transform-origin: 50% 100%; pointer-events: auto; }
.aura2-coin-snitch.is-toss { animation: aura2-snitch-shake .32s ease-out; }
@keyframes aura2-snitch-shake { 0% { scale: 1 1; } 30% { scale: 1.08 .9; } 60% { scale: .95 1.07; } 100% { scale: 1 1; } }
.aura2-hint-snitch { display: none; }
#aura-spin-stage:has(.aura2-coin-snitch.is-snitch:not(.is-yield)) .aura2-spin-coinwrap { display: none !important; }
.aura2-showcase:has(.aura2-coin-snitch.is-snitch:not(.is-yield)) .aura2-hint-coin { display: none; }
.aura2-showcase:has(.aura2-coin-snitch.is-snitch:not(.is-yield)) .aura2-hint-snitch { display: inline; }
@media (prefers-reduced-motion: reduce) { .aura2-coin-snitch.is-toss { animation: none; } }
.sc-card__snitch { display: flex; align-items: center; gap: 6px; margin-bottom: 3px; font-weight: 700; font-size: 13px; }
.sc-card__snitch img { width: 22px; height: 25px; flex: none; }

/* Peeks: he slides out from behind an edge (a card's, the hero's), clipped to it. */
.df-snitch-peekbox { position: absolute; right: 0; z-index: 5; overflow: hidden; pointer-events: none; }
.df-snitch-peekbox > .df-snitch-slot { position: absolute; left: 0; top: 0; transform: translateX(100%); transition: transform .4s cubic-bezier(.3, 1.3, .5, 1); pointer-events: auto; }
.df-snitch-peekbox.is-out > .df-snitch-slot { transform: translateX(12%); transform-origin: 50% 100%; animation: df-peek-wobble .7s .38s ease-out; }
/* A little wobble as he lands: movement at the edge is what the eye catches. */
@keyframes df-peek-wobble { 0% { rotate: 0deg; } 35% { rotate: -9deg; } 65% { rotate: 4deg; } 100% { rotate: 0deg; } }

/* A live Snitch can be picked up and dragged. */
.df-snitch.is-live[role="button"] { cursor: grab; touch-action: manipulation; }
html.df-snitch-dragging, html.df-snitch-dragging * { cursor: grabbing !important; user-select: none !important; -webkit-user-select: none !important; }
.df-snitch-drag { position: fixed; left: 0; top: 0; z-index: 9995; pointer-events: none; will-change: transform; filter: drop-shadow(0 8px 10px rgba(0, 0, 0, .22)); }
.df-snitch-drag .df-snitch-slot { display: block; }
.df-snitch-drag.is-returning { transition: transform .45s cubic-bezier(.3, 1.25, .5, 1), opacity .4s ease; }
.df-snitch-drag.is-running { transition: transform .55s cubic-bezier(.5, 0, .7, .4), opacity .4s ease; }
.df-snitch-drag.is-instant { transition: none !important; }
.df-snitch-drag.is-flying { transition: transform .8s cubic-bezier(.2, .6, .4, 1), opacity .8s ease; opacity: 0; }
.df-snitch-drag.is-gone { opacity: 0; }
.df-snitch-drag.is-mirror .df-snitch { transform: scaleX(-1); }
.hv2-deal.is-sniff-target { outline: 2px dashed #FF8A3D; outline-offset: -3px; }
.df-snitch.is-wobble { animation: dfs-wobble .9s ease; }
@keyframes dfs-wobble { 0% { transform: translateY(40%) scale(.4); opacity: 0; } 45% { transform: translateY(-10%) scale(1.08); opacity: 1; } 65% { transform: rotate(-10deg); } 82% { transform: rotate(7deg); } 100% { transform: none; } }

/* A peeking Snitch's line, on the page (his box is clipped). */
.df-snitch-say.is-fixed { position: fixed; z-index: 9996; }
.df-snitch-say.is-fixed:not(.is-left) { right: auto; }
.df-snitch-say.is-fixed.is-left { left: auto; }

@media (prefers-reduced-motion: reduce) {
    .df-snitch, .df-snitch-say, .df-snitch-drop, .df-snitch-egg, .sr2-snitch, .df-snitch-peekbox > .df-snitch-slot, .df-snitch-drag { transition: none !important; animation: none !important; }
}

/* Each event's joke (version 2, 2026-10-10): layers drawn from season.gag. */
.df-snitch__body { position: absolute; inset: 0; }
.df-snitch__gag { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
/* The header logo's light trim during an event. */
.hv2-logo { position: relative; }
.df-logo-trim { position: absolute; left: 0; top: 50%; width: 40px; height: 40px; transform: translateY(-50%); pointer-events: none; }
.df-logo-trim__glow { position: absolute; inset: -6px; border-radius: 50%; background: radial-gradient(circle, var(--trim), transparent 68%); opacity: .35; z-index: -1; }
.df-logo-trim__accent { display: none; }
@keyframes df-trim-twinkle { from { opacity: 1; transform: scale(1); } to { opacity: .5; transform: scale(.85); } }
@media (prefers-reduced-motion: reduce) {
    .df-snitch__gag *, .df-snitch__body.is-gag, .df-logo-trim__accent { animation: none !important; }
}

/* Snitch is the search (2026-10-10): his magnifying glass, swept while he hunts. */
/* Held up to his eye: he peers through it, nudging it round the way you
   would scanning a shelf, and leans in now and then. */
.df-snitch__lens { transform-box: view-box; transform-origin: 160px 196px; animation: df-lens-peer 3.2s ease-in-out 3; }
/* He settles after three peers; while a search is being typed he peers again. */
.df-search-field:focus-within .df-snitch__lens, .df-ss .df-snitch__lens { animation: df-lens-peer 3.2s ease-in-out infinite; }
@keyframes df-lens-peer {
    0%, 100% { transform: translate(0, 0) rotate(0deg) scale(1); }
    25% { transform: translate(-4px, 1px) rotate(-5deg) scale(1); }
    50% { transform: translate(2px, -2px) rotate(3deg) scale(1.08); }
    60% { transform: translate(2px, -2px) rotate(3deg) scale(1.08); }
    80% { transform: translate(3px, 0) rotate(4deg) scale(1); }
}
@media (prefers-reduced-motion: reduce) { .df-snitch__lens { animation: none !important; } }

/* The header search button with Snitch in it (phones): a button like the
   account one beside it, Snitch inside. The icon stays as the fallback. */
.hv2-header__searchbtn .df-snitch-slot.is-snitch:not(.is-yield) > svg { display: none; }
.hv2-header__searchbtn .df-snitch-slot { display: inline-flex; align-items: flex-end; justify-content: center; }
.hv2-header .hv2-header__searchbtn.has-snitch { width: 46px; height: 46px; border-radius: 10px; background: rgba(255,255,255,.08); overflow: visible; }
.hv2-header .hv2-header__searchbtn.has-snitch:hover { background: rgba(255,255,255,.14); }

/* The search panel (header search overlay and dropdown). Neutral colours that
   read on the white dropdown and the dark overlay alike. */
.df-ss { display: flex; flex-direction: column; gap: 14px; padding: 16px 16px 8px; text-align: left; }
.df-ss__hero { display: flex; align-items: center; gap: 12px; }
.df-ss__hero .df-snitch-slot { flex: none; }
.df-ss__say { position: relative; margin: 0; padding: 7px 12px 8px; border-radius: 4px 14px 14px 14px; background: var(--dfs-stk-bg); color: var(--dfs-stk-text);
    border: 1.5px solid var(--dfs-stk-edge); box-shadow: 2px 2px 0 var(--dfs-stk-shadow); transform: rotate(-1deg);
    font: 800 15px/1.3 "Bricolage Grotesque", Figtree, system-ui, sans-serif; letter-spacing: -.01em; min-width: 0; }
.df-ss__say:empty { display: none; }
.df-ss__group { display: flex; flex-direction: column; gap: 8px; }
.df-ss__h { margin: 0; font-size: 11.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; opacity: .6; }
.df-ss__chips { display: flex; flex-wrap: wrap; gap: 6px; }
.df-ss__chip { display: inline-flex; align-items: center; gap: 6px; min-height: 36px; padding: 6px 12px; border-radius: 999px; border: 1px solid rgba(127,127,127,.28); background: transparent; color: inherit; font-size: 14px; font-weight: 600; cursor: pointer; text-decoration: none; }
.df-ss__chip:hover, .df-ss__chip:focus-visible { border-color: #FF6B2C; outline: none; }
.df-ss__chip--ask { background: rgba(255,107,44,.08); border-color: rgba(255,107,44,.35); }
.df-ss__now { display: flex; flex-direction: column; gap: 4px; margin: 0; padding: 0; list-style: none; font-size: 13.5px; opacity: .8; }
.df-ss__now li::before { content: "•"; margin-right: 8px; color: #FF6B2C; }
.df-ss__rule { height: 1px; margin: 4px 16px 0; background: rgba(127,127,127,.18); }

/* The results header on /search: Snitch, what was searched, his line. */
.sr2-head { display: flex; align-items: center; gap: 14px; margin-top: 24px; }
.sr2-head .sr2-title { margin: 0; }
.sr2-head__sn { flex: none; }
.sr2-head__text { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
/* His search narration is a sticker like every other line of his (owner picked "C", 2026-10-11). */
.sr2-head__say { margin: 0; align-self: flex-start; padding: 6px 12px 7px; border-radius: 4px 14px 14px 14px; background: var(--dfs-stk-bg); color: var(--dfs-stk-text);
    border: 1.5px solid var(--dfs-stk-edge); box-shadow: 2px 2px 0 var(--dfs-stk-shadow); transform: rotate(-1deg);
    font: 800 14.5px/1.35 "Bricolage Grotesque", Figtree, system-ui, sans-serif; letter-spacing: -.01em; }
@media (max-width: 639px) { .sr2-head { margin-top: 16px; gap: 10px; } .sr2-head .sr2-title { font-size: 22px; } }
.sr2-pick { margin: 6px 0 22px; }
.sr2-pick__label { margin: 0; font-size: 12px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: #c2410c; }
html.dark .sr2-pick__label { color: #fb923c; }
.sr2-pick .fy2-card__title a { color: inherit; }
.sr2-pick .fy2-feed.is-rows .fy2-card { border: 1px solid #FF6B2C; box-shadow: 0 0 0 1px #FF6B2C inset, var(--shadow, none); }
.sr2-watch { display: flex; flex-direction: column; align-items: center; gap: 8px; margin: 6px 0 4px; }
.sr2-watch button { min-height: 44px; }
/* In the homepage hero's bar he is a little bigger and sits a touch further in. */
.hv2-search .df-search-sn.is-snitch:not(.is-yield) { left: 12px; }
.hv2-search .df-search-field:has(.df-search-sn.is-snitch:not(.is-yield)) .df-search-input { padding-left: 62px; }
@media (max-width: 639px) { .hv2-search .df-search-sn.is-snitch:not(.is-yield) { left: 8px; } .hv2-search .df-search-field:has(.df-search-sn.is-snitch:not(.is-yield)) .df-search-input { padding-left: 54px; } }

/* The season's garland along the bottom of the header (seasonBand in
   snitch.js): hangs just below the header line, no space taken, nothing to
   press, sways twice then rests. */
.df-garland { position: absolute; left: 0; right: 0; top: 100%; height: 26px; pointer-events: none; z-index: 1; overflow: hidden; line-height: 0; }
.df-garland svg { display: block; overflow: visible; }
.df-garland__piece { transform-box: fill-box; transform-origin: 50% 0; animation: df-garland-sway 2.4s ease-in-out 2; }
@keyframes df-garland-sway { 0%, 100% { transform: rotate(0); } 30% { transform: rotate(5deg); } 70% { transform: rotate(-4deg); } }
@media (prefers-reduced-motion: reduce) { .df-garland__piece { animation: none; } }

/* The season's swing tag on the logo (trimLogo): hangs from the mark's
   bottom edge and rests entirely under the logo, never over it (owner, 2026-10-10), swings three times as the page opens, then rests; hover swings it. */
.df-logo-tag { position: absolute; left: 14px; top: 41px; width: auto; height: auto; transform: rotate(-3deg); transform-origin: 4px 0;
    pointer-events: none; z-index: 2; animation: df-tag-swing 2s ease-in-out 3; }
.hv2-logo:hover .df-logo-tag { animation: df-tag-swing 1.6s ease-in-out 1; }
.df-logo-tag::before { content: ""; position: absolute; left: 3px; top: -6px; width: 1.5px; height: 10px; background: rgba(232,220,192,.85); }
.df-logo-tag__label { display: flex; align-items: center; gap: 4px; margin-top: 4px; background: var(--tag-bg); color: var(--tag-fg); font: 800 9px/1 Figtree, system-ui, sans-serif;
    letter-spacing: .06em; padding: 4px 6px 4px 9px; border-radius: 2px 4px 4px 2px; white-space: nowrap;
    clip-path: polygon(6px 0, 100% 0, 100% 100%, 6px 100%, 0 50%); box-shadow: 0 2px 6px rgba(0,0,0,.35); }
@keyframes df-tag-swing { 0%, 100% { transform: rotate(-3deg); } 30% { transform: rotate(-7deg); } 70% { transform: rotate(3deg); } }
@media (max-width: 767px) { .df-logo-tag { left: 11px; top: 33px; } .df-logo-tag__label { font-size: 8px; padding: 3px 5px 3px 8px; } }
@media (prefers-reduced-motion: reduce) { .df-logo-tag, .hv2-logo:hover .df-logo-tag { animation: none; } }
.df-logo-tag__label svg { width: 12px; height: 12px; flex: none;
    /* A thin outline in the tag's text colour, so a piece the same colour as
       its tag (an orange pumpkin on an orange tag) still reads. */
    filter: drop-shadow(0 0 .5px var(--tag-fg)) drop-shadow(0 0 .5px var(--tag-fg)); }
@media (max-width: 767px) { .df-logo-tag__label svg { width: 10px; height: 10px; } }

/* The companion (2026-10-11): he lives in a bottom corner of every page when
   no other Snitch is on screen, travels to wherever he is needed, and keeps
   out of the way (lifted above bottom bars, tucked away under dialogs). */
.df-companion { position: fixed; right: 14px; bottom: calc(14px + var(--df-companion-lift, 0px) + env(safe-area-inset-bottom, 0px)); z-index: 900;
    transform: translateY(140%) scale(.6); opacity: 0; transition: transform .45s cubic-bezier(.3, 1.35, .5, 1), opacity .3s ease, bottom .3s ease; filter: drop-shadow(0 6px 10px rgba(0, 0, 0, .25)); }
.df-companion.is-left { right: auto; left: 14px; }
.df-companion.is-on { transform: none; opacity: 1; }
.df-companion.is-tucked, .df-companion.is-leaving { transform: translateY(140%) scale(.6); opacity: 0; pointer-events: none; }
.df-companion__slot { display: block; }
.df-companion__slot.is-yield { pointer-events: none; }
.df-companion .df-snitch { cursor: pointer; }
@media (hover: hover) and (pointer: fine) { .df-companion .df-snitch:hover { transform: translateY(-3px) rotate(-4deg); transition: transform .2s ease; } }
.df-companion-bubble { position: absolute; right: 4px; bottom: calc(100% + 6px); width: max-content; max-width: min(240px, calc(100vw - 40px)); padding: 5px 12px 6px;
    border-radius: 16px 16px 4px 16px; background: var(--dfs-stk-bg); color: var(--dfs-stk-text); border: 1.5px solid var(--dfs-stk-edge); box-shadow: 2px 3px 0 var(--dfs-stk-shadow);
    font: 800 14.5px/1.25 "Bricolage Grotesque", Figtree, system-ui, sans-serif; letter-spacing: -.01em;
    opacity: 0; transform: translateY(6px) rotate(-1.5deg) scale(.96); transform-origin: 90% 100%; transition: opacity .2s ease, transform .2s ease; }
.df-companion-bubble.is-left { right: auto; left: 4px; border-radius: 16px 16px 16px 4px; transform-origin: 10% 100%; }
.df-companion-bubble.is-on { opacity: 1; transform: rotate(-1.5deg); }
.df-companion-bubble.is-left.is-on { transform: rotate(1.5deg); }
.df-companion-bubble p { margin: 0; }

/* The useful panel a tap opens (owner: "make him genuinely useful"): ask him
   anything, then only what is true right now, each row a link. */
.df-companion-panel { position: absolute; right: 0; bottom: calc(100% + 8px); width: min(300px, calc(100vw - 28px)); box-sizing: border-box;
    display: flex; flex-direction: column; gap: 4px; padding: 12px; border-radius: 18px;
    background: var(--dfs-pan-bg); color: var(--dfs-pan-text); border: 1px solid var(--dfs-pan-edge); box-shadow: 0 14px 34px rgba(20, 16, 10, .18);
    font: 600 13.5px/1.35 Figtree, system-ui, sans-serif;
    opacity: 0; transform: translateY(8px) scale(.97); transform-origin: 92% 100%; transition: opacity .2s ease, transform .2s ease; }
.df-companion.is-left .df-companion-panel { right: auto; left: 0; transform-origin: 8% 100%; }
.df-companion-panel.is-on { opacity: 1; transform: none; }
.df-companion-panel__say { align-self: flex-start; margin: -26px 0 6px -4px; padding: 4px 11px 5px; max-width: 100%; border-radius: 14px 14px 14px 4px;
    background: var(--dfs-stk-bg); color: var(--dfs-stk-text); border: 1.5px solid var(--dfs-stk-edge); box-shadow: 2px 2px 0 var(--dfs-stk-shadow);
    font: 800 14.5px/1.25 "Bricolage Grotesque", Figtree, system-ui, sans-serif; letter-spacing: -.01em; transform: rotate(-1.5deg); }
.df-companion-panel__ask { display: flex; gap: 6px; margin: 0 0 4px; padding: 4px; border: 1px solid var(--dfs-pan-edge); background: var(--dfs-pan-sunk); border-radius: 12px; }
.df-companion-panel__ask input { flex: 1; min-width: 0; border: 0; background: transparent; color: inherit; font: 600 16px Figtree, system-ui, sans-serif; padding: 6px 8px; outline: none; }
.df-companion-panel__ask input::placeholder { color: var(--dfs-pan-muted); font-weight: 500; }
.df-companion-panel__ask button { border: 0; border-radius: 9px; padding: 0 14px; background: #E8650A; color: #fff; font: 700 13.5px Figtree, system-ui, sans-serif; cursor: pointer; min-height: 36px; }
.df-companion-panel__ask:focus-within { border-color: var(--dfs-stk-edge); }
.df-companion-panel__row { display: grid; grid-template-columns: 62px minmax(0, 1fr) auto; align-items: center; gap: 8px; padding: 8px 6px; border-radius: 10px; color: inherit; text-decoration: none; min-height: 40px; box-sizing: border-box; }
.df-companion-panel__row:hover, .df-companion-panel__row:focus-visible { background: var(--dfs-pan-sunk); outline: none; }
.df-companion-panel__k { font-size: 10.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--dfs-pan-muted); line-height: 1.15; }
.df-companion-panel__row.is-hot .df-companion-panel__k { color: var(--dfs-pan-hot); }
.df-companion-panel__t { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.df-companion-panel__m { color: var(--dfs-pan-muted); font-size: 12px; font-variant-numeric: tabular-nums; }
.df-companion-panel__foot { display: flex; justify-content: space-between; align-items: center; margin-top: 4px; padding-top: 8px; border-top: 1px solid var(--dfs-pan-edge); }
.df-companion-panel__foot a, .df-companion-panel__foot button { font: 700 13px Figtree, system-ui, sans-serif; color: var(--dfs-stk-link); text-decoration: none; background: none; border: 0; cursor: pointer; padding: 6px 2px; }
.df-companion-panel__foot button { color: var(--dfs-pan-muted); }
.df-companion-panel__note { display: block; margin: 6px 6px 0; font: 600 12px Figtree, system-ui, sans-serif; color: var(--dfs-pan-muted); text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.df-companion-panel__note:hover, .df-companion-panel__note:focus-visible { color: inherit; outline: none; text-decoration: underline; }
/* One sticker at a time: the tag steps aside while his sticker or panel is up. */
.df-companion-tag[hidden] { display: none !important; }
.df-companion-panel__wait { height: 36px; border-radius: 10px; background: var(--dfs-pan-sunk); opacity: .7; }
/* His flight between spots (one Snitch, moving). */
.df-snitch-travel { position: fixed; z-index: 2147483002; pointer-events: none; transform-origin: 50% 50%; filter: drop-shadow(0 10px 14px rgba(0, 0, 0, .3)); }
@media (prefers-reduced-motion: reduce) { .df-companion { transition: opacity .2s ease; transform: none; } .df-companion.is-tucked, .df-companion.is-leaving { transform: none; } }
@media print { .df-companion { display: none; } }

/* The play page (the Aura coin sheet with Snitch on): his line under him,
   what he remembers, and sulking. Nothing to press: stroke, doze and shades
   happen from how he is treated (aura.blade.php). */
.aura2-coin-snitch.is-sulk { transition: transform .5s cubic-bezier(.5, 0, .7, .4), opacity .4s ease; transform: translateX(-50%) translateY(70%) scale(.5) !important; opacity: 0; }
.aura2-play__say { margin: 0; height: 0; overflow: visible; position: relative; z-index: 2; text-align: center; font-weight: 700; font-size: 15px; color: var(--text); opacity: 0; transform: translateY(4px); transition: opacity .2s ease, transform .2s ease; pointer-events: none; }
.aura2-play__say.is-on { opacity: 1; transform: none; }
.aura2-showcase:has(.aura2-play__say.is-on) .aura2-showcase__hint { visibility: hidden; }
.aura2-play__mem { margin: 0 0 14px; font-size: 12.5px; color: var(--text-muted); line-height: 1.4; }
@media (prefers-reduced-motion: reduce) { .aura2-coin-snitch.is-sulk { transition: opacity .2s ease; } }
/* Something tappable under him: he slides mostly off the edge and peeks. */
.df-companion.is-edge.is-on { transform: translateX(68%) rotate(-10deg); }
.df-companion.is-left.is-edge.is-on { transform: translateX(-68%) rotate(10deg); }
.df-companion.is-edge.is-on:hover, .df-companion.is-edge.is-on:focus-within { transform: none; }
.df-companion .df-snitch:focus-visible { outline: 2px solid var(--dfs-stk-edge); outline-offset: 3px; border-radius: 45%; }
.df-companion-panel__row.is-hot .df-companion-panel__m { color: var(--dfs-pan-text); font-weight: 800; }

/* What's waiting (2026-10-11): one sticker tag beside him, or a number on him. */
.df-companion-tag { position: absolute; right: 2px; bottom: calc(100% + 6px); white-space: nowrap; cursor: pointer;
    padding: 4px 10px 5px; border-radius: 14px 14px 4px 14px; background: var(--dfs-stk-bg); color: var(--dfs-stk-text);
    border: 1.5px solid var(--dfs-stk-edge); box-shadow: 2px 2px 0 var(--dfs-stk-shadow);
    font: 800 13px/1.2 "Bricolage Grotesque", Figtree, system-ui, sans-serif; letter-spacing: -.01em;
    opacity: 0; transform: translateY(6px) rotate(-2deg) scale(.95); transform-origin: 90% 100%; transition: opacity .25s ease, transform .3s cubic-bezier(.3, 1.4, .5, 1); }
.df-companion-tag.is-on { opacity: 1; transform: rotate(-2deg); }
.df-companion-tag:hover { transform: rotate(-2deg) translateY(-1px); }
.df-companion-tag:focus-visible { outline: 2px solid var(--dfs-stk-edge); outline-offset: 2px; }
.df-companion.is-left .df-companion-tag { right: auto; left: 2px; border-radius: 14px 14px 14px 4px; transform: translateY(6px) rotate(2deg) scale(.95); transform-origin: 10% 100%; }
.df-companion.is-left .df-companion-tag.is-on { transform: rotate(2deg); }
.df-companion-count { position: absolute; top: -4px; right: -4px; min-width: 20px; height: 20px; padding: 0 5px; box-sizing: border-box; border-radius: 10px;
    background: #E8650A; color: #fff; font: 800 11.5px/20px Figtree, system-ui, sans-serif; text-align: center; border: 2px solid var(--dfs-pan-bg);
    opacity: 0; transform: scale(.6); transition: opacity .2s ease, transform .25s cubic-bezier(.3, 1.5, .5, 1); pointer-events: none; z-index: 2; }
.df-companion.is-left .df-companion-count { right: auto; left: -4px; }
.df-companion-count.is-on { opacity: 1; transform: none; }
.df-companion:has(.df-companion__slot.is-yield) .df-companion-tag, .df-companion:has(.df-companion__slot.is-yield) .df-companion-count,
.df-companion.is-edge .df-companion-tag, .df-companion.is-edge .df-companion-count { display: none; }
@media (max-width: 380px) { .df-companion-tag { font-size: 12px; padding: 3px 8px 4px; } }
@media (prefers-reduced-motion: reduce) { .df-companion-tag, .df-companion-count { transition: opacity .2s ease; } }
