/* ==========================================================================
   Dynamic Mockups — the evolution's app screens
   --------------------------------------------------------------------------
   Each step of the homepage stage shows a simplified screen of the Dynamic
   Mockups app inside the stage's media slot: what the reader will actually see
   once they sign up, drawn in HTML and CSS, with a real render where the app
   would show one. The screen is treated as a PICTURE OF THE PRODUCT, not as
   site UI: everything around it (card, badge, title, exit chip) is the site's
   own language from tokens.css, and everything inside `.dm-evo-screen` reads
   from the `--dm-evo-app-*` variables below, which mirror the app's own theme
   (mockup-generator-react, src/v2/styles/v2.css: a ladder of cool greys on hue
   214, one hairline border, no shadows, 10px base radius, Geist at 14px).

   The oklch literals are a deliberate, documented exception to the tokens-only
   rule: the site's neutrals are warm (page #F4F5F1) and the app's are cool, and
   mapping one onto the other would lose the match this section exists for.
   One screen goes the other way: the composer (Create's opening screen) has
   no app frame around it and floats on the section's own ground, so it reads
   the site's neutral ramp; its override sits at the top of its block.

   Every rule is scoped to `.dm`; every class carries the `dm-` prefix. Nothing
   here moves without `html.dm-motion`.
   ========================================================================== */

.dm .dm-evo-screen {
  /* surfaces, back to front */
  --dm-evo-app-page: oklch(0.94 0.003 214.3);
  --dm-evo-app-well: oklch(0.963 0.003 214.3);
  --dm-evo-app-tile: oklch(0.987 0.002 214.3);
  --dm-evo-app-card: oklch(1 0 0);
  --dm-evo-app-border: oklch(0.925 0.005 214.3);
  --dm-evo-app-ghost: oklch(0.905 0.003 214.3);   /* a picture that is not there yet */
  --dm-evo-app-navy: oklch(0.26 0.075 262);        /* the lookbook's cover: a deep, clearly blue navy */
  /* ink */
  --dm-evo-app-ink: oklch(0.148 0.004 228.8);
  --dm-evo-app-muted: oklch(0.56 0.021 213.5);
  --dm-evo-app-primary: oklch(0.218 0.008 223.9);
  --dm-evo-app-on-primary: oklch(0.987 0.002 214.3);
  /* shape */
  --dm-evo-app-r: 10px;
  --dm-evo-app-r-sm: 6px;
  --dm-evo-app-r-lg: 14px;
  --dm-evo-app-r-pill: 26px;

  position: absolute;
  inset: 0;
  overflow: hidden;
  /* no surface of its own: every screen stands on the stage card (2026-09-10) */
  background: transparent;
  color: var(--dm-evo-app-ink);
  font-family: var(--dm-font-body);
  font-size: 14px;
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
}

/* placeholder while a step's screen is still on the storyboard */
.dm .dm-evo-screen--todo {
  display: grid;
  place-items: center;
}

.dm .dm-evo-screen--todo span {
  font-family: var(--dm-font-mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--dm-evo-app-muted);
}

/* ---------- the screen's grammar ----------
   Everything below is a 0.46-scale picture of the app: 10px type, 34px top
   nav, 12-14px radii. Body copy inside a screen is skeleton bars, never real
   sentences; only titles, chips and buttons carry words. */
.dm .dm-evo-screen {
  display: flex;
  flex-direction: column;
  font-size: 10px;
  line-height: 1.3;
}
/* display above outranks the UA's [hidden]; a screen parked beside its
   replacement (the lookbook fan next to the book) needs this to be gone */
.dm .dm-evo-screen[hidden] { display: none; }

/* top nav: same tone as the page, menu centred, the active stage a white pill */
.dm .dm-evo-nav {
  position: relative;
  flex: none;
  height: 34px;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 14px;
}

.dm .dm-evo-nav-ws { display: flex; align-items: center; gap: 6px; font-weight: 500; }
.dm .dm-evo-nav-ws i { display: block; width: 14px; height: 14px; border-radius: 4px; background: var(--dm-evo-app-primary); }

.dm .dm-evo-nav-menu {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 2px;
}

.dm .dm-evo-nav-menu span { padding: 4px 8px; border-radius: 999px; color: var(--dm-evo-app-muted); }
.dm .dm-evo-nav-menu .is-on { background: var(--dm-evo-app-card); color: var(--dm-evo-app-ink); box-shadow: 0 0 0 1px var(--dm-evo-app-border); }

.dm .dm-evo-nav-right { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.dm .dm-evo-avatar { width: 16px; height: 16px; border-radius: 999px; background: var(--dm-evo-app-border); }

.dm .dm-evo-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 8px;
  border: 1px solid var(--dm-evo-app-border);
  border-radius: 999px;
  background: var(--dm-evo-app-card);
  font-size: 9px;
  font-weight: 500;
  white-space: nowrap;
}

/* buttons: one dark primary, one hairline ghost, pill-shaped like the app's */
.dm .dm-evo-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  height: 20px;
  padding: 0 9px;
  border-radius: 999px;
  background: var(--dm-evo-app-primary);
  color: var(--dm-evo-app-on-primary);
  font-size: 9px;
  font-weight: 500;
  white-space: nowrap;
}

.dm .dm-evo-btn--ghost {
  background: var(--dm-evo-app-card);
  color: var(--dm-evo-app-ink);
  border: 1px solid var(--dm-evo-app-border);
}

/* skeleton text */
.dm .dm-evo-line { display: block; height: 5px; border-radius: 999px; background: var(--dm-evo-app-border); }
.dm .dm-evo-line--ink { background: var(--dm-evo-app-muted); opacity: 0.55; }

/* library shell: rail + pane card */
.dm .dm-evo-main {
  flex: 1;
  min-height: 0;
  display: flex;
  gap: 10px;
  padding: 0 12px 12px;
}

.dm .dm-evo-rail {
  flex: none;
  width: 92px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px;
  border: 1px solid var(--dm-evo-app-border);
  border-radius: 12px;
  background: var(--dm-evo-app-tile);
}

.dm .dm-evo-rail h4 { margin: 2px 4px 6px; font-size: 10px; font-weight: 600; }
.dm .dm-evo-rail span { padding: 4px 6px; border-radius: 7px; color: var(--dm-evo-app-muted); }
.dm .dm-evo-rail .is-on { background: var(--dm-evo-app-card); color: var(--dm-evo-app-ink); box-shadow: 0 0 0 1px var(--dm-evo-app-border); }

.dm .dm-evo-pane {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--dm-evo-app-border);
  border-radius: 12px;
  background: var(--dm-evo-app-tile);
}

.dm .dm-evo-pane-head { flex: none; display: flex; align-items: center; gap: 8px; padding: 7px 10px; }
.dm .dm-evo-pane-head h4 { margin: 0; font-size: 11px; font-weight: 600; }
.dm .dm-evo-search { margin-left: auto; width: 34%; height: 18px; border: 1px solid var(--dm-evo-app-border); border-radius: 999px; background: var(--dm-evo-app-card); }
.dm .dm-evo-pane-body { position: relative; flex: 1; min-height: 0; padding: 10px; background: var(--dm-evo-app-well); }

/* tiles */
.dm .dm-evo-grid { display: grid; grid-template-columns: repeat(var(--cols, 4), 1fr); gap: 8px; }

.dm .dm-evo-tile {
  position: relative;
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  overflow: hidden;
  border: 1px solid var(--dm-evo-app-border);
  border-radius: 8px;
  background: var(--dm-evo-app-tile);
}

.dm .dm-evo-tile.is-on { box-shadow: inset 0 0 0 2px var(--dm-evo-app-primary); }

/* a product silhouette with the design sitting on its print area */
.dm .dm-evo-product { position: relative; width: 72%; height: 72%; }
.dm .dm-evo-product > svg { display: block; width: 100%; height: 100%; fill: var(--dm-evo-prod, #fff); stroke: var(--dm-evo-app-border); stroke-width: 1.5; }
.dm .dm-evo-product .dm-evo-mark { position: absolute; left: 50%; top: var(--my, 50%); width: var(--mw, 34%); height: var(--mw, 34%); transform: translate(-50%, -50%); }
.dm .dm-evo-product .dm-evo-area { position: absolute; left: 50%; top: var(--my, 50%); width: calc(var(--mw, 34%) + 12%); height: calc(var(--mw, 34%) + 12%); transform: translate(-50%, -50%); border: 1px dashed var(--dm-evo-app-muted); border-radius: 2px; }
.dm .dm-evo-mark { display: block; }
.dm .dm-evo-mark svg { display: block; width: 100%; height: 100%; }

/* editor frame: header strip, well body, side column */
.dm .dm-evo-editor {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  margin: 10px 12px 12px;
  border: 1px solid var(--dm-evo-app-border);
  border-radius: 14px;
  background: var(--dm-evo-app-card);
}

.dm .dm-evo-editor-head {
  flex: none;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border-bottom: 1px solid var(--dm-evo-app-border);
  background: var(--dm-evo-app-tile);
}

.dm .dm-evo-editor-head h4 { margin: 0; font-size: 11px; font-weight: 500; }
.dm .dm-evo-editor-head .dm-evo-actions { margin-left: auto; display: flex; gap: 6px; }
.dm .dm-evo-editor-body { position: relative; flex: 1; min-height: 0; display: flex; gap: 10px; padding: 10px; background: var(--dm-evo-app-well); }

.dm .dm-evo-canvas {
  position: relative;
  flex: 1;
  min-width: 0;
  display: grid;
  place-items: center;
  overflow: hidden;
  border-radius: 10px;
  background: var(--dm-evo-app-tile);
}

.dm .dm-evo-canvas .dm-evo-product { width: 58%; height: 78%; }
.dm .dm-evo-canvas img.dm-evo-shot { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.dm .dm-evo-side { flex: none; width: 30%; display: flex; flex-direction: column; gap: 8px; }
.dm .dm-evo-side-card { display: flex; flex-direction: column; gap: 6px; padding: 8px; border: 1px solid var(--dm-evo-app-border); border-radius: 8px; background: var(--dm-evo-app-card); }
.dm .dm-evo-side-card h5 { margin: 0; font-size: 8px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--dm-evo-app-muted); }

.dm .dm-evo-chips { display: flex; gap: 6px; }
.dm .dm-evo-chip { width: 14px; height: 14px; border-radius: 999px; background: var(--c); box-shadow: 0 0 0 1px var(--dm-evo-app-border); }
.dm .dm-evo-chip.is-on { box-shadow: 0 0 0 2px var(--dm-evo-app-primary); }

/* ---------- detail screens ----------
   The square slot is a crop of the app around the object, not a whole window:
   no nav, no rail, the canvas fills the slot, the product (later the real
   render) is the picture, and only the one or two controls that carry the
   step's verb float in the corners, drawn in the app's language. */
.dm .dm-evo-screen--detail { padding: 0; }
/* `isolation` keeps the picture layers' stacking order inside the canvas, so a
   photo on its way in never rises above the controls floating next to it */
.dm .dm-evo-screen--detail .dm-evo-canvas { position: absolute; inset: 0; border-radius: 0; background: transparent; isolation: isolate; }
.dm .dm-evo-screen--detail .dm-evo-canvas .dm-evo-product { width: auto; height: 74%; aspect-ratio: 1; }
.dm .dm-evo-float-card {
  position: absolute;
  left: 16px;
  bottom: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 12px;
  border: 1px solid var(--dm-evo-app-border);
  border-radius: var(--dm-evo-app-r);
  background: var(--dm-evo-app-card);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.06);
}
.dm .dm-evo-float-card h5 { margin: 0; font-size: 9px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--dm-evo-app-muted); }
.dm .dm-evo-float-card .dm-evo-chips { gap: 8px; }
.dm .dm-evo-float-card .dm-evo-chip { width: 18px; height: 18px; }
/* the template's facts, top right, where a button used to be (03) */
.dm .dm-evo-float-card--info { left: auto; bottom: auto; right: 16px; top: 16px; gap: 5px; }
.dm .dm-evo-float-card--info strong { font-size: 10px; font-weight: 600; }
.dm .dm-evo-float-card--info ul { display: grid; gap: 3px; margin: 0; padding: 0; list-style: none; }
.dm .dm-evo-float-card--info li { font-size: 9px; color: var(--dm-evo-app-muted); }
.dm .dm-evo-float-card--info li::before { content: "\2013\00a0"; }
.dm .dm-evo-float-actions { position: absolute; right: 16px; top: 16px; display: flex; gap: 8px; }
.dm .dm-evo-float-actions .dm-evo-btn { height: 28px; padding: 0 13px; font-size: 11px; }

/* the floating selection bar of the batch flow */
.dm .dm-evo-float {
  position: absolute;
  left: 50%;
  bottom: 12px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 6px 5px 12px;
  border: 1px solid var(--dm-evo-app-border);
  border-radius: 999px;
  background: var(--dm-evo-app-card);
  box-shadow: 0 8px 24px rgba(20, 20, 18, 0.10);
  font-size: 9px;
  white-space: nowrap;
}

.dm .dm-evo-float i { width: 1px; height: 12px; background: var(--dm-evo-app-border); }

/* layouts: the same picture in a square, a tall, a wide and a custom frame */
.dm .dm-evo-frames { display: flex; align-items: flex-end; gap: 10px; height: 100%; }

.dm .dm-evo-frame {
  position: relative;
  display: grid;
  place-items: center;
  overflow: hidden;
  border: 1px solid var(--dm-evo-app-border);
  border-radius: 8px;
  background: var(--dm-evo-app-tile);
}

