/* Talk on the drawing: the words over the studio's plan on the page's plate, the two conversations
   pinned to it in the colours of whoever started them, and the card the app opens beside a pin,
   standing over the paper as the app stands it. js/talk.js sizes the plate as the scene above sizes
   its canvas, places each card where the app's rule places it, and plays the scene. Nothing here
   paints a ground: the plan stands on .plate (css/base.css), as on the scene above, and the card is
   an island. */
.talk { --top: clamp(40px, 7.5vh, 84px); --foot: clamp(14px, 3.4vh, 34px); }
.tk-layout { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: var(--top) 0 var(--foot); }
.tk-head { flex: none; text-align: center; }
.tk-head .say { margin: clamp(12px, 2.2vh, 22px) auto 0; }
/* Under the words, the room for the plate; js/talk.js sizes the plate inside it. Under the words on
   a desktop the board is as tall as the plate, so the words and the plate stand together in the
   middle of the stage, as on the scene above. The plan arrives whole and closer in, on the stair and
   the studio: the scene above has just drawn it, and condensing it out of cells a second time read
   as the page starting over. Its figures wear the page's pill (css/app.css), sized and faded by the
   app's measure in js/talk.js. */
.tk-board { position: relative; flex: 1 1 0; min-height: 0; width: 100%; margin-top: clamp(22px, 4.2vh, 44px); }
.talk[data-mode="over"] .tk-board { flex: none; height: var(--ch, 0px); }
.tk-card { position: absolute; left: var(--cl, 0px); top: var(--ct, 0px); width: var(--cw, 100%); height: var(--ch, 100%); overflow: hidden; }

/* A figure, its lines or a word an open card stands over (js/talk.js). A line's own fade is its
   inline opacity, so the card's is said in the stroke's and the arrowhead's. */
.tk-plan .pill .pill-in, .tk-plan .ly-text text { transition: opacity 0.3s var(--ease); }
.tk-plan .pill.under .pill-in, .tk-plan .ly-text text.under { opacity: 0; }
.tk-plan .ly-dimensions path { transition: stroke-opacity 0.3s var(--ease), fill-opacity 0.3s var(--ease); }
.tk-plan .ly-dimensions path.under { stroke-opacity: 0; fill-opacity: 0; }
/* A word the plate's edge would cut is left off; hidden, not taken out, so it can be measured again
   at the next size. */
.tk-plan .ly-text text.off { visibility: hidden; }

/* ── a conversation pinned to a place, as the app pins it (its on-the-paper.css) ──
   A drop of the starter's colour standing up and to the right of the point, its square corner on
   the point, a speech mark in it; an unread point on its shoulder in the app's accent; lifted by a
   deeper shadow when its card is open. The shadows are the app's, black under the mark, never a
   light round it. --pk is the page's size for the app's own. */
.tk-pins { position: absolute; inset: 0; pointer-events: none; }
.tk-pin { position: absolute; left: 0; top: 0; width: 0; height: 0; }
.tk-drop {
  position: absolute; left: 0; bottom: 0; width: calc(30px * var(--pk, 1)); height: calc(30px * var(--pk, 1));
  display: grid; place-items: center; border-radius: 50% 50% 50% 0; background: var(--tint); color: #fff;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.45);
  transform-origin: 0 100%; opacity: 0; transform: translateY(-22px) scale(0.6);
  transition: opacity 0.25s var(--ease), transform 0.6s cubic-bezier(0.3, 1.5, 0.5, 1), box-shadow 0.35s var(--ease), filter 0.35s var(--ease);
}
.tk-drop svg { width: calc(14px * var(--pk, 1)); height: calc(14px * var(--pk, 1)); fill: currentColor; }
.tk-pin.on .tk-drop { opacity: 1; transform: none; }
/* Open is said by lift, not by a ring, as the app says it: a deeper shadow and a touch of light. */
.tk-pin.open .tk-drop { transform: translateY(-2px); box-shadow: 0 10px 24px rgba(0, 0, 0, 0.6); filter: brightness(1.08); }
.tk-drop::after {
  content: ""; position: absolute; top: -2px; right: -2px; width: calc(9px * var(--pk, 1)); height: calc(9px * var(--pk, 1));
  border-radius: 50%; background: var(--you); box-shadow: 0 0 0 2px var(--raise-2); transform: scale(0); transition: transform 0.35s var(--ease);
}
.tk-pin.unread .tk-drop::after { transform: scale(1); transition-delay: 0.25s; }
/* Where a pin lands: two soft discs of its colour swelling from the point, a beat apart, the press
   the hands make on the scene above. */
.tk-ring > span {
  position: absolute; left: -16px; top: -16px; width: 32px; height: 32px; border-radius: 50%;
  background: color-mix(in srgb, var(--tint) 38%, transparent); opacity: 0;
  animation: tk-ring 900ms cubic-bezier(0.22, 1, 0.36, 1) 120ms forwards;
}
.tk-ring > span + span { animation-delay: 260ms; }
@keyframes tk-ring { 0% { opacity: 0.7; transform: scale(0.2); } 100% { opacity: 0; transform: scale(1.6); } }

/* ── the card beside a pin: the app's pin card, on the page's island ──
   The app's measures, times --k: 300 wide, 14 round, 12 in, faces of 20, the words at 13 and the
   names at 12 in their own weight with the time after them in the quiet ink. It opens growing out
   of its pin's side and closes the same way; each message rises into its place as it is said. */
