/* ============================================================================
   assistant-motion.css — shared motion engine for the six assistant scenes.

   HOW IT WORKS
   The base style of every helper is the FINAL state. Keyframes only describe
   where the element comes from. Nothing animates until the controller puts
   `is-live` on the <article data-as-scene>, so a scene that never plays still
   renders its complete result. `is-paused` on the article freezes everything,
   and reduced motion drops the animations altogether.

   TIMING
   Two custom properties per element, set inline:
     --at   start of the animation, measured from cycle start   (default 0ms)
     --dur  length of the animation                             (helper default)
   The cycle length lives on the scene's .as-browser-body as data-as-cycle.

   HELPERS (one class per behaviour, combine freely)
     m-enter    opacity 0 + translateY(8px)  -> final          360ms  ease out
     m-word     opacity 0 -> 1, no movement (word streams)     250ms  ease out
     m-pop      opacity 0 + scale(.92)       -> final          220ms  ease out
     m-fill     highlight fill, background-size 0% -> 100%     320ms  ease out
     m-band     reading band sweeping down the element         800ms  linear
     m-band-x   reading band sweeping across the element       620ms  linear
     m-progress line at the bottom edge, scaleX 0->1 then settles  620ms  linear
     m-ink      colour var(--lw-muted) -> var(--lw-ink)        320ms  ease out
     m-mute     colour var(--lw-ink)   -> var(--lw-muted)      320ms  ease out
     m-dim-in   opacity var(--o0, .28) -> 1                    320ms  ease out
     m-lift     translateY(-2px) + shadow, settles back        520ms  movement
     m-draw     SVG stroke-dashoffset 1 -> 0, needs pathLength 420ms  movement

   EXAMPLES
     <div class="as-question m-enter" style="--at:0ms"> … </div>
     <span class="m-pop" style="--at:700ms;--dur:220ms">Claude</span>
     <mark class="m-fill" style="--at:4200ms">180,00 Euro</mark>
     <div class="as-paper m-band" style="--at:2600ms;--dur:800ms"> … </div>
     <div class="as-row m-band-x m-progress" style="--at:1200ms;--dur:620ms"> … </div>
     <span class="m-ink" style="--at:1820ms">Schreiben.pdf</span>
     <div class="as-doc-row m-dim-in" style="--at:1820ms;--o0:.42"> … </div>
     <div class="as-paper m-lift" style="--at:4300ms"> … </div>
     <path class="m-draw" pathLength="1" style="--at:3500ms" d="M0 0h40" />

   CONTENT ATOMS
   Neutral, reusable pieces the storyboards need and the site CSS lacks:
   .as-source-page, .as-locator, .as-keyword, .as-progress, .as-route,
   .as-doc-row, .as-export. They carry no animation of their own.

   Easings: enter/reveal cubic-bezier(.23,1,.32,1), on screen movement
   cubic-bezier(.77,0,.175,1), reading and progress linear.

   FILE ORDER
   Engine, then the content atoms, then one section per scene at the bottom,
   each scoped to its own `[data-as-scene]`. This is the only stylesheet the
   assistant motion needs.
   ========================================================================== */