.dm .dm-evo-frame .dm-evo-product { width: 64%; height: 64%; }
.dm .dm-evo-frame--sq { flex: 0 0 34%; aspect-ratio: 1; }
.dm .dm-evo-frame--tall { flex: 0 0 20%; aspect-ratio: 9 / 16; }
.dm .dm-evo-frame--wide { flex: 1; aspect-ratio: 16 / 9; }
.dm .dm-evo-frame--custom { flex: 0 0 12%; aspect-ratio: 3 / 4; border-style: dashed; background: transparent; color: var(--dm-evo-app-muted); font-size: 16px; }
.dm .dm-evo-frame small { position: absolute; left: 6px; bottom: 4px; font-size: 8px; color: var(--dm-evo-app-muted); }

/* lookbook: fanned pages and the send-side metadata */
.dm .dm-evo-book { position: relative; flex: 0 0 46%; }
.dm .dm-evo-page { position: absolute; inset: 0; display: grid; place-items: center; border: 1px solid var(--dm-evo-app-border); border-radius: 8px; background: var(--dm-evo-app-card); }
.dm .dm-evo-page:nth-child(1) { transform: translate(16px, -12px) rotate(3deg); }
.dm .dm-evo-page:nth-child(2) { transform: translate(8px, -6px) rotate(1.5deg); }
.dm .dm-evo-page .dm-evo-product { width: 56%; height: 56%; }
.dm .dm-evo-client { position: absolute; left: 10px; top: 8px; font-size: 8px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--dm-evo-app-muted); }

.dm .dm-evo-meta { flex: 1; display: flex; flex-direction: column; justify-content: center; gap: 8px; }
.dm .dm-evo-meta h5 { margin: 0; font-size: 12px; font-weight: 600; }
.dm .dm-evo-tags { display: flex; flex-wrap: wrap; gap: 6px; }
.dm .dm-evo-tag { display: inline-flex; align-items: center; gap: 5px; padding: 3px 8px; border: 1px solid var(--dm-evo-app-border); border-radius: 999px; background: var(--dm-evo-app-tile); font-size: 9px; }
.dm .dm-evo-tag svg { width: 10px; height: 10px; stroke: currentColor; fill: none; stroke-width: 1.75; }

/* player */
.dm .dm-evo-playbtn { position: absolute; left: 50%; top: 50%; width: 34px; height: 34px; transform: translate(-50%, -50%); display: grid; place-items: center; border-radius: 999px; background: rgba(255, 255, 255, 0.92); box-shadow: 0 4px 14px rgba(20, 20, 18, 0.12); }
.dm .dm-evo-playbtn svg { width: 14px; height: 14px; fill: var(--dm-evo-app-ink); }
.dm .dm-evo-bar { position: absolute; left: 12px; right: 12px; bottom: 10px; height: 3px; overflow: hidden; border-radius: 999px; background: rgba(20, 20, 18, 0.14); }
.dm .dm-evo-bar::after { content: ""; position: absolute; inset: 0; width: 46%; border-radius: 999px; background: var(--dm-evo-app-primary); }
.dm .dm-evo-time { position: absolute; right: 12px; bottom: 16px; font-size: 8px; font-family: var(--dm-font-mono); color: var(--dm-evo-app-muted); }
.dm .dm-evo-corner { position: absolute; right: 10px; top: 10px; display: flex; gap: 4px; }

@keyframes dm-evo-play { from { width: 0; } to { width: 100%; } }
.dm-motion .dm .dm-evo-bar::after { animation: dm-evo-play 8s linear infinite; }

/* stitch: parameter column, viewer, file cards */
.dm .dm-evo-stitch .dm-evo-side { width: 34%; }
.dm .dm-evo-stitch .dm-evo-canvas .dm-evo-product { width: 48%; height: 62%; }
.dm .dm-evo-files { position: absolute; left: 10px; right: 10px; bottom: 10px; display: flex; gap: 8px; }
.dm .dm-evo-file { flex: 1; display: flex; align-items: center; gap: 6px; padding: 6px 8px; border: 1px solid var(--dm-evo-app-border); border-radius: 8px; background: var(--dm-evo-app-card); font-size: 9px; white-space: nowrap; }
.dm .dm-evo-file b { padding: 1px 5px; border-radius: 4px; background: var(--dm-evo-app-well); font-family: var(--dm-font-mono); font-size: 8px; font-weight: 600; }

/* automate: no code on screen — a hand-off diagram */
.dm .dm-evo-flow { flex: 1; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 12px; padding: 16px 18px 18px; }
.dm .dm-evo-node { display: flex; flex-direction: column; gap: 6px; padding: 10px; border: 1px solid var(--dm-evo-app-border); border-radius: 12px; background: var(--dm-evo-app-card); }
.dm .dm-evo-node h5 { margin: 0 0 2px; font-size: 10px; font-weight: 600; }
.dm .dm-evo-node .dm-evo-row { display: flex; align-items: center; gap: 6px; }
.dm .dm-evo-node .dm-evo-row .dm-evo-mark { width: 12px; height: 12px; flex: none; }
.dm .dm-evo-hubcol { display: flex; flex-direction: column; align-items: center; gap: 6px; font-size: 8px; color: var(--dm-evo-app-muted); white-space: nowrap; }
.dm .dm-evo-hub { display: grid; place-items: center; width: 56px; height: 56px; border: 1px solid var(--dm-evo-app-border); border-radius: 999px; background: var(--dm-evo-app-card); }
.dm .dm-evo-hub img { width: 26px; height: 26px; }
.dm .dm-evo-outs { display: flex; flex-direction: column; gap: 6px; }
.dm .dm-evo-outs .dm-evo-file { flex: none; }

/* small parts the nine screens share */
.dm .dm-evo-pane-body--row { display: flex; gap: 14px; }
.dm .dm-evo-pane-body--col { display: flex; flex-direction: column; gap: 10px; }
.dm .dm-evo-grid--fill { height: 100%; grid-auto-rows: 1fr; }
.dm .dm-evo-grid--fill .dm-evo-tile { aspect-ratio: auto; }
.dm .dm-evo-drop { flex: 1; min-height: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; border: 1px dashed var(--dm-evo-app-muted); border-radius: 10px; background: var(--dm-evo-app-tile); color: var(--dm-evo-app-muted); }
.dm .dm-evo-drop .dm-evo-mark { width: 44px; height: 44px; }
.dm .dm-evo-drop strong { font-size: 10px; font-weight: 500; color: var(--dm-evo-app-ink); }
.dm .dm-evo-drop small { font-size: 8px; }
.dm .dm-evo-strip { flex: none; display: flex; gap: 8px; }
.dm .dm-evo-strip .dm-evo-tile { width: 44px; }
.dm .dm-evo-back { display: grid; place-items: center; width: 14px; height: 14px; font-size: 14px; line-height: 1; color: var(--dm-evo-app-muted); }
.dm .dm-evo-tool { display: grid; place-items: center; width: 16px; height: 16px; border-radius: 5px; background: var(--dm-evo-app-well); color: var(--dm-evo-app-primary); }
.dm .dm-evo-tool svg { width: 10px; height: 10px; stroke: currentColor; fill: none; stroke-width: 1.75; }
.dm .dm-evo-hubrow { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--dm-evo-app-muted); }
.dm .dm-evo-pill.is-on { background: var(--dm-evo-app-primary); color: var(--dm-evo-app-on-primary); border-color: var(--dm-evo-app-primary); }
.dm .dm-evo-file .dm-evo-product { width: 14px; height: 14px; flex: none; }
.dm .dm-evo-rail .dm-evo-line { margin: 6px 6px; width: 64%; }

/* ==========================================================================
   The nine stations as detail crops (plan of 2026-09-10)
   --------------------------------------------------------------------------
   Every screen is `.dm-evo-screen--detail`: the canvas fills the slot, the
   product (a silhouette until the real photo lands, then `.dm-evo-shot`) is the
   picture, and at most two app controls float in the corners. The design that
   travels through the story is the logo mark (`#dm-evo-logo`), dark on light
   products and light on dark ones. One beat per station, CSS wherever the beat
   needs no data, JS (evolution.js) only for the photo swap and the videos.
   ========================================================================== */

/* the logo mark: fill inherits, so the same symbol reads on white and on black */
.dm .dm-evo-logo { display: block; }
.dm .dm-evo-logo svg { display: block; width: 100%; height: 100%; fill: currentColor; }
.dm .dm-evo-mark { color: var(--dm-evo-app-ink); }
.dm .dm-evo-mark svg { fill: currentColor; }
.dm .is-dark .dm-evo-mark { color: var(--dm-evo-app-on-primary); }

/* photos and videos: stacked in the canvas, cover, only the active one visible.
   The swap dissolves ONE layer: the frame that is leaving keeps full opacity a
   layer down, so the incoming colour fades over a picture and never over the
   empty well. Two layers fading at once leave a gap the well shines through,
   which reads as a white flash on frames that differ only in colour. The ease
   is symmetric for the same reason: no snap at either end. */
.dm .dm-evo-shot { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; }
.dm .dm-evo-shot.is-on, .dm .dm-evo-shot:only-of-type { opacity: 1; }
.dm .dm-evo-shot.is-on { z-index: 2; }
.dm .dm-evo-shot.is-prev { opacity: 1; z-index: 1; }
.dm-motion .dm .dm-evo-shot { transition: opacity 620ms cubic-bezier(0.4, 0, 0.6, 1); }
.dm .dm-evo-video { pointer-events: none; }
/* the lifestyle renders are square; in the 1.6 slot they show their upper band
   (cap to below the print), never a headless torso */
.dm .dm-evo-shot--scene { object-position: 50% 21%; }

/* 04 · the shop, in two acts on one 8 s line. First the app: a four by two
   of finished mockups, a marquee drawn over them, the count. Then the seller's
   storefront: the listing behind, the open product page in front, stacked the
   way the reel sits over the still on station 7, and a shopper picks the black
   one. Without motion the storefront stands. */
