/* ==========================================================================
   KcalExpose — startsidan (site/index.html)
   ==========================================================================

   BÄRANDE GREPP: vita rundade PANELER (.shell) som flyter på en tonad
   sidbakgrund, med luft emellan — inte band som går kant i kant. Det är det
   som håller ihop sidan och gör att den läser som en produkt i stället för en
   staplad mall. Allt annat (typografi, kort, knappar) hänger på det.

   1.  Tokens och bas
   2.  Paneler och rubrikblock
   3.  Knappar
   4.  Sidhuvud och navigering
   4b. Inloggningsrutan (sidhuvudet + streak-kortet öppnar samma ruta)
   5.  Hero: scen, telefon, robotyta
   6.  Smartare spårning: robot, flöde, kort
   7.  Funktionsblock
   8.  Integritet och ärlighet
   9.  Nedladdningspanel
   10. FAQ och support
   11. Sidfot
   12. Fokus, rörelse, utskrift

   TVÅ SAKER SOM MÅSTE HÅLLAS I SYNK MED assets/policy.css:

   a) TOKENBLOCKET i :root nedan är kopierat därifrån (som i sin tur kopierat
      det ur appens www/style.css). Ändras en grön färg på ett ställe måste den
      ändras på alla tre. De delar MEDVETET inte fil: policy.css är 27 kB
      juridiksideslayout som startsidan inte har någon nytta av.

   b) ALLTID LJUST LÄGE. color-scheme: light krävs utöver färgerna, annars
      ritas rullningslister i mörk stil på en mörkt inställd dator. Lägg inte
      tillbaka något @media (prefers-color-scheme: dark)-block.

   Inga webbfonter: CSP:n (site/_headers) har ingen font-src och faller till
   default-src 'self'. Systemstacken ger dessutom SF Pro på Apple-enheter.
   ========================================================================== */


/* ==========================================================================
   1. TOKENS OCH BAS
   ========================================================================== */
:root {
  color-scheme: light;

  /* Appens gröna (www/style.css :root, via assets/policy.css) */
  --kx-green:       #51CA7B;
  --kx-green-light: #68D990;
  --kx-green-deep:  #49BE73;
  /* Mörkare grön för text och länkar — AA mot vitt (~5,2:1). Appens --green
     är för ljus för brödtextsstorlek och används bara som yta/accent. */
  --kx-green-ink:   #1a7f4b;

  /* Appens premiumgradient, oförändrad (www/style.css --premium-green-gradient) */
  --kx-premium:
    radial-gradient(ellipse at 12% 8%,
      rgba(150, 235, 174, 0.26) 0%,
      rgba(112, 215, 150, 0.16) 42%,
      rgba(112, 215, 150, 0) 76%),
    radial-gradient(ellipse at 88% 86%,
      rgba(130, 226, 170, 0.22) 0%,
      rgba(92, 202, 140, 0.14) 46%,
      rgba(92, 202, 140, 0) 82%),
    linear-gradient(135deg,
      #63D98D 0%, #5AD283 24%, #51CA7B 48%, #49BE73 72%, #68D990 100%);

  --kx-ink:    #0f1115;
  --kx-body:   #2b313b;
  --kx-soft:   #5b6472;
  --kx-line:   rgba(15, 17, 21, 0.08);
  --kx-hair:   rgba(15, 17, 21, 0.06);

  --kx-ease-out:   cubic-bezier(0.16, 1, 0.3, 1);
  --kx-ease-glide: cubic-bezier(0.32, 0.72, 0, 1);

  --kx-head-h: 4.25rem;

  /* --- Startsidans egna --------------------------------------------------- */

  /* Sidbakgrunden. Svagt mintgrå så att de vita panelerna får en kant att
     lysa mot — på rent vitt försvinner hela panelidén. */
  --kx-page:      #EFF4F1;
  --kx-mint:      #F4FBF7;
  --kx-mint-deep: #EAF6EF;

  --r-sm:   12px;
  --r-md:   18px;
  --r-lg:   24px;
  --r-xl:   34px;   /* panelradie */
  --r-pill: 999px;

  --sh-sm:    0 1px 2px rgba(15, 17, 21, 0.04);
  --sh-card:  0 1px 2px rgba(15, 17, 21, 0.04), 0 12px 28px -18px rgba(15, 17, 21, 0.18);
  --sh-shell: 0 1px 2px rgba(15, 17, 21, 0.04), 0 40px 80px -52px rgba(15, 17, 21, 0.30);
  --sh-green: 0 12px 28px rgba(81, 202, 123, 0.32);

  --w-max:   84rem;   /* panelernas yttermått */
  --w-prose: 42rem;
  --gutter:  clamp(1.15rem, 0.6rem + 1.6vw, 2.75rem);

  --shell-y: clamp(3.25rem, 2rem + 4.4vw, 6rem);
  --shell-gap: clamp(0.75rem, 0.4rem + 1.1vw, 1.5rem);
}

* { box-sizing: border-box; }

/* hidden-attributet måste vinna. Webbläsarens egen regel är `display: none` med
   noll specificitet, så vilken egen `display` som helst på ett element eller en
   klass slår ut den — och elementet syns fast markupen säger motsatsen. Det
   bränner varje gång ett tillstånd döljs med hidden i stället för en klass. */
[hidden] { display: none !important; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--kx-head-h) + 1rem);
  background: var(--kx-page);
}

body {
  margin: 0;
  padding: 0 var(--shell-gap) var(--shell-gap);
  font: 16px/1.65 -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  color: var(--kx-body);
  background: var(--kx-page);
  -webkit-text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
  /* Dekorlager sticker medvetet utanför sina föräldrar. */
  overflow-x: hidden;
}
/* clip klipper likadant men skapar INGEN rullningsbehållare. Skillnaden är
   avgörande: overflow-x: hidden på <body> gör kroppen till scrollport, och då
   får position: sticky ingenting att klistra sig mot — det klistrade
   kontaktkortet i hjälppanelen slutar följa med. hidden ligger kvar som
   fallback för webbläsare utan clip (Safari < 16), där kortet i stället bara
   rullar med sidan. Ingen av dem får bytas mot `visible`: dekorlagren skulle
   ge en vågrät rullningslist. */
@supports (overflow-x: clip) {
  body { overflow-x: clip; }
}

h1, h2, h3 { color: var(--kx-ink); margin: 0; text-wrap: balance; }

h1 {
  /* Låg vw-faktor med flit: hjältens textspalt är bara ~430 px vid 1024, och
     en brantare kurva gav en 59 px-rubrik som bröt i fyra rader där. */
  font-size: clamp(2.3rem, 1.75rem + 2.4vw, 4rem);
  line-height: 1.03;
  letter-spacing: -0.042em;
  font-weight: 800;
}
h2 {
  font-size: clamp(1.8rem, 1.28rem + 2.1vw, 2.9rem);
  line-height: 1.08;
  letter-spacing: -0.036em;
  font-weight: 800;
}
h3 {
  font-size: 1.16rem;
  line-height: 1.32;
  letter-spacing: -0.015em;
  font-weight: 750;
}

/* Den gröna frasen i rubrikerna. <em> för att den bär betoning, inte kursiv. */
h1 em, h2 em, h3 em {
  font-style: normal;
  color: var(--kx-green-deep);
}

p { margin: 0 0 1rem; }
p:last-child { margin-bottom: 0; }

a { color: var(--kx-green-ink); }
strong { color: var(--kx-ink); font-weight: 700; }

img, svg { max-width: 100%; }
img { height: auto; display: block; }

ul, ol { margin: 0; padding: 0; list-style: none; }

.skip {
  position: fixed;
  top: 0.75rem;
  left: 0.75rem;
  z-index: 100;
  padding: 0.7rem 1.05rem;
  border-radius: var(--r-sm);
  background: var(--kx-ink);
  color: #fff;
  font-weight: 650;
  text-decoration: none;
  transform: translateY(-180%);
  transition: transform 0.22s var(--kx-ease-out);
}
.skip:focus-visible { transform: translateY(0); }


/* ==========================================================================
   2. PANELER OCH RUBRIKBLOCK
   ========================================================================== */
.shell {
  position: relative;
  max-width: var(--w-max);
  margin: 0 auto var(--shell-gap);
  padding: var(--shell-y) var(--gutter);
  border: 1px solid rgba(15, 17, 21, 0.055);
  border-radius: var(--r-xl);
  background: #fff;
  box-shadow: var(--sh-shell);
  /* Auroralagren målar utanför panelens kant om de inte klipps. */
  overflow: hidden;
  isolation: isolate;
}

.section-head { max-width: 46rem; margin-bottom: clamp(2.25rem, 1.4rem + 2.6vw, 3.5rem); }
.section-head h2 { margin-bottom: 0.9rem; }

.section-lede {
  font-size: clamp(1.02rem, 0.97rem + 0.3vw, 1.18rem);
  line-height: 1.62;
  color: var(--kx-soft);
  max-width: 38rem;
}

/* Mjukt mintljus. Ett återkommande lager i flera paneler — alltid dekor,
   alltid aria-hidden, alltid bakom innehållet. */
.hero-aurora, .smart-aurora, .priv-aurora, .cta-aurora, .feat-aurora,
.help-aurora {
  position: absolute;
  z-index: -1;
  pointer-events: none;
}


/* ==========================================================================
   3. KNAPPAR
   ========================================================================== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 0.85rem 1.35rem;
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  font: inherit;
  font-weight: 650;
  line-height: 1.15;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: transform 0.22s var(--kx-ease-out),
              box-shadow 0.25s var(--kx-ease-out),
              border-color 0.2s var(--kx-ease-out);
}
a.btn:active { transform: scale(0.97); }

/* Primär: appens premiumgradient. Vit text på den gröna är ett medvetet
   varumärkesval (samma som i appen) — mörka inte ned den för kontrastens skull. */
.btn-store {
  background: var(--kx-premium);
  color: #fff;
  box-shadow: var(--sh-green);
  padding: 0.7rem 1.4rem;
}
/* Långsam ljusstrimma över knappen. Går EN gång var åttonde sekund och tar
   1,4 s — resten av tiden är den helt stilla. En strimma som går hela tiden
   blir en blinkande reklamskylt; den här ska bara antyda att ytan är blank.
   overflow: hidden på .btn-store krävs, annars svischar den utanför pillret. */
@keyframes storeSheen {
  0%, 82%  { transform: translateX(-140%) skewX(-18deg); }
  100%     { transform: translateX(240%)  skewX(-18deg); }
}
/* BARA de stora knapparna (hjälten och #get). Den lilla i sidhuvudet är alltid
   synlig medan man läser — en strimma som återkommer där blir rastlös. */
.btn-store { position: relative; }
.btn-store.btn-lg { overflow: hidden; }
.btn-store.btn-lg::after {
  content: "";
  position: absolute;
  top: -30%;
  bottom: -30%;
  left: 0;
  width: 32%;
  pointer-events: none;
  background: linear-gradient(100deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.34) 50%,
    rgba(255, 255, 255, 0) 100%);
  animation: storeSheen 8s ease-in-out infinite;
}
/* Knappens innehåll måste ligga över strimman. */
.btn-store > * { position: relative; z-index: 1; }

.btn-store-lines { display: flex; flex-direction: column; align-items: flex-start; }
.btn-store-lines small {
  font-size: 0.7rem;
  font-weight: 600;
  opacity: 0.92;
  line-height: 1.2;
}
.btn-store-lines strong {
  color: #fff;
  font-size: 1.06rem;
  font-weight: 750;
  letter-spacing: -0.015em;
  line-height: 1.2;
}
.btn-glyph { width: 22px; height: 22px; flex: none; }

/* Förlanseringsläget. Knappen är ett <span> — det finns inget att aktivera
   förrän App Store-länken finns, och en låtsaslänk till ingenstans är sämre än
   en ärlig etikett. Se STORE-URL-kommentaren i index.html. */
.btn-store.is-soon { cursor: default; box-shadow: 0 10px 24px rgba(81, 202, 123, 0.26); }
/* I rubrikraden dämpas glöden — en stor grön sky under en klistrad rad ser ut
   som ett renderingsfel. Gäller varje knapp i .nav-cta, oavsett variant. */
.nav-cta .btn { box-shadow: 0 4px 12px rgba(81, 202, 123, 0.22); }
.nav-cta .btn:hover { box-shadow: 0 8px 20px rgba(81, 202, 123, 0.3); }

.btn-sm { padding: 0.5rem 0.95rem; }
.btn-sm .btn-store-lines small { font-size: 0.62rem; }
.btn-sm .btn-store-lines strong { font-size: 0.9rem; }

.btn-lg { padding: 0.95rem 1.9rem; }
.btn-lg .btn-store-lines small { font-size: 0.76rem; }
.btn-lg .btn-store-lines strong { font-size: 1.2rem; }
.btn-lg .btn-glyph { width: 26px; height: 26px; }

.btn-ghost {
  background: #fff;
  color: var(--kx-ink);
  border-color: var(--kx-line);
  box-shadow: var(--sh-sm);
}
.btn-ghost:hover { border-color: rgba(81, 202, 123, 0.42); box-shadow: 0 6px 18px rgba(81, 202, 123, 0.14); }

.btn-solid {
  background: var(--kx-premium);
  color: #fff;
  box-shadow: var(--sh-green);
}
.btn-solid:hover { box-shadow: 0 16px 34px rgba(81, 202, 123, 0.38); }


/* ==========================================================================
   4. SIDHUVUD OCH NAVIGERING
   Genomskinligt i toppläget så att det sitter "i" hjältepanelen, frostat
   flytande band när sidan rullat (.is-stuck sätts av site.js).
   ========================================================================== */
.site-head {
  position: sticky;
  top: 0;
  z-index: 40;
  margin: 0 calc(var(--shell-gap) * -1);
  padding: 0 var(--shell-gap);
  background: transparent;
  transition: background-color 0.28s var(--kx-ease-out), box-shadow 0.28s var(--kx-ease-out);
}
.site-head.is-stuck {
  background: rgba(255, 255, 255, 0.82);
  backdrop-filter: saturate(180%) blur(18px);
  -webkit-backdrop-filter: saturate(180%) blur(18px);
  box-shadow: 0 1px 0 rgba(15, 17, 21, 0.06), 0 14px 30px -24px rgba(15, 17, 21, 0.3);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .site-head.is-stuck { background: rgba(255, 255, 255, 0.97); }
}

.site-head-inner {
  max-width: var(--w-max);
  margin: 0 auto;
  min-height: var(--kx-head-h);
  padding: 0 var(--gutter);
  display: flex;
  align-items: center;
  gap: 1rem;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  margin-inline-end: auto;
  margin-inline-start: -0.3rem;
  padding: 0.3rem;
  border-radius: 14px;
  text-decoration: none;
  transition: transform 0.22s var(--kx-ease-out);
}
.brand:active { transform: scale(0.97); }
.brand-mark {
  width: 36px;
  height: 36px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: var(--r-sm);
  background: var(--kx-premium);
  box-shadow: 0 8px 18px rgba(81, 202, 123, 0.28);
}
.brand-mark svg { width: 21px; height: 21px; }
.brand-name {
  font-size: 1.05rem;
  font-weight: 800;
  letter-spacing: -0.035em;
  color: var(--kx-ink);
}
.brand-name span { color: var(--kx-green); }

.nav { display: flex; align-items: center; gap: 0.35rem; }
.nav > a {
  padding: 0.5rem 0.7rem;
  border-radius: 10px;
  font-size: 0.9rem;
  font-weight: 650;
  color: var(--kx-body);
  text-decoration: none;
  transition: color 0.2s var(--kx-ease-out), background-color 0.2s var(--kx-ease-out);
}
.nav > a:hover { color: var(--kx-ink); background: rgba(15, 17, 21, 0.05); }
.nav-cta { margin-inline-start: 0.5rem; }

/* Hamburgaren. Två streck i stället för tre — lugnare, och den blir ett kryss
   utan att ett tredje streck behöver gömmas. */
