/* ============================================================
   TEACH RWANDA · MOTION LAYER
   ------------------------------------------------------------
   Behaviour only. The site looks EXACTLY the same when nothing
   is moving: no font, colour, size, spacing or layout change.
   Everything here is either a transition, a transform, or a
   hover state whose end point matches what styles.css already
   did, so the design is untouched and only the feel changes.

   Loads after styles.css. Pairs with motion.js.

   PROJECT RULES KEPT:
   · no CSS grid, nothing here lays anything out at all
   · no new fonts, no new colours, no new remote assets
   · every hidden-until-revealed state is scoped to .mo-ready,
     a class only motion.js adds, so if the script never runs
     the page still shows everything.
   ============================================================ */

:root{
  --mo-ease:cubic-bezier(.22,1,.36,1);
  --mo-ease-soft:cubic-bezier(.16,.84,.34,1);
}

/* ============================================================
   01 · SCROLL PROGRESS
   A 2px hairline in the brand gradient. Delete this block and
   the `progress` section of motion.js to remove it.
   ============================================================ */
.mo-progress{
  position:fixed;top:0;left:0;height:2px;width:100%;z-index:300;
  transform:scaleX(0);transform-origin:0 50%;pointer-events:none;
  background:linear-gradient(90deg,var(--orange) 0%,var(--gold) 100%);
}

/* ============================================================
   02 · PAGE TRANSITION
   A short wipe on internal links so the site reads as one
   document rather than a series of reloads.
   ============================================================ */
.mo-veil{
  position:fixed;inset:0;z-index:400;background:var(--charcoal);
  transform:translateY(100%);pointer-events:none;
  transition:transform .6s var(--mo-ease);
}
.mo-veil.is-out{transform:translateY(0);}

/* ============================================================
   03 · REVEAL, the existing .reveal, given a better curve
   Same start and end state as before (opacity + 22px rise),
   only slower, softer and with a touch of focus-in.
   ============================================================ */
.reveal{
  transition:opacity .9s var(--mo-ease),transform 1s var(--mo-ease),filter .9s var(--mo-ease);
}
.mo-ready .reveal{filter:blur(5px);}
.reveal.in{filter:none;}
/* will-change is only set while an element is still waiting. Leaving it on
   permanently keeps the element on its own GPU layer, which changes how the
   browser anti-aliases text, the page would render very slightly
   differently from the original even at rest. */
.mo-ready .reveal:not(.in),
.mo-ready .mo-fade:not(.in){will-change:opacity,transform,filter;}

/* rows animate one item after the next */
.mo-ready .mo-stagger>*{transition-delay:calc(var(--i,0) * 85ms);}

/* items in a row that had no .reveal of their own */
.mo-ready .mo-fade{
  opacity:0;transform:translateY(20px);
  transition:opacity .85s var(--mo-ease),transform .95s var(--mo-ease);
  transition-delay:calc(var(--i,0) * 85ms);
}
.mo-ready .mo-fade.in{opacity:1;transform:none;}

/* ============================================================
   04 · PICTURE WIPE
   Photographs uncover themselves from the bottom edge and
   settle out of a slight over-scale. The final frame is pixel
   for pixel what the page showed before.
   ============================================================ */
.mo-wipe{overflow:hidden;}
.mo-wipe img,.mo-wipe .ph{
  transition:clip-path 1.15s var(--mo-ease),transform 1.5s var(--mo-ease);
}
.mo-wipe img{
  transform:translate3d(0,var(--py,0px),0) scale(var(--sc,1.12));
}
.mo-ready .mo-wipe:not(.in) img,
.mo-wipe.mo-para-host img{will-change:transform,clip-path;}
.mo-ready .mo-wipe img,.mo-ready .mo-wipe .ph{clip-path:inset(0 0 100% 0);}
.mo-ready .mo-wipe.in img,.mo-ready .mo-wipe.in .ph{clip-path:inset(0 0 0 0);}
.mo-wipe.in img{--sc:1;}
/* a parallax host tracks the wheel once it has arrived */
.mo-wipe.mo-para-host.in img{transition:transform .2s linear;}

/* the media-card / gallery / pathway hover zooms stay exactly as
   they were, they just get a longer, smoother curve */
.media-card .frame img,.gallery-track .frame img,
.pathway-photo .frame img,.article-card .frame img{
  transition:transform .9s var(--mo-ease),clip-path 1.15s var(--mo-ease);
}

/* ============================================================
   05 · HEADLINE LINE MASKS
   motion.js measures the real rendered lines and masks each one.
   The type itself is untouched, same face, weight, size, colour.
   ============================================================ */
.mo-line{display:block;overflow:hidden;padding-bottom:.16em;margin-bottom:-.16em;}
.mo-line>i{
  display:block;font-style:inherit;transform:translateY(105%);
  transition:transform 1s var(--mo-ease);
}
.mo-split.in .mo-line>i{transform:translateY(0);}
.mo-split .mo-line:nth-child(2)>i{transition-delay:.08s;}
.mo-split .mo-line:nth-child(3)>i{transition-delay:.16s;}
.mo-split .mo-line:nth-child(4)>i{transition-delay:.24s;}
.mo-split .mo-line:nth-child(5)>i{transition-delay:.32s;}
.mo-split .mo-line:nth-child(6)>i{transition-delay:.4s;}

