/* ═══════════════════════════════════════════════════════════════════════
   FIDA — HOME
   A 1:1 build of Figma frame "HOME" (1440 × 6640, id 3:24).

   Every left / top / width / height in index.html is the exact Figma
   coordinate, measured from the top-left of the HOME frame. The whole
   1440-wide artboard is then scaled proportionally to the viewport, so the
   page is pixel-identical to the design at any screen width.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── reset ─────────────────────────────────────────────────────────── */
*,*::before,*::after{box-sizing:border-box}
html,body{margin:0;padding:0}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{background:#181717;overflow-x:hidden}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer}
h2,h3{margin:0;font-weight:inherit}

/* ── tokens ────────────────────────────────────────────────────────── */
:root{
  /* proportional scale — JS refines this to exclude the scrollbar */
  --scale:calc(100vw / 1440);
  /* artboard height of the Figma frame this page reproduces. HOME is 6640;
     each other page overrides it on <html>. */
  --stage-h:6640px;

  --ink:#000000;
  --lilac:#ddd2f0;
  --lilac-logo:#ded1f2;
  --white:#ffffff;
  --page:#181717;

  /* First name in each stack is the licensed Figma font — it takes over the
     moment its block in fonts.css is uncommented. Second is the self-hosted
     open-licence stand-in, size-adjusted to the same metrics. See fonts.css. */
  --ff-sans:'Inter',-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
  --ff-display:'Pujarelah','Cormorant Garamond',Georgia,'Times New Roman',serif;
  --ff-name:'Romelu Vomelu','Bodoni Moda',Georgia,'Times New Roman',serif;
  --ff-script:'Edwardian Script ITC','Mrs Saint Delafield','Segoe Script',cursive;
  --ff-banner:'Miller Banner','Playfair Display',Georgia,'Times New Roman',serif;

  /* ── ASSET SLOTS ──────────────────────────────────────────────────
     Every image on the page is referenced through one of these. To put a
     real photo / logo in, drop the file in site/assets/ and change ONLY
     the line below — nothing else in the project needs touching.        */
  --img-hero-photo:url('../assets/img/hero-photo.png');
  --img-about:url('../assets/img/about-portrait.jpg');
  --img-work1:url('../assets/img/work-1-mozitti.jpg');
  --img-work2:url('../assets/img/work-2-khadera.jpg');
  --img-work3:url('../assets/img/work-3-lalla-tea.jpg');
  --img-proc1:url('../assets/img/process-1-discovery.jpg');
  --img-proc2:url('../assets/img/process-2-strategy.jpg');
  --img-proc3:url('../assets/img/process-3-design.jpg');
  --img-proc4:url('../assets/img/process-4-refinement.jpg');
  --img-tex-create:url('../assets/img/texture-what-i-create.jpg');
  --img-tex-cta:url('../assets/img/texture-cta.png');
  --img-logo-nav:url('../assets/img/fida-logo-nav.svg');
  --img-logo-footer:url('../assets/img/fida-logo-footer.png');
  --img-badge:url('../assets/img/rotating-badge.svg');

  /* the 15 × 15 ornament that flanks every heading — real Figma geometry,
     used as a mask so .ink / .lilac can recolour it                        */
  --spark:url('../assets/img/star-ornament.svg');

  /* the "Explore Project" arrow — Figma "Arrow 1", exported from its real
     strokeGeometry, head and all. Masked, so it recolours like the ornament. */
  --arrow:url('../assets/img/arrow-explore.svg');
}

/* ── preview mode: what a visitor WITHOUT the licensed fonts sees ───────
   Edwardian Script ITC ships with Microsoft Office, so on this machine the
   browser quietly uses the real one and the page looks better here than it
   does for everyone else. Open the page with  ?standin  on the URL to force
   the open-licence stand-ins and see the honest result.                   */
html.standin{
  --ff-display:'Cormorant Garamond',Georgia,'Times New Roman',serif;
  --ff-name:'Bodoni Moda',Georgia,'Times New Roman',serif;
  --ff-script:'Mrs Saint Delafield',cursive;
  --ff-banner:'Playfair Display',Georgia,'Times New Roman',serif;
}

/* ── the artboard ──────────────────────────────────────────────────── */
.stage-wrap{width:100%;overflow:hidden;height:calc(var(--stage-h) * var(--scale))}
.stage{
  position:relative;width:1440px;height:var(--stage-h);background:var(--page);
  overflow:hidden;transform:scale(var(--scale));transform-origin:0 0;
}
.sec{position:absolute;overflow:hidden}

/* Figma z-order: children[0] paints first. The HOME frame lists
   FOOTER → … → NAVEBAR, so the navbar is the front-most layer.          */
.sec-footer{z-index:1}
.sec-cta   {z-index:2}
.sec-logos {z-index:3}
.sec-words {z-index:4}
.z-mani2   {z-index:5}
.sec-vision{z-index:6}
.sec-create{z-index:7}
.sec-about {z-index:8}
.sec-work  {z-index:9}
.z-mani1   {z-index:10}
.sec-hero  {z-index:11}

/* ── text boxes ────────────────────────────────────────────────────── */
.txt{position:absolute;display:flex;margin:0}
.vt{align-items:flex-start}          /* Figma textAlignVertical: TOP    */
.vc{align-items:center}              /* Figma textAlignVertical: CENTER */
.in{display:block;width:100%;margin:0;white-space:pre-wrap}

/* Text nodes that are a single line in Figma stay a single line here, even
   while a substitute face is standing in for Pujarelah / Romelu Vomelu /
   Edwardian Script / Miller Banner. Without this the wider fallback glyphs
   wrap the headings onto two lines and the whole page drifts.            */
.f-nav .in, .f-h48 .in, .f-h32 .in, .f-script80 .in, .f-script40 .in,
.f-num .in, .f-name24 .in, .f-i16i .in, .f-i18sb .in, .f-i13sb .in,
.f-p24c .in, .f-p14 .in, .f-hi .in, .f-hero-title .in{white-space:pre}
.ta-c{text-align:center}
.ta-r{text-align:right}
.ta-j{text-align:justify}
.ink{color:var(--ink)}
.lilac{color:var(--lilac)}
.white{color:var(--white)}
.lsp{letter-spacing:.18px}

/* ── type scale, straight out of the Figma text styles ─────────────── */
.f-nav      {font:400 14px/16.94px var(--ff-sans);color:var(--lilac)}
.f-h48      {font:500 48px/73.44px var(--ff-display)}
.f-h32      {font:500 32px/48.96px var(--ff-display)}
.f-p32      {font:400 32px/37.12px var(--ff-display)}
.f-p25      {font:400 25px/38.25px var(--ff-display)}
.f-p24m     {font:500 24px/35.04px var(--ff-display)}
.f-p24c     {font:500 24px/36.72px var(--ff-display)}
.f-p16m     {font:500 16px/24.48px var(--ff-display)}
.f-p16m2    {font:500 16px/20.64px var(--ff-display)}
.f-p14      {font:400 14px/21.42px var(--ff-display)}
.f-p22i     {font:italic 400 22px/33.66px var(--ff-display)}
.f-p24i     {font:italic 400 24px/36.72px var(--ff-display)}
/* The Sarah Bouftila testimonial is about twice the length of the other three
   and does not fit the slot FIDA drew for it. Her box says 856 × 272 — eight
   lines — but the copy carries SIX hard breaks: five paragraphs plus two blank
   lines. That floors it at eleven lines, 370px, even given the FULL width of
   the carousel window. It was running over the client name, the company and
   the prev/next arrows.

   Not a substitute-font artefact. Slides 1, 3 and 4 all render SHORTER than
   their Figma boxes (168/193, 168/193, 184/193) — only this one box is stale.
   Figma has it as textAutoResize:HEIGHT with absoluteRenderBounds:null, i.e.
   the variant was never re-rendered after the copy was lengthened, so the 272
   was never recomputed.

   18px is the smallest change that clears the name with room to spare (ends
   361 against the name at 384), and per-testimonial sizing is FIDA's own
   precedent — she sets slide 4 at 24px where the others are 22.

   Specificity is deliberately (0,1,0) and placed after .f-p22i so mobile.css,
   which loads later, still wins on the phone.

   RE-CHECKED 2026-08-15, once the real Pujarelah Italic was installed: it is
   slightly WIDER than the synthetic slant it replaced (530.5 vs 520.4 on a
   55-character sample at 22px), so the quote now needs 438px at 22px against
   326 available. This rule stays. Only a shorter quote or a taller slot from
   FIDA removes it.                                                        */
.cw-long{font-size:18px;line-height:27.54px}
.f-num      {font:italic 400 100px/126px var(--ff-name)}
.f-name24   {font:italic 400 24px/36.72px var(--ff-name)}
.f-script80 {font:400 80px/122.4px var(--ff-script)}
.f-script40 {font:400 40px/61.2px var(--ff-script)}
.f-mb32     {font:400 32px/38.4px var(--ff-banner)}
.f-i18sb    {font:600 18px/27.54px var(--ff-sans)}
.f-i18l     {font:300 18px/26.28px var(--ff-sans)}
.f-i16i     {font:italic 400 16px/24.48px var(--ff-sans)}
.f-i15m     {font:500 15px/22.95px var(--ff-sans)}
.f-i13sb    {font:600 13px/15.08px var(--ff-sans)}
.f-i12      {font:400 12px/15.12px var(--ff-sans)}

/* per-character overrides taken from Figma's styleOverrideTable */
.pj-sb20{font-weight:600;font-size:20px}                       /* project titles  */
.pj-m24 {font:500 24px/33px var(--ff-display)}                 /* "Hi, I'm"       */
.in-sb24{font:600 24px/33px var(--ff-sans)}                    /* the space + "." */
.ed-40  {font:400 40px/33px var(--ff-script)}                  /* "Fida"          */

/* ── shared primitives ─────────────────────────────────────────────── */
.spark{
  position:absolute;width:15px;height:15px;background-color:currentColor;
  -webkit-mask:var(--spark) center/contain no-repeat;
          mask:var(--spark) center/contain no-repeat;
}
.hairline{position:absolute;height:.5px;background:var(--lilac)}   /* Figma "Vector 4", 0.5px */
/* A line break taken from one of FIDA's PHONE screens. The desktop artboard
   wraps inside its own Figma box, so these are off here and switched on in
   mobile.css. */
.pb{display:none}
.rule-v{position:absolute;background:var(--lilac)}                 /* Figma "Vector 1", 1px   */
/* Figma "Arrow 1" — an ARROW, with a chevron head, not a dash.
   Its absoluteBoundingBox is 14 × 0 because that is the GEOMETRY box: Figma
   measures the bare line and ignores both the 1px stroke and the head. The
   painted box is absoluteRenderBounds, 14.5 × 7.364, with the shaft sitting
   3.682px down from its top — which is why every instance carries
   top = (text centre − 3.682) rather than (text centre − 0.5).
   Reading the geometry box instead of the render box is what shipped a plain
   bar here; the same trap is why "Vector 4" and "Vector 1" are worth a look
   before they are ever redrawn in CSS. */
.arrow{
  position:absolute;background-color:currentColor;color:var(--ink);
  -webkit-mask:var(--arrow) left center/contain no-repeat;
          mask:var(--arrow) left center/contain no-repeat;
}
.btn{position:absolute;display:block;border-radius:40px}
.btn-lilac{background:var(--lilac)}
.btn-black{background:var(--ink)}
.pill-outline{position:absolute;display:block;border-radius:15px}
.explore{position:absolute;display:block}
/* Figma strokes are INSIDE-aligned. Drawing them on a ::before instead of on
   the element keeps the element's containing block at the border box, so the
   absolutely-placed label inside still lands on its exact Figma coordinate. */
.btn-outline-black{background:transparent}
.btn-outline-black::before{content:'';position:absolute;inset:0;border:1px solid var(--ink);border-radius:40px;pointer-events:none}
.pill-outline::before{content:'';position:absolute;inset:0;border:.5px solid var(--lilac);border-radius:15px;pointer-events:none}

/* ══ NAVEBAR — position:fixed, outside the scaled stage ═════════════ */
.navwrap{
  position:fixed;left:0;top:0;width:1441px;height:102px;
  transform:scale(var(--scale));transform-origin:0 0;z-index:1000;
}
.navbar{position:absolute;left:0;top:0;width:1441px;height:101px;background:var(--ink)}
.nav-links{position:static}
/* The wordmark and the social glyphs are one shape in Figma but a different
   colour per page — lilac on HOME/ABOUT/SERVICES, black on CONTACT. They are
   exported flat black and drawn as masks so `color` picks the fill, exactly
   the way Figma re-tints the same component.                              */
.logo-nav{
  position:absolute;display:block;
  background-color:currentColor;color:var(--lilac-logo);
  -webkit-mask:var(--img-logo-nav) center/contain no-repeat;
          mask:var(--img-logo-nav) center/contain no-repeat;
}
.soc-i{
  display:block;width:22px;height:22px;
  background-color:currentColor;
  -webkit-mask:var(--icon) center/contain no-repeat;
          mask:var(--icon) center/contain no-repeat;
}
.i-tiktok   {--icon:url('../assets/img/icon-tiktok.svg')}
.i-instagram{--icon:url('../assets/img/icon-instagram.svg')}

/* ══ HERO ══════════════════════════════════════════════════════════ */
/* fills = [IMAGE@20%, SOLID #000] — in Figma the solid paints over the
   image, so the hero background is flat black. The texture file is kept
   in assets/img/texture-hero.svg for reference only.                    */
.sec-hero{background:var(--ink)}
.hero-photo{position:absolute;background:var(--img-hero-photo) center/cover no-repeat}
.f-hero-title{color:var(--lilac)}
.ht-script{font:400 100px/118.01px var(--ff-script)}
.ht-gap   {font:400 100px/118.01px var(--ff-sans)}
.ht-name  {font:italic 400 75px/82.6px var(--ff-name)}
.hero-star{position:absolute}
.star-inner{position:absolute;left:3px;top:3.01px;transform-origin:50% 50%}

/* ══ NANIFESTO strip ═══════════════════════════════════════════════ */
.sec-mani{background:var(--lilac)}
.mani-view{position:absolute;overflow:hidden}
.mani-track{position:absolute;display:flex;will-change:transform}
.mani-copy{
  display:flex;align-items:center;height:40px;
  flex:0 0 var(--mani-w,2202px);white-space:nowrap;color:var(--ink);
}

/* ══ SELECTED WORK ═════════════════════════════════════════════════ */
.sec-work{background:var(--white)}
.work-img{position:absolute;display:block;border-radius:15px;overflow:hidden;background-repeat:no-repeat}
.img-work1{background-image:var(--img-work1);background-size:169.61% 117.01%;background-position:17.03% 13.67%}
.img-work2{background-image:var(--img-work2);background-size:149.54% 188.05%;background-position:45.40% 54.47%}
.img-work3{background-image:var(--img-work3);background-size:138.50% 180.29%;background-position:43.77% 49.68%}

/* ══ ABOUT ME ══════════════════════════════════════════════════════ */
.sec-about{background:var(--lilac)}
/* The portrait frame is MIRRORED in Figma, not rotated. Node 13:76 carries
   relativeTransform [[-1,0,500],[0,1,49.0782]] — determinant -1, a horizontal
   reflection; a true 180° would be [[-1,0,tx],[0,-1,ty]], determinant +1.
   Figma's own `rotation` field reports pi for it, because it extracts an angle
   from a negative-determinant matrix, and that scalar is what this build
   trusted — so the photograph shipped as its own mirror image. The matrix is
   ground truth. The reflection does not change the AABB, so left/top/size and
   the crop percentages below all stay exactly as they are. */
.about-photo{
  position:absolute;opacity:.97;background-repeat:no-repeat;
  background-image:var(--img-about);background-size:118.79% 120.57%;background-position:67.74% 94.95%;
  transform:scaleX(-1);
}

/* ══ WHAT I CREATE ═════════════════════════════════════════════════ */
.sec-create{background:var(--white)}
.create-inner{position:absolute;background:var(--ink)}
.create-inner::after{
  content:'';position:absolute;inset:0;opacity:.17;background-repeat:no-repeat;
  background-image:var(--img-tex-create);background-size:110.12% 484.21%;background-position:49.96% 55.60%;
}

/* ══ FROM VISION TO IDENTITY ═══════════════════════════════════════ */
.sec-vision{background:var(--white)}
.vision-band{position:absolute;background:var(--ink)}
.proc-img{position:absolute;overflow:hidden;background-repeat:no-repeat}
.img-proc1{background-image:var(--img-proc1);background-size:154.24% 199.87%;background-position:9.74% 89.65%}
.img-proc2{background-image:var(--img-proc2);background-size:133.84% 154.19%;background-position:19.19% 91.02%}
.img-proc3{background-image:var(--img-proc3);background-size:100% 129.48%;background-position:0% 62.19%}
/* Card 04 is ALSO mirrored, on top of its fill rotation. Node 32:38 carries
   relativeTransform [[-1,0,305],[0,1,0]] — determinant -1. Siblings 30:43,
   32:25 and 32:31 are all identity, so 04 really is the odd one out. Only the
   fill's 90° was reproduced below; the frame's reflection was missed, and
   mirror ∘ rotate(-90°) is a reflection about the anti-diagonal, which no
   rotation can absorb. Scoped by :not() so it hits only card 04 — .proc-img
   is on all four wrappers. */
.proc-img:not(.img-proc1):not(.img-proc2):not(.img-proc3){transform:scaleX(-1)}
/* card 04's fill carries a 90° rotation in Figma (imageTransform
   [[0,-0.6413,0.8219],[0.8311,0,0.0436]]). Reproduced exactly:          */
.img-proc4{
  position:absolute;left:0;top:0;width:550.44px;height:366.98px;display:block;
  background:var(--img-proc4) center/cover no-repeat;
  transform-origin:0 0;transform:translate(-16px,452.41px) rotate(-90deg);
}

/* ══ CLIENT WORDS ══════════════════════════════════════════════════ */
.sec-words{background:var(--ink)}
/* The chip and its label are TILTED in Figma — the chip by -10.0636°, the
   label by -9.4795°. The two angles differ by a degree, which is what makes it
   read as hand-placed rather than as a component.

   absoluteBoundingBox on a rotated node is the AABB of the tilt, not the
   shape: the chip's own size is 97.105 × 18.582 but its AABB is 98.858 ×
   35.265. Reading the AABB shipped a level slab 1.90× too tall. Each element
   now carries its true size, with transform-origin at 0 0 so `left` is
   unchanged and only `top` moves — by (width × sinθ), which is exactly the
   relativeTransform ty Figma records (16.9682 for the chip).

   The shadow offset is pre-rotated. Figma applies a DROP_SHADOW in absolute
   space, so it does NOT tilt with the layer — proof: bb.y 4297.0001 − 4
   (offset) + 2 (spread) − 5.4225 (blur) = 4289.5776, exactly the recorded
   absoluteRenderBounds.y. A CSS box-shadow inside a rotate() DOES tilt, so
   the authored offset is R(+10.0636°)·(−6,−4) = (−5.209, −4.987), which lands
   back on (−6,−4) once the element's own rotation is applied.               */
.chip{
  position:absolute;background:var(--lilac);border-radius:3px;
  transform-origin:0 0;transform:rotate(-10.0636deg);
  box-shadow:-5.209px -4.987px 5.9px -2px #000;
}
.chip-t{z-index:1;transform-origin:0 0;transform:rotate(-9.4795deg)}
.wz{z-index:2}                       /* the script heading sits above the chip */
.cw-view{position:absolute;overflow:hidden;z-index:3}
.cw-track{position:absolute;left:0;top:0;width:4990px;height:492px;transition:transform .3s linear}
.cw-dots{position:absolute;inset:0;pointer-events:none}
.cw-dot{position:absolute;pointer-events:auto;cursor:pointer}
/* at either end the arrow is dim AND inert — main.js sets `disabled` */
.cw-dot[disabled]{cursor:default}
/* The carousel's prev/next are ARROW glyphs, not blocks. Nothing in the
   bounding boxes says so — box and render bounds are both exactly 52 × 18 and
   both correct — only the node's fillGeometry shows the 3.15px shaft and the
   chevron, which is why a bounds sweep can't find this class of bug.

   Direction comes from the composed transform chain, not from guesswork:
     Frame 176 (prev) — the Vector alone carries [[-1,0],[0,-1]], a 180°
                        rotation, det +1  → points LEFT
     Frame 177 (next) — Frame 177 adds [[-1,0],[0,1]], a horizontal mirror, so
                        the composition is [[1,0],[0,-1]], det -1 → points
                        RIGHT, vertically flipped. The glyph is NOT symmetric
                        about its own centre (shaft at y 9.05 against a 9.00
                        box centre), so the flip is not a no-op.             */
.cw-dot .bar{
  position:absolute;display:block;background-color:var(--lilac);
  -webkit-mask:url('../assets/img/arrow-carousel.svg') center/contain no-repeat;
          mask:url('../assets/img/arrow-carousel.svg') center/contain no-repeat;
  opacity:.2;transition:opacity .3s linear;
}
.cw-dot .bar.on{opacity:1}
.cw-dot[data-dir="-1"] .bar{transform:rotate(180deg)}
.cw-dot[data-dir="1"]  .bar{transform:scaleY(-1)}

/* ══ LOGOS ═════════════════════════════════════════════════════════ */
.sec-logos{background:var(--white)}
.mq{position:absolute;overflow:hidden}
.mq-track{position:absolute;will-change:transform}
.lg{position:absolute;display:block;background-position:center;background-repeat:no-repeat;background-size:contain}
.lg-khadera  {background-image:url('../assets/logos/khadera.svg')}
.lg-miskie   {background-image:url('../assets/logos/miskie.svg')}
.lg-cook     {background-image:url('../assets/logos/cookrunchy.svg')}
.lg-valena   {background-image:url('../assets/logos/valena-living.svg')}
.lg-fespotte {background-image:url('../assets/logos/fespotte.svg')}
.lg-marocca  {background-image:url('../assets/logos/marocca.svg')}
.lg-soft     {background-image:url('../assets/logos/soft-skin.svg')}
.lg-imanelle {background-image:url('../assets/logos/imanelle.svg')}
.lg-ss       {background-image:url('../assets/logos/ss.svg')}
.lg-lalla    {background-image:url('../assets/logos/lalla-tea.svg')}
.lg-konoz    {background-image:url('../assets/logos/konoz-firas.svg')}
.lg-mozitti  {background-image:url('../assets/logos/mozitti.svg')}
.lg-isolation{background-image:url('../assets/logos/isolation-mode.svg')}
.lg-dardifa  {background-image:url('../assets/logos/dar-difa.png')}
.lg-zifi     {background-image:url('../assets/logos/zifi.svg')}
.lg-tomoury  {background-image:url('../assets/logos/tomoury.svg')}
.lg-amazir   {background-image:url('../assets/logos/amazir.svg')}
.lg-demure   {background-image:url('../assets/logos/demure.svg')}

/* ══ CTA ═══════════════════════════════════════════════════════════ */
.sec-cta{background:var(--lilac)}
.sec-cta::before{
  content:'';position:absolute;inset:0;opacity:.18;background-repeat:no-repeat;
  background-image:var(--img-tex-cta);background-size:122.83% 207.24%;background-position:87.84% 67.50%;
}
.badge{position:absolute;background:var(--img-badge) center/contain no-repeat}

/* ══ FOOTER ════════════════════════════════════════════════════════ */
.sec-footer{background:var(--ink)}
.logo-footer{position:absolute;background:var(--img-logo-footer) center/cover no-repeat}
.soc{position:absolute;display:block;color:var(--lilac)}

/* ── builder credit — THE ONLY THING ON THIS SITE NOT IN THE FIGMA ──────
   Placed at y=425 in the footer's dead band: "©2026 FIDA" ends at y=409
   and the frame ends at 466, so this covers and displaces nothing. Every
   Figma element still sits on its exact coordinate.
   To remove: delete this rule and the one .built-by line in each footer. */
.built-by{
  position:absolute;left:0;top:425px;width:1440px;text-align:center;
  font:400 11px/14px var(--ff-sans);color:var(--lilac);opacity:.45;
  transition:opacity .2s ease;
}
.built-by:hover{opacity:.9}
.built-by a{border-bottom:1px solid currentColor;padding-bottom:1px}

/* ═══════════════════════════════════════════════════════════════════
   MOTION — every timing below is read straight from the Figma prototype
   ═══════════════════════════════════════════════════════════════════ */

/* LOGOS1 · SMART_ANIMATE, LINEAR, 10s · track travels 11px → −1529px  */
@keyframes mq-left {from{transform:translateX(0)}      to{transform:translateX(-1540px)}}
/* LOGOS2 · SMART_ANIMATE, LINEAR, 10s · track travels −1482px → 9px   */
@keyframes mq-right{from{transform:translateX(0)}      to{transform:translateX(1491px)}}
.mq-l{animation:mq-left 10s linear infinite}
.mq-r{animation:mq-right 10s linear infinite}

/* NANIFESTO · one full copy of the line, at the same 154 px/s the logo
   rows run at. JS re-measures the copy so the loop is always seamless. */
@keyframes mani{from{transform:translateX(0)} to{transform:translateX(calc(-1 * var(--mani-w,2202px)))}}
.mani-track{animation:mani var(--mani-dur,14.3s) linear infinite}

/* ROTATING TEXTE · 4 variants × SMART_ANIMATE LINEAR 1.5s = 6s / turn  */
@keyframes spin{to{transform:rotate(360deg)}}
.badge{animation:spin 6s linear infinite}

/* Component 2 (hero star) · 40px → 18px over 0.4s EASE_IN_AND_OUT,
   instant cut to 10px, then 10px → 40px over 0.4s EASE_IN_AND_OUT     */
@keyframes twinkle{
  0%     {transform:scale(1);   animation-timing-function:ease-in-out}
  50%    {transform:scale(.45); animation-timing-function:step-start}
  50.01% {transform:scale(.25); animation-timing-function:ease-in-out}
  100%   {transform:scale(1)}
}
.star-inner{animation:twinkle .8s infinite}

@media (prefers-reduced-motion:reduce){
  .mq-l,.mq-r,.mani-track,.badge,.star-inner{animation:none}
  .cw-track,.cw-dot .bar{transition:none}
}