.nav-toggle {
  display: none;
  width: 42px;
  height: 42px;
  padding: 0;
  border: 1px solid var(--kx-line);
  border-radius: var(--r-sm);
  background: #fff;
  color: var(--kx-ink);
  cursor: pointer;
  box-shadow: var(--sh-sm);
}
.nav-toggle-bars { display: grid; gap: 5px; justify-items: center; }
.nav-toggle-bars i {
  display: block;
  width: 17px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transition: transform 0.26s var(--kx-ease-out);
}
.nav-toggle[aria-expanded="true"] .nav-toggle-bars i:first-child { transform: translateY(3.5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars i:last-child  { transform: translateY(-3.5px) rotate(-45deg); }

.nav-scrim {
  position: fixed;
  inset: 0;
  z-index: 35;
  background: rgba(15, 17, 21, 0.28);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  opacity: 0;
  transition: opacity 0.24s var(--kx-ease-out);
}
.nav-scrim.is-open { opacity: 1; }

@media (max-width: 900px) {
  .nav-toggle { display: grid; place-items: center; }

  /* visibility (inte bara opacity) så att stängd meny lämnar tabbordningen —
     annars kan man tabba till osynliga länkar. */
  .nav {
    position: fixed;
    inset: var(--kx-head-h) var(--shell-gap) auto;
    z-index: 36;
    flex-direction: column;
    align-items: stretch;
    gap: 0.15rem;
    padding: 0.75rem 0.9rem 1.1rem;
    border-radius: var(--r-lg);
    /* Nästan ogenomskinlig med flit: en hel meny med hjältetexten lysande
       igenom blir oläslig — läsbarhet före glaseffekt. */
    background: rgba(255, 255, 255, 0.985);
    backdrop-filter: saturate(180%) blur(20px);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    border: 1px solid var(--kx-line);
    box-shadow: 0 24px 60px rgba(15, 17, 21, 0.16);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-10px);
    transition: opacity 0.24s var(--kx-ease-out),
                transform 0.26s var(--kx-ease-out),
                visibility 0s linear 0.26s;
  }
  .nav.is-open { opacity: 1; visibility: visible; transform: translateY(0); transition-delay: 0s; }
  .nav > a { padding: 0.8rem 0.75rem; font-size: 1rem; }
  .nav-cta { margin: 0.6rem 0 0; }
  .nav-cta .btn { width: 100%; }
}


/* ==========================================================================
   4b. INLOGGNINGSRUTAN
   Sidhuvudets knapp och streak-kortets "Logga in för att se dina egna" öppnar
   SAMMA ruta (#signInModal, sist i index.html). Formuläret finns i ett enda
   exemplar; assets/account.js sköter öppning, stängning och fokus.

   Två lager: skärmen (.signin-scrim) och behållaren (.signin). Behållaren är
   rullningsbar — på en låg skärm med uppslaget tangentbord måste kortet gå att
   nå, annars ligger lösenordsfältet under tangentbordet utan väg dit.
   ========================================================================== */
/* Rullningslåset är en KLASS, inte en inline-stil på <body>. Mobilmenyn i
   site.js låser med body.style.overflow och NOLLSTÄLLER den när menyn stängs —
   och menyn stängs av samma klick som öppnar rutan. En inline-låsning här hade
   alltså tagits bort en bildruta senare, och sidan hade rullat bakom rutan. */
html.is-locked, html.is-locked body { overflow: hidden; }

.signin-scrim {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: rgba(15, 17, 21, 0.34);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity 0.24s var(--kx-ease-out);
}
.signin-scrim.is-open { opacity: 1; }

.signin {
  position: fixed;
  inset: 0;
  z-index: 51;
  display: grid;
  place-items: center;
  padding: clamp(1rem, 0.6rem + 2vw, 2rem);
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* Samma material som streak-kortet — rutan är kortets formulär, flyttat fram
   över sidan, inte en främmande dialog. */
.signin-card {
  position: relative;
  width: 100%;
  max-width: 25rem;
  padding: 1.8rem 1.6rem 1.5rem;
  border: 1px solid rgba(81, 202, 123, 0.2);
  border-radius: var(--r-lg);
  background:
    radial-gradient(120% 150% at 100% 0%, rgba(104, 217, 144, 0.14), rgba(104, 217, 144, 0) 62%),
    #fff;
  box-shadow: 0 34px 74px -30px rgba(15, 17, 21, 0.45), var(--sh-card);
  opacity: 0;
  transform: translateY(12px) scale(0.985);
  transition: opacity 0.26s var(--kx-ease-out), transform 0.32s var(--kx-ease-out);
}
.signin.is-open .signin-card { opacity: 1; transform: none; }

.signin-close {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid var(--kx-line);
  border-radius: 50%;
  background: #fff;
  color: var(--kx-soft);
  cursor: pointer;
  transition: color 0.2s var(--kx-ease-out), border-color 0.2s var(--kx-ease-out);
}
.signin-close:hover { color: var(--kx-ink); border-color: rgba(81, 202, 123, 0.42); }
.signin-close svg { width: 15px; height: 15px; }

/* margin-right, inte margin-inline-end: krysset sitter alltid fysiskt till
   höger, även när rubriken är arabisk och sätts med dir="rtl". Då börjar texten
   i högerkanten — och det är just där utrymmet måste reserveras. */
.signin-title {
  margin: 0 2.75rem 1.1rem 0;
  font-size: clamp(1.22rem, 1.1rem + 0.5vw, 1.4rem);
  font-weight: 800;
  letter-spacing: -0.032em;
  line-height: 1.25;
  color: var(--kx-ink);
}

.signin-form { display: grid; gap: 0.7rem; }
.signin-field { display: grid; gap: 0.3rem; }
.signin-field > span { font-size: 0.78rem; font-weight: 650; color: var(--kx-soft); }
.signin-field input {
  width: 100%;
  padding: 0.68rem 0.85rem;
  font: inherit;
  font-size: 0.95rem;
  color: var(--kx-ink);
  background: #fff;
  border: 1px solid var(--kx-line);
  border-radius: var(--r-sm);
  transition: border-color 0.24s var(--kx-ease-out), box-shadow 0.24s var(--kx-ease-out);
}
.signin-field input:focus-visible {
  outline: none;
  border-color: rgba(81, 202, 123, 0.55);
  box-shadow: 0 0 0 3px rgba(81, 202, 123, 0.16);
}
.signin-field input:disabled { background: #f7f8f7; color: var(--kx-soft); }

.signin-actions { display: flex; gap: 0.5rem; margin-top: 0.15rem; }
.signin-actions .btn { flex: 1; }

/* BOTSKYDDETS RUTA. Tom och nollhög så länge Cloudflare inte behöver fråga
   något — widgeten körs i "interaction-only" och ritar då ingenting alls.
   Ingen min-height, ingen ram, ingen reserverad yta: en captcha-låda som
   syns när den inte har något att säga är precis det formuläret inte ska ha.

   Först när en utmaning FAKTISKT visas får rutan höjd, och då är det innehåll
   besökaren väntar på — inte ett hopp i layouten. :empty täcker det tomma
   fallet; iframen som Turnstile lägger in gör den icke-tom.
   max-width skyddar mot vågrät overflow i den smalaste rutan (390 px). */
.signin-captcha { display: grid; justify-items: center; max-width: 100%; overflow: hidden; }
.signin-captcha:empty { display: none; }
.signin-captcha iframe { max-width: 100%; }

/* Visuellt dold, men läses av skärmläsare. Klipps i stället för display:none —
   det senare tar bort elementet ur tillgänglighetsträdet och tystar role=status. */
.u-sr {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}

.signin-error {
  margin: 0;
  font-size: 0.82rem;
  font-weight: 600;
  color: #b4231f;              /* AA mot vitt — felet ska gå att läsa, inte anas */
}
.signin-fine { margin: 0.2rem 0 0; font-size: 0.72rem; line-height: 1.45; color: var(--kx-soft); }


/* ==========================================================================
   5. HERO
   ========================================================================== */
/* Hjältepanelen bär en hög produktbild i ena spalten och en kortare textspalt
   i den andra. Full --shell-y i botten ger då ett stort tomrum under texten —
   knappare bottenluft här, panelens egen höjd räcker som andrum. */
.shell-hero {
  padding-top: clamp(1.5rem, 0.6rem + 2.6vw, 3rem);
  padding-bottom: clamp(2rem, 1.2rem + 2.4vw, 3.25rem);
  background:
    radial-gradient(120% 90% at 92% 0%, rgba(104, 217, 144, 0.13), rgba(104, 217, 144, 0) 58%),
    linear-gradient(180deg, #FFFFFF 0%, #FAFDFB 62%, #F4FBF7 100%);
}
.hero-aurora {
  top: -30%;
  right: -6%;
  width: min(52rem, 90%);
  height: 42rem;
  background:
    radial-gradient(44% 48% at 62% 44%, rgba(104, 217, 144, 0.24), rgba(104, 217, 144, 0) 72%),
    radial-gradient(32% 36% at 22% 28%, rgba(150, 235, 174, 0.22), rgba(150, 235, 174, 0) 70%);
  filter: blur(12px);
}

/* Långsam drift i auroran bakom hjälten. 26 s och några få procent — det ska
   inte gå att peka på, bara kännas som att ytan lever. */
@keyframes heroAuroraDrift {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  50%  { transform: translate3d(-2.4%, 1.8%, 0) scale(1.06); }
  100% { transform: translate3d(0, 0, 0) scale(1); }
}
.hero-aurora { animation: heroAuroraDrift 26s ease-in-out infinite; }

/* ENTRÉ FÖR HJÄLTETEXTEN.
   Spalten stod helt stilla medan resten av sidan rör sig. Raderna stiger in
   med en kort trappa — 90 ms mellan varje, inte mer: blir det längre känns
   sidan seg i stället för mjuk.

   LCP: rubriken är sidans största textelement, och att starta den på
   opacity 0 skjuter LCP framåt med animationens längd. 0,62 s på en sida som
   målar första bildrutan efter ~100 ms landar långt under gränsvärdet, så det
   är en medveten avvägning — inte ett förbiseende. Vill man ha tillbaka den
   omedelbara rubriken räcker det att ta bort .hero-copy-raderna nedan.

   'both' krävs: utan fill-mode ligger texten synlig i en bildruta innan
   animationen börjar, och då blinkar den. */
@keyframes heroRise {
  from { opacity: 0; transform: translate3d(0, 14px, 0); }
  to   { opacity: 1; transform: none; }
}
.hero-copy h1,
.hero-copy .lede,
.hero-copy .cta-row,
.hero-copy .hero-trust {
  animation: heroRise 0.62s var(--kx-ease-out) both;
}
.hero-copy h1          { animation-delay: 0.04s; }
.hero-copy .lede       { animation-delay: 0.13s; }
.hero-copy .cta-row    { animation-delay: 0.22s; }
.hero-copy .hero-trust { animation-delay: 0.31s; }

.hero-grid { display: grid; gap: clamp(2rem, 1rem + 3.4vw, 3.5rem); align-items: center; }

.hero-copy h1 { margin-bottom: 1.2rem; }
.lede {
  font-size: clamp(1.04rem, 0.98rem + 0.4vw, 1.24rem);
  line-height: 1.6;
  color: var(--kx-soft);
  max-width: 33rem;
  margin-bottom: 2rem;
}

.cta-row { display: flex; flex-wrap: wrap; gap: 0.85rem; margin-bottom: 2rem; }

.hero-trust {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.4rem;
  font-size: 0.87rem;
  color: var(--kx-soft);
}
.hero-trust li { display: flex; align-items: center; gap: 0.5rem; }
/* Bocken ligger som data-URI i background — ett extra element per punkt vore
   brus i markupen, och CSP:n tillåter img-src data: (se site/_headers). */
/* Bocken. Delas med .check-list i integritetsavsnittet — samma primitiv på två
   ställen, lyft hit på samma sätt som auroralagren delar sin regel längre upp.
   Den gröna färgen är hårdkodad som %231a7f4b (= --kx-green-ink) inne i
   data-URI:n; en var() går inte att använda där. Ändras grönskan måste den
   alltså ändras HÄR, och nu bara här. */
.hero-trust li::before,
.check-list li::before {
  content: "";
  width: 16px;
  height: 16px;
  flex: none;
  border-radius: 50%;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.6 6.2 5 8.6l4.4-5.1' fill='none' stroke='%231a7f4b' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")
      center / 10px 10px no-repeat,
    rgba(81, 202, 123, 0.16);
  box-shadow: inset 0 0 0 1px rgba(81, 202, 123, 0.26);
}

/* --- Produktscenen ------------------------------------------------------ */
.stage {
  /* --phone styr HELA scenen: telefonens bredd, robotytans mått och
     brickornas placering. Ändra bara den här. */
  --phone: clamp(196px, 24.5vw, 340px);
  position: relative;
  display: flex;
  justify-content: flex-end;
  padding-inline-start: calc(var(--phone) * 0.42);   /* plats åt roboten */
}
.stage-glow {
  position: absolute;
  z-index: 0;
  inset: 6% -8% 0 -4%;
  border-radius: 50%;
  background: radial-gradient(50% 44% at 56% 52%, rgba(104, 217, 144, 0.22), rgba(104, 217, 144, 0) 72%);
  filter: blur(10px);
  pointer-events: none;
}

/* PRODUKTBILDEN — originalfilen, oredigerad. Ingen ritad ram, ingen
   drop-shadow: bilden har sin egen bakgrund och sin egen skugga inbakad. */
.phone-shot {
  position: relative;
  z-index: 2;
  width: var(--phone);
  height: auto;
}

/* ANDRA TELEFONEN — skanningsskärmen, till vänster och längre bak i djupled.
   Mindre (0,62 × --phone) och med en svagare, mjukare skugga än huvud-
   telefonen: det är så avstånd läses i en bild. Den här bilden har INTE någon
   skugga inbakad — till skillnad från iphone2.png — så den ritas här med
   drop-shadow, som följer alfakanalen i stället för att bli en rektangel.
   z-index 1: bakom både roboten (3) och huvudtelefonen (2), framför brickorna. */
.phone-scan {
  position: absolute;
  z-index: 1;
  left: 0;
  bottom: 9%;
  width: calc(var(--phone) * 0.62);
  height: auto;
  filter:
    drop-shadow(0 26px 34px rgba(15, 17, 21, 0.17))
    drop-shadow(0 5px 10px rgba(15, 17, 21, 0.09));
}

/* Svävande varumärkesbrickor — ren dekor.
   Nästan ogenomskinliga med flit. Med 0,62 vitt + blur(9px) blev de disiga
   fläckar där glyfen knappt gick att urskilja; på en redan ljus panel finns
   inget bakom dem att göra glaseffekt av. Nu läser de som fasta brickor. */
.tile {
  position: absolute;
  z-index: 1;
  display: grid;
  place-items: center;
  border-radius: 26%;
  background: rgba(255, 255, 255, 0.94);
  border: 1px solid rgba(15, 17, 21, 0.05);
  box-shadow:
    0 1px 2px rgba(15, 17, 21, 0.05),
    0 18px 34px -16px rgba(15, 17, 21, 0.22);
  color: var(--kx-green-deep);
  pointer-events: none;
  /* SKÄRPEDJUP. Brickorna ligger BAKOM telefonen i rummet och ska därför vara
     ur fokus, precis som i designreferensen — telefonen är det enda som är
     skarpt. filter (inte backdrop-filter) suddar själva brickan, inklusive
     dess kant och skugga, vilket är just det en kamera gör.
     Blurradien följer --phone så att oskärpan håller sig proportionell när
     scenen skalas ned; en fast pixelradie blir gröt på mobil. */
  filter: blur(calc(var(--phone) * 0.011));
}
.tile svg { width: 56%; height: 56%; }
/* Flamman ligger längst bak av de två men får INTE bli en oigenkännlig fläck —
   i referensen syns det fortfarande att det är eld. Samma blurfaktor som
   äpplet, och lite större bricka så att formen överlever oskärpan.
   Egna gradienter, så .tile { color } påverkar den inte. */
.tile-b svg { width: 62%; height: 62%; }
.tile-a {
  width: calc(var(--phone) * 0.27);
  height: calc(var(--phone) * 0.27);
  top: 4%;
  left: calc(var(--phone) * 0.06);
  transform: rotate(-9deg);
}
/* Ligger BAKOM telefonen (z-index 1) och kikar fram vid högerkanten. Måste
   hållas innanför panelens innerkant — sticker den ut ser den ut att ramla av. */
.tile-b {
  width: calc(var(--phone) * 0.26);
  height: calc(var(--phone) * 0.26);
  right: calc(var(--phone) * 0.015);
  bottom: 16%;
  transform: rotate(8deg);
  /* Flamman har egna gradienter — ingen currentColor att sätta. */
}

/* --- Reserverade robotytor ---------------------------------------------- */
/* Samma komponent på båda ställena. Tom renderas den som ren scenbelysning —
   mjuk mintglöd plus markskugga. Ingen ram, ingen platshållartext, inget som
   ser ut som en trasig bild. Måtten är det som betyder något: de bestämmer
   exakt var roboten hamnar när scenen respektive bilden monteras. */
.robot-stage { position: relative; pointer-events: none; }
.robot-stage canvas { width: 100%; height: 100%; display: block; }

/* --- Spline-scenen i hjälten ----------------------------------------------
   Scenen sköter ALL rörelse och pekarreaktion själv. Sajten flyttar aldrig
   rutan — bara innehållet i scenen rör sig, precis som den är byggd.

   Selektorn var tidigare `#interactive-robot-stage spline-viewer`. Scenen
   monteras nu i en vanlig <canvas> av /assets/robot/hero.js i stället för i
   webbkomponenten — samma yta, samma mått, samma skugga. Varje egenskap nedan
   är oförändrad så när som på --spline-viewer-background, som bara vyn läste. */
#interactive-robot-stage canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  z-index: 1;
  /* Föräldern är pointer-events: none så att robotytan aldrig stjäl klick från
     rubrik eller knappar. Canvasen själv måste däremot ta emot pekaren, annars
     dör blickföljningen som redan är konfigurerad i Spline. */
  pointer-events: auto;
  background: transparent;
  /* Skuggan MÅSTE vara drop-shadow, inte box-shadow: canvasen är genomskinlig,
     så box-shadow hade ritat en rektangel runt rutan. drop-shadow följer
     robotens alfakanal och bäddar in henne i scenen i stället för att låta
     henne ligga som ett klistermärke ovanpå. */
  filter:
    drop-shadow(0 18px 22px rgba(15, 17, 21, 0.18))
    drop-shadow(0 3px 6px rgba(15, 17, 21, 0.10));
}
/* Den gamla noteringen om ::part() och shadow-DOM gäller inte längre: med
   runtimen finns ingen shadow-rot och ingen <a id="logo">-bricka att dölja.
   Scenen bär heller ingen SplineWatermark-textur, så inget märke ritas i
   canvasen. site.js injicerar därför inte längre någon <style> någonstans. */

/* Fallbacken är en BELYST PLATS, inte en tom ruta: ett vitt ljusfält närmast
   golvet, en mintglöd ovanför och en tydlig markskugga. Ett enda diffust grönt
   moln (första försöket) försvann helt mot den redan mintade panelen och läste
   som en smutsfläck. Tre lager med olika skärpa ger i stället djup. */
.robot-light {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(36% 24% at 50% 86%, rgba(255, 255, 255, 0.98), rgba(255, 255, 255, 0) 70%),
    radial-gradient(42% 38% at 50% 52%, rgba(81, 202, 123, 0.34), rgba(81, 202, 123, 0) 70%),
    radial-gradient(64% 56% at 50% 38%, rgba(150, 235, 174, 0.22), rgba(150, 235, 174, 0) 76%);
  filter: blur(5px);
}
.robot-shadow {
  position: absolute;
  left: 20%;
  right: 20%;
  bottom: 3%;
  height: 7%;
  border-radius: 50%;
  background: radial-gradient(50% 50% at 50% 50%, rgba(15, 17, 21, 0.22), rgba(15, 17, 21, 0) 70%);
  filter: blur(4px);
}
/* När scenen väl ritat tas den ritade markskuggan bort — 3D-scenen har egen. */
.robot-stage.is-live .robot-shadow { opacity: 0; }
/* Den statiska bilden, när den läggs in. */
.robot-img { position: relative; z-index: 1; width: 100%; height: 100%; object-fit: contain; object-position: bottom center; }

/* Hjältens robotyta: framför telefonens nedre vänstra hörn, som i referensen. */
/* Robotens ruta. Scenen har egen luft runt figuren, så rutan måste vara
   rejält större än roboten ser ut att vara — annars blir hon en liten prick.
   Står FRAMFÖR telefonens nedre vänstra hörn, mellan rubriken och telefonen,
   som i designreferensen. */
#interactive-robot-stage {
  position: absolute;
  z-index: 3;
  /* Placering mellan de två telefonerna. Flyttad NED och åt HÖGER 2026-08-03:
     hon skymde skanningstelefonens högerkant och låg för högt över
     History-telefonens måltidslista. Lägre + högre upp i högerled lägger henne
     mot flikraden i stället, där det inte finns något innehåll att dölja.
     right justerad i sidled 2026-08-03: 0.56 -> 0.44 -> 0.54 -> 0.62. Högre
     värde = längre åt VÄNSTER (avstånd från scenens högerkant). bottom är
     MEDVETET orörd sedan sänkningen — bara sidled ändras här. */
  right: calc(var(--phone) * 0.62);
  bottom: calc(var(--phone) * -0.14);
  width: calc(var(--phone) * 1.12);
  height: calc(var(--phone) * 1.37);
}

/* Markskugga. Utan den ser roboten pålimmad ut — en platt overlay ovanpå
   panelen. Den mjuka ellipsen vid fötterna ger henne kontakt med ytan.
   Ligger UNDER vyn (z-index) men över mintglöden. */
/* SKÄRPEDJUP BAKOM ROBOTEN.
   backdrop-filter suddar det som ligger BAKOM lagret — här telefonen och
   panelen — så att roboten lyfter ur bakgrunden i stället för att ligga platt
   på den. En vanlig filter/blur hade suddat lagret självt och inte gjort något
   alls, eftersom lagret är genomskinligt.

   mask-image är det som gör greppet användbart: utan den slutar suddigheten
   tvärt vid elementets kant och man ser en rektangel mitt i bilden. Masken
   tonar ut oskärpan radiellt, så övergången är osynlig.

   Ligger MELLAN mintglöden och roboten (z-index 0, vyn har 1). */
.robot-halo {
  position: absolute;
  z-index: 0;
  /* Hålls TÄTT runt roboten. Den var tidigare 16 % bredare åt varje håll, och
     när skanningstelefonen kom in till vänster hamnade den halva innanför
     halon — dumplingsskärmen blev suddig och urtvättad. Halon ska lyfta fram
     roboten, inte blekna bilderna omkring henne. */
  inset: -8% -3% -4%;
  backdrop-filter: blur(22px) saturate(110%);
  -webkit-backdrop-filter: blur(22px) saturate(110%);
  -webkit-mask-image: radial-gradient(50% 50% at 50% 55%, #000 34%, rgba(0, 0, 0, 0) 72%);
          mask-image: radial-gradient(50% 50% at 50% 55%, #000 34%, rgba(0, 0, 0, 0) 72%);
  /* Glöden ovanpå oskärpan — samma mint som resten av scenen. Den vita kärnan
     är nedtonad från 0,52: den var det som bleknade skärmen bakom. */
  background:
    radial-gradient(44% 40% at 50% 52%, rgba(104, 217, 144, 0.26), rgba(104, 217, 144, 0) 70%),
    radial-gradient(58% 52% at 50% 50%, rgba(255, 255, 255, 0.26), rgba(255, 255, 255, 0) 74%);
  pointer-events: none;
}
/* Utan backdrop-filter (äldre webbläsare) blir det bara glöden — aldrig en
   grå platta över telefonen. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .robot-halo { -webkit-mask-image: none; mask-image: none; }
}

.robot-ground {
  position: absolute;
  z-index: 0;
  /* Uppmätt: robotens fötter ligger ~20 % upp från rutans underkant, inte vid
     0. Skuggan MÅSTE ligga där, annars svävar den under henne och gör saken
     värre än ingen skugga alls. */
  left: 19%;
  right: 19%;
  bottom: 19%;
  height: 8%;
  border-radius: 50%;
  background: radial-gradient(50% 50% at 50% 50%,
    rgba(15, 17, 21, 0.32), rgba(15, 17, 21, 0.13) 46%, rgba(15, 17, 21, 0) 74%);
  filter: blur(8px);
}

@media (min-width: 1000px) {
  /* Scenkolumnen breddades från 30rem när den andra telefonen kom in: roboten
     nådde redan fram till textspaltens kant, så en tredje kropp fick inte plats
     utan att krypa in i rubriken. */
  .hero-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 39rem); }
}
@media (max-width: 999px) {
  .shell-hero { text-align: center; }
  .hero-copy { max-width: 42rem; margin: 0 auto; }
  .lede { margin-inline: auto; }
  .cta-row, .hero-trust { justify-content: center; }
  .stage {
    --phone: clamp(200px, 46vw, 300px);
    justify-content: center;
    /* Mer reserverad plats till vänster än på desktop: roboten ska stå BREDVID
       telefonen här, inte framför den. */
    padding-inline-start: calc(var(--phone) * 0.36);
    margin-top: 0.5rem;
  }
  /* Mindre och längre ut. I stackat läge hamnade en desktopstor robot mitt över
     telefonens måltidslista — den ska aldrig skymma skärmen.
     0,62 + 0,70 = 1,32 mot 1,36 inre bredd: ryms. */
  #interactive-robot-stage {
    right: calc(var(--phone) * 0.62);
    /* Bunden explicit: basregelns bottom sänktes för desktopvyn, och utan den
       här raden hade roboten glidit ur scenen i stackat läge. */
    bottom: calc(var(--phone) * -0.05);
    width: calc(var(--phone) * 0.70);
    height: calc(var(--phone) * 0.86);
  }
}
@media (max-width: 560px) {
  /* Två knappar i bredd får plats ända ned till ~560 px, men bara med några
     pixlars marginal — en knapprad som "nästan" håller ser trasig ut. */
  .cta-row { flex-direction: column; align-items: stretch; }
  .cta-row .btn { width: 100%; }
  .hero-trust { flex-direction: column; align-items: center; gap: 0.45rem; }
}

