/* Site-wide motion layer. See motion/README.md.
   html.m-js     set by the head script: full motion allowed, hidden start states may apply.
   html.m-full   motion.mjs is running with full motion.
   html.m-reduced motion.mjs is running for reduced motion (no movement, gentle fades only).
   Transitions carry !important only so the local-preview override survives site.css's
   reduced-motion kill switch, exactly as html.reveal-motion does. Tokens: --ease-enter, --ease-move (v2.css). */

/* ---------- Masked words (shared) ---------- */
/* The clip box is padded so Vietnamese diacritics and italic overhangs are never cut. */
m-w{display:inline-block;overflow:clip;padding:.2em .1em .08em;margin:-.2em -.1em -.08em;vertical-align:baseline}
m-wi{display:inline-block}
.m-full :is(.m-story .story-step,.m-open,.m-quote) m-wi{transform:translateY(112%)}
.m-full :is(.m-story .story-step.m-in,.m-open.m-in,.m-quote.m-in) m-wi{transform:none;transition:transform 900ms var(--ease-enter)!important}

/* ---------- Story: pinned stage, photos wipe in place ---------- */
.m-story .story-frame{opacity:1;clip-path:inset(100% 0 0 0)}
.m-story .story-frame[data-m-state=on],.m-story .story-frame[data-m-state=above]{clip-path:inset(0)}
.m-story .story-frame::after{content:"";position:absolute;inset:0;z-index:1;background:#1c1917;opacity:0;pointer-events:none}
.m-story .story-frame[data-m-state=above]::after{opacity:.28}
.m-story .story-frame img{transform:scale(1.12)}
.m-story .story-frame[data-m-state=on] img{transform:none}
.m-story .story-frame[data-m-state=above] img{transform:translateY(-6%) scale(1.04)}
.m-full .m-story .story-frame{transition:clip-path 1100ms var(--ease-move)!important}
.m-full .m-story .story-frame::after{transition:opacity 1100ms var(--ease-move)!important}
.m-full .m-story .story-frame img{transition:transform 1600ms var(--ease-enter)!important}
.m-full .m-story .story-frame[data-m-state=above] img{transition:transform 1100ms var(--ease-move)!important}
/* Reduced motion: no wipe and no zoom, the photos simply crossfade. */
.m-reduced .m-story .story-frame{clip-path:none;opacity:0;transition:opacity 300ms ease!important}
.m-reduced .m-story .story-frame[data-m-state=on]{opacity:1}
.m-reduced .m-story .story-frame::after{display:none}
.m-reduced .m-story .story-frame img{transform:none}

/* Step counter on the stage */
.m-story-count{position:absolute;left:16px;bottom:16px;z-index:10;display:flex;align-items:center;gap:6px;padding:7px 12px;border-radius:999px;background:rgba(255,255,255,.94);color:var(--poet-heading,#332b27);font-size:13px;font-weight:700;line-height:1.2;font-variant-numeric:tabular-nums;box-shadow:0 8px 20px -12px rgba(20,18,16,.5)}
.m-roll{display:block;height:1.2em;overflow:clip}
.m-roll-col{display:flex;flex-direction:column}
.m-roll-col>span{height:1.2em}
.m-full .m-roll-col{transition:transform 700ms var(--ease-move)!important}
.m-roll-total{color:var(--poet-muted,#6f6862);font-weight:400}

/* Text: the line being read is full strength, the others step back. */
.m-story .story-line{opacity:1!important}
@media(min-width:901px){
 .m-story .story-step{opacity:.24}
 .m-story .story-step.is-active{opacity:1}
 .m-full .m-story .story-step{transition:opacity 600ms ease!important}
}
/* Highlights sweep in after their words have landed. */
.m-full .m-story .story-line mark{box-shadow:none;background:linear-gradient(var(--m-hl,var(--yellow-tint)),var(--m-hl,var(--yellow-tint))) 0 88%/0% .34em no-repeat;transition:background-size 800ms var(--ease-enter)!important}
.m-full .m-story .story-line mark.hl-coral{--m-hl:var(--coral-tint)}
.m-full .m-story .story-line mark.hl-mint{--m-hl:var(--poet-mint)}
.m-full .m-story .m-in .story-line mark{background-size:100% .34em}
.m-full .m-story .pd-chips>li{opacity:0;transform:translateY(12px)}
.m-full .m-story .m-in .pd-chips>li{opacity:1;transform:none;transition:opacity 500ms ease,transform 700ms var(--ease-enter)!important}

/* Phones: the photo pins under the menu and the text cards scroll over it. */
@media(max-width:900px){
 .m-story{--m-nav:72px;--m-stage:min(calc(100svh - var(--m-nav) - 24px),150vw)}
 .m-story .story-scrolly{display:block;padding:0 var(--site-gutter)}
 .m-story .story-stage{display:block;position:sticky;top:calc(var(--m-nav) + 12px);height:var(--m-stage);margin:clamp(32px,6vw,48px) 0 0;z-index:0}
 .m-story .story-frame{border-radius:24px 56px 24px 24px}
 .m-story .story-crop{transform:none}
 .m-story .story-steps{position:relative;z-index:1;margin-top:calc(-1 * var(--m-stage));padding:calc(var(--m-stage) * .62) 0 40svh}
 .m-story .story-step{position:relative;margin:0 12px;padding:20px 20px 22px;background:var(--poet-white,#fff);border-radius:18px;box-shadow:0 14px 34px -18px rgba(36,30,26,.55)}
 .m-story .story-step+.story-step{margin-top:72svh}
 .m-story .story-step-photo{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
 .m-story .story-step .story-line{margin:0;padding:0;background:none;box-shadow:none;font-size:clamp(21px,5.6vw,26px)}
 .m-story .story-step .story-line.long{font-size:clamp(19px,5vw,23px)}
 .pd-story.m-story .story-step .story-line{font-size:17px}
 .m-story-count{left:12px;top:12px;bottom:auto}
 .m-story .story-step{opacity:1;transform:none}
}

/* ---------- Openers: photo settles, title rises, the rest follows ---------- */
.m-open>img{transform:none}
.m-full .m-open>img{transform:scale(1.08)}
.m-full .m-open.m-in>img{transform:none;transition:transform 2400ms var(--ease-enter)!important}
.m-full .m-open .story-open-text>:not(h1,h2){opacity:0;transform:translateY(14px)}
.m-full .m-open.m-in .story-open-text>:not(h1,h2){opacity:1;transform:none;transition:opacity 700ms ease var(--m-after,0ms),transform 900ms var(--ease-enter) var(--m-after,0ms)!important}

/* ---------- Quote ---------- */
.m-full .m-quote :is(.pd-quote-ic,cite){opacity:0;transform:translateY(10px)}
.m-full .m-quote.m-in :is(.pd-quote-ic,cite){opacity:1;transform:none;transition:opacity 600ms ease var(--m-after,0ms),transform 800ms var(--ease-enter) var(--m-after,0ms)!important}
.m-full .m-quote.m-in .pd-quote-ic{transition-delay:0ms!important}

/* ---------- Group entrances ---------- */
.m-full .m-rise{opacity:0;transform:translateY(16px)}
.m-full .m-rise.m-in{opacity:1;transform:none;transition:opacity 600ms ease,transform 700ms var(--ease-enter)!important}
.m-full .pd-g.m-rise{transform:none;clip-path:inset(6% round 16px)}
.m-full .pd-g.m-rise img{transform:scale(1.1)}
.m-full .pd-g.m-rise.m-in{clip-path:inset(0 round 0);transition:opacity 600ms ease,clip-path 1000ms var(--ease-enter)!important}
.m-full .pd-g.m-rise.m-in img{transform:none;transition:transform 1400ms var(--ease-enter)!important}

/* ---------- Numbers and bars ---------- */
/* Reserved at the final width; digits grow leftward like an odometer. */
m-num{display:inline-block;font-variant-numeric:tabular-nums;text-align:right}
/* Budget split fills as one continuous wipe, in step with the total counting up. */
.m-full .budget-stack.m-pre{clip-path:inset(0 100% 0 0)}
.m-full .budget-stack.m-pre.m-in{clip-path:inset(0);transition:clip-path 1500ms var(--ease-enter)!important}
.fund-timeline-track i{transform-origin:left center}
/* The "Đạt 64%" badge pops in once the count has finished. */
.m-full [data-fund-animate]:is([data-fund-motion=pending],[data-fund-motion=running]) .fund-status{opacity:0;transform:scale(.92)}
.m-full [data-fund-animate] .fund-status{transition:opacity 400ms ease,transform 500ms var(--ease-enter)!important}