.assistant-showcase {
  --as-ease-out: cubic-bezier(.23, 1, .32, 1);
  --as-ease-move: cubic-bezier(.77, 0, .175, 1);
  --as-band: var(--lw-selected, #dfe8d7);
  --as-fill: var(--lw-selected-strong, #cbdabe);
}

/* ---- helper base state: the finished frame ------------------------------ */

.assistant-showcase .m-enter,
.assistant-showcase .m-word,
.assistant-showcase .m-pop,
.assistant-showcase .m-fill,
.assistant-showcase .m-ink,
.assistant-showcase .m-mute,
.assistant-showcase .m-dim-in,
.assistant-showcase .m-lift,
.assistant-showcase .m-draw,
.assistant-showcase .m-band::after,
.assistant-showcase .m-band-x::after,
.assistant-showcase .m-progress::after {
  animation-delay: var(--at, 0ms);
  animation-fill-mode: both;
  animation-iteration-count: 1;
}

.assistant-showcase .m-enter { animation-duration: var(--dur, 360ms); animation-timing-function: var(--as-ease-out); }
.assistant-showcase .m-word { animation-duration: var(--dur, 250ms); animation-timing-function: var(--as-ease-out); }
.assistant-showcase .m-pop { animation-duration: var(--dur, 220ms); animation-timing-function: var(--as-ease-out); }
.assistant-showcase .m-ink { color: var(--lw-ink); animation-duration: var(--dur, 320ms); animation-timing-function: var(--as-ease-out); }
.assistant-showcase .m-mute { color: var(--lw-muted); animation-duration: var(--dur, 320ms); animation-timing-function: var(--as-ease-out); }
.assistant-showcase .m-dim-in { opacity: 1; animation-duration: var(--dur, 320ms); animation-timing-function: var(--as-ease-out); }
.assistant-showcase .m-lift { animation-duration: var(--dur, 520ms); animation-timing-function: var(--as-ease-move); }
.assistant-showcase .m-draw { fill: none; stroke: var(--lw-line-strong); stroke-width: 1.5; stroke-linecap: round; stroke-dasharray: 1; stroke-dashoffset: 0; animation-duration: var(--dur, 420ms); animation-timing-function: var(--as-ease-move); }

/* Highlight fill. The mark breathes around its glyphs; the negative margin
   gives most of that padding back to the line so the text flow holds. */
.assistant-showcase .m-fill {
  padding: 2px 7px;
  margin: 0 -2px;
  border-radius: 5px;
  color: var(--lw-forest);
  white-space: nowrap;
  background-color: transparent;
  background-image: linear-gradient(var(--as-fill), var(--as-fill));
  background-repeat: no-repeat;
  background-position: 0 50%;
  background-size: 100% 100%;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  animation-duration: var(--dur, 320ms);
  animation-timing-function: var(--as-ease-out);
}

/* Reading bands. Wide, soft, multiplying, so the text underneath keeps its
   ink. About a third of the container, which reads as one line at a time. */
.assistant-showcase .m-band,
.assistant-showcase .m-band-x { position: relative; overflow: hidden; isolation: isolate; }
.assistant-showcase .m-band::after,
.assistant-showcase .m-band-x::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  mix-blend-mode: multiply;
  background-repeat: no-repeat;
  animation-timing-function: linear;
}
.assistant-showcase .m-band::after {
  background-image: linear-gradient(180deg, rgb(223 232 215 / 0) 0%, rgb(223 232 215 / .45) 38%, rgb(223 232 215 / .45) 62%, rgb(223 232 215 / 0) 100%);
  background-size: 100% 30%;
  background-position: 0 150%;
  animation-duration: var(--dur, 800ms);
}
.assistant-showcase .m-band-x::after {
  background-image: linear-gradient(90deg, rgb(223 232 215 / 0) 0%, rgb(223 232 215 / .45) 38%, rgb(223 232 215 / .45) 62%, rgb(223 232 215 / 0) 100%);
  background-size: 34% 100%;
  background-position: 150% 0;
  animation-duration: var(--dur, 620ms);
}

/* Progress line at the bottom edge of whatever carries it. Two animations on
   one pseudo element: the line runs in the icon green, because that is the
   moment it has to be legible, and 280 ms after it is full it settles to the
   strong line token. A line that stays dark for the rest of the cycle
   outweighs the highlights that carry the finding, and once every line is
   full its colour says nothing any more. Final state: full and settled. */
.assistant-showcase .m-progress { position: relative; }
.assistant-showcase .m-progress::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  border-radius: 2px;
  background: var(--lw-line-strong);
  transform: scaleX(1);
  transform-origin: left center;
  animation-delay: var(--at, 0ms), calc(var(--at, 0ms) + var(--dur, 620ms));
  animation-duration: var(--dur, 620ms), 280ms;
  animation-timing-function: linear;
}

/* ---- the cycle ---------------------------------------------------------- */