/* Brickorna hör ihop med telefonen. På smala skärmar hamnar de så långt från
   den att de läser som lösa element — då är de bättre borta. */
@media (max-width: 700px) {
  .tile { display: none; }
}


/* ==========================================================================
   6. SMARTARE SPÅRNING
   ========================================================================== */
.shell-smart {
  background:
    radial-gradient(90% 70% at 12% 0%, rgba(104, 217, 144, 0.10), rgba(104, 217, 144, 0) 62%),
    linear-gradient(180deg, #FCFEFD 0%, #F4FBF7 100%);
}
.smart-aurora {
  left: -10%;
  bottom: -20%;
  width: 40rem;
  height: 32rem;
  background: radial-gradient(46% 46% at 50% 50%, rgba(104, 217, 144, 0.20), rgba(104, 217, 144, 0) 70%);
  filter: blur(14px);
}

.smart-grid { display: grid; gap: clamp(2rem, 1.2rem + 3vw, 3.25rem); align-items: center; }

/* Den dekorativa robotens yta. Egna proportioner, egen belysning — kolumnen
   är balanserad redan innan bilden hunnit laddas. Förhållandet är robotbildens
   eget (510 × 935), så object-fit: contain fyller spalten på BREDDEN. Med en
   bredare ruta (4/5 var första måttet) fick bilden i stället passa in på
   höjden och krympte till två tredjedels spaltbredd — en liten figur med luft
   på båda sidor, som läste som en ikon i stället för som en karaktär. */
.robot-stage-static {
  width: 100%;
  aspect-ratio: 51 / 93;
  align-self: center;
}
/* Bilden lyfts en aning så att markskuggan hamnar UNDER roboten. Utan lyftet
   ligger figurens rundade botten exakt på ytans nederkant och täcker skuggan
   helt — den ritas, men syns inte, och figuren ser ut att sväva utan grund.

   Glöden är TVÅ drop-shadow på själva bilden, inte en gradient bakom den:
   drop-shadow följer alfakanalen, så ljuset hugger om silhuetten i stället för
   att lägga sig som ett runt klot bakom en avlång figur. Den tajta skuggan ger
   kantljuset, den vida ger spillet ut i panelen. En tredje, nästan svart och
   knappt förskjuten, håller kvar figuren mot ytan — utan den flyter den. */
.robot-stage-static .robot-img {
  transform: translateY(-6%);
  filter:
    drop-shadow(0 0 15px rgba(104, 217, 144, 0.42))
    drop-shadow(0 6px 30px rgba(81, 202, 123, 0.38))
    drop-shadow(0 3px 6px rgba(15, 17, 21, 0.07));
}
/* Den statiska ytan står ENSAM i sin spalt — den har ingen telefon bredvid sig
   att läsa som ljusspill mot. Ett centrerat glödklot blir då bara en grön
   fläck. Ljuset ankras därför nere vid "golvet": ett vitt fält vid marken och
   en svagare grön stämning ovanför, som bakgrund till bildens egen glöd. */
.robot-stage-static .robot-light {
  inset: 20% -16% 0;
  background:
    radial-gradient(46% 24% at 50% 78%, rgba(255, 255, 255, 0.62), rgba(255, 255, 255, 0) 74%),
    radial-gradient(56% 46% at 50% 62%, rgba(81, 202, 123, 0.22), rgba(81, 202, 123, 0) 74%);
  filter: blur(11px);
}
/* Markskuggan är en BILD, framtagen ur robotens egen silhuett (se
   scripts/make-robot-asset.py), inte ellipsen som ytan ritar när bilden saknas.
   En oval under en figur med utstickande armar och runt huvud läser direkt som
   fusk — formen på marken har ingenting med formen ovanför att göra.

   Måtten hänger ihop med hur filen genereras och får inte pillas på var för
   sig: filen är robotens bredd + 16 % marginal på var sida (därav -16 %) och
   0,43 av robotens höjd, och kontaktlinjen ligger 12,9 % av robothöjden ovanför
   filens underkant. Bilden är lyft 6 %, vilket ger −7 %; ytterligare några
   procent ned separerar skuggan från figuren, som ju svävar.
   Ändras SHADOW_*-konstanterna i skriptet måste de här räknas om. */
.robot-stage-static .robot-shadow {
  left: -16%;
  right: -16%;
  bottom: -10%;
  height: 43%;
  border-radius: 0;
  filter: none;
  background: url("/assets/img/robot-shadow.webp") center bottom / 100% 100% no-repeat;
}

.smart-copy h2 { margin-bottom: 1rem; }

/* Flödet. Fyra steg, ingen numrering — ordningen läses av pilarna mellan dem. */
.flow {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.4rem 1rem;
  margin-top: 2rem;
}
.flow > li {
  display: grid;
  align-content: start;
  justify-items: center;
  text-align: center;
  gap: 0.2rem;
  position: relative;
}
.flow-ico {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  margin-bottom: 0.55rem;
  border-radius: var(--r-md);
  background: #fff;
  border: 1px solid rgba(81, 202, 123, 0.22);
  color: var(--kx-green-ink);
  box-shadow: 0 8px 18px -10px rgba(81, 202, 123, 0.5);
}
.flow-ico svg { width: 22px; height: 22px; }
.flow strong { font-size: 0.95rem; font-weight: 750; color: var(--kx-ink); letter-spacing: -0.012em; }
.flow span { font-size: 0.85rem; color: var(--kx-soft); }

@media (min-width: 620px) {
  .flow { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.75rem; --flow-cycle: 5.1s; }
  /* Förbindelsen mellan stegen ritas som små lodräta streck, inte prickar.
     ::after = grå grundlinje (alltid lika korta streck),
     ::before = den gröna vågen, där strecken växer på höjden mot vågens mitt. */
  .flow > li:not(:last-child)::after,
  .flow > li:not(:last-child)::before {
    content: "";
    position: absolute;
    top: 14px;          /* ikonens mitt ligger på 23px; fältet är 18px högt */
    height: 18px;
    left: calc(50% + 32px);
    right: calc(-50% + 32px);
    background-image: linear-gradient(90deg, currentColor 0 2px, transparent 2px);
    background-repeat: repeat-x;
    background-position: 0 50%;
  }
  .flow > li:not(:last-child)::after {
    color: rgba(15, 17, 21, 0.22);
    background-size: 7px 3px;
  }
  /* Vågen: samma raster men i full höjd och grönt, maskat av en ellips som
     vandrar. Ellipsens form är det som ger spolen — höga streck i mitten,
     korta i utkanten. drop-shadow ger glöden och följer masken. */
  .flow > li:not(:last-child)::before {
    color: #35c26f;
    background-size: 7px 100%;
    z-index: 1;
    filter: drop-shadow(0 0 5px rgba(53, 194, 111, 0.45));
    -webkit-mask-image: radial-gradient(ellipse 9% 52% at 50% 50%,
      #000 0 86%, rgba(0,0,0,0.4) 96%, transparent 100%);
            mask-image: radial-gradient(ellipse 9% 52% at 50% 50%,
      #000 0 86%, rgba(0,0,0,0.4) 96%, transparent 100%);
    -webkit-mask-size: 300% 100%;
            mask-size: 300% 100%;
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
    animation: flowPulse var(--flow-cycle) linear infinite;
  }
  /* Ikonerna ingår i vågen: de tänds grönt när den passerar dem. Fördröjningarna
     nedan är ett enda schema — ikon, sträcka, ikon, sträcka … genom hela raden. */
  .flow-ico { animation: flowIcoPulse var(--flow-cycle) linear infinite; }
  .flow > li:nth-child(1) .flow-ico { animation-delay: 0s; }
  .flow > li:nth-child(1)::before    { animation-delay: 0.55s; }
  .flow > li:nth-child(2) .flow-ico { animation-delay: 1.1s; }
  .flow > li:nth-child(2)::before    { animation-delay: 1.65s; }
  .flow > li:nth-child(3) .flow-ico { animation-delay: 2.2s; }
  .flow > li:nth-child(3)::before    { animation-delay: 2.75s; }
  .flow > li:nth-child(4) .flow-ico { animation-delay: 3.3s; }
}

@keyframes flowPulse {
  0%   { -webkit-mask-position: 100% 0; mask-position: 100% 0; }
  /* Svepet tar 20 % av varvet (~1 s), resten är paus — vågen ska passera, inte snurra. */
  20%, 100% { -webkit-mask-position: 0% 0; mask-position: 0% 0; }
}

/* Ikonens del av vågen: kort grönt anslag, sedan tillbaka till viloläget. */
@keyframes flowIcoPulse {
  0%, 100% {
    color: var(--kx-soft);
    border-color: rgba(81, 202, 123, 0.22);
    box-shadow: 0 8px 18px -10px rgba(81, 202, 123, 0.5);
    transform: none;
  }
  7.5% {
    color: #2bb768;
    border-color: rgba(53, 194, 111, 0.6);
    box-shadow: 0 8px 18px -10px rgba(81, 202, 123, 0.5),
                0 0 0 4px rgba(53, 194, 111, 0.13);
    transform: translateY(-1px);
  }
  25% {
    color: var(--kx-soft);
    border-color: rgba(81, 202, 123, 0.22);
    box-shadow: 0 8px 18px -10px rgba(81, 202, 123, 0.5);
    transform: none;
  }
}

/* Korten. Två i bredd, mjuk mintton, tunn kant — inte fyra generiska rutor. */
.smart-cards { display: grid; gap: 0.9rem; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.smart-cards > li {
  padding: 1.4rem 1.25rem 1.5rem;
  border: 1px solid rgba(81, 202, 123, 0.18);
  border-radius: var(--r-lg);
  background:
    radial-gradient(120% 140% at 0% 0%, rgba(104, 217, 144, 0.13), rgba(104, 217, 144, 0) 60%),
    #fff;
  box-shadow: var(--sh-card);
  transition: transform 0.28s var(--kx-ease-out), box-shadow 0.28s var(--kx-ease-out);
}
.smart-cards > li:hover { transform: translateY(-3px); box-shadow: 0 1px 2px rgba(15,17,21,.04), 0 22px 40px -22px rgba(81, 202, 123, 0.45); }
.smart-cards h3 { font-size: 1.04rem; margin-bottom: 0.4rem; }
.smart-cards p { font-size: 0.92rem; line-height: 1.55; color: var(--kx-soft); margin: 0; }

.card-ico {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  margin-bottom: 0.9rem;
  border-radius: var(--r-sm);
  background: rgba(81, 202, 123, 0.13);
  color: var(--kx-green-ink);
}
.card-ico svg { width: 22px; height: 22px; }

@media (max-width: 1079px) {
  /* Under 1080 px finns ingen plats där den dekorativa roboten inte skulle
     tränga undan texten. Ytan tas ur flödet helt. */
  #decorative-robot-stage { display: none; }
}
@media (min-width: 1080px) {
  .smart-grid { grid-template-columns: minmax(0, 13rem) minmax(0, 1fr) minmax(0, 27rem); }
}
@media (max-width: 700px) {
  .smart-cards { grid-template-columns: minmax(0, 1fr); }
}


/* ==========================================================================
   7. FUNKTIONSBLOCK
   Få och stora hellre än ett rutnät av generiska kort.
   ========================================================================== */
.feature {
  display: grid;
  gap: clamp(1.75rem, 1rem + 3vw, 3.5rem);
  align-items: center;
  padding: clamp(2.25rem, 1.4rem + 3vw, 3.5rem) 0;
  border-top: 1px solid var(--kx-line);
}
.feature:first-of-type { border-top: 0; padding-top: 0; }
.feature:last-of-type { padding-bottom: 0; }
.feature h3 {
  font-size: clamp(1.35rem, 1.15rem + 0.8vw, 1.8rem);
  letter-spacing: -0.028em;
  margin-bottom: 0.85rem;
}
.feature-text p { color: var(--kx-soft); max-width: 32rem; }

@media (min-width: 900px) {
  /* Spegelvändningen görs med EXPLICIT kolumnplacering, inte med order:
     order flyttar bara innehållet mellan kolumnerna och låter bredderna ligga
     kvar, så den speglade raden fick texten i den smala kolumnen. Texten ska
     alltid ha den bredare. */
  .feature       { grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr); }
  .feature-flip  { grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr); }
  .feature-flip .feature-visual { grid-column: 1; grid-row: 1; }
  .feature-flip .feature-text   { grid-column: 2; grid-row: 1; }

  .feature-visual { width: 100%; max-width: 26rem; justify-self: end; }
  .feature-flip .feature-visual { justify-self: start; }

  /* Viktkurvan är blockets hela poäng och tålde inte 26rem — kortet stod smalt
     och intryckt mot högerkanten med en tunn kurva i. Här vänds kolumnförhållandet
     så bilden får den bredare spalten, och kortet fyller den. Kortet växer
     VÄNSTERUT (justify-self: end ligger kvar), så högerkanten löper fortfarande i
     linje med de andra funktionsblocken. Texten klarar den smalare spalten:
     .feature-text p kapas ändå vid 32rem. */
  .feature-trend { grid-template-columns: minmax(0, 1fr) minmax(0, 1.28fr); }
  .feature-trend .feature-visual { max-width: 40rem; }
}

/* Rubrikraden i funktionsavsnittet. Samma kolumnförhållande som .feature,
   så siffrorna hamnar exakt över chipsen — högerkanten ska löpa rakt genom
   hela avsnittet, inte hoppa in och ut. */
.feat-head { display: grid; gap: clamp(1.75rem, 1rem + 3vw, 3.5rem); }
@media (min-width: 900px) {
  .feat-head { grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr); align-items: center; }
  .feat-head .section-head { margin-bottom: 0; }
  .glance { width: 100%; max-width: 26rem; justify-self: end; }
}

/* Streak-kortet. Samma material som .mini-card — det är ett tredje kort i
   samma familj, inte en egen komponent. */
.glance {
  padding: 1.5rem 1.4rem 1.3rem;
  border: 1px solid rgba(81, 202, 123, 0.18);
  border-radius: var(--r-lg);
  background:
    radial-gradient(120% 150% at 100% 0%, rgba(104, 217, 144, 0.15), rgba(104, 217, 144, 0) 62%),
    #fff;
  box-shadow: var(--sh-card);
}
.glance-hero {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  margin: 0 0 1.1rem;
  font-size: 0.95rem;
  font-weight: 650;
  color: var(--kx-soft);
}
.glance-flame { font-size: 1.5rem; line-height: 1; align-self: center; }
.glance-hero b {
  font-size: clamp(2.1rem, 1.6rem + 1.6vw, 2.9rem);
  font-weight: 800;
  letter-spacing: -0.045em;
  line-height: 1;
  color: var(--kx-green-deep);
  font-variant-numeric: tabular-nums;
}
.glance-rows { display: grid; }
.glance-rows > li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.75rem 0;
  font-size: 0.92rem;
  color: var(--kx-soft);
}
.glance-rows > li + li { border-top: 1px solid var(--kx-hair); }
.glance-rows b {
  font-size: 1.15rem;
  font-weight: 750;
  letter-spacing: -0.025em;
  color: var(--kx-ink);
  font-variant-numeric: tabular-nums;
}

/* Inloggningsdelen. Står `hidden` i markupen och visas av assets/account.js —
   utan JS finns ingen inloggning, och då ska kortet inte heller erbjuda en.
   Själva formuläret ligger i inloggningsrutan (avsnitt 4b): knappen här öppnar
   den, precis som knappen i sidhuvudet. */
.glance-auth { margin-top: 1.1rem; padding-top: 1rem; border-top: 1px solid var(--kx-hair); }
.glance-strings { display: none; }
.glance-open { width: 100%; }

