/* Sariio shared visual tokens and motion vocabulary.
   Read docs/VISUAL-ETHIC.md before changing this file.
   Everything except the page-to-page wipe is opt-in: it applies only to
   pages whose <html> element carries data-motion. */

:root{
  /* Colour: the four logo colours plus ink and paper. See docs/BRAND-COLOURS.md. */
  --s-ink:#202421;
  --s-paper:#fff;
  --s-amber:#FFAF2E;
  --s-blue:#00B3EA;
  --s-teal:#00D3B9;
  --s-coral:#FF697B;

  /* Motion: two easings and three durations. Do not add more. */
  --m-snap:cubic-bezier(.34,1.56,.64,1);   /* arrives with a small overshoot */
  --m-settle:cubic-bezier(.2,.8,.2,1);     /* arrives and stops */
  --m-fast:140ms;                          /* hover, press, small feedback */
  --m-beat:280ms;                          /* one element arriving */
  --m-scene:480ms;                         /* a panel or a page arriving */
  --m-gap:90ms;                            /* delay between siblings */
}

/* ------------------------------------------------------------------
   1. Page to page: a halftone dot wipe.
   Works between any two pages that load this file. Browsers without
   cross-document view transitions keep the ordinary page change.
   ------------------------------------------------------------------ */
@view-transition{navigation:auto}

@property --m-dot{syntax:'<length>';inherits:false;initial-value:0px}

@media (prefers-reduced-motion:no-preference){
  .site-header{view-transition-name:m-header}
  ::view-transition-old(root){animation:none;mix-blend-mode:normal}
  ::view-transition-new(root){
    mix-blend-mode:normal;
    -webkit-mask-image:radial-gradient(circle,#000 var(--m-dot),transparent calc(var(--m-dot) + .5px));
    mask-image:radial-gradient(circle,#000 var(--m-dot),transparent calc(var(--m-dot) + .5px));
    -webkit-mask-size:24px 24px;
    mask-size:24px 24px;
    animation:m-dots var(--m-scene) steps(8,end) both;
  }
}
@media (prefers-reduced-motion:reduce){
  ::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none!important}
}
@keyframes m-dots{from{--m-dot:0px}to{--m-dot:18px}}

/* ------------------------------------------------------------------
   2. The speech bubble. "Says who?" is spoken, so it is drawn as speech.
   This is styling, so it applies with or without motion.
   ------------------------------------------------------------------ */
html[data-motion] .v3-hero #research{
  position:relative;
  display:inline-block;
  margin:26px 0 22px;
  padding:.3em .75em .22em;
  background:var(--s-paper);
  border:2px solid var(--s-ink);
  border-radius:999px;
  box-shadow:4px 4px 0 var(--s-ink);
  transform:rotate(-2deg);
  transform-origin:18% 100%;
}
html[data-motion] .v3-hero #research::before,
html[data-motion] .v3-hero #research::after{
  content:"";
  position:absolute;
  left:1.1em;
  width:0;height:0;
  border-style:solid;
  border-color:transparent;
}
html[data-motion] .v3-hero #research::before{
  top:100%;
  border-width:16px 14px 0 2px;
  border-top-color:var(--s-ink);
}
html[data-motion] .v3-hero #research::after{
  top:calc(100% - 3px);
  left:calc(1.1em + 2px);
  border-width:12px 10px 0 1px;
  border-top-color:var(--s-paper);
}

/* "Says who?" heading a block of evidence: one small bubble per block,
   then each source set apart beneath its claim. */