.assistant-showcase .as-scene.is-live .m-enter { animation-name: m-enter; }
.assistant-showcase .as-scene.is-live .m-word { animation-name: m-word; }
.assistant-showcase .as-scene.is-live .m-pop { animation-name: m-pop; }
.assistant-showcase .as-scene.is-live .m-fill { animation-name: m-fill; }
.assistant-showcase .as-scene.is-live .m-ink { animation-name: m-ink; }
.assistant-showcase .as-scene.is-live .m-mute { animation-name: m-mute; }
.assistant-showcase .as-scene.is-live .m-dim-in { animation-name: m-dim-in; }
.assistant-showcase .as-scene.is-live .m-lift { animation-name: m-lift; }
.assistant-showcase .as-scene.is-live .m-draw { animation-name: m-draw; }
.assistant-showcase .as-scene.is-live .m-band::after { animation-name: m-band; }
.assistant-showcase .as-scene.is-live .m-band-x::after { animation-name: m-band-x; }
.assistant-showcase .as-scene.is-live .m-progress::after { animation-name: m-progress, m-progress-settle; }

.assistant-showcase .as-scene.is-paused *,
.assistant-showcase .as-scene.is-paused *::before,
.assistant-showcase .as-scene.is-paused *::after { animation-play-state: paused; }

@keyframes m-enter { from { opacity: 0; transform: translateY(8px); } }
@keyframes m-enter-control { from { opacity: 0; visibility: hidden; transform: translateY(8px); } }
/* Interactive controls stay unfocusable until they enter. */
.assistant-showcase .as-scene.is-live button.m-enter { animation-name: m-enter-control; }
@keyframes m-word { from { opacity: 0; } }
@keyframes m-pop { from { opacity: 0; transform: scale(.92); } }
@keyframes m-fill { from { background-size: 0% 100%; } }
@keyframes m-ink { from { color: var(--lw-muted); } }
@keyframes m-mute { from { color: var(--lw-ink); } }
@keyframes m-dim-in { from { opacity: var(--o0, .28); } }
@keyframes m-draw { from { stroke-dashoffset: 1; } }
@keyframes m-progress { from { transform: scaleX(0); } }
@keyframes m-progress-settle { from { background-color: var(--lw-icon); } }
@keyframes m-lift {
  from { transform: translateY(0); box-shadow: none; }
  55% { transform: translateY(-2px); box-shadow: 0 10px 20px -14px rgb(36 53 43 / .45); }
  to { transform: translateY(0); box-shadow: none; }
}
@keyframes m-band {
  from { opacity: 0; background-position: 0 -50%; }
  6% { opacity: 1; background-position: 0 -50%; }
  94% { opacity: 1; background-position: 0 150%; }
  to { opacity: 0; background-position: 0 150%; }
}
@keyframes m-band-x {
  from { opacity: 0; background-position: -50% 0; }
  6% { opacity: 1; background-position: -50% 0; }
  94% { opacity: 1; background-position: 150% 0; }
  to { opacity: 0; background-position: 150% 0; }
}

/* ---- reduced motion: the finished frame, no movement -------------------- */

@media (prefers-reduced-motion: reduce) {
  .assistant-showcase .m-enter,
  .assistant-showcase .m-word,
  .assistant-showcase .m-pop,
  .assistant-showcase .m-fill,
  .assistant-showcase .m-ink,
  .assistant-showcase .m-mute,
  .assistant-showcase .m-dim-in,
  .assistant-showcase .m-lift,
  .assistant-showcase .m-draw,
  .assistant-showcase .m-band,
  .assistant-showcase .m-band-x,
  .assistant-showcase .m-progress,
  .assistant-showcase .m-band::after,
  .assistant-showcase .m-band-x::after,
  .assistant-showcase .m-progress::after { animation: none !important; }
}

/* ============================================================================
   CONTENT ATOMS
   Static building blocks shared by the scenes. No animation lives here.
   ========================================================================== */

/* Source page card: a small excerpt of an original document (scene 02). */
.assistant-showcase .as-source-page { display: flex; flex-direction: column; gap: 7px; padding: 14px 16px; background: var(--lw-panel); border: 1px solid var(--lw-line); border-radius: 7px; }
.assistant-showcase .as-source-page p { margin: 0; font-size: 13px; line-height: 1.7; }
.assistant-showcase .as-source-page .as-mini { overflow-wrap: anywhere; }
.assistant-showcase .as-source-pages { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }

/* Locator chip: a page marker that ties a finding to its place in the file. */
.assistant-showcase .as-locator { display: inline-flex; align-items: center; gap: 8px; padding: 7px 11px; background: var(--lw-selected); border-radius: 5px; font: 600 12px/1.4 var(--lw-body); color: var(--lw-forest); }
.assistant-showcase .as-locator svg { width: 16px; height: 16px; flex: none; color: var(--lw-icon); }
.assistant-showcase .as-locators { display: flex; flex-wrap: wrap; gap: 8px; }

