/* Speakingboard preview: the demos' frames, the speaking heads and their speech bubbles (split out of site.css, 2026-10-02 site v3
   phase 1). demos.js mounts each scene at the size these frames give it. Loaded after site.css. */
/* ---- a demo's frame: the real app, replayed; what's said comes from the speaker ---- */
.demo { position: relative; }
.v { position: relative; aspect-ratio: 16 / 10; border-radius: 22px; overflow: hidden; background: var(--ground); border: 1px solid var(--line); isolation: isolate; }
.card .v { aspect-ratio: 5 / 4; border-radius: 16px; }
/* A HEAD PER DEMO (Mark, 2026-10-02 2:01 pm; art.js): sized by height, so every face is drawn at one scale whatever the drawing's width */
.speaker { position: absolute; left: -34px; bottom: -26px; z-index: 4; pointer-events: none; }
.speaker img { height: 119px; }
.card .speaker { left: -22px; bottom: -20px; } .card .speaker img { height: 98px; }
.mcard .speaker { left: -22px; bottom: -20px; } .mcard .speaker img { height: 104px; }
/* THE SECOND VOICE (the managers' demo): Sarah faces the speaker across the board from its top right corner (the bottom right is where
   Esbi's own bubbles rise, left of the scene's orb), her line in her own colour (the app's colour for her name on a live board, board.js
   byColor), never Esbi's Ember */
.speaker.right { left: auto; right: -18px; top: -22px; bottom: auto; } .speaker.right img { height: 84px; }
.mcard .speaker.right { right: -14px; top: -18px; } .mcard .speaker.right img { height: 77px; }
.speaker.right img { transform: scaleX(-1); }
/* her bubble faces the board from the top edge, tip back at her, wide so a line spreads instead of stacking past two lines
   (Mark, 2026-10-02 2:11 pm: "place it all the way to the top edge ... make the speech bubble directly in front of her and
   longer ... bubble tip facing her"). bottom:100% floats it off the TOP of .speaker.right itself (which is already lifted
   -22/-18/-14px above the demo frame, same as her head) -- height-independent, and it clears the board's own top-of-frame
   "This Week" goal label every time, where an absolute top: Npx landed the bubble's bottom edge straight through that label. */
.speaker.right .say { left: auto; right: calc(100% + 16px); bottom: calc(100% + 6px); top: auto; }
.speaker img { display: block; width: auto; max-width: none; filter: drop-shadow(0 12px 18px rgba(0,0,0,.5)); }
/* real air between her face and the bubble, on every speaker (Mark, 2026-10-02 2:01/2:11 pm: "need space between faces and bubble").
   THE HEADS' BUBBLES (Mark, 2026-10-02 3:20 pm: "just make like esbi's chat buble pointer exactly. it's also too big for the talking heads.
   size down bubbles a bit. dont add outline animation on talking heads, just simple fast fade"): the app's own outline and pointer
   (board.js bubble(), drawn by demos.js), mirrored for a head on the left so the pointer is at its side; a head's size, not a headline's;
   drawn whole and faded in and out. demos.js narrows it so a long line stacks, hugs it to its widest line, sets the pointer's tip just
   above the mouth, and keeps it off Esbi's bubbles */
.speaker .say { position: absolute; left: calc(100% + 16px); bottom: 62%; margin: 0; width: max-content; max-width: 290px; padding: 7px 12px 8px; isolation: isolate;
  font: 500 14.5px/1.34 "Mona Sans", system-ui, sans-serif; font-stretch: 94%; color: var(--cream); text-wrap: balance; opacity: 0; transition: opacity .15s var(--ease); }
