/* Crushie — dock, hint, sheet */

/* ---------- dock ---------- */
.cr-dock { position: fixed; right: 20px; bottom: 20px; z-index: 80; display: flex; align-items: flex-end; gap: 10px; transition: right var(--med) var(--ease), opacity var(--med); }
body.cr-open .cr-dock { opacity: 0; pointer-events: none; }
.cr-owl {
  position: relative; width: 60px; height: 60px; border-radius: 50%; flex: none;
  background: radial-gradient(circle at 50% 30%, var(--plate-hi), var(--hull) 70%);
  box-shadow: 0 0 0 1px var(--line-hi), 0 10px 30px -8px rgb(0 0 0 / .7);
  transition: transform var(--med) var(--ease), box-shadow var(--med) var(--ease);
}
.cr-owl:hover { transform: translateY(-2px) scale(1.04); box-shadow: 0 0 0 1px var(--teal-glow), 0 0 26px var(--teal-glow-a), 0 10px 30px -8px rgb(0 0 0 / .7); }
/* The owl is drawn much larger than the plate: feet stand inside the circle, head and headphones break out over its top edge.
   It's a stack of alpha clips (scripts/owl.js, assets/crush-brand/anim/), 320×368 frames shown at 118×136: the rest-pose
   owl is ~95px tall, centred, with its feet ~4 frame px (1.6 CSS px) above the frame bottom, so bottom:-1px puts them
   ~1px above the plate's bottom edge. Layers, outside in: .cr-owl__fig carries the hover tilt, press squash and hop
   (individual translate/scale props, so they compose with the hover transform); inside it the poster still, one
   <video> per clip, and the blink lids. */