.glance-who {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  margin: 0;
  font-size: 0.8rem;
  color: var(--kx-soft);
  word-break: break-word;
}
.glance-out {
  flex: none;
  padding: 0;
  font: inherit;
  font-weight: 650;
  color: var(--kx-green-ink);
  background: none;
  border: 0;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Inloggat läge: kortet får en tydligare grön kant — siffrorna är riktiga nu. */
.glance.is-live { border-color: rgba(81, 202, 123, 0.42); }
/* Viktkurvan byter också till egna siffror vid inloggning — samma markering
   som streak-kortet, så de två live-korten ser likadana ut. */
.mini-card.is-live { border-color: rgba(81, 202, 123, 0.42); }

/* Chipsen. Kortet är <li>:n, raden inuti är en <summary> — vadderingen ligger
   alltså på raden, inte på kortet, så det utvikta svaret får hela bredden och
   svallet kan klippas av kortets radie. */
.chips { display: grid; gap: 0.6rem; }
.chips > li {
  border: 1px solid var(--kx-line);
  border-radius: var(--r-md);
  background: #fff;
  font-weight: 650;
  color: var(--kx-ink);
  box-shadow: var(--sh-card);
}
.chips details { border-radius: inherit; }
.chips summary {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.85rem 1.1rem;
  cursor: pointer;
  list-style: none;
}
.chips summary::-webkit-details-marker { display: none; }
.chip-a { padding: 0 1.1rem 1.05rem; }
.chip-a p {
  margin: 0;
  font-size: 0.92rem;
  font-weight: 400;
  line-height: 1.65;
  color: var(--kx-soft);
}

/* Öppet kort: grönare ram och djupare skugga. Kortet växer bara i HÖJD.
   Här stod förut också en utväxning i sidled (margin-inline: -0.55rem, -1.2rem
   över 900px). Den hörde till listformen, där kortet låg ensamt på sin rad och
   hade luft att växa ut i. I rutnätet finns ingen sådan luft: negativ marginal
   flyttar inte gridspåret utan ritar bara kortet ut över gapet och in på
   grannens yta. Sedan chipsen blev en rad fanns ingen kvar som använde den.

   Två regler, inte en lista: :has() ogiltigförklarar hela selektorlistan i en
   webbläsare som inte kan den, och då hade även .is-open fallit bort. */
.chips > li.is-open {
  border-color: rgba(81, 202, 123, 0.32);
  box-shadow: 0 1px 2px rgba(15, 17, 21, 0.04), 0 22px 44px -26px rgba(81, 202, 123, 0.75);
}
/* Utan JS (och vid reducerad rörelse) finns ingen klass — då räcker [open]. */
.chips:not(.chips-js) > li:has(details[open]) {
  border-color: rgba(81, 202, 123, 0.32);
  box-shadow: 0 1px 2px rgba(15, 17, 21, 0.04), 0 22px 44px -26px rgba(81, 202, 123, 0.75);
}
.chip-ico {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  flex: none;
  border-radius: 10px;
  background: rgba(81, 202, 123, 0.12);
  color: var(--kx-green-ink);
}
.chip-ico svg { width: 19px; height: 19px; }

/* --------------------------------------------------------------------------
   LOGGSÄTTEN SOM KORT PÅ RAD (.chips-row)
   Samma <details>, samma JS, samma utvikning — bara en annan uppställning:
   fyra kort bredvid varandra i stället för fyra rader under varandra. Allt som
   rör ÖPPNANDET ligger kvar i den gemensamma .chips-CSS:en längre ned; här
   står bara det som skiljer radformen från listformen.
   -------------------------------------------------------------------------- */
.chips-row {
  /* align-items: start är inte kosmetik. Med grid-standardvärdet stretch blir
     alla fyra korten lika höga som radens högsta — och då VÄXER de tre stängda
     korten med när ett fjärde öppnas, med tom vit yta under sin text. Kortet
     ska växa på plats, ensamt. */
  align-items: start;
  /* EN spalt på telefon, som listan var förut. Två spalter på 390 px ger
     158 px breda kort där varje mening bryts på fyra rader — trångt att läsa,
     och korten blir olika höga eftersom de bryter olika. */
  grid-template-columns: minmax(0, 1fr);
  gap: 0.7rem;
  /* Ärver rytmen från .feature, som blocket låg i förut: samma skiljelinje mot
     rubrikraden ovanför och samma luft. Utan detta klistrade korten upp i
     rubriken och avsnittets vågräta linjer slutade mitt i sidan. */
  padding: clamp(2.25rem, 1.4rem + 3vw, 3.5rem) 0;
  border-top: 1px solid var(--kx-line);
}
/* ARABISKAN. Sidan speglas ALDRIG som helhet — site.js sätter dir bara på
   textnoderna, aldrig på behållare, just för att inte kasta om rutnät och
   flexrader. I den gamla VÅGRÄTA raden märktes det inte: ikonen låg först och
   texten började direkt efter den. I ett LODRÄTT kort blir det däremot tydligt
   att texten går ut till högerkanten medan ikonen och plustecknet står kvar
   till vänster.

   Därför vänds bara KORTETS egen tvärsaxel. Rutnätet lämnas orört — de fyra
   korten ska stå i samma ordning oavsett språk. lang på <html> sätts av
   site.js vid språkbytet, så regeln slår till utan att något nytt behöver
   skrivas i markupen. */
html[lang="ar"] .chips-row summary { align-items: flex-end; }
html[lang="ar"] .chips-row .chip-t,
html[lang="ar"] .chips-row .chip-s { width: 100%; }

/* Reserverad radhöjd, inte stretch. Korten är avsiktligt inte lika höga via
   align-items (se ovan) — då hade de tre stängda växt med när ett fjärde
   öppnades. I stället reserveras plats för det längsta radbrytningsfallet, så
   att de fyra STÄNGDA ändå står på linje.

   Måttet skrivs i lh (radhöjder), inte som calc(rader × line-height × storlek):
   det senare upprepar två värden som deklareras några rader bort och glider
   isär så fort typografin ändras.

   ANTALET RADER ÄR UPPMÄTT, inte gissat. Naturlig radbrytning för samtliga
   tolv språk, mätt per brytpunkt:
       560–799 px   2 spalter, smala   →  3 rader (en, da, fr)
       800–1199 px  2 spalter, breda   →  2 rader
       1200 px och uppåt, 4 spalter    →  3 rader (da, de, fr)
   Därav tre band. Ett enda värde på 3 rader hela vägen vore enklare men
   reserverar en hel tom rad per kort genom hela mellanregistret — ca 45 px död
   yta i varje kort mellan 800 och 1199 px, där varenda mening får plats på två
   rader. Först när korten står SIDA VID SIDA spelar höjden roll alls; i en
   spalt är reserverad höjd bara bortkastad luft.

   Två deklarationer per band, inte en: lh kräver Chrome 109 / Safari 16.4 /
   Firefox 120. En äldre motor kastar lh-raden och faller till auto — alltså
   precis det ojämna som raden finns till för att förhindra. calc:en är samma
   mått för hand och plockas av dem; nyare motorer tar lh-raden. Håll paren i
   synk om typografin ändras. */
@media (min-width: 560px) {
  .chips-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .chip-s { min-height: calc(3 * 1.55 * 0.9rem); }
  .chip-s { min-height: 3lh; }
}
@media (min-width: 800px) {
  .chip-s { min-height: calc(2 * 1.55 * 0.9rem); }
  .chip-s { min-height: 2lh; }
}
/* 1200 px, inte 760: vid 760 blir fyra spalter ~170 px breda och varje mening
   bryts på fyra rader. Även 1000 px är för trångt — där tar franskan och
   spanskan fyra rader medan de andra tar tre. Två spalter bär ända upp hit. */
@media (min-width: 1200px) {
  .chips-row { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.75rem; }
  .chip-s { min-height: calc(3 * 1.55 * 0.9rem); }
  .chip-s { min-height: 3lh; }
}

/* Raden staplar innehållet i stället för att lägga det på en linje. Ordningen
   blir ikon → rubrik → kort mening → plustecknet, som är summary::after och
   därför alltid hamnar sist. */
.chips-row summary {
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
  padding: 1.2rem 1.2rem 1.15rem;
}
.chips-row .chip-ico { margin-bottom: 0.9rem; }
.chip-t {
  display: block;
  font-size: 1.02rem;
  font-weight: 650;
  letter-spacing: -0.012em;
  color: var(--kx-ink);
}
.chip-s {
  display: block;
  margin-top: 0.4rem;
  font-size: 0.9rem;
  font-weight: 400;
  line-height: 1.55;
  color: var(--kx-soft);
}
/* margin-inline-start: auto sköt plustecknet till radens slut när summary var
   vågrät. I en lodrät summary är det tvärsaxeln — auto hade kastat det till
   kortets högerkant i stället för att låta det stå kvar under texten.

   Extra .chips i selektorn är inte kosmetik: basregeln .chips summary::after
   står LÄNGRE NER i filen (i utviknings-avsnittet) och har samma specificitet,
   så den vinner annars på ordning och plustecknet åker ut till högerkanten. */
.chips.chips-row summary::after {
  margin-inline-start: 0;
  margin-top: 0.95rem;
}

/* --------------------------------------------------------------------------
   DEN VINKANDE ROBOTEN VID STREAK-KORTET (.feat-bot)
   Roboten ska luta in ÖVER kortets vänsterkant, som i designreferensen.

   Den ligger därför absolut placerad och mäts från KORTETS kant, inte från
   kolumnens. Kortet är alltid exakt 26rem brett här (max-width, och kolumnen
   är bredare än så över 1240 px), så right: 26rem − överlapp ger ett
   KONSTANT överlapp vid varje fönsterbredd.

   Så var det inte förut. Då stod roboten som ett tredje gridbarn, vänsterställt
   i kortets cell, med bredd i vw. Kortets bredd är fast och robotens följde
   fönstret, så avståndet dem emellan gungade: uppmätt +30 px överlapp vid
   1240, men −12 och −13 px (alltså ett glapp) vid 1366 och 1440 — de två
   vanligaste laptopbredderna, där den alltså inte rörde kortet alls.

   Absolut placering tar den ur flödet, så .feat-head auto-placerar rubriken och
   kortet precis som innan roboten fanns. Under 1240 px döljs den helt: där är
   kolumnen inte nämnvärt bredare än kortet.
   -------------------------------------------------------------------------- */
.feat-bot { display: none; }
@media (min-width: 1240px) {
  .feat-head { position: relative; }
  .feat-bot {
    display: block;
    position: absolute;
    /* Överlappet är EXAKT kortets egen vaddering (1.4rem). Roboten lutar alltså
       in över kortets kant och rundade hörn — det layerade djupet finns kvar —
       men hennes ruta slutar precis där textkolumnen börjar och kan aldrig nå
       en siffra eller en etikett. Med 2.5rem gick den 16,6 px in i texten på
       varje bredd, uppmätt mot radernas egna klientrutor. */
    right: calc(26rem - 1.4rem);
    /* Lyft från .feat-head:s underkant. Med bottom: 0 stod fötterna exakt på
       skiljelinjen mot kortraden nedanför, och markskuggan lade sig tvärs över
       den — linjen skar rakt genom skuggan. Nu faller den på ren yta. */
    bottom: 1.35rem;
    z-index: 2;
    width: 11rem;
    /* Ren dekor. Roboten lägger sig delvis framför kortets vänsterkant och får
       aldrig fånga ett klick som var på väg till inloggningsknappen under. */
    pointer-events: none;
  }
}
/* FORMSKUGGAN. drop-shadow, inte box-shadow: box-shadow ritar en skugga av
   elementets RUTA, drop-shadow ritar en skugga av den friläggda SILUETTEN —
   armen, benen och mellanrummen kastar var och en sin egen.

   Tre lager med växande radie och avtagande täthet. Det är så en verklig
   skugga beter sig: precis vid kontaktpunkten är den tät och nästan skarp,
   och ju längre från ytan desto bredare och suddigare blir den. Ett enda
   suddigt lager läser som en gråtonad kopia bakom figuren; tre i trappa läser
   som ljus. Sista lagret är nästan genomskinligt och gör bara att figuren
   sitter fast i sidan i stället för att sväva ovanpå den. */
.feat-bot-img {
  position: relative;
  z-index: 2;
  display: block;
  width: 100%;
  height: auto;
  filter:
    drop-shadow(0 1px 1px rgba(15, 17, 21, 0.18))
    drop-shadow(0 5px 6px rgba(15, 17, 21, 0.13))
    drop-shadow(0 14px 18px rgba(15, 17, 21, 0.10))
    drop-shadow(0 30px 34px rgba(15, 17, 21, 0.07));
}
/* MARKSKUGGAN, i två lager. Formskuggan ovan faller rakt ned och säger inget
   om VAR figuren möter underlaget; det gör de här.

   Samma trappa som formskuggan, fast mot marken: ::before är den breda,
   ljusa och kraftigt suddade ytan som figuren skuggar av rummet omkring sig,
   ::after är den smala mörka kärnan precis under fötterna med nästan ingen
   suddning alls. Det är kontrasten mellan de två som läser som kontakt — en
   enda jämnt suddad ellips ser i stället ut som en fläck under en figur som
   svävar. */
.feat-bot::before,
.feat-bot::after {
  content: "";
  position: absolute;
  z-index: 1;
  left: 50%;
  transform: translateX(-50%);
  border-radius: 50%;
  pointer-events: none;
}
/* Måtten i px, inte %: de ska hålla sig till FOTLINJEN, och procent av en
   ruta som är dubbelt så hög som bred flyttar skuggan så fort roboten skalas.
   Skuggorna ligger bakom bilden (z-index 1 mot 2), så det som syns är det som
   sticker ut utanför siluetten — därför måste de vara bredare än fötterna. */
.feat-bot::before {
  bottom: -7px;
  width: 108%;
  height: 34px;
  background: radial-gradient(50% 50% at 50% 50%,
    rgba(15, 17, 21, 0.22), rgba(15, 17, 21, 0) 72%);
  filter: blur(12px);
}
.feat-bot::after {
  bottom: 1px;
  width: 64%;
  height: 17px;
  background: radial-gradient(50% 50% at 50% 50%,
    rgba(15, 17, 21, 0.50), rgba(15, 17, 21, 0.14) 55%, rgba(15, 17, 21, 0) 78%);
  filter: blur(4px);
}
/* Ljuset ritas här, inte i bilden: glorian i renderingen följde med bort vid
   friläggningen, och två glorior ovanpå varandra läser som en smutsfläck. */
.feat-bot-light {
  position: absolute;
  z-index: 0;          /* bakom både kontaktskuggan och figuren */
  left: 50%;
  bottom: 2%;
  width: 132%;
  aspect-ratio: 1;
  transform: translateX(-50%);
  border-radius: 50%;
  background: radial-gradient(closest-side,
    rgba(104, 217, 144, 0.30), rgba(104, 217, 144, 0) 70%);
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   MÅLSCENEN (.goal-scene)
   Målkortet till vänster, roboten som går till höger, tre skarpa brickor
   runt den. Roboten ligger BAKOM kortet i djupled (z-index 1 mot kortets 2),
   brickorna framför båda.
   -------------------------------------------------------------------------- */
.goal-scene { position: relative; }
.goal-scene .mini-card { position: relative; z-index: 2; }
.goal-bot, .goal-tile { display: none; }

/* 1100 px, inte 900. Reservationen nedan är ABSOLUT (10,5rem) medan kolumnen
   den tas ur är en BRÅKDEL av fönstret. Vid 920 px är visualkolumnen bara
   ~24rem, så roboten hade ätit drygt 40 % av den: målkortet kläms ihop, dess
   makrostaplar halveras, och brickorna hamnar PÅ kortet i stället för runt
   roboten. Under tröskeln står kortet ensamt i sin vanliga bredd, precis som
   den vinkande roboten gör under 1240 px. */
@media (min-width: 1100px) {
  /* Scenen behöver mer bredd än en ensam illustration: kortet OCH roboten ska
     rymmas sida vid sida. Kolumnen är ~36rem vid full bredd, så 32 går in. */
  .feature-goal .feature-visual { max-width: 32rem; }

  /* EN storlek styr scenen. Robotens höjd är det enda handplockade måttet;
     bredden räknas ur friläggningens proportioner (634×1303) och allt annat —
     kortets vaddering och de två brickornas sidled — hängs på den. Skrivna som
     literaler gled de isär så fort roboten eller bilden ändrades. */
  .goal-scene {
    --bot-h: 17.5rem;
    --bot-w: calc(var(--bot-h) * 634 / 1303);
    /* Vadderingen är robotens yta. Kortet krymper till den plats som blir
       kvar, i stället för att roboten läggs ovanpå siffrorna. */
    padding-inline-end: calc(var(--bot-w) + 2rem);
  }

  /* Måttet sätts på HÖJDEN, inte bredden: ramen är mycket smal och hög, och en
     bredd på 10rem hade gjort roboten en halv meter högre än kortet den ska stå
     bredvid. bottom ankrar den vid kortets fot när kortet växer med språket. */
  /* Samma skuggtrappa som den vinkande roboten — se .feat-bot-img för varför
     det är drop-shadow och varför lagren växer. */
  .goal-bot {
    display: block;
    position: absolute;
    inset-inline-end: 1.4rem;
    bottom: -0.5rem;
    z-index: 1;
    height: var(--bot-h);
    width: auto;
    pointer-events: none;
    filter:
      drop-shadow(0 1px 1px rgba(15, 17, 21, 0.18))
      drop-shadow(0 5px 6px rgba(15, 17, 21, 0.13))
      drop-shadow(0 14px 18px rgba(15, 17, 21, 0.10))
      drop-shadow(0 30px 34px rgba(15, 17, 21, 0.07));
  }
  /* Markskuggan under fötterna, samma två lager som den vinkande roboten —
     se .feat-bot::before/::after för varför det är två och inte ett. Måtten
     är bundna till --bot-w och robotens egen placering, så de följer med om
     roboten skalas om. */
  .goal-scene::before,
  .goal-scene::after {
    content: "";
    position: absolute;
    z-index: 0;
    inset-inline-end: calc(1.4rem + var(--bot-w) * 0.5);
    transform: translateX(50%);
    border-radius: 50%;
    pointer-events: none;
  }
  .goal-scene::before {
    bottom: -0.75rem;
    width: calc(var(--bot-w) * 1.15);
    height: 1.5rem;
    background: radial-gradient(50% 50% at 50% 50%,
      rgba(15, 17, 21, 0.16), rgba(15, 17, 21, 0) 72%);
    filter: blur(10px);
  }
  .goal-scene::after {
    bottom: -0.3rem;
    width: calc(var(--bot-w) * 0.6);
    height: 0.7rem;
    background: radial-gradient(50% 50% at 50% 50%,
      rgba(15, 17, 21, 0.42), rgba(15, 17, 21, 0.12) 55%, rgba(15, 17, 21, 0) 78%);
    filter: blur(3.5px);
  }

  /* Samma material som brickorna i hjälten (.tile) — samma radie, samma vita,
     samma skugga — men SKARPA: de i hjälten ligger bakom telefonen och är
     suddiga med flit, dessa ligger framför roboten och ska läsas. */
  .goal-tile {
    display: grid;
    place-items: center;
    position: absolute;
    z-index: 3;
    width: 2.85rem;
    height: 2.85rem;
    border-radius: 26%;
    background: rgba(255, 255, 255, 0.94);
    border: 1px solid rgba(15, 17, 21, 0.05);
    box-shadow:
      0 1px 2px rgba(15, 17, 21, 0.05),
      0 18px 34px -16px rgba(15, 17, 21, 0.22);
    color: var(--kx-green-deep);
    pointer-events: none;
  }
  .goal-tile svg { width: 54%; height: 54%; }
  /* Placerade RUNT roboten, aldrig över ansiktet: kameran uppe till vänster
     där den nätt och jämnt går in över kortets kant, kurvan ute till höger,
     vattnet nere till vänster. De två vänstra följer robotens bredd. */
  .goal-tile-a { inset-inline-end: calc(var(--bot-w) + 0.3rem); top: 2%; }
  .goal-tile-b { inset-inline-end: 0; top: 40%; }
  /* Nere vid kortets underkant, INTE mitt över noten: brickan är dekor och
     får aldrig lägga sig över en rad text som ska gå att läsa. Marginalen är
     satt efter ARABISKAN, som är trängst: där ligger noten på en enda rad som
     fyller kortets hela innehållsbredd, medan övriga språk bryter till två
     kortare rader.

     Måttet är räknat, inte provat fram: kortets högerkant ligger
     (bot-w + 2rem) från scenens högerkant, och brickans vänsterkant ligger
     (inset + 2.85rem) därifrån. inset = bot-w − 0.9rem sätter alltså brickans
     vänsterkant strax UTANFÖR kortet, oavsett språk och bredd.
     OBS riktningen: inset-inline-end mäts från högerkanten, så ett STÖRRE
     värde flyttar brickan åt VÄNSTER, in mot texten. */
  .goal-tile-c { inset-inline-end: calc(var(--bot-w) - 0.9rem); bottom: 1%; }
}

/* Litet kort för illustrationerna. Innehåller MEDVETET inga siffror — det är
   dekor som visar formen på något appen gör, inte en skärmbild. */
.mini-card {
  padding: 1.5rem 1.4rem 1.3rem;
  border: 1px solid rgba(81, 202, 123, 0.18);
  border-radius: var(--r-lg);
  background:
    radial-gradient(120% 150% at 0% 0%, rgba(104, 217, 144, 0.14), rgba(104, 217, 144, 0) 62%),
    #fff;
  box-shadow: var(--sh-card);
}
/* Dämpad med flit: versaler i grönt drar tillbaka mall-looken. Det här är en
   bildtext till illustrationen, inte sidkrom. */
.mini-card-label {
  margin: 0 0 1.05rem;
  font-size: 0.88rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--kx-ink);
}
.mini-card-note { margin: 1rem 0 0; font-size: 0.78rem; line-height: 1.5; color: var(--kx-soft); }

/* Noten och inloggningsknappen på samma rad, knappen i högerkanten. flex-end
   i höjdled så knappen står i linje med notens SISTA rad — noten är två rader
   på engelska och tre på tyskan, och baseline hade flyttat knappen med den. */
.mini-card-foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
}
.mini-card-foot .mini-card-note { flex: 1; min-width: 0; }
/* Knappen får aldrig krympa ihop till radbrytning mitt i ordet; noten ger
   efter i stället (min-width:0 ovan). */
.spark-signin { flex: none; white-space: nowrap; }

/* Smala kort: knappen under noten, fortfarande högerställd. Utan detta pressas
   noten ihop till en spalt på ~40 % på mobil. */
@media (max-width: 40rem) {
  .mini-card-foot { flex-direction: column; align-items: flex-end; gap: 0.6rem; }
  .mini-card-foot .mini-card-note { width: 100%; }
}

.macro-list { display: grid; gap: 0.85rem; }
/* Etikettspalten VÄXER med det längsta ordet i stället för att kapas vid ett
   fast mått. 5.2rem räckte för engelskans "Carbs" men inte för tyskans
   "Kohlenhydrate" (98,7 px), norskans "Karbohydrater" eller spanskans
   "Carbohidratos" — de rann ur spalten och lade sig an mot stapelns ände.
   minmax håller kvar 5.2rem som GOLV, så de fyra raderna står i linje precis
   som förut på de språk som fick plats; auto-delen ger bara efter där ordet är
   längre. Grid-spalten är gemensam för raderna, så staplarna börjar fortfarande
   på samma x. */
.macro-list > li { display: grid; grid-template-columns: minmax(5.2rem, max-content) 1fr; align-items: center; gap: 0.8rem; }
.macro-list span { font-size: 0.87rem; font-weight: 650; color: var(--kx-body); }
.macro-list .bar {
  display: block;
  height: 8px;
  border-radius: var(--r-pill);
  background: rgba(15, 17, 21, 0.06);
  overflow: hidden;
}
.macro-list .bar::after {
  content: "";
  display: block;
  width: var(--fill);
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--kx-green-light), var(--kx-green-deep));
}

.spark { width: 100%; height: auto; display: block; }

/* Rubrikraden i viktkortet: rubrik till vänster, förändringsbricka till höger.
   Marginalen flyttas från rubriken till raden, annars hamnar brickan snett. */
.mini-card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 1.05rem;
}
.mini-card-head .mini-card-label { margin: 0; }

/* Brickan säger TVÅ saker på en gång: hur mycket, och åt vilket håll. Pilen är
   inte dekor — den är samma avläsning som siffrans tecken, för den som läser
   form snabbare än text. */
.spark-stat {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  flex: none;
  padding: 0.22rem 0.55rem;
  border: 1px solid var(--kx-line);
  border-radius: var(--r-pill);
  background: #fff;
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1.3;
  color: var(--kx-soft);
  white-space: nowrap;
}
.spark-stat b { font-weight: 800; color: var(--kx-ink); }
.spark-stat-arrow { width: 0.72em; height: 0.72em; flex: none; }
/* Grönt när vikten rör sig MOT målet, dämpat gult när den rör sig ifrån det —
   samma avläsning som appens [data-trend] på statistikrutorna. Aldrig rött:
   en vägning åt fel håll är information, inte ett fel. */