/* Keyword token: one search term of a keyword route (scene 04). */
.assistant-showcase .as-keyword { display: inline-flex; align-items: center; padding: 6px 10px; background: var(--lw-surface-muted); border-radius: 5px; font: 600 12px/1.4 var(--lw-body); color: var(--lw-text); }
.assistant-showcase .as-keywords { display: flex; flex-wrap: wrap; gap: 6px; }

/* Progress rail: a standalone track for m-progress. */
.assistant-showcase .as-progress { position: relative; height: 2px; border-radius: 2px; background: var(--lw-line); }

/* Search route card: one way to the same source (scene 04). */
.assistant-showcase .as-route { display: flex; flex-direction: column; gap: 9px; padding: 14px 16px; background: var(--lw-panel); border: 1px solid var(--lw-line); border-radius: 7px; }
.assistant-showcase .as-route p { margin: 0; font-size: 13px; line-height: 1.65; }
.assistant-showcase .as-route .as-locator { align-self: flex-start; }
.assistant-showcase .as-routes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }

/* Document row: one file of the case, unread or read (scene 03). */
.assistant-showcase .as-doc-row { position: relative; display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 0 14px; border-bottom: 1px solid var(--lw-line); }
.assistant-showcase .as-doc-row:last-child { border-bottom: 0; }
.assistant-showcase .as-doc-row > span { font-size: 13px; overflow-wrap: anywhere; }
.assistant-showcase .as-doc-row > strong { font: 600 12px/1.4 var(--lw-body); white-space: nowrap; }

/* Export row: platform, direction, resulting document (scene 06). */
.assistant-showcase .as-export { display: grid; grid-template-columns: minmax(0, 1fr) 34px minmax(0, 1fr); align-items: center; gap: 12px; }
.assistant-showcase .as-export-side { display: flex; align-items: center; gap: 9px; padding: 12px 14px; border: 1px solid var(--lw-line); border-radius: 7px; font: 600 12px/1.4 var(--lw-body); color: var(--lw-ink); }
.assistant-showcase .as-export-side svg { width: 18px; height: 18px; flex: none; color: var(--lw-icon); }
.assistant-showcase .as-export-arrow { display: block; width: 34px; height: 24px; justify-self: center; }
.assistant-showcase .as-export-doc { flex-direction: column; align-items: stretch; gap: 8px; background: var(--lw-panel); }
.assistant-showcase .as-export-doc-head { display: flex; align-items: center; gap: 9px; }
.assistant-showcase .as-export-line { height: 3px; border-radius: 2px; background: var(--as-fill); }