.cr-owl__fig {
  position: absolute; left: 50%; bottom: -1px; width: 118px; height: 136px; margin-left: -59px;
  transform-origin: 50% 100%; pointer-events: none; z-index: 1;
  filter: drop-shadow(0 6px 10px color-mix(in oklch, var(--ink) 80%, transparent));
  transition: transform var(--med) var(--ease), scale 90ms var(--ease);
}
.cr-owl:hover .cr-owl__fig { transform: translateY(-3px) rotate(-3deg); }
.cr-owl:active .cr-owl__fig { scale: 1.05 .94; }
.cr-owl__still, .cr-owl__clip, .cr-owl__blink { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.cr-owl__fig.is-live .cr-owl__still { visibility: hidden; }
.cr-owl__clip { opacity: 0; transition: opacity 120ms linear; }
.cr-owl__clip.is-on { opacity: 1; }
.cr-owl__blink { opacity: 0; }
.cr-owl__blink.is-on { opacity: 1; }
/* Contact shadow on the plate under the feet. It shrinks and fades whenever the owl leaves the ground. */
.cr-owl__shadow {
  position: absolute; left: 50%; bottom: 3px; width: 46px; height: 9px; margin-left: -23px; border-radius: 50%;
  background: radial-gradient(closest-side, color-mix(in oklch, var(--ink) 75%, transparent), transparent);
  pointer-events: none;
}
/* attention hop: two quick soft jumps, every ~20s (scripts/crushie.js director). */
.cr-owl.is-hopping .cr-owl__fig { animation: crHop .95s var(--ease) both; }
.cr-owl.is-hopping .cr-owl__shadow { animation: crHopShadow .95s var(--ease) both; }
@keyframes crHop {
  0%   { translate: 0 0;     scale: 1; }
  8%   { translate: 0 0;     scale: 1.06 .93; }
  22%  { translate: 0 -12px; scale: .96 1.05; }
  36%  { translate: 0 0;     scale: 1.05 .94; }
  44%  { translate: 0 0;     scale: 1; }
  56%  { translate: 0 -8px;  scale: .97 1.03; }
  70%  { translate: 0 0;     scale: 1.03 .96; }
  80%, 100% { translate: 0 0; scale: 1; }
}
@keyframes crHopShadow {
  0%   { scale: 1;      opacity: 1; }
  8%   { scale: 1.08 1; opacity: 1; }
  22%  { scale: .72;    opacity: .45; }
  36%  { scale: 1.1 1;  opacity: 1; }
  44%  { scale: 1;      opacity: 1; }
  56%  { scale: .8;     opacity: .6; }
  70%  { scale: 1.06 1; opacity: 1; }
  80%, 100% { scale: 1; opacity: 1; }
}
/* The celebrate clip's own hop, measured from its alpha (95 frames, 3.96s): crouch frames 6–10, airborne 12–24
   (peak 17, ~40 CSS px up), landing 25–29. The shadow follows it frame for frame. */
.cr-owl:has(.cr-owl__fig[data-mood="celebrate"]) .cr-owl__shadow { animation: crCelebrateShadow 3.96s linear both; }
@keyframes crCelebrateShadow {
  0%, 6%  { scale: 1;      opacity: 1; }
  10.5%   { scale: 1.1 1;  opacity: 1; }
  12.6%   { scale: .9;     opacity: .8; }
  17.9%   { scale: .55;    opacity: .3; }
  23%     { scale: .75;    opacity: .55; }
  25.3%   { scale: 1.12 1; opacity: 1; }
  30%, 100% { scale: 1;    opacity: 1; }
}
.cr-owl__ring { position: absolute; inset: -4px; border-radius: 50%; border: 1px solid color-mix(in oklch, var(--teal-glow) 35%, transparent); animation: crPulse 4.8s var(--ease) infinite; }
.cr-dock.is-quiet .cr-owl__ring { animation: none; opacity: 0; }
@keyframes crPulse { 0%, 70%, 100% { transform: scale(1); opacity: .0; } 80% { opacity: .9; } 95% { transform: scale(1.25); opacity: 0; } }
.cr-owl__dot { position: absolute; right: -1px; bottom: 6px; z-index: 2; width: 10px; height: 10px; border-radius: 50%; background: var(--teal-glow); box-shadow: 0 0 0 2px var(--ink); }
.cr-dock.is-quiet .cr-owl__dot { background: var(--mist); }

.cr-hint {
  display: flex; align-items: center; gap: 2px; max-width: 290px; margin-bottom: 8px;
  padding: 4px 4px 4px 14px; border-radius: 14px 14px 4px 14px;
  background: color-mix(in oklch, var(--plate) 96%, transparent); border: 1px solid var(--line-hi); backdrop-filter: blur(10px);
  box-shadow: 0 14px 40px -14px #000;
  opacity: 0; transform: translateY(6px); transition: opacity var(--med) var(--ease), transform var(--med) var(--ease);
}
.cr-hint.is-on { opacity: 1; transform: none; }
.cr-hint__text { text-align: left; font-size: .8125rem; line-height: 1.4; color: var(--paper); padding: 6px 0; }
.cr-hint__text:hover { color: var(--teal-glow); }
.cr-hint__x { width: 28px; height: 28px; display: grid; place-items: center; border-radius: 50%; color: var(--mist); flex: none; }
.cr-hint__x:hover { color: var(--paper); background: rgb(255 255 255 / .06); }
.cr-hint__x svg { width: 14px; height: 14px; }

/* ---------- sheet ---------- */
.cr-sheet {
  position: fixed; z-index: 90; top: 0; right: 0; bottom: 0; width: var(--sheet-w); max-width: 100vw;
  display: flex; flex-direction: column;   /* the log takes the spare height (a fixed grid broke when the theme panel is hidden) */
  background: linear-gradient(180deg, color-mix(in oklch, var(--hull) 98%, transparent), color-mix(in oklch, var(--ink) 98%, transparent));
  border-left: 1px solid var(--line-hi);
  box-shadow: -30px 0 80px -30px rgb(0 0 0 / .9);
  transform: translateX(102%); visibility: hidden;
  transition: transform var(--med) var(--ease), visibility 0s linear var(--med);
}
.cr-sheet::before { content: ""; position: absolute; inset: 0 0 auto; height: 220px; pointer-events: none; background: radial-gradient(90% 100% at 80% 0%, color-mix(in oklch, var(--teal) 25%, transparent), transparent 70%); }
.cr-sheet.is-open { transform: none; visibility: visible; transition: transform var(--med) var(--ease); }
body.cr-push .page { margin-right: var(--sheet-w); }
body.cr-push .hdr { /* sticky header follows page width automatically */ }

.cr-head { position: relative; display: flex; align-items: center; gap: 12px; padding: 16px 16px 12px 18px; }
.cr-head__id { flex: 1; min-width: 0; margin: 0; font-family: var(--f-display); font-size: 1.125rem; font-weight: 800; line-height: 1.25; letter-spacing: .02em; font-variation-settings: "wdth" 115; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cr-iconbtn { width: 36px; height: 36px; display: grid; place-items: center; border-radius: 50%; color: var(--fog); border: 1px solid transparent; transition: background var(--fast), color var(--fast), border-color var(--fast); }
.cr-iconbtn:hover { background: rgb(255 255 255 / .05); color: var(--paper); }
.cr-iconbtn svg { width: 18px; height: 18px; }
.cr-quiet[aria-pressed="true"] { color: var(--sodium); border-color: rgb(217 150 58 / .4); background: var(--sodium-a); }
.cr-palette[aria-expanded="true"] { color: var(--teal-glow); border-color: var(--line-hi); background: color-mix(in oklch, var(--teal) 14%, transparent); }

/* live theme panel: preset (vivid / muted), hue and saturation. Tracks are painted by scripts/theme.js */
.cr-theme { position: relative; display: grid; gap: 8px; margin: 0 18px 10px; padding: 10px 12px 8px; border-radius: 10px; background: color-mix(in oklch, var(--ink) 50%, transparent); border: 1px solid var(--line); }
.cr-theme[hidden] { display: none; }
.cr-theme__top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.cr-theme__mode { display: inline-flex; padding: 2px; border-radius: var(--r-pill); border: 1px solid var(--line); background: color-mix(in oklch, var(--hull) 80%, transparent); }
.cr-theme__mode button, .cr-theme__reset { height: 24px; padding: 0 10px; border-radius: var(--r-pill); font-family: var(--f-mono); font-size: .5625rem; letter-spacing: .12em; text-transform: uppercase; color: var(--fog); transition: border-color var(--fast), color var(--fast), background var(--fast); }
.cr-theme__mode button:hover { color: var(--paper); }
.cr-theme__mode button[aria-pressed="true"] { color: var(--paper); background: color-mix(in oklch, var(--teal) 30%, transparent); box-shadow: inset 0 0 0 1px var(--teal); }
.cr-theme__reset { border: 1px solid var(--line-hi); }
.cr-theme__reset:hover { border-color: var(--teal-glow); color: var(--paper); }
.cr-theme__row { display: grid; grid-template-columns: 30px 1fr 38px; align-items: center; gap: 8px; }
.cr-theme__row > span, .cr-theme__val { font-family: var(--f-mono); font-size: .5625rem; letter-spacing: .1em; text-transform: uppercase; color: var(--mist); }
.cr-theme__val { text-align: right; color: var(--fog); font-variant-numeric: tabular-nums; }
.cr-theme input { --track: linear-gradient(90deg, var(--teal-burnt), var(--teal-glow)); width: 100%; min-width: 0; height: 22px; margin: 0; background: transparent; -webkit-appearance: none; appearance: none; cursor: pointer; }
.cr-theme input::-webkit-slider-runnable-track { height: 8px; border-radius: 4px; background: var(--track); }
.cr-theme input::-moz-range-track { height: 8px; border-radius: 4px; background: var(--track); }
.cr-theme input::-webkit-slider-thumb { -webkit-appearance: none; width: 18px; height: 18px; margin-top: -5px; border-radius: 50%; background: var(--teal); border: 2px solid var(--paper); box-shadow: 0 0 0 1px var(--ink), 0 0 12px var(--teal-glow-a); }
.cr-theme input::-moz-range-thumb { width: 14px; height: 14px; border-radius: 50%; background: var(--teal); border: 2px solid var(--paper); box-shadow: 0 0 0 1px var(--ink), 0 0 12px var(--teal-glow-a); }
.cr-theme input:focus-visible { outline: none; }
.cr-theme input:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 1px var(--ink), 0 0 0 4px var(--teal-glow-a); }
.cr-theme input:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 1px var(--ink), 0 0 0 4px var(--teal-glow-a); }