/* ============================================================
   06 · MICRO-INTERACTIONS
   Every hover below ends on the colour styles.css already used.
   Only the way it gets there changed.
   ============================================================ */

/* buttons fill from the bottom instead of cross-fading */
.btn{position:relative;overflow:hidden;isolation:isolate;}
.btn::before{
  content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;
  transform:translateY(101%);transition:transform .5s var(--mo-ease);
}
.btn-primary::before{background:var(--orange-deep);}
.btn-ghost-light::before{background:var(--white);}
.btn-light::before{background:var(--gold);}
.btn:hover::before,.btn:focus-visible::before{transform:translateY(0);}
.btn-primary:hover{background:var(--orange);}

/* text links draw their own underline */
/* no padding is added here, the rule is drawn just below the text so
   the resting layout is identical to the original */
.arrow-link{position:relative;}
.arrow-link::after{
  content:"";position:absolute;left:0;bottom:-3px;height:1px;width:100%;
  background:currentColor;opacity:.32;
  transform:scaleX(0);transform-origin:left;
  transition:transform .45s var(--mo-ease);
}
.arrow-link:hover::after,.arrow-link:focus-visible::after{transform:scaleX(1);}

/* dropdown items step in from the left on hover */
.dropdown a{transition:padding-left .3s var(--mo-ease),background .3s var(--mo-ease),color .3s var(--mo-ease);}
.dropdown a:hover{padding-left:1.8em;}

/* cards lift a little more slowly and land more softly */
.icon-card,.pathway,.pathway-photo,.media-card,.book-card{
  transition:transform .5s var(--mo-ease),box-shadow .5s var(--mo-ease),
             background .4s var(--mo-ease),border-color .4s var(--mo-ease);
}

/* carousel arrows and the photo rail itself */
.gallery-nav button,.gallery-toggle{transition:all .3s var(--mo-ease);}
.gallery-track{cursor:grab;}
.gallery-track:active{cursor:grabbing;}

/* the person portraits come to colour on hover */
.person .portrait img{transition:transform 1s var(--mo-ease),filter .6s var(--mo-ease);}
.person:hover .portrait img{transform:scale(1.03);}

/* ============================================================
   07 · MOBILE PANEL
   Same panel, same colours, the links now arrive in sequence.
   ============================================================ */
@media(max-width:1080px){
  .mo-ready .navlinks>ul>li{
    opacity:0;transform:translateX(18px);
    transition:opacity .45s var(--mo-ease),transform .5s var(--mo-ease);
  }
  .mo-ready .navlinks.open>ul>li{opacity:1;transform:none;}
  .navlinks.open>ul>li:nth-child(1){transition-delay:.12s;}
  .navlinks.open>ul>li:nth-child(2){transition-delay:.17s;}
  .navlinks.open>ul>li:nth-child(3){transition-delay:.22s;}
  .navlinks.open>ul>li:nth-child(4){transition-delay:.27s;}
  .navlinks.open>ul>li:nth-child(5){transition-delay:.32s;}
  .navlinks.open>ul>li:nth-child(6){transition-delay:.37s;}
  .navlinks.open>ul>li:nth-child(7){transition-delay:.42s;}
  .mo-ready .navlinks .nav-cta{
    opacity:0;transform:translateX(18px);
    transition:opacity .45s var(--mo-ease) .46s,transform .5s var(--mo-ease) .46s;
  }
  .mo-ready .navlinks.open .nav-cta{opacity:1;transform:none;}
}

/* ============================================================
   08 · REDUCED MOTION / PRINT
   Both fall back to the original static page.
   ============================================================ */
@media(prefers-reduced-motion:reduce){
  .mo-ready .reveal,.mo-ready .mo-fade{opacity:1 !important;transform:none !important;filter:none !important;}
  .mo-line>i{transform:none !important;}
  .mo-ready .mo-wipe img,.mo-ready .mo-wipe .ph{clip-path:none !important;}
  .mo-wipe img{transform:none !important;}
  .mo-veil{display:none;}
  .mo-ready .navlinks>ul>li,.mo-ready .navlinks .nav-cta{opacity:1 !important;transform:none !important;}
}
@media print{
  .mo-progress,.mo-veil{display:none !important;}
  .mo-ready .reveal,.mo-ready .mo-fade{opacity:1 !important;transform:none !important;filter:none !important;}
  .mo-ready .mo-wipe img{clip-path:none !important;transform:none !important;}
}


/* ============================================================
   09 · ONE LAYOUT FIX
   styles.css gives .article-card `height:100%`, a definite cross
   size, which opts the card out of flex stretch, so Field Notes
   cards in a row came out different heights with their dates on
   different lines. `auto` lets the row stretch them to a common
   height and the existing p{flex-grow:1} aligns every date.
   ============================================================ */
.article-grid>.article-card{height:auto;align-self:stretch;}