.spark-stat[data-trend="good"] b,
.spark-stat[data-trend="good"] .spark-stat-arrow { color: var(--kx-green-deep); }
.spark-stat[data-trend="bad"] b,
.spark-stat[data-trend="bad"] .spark-stat-arrow { color: #B0761A; }
.spark-stat[data-dir="up"] .spark-stat-arrow { transform: rotate(180deg); }
.spark-stat[data-dir="flat"] .spark-stat-arrow { transform: rotate(-90deg); }

/* ── Diagrammets överlägg: etiketter och skrubber ──────────────────────────
   Båda ligger i .spark-graph, som är exakt lika stor som SVG:n. Procent, inte
   pixlar: kortet är gummi och SVG:n har height:auto, så varje mått måste följa
   med när bredden ändras — appens px-offsetar hade suttit fel vid varje
   brytpunkt. */
.spark-graph { position: relative; }
/* touch-action: pan-y, INTE none som i appen. Appens diagram sitter på en
   skärm som ändå inte rullar; det här kortet ligger mitt i en lång sida, och
   none hade låst sidrullningen för varje finger som råkade landa på kurvan.
   pan-y ger lodrät rullning till sidan och vågrätt drag till skrubbern. */
.spark-graph.is-scrubbable { touch-action: pan-y; cursor: crosshair; }

.spark-labels { position: absolute; inset: 0; pointer-events: none; }
.spark-label {
  position: absolute;
  transform: translate(-50%, -100%);
  margin-top: -6px;
  padding: 3px 8px;
  border: 1px solid var(--kx-line);
  border-radius: 10px;
  background: #fff;
  box-shadow: 0 4px 12px rgba(15, 17, 21, 0.08);
  font-size: 0.7rem;
  font-weight: 800;
  line-height: 1.2;
  color: var(--kx-ink);
  white-space: nowrap;
  transition: opacity 140ms ease;
}
/* Startvikten står precis där avläsningsrutan dyker upp — kurvans början är
   en trång plats. Den viker undan medan man skrubbar och kommer tillbaka
   efteråt; målvikten ligger långt till höger och får stå kvar. */
.mini-card.is-scrubbing .spark-label { opacity: 0; }
.mini-card.is-scrubbing .spark-label-goal { opacity: 1; }
/* Målvikten sitter PÅ mållinjen, inte ovanför en punkt — därför egen
   centrering i höjdled. Grön fyllning, som i appen. */
.spark-label-goal {
  transform: translate(-50%, -50%);
  margin-top: 0;
  border-color: transparent;
  background: var(--kx-green-deep);
  color: #fff;
}

.spark-scrub {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;               /* pekaren tillhör .spark-graph */
  opacity: 0;
  transition: opacity 140ms ease;
}
.spark-scrub.is-on { opacity: 1; }
.spark-scrub-line {
  position: absolute;
  top: 8%;
  bottom: 6%;
  width: 1.5px;
  transform: translateX(-50%);
  /* Tonar ut i båda ändar — utan det ser linjen ut som en avhuggen pinne. */
  background: linear-gradient(to bottom,
    rgba(91, 100, 114, 0) 0%, rgba(91, 100, 114, 0.42) 14%,
    rgba(91, 100, 114, 0.42) 86%, rgba(91, 100, 114, 0) 100%);
}
.spark-scrub-dot {
  position: absolute;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  background: #fff;
  border: 3px solid var(--kx-green-deep);
  box-shadow: 0 2px 8px rgba(15, 17, 21, 0.2);
}
.spark-scrub-tip {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  padding: 4px 10px;
  border: 1px solid var(--kx-line);
  border-radius: 10px;
  background: #fff;
  box-shadow: 0 6px 18px rgba(15, 17, 21, 0.14);
  white-space: nowrap;
}
.spark-scrub-date { font-size: 0.62rem; font-weight: 700; letter-spacing: 0.02em; color: var(--kx-soft); }
.spark-scrub-val  { font-size: 0.78rem; font-weight: 800; color: var(--kx-ink); }

/* Kortet svävar med cardFloat. Under ett drag måste det stå still, annars
   glider pricken ifrån fingret medan man läser av. */
.mini-card.is-scrubbing { animation-play-state: paused; }

/* Prognoslinjen — samma streckade språk som appens .progress-future-line, så
   kortet och Utveckling-fliken säger samma sak om samma data. */
.spark-future {
  stroke: rgba(81, 202, 123, 0.55);
  stroke-width: 2.2;
  stroke-dasharray: 4 5;
  stroke-linecap: round;
}

.lang-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.5rem; }
.lang-grid > li {
  border: 1px solid var(--kx-line);
  border-radius: var(--r-sm);
  background: #fff;
  font-size: 0.9rem;
  font-weight: 650;
  color: var(--kx-body);
  text-align: center;
}
/* Rutorna BYTER språk — de är knappar, inte etiketter. Vaddningen sitter på
   knappen, inte på <li>: vågen nedan mäter sitt radavstånd i procent av
   knappens höjd, och då måste knappen fylla hela rutan. */
.lang-grid > li > button {
  display: block;
  width: 100%;
  padding: 0.65rem 0.9rem;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: inherit;
  cursor: pointer;
}
/* Valt språk. Bara ram och botten på <li> — texten lämnas åt vågen, annars
   blir den valda rutan ett hål i svepet. */
.lang-grid > li.is-current {
  border-color: rgba(81, 202, 123, 0.55);
  background: rgba(104, 217, 144, 0.09);
}
@media (min-width: 520px) { .lang-grid { grid-template-columns: repeat(3, 1fr); } }


/* --------------------------------------------------------------------------
   LEVANDE FUNKTIONSBLOCK
   Avsnittet stod stilla och kändes tomt. Två sorters rörelse läggs till:

   VILOPULS — går hela tiden, långsamt och lågmält. Varje illustration har
   sin egen puls med lång cykel (14–34 s) och stegvisa fördröjningar, så att
   ögat fångar EN sak i taget i stället för att allt blinkar samtidigt.

   SVAR PÅ PEKARE — bara @media (hover: hover), aldrig på touch där :hover
   fastnar. Sken följer muspekaren via --mx/--my som sätts i site.js.

   Vilopulsen ligger genomgående på ::after-lager och egna element, ALDRIG på
   samma egenskap som hovringen använder — annars vinner animationen över
   övergången och hovringen tar inte.
   -------------------------------------------------------------------------- */
.feat-aurora {
  right: -16%;
  top: 4%;
  width: 44rem;
  height: 44rem;
  background: radial-gradient(46% 46% at 50% 50%, rgba(104, 217, 144, 0.17), rgba(104, 217, 144, 0) 70%);
  filter: blur(16px);
  animation: featDrift 34s var(--kx-ease-glide) infinite alternate;
}
@keyframes featDrift {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(-5rem, 3.5rem, 0) scale(1.14); }
}

/* Siffrorna: en i taget lyfter och ljusnar, i samma lugna takt som chipsen. */
.glance {
  position: relative;
  overflow: hidden;
  animation: cardFloat 15s ease-in-out infinite;
  transition: box-shadow 0.45s var(--kx-ease-out), border-color 0.45s var(--kx-ease-out);
}
.glance::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(18rem 18rem at var(--mx, 50%) var(--my, 0%),
    rgba(104, 217, 144, 0.2), rgba(104, 217, 144, 0) 60%);
  transition: opacity 0.45s var(--kx-ease-out);
}
.glance > * { position: relative; z-index: 1; }
.glance-hero b, .glance-flame { display: inline-block; }
.glance-hero b { animation: glanceNum 12s var(--kx-ease-out) infinite; }
/* Lågan lever hela tiden — den är kortets puls, som i appen. */
.glance-flame { animation: flameFlicker 4.2s ease-in-out infinite; transform-origin: 50% 85%; }
.glance-rows b { animation: glanceRowNum 12s var(--kx-ease-out) infinite; }
.glance-rows > li:nth-child(1) b { animation-delay: 4s; }
.glance-rows > li:nth-child(2) b { animation-delay: 8s; }
@keyframes glanceNum {
  0%, 100% { transform: none; color: var(--kx-green-deep); text-shadow: none; }
  5%       { transform: translateY(-3px) scale(1.05); color: #35c26f;
             text-shadow: 0 12px 22px rgba(53, 194, 111, 0.35); }
  17%      { transform: none; color: var(--kx-green-deep); text-shadow: none; }
}
@keyframes glanceRowNum {
  0%, 100% { color: var(--kx-ink); }
  5%       { color: var(--kx-green-deep); }
  17%      { color: var(--kx-ink); }
}
@keyframes flameFlicker {
  0%, 100% { transform: scale(1) rotate(0deg); }
  28%      { transform: scale(1.09) rotate(-3deg); }
  62%      { transform: scale(0.97) rotate(2.5deg); }
}

/* Chipsen: ett i taget tänds i en långsam runda. */
.chips > li {
  position: relative;
  transition: transform 0.4s var(--kx-ease-out),
              box-shadow 0.4s var(--kx-ease-out),
              border-color 0.4s var(--kx-ease-out),
              margin 0.5s var(--kx-ease-glide),
              /* Korten tonas in ett och ett av site.js (REVEAL). [data-rv]
                 sätter en egen opacity-övergång, men den här regeln är mer
                 specifik och skriver över hela transition-listan — utan
                 opacity HÄR poppar korten fram i stället för att tona. */
              opacity 0.6s var(--kx-ease-out);
}
.chips > li::after {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  border: 1px solid rgba(81, 202, 123, 0.42);
  background: radial-gradient(120% 180% at 4% 50%, rgba(104, 217, 144, 0.14), rgba(104, 217, 144, 0) 62%);
  box-shadow: 0 14px 30px -18px rgba(81, 202, 123, 0.9), 0 0 0 4px rgba(81, 202, 123, 0.08);
  animation: softGlow 14s var(--kx-ease-out) infinite;
}
.chips > li:nth-child(2)::after { animation-delay: 3.5s; }
.chips > li:nth-child(3)::after { animation-delay: 7s; }
.chips > li:nth-child(4)::after { animation-delay: 10.5s; }

.chip-ico { animation: chipIco 14s var(--kx-ease-out) infinite; }
.chips > li:nth-child(2) .chip-ico { animation-delay: 3.5s; }
.chips > li:nth-child(3) .chip-ico { animation-delay: 7s; }
.chips > li:nth-child(4) .chip-ico { animation-delay: 10.5s; }
.chip-ico svg { transition: transform 0.4s var(--kx-ease-glide); }

@keyframes softGlow {
  0%, 100% { opacity: 0; }
  4%       { opacity: 1; }
  15%      { opacity: 0; }
}
@keyframes chipIco {
  0%, 100% { transform: none; background-color: rgba(81, 202, 123, 0.12); }
  4%       { transform: scale(1.09); background-color: rgba(81, 202, 123, 0.24); }
  15%      { transform: none; background-color: rgba(81, 202, 123, 0.12); }
}

/* Staplarna andas och får ett ljus som sveper genom fyllningen. */
.macro-list .bar::after {
  transform-origin: left center;
  background-image:
    linear-gradient(90deg, rgba(255, 255, 255, 0) 38%, rgba(255, 255, 255, 0.5) 50%, rgba(255, 255, 255, 0) 62%),
    linear-gradient(90deg, var(--kx-green-light), var(--kx-green-deep));
  background-size: 260% 100%, 100% 100%;
  background-repeat: no-repeat;
  /* Skenet måste gå LINJÄRT — med ease-out är det framme på en tiondel av
     tiden och står sedan still, vilket läser som en glitch, inte en rörelse. */
  animation: barBreathe 8s ease-in-out infinite, barSheen 8s linear infinite;
}
.macro-list > li:nth-child(2) .bar::after { animation-delay: 0.7s, 0.7s; }
.macro-list > li:nth-child(3) .bar::after { animation-delay: 1.4s, 1.4s; }
.macro-list > li:nth-child(4) .bar::after { animation-delay: 2.1s, 2.1s; }
@keyframes barBreathe {
  0%, 100% { transform: scaleX(0.955); }
  50%      { transform: scaleX(1); }
}
@keyframes barSheen {
  0%       { background-position: 165% 0, 0 0; }
  55%, 100% { background-position: -75% 0, 0 0; }
}

/* Kurvan: en ljusprick vandrar längs linjen, slutpunkten andas en ring. */
.spark-trace {
  stroke: #B4F0CC;
  stroke-dasharray: 16 100;
  stroke-dashoffset: 16;
  opacity: 0;
  animation: sparkTrace 11s linear infinite;
}
@keyframes sparkTrace {
  0%        { stroke-dashoffset: 16; opacity: 0; }
  6%        { opacity: 0.95; }
  56%       { opacity: 0.95; }
  64%, 100% { stroke-dashoffset: -100; opacity: 0; }
}
.spark-ping {
  transform-box: view-box;
  transform-origin: 254px 76px;
  animation: sparkPing 11s var(--kx-ease-out) infinite;
}
@keyframes sparkPing {
  0%, 62%   { transform: scale(1); opacity: 0; }
  72%       { opacity: 0.7; }
  92%, 100% { transform: scale(2.6); opacity: 0; }
}

/* Språkrutorna: en grön våg sveper diagonalt genom rutnätet — den träffar
   English, sedan Svenska+Dansk, sedan Norsk+Suomi+Français, och så vidare
   tills bara العربية är kvar i hörnet. Fördröjningen per ruta är dess
   diagonal (rad + kolumn) gånger --wave-step, satt via --wd på varje <li>. */
.lang-grid {
  /* Vågen mäts i RUTNÄTETS koordinater, inte i varje rutas egna — det är hela
     poängen. Mönsterbilden görs --wave-n kolumnavstånd bred och lika många
     radavstånd hög, och `to bottom right` lägger då gradientens jämnfaslinje
     genom de andra två hörnen. Ett steg åt höger väger alltså exakt lika
     mycket som ett steg neråt, vilket är precis villkoret för att Svenska och
     Dansk ska träffas samtidigt. Bandet får därmed samma lutning som vågfronten
     i ALLA rutor, i stället för att varje ruta ha sitt eget lilla svep.

     Fördröjningen dras av ett helt varv och blir NEGATIV. Med positiv
     fördröjning står rutan kvar på utgångsläget tills dess tur kommer, och
     utgångsläget råkar vara krönets kant — då syns en grön fläck i varje rutas
     övre vänstra hörn de första sekunderna. Negativ fördröjning ger samma fas
     men låter alla rutor rulla direkt.

     Rutans fördröjning (--wd) flyttar mönstret exakt ett diagonalsteg, och
     eftersom ett steg = ett kolumnavstånd blir fasen kontinuerlig rakt över
     mellanrummen: skillnaden mellan rutkant och grannens kant blir gapet, som
     sig bör.

     --wave-n sätts en diagonal högre än rutnätet är djupt (7 diagonaler i två
     kolumner, 6 i tre), så vågen hinner lämna العربية innan nästa kommer in i
     English.

     Gradienten MÅSTE vara repeating- med perioden 50% av gradientlinjen. En
     vanlig linear-gradient är inte periodisk: hörnregeln ovan gör att ett steg
     på en hel bildbredd flyttar fasen exakt en halv gradientlinje, så när
     bakgrunden kaklas hoppar fasen ett halvt varv vid varje skarv och krönet
     får en hård kant mitt i rutan. Med perioden 50% går skarven jämnt upp. */
  --wave-n: 9;
  --wave-step: 0.6s;
  --wave-cycle: calc(var(--wave-n) * var(--wave-step));
  --wave-col: calc((100cqw + 0.5rem) / 2);           /* kolumnavstånd = ruta + gap */
  --wave-x: calc(var(--wave-n) * var(--wave-col));
  /* Radavstånd i procent av spannets höjd. + 2px är rutans ram, som spannet
     ligger innanför — utan den blir mönstret en aning för lågt och lutningen
     stämmer inte med kolumnavståndet. */
  --wave-y: calc(var(--wave-n) * (100% + 0.5rem + 2px));
}
.lang-grid > li {
  position: relative;
  --wd: 0s;
  transition: transform 0.4s var(--kx-ease-out),
              box-shadow 0.4s var(--kx-ease-out),
              border-color 0.4s var(--kx-ease-out);
}
/* cqw kräver en container. Faller stödet bort blir --wave-x ogiltig, och då
   måste texten ha kvar sin vanliga färg — annars står rutorna tomma. Därför
   ligger allt som gör texten genomskinlig bakom samma @supports. */
@supports (container-type: inline-size) {
  .lang-grid { container-type: inline-size; }

  .lang-grid > li > button {
    /* Krönet ligger vid periodens kant (0 = 50%), så varvet börjar med vågen
       i English i stället för mitt i rutnätet. Stoppen räknas i procent av
       gradientlinjen, där 6.25% = ett diagonalsteg = en kolumnbredd. Kärnan
       håller full grönska en bit och trappas sedan av — det ger starkast färg
       mitt i vågen och svagast längst ut. De ensamma procenttalen är
       gradientens interpolationstips (halvvägspunkten), inte färgstopp: de
       skjuter avtrappningen utåt utan att någon blandfärg behöver hårdkodas. */
    background-image: repeating-linear-gradient(to bottom right,
      var(--kx-green-ink) 0 1%,
      3.2%,
      var(--kx-body) 4.6% 45.4%,
      46.8%,
      var(--kx-green-ink) 49% 50%);
    background-size: var(--wave-x) var(--wave-y);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
    animation: langWave var(--wave-cycle) linear infinite;
    animation-delay: calc(var(--wd) - var(--wave-cycle));
  }
  /* Skenet: samma mönster och samma fas, bara bredare och mjukare. Måste ha
     inset 0 — med -1px blir dess ruta 2px större än spannets och lutningen
     skulle skilja sig från textens. */
  .lang-grid > li::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    background-image: repeating-linear-gradient(to bottom right,
      rgba(104, 217, 144, 0.30) 0 1%,
      rgba(104, 217, 144, 0.20) 2.8%,
      rgba(104, 217, 144, 0.09) 4.8%,
      rgba(104, 217, 144, 0)    7.5% 42.5%,
      rgba(104, 217, 144, 0.09) 45.2%,
      rgba(104, 217, 144, 0.20) 47.2%,
      rgba(104, 217, 144, 0.30) 49% 50%);
    background-size: var(--wave-x) var(--wave-y);
    animation: langWave var(--wave-cycle) linear infinite;
    animation-delay: calc(var(--wd) - var(--wave-cycle));
  }
}
/* Ett varv = exakt en mönsterbredd, så slutet möter början utan skarv och
   loopen behöver ingen paus. Linjär takt är inte kosmetik: minsta easing
   bryter överlämningen mellan rutor och vågen blir hackig. */
@keyframes langWave {
  from { background-position-x: 0; }
  to   { background-position-x: var(--wave-x); }
}

/* Två kolumner (mobil): diagonal = floor((n-1)/2) + (n-1)%2 */
.lang-grid > li:nth-child(1)  { --wd: 0s; }
.lang-grid > li:nth-child(2),
.lang-grid > li:nth-child(3)  { --wd: calc(var(--wave-step) * 1); }
.lang-grid > li:nth-child(4),
.lang-grid > li:nth-child(5)  { --wd: calc(var(--wave-step) * 2); }
.lang-grid > li:nth-child(6),
.lang-grid > li:nth-child(7)  { --wd: calc(var(--wave-step) * 3); }
.lang-grid > li:nth-child(8),
.lang-grid > li:nth-child(9)  { --wd: calc(var(--wave-step) * 4); }
.lang-grid > li:nth-child(10),
.lang-grid > li:nth-child(11) { --wd: calc(var(--wave-step) * 5); }
.lang-grid > li:nth-child(12) { --wd: calc(var(--wave-step) * 6); }

/* Tre kolumner: diagonal = floor((n-1)/3) + (n-1)%3 */
@media (min-width: 520px) {
  /* Tre kolumner ger ett smalare kolumnavstånd och en diagonal mindre att
     resa igenom, så både mönsterbredden och varvet krymper. */
  .lang-grid {
    --wave-n: 8;
    --wave-col: calc((100cqw + 0.5rem) / 3);
  }
  .lang-grid > li:nth-child(1)  { --wd: 0s; }                          /* English */
  .lang-grid > li:nth-child(2),                                        /* Svenska */
  .lang-grid > li:nth-child(4)  { --wd: calc(var(--wave-step) * 1); }  /* Dansk   */
  .lang-grid > li:nth-child(3),                                        /* Norsk   */
  .lang-grid > li:nth-child(5),                                        /* Suomi   */
  .lang-grid > li:nth-child(7)  { --wd: calc(var(--wave-step) * 2); }  /* Français */
  .lang-grid > li:nth-child(6),                                        /* Deutsch */
  .lang-grid > li:nth-child(8),                                        /* Español */
  .lang-grid > li:nth-child(10) { --wd: calc(var(--wave-step) * 3); }  /* Türkçe  */
  .lang-grid > li:nth-child(9),                                        /* Italiano */
  .lang-grid > li:nth-child(11) { --wd: calc(var(--wave-step) * 4); }  /* Русский */
  .lang-grid > li:nth-child(12) { --wd: calc(var(--wave-step) * 5); }  /* العربية */
}

