/* The story: the app's own interface (the demo, built into demo/ from the app, see
   packages/app/src/renderer/demo) pinned on a stage while the page scrolls past a step per scene
   and a gap between each two. On a step, its scene holds still; through a gap, the captions fade
   and the camera pans and zooms the window (drawn at the app's 1280×800) from one scene's part of
   it to the next's, as far as the page has scrolled (story.js). It isn't meant to be clicked.
   Shared by the pages with a story. */
.story { position: relative; --stage-top: 56px; --stage-height: calc(100svh - var(--stage-top)); }
.stage { position: sticky; top: var(--stage-top); height: var(--stage-height); overflow: hidden; }
.camera {
  position: absolute; top: 0; left: 0; width: 1280px; height: 800px; transform-origin: 0 0;
  border-radius: 12px; overflow: hidden; background: var(--bg); /* the app's own background, light or dark, while it loads */ border: 1px solid rgba(0, 0, 0, 0.12); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08), 0 24px 60px rgba(0, 0, 0, 0.18);
}
/* The hero's two windows (the home page): the one showing in place, the other waiting to the side,
   faded out. Draft → highlight, the second comes in from the right as the first goes left; back,
   the other way. Once the story moves on, the first window's back. */
.camera { transition: opacity 0.6s ease, translate 0.6s cubic-bezier(0.3, 0, 0.2, 1); }
.camera.alt { opacity: 0; translate: 6% 0; pointer-events: none; }
.stage.on-hero[data-hero="highlights"] .camera:not(.alt) { opacity: 0; translate: -6% 0; }
.stage.on-hero[data-hero="highlights"] .camera.alt { opacity: 1; translate: 0 0; }
.camera iframe { display: block; width: 1280px; height: 800px; border: 0; pointer-events: none; opacity: 0; transition: opacity 0.4s; }
.camera iframe.loaded { opacity: 1; }
/* Shown instead of the demo on a page opened as a file, where browsers block it. */
.camera .needs-server { position: absolute; inset: 0; display: grid; place-content: center; gap: 8px; padding: 40px; text-align: center; font-size: 22px; color: #6e6e73; }
.camera .needs-server code { font-size: 20px; color: #1d1d1f; }
.steps { position: relative; margin-top: calc(-1 * var(--stage-height)); pointer-events: none; }
.step { min-height: calc(var(--stage-height) * 0.7); }
.step:first-child { min-height: calc(var(--stage-height) * 0.5); }
.step[data-side="below"] { min-height: calc(var(--stage-height) * 1.5); } /* the hero, its tools under it: held a while, to try them */
.step:last-child { min-height: calc(var(--stage-height) * 0.4); } /* "settle": back to the whole window before the page moves on */
.step[data-scene="upload"] { min-height: calc(var(--stage-height) * 1.2); } /* room to drag the file in */
.gap { height: calc(var(--stage-height) * 0.6); } /* where one scene changes to the next */
/* The captions stay still on the stage, on the page's background: each fades in for its scene, on
   its side, and out for the next, as the page scrolls through the gaps (--show and --shift, set by
   story.js). The camera keeps the window clear of them. */
.caption { position: absolute; top: 50%; left: 48px; width: 344px; opacity: var(--show, 0); visibility: hidden; text-align: left; transform: translateY(calc(-50% + var(--shift, 32px))); }
/* Each side's captions share one column (COLUMN in story.js, 440px from the screen's edge), centred
   in it, so they line up from scene to scene; a caption on the left is aligned towards the window,
   which meets the column's edge where it can. */
.caption[data-side="right"] { left: auto; right: 48px; }
.caption[data-side="left"] { text-align: right; }
/* Below the window, across the foot (the home page's hero: its tools, under the window they change). */
.caption[data-side="below"] { top: auto; bottom: 28px; left: 50%; width: min(720px, calc(100% - 80px)); text-align: center; transform: translate(-50%, var(--shift, 32px)); }
.hero-caption .hero-tools { margin: 0 0 14px; }
.hero-caption .lede { margin-bottom: 0; }
/* Across the top, over a window using the full width under it (story.js frames it). */
.caption[data-side="top"] { top: 28px; left: 50%; width: min(640px, calc(100% - 80px)); text-align: center; transform: translate(-50%, var(--shift, 32px)); }
.agent { text-align: left; }
.caption h2 { margin-bottom: 12px; font-size: clamp(26px, 3vw, 38px); text-wrap: balance; }
/* No short word alone on a line: headings wrap into even lines, paragraphs avoid a last line of
   one word (and story.js ties each one's last two words together, for browsers without these). */
.caption p { text-wrap: pretty; }
.caption > p:last-of-type { margin: 0; color: var(--muted); font-size: 17px; }
.caption .kicker { color: var(--blue); }
.caption.highlight .kicker { color: var(--brown); }
/* A file beside the window, under a caption (the first scene's): dragged onto the window and
   dropped as the page scrolls through its step (placeFile in story.js), as from the desktop. */
.drag-file { display: inline-grid; justify-items: center; gap: 6px; margin-top: 24px; width: 140px; font-size: 13px; font-weight: 500; color: var(--text); text-align: center; }
.drag-file-icon { display: grid; place-items: end center; width: 56px; height: 70px; padding-bottom: 8px; border-radius: 4px 14px 4px 4px; background: #fff; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12), 0 4px 12px rgba(0, 0, 0, 0.12); font-size: 11px; font-weight: 800; color: #d64545; }
.drag-file.picked { visibility: hidden; }
.drag-ghost > span:last-child { padding: 1px 6px; border-radius: 4px; background: #2f6fde; color: #fff; } /* as macOS labels a file being dragged */
.drag-ghost { position: absolute; z-index: 3; margin: 0; pointer-events: none; filter: drop-shadow(0 10px 18px rgba(0, 0, 0, 0.3)); }
.drag-ghost[hidden] { display: none; }

/* Progress through the story: a dot per captioned scene beside the caption, on its side (a set
   on each side, the one in use slid in from the window's edge). Scenes passed are blue, those
   to come grey, and the current one is a taller pill filling with blue as the page scrolls
   through it (--fill, see track()). */
.progress { position: absolute; top: 50%; display: flex; flex-direction: column; align-items: center; gap: 8px; opacity: 0; transition: opacity 0.4s, transform 0.5s cubic-bezier(0.3, 0, 0.2, 1); pointer-events: none; }
.progress[data-side="left"] { left: 20px; transform: translate(-56px, -50%); }
.progress[data-side="right"] { right: 20px; transform: translate(56px, -50%); }
.progress.shown { opacity: 1; transform: translate(0, -50%); }
.dot { position: relative; width: 7px; height: 7px; border-radius: 4px; background: var(--line); overflow: hidden; transition: height 0.35s; }
.dot::after { content: ""; position: absolute; inset: 0; background: var(--blue); transform: scaleY(var(--fill, 0)); transform-origin: top; }
.dot.passed { --fill: 1; }
.dot.current { height: 34px; }
/* The agent's side: a window of its own floating over the app's, as another app on the desktop
   would, over the app window's left side (placed by story.js) so the cards appearing in its right
   margin stay in view. The demo tells the page what the agent is doing: the user's prompt, the
   agent's replies (typed out) and its SmartDoc tool calls, a spinner while one's under way and a
   tick once done. Its height is fixed: what's new comes in at the bottom and the oldest scrolls
   off the top. It shows while it has something to say. Generic, standing for whichever agent the
   visitor uses. */
.agent { position: absolute; bottom: 32px; left: 32px; z-index: 2; display: flex; flex-direction: column; width: 360px; height: min(440px, calc(100% - 64px)); border-radius: 12px; overflow: hidden; background: #1d1d1f; color: #e8e8ed; font-size: 13px; line-height: 1.45; text-align: left; border: 1px solid rgba(255, 255, 255, 0.1); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2), 0 24px 60px rgba(0, 0, 0, 0.35); opacity: 0; transform: translateY(16px) scale(0.98); transition: opacity 0.35s, transform 0.35s; pointer-events: none; }
.agent.shown { opacity: 1; transform: none; }
.agent-bar { position: relative; flex: none; margin: 0; padding: 8px 12px; background: #2c2c2e; border-bottom: 1px solid rgba(255, 255, 255, 0.08); font-size: 12px; font-weight: 600; color: #a1a1a6; text-align: center; }
.agent-lights { position: absolute; left: 12px; top: 50%; display: flex; gap: 6px; transform: translateY(-50%); }
.agent-lights i { width: 10px; height: 10px; border-radius: 50%; background: #ff5f57; }
.agent-lights i:nth-child(2) { background: #febc2e; }
.agent-lights i:nth-child(3) { background: #28c840; }
/* Newest at the bottom; what doesn't fit goes off the top, fading out as it goes. */
.agent-body { flex: 1; min-height: 0; display: flex; flex-direction: column; justify-content: flex-end; gap: 6px; padding: 12px 14px; overflow: hidden; mask-image: linear-gradient(to bottom, transparent 0, #000 40px); }
.agent-body > * { flex: none; margin: 0; animation: agent-in 0.3s ease-out; }
.agent-prompt { align-self: flex-end; max-width: 85%; margin-bottom: 4px; padding: 8px 11px; border-radius: 12px 12px 4px 12px; background: #2f6fde; color: #fff; }
.agent-say { color: #f2f2f4; }
.agent-tool { display: flex; align-items: baseline; gap: 7px; min-width: 0; font: 12px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace; color: #8e8e93; }
.agent-tool::before { content: ""; flex: none; align-self: center; width: 10px; height: 10px; border: 2px solid #5a5a5e; border-top-color: #e8e8ed; border-radius: 50%; animation: agent-spin 0.8s linear infinite; }
.agent-tool.done::before { border: 0; border-radius: 0; animation: none; background: center / contain no-repeat url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 8.5 6.5 12 13 4.5' fill='none' stroke='%2334c759' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
.agent-tool b { flex: none; font-weight: 600; color: #c7c7cc; }
.agent-tool span { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
@keyframes agent-spin { to { transform: rotate(360deg); } }
@keyframes agent-in { from { opacity: 0; transform: translateY(4px); } }
/* Narrow: the window and the caption one above the other, either way round (story.js places
   them), and the progress dots in a row, centred at the foot, the current one long. */
@media (max-width: 899px) {
  .caption, .caption[data-side="right"], .caption[data-side="left"], .caption[data-side="top"], .caption[data-side="below"] { top: var(--narrow-top, 50%); bottom: auto; left: 16px; right: 16px; width: auto; text-align: left; transform: translateY(var(--shift, 32px)); }
  .caption[data-side="below"] { text-align: center; }
  .progress[data-side] { top: auto; bottom: 16px; left: 50%; right: auto; flex-direction: row; transform: translate(-50%, 12px); }
  .progress.shown { transform: translateX(-50%); }
  .dot { transition: width 0.35s; }
  .dot::after { transform: scaleX(var(--fill, 0)); transform-origin: left; }
  .dot.current { width: 34px; height: 7px; }
  .caption h2 { font-size: 24px; margin-bottom: 6px; }
  .caption > p:last-of-type { font-size: 15px; }
  /* docked over the lower part of the window (story.js sets its top and height), across its width */
  .agent { bottom: auto; left: 12px; right: 12px; width: auto; font-size: 12px; }
}
@media (prefers-reduced-motion: reduce) {
  .camera, .caption, .progress, .dot { transition: none; }
  .agent, .agent-body > *, .agent-tool::before { animation: none; transition: none; }
}
