/* ==========================================================================
   MISCAREA, o singura data, pentru toate paginile.
   Pana acum tot ce facea site-ul sa para scump traia doar in index.html:
   cortina, dezvaluirea la derulare, blurul dintre pagini, haloul de sub
   butoane. Cine deschidea portofoliul sau calculatorul ateriza pe o pagina
   moarta, si diferenta se citea instant ca "prima pagina e vitrina, restul e
   graba". Fisierul asta muta tot stratul de miscare intr-un loc si il pune pe
   fiecare pagina.

   Trei reguli pe care nu le incalc aici:
   1. Miscarea explica ceva sau nu exista. Nimic in bucla, nimic decorativ.
   2. Starea de plecare se scrie in CSS, dar numai sub `.js`. Fara asta,
      cine are JavaScript oprit vede o pagina goala.
   3. Nimic nu tine omul pe loc. Continutul e randat dedesubt de la inceput.
   ========================================================================== */

/* ---------- scala pentru telefon ----------
   Pe 390 px scala de desktop nu se micsoreaza singura, doar se inghesuie.
   Titlul manca jumatate de ecran, iar textul de sub el venea la aceeasi
   greutate vizuala, deci ochiul nu mai stia ce sa citeasca intai.
   Aici se rescriu chiar variabilele, o data, si se aplica peste tot. */
@media (max-width:760px){
  :root{
    /* Verticala se strange. 112 px intre sectiuni pe un ecran de 844 px
       inseamna ca un sfert din ecran e gol la fiecare trecere. */
    --s7:36px; --s8:52px; --s9:68px; --s10:88px;

    /* Titlul coboara, textul coboara mai mult. Raportul dintre ele urca de
       la 1,9 la 2,4, deci ierarhia se vede din prima privire. */
    --t-hero:clamp(31px,8.4vw,38px);
    --t-2xl:clamp(25px,6.6vw,31px);
    --t-xl:clamp(21px,5.4vw,25px);
    --t-lg:17px;
    --t-md:15.5px;
    --t-sm:13px;
    --t-xs:10.5px;
  }
  h1{max-width:15ch;letter-spacing:-.032em;line-height:1.06}
  h2{max-width:16ch;letter-spacing:-.026em;line-height:1.12}
  .lede{max-width:38ch;line-height:1.5}
  /* Mono la 15 px pe telefon citeste a terminal, nu a produs scump. */
  .mono,code,kbd,samp,pre,.kicker,.eticheta{letter-spacing:.02em}
}

/* ---------- un singur antet, pe toate paginile ----------
   Erau cinci feluri: unul lipit cu logo si buton, unul cu logo si "inapoi",
   doua doar cu logo static, si o pagina fara nimic. Cine deschidea un demo
   din portofoliu ramanea fara drum inapoi si fara sa mai stie al cui e site-ul.
   Numele de clasa difera de la pagina la pagina din motive istorice, deci le
   prindem pe amandoua. */