/* Illustrationskorten svävar långsamt och får ett sken under pekaren.
   Flytet ligger på transform, hovringen rör bara ram och skugga. */
.mini-card {
  position: relative;
  overflow: hidden;
  animation: cardFloat 13s ease-in-out infinite;
  transition: box-shadow 0.45s var(--kx-ease-out), border-color 0.45s var(--kx-ease-out);
}
/* De två korten får aldrig sväva i takt — det läser som att sidan guppar. */
.feature-flip .mini-card { animation-delay: -5.5s; }
.mini-card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(18rem 18rem at var(--mx, 50%) var(--my, 0%),
    rgba(104, 217, 144, 0.22), rgba(104, 217, 144, 0) 60%);
  transition: opacity 0.45s var(--kx-ease-out);
}
.mini-card > * { position: relative; z-index: 1; }
@keyframes cardFloat {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-6px); }
}

@media (hover: hover) {
  /* Lyftet gäller bara stängda chips — ett öppet kort har redan sin egen
     grönare ram och djupare skugga, och hovern skulle bara släcka dem. */
  .chips > li:not(.is-open):hover {
    transform: translateY(-2px);
    border-color: rgba(81, 202, 123, 0.34);
    box-shadow: 0 18px 32px -22px rgba(81, 202, 123, 0.85), var(--sh-card);
  }
  .chips > li:hover .chip-ico svg { transform: scale(1.12); }

  .lang-grid > li:hover {
    transform: translateY(-2px);
    border-color: rgba(81, 202, 123, 0.34);
    box-shadow: 0 14px 26px -20px rgba(81, 202, 123, 0.85);
  }

  .mini-card:hover, .glance:hover {
    border-color: rgba(81, 202, 123, 0.38);
    box-shadow: 0 1px 2px rgba(15, 17, 21, 0.04), 0 26px 50px -28px rgba(81, 202, 123, 0.55);
  }
  .mini-card:hover::before, .glance:hover::before { opacity: 1; }
}


/* ==========================================================================
   8. INTEGRITET OCH ÄRLIGHET
   ========================================================================== */
.shell-privacy {
  background:
    radial-gradient(80% 60% at 88% 4%, rgba(104, 217, 144, 0.12), rgba(104, 217, 144, 0) 60%),
    linear-gradient(180deg, #FCFEFD 0%, #F3FAF6 100%);
}
.priv-aurora {
  right: -12%;
  top: -18%;
  width: 38rem;
  height: 30rem;
  background: radial-gradient(46% 46% at 50% 50%, rgba(150, 235, 174, 0.24), rgba(150, 235, 174, 0) 70%);
  filter: blur(14px);
}

.priv-grid { display: grid; gap: 1rem; }
.priv-card {
  padding: 1.6rem 1.5rem;
  border: 1px solid rgba(81, 202, 123, 0.2);
  border-radius: var(--r-lg);
  background: #fff;
  box-shadow: var(--sh-card);
}
.priv-card h3 { margin-bottom: 0.55rem; }
/* margin-top sätts MEDVETET inte här. Regeln är (0-1-1) och skulle annars slå
   .priv-tag { margin-top: auto } längre ned, som är (0-1-0) — märkningen föll
   då tillbaka mot texten i stället för att tryckas ned i kortets fot. Den
   globala p-reseten ger redan margin-top: 0, och den är (0-0-1) och förlorar
   mot märkningen, som avsett. */
.priv-card p { color: var(--kx-soft); margin-bottom: 1.15rem; }
.priv-card p:last-child { margin-bottom: 0; }

/* Huvudkortet — kroppsfotona är sidans starkaste integritetspåstående. */
.priv-card-lead {
  background:
    radial-gradient(110% 160% at 0% 0%, rgba(104, 217, 144, 0.18), rgba(104, 217, 144, 0) 60%),
    var(--kx-mint);
  border-color: rgba(81, 202, 123, 0.3);
}
.priv-card-lead h3 { font-size: 1.32rem; }
.priv-card-lead p { color: var(--kx-body); max-width: 42rem; }

.priv-ico {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  margin-bottom: 1rem;
  border-radius: var(--r-sm);
  background: rgba(81, 202, 123, 0.14);
  color: var(--kx-green-ink);
}
.priv-ico svg { width: 22px; height: 22px; }

/* --------------------------------------------------------------------------
   MÄRKET ÖVER RUBRIKEN OCH MÄRKNINGARNA I KORTEN
   Samma kapsel i två storlekar. Materialet är lånat från .spark-stat — vit
   botten, hårfin ram, --r-pill — så att det läser som samma familj som
   siffermärkningen i viktkortet, inte som en ny komponent.
   -------------------------------------------------------------------------- */
.priv-badge,
.priv-tag {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  border-radius: var(--r-pill);
  background: #fff;
  border: 1px solid var(--kx-line);
  color: var(--kx-green-ink);
  font-weight: 650;
  line-height: 1.3;
}
.priv-badge {
  margin-bottom: 1.1rem;
  padding: 0.4rem 0.9rem 0.4rem 0.7rem;
  font-size: 0.86rem;
  border-color: rgba(81, 202, 123, 0.3);
  box-shadow: 0 2px 10px rgba(15, 17, 21, 0.04);
}
.priv-badge svg { width: 17px; height: 17px; flex: none; }

/* Märkningen sitter i kortets fot. margin-top: auto trycker ned den mot
   underkanten så att alla tre korten får sina märkningar på samma linje —
   .priv-grid sträcker korten till lika höjd, men texterna är olika långa. */
/* --r-md, inte --r-pill. En radie är alltid kapad till halva elementets höjd,
   så på en ENRADIG märkning (~30 px hög) ger 18px exakt samma helrunda ändar
   som 999px — ingen synlig skillnad. Men de längsta märkningarna bryts till två
   rader i elva av tolv språk mellan 760 och 1280 px, där korten är smala, och
   DÅ blir full pillerradie en klump. Med den här radien läser den som en
   etikett i stället, oavsett antal rader. */
.priv-tag {
  align-self: flex-start;
  padding: 0.34rem 0.75rem 0.34rem 0.6rem;
  border-radius: var(--r-md);
  font-size: 0.8rem;
}
/* Bryts den ändå ska raderna bli jämna i stället för att lämna ett ensamt ord
   sist. Gäller alla bredder, inte bara telefon. */
.priv-tag > span { text-wrap: balance; }
.priv-tag svg { width: 15px; height: 15px; flex: none; }
/* Smala telefoner. De längsta märkningarna — "Inga annonsprofiler. Inga
   annonser." och dess tyska, finska, franska och ryska motsvarigheter — bröts
   till två rader i ett kort på 360 px, och en kapsel med full pillerradie ser
   ut som en klump när den blir tvåradig. Något mindre grad och stramare
   vaddering räcker för att de ska rymmas på en rad. Skulle en översättning
   ändå bryta balanserar text-wrap raderna i stället för att lämna ett ensamt
   ord på rad två. */
@media (max-width: 460px) {
  .priv-card .priv-tag { font-size: 0.75rem; padding: 0.3rem 0.62rem 0.3rem 0.5rem; gap: 0.38rem; }
  .priv-tag svg { width: 14px; height: 14px; }
}

/* ARABISKAN. site.js sätter dir="rtl" på det element som bär data-i18n, och i
   de här kapslarna är det den INRE spannen — flexbehållaren förblir alltså
   ltr, och ikonen blev kvar till vänster om högerställd arabisk text. Samma
   sak i listrubriken och löftesrutan.
   Bocklistan behöver INGEN sådan regel: där sitter data-i18n på <li>:n själv,
   som också är flexbehållaren, så den vänder av sig själv. Att de två
   fungerade olika var precis det som syntes i kortet — stapelikonen till
   vänster medan bockarna under stod till höger.
   Kapslarna måste dessutom fästa i motsatt kant, annars hänger de kvar längst
   ut till vänster under en högerställd text. */
html[lang="ar"] .priv-badge,
html[lang="ar"] .priv-tag,
html[lang="ar"] .honest-list-t,
html[lang="ar"] .honest-promise { flex-direction: row-reverse; }
/* Märket är inline-flex i ett vanligt block, inte ett flexobjekt — align-self
   biter inte på det. Dess placering styrs av blockets textriktning, så den
   sätts på behållaren. Rubriken och ingressen där inne är redan högerställda
   via sin egen dir, så raden ändrar bara märkets läge. */
html[lang="ar"] .priv-head .section-head { text-align: right; }
html[lang="ar"] .priv-card .priv-tag { align-self: flex-end; }
html[lang="ar"] .priv-lead-body { align-items: flex-end; }
/* Bara rutnätskorten trycker ned sin märkning: där sträcks korten till lika
   höjd och märkningarna ska hamna på samma linje. Ledkortet har ingen granne
   att linjera mot och får ett vanligt avstånd i stället (se .priv-lead-body).
   Att skriva .priv-grid i selektorn i stället för att lita på källordningen
   gör den avsikten läsbar — de två reglerna har annars samma specificitet. */
.priv-grid .priv-tag { margin-top: auto; }
/* Färgen måste vinna över .priv-card p och .priv-card-lead p, som båda är
   (0-1-1) och sätter grått respektive brödtextsfärg. Utan den här raden
   renderades märkningarna i två olika gråtoner medan koden sa grönt. */
.priv-card .priv-tag { color: var(--kx-green-ink); }
/* Korten blir flexspalter enbart för att fotmarginalen ovan ska ha något att
   trycka mot. Utan detta faller margin-top: auto tillbaka på 0. */
.priv-card { display: flex; flex-direction: column; }

/* --------------------------------------------------------------------------
   ÄRLIGHETSBLOCKET
   Var tidigare en linje och en textspalt, medvetet ("en eftertanke, inte en
   till funktion"). Är nu ett eget tonat kort med robot och checklista, enligt
   designreferensen. Linjen är därför borta — kortets egen kant avgränsar.
   -------------------------------------------------------------------------- */
.honest {
  margin-top: clamp(2rem, 1.4rem + 2vw, 3rem);
  padding: clamp(1.6rem, 1.1rem + 1.8vw, 2.4rem);
  border: 1px solid rgba(81, 202, 123, 0.26);
  border-radius: var(--r-lg);
  background:
    radial-gradient(90% 130% at 0% 0%, rgba(104, 217, 144, 0.16), rgba(104, 217, 144, 0) 62%),
    var(--kx-mint);
  display: grid;
  gap: clamp(1.5rem, 1rem + 2vw, 2.75rem);
}
.honest h3 { font-size: clamp(1.15rem, 1rem + 0.6vw, 1.45rem); margin-bottom: 0.75rem; letter-spacing: -0.024em; }
.honest p { color: var(--kx-soft); }
/* Taket för radlängden följer med texten in i sin egen spalt. Det binder inte i
   praktiken — gridspalten är smalare än 42rem vid varje bredd — men står kvar
   som skydd om spaltförhållandet någon gång ändras. */
.honest-text { max-width: var(--w-prose); }
.priv-more { margin-top: 1rem; font-size: 0.95rem; }

/* Roboten och checklistan. Roboten står bakom listkortets vänsterkant. */
.honest-visual { display: grid; }
.honest-bot { display: none; }
.honest-list {
  width: 100%;
  padding: 1.1rem 1.15rem 1.2rem;
  border: 1px solid rgba(81, 202, 123, 0.2);
  border-radius: var(--r-md);
  background: #fff;
  box-shadow: var(--sh-card);
}
/* .honest i selektorn, inte !important: den enda motståndaren är
   .honest p { color: var(--kx-soft) }, som är (0-1-1). Två klasser räcker. */
.honest .honest-list-t {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.9rem;
  font-size: 0.92rem;
  font-weight: 700;
  color: var(--kx-ink);
  line-height: 1.35;
}
.honest-list-ico {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  flex: none;
  border-radius: 9px;
  background: rgba(81, 202, 123, 0.14);
  color: var(--kx-green-ink);
}
.honest-list-ico svg { width: 17px; height: 17px; }

/* Bocklistan. Samma bock som .hero-trust: ritad som data-URI i ::before i
   stället för ett svg-element per rad, vilket skulle vara fyra extra noder
   utan eget innehåll. CSP:n tillåter img-src data: — se site/_headers. */
/* Själva bocken ritas av den delade regeln i avsnitt 3 (.hero-trust li::before,
   .check-list li::before) — här står bara listans egen typografi. */
.check-list { display: grid; gap: 0.6rem; font-size: 0.88rem; color: var(--kx-soft); }
/* flex-start, inte center: bryts en rad ska bocken stå vid FÖRSTA raden, inte
   sväva mitt emellan de två. Toppmarginalen centrerar den mot första radens
   x-höjd. */
.check-list li { display: flex; align-items: flex-start; gap: 0.55rem; }
.check-list li::before { margin-top: 0.12rem; }

/* Löftesrutan. Tonad, inte vit — den är en avslutning på blocket, inte ett
   femte kort. */
.honest-promise {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  margin-top: 1.35rem;
  padding: 0.9rem 1.05rem;
  border: 1px solid rgba(81, 202, 123, 0.24);
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, 0.72);
  font-size: 0.92rem;
  line-height: 1.6;
}
.honest-promise strong { color: var(--kx-ink); font-weight: 700; }
.honest-promise-ico {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  flex: none;
  margin-top: 0.05rem;
  border-radius: 50%;
  background: rgba(81, 202, 123, 0.16);
  color: var(--kx-green-ink);
}
.honest-promise-ico svg { width: 15px; height: 15px; }

@media (min-width: 760px) {
  /* Tre kort nu, inte fyra: ledkortet har flyttat upp till rubrikraden, så
     regeln .priv-card-lead { grid-column: 1 / -1 } behövs inte längre. */
  .priv-grid { grid-template-columns: repeat(3, 1fr); gap: 1.15rem; }
}

/* --------------------------------------------------------------------------
   RUBRIKRADEN: text till vänster, ledkortet till höger.

   Basreglerna står FÖRE sina media queries. Media queries ger ingen extra
   specificitet, så en basregel som skrivs efteråt vinner på källordning och
   tystar skrivbordsläget helt — bilden nedan låg först på 156 px i stället för
   sina 272, utan att något syntes fel i koden.
   -------------------------------------------------------------------------- */
.priv-lead-body { display: flex; flex-direction: column; align-items: flex-start; }
.priv-lead-body .priv-tag { margin-top: 1.15rem; }
.priv-shot {
  display: block;
  width: min(13rem, 60%);
  height: auto;
  margin: 1.25rem auto 0;
  /* Glöden runt siluetten. Friläggningen tog bort renderingens egna ljus kring
     skölden; drop-shadow lägger tillbaka ett grönt sken — runt HELA figuren,
     inte bara skölden, vilket är det som får den att lyfta från kortet. */
  filter:
    drop-shadow(0 0 18px rgba(104, 217, 144, 0.45))
    drop-shadow(0 6px 10px rgba(15, 17, 21, 0.10))
    drop-shadow(0 22px 30px rgba(15, 17, 21, 0.08));
}

.priv-head { display: grid; gap: clamp(1.75rem, 1rem + 3vw, 3rem); margin-bottom: clamp(1.25rem, 0.9rem + 1.4vw, 2rem); }
/* Nollas vid ALLA bredder, inte bara på skrivbord. .section-head bär en egen
   margin-bottom på 36–56 px, och i enspaltsläget lades den ovanpå .priv-head:s
   gap — tillsammans 64–94 px tomt band mellan ingressen och första kortet, på
   varje telefon- och surfplattebredd. Avståndet ska komma från gapet, en gång. */
.priv-head .section-head { margin-bottom: 0; }

/* 1200, inte 1000: vid 1000 delas rubrikraden OCH ledkortet i samma steg, och
   den inre delningen lämnade brödtexten i en 158 px-spalt där den bröts på
   tjugo rader. Kortet delas alltså först när det finns bredd till båda.
   Bildspåret sätts UTTRYCKLIGT till 17rem. Med auto + min(13rem, 60%) kunde
   procenten inte lösas mot ett obestämt spår: spåret dimensionerades efter
   bildens naturliga bidrag medan bilden ritades på 60 % av det, vilket lämnade
   drygt hundra pixlar död yta bredvid en text som samtidigt trängdes. */
/* EN brytpunkt för hela rubrikraden — både spaltdelningen och kortets inre
   delning sker vid 1200. Med rubrikraden delad vid 1000 men kortet enspaltigt
   till 1200 uppstod ett band där ett dubbelt så högt kort stod bredvid en
   centrerad rubrik: 446 px tom vänsterspalt vid 1000, 412 vid 1100. Nu är allt
   staplat under tröskeln och allt delat över den.

   HÖGERkanterna är det som linjerar mellan avsnitten, inte spaltdelningen:
   .feat-head är 1.08fr/1fr och den här 0.9fr/1.1fr, alltså spegelvänt
   förhållande. Ytterkanterna sammanfaller ändå, och det är den kant besökaren
   läser panelen efter.

   Kortets inre spår är ANDELAR, inte ett fast bildmått. Med 17rem fast åt
   bilden blev textspalten 220 px och tyskan bröts på fjorton rader medan bilden
   låg lika bred hur trångt det än blev. Andelar låter de två krympa ihop. */
@media (min-width: 1200px) {
  .priv-head { grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); align-items: center; }
  .priv-card-lead { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); gap: 1.4rem; align-items: center; }
  .priv-shot { width: 100%; margin: 0; }
}

/* 1280, inte 900 och inte 1100. Roboten tar 192 px ur vänsterspalten, så
   listkortet blev 144 px vid 900 och fortfarande bara 209 px vid 1100 — där
   bröts bockraderna i tio av tolv språk, och franskan och italienskan bröt alla
   fyra. Kortet växte då på höjden och dess överkant klättrade upp i robotens
   lyfta hand, som kapades mitt itu av kortkanten i stället för att ligga
   framför den. Vid 1280 är kortet 283 px, varje bockrad ryms på en rad i
   samtliga språk, och handen ligger fritt ovanför kortet.
   Under tröskeln står listkortet ensamt i full bredd och roboten är dold. */
@media (min-width: 1280px) {
  /* Uttrycklig placering, inte order: rubriken är ett eget barn och måste
     hamna ÖVER texten i högerspalten medan bilddelen spänner båda raderna till
     vänster. Med order hade allt legat i en enda ordning och rubriken hamnat
     bredvid checklistan i stället för ovanför sin egen text. */
  .honest {
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    grid-template-rows: auto 1fr;
    align-items: start;
    column-gap: clamp(1.5rem, 1rem + 2vw, 2.75rem);
    row-gap: 0.75rem;
  }
  .honest > h3        { grid-column: 2; grid-row: 1; }
  .honest-text        { grid-column: 2; grid-row: 2; }
  .honest-visual      { grid-column: 1; grid-row: 1 / span 2; align-self: center;
                        grid-template-columns: auto minmax(0, 1fr); align-items: center; }
  .honest-bot {
    display: block;
    position: relative;
    z-index: 1;
    width: 12rem;
    height: auto;
    pointer-events: none;
    /* Samma skuggtrappa som de andra robotarna, se .feat-bot-img. */
    filter:
      drop-shadow(0 1px 1px rgba(15, 17, 21, 0.18))
      drop-shadow(0 5px 6px rgba(15, 17, 21, 0.13))
      drop-shadow(0 14px 18px rgba(15, 17, 21, 0.10))
      drop-shadow(0 30px 34px rgba(15, 17, 21, 0.07));
  }
  /* Överlappet läggs på KORTET, inte på roboten. En negativ marginal på
     roboten räknas in i auto-spårets storlek, och img { max-width: 100% }
     klämde då bilden till spåret: 12rem beställdes, 11,1rem levererades, och
     överlappet blev hälften av det avsedda. Kortet ligger i ett fr-spår och
     har inte det problemet. */
  .honest-list { position: relative; z-index: 2; margin-inline-start: -1.2rem; }
}


/* ==========================================================================
   9. NEDLADDNINGSPANEL
   ========================================================================== */