.card .speaker .say { font-size: 13.5px; padding: 6px 11px 7px; }
.speaker .say[hidden] { display: none; }
.speaker .say[data-in="1"] { opacity: 1; }
.speaker .say[data-out="1"] { opacity: 0; transition-duration: .22s; }
.speaker .say b { font-weight: 680; }
.speaker .say > svg.bubble { position: absolute; left: 0; top: 0; z-index: -1; overflow: visible; pointer-events: none; }
.speaker:not(.right) .say > svg.bubble { transform: scaleX(-1); }
.speaker .say .bubble .b-ground { fill: #191b22; fill: color-mix(in srgb, #15181b 86%, #b0b8ff); stroke: none; }   /* every speaker in periwinkle, Sarah's colour first (Mark, 2026-10-04 9:41 am: "change the bubble color for speakers in demo. the new one is acgtually really good"); amber stays Esbi's and action's */
.speaker .say .bubble .b-line { fill: none; stroke: #b0b8ff; stroke-width: 1.5; stroke-linejoin: round; }
.speaker .say .bubble .b-draw { fill: none; stroke: #fff; stroke-width: 8; stroke-dasharray: 100 100; }   /* the outline's mask, whole: no draw-on */
.speaker.head-sarah .say .bubble .b-ground { fill: #171d1b; fill: color-mix(in srgb, #15181b 86%, #8fd6c0); }   /* a demo's second voice stays told apart: mint beside the periwinkle */
.speaker.head-sarah .say .bubble .b-line { stroke: #8fd6c0; }
@media (max-width: 759px) { .speaker { left: 8px; bottom: -18px; } .speaker img { height: 91px; } :is(.card, .mcard) .speaker { left: 6px; bottom: -16px; }
  :is(.card, .mcard) .speaker img { height: 83px; } .speaker .say { font-size: 13.5px; } .demo { margin-bottom: 18px; }
  :is(.card, .mcard) .speaker.right, .speaker.right { left: auto; right: 4px; top: -14px; bottom: auto; } :is(.card, .mcard) .speaker.right img, .speaker.right img { height: 65px; }
  /* mobile has no empty run above the demo the way the hero does -- .mdemo sits under its own "Start Speaking" button, .mcard sits
     under the previous stacked card's link -- so floating a full .speaker-height above (the desktop bottom:calc(100%+6px)) lands on
     them. Measured on both (agent-browser, 390px): bottom:37px clears the board's own top-of-frame label below with room to spare
     and sits mid-gap above whichever card or button sits above it, one or two lines tall. */
  .speaker.right .say { bottom: 37px; } }
.mcard .v { aspect-ratio: 16 / 10; border-radius: 16px; }
/* "Just say it": one demo the content's full width, 16:10 (at 1280 wide, 800 tall: under the nav on a 900 px screen); on a phone the app at a
   phone's size, 4:5, like a market's demo (demos.js dims) */
/* ...plus a band at its foot where the head's line sits, the board's drawing area ending above it (demos.js dims): what clears her line over
   the lowest box in every view, measured at each width (1496: 30 px over, the iPads 53 and 69) and 12 px of air */
.demo.wide { container-type: inline-size; --foot: 48px; }
.demo.wide .v { aspect-ratio: auto; height: calc(100cqw / 1.6 + var(--foot)); }
@media (max-width: 1299px) { .demo.wide { --foot: 68px; } }
@media (max-width: 999px) { .demo.wide { --foot: 84px; } }
@media (max-width: 759px) { .demo.wide { --foot: 0px; } .demo.wide .v { height: calc(100cqw * 1.25); } }
@media (max-width: 759px) { :is(.mcard, .mdemo) .v { aspect-ratio: 4 / 5; } }

@media (prefers-reduced-motion: reduce) { .speaker .say { transition: none; } }

/* ---- ONE DEMO ON SCREEN AT A TIME (demos.js SLOTS; Mark, 2026-10-04 1:08 pm: "i think we remove the side scroll feature altogether. instead
   we just add a button below the demo if it's a sequence. just have all the buttons in the sequence below so user can jump ahead"). A sequence
   is one frame, its demos in turn, the content's full width; as tall as 16:10 and the head's band allow, kept short enough that its buttons
   show under it on the screen; a phone's 4:5. Each demo is its own frame inside, only the current one shown ---- */
.seq { padding-top: clamp(36px, 4.4vw, 60px); }
.seq .demo { container-type: inline-size; --foot: 48px; }
.seq .v { aspect-ratio: auto; height: clamp(50cqw, min(calc(100cqw / 1.6 + var(--foot)), calc(100svh - var(--nav, 72px) - 120px)), calc(100cqw / 1.6 + var(--foot))); }
@media (max-width: 1299px) { .seq .demo { --foot: 68px; } }
@media (max-width: 999px) { .seq .demo { --foot: 84px; } }
@media (max-width: 759px) { .seq .demo { --foot: 0px; } .seq .v { height: calc(100cqw * 1.25); } }   /* a phone's: 4:5, drawn 660 wide (demos.js dims): of 560 x 700 (the old cards), 600 x 900, 600 x 1000 and 660 x 825, the one with the least of a row past the frame's edge in all eleven (Chromium as a touch phone, 2026-10-04) */
.v > iframe:not([data-on]) { visibility: hidden; }
/* A SWIPE ON A DEMO SCROLLS THE PAGE (Mark, 2026-10-04 4:47 pm: "Touch devices: user cant scroll page when swiping on demo box"): a clear cover of
   the page's own over the demo's frames. The frames ignore pointers (pointer-events: none), but iOS scrolls on its own thread and an iframe under
   the finger can still take the swipe; the cover makes the page the only thing under it. Nothing in a demo is meant to be touched */
.v::after { content: ""; position: absolute; inset: 0; z-index: 2; touch-action: pan-y pinch-zoom; }
.speaker[hidden] { display: none; }
/* its buttons: a demo each, the one showing marked; wrapped, never scrolled sideways */
.seq-tabs { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 26px; }
.seq-tabs button { min-height: 44px; padding: 10px 18px; border-radius: 22px; border: 1px solid var(--line); background: none; color: var(--quiet); cursor: pointer;
  font: 600 15.5px/1.25 "Mona Sans", system-ui, sans-serif; font-stretch: 94%; text-align: left; transition: color .2s, border-color .2s, background-color .2s; }
.seq-tabs button:hover { color: var(--ink); border-color: var(--dim); }
.seq-tabs button[aria-current="true"] { color: var(--ink); background: var(--raised2); border-color: var(--dim); }
.seq-tabs button:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }
@media (max-width: 759px) { .seq-tabs { margin-top: 30px; gap: 8px; } .seq-tabs button { padding: 9px 15px; font-size: 14.5px; } }
/* ONE LINE UNDER A SEQUENCE ON A PHONE (Mark, 2026-10-04 10:35 pm: "only one line below the demo and users can swipe"): the demo's own title, and at
   the right the NEXT one's name on a pill with an arrow (3:38 pm, 10-05: "Similar to the end session button on app": the app's End session, its 15 px,
   8 x 14 padding, 16 px corners on her orange-touched ground; demos.js swipeable) */
.seq-next { display: none; }
@media (max-width: 759px) {
  .seq-tabs { flex-wrap: nowrap; align-items: center; justify-content: space-between; gap: 14px; margin-top: 22px; }
  .seq-tabs button:not([aria-current="true"]):not(.seq-next) { display: none; }
  .seq-tabs button[aria-current="true"] { flex: 1 1 auto; min-width: 38%; padding: 0; border: 0; background: none; color: var(--ink); font-size: 16.5px; text-align: left; cursor: default; text-wrap: balance; }
  .seq-tabs .seq-next { display: inline-flex; align-items: center; gap: 7px; flex: 0 0 auto; max-width: calc(62% - 14px); min-height: 34px; padding: 8px 12px 8px 14px; border-radius: 16px;
    border: 1px solid transparent; background: color-mix(in srgb, #15181b 91%, #f79a10); color: #cfd3d8; font-size: 15px; line-height: 1.2; text-align: left; cursor: pointer; text-wrap: balance; }
  .seq-next svg { width: 14px; height: 14px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
  .seq-next:focus:not(:focus-visible) { outline: none; }   /* a tap leaves no ring; a keyboard still gets one */
  .seq-next:active { background: color-mix(in srgb, #15181b 82%, #f79a10); color: var(--ink); }
}
/* a market's line and its link, under the buttons */
.mtexts { margin-top: 22px; min-height: 84px; }
.mtext p { margin: 0; color: var(--quiet); font-size: 17px; line-height: 1.5; max-width: 52ch; }
.mtext[hidden] { display: none; }
/* until its board shows, and only if that takes a moment: a 1 px line running round the frame's own edge (Mark, 2026-10-04 2:24 pm: "make a 1px
   outline going around until demo loads"), laid over its border, a fifth of the way round, once round a second and a half */
.demo-load { position: absolute; left: .5px; top: .5px; width: calc(100% - 1px); height: calc(100% - 1px); z-index: 3; overflow: visible; pointer-events: none;
  opacity: 0; transition: opacity .2s var(--ease); }
.v:not([data-ready="1"]) .demo-load { opacity: 1; transition: opacity .35s var(--ease) .4s; }
.demo-load rect { fill: none; stroke: var(--amber); stroke-width: 1; stroke-dasharray: 20 80; stroke-linecap: round; animation: demo-round 1.5s linear infinite; }
.v[data-ready="1"] .demo-load rect { animation-play-state: paused; }
@keyframes demo-round { to { stroke-dashoffset: -100; } }
@media (prefers-reduced-motion: reduce) { .demo-load rect { animation: none; stroke-dasharray: none; opacity: .6; } }

/* ---- "Hand her the homework." (#sources): its four points in a row over its demo, the awareness section's type (site.css .tgroup) ---- */
.src-pts { list-style: none; margin: clamp(36px, 4vw, 56px) 0 clamp(36px, 4vw, 52px); padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 28px clamp(24px, 3vw, 44px); }
.src-pts li { margin: 0; padding-top: 16px; border-top: 1px solid var(--line); color: var(--quiet); font-size: 17px; line-height: 1.5; }
.src-pts strong { display: block; margin-bottom: 4px; color: var(--ink); font-weight: 600; }
@media (max-width: 1099px) { .src-pts { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 599px) { .src-pts { grid-template-columns: 1fr; gap: 22px; } }