html[data-motion] .m-says{
  position:relative;
  display:block;
  width:max-content;
  max-width:100%;
  margin:6px 0 28px;
  padding:.32em .8em .2em;
  font:400 22px/1.2 'Special Elite',monospace;
  color:var(--s-ink);
  background:var(--s-paper);
  border:2px solid var(--s-ink);
  border-radius:999px;
  box-shadow:4px 4px 0 var(--s-ink);
  transform:rotate(-2deg);
  transform-origin:18% 100%;
}
html[data-motion] .m-says::before,
html[data-motion] .m-says::after{content:"";position:absolute;left:1.1em;width:0;height:0;border-style:solid;border-color:transparent}
html[data-motion] .m-says::before{top:100%;border-width:13px 11px 0 2px;border-top-color:var(--s-ink)}
html[data-motion] .m-says::after{top:calc(100% - 3px);left:calc(1.1em + 2px);border-width:9px 8px 0 1px;border-top-color:var(--s-paper)}
html[data-motion] .m-source{
  display:block;margin-top:8px;
  font:700 11px/1.4 'DM Sans',sans-serif;letter-spacing:.1em;text-transform:uppercase;color:var(--s-ink);
}

/* The same bubble for a headline that is itself a spoken question. */
html[data-motion] .m-bubble{
  position:relative;
  display:inline-block;
  padding:.14em .6em .06em;
  background:var(--s-paper);
  border:3px solid var(--s-ink);
  border-radius:999px;
  box-shadow:6px 6px 0 var(--s-ink);
  transform:rotate(-2deg);
  transform-origin:18% 100%;
}
html[data-motion] .m-bubble::before,
html[data-motion] .m-bubble::after{
  content:"";
  position:absolute;
  left:1em;
  width:0;height:0;
  border-style:solid;
  border-color:transparent;
}
html[data-motion] .m-bubble::before{top:100%;border-width:.42em .36em 0 .06em;border-top-color:var(--s-ink)}
html[data-motion] .m-bubble::after{top:calc(100% - 4px);left:calc(1em + 3px);border-width:.3em .26em 0 .03em;border-top-color:var(--s-paper)}

/* The hero's onward link sits below both columns, after the featured article. */
html[data-motion] .v3-hero > .v3-actions{grid-column:1/-1;margin:0}

/* The marker stroke under the quoted phrase in the headline. */
html[data-motion] .m-mark{
  background:linear-gradient(var(--s-amber),var(--s-amber)) no-repeat 0 92%/100% .3em;
}