.tk-islands { position: absolute; inset: 0; pointer-events: none; z-index: 3; }
.tk-island {
  position: absolute; left: 0; top: 0; width: calc(300px * var(--k, 1)); padding: calc(12px * var(--k, 1));
  display: flex; flex-direction: column; gap: calc(9px * var(--k, 1)); border-radius: calc(14px * var(--k, 1));
  font-size: calc(13px * var(--k, 1)); line-height: 1.4;
  opacity: 0; transform: scale(0.92); transform-origin: var(--from, 0 0); visibility: hidden;
  transition: opacity 0.28s var(--ease), transform 0.5s cubic-bezier(0.2, 1.2, 0.3, 1), visibility 0s linear 0.5s;
}
.tk-island.on { opacity: 1; transform: none; visibility: visible; transition-delay: 0s; }
.tk-top { display: flex; align-items: flex-start; gap: calc(8px * var(--k, 1)); }
.tk-top strong { flex: 1; min-width: 0; padding-top: 0.12em; font-weight: 600; line-height: 1.3; letter-spacing: -0.005em; text-wrap: balance; }
.tk-resolve {
  flex: none; padding: 0.2em 0.8em 0.25em; border-radius: 999px; font-size: 0.88em; font-weight: 500;
  color: var(--snow-dim); box-shadow: inset 0 0 0 1px var(--hair-2);
}
.tk-close { flex: none; display: grid; place-items: center; width: 1.7em; height: 1.7em; margin-right: -0.25em; color: var(--snow-faint); }
.tk-close svg { width: 44%; height: 44%; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; fill: none; }
/* What has been said: a window onto the list, as tall as what has arrived, holding the newest
   whole in view once the card has no more room, the oldest let go whole over the top edge. The fade
   there lies over the gap above the first message shown, never over its words: it says there is
   more above, and dims the one going as it passes. */
.tk-said { position: relative; height: 0; overflow: hidden; transition: height 0.45s var(--ease); }
.tk-said.clipped { -webkit-mask-image: linear-gradient(transparent, #000 calc(10px * var(--k, 1))); mask-image: linear-gradient(transparent, #000 calc(10px * var(--k, 1))); }
.tk-said ol { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; row-gap: calc(10px * var(--k, 1)); transition: transform 0.45s var(--ease); }
.tk-msg { display: flex; gap: calc(8px * var(--k, 1)); align-items: flex-start; opacity: 0; transform: translateY(12px); transition: opacity 0.35s var(--ease), transform 0.5s var(--ease); }
.tk-msg.on { opacity: 1; transform: none; }
.tk-face {
  flex: none; width: calc(20px * var(--k, 1)); height: calc(20px * var(--k, 1)); margin-top: 1px; border-radius: 50%; overflow: hidden;
  display: grid; place-items: center; background: var(--tint); color: #fff;
  font-size: calc(20px * 0.38 * var(--k, 1)); font-weight: 600; letter-spacing: 0.02em; line-height: 1;
}
.tk-face img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tk-who { display: block; font-size: 0.92em; font-weight: 600; }
.tk-who em { font-style: normal; font-weight: 400; color: var(--snow-faint); margin-left: 4px; }
.tk-msg p { margin-top: 1px; color: color-mix(in oklab, var(--snow) 88%, transparent); text-wrap: pretty; }
.tk-reply {
  padding: calc(7px * var(--k, 1)) calc(10px * var(--k, 1)); border-radius: calc(10px * var(--k, 1));
  background: rgba(255, 255, 255, 0.05); color: var(--snow-faint);
}
.tk-more { font-size: 0.92em; color: var(--you); }
/* The room's line under the reply box of a thread the client can read (collab-room.css,
   .thread-warn): the one coloured line in the room, in the warning's text ink, at the room's size
   and weight and in from the field's edge by the room's padding, all read from the app into
   data/talk.json. It rises into place a beat after the card opens, as the room reveals it, so the
   eye finds it. */
.tk-warn {
  margin: calc(-3px * var(--k, 1)) 0 0; padding: 0 calc(var(--warn-inset) * var(--k, 1));
  font-size: calc(var(--warn-size) * var(--k, 1)); font-weight: var(--warn-weight); color: var(--warn-text);
  opacity: 0; transform: translateY(-4px); transition: opacity 0.35s var(--ease) 0.35s, transform 0.5s var(--ease) 0.35s;
}
.tk-island.on .tk-warn { opacity: 1; transform: none; }

/* A short, wide window: the words take a column on the left and the plate stands in the rest of the
   height beside them, as the scene above lays itself out there. */
@media (max-height: 640px) and (min-aspect-ratio: 3/2) and (min-width: 761px) {
  .tk-layout { flex-direction: row; align-items: stretch; gap: clamp(28px, 4vw, 64px); padding-top: clamp(28px, 7vh, 56px); }
  .tk-head { width: min(34%, 440px); align-self: center; text-align: left; }
  .tk-head .say { margin-left: 0; }
  .tk-board { flex: 1 1 0; min-width: 0; margin-top: 0; }
}
/* A phone: the plate the plan's own shape under the words, and the card under the plate. */
@media (max-width: 760px) {
  .tk-head .say { font-size: 19px; }
  .tk-board { margin-top: 20px; }
}
@media (prefers-reduced-motion: reduce) {
  .scene.talk { height: 100vh; height: 100svh; }
  .tk-drop, .tk-drop::after, .tk-island, .tk-warn, .tk-said, .tk-said ol, .tk-msg, .tk-plan { transition: none; }
}
/* A jump (a reload mid-page, a link from further up) lands without playing what nobody saw. */
.talk.cut .tk-drop, .talk.cut .tk-drop::after, .talk.cut .tk-island, .talk.cut .tk-warn, .talk.cut .tk-said, .talk.cut .tk-said ol, .talk.cut .tk-msg { transition: none; }