.cr-ctx { position: relative; margin: 0 18px 4px; display: flex; gap: 6px; align-items: center; padding: 8px 12px; border-radius: 8px; background: color-mix(in oklch, var(--ink) 50%, transparent); border: 1px dashed var(--line-hi); font-size: .8125rem; min-width: 0; }
.cr-ctx span { font-family: var(--f-mono); font-size: .5625rem; letter-spacing: .12em; text-transform: uppercase; color: var(--teal-glow); flex: none; }
.cr-ctx b { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* The log runs top to bottom, down to the message box; Crushie stands in front of its bottom-right corner. The 104px
   bottom padding is scroll room only, so the newest message and its pills can always scroll up clear of him. */
.cr-log { flex: 1; min-height: 0; overflow-y: auto; padding: 16px 18px 104px; display: flex; flex-direction: column; gap: 14px; scrollbar-width: thin; scrollbar-color: var(--line) transparent; }
.cr-msg { display: flex; gap: 10px; align-items: flex-start; max-width: 100%; animation: crIn var(--med) var(--ease) both; }
@keyframes crIn { from { opacity: 0; transform: translateY(6px); } }
.cr-msg__av { width: 28px; height: 28px; border-radius: 50%; object-fit: cover; object-position: 30% 40%; flex: none; background: var(--plate-hi); }
.cr-msg__b > * + * { margin-top: 8px; }
.cr-msg__b { display: block; font-family: var(--f-read); font-weight: 400; font-size: .8438rem; line-height: 1.6; color: var(--paper); min-width: 0; }
/* Crushie's replies: paper at 78% so long text isn't glaring white; bold words and card titles stay full paper as the emphasis. */
.cr-msg--bot .cr-msg__b { padding: 2px 0; color: color-mix(in oklch, var(--paper) 78%, transparent); }
.cr-msg--bot .cr-msg__b b { color: var(--paper); }
.cr-msg--me { justify-content: flex-end; }
.cr-msg--me .cr-msg__b { padding: 9px 14px; border-radius: 14px 14px 4px 14px; background: linear-gradient(180deg, var(--teal), var(--teal-burnt)); color: var(--on-teal); max-width: 82%; }
.cr-msg__b b { font-weight: 600; }
.cr-src { font-family: var(--f-mono); font-size: .625rem; letter-spacing: .04em; color: var(--mist); }
.cr-src a { color: var(--fog); text-decoration: underline; text-decoration-color: var(--line-hi); text-underline-offset: 2px; }
.cr-note { font-size: .8125rem; color: var(--fog); }

.cr-cards { display: grid; gap: 6px; }
.cr-card { display: grid; grid-template-columns: 88px 1fr; gap: 10px; align-items: center; padding: 6px; border-radius: 8px; background: color-mix(in oklch, var(--ink) 45%, transparent); border: 1px solid var(--line); transition: border-color var(--fast), background var(--fast); }
.cr-card:hover { border-color: var(--teal); background: color-mix(in oklch, var(--plate) 60%, transparent); }
.cr-card__img .media { border-radius: 5px; }
.cr-card__img .media--ph .ph__glyph { width: 40%; right: 30%; top: 18%; }
.cr-card__txt { display: grid; gap: 1px; min-width: 0; }
.cr-card__txt b { font-size: .8125rem; line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cr-card__txt span { font-family: var(--f-mono); font-size: .5938rem; letter-spacing: .04em; color: var(--mist); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cr-card__txt span:nth-child(2) { color: var(--teal-glow); }

.cr-typing { display: inline-flex; gap: 4px; padding: 10px 0; }
.cr-typing i { width: 6px; height: 6px; border-radius: 50%; background: var(--teal-glow); opacity: .4; animation: crDot 1s infinite; }
.cr-typing i:nth-child(2) { animation-delay: .15s; } .cr-typing i:nth-child(3) { animation-delay: .3s; }
@keyframes crDot { 50% { opacity: 1; transform: translateY(-3px); } }

/* Suggested replies live in the chat, under Crushie's latest message (scripts/crushie.js suggest()): a bento of pills,
   each as wide as its text, then growing in proportion to its text length (flex-grow is set per pill) to fill the row,
   so rows end flush and every pill keeps a width that matches its label. Indented to line up with
   his text (28px avatar + 10px gap). A fresh set comes with every reply; sending anything clears it. */
.cr-sugg { display: flex; flex-wrap: wrap; gap: 6px; margin: -4px 0 0 38px; }
.cr-pill {
  flex: 1 1 auto; height: 34px; padding: 0 14px; border-radius: var(--r-pill); white-space: nowrap;
  border: 1px solid var(--line-hi); background: color-mix(in oklch, var(--ink) 40%, transparent);
  font-size: .78rem; color: var(--fog);
  animation: crIn var(--med) var(--ease) both; animation-delay: calc(var(--i, 0) * 50ms + 120ms);
  transition: border-color var(--fast), color var(--fast), background var(--fast);
}
.cr-pill:hover { border-color: var(--teal-glow); color: var(--paper); background: color-mix(in oklch, var(--teal) 12%, transparent); }


.cr-input { position: relative; display: flex; align-items: center; gap: 8px; margin: 0 18px; padding: 6px 6px 6px 16px; border-radius: var(--r-pill); border: 1px solid var(--line-hi); background: color-mix(in oklch, var(--ink) 70%, transparent); transition: border-color var(--fast), box-shadow var(--fast); }
.cr-input:focus-within { border-color: var(--teal-glow); box-shadow: 0 0 0 4px color-mix(in oklch, var(--teal-glow) 12%, transparent); }
.cr-input input { flex: 1; min-width: 0; height: 32px; background: none; border: 0; outline: 0; color: var(--paper); font: inherit; font-family: var(--f-read); font-size: .9rem; }
.cr-input input::placeholder { color: var(--mist); }
.cr-send { width: 36px; height: 36px; border-radius: 50%; display: grid; place-items: center; background: var(--teal); color: var(--on-teal); flex: none; transition: background var(--fast); }
.cr-send:hover { background: var(--teal-glow); color: var(--ink); }
.cr-send svg { width: 16px; height: 16px; }
/* Crushie stands on the message box while the chat is open: scripts/crushie.js perchOwl() moves the dock's figure and
   contact shadow in here (same player, same videos). His feet sit on the box's top edge, above the send button; the
   log scrolls behind him, with bottom padding so its newest content can clear him. */
.cr-perch { position: absolute; right: 12px; bottom: calc(100% - 2px); width: 118px; height: 136px; pointer-events: none; z-index: 2; }
.cr-perch .cr-owl__shadow { bottom: -4px; }
.cr-perch:has(.cr-owl__fig[data-mood="celebrate"]) .cr-owl__shadow { animation: crCelebrateShadow 3.96s linear both; }
.cr-fine { padding: 8px 18px 14px; font-size: .6875rem; color: var(--mist); text-align: center; }

/* small screens: bottom sheet over content */
@media (max-width: 1199px) {
  .cr-sheet { box-shadow: -30px 0 80px -10px rgb(0 0 0 / .9); }
  body.cr-open::after { content: ""; position: fixed; inset: 0; z-index: 85; background: color-mix(in oklch, var(--ink) 55%, transparent); backdrop-filter: blur(2px); }
}
@media (max-width: 640px) {
  .cr-dock { right: 14px; bottom: 14px; }
  .cr-hint { max-width: calc(100vw - 100px); }
  .cr-sheet { top: auto; left: 0; width: 100vw; height: 86vh; border-left: 0; border-top: 1px solid var(--line-hi); border-radius: 18px 18px 0 0; transform: translateY(102%); }
  .cr-sheet.is-open { transform: none; }
  .cr-head::before { content: ""; position: absolute; top: 6px; left: 50%; width: 36px; height: 4px; margin-left: -18px; border-radius: 2px; background: var(--line-hi); }
}