@media (prefers-reduced-motion:no-preference){

  /* ----------------------------------------------------------------
     3. The opening: runs once on load, with no JavaScript.
     Headline marker, then the bubble pops, then each source is stamped.
     ---------------------------------------------------------------- */
  html[data-motion] .m-mark{animation:m-mark var(--m-scene) steps(9,end) 320ms backwards}
  html[data-motion] .v3-hero #research{animation:m-pop var(--m-beat) var(--m-snap) 620ms backwards}
  html[data-motion] .v3-hero #research + ul > li{animation:m-stamp var(--m-beat) var(--m-settle) backwards}
  html[data-motion] .v3-hero #research + ul > li:nth-child(1){animation-delay:860ms}
  html[data-motion] .v3-hero #research + ul > li:nth-child(2){animation-delay:980ms}
  html[data-motion] .v3-hero #research + ul > li:nth-child(3){animation-delay:1100ms}
  html[data-motion] .v3-hero #research + ul > li:nth-child(n+4){animation-delay:1220ms}

  html[data-motion] .m-bubble{animation:m-pop var(--m-beat) var(--m-snap) 320ms backwards}

  /* The featured card is slapped onto the page. It stays visible throughout. */
  html[data-motion] .v3-hero > aside,
  html[data-motion] .v3-hero > figure{animation:m-slap var(--m-scene) var(--m-snap) 120ms backwards}
  html[data-motion] .home-featured-article{animation:m-slap var(--m-scene) var(--m-snap) 120ms backwards}
  html[data-motion] .home-featured-article .featured-article-ribbon{animation:m-sticker var(--m-beat) var(--m-snap) 640ms backwards}

  /* A row of example panels is laid down like a comic strip, left to right. */
  html[data-motion] .sbx-panel{animation:m-panel var(--m-scene) var(--m-snap) backwards}
  html[data-motion] .sbx-panel:nth-child(1){animation-delay:160ms}
  html[data-motion] .sbx-panel:nth-child(2){animation-delay:250ms}
  html[data-motion] .sbx-panel:nth-child(3){animation-delay:340ms}
  html[data-motion] .sbx-panel:nth-child(4){animation-delay:430ms}
  html[data-motion] .sbx-panel:nth-child(5){animation-delay:520ms}
  html[data-motion] .sbx-panel:nth-child(n+6){animation-delay:610ms}

  /* ----------------------------------------------------------------
     4. Arriving on scroll. js/sariio-motion.js sets data-m on elements
     that start below the fold and adds .m-in when they come into view.
     ---------------------------------------------------------------- */
  html[data-motion] [data-m]:not(.m-in){opacity:0}
  html[data-motion] [data-m="type"]:not(.m-in){opacity:1;clip-path:inset(-.2em 100% -.2em -.1em)}

  html[data-motion] [data-m="panel"].m-in{
    animation:m-panel var(--m-scene) var(--m-snap) calc(var(--m-i,0) * var(--m-gap)) backwards;
  }
  html[data-motion] [data-m="type"].m-in{
    animation:m-type var(--m-scene) steps(14,end) backwards;
  }
  html[data-motion] [data-m="tab"].m-in{
    animation:m-tab var(--m-beat) var(--m-settle) backwards;
  }
  html[data-motion] [data-m="pop"].m-in{animation:m-pop var(--m-beat) var(--m-snap) backwards}
  /* Evidence is stamped: figures land once, in order, and hold still. */
  html[data-motion] [data-m="stamp"].m-in{
    animation:m-stamp var(--m-beat) var(--m-settle) calc(var(--m-i,0) * var(--m-gap)) backwards;
  }
  /* Numbered steps: the number is stuck on just after its panel lands. */
  html[data-motion] [data-m].m-in .coaching-step__marker > span{
    display:inline-block;
    animation:m-sticker var(--m-beat) var(--m-snap) calc(var(--m-i,0) * var(--m-gap) + 150ms) backwards;
  }

  /* ----------------------------------------------------------------
     5. Changing state: the SARIIO letters. The animation starts each
     time a panel is shown, so no script is needed.
     ---------------------------------------------------------------- */
  html[data-motion] .sariio-panel:not([hidden]) > :is(img,.m-art){animation:m-turn var(--m-scene) var(--m-snap) backwards}
  html[data-motion] .sariio-panel:not([hidden]) > div{animation:m-follow var(--m-beat) var(--m-settle) 80ms backwards}
  html[data-motion] .sariio-model [aria-selected="true"] .sariio-letter{animation:m-letter var(--m-beat) var(--m-snap)}
  html[data-motion] .sariio-model .sariio-letter{display:inline-block;transition:transform var(--m-fast) var(--m-snap)}
  html[data-motion] .sariio-model button:hover .sariio-letter{transform:rotate(-7deg) scale(1.12)}
  /* Opening an answer or a summary: the content follows in from the side. */
  html[data-motion] main details[open] > :not(summary){animation:m-follow var(--m-beat) var(--m-settle) backwards}
  html[data-motion] .home-featured-article details[open] > *{animation:none}

  /* ----------------------------------------------------------------
     6. Touch: things on the page respond like card on a desk.
     Hover lifts a corner. Press pushes the card onto its shadow.
     ---------------------------------------------------------------- */
  html[data-motion] .v3-insight,
  html[data-motion] .home-panel,
  html[data-motion] .v3-asks a{
    transition:transform var(--m-fast) var(--m-snap),box-shadow var(--m-fast) var(--m-settle);
  }
  /* Lift only where there is a real pointer: on a touch screen a card that
     moves under the finger can swallow the tap. A card holding a video
     never moves, so its player controls stay put. */
  @media (hover:hover){
    html[data-motion] .v3-insight:not(:has(video)):hover,
    html[data-motion] .home-panel:hover,
    html[data-motion] .v3-asks a:hover,
    html[data-motion] .v3-asks a:focus-visible{transform:translate(-3px,-4px) rotate(-.5deg)}
  }
  html[data-motion] .v3-insight:has(video):hover{transform:none}
  html[data-motion] .v3-insight:not(:has(video)):active,
  html[data-motion] .home-panel:active,
  html[data-motion] .v3-asks a:active{transform:translate(3px,3px);transition-duration:60ms}

  /* Buttons press into the page. */
  html[data-motion] .v3-button{transition:transform var(--m-fast) var(--m-snap),background-color var(--m-fast) var(--m-settle)}
  html[data-motion] .v3-button:active{transform:translate(2px,2px);transition-duration:60ms}

  /* Arrows travel in the direction they point. */
  html[data-motion] .v3-link > span[aria-hidden],
  html[data-motion] .home-panel-link > span[aria-hidden]{display:inline-block;transition:transform var(--m-fast) var(--m-snap)}
  html[data-motion] .v3-link:hover > span[aria-hidden],
  html[data-motion] .home-panel-link:hover > span[aria-hidden]{transform:translateX(5px)}
  html[data-motion] .v3-link[href^="#"]:hover > span[aria-hidden],
  html[data-motion] .home-panel-link[href^="#"]:hover > span[aria-hidden]{transform:translateY(4px)}

  /* The ribbon is a sticker; it lifts when the card is touched. */
  html[data-motion] .home-featured-article .featured-article-ribbon{transition:transform var(--m-fast) var(--m-snap)}
  html[data-motion] .home-featured-article:hover .featured-article-ribbon{transform:rotate(-10deg) scale(1.06)}

  /* Navigation: the underline is drawn with a marker, left to right. */
  html[data-motion] #sariio-site .site-nav a{
    background:linear-gradient(var(--s-amber),var(--s-amber)) no-repeat 0 100%/0 3px;
    transition:background-size var(--m-beat) var(--m-settle);
    padding-bottom:5px;
  }
  html[data-motion] #sariio-site .site-nav a:hover,
  html[data-motion] #sariio-site .site-nav a:focus-visible{background-size:100% 3px;text-decoration:none}
}