@media (max-width: 700px) {
  .assistant-showcase .as-source-pages,
  .assistant-showcase .as-routes { grid-template-columns: minmax(0, 1fr); }
  .assistant-showcase .as-export { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .assistant-showcase .as-export-arrow { transform: rotate(90deg); height: 20px; }
}

/* ============================================================================
   SCENE CHOREOGRAPHY
   One section per scene, in the order of the navigation. Each section keeps its
   own `[data-as-scene="…"]` scope, so a rule can only reach the scene it
   belongs to. The timeline in each header is the contract the markup's --at
   values implement.

     01 Modelle      · the model row and one sourced answer
     02 Quellen      · two originals, two figures, one difference
     03 Akten        · every document of the file read in sequence
     04 Suchwege     · two routes to the same source
     05 Diktat       · spoken text becomes a clean draft
     06 Word         · selected passages leave as one document
   ========================================================================== */

/* ============================================================================
   01 Modelle
   One question, the model row, one sourced answer with an open point.

   0.00 s  the question block enters
   0.70 s  Claude, GPT, Gemini, + 4 Modelle pop in 90 ms apart, 220 ms each;
           Claude carries the active chip from its own first frame and the row
           never moves again
   1.50 s  a reading band passes the question, 700 ms
   2.10 s  the answer paper enters
   2.70 s  2.160 € fills, 2.95 s 2.340 € fills
   3.80 s  the open point enters, then the frame holds to 9.6 s

   The question needs an entrance and a reading band from one timeline, so the
   entrance sits on the .as-ask wrapper and the band on the question box below
   it. The wrapper is a plain flex item and needs no styling of its own.

   Every block holds its space from frame zero, so the frame height is the same
   at every moment of the cycle.
   ========================================================================== */

/* Band tuned to the height of a question box: wide enough to read as one pass
   over the sentence rather than a thin line crossing it. */
.assistant-showcase [data-as-scene="modelle"] .as-question.m-band::after { background-size: 100% 38%; }

/* Chips read as four quick taps. Scaling from the left edge keeps the row
   building outwards instead of every chip breathing around its own centre. */
.assistant-showcase [data-as-scene="modelle"] .as-models span { transform-origin: left center; }

/* Answer paper: even rhythm between label, headline, statement and open point,
   the same setting the finished draft uses in 05 Diktat. */
.assistant-showcase [data-as-scene="modelle"] .as-paper { display: flex; flex-direction: column; gap: 7px; }
.assistant-showcase [data-as-scene="modelle"] .as-paper h4 { margin: 0; }
.assistant-showcase [data-as-scene="modelle"] .as-paper p { margin: 0; }

@media (max-width: 700px) {
  /* 390: the same three blocks stacked. The chip row stays a wrapping row of
     chips, never a horizontal scroller, so it needs a row gap once it wraps. */
  .assistant-showcase [data-as-scene="modelle"] .as-models { row-gap: 8px; }
}

/* ============================================================================
   02 Quellen und Literatur
   The two originals and the two compared figures share one column grid: each
   source page sits directly above the row it produced, so the alignment
   carries the link and nothing has to be drawn between them.

   0.00 s  the question enters
   0.80 s  the first original loads
   1.30 s  a reading band passes it, 1.90 s 2.160,00 Euro fills
   2.20 s  its row (figure, label, locator) settles down out of the page
   2.90 s  the second original loads
   3.40 s  reading band, 4.00 s 2.340,00 Euro fills
   4.30 s  its row settles down out of the page
   5.00 s  the result with the open question
   5.60 s  the source button, then the frame holds to 9.6 s
   One thing at a time, left to right: read, extract, read, extract, compare.

   Every block holds its space from frame zero, so the frame height is fixed.
   ========================================================================== */

.assistant-showcase [data-as-scene="quellen"] .as-evidence { display: flex; flex-direction: column; gap: 16px; }

/* Source page: file name, locator, verbatim excerpt. The wrapper carries the
   load, the card itself carries the reading band, so the two behaviours keep
   their own --at. */
.assistant-showcase [data-as-scene="quellen"] .as-source-pages > div { display: grid; }
.assistant-showcase [data-as-scene="quellen"] .as-source-page { gap: 5px; }
.assistant-showcase [data-as-scene="quellen"] .as-source-page .as-source-location { margin: 0; }
.assistant-showcase [data-as-scene="quellen"] .as-source-page blockquote { margin: 5px 0 0; font-size: 13px; line-height: 1.7; }

/* Comparison: the same two columns as the source pages, inset to the page's
   text edge, so a value drops straight out of the excerpt above it. */
.assistant-showcase [data-as-scene="quellen"] .as-comparison { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.assistant-showcase [data-as-scene="quellen"] .as-comparison .as-row { padding: 2px 16px 0; border-bottom: 0; justify-content: flex-start; align-items: center; gap: 14px; }
.assistant-showcase [data-as-scene="quellen"] .as-comparison .as-row > strong { order: -1; line-height: 1.15; }

/* The figure settles down out of the source page instead of rising. */
.assistant-showcase [data-as-scene="quellen"].is-live .as-comparison .as-row.m-enter { animation-name: q-settle; }
@keyframes q-settle { from { opacity: 0; transform: translateY(-6px); } }

/* 390: the same vertical story, one pair at a time. Each source page is
   followed by the row it produced. */
@media (max-width: 700px) {
  .assistant-showcase [data-as-scene="quellen"] .as-evidence { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .assistant-showcase [data-as-scene="quellen"] .as-source-pages,
  .assistant-showcase [data-as-scene="quellen"] .as-comparison { display: contents; }
  .assistant-showcase [data-as-scene="quellen"] .as-source-pages > div:first-child { order: 1; }
  .assistant-showcase [data-as-scene="quellen"] .as-comparison > .as-row:first-child { order: 2; }
  .assistant-showcase [data-as-scene="quellen"] .as-source-pages > div:last-child { order: 3; margin-top: 6px; }
  .assistant-showcase [data-as-scene="quellen"] .as-comparison > .as-row:last-child { order: 4; }
  .assistant-showcase [data-as-scene="quellen"] .as-comparison .as-row { padding: 0 16px; }
}

/* ============================================================================
   03 Akten und Vollkontext
   The whole file is read, not a snippet.
   0.00 s  case heading and four unread documents hold their space
   0.30 s  the four rows enter, 70 ms apart, name and Blatt marker at .42
   1.20 s  document 1 is read: the band sweeps the row, the progress line
           fills, and the row is full ink when the sweep ends
   1.82 s  document 2, 2.44 s document 3, 3.06 s document 4, no overlap
   4.00 s  Schreiben.pdf and Blatt 42 fill, 4.12 s Gespraechsnotiz.pdf and
           Blatt 43; the other two documents stay in ink and unmarked
   4.60 s  the result enters, 5.00 s the two locator chips, then it holds
   Every element sits in its final box from frame zero, so the frame height
   never changes.
   ========================================================================== */

.assistant-showcase [data-as-scene="akten"] .as-document-list { display: flex; flex-direction: column; }

/* One document. The wrapper carries the entry, so the row itself is free to
   carry the reading band on its ::after. */
.assistant-showcase [data-as-scene="akten"] .as-doc { position: relative; }

/* The row keeps the atom's layout. Its progress rail replaces the hairline,
   so an unread and a read document differ only in how far the line has run. */
.assistant-showcase [data-as-scene="akten"] .as-doc-row { gap: 11px; padding: 13px 0 15px; border-bottom: 0; }
.assistant-showcase [data-as-scene="akten"] .as-doc-row > svg { width: 19px; height: 19px; flex: none; color: var(--lw-icon); }
.assistant-showcase [data-as-scene="akten"] .as-doc-row > strong { margin-left: auto; }
.assistant-showcase [data-as-scene="akten"] .as-doc-row mark { padding: 1px 3px; }

/* The rail sits on the row's bottom edge and replaces the hairline: unread is
   the pale track, the document being read carries the running icon green line,
   a read document keeps the settled line. The engine owns the run and the
   settle, so this scene only supplies the track. */
.assistant-showcase [data-as-scene="akten"] .as-doc-rail { position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: var(--lw-line); }
.assistant-showcase [data-as-scene="akten"] .as-doc-rail::after { opacity: 1; }

/* The reading band on a single row is a third of the height of the paper the
   engine default was tuned for, so it carries a little more sage. */
.assistant-showcase [data-as-scene="akten"] .as-doc-row::after {
  background-image: linear-gradient(90deg, rgb(203 218 190 / 0) 0%, rgb(203 218 190 / .72) 38%, rgb(203 218 190 / .72) 62%, rgb(203 218 190 / 0) 100%);
  background-size: 42% 100%;
}

.assistant-showcase [data-as-scene="akten"] .as-result { display: flex; flex-direction: column; gap: 6px; }
.assistant-showcase [data-as-scene="akten"] .as-result > p { margin-top: 0; }

/* 390: one document becomes a two line block with the marker under the file
   name, so no long file name is squeezed and nothing scrolls sideways. */
@media (max-width: 700px) {
  .assistant-showcase [data-as-scene="akten"] .as-doc-row { display: grid; grid-template-columns: 19px minmax(0, 1fr); align-items: start; column-gap: 11px; row-gap: 4px; padding: 12px 0 14px; }
  .assistant-showcase [data-as-scene="akten"] .as-doc-row > svg { grid-row: 1 / span 2; margin-top: 2px; }
  .assistant-showcase [data-as-scene="akten"] .as-doc-row > strong { grid-column: 2; margin-left: 0; }
}

/* ============================================================================
   04 Suchwege und Web
   One question, two search routes, one shared source.

   0.00 s  the question enters
   0.80 s  both route cards enter together, each already at its final height
   1.40 s  route A: a reading band passes its sentence
           route B: the four key terms pop in, 90 ms apart
   2.20 s  both progress lines run in parallel, A 1.1 s, B 1.4 s
   3.30 s  route A drops Blatt 17 into its reserved slot, 3.60 s route B Blatt 24
   4.20 s  the result enters, 4.60 s the same two chips repeat inside it,
           then the frame holds to 9.6 s

   Every block, both chip slots and both progress rails hold their space from
   frame zero, so nothing in the frame moves except the animated transforms
   themselves. No connectors.
   ========================================================================== */

/* Question, routes and result read as three steps of one thought. The card
   keeps the atom's padding, so a route card and a source page in 02 are the
   same object at the same size; only the inner rhythm is a little wider. */
.assistant-showcase [data-as-scene="suchwege"] .as-routes { align-items: stretch; }
.assistant-showcase [data-as-scene="suchwege"] .as-route { gap: 12px; }
.assistant-showcase [data-as-scene="suchwege"] .as-route-read { display: flex; flex-direction: column; gap: 7px; }
.assistant-showcase [data-as-scene="suchwege"] .as-route-read p { color: var(--lw-text); }

/* The foot is pinned to the bottom of the card, so both progress rails and both
   chips sit on one line whatever the sentence above them wraps to. */
.assistant-showcase [data-as-scene="suchwege"] .as-route-foot { margin-top: auto; display: flex; flex-direction: column; gap: 13px; padding-top: 3px; }

/* The chip slot is present at full size from the first frame; only the chip's
   own opacity and scale animate inside it. */
.assistant-showcase [data-as-scene="suchwege"] .as-locator-slot { display: flex; align-items: center; min-height: 31px; }

/* Two searches run side by side, so the running rail has to be readable
   against its own empty track at a glance; the engine's icon green does that
   and settles when the route is done. The explicit opacity keeps the rail
   visible under any other engine on the page. */
.assistant-showcase [data-as-scene="suchwege"] .m-progress::after { opacity: 1; }

.assistant-showcase [data-as-scene="suchwege"] .as-keywords { gap: 7px; }
.assistant-showcase [data-as-scene="suchwege"] .as-result > strong { display: block; }
.assistant-showcase [data-as-scene="suchwege"] .as-result .as-locators { margin-top: 15px; }
.assistant-showcase [data-as-scene="suchwege"] .as-result .as-locator { background: var(--lw-panel); }

@media (max-width: 700px) {
  .assistant-showcase [data-as-scene="suchwege"] .as-route { gap: 11px; }
  .assistant-showcase [data-as-scene="suchwege"] .as-route-foot { gap: 12px; }
  .assistant-showcase [data-as-scene="suchwege"] .as-result .as-locators { margin-top: 13px; }
}

/* ============================================================================
   05 Diktat
   Spoken text becomes a clean draft, the facts stay untouched.
   0.00 s  the sentence streams in word by word, 55 ms apart
   2.60 s  the command words dim, a reading band passes the sentence
   3.30 s  the set paper enters
   4.20 s  12. Mai 2026 fills, 4.30 s 180,00 Euro fills
   4.60 s  the review line enters, then the frame holds to 9.6 s
   Both blocks hold their space from frame zero, so the frame height is fixed.
   ========================================================================== */

.assistant-showcase [data-as-scene="diktat"] .as-dictated { gap: 7px; }
.assistant-showcase [data-as-scene="diktat"] .as-dictated p { margin-top: 0; }
.assistant-showcase [data-as-scene="diktat"] .as-paper { display: flex; flex-direction: column; gap: 7px; }
.assistant-showcase [data-as-scene="diktat"] .as-paper h4 { margin: 0; }
.assistant-showcase [data-as-scene="diktat"] .as-paper p { margin: 0; }
.assistant-showcase [data-as-scene="diktat"] .as-word { white-space: nowrap; }

/* ============================================================================
   06 Export nach Word
   Selected passages live in LegalWinner, then they leave as one Word document.

   0.00 s  the paper holds its three passages at opacity .28; below it the
           export row already reserves its full space: platform badge, arrow,
           document card (the card and the arrow stroke are still invisible)
   0.50 s  passage 1 highlight fills, 0.62 s the sentence goes to full ink
   1.30 s  passage 2 fills, 1.42 s ink
   2.10 s  passage 3 fills, 2.22 s ink
   2.90 s  the selection chip enters above the paper
   3.50 s  the arrow draws, shaft then head, 420 ms in total
   3.80 s  the document card enters and its three content lines, one per
           selected passage, fill left to right 120 ms apart
   4.30 s  the three selected passages lift 2 px and settle: the export origin
   4.80 s  the review line enters under the document card, hold to 9.6 s

   Every block sits in the layout from frame zero, so the frame height never
   changes. Only opacity, transform, background-size, box-shadow and
   stroke-dashoffset animate.
   ========================================================================== */

/* ---- the source paper ---------------------------------------------------- */

.assistant-showcase [data-as-scene="word"] .as-paper { display: flex; flex-direction: column; gap: 15px; }
.assistant-showcase [data-as-scene="word"] .w-head { display: flex; flex-direction: column; gap: 3px; }
.assistant-showcase [data-as-scene="word"] .as-paper h4 { margin: 0; }

/* One selected passage. The paragraph hugs its highlight, so the lift at 4.3 s
   casts its shadow under the selection and not under the full column width. */
.assistant-showcase [data-as-scene="word"] .w-pass { margin: 0; width: fit-content; max-width: 100%; border-radius: 3px; }
.assistant-showcase [data-as-scene="word"] .w-pass + .w-pass { margin-top: 0; }
.assistant-showcase [data-as-scene="word"] .w-pass b { font-weight: 700; white-space: nowrap; }

/* The highlight itself. m-fill is built for an inline figure, so the block
   behaviour and the wrapping are restated here; the fill keyframe stays the
   engine's. */
.assistant-showcase [data-as-scene="word"] .w-mark { display: block; white-space: normal; margin: 0; padding: 5px 8px; border-radius: 5px; }

/* ---- the export row ------------------------------------------------------ */

.assistant-showcase [data-as-scene="word"] .as-export { align-items: center; column-gap: 14px; row-gap: 12px; }
.assistant-showcase [data-as-scene="word"] .as-export-arrow { width: 24px; height: 24px; }
.assistant-showcase [data-as-scene="word"] .as-export-arrow .m-draw { stroke: var(--lw-icon); stroke-width: 2; stroke-linejoin: round; }

/* The exported document carries the ground of the selection, so the card reads
   as the passages that were just marked. The atom's panel white is the same
   colour as the frame behind it and would only show as a border. */
.assistant-showcase [data-as-scene="word"] .as-export-doc { justify-content: center; padding: 13px 14px; background: var(--lw-selected-soft); }
.assistant-showcase [data-as-scene="word"] .as-export-doc-head span { overflow-wrap: anywhere; }

/* The three content lines of the new document, one per exported passage. They
   start under the file name, not under its icon. */
.assistant-showcase [data-as-scene="word"] .w-doc-lines { display: flex; flex-direction: column; gap: 6px; padding-left: 27px; }
.assistant-showcase [data-as-scene="word"] .w-doc-lines .as-export-line:nth-child(2) { width: 86%; }
.assistant-showcase [data-as-scene="word"] .w-doc-lines .as-export-line:nth-child(3) { width: 64%; }

/* .as-export-line paints its sage through the background shorthand, which
   clears the gradient m-fill animates. Restated at higher specificity so the
   engine's fill keyframe drives these lines too. */
.assistant-showcase [data-as-scene="word"] .as-export-line.m-fill {
  padding: 0;
  margin: 0;
  background-color: transparent;
  background-image: linear-gradient(var(--as-fill), var(--as-fill));
  background-repeat: no-repeat;
  background-position: 0 50%;
  background-size: 100% 100%;
}

/* The review line belongs to the exported document, so it sits in the document
   column. */
.assistant-showcase [data-as-scene="word"] .as-export > .as-review { grid-column: 3; margin: 0; }

@media (max-width: 700px) {
  .assistant-showcase [data-as-scene="word"] .as-paper { gap: 13px; }
  .assistant-showcase [data-as-scene="word"] .as-export > .as-review { grid-column: 1; }
  /* 390: the arrow sits on the icon rail of the two cards it connects, so the
     platform, the arrow and the document read down one axis. */
  .assistant-showcase [data-as-scene="word"] .as-export-arrow { width: 22px; height: 22px; justify-self: start; margin-left: 13px; }
}