.dm .dm-evo-screen--shop { overflow: visible; }
.dm .dm-evo-screen--shop .dm-evo-canvas { display: block; overflow: visible; }
/* the storefront: two low-fidelity pages, real pictures, grey lines for the words */
.dm .dm-evo-store, .dm .dm-evo-pdp { position: absolute; display: flex; flex-direction: column; padding: 10px; border: 1px solid var(--dm-evo-app-border); border-radius: var(--dm-evo-app-r); background: var(--dm-evo-app-card); }
.dm .dm-evo-store { left: 0; top: 3%; bottom: 3%; z-index: 1; width: 60%; gap: 10px; box-shadow: 0 8px 22px rgba(20, 20, 18, 0.13); }
.dm .dm-evo-store-bar { display: flex; align-items: center; gap: 6px; height: 18px; }
.dm .dm-evo-store-bar b { margin-right: 6px; font-family: var(--dm-font-body); letter-spacing: -0.01em; font-size: 12px; font-weight: 600; letter-spacing: -0.01em; }
.dm .dm-evo-store-bar i { width: 18px; height: 4px; border-radius: 999px; background: var(--dm-evo-app-border); }
.dm .dm-evo-store-bar svg { width: 12px; height: 12px; margin-left: auto; fill: none; stroke: var(--dm-evo-app-ink); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.dm .dm-evo-store-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.dm .dm-evo-store-item { display: flex; flex-direction: column; gap: 4px; }
.dm .dm-evo-store-pic { position: relative; display: grid; place-items: center; aspect-ratio: 1; overflow: hidden; margin-bottom: 2px; border-radius: var(--dm-evo-app-r-sm); background: var(--dm-evo-app-tile); }
.dm .dm-evo-line { display: block; width: var(--w, 70%); height: 4px; border-radius: 999px; background: var(--dm-evo-app-border); }
.dm .dm-evo-line--price { width: 34%; }
.dm .dm-evo-pdp { right: 0; top: 0; bottom: 0; z-index: 2; width: 48%; gap: 8px; box-shadow: -8px 14px 38px rgba(20, 20, 18, 0.18); }
.dm .dm-evo-pdp-pic { position: relative; aspect-ratio: 5 / 4; overflow: hidden; border-radius: var(--dm-evo-app-r-sm); background: var(--dm-evo-app-tile); }
.dm .dm-evo-pdp-alt { z-index: 3; }
.dm .dm-evo-pdp-row { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
/* the swatches, the sizes and the button hold the bottom edge, so the black
   swatch is a fixed distance from it and the cursor can find it at any width */
.dm .dm-evo-pdp-swatches { margin-top: auto; }
.dm .dm-evo-pdp-row b { font-size: 12px; font-weight: 600; }
.dm .dm-evo-pdp-row span { font-size: 11px; color: var(--dm-evo-app-muted); }
.dm .dm-evo-pdp-sizes { display: flex; gap: 4px; }
.dm .dm-evo-pdp-sizes i { display: grid; place-items: center; min-width: 22px; height: 16px; padding: 0 5px; border: 1px solid var(--dm-evo-app-border); border-radius: 4px; font-size: 7px; font-style: normal; font-weight: 600; color: var(--dm-evo-app-muted); }
.dm .dm-evo-pdp-sizes i:first-child { border-color: var(--dm-evo-app-ink); color: var(--dm-evo-app-ink); }
.dm .dm-evo-pdp-cta { display: grid; place-items: center; height: 26px; border-radius: var(--dm-evo-app-r-sm); background: var(--dm-evo-app-primary); color: var(--dm-evo-app-on-primary); font-size: 10px; font-weight: 600; }
/* the app: the batch result, eight tiles that come out square in a slot 1.6
   wide (12% above and below, 3% at the sides) */
.dm .dm-evo-batch { position: absolute; inset: 12% 3%; z-index: 3; display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(2, 1fr); gap: 7px; opacity: 0; }
.dm .dm-evo-batch-tile { position: relative; display: grid; place-items: center; overflow: hidden; border: 1px solid var(--dm-evo-app-border); border-radius: var(--dm-evo-app-r); background: var(--dm-evo-app-tile); }
.dm .dm-evo-batch-tile::after { content: ""; position: absolute; inset: 0; z-index: 3; border: 2px solid var(--dm-evo-app-primary); border-radius: inherit; opacity: 0; pointer-events: none; }
.dm .dm-evo-pick { position: absolute; left: 6px; top: 6px; z-index: 4; display: grid; place-items: center; width: 16px; height: 16px; border-radius: 999px; background: var(--dm-evo-app-primary); opacity: 0; transform: scale(0.6); }
.dm .dm-evo-pick svg { width: 10px; height: 10px; fill: none; stroke: var(--dm-evo-app-on-primary); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.dm .dm-evo-marquee { position: absolute; left: -3%; top: -3%; z-index: 5; width: 0; height: 0; border: 1.5px solid var(--dm-evo-app-primary); border-radius: 4px; background: rgba(20, 20, 18, 0.05); opacity: 0; pointer-events: none; }
.dm .dm-evo-count { position: absolute; left: 50%; bottom: calc(12% - 13px); z-index: 4; display: flex; align-items: center; gap: 6px; height: 26px; padding: 0 12px 0 9px; border-radius: 999px; background: var(--dm-evo-app-primary); color: var(--dm-evo-app-on-primary); font-size: 10px; font-weight: 600; white-space: nowrap; box-shadow: 0 8px 20px rgba(20, 20, 18, 0.18); opacity: 0; transform: translate(-50%, 0); }
.dm .dm-evo-count svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.dm .dm-evo-cursor { --dm-evo-sw-x: calc(52% + 34px); --dm-evo-sw-y: calc(100% - 78px); position: absolute; left: 0; top: 9%; z-index: 6; width: 18px; height: 18px; fill: #fff; stroke: var(--dm-evo-app-ink); stroke-width: 1.5; stroke-linejoin: round; opacity: 0; pointer-events: none; }
/* the line: grid in (0–5%), marquee and cursor corner to corner (8–28%) with
   the tiles ticking in three groups behind it, the count (31%), the grid packs
   up (40–46%) while the two pages rise (43–52%) and the products land, the
   cursor comes back for the black swatch (60–63%), a long look, the pages go
   (91–96%) and the grid is back at 0 */
@keyframes dm-evo-batch { 0% { opacity: 0; transform: scale(0.96); } 5%, 40% { opacity: 1; transform: none; } 46%, 100% { opacity: 0; transform: scale(0.9); } }
@keyframes dm-evo-marquee { 0%, 8% { width: 0; height: 0; opacity: 0; } 9% { opacity: 1; } 28% { width: 106%; height: 106%; opacity: 1; } 31%, 100% { width: 106%; height: 106%; opacity: 0; } }
@keyframes dm-evo-ring { 0%, 14% { opacity: 0; } 16%, 44% { opacity: 1; } 46%, 100% { opacity: 0; } }
@keyframes dm-evo-pick { 0%, 14% { opacity: 0; transform: scale(0.6); } 16%, 44% { opacity: 1; transform: none; } 46%, 100% { opacity: 0; transform: scale(0.6); } }
@keyframes dm-evo-count { 0%, 28% { opacity: 0; transform: translate(-50%, 6px); } 31%, 40% { opacity: 1; transform: translate(-50%, 0); } 45%, 100% { opacity: 0; transform: translate(-50%, 0); } }
@keyframes dm-evo-store { 0%, 43% { opacity: 0; transform: translateY(14px); } 49%, 91% { opacity: 1; transform: none; } 96%, 100% { opacity: 0; transform: none; } }
@keyframes dm-evo-pdp { 0%, 45% { opacity: 0; transform: translateY(18px); } 52%, 91% { opacity: 1; transform: none; } 96%, 100% { opacity: 0; transform: none; } }
@keyframes dm-evo-store-item { 0%, 47% { opacity: 0; transform: scale(0.9); } 51%, 100% { opacity: 1; transform: none; } }
@keyframes dm-evo-pdp-alt { 0%, 61% { opacity: 0; } 65%, 100% { opacity: 1; } }
@keyframes dm-evo-swatch-off { 0%, 61% { box-shadow: 0 0 0 2px var(--dm-evo-app-primary); } 63%, 100% { box-shadow: 0 0 0 1px var(--dm-evo-app-border); } }
@keyframes dm-evo-swatch-on { 0%, 61% { box-shadow: 0 0 0 1px var(--dm-evo-app-border); } 63%, 100% { box-shadow: 0 0 0 2px var(--dm-evo-app-primary); } }
@keyframes dm-evo-cursor {
  0%, 5% { left: 0; top: 9%; opacity: 0; transform: none; }
  8% { left: 0; top: 9%; opacity: 1; animation-timing-function: linear; }
  28%, 30% { left: 102%; top: 92%; opacity: 1; }
  34% { left: 102%; top: 92%; opacity: 0; }
  52% { left: 72%; top: 86%; opacity: 0; animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); }
  55% { opacity: 1; }
  60% { left: var(--dm-evo-sw-x); top: var(--dm-evo-sw-y); opacity: 1; transform: none; }
  61.5% { transform: scale(0.82); }
  63%, 66% { left: var(--dm-evo-sw-x); top: var(--dm-evo-sw-y); opacity: 1; transform: none; }
  70%, 100% { left: var(--dm-evo-sw-x); top: var(--dm-evo-sw-y); opacity: 0; transform: none; }
}
.dm-motion .dm-stage-panel.is-on .dm-evo-batch { animation: dm-evo-batch 8000ms var(--dm-ease-press) infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-marquee { animation: dm-evo-marquee 8000ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-batch-tile::after { animation: dm-evo-ring 8000ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-pick { animation: dm-evo-pick 8000ms var(--dm-ease-press) infinite; }
/* the marquee reaches the tiles along the diagonal, five groups from the top
   left to the bottom right */
.dm-motion .dm-stage-panel.is-on .dm-evo-batch-tile::after, .dm-motion .dm-stage-panel.is-on .dm-evo-pick { animation-delay: calc(var(--g, 0) * 200ms); }
.dm-motion .dm-stage-panel.is-on .dm-evo-count { animation: dm-evo-count 8000ms var(--dm-ease-press) infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-store { animation: dm-evo-store 8000ms var(--dm-ease-press) infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-pdp { animation: dm-evo-pdp 8000ms var(--dm-ease-press) infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-store-item { animation: dm-evo-store-item 8000ms var(--dm-ease-press) infinite; animation-delay: calc(var(--i, 0) * 70ms); }
.dm-motion .dm-stage-panel.is-on .dm-evo-pdp-alt { animation: dm-evo-pdp-alt 8000ms var(--dm-ease-press) infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-pdp-swatches .dm-evo-chip:nth-child(1) { animation: dm-evo-swatch-off 8000ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-pdp-swatches .dm-evo-chip:nth-child(2) { animation: dm-evo-swatch-on 8000ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-cursor { animation: dm-evo-cursor 8000ms linear infinite; }

/* 05 · one frame that changes shape: square, tall, wide, with the preset's name;
   the tall one carries the motion clip */
.dm .dm-evo-screen--morph .dm-evo-canvas { display: grid; place-items: center; }
.dm .dm-evo-screen--morph { overflow: visible; }
.dm .dm-evo-screen--morph .dm-evo-canvas { overflow: visible; }
.dm .dm-evo-morph { position: relative; width: 62.5%; height: 100%; overflow: hidden; border-radius: var(--dm-evo-app-r); box-shadow: 0 12px 34px rgba(20, 20, 18, 0.16); }
.dm .dm-evo-morph .dm-evo-product { position: absolute; left: 50%; top: 50%; width: auto; height: 72%; aspect-ratio: 1; transform: translate(-50%, -50%); }
/* the clip: the Story shape is the one the motion mockup was made in, so the
   clip lives inside that hold only. It sits over the tee photo and under the
   story overlay, fades in and out on its own keyframe inside the frame's still
   window (the frame holds 35.2% wide from 24% to 68% of the 9s round), and stays at zero in the
   other two shapes and without motion, where the tee photo is the still. The
   poster is the clip's own first frame and lives on the poster attribute: a
   second <img> in here would cost the tee photo its :only-of-type and blank it. */
.dm .dm-evo-morph .dm-evo-video { opacity: 0; }
@keyframes dm-evo-morph-clip { 0%, 24% { opacity: 0; } 27%, 65% { opacity: 1; } 68%, 100% { opacity: 0; } }
.dm-motion .dm-stage-panel.is-on .dm-evo-morph .dm-evo-video { animation: dm-evo-morph-clip 9000ms linear infinite; }
/* top right, clear of the story's progress bars above it and of the post
   content below, which owns the bottom of the frame */
.dm .dm-evo-morph-labels { position: absolute; right: 9px; top: 18px; display: grid; }
.dm .dm-evo-morph-labels small { grid-area: 1 / 1; justify-self: end; padding: 4px 9px; border-radius: 999px; background: rgba(20, 20, 18, 0.44); font-size: 9px; font-weight: 500; white-space: nowrap; color: #fff; opacity: 0; }
.dm .dm-evo-morph-labels small:first-child { opacity: 1; }
/* a 9s round: the square rests 1.6s, the tall story shape holds 4s because it carries
   the clip, the wide one rests 1.6s; the moves between them take 0.55s each */
@keyframes dm-evo-morph { 0%, 18% { width: 62.5%; height: 100%; } 24%, 68% { width: 35.2%; height: 100%; } 74%, 92% { width: 100%; height: 90%; } 100% { width: 62.5%; height: 100%; } }
@keyframes dm-evo-lab-1 { 0%, 20% { opacity: 1; } 21%, 95% { opacity: 0; } 96%, 100% { opacity: 1; } }
@keyframes dm-evo-lab-2 { 0%, 20% { opacity: 0; } 21%, 70% { opacity: 1; } 71%, 100% { opacity: 0; } }
@keyframes dm-evo-lab-3 { 0%, 70% { opacity: 0; } 71%, 95% { opacity: 1; } 96%, 100% { opacity: 0; } }
.dm-motion .dm-stage-panel.is-on .dm-evo-morph { animation: dm-evo-morph 9000ms cubic-bezier(.5, 0, .5, 1) infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-morph-labels small:nth-child(1) { animation: dm-evo-lab-1 9000ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-morph-labels small:nth-child(2) { animation: dm-evo-lab-2 9000ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-morph-labels small:nth-child(3) { animation: dm-evo-lab-3 9000ms linear infinite; }

/* What each shape is actually used for, laid over the picture, set like the
   creatives a shop would actually export: the site's own display face for the
   headline, one campaign colour across the formats, a real button. The story
   carries its bars, a sticker, a headline and the button; the thumbnail one
   tag, one big line and the handle; the square carries nothing at all, because
   a square post is usually just the picture. They change with the shape, on
   the label's own keyframes. */
.dm .dm-evo-post { position: absolute; inset: 0; opacity: 0; color: #fff; }
/* the feed post: the tag up top, the line and the handle along the bottom; it
   is the shape the frame rests in, so it is the one that shows without motion */
.dm .dm-evo-post--feed { opacity: 1; display: flex; flex-direction: column; justify-content: space-between; align-items: flex-start; padding: 12px; background: linear-gradient(to top, rgba(10, 12, 18, 0.74), rgba(10, 12, 18, 0.22) 34%, rgba(10, 12, 18, 0) 54%); }
.dm .dm-evo-post-row { display: flex; align-items: flex-end; justify-content: space-between; gap: 10px; align-self: stretch; }
.dm .dm-evo-post-row b { max-width: 72%; font-family: var(--dm-font-display); font-size: 30px; font-weight: 600; line-height: 0.95; letter-spacing: -0.02em; text-wrap: balance; }
.dm .dm-evo-post-row small { font-size: 9px; font-weight: 500; color: rgba(255, 255, 255, 0.72); white-space: nowrap; }
.dm .dm-evo-post--story { display: flex; flex-direction: column; justify-content: space-between; padding: 10px; background: linear-gradient(to bottom, rgba(10, 12, 18, 0.34), rgba(10, 12, 18, 0) 24%), linear-gradient(to top, rgba(10, 12, 18, 0.82), rgba(10, 12, 18, 0.36) 34%, rgba(10, 12, 18, 0) 56%); }
.dm .dm-evo-post-bars { display: flex; gap: 3px; }
.dm .dm-evo-post-bars i { flex: 1; height: 2px; border-radius: 999px; background: rgba(255, 255, 255, 0.4); }
.dm .dm-evo-post-bars i:first-child { background: #fff; }
.dm .dm-evo-post-body { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.dm .dm-evo-sticker { display: inline-block; padding: 4px 9px; border-radius: 999px; background: var(--dm-pink-400); font-style: normal; font-size: 8px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; transform: rotate(-5deg); transform-origin: left bottom; }
.dm .dm-evo-post-body b { font-family: var(--dm-font-display); font-size: 27px; font-weight: 600; line-height: 0.96; letter-spacing: -0.02em; text-wrap: balance; }
.dm .dm-evo-post-cta { display: flex; align-items: center; justify-content: center; gap: 5px; align-self: stretch; height: 28px; border-radius: 999px; background: #fff; color: var(--dm-evo-app-ink); font-size: 10px; font-weight: 600; }
.dm .dm-evo-post-cta svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.dm .dm-evo-post--thumb { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 10px; padding: 0 6%; background: linear-gradient(to right, rgba(10, 12, 18, 0.78), rgba(10, 12, 18, 0.4) 44%, rgba(10, 12, 18, 0) 76%); }
.dm .dm-evo-post-tag { display: inline-block; padding: 4px 8px; border-radius: 4px; background: var(--dm-pink-400); font-style: normal; font-size: 8px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; }
.dm .dm-evo-post--thumb b { max-width: 58%; font-family: var(--dm-font-display); font-size: 40px; font-weight: 600; line-height: 0.95; letter-spacing: -0.025em; text-wrap: balance; }
.dm .dm-evo-post--thumb small { font-size: 9px; font-weight: 500; color: rgba(255, 255, 255, 0.72); }
.dm-motion .dm-stage-panel.is-on .dm-evo-post--feed { animation: dm-evo-lab-1 9000ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-post--story { animation: dm-evo-lab-2 9000ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-post--thumb { animation: dm-evo-lab-3 9000ms linear infinite; }

/* 06 · the lookbook as a document, across the whole slot: the cover in
   front, a product page either side. Each page is a full photo on top and a
   footer below: name, two grey lines for the words, the colours it comes in;
   the cover carries the collection's name, count and date, the client and the
   signature; its picture is a four-tile collage of the products inside, one
   large and three around it. The photos run the whole page and simply overlap;
   the side pages keep their words on the half that shows past the cover. --k is the side (-1, 0, 1). The pages pivot around a point
   well below their bottom edge, so they fan: wide at the top, close at the
   foot. The fan breathes: the sides gather a little and spread a little on a
   slow 6 s line, the cover holds still; without motion they stand mid-breath. */
.dm .dm-evo-screen--book { overflow: visible; }
.dm .dm-evo-screen--book .dm-evo-canvas { display: grid; place-items: center; overflow: visible; }
.dm .dm-evo-fan { position: relative; height: 100%; aspect-ratio: 3 / 4; }
.dm .dm-evo-fan-page { position: absolute; inset: 0; overflow: hidden; border: 1px solid var(--dm-evo-app-border); border-radius: var(--dm-evo-app-r); background: var(--dm-evo-app-card); box-shadow: 0 8px 24px rgba(20, 20, 18, 0.1); transform: translateX(calc(var(--k, 0) * 27%)) rotate(calc(var(--k, 0) * 7.75deg)); transform-origin: 50% 170%; }
.dm .dm-evo-fan-photo { position: absolute; left: 0; right: 0; top: 0; height: 70%; overflow: hidden; }
/* the cover: a collage instead of one picture, and room under it for a title
   that carries the collection's name */
.dm .dm-evo-fan-photo--grid { height: 63%; display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr); gap: 3px; padding: 3px; background: var(--dm-evo-app-card); }
.dm .dm-evo-fan-photo--grid i { position: relative; overflow: hidden; border-radius: 3px; background: var(--dm-evo-app-tile); }
.dm .dm-evo-fan-photo--grid i:first-child { grid-column: span 2; grid-row: span 2; }
.dm .dm-evo-fan-photo--grid i:last-child { grid-column: span 3; }
.dm .dm-evo-fan-page--cover .dm-evo-fan-foot { top: 63%; }
.dm .dm-evo-fan-foot { position: absolute; left: 10px; right: 10px; top: 70%; bottom: 9px; display: flex; flex-direction: column; justify-content: space-between; padding-top: 9px; }
.dm .dm-evo-fan-page--right .dm-evo-fan-foot { align-items: flex-end; text-align: right; }
.dm .dm-evo-fan-head { display: grid; gap: 4px; justify-items: start; }
.dm .dm-evo-fan-page--right .dm-evo-fan-head { justify-items: end; }
.dm .dm-evo-fan-head b { font-size: 10px; font-weight: 600; line-height: 1.2; }
.dm .dm-evo-fan-head .dm-evo-line { margin-top: 1px; }
.dm .dm-evo-fan-head b.dm-evo-fan-title { font-family: var(--dm-font-display); font-size: 30px; font-weight: 400; line-height: 1; letter-spacing: var(--dm-tracking-display); text-wrap: balance; }
.dm .dm-evo-fan-head small, .dm .dm-evo-fan-row small { font-size: 8px; line-height: 1.2; color: var(--dm-evo-app-muted); }
.dm .dm-evo-fan-row { display: flex; align-items: center; gap: 5px; }
.dm .dm-evo-fan-page--right .dm-evo-fan-row { flex-direction: row-reverse; }
.dm .dm-evo-fan-page--cover .dm-evo-fan-row { justify-content: space-between; }
.dm .dm-evo-fan-row .dm-evo-chips { gap: 3px; }
.dm .dm-evo-fan-row .dm-evo-chip { width: 9px; height: 9px; }
.dm .dm-evo-fan-credit { font-size: 7px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--dm-evo-app-muted); }
@keyframes dm-evo-fan-breathe { 0%, 100% { transform: translateX(calc(var(--k, 0) * 25%)) rotate(calc(var(--k, 0) * 6.5deg)); } 50% { transform: translateX(calc(var(--k, 0) * 30%)) rotate(calc(var(--k, 0) * 9deg)); } }
.dm-motion .dm-stage-panel.is-on .dm-evo-fan-page { animation: dm-evo-fan-breathe 6000ms cubic-bezier(0.45, 0, 0.55, 1) infinite; }

/* 06 · the lookbook as a floating book (Thu 17 Sep). The fan above stays in
   the markup, hidden, until one of the two is chosen; this block is the book.
   A closed 3:4 cover floats at the centre of the slot, turned a little so its
   spine faces the reader. It opens along its spine, twelve pages riffle past too fast to
   read, the book rests on the mug and hoodie spread, then the pages riffle
   back in reverse order and the cover closes, on one loop of about 12 s that
   every moving part shares so nothing drifts.
   The 3D lives inside .dm-evo-book only: perspective on the bob, preserve-3d
   on the body and the leaves. NOTHING on those may clip, fade,
   filter, mask, blend, isolate or contain, or the whole context flattens and
   the back faces vanish. A leaf is rotateY(flip) then translateZ(z): the
   offset runs along the leaf's own normal, so after the half turn the left
   stack orders itself (the cover lowest, the last page on top) with no
   z-index. Leaves stand 1px apart and a leaf's two faces 0.3px either side
   of it, so nothing is ever coplanar. Faces clip and carry the page; leaves
   never clip; only the outer corners round, and barely. The body is exactly one page
   wide, so sliding it by 50% puts the spine at the centre while the cover is
   open. Without motion the book sits closed. */
.dm .dm-evo-book { --dm-evo-bh: 86%; --dm-evo-bz: 1px; --ph-mix: 46%; position: relative; height: var(--dm-evo-bh); aspect-ratio: 3 / 4; perspective: 900px; perspective-origin: 50% 46%; isolation: isolate; }
/* the floor shadow, outside the 3D context and behind the book (the book is
   its own stacking context, so a negative z-index lands under the pages and
   above the canvas): an ellipse at the foot that widens with the book */
.dm .dm-evo-book::after { content: ""; position: absolute; z-index: -1; left: 50%; bottom: -5%; width: 112%; height: 13%; border-radius: 50%; background: radial-gradient(ellipse at center, rgba(20, 20, 18, 0.26), rgba(20, 20, 18, 0) 72%); transform: translateX(-50%) scaleX(1); pointer-events: none; }
/* two cameras. The bob is the inner one: it holds the scene's perspective and
   floats as one flat picture, so the pages never re-rasterize against each
   other while the book drifts. The outer one sits on .dm-evo-book and tilts
   that whole picture a little, top away and right side forward, so the open
   book reads in perspective while everything inside it stays aligned. The body
   is the 3D scene: turned toward the reader while closed, the spine side
   forward; flat once open, so the stacked leaves do not creep as they pile up. */
.dm .dm-evo-book-bob { position: absolute; inset: 0; perspective: 1600px; perspective-origin: 50% 45%; transform: translateY(0) rotateX(24deg); }
.dm .dm-evo-book-body { position: absolute; inset: 0; transform-style: preserve-3d; transform: translateX(0) rotateX(3deg) rotateY(6deg); }
/* the spine: the book's thickness, a dark strip standing at the hinge from
   the base board up to the cover, seen while the book is closed and turned */
.dm .dm-evo-book-spine { position: absolute; left: 0; top: 0; width: calc(15 * var(--dm-evo-bz)); height: 100%; transform-origin: left center; transform: rotateY(-90deg); background: linear-gradient(90deg, rgba(20, 20, 18, 0.62), rgba(20, 20, 18, 0.34)); }
.dm .dm-evo-leaf { position: absolute; inset: 0; transform-origin: left center; transform-style: preserve-3d; transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); }
/* the page block sits just inside the two boards, flush at the hinge. The
   cover and the base are the boards, full size and plain inside; the last
   page never turns, so an open spread shows a page over a board on both
   sides, with the same overhang left and right */
.dm .dm-evo-leaf--page { inset: 1.5% 1.5% 1.5% 0; }
/* the outer corners are barely rounded, the spine corners square; a back face
   is mirrored, so its outer corners are its left ones */
.dm .dm-evo-leaf-face { position: absolute; inset: 0; overflow: hidden; border: 1px solid var(--dm-evo-app-border); border-radius: 0 3px 3px 0; background: var(--dm-evo-app-card); backface-visibility: hidden; -webkit-backface-visibility: hidden; transform: translateZ(0.3px); }
.dm .dm-evo-leaf-face--back { border-radius: 3px 0 0 3px; transform: rotateY(180deg) translateZ(0.3px); }
.dm .dm-evo-leaf-face--quiet { background: var(--dm-evo-app-tile); }
/* the page sits 1.5% inside the board on three sides, and on the bottom that
   put a hard hairline straight across the open spread, above the board's own
   edge and parallel to it: two rules a hair apart, which is what the eye
   caught. The bottom edge goes; the spine and outer edges stay, because the
   line down the gutter is what makes the two pages read as pages */
.dm .dm-evo-leaf--page .dm-evo-leaf-face { border-bottom: 0; }
/* the front cover is deep navy with light type; the collage keeps navy gutters */
.dm .dm-evo-leaf-face--cover { background: var(--dm-evo-app-navy); border-color: var(--dm-evo-app-navy); color: var(--dm-evo-app-on-primary); }
.dm .dm-evo-leaf-face--cover .dm-evo-leaf-photo--grid { background: var(--dm-evo-app-navy); }
.dm .dm-evo-leaf-face--cover .dm-evo-leaf-photo--grid i { background: oklch(0.34 0.07 262); }
.dm .dm-evo-leaf-face--cover .dm-evo-leaf-head small, .dm .dm-evo-leaf-face--cover .dm-evo-leaf-row small, .dm .dm-evo-leaf-face--cover .dm-evo-leaf-credit { color: rgba(255, 255, 255, 0.66); }
/* the hinge: a deep shade right at the spine edge, dying out over the first
   fifth of the page, so the fold reads as a fold; a back face is mirrored, so
   its spine is its right edge. And the flip shade: the cover darkens while it
   turns, peaking at the half turn, where the frame says the least */
.dm .dm-evo-leaf-face::before { content: ""; position: absolute; inset: 0; z-index: 3; pointer-events: none; background: linear-gradient(90deg, rgba(20, 20, 18, 0.34), rgba(20, 20, 18, 0.14) 3%, rgba(20, 20, 18, 0.05) 9%, rgba(20, 20, 18, 0) 18%); }
.dm .dm-evo-leaf-face--back::before { background: linear-gradient(270deg, rgba(20, 20, 18, 0.34), rgba(20, 20, 18, 0.14) 3%, rgba(20, 20, 18, 0.05) 9%, rgba(20, 20, 18, 0) 18%); }
.dm .dm-evo-leaf-face::after { content: ""; position: absolute; inset: 0; z-index: 4; pointer-events: none; background: linear-gradient(100deg, rgba(20, 20, 18, 0.30), rgba(20, 20, 18, 0.08)); opacity: 0; }
/* the page: the fan's own layout, one photo on top and a footer below. A
   page that riffles past is laid out like a real one, with grey placeholders
   where the pictures and words would be, in three arrangements that cycle:
   one picture and a short text, two pictures and a longer text, a shallow
   picture and a paragraph. Enough for a frame on screen a tenth of a second. */
.dm .dm-evo-leaf-photo { position: absolute; left: 0; right: 0; top: 0; height: 70%; overflow: hidden; }
/* The pages that fly past in the riffle carry no photograph, and a flat grey
   made the whole shuffle read as an empty document rather than a lookbook
   with work in it. Each one takes a two-stop gradient off a brand ramp
   instead, deep enough to hold its colour through the motion blur, and the
   ramp changes every page so the flick reads as a run of different products.

   Every pair is cut with neutral-1000 at --ph-mix before it is painted, which
   takes the ramp's lightness and its chroma down together: a photograph of a
   product is darker and quieter than the swatch its colour came from, and at
   full strength the shuffle read as a stack of paint chips. One knob, on the
   book, tunes the whole set.

   The pair is assigned on the face and read here through var()'s own fallback,
   not declared on the photo first: a custom property set on the element beats
   the one it would inherit, so a default here would shadow every assignment
   below and the whole riffle would stay grey. */
.dm .dm-evo-leaf-photo--blank,
.dm .dm-evo-leaf-photo--split {
  --ph-1: color-mix(in oklab, var(--ph-a, var(--dm-evo-app-ghost)) var(--ph-mix), var(--dm-neutral-1000));
  --ph-2: color-mix(in oklab, var(--ph-b, var(--dm-evo-app-ghost)) var(--ph-mix), var(--dm-neutral-1000));
}
.dm .dm-evo-leaf-photo--blank { background: linear-gradient(150deg, var(--ph-1), var(--ph-2)); }
/* two pictures side by side with the page showing through between them */
.dm .dm-evo-leaf-photo--split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
  background:
    linear-gradient(150deg, var(--ph-1), var(--ph-2)) 0 0 / calc(50% - 2px) 100% no-repeat,
    linear-gradient(150deg, var(--ph-2), var(--ph-1)) 100% 0 / calc(50% - 2px) 100% no-repeat;
}
.dm .dm-evo-leaf-photo--split > i { position: relative; overflow: hidden; }

/* The riffle pages carry real photographs, blurred past reading: what flies
   past should look like a lookbook full of work, not like a document waiting
   for it. They are the block's own product shots, so nothing new is fetched
   and nothing new is embedded in the send-away file.

   Not .dm-evo-shot: that class is the swap machinery and hides itself unless
   it is :only-of-type or .is-on, so the two halves of a split page would both
   vanish. The blur is on the image, inside the face, never on the leaf, which
   would flatten the 3D. The scale swallows the soft edge the blur leaves at
   the box's rim. The gradient under them stays as the ground a lazy image has
   not covered yet. */
.dm .dm-evo-leaf-fill {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: blur(8px);
  transform: scale(1.2);
}
.dm .dm-evo-leaf--r2 .dm-evo-leaf-face--back   { --ph-a: var(--dm-cyan-600);   --ph-b: var(--dm-cyan-800); }
.dm .dm-evo-leaf--r4 .dm-evo-leaf-face--front  { --ph-a: var(--dm-orange-400); --ph-b: var(--dm-orange-600); }
.dm .dm-evo-leaf--r4 .dm-evo-leaf-face--back   { --ph-a: var(--dm-purple-500); --ph-b: var(--dm-purple-700); }
.dm .dm-evo-leaf--r5 .dm-evo-leaf-face--front  { --ph-a: var(--dm-lime-600);   --ph-b: var(--dm-lime-800); }
.dm .dm-evo-leaf--r5 .dm-evo-leaf-face--back   { --ph-a: var(--dm-pink-400);   --ph-b: var(--dm-pink-600); }
.dm .dm-evo-leaf--r6 .dm-evo-leaf-face--front  { --ph-a: var(--dm-cyan-500);   --ph-b: var(--dm-cyan-700); }
.dm .dm-evo-leaf--r6 .dm-evo-leaf-face--back   { --ph-a: var(--dm-orange-500); --ph-b: var(--dm-orange-700); }
.dm .dm-evo-leaf--r7 .dm-evo-leaf-face--front  { --ph-a: var(--dm-purple-400); --ph-b: var(--dm-purple-600); }
.dm .dm-evo-leaf--r7 .dm-evo-leaf-face--back   { --ph-a: var(--dm-lime-500);   --ph-b: var(--dm-lime-700); }
.dm .dm-evo-leaf--r8 .dm-evo-leaf-face--front  { --ph-a: var(--dm-pink-500);   --ph-b: var(--dm-pink-700); }
.dm .dm-evo-leaf--r8 .dm-evo-leaf-face--back   { --ph-a: var(--dm-cyan-700);   --ph-b: var(--dm-cyan-900); }
.dm .dm-evo-leaf--r9 .dm-evo-leaf-face--front  { --ph-a: var(--dm-orange-600); --ph-b: var(--dm-orange-800); }
.dm .dm-evo-leaf--r9 .dm-evo-leaf-face--back   { --ph-a: var(--dm-purple-600); --ph-b: var(--dm-purple-800); }
.dm .dm-evo-leaf--r10 .dm-evo-leaf-face--front { --ph-a: var(--dm-lime-400);   --ph-b: var(--dm-lime-600); }
.dm .dm-evo-leaf--r10 .dm-evo-leaf-face--back  { --ph-a: var(--dm-pink-300);   --ph-b: var(--dm-pink-500); }
.dm .dm-evo-leaf--r11 .dm-evo-leaf-face--front { --ph-a: var(--dm-cyan-400);   --ph-b: var(--dm-cyan-600); }
.dm .dm-evo-leaf--r11 .dm-evo-leaf-face--back  { --ph-a: var(--dm-orange-300); --ph-b: var(--dm-orange-500); }
.dm .dm-evo-leaf--r12 .dm-evo-leaf-face--front { --ph-a: var(--dm-purple-300); --ph-b: var(--dm-purple-500); }
.dm .dm-evo-leaf-face--q2 .dm-evo-leaf-photo { height: 58%; }
.dm .dm-evo-leaf-face--q2 .dm-evo-leaf-foot { top: 58%; }
.dm .dm-evo-leaf-face--q3 .dm-evo-leaf-photo { height: 46%; }
.dm .dm-evo-leaf-face--q3 .dm-evo-leaf-foot { top: 46%; }
.dm .dm-evo-leaf-head .dm-evo-line--ink { height: 7px; margin-bottom: 3px; }
/* the cover collage: six columns so the big picture takes four, the two beside
   it two each, and the bottom row splits into two equal halves */
.dm .dm-evo-leaf-photo--grid { height: 63%; display: grid; grid-template-columns: repeat(6, 1fr); grid-template-rows: repeat(3, 1fr); gap: 3px; padding: 3px; background: var(--dm-evo-app-card); }
.dm .dm-evo-leaf-photo--grid i { position: relative; overflow: hidden; grid-column: span 2; background: var(--dm-evo-app-tile); }
.dm .dm-evo-leaf-photo--grid i:first-child { grid-column: span 4; grid-row: span 2; }
.dm .dm-evo-leaf-photo--grid i:nth-child(n + 4) { grid-column: span 3; }
.dm .dm-evo-leaf-foot { position: absolute; left: 10px; right: 10px; top: 70%; bottom: 9px; display: flex; flex-direction: column; justify-content: space-between; padding-top: 9px; }
.dm .dm-evo-leaf-face--cover .dm-evo-leaf-foot { top: 63%; }
.dm .dm-evo-leaf-face--right .dm-evo-leaf-foot { align-items: flex-end; text-align: right; }
.dm .dm-evo-leaf-head { display: grid; gap: 4px; justify-items: start; }
.dm .dm-evo-leaf-face--right .dm-evo-leaf-head { justify-items: end; }
.dm .dm-evo-leaf-head b { font-size: 10px; font-weight: 600; line-height: 1.2; }
.dm .dm-evo-leaf-head .dm-evo-line { margin-top: 1px; }
/* the one serif on the block: the lookbook is the reader's own document,
   a human moment in the brand's terms, so its title is Fraunces at the brand
   weight while every other word on the page stays Geist */
.dm .dm-evo-leaf-head b.dm-evo-leaf-title { font-family: var(--dm-font-display); font-size: 30px; font-weight: 400; line-height: 1; letter-spacing: var(--dm-tracking-display); text-wrap: balance; }
.dm .dm-evo-leaf-head small, .dm .dm-evo-leaf-row small { font-size: 8px; line-height: 1.2; color: var(--dm-evo-app-muted); }
.dm .dm-evo-leaf-row { display: flex; align-items: center; gap: 5px; }
.dm .dm-evo-leaf-face--right .dm-evo-leaf-row { flex-direction: row-reverse; }
.dm .dm-evo-leaf-face--cover .dm-evo-leaf-row { justify-content: space-between; }
.dm .dm-evo-leaf-row .dm-evo-chips { gap: 3px; }
.dm .dm-evo-leaf-row .dm-evo-chip { width: 9px; height: 9px; }
.dm .dm-evo-leaf-credit { font-size: 7px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--dm-evo-app-muted); }
/* the loop, 11850 ms, in percent: closed to 8.44, the cover opens to 17.72
   (the half turn at 40% of the way: a fast lift, a slow lay-down), a beat, then
   the riffle: twelve pages from 19.41, one every 75 ms, each turn 260 ms,
   the last one down at 28.57; the spread holds to 70.89; the pages
   come back in reverse order to 80.04, the cover closes 81.01 to 90.3,
   closed to the end and on to 8.44: about 2 s of cover per loop. Holds are
   linear so the closed book never creeps. */
@keyframes dm-evo-book-cover { 0%, 8.44% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.55, 0.06, 0.68, 0.19); } 12.15% { transform: rotateY(-90deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.22, 0.61, 0.36, 1); } 17.72%, 81.01% { transform: rotateY(-180deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.55, 0.06, 0.68, 0.19); } 84.73% { transform: rotateY(-90deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.22, 0.61, 0.36, 1); } 90.3%, 100% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: linear; } }
@keyframes dm-evo-book-r1 { 0%, 19.41% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 21.6%, 77.85% { transform: rotateY(-180deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 80.04%, 100% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: linear; } }
@keyframes dm-evo-book-r2 { 0%, 20.04% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 22.24%, 77.22% { transform: rotateY(-180deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 79.41%, 100% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: linear; } }
@keyframes dm-evo-book-r3 { 0%, 20.68% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 22.87%, 76.58% { transform: rotateY(-180deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 78.78%, 100% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: linear; } }
@keyframes dm-evo-book-r4 { 0%, 21.31% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 23.5%, 75.95% { transform: rotateY(-180deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 78.14%, 100% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: linear; } }
@keyframes dm-evo-book-r5 { 0%, 21.94% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 24.14%, 75.32% { transform: rotateY(-180deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 77.51%, 100% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: linear; } }
@keyframes dm-evo-book-r6 { 0%, 22.57% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 24.77%, 74.68% { transform: rotateY(-180deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 76.88%, 100% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: linear; } }
@keyframes dm-evo-book-r7 { 0%, 23.21% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 25.4%, 74.05% { transform: rotateY(-180deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 76.24%, 100% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: linear; } }
@keyframes dm-evo-book-r8 { 0%, 23.84% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 26.03%, 73.42% { transform: rotateY(-180deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 75.61%, 100% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: linear; } }
@keyframes dm-evo-book-r9 { 0%, 24.47% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 26.67%, 72.78% { transform: rotateY(-180deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 74.98%, 100% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: linear; } }
@keyframes dm-evo-book-r10 { 0%, 25.11% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 27.3%, 72.15% { transform: rotateY(-180deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 74.35%, 100% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: linear; } }
@keyframes dm-evo-book-r11 { 0%, 25.74% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 27.93%, 71.52% { transform: rotateY(-180deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 73.71%, 100% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: linear; } }
@keyframes dm-evo-book-r12 { 0%, 26.37% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 28.57%, 70.89% { transform: rotateY(-180deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); } 73.08%, 100% { transform: rotateY(0deg) translateZ(calc(var(--z, 0) * var(--dm-evo-bz))); animation-timing-function: linear; } }
@keyframes dm-evo-book-shade-cover { 0%, 8.44% { opacity: 0; } 12.15% { opacity: 0.18; } 17.72%, 81.01% { opacity: 0; } 84.73% { opacity: 0.18; } 90.3%, 100% { opacity: 0; } }
@keyframes dm-evo-book-body { 0%, 8.44% { transform: translateX(0) rotateX(3deg) rotateY(6deg); animation-timing-function: cubic-bezier(0.62, 0.02, 0.24, 1); } 17.72%, 81.01% { transform: translateX(50%) rotateX(0deg) rotateY(0deg); animation-timing-function: cubic-bezier(0.62, 0.02, 0.24, 1); } 90.3%, 100% { transform: translateX(0) rotateX(3deg) rotateY(6deg); animation-timing-function: linear; } }
@keyframes dm-evo-book-shadow { 0%, 8.44% { transform: translateX(-50%) scaleX(1); animation-timing-function: cubic-bezier(0.62, 0.02, 0.24, 1); } 17.72%, 81.01% { transform: translateX(-50%) scaleX(1.9); animation-timing-function: cubic-bezier(0.62, 0.02, 0.24, 1); } 90.3%, 100% { transform: translateX(-50%) scaleX(1); animation-timing-function: linear; } }
/* the camera pulls back while the book is open: with the two boards 15px apart
   in depth, any real perspective projects the far one a pixel smaller and the
   spread's edges step; near-orthographic, they line up. It comes in again for
   the cover turn, which wants the depth. */
/* The camera is not fixed. Two boards sitting 15px apart in depth project at
   different sizes under any real perspective, which is what made the open
   spread look a hair out of true, so the held spread is watched from almost
   orthographic. The riffle wants the opposite: at 7000px a turning page hardly
   foreshortens and the flick reads flat. So the camera is close for both
   riffles and pulls back only for the pause between them, when the eye has
   time to compare the two halves. The tilt that angles the whole book lives on
   the bob, outside the 3D scene, where it costs no alignment. */
@keyframes dm-evo-book-camera { 0%, 8.44% { perspective: 1300px; animation-timing-function: cubic-bezier(0.62, 0.02, 0.24, 1); } 17.72%, 30.5% { perspective: 1800px; animation-timing-function: cubic-bezier(0.62, 0.02, 0.24, 1); } 40%, 66% { perspective: 7000px; animation-timing-function: cubic-bezier(0.62, 0.02, 0.24, 1); } 70%, 81.01% { perspective: 1800px; animation-timing-function: cubic-bezier(0.62, 0.02, 0.24, 1); } 90.3%, 100% { perspective: 1300px; animation-timing-function: linear; } }
/* motion blur on the page that is turning, and only that page, only while it
   turns: its faces soften to 3px for the middle of the quarter second and
   are sharp again as it lands. The filter sits on the faces, flat nodes at
   the bottom of the 3D tree; on the leaf it would flatten the turn. */
@keyframes dm-evo-book-mb1 { 0%, 19.41% { filter: none; } 20%, 21.01% { filter: blur(3px); } 21.6%, 77.85% { filter: none; } 78.44%, 79.45% { filter: blur(3px); } 80.04%, 100% { filter: none; } }
@keyframes dm-evo-book-mb2 { 0%, 20.04% { filter: none; } 20.63%, 21.65% { filter: blur(3px); } 22.24%, 77.22% { filter: none; } 77.81%, 78.82% { filter: blur(3px); } 79.41%, 100% { filter: none; } }
@keyframes dm-evo-book-mb3 { 0%, 20.68% { filter: none; } 21.27%, 22.28% { filter: blur(3px); } 22.87%, 76.58% { filter: none; } 77.17%, 78.19% { filter: blur(3px); } 78.78%, 100% { filter: none; } }
@keyframes dm-evo-book-mb4 { 0%, 21.31% { filter: none; } 21.9%, 22.91% { filter: blur(3px); } 23.5%, 75.95% { filter: none; } 76.54%, 77.55% { filter: blur(3px); } 78.14%, 100% { filter: none; } }
@keyframes dm-evo-book-mb5 { 0%, 21.94% { filter: none; } 22.53%, 23.54% { filter: blur(3px); } 24.14%, 75.32% { filter: none; } 75.91%, 76.92% { filter: blur(3px); } 77.51%, 100% { filter: none; } }
@keyframes dm-evo-book-mb6 { 0%, 22.57% { filter: none; } 23.16%, 24.18% { filter: blur(3px); } 24.77%, 74.68% { filter: none; } 75.27%, 76.29% { filter: blur(3px); } 76.88%, 100% { filter: none; } }
@keyframes dm-evo-book-mb7 { 0%, 23.21% { filter: none; } 23.8%, 24.81% { filter: blur(3px); } 25.4%, 74.05% { filter: none; } 74.64%, 75.65% { filter: blur(3px); } 76.24%, 100% { filter: none; } }
@keyframes dm-evo-book-mb8 { 0%, 23.84% { filter: none; } 24.43%, 25.44% { filter: blur(3px); } 26.03%, 73.42% { filter: none; } 74.01%, 75.02% { filter: blur(3px); } 75.61%, 100% { filter: none; } }
@keyframes dm-evo-book-mb9 { 0%, 24.47% { filter: none; } 25.06%, 26.08% { filter: blur(3px); } 26.67%, 72.78% { filter: none; } 73.38%, 74.39% { filter: blur(3px); } 74.98%, 100% { filter: none; } }
@keyframes dm-evo-book-mb10 { 0%, 25.11% { filter: none; } 25.7%, 26.71% { filter: blur(3px); } 27.3%, 72.15% { filter: none; } 72.74%, 73.76% { filter: blur(3px); } 74.35%, 100% { filter: none; } }
@keyframes dm-evo-book-mb11 { 0%, 25.74% { filter: none; } 26.33%, 27.34% { filter: blur(3px); } 27.93%, 71.52% { filter: none; } 72.11%, 73.12% { filter: blur(3px); } 73.71%, 100% { filter: none; } }
@keyframes dm-evo-book-mb12 { 0%, 26.37% { filter: none; } 26.96%, 27.97% { filter: blur(3px); } 28.57%, 70.89% { filter: none; } 71.48%, 72.49% { filter: blur(3px); } 73.08%, 100% { filter: none; } }
/* the float: four slow bobs inside the loop */
@keyframes dm-evo-book-bob { 0%, 25%, 50%, 75%, 100% { transform: translateY(0) rotateX(24deg); } 12.5%, 37.5%, 62.5%, 87.5% { transform: translateY(-6px) rotateX(24deg); } }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--cover { animation: dm-evo-book-cover 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r1 { animation: dm-evo-book-r1 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r2 { animation: dm-evo-book-r2 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r3 { animation: dm-evo-book-r3 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r4 { animation: dm-evo-book-r4 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r5 { animation: dm-evo-book-r5 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r6 { animation: dm-evo-book-r6 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r7 { animation: dm-evo-book-r7 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r8 { animation: dm-evo-book-r8 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r9 { animation: dm-evo-book-r9 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r10 { animation: dm-evo-book-r10 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r11 { animation: dm-evo-book-r11 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r12 { animation: dm-evo-book-r12 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r1 .dm-evo-leaf-face { animation: dm-evo-book-mb1 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r2 .dm-evo-leaf-face { animation: dm-evo-book-mb2 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r3 .dm-evo-leaf-face { animation: dm-evo-book-mb3 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r4 .dm-evo-leaf-face { animation: dm-evo-book-mb4 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r5 .dm-evo-leaf-face { animation: dm-evo-book-mb5 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r6 .dm-evo-leaf-face { animation: dm-evo-book-mb6 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r7 .dm-evo-leaf-face { animation: dm-evo-book-mb7 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r8 .dm-evo-leaf-face { animation: dm-evo-book-mb8 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r9 .dm-evo-leaf-face { animation: dm-evo-book-mb9 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r10 .dm-evo-leaf-face { animation: dm-evo-book-mb10 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r11 .dm-evo-leaf-face { animation: dm-evo-book-mb11 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--r12 .dm-evo-leaf-face { animation: dm-evo-book-mb12 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-leaf--cover .dm-evo-leaf-face::after { animation: dm-evo-book-shade-cover 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-book-body { animation: dm-evo-book-body 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-book::after { animation: dm-evo-book-shadow 11850ms linear infinite; }
.dm-motion .dm-stage-panel.is-on .dm-evo-book-bob { animation: dm-evo-book-bob 11850ms cubic-bezier(0.45, 0, 0.55, 1) infinite, dm-evo-book-camera 11850ms linear infinite; }
/* 08 · the Stitch clip: the picture moves. A promo loop that carries nothing
   else, no bar and no card. */
.dm .dm-evo-screen--film { overflow: visible; }
.dm .dm-evo-screen--film .dm-evo-canvas { display: grid; place-items: center; overflow: visible; }
.dm .dm-evo-film { position: relative; width: 100%; aspect-ratio: 16 / 9; overflow: hidden; border-radius: var(--dm-evo-app-r); background: var(--dm-evo-app-tile); box-shadow: 0 12px 34px rgba(20, 20, 18, 0.16); }

.dm .dm-evo-video.is-seam { opacity: 0; }
.dm-motion .dm .dm-evo-video { transition-duration: 260ms; }

/* ---------- the Create composite ----------
   One panel, one story, two sub-screens stacked in the slot: the composer
   being filled in, then the finished tee in its colours (03). Only one shows,
   and a hidden sub has no box, so its beats are cancelled and start from the
   top when it is shown again. The one leaving stays for 320ms under the one
   arriving, so the hand-over is a cross-fade; the composer's last frame is
   the same photo the tee sub opens on and it holds it without fading (see
   below), so that hand-over cannot be seen.
   evolution.js walks them and writes the panel's dwell. Without the script
   the `see` sub, marked is-on in the markup, stands as the still. */
.dm .dm-evo-sub { display: none; }
.dm .dm-evo-sub.is-on { display: block; z-index: 2; }
.dm .dm-evo-sub.is-out { display: block; z-index: 1; }
@keyframes dm-evo-sub-in { from { opacity: 0; } }
@keyframes dm-evo-sub-out { to { opacity: 0; } }
.dm-motion .dm .dm-evo-sub.is-on { animation: dm-evo-sub-in 320ms var(--dm-ease-press) both; }
.dm-motion .dm .dm-evo-sub.is-out { animation: dm-evo-sub-out 320ms var(--dm-ease-press) both; }
/* the composer's last frame is the photo the tee sub opens on, so it does not
   fade under it (two half-faded copies would let the surface flash through);
   it simply holds, at full opacity, until it is dropped 340ms later. Its beats
   are gated on is-out as well as is-on for the same reason: the gate that
   opened them must not close on the way out, or the photo layers would snap
   back to their hidden base and the white card would show. */
.dm-motion .dm .dm-evo-screen--composer.is-out { animation: none; }

/* the composer: the production composer cut down to what the story needs, a
   compact card floating on the stage card's surface, no outline and no canvas
   of its own, lifted by a deep soft shadow: a two-line prompt field with
   the square design slot beside it, the product picker and the round arrow
   along the bottom, the picker's menu when it is open. Its geometry is four
   custom properties (--cmp-l/-r the card's side insets, --cmp-h its height,
   --cmp-s the field's and the slot's height), so every mark the pointer hits
   and every anchor the camera zooms on is written once, in calc(), and holds
   at every slot size. One 10.6s statement:

   the camera zooms only twice, and only ever zooms (transform-origin is
   re-aimed while it is flat, so nothing pans): a macro view on the line's first letter while it types itself (evolution.js), and on the card's foot
   while the pointer clicks the picker, the menu opens, the pointer clicks the
   Gildan and the menu closes. Then it comes back flat and stays flat: the
   pointer leaves by the right edge and returns dragging the design tile,
   which drops into its slot, and the pointer presses the arrow. Generating:
   the line dims, one liquid highlight sweeps the field and the card takes a
   breath. Then the card becomes the mockup: the photo, blurred, fills the
   card's own rectangle in place of its face, and that rectangle swells to
   the whole slot, shadow and all, while the picture sharpens, ending on
   exactly the frame the next sub opens with.

   Every keyframe starts from the empty state explicitly, so the base rules can
   describe the FILLED card, which is what a tile of it shows with no motion at
   all. 1% of the timeline is 106ms. */
/* the card is 80% of the slot and never wider than 500px; the 16px line
   wraps to exactly two (its last two words are bound), and the macro frame
   (the slot's width over --cmp-z1, opening from the line's first letter)
   holds the whole first line */
/* The composer floats on the section's own ground with no app frame around it,
   so the app's cool greys read as colourless there. It is the one screen that
   takes the site's neutral ramp instead (Thu 17 Sep); every value is a token. */
.dm .dm-evo-screen--composer {
  --dm-evo-app-page: var(--dm-surface-page);
  --dm-evo-app-well: var(--dm-neutral-50);
  --dm-evo-app-tile: var(--dm-surface-page);
  --dm-evo-app-card: var(--dm-surface-white);
  --dm-evo-app-border: var(--dm-border-card-soft);
  --dm-evo-app-ink: var(--dm-ink);
  --dm-evo-app-muted: var(--dm-text-secondary);
  --dm-evo-app-primary: var(--dm-surface-dark);
  --dm-evo-app-on-primary: var(--dm-on-ink);
}
.dm .dm-evo-screen--composer { --cmp-l: max(10%, 50% - 250px); --cmp-r: max(10%, 50% - 250px); --cmp-h: 136px; --cmp-s: 72px; --cmp-z1: 1.7; --cmp-z2: 1.8; background: transparent; }
/* no canvas of its own: the card floats on the stage card's surface */
.dm .dm-evo-screen--composer .dm-evo-canvas { display: block; background: transparent; }
.dm .dm-evo-cmp-cam { position: absolute; inset: 0; transform-origin: 50% 50%; }
.dm .dm-evo-cmp { position: absolute; left: var(--cmp-l); right: var(--cmp-r); top: calc(50% - var(--cmp-h) / 2); height: var(--cmp-h); display: flex; flex-direction: column; gap: 10px; padding: 14px; border-radius: 16px; background: var(--dm-evo-app-card); color: var(--dm-evo-app-ink); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7), 0 1px 2px rgba(20, 20, 18, 0.05), 0 14px 30px rgba(20, 20, 18, 0.10), 0 44px 90px -24px rgba(20, 20, 18, 0.24); }
.dm .dm-evo-cmp-body { display: flex; gap: 10px; height: var(--cmp-s); }
.dm .dm-evo-cmp-field { position: relative; flex: 1; margin: 0; padding: 12px 14px; border-radius: 10px; background: var(--dm-evo-app-well); font-size: 16px; line-height: 1.5; color: var(--dm-evo-app-ink); overflow: hidden; }
.dm .dm-evo-cmp-field .dm-evo-typed { display: inline; min-height: 0; }
/* the liquid highlight that sweeps the field while it generates */
.dm .dm-evo-cmp-field::after { content: ""; position: absolute; inset: 0; background: linear-gradient(100deg, rgba(183, 255, 255, 0) 30%, rgba(183, 255, 255, 0.85) 50%, rgba(183, 255, 255, 0) 70%); background-size: 250% 100%; background-position: 200% 0; opacity: 0; pointer-events: none; }
.dm .dm-evo-cmp-drop { position: relative; flex: none; width: var(--cmp-s); display: grid; place-items: center; overflow: hidden; border: 1.5px dashed transparent; border-radius: 10px; }
.dm .dm-evo-cmp-drop-hint { display: flex; flex-direction: column; align-items: center; gap: 2px; text-align: center; color: var(--dm-evo-app-muted); opacity: 0; }
.dm .dm-evo-cmp-drop-hint svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.dm .dm-evo-cmp-drop-hint b { font-size: 9px; font-weight: 500; color: var(--dm-evo-app-ink); }
.dm .dm-evo-cmp-drop-hint small { font-size: 7.5px; line-height: 1.2; }
.dm .dm-evo-cmp-art { position: absolute; inset: 0; display: grid; place-items: center; background: var(--dm-evo-app-tile); }
.dm .dm-evo-cmp-art svg { width: 52%; height: 52%; fill: var(--dm-evo-app-ink); }
.dm .dm-evo-cmp-art img { width: 72%; height: 72%; object-fit: contain; }
.dm .dm-evo-cmp-bar { display: flex; align-items: center; gap: 10px; height: 26px; font-size: 11px; color: var(--dm-evo-app-muted); }
.dm .dm-evo-cmp-bar svg { flex: none; width: 10px; height: 10px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.dm .dm-evo-cmp-pick { display: inline-grid; grid-template-columns: auto auto; align-items: center; gap: 6px; height: 26px; padding: 0 10px; border: 1px solid var(--dm-evo-app-border); border-radius: 999px; background: var(--dm-evo-app-tile); white-space: nowrap; }
.dm .dm-evo-cmp-pick-idle, .dm .dm-evo-cmp-pick-done { grid-area: 1 / 1; display: inline-flex; align-items: center; gap: 6px; }
.dm .dm-evo-cmp-pick-idle { opacity: 0; }
.dm .dm-evo-cmp-pick-idle svg { width: 13px; height: 13px; stroke-width: 1.6; }
.dm .dm-evo-cmp-pick-done { color: var(--dm-evo-app-ink); }
.dm .dm-evo-cmp-pick > svg { grid-area: 1 / 2; }
.dm .dm-evo-cmp-go { position: relative; flex: none; margin-left: auto; width: 26px; height: 26px; border-radius: 999px; background: var(--dm-evo-app-primary); color: var(--dm-evo-app-on-primary); display: grid; place-items: center; }
.dm .dm-evo-cmp-go svg { width: 12px; height: 12px; transform: rotate(-90deg); stroke-width: 2.2; }
/* the ring that leaves the arrow when it is pressed */
.dm .dm-evo-cmp-go::after { content: ""; position: absolute; inset: 0; border-radius: 999px; border: 2px solid var(--dm-evo-app-primary); opacity: 0; }
/* the picker's menu, above the bar: 5px padding, three 22px rows, 2px apart,
   so the first row's centre is 118px above the card's foot */
.dm .dm-evo-cmp-menu { position: absolute; left: 14px; bottom: 54px; z-index: 2; display: flex; flex-direction: column; gap: 2px; padding: 5px; border-radius: 10px; background: var(--dm-evo-app-card); box-shadow: 0 2px 6px rgba(20, 20, 18, 0.06), 0 14px 34px rgba(20, 20, 18, 0.16); opacity: 0; transform: translateY(6px); }
.dm .dm-evo-cmp-menu i { display: flex; align-items: center; height: 22px; padding: 0 8px; border-radius: 7px; font-size: 11px; font-style: normal; color: var(--dm-evo-app-ink); white-space: nowrap; }
/* the photo, over the whole slot and cropped like the tee sub's shots, hidden
   until the card becomes it: clipped to the card's rectangle first, then to
   the slot */
.dm .dm-evo-cmp-gen { position: absolute; inset: 0; z-index: 3; overflow: hidden; opacity: 0; pointer-events: none; }
.dm .dm-evo-cmp-gen img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 21%; }
/* the design tile on its way in, the pointer holding it by the corner; it
   rests where it lands, invisible, so the filled card shows nothing of it */
.dm .dm-evo-cmp-drag { position: absolute; left: calc(100% - var(--cmp-r) - 14px - var(--cmp-s) / 2); top: calc(50% - var(--cmp-h) / 2 + 14px + var(--cmp-s) / 2); z-index: 4; width: calc(var(--cmp-s) - 10px); aspect-ratio: 1; transform: translate(-50%, -50%) scale(0.7); opacity: 0; }
.dm .dm-evo-cmp-drag-tile { display: grid; place-items: center; width: 100%; height: 100%; border-radius: 12px; background: var(--dm-evo-app-card); box-shadow: 0 10px 26px rgba(20, 20, 18, 0.18); color: var(--dm-evo-app-ink); }
.dm .dm-evo-cmp-drag-tile svg { width: 58%; height: 58%; fill: currentColor; }
.dm .dm-evo-cmp-drag-tile img { width: 76%; height: 76%; object-fit: contain; }
.dm .dm-evo-cmp-drag-cursor { position: absolute; right: -9px; bottom: -11px; width: 17px; height: 17px; fill: #fff; stroke: var(--dm-evo-app-ink); stroke-width: 1.5; stroke-linejoin: round; }
.dm .dm-evo-cmp-cursor { position: absolute; left: calc(100% - var(--cmp-r) - 27px); top: calc(50% + var(--cmp-h) / 2 - 27px); z-index: 5; width: 18px; height: 18px; fill: #fff; stroke: var(--dm-evo-app-ink); stroke-width: 1.5; stroke-linejoin: round; opacity: 0; pointer-events: none; }
.dm .dm-evo-typed::after { content: ""; display: inline-block; width: 1px; height: 1em; margin-left: 2px; vertical-align: -0.15em; background: currentColor; opacity: 0; }
/* the timeline, in ms: camera to the field 400 to 900 · type 700 to 2260,
   caret to 2900 · camera flat 3100 · pointer to the picker 3000 to 3500,
   camera on the foot 3300 to 3800 · click 3600, menu open 4000 · pointer to
   the Gildan 4200 to 4700, click 4800, menu closes 5300, the chip fills ·
   camera flat 5900, and flat from here · pointer out by the right edge 6100 ·
   the tile in from 6100, lands 7100, drops · pointer to the arrow 7600 to
   8100, press 8200 · generating 8300 to 8900: dimmed line, one sweep, a
   breath · the photo fills the card 8900 to 9100, the card swells to the
   slot 9100 to 10100 and sharpens to 10600 · the next sub takes over 10600 */
@keyframes dm-evo-cmp-cam {
  0%, 3.8% { transform: none; transform-origin: calc(var(--cmp-l) + 28px) calc(50% - var(--cmp-h) / 2 + 26px); }
  8.5%, 24.5% { transform: scale(var(--cmp-z1)); transform-origin: calc(var(--cmp-l) + 28px) calc(50% - var(--cmp-h) / 2 + 26px); }
  29.2% { transform: none; transform-origin: calc(var(--cmp-l) + 28px) calc(50% - var(--cmp-h) / 2 + 26px); }
  29.21%, 31.1% { transform: none; transform-origin: calc(var(--cmp-l) + 14px) calc(50% + var(--cmp-h) / 2 - 14px); }
  35.8%, 50.9% { transform: scale(var(--cmp-z2)); transform-origin: calc(var(--cmp-l) + 14px) calc(50% + var(--cmp-h) / 2 - 14px); }
  55.7%, 100% { transform: none; transform-origin: calc(var(--cmp-l) + 14px) calc(50% + var(--cmp-h) / 2 - 14px); }
}
@keyframes dm-evo-caret { 0%, 6.5% { opacity: 0; } 6.6%, 27.3% { opacity: 1; } 27.4%, 100% { opacity: 0; } }
@keyframes dm-evo-cmp-text { 0%, 77.8% { opacity: 1; } 79.5%, 100% { opacity: 0.4; } }
@keyframes dm-evo-cmp-cursor {
  0%, 28.3% { left: 55%; top: 55%; opacity: 0; transform: none; }
  29.5% { left: 52%; top: 58%; opacity: 1; }
  33%, 33.9% { left: calc(var(--cmp-l) + 64px); top: calc(50% + var(--cmp-h) / 2 - 27px); transform: none; }
  34.4%, 34.9% { left: calc(var(--cmp-l) + 64px); top: calc(50% + var(--cmp-h) / 2 - 27px); transform: scale(0.85); }
  35.5%, 39.6% { left: calc(var(--cmp-l) + 64px); top: calc(50% + var(--cmp-h) / 2 - 27px); transform: none; }
  44.3%, 45.2% { left: calc(var(--cmp-l) + 64px); top: calc(50% + var(--cmp-h) / 2 - 118px); transform: none; }
  45.7%, 46.2% { left: calc(var(--cmp-l) + 64px); top: calc(50% + var(--cmp-h) / 2 - 118px); transform: scale(0.85); }
  46.8%, 51.9% { left: calc(var(--cmp-l) + 64px); top: calc(50% + var(--cmp-h) / 2 - 118px); transform: none; opacity: 1; }
  56.5%, 57.5% { left: 104%; top: 34%; opacity: 0; transform: none; }
  69.8% { left: calc(100% - var(--cmp-r) - 14px - var(--cmp-s) / 2); top: calc(50% - var(--cmp-h) / 2 + 14px + var(--cmp-s) / 2); opacity: 0; transform: none; }
  70.8%, 71.7% { left: calc(100% - var(--cmp-r) - 14px - var(--cmp-s) / 2); top: calc(50% - var(--cmp-h) / 2 + 14px + var(--cmp-s) / 2); opacity: 1; }
  76.4%, 77.3% { left: calc(100% - var(--cmp-r) - 27px); top: calc(50% + var(--cmp-h) / 2 - 27px); transform: none; }
  77.4%, 77.9% { left: calc(100% - var(--cmp-r) - 27px); top: calc(50% + var(--cmp-h) / 2 - 27px); transform: scale(0.85); }
  78.4%, 79% { left: calc(100% - var(--cmp-r) - 27px); top: calc(50% + var(--cmp-h) / 2 - 27px); transform: none; opacity: 1; }
  81%, 100% { left: calc(100% - var(--cmp-r) - 27px); top: calc(50% + var(--cmp-h) / 2 - 27px); opacity: 0; transform: none; }
}
@keyframes dm-evo-cmp-pick { 0%, 34.4% { border-color: var(--dm-evo-app-border); } 35%, 48.6% { border-color: var(--dm-evo-app-ink); } 50%, 100% { border-color: var(--dm-evo-app-border); } }
@keyframes dm-evo-cmp-menu { 0%, 35.4% { opacity: 0; transform: translateY(6px); } 37.7%, 48.1% { opacity: 1; transform: none; } 50%, 100% { opacity: 0; transform: translateY(6px); } }
@keyframes dm-evo-cmp-row { 0%, 45.3% { background: transparent; } 45.8%, 48.6% { background: var(--dm-evo-app-well); } 49.5%, 100% { background: transparent; } }
@keyframes dm-evo-cmp-idle { 0%, 48.6% { opacity: 1; transform: none; } 50%, 100% { opacity: 0; transform: translateY(-4px); } }
@keyframes dm-evo-cmp-done { 0%, 49% { opacity: 0; transform: translateY(5px); } 51.4%, 100% { opacity: 1; transform: none; } }
@keyframes dm-evo-cmp-drag {
  0%, 57.5% { left: 106%; top: 34%; opacity: 0; transform: translate(-50%, -50%) rotate(9deg) scale(0.9); animation-timing-function: cubic-bezier(0.45, 0, 0.2, 1); }
  59.5% { opacity: 1; }
  67% { left: calc(100% - var(--cmp-r) - 14px - var(--cmp-s) / 2); top: calc(50% - var(--cmp-h) / 2 + 14px + var(--cmp-s) / 2); opacity: 1; transform: translate(-50%, -50%) rotate(-3deg) scale(1); animation-timing-function: ease-in; }
  68.4%, 100% { left: calc(100% - var(--cmp-r) - 14px - var(--cmp-s) / 2); top: calc(50% - var(--cmp-h) / 2 + 14px + var(--cmp-s) / 2); opacity: 0; transform: translate(-50%, -50%) rotate(0deg) scale(0.7); }
}
@keyframes dm-evo-cmp-drop { 0%, 65% { border-color: var(--dm-evo-app-muted); } 65.5%, 67.5% { border-color: var(--dm-evo-app-ink); } 68.5%, 100% { border-color: transparent; } }
@keyframes dm-evo-cmp-hint { 0%, 67% { opacity: 1; } 68.4%, 100% { opacity: 0; } }
@keyframes dm-evo-cmp-art { 0%, 67.5% { opacity: 0; transform: scale(0.7); } 70.3%, 100% { opacity: 1; transform: none; } }
@keyframes dm-evo-cmp-go { 0%, 77.3% { transform: none; } 77.9%, 78.5% { transform: scale(0.88); } 79.7%, 100% { transform: none; } }
@keyframes dm-evo-cmp-ring { 0%, 77.8% { opacity: 0; transform: none; } 78.5% { opacity: 0.5; } 84%, 100% { opacity: 0; transform: scale(2.2); } }
@keyframes dm-evo-cmp-go-ico { 0%, 77.8% { opacity: 1; } 79%, 100% { opacity: 0; } }
@keyframes dm-evo-cmp-sweep {
  0%, 77.8% { opacity: 0; background-position: 200% 0; }
  79% { opacity: 1; }
  84% { background-position: -60% 0; opacity: 1; }
  85.5%, 100% { background-position: -60% 0; opacity: 0; }
}
/* the card takes a breath while it generates, then swells to the slot; its
   rectangle and the photo's clip are the same numbers, so they move as one */
@keyframes dm-evo-cmp-card {
  0%, 77.8% { left: var(--cmp-l); right: var(--cmp-r); top: calc(50% - var(--cmp-h) / 2); height: var(--cmp-h); border-radius: 16px; transform: none; }
  80.5% { transform: scale(1.015); }
  83.5%, 85.8% { left: var(--cmp-l); right: var(--cmp-r); top: calc(50% - var(--cmp-h) / 2); height: var(--cmp-h); border-radius: 16px; transform: none; }
  95.3%, 100% { left: 0; right: 0; top: 0; height: 100%; border-radius: 0; transform: none; }
}
@keyframes dm-evo-cmp-face { 0%, 84% { opacity: 1; } 86%, 100% { opacity: 0; } }
@keyframes dm-evo-cmp-gen {
  0%, 84% { opacity: 0; clip-path: inset(calc(50% - var(--cmp-h) / 2) var(--cmp-r) calc(50% - var(--cmp-h) / 2) var(--cmp-l) round 16px); }
  85.8% { opacity: 1; clip-path: inset(calc(50% - var(--cmp-h) / 2) var(--cmp-r) calc(50% - var(--cmp-h) / 2) var(--cmp-l) round 16px); }
  95.3%, 100% { opacity: 1; clip-path: inset(0px 0px 0px 0px round 0px); }
}
@keyframes dm-evo-cmp-gen-img { 0%, 84% { filter: blur(16px); transform: scale(1.06); } 100% { filter: blur(0px); transform: none; } }
.dm-motion .dm-evo-sub:is(.is-on, .is-out) .dm-evo-cmp-cam { animation: dm-evo-cmp-cam 10600ms cubic-bezier(0.45, 0, 0.2, 1) both; }
.dm-motion .dm-evo-sub:is(.is-on, .is-out) .dm-evo-typed::after { animation: dm-evo-caret 10600ms steps(1) both; }
.dm-motion .dm-evo-sub:is(.is-on, .is-out) .dm-evo-cmp-field .dm-evo-typed { animation: dm-evo-cmp-text 10600ms linear both; }
.dm-motion .dm-evo-sub:is(.is-on, .is-out) .dm-evo-cmp-field::after { animation: dm-evo-cmp-sweep 10600ms cubic-bezier(0.4, 0, 0.6, 1) both; }
.dm-motion .dm-evo-sub:is(.is-on, .is-out) .dm-evo-cmp-cursor { animation: dm-evo-cmp-cursor 10600ms cubic-bezier(0.4, 0, 0.2, 1) both; }
.dm-motion .dm-evo-sub:is(.is-on, .is-out) .dm-evo-cmp-pick { animation: dm-evo-cmp-pick 10600ms linear both; }
.dm-motion .dm-evo-sub:is(.is-on, .is-out) .dm-evo-cmp-menu { animation: dm-evo-cmp-menu 10600ms var(--dm-ease-press) both; }
.dm-motion .dm-evo-sub:is(.is-on, .is-out) .dm-evo-cmp-menu .is-pick { animation: dm-evo-cmp-row 10600ms linear both; }
.dm-motion .dm-evo-sub:is(.is-on, .is-out) .dm-evo-cmp-pick-idle { animation: dm-evo-cmp-idle 10600ms var(--dm-ease-press) both; }
.dm-motion .dm-evo-sub:is(.is-on, .is-out) .dm-evo-cmp-pick-done { animation: dm-evo-cmp-done 10600ms var(--dm-ease-press) both; }
.dm-motion .dm-evo-sub:is(.is-on, .is-out) .dm-evo-cmp-drag { animation: dm-evo-cmp-drag 10600ms linear both; }
.dm-motion .dm-evo-sub:is(.is-on, .is-out) .dm-evo-cmp-drop { animation: dm-evo-cmp-drop 10600ms linear both; }
.dm-motion .dm-evo-sub:is(.is-on, .is-out) .dm-evo-cmp-drop-hint { animation: dm-evo-cmp-hint 10600ms linear both; }
.dm-motion .dm-evo-sub:is(.is-on, .is-out) .dm-evo-cmp-art { animation: dm-evo-cmp-art 10600ms var(--dm-ease-press) both; }
.dm-motion .dm-evo-sub:is(.is-on, .is-out) .dm-evo-cmp-go { animation: dm-evo-cmp-go 10600ms var(--dm-ease-press) both; }
.dm-motion .dm-evo-sub:is(.is-on, .is-out) .dm-evo-cmp-go::after { animation: dm-evo-cmp-ring 10600ms cubic-bezier(0.2, 0.7, 0.3, 1) both; }
.dm-motion .dm-evo-sub:is(.is-on, .is-out) .dm-evo-cmp-go > svg { animation: dm-evo-cmp-go-ico 10600ms linear both; }
.dm-motion .dm-evo-sub:is(.is-on, .is-out) .dm-evo-cmp { animation: dm-evo-cmp-card 10600ms var(--dm-ease-press) both; }
.dm-motion .dm-evo-sub:is(.is-on, .is-out) .dm-evo-cmp-body, .dm-motion .dm-evo-sub:is(.is-on, .is-out) .dm-evo-cmp-bar { animation: dm-evo-cmp-face 10600ms linear both; }
.dm-motion .dm-evo-sub:is(.is-on, .is-out) .dm-evo-cmp-gen { animation: dm-evo-cmp-gen 10600ms var(--dm-ease-press) both; }
.dm-motion .dm-evo-sub:is(.is-on, .is-out) .dm-evo-cmp-gen img { animation: dm-evo-cmp-gen-img 10600ms cubic-bezier(0.3, 0, 0.3, 1) both; }

/* ---------- smaller slots ----------
   Below 1100 the slot is 16/10 and full width; on a phone it is about 314x196,
   so the floating controls shrink, the secondary control goes, the shop
   shrinks its type and the video stations show only the picture. */
@media (max-width: 1100px) {
  .dm .dm-evo-float-card { left: 12px; bottom: 12px; gap: 6px; padding: 8px 10px; }
  .dm .dm-evo-float-card .dm-evo-chip { width: 16px; height: 16px; }
  .dm .dm-evo-float-card--info { left: auto; bottom: auto; right: 12px; top: 12px; }
  .dm .dm-evo-float-actions { right: 12px; top: 12px; }
  .dm .dm-evo-float-actions .dm-evo-btn { height: 24px; padding: 0 10px; font-size: 10px; }
}

@media (max-width: 720px) {
  .dm .dm-evo-float-actions { display: none; }
  .dm .dm-evo-float-card { left: 10px; bottom: 10px; padding: 6px 8px; }
  .dm .dm-evo-float-card h5 { font-size: 8px; }
  .dm .dm-evo-float-card .dm-evo-chip { width: 14px; height: 14px; }
  .dm .dm-evo-float-card--file { min-width: 0; }
  .dm .dm-evo-float-card--info { display: none; }
  .dm .dm-evo-float { bottom: 10px; padding: 4px 5px 4px 9px; font-size: 8px; }
  .dm .dm-evo-float .dm-evo-btn { height: 18px; font-size: 8px; }
  /* the shop keeps both pages and the whole grid; the type and the chrome shrink, the sizes go */
  .dm .dm-evo-store, .dm .dm-evo-pdp { padding: 6px; }
  .dm .dm-evo-store { gap: 6px; }
  .dm .dm-evo-store-bar { height: 12px; gap: 4px; }
  .dm .dm-evo-store-bar b { margin-right: 4px; font-size: 9px; }
  .dm .dm-evo-store-bar i { width: 12px; height: 3px; }
  .dm .dm-evo-store-bar svg { width: 9px; height: 9px; }
  .dm .dm-evo-store-grid { gap: 5px; }
  .dm .dm-evo-store-item { gap: 3px; }
  .dm .dm-evo-store-pic { margin-bottom: 1px; }
  .dm .dm-evo-line { height: 3px; }
  .dm .dm-evo-pdp { gap: 5px; }
  .dm .dm-evo-pdp-pic { aspect-ratio: 4 / 3; }
  .dm .dm-evo-pdp-row b { font-size: 9px; }
  .dm .dm-evo-pdp-row span { font-size: 8px; }
  .dm .dm-evo-pdp-swatches { gap: 4px; }
  .dm .dm-evo-pdp-swatches .dm-evo-chip { width: 10px; height: 10px; }
  .dm .dm-evo-pdp-sizes { display: none; }
  .dm .dm-evo-pdp-cta { height: 20px; font-size: 8px; }
  .dm .dm-evo-batch { gap: 4px; }
  .dm .dm-evo-pick { left: 4px; top: 4px; width: 12px; height: 12px; }
  .dm .dm-evo-pick svg { width: 8px; height: 8px; }
  .dm .dm-evo-count { bottom: calc(12% - 10px); height: 20px; padding: 0 9px 0 7px; font-size: 8px; }
  .dm .dm-evo-count svg { width: 10px; height: 10px; }
  /* the fan's pages are 112px wide and 45px of footer here: the words shrink, the grey lines and the signature go */
  .dm .dm-evo-fan-foot { left: 6px; right: 6px; bottom: 5px; padding-top: 5px; }
  .dm .dm-evo-fan-head { gap: 2px; }
  .dm .dm-evo-fan-head b { font-size: 7px; }
  .dm .dm-evo-fan-head b.dm-evo-fan-title { font-size: 15px; }
  .dm .dm-evo-fan-photo--grid { gap: 2px; padding: 2px; }
  .dm .dm-evo-fan-head .dm-evo-line, .dm .dm-evo-fan-credit { display: none; }
  .dm .dm-evo-fan-head small, .dm .dm-evo-fan-row small { font-size: 6px; }
  .dm .dm-evo-fan-row { gap: 4px; }
  .dm .dm-evo-fan-row .dm-evo-chips { gap: 3px; }
  .dm .dm-evo-fan-row .dm-evo-chip { width: 7px; height: 7px; }
  /* the book's pages are 109px wide here: the same cuts as the fan's */
  .dm .dm-evo-leaf-foot { left: 6px; right: 6px; bottom: 5px; padding-top: 5px; }
  .dm .dm-evo-leaf-head { gap: 2px; }
  .dm .dm-evo-leaf-head b { font-size: 7px; }
  .dm .dm-evo-leaf-head b.dm-evo-leaf-title { font-size: 15px; }
  .dm .dm-evo-leaf-photo--grid { gap: 2px; padding: 2px; }
  .dm .dm-evo-leaf-head .dm-evo-line, .dm .dm-evo-leaf-credit { display: none; }
  .dm .dm-evo-leaf-head small, .dm .dm-evo-leaf-row small { font-size: 6px; }
  .dm .dm-evo-leaf-row { gap: 4px; }
  .dm .dm-evo-leaf-row .dm-evo-chips { gap: 3px; }
  .dm .dm-evo-leaf-row .dm-evo-chip { width: 7px; height: 7px; }
  .dm .dm-evo-book { --dm-evo-bz: 0.75px; }
  /* the book is a third of the size here, so both cameras come in with it,
     keeping the same lean and the same depth in the turn */
  .dm .dm-evo-book { perspective: 640px; }
  .dm .dm-evo-book-bob { perspective: 1200px; }
  .dm .dm-evo-cursor { --dm-evo-sw-x: calc(52% + 22.5px); --dm-evo-sw-y: calc(100% - 38.5px); width: 14px; height: 14px; }
  /* a preset's name does not fit across a frame this narrow, and the copy
     beside the slot already names the three of them */
  .dm .dm-evo-morph-labels { display: none; }
  .dm .dm-evo-post--story, .dm .dm-evo-post--feed { padding: 6px; }
  .dm .dm-evo-post-row b { font-size: 14px; }
  .dm .dm-evo-post-row small { font-size: 7px; }
  .dm .dm-evo-post-body { gap: 5px; }
  .dm .dm-evo-post-body b { font-size: 14px; }
  .dm .dm-evo-sticker, .dm .dm-evo-post-tag { padding: 2px 5px; font-size: 6px; }
  .dm .dm-evo-post-cta { height: 16px; gap: 3px; font-size: 7px; }
  .dm .dm-evo-post-cta svg { width: 8px; height: 8px; }
  .dm .dm-evo-post--thumb { gap: 5px; }
  .dm .dm-evo-post--thumb b { font-size: 19px; }
  .dm .dm-evo-post--thumb small { font-size: 7px; }
  /* the composer spans the slot, its field and slot shrink with its type, and
     the pointer's marks follow through the custom properties */
  .dm .dm-evo-screen--composer { --cmp-l: 14px; --cmp-r: 14px; --cmp-h: 110px; --cmp-s: 46px; --cmp-z1: 1.5; --cmp-z2: 1.5; }
  .dm .dm-evo-cmp-field { padding: 8px 10px; font-size: 10px; }
  .dm .dm-evo-cmp-drop-hint svg { width: 11px; height: 11px; }
  .dm .dm-evo-cmp-drop-hint b { font-size: 7.5px; }
  .dm .dm-evo-cmp-drop-hint small { font-size: 6.5px; }
  .dm .dm-evo-cmp-bar, .dm .dm-evo-cmp-menu i { font-size: 8.5px; }
  .dm .dm-evo-cmp-drag-cursor { width: 13px; height: 13px; right: -7px; bottom: -8px; }
  .dm .dm-evo-cmp-cursor { width: 14px; height: 14px; }
}