/* ------------------------------------------------------------------
   7. Artwork: printed, not rendered.
   js/sariio-motion.js gives each illustration an .m-art frame and adds
   the #m-print filter. Colour is flattened into steps and a dot screen
   is laid over it. This is styling, so it applies with or without motion.
   ------------------------------------------------------------------ */
html[data-motion] .m-art{position:relative;display:block;overflow:hidden}
html[data-motion] span.m-art > img{display:block;width:100%;height:auto}
html[data-motion] .home-featured-article > span.m-art{margin-bottom:12px;border:2px solid var(--s-ink)}
html[data-motion] .m-art > img,
html[data-motion] #sariio-site .m-art > img.v3-art-reveal{filter:url(#m-print)!important;transition:transform .5s ease}
html[data-motion] .m-art::after{
  content:"";position:absolute;inset:0;pointer-events:none;mix-blend-mode:multiply;opacity:.3;
  background:
    radial-gradient(circle,var(--s-ink) 0 24%,transparent 27%) 0 0/5px 5px,
    radial-gradient(circle,var(--s-ink) 0 24%,transparent 27%) 2.5px 2.5px/5px 5px;
}
/* The approved monochrome-until-seen treatment moves to the frame, so it
   still fades in over the printed image. */
html[data-motion] .m-art{transition:filter 3s ease-in-out}
html[data-motion] .m-art:has(> img.v3-art-reveal:not(.is-visible)){filter:grayscale(1);transition:none}

/* Close crops. Only images with one clear figure, and only in card and
   feature slots. Focal point and zoom are set per image below. */