.shell-cta {
  background:
    radial-gradient(70% 100% at 16% 0%, rgba(150, 235, 174, 0.26), rgba(150, 235, 174, 0) 60%),
    linear-gradient(180deg, #FBFEFC 0%, #EDF8F2 100%);
  text-align: center;
}
.cta-aurora {
  left: 50%;
  top: -30%;
  width: min(44rem, 96%);
  height: 26rem;
  transform: translateX(-50%);
  background: radial-gradient(46% 50% at 50% 60%, rgba(104, 217, 144, 0.22), rgba(104, 217, 144, 0) 70%);
  filter: blur(12px);
}
.cta-wave {
  position: absolute;
  z-index: -1;
  left: 0;
  bottom: 0;
  width: 100%;
  height: clamp(70px, 12vh, 130px);
  pointer-events: none;
}
.cta-content { position: relative; max-width: 40rem; margin: 0 auto; }
.cta-content h2 { margin-bottom: 1rem; }
.cta-lede {
  font-size: clamp(1.02rem, 0.97rem + 0.3vw, 1.16rem);
  line-height: 1.6;
  color: var(--kx-soft);
  max-width: 32rem;
  margin: 0 auto 2rem;
}
.cta-actions { display: flex; flex-wrap: wrap; gap: 0.85rem; justify-content: center; margin-bottom: 1.75rem; }
.cta-fine { font-size: 0.83rem; line-height: 1.6; color: var(--kx-soft); max-width: 34rem; margin: 0 auto; }


/* ==========================================================================
   10. FAQ OCH SUPPORT
   Ren <details>/<summary>: fungerar med tangentbord och skärmläsare utan en
   rad JavaScript, och webbläsarens sidsökning öppnar rätt svar av sig själv.
   ========================================================================== */
/* Panelen var ren vit yta. En knappt märkbar ton, tyngst i nedre vänstra
   hörnet där frågelistan tar slut — samma grepp som .shell-privacy. */
.shell-help {
  background:
    radial-gradient(85% 55% at 4% 98%, rgba(104, 217, 144, 0.10), rgba(104, 217, 144, 0) 62%),
    linear-gradient(180deg, #FFFFFF 0%, #FBFEFC 100%);
}

/* --------------------------------------------------------------------------
   LEVANDE HJÄLPPANEL
   Avsnittet stod helt stilla, och spalterna är olika höga: frågelistan tar
   slut ovanför kontosvaren och lämnade en tom fjärdedel nere till vänster.
   Tre saker, samma språk som funktionsblocket (se LEVANDE FUNKTIONSBLOCK):

   1) TVÅ AURORALAGER som driver hela tiden, 38 s och 46 s i olika riktningar
      och med olika fas — aldrig i takt, för då läser det som att panelen
      andas. Det första ligger i nedre vänstra fjärdedelen: just den yta som
      annars är tom.
   2) KONTAKTKORTET svävar (cardFloat, 15 s) och knappen får butiksknapparnas
      strimma en gång per varv. Kortet är avsnittets enda uppmaning — det är
      det som ska dra blicken.
   3) SVAR PÅ PEKARE, bara @media (hover: hover): frågekort och kontosvar
      lyfter två pixlar, aldrig på touch där :hover fastnar.

   Vilopulsen ligger på transform och egna ::after-lager, aldrig på samma
   egenskap som hovringen — annars vinner animationen över övergången.
   -------------------------------------------------------------------------- */
.help-aurora {
  left: -14%;
  bottom: -20%;
  width: 42rem;
  height: 42rem;
  background: radial-gradient(46% 46% at 50% 50%, rgba(104, 217, 144, 0.18), rgba(104, 217, 144, 0) 70%);
  filter: blur(18px);
  animation: helpDriftA 38s var(--kx-ease-glide) infinite alternate;
}
.help-aurora-b {
  left: auto;
  bottom: auto;
  right: -12%;
  top: -14%;
  width: 34rem;
  height: 34rem;
  background: radial-gradient(44% 44% at 50% 50%, rgba(150, 235, 174, 0.16), rgba(150, 235, 174, 0) 72%);
  /* Negativ fördröjning: lagret startar mitt i sitt varv, så de två aldrig
     vänder samtidigt. */
  animation: helpDriftB 46s var(--kx-ease-glide) infinite alternate -13s;
}
/* Tredje lagret: minst, snabbast och mitt i panelen. Det är det som gör att
   NÅGOT alltid rör sig i bild — de två stora vänder så sällan att en besökare
   som stannar i tio sekunder annars ser en stillastående yta. */
.help-aurora-c {
  left: 26%;
  bottom: -26%;
  width: 26rem;
  height: 26rem;
  background: radial-gradient(44% 44% at 50% 50%, rgba(104, 217, 144, 0.13), rgba(104, 217, 144, 0) 72%);
  animation: helpDriftC 27s ease-in-out infinite -6s;
}
@keyframes helpDriftA {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(4.5rem, -3.5rem, 0) scale(1.13); }
}
@keyframes helpDriftB {
  from { transform: translate3d(0, 0, 0) scale(1.07); }
  to   { transform: translate3d(-4rem, 3.5rem, 0) scale(1); }
}
/* Fram och tillbaka i EN cykel (inte alternate): banan är en båge, så lagret
   kommer tillbaka en annan väg än det gick. */
@keyframes helpDriftC {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  33%  { transform: translate3d(7rem, -4rem, 0) scale(1.1); }
  66%  { transform: translate3d(11rem, 2rem, 0) scale(0.96); }
  100% { transform: translate3d(0, 0, 0) scale(1); }
}

.help-grid { display: grid; gap: clamp(2.5rem, 1.5rem + 3vw, 4rem); align-items: start; }
.help-faq h2, .help-support h2 { margin-bottom: 1.5rem; }

.faq { display: grid; gap: 0.7rem; }
.faq details {
  border: 1px solid var(--kx-line);
  border-radius: var(--r-md);
  background: #fff;
  box-shadow: var(--sh-sm);
  transition: border-color 0.24s var(--kx-ease-out), box-shadow 0.24s var(--kx-ease-out);
}
.faq details[open] { border-color: rgba(81, 202, 123, 0.28); box-shadow: var(--sh-card); }

.faq summary {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1.05rem 1.25rem;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--kx-ink);
  cursor: pointer;
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }

/* Plustecken som blir minus. Ritat med två gradienter — inget extra element. */
.faq summary::after,
.chips summary::after {
  content: "";
  width: 26px;
  height: 26px;
  flex: none;
  margin-inline-start: auto;
  border-radius: 50%;
  background:
    linear-gradient(var(--kx-green-ink), var(--kx-green-ink)) center/11px 1.8px no-repeat,
    linear-gradient(var(--kx-green-ink), var(--kx-green-ink)) center/1.8px 11px no-repeat,
    rgba(81, 202, 123, 0.13);
  transition: transform 0.28s var(--kx-ease-glide);
}
.faq details[open] summary::after,
.chips details[open] summary::after {
  transform: rotate(90deg);
  background:
    linear-gradient(var(--kx-green-ink), var(--kx-green-ink)) center/11px 1.8px no-repeat,
    rgba(81, 202, 123, 0.13);
}

.faq-a { padding: 0 1.25rem 1.2rem; }
.faq-a p { color: var(--kx-soft); margin: 0; }

/* --------------------------------------------------------------------------
   MJUK UTVIKNING (bara när site.js tagit över klicket — .faq-js)
   Samma tre lager som appens "your estimate" i www/style.css:
     1) fluid utvikning: grid-rows 0fr→1fr med lätt overshoot,
     2) materialisering: texten landar ur blur med lyft, en aning efter,
     3) ljus-bloom: ett grönt svall som blommar en gång och tonar ut.
   Stängningen har inga fördröjningar och kortare kurva — ut < in.
   -------------------------------------------------------------------------- */
.faq-js .faq-a,
.chips-js .chip-a {
  display: grid;
  grid-template-rows: 0fr;
  padding-bottom: 0;
  transition: grid-template-rows 0.34s var(--kx-ease-glide),
              padding-bottom 0.34s var(--kx-ease-glide);
}
.faq-js details.is-open .faq-a {
  grid-template-rows: 1fr;
  padding-bottom: 1.2rem;
  transition: grid-template-rows 0.55s cubic-bezier(0.34, 1.2, 0.4, 1),
              padding-bottom 0.55s cubic-bezier(0.34, 1.2, 0.4, 1);
}
.chips-js details.is-open .chip-a {
  grid-template-rows: 1fr;
  padding-bottom: 1.05rem;
  transition: grid-template-rows 0.55s cubic-bezier(0.34, 1.2, 0.4, 1),
              padding-bottom 0.55s cubic-bezier(0.34, 1.2, 0.4, 1);
}
.faq-a-in,
.chip-a-in {
  overflow: hidden;
  min-height: 0;
}
.faq-js .faq-a-in > *,
.chips-js .chip-a-in > * {
  opacity: 0;
  transform: translateY(-8px) scale(0.985);
  filter: blur(6px);
  transition: opacity 0.22s var(--kx-ease-out),
              transform 0.3s var(--kx-ease-glide),
              filter 0.26s var(--kx-ease-out);
}
.faq-js details.is-open .faq-a-in > *,
.chips-js details.is-open .chip-a-in > * {
  opacity: 1;
  transform: none;
  filter: blur(0);
  transition: opacity 0.32s var(--kx-ease-out) 0.09s,
              transform 0.48s var(--kx-ease-glide) 0.09s,
              filter 0.42s var(--kx-ease-out) 0.09s;
}

/* Under ihopvikningen ligger open kvar på elementet — utseendet ska ändå
   följa is-open, annars släcks ram och plustecken först när allt är klart. */
.faq-js details[open]:not(.is-open) {
  border-color: var(--kx-line);
  box-shadow: var(--sh-sm);
}
.faq-js details[open]:not(.is-open) summary::after,
.chips-js details[open]:not(.is-open) summary::after {
  transform: none;
  background:
    linear-gradient(var(--kx-green-ink), var(--kx-green-ink)) center/11px 1.8px no-repeat,
    linear-gradient(var(--kx-green-ink), var(--kx-green-ink)) center/1.8px 11px no-repeat,
    rgba(81, 202, 123, 0.13);
}

/* Svallet. Engångsanimation, klassen sätts och tas bort av site.js.
   Klipps av kortets radie; ligger över bakgrunden men under texten. */
.faq-js details, .chips-js details { position: relative; overflow: hidden; }
/* …och just den klippningen åt upp tangentbordsfokuset. <summary>:s box är
   exakt lika stor som <details>:s, så den globala ringen (:focus-visible,
   outline-offset: 2px) ritas UTANFÖR kortet och klipptes bort på alla fyra
   sidor — verifierat med riktiga Tab-tryck: :focus-visible var sant, ringen
   fanns i beräknad stil, och ändå syntes inte en grön pixel. Ritad inåt
   hamnar den innanför klippningen och syns hela vägen runt.
   Gäller FAQ:n lika mycket som chipsen — samma regel, samma fälla. */
.faq-js summary:focus-visible,
.chips-js summary:focus-visible { outline-offset: -3px; }
.faq-js details.is-blooming::after,
.chips-js details.is-blooming::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(140% 120% at 92% 22%,
    rgba(81, 202, 123, 0.22), rgba(81, 202, 123, 0.06) 45%, rgba(81, 202, 123, 0) 70%);
  transform-origin: 92% 22%;
  animation: faqBloom 0.8s var(--kx-ease-out) both;
}
.faq-js details > summary,
.faq-js details > .faq-a,
.chips-js details > summary,
.chips-js details > .chip-a { position: relative; z-index: 1; }
@keyframes faqBloom {
  0%   { opacity: 0; transform: scale(0.4); }
  35%  { opacity: 1; }
  100% { opacity: 0; transform: scale(1.6); }
}

.sup-contact {
  position: relative;
  overflow: hidden;
  padding: 1.6rem 1.5rem;
  border: 1px solid rgba(81, 202, 123, 0.22);
  border-radius: var(--r-lg);
  background:
    radial-gradient(120% 150% at 0% 0%, rgba(104, 217, 144, 0.14), rgba(104, 217, 144, 0) 62%),
    #fff;
  box-shadow: var(--sh-card);
  margin-bottom: 1.1rem;
  animation: cardFloat 15s ease-in-out infinite;
  transition: box-shadow 0.45s var(--kx-ease-out),
              border-color 0.45s var(--kx-ease-out),
              opacity 0.6s var(--kx-ease-out);          /* se .faq details */
}
/* Skenet under pekaren. --mx/--my sätts av site.js, samma lyssnare som
   illustrationskorten — kortet står i den listan. */
.sup-contact::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(20rem 20rem at var(--mx, 50%) var(--my, 0%),
    rgba(104, 217, 144, 0.2), rgba(104, 217, 144, 0) 60%);
  transition: opacity 0.45s var(--kx-ease-out);
}
.sup-contact > * { position: relative; z-index: 1; }
.sup-contact p { color: var(--kx-body); }
.sup-hint { font-size: 0.9rem; color: var(--kx-soft); }
.sup-contact .btn { margin-top: 0.5rem; }

/* Strimman: samma keyframes som de stora butiksknapparna, men egen takt så
   att de två inte blinkar i kör om båda syns på skärmen samtidigt. */
.sup-contact .btn { position: relative; overflow: hidden; }
.sup-contact .btn::after {
  content: "";
  position: absolute;
  top: -30%;
  bottom: -30%;
  left: 0;
  width: 34%;
  pointer-events: none;
  background: linear-gradient(100deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.3) 50%,
    rgba(255, 255, 255, 0) 100%);
  animation: storeSheen 9.5s ease-in-out infinite;
}

.sup-list {
  display: grid;
  gap: 0.7rem;
  margin: clamp(1.75rem, 1.1rem + 2vw, 3rem) 0 0;   /* egen rad nu, inte en spalt */
}
.sup-list > div {
  padding: 1.1rem 1.25rem;
  border: 1px solid var(--kx-line);
  border-radius: var(--r-md);
  background: #fff;
  transition: transform 0.45s var(--kx-ease-out),
              opacity 0.6s var(--kx-ease-out),          /* se .faq details */
              border-color 0.24s var(--kx-ease-out),
              box-shadow 0.24s var(--kx-ease-out);
}
.sup-list dt { font-weight: 700; color: var(--kx-ink); margin-bottom: 0.3rem; }
.sup-list dd { margin: 0; color: var(--kx-soft); font-size: 0.94rem; }

/* Frågekorten fick bara ram och skugga på öppning. Lyftet ligger på transform,
   som är fri: utvikningen animerar grid-template-rows, inte transform.

   opacity OCH transform MÅSTE stå i listan, fast hovringen inte rör opacity.
   Inrullningen (`[data-rv]` i avsnitt 12) tonar in kortet med sin egen
   transition — men `.faq details` (0,1,1) slår `[data-rv]` (0,1,0) och ersätter
   HELA listan. Utan de två raderna här hoppar kortet fram i stället för att
   tona in, och det syns inte i den regel man just skrev. Samma sak gäller
   .sup-list > div och .sup-contact nedan. */
.faq details { transition: transform 0.45s var(--kx-ease-out),
                           opacity 0.6s var(--kx-ease-out),
                           border-color 0.24s var(--kx-ease-out),
                           box-shadow 0.24s var(--kx-ease-out); }

@media (hover: hover) {
  /* Bara STÄNGDA kort lyfter. Ett öppet har redan sin grönare ram och djupare
     skugga, och hovringen skulle bara släcka dem — samma regel som chipsen. */
  .faq details:not([open]):hover {
    transform: translateY(-2px);
    border-color: rgba(81, 202, 123, 0.34);
    box-shadow: 0 18px 32px -22px rgba(81, 202, 123, 0.85), var(--sh-card);
  }
  .faq details:not([open]):hover summary::after { transform: scale(1.1); }

  .sup-list > div:hover {
    transform: translateY(-2px);
    border-color: rgba(81, 202, 123, 0.32);
    box-shadow: 0 16px 30px -22px rgba(81, 202, 123, 0.8);
  }

  .sup-contact:hover {
    border-color: rgba(81, 202, 123, 0.4);
    box-shadow: 0 1px 2px rgba(15, 17, 21, 0.04), 0 26px 50px -28px rgba(81, 202, 123, 0.55);
  }
  .sup-contact:hover::before { opacity: 1; }
}

/* --------------------------------------------------------------------------
   LEVANDE YTA UNDER KONTAKTKORTET (.sup-field)
   Den tomma fjärdedelen som uppstår när frågorna viks ut. Tre mintfält som
   driver i olika takt plus sex partiklar som stiger — allt så lågmält att man
   inte tittar på det, bara märker att ytan lever.

   Ytan är ett FLEXBARN som växer (flex: 1), så den tar precis det som blir kvar
   under kortet — och den är därmed självjusterande: viks svaren ut växer den,
   stängs de krymper den. Ingen JS, ingen mätning.

   VARFÖR nth-child och inte style="--x:…": värdena hör till designen, inte till
   innehållet. Markupen är nio tomma element, hela utseendet ligger här.
   -------------------------------------------------------------------------- */
.sup-field { display: none; }