.head,.antet{
  position:sticky;top:0;z-index:50;
  background:color-mix(in srgb,var(--fond,#0A0910) 90%,transparent);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border-bottom:1px solid rgba(195,180,230,.10);
}
.antet{padding-block:var(--s4);gap:var(--s3)}
/* Legatura inapoi, acolo unde pagina nu avea niciuna. */
/* Era text gol, latime 30 px pe telefon: sub degetul care acopera vreo 45 se
   nimerea din a doua incercare. Devine pastila, ca restul butoanelor din antet,
   cu sageata care spune incotro duce. */
.antet .inapoi,.head .inapoi{
  margin-left:auto;color:var(--text-2);text-decoration:none;
  font-size:var(--t-sm);min-height:44px;min-width:44px;
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  padding:0 14px;border:1px solid var(--linie,#272232);border-radius:var(--raza,10px);
  transition:color var(--cut,160ms ease),border-color var(--cut,160ms ease),
             background var(--cut,160ms ease);
}
.antet .inapoi::before,.head .inapoi::before{
  content:"";width:6px;height:6px;flex:none;
  border-left:1px solid currentColor;border-bottom:1px solid currentColor;
  transform:rotate(45deg) translateX(1px);opacity:.65;
}
.antet .inapoi:hover,.head .inapoi:hover{
  color:var(--text);border-color:var(--text-3,#8A83A0);
  background:color-mix(in srgb,var(--luciu,#C3B4E6) 7%,transparent);
}
.antet .inapoi:focus-visible{outline:2px solid var(--luciu);outline-offset:4px;border-radius:2px}

/* ---------- fumul din fundal ----------
   Trei panze de zgomot fractal care se rotesc si plutesc foarte incet peste
   tot fundalul. Umplu golurile dintre sectiuni fara sa adauge continut si dau
   adancime: fara ele, negrul e o suprafata plata si fiecare gol se citeste ca
   spatiu uitat.

   De ce zgomot si nu gradienti blurati: un gradient radial estompat ramane un
   CERC, oricat l-ai face de moale, iar ochiul il citeste ca pata, nu ca fum.
   `feTurbulence` cu `fractalNoise` da structura pe care o are fumul adevarat,
   neregulata la mai multe scari deodata.

   Si e de zece ori mai ieftin. Prima varianta anima `scale()` pe cinci
   elemente cu `blur(60px)`: blurul se recalcula la fiecare cadru si pagina
   mergea in 19 cadre pe secunda pe desktop. Masurat, nu banuit. Aici textura
   se picteaza O DATA, iar animatia atinge doar `transform`, care merge pe
   compozitor.

   Trei conditii pe care nu le incalc:
   1. Foarte estompat. Peste `opacity:.5` pe panza se citeste ca zgomot de
      televizor si iese tot efectul.
   2. Nu atinge textul: `z-index:0` si `pointer-events:none`, iar `main` si
      `footer` stau pe 1.
   3. Se misca INCET. O rotatie completa in doua minute. Daca se vede ca se
      misca, e prea repede. */
:root{
  --fum-a:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22700%22%20height%3D%22700%22%3E%3Cfilter%20id%3D%22f%22%20x%3D%220%22%20y%3D%220%22%20width%3D%22100%25%22%20height%3D%22100%25%22%3E%3CfeTurbulence%20type%3D%22fractalNoise%22%20baseFrequency%3D%220.005%22%20numOctaves%3D%224%22%20seed%3D%227%22%20stitchTiles%3D%22stitch%22%2F%3E%3CfeColorMatrix%20values%3D%220%200%200%200%200.58%200%200%200%200%200.48%200%200%200%200%200.82%200%200%200%20-3.4%201.02%22%2F%3E%3C%2Ffilter%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20filter%3D%22url%28%23f%29%22%2F%3E%3C%2Fsvg%3E");
  --fum-b:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22700%22%20height%3D%22700%22%3E%3Cfilter%20id%3D%22f%22%20x%3D%220%22%20y%3D%220%22%20width%3D%22100%25%22%20height%3D%22100%25%22%3E%3CfeTurbulence%20type%3D%22fractalNoise%22%20baseFrequency%3D%220.0085%22%20numOctaves%3D%223%22%20seed%3D%2221%22%20stitchTiles%3D%22stitch%22%2F%3E%3CfeColorMatrix%20values%3D%220%200%200%200%200.92%200%200%200%200%200.46%200%200%200%200%200.28%200%200%200%20-3.8%201.14%22%2F%3E%3C%2Ffilter%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20filter%3D%22url%28%23f%29%22%2F%3E%3C%2Fsvg%3E");
  --fum-c:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22700%22%20height%3D%22700%22%3E%3Cfilter%20id%3D%22f%22%20x%3D%220%22%20y%3D%220%22%20width%3D%22100%25%22%20height%3D%22100%25%22%3E%3CfeTurbulence%20type%3D%22fractalNoise%22%20baseFrequency%3D%220.0035%22%20numOctaves%3D%225%22%20seed%3D%2243%22%20stitchTiles%3D%22stitch%22%2F%3E%3CfeColorMatrix%20values%3D%220%200%200%200%200.45%200%200%200%200%200.4%200%200%200%200%200.66%200%200%200%20-3.1%200.93%22%2F%3E%3C%2Ffilter%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20filter%3D%22url%28%23f%29%22%2F%3E%3C%2Fsvg%3E");
}
.fum-fond{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden;contain:strict}
/* Panza are FIX cat ecranul, plus o margine cat sa nu apara colturi cand
   aluneca. Prima varianta o facea de 190vmax ca sa se poata roti in jurul
   centrului fara sa iasa din cadru: la 1440 px inseamna 2736 pe 2736, iar
   `will-change:transform` cere atunci un strat pe placa video de vreo 30 MB
   PER PANZA. De aici cele 19, apoi 27 de cadre pe secunda.

   Deci nu se roteste nimic. Textura se REPETA, deci e continua oricat o muti,
   si e de ajuns s-o plimbi cateva procente ca sa para ca fumul curge. Doua
   panze care aluneca in directii diferite dau si senzatia de rotatie, fara
   ca ceva sa se roteasca de fapt. */
/* UN SINGUR strat, cu trei texturi suprapuse care curg fiecare in alta
   directie. Nu se misca elementul, se misca textura pe sub el.

   De ce asa: trei panze separate, fiecare cat ecranul plus o margine, inseamna
   trei straturi pe placa video de cate cateva zeci de megaocteti, plus
   compunerea lor la fiecare cadru. Masurat pe desktop: 65 din cele 121 de
   cadre pe secunda se duceau numai pe asta.

   `background-position` pe o textura care se repeta nu muta nimic, doar
   schimba de unde incepe citirea ei. Elementul sta pe loc, deci nu are nevoie
   nici de margine in plus ca sa nu apara colturi goale. */
/* UN SINGUR strat care se misca, cu trei texturi suprapuse pe el.

   Trei incercari masurate, ca sa ajung aici:
     trei panze separate, fiecare cu `transform`  -> 54 cadre pe secunda
     un strat, cu `background-position` animat    -> 32 (repicteaza tot ecranul)
     un strat, cu `transform`                     -> vezi mai jos

   `background-position` pare ieftin fiindca nu misca niciun element, dar
   browserul recalculeaza umplerea intregii suprafete la fiecare cadru.
   `transform` pe un strat deja pictat doar il muta, si aia o face placa video.
   Un strat in loc de trei inseamna o treime din memoria video si o singura
   compunere. */
.fum-fond i{display:none}
.fum-fond::before{
  content:"";position:absolute;
  left:-10%;top:-10%;width:120%;height:120%;
  background-image:var(--fum-a),var(--fum-b),var(--fum-c);
  background-size:700px 700px,1020px 1020px,1380px 1380px;
  background-position:0 0,180px 90px,-90px 240px;
  background-repeat:repeat,repeat,repeat;
  /* Foarte palid. La .34 arata ca o patura de piatra intinsa peste pagina,
     nu ca fum: se vedea textura, iar textul parea asezat peste o poza.
     Vazut pe captura, la 1440. Fumul trebuie sa se simta, nu sa se vada. */
  /* Era .11, adica se simtea doar unde pagina era deja plina. Fondatorul are
     dreptate: golurile mari raman goale, si un gol negru nu e liniste, e loc
     nefolosit. Urcat la .17, cat sa se citeasca aer greu, nu tapet. Masca de
     mai jos face restul: densitatea creste spre margini si spre colturi, deci
     unde e scris ramane limpede. */
  opacity:.21;
  will-change:transform;
  animation:fond-pluteste 150s cubic-bezier(.45,.05,.55,.95) infinite alternate;

  /* Cenusa e mai deasa la margini si la colturi, si se subtiaza spre mijloc,
     unde sta scrisul. Asa fumul OCOLESTE textul fara niciun calcul: nu se
     uita nimeni unde e fiecare paragraf, doar densitatea urmeaza forma
     paginii. Si e si mai aproape de adevar: dupa o eruptie, aerul din fata
     ochilor e mai limpede decat cel de la distanta. */
  /* Masca lasa fumul mai gros la margini si il subtiaza spre mijloc, unde sta
     scrisul. Mijlocul era insa complet TRANSPARENT, iar golurile mari ale
     paginii cad tocmai acolo: fondatorul se uita la ele si nu vedea nimic.
     Acum si mijlocul primeste ceva, doar mai putin: fumul e peste tot, textul
     ramane lizibil pentru ca albul pe negru nu se pierde sub o pelicula de
     douazeci de procente. */
  -webkit-mask-image:radial-gradient(ellipse 60% 54% at 50% 42%,
    rgba(0,0,0,.30) 0%, rgba(0,0,0,.48) 34%, rgba(0,0,0,.84) 62%, #000 88%);
  mask-image:radial-gradient(ellipse 60% 54% at 50% 42%,
    rgba(0,0,0,.30) 0%, rgba(0,0,0,.48) 34%, rgba(0,0,0,.84) 62%, #000 88%);
}
/* Al doilea strat, mai rar si mai mare, care se misca in cealalta directie.
   Doua straturi care aluneca invers dau adancime: ochiul vede volum, nu un
   tapet. Un singur `transform` pe un strat deja pictat, deci nu costa cadre.
   Merge doar de la 900 px in sus: pe telefon nu exista goluri de umplut, iar
   acolo fiecare strat in plus se plateste. */
@media (min-width:900px){
  .fum-fond::after{
    content:"";position:absolute;
    left:-14%;top:-14%;width:128%;height:128%;
    background-image:var(--fum-c),var(--fum-b);
    background-size:1640px 1640px,1180px 1180px;
    background-position:220px -80px,-140px 320px;
    opacity:.16;
    will-change:transform;
    animation:fond-pluteste-invers 210s cubic-bezier(.42,.02,.58,.98) infinite alternate;
    /* Mai gol la mijloc decat primul strat: acolo sta coloana de text. */
    -webkit-mask-image:radial-gradient(ellipse 50% 48% at 50% 44%,
      rgba(0,0,0,.18) 0%, rgba(0,0,0,.38) 40%, rgba(0,0,0,.8) 70%, #000 92%);
    mask-image:radial-gradient(ellipse 50% 48% at 50% 44%,
      rgba(0,0,0,.18) 0%, rgba(0,0,0,.38) 40%, rgba(0,0,0,.8) 70%, #000 92%);
  }
}
@keyframes fond-pluteste-invers{
  from{transform:translate3d(0,0,0) rotate(0deg)}
  to  {transform:translate3d(5%,-3.5%,0) rotate(-3deg)}
}

/* ---------- licaririle ----------
   Din cand in cand, ceva se aprinde scurt dincolo de fum, dinspre marginea pe
   care sta piatra. Nu e fulger de furtuna: e portocaliu, si se citeste ca
   erupția care inca se simte sub pagina.

   Trei reguli, ca sa nu devina o reclama luminoasa:
   rar (o data la vreo 40 de secunde, la intervale neregulate), scurt (sub
   250 ms), si slab. Peste trei clipiri pe secunda intram in zona care poate
   declansa probleme la oamenii fotosensibili; aici suntem la una la 40 de
   secunde, adica de o suta de ori sub prag. Si se opreste de tot la
   `prefers-reduced-motion`.

   Costa un singur strat pe placa video, cu `opacity` animat, care e compus,
   nu repictat. */
.fum-fond .licarire{
  position:absolute;inset:0;pointer-events:none;opacity:0;
  background:
    radial-gradient(ellipse 46% 34% at 88% 26%, rgba(255,150,70,.20), transparent 62%),
    radial-gradient(ellipse 60% 50% at 78% 40%, rgba(224,98,63,.10), transparent 70%);
  will-change:opacity;
}
.fum-fond b.licarire:nth-of-type(1){animation:licar-a 41s steps(1,end) 9s infinite}
.fum-fond b.licarire:nth-of-type(2){
  animation:licar-b 67s steps(1,end) 26s infinite;
  background:
    radial-gradient(ellipse 40% 30% at 16% 70%, rgba(255,140,60,.15), transparent 60%),
    radial-gradient(ellipse 56% 46% at 26% 60%, rgba(214,84,40,.08), transparent 72%);
}
/* Doua aprinderi pe ciclu, la distante inegale, si a doua mai slaba: asa nu se
   prinde ritmul. Un ritm care se prinde nu mai e o licarire, e un semnalizator. */
@keyframes licar-a{
  0%,   23.9%  {opacity:0}
  24%          {opacity:.85}
  24.4%        {opacity:.18}
  24.7%        {opacity:.62}
  25.3%,  71%  {opacity:0}
  71.2%        {opacity:.34}
  71.7%, 100%  {opacity:0}
}
@keyframes licar-b{
  0%,   47.5%  {opacity:0}
  47.6%        {opacity:.55}
  48%          {opacity:.12}
  48.3%        {opacity:.4}
  48.9%, 100%  {opacity:0}
}
@media (prefers-reduced-motion:reduce){
  .fum-fond .licarire{animation:none;opacity:0}
}

/* O traversare completa la doua minute si jumatate. Daca se vede ca se misca,
   e prea repede. */
@keyframes fond-pluteste{
  from{transform:translate3d(0,0,0) rotate(0deg)}
  to  {transform:translate3d(-6%,4%,0) rotate(4deg)}
}
@media (max-width:760px){
  /* Pe telefon: o singura textura, mai mare, deci mai putin de repetat si de
     compus. Telefonul e si cel mai slab, si cel mai des folosit. */
  .fum-fond::before{
    left:0;top:0;width:100%;height:100%;
    background-image:var(--fum-a);
    background-size:520px 520px;
    background-position:0 0;
    background-repeat:repeat;
    opacity:.10;
    /* Fara `will-change` aici: pe un telefon, un strat separat pe placa video
       costa mai mult decat economiseste, iar miscarea e oricum abia vizibila. */
    will-change:auto;
    animation-duration:200s;
  }
}
/* Lumina care trece prin fum, pe unde a fost cursorul.
   NU dam fumul la o parte: aia cere simulare de particule, costa mult si, mai
   rau, se vede ca e un truc. Aici fumul se limpezeste in jurul cursorului, ca
   si cum ai duce o lampa prin ceata, si se inchide la loc incet in urma.

   Facut cu o PATA care se plimba peste fum, nu cu o masca pe fum.
   Prima varianta punea o masca radiala pe stratul de fum si o muta prin doua
   variabile: masca se recalcula pe toata suprafata ecranului la fiecare
   miscare de cursor si pagina cadea de la 69 la 41 de cadre pe secunda.
   Masurat. O pata de 560 px care se muta cu `translate` costa aproape nimic,
   iar efectul pe ecran e acelasi: peste fum se aseaza culoarea fondului. */
.fum-lumina{
  position:fixed;left:0;top:0;z-index:0;pointer-events:none;
  width:560px;height:560px;margin:-280px 0 0 -280px;
  background:radial-gradient(circle,
    var(--fond,#0A0910) 0%,
    color-mix(in srgb,var(--fond,#0A0910) 62%,transparent) 38%,
    transparent 72%);
  will-change:transform;
  opacity:0;transition:opacity 600ms ease;
}
.fum-lumina.vazut{opacity:1}
@media (max-width:900px),(hover:none),(pointer:coarse){ .fum-lumina{display:none} }
@media (prefers-reduced-motion:reduce){ .fum-fond::before{animation:none} }
@media (prefers-reduced-motion:reduce){
  .fum-fond i{animation:none}
}

/* ---------- meniul lateral ----------
   Trei dungi care devin un X, si un panou care intra din dreapta.
   Doar sub 900 px: mai sus incape bara intreaga si un meniu ascuns ar fi un
   click in plus pentru nimic. */
.meniu-buton{
  display:none;position:relative;flex:none;
  width:44px;height:44px;padding:0;margin-left:var(--s3,12px);
  background:none;border:1px solid var(--linie,#272232);border-radius:var(--raza,10px);
  cursor:pointer;transition:border-color var(--cut,160ms ease);
}
.meniu-buton:hover{border-color:var(--text-3,#8A83A0)}
.meniu-buton:focus-visible{outline:2px solid var(--luciu,#C3B4E6);outline-offset:3px}
.meniu-buton i{
  position:absolute;left:12px;width:20px;height:1.5px;border-radius:2px;
  background:var(--text,#EDEAF4);
  transition:transform 380ms cubic-bezier(.34,1.4,.64,1),opacity 200ms ease,top 300ms cubic-bezier(.34,1.4,.64,1);
}
/* Dungile pornesc departate si se aduna in X. Curba cu depasire, ca la
   trecerile din iOS: se duce putin peste tinta si revine. */
.meniu-buton i:nth-child(1){top:15px}
.meniu-buton i:nth-child(2){top:21px}
.meniu-buton i:nth-child(3){top:27px}
.meniu-buton.apasat i:nth-child(1){top:21px;transform:rotate(45deg)}
.meniu-buton.apasat i:nth-child(2){opacity:0;transform:scaleX(.3)}
.meniu-buton.apasat i:nth-child(3){top:21px;transform:rotate(-45deg)}

.meniu-val{
  position:fixed;inset:0;z-index:190;
  background:rgba(6,5,10,.62);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  opacity:0;transition:opacity 380ms ease;
}
.meniu-val.vazut{opacity:1}
.meniu-val[hidden]{display:none}

.meniu-panou{
  position:fixed;top:0;right:0;bottom:0;z-index:200;
  width:min(82vw,360px);
  display:flex;flex-direction:column;justify-content:center;gap:var(--s6,32px);
  padding:var(--s8,72px) var(--s6,32px) calc(var(--s7,48px) + env(safe-area-inset-bottom));
  padding-right:max(var(--s6,32px),env(safe-area-inset-right));
  background:linear-gradient(200deg,rgba(26,22,38,.97),rgba(10,9,16,.99));
  border-left:1px solid rgba(195,180,230,.14);
  box-shadow:-30px 0 80px -20px rgba(0,0,0,.9);
  transform:translateX(102%);
  transition:transform 460ms cubic-bezier(.32,1.2,.5,1);
  overflow-y:auto;overscroll-behavior:contain;
}
.meniu-panou.vazut{transform:none}
.meniu-panou[hidden]{display:none}

.meniu-lista{display:flex;flex-direction:column;gap:var(--s2,8px)}
.meniu-lista a{
  display:flex;align-items:center;min-height:52px;
  color:var(--text,#EDEAF4);text-decoration:none;
  font-size:var(--t-xl,24px);font-weight:600;letter-spacing:-.02em;line-height:1.15;
  /* Fiecare rand intra putin dupa cel de deasupra. Asa panoul se ASEAZA,
     nu apare dintr-o data. */
  opacity:0;transform:translateX(22px);
  transition:opacity 420ms ease,transform 520ms cubic-bezier(.16,1,.3,1),color 160ms ease;
  transition-delay:calc(var(--i,0) * 45ms + 120ms);
}
.meniu-panou.vazut .meniu-lista a{opacity:1;transform:none}
.meniu-lista a:hover{color:var(--luciu,#C3B4E6)}
.meniu-lista a:focus-visible{outline:2px solid var(--luciu,#C3B4E6);outline-offset:4px;border-radius:4px}

.meniu-panou .limbi.in-meniu{
  margin:0;padding-top:var(--s5,24px);border-top:1px solid var(--linie,#272232);
  opacity:0;transform:translateX(22px);
  transition:opacity 420ms ease 320ms,transform 520ms cubic-bezier(.16,1,.3,1) 320ms;
}
.meniu-panou.vazut .limbi.in-meniu{opacity:1;transform:none}
.meniu-panou .limbi.in-meniu summary{display:none}
.meniu-panou .limbi.in-meniu .limbi-lista{
  position:static;display:flex;flex-wrap:wrap;gap:2px;padding:0;border:0;
  background:none;backdrop-filter:none;-webkit-backdrop-filter:none;box-shadow:none;
}

@media (max-width:899px){
  .meniu-buton{display:block}
  /* Bara din antet pleaca in panou, ca sa nu fie in doua locuri deodata.
     Butonul de actiune ramane: e singurul lucru pentru care a venit omul. */
  .head .nav a:not(.cta),.antet .nav a:not(.cta){display:none}

  /* Comutatorul de limba RAMANE in antet, si pe telefon.
     Il ascunsesem in meniul lateral, iar fondatorul a incercat sa schimbe
     limba pe telefon si nu l-a gasit. Pe un site in sase limbi, aia e a doua
     functie ca importanta dupa butonul de actiune: cine aterizeaza pe versiunea
     gresita si nu vede cum sa treaca pe a lui, pleaca.
     Ca sa incapa langa logo si buton, aici e doar codul limbii, fara sageata,
     si cu chenar mai stramt. */
  .head .limbi,.antet .limbi{display:block;margin-left:auto;margin-right:var(--s2,8px)}
  .head .limbi summary,.antet .limbi summary{
    padding:0 10px;min-width:44px;justify-content:center;letter-spacing:.1em;
    font-size:11px;
  }
  .head .limbi summary::after,.antet .limbi summary::after{margin-left:5px;width:4px;height:4px}
  /* In panoul lateral nu mai are ce cauta, ar fi in doua locuri deodata. */
  .meniu-panou .limbi.in-meniu{display:none}
}
@media (min-width:900px){
  .meniu-buton,.meniu-panou,.meniu-val{display:none!important}
}
@media (prefers-reduced-motion:reduce){
  .meniu-panou,.meniu-lista a,.meniu-val,.limbi.in-meniu{transition:none!important}
}

/* ---------- sugestia de limba ----------
   Sus, discreta, se poate inchide. Nu acopera continutul si nu se intoarce. */
.sugestie{
  /* SUB antet, nu peste el. La 14 px de sus acoperea logo-ul si butonul de
     meniu, deci primul lucru pe care il facea sugestia era sa ascunda
     navigatia. Vazut pe captura, pe pagina germana. */
  position:fixed;left:50%;top:74px;translate:-50% 0;z-index:150;
  display:flex;align-items:center;gap:var(--s4,16px);
  padding:10px 12px 10px 16px;border-radius:999px;
  border:1px solid rgba(195,180,230,.22);
  background:color-mix(in srgb,var(--fond-2,#121019) 94%,transparent);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  box-shadow:0 18px 44px -14px rgba(0,0,0,.8);
  font-size:var(--t-sm,13px);color:var(--text-2,#A29CB5);
  opacity:0;transform:translateY(-10px);
  transition:opacity 420ms cubic-bezier(.16,1,.3,1),transform 420ms cubic-bezier(.16,1,.3,1);
  max-width:calc(100vw - 24px);
}
.sugestie.vazut{opacity:1;transform:none}
.sugestie a{color:var(--luciu,#C3B4E6);text-decoration:none;white-space:nowrap;
  min-height:44px;display:inline-flex;align-items:center}
.sugestie a:hover{text-decoration:underline;text-underline-offset:3px}
.sugestie-x{
  background:none;border:0;color:var(--text-3,#8A83A0);cursor:pointer;font:inherit;
  min-width:44px;min-height:44px;padding:0;line-height:1;
}
.sugestie-x:hover{color:var(--text,#EDEAF4)}
.sugestie a:focus-visible,.sugestie-x:focus-visible{outline:2px solid var(--luciu,#C3B4E6);outline-offset:2px;border-radius:6px}
@media (min-width:900px){ .sugestie{top:84px} }
@media (max-width:520px){
  .sugestie{left:12px;right:12px;top:68px;translate:none;gap:var(--s3,12px);padding:8px 8px 8px 14px;
    font-size:12.5px;justify-content:space-between}
  .sugestie span{min-width:0}
}

/* ---------- comutatorul de limba ---------- */
.limbi{position:relative;flex:none;margin-left:auto}
.limbi summary{
  list-style:none;cursor:pointer;user-select:none;
  font-family:var(--mono,monospace);font-size:var(--t-xs,11px);letter-spacing:.14em;
  color:var(--text-2,#A29CB5);min-height:44px;display:inline-flex;align-items:center;
  padding:0 var(--s3,12px);border:1px solid var(--linie,#272232);border-radius:var(--raza,10px);
  transition:color var(--cut,160ms ease),border-color var(--cut,160ms ease);
}
.limbi summary::-webkit-details-marker{display:none}
.limbi summary::after{content:"";width:5px;height:5px;margin-left:8px;
  border-right:1px solid currentColor;border-bottom:1px solid currentColor;
  transform:rotate(45deg) translateY(-1px);opacity:.6}
.limbi summary:hover{color:var(--text,#EDEAF4);border-color:var(--text-3,#8A83A0)}
.limbi summary:focus-visible{outline:2px solid var(--luciu,#C3B4E6);outline-offset:3px}
.limbi-lista{
  position:absolute;right:0;top:calc(100% + 6px);z-index:60;
  display:grid;grid-template-columns:repeat(2,minmax(56px,1fr));gap:2px;
  padding:6px;border:1px solid var(--linie,#272232);border-radius:var(--raza,10px);
  background:color-mix(in srgb,var(--fond,#0A0910) 96%,transparent);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  box-shadow:0 18px 40px -12px rgba(0,0,0,.8);
}
.limbi-lista a{
  font-family:var(--mono,monospace);font-size:var(--t-xs,11px);letter-spacing:.14em;
  color:var(--text-2,#A29CB5);text-decoration:none;text-align:center;
  min-height:40px;display:inline-flex;align-items:center;justify-content:center;
  border-radius:6px;transition:color var(--cut,160ms ease),background var(--cut,160ms ease);
}
.limbi-lista a:hover{color:var(--text,#EDEAF4);background:rgba(195,180,230,.10)}
.limbi-lista a[aria-current]{color:var(--luciu,#C3B4E6);background:rgba(195,180,230,.08)}
.limbi-lista a:focus-visible{outline:2px solid var(--luciu,#C3B4E6);outline-offset:-2px}

/* Pe ecran mare comutatorul e tot un sertar, nu un rand de sase coduri.
   Sase legaturi insirate in antet arata a lista de linkuri si mananca latime
   langa butonul de contact; un singur buton care coboara un panou e si mai
   linistit, si mai usor de gasit.

   `<details>` sta DESCHIS in HTML, ca sa se vada si fara JavaScript, si il
   inchide motorul la incarcare, pe orice latime. Motivul: continutul unui
   `<details>` inchis nu se randeaza, orice i-ai spune din CSS, iar pe asta am
   pierdut doua ture. */
@media (min-width:900px){
  .limbi{display:block;position:relative;margin-left:auto;flex:0 0 auto}
  .limbi summary{display:inline-flex}
  .limbi-lista{
    position:absolute;right:0;left:auto;top:calc(100% + 9px);bottom:auto;
    z-index:60;display:grid;grid-template-columns:1fr;gap:0;
    min-width:210px;padding:7px;
    border:1px solid var(--linie,#272232);border-radius:14px;
    background:color-mix(in srgb,var(--fond-2,#100E18) 97%,transparent);
    backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);
    box-shadow:0 24px 56px -18px rgba(0,0,0,.9);
    animation:limbi-coboara 280ms cubic-bezier(.16,1,.3,1) both;
    transform-origin:100% 0;max-height:none;overflow:visible;white-space:nowrap;
  }
  .limbi-lista::before,.limbi-lista::after{display:none}
  .limbi-lista a{
    min-height:42px;justify-content:flex-start;gap:13px;padding:0 11px;
    text-align:left;border-radius:9px;flex:none;
    border-bottom:1px solid color-mix(in srgb,var(--linie,#272232) 45%,transparent);
  }
  .limbi-lista a:last-child{border-bottom:0}
  /* Numele limbii, in limba ei. Codul ramane in fata, mic, ca reper. */
  .limbi-lista a::after{
    content:attr(title);font-family:var(--sans,system-ui);font-size:13.5px;
    letter-spacing:0;color:var(--text,#EDEAF4);font-weight:450;
  }
  .limbi-lista a[aria-current]{background:rgba(195,180,230,.07)}
  .limbi-lista a[aria-current]::after{color:var(--luciu,#C3B4E6)}
}

/* Pe telefon lista se deschidea ca un mic panou agatat sub eticheta, cu sase
   casute de 56 pe 40 px lipite doua cate doua. Mecanic functiona: am probat-o
   pe Chromium si pe WebKit, la 360 si la 390 px, si tapul chiar ducea pe pagina
   in romana. Numai ca fondatorul, pe telefonul lui, nu reusea s-o apese.
   Cauza nu e o eroare de cod, e marimea: 40 px inaltime sub un deget care
   acopera vreo 45, sase tinte alipite cu doi px intre ele, in coltul de sus al
   ecranului, unde degetul mare nici nu ajunge comod.

   Deci nu mai reparam panoul, il schimbam. Pe telefon limbile ies ca o foaie de
   jos: latime intreaga, sase randuri de 56 px, numele limbii scris intreg in
   limba ei, si o pinza intunecata peste rest care spune clar ca ai deschis ceva.
   Ajunge la degetul mare, nu se poate rata, si arata a produs, nu a meniu. */
@media (max-width:899px){
  /* Prima incercare a fost o foaie lipita de marginea de jos a ecranului.
     N-a mers, si motivul merita scris: antetul are `backdrop-filter`, iar un
     strămos cu backdrop-filter devine ancora pentru `position:fixed`. Foaia,
     nascuta in antet, se aseza pe marginea de jos A ANTETULUI, adica sus.
     Deci nu ne mai luptam cu asta: panoul coboara din antet, pe toata latimea,
     cu randuri de 56 px si numele limbii scris intreg. Ajunge in acelasi loc,
     e la fel de greu de ratat, si nu depinde de niciun context de stivuire. */
  /* `.limbi` e `position:relative`, deci un panou absolut in ea iesea lat de
     47 px, cat eticheta. Aici nu mai avem nevoie de ancora aia: panoul se
     agata de `.wrap`, care tine toata latimea antetului. */
  .limbi{position:static}
  .limbi-lista{
    position:absolute;left:0;right:0;top:calc(100% + 10px);
    grid-template-columns:1fr;gap:0;
    padding:6px 8px 8px;
    border:1px solid var(--linie,#272232);
    border-radius:var(--raza-mare,18px);
    background:color-mix(in srgb,var(--fond-2,#100E18) 98%,transparent);
    backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);
    box-shadow:0 26px 60px -18px rgba(0,0,0,.92);
    animation:limbi-coboara 300ms cubic-bezier(.16,1,.3,1) both;
    transform-origin:100% 0;
    max-height:calc(100vh - 140px);overflow-y:auto;overscroll-behavior:contain;
  }
  /* Pinza care intuneca pagina de sub panou, ca sa se citeasca drept ceva
     deschis peste, nu ca o bucata noua de pagina. */
  .limbi-lista::after{
    content:"";position:absolute;left:-50vw;right:-50vw;top:100%;height:100vh;
    background:linear-gradient(180deg,rgba(6,5,11,.72),rgba(6,5,11,.5) 40%,transparent);
    pointer-events:none;animation:limbi-pinza 300ms ease both;
  }
  .limbi-lista a{
    min-height:56px;justify-content:flex-start;gap:14px;padding:0 12px;
    text-align:left;border-radius:11px;font-size:11px;
    border-bottom:1px solid color-mix(in srgb,var(--linie,#272232) 55%,transparent);
  }
  .limbi-lista a:last-child{border-bottom:0}
  /* Numele limbii, in limba lui, luat din `title`. Codul ramane in fata, mic,
     ca reper. Cine cauta romana cauta "Romana", nu "RO". */
  .limbi-lista a::after{
    content:attr(title);font-family:var(--sans,system-ui);font-size:14.5px;
    letter-spacing:0;color:var(--text,#EDEAF4);font-weight:450;
  }
  .limbi-lista a[aria-current]{background:rgba(195,180,230,.07)}
  .limbi-lista a[aria-current]::after{color:var(--luciu,#C3B4E6)}
}
@keyframes limbi-coboara{from{opacity:0;transform:translateY(-8px) scale(.97)}to{opacity:1;transform:none}}
@keyframes limbi-pinza{from{opacity:0}to{opacity:1}}
@media (prefers-reduced-motion:reduce){
  .limbi-lista,.limbi-lista::after{animation-duration:1ms}
}


/* In cadru, antetul ar manca 56 din cele 520 de px ale demo-ului, ca sa arate
   un logo pe care omul tocmai l-a vazut pe pagina din jur. */
.in-cadru .head,.in-cadru .antet{display:none}

/* Marginea sub barbia iPhone-ului si sub coltul rotunjit. */
@supports(padding:max(0px)){
  .wrap{
    padding-left:max(var(--s5),env(safe-area-inset-left));
    padding-right:max(var(--s5),env(safe-area-inset-right));
  }
  body{padding-bottom:env(safe-area-inset-bottom)}
}

/* Degetul are nevoie de 44 px. Sub atat, omul apasa de doua ori si pleaca. */
@media (pointer:coarse){
  a,button,summary,[role="button"]{min-height:44px}
  a.lin,a.in-text{min-height:0}
}

/* ---------- cortina de intrare ----------
   Sta peste continutul deja randat si pleaca la `load`, dar nu mai tarziu de
   1,4 secunde. Un ecran de incarcare care asteapta la nesfarsit e cel mai
   scump bug de pe un site care vinde.

   Ce se vede: piatra are jar in miez, ca o lava care nu s-a racit inca de tot,
   si fum care se roteste in jurul ei. Obsidianul chiar asta e, lava racita
   brusc, deci povestea nu e decor: e chiar ce vinde numele firmei. Jarul se
   stinge in timp ce cortina se ridica.

   Totul din CSS, fara panza si fara particule. Trei elipse blurate care se
   rotesc incet arata ca fumul si costa nimic; o simulare de particule ar
   manca bateria exact in secunda in care omul asteapta pagina. */
.cortina{
  position:fixed;inset:0;z-index:900;background:var(--fond,#0A0910);
  display:grid;place-content:center;justify-items:center;gap:var(--s6,32px);
  transition:transform 780ms cubic-bezier(.76,0,.24,1),opacity 420ms ease 300ms;
  overflow:hidden;
}
.cortina[data-plecat]{transform:translateY(-100%);opacity:0;pointer-events:none}
.cortina[hidden]{display:none}

/* Fumul. Trei straturi, marimi si viteze diferite, doua intr-un sens si unul
   in celalalt: asa nu se citeste ca o singura forma care se invarte. */
.cortina .fum{
  position:absolute;left:50%;top:50%;pointer-events:none;
  width:min(560px,120vw);aspect-ratio:1;translate:-50% -50%;
  border-radius:50%;opacity:0;
  will-change:transform,opacity;
}
.cortina .fum:nth-of-type(1){
  background:radial-gradient(circle at 42% 44%,rgba(150,124,222,.20),transparent 58%),
             radial-gradient(circle at 62% 60%,rgba(96,84,150,.16),transparent 54%);
  filter:blur(46px);
  animation:mc-fum1 13s cubic-bezier(.4,0,.6,1) infinite, mc-fum-intra 1.6s ease-out .1s forwards;
}
.cortina .fum:nth-of-type(2){
  width:min(420px,96vw);
  background:radial-gradient(circle at 58% 40%,rgba(224,98,63,.13),transparent 52%),
             radial-gradient(circle at 40% 66%,rgba(126,106,186,.15),transparent 58%);
  filter:blur(38px);
  animation:mc-fum2 17s cubic-bezier(.4,0,.6,1) infinite, mc-fum-intra 1.8s ease-out .25s forwards;
}
.cortina .fum:nth-of-type(3){
  width:min(300px,72vw);
  background:radial-gradient(circle at 50% 54%,rgba(224,98,63,.10),transparent 46%);
  filter:blur(30px);
  animation:mc-fum1 9s cubic-bezier(.4,0,.6,1) infinite reverse, mc-fum-intra 1.4s ease-out .35s forwards;
}
@keyframes mc-fum-intra{to{opacity:1}}
@keyframes mc-fum1{
  0%  {transform:rotate(0deg)   scale(1)    translate(0,0)}
  33% {transform:rotate(48deg)  scale(1.14) translate(3%,-2%)}
  66% {transform:rotate(96deg)  scale(.94)  translate(-2%,3%)}
  100%{transform:rotate(144deg) scale(1)    translate(0,0)}
}
@keyframes mc-fum2{
  0%  {transform:rotate(0deg)    scale(1.06) translate(0,0)}
  50% {transform:rotate(-70deg)  scale(.9)   translate(-4%,2%)}
  100%{transform:rotate(-140deg) scale(1.06) translate(0,0)}
}

/* Jarul din miez. Sta SUB semn, deci lumineaza prin el si prin fum. */
.cortina .jar{
  position:absolute;left:50%;top:50%;translate:-50% -50%;pointer-events:none;
  width:min(190px,44vw);aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle,
    rgba(255,168,88,.62) 0%,
    rgba(224,98,63,.42) 22%,
    rgba(168,62,42,.20) 44%,
    transparent 66%);
  filter:blur(22px);
  opacity:0;
  animation:mc-jar-intra 1.1s ease-out .15s forwards, mc-jar 3.4s ease-in-out 1.2s infinite alternate;
}
@keyframes mc-jar-intra{to{opacity:1}}
@keyframes mc-jar{
  from{transform:scale(.92);opacity:.78}
  to  {transform:scale(1.1);opacity:1}
}
/* Cand cortina pleaca, jarul se stinge inaintea ei. Lava care se raceste. */
.cortina[data-plecat] .jar{animation:none;opacity:0;transform:scale(.7);
  transition:opacity 420ms ease,transform 620ms cubic-bezier(.4,0,.2,1)}
.cortina[data-plecat] .fum{animation-play-state:paused;opacity:0;transition:opacity 520ms ease}

.cortina .semn{
  position:relative;z-index:2;
  width:min(84px,22vw);height:auto;color:var(--luciu,#C3B4E6);
  opacity:0;
  animation:mc-creste 900ms cubic-bezier(.16,1,.3,1) .1s forwards,
            mc-glitch 4.2s steps(1,end) 1.5s infinite;
  /* Muchia calda pe care o are o piatra care tocmai s-a racit. */
  filter:drop-shadow(0 0 18px rgba(224,98,63,.30)) drop-shadow(0 2px 6px rgba(0,0,0,.6));
}

/* Glitch-ul. RAR si SCURT: doua zvacniri de cate 60 de milisecunde intr-un
   ciclu de patru secunde, restul timpului piatra sta perfect.
   Aici se decide daca arata a semnal care se pierde o clipa sau a bannere din
   2014. Trei reguli:
     - se intampla de doua ori, nu incontinuu
     - deplasarea e de 2 px, nu de 20
     - despicarea de culoare e un contur subtire, nu un curcubeu
   `steps(1,end)` face saritura instantanee: un glitch care se interpoleaza
   lin nu mai e glitch, e o alunecare. */
@keyframes mc-glitch{
  0%,   40%  {transform:none;filter:drop-shadow(0 0 18px rgba(224,98,63,.30)) drop-shadow(0 2px 6px rgba(0,0,0,.6))}
  41%        {transform:translate3d(-2px,1px,0) skewX(-1.5deg);
              filter:drop-shadow(2px 0 0 rgba(224,98,63,.55)) drop-shadow(-2px 0 0 rgba(120,190,255,.35))}
  42.5%      {transform:translate3d(2px,-1px,0) skewX(1deg);
              filter:drop-shadow(-2px 0 0 rgba(224,98,63,.5)) drop-shadow(2px 0 0 rgba(150,124,222,.4))}
  44%,  71%  {transform:none;filter:drop-shadow(0 0 18px rgba(224,98,63,.30)) drop-shadow(0 2px 6px rgba(0,0,0,.6))}
  72%        {transform:translate3d(1px,-2px,0);
              filter:drop-shadow(-1px 0 0 rgba(224,98,63,.6)) drop-shadow(1px 0 0 rgba(120,190,255,.3))}
  73.5%,100% {transform:none;filter:drop-shadow(0 0 18px rgba(224,98,63,.30)) drop-shadow(0 2px 6px rgba(0,0,0,.6))}
}
/* Prima pagina are in cortina o panza cu animatia ei, nu semnul. Primeste
   aceeasi asezare: jarul si fumul stau in spatele ei, nu langa. */
.cortina canvas{
  position:relative;z-index:2;
  width:min(220px,48vw);height:auto;display:block;
  filter:drop-shadow(0 0 22px rgba(224,98,63,.26));
  animation:mc-glitch-panza 5.6s steps(1,end) 2.2s infinite;
}
/* Pe panza glitch-ul e si mai discret: acolo se roteste deja o piatra, iar
   doua miscari deodata se citesc ca stricaciune, nu ca stil. */
@keyframes mc-glitch-panza{
  0%,   62%  {transform:none;opacity:1}
  63%        {transform:translate3d(-3px,0,0);opacity:.86}
  64.2%      {transform:translate3d(2px,1px,0);opacity:1}
  65.4%,100% {transform:none;opacity:1}
}
.cortina .semnatura{
  position:relative;z-index:2;
  font-family:var(--mono,monospace);font-size:var(--t-xs,11px);letter-spacing:.28em;
  text-transform:uppercase;color:var(--text-3,#8A83A0);
  opacity:0;animation:mc-iese 800ms cubic-bezier(.16,1,.3,1) .75s forwards;
}
.cortina .fir{position:relative;z-index:2;width:112px;height:1px;
  background:var(--linie,#272232);overflow:hidden}
.cortina .fir::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,var(--luciu,#C3B4E6),rgba(224,98,63,.9));
  transform:translateX(-100%);animation:mc-treci 1.15s cubic-bezier(.5,0,.2,1) .3s forwards;
}
@keyframes mc-iese{from{opacity:0;transform:translateY(9px)}to{opacity:1;transform:none}}
@keyframes mc-treci{to{transform:translateX(100%)}}
@keyframes mc-creste{from{opacity:0;transform:scale(.82) rotate(-8deg)}to{opacity:1;transform:none}}

/* ---------- firul de progres ----------
   O linie de un pixel sub antet, care arata cat a mai ramas. Costa nimic si
   spune omului ca pagina are un capat. */
.progres{
  position:fixed;top:0;left:0;height:2px;z-index:120;
  background:linear-gradient(90deg,transparent,var(--luciu,#C3B4E6));
  width:0;pointer-events:none;
  box-shadow:0 0 12px rgba(195,180,230,.5);
}

/* ---------- dezvaluirea la derulare ----------
   Starea de plecare traieste sub `.js`, deci fara JavaScript pagina e
   completa si citibila. Copiii unui `[data-intra]` pleaca decalat: asta e
   diferenta dintre "un bloc apare" si "ceva se aseaza". */
.js [data-intra]{opacity:0;transform:translateY(26px);filter:blur(6px)}
.js [data-intra][data-intra="stanga"]{transform:translateX(-30px)}
.js [data-intra][data-intra="dreapta"]{transform:translateX(30px)}
.js [data-intra][data-intra="scara"]{transform:scale(.94);filter:blur(9px)}
.js [data-intra].vazut{
  opacity:1;transform:none;filter:blur(0);
  transition:opacity 760ms cubic-bezier(.16,1,.3,1),
             transform 900ms cubic-bezier(.16,1,.3,1),
             filter 620ms ease-out;
  transition-delay:var(--intarziere,0ms);
}

/* Titlul care se ridica din masca, rand cu rand.
   `inline-block`, NU `block`: altfel fiecare cuvant cade pe randul lui.
   Padding plus margine negativa ca `overflow:hidden` sa nu taie coada
   literelor care coboara sub linie (g, y, p). */
.js .linie-titlu{display:inline-block;overflow:hidden;vertical-align:top;
  padding-bottom:.14em;margin-bottom:-.14em}
.js .linie-titlu>span{display:block;transform:translateY(110%);
  transition:transform 1000ms cubic-bezier(.16,1,.3,1);transition-delay:var(--intarziere,0ms)}
.js .linie-titlu.vazut>span{transform:none}

/* ---------- haloul de sub buton ----------
   Un `box-shadow` colorat arata plat, pentru ca umbra are muchie. Haloul
   adevarat e un element in spate, dilatat si neclar, care nu are muchie. */
.lumina{position:relative;isolation:isolate}
.lumina::before{
  content:"";position:absolute;inset:-6px;z-index:-1;
  border-radius:calc(var(--raza,10px) + 6px);
  background:radial-gradient(60% 120% at 50% 0%,var(--halou,rgba(195,180,230,.85)),transparent 72%);
  filter:blur(16px);opacity:0;transform:scale(.86);
  transition:opacity 320ms var(--cut,160ms ease),transform 320ms var(--cut,160ms ease);
  pointer-events:none;
}
.lumina:hover::before,.lumina:focus-visible::before{opacity:.9;transform:scale(1)}

/* ---------- cardul care se inclina spre cursor ----------
   Doar pe mouse. Pe deget ar face pagina sa para stricata. Unghiul e mic
   dinadins: peste 6 grade se citeste ca jucarie de portofoliu. */
@media (hover:hover) and (pointer:fine){
  .inclina{transition:transform 420ms cubic-bezier(.16,1,.3,1);transform-style:preserve-3d;will-change:transform}
  .inclina:hover{transition-duration:120ms}
}

/* ---------- trecerea intre pagini ----------
   Blur de miscare, dar DOAR pe durata trecerii. Un blur permanent ar aduce
   inapoi exact saltul de care am scapat: e cel mai scump efect de pe placa
   video. Aici traieste 420 ms si dispare complet. */
@view-transition{navigation:auto}
::view-transition-old(root){animation:mc-pleaca 380ms cubic-bezier(.5,0,.75,0) both}
::view-transition-new(root){animation:mc-vine 420ms cubic-bezier(.25,1,.5,1) both}
@keyframes mc-pleaca{
  from{opacity:1;filter:blur(0);transform:scale(1)}
  to{opacity:0;filter:blur(10px);transform:scale(.985)}
}
@keyframes mc-vine{
  from{opacity:0;filter:blur(12px);transform:scale(1.012)}
  to{opacity:1;filter:blur(0);transform:scale(1)}
}
/* Pentru browserele fara View Transitions, acelasi efect pus de mana. */
body.pleaca{animation:mc-pleaca 380ms cubic-bezier(.5,0,.75,0) both}

/* ---------- totul se opreste, cu continutul la locul lui ---------- */
@media (prefers-reduced-motion:reduce){
  *{animation:none!important;transition:none!important}
  .cortina{display:none}
  .cortina .fum,.cortina .jar{animation:none;opacity:.5}
  .cortina .semn,.cortina canvas{animation:none}
  .js [data-intra]{opacity:1!important;transform:none!important;filter:none!important}
  .js .linie-titlu>span{transform:none!important}
  ::view-transition-old(root),::view-transition-new(root),body.pleaca{animation:none}
  .progres{display:none}
}

/* Datele de firma care inca nu exista. Se scriu, nu se lasa goale si nu se
   inventeaza. Un camp gol intr-un Impressum pare uitat; un numar inventat e
   chiar incalcarea pe care scanerul nostru o raporteaza altora. */
.in-curs{
  font-style:italic;color:var(--text-3,#8A83A0);
  border-bottom:1px dotted rgba(195,180,230,.3);
}


/* ---------- antetul pe telefon ----------
   Pragul era 379 px, si era gresit. Pe orice telefon obisnuit antetul cerea
   mai mult decat ecranul: 411 px pe engleza, 435 pe romana si 482 pe germana,
   pe un ecran de 390. Pe germana meniul iesea complet in afara, iar pagina se
   clatina pe orizontala. Se vede doar cand masori fiecare limba, nu doar
   engleza. Prins de auditul vizual.

   Butonul de actiune pleaca in meniu incepand de la 720, unde e oricum, si mai
   e o data si in bara de jos. Raman trei lucruri in antet: logo, limba, meniu. */
@media (max-width:720px){
  .head .nav .cta,.antet .nav .cta{display:none}
  /* Butonul de meniu peste panou, altfel "inchide" ramane dedesubt si nu se
     poate apasa: panoul e la 200, butonul avea z-index automat. */
  .meniu-buton{position:relative;z-index:210}
}
@media (max-width:379px){
  /* Bara de degete are trei lucruri: pietricica, preturile si verificarea.
     La 320 nu incap, iar browserul micsoreaza toata pagina cu 8% ca sa le faca
     loc. Textul se strange, nu dispare nimic. */
  /* La 320 raman doua: pietricica si actiunea principala. "See prices" pleaca,
     e la o derulare distanta si e in meniu. In germana si romana textele sunt
     cu 30% mai lungi decat in engleza, deci acolo se rupea prima. */
  .bara-jos{gap:6px;padding-left:8px;padding-right:8px;grid-template-columns:44px 1fr}
  .bara-jos a.gol{display:none}
  .bara-jos a{font-size:12px;padding-left:8px;padding-right:8px;white-space:nowrap}
  /* Antetul peretelui e alt markup si nu prinde regulile de mai sus. */
  .head{flex-wrap:nowrap;gap:6px}
  .head .mark .word{max-width:38vw}
  .head .wrap,.antet{gap:8px}
  .marca span,.mark span{font-size:10.5px;letter-spacing:.14em}
  /* Iesea 43 px lat la 360, cu un px sub pragul degetului. Nu se vede
     diferenta, dar se simte: rateaza o data din trei. */
  .limbi summary{padding:0 7px;min-width:44px;font-size:10px;justify-content:center}
  .meniu-buton{margin-left:4px}
  .inapoi{font-size:12px;padding:0 11px;gap:6px}
}
/* Piatra nu are voie sa largeasca pagina: e fundal, deci se taie la marginea
   sectiunii, nu impinge ecranul. */
.hero{overflow-x:clip}


/* ---------- piatra din ecranul de incarcare ----------
   Aceeasi piatra ca pe pagina, copiata cadru cu cadru de motor. Semnul plat
   ramane ca rezerva, pentru paginile care nu au piatra (portofoliu, legale) si
   pentru cazul in care JavaScript-ul nu ruleaza. */
.cortina .piatra-mica{
  position:relative;z-index:2;width:min(190px,44vw);height:auto;display:block;
  filter:drop-shadow(0 0 26px rgba(224,98,63,.22));
}
/* Cand exista piatra, semnul de rezerva nu se mai vede. */
.cortina:has(.piatra-mica) .semn.de-rezerva{display:none}
/* Fara `:has`, sau fara piatra pe pagina, ramane semnul. */
@supports not selector(:has(*)){ .cortina .piatra-mica{display:none} }

/* Punctul portocaliu de langa eticheta a fost scos: un punct care pulseaza
   langa un cuvant e semnul cel mai des intalnit al paginilor facute repede,
   si il recunoaste oricine. Eticheta ramane, ca specimen de muzeu. */
.piatra .eticheta::before{display:none}
.piatra .eticheta{gap:0}


/* Antetul nu taie continutul lui. Legatura "Back" sta pe marginea din dreapta
   si era retezata cand antetul avea `overflow` inchis. */
.head,.antet,.head .wrap,.antet .wrap{overflow:visible}
.head .ecou,.antet .ecou{display:none}
/* Si are aer la dreapta, ca legatura sa nu atinga muchia ecranului. */
.head .wrap,.antet{padding-right:max(var(--s5,24px),env(safe-area-inset-right))}

/* Pastila "Ask the stone" sta DEASUPRA barei de degete: la acelasi z-index,
   bara castiga fiindca vine mai tarziu in pagina, si atingerea ajungea la ea. */
.piatra .atinge{z-index:130}


/* ---------- titlurile care se racesc ----------
   Fiecare cuvant intra de jos, aprins, si se stinge in alb. Se anima `opacity`,
   `transform` si `color`: primele doua sunt compuse pe placa video, a treia e
   o singura interpolare pe un text scurt, care se intampla o data. Zero
   `filter`, deci zero cadre pierdute. */
[data-raceste] .cuv{
  display:inline-block;
  opacity:0;transform:translateY(.34em) scale(.985);
  color:#FF9A4E;
  text-shadow:0 0 22px rgba(255,140,60,.5);
  will-change:opacity,transform;
}
[data-raceste].racit .cuv{
  animation:cuvant-se-raceste 900ms cubic-bezier(.16,1,.3,1) var(--pas,0ms) both;
}
@keyframes cuvant-se-raceste{
  0%  {opacity:0;transform:translateY(.34em) scale(.985);
       color:#FFB877;text-shadow:0 0 26px rgba(255,150,70,.62)}
  38% {opacity:1;transform:translateY(0) scale(1);
       color:#FF9A4E;text-shadow:0 0 18px rgba(255,140,60,.42)}
  100%{opacity:1;transform:none;
       color:inherit;text-shadow:none}
}
/* Fara JavaScript, sau cu miscarea oprita, titlul e pur si simplu acolo. */
html:not(.js) [data-raceste] .cuv{opacity:1;transform:none;color:inherit;text-shadow:none}
@media (prefers-reduced-motion:reduce){
  [data-raceste] .cuv,[data-raceste].racit .cuv{
    animation:none;opacity:1;transform:none;color:inherit;text-shadow:none}
}


/* ---------- butonul de sunet ----------
   Trei dungi care stau pe loc cat e oprit si respira cand canta. Nu e o
   pictograma de difuzor: aia se citeste ca "video", si aici nu e video.
   Sta langa comutatorul de limba, la fel de discret. */
.sunet{
  /* Dungile se aliniaza pe mijloc, nu pe fundul butonului: cu `flex-end` stateau
     lipite de marginea de jos si butonul parea gol in partea de sus. */
  flex:none;display:inline-flex;align-items:center;gap:3px;
  height:44px;min-width:44px;padding:0 12px;margin-left:var(--s3,12px);
  background:transparent;border:1px solid var(--linie,#272232);
  border-radius:var(--raza,10px);cursor:pointer;
  transition:border-color var(--cut,160ms ease),background var(--cut,160ms ease);
}
.sunet:hover{border-color:var(--text-3,#8A83A0)}
.sunet:focus-visible{outline:2px solid var(--luciu,#C3B4E6);outline-offset:3px}
.sunet i{
  /* Inaltime FIXA, iar miscarea se face din `scaleY`. Animarea lui `height`
     obliga browserul sa reaseze antetul de 120 de ori pe secunda cat canta
     sunetul, iar antetul are `backdrop-filter`, deci fiecare reasezare costa
     dublu: 598 de asezari pe secunda, masurate de audit, fata de zero in repaus. */
  display:block;width:2px;height:16px;border-radius:2px;
  background:var(--text-3,#8A83A0);
  transform:scaleY(.44);transform-origin:50% 50%;
  transition:transform 260ms cubic-bezier(.16,1,.3,1),background 260ms ease;
  will-change:transform;
}
.sunet i:nth-child(2){transform:scaleY(.69)}
.sunet.canta{border-color:rgba(255,140,60,.3);background:rgba(255,140,60,.05)}
.sunet.canta i{background:#F0A464}
.sunet.canta i:nth-child(1){animation:sunet-1 1.35s ease-in-out infinite alternate}
.sunet.canta i:nth-child(2){animation:sunet-2 .95s ease-in-out infinite alternate}
.sunet.canta i:nth-child(3){animation:sunet-3 1.7s ease-in-out infinite alternate}
@keyframes sunet-1{from{transform:scaleY(.31)}to{transform:scaleY(.88)}}
@keyframes sunet-2{from{transform:scaleY(.81)}to{transform:scaleY(.38)}}
@keyframes sunet-3{from{transform:scaleY(.5)}to{transform:scaleY(1)}}
@media (max-width:720px){ .sunet{padding:0 8px;margin-left:6px;min-width:38px} }
@media (prefers-reduced-motion:reduce){ .sunet{display:none} }


/* ---------- lumina de pe fatete ----------
   O pata pre-pictata care se plimba pe card sub cursor. Se muta cu `translate`,
   deci e un strat compus pe placa video: gradientul se deseneaza o data, la
   incarcare, si nu se mai recalculeaza niciodata.

   Foarte slaba dinadins. Trebuie sa se simta ca suprafata prinde lumina cand
   te apropii, nu sa se vada ca ai trecut cu o lanterna. Daca o observi ca
   efect, e prea tare. */
/* Pata sta intr-un strat care o taie la marginea cardului, iar CARDUL ramane
   liber. Prima varianta punea `overflow:clip` pe card si retezа eticheta
   "Recommended", care iese dinadins deasupra marginii de sus. Prins de
   fondator pe captura. */
.fatet{
  position:absolute;inset:0;pointer-events:none;z-index:0;
  overflow:hidden;border-radius:inherit;
  opacity:0;transition:opacity 420ms cubic-bezier(.16,1,.3,1);
}
.fatet::before{
  content:"";position:absolute;left:50%;top:50%;
  width:420px;height:420px;margin:-210px 0 0 -210px;border-radius:50%;
  background:radial-gradient(circle,
    rgba(255,150,70,.085) 0%, rgba(255,140,60,.045) 34%, transparent 68%);
  transform:translate3d(var(--fx,0px),var(--fy,0px),0);
  will-change:transform;
}
.lucios > .fatet{opacity:1}
/* Cardurile au deja `isolation:isolate`, deci pata sta sub continut fara sa
   ceara z-index pe fiecare copil. */
.pachet > .fatet,.lucrare > .fatet,.produs > .fatet{z-index:0}
@media (hover:none),(pointer:coarse),(prefers-reduced-motion:reduce){
  .fatet{display:none}
}


/* Bara de sugestie a limbii statea fixa pe toate cele douazeci de ecrane si
   acoperea titlul, prima intrebare din FAQ, si impreuna cu antetul si bara de
   jos manca 196 din 844 px. Are un singur rost: sa fie vazuta la inceput.
   Dupa prima derulare adevarata, se retrage. */
body.a-derulat .sugestie{opacity:0;pointer-events:none;transform:translateY(-8px)}
.sugestie{transition:opacity 420ms cubic-bezier(.16,1,.3,1),transform 420ms cubic-bezier(.16,1,.3,1)}

/* Starea de APASAT. Pe telefon nu exista hover, deci fara ea nimic nu raspunde
   la deget si totul pare mort. O regula pentru tot ce se apasa. */
.pachet .ia:active,.demo:active,.chemare:active,.sag:active,.sug:active,
.bara-jos a:active,.usa a:active,.produs .deschide:active,.deschide:active,
.limbi-lista a:active,.inapoi:active,.sunet:active{
  transform:scale(.985);transition-duration:80ms;
}

/* Antetul lipicios lasa continutul sa se citeasca prin el. */
.head,.antet{background:color-mix(in srgb,var(--fond,#0A0910) 94%,transparent)}

/* Etichetele mici erau la 9 px pe telefon: prea mic pentru un text care chiar
   se citeste. Prag: 11 px pentru eticheta, 12 pentru kicker. */
@media (max-width:760px){
  .mini-et,.eticheta-pachet,.eticheta{font-size:11px}
  .kicker{font-size:12px}
}