html[data-motion] :is(.v3-insight-thumb,.home-panel-art,.home-featured-article > span).m-art > img{
  transform:scale(var(--m-z,1));transform-origin:var(--m-fx,50%) var(--m-fy,50%);
}
html[data-motion] .v3-insight:hover .v3-insight-thumb.m-art > img{transform:scale(calc(var(--m-z,1) * 1.04))}
html[data-motion] .m-art > img[src*="we-do-our-best-work-when-we-play-to-our-preferences"]{--m-z:2.1;--m-fx:60%;--m-fy:38%}
html[data-motion] .m-art > img[src*="what-are-work-preferences"]{--m-z:1.9;--m-fx:52%;--m-fy:30%}
html[data-motion] .m-art > img[src*="feedback-sandwich-review-everyday"]{--m-z:1.5;--m-fx:72%;--m-fy:40%}
html[data-motion] .m-art > img[src*="the-global-engagement-crisis"]{--m-z:1.45;--m-fx:6%;--m-fy:72%}
html[data-motion] .m-art > img[src*="is-outsourcing-to-south-africa-legit"]{--m-z:1.6;--m-fx:30%;--m-fy:36%}
html[data-motion] .m-art > img[src*="why-it-takes-ai-to-keep-the-human-at-the-centre"]{--m-z:1.6;--m-fx:40%;--m-fy:36%}
html[data-motion] .m-art > img[src*="can-ai-replace-call-centre-agents"]{--m-z:1.7;--m-fx:50%;--m-fy:42%}
html[data-motion] .m-art > img[src*="will-ai-take-call-centre-jobs-in-south-africa"]{--m-z:1.7;--m-fx:62%;--m-fy:40%}
html[data-motion] .m-art > img[src*="how-do-you-motivate-call-centre-agents"]{--m-z:1.8;--m-fx:62%;--m-fy:56%}
html[data-motion] .m-art > img[src*="what-is-impact-sourcing"]{--m-z:1.5;--m-fx:54%;--m-fy:46%}
/* A cropped image may lose the logo hidden in the scene, so the frame
   carries the real mark as a small sticker. */
html[data-motion] .m-art--crop::before{
  content:"";position:absolute;right:8px;bottom:8px;z-index:1;width:30px;height:30px;
  border:2px solid var(--s-ink);border-radius:50%;
  background:var(--s-paper) url(/assets/images/hero/sariio-mark-80.webp) center/20px 20px no-repeat;
  box-shadow:2px 2px 0 var(--s-ink);transform:rotate(-8deg);
}

@media print{
  html[data-motion] [data-m]{opacity:1!important;clip-path:none!important;animation:none!important}
}

@keyframes m-mark{from{background-size:0 .3em}}
@keyframes m-pop{from{opacity:0;transform:rotate(-12deg) scale(.2)}}
@keyframes m-stamp{from{opacity:0;transform:scale(1.08) rotate(-1.2deg)}}
@keyframes m-slap{from{transform:translate(22px,-16px) rotate(2.4deg)}}
@keyframes m-sticker{from{opacity:0;transform:rotate(-20deg) scale(2)}}
@keyframes m-panel{
  from{opacity:0;transform:translate(-12px,18px) rotate(-1.6deg) scale(.97);box-shadow:0 0 0 var(--s-ink)}
  55%{opacity:1}
}
@keyframes m-type{from{clip-path:inset(-.2em 100% -.2em -.1em)}to{clip-path:inset(-.2em -.1em)}}
@keyframes m-tab{from{opacity:0;transform:translateX(-14px)}}
@keyframes m-turn{from{opacity:0;transform:translateX(-18px) rotate(-3deg) scale(.94)}}
@keyframes m-follow{from{opacity:0;transform:translateX(16px)}}
@keyframes m-letter{from{transform:scale(1.5) rotate(-10deg)}}