@media (min-width: 940px) {
  .sup-field {
    display: block;
    position: relative;
    flex: 1;
    min-height: 8rem;
    /* Molnen är större än ytan och måste hållas inne i spalten. */
    overflow: hidden;

    /* INGEN LÅDA FÅR SYNAS.
       overflow: hidden ensamt kapar molnen tvärt och gör ytan till en synlig
       rundad rektangel med animationer i — precis det den inte ska vara. Masken
       nollar allt långt innan lådans kant, så klippningen aldrig hinner bli en
       linje. TVÅ ovaler som adderas, inte en: en enda läser fortfarande som "en
       form", två överlappande ger en oregelbunden fläck utan mitt och utan kant.
       mask-repeat måste vara no-repeat — standardvärdet är repeat, och då
       tilear gradienten ut i lådans hörn igen. */
    -webkit-mask-image:
      radial-gradient(58% 34% at 40% 22%, #000 0%, rgba(0, 0, 0, 0.55) 46%, transparent 76%),
      radial-gradient(52% 30% at 63% 58%, #000 0%, rgba(0, 0, 0, 0.5) 48%, transparent 78%);
            mask-image:
      radial-gradient(58% 34% at 40% 22%, #000 0%, rgba(0, 0, 0, 0.55) 46%, transparent 76%),
      radial-gradient(52% 30% at 63% 58%, #000 0%, rgba(0, 0, 0, 0.5) 48%, transparent 78%);
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
    -webkit-mask-composite: source-over;      /* = add, Safaris egen skala */
            mask-composite: add;
  }

  /* PUNKTRASTRET. Mjuka moln ensamma läser som "tomt med en grön skiftning" —
     ett raster ger ytan STRUKTUR, så att den läser som en avsiktlig yta. Det
     driver en tile i x och två i y (44/88 px mot 22 px-rutan), vilket gör varvet
     sömlöst: inget hopp när animationen börjar om.
     Masken tonar ut mot kanterna, annars slutar rastret med en hård linje. */
  .sup-field::before {
    content: "";
    position: absolute;
    /* Överdimensionerat med flit: lagret FLYTTAS, och utan marginal skulle en
       tom kant skjutas in i bild. Föräldern klipper och maskar bort resten. */
    inset: -7rem;
    pointer-events: none;
    background-image: radial-gradient(rgba(73, 190, 115, 0.32) 1.5px, rgba(73, 190, 115, 0) 1.6px);
    background-size: 22px 22px;
    /* Ingen egen mask här: förälderns mask gäller hela subträdet, och två
       lager av uttoning gör bara rastret gråare i mitten. */
    animation: fieldGrid 36s linear infinite;
  }
  /* transform, INTE background-position: en flyttad bakgrund målar om hela
     lagret varje bildruta, och lagret är både stort och maskat. En transform
     komponeras i stället. Steget är exakta multiplar av 22 px-rutan (2 åt sidan,
     4 uppåt), så varvet är sömlöst — inget hopp när animationen börjar om. */
  @keyframes fieldGrid {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(44px, -88px, 0); }
  }

  .sup-blob {
    position: absolute;
    border-radius: 50%;
    pointer-events: none;
    filter: blur(30px);
  }
  .sup-blob:nth-child(1) {
    left: -18%;
    top: 6%;
    width: 22rem;
    height: 22rem;
    background: radial-gradient(50% 50% at 50% 50%, rgba(104, 217, 144, 0.3), rgba(104, 217, 144, 0) 70%);
    animation: fieldBlobA 31s var(--kx-ease-glide) infinite alternate;
  }
  .sup-blob:nth-child(2) {
    right: -22%;
    bottom: 4%;
    width: 26rem;
    height: 26rem;
    background: radial-gradient(50% 50% at 50% 50%, rgba(150, 235, 174, 0.28), rgba(150, 235, 174, 0) 72%);
    animation: fieldBlobB 39s var(--kx-ease-glide) infinite alternate -14s;
  }
  .sup-blob:nth-child(3) {
    left: 30%;
    top: 38%;
    width: 15rem;
    height: 15rem;
    background: radial-gradient(50% 50% at 50% 50%, rgba(104, 217, 144, 0.24), rgba(104, 217, 144, 0) 74%);
    animation: fieldBlobC 24s ease-in-out infinite -7s;
  }
  @keyframes fieldBlobA {
    from { transform: translate3d(0, 0, 0) scale(1); }
    to   { transform: translate3d(3.5rem, 5rem, 0) scale(1.16); }
  }
  @keyframes fieldBlobB {
    from { transform: translate3d(0, 0, 0) scale(1.08); }
    to   { transform: translate3d(-3rem, -6rem, 0) scale(1); }
  }
  /* En båge, inte en linje: lagret kommer tillbaka en annan väg än det gick. */
  @keyframes fieldBlobC {
    0%   { transform: translate3d(0, 0, 0) scale(1); }
    33%  { transform: translate3d(-4rem, -3rem, 0) scale(1.12); }
    66%  { transform: translate3d(2rem, -6rem, 0) scale(0.94); }
    100% { transform: translate3d(0, 0, 0) scale(1); }
  }

  /* Partiklarna. Stiger, tonar in och ut, och sidodriften (--dx) skiljer dem åt
     så att de inte läser som en kolonn. Negativa fördröjningar: alla är redan
     igång när ytan kommer i vy — annars står den tom de första sekunderna. */
  .sup-field i {
    position: absolute;
    bottom: -1.5rem;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: radial-gradient(50% 50% at 50% 50%, rgba(81, 202, 123, 0.75), rgba(81, 202, 123, 0) 70%);
    opacity: 0;
    animation: moteRise 26s linear infinite;
  }
  .sup-field i:nth-of-type(1) { left: 14%; --dx:  2.5rem; animation-duration: 27s; animation-delay:  -2s; }
  .sup-field i:nth-of-type(2) { left: 33%; --dx: -1.8rem; animation-duration: 33s; animation-delay: -11s; width: 7px;  height: 7px; }
  .sup-field i:nth-of-type(3) { left: 52%; --dx:  3.2rem; animation-duration: 23s; animation-delay: -18s; width: 12px; height: 12px; }
  .sup-field i:nth-of-type(4) { left: 68%; --dx: -2.6rem; animation-duration: 30s; animation-delay:  -6s; }
  .sup-field i:nth-of-type(5) { left: 82%; --dx:  1.4rem; animation-duration: 36s; animation-delay: -24s; width: 7px;  height: 7px; }
  .sup-field i:nth-of-type(6) { left: 45%; --dx: -3.4rem; animation-duration: 29s; animation-delay: -15s; width: 10px; height: 10px; }

  @keyframes moteRise {
    0%   { transform: translate3d(0, 0, 0); opacity: 0; }
    14%  { opacity: 1; }
    82%  { opacity: 1; }
    100% { transform: translate3d(var(--dx, 2rem), -34rem, 0); opacity: 0; }
  }
}

/* KLISTRAT KONTAKTKORT — svaret på "alla svar öppna".
   Viker man ut alla nio frågorna blir vänsterspalten dubbelt så hög som
   högerspalten, och högersidan stod tom hela vägen ned. Nu följer kontaktkortet
   med i stället: spalten sträcks till radens höjd (align-items: stretch, inte
   start) och kortet klistras. Det som förut var dött utrymme är nu ytan
   supportkortet färdas i, och hjälpen finns kvar på skärmen medan man läser.

   TVÅ FÖRUTSÄTTNINGAR SOM ÄR LÄTTA ATT RIVA:
     1. Ingen förälder får skapa en rullningsbehållare. .shell har overflow:
        hidden för att klippa auroran — därför overflow: clip här i stället,
        som klipper likadant men utan scrollport. Samma sak på <body> (se
        @supports-blocket i avsnitt 1).
     2. Höjden. Ett klistrat element som är högre än visningsytan kan inte
        klistra sig. Därför ligger de tre kontosvaren i en egen rad utanför
        griden — med dem kvar i spalten blev blocket ~780 px och satt fast på
        varje normal bärbar skärm. */
.shell-help { overflow: clip; }

@media (min-width: 940px) {
  .help-grid {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    align-items: stretch;
  }
  /* Kolumn i flex så att .sup-field kan växa in i det som blir kvar. */
  .help-support { display: flex; flex-direction: column; }
  .sup-contact {
    position: sticky;
    top: calc(var(--kx-head-h) + 1.25rem);
  }
  .sup-list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}


/* ==========================================================================
   11. SIDFOT
   Ligger UTANFÖR panelerna, direkt på den tonade sidbakgrunden — sidan ska
   sluta lugnt, inte med ännu en vit ruta.
   ========================================================================== */
.site-foot {
  max-width: var(--w-max);
  margin: 0 auto;
  padding: clamp(2.5rem, 1.8rem + 2.4vw, 4rem) var(--gutter) 1.5rem;
}
.foot-grid { display: grid; gap: 2rem; }
.foot-brand .brand { margin-inline-end: 0; }
.foot-tag { margin: 0.85rem 0 0; font-size: 0.92rem; color: var(--kx-soft); max-width: 18rem; }

/* Butiksstatus i sidfoten. En RAD, inte en bricka: den grönlaserade pillret såg
   ut som en knapp man inte kan trycka på, och gav sidfoten ett generiskt
   mall-utseende. Texten står kvar — det är den som är informationen. Färgen är
   sidfotens dämpade, inte grön: grön text utan pillret läser som en länk. */
.foot-store {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  margin: 0.85rem 0 0;
  font-size: 0.86rem;
  color: var(--kx-soft);
}
.foot-store svg { width: 15px; height: 15px; display: block; opacity: 0.75; }

.foot-links h2, .foot-org h2 {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--kx-soft);
  margin-bottom: 0.9rem;
}
.foot-links ul { display: grid; gap: 0.55rem; }
.foot-links a {
  font-size: 0.93rem;
  font-weight: 600;
  color: var(--kx-body);
  text-decoration: none;
  /* Underlinjen bara vid hover/fokus — men den finns, så länkarna är inte
     enbart färgkodade. */
  border-bottom: 1px solid transparent;
  transition: color 0.2s var(--kx-ease-out), border-color 0.2s var(--kx-ease-out);
}
.foot-links a:hover { color: var(--kx-green-ink); border-bottom-color: rgba(26, 127, 75, 0.4); }

.foot-org p { font-size: 0.9rem; line-height: 1.75; color: var(--kx-soft); margin: 0; }

.foot-base {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.5rem;
  justify-content: space-between;
  margin-top: clamp(2.25rem, 1.6rem + 2vw, 3.25rem);
  padding-top: 1.4rem;
  border-top: 1px solid rgba(15, 17, 21, 0.09);
}
.foot-base p { margin: 0; font-size: 0.85rem; color: var(--kx-soft); }

/* --- Språkväljaren -------------------------------------------------------
   Samma komponent och samma klassnamn som på de juridiska sidorna, medvetet
   kopierad hit ur assets/policy.css i stället för delad: filerna delar redan
   tokenblock på samma villkor (se filhuvudet), och policy.css är 27 kB
   juridiksideslayout som startsidan inte ska behöva ladda. Ändras utseendet
   på ett ställe måste det ändras på båda.

   Menyn fälls UPPÅT här — väljaren står i sidfoten, och nedåt skulle den
   hamna utanför sidan. Det är hela skillnaden mot policy.css. */
.foot-lang { order: -1; flex: 0 0 auto; }
.lang-picker { position: relative; }

.lang-trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.45rem 0.7rem 0.45rem 0.6rem;
  font: inherit;
  font-size: 0.88rem;
  font-weight: 650;
  color: var(--kx-ink);
  background: #fff;
  border: 1px solid var(--kx-line);
  border-radius: var(--r-pill);
  cursor: pointer;
  box-shadow: 0 2px 10px rgba(15, 17, 21, 0.04);
  transition: transform 0.22s var(--kx-ease-out),
              box-shadow 0.25s var(--kx-ease-out),
              border-color 0.25s var(--kx-ease-out);
}
.lang-trigger:hover { border-color: rgba(81, 202, 123, 0.45); box-shadow: 0 6px 18px rgba(81, 202, 123, 0.14); }
.lang-trigger:active { transform: scale(0.96); }
.lang-trigger .lang-flag { font-size: 1.05rem; line-height: 1; }
.lang-trigger .lang-label { max-width: 8rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lang-chev {
  width: 12px;
  height: 12px;
  flex: none;
  color: var(--kx-soft);
  transition: transform 0.28s var(--kx-ease-glide);
}
.lang-trigger[aria-expanded="true"] .lang-chev { transform: rotate(180deg); }

.lang-menu {
  position: absolute;
  bottom: calc(100% + 0.55rem);
  left: 0;
  z-index: 40;
  width: max(13.5rem, 100%);
  max-height: min(60vh, 26rem);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  margin: 0;
  padding: 0.4rem;
  list-style: none;
  background: rgba(255, 255, 255, 0.94);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border: 1px solid var(--kx-line);
  border-radius: 18px;
  box-shadow: 0 24px 60px rgba(15, 17, 21, 0.14), 0 2px 8px rgba(15, 17, 21, 0.06);
  /* Stängd: osynlig, oklickbar och borta ur både tabbordning och
     tillgänglighetsträdet (visibility, inte bara opacity). */
  opacity: 0;
  visibility: hidden;
  transform: translateY(8px) scale(0.97);
  transform-origin: 0 100%;
  transition: opacity 0.22s var(--kx-ease-out),
              transform 0.26s var(--kx-ease-out),
              visibility 0s linear 0.26s;
}
.lang-picker.open .lang-menu {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
}

.lang-menu li {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.55rem 0.6rem;
  border-radius: 12px;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--kx-body);
  cursor: pointer;
  transition: background-color 0.18s var(--kx-ease-out), color 0.18s var(--kx-ease-out);
}
.lang-menu li:hover { background: rgba(81, 202, 123, 0.10); color: var(--kx-ink); }
.lang-menu li[aria-selected="true"] { color: var(--kx-green-ink); }
.lang-menu .lang-flag { font-size: 1.15rem; line-height: 1; flex: none; }
.lang-menu .lang-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* --------------------------------------------------------------------------
   SPRÅKVÄLJAREN I SIDHUVUDET (.navlang)
   Egen uppsättning, skild från sidfotens .lang-picker. De delar formspråk men
   inte regler: sidfotens meny fälls UPPÅT (den sitter längst ned på sidan),
   den här fälls NEDÅT. Slås de ihop måste båda riktningarna hanteras i samma
   selektor, och då blir en ändring för den ena lätt ett fel för den andra.

   Knappen bär en glob i stället för en flagga. Flaggan hör hemma i listan, där
   den hjälper ögat hitta rätt rad — på knappen hade den påstått att ett språk
   tillhör ett land, vilket engelska, arabiska och spanska inte gör.
   -------------------------------------------------------------------------- */
.navlang { position: relative; display: inline-flex; }

.navlang-trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.42rem 0.6rem 0.42rem 0.65rem;
  font: inherit;
  font-size: 0.88rem;
  font-weight: 650;
  color: var(--kx-ink);
  background: #fff;
  border: 1px solid var(--kx-line);
  border-radius: var(--r-pill);
  cursor: pointer;
  box-shadow: 0 2px 10px rgba(15, 17, 21, 0.04);
  transition: transform 0.22s var(--kx-ease-out),
              box-shadow 0.25s var(--kx-ease-out),
              border-color 0.25s var(--kx-ease-out);
}
.navlang-trigger:hover { border-color: rgba(81, 202, 123, 0.45); box-shadow: 0 6px 18px rgba(81, 202, 123, 0.14); }
.navlang-trigger:active { transform: scale(0.96); }

.navlang-globe { width: 17px; height: 17px; flex: none; color: var(--kx-soft); }
.navlang-label { max-width: 7.5rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.navlang-chev {
  width: 12px;
  height: 12px;
  flex: none;
  color: var(--kx-soft);
  transition: transform 0.28s var(--kx-ease-glide);
}
.navlang-trigger[aria-expanded="true"] .navlang-chev { transform: rotate(180deg); }

.navlang-menu {
  position: absolute;
  top: calc(100% + 0.55rem);      /* NEDÅT — sidhuvudet sitter överst */
  right: 0;                        /* högerkanten fäst, annars sticker den ut */
  z-index: 60;                     /* över hjältens paneler och roboten */
  width: max(13.5rem, 100%);
  max-height: min(70vh, 30rem);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  margin: 0;
  padding: 0.4rem;
  list-style: none;
  background: rgba(255, 255, 255, 0.94);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border: 1px solid var(--kx-line);
  border-radius: 18px;
  box-shadow: 0 24px 60px rgba(15, 17, 21, 0.14), 0 2px 8px rgba(15, 17, 21, 0.06);
  /* Stängd: osynlig, oklickbar och borta ur tabbordningen — visibility, inte
     bara opacity. Samma resonemang som sidfotens meny. */
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px) scale(0.97);
  transform-origin: 100% 0;
  transition: opacity 0.22s var(--kx-ease-out),
              transform 0.26s var(--kx-ease-out),
              visibility 0s linear 0.26s;
}
.navlang.open .navlang-menu {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
}

.navlang-menu li {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.55rem 0.6rem;
  border-radius: 12px;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--kx-body);
  cursor: pointer;
  transition: background-color 0.18s var(--kx-ease-out), color 0.18s var(--kx-ease-out);
}
.navlang-menu li:hover { background: rgba(81, 202, 123, 0.10); color: var(--kx-ink); }
.navlang-menu li[aria-selected="true"] { color: var(--kx-green-ink); }
.navlang-flag { font-size: 1.15rem; line-height: 1; flex: none; }
.navlang-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Bocken syns bara på det valda språket. Den ligger alltid i DOM:en så att
   raden inte hoppar i bredd när markeringen flyttas. */
.navlang-check { width: 16px; height: 16px; flex: none; color: var(--kx-green-ink); opacity: 0; }
.navlang-menu li[aria-selected="true"] .navlang-check { opacity: 1; }

/* I mobilmenyn ligger knapparna staplade och breda. Väljaren följer med. */
@media (max-width: 899px) {
  .navlang { display: flex; }
  .navlang-trigger { width: 100%; justify-content: center; }
  .navlang-menu { right: auto; left: 0; width: 100%; }
}

@media (min-width: 620px) { .foot-grid { grid-template-columns: repeat(2, 1fr); gap: 2.5rem 2rem; } }
@media (min-width: 960px) { .foot-grid { grid-template-columns: 1.4fr 1fr 1fr 1.2fr; } }


/* ==========================================================================
   12. FOKUS, RÖRELSE, UTSKRIFT
   ========================================================================== */
:focus-visible {
  outline: 2px solid var(--kx-green-deep);
  outline-offset: 2px;
  border-radius: 8px;
}
/* Aldrig avstängt: raden finns för att ingen ska "städa bort" fokus. */

/* Inrullning. data-rv sätts av site.js, aldrig i HTML — utan JS finns
   attributet inte, och då är allt synligt från början. */
[data-rv] {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.6s var(--kx-ease-out), transform 0.6s var(--kx-ease-out);
}
[data-rv].rv-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  /* Spline-scenen animerar oavbrutet och kan inte pausas utifrån — den tas bort
     helt. Mintglöden (.robot-light) ligger kvar, så kompositionen håller.
     hero.js hoppar dessutom över hela laddningen vid reducerad rörelse, så
     regeln här är ett bälte till hängslena (och skyddar om JS är av). */
  #interactive-robot-stage canvas { display: none; }
  /* Halon suddar bakgrunden BAKOM roboten. Utan robot framför blir den bara en
     oförklarlig suddig fläck över telefonen — bort med den också. */
  .robot-halo { display: none; }
  [data-rv] { opacity: 1 !important; transform: none !important; transition: none !important; }
  /* Hjältens rörelse. Entrén måste nollas med opacity/transform, INTE bara med
     animation: none — annars fastnar raderna i sitt startläge (opacity 0) och
     texten blir osynlig för just de besökare som bett om mindre rörelse. */
  .hero-copy h1,
  .hero-copy .lede,
  .hero-copy .cta-row,
  .hero-copy .hero-trust {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
  .hero-aurora { animation: none !important; }
  .btn-store.btn-lg::after { display: none; }
  .btn, .brand, .nav > a, .nav, .nav-scrim, .faq details,
  .faq summary::after, .chips summary::after, .chips > li,
  .smart-cards > li, .site-head, .signin-scrim, .signin-card {
    transition-duration: 0.01ms !important;
  }
  .smart-cards > li:hover { transform: none; }
  .flow > li:not(:last-child)::before { animation: none; opacity: 0; }
  .flow-ico { animation: none !important; }
  /* Funktionsblockets vilopuls: allt står still, inget lyser. */
  .feat-aurora, .chip-ico, .macro-list .bar::after,
  .mini-card, .glance, .glance-hero b, .glance-rows b,
  .glance-flame { animation: none !important; }
  .glance::before { display: none; }
  /* Hjälppanelens vilopuls: auroralagren står still, kontaktkortet slutar
     sväva, strimman över knappen tas bort helt. */
  .help-aurora, .sup-contact { animation: none !important; }
  .sup-contact::before, .sup-contact .btn::after { display: none; }
  /* Den levande ytan ÄR rörelse och har inget innehåll — den tas bort helt
     i stället för att stå kvar som tre stillastående fläckar. */
  .sup-field { display: none !important; }
  .sup-list > div, .sup-contact { transition-duration: 0.01ms !important; }
  .faq details:not([open]):hover, .sup-list > div:hover { transform: none; }
  .chips > li::after, .lang-grid > li::after,
  .spark-trace, .spark-ping { animation: none !important; opacity: 0 !important; }
  /* Vågen klipper färgen ur texten — utan den måste fyllnadsfärgen tillbaka,
     annars står rutorna tomma. */
  .lang-grid > li > button {
    animation: none !important;
    background-image: none !important;
    color: var(--kx-body) !important;
    -webkit-text-fill-color: currentColor !important;
  }
  .mini-card::before { display: none; }
}

@media print {
  .site-head, .nav-scrim, .skip, .stage, .cta-wave,
  .signin, .signin-scrim,
  .hero-aurora, .smart-aurora, .priv-aurora, .cta-aurora, .feat-aurora,
  .help-aurora, .sup-field, .robot-stage,
  /* Robotarna och brickorna i funktionsavsnittet är ren dekor — samma skäl som
     hjältens scen ovan: de säger ingenting på papper och äter bara toner. */
  .feat-bot, .goal-bot, .goal-tile,
  /* Robotarna i integritetsavsnittet är också ren dekor. .priv-shot upprepar
     bara vad kortet redan säger, och .honest-bot bär ingen information alls. */
  .priv-shot, .honest-bot { display: none !important; }
  .chips > li::after, .lang-grid > li::after, .spark-trace, .spark-ping,
  .mini-card::before, .sup-contact::before,
  .sup-contact .btn::after { display: none !important; }
  .lang-grid > li > button {
    animation: none !important;
    background-image: none !important;
    color: var(--kx-body) !important;
    -webkit-text-fill-color: currentColor !important;
  }
  body { padding: 0; background: #fff; }
  .shell { box-shadow: none; border: 0; background: none; padding-block: 1rem; margin: 0; max-width: none; }
  [data-rv] { opacity: 1 !important; transform: none !important; }
  .faq details, .chips > li { break-inside: avoid; box-shadow: none; }
  /* Roboten är borttagen ovan — utan detta står dess reserverade yta kvar som
     en tom tio-rems spalt bredvid målkortet. Fyra spalter blir dessutom
     obrukbart smala på ett A4; två räcker. */
  .goal-scene { padding-inline-end: 0 !important; }
  /* Markskuggorna sitter på .goal-scene, inte på roboten, så de överlever
     display: none ovan — utan den här raden skrivs två grå fläckar ut på ett
     papper där roboten inte finns. (Den vinkande robotens skuggor sitter på
     .feat-bot och försvinner med den.) */
  .goal-scene::before, .goal-scene::after { display: none !important; }
  .chips-row { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  /* Samma skäl för integritetskorten: tre spalter blir 237 px på ett A4. Och
     korten ska inte kunna delas mitt itu av en sidbrytning — .honest bär hela
     den juridiskt bundna texten. */
  .priv-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  .priv-card, .honest { break-inside: avoid; }
  .faq-a { display: block !important; padding-bottom: 1.2rem !important; }
  .chip-a { display: block !important; padding-bottom: 1.05rem !important; }
  .faq-a-in, .chip-a-in { overflow: visible !important; }
  .faq-js .faq-a-in > *, .chips-js .chip-a-in > * {
    opacity: 1 !important; transform: none !important; filter: none !important;
  }
}
