/* Who's Inside the Costume? / Kostümün İçinde Kim Var? (Memory & Focus Games, D-214)
   Engine prefix kfcp-. Nova's spec (concepts/costume-parade/04-nova-spec.md)
   is the source of every number here; Elias C1-C44 of every rule marked
   with a C. One grid row per child, air on every edge, nothing that loops
   or flashes, the board ends above the fold and never scrolls. The sizes the
   solve computes arrive as custom properties on the stage:
     --kfcp-scene-w, --kfcp-scene-h   the parade
     --kfcp-p                         a portrait's picture side
     --kfcp-namew                     the name beside a horizontal card
     --kfcp-gap                       between the cards
     --kfcp-right                     the split board's right column */

.kf-costume-parade { display: block; }
.kf-costume-parade:not(.kfcp-ready) { min-height: 60vh; }

.kfcp-stage {
  position: relative;
  max-width: 100%;
  margin: 0 auto;
  box-sizing: border-box;
  background: var(--kf-lilac-soft);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-soft);
  padding: 24px;
  display: grid;
  /* title, Barnaby's line, the bar, the parade + portraits: implicit rows
     only, so a title kept for screen readers leaves no empty track and no
     extra 8 px gap behind (measured: 660 px in a 652 px box) */
  row-gap: 8px;
  overflow: hidden;
}
.kfcp-stage--phone { padding: 10px 10px 14px; }
.kfcp-fslead { height: 0; }
[data-kf-fs].kf-costume-parade.kf-fs-on[data-kf-fs-wide] > .kfcp-fslead,
[data-kf-fs].kf-costume-parade.kf-fs-fake[data-kf-fs-wide] > .kfcp-fslead { padding-top: 0 !important; }
[data-kf-fs].kf-costume-parade.kf-fs-on[data-kf-fs-wide],
[data-kf-fs].kf-costume-parade.kf-fs-fake[data-kf-fs-wide] { display: flex; flex-direction: column; justify-content: center; }
[data-kf-fs].kf-costume-parade.kf-fs-on[data-kf-fs-wide] > .kfcp-stage,
[data-kf-fs].kf-costume-parade.kf-fs-fake[data-kf-fs-wide] > .kfcp-stage { flex: 0 1 auto; }

.kfcp-title {
  margin: 0;
  text-align: center;
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 1.9rem;
  line-height: 1.2;
  color: var(--kf-purple-deep);
}
.kfcp-stage--phone .kfcp-title { font-size: 1.15rem; }
/* a short board keeps the title for screen readers only (Nova 2.2) */
.kfcp-stage--notitle .kfcp-title,
.kfcp-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------- the head row: Barnaby | Listen | his line (Nova 2.4) ---------- */
.kfcp-head {
  display: flex;
  align-items: center;
  gap: 12px;
  height: 80px;
  min-width: 0;
}
.kfcp-stage--phone .kfcp-head { height: 73px; gap: 8px; }
/* small and still (Elias C44): a speaker, not a second picture */
.kfcp-host {
  position: relative;
  flex: none;
  width: 60px;
  height: 80px;
  align-self: flex-end;
  overflow: hidden;
  pointer-events: none;
  user-select: none;
}
.kfcp-host img { position: absolute; left: 0; top: 0; width: 100%; height: 100%; object-fit: contain; object-position: center bottom; display: block; }
/* phone: a round avatar cropped on his face (the engine sizes the picture) */
.kfcp-stage--phone .kfcp-host {
  align-self: flex-start;
  border-radius: 50%;
  background: #fff6e8;
  box-shadow: 0 0 0 2px var(--kf-lilac);
}
/* the site's img { max-width: 100% } would squeeze the cropped picture back
   into the 48 px circle (measured: 48 px wide instead of 109) */
.kfcp-stage--phone .kfcp-host img { object-fit: fill; max-width: none; }
/* Listen is the house kf-speak--bare at its own size on EVERY screen, a phone
   too: 64 px (icon 44, glyph 28), the game's F2 rule; the house --sm size is
   "never on a live play surface" (Nova 04 § 2026-10-24 K1). On a phone the
   line keeps its 228 px budget because Barnaby's avatar steps down (engine,
   placeHost: 40, 32, none). */
.kfcp-listen { flex: none; }
.kfcp-msg {
  flex: 1 1 auto;
  min-width: 0;
  max-width: 46rem;
  /* a FIXED box: two lines here, three on a phone, so nothing moves */
  height: calc(2 * 1.3 * 1.35rem);
  margin: 0;
  display: flex;
  align-items: center;
  white-space: pre-line;
  text-wrap: pretty;
  text-align: left;
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 1.35rem;
  line-height: 1.3;
  color: var(--kf-gold-deeper, #775e26);
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.55);
}
.kfcp-stage--phone .kfcp-msg { font-size: 1.1rem; height: calc(3 * 1.3 * 1.1rem); }

