@charset "utf-8";
/* ═══ Manara Studio · The Stack ═════════════════════════════════════════
   Six full-screen cards that slide up and stack as you scroll, in the
   brand's own colours used loud: cream paper, logo forest green, marigold
   for every button, near-black ink, tomato as a rare pop. Chunky 2px ink
   edges and hard offset shadows give it a sticker-book feel.

   Every text/ground pair below was measured (WCAG). The two that FAILED in
   the brief and are designed around, not ignored:
     · marigold on cream is 1.61:1 — so every marigold button carries a 2px
       ink edge (15.68:1) and a hard ink shadow; the edge does the separating.
     · cream on tomato is 3.14:1 — so the tomato card uses ink text (5.00:1),
       and tomato is never used as a text colour at all.
   All box-model properties are logical so Arabic mirrors without a second
   stylesheet. */

/* ─── tokens ─────────────────────────────────────────────────────────── */
/* A card's four colours are registered as real colours, so a card can change
   ground in one smooth transition and every word, rule and skyline piece on it
   follows the same frame ("What we make" turning from cream to forest). */
@property --bg{syntax:"<color>";inherits:true;initial-value:#f6f0e4;}
@property --fg{syntax:"<color>";inherits:true;initial-value:#16181a;}
@property --soft{syntax:"<color>";inherits:true;initial-value:#4a4d52;}
@property --accent{syntax:"<color>";inherits:true;initial-value:#0f4a37;}

:root{
  --cream:#f6f0e4;
  --forest:#0f4a37;     /* sampled from the logo sheet's dark-accent variant */
  --marigold:#f3b52f;
  --ink:#16181a;
  --tomato:#e9573f;

  /* secondary text, one per ground — each measured on its own ground */
  --soft-on-cream:#4a4d52;     /* 7.48:1 */
  --soft-on-forest:#b9d0c4;    /* 6.27:1 */
  --soft-on-ink:#b8b2a6;       /* 8.44:1 */
  --soft-on-marigold:#3d3322;  /* 6.76:1 */

  --font-display:"Jost","Futura","Century Gothic",sans-serif;
  --font-sans:"Instrument Sans","Helvetica Neue",Helvetica,sans-serif;
  --font-serif:"Instrument Serif","Times New Roman",serif;
  --font-mono:"JetBrains Mono",ui-monospace,"SF Mono",monospace;
  --font-ar-display:"Noto Kufi Arabic","Jost",sans-serif;
  --font-ar:"Noto Sans Arabic","Instrument Sans",sans-serif;

  --gutter:clamp(1.1rem,4.5vw,4.5rem);
  --header-h:4.4rem;
  --r-card:clamp(22px,3vw,40px);
  --r-sm:16px;
  --pill:999px;

  --edge:2px solid var(--ink);
  --pop:4px 4px 0 var(--ink);
  --pop-lg:7px 7px 0 var(--ink);

  --ease:cubic-bezier(.16,1,.3,1);
  /* a sampled spring: overshoots once and settles. Every rule that uses it
     declares a cubic-bezier transition on the line before, as the fallback. */
  --spring:linear(0,.006,.025,.101,.539,.826,.946,1.001,1.017,1.017,1.009,1.003,.999,.998,1);
}

*,*::before,*::after{box-sizing:border-box;}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto;}}

body{
  margin:0;min-height:100svh;
  background:var(--forest);          /* what shows below the last card */
  color:var(--ink);
  font:400 1.0625rem/1.6 var(--font-sans);
  -webkit-font-smoothing:antialiased;
  /* clip, not hidden: tilted cards must not cause sideways scroll, and clip
     does not create a scroll container, so position:sticky still keys off the
     viewport. */
  overflow-x:clip;
}
[lang="ar"] body{font-family:var(--font-ar);}

img,svg,video{display:block;}
::selection{background:var(--marigold);color:var(--ink);}
:focus-visible{outline:3px solid var(--focus,var(--ink));outline-offset:3px;border-radius:4px;}

.skip{
  position:fixed;inset-block-start:.5rem;inset-inline-start:.5rem;z-index:99;
  transform:translateY(-150%);
  background:var(--marigold);color:var(--ink);border:var(--edge);border-radius:var(--pill);
  padding:.7rem 1.1rem;font:600 .8rem/1 var(--font-sans);text-decoration:none;
}
.skip:focus{transform:none;}

/* ─── header: three solid pills that read on any card ─────────────────── */
/* The menu at the inline start, the logo in the middle, the languages at the
   inline end (2026-10-09, his call). A grid keeps the logo centred, and Arabic
   mirrors by itself: the menu moves to the right, the languages to the left.
   z-index 56 puts it above the menu's scrim (55), which dims the dock too. */
.chrome{
  position:fixed;inset-block-start:0;inset-inline:0;z-index:56;
  display:grid;grid-template-columns:1fr auto 1fr;align-items:center;column-gap:.75rem;
  padding:.9rem var(--gutter);
  pointer-events:none;
}
.chrome > *{pointer-events:auto;}
.chrome > .menu{grid-column:1;justify-self:start;}
.chrome > .brand{grid-column:2;}
.chrome > .langs{grid-column:3;justify-self:end;}
/* The logo is the kit's (2026-09-24): MANARA with the lighthouse as its last
   A. Arabic swaps in the bilingual lockup, MANARA | منارة. */
.brand{
  display:inline-flex;align-items:center;
  padding:.5rem 1rem;
  background:var(--cream);color:var(--ink);text-decoration:none;
  border:var(--edge);border-radius:var(--pill);box-shadow:3px 3px 0 var(--ink);
}
.brand__logo{width:auto;height:1.85rem;}
.brand__logo--ar{display:none;height:2.25rem;}
[lang="ar"] .brand__logo--latin{display:none;}
[lang="ar"] .brand__logo--ar{display:block;}

.langs{
  display:flex;gap:.15rem;padding:.22rem;
  background:var(--cream);border:var(--edge);border-radius:var(--pill);box-shadow:3px 3px 0 var(--ink);
}
.langs button{
  appearance:none;border:0;background:none;cursor:pointer;
  padding:.5rem .8rem;border-radius:var(--pill);
  color:var(--ink);font:600 .74rem/1 var(--font-mono);letter-spacing:.12em;
  transition:background .2s,color .2s;
}
.langs button:hover{background:rgba(22,24,26,.09);}
.langs button[aria-pressed="true"]{background:var(--ink);color:var(--cream);}

/* ─── the menu (2026-10-09, his call) ─────────────────────────────────────
   One cream pill, like its two neighbours, that opens a small card of the
   site's pages: Home, Pricing, Web design, FAQ, and Privacy kept quiet under a
   dashed rule. A native <details>, so it opens with no JS at all; menu.js
   (.is-live) adds the motion: the card unfolds from the pill on the house
   spring, each row climbs out from behind its own edge one after another (the
   skyline's own gesture, small), the lamp beside the page you are on lights
   last, and the pill's two bars cross into an X. Closing is faster than
   opening. The current page is ink with a lit lamp; the pointer is marigold
   with its ink edge. Reduced motion: the card only fades. */
.menu{position:relative;}
.menu__btn{
  display:inline-flex;align-items:center;gap:.55rem;list-style:none;cursor:pointer;
  padding-block:.72rem;padding-inline:.85rem 1rem;
  background:var(--cream);color:var(--ink);
  border:var(--edge);border-radius:var(--pill);box-shadow:3px 3px 0 var(--ink);
  font:600 .74rem/1 var(--font-mono);letter-spacing:.12em;text-transform:uppercase;
  user-select:none;-webkit-tap-highlight-color:transparent;
  transition:background-color .25s var(--ease),color .25s var(--ease),transform .18s var(--ease),box-shadow .18s var(--ease);
}
.menu__btn::-webkit-details-marker{display:none;}
.menu__btn::marker{content:"";}
.menu__btn:hover{background:#ece4d3;}
@media (hover:hover){.menu__btn:hover{transform:translate(-1px,-1px);box-shadow:4px 4px 0 var(--ink);}}
.menu__btn:active{transform:translate(2px,2px);box-shadow:1px 1px 0 var(--ink);}
.menu.is-open .menu__btn,.menu.is-open .menu__btn:hover{background:var(--ink);color:var(--cream);}
/* the header floats over every card colour, so its focus ring is two-toned: a
   cream band that shows on ink, an ink line that shows on cream */
.menu__btn:focus-visible{outline:3px solid var(--ink);outline-offset:3px;box-shadow:0 0 0 3px var(--cream),3px 3px 0 3px var(--ink);border-radius:var(--pill);}
.menu__ico{flex:none;width:1.1rem;height:.75rem;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;overflow:visible;}
.menu__b1,.menu__b2{transform-box:view-box;transform-origin:9px 6px;transition:transform .4s var(--ease);transition:transform .5s var(--spring);}
.menu.is-open .menu__b1{transform:rotate(45deg) translateY(3px);}
.menu.is-open .menu__b2{transform:rotate(-45deg) translateY(-3px);}

.menu__panel{
  position:absolute;inset-block-start:calc(100% + .7rem);inset-inline-start:0;
  width:min(19.5rem,calc(100vw - 2 * var(--gutter)));
  padding:.45rem;
  background:var(--cream);color:var(--ink);
  border:var(--edge);border-radius:var(--r-sm);box-shadow:var(--pop);
  transform-origin:var(--menu-ox,0%) 0;
}
[dir="rtl"] .menu{--menu-ox:100%;}
.menu__list{list-style:none;margin:0;padding:0;display:grid;gap:.15rem;}
.menu__link{
  display:flex;align-items:center;gap:.7rem;
  padding:.8rem .95rem;border-radius:11px;
  color:var(--ink);text-decoration:none;
  font:600 1.12rem/1.1 var(--font-display);letter-spacing:-.01em;text-transform:uppercase;
  transition:background-color .2s var(--ease),color .2s var(--ease),box-shadow .2s var(--ease);
}
/* the mask each label climbs out of */
.menu__t{display:block;overflow:hidden;padding-block:.12em;margin-block:-.12em;}
.menu__t > span{display:block;}
.menu__arr{flex:none;margin-inline-start:auto;width:1rem;height:1rem;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;transition:transform .25s var(--ease);}
[dir="rtl"] .menu__arr{transform:scaleX(-1);}
@media (hover:hover){
  .menu__link:not([aria-current]):hover{background:var(--marigold);box-shadow:inset 0 0 0 2px var(--ink);}
  .menu__link:hover .menu__arr{transform:translateX(4px);}
  [dir="rtl"] .menu__link:hover .menu__arr{transform:scaleX(-1) translateX(4px);}
}
.menu__link:not([aria-current]):focus-visible{background:var(--marigold);box-shadow:inset 0 0 0 2px var(--ink);outline:0;}
.menu__link[aria-current]:focus-visible{outline:3px solid var(--ink);outline-offset:2px;}
.menu__link[aria-current]{background:var(--ink);color:var(--cream);}
/* the page you are on: a lit lamp, the lighthouse's own mark */
.menu__link[aria-current]::before{
  content:"";flex:none;width:.55rem;height:.55rem;border-radius:50%;margin-inline-end:.1rem;
  background:var(--marigold);box-shadow:0 0 0 3px rgb(243 181 47 / .32),0 0 12px 2px rgb(243 181 47 / .5);
}
/* Privacy: a quiet line under a dashed rule, not a destination of its own */
.menu__more{margin-block-start:.35rem;padding-block-start:.4rem;border-block-start:2px dashed rgb(22 24 26 / .32);}
.menu__link--quiet{padding:.62rem .95rem;font:600 .72rem/1 var(--font-mono);letter-spacing:.12em;color:var(--soft-on-cream);}
.menu__link--quiet:not([aria-current]):hover,.menu__link--quiet:not([aria-current]):focus-visible{color:var(--ink);}

/* the page dims behind the open menu, the dock and WhatsApp button included */
.menu-scrim{
  position:fixed;inset:0;z-index:55;background:rgb(22 24 26 / .4);
  opacity:0;visibility:hidden;transition:opacity .2s linear,visibility 0s .2s;
}
.menu-scrim.is-on{opacity:1;visibility:visible;transition:opacity .25s linear;}

/* the motion, only once menu.js is running: without it the <details> simply
   opens and every word is there. Entrance on the house spring, exit quicker. */
.menu.is-live .menu__panel{
  opacity:0;transform:translateY(-12px) scale(.93);
  transition:opacity .16s linear,transform .2s var(--ease);
}
.menu.is-live.is-open .menu__panel{
  opacity:1;transform:none;
  transition:opacity .1s linear,transform .5s var(--ease);
  transition:opacity .1s linear,transform .6s var(--spring);
}
.menu__list > li:nth-child(2){--i:1;}
.menu__list > li:nth-child(3){--i:2;}
.menu__list > li:nth-child(4){--i:3;}
.menu__list > li:nth-child(5){--i:4;}
.menu.is-live .menu__t > span{transform:translateY(118%);transition:transform .16s var(--ease);}
.menu.is-live.is-open .menu__t > span{
  transform:none;transition:transform .7s var(--ease);
  transition-delay:calc(70ms + var(--i,0) * 55ms);
}
.menu.is-live .menu__arr{opacity:0;transition:opacity .12s linear,transform .25s var(--ease);}
.menu.is-live.is-open .menu__arr{opacity:1;transition:opacity .3s linear calc(180ms + var(--i,0) * 55ms),transform .25s var(--ease);}
.menu.is-live .menu__link[aria-current]::before{opacity:0;transform:scale(.3);transition:opacity .12s linear,transform .16s var(--ease);}
.menu.is-live.is-open .menu__link[aria-current]::before{
  opacity:1;transform:none;
  transition:opacity .2s linear 340ms,transform .5s var(--ease) 340ms;
  transition:opacity .2s linear 340ms,transform .6s var(--spring) 340ms;
}
@media (prefers-reduced-motion:reduce){
  .menu__btn,.menu__btn:hover,.menu__btn:active{transform:none;}
  .menu__b1,.menu__b2{transition:none;}
  .menu.is-live .menu__panel,.menu.is-live.is-open .menu__panel{transform:none;transition:opacity .12s linear;}
  .menu.is-live .menu__t > span,.menu.is-live.is-open .menu__t > span{transform:none;transition:none;}
  .menu.is-live .menu__arr,.menu.is-live.is-open .menu__arr,
  .menu.is-live .menu__link[aria-current]::before,.menu.is-live.is-open .menu__link[aria-current]::before{opacity:1;transform:none;transition:none;}
  [dir="rtl"] .menu.is-live .menu__arr{transform:scaleX(-1);}
  .menu-scrim,.menu-scrim.is-on{transition:opacity .12s linear;}
}
.brand__logo--mark{display:none;height:1.6rem;}
/* The full logo is ~157px wide; with the menu and the languages either side it
   only sits in the middle from about 30rem up (measured), so below that the
   logo pill shows the kit's ink mark alone. */
@media (max-width:29.99rem){
  .brand .brand__logo--latin,.brand .brand__logo--ar{display:none;}
  .brand .brand__logo--mark{display:block;}
  .brand{padding-inline:.7rem;}
}

/* ─── the stack ──────────────────────────────────────────────────────── */
/* overflow-x:clip — nothing tilted, turning or slapped on may push the page
   wider than the screen. Tilted stickers at a card's edge (and their 130%
   slap-in state) made a 390px phone page 424px wide, and in Arabic, where they
   sit on the left, the whole page shifted sideways. clip, not hidden: it makes
   no scroll container, so the cards still stick to the viewport, and it clips
   only the x axis, so the skylines can still climb out of the top of a card. */
.stack{position:relative;overflow-x:clip;}
.card{
  --bg:var(--cream);--fg:var(--ink);--soft:var(--soft-on-cream);--accent:var(--forest);--focus:var(--ink);
  position:relative;isolation:isolate;
  min-height:100svh;
  display:flex;flex-direction:column;justify-content:center;
  padding:calc(var(--header-h) + clamp(1.25rem,5vh,3.5rem)) var(--gutter) clamp(3.5rem,9vh,6rem);
  background:var(--bg);color:var(--fg);
  border-radius:var(--r-card) var(--r-card) 0 0;
}
/* each card overlaps the one before by its own corner radius, so the rounded
   top reads as a card lying ON the previous one — with or without JS */
.card + .card{margin-block-start:calc(var(--r-card) * -1);box-shadow:0 -22px 44px -26px rgba(0,0,0,.5);}
.card--hero{border-radius:0;}

/* With JS every card sticks, and the next one slides over it. --stick is set
   per card by app.js: 0 for a card that fits the screen, negative for a card
   taller than the screen, so a tall card scrolls to its own bottom BEFORE it
   sticks. Without that, the bottom of a tall card (common on phones) would be
   covered by the next card and never be seen. */
.js .card{position:sticky;top:var(--stick,0px);}
/* The hero is not a card in the deck: it scrolls away like paper, and "What we
   make" follows it in the same cream, so the two read as one sheet until the
   second turns green (see .card--make). With the hero stuck, the cream card
   would have slid over it with an invisible edge and wiped its words away. */
.js .card--hero{position:relative;top:auto;}
/* With JS, each card's top edge is its skyline (.crest), so the flat edge
   loses its rounding and shadow; without JS the plain rounded deck stays. */
.js .card + .card{border-radius:0;box-shadow:none;}

/* ─── the coastline: each card climbs in behind a skyline ────────────────
   Domes and towers of different widths and heights ride on each card's top
   edge and climb ahead of it as it rises; one of them is a lighthouse with
   its lamp lit — manara is Arabic for lighthouse, and the hero is a
   lighthouse above low roofs. app.js builds the pieces and moves them from
   the scroll position; each is a card-coloured shape that rises out from
   behind the card's edge (the crest clips it there) and then rides up with
   the card. Transform only; will-change only while that card is rising. */
/* The cards that a skyline climbs over (01–03) keep extra room at the bottom:
   the next card's towers lead it by up to --crest-lead, so without this they
   reached the last lines of a card as soon as the next one began to rise.
   With it, a card's content ends clear of the towers' first stretch. */
:root{--crest-lead:clamp(8rem,34vh,21rem);}
.js .card--make,.js .card--work,.js .card--who,.js .card--prices,.js .card--faq{
  padding-block-end:calc(clamp(4.5rem,10vh,6rem) + var(--crest-lead) * .8);
}
.crest{
  --lead:var(--crest-lead);               /* how far the tallest tower leads */
  position:absolute;left:0;right:0;bottom:calc(100% - 1px);height:var(--lead);
  overflow:hidden;pointer-events:none;container-type:inline-size;
}
.crest__p{
  --ph:calc(var(--lead) * var(--h));
  --rv:min(var(--ph), calc(var(--w) * .5cqw));    /* semicircle, or a low dome */
  position:absolute;bottom:0;height:var(--ph);width:calc(var(--w) * 1% + 1px);
  background:var(--bg);
  border-radius:50% 50% 0 0 / var(--rv) var(--rv) 0 0;
  transform:translateY(101%);
}
.is-rising .crest__p{will-change:transform;}
/* the lighthouse: a lit lamp under its dome, and a spire */
.crest__p--tower::before{
  content:"";position:absolute;left:50%;top:calc(var(--w) * .5cqw + 3px);translate:-50% 0;
  width:44%;aspect-ratio:1;border-radius:50%;
  background:var(--lamp,var(--marigold));
  box-shadow:0 0 0 3px color-mix(in srgb,var(--lamp,var(--marigold)) 30%,transparent),
             0 0 22px 7px color-mix(in srgb,var(--lamp,var(--marigold)) 45%,transparent);
}
.crest__p--tower::after{
  content:"";position:absolute;left:50%;bottom:100%;translate:-50% 0;
  width:3px;height:14px;border-radius:2px;background:var(--bg);
}

/* depth: as the next card rises, this one sinks back and dims. app.js writes
   the inner's transform and the dimmer's opacity directly, only when they
   change (not through an inherited custom property — that re-styled every
   element in every card, every frame). will-change keeps both on the
   compositor, so a scroll frame repaints nothing. Transform and opacity only.
   The dimmer (.card__dim) is added by app.js; without JS nothing dims. */
.card__inner{
  position:relative;width:100%;max-width:1320px;margin-inline:auto;
  transform-origin:50% 0;
}
.js .card__inner{will-change:transform;}
.card__dim{
  position:absolute;inset:0;z-index:5;border-radius:inherit;pointer-events:none;
  background:#000;opacity:0;will-change:opacity;
}
/* A fully covered card can't be seen: its looping animations stop. */
.is-under .hero__frame::after,.is-under .seal__ring{animation-play-state:paused;}

/* The glide (Lenis, desktop mouse and trackpad only — see app.js). Lenis sets
   the scroll position itself, so the browser's own smooth scrolling must not
   ease on top of it. Lenis's stylesheet also hides overflow while stopped;
   that is left out on purpose, or the scrollbar would vanish and the page
   jump sideways each time the work viewer opened. */
html.lenis,html.lenis body{height:auto;}
html.lenis{scroll-behavior:auto;}

.card--make{--bg:var(--forest);--fg:var(--cream);--soft:var(--soft-on-forest);--accent:var(--marigold);--focus:var(--marigold);}
/* The hand-off. With JS, "What we make" arrives in the hero's cream and turns
   forest (text to cream) once it has climbed halfway up the screen — app.js
   adds .is-lit. One transition, not a scroll-linked wash; it reverses on the
   way back up. Its skyline stays hidden until then: cream on cream it would
   cut invisible holes in the hero. Without JS it is simply forest. */
.js .card--make{transition:--bg .9s var(--ease),--fg .9s var(--ease),--soft .9s var(--ease),--accent .9s var(--ease);}
.js .card--make:not(.is-lit){--bg:var(--cream);--fg:var(--ink);--soft:var(--soft-on-cream);--accent:var(--forest);--focus:var(--ink);}
.js .card--make:not(.is-lit) .crest{visibility:hidden;}
.card--who{--lamp:var(--cream);}   /* a marigold lamp would vanish on a marigold tower */
/* Work's accent is tomato (2026-09-26, his call): it matches the tomato dock
   and WhatsApp button that arrive with this card. Tomato on ink is 5.00:1, so
   here — and only here, on ink — tomato may carry text (the "02", the links);
   on cream it is 3.14 and stays a fill. The lamp on its skyline tower is
   tomato too. */
.card--work{--bg:var(--ink);--fg:var(--cream);--soft:var(--soft-on-ink);--accent:var(--tomato);--focus:var(--tomato);--lamp:var(--tomato);}
.card--who{--bg:var(--marigold);--fg:var(--ink);--soft:var(--soft-on-marigold);--accent:var(--ink);--focus:var(--ink);}
/* Prices (2026-09-26, his call): tomato, the one brand colour that had no card
   of its own — this retires the old "four card colours" rule. Cream on tomato
   is 3.14, so everything on it is ink (5.00); a softer ink would fall under
   4.5, so hierarchy comes from size and weight, not a second text colour. The
   lamp on its skyline tower is cream: marigold on tomato is only 2.0. */
.card--prices{--bg:var(--tomato);--fg:var(--ink);--soft:var(--ink);--accent:var(--ink);--focus:var(--ink);--lamp:var(--cream);}
/* Questions (2026-09-27): cream, the page's paper, so the ink dock and the
   forest WhatsApp disc read on it; forest accent (9.00 on cream) */
.card--faq{--bg:var(--cream);--fg:var(--ink);--soft:var(--soft-on-cream);--accent:var(--forest);--focus:var(--ink);}
.card--hi{--bg:var(--forest);--fg:var(--cream);--soft:var(--soft-on-forest);--accent:var(--marigold);--focus:var(--marigold);}

/* ─── type ───────────────────────────────────────────────────────────── */
.display,.headline,.giant{
  margin:0;font-family:var(--font-display);font-weight:600;
  text-transform:uppercase;text-wrap:balance;
}
.display{font-size:clamp(2.5rem,6.6vw,6.2rem);line-height:.95;letter-spacing:-.035em;margin-block-end:1.4rem;}
/* the highlighted phrase: a serif italic on a marigold marker stroke. The
   ink stays ink; the marker is behind it, so contrast never depends on it.
   The stroke is drawn once on arrival, from "from" to "off" — easing in and
   out like a hand pulling a highlighter. box-decoration-break:slice treats
   the phrase's lines as one strip, so the sweep finishes the first line and
   carries on into the second instead of drawing both at once. RTL draws from
   the right. The resting state is the full stroke, so reduced motion (and a
   failed animation) simply shows it. */
.display em{
  font:italic 400 1.04em/1 var(--font-serif);letter-spacing:-.01em;text-transform:none;
  background:linear-gradient(transparent 56%,var(--marigold) 56%,var(--marigold) 90%,transparent 90%) 0 0 / 100% 100% no-repeat;
  padding-inline:.06em;
  -webkit-box-decoration-break:slice;box-decoration-break:slice;
}
[dir="rtl"] .display em{background-position:100% 0;}
@keyframes marker-draw{from{background-size:0% 100%;}}
.headline{font-size:clamp(2rem,5.2vw,4.4rem);line-height:1;letter-spacing:-.03em;max-width:17ch;margin-block-end:clamp(1.75rem,4.5vh,3rem);}
.giant{font-weight:700;font-size:clamp(4.5rem,17vw,13.5rem);line-height:.84;letter-spacing:-.05em;margin-block-end:1.5rem;}
.lead{margin:0 0 2rem;max-width:36ch;font-size:clamp(1.05rem,1.5vw,1.3rem);line-height:1.5;color:var(--soft);}

/* Arabic: Kufi, never uppercase, never negative tracking, taller lines. The
   Latin display settings are not portable — Kufi collapses under them. */
[lang="ar"] .display,[lang="ar"] .headline,[lang="ar"] .giant{
  font-family:var(--font-ar-display);font-weight:700;text-transform:none;letter-spacing:0;line-height:1.25;
}
[lang="ar"] .display em{font-family:inherit;font-style:normal;font-weight:700;}
[lang="ar"] .giant{line-height:1.1;}

.tag{
  display:inline-flex;align-items:center;gap:.6rem;
  margin:0 0 1.25rem;padding:.42rem .85rem;
  border:1.5px solid currentColor;border-radius:var(--pill);
  font:600 .72rem/1 var(--font-mono);letter-spacing:.14em;text-transform:uppercase;
}
.tag__no{color:var(--accent);}
[lang="ar"] .tag{letter-spacing:0;}

/* ─── the button: marigold, ink edge, hard shadow — pressable ─────────── */
.btn{
  display:inline-flex;align-items:center;gap:.7rem;
  padding:1rem 1.5rem;
  background:var(--marigold);color:var(--ink);text-decoration:none;
  border:var(--edge);border-radius:var(--pill);box-shadow:var(--pop);
  font:600 1rem/1 var(--font-sans);
  transition:transform .18s var(--ease),box-shadow .18s var(--ease);
}
.btn:hover{transform:translate(-2px,-2px);box-shadow:6px 6px 0 var(--ink);}
.btn:active{transform:translate(3px,3px);box-shadow:1px 1px 0 var(--ink);}
.btn__icon{width:1.2rem;height:1.2rem;flex:none;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;}
.btn--big{padding:1.2rem 1.9rem;font-size:1.1rem;box-shadow:6px 6px 0 rgba(0,0,0,.45);}
.btn--big:hover{box-shadow:8px 8px 0 rgba(0,0,0,.45);}
@media (prefers-reduced-motion:reduce){.btn,.btn:hover,.btn:active{transform:none;transition:none;}}

/* ─── the email: spelled out on the button, copied when pressed ───────── */
/* Contact is by email (2026-09-24, replacing WhatsApp). The address reads
   "email: contact [at] manara-studio (dot) com" — the label in the serif italic
   the headline uses, [at] and (dot) a step softer so the address itself
   stands out. The same marigold button as always; only its insides changed. */
.mail{position:relative;cursor:pointer;}
.mail__label{font:italic 400 1.2em/1 var(--font-serif);color:var(--soft-on-marigold);}
.mail__addr{white-space:nowrap;}
.mail__sep{font-weight:500;color:var(--soft-on-marigold);}
/* the icon says what a press does: copy (computer), open the mail app
   (phone or tablet — see app.js), then a tick once done */
.mail__done,.mail__open{display:none;}
@media (hover:none) and (pointer:coarse){
  .mail .mail__copy{display:none;}
  .mail .mail__open{display:inline;}
}
.mail.is-copied .mail__copy,.mail.is-copied .mail__open{display:none;}
.mail.is-copied .mail__done{display:inline;}
[lang="ar"] .mail__label{font:600 .95em/1 var(--font-ar);}

/* The bubble: a cream pill with an ink edge, like the header's, so it reads
   on cream, forest and the ink dock alike. "Click to copy" on hover and
   focus; app.js holds it open (.is-said) to say "Copied!". Hover only where
   hover exists — on a phone a tap would otherwise leave it stuck open. */
.tip{
  position:absolute;left:50%;bottom:calc(100% + 14px);z-index:3;
  padding:.5rem .8rem;white-space:nowrap;pointer-events:none;
  background:var(--cream);color:var(--ink);border:var(--edge);border-radius:var(--pill);
  box-shadow:3px 3px 0 var(--ink);
  font:600 .72rem/1 var(--font-mono);letter-spacing:.12em;text-transform:uppercase;
  opacity:0;transform:translate(-50%,6px);
  transition:opacity .18s var(--ease),transform .25s var(--ease);
}
/* the tail: a cream square turned 45°, inked on its two lower sides, laid
   over the pill's bottom edge so the two read as one shape */
.tip::after{
  content:"";position:absolute;left:50%;top:calc(100% - 3px);
  width:10px;height:10px;margin-left:-5px;   /* physical, like left:50% */
  background:var(--cream);border-right:var(--edge);border-bottom:var(--edge);
  transform:rotate(45deg);
}
/* Phones: on one line the address is ~400px and pushed the page wider than
   the screen (477px on a 390px phone). Below 34rem the label goes on its own
   line above the address, the copy icon sits beside both, and the address
   scales with the screen — it fits down to 320px. Still a pill: at two lines
   tall the rounded ends clear the text. */
@media (max-width:33.99rem){
  .mail.btn{
    display:inline-grid;grid-template-columns:auto auto;align-items:center;
    column-gap:.65rem;row-gap:.35rem;padding-block:.85rem;padding-inline:1.15rem .95rem;text-align:start;
  }
  .mail .mail__label{grid-column:1;grid-row:1;font-size:1.1em;}
  /* contact [at] manara-studio (dot) com: 12px at 320px wide, 16px by 427px */
  .mail .mail__addr{grid-column:1;grid-row:2;font-size:clamp(.75rem,3.75vw,1rem);}
  .mail .mail__icon{grid-column:2;grid-row:1 / span 2;}
  .mail.btn--big{padding-block:1rem;}
}
@media (hover:hover){.mail:hover .tip{opacity:1;transform:translate(-50%,0);}}
.mail:focus-visible .tip,.mail.is-said .tip{opacity:1;transform:translate(-50%,0);}
@media (prefers-reduced-motion:reduce){.tip{transform:translate(-50%,0);transition:opacity .18s;}}

/* ─── the underline that follows the pointer ─────────────────────────────
   Every underlined link (.u-line inside .work__link and .client__cta). At
   rest a faint track, so a link still looks like a link. On hover the full
   line draws in from the side the pointer came from, and on leave it pulls
   away toward the side the pointer left by — app.js sets --l and --r, the
   line's two ends as fractions of the text width (0,1 = collapsed on the
   left; 1,0 = collapsed on the right; 0,0 = full). Both ends transition, so
   a quick in-and-out reverses from wherever the line is, never jumping.
   Physical left/right on purpose: the pointer's side is physical in Arabic
   too. Keyboard focus shows the full line. */
.u-line{position:relative;}
.u-line::before,.u-line::after{
  content:"";position:absolute;left:0;right:0;bottom:-6px;height:2px;border-radius:2px;
  background:currentColor;pointer-events:none;
}
.u-line::before{opacity:.32;}
.u-line::after{
  transform-origin:0 50%;
  transform:translateX(calc(var(--l,0) * 100%)) scaleX(calc(1 - var(--l,0) - var(--r,1)));
  transition:transform .42s var(--ease);
}
.is-snap .u-line::after{transition:none;}
a:focus-visible .u-line::after{transform:none;}
@media (prefers-reduced-motion:reduce){.u-line::after{transition:none;}}

/* for screen readers only */
.vh{position:absolute;top:0;inset-inline-start:0;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;}

/* ─── 1 · hero ───────────────────────────────────────────────────────── */
/* minmax(0,1fr): the single phone column can never be widened by its content */
.hero{display:grid;grid-template-columns:minmax(0,1fr);gap:clamp(2.25rem,5vw,4.5rem);align-items:center;}
@media (min-width:60rem){.hero{grid-template-columns:minmax(0,1.1fr) minmax(0,.9fr);}}
.hero__art{position:relative;}
.hero__frame{
  /* The image's own aspect ratio (1200×1178), so the cutout fills the frame
     exactly and the lamp is always at 35% across, 22% down. The beam and the
     glow are positioned from those two numbers. */
  position:relative;isolation:isolate;margin:0;aspect-ratio:1200/1178;overflow:hidden;
  border:var(--edge);border-radius:var(--r-card);box-shadow:var(--pop-lg);
  /* the sky, in brand colours: marigold holding for the top third, then
     warming to tomato at the horizon, behind the buildings */
  background:linear-gradient(180deg,var(--marigold) 0%,var(--marigold) 34%,#ef8a37 70%,var(--tomato) 100%);
  transform:rotate(1.6deg);
}
[dir="rtl"] .hero__frame{transform:rotate(-1.6deg);}

/* The tower. A transparent cutout (alpha 254 in the body, so the sky does not
   show through), exported to WebP at 31 KB. */
.hero__tower{position:absolute;inset:0;z-index:1;width:100%;height:100%;object-fit:contain;}

/* The beam: a still wedge of cream light from the lamp toward the upper right,
   BEHIND the tower so it appears to leave the lantern. It does not move —
   a moving light was removed from this site on request and stays removed.

   PHYSICAL left, deliberately: the picture is not mirrored in Arabic (it is a
   real building), so the lamp is at 35% from the LEFT in every language. */
.hero__frame::before{
  content:"";position:absolute;z-index:0;pointer-events:none;
  left:35%;right:0;top:0;height:44%;
  clip-path:polygon(0 50%,100% -6%,100% 36%);
  background:linear-gradient(90deg,rgba(255,247,226,.9) 0%,rgba(255,247,226,.45) 38%,rgba(255,247,226,0) 92%);
}
/* The lamp's glow, over the tower, screened so it only ever brightens. It
   breathes slowly — the one motion in the picture, and it stays in place. */
.hero__frame::after{
  content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  background:radial-gradient(circle at 35% 22%,rgba(255,246,222,.95) 0,rgba(255,214,140,.5) 4.5%,rgba(255,214,140,0) 13%);
  mix-blend-mode:screen;
  animation:lamp-breathe 3.4s ease-in-out infinite alternate;
}
@keyframes lamp-breathe{from{opacity:.62;}to{opacity:1;}}
@media (prefers-reduced-motion:reduce){.hero__frame::after{animation:none;opacity:.85;}}

/* the seal: overlaps the frame's top-RIGHT corner and turns slowly.
   PHYSICAL right, deliberately — not inset-inline-end. The photograph is not
   mirrored in Arabic, so the lighthouse is on the left in every language, and
   a logical position would put the seal straight on top of it in RTL. (It did
   sit on the lighthouse in the first build, at inline-start.) */
/* The ring turns as a whole element (so the GPU turns it, not the main
   thread). A turning square's box grows by up to 41%; on a phone that box once
   poked past the screen edge (a 390px page measured 396px wide). .seal used to
   clip it, which also cut the new seal's shadow into a visible square; the
   stack now clips the x axis instead (see .stack), so the seal needn't. */
.seal{
  position:absolute;z-index:2;
  width:clamp(104px,12.5vw,172px);aspect-ratio:1;
  top:-12%;right:-5%;
}
/* the kit's seal in two layers: the still base (disc, lighthouse, beam) and the
   ring of lettering, which turns. The ring sits inside the base's band, so the
   base's shadow is the seal's shadow. */
.seal__base,.seal__ring{position:absolute;inset:0;width:100%;height:100%;}
.seal__base{filter:drop-shadow(0 8px 10px rgb(0 0 0/.25));}
.seal__ring{animation:seal-turn 24s linear infinite;}
@keyframes seal-turn{to{transform:rotate(360deg);}}
@media (prefers-reduced-motion:reduce){.seal__ring{animation:none;}}

/* the first viewport arrives without JavaScript: CSS-only entrance */
.display > span,.display > em,.hero .lead,.hero .btn,.hero__mail{animation:rise .8s var(--ease) both;}
/* the phrase rises with the rest, then the marker is drawn across it */
.display > em{animation:rise .8s var(--ease) .08s both,marker-draw 1.15s cubic-bezier(.65,0,.35,1) .7s both;}
.hero .lead{animation-delay:.16s;}
.hero .btn,.hero__mail{animation-delay:.24s;}
.hero__frame{animation:frame-in 1s var(--ease) .1s both;}
@keyframes rise{from{opacity:0;transform:translateY(.45em);}}
@keyframes frame-in{from{opacity:0;transform:translateY(24px) rotate(0);}}
@media (prefers-reduced-motion:reduce){
  .display > span,.display > em,.hero .lead,.hero .btn,.hero__mail,.hero__frame{animation:none;}
}

/* ─── reveals for cards 2–5 (JS only; without JS everything is visible) ─ */
.js .card:not(.card--hero):not(.is-in) .reveal{opacity:0;transform:translateY(28px);}
.js .card .reveal{transition:opacity .7s var(--ease),transform .7s var(--ease);}
.js .card .reveal:nth-child(2){transition-delay:.06s;}
.js .card .reveal:nth-child(3){transition-delay:.12s;}
.js .card .reveal:nth-child(4){transition-delay:.18s;}
@media (prefers-reduced-motion:reduce){
  .js .card:not(.is-in) .reveal{opacity:1;transform:none;}
  .js .card .reveal{transition:none;}
}

/* ─── 2 · what we make ───────────────────────────────────────────────── */
.offers{list-style:none;margin:0;padding:0;display:grid;gap:clamp(.8rem,1.6vw,1.2rem);grid-template-columns:1fr;}
@media (min-width:36rem){.offers{grid-template-columns:repeat(2,1fr);}}
@media (min-width:72rem){.offers{grid-template-columns:repeat(4,1fr);}}
/* Colours come from the card (--fg, --accent), so they follow the cream →
   forest hand-off exactly. Colour eases only on the way INTO hover: a
   standing colour transition would make the offers trail the hand-off. */
.offer{
  padding:clamp(1.25rem,2vw,1.65rem);
  border:2px solid color-mix(in srgb,var(--fg) 30%,transparent);border-radius:var(--r-sm);
  transition:background .25s,transform .35s var(--ease);
  transition:background .25s,transform .45s var(--spring);
}
.offer__no{display:block;margin-block-end:.9rem;font:600 clamp(2.3rem,4vw,3.3rem)/1 var(--font-display);color:var(--accent);}
.offer__t{margin:0 0 .5rem;font:600 1.35rem/1.15 var(--font-display);}
.offer__b{margin:0;font-size:.97rem;line-height:1.55;color:var(--soft);}
/* hover flips the card to marigold — a small reward for pointing at it */
.offer:hover{
  background:var(--marigold);color:var(--ink);border-color:var(--ink);transform:translateY(-4px) rotate(-1.2deg);
  transition:background .25s,color .25s,border-color .25s,transform .35s var(--ease);
  transition:background .25s,color .25s,border-color .25s,transform .45s var(--spring);
}
.offer:hover .offer__no{color:var(--ink);}
.offer:hover .offer__b{color:var(--soft-on-marigold);}
.offer:hover .more-link{color:var(--forest);}   /* marigold card: the marigold link would vanish */
[lang="ar"] .offer__t{font-family:var(--font-ar-display);}
@media (prefers-reduced-motion:reduce){.offer:hover{transform:none;}}

/* ─── 3 · work ───────────────────────────────────────────────────────── */
.works{list-style:none;margin:0;padding:0;display:grid;gap:clamp(2.5rem,5vw,4rem);}
@media (min-width:52rem){.works{grid-template-columns:repeat(2,1fr);}}
.work--1{--tilt:-1.6deg;}
.work--2{--tilt:1.6deg;}
.work__plate{
  position:relative;margin:0 0 1.4rem;overflow:hidden;
  border:2px solid var(--cream);border-radius:var(--r-sm);
  box-shadow:7px 7px 0 var(--accent);
  transform:rotate(var(--tilt));
  transition:transform .3s var(--ease),box-shadow .3s var(--ease);
  transition:transform .5s var(--spring),box-shadow .3s var(--ease);
}
.work__plate:has(.work__open:hover),
.work__plate:has(.work__open:focus-visible){transform:rotate(0) translateY(-4px);box-shadow:10px 10px 0 var(--accent);}
.work__open{display:block;width:100%;padding:0;border:0;background:none;cursor:zoom-in;}
.work__open img{width:100%;height:auto;}
.work__zoom{
  position:absolute;inset-block-end:.75rem;inset-inline-end:.75rem;
  display:inline-flex;align-items:center;gap:.45rem;padding:.5rem .8rem;
  background:var(--accent);color:var(--ink);border:var(--edge);border-radius:var(--pill);   /* ink on tomato 5.00 */
  font:600 .7rem/1 var(--font-mono);letter-spacing:.12em;text-transform:uppercase;
  pointer-events:none;
}
.work__zoom svg{width:.8rem;height:.8rem;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;}
.work__name{margin:0 0 .45rem;font:600 clamp(1.5rem,2.6vw,2.1rem)/1.1 var(--font-display);}
.work__meta{margin:0 0 .8rem;font:600 .72rem/1.5 var(--font-mono);letter-spacing:.12em;text-transform:uppercase;color:var(--soft);}
.work__body{margin:0 0 1rem;color:var(--soft);max-width:44ch;}
.work__link{
  display:inline-flex;align-items:center;gap:.4rem;
  color:var(--accent);font:600 .95rem/1 var(--font-sans);text-decoration:none;
}.work__link svg{width:.8rem;height:.8rem;fill:none;stroke:currentColor;stroke-width:1.8;}
[dir="rtl"] .work__link svg{transform:scaleX(-1);}
[lang="ar"] .work__meta{letter-spacing:0;}
@media (prefers-reduced-motion:reduce){.work__plate{transform:none;transition:none;}}

/* the expanded plate */
.viewer{
  position:fixed;inset:0;z-index:60;
  inline-size:100%;block-size:100%;max-inline-size:100%;max-block-size:100%;
  margin:0;border:0;padding:clamp(1rem,3vw,2.5rem);
  display:grid;grid-template-rows:auto 1fr;gap:1rem;
  background:rgba(22,24,26,.94);color:var(--cream);
}
/* An author `display:grid` beats the UA sheet's dialog:not([open]) rule —
   author styles outrank UA styles regardless of specificity. Without this
   line the dialog covers the whole page on load. */
.viewer:not([open]){display:none;}
.viewer::backdrop{background:rgba(22,24,26,.6);}
.viewer__bar{display:flex;align-items:center;justify-content:space-between;gap:1rem;}
.viewer__title{margin:0;font:600 clamp(1.1rem,2vw,1.5rem)/1.2 var(--font-display);}
.viewer__close{
  display:inline-flex;align-items:center;padding:.65rem 1.1rem;cursor:pointer;
  background:var(--marigold);color:var(--ink);border:var(--edge);border-radius:var(--pill);
  font:600 .75rem/1 var(--font-mono);letter-spacing:.12em;text-transform:uppercase;
}
.viewer__frame{display:grid;place-items:center;min-block-size:0;}
.viewer__frame img{max-inline-size:100%;max-block-size:100%;width:auto;height:auto;object-fit:contain;border-radius:var(--r-sm);border:2px solid var(--cream);}
/* one screenshot flies from its place in the card to full size: the group
   (position and size) and the cross-fade inside it share one timing */
::view-transition-group(work-plate),::view-transition-old(work-plate),::view-transition-new(work-plate){animation-duration:.5s;animation-timing-function:var(--ease);}
@media (prefers-reduced-motion:reduce){::view-transition-group(work-plate),::view-transition-old(work-plate),::view-transition-new(work-plate){animation-duration:.01ms;}}

/* ─── an example site (2026-09-27) ───────────────────────────────────────
   "See an example" on a Who card opens a browser window over the page: a
   chrome bar with its three dots and a made-up address, the whole example
   page inside to scroll, and a phone view that narrows the window to a
   phone. The page behind dims like the work viewer's. */
.ex{
  position:fixed;inset:0;z-index:60;
  inline-size:100%;block-size:100%;max-inline-size:100%;max-block-size:100%;
  margin:0;border:0;padding:clamp(.75rem,2.5vw,2rem);
  display:grid;grid-template-rows:auto minmax(0,1fr) auto;gap:clamp(.75rem,1.6vh,1.1rem);
  background:rgba(22,24,26,.94);color:var(--cream);
}
.ex:not([open]){display:none;}
.ex::backdrop{background:rgba(22,24,26,.6);}
.ex[open]{animation:ex-in .35s var(--ease);}
@keyframes ex-in{from{opacity:0;}}
.ex__bar{display:flex;flex-wrap:wrap;align-items:center;gap:.75rem 1rem;}
.ex__title{margin:0;margin-inline-end:auto;font:600 clamp(1.05rem,2vw,1.45rem)/1.2 var(--font-display);}
[lang="ar"] .ex__title{font-family:var(--font-ar-display);}
.ex__views{display:flex;gap:.15rem;padding:.2rem;background:var(--cream);border:var(--edge);border-radius:var(--pill);}
.ex__views button{
  appearance:none;border:0;background:none;cursor:pointer;padding:.5rem .8rem;border-radius:var(--pill);
  color:var(--ink);font:600 .72rem/1 var(--font-mono);letter-spacing:.1em;text-transform:uppercase;
}
.ex__views button[aria-pressed="true"]{background:var(--ink);color:var(--cream);}
[lang="ar"] .ex__views button{font-family:var(--font-ar);font-size:.82rem;letter-spacing:0;}
.ex__stage{display:grid;justify-items:center;min-block-size:0;}
.ex__win{
  display:grid;grid-template-rows:auto minmax(0,1fr);width:min(100%,72rem);min-block-size:0;
  background:var(--cream);border:2px solid var(--cream);border-radius:var(--r-sm);overflow:hidden;
  box-shadow:8px 8px 0 var(--marigold);
  transition:width .45s var(--ease),border-radius .45s var(--ease);
}
.ex.is-phone .ex__win{width:min(100%,24rem);border-radius:28px;}
.ex__chrome{display:flex;align-items:center;gap:.4rem;padding:.6rem .85rem;background:#e6dfd1;color:var(--soft-on-cream);direction:ltr;}
.ex__chrome i{width:.7rem;height:.7rem;border-radius:50%;background:color-mix(in srgb,var(--ink) 25%,transparent);}
.ex__chrome i:first-child{background:var(--tomato);}
.ex__chrome i:nth-child(2){background:var(--marigold);}
.ex__url{
  flex:1;margin-inline-start:.6rem;padding:.3rem .8rem;border-radius:var(--pill);background:var(--cream);
  font:500 .75rem/1.2 var(--font-mono);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.ex.is-phone .ex__chrome i{display:none;}
.ex.is-phone .ex__url{margin:0;text-align:center;}
.ex__scroll{overflow-y:auto;overscroll-behavior:contain;min-block-size:0;background:#fff;}
.ex__scroll:focus-visible{outline:3px solid var(--marigold);outline-offset:-3px;}
.ex__img{width:100%;height:auto;}
.ex__foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.75rem 1.5rem;}
.ex__note{margin:0;max-width:52ch;font-size:.92rem;color:var(--soft-on-ink);}
.ex__acts{display:flex;flex-wrap:wrap;align-items:center;gap:.9rem 1.4rem;}
.ex__go{padding:.85rem 1.25rem;box-shadow:4px 4px 0 rgba(0,0,0,.5);}
.ex__talk{color:var(--cream);font:600 .95rem/1 var(--font-sans);text-decoration:none;}
@media (max-width:40rem){
  /* the title gets its own line; the view switch and Close share the next */
  .ex__title{flex:1 1 100%;}
  .ex__views{margin-inline-end:auto;}
  .ex__note{font-size:.84rem;}
  .ex__acts{width:100%;}
  .ex__go{flex:1;justify-content:center;}
}
@media (prefers-reduced-motion:reduce){.ex[open]{animation:none;}.ex__win{transition:none;}}

/* ─── 4 · who we build for ───────────────────────────────────────────── */
.clients{
  list-style:none;margin:0;padding:0;
  display:grid;gap:clamp(1.1rem,2.2vw,1.6rem);grid-template-columns:1fr;
}
@media (min-width:40rem){.clients{grid-template-columns:repeat(2,1fr);}}
@media (min-width:72rem){.clients{grid-template-columns:repeat(4,1fr);}}
.client{
  --tilt:0deg;--drop:0px;
  position:relative;display:flex;flex-direction:column;
  min-height:clamp(12.5rem,28vh,16.5rem);
  padding:clamp(1.3rem,2vw,1.7rem);
  border:var(--edge);border-radius:var(--r-sm);box-shadow:var(--pop);
  transform:rotate(var(--tilt)) translateY(var(--drop));
  transition:transform .3s var(--ease),opacity .3s,filter .3s,box-shadow .3s;
  transition:transform .5s var(--spring),opacity .3s,filter .3s,box-shadow .3s;
}
/* Four colours, each with its own ink so every pair passes:
   cream/ink 15.68 · forest/cream 9.00 · tomato/ink 5.00 · ink/cream 15.68 */
.client--1{background:var(--cream);color:var(--ink);--cta:var(--forest);--tilt:-3deg;--drop:8px;}
.client--2{background:var(--forest);color:var(--cream);--cta:var(--marigold);--tilt:2deg;}
.client--3{background:var(--tomato);color:var(--ink);--cta:var(--ink);--tilt:-1.5deg;--drop:14px;}
.client--4{background:var(--ink);color:var(--cream);--cta:var(--marigold);--tilt:3deg;--drop:4px;}
/* the pointed-at card squares up and comes forward … */
.client:hover,.client:focus-within{--tilt:0deg;--drop:-8px;box-shadow:8px 8px 0 var(--ink);z-index:2;}
/* … and the other three step back. :has() on the container, so no JS. */
@supports selector(:has(*)){
  .clients:has(.client:hover) .client:not(:hover),
  .clients:has(.client:focus-within) .client:not(:focus-within){opacity:.72;filter:saturate(.7);}
}
.client__no{font:600 .75rem/1 var(--font-mono);letter-spacing:.12em;opacity:.8;margin-block-end:1rem;}
.client__t{margin:0 0 .7rem;font:600 clamp(1.3rem,1.9vw,1.6rem)/1.12 var(--font-display);}
.client__p{margin:0 0 1.5rem;font:italic 400 clamp(1.1rem,1.5vw,1.25rem)/1.35 var(--font-serif);}
.client__cta{
  margin-block-start:auto;display:inline-flex;align-items:center;gap:.5rem;align-self:flex-start;
  color:var(--cta);font:600 .8rem/1 var(--font-mono);letter-spacing:.12em;text-transform:uppercase;
  text-decoration:none;
}
.client__cta svg{width:.85rem;height:.85rem;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;}
[dir="rtl"] .client__cta svg{transform:scaleX(-1);}
.client--2 .client__cta,.client--4 .client__cta{--focus:var(--marigold);}
[lang="ar"] .client__t{font-family:var(--font-ar-display);}
[lang="ar"] .client__p{font-family:var(--font-ar);font-style:normal;}
[lang="ar"] .client__cta,[lang="ar"] .client__no{letter-spacing:0;}
@media (max-width:39.99rem){
  /* narrower tilts on a single column, so rotated corners stay on screen */
  .client--1{--tilt:-1.5deg;} .client--2{--tilt:1deg;} .client--3{--tilt:-.8deg;} .client--4{--tilt:1.5deg;}
}
@media (prefers-reduced-motion:reduce){
  .client{transition:opacity .2s,filter .2s;}
  .client:hover,.client:focus-within{--tilt:inherit;transform:rotate(var(--tilt)) translateY(var(--drop));}
}

/* ─── the currency dropdown (homepage prices card and the pricing page) ──
   Was four buttons always on show; since 2026-10-09 (his call: clutter) it is
   one cream pill — "Prices in" and the chosen code, in an ink chip like the
   active language — that opens a small card of the four currencies, in the
   menu's own grammar: the card unfolds from the pill on the house spring, each
   row climbs out from behind its edge, the chosen row is ink with a lit lamp,
   the pointer marigold with its ink edge. A native <details>, so it opens with
   no JS; menu.js (.is-live) adds the motion, Esc, press-outside and arrow
   keys, and picks which side of the pill the card hangs from so it never runs
   off a phone. The codes stay Latin mono in every language. The buttons inside
   are the same [data-cur] buttons as before, so app.js did not change how a
   choice rolls every price. */
.cur{position:relative;display:inline-block;}
.cur__btn{
  display:inline-flex;align-items:center;gap:.4rem;list-style:none;cursor:pointer;
  padding:.22rem .7rem .22rem .22rem;
  background:var(--cream);color:var(--ink);
  border:var(--edge);border-radius:var(--pill);box-shadow:3px 3px 0 var(--ink);
  user-select:none;-webkit-tap-highlight-color:transparent;
  transition:background-color .2s var(--ease),transform .18s var(--ease),box-shadow .18s var(--ease);
}
.cur__btn::-webkit-details-marker{display:none;}
.cur__btn::marker{content:"";}
.cur__btn:hover{background:#ece4d3;}
@media (hover:hover){.cur__btn:hover{transform:translate(-1px,-1px);box-shadow:4px 4px 0 var(--ink);}}
.cur__btn:active{transform:translate(2px,2px);box-shadow:1px 1px 0 var(--ink);}
.cur__btn:focus-visible{outline:3px solid var(--ink);outline-offset:3px;box-shadow:0 0 0 3px var(--cream),3px 3px 0 3px var(--ink);border-radius:var(--pill);}
.cur__label{padding-inline:.7rem .1rem;font:600 .7rem/1 var(--font-mono);letter-spacing:.12em;text-transform:uppercase;color:var(--soft-on-cream);}
.cur__now{padding:.6rem .75rem;border-radius:var(--pill);background:var(--ink);color:var(--cream);font:600 .74rem/1 var(--font-mono);letter-spacing:.1em;}
.cur__chev{flex:none;width:.7rem;height:.7rem;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;transition:transform .35s var(--ease);transition:transform .5s var(--spring);}
.cur.is-open .cur__chev{transform:rotate(180deg);}
[lang="ar"] .cur__label{font-family:var(--font-ar);font-size:.8rem;letter-spacing:0;text-transform:none;}

.cur__panel{
  position:absolute;z-index:40;inset-block-start:calc(100% + .6rem);inset-inline-end:0;
  width:min(16.5rem,calc(100vw - 2 * var(--gutter)));
  display:grid;gap:.15rem;padding:.4rem;
  background:var(--cream);color:var(--ink);
  border:var(--edge);border-radius:var(--r-sm);box-shadow:var(--pop);
  transform-origin:100% 0;
}
[dir="rtl"] .cur__panel{transform-origin:0 0;}
.cur--start .cur__panel{inset-inline-end:auto;inset-inline-start:0;transform-origin:0 0;}
[dir="rtl"] .cur--start .cur__panel{transform-origin:100% 0;}
.cur__panel button{
  appearance:none;border:0;background:none;cursor:pointer;text-align:start;
  display:flex;align-items:center;gap:.7rem;width:100%;
  padding:.72rem .85rem;border-radius:11px;color:var(--ink);
  transition:background-color .2s var(--ease),color .2s var(--ease),box-shadow .2s var(--ease);
}
/* the mask each row climbs out of */
.cur__t{display:flex;align-items:baseline;gap:.75rem;overflow:hidden;padding-block:.12em;margin-block:-.12em;min-width:0;}
.cur__code{flex:none;min-width:2.5rem;font:600 .8rem/1.1 var(--font-mono);letter-spacing:.1em;}
.cur__name{min-width:0;font:500 .92rem/1.2 var(--font-sans);color:var(--soft-on-cream);}
[lang="ar"] .cur__name{font-family:var(--font-ar);}
@media (hover:hover){.cur__panel button[aria-pressed="false"]:hover{background:var(--marigold);box-shadow:inset 0 0 0 2px var(--ink);}}
.cur__panel button[aria-pressed="false"]:focus-visible{background:var(--marigold);box-shadow:inset 0 0 0 2px var(--ink);outline:0;}
.cur__panel button:hover .cur__name,.cur__panel button:focus-visible .cur__name{color:var(--ink);}
.cur__panel button[aria-pressed="true"]{background:var(--ink);color:var(--cream);}
.cur__panel button[aria-pressed="true"]:focus-visible{outline:3px solid var(--ink);outline-offset:2px;}
.cur__panel button[aria-pressed="true"] .cur__name{color:var(--soft-on-ink);}
/* the chosen one: a lit lamp, as in the menu */
.cur__panel button[aria-pressed="true"]::after{
  content:"";flex:none;margin-inline-start:auto;width:.55rem;height:.55rem;border-radius:50%;
  background:var(--marigold);box-shadow:0 0 0 3px rgb(243 181 47 / .32),0 0 12px 2px rgb(243 181 47 / .5);
}
/* the homepage's bar sits over the price tags: lift it above their tilts */
.prices__bar{position:relative;z-index:3;}

/* the motion, only once menu.js is running */
.cur.is-live .cur__panel{
  opacity:0;transform:translateY(-10px) scale(.94);
  transition:opacity .14s linear,transform .2s var(--ease);
}
.cur.is-live.is-open .cur__panel{
  opacity:1;transform:none;
  transition:opacity .1s linear,transform .5s var(--ease);
  transition:opacity .1s linear,transform .6s var(--spring);
}
.cur__panel > button:nth-child(2){--i:1;}
.cur__panel > button:nth-child(3){--i:2;}
.cur__panel > button:nth-child(4){--i:3;}
.cur.is-live .cur__t{--lift:118%;}
.cur.is-live .cur__t > span{transform:translateY(118%);transition:transform .14s var(--ease);}
.cur.is-live.is-open .cur__t > span{
  transform:none;transition:transform .65s var(--ease);
  transition-delay:calc(60ms + var(--i,0) * 50ms);
}
.cur.is-live .cur__panel button::after{opacity:0;transform:scale(.3);transition:opacity .12s linear,transform .14s var(--ease);}
.cur.is-live.is-open .cur__panel button::after{
  opacity:1;transform:none;
  transition:opacity .2s linear 300ms,transform .5s var(--ease) 300ms;
  transition:opacity .2s linear 300ms,transform .6s var(--spring) 300ms;
}
@media (prefers-reduced-motion:reduce){
  .cur__btn,.cur__btn:hover,.cur__btn:active{transform:none;}
  .cur__chev{transition:none;}
  .cur.is-live .cur__panel,.cur.is-live.is-open .cur__panel{transform:none;transition:opacity .12s linear;}
  .cur.is-live .cur__t > span,.cur.is-live.is-open .cur__t > span{transform:none;transition:none;}
  .cur.is-live .cur__panel button::after,.cur.is-live.is-open .cur__panel button::after{opacity:1;transform:none;transition:none;}
}

/* ─── 5 · prices ─────────────────────────────────────────────────────────
   Three starting prices as hanging price tags: cream card, ink edge, a hole
   punched near the top with a short string running up out of it. Each hangs
   at its own small angle from that hole and swings square on hover (the
   house spring). The figure is the tag's loudest line, set in JetBrains Mono (tabular); "from"
   and "a month" are the small mono print around it. */
.prices__bar{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:1.1rem 2rem;margin-block-end:clamp(2.5rem,6vh,3.75rem);
}
.prices__note{margin:0;max-width:40ch;font-size:clamp(1.02rem,1.4vw,1.2rem);line-height:1.5;}
.ptags{
  list-style:none;margin:0 0 clamp(2.25rem,5vh,3.25rem);padding:0;
  display:grid;gap:clamp(2.25rem,3vw,2.5rem);grid-template-columns:1fr;
}
@media (min-width:52rem){.ptags{grid-template-columns:repeat(3,1fr);}}
.ptag{
  --tilt:0deg;
  position:relative;display:flex;flex-direction:column;
  padding:3.1rem clamp(1.3rem,2vw,1.7rem) clamp(1.3rem,2vw,1.6rem);
  background:var(--cream);color:var(--ink);
  border:var(--edge);border-radius:var(--r-sm);box-shadow:var(--pop);
  transform-origin:50% 1.45rem;transform:rotate(var(--tilt));
  transition:transform .35s var(--ease),box-shadow .3s var(--ease);
  transition:transform .6s var(--spring),box-shadow .3s var(--ease);
}
/* the hole: the card's own tomato showing through a ring of ink */
.ptag::before{
  content:"";position:absolute;left:50%;top:1.45rem;translate:-50% -50%;
  width:1.05rem;height:1.05rem;border-radius:50%;
  background:var(--bg);border:var(--edge);
}
/* the string it hangs from, running up out of the hole past the tag's top */
.ptag::after{
  content:"";position:absolute;left:50%;bottom:calc(100% - 1.45rem);
  width:2px;height:3rem;margin-left:-1px;border-radius:2px;
  background:var(--ink);transform-origin:50% 100%;rotate:var(--string,-14deg);
  z-index:-1;
}
.ptag--1{--tilt:-2.5deg;--string:-12deg;}
.ptag--2{--tilt:1.8deg;--string:10deg;}
.ptag--3{--tilt:-1.4deg;--string:-8deg;}
.ptag:hover{--tilt:0deg;box-shadow:7px 7px 0 var(--ink);}
.ptag__t{margin:0 0 .9rem;font:600 1.3rem/1.15 var(--font-display);text-transform:uppercase;letter-spacing:-.01em;}
.ptag__price{
  display:flex;flex-wrap:wrap;align-items:baseline;gap:.2rem .5rem;
  margin:0 0 1rem;padding-block-start:.95rem;
  border-block-start:2px dashed color-mix(in srgb,var(--ink) 28%,transparent);
}
.ptag__from,.ptag__per{font:600 .7rem/1 var(--font-mono);letter-spacing:.12em;text-transform:uppercase;color:var(--soft-on-cream);}
.ptag__n{font:600 clamp(1.9rem,3vw,2.6rem)/1 var(--font-mono);letter-spacing:-.03em;font-variant-numeric:tabular-nums;unicode-bidi:isolate;}
.ptag__b{margin:0 0 1.35rem;font-size:.97rem;line-height:1.55;color:var(--soft-on-cream);}
/* each tag's own "Build your order" (2026-09-27): it opens the pricing page's
   builder on that service. Pinned to the tag's foot, so the three line up. */
.ptag__go{margin-block-start:auto;align-self:flex-start;padding:.8rem 1.15rem;font-size:.93rem;box-shadow:3px 3px 0 var(--ink);}
.ptag__go:hover{box-shadow:5px 5px 0 var(--ink);}
:is(.ptag__go,.ex__go) svg{transition:transform .25s var(--ease);}
:is(.ptag__go,.ex__go):hover svg{transform:translateX(3px);}
[dir="rtl"] :is(.ptag__go,.ex__go) svg{transform:scaleX(-1);}
[dir="rtl"] :is(.ptag__go,.ex__go):hover svg{transform:scaleX(-1) translateX(3px);}
[lang="ar"] .ptag__t{font-family:var(--font-ar-display);text-transform:none;letter-spacing:0;}
[lang="ar"] .ptag__from,[lang="ar"] .ptag__per{font-family:var(--font-ar);font-size:.85rem;letter-spacing:0;text-transform:none;}
/* figures stay JetBrains Mono; ر.س and د.إ take Noto Sans Arabic, never the device's font */
[lang="ar"] .ptag__n{font-family:"JetBrains Mono","Noto Sans Arabic",monospace;letter-spacing:0;}
@media (max-width:51.99rem){
  /* one column: smaller swings, so the rotated corners stay on screen */
  .ptag--1{--tilt:-1.2deg;} .ptag--2{--tilt:1deg;} .ptag--3{--tilt:-.8deg;}
}
@media (prefers-reduced-motion:reduce){
  .ptag{transition:box-shadow .2s;}
  .ptag:hover{--tilt:inherit;}
  :is(.ptag__go,.ex__go) svg,:is(.ptag__go,.ex__go):hover svg{transition:none;transform:none;}
  [dir="rtl"] :is(.ptag__go,.ex__go) svg{transform:scaleX(-1);}
}

/* every price figure (the homepage tags, the pricing page) rolls over to
   the new currency at once when the visitor switches — app.js adds .is-roll
   to each [data-price] and takes it off when it ends. Figures sit in flex or
   grid parents, so they are blockified and can move. */
@keyframes price-roll{from{opacity:0;transform:translateY(.5em);filter:blur(3px);}}
.is-roll{animation:price-roll .5s var(--ease) both;}
@media (prefers-reduced-motion:reduce){.is-roll{animation:none;}}

/* ─── questions and answers (2026-09-27) ─────────────────────────────────
   The homepage FAQ card and the pricing page's "Good to know", in the
   structure of WaxPoint's FAQ (his pick): a heading and a WhatsApp line in
   an aside that sticks beside the list on a wide screen; native <details>
   rows between hairline rules, the question and a drawn +/− whose upright
   stroke turns flat when open, the first row open. Colours come from the
   card (--fg, --soft, --accent), so it works on cream and on ink alike. The
   aside's sticky needs no ancestor with overflow — the stack clips only x. */
.qa{display:grid;grid-template-columns:minmax(0,1fr);gap:clamp(1.5rem,4vw,2.5rem);align-items:start;}
@media (min-width:64rem){
  .qa{grid-template-columns:minmax(0,4fr) minmax(0,8fr);column-gap:clamp(3rem,6vw,6rem);}
  .qa__aside{position:sticky;top:calc(var(--header-h) + 2rem);}
}
.qa__aside .headline{margin-block-end:1.1rem;}
.qa__more{margin:0;max-width:30ch;color:var(--soft);font-size:1.02rem;line-height:1.5;}
.qa__ask{color:var(--accent);font-weight:600;text-decoration:none;}
.qa__list{border-block-start:1.5px solid color-mix(in srgb,var(--fg) 26%,transparent);}
.qa__item{border-block-end:1.5px solid color-mix(in srgb,var(--fg) 26%,transparent);}
.qa__item summary{
  display:grid;grid-template-columns:minmax(0,1fr) 1.1rem;gap:1rem;align-items:center;
  min-height:4rem;padding-block:1rem;cursor:pointer;list-style:none;
  font:600 clamp(1.05rem,1.5vw,1.3rem)/1.3 var(--font-display);
}
.qa__item summary::-webkit-details-marker{display:none;}
.qa__item summary::marker{content:"";}
.qa__q{text-decoration-thickness:2px;text-underline-offset:.24em;text-decoration-color:var(--accent);}
.qa__item summary:hover .qa__q,.qa__item summary:focus-visible .qa__q{text-decoration-line:underline;}
.qa__item summary:focus-visible{outline-offset:2px;}
.pm{position:relative;width:1.1rem;height:1.1rem;justify-self:end;color:var(--accent);}
.pm::before,.pm::after{
  content:"";position:absolute;left:0;top:50%;width:100%;height:2px;margin-top:-1px;border-radius:2px;
  background:currentColor;transition:transform .35s var(--ease);
}
.pm::after{transform:rotate(90deg);}
.qa__item[open] .pm::after{transform:rotate(0deg);}
.qa__a{margin:0;padding:0 2.2rem 1.4rem 0;max-width:62ch;color:var(--soft);font-size:1rem;line-height:1.6;}
[dir="rtl"] .qa__a{padding:0 0 1.4rem 2.2rem;}
[lang="ar"] .qa__item summary{font-family:var(--font-ar-display);font-weight:700;line-height:1.5;}
@media (prefers-reduced-motion:reduce){.pm::before,.pm::after{transition:none;}}

/* ─── 6 · say hi ─────────────────────────────────────────────────────── */
.hi{display:flex;flex-direction:column;align-items:flex-start;}
.hi .lead{margin-block-end:2.2rem;}
/* The contact (2026-09-27): the address as it is, a mailto: link built in
   app.js (never in the HTML), and WhatsApp beside it — both marigold, the
   one button colour. The address scales on a phone so it never has to
   break: 13px at 320px wide, 17.6px from 490px. A press also copies the
   address; the bubble ("Copied!") only shows then, never on hover. */
.reach{display:flex;flex-wrap:wrap;align-items:center;gap:1rem 1.1rem;}
.reach .btn{position:relative;}
.reach__addr{white-space:nowrap;font-size:clamp(.8rem,3.6vw,1.1rem);unicode-bidi:isolate;}
.reach__glyph{width:1.3rem;height:1.3rem;flex:none;}
.reach__mail .tip{opacity:0;}
.reach__mail.is-said .tip{opacity:1;transform:translate(-50%,0);}
/* a computer: the press copies, so hover says so ("Copy email") */
@media (hover:hover){.reach__mail:hover .tip{opacity:1;transform:translate(-50%,0);}}
@media (max-width:33.99rem){
  .reach{flex-direction:column;align-items:stretch;width:100%;}
  .reach .btn{justify-content:center;padding-inline:1rem;}
}
/* the hero's two ways in (2026-10-10, his call: WhatsApp first): the button
   opens WhatsApp, and a quiet link beside it copies the email on a computer
   (its bubble says so) or opens the mail app on a phone */
.hero__act{display:flex;flex-wrap:wrap;align-items:center;gap:.9rem 1.4rem;}
.hero__mail{
  position:relative;color:var(--ink);
  font:600 .95rem/1.2 var(--font-sans);
  text-decoration:underline;text-decoration-thickness:1.5px;text-underline-offset:.24em;
}
.hero__mail:hover{text-decoration-thickness:2.5px;}
[lang="ar"] .hero__mail{font-family:var(--font-ar);}
.hero__mail .tip{opacity:0;}
.hero__mail.is-said .tip,.hero__mail:focus-visible .tip{opacity:1;transform:translate(-50%,0);}
@media (hover:hover){.hero__mail:hover .tip{opacity:1;transform:translate(-50%,0);}}
/* the kit's "sweep" logo — its beam swings inside the SVG */
.hi__lockup{width:clamp(190px,22vw,290px);height:auto;margin-block-start:clamp(2.75rem,7vh,4.5rem);}

/* ─── stickers (2026-09-24 kit) ──────────────────────────────────────────
   Six of his die-cut stickers, one or two per card, each saying something the
   card already says: the name's meaning (hero), search (What we make), first
   sketch to live site (Work), the markets (Who), and hello in three languages
   (Say hi). Drawn flat in the kit; the tilt and the shadow are added here so
   hover can square them up. Each one is slapped on — a spring from 130% —
   when its card first arrives, and the hero's on load, in CSS. Stickers go to
   the empty side of each card: logical inline-end, so in Arabic they swap
   sides with the headline; the hero's is tied to the (unmirrored) photo, so it
   is physical. Decorative: alt="". */
.sticker{
  --tilt-s:-6deg;
  position:absolute;z-index:3;height:auto;
  transform:rotate(var(--tilt-s));
  filter:drop-shadow(0 12px 16px rgb(0 0 0/.3));
  transition:transform .35s var(--ease) .25s,opacity .45s var(--ease) .25s;
  transition:transform .6s var(--spring) .25s,opacity .45s var(--ease) .25s;
}
.sticker:hover{transform:rotate(0) scale(1.06);transition-delay:0s;}
.js .card:not(.is-in) .sticker{opacity:0;transform:rotate(var(--tilt-s)) scale(1.3);}
@keyframes sticker-slap{from{opacity:0;transform:rotate(var(--tilt-s)) scale(1.3);}}
.sticker--word,.sticker--pills{left:-6%;bottom:-9%;width:38%;--tilt-s:-7deg;animation:sticker-slap .7s var(--ease) 1.1s backwards;}
.sticker--pills{width:44%;--tilt-s:-5deg;}   /* wider than tall: a little bigger so its words read */
/* the hero's sticker follows the language: the Arabic word only in Arabic, the
   pills everywhere else (no-JS pages are English, so they get the pills) */
html:not([lang="ar"]) .sticker--word,[lang="ar"] .sticker--pills{display:none;}
.sticker--search{inset-inline-end:0;inset-block-start:.25rem;width:clamp(240px,27vw,360px);--tilt-s:4deg;}
.sticker--diamond{inset-inline-end:4%;inset-block-start:-1.25rem;width:clamp(140px,14vw,200px);--tilt-s:-9deg;}
.sticker--pass{inset-inline-end:0;inset-block-start:.5rem;width:clamp(250px,28vw,370px);--tilt-s:5deg;}
.sticker--hi{inset-inline-end:6%;inset-block-start:-.5rem;width:clamp(150px,16vw,220px);--tilt-s:9deg;}
.sticker--fluent{inset-inline-end:4%;inset-block-end:0;width:clamp(140px,14vw,200px);--tilt-s:-8deg;}
/* the Arabic "قل مرحباً." runs much wider than "SAY HI.": lift the sticker
   above its full stop */
[dir="rtl"] .sticker--hi{inset-inline-end:1%;inset-block-start:-3.5rem;}
/* tablet: the hero stacks, the photo runs the full width, and a sticker
   hanging off its left corner would hang off the screen */
@media (min-width:40rem) and (max-width:59.99rem){
  .sticker--word{left:2%;bottom:-5%;width:32%;}
  .sticker--pills{left:2%;bottom:-5%;width:38%;}
}
@media (prefers-reduced-motion:reduce){
  .sticker,.sticker:hover{transition:none;}
  .sticker--word,.sticker--pills{animation:none;}
  .js .card:not(.is-in) .sticker{opacity:1;transform:rotate(var(--tilt-s));}
}

/* ─── footer: continues the last card's green ────────────────────────── */
.foot{
  display:flex;flex-wrap:wrap;align-items:baseline;gap:.5rem 2rem;
  padding:1.5rem var(--gutter) calc(1.5rem + 5rem);  /* room for the dock */
  background:var(--forest);color:var(--soft-on-forest);
  border-block-start:1px solid rgba(246,240,228,.14);
  font:500 .78rem/1.6 var(--font-mono);
}
.foot p{margin:0;}
.foot__mark img{width:auto;height:1.15rem;}
.foot__end{margin-inline-start:auto !important;}
/* the privacy link (2026-10-05): three links, one per language, one showing (see [data-only]) */
.foot__legal{display:flex;gap:1rem;}
.foot__legal a{color:inherit;text-decoration:underline;text-underline-offset:.2em;}
.foot__legal a:hover{color:var(--cream);}
[lang="ar"] .foot__legal{font-family:var(--font-ar);}
@media (max-width:40rem){.foot__end{margin-inline-start:0 !important;}}

/* ─── the dock ───────────────────────────────────────────────────────── */
/* The dock and the WhatsApp button are one set (2026-09-26, his request):
   the same die-cut edge — an ink rim, a cream ring, a hard shadow — the same
   height (56px) on the same baseline, and the same colours, changed together
   as each card slides in under them (app.js sets data-on on both). Each set
   is the WhatsApp disc's colours: the dock's body is the disc, its accent
   (the current link and the envelope) is the glyph. Every pair measured:
     hero   forest body · cream links 9.00 · marigold accent, ink 9.72
     make   marigold body · ink links 9.72 · ink accent, marigold 9.72
     work   tomato body · ink links 5.00 · ink accent, cream 15.68
     who    ink body · cream links 15.68 · marigold accent, ink 9.72
     hi     cream body · ink links 15.68 · forest accent, cream 9.00
   The mark follows the body, as his kit's README says: cream on forest and
   ink, the on-marigold mark on marigold and tomato, ink on cream. Colour eases
   in the button's .45s, so the two change as one. */
.dock{
  --dock-bg:var(--ink);--dock-fg:var(--cream);--dock-acc:var(--marigold);--dock-acc-fg:var(--ink);
  --dock-shadow:var(--ink);--focus:var(--marigold);
  position:fixed;z-index:50;
  inset-block-end:clamp(.75rem,2.5vh,1.4rem);inset-inline:0;margin-inline:auto;
  width:max-content;max-width:calc(100% - 1.25rem);
  display:flex;align-items:center;gap:.3rem;padding:.375rem;
  background:var(--dock-bg);border:var(--edge);border-radius:var(--pill);
  box-shadow:0 0 0 2px var(--cream),4px 4px 0 2px var(--dock-shadow);
  opacity:0;transform:translateY(150%);
  transition:opacity .5s var(--ease),transform .5s var(--ease),
             background-color .45s var(--ease),box-shadow .45s var(--ease);
}
.dock.is-up{opacity:1;transform:none;}
/* the homepage FAQ (cream, like the hero) takes the hero's set; the pricing
   page's order card keeps the default ink body with marigold (his call) */
.dock[data-on="hero"],.dock[data-on="faq"]{--dock-bg:var(--forest);}
.dock[data-on="make"]{--dock-bg:var(--marigold);--dock-fg:var(--ink);--dock-acc:var(--ink);--dock-acc-fg:var(--marigold);--dock-shadow:rgb(0 0 0/.45);--focus:var(--ink);}
.dock[data-on="work"]{--dock-bg:var(--tomato);--dock-fg:var(--ink);--dock-acc:var(--ink);--dock-acc-fg:var(--cream);--dock-shadow:rgb(0 0 0/.6);--focus:var(--ink);}
/* over the pricing page's ink "Good to know": marigold body, ink links and
   an ink current pill with marigold text (his call, 2026-09-27) — 9.72 each way */
.dock[data-on="know"]{--dock-bg:var(--marigold);--dock-fg:var(--ink);--dock-acc:var(--ink);--dock-acc-fg:var(--marigold);--dock-shadow:rgb(0 0 0/.45);--focus:var(--ink);}
.dock[data-on="know"] .dock__mark--cream{display:none;}
.dock[data-on="know"] .dock__mark--gold{display:block;}
.dock[data-on="hi"]{--dock-bg:var(--cream);--dock-fg:var(--ink);--dock-acc:var(--forest);--dock-acc-fg:var(--cream);--dock-shadow:rgb(0 0 0/.45);--focus:var(--ink);}
/* prices (tomato card): cream body 3.14 on tomato (graphics, with its ink rim)
   · ink links 15.68 · ink accent, cream 15.68 */
.dock[data-on="prices"]{--dock-bg:var(--cream);--dock-fg:var(--ink);--dock-acc:var(--ink);--dock-acc-fg:var(--cream);--dock-shadow:rgb(0 0 0/.45);--focus:var(--ink);}
.dock__seal{flex:none;display:grid;place-items:center;width:2.5rem;height:2.5rem;border-radius:50%;}
.dock__mark{width:auto;height:1.55rem;grid-area:1/1;}
.dock__mark--ink,.dock__mark--gold,
.dock[data-on="make"] .dock__mark--cream,.dock[data-on="work"] .dock__mark--cream,
.dock[data-on="hi"] .dock__mark--cream,.dock[data-on="prices"] .dock__mark--cream{display:none;}
.dock[data-on="make"] .dock__mark--gold,.dock[data-on="work"] .dock__mark--gold,
.dock[data-on="hi"] .dock__mark--ink,.dock[data-on="prices"] .dock__mark--ink{display:block;}
.dock__links{display:flex;align-items:center;gap:.1rem;list-style:none;margin:0;padding:0;}
.dock__links a{
  display:block;padding:.62rem .9rem;border-radius:var(--pill);
  color:var(--dock-fg);text-decoration:none;white-space:nowrap;
  font:600 .72rem/1 var(--font-mono);letter-spacing:.12em;text-transform:uppercase;
  transition:background-color .45s var(--ease),color .45s var(--ease);
}
.dock__links a:hover{background:color-mix(in srgb,var(--dock-fg) 14%,transparent);transition-duration:.2s;}
.dock__links a[aria-current="true"]{background:var(--dock-acc);color:var(--dock-acc-fg);}
/* the dock's envelope copies the email on a computer (an envelope, a tick
   once copied) and opens the contact choice on a phone; its bubble rises
   above the dock. Accent-coloured, like the current link. */
.dock__cta{
  flex:none;display:grid;place-items:center;width:2.5rem;height:2.5rem;border-radius:50%;
  padding:0;border:0;cursor:pointer;
  background:var(--dock-acc);color:var(--dock-acc-fg);
  transition:background-color .45s var(--ease),color .45s var(--ease);
}
.dock__cta svg{width:1rem;height:1rem;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;overflow:visible;}
/* its own icon classes, not .mail__copy/.mail__open: those swap by device for
   the big buttons, and on a phone they hid the envelope here too. The cross
   turns in when the contact choice opens; the tick replaces both once copied. */
.dock__env,.dock__x{transform-box:fill-box;transform-origin:center;transition:opacity .2s var(--ease),transform .35s var(--ease);}
.dock__x{opacity:0;transform:rotate(-90deg) scale(.4);}
.dock.is-open .dock__env{opacity:0;transform:rotate(90deg) scale(.4);}
.dock.is-open .dock__x{opacity:1;transform:none;}
.dock__cta.is-copied .dock__env,.dock__cta.is-copied .dock__x{display:none;}
/* where the envelope opens the choice, its "Copy email" bubble would lie; it
   still says "Copied!" after an email pick */
.dock.is-pick .dock__cta:not(.is-said) .tip{opacity:0;}

/* ─── the contact choice (phones, tablets, narrow windows) ───────────────
   Email and WhatsApp pop out of the dock's envelope. Each is a cream pill
   with an ink edge (the header's pill, so it reads on any card) whose round
   icon sits in a column right above the envelope; the label runs toward the
   middle of the screen. Opening, each pill grows out of the envelope's
   centre on the house spring — email first (it is nearer), WhatsApp 55ms
   behind — and its label slides in once the pill has landed. Closing is
   quicker and in reverse. Transform and opacity only. */
.pick{
  position:absolute;inset-block-end:calc(100% + .75rem);inset-inline-end:-2px;   /* the dock's rim: align with its outer edge */
  display:flex;flex-direction:column;align-items:flex-end;gap:.6rem;
  visibility:hidden;pointer-events:none;
  transition:visibility 0s linear .3s;
}
.dock.is-open .pick{visibility:visible;pointer-events:auto;transition-delay:0s;}
.pick__opt{
  --k:1;--from:3.95rem;
  display:inline-flex;align-items:center;gap:.75rem;min-height:3.15rem;margin:0;
  padding-block:.28rem;padding-inline:1.15rem .375rem;
  background:var(--cream);color:var(--ink);text-decoration:none;cursor:pointer;
  border:var(--edge);border-radius:var(--pill);box-shadow:3px 3px 0 var(--ink);
  font:600 .74rem/1 var(--font-mono);letter-spacing:.12em;text-transform:uppercase;
  --focus:var(--ink);
  /* grows from the icon's centre, which sits over the envelope's centre */
  transform-origin:calc(100% - 1.75rem) 50%;
  opacity:0;transform:translateY(var(--from)) scale(.3);
  transition:transform .2s cubic-bezier(.5,0,.75,0) calc((2 - var(--k)) * 30ms),
             opacity .14s linear calc((2 - var(--k)) * 30ms + 50ms);
}
.pick__opt--wa{--k:2;--from:7.7rem;}
.dock.is-open .pick__opt{
  opacity:1;transform:none;
  transition:transform .5s var(--ease) calc((var(--k) - 1) * 55ms),opacity .12s linear calc((var(--k) - 1) * 55ms);
  transition:transform .55s var(--spring) calc((var(--k) - 1) * 55ms),opacity .12s linear calc((var(--k) - 1) * 55ms);
}
.pick__label{opacity:0;translate:.6rem 0;transition:opacity .1s,translate .1s;}
.dock.is-open .pick__label{
  opacity:1;translate:0;
  transition:opacity .25s var(--ease) calc(150ms + (var(--k) - 1) * 55ms),translate .4s var(--ease) calc(150ms + (var(--k) - 1) * 55ms);
}
.pick__ico{flex:none;display:grid;place-items:center;width:2.5rem;height:2.5rem;border-radius:50%;}
.pick__ico svg{width:1.15rem;height:1.15rem;}
.pick__opt--mail .pick__ico{background:var(--marigold);color:var(--ink);}   /* ink on marigold 9.72 */
.pick__opt--mail .pick__ico svg{fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;}
.pick__opt--wa .pick__ico{background:var(--forest);color:var(--cream);}     /* cream on forest 9.00 */
.pick__opt--wa .pick__ico svg{width:1.3rem;height:1.3rem;}
.pick__opt:active{transform:translate(2px,2px);box-shadow:1px 1px 0 var(--ink);}
[dir="rtl"] .pick__opt{transform-origin:1.75rem 50%;}
[dir="rtl"] .pick__label{translate:-.6rem 0;}
[dir="rtl"] .dock.is-open .pick__label{translate:0;}
.pick-scrim{
  position:fixed;inset:0;z-index:49;
  background:rgb(22 24 26/.4);
  opacity:0;visibility:hidden;
  transition:opacity .25s var(--ease),visibility 0s linear .25s;
}
.pick-scrim.is-on{opacity:1;visibility:visible;transition-delay:0s;}
@media (prefers-reduced-motion:reduce){
  /* no travel: the choices and the cross simply fade */
  .pick__opt,.dock.is-open .pick__opt{transform:none;transition:opacity .15s linear;}
  .pick__label,.dock.is-open .pick__label{translate:0;transition:none;}
  .dock__env,.dock__x,.dock.is-open .dock__env{transform:none;}
}

/* ─── WhatsApp: the corner button (computers) ────────────────────────────
   A round button in the bottom corner, on every card. Its colours are picked
   for the card it is sitting on, and change as each new card slides in under
   it (app.js sets data-on, with a small pop). It is the one thing on the
   page that isn't marigold-and-ink — his call (2026-09-26). Every pair is
   measured: glyph on disc, and disc on the card beneath (graphics, 3:1):
     hero, cream  → forest disc, cream glyph 9.00 · disc on cream 9.00
     make, forest → marigold disc, ink glyph 9.72 · disc on forest 5.8
     work, ink    → tomato disc, ink glyph 5.00 · disc on ink 4.7
     who, marigold→ ink disc, marigold glyph 9.72 · disc on marigold 9.72
     hi, forest   → cream disc, forest glyph 9.00 · disc on forest 9.00
   Content passes under it too (the ink "Property & retail" card swallowed
   the ink disc), so it wears a sticker's die-cut edge: an ink rim, then a
   cream ring (the dock's own trick), which reads on every card and every
   picture. Logical inline-end, so in Arabic it moves to the left corner
   with the layout. */
.wa{
  --wa-bg:var(--forest);--wa-fg:var(--cream);--wa-shadow:var(--ink);--focus:var(--ink);
  position:fixed;z-index:50;
  inset-block-end:clamp(.75rem,2.5vh,1.4rem);inset-inline-end:var(--gutter);
  display:grid;place-items:center;width:3.5rem;height:3.5rem;border-radius:50%;
  background:var(--wa-bg);color:var(--wa-fg);text-decoration:none;
  border:var(--edge);box-shadow:0 0 0 2px var(--cream),4px 4px 0 2px var(--wa-shadow);
  transition:background-color .45s var(--ease),color .45s var(--ease),border-color .45s var(--ease),
             box-shadow .45s var(--ease),transform .18s var(--ease);
  animation:wa-in .6s var(--ease) 1.2s backwards;
  animation:wa-in .7s var(--spring) 1.2s backwards;
}
.wa__glyph{width:1.65rem;height:1.65rem;}
.wa[data-on="make"]{--wa-bg:var(--marigold);--wa-fg:var(--ink);--wa-shadow:rgb(0 0 0/.45);--focus:var(--marigold);}
.wa[data-on="work"]{--wa-bg:var(--tomato);--wa-fg:var(--ink);--wa-shadow:rgb(0 0 0/.6);--focus:var(--marigold);}
.wa[data-on="who"]{--wa-bg:var(--ink);--wa-fg:var(--marigold);}
.wa[data-on="hi"]{--wa-bg:var(--cream);--wa-fg:var(--forest);--wa-shadow:rgb(0 0 0/.45);--focus:var(--marigold);}
/* prices, tomato → cream disc, ink glyph 15.68 · disc on tomato 3.14 */
.wa[data-on="prices"]{--wa-bg:var(--cream);--wa-fg:var(--ink);--wa-shadow:rgb(0 0 0/.45);--focus:var(--ink);}
@media (hover:hover){.wa:hover{transform:translate(-2px,-2px);box-shadow:0 0 0 2px var(--cream),6px 6px 0 2px var(--wa-shadow);}}
.wa:active{transform:translate(2px,2px);box-shadow:0 0 0 2px var(--cream),1px 1px 0 2px var(--wa-shadow);}
/* the entrance plays once: app.js marks it .is-seen when it ends (or when the
   first pop cuts it short), or taking the pop's class off would replay it */
.wa.is-seen{animation:none;}
/* a new card has slid in under it: it pops as it takes the new colours */
.wa.is-bump{animation:wa-bump .45s var(--ease);animation:wa-bump .55s var(--spring);}
@keyframes wa-in{from{opacity:0;scale:.4;}}
@keyframes wa-bump{from{scale:.82;}}
/* its bubble opens toward the middle of the screen, so it never runs off
   the edge; the tail stays over the button */
.wa .tip{left:auto;right:0;transform:translateY(6px);}
.wa .tip::after{left:auto;right:calc(1.75rem - 7px);margin-left:0;}
[dir="rtl"] .wa .tip{right:auto;left:0;}
[dir="rtl"] .wa .tip::after{right:auto;left:calc(1.75rem - 7px);}
@media (hover:hover){.wa:hover .tip{opacity:1;transform:none;}}
.wa:focus-visible .tip{opacity:1;transform:none;}
/* ─── the split (2026-10-08) ─────────────────────────────────────────────
   While the next card rises through the dock and the disc, app.js cuts each
   along that card's skyline: the real one keeps the old colours, a ghost —
   a visual copy in the new card's colours — is clipped to the part the new
   card has reached (clip-path written each frame). The ghost is aria-hidden,
   inert and never takes the pointer; a hover on the real one is mirrored
   onto it (.is-hov). .is-snap takes the real one to the new colours with no
   transition, in the frame the ghost steps aside. */
.dock.is-snap,.dock.is-snap *,.wa.is-snap{transition:none !important;}
.dock--ghost,.wa--ghost{visibility:hidden;pointer-events:none;transition:none !important;animation:none !important;}
.dock--ghost *{transition:none !important;pointer-events:none;}
.dock--ghost.is-on,.wa--ghost.is-on{visibility:visible;}
.dock--ghost .tip,.wa--ghost .tip{display:none;}
@media (hover:hover){
  .dock--ghost .dock__links a.is-hov{background:color-mix(in srgb,var(--dock-fg) 14%,transparent);}
  .wa--ghost.is-hov{transform:translate(-2px,-2px);box-shadow:0 0 0 2px var(--cream),6px 6px 0 2px var(--wa-shadow);}
}
/* Phones, tablets and windows under 52rem: no corner button (the dock's
   envelope opens the choice instead), and the dock drops its "Say hi" link —
   the envelope beside it is the way to say hi there, and four links don't fit
   a phone. Keep this query and pickMq in app.js the same. */
@media (hover:none) and (pointer:coarse),(max-width:51.99rem){.wa,.dock__hi{display:none;}}
@media (prefers-reduced-motion:reduce){
  .wa,.wa.is-bump{animation:none;}
  .wa:hover,.wa:active{transform:none;}
  .wa .tip{transform:none;}
}
[lang="ar"] .dock__links a{letter-spacing:0;font-family:var(--font-ar);font-size:.8rem;}
@media (max-width:30rem){
  .dock__seal{display:none;}
  .dock__links a{padding:.6rem .62rem;letter-spacing:.04em;font-size:.66rem;}
}
/* the smallest phones (320px): three links and the envelope still fit, with
   the links a little closer and their tracking off */
@media (max-width:22.49rem){.dock__links a{padding-inline:.45rem;letter-spacing:0;}}
/* four links since FAQ joined (2026-09-27): on the smallest phones English
   and Arabic ran 12–13px past the dock at 320px, so the links close up a
   little more there (up to 384px: English ran over at 360 too) */
@media (max-width:24rem){
  .dock{gap:.15rem;}
  .dock__links a{padding-inline:.36rem;font-size:.62rem;}
  [lang="ar"] .dock__links a{font-size:.72rem;padding-inline:.3rem;}
}
/* 320px with "Prices" in the dock (2026-09-27): English ran a few px over */
@media (max-width:21rem){.dock__links a{padding-inline:.28rem;font-size:.6rem;}}

/* ─── Arabic labels ──────────────────────────────────────────────────────
   JetBrains Mono has no Arabic glyphs, so every mono label would fall back to
   whatever font the device has. In Arabic they take Noto Sans Arabic instead,
   at a size that reads (mono caps are small by design; Arabic is not caps). */
[lang="ar"] .tag,[lang="ar"] .client__cta,[lang="ar"] .client__no,[lang="ar"] .work__meta,
[lang="ar"] .work__zoom,[lang="ar"] .viewer__close,[lang="ar"] .foot,[lang="ar"] .langs button,[lang="ar"] .tip,
[lang="ar"] .pick__opt{
  font-family:var(--font-ar);letter-spacing:0;text-transform:none;
}
[lang="ar"] .tag,[lang="ar"] .client__cta,[lang="ar"] .pick__opt{font-size:.85rem;}
[lang="ar"] .tip{font-size:.8rem;}
/* the language buttons read EN / ID / AR in Latin, so they keep the mono */
[lang="ar"] .langs button{font-family:var(--font-mono);}
/* the menu: Noto Sans Arabic for the pill and the quiet row, Kufi for the rows
   (no uppercase, no tracking, Kufi's own line height) */
[lang="ar"] .menu__btn,[lang="ar"] .menu__link--quiet{font-family:var(--font-ar);font-size:.85rem;letter-spacing:0;text-transform:none;}
[lang="ar"] .menu__link{font-family:var(--font-ar-display);font-weight:700;font-size:1.08rem;line-height:1.25;letter-spacing:0;text-transform:none;}
[lang="ar"] .menu__link--quiet{font-family:var(--font-ar);font-weight:600;font-size:.85rem;}

/* ─── phones and tablets ─────────────────────────────────────────────── */
@media (max-width:40rem){
  :root{--header-h:4rem;}
  .chrome{padding:.7rem var(--gutter);}
  .brand{padding:.45rem .8rem;}
  .brand__logo{height:1.45rem;}
  .brand__logo--ar{height:1.8rem;}
  .langs button{padding:.45rem .62rem;}
  .menu__btn{padding-block:.67rem;padding-inline:.75rem .85rem;}
  .card{padding-block-end:clamp(4.5rem,10vh,6rem);}   /* clear the dock */
  .seal{top:-8%;right:-2%;}     /* clear of the email button just above */
  /* Stickers on a phone: after the headline, in the flow, at the end side —
     there is no empty corner to put them in. The hero's sticker (pills, or the
     Arabic word) stays off: below the photo it would only push the page down;
     "fluent" keeps the corner beside the logo. */
  .sticker{position:relative;inset:auto;display:block;margin-block:.25rem 1.75rem;margin-inline:auto 0;}
  .sticker--word,.sticker--pills{display:none;}
  .sticker--search{width:84%;}
  .sticker--diamond{width:44%;margin-block-start:-.5rem;}
  .sticker--pass{width:86%;}
  .sticker--hi{width:36%;margin-block-start:-1.75rem;}
  /* beside the logo, hanging into the card's bottom padding: higher up it
     touched the email button */
  .sticker--fluent{position:absolute;inset-inline-end:0;inset-block-end:-3rem;width:34%;margin:0;}
  .hi__lockup{width:52%;}
}

/* the narrowest phones (320–359): the language pill is the widest of the three,
   so it gives up a little padding to let the logo sit nearer the middle */
@media (max-width:22.49rem){
  .chrome{column-gap:.5rem;}
  .langs button{padding-inline:.5rem;}
}

/* ─── links to a page that exists in one language (2026-10-04) ───────────
   Each language has its own service page at its own address (/web-design/,
   /id/jasa-pembuatan-website/, /ar/web-design/), so each link exists three
   times, one per language, as plain text that only shows on pages in that
   language. They pass through the generator untouched, setLang never
   rewrites them, and switching language in place swaps which one shows. */
html:not([lang="id"]) [data-only="id"],
html:not([lang="en"]) [data-only="en"],
html:not([lang="ar"]) [data-only="ar"]{display:none !important;}
.more-link{
  display:inline-block;margin-block-start:.7rem;
  color:var(--accent);font-weight:600;
  text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:.18em;
}
.more-link--qa{display:block;width:fit-content;margin:-.7rem 0 1.4rem;}

/* ─── the page transition: the deck is dealt (2026-10-09) ────────────────
   Pressing a link to another page deals three full-screen cards up the screen,
   one after another, each in a brand colour picked at random and each behind
   its own skyline (the page's own .crest pieces, lighthouse and all), until the
   screen is full and his mark sits on the top card. The next page opens under
   the same cards, which sink back down, top card first. Built by leap.js, which
   is loaded in <head> on every page.
   Only transform moves. Cover ≈ 0.64 s, uncover ≈ 0.55 s; the exit is shorter
   than the entrance. Reduced motion and Save-Data never get any of it. */
:root{--leap-mark:clamp(5rem,15vmin,8.5rem);}
.leap{position:fixed;inset:0;z-index:2147483000;overflow:hidden;pointer-events:auto;}
.leap__c{
  position:absolute;inset:0;background:var(--bg);
  transform:translate3d(0,calc(100% + var(--crest-lead)),0);
  will-change:transform;
}
.leap .crest__p{transform:translateY(101%);}
/* cover: each card climbs, its towers rising out from behind its edge a beat later */
.leap--in .leap__c{
  transform:none;
  transition:transform .5s var(--ease) calc(var(--ci) * 70ms);
}
.leap--in .crest__p{
  transform:none;
  transition:transform .5s var(--ease) calc(var(--ci) * 70ms + 140ms + var(--d) * 350ms);
}
/* the new page is under the cards, already covering: no motion until they lift */
.leap--set .leap__c,.leap--set .crest__p{transform:none;transition:none;}
/* uncover: the top card goes first, the skylines stay up as they sink */
.leap--out .leap__c{
  transform:translate3d(0,calc(100% + var(--crest-lead)),0);
  transition:transform .46s cubic-bezier(.65,0,.35,1) calc((2 - var(--ci)) * 55ms);
}
.leap--out .crest__p{transform:none;}
/* his mark, on the top card, lights as the screen fills and goes at once as it lifts */
.leap__mark{
  position:absolute;left:50%;top:50%;translate:-50% -50%;
  height:var(--leap-mark);width:auto;aspect-ratio:328/364;
  opacity:0;scale:.72;
}
.leap--in .leap__mark{
  opacity:1;scale:1;
  transition:opacity .2s linear 430ms,scale .5s var(--ease) 430ms;
  transition:opacity .2s linear 430ms,scale .6s var(--spring) 430ms;
}
.leap--set .leap__mark{opacity:1;scale:1;transition:none;}
.leap--out .leap__mark{opacity:0;scale:.9;transition:opacity .14s linear,scale .2s var(--ease);}

/* arriving: until leap.js has rebuilt the cards, the new page starts under a
   plain cover in the top card's colour with his mark in the middle, so nothing
   flashes. If the script never runs, the cover removes itself after 3 s. The
   page's own entrance animations wait (leap-wait) and begin as the cards lift. */
html.leap-in::before,html.leap-in::after{content:"";position:fixed;z-index:2147483000;animation:leap-failsafe 0s linear 3s forwards;}
html.leap-in::before{inset:0;background:var(--leap-c,var(--forest));}
html.leap-in::after{
  left:50%;top:50%;translate:-50% -50%;height:var(--leap-mark);aspect-ratio:328/364;
  background:var(--leap-m,url(/assets/brand/manara-mark-cream.svg)) center/contain no-repeat;
}
html[data-leap="tomato"],html[data-leap="marigold"]{--leap-m:url(/assets/brand/manara-mark-on-marigold.svg);}
html[data-leap="forest"],html[data-leap="ink"]{--leap-m:url(/assets/brand/manara-mark-cream.svg);}
html[data-leap="tomato"]{--leap-c:var(--tomato);}
html[data-leap="marigold"]{--leap-c:var(--marigold);}
html[data-leap="forest"]{--leap-c:var(--forest);}
html[data-leap="ink"]{--leap-c:var(--ink);}
@keyframes leap-failsafe{to{opacity:0;visibility:hidden;}}
html.leap-wait *,html.leap-wait *::before,html.leap-wait *::after{animation-play-state:paused !important;}

/* ─── the scrollbar (2026-10-05, his request) ────────────────────────────
   Coloured like the dock: it takes the card the dock is sitting on
   (paintGround in app.js writes html[data-ground]) and switches with it, a
   state change rather than a colour driven by the scroll. Track = the
   card's ground, thumb = its accent, each pair at 5:1 or better, fading
   from one pair to the next (below). Every page
   is covered: homepage cards, the pricing page's order / know / hi, the
   service pages' content / hi. */
/* The two colours fade into the next card's pair (0.6 s) instead of
   jumping: registered as colours, like --bg in "What we make", so the
   browser can interpolate them. No fade under reduced motion. */
@property --sb-thumb{syntax:"<color>";inherits:true;initial-value:#0f4a37;}
@property --sb-track{syntax:"<color>";inherits:true;initial-value:#f6f0e4;}
:root{--sb-thumb:var(--forest);--sb-track:var(--cream);}
html{
  scrollbar-color:var(--sb-thumb) var(--sb-track);
  transition:--sb-thumb .6s var(--ease),--sb-track .6s var(--ease);
}
@media (prefers-reduced-motion:reduce){html{transition:none;}}
html[data-ground="make"],html[data-ground="hi"]{--sb-thumb:var(--marigold);--sb-track:var(--forest);}
html[data-ground="work"]{--sb-thumb:var(--tomato);--sb-track:var(--ink);}
html[data-ground="know"]{--sb-thumb:var(--marigold);--sb-track:var(--ink);}
html[data-ground="who"]{--sb-thumb:var(--ink);--sb-track:var(--marigold);}
html[data-ground="prices"]{--sb-thumb:var(--ink);--sb-track:var(--tomato);}