/* ---------- the bar: progress | Another clue, sound, full screen | the way out ---------- */
.kfcp-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 72px;
}
.kfcp-prog {
  margin: 0 auto 0 0;
  padding: 10px 14px;
  min-height: 60px;
  box-sizing: border-box;
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border-radius: var(--radius-pill);
  background: var(--surface-on-art, #271f3c);
  box-shadow: var(--rim-on-art, 0 0 0 2px #fdfaf4);
}
/* five drawn pictograms: upcoming faint, current bright with a gold ring,
   found gold (C36: a picture, never a score) */
.kfcp-prog-i {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: rgba(253, 250, 244, 0.3);
  transition: color 0.3s ease;
}
.kfcp-prog-i svg { width: 32px; height: 32px; display: block; }
.kfcp-prog-i.is-now { color: var(--kf-cream, #fdfaf4); box-shadow: 0 0 0 2px var(--kf-gold); }
.kfcp-prog-i.is-done { color: var(--kf-gold); }
.kfcp-barright { display: flex; align-items: center; gap: 8px; }
.kfcp-barbtn {
  min-width: 64px;
  min-height: 64px;
  box-sizing: border-box;
  display: grid;
  place-items: center;
  background: var(--color-surface);
  border: 2px solid var(--kf-lilac);
  border-radius: var(--radius-md);
  color: var(--kf-purple-deep);
  cursor: pointer;
  padding: 0;
  -webkit-tap-highlight-color: transparent;
}
.kfcp-barbtn[hidden] { display: none; }
.kfcp-barbtn:hover { border-color: var(--kf-gold); }
.kfcp-barbtn:focus-visible { outline: 3px solid var(--kf-purple-deep); outline-offset: 3px; }
/* "Another clue": the house gold hint pill with the magnifier (D-114) */
.kfcp-cluebtn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 64px;
  padding: 0 22px 0 14px;
  box-sizing: border-box;
  background: linear-gradient(180deg, #fff6dc 0%, #ffe9a8 100%);
  border: 3px solid var(--kf-gold);
  border-radius: var(--radius-pill);
  color: var(--kf-purple-deep);
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 1.05rem;
  cursor: pointer;
  box-shadow: var(--shadow-soft);
  -webkit-tap-highlight-color: transparent;
}
.kfcp-cluebtn[hidden] { display: none; }
.kfcp-cluebtn:hover { filter: brightness(1.04); }
.kfcp-cluebtn:focus-visible { outline: 3px solid var(--kf-purple-deep); outline-offset: 3px; }
.kfcp-cluebtn svg { display: block; }
/* the 40-second helper: one soft glow, 700 in, 600 held, 700 out (C15) */
.kfcp-cluebtn.is-glow { animation: kfcp-glow 2s ease-in-out 1; }
@keyframes kfcp-glow {
  0% { box-shadow: var(--shadow-soft); }
  35%, 65% { box-shadow: var(--glow-hint-soft, 0 0 18px 6px rgba(212, 168, 67, 0.4)); }
  100% { box-shadow: var(--shadow-soft); }
}
/* WIDE: the red X's 72 px box reaches the bar's bottom edge and the top
   portrait sits one row gap under it; a mouse over that portrait lifts it
   2 px (hover), which left 7 px between the two (Sage S2). 4 px more keeps
   8 px or more in every state; the solve counts this margin. */
.kfcp-stage--wide .kfcp-bar { margin-bottom: 4px; }
.kfcp-exit { background: transparent; border-color: transparent; min-width: 72px; min-height: 72px; margin-left: 4px; }
.kfcp-exit:hover { border-color: transparent; }
.kfcp-exit-img { width: 66px; height: 66px; display: block; filter: drop-shadow(0 2px 4px rgba(15, 10, 36, 0.28)); }
/* phone and split: row 1 progress ... X, row 2 the tools RIGHT-aligned, so
   nothing slides when the pill comes and goes (Nova 2.5). Every control here
   is 64 px with 8 px between them, the brief's F2 (Sage S2: they were 56 px
   with 6 px between the full-screen button and the X). The red X keeps its
   50 px picture, the house phone X, inside the bigger target. */
.kfcp-stage--phone .kfcp-bar {
  display: grid;
  grid-template-columns: auto 1fr auto;
  grid-template-areas: "prog . x" "tools tools tools";
  row-gap: 8px;
  column-gap: 8px;
  min-height: 0;
}
.kfcp-stage--phone .kfcp-prog { grid-area: prog; padding: 6px 10px; min-height: 44px; gap: 4px; }
.kfcp-stage--phone .kfcp-prog-i { width: 30px; height: 30px; }
.kfcp-stage--phone .kfcp-prog-i svg { width: 24px; height: 24px; }
.kfcp-stage--phone .kfcp-barright { grid-area: tools; justify-content: flex-end; min-height: 64px; }
.kfcp-stage--phone .kfcp-exit { grid-area: x; min-width: 64px; min-height: 64px; margin-left: 0; }
.kfcp-stage--phone .kfcp-exit-img { width: 50px; height: 50px; }
.kfcp-stage--phone .kfcp-barbtn { min-width: 64px; min-height: 64px; }
.kfcp-stage--phone .kfcp-cluebtn { min-height: 64px; font-size: 0.95rem; padding: 0 16px 0 10px; line-height: 1.1; }
/* under 340 px, and in the split board's 302 px column, the pill's words may
   go onto two lines inside the 64 px pill (at 320 they did at 56 px too);
   less side padding keeps them to two, or one where they fit */
@media (max-width: 339px) {
  .kfcp-stage--phone .kfcp-cluebtn { gap: 6px; padding: 0 12px 0 8px; }
}
.kfcp-stage--split .kfcp-cluebtn { gap: 6px; padding: 0 12px 0 8px; }

/* ---------- the parade and the portraits ---------- */
.kfcp-main {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  min-height: 0;
  min-width: 0;
}
.kfcp-stage--stacked .kfcp-main { flex-direction: column; gap: 8px; }
.kfcp-scene {
  position: relative;
  flex: none;
  width: var(--kfcp-scene-w, 640px);
  height: var(--kfcp-scene-h, 360px);
  border-radius: var(--radius-md);
  overflow: hidden;
  box-shadow: 0 2px 10px rgba(45, 27, 78, 0.22);
  background: #3b2a5e;
}
.kfcp-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* the path wins over the sky (Nova 2.6) */
  object-position: 50% 62%;
  display: block;
  user-select: none;
  pointer-events: none;
}

/* the friend: costume on and costume off in the same box, the contact shadow
   under the feet, walking in together */
.kfcp-fig { position: absolute; pointer-events: none; z-index: 1; }
.kfcp-fig.is-away { opacity: 0; }
/* a costume picture that did not load: no broken-picture frame and no shadow
   walking in alone; Barnaby's line says what happened (Sage B1) */
.kfcp-fig.is-broken { visibility: hidden; }
.kfcp-shadow {
  position: absolute;
  left: 21%;
  width: 58%;
  top: 96.5%;
  height: 7%;
  background: radial-gradient(closest-side, rgba(45, 27, 78, 0.3), rgba(45, 27, 78, 0));
}
.kfcp-stage--dragon .kfcp-shadow { left: 7%; width: 86%; }
/* the pair cross-fades inside its own group: plus-lighter keeps the sum of the
   two pictures one solid figure all the way through the fade */
.kfcp-fig-pair { position: absolute; inset: 0; isolation: isolate; }
.kfcp-fig-pair img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  user-select: none;
}
.kfcp-fig-out { opacity: 0; mix-blend-mode: plus-lighter; }
/* the reveal (Nova 2.9): 150 to 1350 ms, ease-in-out, under the veil */
.kfcp-fig.is-revealed .kfcp-fig-in { opacity: 0; transition: opacity 1200ms ease-in-out 150ms; }
.kfcp-fig.is-revealed .kfcp-fig-out { opacity: 1; transition: opacity 1200ms ease-in-out 150ms; }
/* the walk in: a plain lateral glide, no bob (C27, C29) */
.kfcp-fig.is-arriving { animation: kfcp-glide 1600ms cubic-bezier(0.25, 0.8, 0.35, 1) both; }
@keyframes kfcp-glide {
  from { transform: translateX(var(--kfcp-from-x, -100vw)); }
  to { transform: none; }
}
.kfcp-fig.is-fading { animation: kfcp-fade 700ms ease both; }
@keyframes kfcp-fade { from { opacity: 0; } to { opacity: 1; } }

/* round 5: the gold ring round the asked part (C30) */
.kfcp-ring {
  position: absolute;
  z-index: 2;
  border-radius: 24px;
  box-shadow: inset 0 0 0 4px var(--kf-gold), 0 0 0 2px var(--kf-purple-deep), 0 0 16px 4px rgba(212, 168, 67, 0.45);
  opacity: 0;
  transition: opacity 0.25s ease;
  pointer-events: none;
}
.kfcp-ring.is-on { opacity: 1; transition-duration: 0.3s; }
.kfcp-stage--phone .kfcp-ring { border-radius: 16px; }

/* round 5: a found friend becomes a small portrait tag on that part */
.kfcp-tags { position: absolute; inset: 0; pointer-events: none; z-index: 3; }
.kfcp-tag {
  position: absolute;
  display: grid;
  justify-items: center;
  gap: 4px;
  transform: translate(-50%, -50%);
  opacity: 0;
  transition: opacity 0.2s ease;
}
.kfcp-tag.is-on { opacity: 1; }
.kfcp-tag img {
  width: var(--kfcp-tag, 56px);
  height: var(--kfcp-tag, 56px);
  border-radius: 50%;
  object-fit: cover;
  box-shadow: 0 0 0 3px var(--kf-cream, #fdfaf4), 0 0 0 5px var(--kf-purple-deep), var(--shadow-soft);
  background: #fff8e8;
}
.kfcp-tag-name {
  padding: 0 8px;
  border-radius: var(--radius-pill);
  background: var(--kf-cream, #fdfaf4);
  border: 2px solid var(--kf-purple-deep);
  color: var(--kf-purple-deep);
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 1rem;
  line-height: 1.3;
  white-space: nowrap;
}

/* ---------- the magnifying glasses (Nova 2.7) ---------- */
.kfcp-lenses { position: absolute; inset: 0; pointer-events: none; z-index: 4; }
.kfcp-lens {
  position: absolute;
  display: block;
  padding: 0;
  margin: 0;
  border: 0;
  background: transparent;
  border-radius: 50%;
  opacity: 0;
  transform: scale(0.86);
  transition: opacity 0.35s ease-out, transform 0.35s ease-out, left 0.45s ease-in-out, top 0.45s ease-in-out, width 0.45s ease-in-out, height 0.45s ease-in-out;
  pointer-events: auto;
  font: inherit;
  color: inherit;
  --kfcp-ring: 6px;
}
.kfcp-lens.is-on { opacity: 1; transform: scale(1); }
.kfcp-lens.is-docked { --kfcp-ring: 4px; }
.kfcp-lens.is-leaving { opacity: 0; transition: opacity 0.3s ease; pointer-events: none; }
.kfcp-lens.is-hop { opacity: 0; transition: opacity 0.2s ease; }
button.kfcp-lens { cursor: pointer; -webkit-tap-highlight-color: transparent; }
/* controls drawn ON the art: the two-tone focus ring (Nova 2.18) */
button.kfcp-lens:focus-visible { outline: 3px solid var(--kf-purple-deep); outline-offset: 3px; box-shadow: 0 0 0 9px #fdf8ee; }
button.kfcp-lens:active .kfcp-lens-clip { transform: scale(0.97); }
/* a voiceless glass answers a tap with a small press and its sentence in
   Barnaby's line (Pip P6); to assistive technology it stays a picture */
.kfcp-lens--look { cursor: pointer; -webkit-tap-highlight-color: transparent; }
.kfcp-lens.is-pulse .kfcp-lens-clip { animation: kfcp-lens-press 380ms ease-out 1; }
@keyframes kfcp-lens-press { 0% { transform: scale(1); } 35% { transform: scale(0.95); } 100% { transform: scale(1); } }
.kfcp-lens-clip {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  overflow: hidden;
  background: #fff8e8;
}
.kfcp-lens-in { position: absolute; left: 0; top: 0; transform-origin: 0 0; transition: transform 0.45s ease-in-out; }
.kfcp-lens-bg,
.kfcp-lens-fig { position: absolute; display: block; user-select: none; }
/* the same picture as the parade, with the same cover rule, then zoomed:
   the glass is a true close-up */
.kfcp-lens-bg { left: 0; top: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 62%; }
.kfcp-lens-fig { object-fit: contain; }
.kfcp-lens::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  box-shadow: inset 0 0 0 var(--kfcp-ring) var(--kf-gold), 0 0 0 3px var(--kf-purple-deep), 0 6px 18px rgba(15, 10, 36, 0.4);
  pointer-events: none;
}
.kfcp-lens-handle {
  position: absolute;
  width: 24%;
  height: 9%;
  right: -12%;
  bottom: 6%;
  background: linear-gradient(180deg, #8a5a2b 0%, #5d3a1a 100%);
  border: 3px solid var(--kf-purple-deep);
  border-radius: 999px;
  transform: rotate(45deg);
  transform-origin: left center;
  pointer-events: none;
}
.kfcp-lens.is-docked .kfcp-lens-handle { display: none; }
/* the house speaker disc on the ring, lower left, when the clue can speak */
.kfcp-lens-badge.kf-speak {
  position: absolute;
  left: calc(14.6% - 17px);
  top: calc(85.4% - 17px);
  width: 34px;
  height: 34px;
  min-height: 0;
  padding: 0;
  gap: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
  transform: none;
  pointer-events: none;
  z-index: 1;
}
.kfcp-lens-badge .kf-speak-ico { width: 34px; height: 34px; box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--kf-purple-deep); }
.kfcp-lens-badge .kf-speak-ico > i { width: 60%; height: 60%; }
.kfcp-stage--phone .kfcp-lens-badge.kf-speak { width: 28px; height: 28px; left: calc(14.6% - 14px); top: calc(85.4% - 14px); }
.kfcp-stage--phone .kfcp-lens-badge .kf-speak-ico { width: 28px; height: 28px; }
/* the caption: one plate per glass, never a name (C2, A2) */
.kfcp-lens-cap {
  position: absolute;
  box-sizing: border-box;
  padding: 4px 10px;
  border-radius: 14px;
  background: #fdfaf4;
  border: 2px solid var(--kf-purple-deep);
  color: var(--kf-purple-deep);
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 1.35rem;
  line-height: 1.2;
  text-align: center;
  text-wrap: balance;
  white-space: normal;
  box-shadow: var(--shadow-soft);
  pointer-events: none;
}
.kfcp-stage--phone .kfcp-lens-cap { font-size: 1.1rem; }

/* ---------- the reveal: the stardust veil, the sparkles (C21, C28) ---------- */
.kfcp-fx { position: absolute; inset: 0; pointer-events: none; z-index: 5; }
.kfcp-veil {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
  background: radial-gradient(closest-side, rgba(255, 247, 224, 0.92) 0 55%, rgba(255, 247, 224, 0.6) 68%, rgba(242, 197, 61, 0.25) 80%, rgba(255, 247, 224, 0) 100%);
  opacity: 0;
  /* rise 100-400 ms, full 400-1100, fall 1100-1600: one swell, never a flash (WCAG 2.3.1) */
  animation: kfcp-veil 1500ms linear 100ms both;
}
@keyframes kfcp-veil {
  0% { opacity: 0; animation-timing-function: ease-out; }
  20% { opacity: 1; animation-timing-function: linear; }
  66.667% { opacity: 1; animation-timing-function: ease-in; }
  100% { opacity: 0; }
}
.kfcp-sparkle {
  position: absolute;
  width: 18px;
  height: 18px;
  margin: -9px 0 0 -9px;
  background: radial-gradient(circle, #fff6cf 0 30%, #f2c53d 31% 60%, transparent 61%);
  clip-path: polygon(50% 0, 61% 39%, 100% 50%, 61% 61%, 50% 100%, 39% 61%, 0 50%, 39% 39%);
  opacity: 0;
  animation-name: kfcp-spark;
  animation-duration: 1000ms;
  animation-timing-function: ease-in-out;
  animation-fill-mode: both;
}
@keyframes kfcp-spark {
  0% { opacity: 0; transform: translateY(0) scale(0.6); }
  35% { opacity: 1; }
  100% { opacity: 0; transform: translateY(-24px) scale(1); }
}

/* the name BESIDE the head, never over a face (C22, Nova 2.9) */
.kfcp-labels { position: absolute; inset: 0; pointer-events: none; z-index: 6; }
.kfcp-label {
  position: absolute;
  display: inline-flex;
  align-items: center;
  box-sizing: border-box;
  height: calc(2rem * 1.15 + 18px);
  padding: 0 26px;
  white-space: nowrap;
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 2rem;
  line-height: 1.15;
  color: var(--kf-purple-deep);
  background: linear-gradient(180deg, #fff6dc 0%, #ffe9a8 100%);
  border: 3px solid var(--kf-gold);
  border-radius: var(--radius-pill);
  box-shadow: 0 0 0 3px var(--kf-purple-deep), var(--shadow-soft);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.3s ease, transform 0.3s ease;
}
.kfcp-label.is-on { opacity: 1; transform: none; }
/* the pointer toward the face */
.kfcp-label::before {
  content: '';
  position: absolute;
  left: -17px;
  top: calc(50% - 10px);
  border-top: 10px solid transparent;
  border-bottom: 10px solid transparent;
  border-right: 12px solid var(--kf-purple-deep);
}
.kfcp-stage--phone .kfcp-label { font-size: 1.5rem; height: calc(1.5rem * 1.15 + 18px); padding: 0 16px; }
/* round 5: three smaller labels over the heads, pointer down */
.kfcp-label--small,
.kfcp-stage--phone .kfcp-label--small { font-size: 1.35rem; height: calc(1.35rem * 1.15 + 14px); padding: 0 16px; }
/* 4 px less height on a phone: with the 64 px phone bar (S2) a 360 px phone's
   parade is 214 px tall and the dragon's heads sit 39 px under its top edge;
   a 36 px label no longer fit above Ori's hair (measured 41.5 against 38.7) */
.kfcp-stage--phone .kfcp-label--small { font-size: 1.1rem; height: calc(1.1rem * 1.15 + 10px); padding: 0 12px; }
.kfcp-label--small::before {
  left: calc(50% - 10px);
  top: calc(100% + 3px);
  border-top: 12px solid var(--kf-purple-deep);
  border-bottom: 0;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
}
/* the dragon's labels are placed by the engine (Nova 04 T4): above the head
   (pointer down, it grows when the label rises and stays on the head point when
   the label slides sideways), beside the face (side pointer) or under the chin
   (pointer up). The pointer box is measured from the label's border box. */
.kfcp-label--small.kfcp-ptr--down::before {
  left: calc(50% - 10px + var(--kfcp-pdx, 0px));
  top: calc(100% + 3px);
  border-top: var(--kfcp-plen, 12px) solid var(--kf-purple-deep);
  border-bottom: 0;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
}
.kfcp-label--small.kfcp-ptr--up::before {
  left: calc(50% - 10px + var(--kfcp-pdx, 0px));
  top: calc(-3px - var(--kfcp-plen, 12px));
  border-bottom: var(--kfcp-plen, 12px) solid var(--kf-purple-deep);
  border-top: 0;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
}
.kfcp-label--small.kfcp-ptr--right::before {
  left: calc(100% + 3px);
  top: calc(50% - 10px);
  border-left: 12px solid var(--kf-purple-deep);
  border-right: 0;
  border-top: 10px solid transparent;
  border-bottom: 10px solid transparent;
}
.kfcp-label--small.kfcp-ptr--left::before {
  left: -15px;
  top: calc(50% - 10px);
  border-right: 12px solid var(--kf-purple-deep);
  border-left: 0;
  border-top: 10px solid transparent;
  border-bottom: 10px solid transparent;
}
/* the phone's second step when the three names do not fit (Nova 04 T4: 1.0rem, h 30) */
.kfcp-stage--phone .kfcp-label--small.kfcp-label--xs { font-size: 1rem; height: calc(1rem * 1.15 + 10px); padding: 0 12px; }

/* Next lives inside the parade, bottom right, only at the reveal (Nova 2.10) */
.kfcp-next {
  position: absolute;
  right: 16px;
  bottom: 16px;
  z-index: 7;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 72px;
  padding: 0 26px 0 32px;
  box-sizing: border-box;
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 1.35rem;
  line-height: 1.1;
  color: var(--kf-purple-deep);
  background: linear-gradient(180deg, #ffd94d 0%, #f0b929 100%);
  border: 3px solid var(--kf-purple-deep);
  border-radius: var(--radius-pill);
  box-shadow: 0 4px 0 rgba(45, 27, 78, 0.28), 0 6px 16px rgba(15, 10, 36, 0.35);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.3s ease;
  -webkit-tap-highlight-color: transparent;
}
.kfcp-next.is-on { opacity: 1; }
.kfcp-next[hidden] { display: none; }
.kfcp-next:hover { filter: brightness(1.06); }
.kfcp-next:focus-visible { outline: 3px solid var(--kf-purple-deep); outline-offset: 3px; box-shadow: 0 0 0 9px #fdf8ee, 0 4px 0 rgba(45, 27, 78, 0.28); }
/* the engine gives the pill one max-width per layout, the free path right of
   the friends (Nova 04 T1): a word that does not fit goes to two balanced lines */
.kfcp-next-word { text-align: center; text-wrap: balance; }
.kfcp-next-ic { display: inline-flex; }
.kfcp-stage--phone .kfcp-next { right: 10px; bottom: 10px; min-height: 64px; font-size: 1.1rem; padding: 0 12px 0 14px; }

/* the found friend's picture on its way to the tag (round 5) */
.kfcp-fly {
  position: absolute;
  z-index: 30;
  object-fit: cover;
  border-radius: 15px;
  pointer-events: none;
  transform-origin: center;
  transition: transform 450ms ease-in-out, border-radius 450ms ease-in-out;
}

/* the one-time picture how-to (C35): driven by the Web Animations API */
.kfcp-hand {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 25;
  pointer-events: none;
  opacity: 0;
  filter: drop-shadow(0 3px 6px rgba(15, 10, 36, 0.35));
}
.kfcp-hand svg { width: 100%; height: 100%; display: block; }
.kfcp-hand.is-on { opacity: 1; transition: opacity 0.25s ease; }
.kfcp-hand-outline {
  position: absolute;
  z-index: 24;
  box-sizing: border-box;
  border: 3px dashed var(--kf-gold);
  border-radius: 22px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.25s ease;
}
.kfcp-hand-outline.is-on { opacity: 1; }

/* ---------- the portraits: a column beside the parade, a row under it (Nova 2.8) ---------- */
.kfcp-picks {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  gap: var(--kfcp-gap, 16px);
  flex: none;
  transition: opacity 0.3s ease;
}
.kfcp-picks.is-entering { opacity: 0; transition: none; }
.kfcp-stage--wide .kfcp-picks { flex-direction: column; height: var(--kfcp-scene-h); gap: 16px; }
.kfcp-pick {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  width: calc(var(--kfcp-p, 140px) + 6px);
  padding: 0;
  box-sizing: border-box;
  background: var(--color-surface);
  border: 3px solid var(--kf-lilac);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-soft);
  cursor: pointer;
  font: inherit;
  color: var(--kf-purple-deep);
  overflow: hidden;
  -webkit-tap-highlight-color: transparent;
  transition: border-color 0.2s ease, transform 0.2s ease, opacity 0.2s ease, box-shadow 0.2s ease;
}
.kfcp-pick[hidden] { display: none; }
.kfcp-pick-pic {
  display: block;
  width: var(--kfcp-p, 140px);
  height: var(--kfcp-p, 140px);
  flex: none;
  border-radius: 15px 15px 0 0;
  overflow: hidden;
  background: var(--kf-cream, #fdfaf4);
}
.kfcp-pick-pic img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  user-select: none;
  pointer-events: none;
  transition: opacity 0.2s ease-out;
}
.kfcp-pick-name {
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: var(--text-child-label, 1.45rem);
  line-height: 1.1;
  white-space: nowrap;
}
.kfcp-stage--phone .kfcp-pick-name { height: 32px; font-size: 1.35rem; }
/* WIDE: horizontal cards, picture left, name right (Elias C3) */
.kfcp-stage--wide .kfcp-pick { flex-direction: row; width: calc(var(--kfcp-p, 140px) + var(--kfcp-namew, 100px) + 6px); height: calc(var(--kfcp-p, 140px) + 6px); }
.kfcp-stage--wide .kfcp-pick-pic { border-radius: 15px 0 0 15px; }
.kfcp-stage--wide .kfcp-pick-name { width: var(--kfcp-namew, 100px); height: auto; align-self: stretch; justify-content: flex-start; padding-left: 16px; box-sizing: border-box; }
@media (hover: hover) {
  .kfcp-pick:hover { border-color: var(--kf-gold); transform: translateY(-2px); }
}
.kfcp-pick:active { border-color: var(--kf-gold); transform: scale(0.98); transition-duration: 0.08s; }
.kfcp-pick:focus-visible { outline: 3px solid var(--kf-purple-deep); outline-offset: 3px; }
/* found: the strong select halo (never green or red, C41) */
.kfcp-pick.is-right { border-color: var(--kf-gold); box-shadow: var(--halo-select-strong, 0 0 0 3px #fff, 0 0 0 7px #d4a843); }
/* not this time: the PICTURE goes quiet, hue kept; border, surface and name
   unchanged; nothing is taken away (C17) */
.kfcp-pick.is-out .kfcp-pick-pic img { opacity: 0.6; }
/* the one friend left: gold border + a still halo, one slow nod (C18) */
.kfcp-pick.is-last { border-color: var(--kf-gold); box-shadow: 0 0 0 3px rgba(212, 168, 67, 0.55), var(--shadow-soft); animation: kfcp-nod 1.2s ease-in-out 0.3s 1; }
@keyframes kfcp-nod { 0% { transform: scale(1); } 50% { transform: scale(1.06); } 100% { transform: scale(1); } }
/* round 5: a found friend's card fades and leaves */
.kfcp-pick.is-gone { opacity: 0; pointer-events: none; }
.kfcp-picks.is-waiting .kfcp-pick { cursor: default; }
/* at the reveal the cards wait: Next is the only action on screen */
.kfcp-picks.is-reveal .kfcp-pick { cursor: default; }
.kfcp-picks.is-reveal .kfcp-pick:hover { transform: none; }
.kfcp-picks.is-reveal .kfcp-pick:not(.is-right):hover { border-color: var(--kf-lilac); }

/* after Next: the friend, the name and Next fade, the cards swap */
.kfcp-leaving .kfcp-fig,
.kfcp-leaving .kfcp-labels,
.kfcp-leaving .kfcp-next { opacity: 0; transition: opacity 0.4s ease; }
.kfcp-leaving .kfcp-picks { opacity: 0; transition: opacity 0.2s ease; }

/* ---------- a phone held sideways: the SPLIT board (Nova 2.19) ---------- */
.kfcp-stage--split {
  grid-template-columns: var(--kfcp-scene-w) var(--kfcp-right);
  /* auto, not 1fr: an fr row under a spanning parade grew to 263 px for 126 px
     of cards and pushed the board 118 px past its box (measured, in the page) */
  grid-template-rows: auto auto auto;
  grid-template-areas: "head head" "scene bar" "scene picks";
  column-gap: 16px;
}
.kfcp-stage--split .kfcp-main { display: contents; }
.kfcp-stage--split .kfcp-head { grid-area: head; }
.kfcp-stage--split .kfcp-msg { max-width: none; height: calc(2 * 1.3 * 1.1rem); }
.kfcp-stage--split .kfcp-head { height: auto; min-height: 56px; }
.kfcp-stage--split .kfcp-bar { grid-area: bar; }
.kfcp-stage--split .kfcp-scene { grid-area: scene; align-self: start; }
.kfcp-stage--split .kfcp-picks { grid-area: picks; align-self: end; gap: 10px; }
/* SHORT split (Sage T-S2: a phone held sideways under about 358 px, the
   iPhone's Safari height): the bar's first row (progress, the red X) climbs
   beside Barnaby's line, whose box becomes the phone's 3 lines (Nova 04 T3),
   and the tools make ONE row beside the parade, over the cards. The bar box
   itself steps out (display: contents; it is a plain div with no role, its
   controls keep their DOM and Tab order), its children take the stage's grid
   areas of the same names they have in the phone bar. The engine writes the
   three rows (line | tools | the cards' row). Columns 8 px apart, the
   parade's own column 8 px wider than the parade, so the parade keeps its
   16 px to the cards and the line gains 16 px (at 640 px wide, in the page,
   with a Listen slot, that is the difference between under and over the
   228 px budget). */
.kfcp-stage--split.kfcp-stage--splitshort {
  grid-template-columns: calc(var(--kfcp-scene-w) + 8px) minmax(0, 1fr) auto auto;
  grid-template-areas: "head head prog x" "scene tools tools tools" "scene picks picks picks";
  column-gap: 8px;
}
.kfcp-stage--splitshort .kfcp-bar { display: contents; }
.kfcp-stage--splitshort .kfcp-prog,
.kfcp-stage--splitshort .kfcp-exit { align-self: center; }
.kfcp-stage--splitshort .kfcp-msg { height: calc(3 * 1.3 * 1.1rem); }
/* in the short split board the head row's width is set by the progress pill
   and the X beside it, so only the pill can give the line width: compact
   pictograms here (a picture, not a control, C36), 186 to 154 px. At 568x320
   the line box was 218 px and two lines ran to 4 lines in the 3-line box;
   with this it is 242 (Nova 04 § 2026-10-24 K1). Height (44) unchanged. */
.kfcp-stage--splitshort .kfcp-prog { padding: 6px 8px; gap: 2px; }
.kfcp-stage--splitshort .kfcp-prog-i { width: 26px; height: 26px; }
.kfcp-stage--splitshort .kfcp-prog-i svg { width: 22px; height: 22px; }

/* ---------- celebration card (pattern 7, Nova 2.14) ---------- */
.kfcp-panel {
  position: absolute;
  inset: 0;
  z-index: 40;
  display: grid;
  place-items: center;
  background: rgba(15, 10, 36, 0.55);
  padding: 16px;
}
.kfcp-card {
  width: min(34rem, 92%);
  box-sizing: border-box;
  background: var(--color-surface);
  border: 3px solid var(--kf-gold);
  border-radius: var(--radius-lg);
  padding: 40px 24px 24px;
  text-align: center;
  box-shadow: 0 10px 30px rgba(15, 10, 36, 0.4);
  animation: kfcp-pop 0.35s ease both;
}
@keyframes kfcp-pop { from { transform: scale(0.94); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@keyframes kfcp-fadein { from { opacity: 0; } to { opacity: 1; } }
.kfcp-win-h { margin: 0 0 16px; font-family: var(--font-heading); font-weight: 800; font-size: 2rem; line-height: 1.15; color: var(--kf-purple-deep); }
.kfcp-win-four { display: flex; justify-content: center; gap: 12px; margin: 0 0 16px; }
.kfcp-win-friend { display: grid; justify-items: center; gap: 4px; font-family: var(--font-heading); font-weight: 800; font-size: 1.2rem; color: var(--kf-purple-deep); }
.kfcp-win-friend img { width: 72px; height: 72px; border-radius: 14px; object-fit: cover; border: 3px solid var(--kf-gold); box-sizing: border-box; }
.kfcp-win-p { margin: 0 0 24px; font-family: var(--font-body); font-size: 1.25rem; line-height: 1.4; color: var(--color-text); }
.kfcp-win-row { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
.kfcp-win-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 64px;
  padding: 0 28px;
  box-sizing: border-box;
  border-radius: var(--radius-pill);
  border: 3px solid var(--kf-purple-deep);
  background: var(--color-surface);
  color: var(--kf-purple-deep);
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 1.2rem;
  text-decoration: none;
  cursor: pointer;
}
.kfcp-win-btn--gold { background: linear-gradient(180deg, #ffd94d 0%, #f0b929 100%); }
.kfcp-win-btn:focus-visible { outline: 3px solid var(--kf-purple-deep); outline-offset: 4px; }
.kfcp-stage--phone .kfcp-card { width: 90vw; max-width: 100%; padding: 28px 16px 16px; }
.kfcp-stage--phone .kfcp-win-friend img { width: 56px; height: 56px; }
.kfcp-stage--phone .kfcp-win-friend { font-size: 1.05rem; }
.kfcp-stage--phone .kfcp-win-h { font-size: 1.6rem; }

.kfcp-confetti { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 35; }
.kfcp-confetti span {
  position: absolute;
  top: -14px;
  width: 10px;
  height: 14px;
  border-radius: 3px;
  animation: kfcp-fall 1.9s ease-in forwards;
}
@keyframes kfcp-fall { to { transform: translateY(110vh) rotate(540deg); opacity: 0.2; } }

/* ---------- reduced motion (Nova 2.17) ----------
   tokens.css zeroes every duration with !important under reduced motion, so
   every FADE this game keeps is declared again here with !important and a
   class selector (which beats the universal one). What goes: the glide, the
   bob, the scale on opening, the nod, the hover lift, the flight, the hand's
   path, the sparkles and the falling confetti. What stays: opacity. */
@media (prefers-reduced-motion: reduce) {
  .kfcp-fig.is-arriving { animation: none !important; }
  .kfcp-fig.is-fading { animation: kfcp-fade 700ms ease both !important; }
  .kfcp-fig.is-revealed .kfcp-fig-in,
  .kfcp-fig.is-revealed .kfcp-fig-out { transition: opacity 1200ms ease-in-out 150ms !important; }
  .kfcp-veil { animation: kfcp-veil 1500ms linear 100ms both !important; }
  .kfcp-lens { transform: none !important; transition: opacity 350ms ease !important; }
  .kfcp-lens.is-hop { transition: opacity 200ms ease !important; }
  .kfcp-lens.is-docked:not(.is-hop) { transition: opacity 250ms ease !important; }
  .kfcp-lens.is-leaving { transition: opacity 300ms ease !important; }
  .kfcp-lens-in { transition: none !important; }
  /* tokens.css gives EVERY property a 0.01 ms transition here, so a plate's width set and measured in the
     same frame read the old width: rule H's 2-line search and the plate's height came back stale (the
     round-4 dock stayed on one line, 2.7 px over the active glass, at 320 px). A plate never animates. */
  .kfcp-lens-cap { transition: none !important; }
  /* the same for Barnaby's round avatar: each step's size is set and the line box beside it measured at once
     (Nova 04 § 2026-10-24 K1); with the 0.01 ms transition the box read the PREVIOUS step and the avatar went
     at 360 full screen and 375 in the page, where the K1 table keeps 32 px (measured 2026-10-24 evening) */
  .kfcp-host, .kfcp-host img { transition: none !important; }
  .kfcp-lens.is-pulse .kfcp-lens-clip { animation: none !important; }
  .kfcp-pick-pic img { transition: opacity 200ms ease-out !important; }
  .kfcp-pick, .kfcp-pick:hover, .kfcp-pick:active { transform: none !important; }
  .kfcp-pick.is-gone { transition: opacity 300ms ease !important; }
  .kfcp-pick.is-last { animation: none !important; }
  .kfcp-label { transform: none !important; transition: opacity 300ms ease !important; }
  .kfcp-next { transition: opacity 300ms ease !important; }
  .kfcp-tag { transition: opacity 300ms ease !important; }
  .kfcp-ring { transition: opacity 300ms ease !important; }
  .kfcp-picks { transition: opacity 300ms ease !important; }
  .kfcp-leaving .kfcp-fig,
  .kfcp-leaving .kfcp-labels,
  .kfcp-leaving .kfcp-next,
  .kfcp-leaving .kfcp-picks { transition: opacity 400ms ease !important; }
  .kfcp-hand, .kfcp-hand-outline { transition: opacity 250ms ease !important; }
  .kfcp-prog-i { transition: color 300ms ease !important; }
  .kfcp-cluebtn.is-glow { animation: kfcp-glow 2s ease-in-out 1 !important; }
  .kfcp-card { animation: kfcp-fadein 300ms ease both !important; }
  .kfcp-sparkle { display: none !important; }
  .kfcp-confetti span { animation: none !important; }
}
