@import url("https://fonts.googleapis.com/css2?family=Schibsted+Grotesk:wght@500;600;700;800;900&family=Sora:wght@300;400;500;600;700&family=JetBrains+Mono:wght@500;600;700&family=Allura&display=swap");

:root{
  --navy:#020b1a;
  --navy-2:#06152c;
  --ink:#0a1626;
  --muted:#5c6b80;
  --muted-2:#6f7f95;
  --line:#e0e9f5;
  --soft:#f4f8fd;
  --blue:#1a74ff;
  --blue-2:#0d5fe0;
  --blue-ink:#0d62df;
  --card:#ffffff;
  --shadow:0 22px 60px rgba(9,26,56,.10);
  --shadow-sm:0 10px 30px rgba(8,24,53,.06);
  --radius:16px;
  --disp:'Schibsted Grotesk', ui-sans-serif, system-ui, sans-serif;
  /* The wordmark's own face. --disp changes with the visual variant; this
     one never does, because the logotype is a mark, not a heading. */
  --disp-std:'Schibsted Grotesk', ui-sans-serif, system-ui, sans-serif;
  --body:'Sora', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono:'JetBrains Mono', ui-monospace, monospace;
  --hdr-h:70px;
  /* iOS safe areas, same tokens as the app's theme.css. Zero everywhere else,
     so every consumer below is a no-op in a desktop browser. --hdr-total is the
     header's real footprint: the bar plus whatever the status bar takes. */
  --safe-top:env(safe-area-inset-top,0px);
  --safe-bottom:env(safe-area-inset-bottom,0px);
  --hdr-total:calc(var(--hdr-h) + var(--safe-top));
  /* The header and footer colour in the standard look. The variants redefine it,
     and the browser chrome follows it (see theme-color in main.js). */
  --dark-1:#020d20;
  --page-ground:#fff;
}
/* The rubber band at either end of the scroll shows this, not white. */
html{background:var(--page-ground);color-scheme:light}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;font-family:var(--body);color:var(--ink);background:#fff;line-height:1.55;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
a{color:inherit;text-decoration:none}
img{display:block;max-width:100%}
h1,h2,h3,h4,.brand,.disp{font-family:var(--disp);letter-spacing:-.03em}
.wrap{width:min(1200px,calc(100% - 48px));margin:0 auto}
.center{text-align:center}
.muted{color:var(--muted)}
.eyebrow{font-family:var(--mono);font-size:11px;line-height:1;text-transform:uppercase;letter-spacing:.16em;font-weight:700;color:var(--blue);margin-bottom:16px}

/* ---- Icons (inline SVG line icons) ---- */
.ic{width:1em;height:1em;flex:none;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}

/* ============================ HEADER ============================ */
.site-header{position:fixed;left:0;right:0;top:0;z-index:60;border-top:var(--safe-top) solid transparent;background:linear-gradient(180deg,#020d20,#020913);border-bottom:1px solid rgba(255,255,255,.08);box-shadow:0 8px 30px rgba(0,0,0,.22);transition:background .3s ease,box-shadow .3s ease}
.site-header.transparent{background:linear-gradient(180deg,rgba(2,10,23,.86),rgba(2,10,23,.34),rgba(2,10,23,0));border-bottom-color:transparent;box-shadow:none}
.nav{height:var(--hdr-h);display:flex;align-items:center;justify-content:space-between;gap:24px}
.brand{display:flex;align-items:center;gap:12px;color:#fff;font-size:21px;font-weight:800;letter-spacing:-.02em}
.brand-mark{width:auto;height:30px;flex:none;object-fit:contain}
.nav-links{display:flex;align-items:center;gap:30px;font-size:14px;font-weight:600}
.nav-links a{color:rgba(255,255,255,.82);cursor:pointer;padding:6px 0;position:relative;transition:color .18s ease}
.nav-links a:hover{color:#fff}
.nav-links a.active{color:#fff}
.nav-links a.active:after{content:"";position:absolute;left:0;right:0;bottom:-2px;height:2px;border-radius:2px;background:var(--blue)}
.nav-actions{display:flex;align-items:center;gap:18px}
.login{color:#fff;font-size:14px;font-weight:500;border-bottom:1px solid rgba(255,255,255,.55);cursor:pointer;padding-bottom:1px}
.login:hover{border-bottom-color:#fff}
.btn{border:1px solid transparent;border-radius:10px;padding:11px 18px;font-family:var(--body);font-weight:700;font-size:14px;display:inline-flex;align-items:center;gap:9px;cursor:pointer;transition:transform .18s ease,box-shadow .18s ease,background .18s ease;white-space:nowrap}
.btn .ic{font-size:16px;stroke-width:2.1}
.btn-primary{background:linear-gradient(180deg,#2f86ff,#1063e8);color:#fff;box-shadow:0 12px 24px rgba(14,101,232,.3)}
.btn-primary:hover{transform:translateY(-1px);box-shadow:0 18px 34px rgba(14,101,232,.38)}
.btn-secondary{background:rgba(6,20,46,.5);color:#fff;border-color:rgba(120,175,255,.55);backdrop-filter:blur(8px)}
.btn-secondary:hover{background:rgba(10,28,60,.7)}
.btn-outline{border-color:#bcd8ff;color:var(--blue-ink);background:#fff}
.btn-outline:hover{border-color:var(--blue);background:#f4f9ff}
.langtog{display:inline-flex;align-items:center;border:1px solid rgba(255,255,255,.22);border-radius:999px;overflow:hidden;background:rgba(255,255,255,.05)}
.lang-btn{font-family:var(--mono);font-size:11px;font-weight:700;letter-spacing:.05em;padding:7px 11px;border:0;background:none;color:rgba(255,255,255,.72);cursor:pointer;transition:.18s ease;line-height:1}
.lang-btn.on{background:linear-gradient(180deg,#2f86ff,#1063e8);color:#fff}
.lang-btn:not(.on):hover{color:#fff}
.mobile-menu{display:none;align-items:center;justify-content:center;gap:7px;color:#fff;border:1px solid rgba(255,255,255,.2);border-radius:10px;padding:9px 11px;background:rgba(255,255,255,.05);cursor:pointer;font-family:var(--body);font-weight:600;font-size:13px}
.mobile-menu .ic{font-size:16px}

/* ============================ VIEWS ============================ */
.view{display:none}
.view.active{display:block;animation:viewIn .32s ease both}
@keyframes viewIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

/* ---- Platform hero ---- */
.hero{position:relative;overflow:hidden;background:#020b1a;color:#fff;padding:calc(var(--hdr-total) + 66px) 0 108px}
.hero:before{content:"";position:absolute;inset:0;background:
  radial-gradient(72% 55% at 80% 32%,rgba(32,122,255,.22),transparent 60%),
  linear-gradient(90deg,#020b1a 0%,#03122b 30%,rgba(2,10,24,.72) 55%,rgba(2,10,24,.08) 100%),
  url("assets/hero-refinery.jpg");background-size:cover;background-position:center right}
.hero:after{content:"";position:absolute;left:-2%;right:-2%;bottom:-1px;height:96px;background:#fff;clip-path:polygon(0 74%,100% 38%,100% 100%,0 100%)}
.hero-inner{position:relative;z-index:2}
/* The headline is now two full sentences rather than four stub lines, so it
   needs a wider measure and a smaller top end on the clamp. */
.hero-content{max-width:790px}
.hero h1{font-size:clamp(32px,4.1vw,55px);line-height:1.06;margin:0 0 24px;letter-spacing:-.04em;font-weight:800}
.hero h1 .em{color:#2f88ff}
.hero p{font-size:17px;line-height:1.62;color:rgba(255,255,255,.9);margin:0 0 30px;max-width:580px;font-weight:300}
.hero-actions{display:flex;gap:14px;align-items:center;flex-wrap:wrap}
.hero-ai{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-top:26px}
.hero-ai-label{font-size:12px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:rgba(255,255,255,.62)}
.hero-ai-marks{display:flex;gap:8px;flex-wrap:wrap}
.hero-ai-chip{display:inline-flex;align-items:center;gap:8px;padding:7px 13px;border-radius:999px;border:1px solid rgba(255,255,255,.2);background:rgba(255,255,255,.05);color:rgba(255,255,255,.9);font-size:13px;font-weight:600;text-decoration:none;cursor:pointer;transition:background .18s ease,border-color .18s ease,transform .18s ease}
.hero-ai-chip:hover{background:rgba(255,255,255,.12);border-color:rgba(120,175,255,.6);color:#fff;transform:translateY(-1px)}
.hero-ai-mark{width:22px;height:22px;flex:none;border-radius:6px;display:grid;place-items:center;overflow:hidden}
.hero-ai-mark img{width:100%;height:100%;display:block;object-fit:contain}
.hero-ai-mark--plate{background:#fff}
.hero-ai-mark--plate img{width:76%;height:76%}
@media (max-width:720px){.hero-ai{gap:10px;margin-top:20px}.hero-ai-label{font-size:11px}.hero-ai-chip{font-size:12px;padding:6px 11px}}
.hero-proof{display:grid;grid-template-columns:repeat(4,1fr);gap:26px;margin-top:64px;max-width:790px}
.proof-item{color:#fff}
.proof-ic{width:40px;height:40px;border-radius:11px;border:1px solid rgba(255,255,255,.34);display:grid;place-items:center;margin-bottom:13px;font-size:19px;color:#8fbcff;background:rgba(255,255,255,.04)}
.proof-item strong{display:block;font-family:var(--body);font-size:13px;line-height:1.4;font-weight:500;color:rgba(255,255,255,.9)}

.section-lead{font-size:16px;color:var(--muted);line-height:1.62;font-weight:300}

/* ---- Sambanden ----
   Replaced a four-step "thread" band whose four screenshots were four different
   objects — which argued against the very claim the band was making. One image
   carries the claim now, and the four product lines are just text beside it, so
   nothing on the page promises a continuity the pictures cannot show.
   The image sits in a reserved aspect box (3:2, the capture's own ratio) so it
   cannot shove the page around when it lazy-loads. */
/* ==== Vägar in: tre kundtyper (spår 12) ====
   Sits between the hero and the Engineering Map figure and must not compete
   with either, so it is TYPE, a hairline and a link. The product family lower
   down is the page's card row; a second one this high would read as the page
   starting a catalogue, which spår 8 exists to prevent.

   The keyline moves from the top edge to the left edge on hover, which is the
   whole hover state: a row that lifts and shadows would be a card again. */
.paths{padding:56px 0 8px}
.paths .head{max-width:800px;margin:0 auto 30px;text-align:center}
.paths h2{font-size:clamp(23px,2.4vw,32px);line-height:1.12;margin:0 0 12px;font-weight:800;letter-spacing:-.03em}
.paths .section-lead{margin:0}
.path-row{display:grid;grid-template-columns:repeat(3,1fr);gap:0 34px}
/* A flex column with the link pushed to the foot, so the three "Läs om" links
   land on one line however long the three sentences run. Left to flow they sat
   at three different heights, which on a row this sparse is the only thing the
   eye has to line up on. */
.path{
  display:flex;flex-direction:column;align-items:flex-start;
  padding:22px 0 2px;border-top:2px solid var(--line);
  color:inherit;text-decoration:none;
  transition:border-color .18s ease
}
.path .learn{margin-top:auto}
.path:hover{border-top-color:var(--blue)}
.path h3{margin:0 0 9px;font-size:16px;font-weight:700;letter-spacing:-.02em;color:var(--ink)}
.path p{margin:0 0 12px;font-size:14.5px;line-height:1.6;color:var(--muted);font-weight:300}
.path .learn{font-size:13.5px}
@media (max-width:900px){
  .path-row{grid-template-columns:1fr;gap:0}
  .path{padding:18px 0 4px}
}

.samband{background:linear-gradient(180deg,#fff,#f5f9ff);padding:84px 0 88px}
.samband .head{max-width:800px;margin:0 auto 44px;text-align:center}
.samband h2{font-size:clamp(28px,3.4vw,44px);line-height:1.08;margin:0 0 16px;font-weight:800;letter-spacing:-.035em}
.samband .section-lead{margin:0}
/* Four one-liners across, above the map. Standing them in a column beside the
   picture left the text floating in the middle of 600px of nothing; a row reads
   as four equal claims and lets the map have the full measure. */
.samband-list{list-style:none;margin:0 0 34px;padding:0;display:grid;grid-template-columns:repeat(4,1fr);gap:20px 26px}
.samband-list li{position:relative;padding-left:22px;font-size:15px;line-height:1.55;color:var(--muted);font-weight:300}
.samband-list li:before{content:"";position:absolute;left:0;top:8px;width:8px;height:8px;border-radius:999px;background:var(--blue)}
.samband-shot{margin:0;background:#fff;border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;
  box-shadow:var(--shadow-sm)}
/* Reserves the capture's OWN aspect (1600x1200, see index.html's Sambanden
   comment) so object-fit:cover has nothing to crop. It was 1536/1024 while the
   figure held the 3:2 mockup. */
/* A BUTTON since 2026-09-15 (it opens the full-size view), so it carries the
   resets a button brings with it. The aspect box and the cover fit are what
   they were. */
.samband-box{
  display:block;width:100%;padding:0;border:0;font:inherit;color:inherit;
  aspect-ratio:1600/900;background:#eef1f5;overflow:hidden;position:relative;cursor:zoom-in
}
.samband-box img{width:100%;height:100%;object-fit:cover;object-position:center;
  transition:transform .5s cubic-bezier(.22,1,.36,1)}
.samband-box:hover img,.samband-box:focus-visible img{transform:scale(1.015)}
.samband-box:focus-visible{outline:2px solid var(--blue);outline-offset:3px}
/* The affordance is quiet until the pointer is on the image: a badge sitting
   permanently on the page's main figure would read as part of the product. */
.samband-zoom{
  position:absolute;right:12px;bottom:12px;width:38px;height:38px;border-radius:12px;
  display:grid;place-items:center;font-size:17px;
  background:rgba(255,255,255,.93);color:#0a1626;box-shadow:0 6px 18px rgba(3,10,25,.22);
  opacity:0;transform:translateY(6px);transition:opacity .2s ease,transform .2s ease
}
.samband-box:hover .samband-zoom,
.samband-box:focus-visible .samband-zoom{opacity:1;transform:none}
@media (prefers-reduced-motion: reduce){
  .samband-box img{transition:none}
  .samband-box:hover img,.samband-box:focus-visible img{transform:none}
  .samband-zoom{transition:none}
}
.samband-shot figcaption{padding:14px 16px;font-size:13px;line-height:1.55;color:var(--muted);background:var(--soft);
  border-top:1px solid var(--line);font-weight:300}

/* ---- Filosofin: the scope statement ----
   Quiet on purpose. Same keyline-plus-blue-rule idiom as .stmt-card in the dark
   band, translated to the light half of the page: no icon, no badge, no card
   shadow competing with the family tiles right above it. */
.filo{background:linear-gradient(180deg,#f2f7fe,#fff);padding:0 0 84px}
.filo-card{max-width:840px;margin:0 auto;border:1px solid #d3e2f7;border-left:3px solid var(--blue);
  border-radius:18px;padding:34px 36px;background:#fff;box-shadow:var(--shadow-sm)}
.filo-card h2{font-size:clamp(22px,2.5vw,30px);line-height:1.14;margin:0 0 14px;font-weight:800;letter-spacing:-.03em}
.filo-card p{margin:0;font-size:16.5px;line-height:1.66;color:var(--muted);font-weight:300}
.filo-link{margin-top:20px}
@media(max-width:640px){.filo-card{padding:26px 22px}.filo{padding-bottom:64px}}

/* ---- Plattformen: the product family strip ----
   Five tiles directly under the hero, in product order: Core is the base, View,
   Projects and Production sit on it, Maintain is not shipped yet and is
   deliberately the quietest tile on the page. The three tiles that have a deep
   section further down are links; View and Maintain have nowhere to go, so they
   are plain divs and do not pretend to be clickable. */
.family{background:linear-gradient(180deg,#fff,#f2f7fe);padding:36px 0 92px}
.family .head{text-align:center;max-width:760px;margin:0 auto 44px}
.family h2{font-size:clamp(28px,3.4vw,44px);line-height:1.08;margin:0 0 16px;font-weight:800}
.fam-strip{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;align-items:stretch}
.fam-more{text-align:center;margin-top:28px}
.fam-tile{display:flex;flex-direction:column;background:#fff;border:1px solid var(--line);border-radius:var(--radius);
  padding:22px 20px;box-shadow:var(--shadow-sm);transition:transform .2s ease,box-shadow .2s ease,border-color .2s ease}
a.fam-tile:hover{transform:translateY(-4px);box-shadow:var(--shadow);border-color:#cfe0fb}
a.fam-tile:focus-visible{outline:2px solid var(--blue);outline-offset:3px}
a.fam-tile:hover .learn .ic{transform:translateX(3px)}
.fam-tile--base{background:linear-gradient(180deg,#f6faff,#fff);border-color:#cfe0fb}
.fam-ic{width:38px;height:38px;border-radius:11px;border:1px solid #cfe0fb;background:#f4f9ff;color:var(--blue);
  display:grid;place-items:center;font-size:19px;margin-bottom:14px}
.fam-tag{display:inline-flex;align-items:center;align-self:flex-start;min-height:22px;font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;font-weight:700;color:var(--muted-2)}
.fam-tile h3{margin:6px 0 8px;font-size:17px;font-weight:800;letter-spacing:-.02em}
.fam-tile p{margin:0 0 16px;color:var(--muted);font-size:13.5px;line-height:1.55;font-weight:300;flex:1}
.fam-tile .learn{margin-top:auto}
/* Maintain: shipped-nothing-yet, so it reads as a placeholder, not a promise. */
.fam-tile--soon{background:#fbfcfe;border-style:dashed}
.fam-tile--soon .fam-ic{border-color:var(--line);background:#fff;color:var(--muted-2)}
.fam-tile--soon h3{color:var(--muted)}
.fam-tile--soon p{color:var(--muted-2)}
/* neutral, not amber: Maintain should read as the quietest tile on the strip,
   and an amber pill was the loudest thing in it */
.fam-tag--soon{color:var(--muted-2);background:#eef2f8;border:1px solid var(--line);border-radius:999px;padding:0 9px;letter-spacing:.1em}

/* ---- Product sections (Bimdoc Projects / Bimdoc Production) ----
   Same paddings, same head block, same type scale: the two products carry equal
   visual weight, which is the whole point of the page. */
.psec{background:#fff;padding:92px 0}
.psec--alt{background:linear-gradient(180deg,#f4f9ff,#fff)}
.psec-head{max-width:860px;margin:0 0 34px}
.psec-head h2{font-size:clamp(28px,3.2vw,42px);line-height:1.08;margin:0 0 12px;font-weight:800;letter-spacing:-.035em}
.psec .flow{margin-top:0}
.psec-cards{margin-top:34px}
.psec-note{margin:16px 0 0;font-size:12.5px;color:var(--muted-2);font-weight:300}
/* View is a short section: a head block and nothing under it, so it does not
   need the 34px of air a card grid would sit in. */
.psec-head--solo{margin-bottom:0}
.psec-head--solo .section-lead{max-width:760px}

/* Product descriptions share the site's typography and appearance tokens. */
.products-view .page-hero .wrap{max-width:940px}
.products-view .page-hero h1{max-width:22ch}
.products-view .page-hero p{max-width:740px}
.product-index{display:flex;flex-wrap:wrap;justify-content:center;gap:10px;padding:28px 0 48px}
.product-index a{padding:10px 16px;border:1px solid var(--line);border-radius:8px;background:var(--soft);font-size:13px;font-weight:600;transition:border-color .18s ease}
.product-index a:hover{border-color:var(--blue)}
.product-index a:focus-visible,.product-more:focus-visible{outline:2px solid var(--blue);outline-offset:4px}
.product-layout{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.4fr);gap:clamp(32px,6vw,88px);align-items:start}
.product-intro .eyebrow{line-height:1.6}
.product-intro h2{font-size:clamp(30px,3.2vw,42px);line-height:1.08;margin:0 0 18px;font-weight:800}
.product-tagline{font-family:var(--disp);font-size:clamp(20px,2vw,25px);line-height:1.35;letter-spacing:-.02em;margin:0;max-width:360px}
.product-details>.section-lead{margin:0;max-width:none;font-size:16px;line-height:1.8}
.product-features{margin:28px 0 0}
.product-features>div{padding:21px 0;border-top:1px solid var(--line)}
.product-features dt{font-family:var(--disp);font-size:18px;font-weight:700;line-height:1.35;margin-bottom:8px}
.product-features dd{font-size:14px;font-weight:300;line-height:1.8;color:var(--muted);margin:0}
.product-note{margin:16px 0 0;font-size:13px;line-height:1.8;color:var(--muted)}
.product-mcp-overview{border-top:1px solid var(--line)}
.product-mcp-overview .product-intro{border-left:3px solid var(--blue-ink);padding-left:24px}
.product-mcp-overview .product-intro h2{max-width:14ch;margin-bottom:0}
.product-mcp{margin-top:26px;padding:2px 0 2px 20px;border-left:3px solid var(--blue-ink)}
.product-mcp h3{margin:0 0 9px;font-family:var(--disp);font-size:16px;font-weight:700;line-height:1.5;color:var(--blue-ink)}
.product-mcp p{margin:0;font-size:14px;line-height:1.8;color:var(--muted);font-weight:300}
.product-more{margin-top:24px}
.product-planned{border-top:1px dashed var(--line)}
.product-close{padding:64px 0 84px;background:var(--soft);text-align:center}
.product-close h2{font-size:clamp(26px,3vw,36px);line-height:1.2;margin:0 auto 16px;max-width:700px}
.product-close p{color:var(--muted);max-width:630px;margin:0 auto 26px;font-size:15px;line-height:1.8}
@media(max-width:800px){
  .product-layout{grid-template-columns:1fr;gap:26px}
  .product-tagline{max-width:540px}
  .product-index{padding-bottom:30px}
}
@media(max-width:480px){
  .product-index{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
  .product-index a{padding:11px 8px;text-align:center;font-size:12px}
  .product-details>.section-lead{font-size:15px}
}

/* Bimdoc Maintain: nothing has shipped, so it is a single quiet dashed line at
   the foot of the page, exactly the framing the family strip uses. */
.mt-band{background:#fff;padding:0 0 92px}
.mt-row{border:1px dashed #cfdaea;border-radius:var(--radius);background:#fbfcfe;padding:26px 28px}
.mt-h{margin:10px 0 6px;font-size:20px;font-weight:800;letter-spacing:-.02em;color:var(--muted)}
.mt-p{margin:0;font-size:14px;line-height:1.6;color:var(--muted-2);font-weight:300}

/* Production screenshots: real captures, aspect boxes so nothing reflows while
   they lazy-load, cropped from the top-left because that is where the toolbars
   and key figures live in every one of them. */
.shot-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:22px}
.shot-card{margin:0;background:#fff;border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;box-shadow:var(--shadow-sm)}
.shot-bar{height:30px;display:flex;align-items:center;gap:6px;padding:0 12px;background:#0b1c33}
.shot-bar i{width:8px;height:8px;border-radius:50%;background:rgba(255,255,255,.22);flex:none}
.shot-bar span{margin-left:8px;font-family:var(--mono);font-size:10px;letter-spacing:.08em;color:rgba(255,255,255,.66);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.shot-box{aspect-ratio:16/10;background:#0b1c33;overflow:hidden}
.shot-box img{width:100%;height:100%;object-fit:cover;object-position:top left}
/* Core's captures are dense configuration screens: half a column makes the
   tables unreadable, so they run one per row, each cropped to the rows that
   carry the point (object-position is already top left). */
.core-shots{grid-template-columns:1fr;gap:26px}
.core-shots .shot-card--crop90 .shot-box{aspect-ratio:16/9}
.core-shots .shot-card--crop76 .shot-box{aspect-ratio:16/7.6}
.core-shots .shot-card--crop65 .shot-box{aspect-ratio:16/6.5}
.shot-card figcaption{padding:14px 16px;font-size:13px;line-height:1.55;color:var(--muted);background:var(--soft);
  border-top:1px solid var(--line);font-weight:300}

.pr-foot{display:grid;grid-template-columns:1.05fr .95fr;gap:26px;margin-top:26px;align-items:start}
.oee{background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:20px;box-shadow:var(--shadow-sm)}
.oee h3{margin:0 0 14px;font-size:15px;font-weight:800;letter-spacing:-.01em}
.oee-calc{display:grid;grid-template-columns:1fr auto 1fr;gap:14px;align-items:center}
.oee-in,.oee-out{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:8px 11px;
  border:1px solid var(--line);border-radius:9px;font-size:12.5px;color:var(--muted);margin-bottom:6px}
.oee-in b,.oee-out b{font-family:var(--mono);font-size:12px;color:var(--ink);white-space:nowrap}
.oee-out{background:#f4f9ff;border-color:#cfe0fb}
.oee-mid{display:grid;justify-items:center;gap:8px;font-family:var(--mono);font-size:9px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted-2);text-align:center;width:118px;line-height:1.5}
.oee-ar{font-size:22px;line-height:1;color:var(--blue)}
.oee-cap{margin:12px 0 0;font-size:12.5px;color:var(--muted-2);font-weight:300}
.pr-list,.grund-list{list-style:none;margin:0;padding:0;display:grid;gap:12px}
.pr-list li,.grund-list li{position:relative;padding-left:26px;font-size:14px;line-height:1.6;color:var(--muted);font-weight:300}
.pr-list li:before,.grund-list li:before{content:"";position:absolute;left:0;top:8px;width:8px;height:8px;border-radius:999px;background:var(--blue)}

/* ---- Core: the configuration story (Produkter view) ----
   The tree card is ported from the /news/produktion teaser and shows the same
   real objects, restyled into this page's light idiom. Its toggle keeps its own
   state on the card element, so the two surfaces can never move each other. */
/* the two-class selector is deliberate: it has to beat .grund-grid's centring,
   which is declared right below it */
/* The closing "the register lives on" line is the section's point, not a fourth
   caption, so it gets its own air and the body ink rather than caption grey. */
.core-live{margin:36px 0 0;max-width:860px;font-size:17.5px;line-height:1.62;color:var(--ink)}
.grund-grid.core-struct{margin-top:52px;align-items:start}
.core-sub-h{font-size:clamp(21px,2.2vw,28px);line-height:1.15;margin:0 0 12px;font-weight:800;letter-spacing:-.03em}
.grund-grid{display:grid;grid-template-columns:.95fr 1.05fr;gap:48px;align-items:center}
.grund-copy h2{font-size:clamp(26px,3vw,38px);line-height:1.1;margin:0 0 12px;font-weight:800;letter-spacing:-.035em}
.grund-copy .section-lead{margin:0 0 24px}
.tpl{background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:20px;box-shadow:var(--shadow)}
/* Four chips now: two real templates and two that are only announced, so the
   group wraps instead of pushing the card sideways on a phone. */
.tpl-tog{display:inline-flex;flex-wrap:wrap;border:1px solid var(--line);border-radius:13px;overflow:hidden;background:var(--soft)}
.tpl-btn{font-family:var(--mono);font-size:11px;font-weight:700;letter-spacing:.04em;padding:8px 15px;border:0;
  background:none;color:var(--muted);cursor:pointer;line-height:1;transition:.16s ease}
.tpl-btn:hover{color:var(--ink)}
.tpl-btn[aria-pressed="true"]{background:linear-gradient(180deg,#2f86ff,#1063e8);color:#fff}
/* Announced, not shipped: quieter than the real chips, no hover, no pointer,
   and no tree behind them. The product seeds exactly two templates. */
.tpl-btn--soon,.tpl-btn--soon:hover{color:var(--muted-2);opacity:.55;cursor:default;font-weight:600;
  border-left:1px dashed var(--line)}
.tpl-sub{font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--blue-ink);margin-top:14px;line-height:1.5}
.tpl-isa{display:none}
#tplCard[data-tpl="isa"] .tpl-ssg{display:none}
#tplCard[data-tpl="isa"] .tpl-isa{display:inline}
.tpl-tree{list-style:none;margin:12px 0 0;padding:0;display:flex;flex-direction:column;gap:6px}
.tpl-tree[hidden]{display:none}
/* the staircase is the tree: one indent step per level, on the box itself */
.tpl-tree li{background:var(--soft);border:1px solid var(--line);border-radius:10px;padding:9px 12px;margin-left:calc(var(--d)*16px)}
.tr-top{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.tr-id{font-family:var(--mono);font-size:12px;font-weight:700;color:var(--blue-ink);letter-spacing:.03em}
.tr-p{font-family:var(--mono);font-size:9px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted-2);
  background:#fff;border:1px solid var(--line);border-radius:999px;padding:3px 8px;white-space:nowrap}
.tr-n{font-size:13px;color:var(--ink);margin-top:4px;line-height:1.35;overflow-wrap:anywhere}
/* Class groups are a different kind of row from the level rows: code, plural
   class name and the real count, no level pill, drawn lighter so the levels stay
   the ladder and the classes read as how a rung is organised. */
.tpl-tree li.tr-cls{background:transparent;border-style:dashed;padding:7px 12px}
.tr-cls .tr-id{color:var(--muted-2)}
.tr-cn{font-size:12px;color:var(--muted);line-height:1.3}
.tr-ct{margin-left:auto;font-family:var(--mono);font-size:10px;color:var(--muted-2);white-space:nowrap}
.tpl-note{margin-top:12px;font-family:var(--mono);font-size:10px;color:var(--muted-2);letter-spacing:.04em;line-height:1.6}
.grund-engine{margin:16px 0 0;background:var(--soft);border:1px dashed #c9d7ea;border-radius:13px;padding:14px 16px;
  font-size:13px;color:var(--muted);text-align:center;line-height:1.55;font-weight:300}

.cx-actions{display:flex;align-items:center;gap:22px;flex-wrap:wrap;margin-top:22px}
.cx-actions .learn{margin-top:0}

/* ---- Platform: "Why teams choose Bimdoc" + dashboard mockup ---- */
.plat-why{background:#fff;padding:96px 0}
.split{display:grid;grid-template-columns:.85fr 1.15fr;gap:56px;align-items:center}
.split h2{font-size:clamp(28px,3.2vw,42px);line-height:1.08;margin:0 0 8px;font-weight:800;letter-spacing:-.035em}
.bullet-list{display:grid;gap:22px;margin-top:30px}
.bullet{display:grid;grid-template-columns:28px 1fr;gap:16px}
.bullet-dot{width:26px;height:26px;border-radius:999px;background:var(--blue);color:#fff;display:grid;place-items:center;font-size:15px}
.bullet-dot .ic{stroke-width:2.6}
.bullet h3{font-size:17px;margin:0 0 5px;font-weight:700}
.bullet p{margin:0;color:var(--muted);font-size:14px;line-height:1.6;font-weight:300}
.app-window{border-radius:18px;overflow:hidden;background:#fff;box-shadow:var(--shadow);border:1px solid var(--line);display:grid;grid-template-columns:166px 1fr;min-height:430px}
.app-side{background:#051226;color:#fff;padding:20px 14px}
.mini-logo{display:flex;align-items:center;gap:8px;margin-bottom:24px;padding:0 4px}
.mini-logo img{height:18px;width:auto}
.side-link{height:33px;display:flex;align-items:center;gap:9px;color:rgba(255,255,255,.72);font-size:12.5px;border-radius:9px;padding:0 10px;font-weight:400}
.side-link .ic{font-size:15px;opacity:.85}
.side-link.active{background:rgba(47,140,255,.16);color:#fff}
.app-main{padding:22px;background:#fbfdff}
.metric-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-bottom:12px}
.metric{background:#fff;border:1px solid #e6edf7;border-radius:12px;padding:13px 12px}
.metric small{display:block;color:var(--muted-2);font-size:10.5px;margin-bottom:8px;line-height:1.3;min-height:2.6em}
.metric strong{display:block;font-family:var(--disp);font-size:21px;letter-spacing:-.03em;font-weight:800;white-space:nowrap;line-height:1.1}
.mtrend{display:block;margin-top:7px}
.mpct{display:block;font-family:var(--disp);font-size:12px;font-weight:800;color:#00a870;letter-spacing:-.01em}
.mper{display:block;font-size:9.5px;color:var(--muted-2);white-space:nowrap;margin-top:1px}
.dash-grid{display:grid;grid-template-columns:1.1fr 1fr 1fr;gap:10px}
.dash-card{background:#fff;border:1px solid #e6edf7;border-radius:13px;padding:14px 13px;min-height:190px;display:flex;flex-direction:column}
.dash-card h4{margin:0 0 12px;font-size:13px;font-weight:700}
.dash-model .model-wrap{flex:1;border-radius:9px;overflow:hidden;background:#0b1c33;min-height:130px}
.model-img{height:100%;width:100%;object-fit:cover;display:block}

/* ---- Animated lifecycle flow (replaces the old dashboard mockup) ---- */
.plat-why .bullet-grid{grid-template-columns:repeat(2,1fr);gap:22px 44px;margin-top:26px;max-width:920px}
@media(max-width:720px){.plat-why .bullet-grid{grid-template-columns:1fr}}
.flow{background:linear-gradient(165deg,#07182f,#020a18);border-radius:22px;padding:28px 26px 24px;position:relative;overflow:hidden;border:1px solid rgba(120,175,255,.14);box-shadow:var(--shadow);margin-top:48px}
.flow:before{content:"";position:absolute;inset:0;background:radial-gradient(60% 80% at 50% 0%,rgba(47,136,255,.16),transparent 70%);pointer-events:none}
.flow-eyebrow{font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;font-weight:700;color:#5aa0ff;margin-bottom:7px}
.flow-title{font-family:var(--disp);font-size:22px;font-weight:800;color:#fff;letter-spacing:-.02em;margin:0 0 4px}
.flow-sub{font-size:14px;color:#9db6d6;font-weight:300;margin:0 0 22px;max-width:640px;line-height:1.5}
.flow-scroll{position:relative}
.flow-svg{width:100%;height:auto;display:block;overflow:visible}
.flow-ic{fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.flow-node-ring{transform-box:fill-box;transform-origin:center;animation:flowNodePulse 3.4s ease-in-out infinite}
.flow-n1 .flow-node-ring{animation-delay:0s}.flow-n2 .flow-node-ring{animation-delay:.55s}.flow-n3 .flow-node-ring{animation-delay:1.1s}.flow-n4 .flow-node-ring{animation-delay:1.65s}.flow-n5 .flow-node-ring{animation-delay:2.2s}
@keyframes flowNodePulse{0%,72%,100%{opacity:.4;transform:scale(1)}12%{opacity:1;transform:scale(1.1)}30%{opacity:.6;transform:scale(1)}}
.flow-conn{stroke-dasharray:5 7;animation:flowDash 1.1s linear infinite}
@keyframes flowDash{to{stroke-dashoffset:-24}}
.flow-pulse{filter:drop-shadow(0 0 6px #7fd0ff)}
.flow-labels{display:grid;grid-template-columns:repeat(5,1fr);margin-top:6px}
.flow-lab{text-align:center;padding:0 6px}
.flow-lab span{display:block;font-family:var(--disp);font-size:14.5px;font-weight:800;color:#fff;letter-spacing:-.01em}
.flow-lab small{display:block;font-size:11px;color:#9db6d6;margin-top:2px;line-height:1.35}
@media (prefers-reduced-motion:reduce){.flow-node-ring,.flow-conn,.flow-pulse{animation:none}.flow-node-ring{opacity:.85}}
@media(max-width:820px){.flow-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;padding-bottom:8px}.flow-svg,.flow-labels{min-width:700px}}

/* ---- Handover / Object-360 section ---- */
.handover{background:linear-gradient(180deg,#f2f7fe,#fff);padding:82px 0}
.handover-h2{font-size:clamp(28px,3.2vw,42px);line-height:1.08;margin:0 0 12px;font-weight:800;letter-spacing:-.035em}
.handover-lead{max-width:740px;margin:0 0 30px}
.handover-shot{margin:0;border-radius:16px;overflow:hidden;border:1px solid var(--line);box-shadow:var(--shadow);background:#fff}
/* aspect box: the diagram lazy-loads mid-page, and without a reserved height it
   grows the page under the reader (and under any anchor scroll) when it lands */
.handover-shot img{width:100%;height:auto;display:block;aspect-ratio:1826/636}
.handover-land{margin-top:34px}
.handover-land-lbl{display:inline-block;font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;font-weight:700;color:var(--blue);margin-bottom:16px}
.handover-sys-row{display:grid;grid-template-columns:repeat(4,1fr);gap:16px}
.handover-sys{display:flex;align-items:center;gap:12px;padding:14px 16px;border:1px solid var(--line);border-radius:12px;background:#fff;box-shadow:var(--shadow-sm)}
.handover-sys .ic{font-size:22px;color:var(--blue);flex:none}
.handover-sys strong{display:block;font-size:14.5px;font-weight:700}
.handover-sys small{display:block;font-size:12px;color:var(--muted);margin-top:1px}
@media(max-width:820px){.handover-sys-row{grid-template-columns:repeat(2,1fr)}}
@media(max-width:460px){.handover-sys-row{grid-template-columns:1fr}}
.activity{display:grid;gap:12px;align-content:start}
.activity-row{display:grid;grid-template-columns:20px 1fr;gap:9px;font-size:12px;color:var(--muted);line-height:1.35;align-items:start}
.activity-dot{width:20px;height:20px;border-radius:999px;background:#eaf3ff;color:var(--blue-ink);display:grid;place-items:center;font-size:9.5px;font-weight:700;font-family:var(--mono)}
.dash-ai{gap:2px}
.ai-stat{margin-bottom:6px}
.ai-stat .muted{font-size:10.5px;display:block}
.ai-stat strong{display:block;font-family:var(--disp);font-size:20px;letter-spacing:-.02em;font-weight:800;margin:1px 0 4px;white-space:nowrap}
.spark{width:100%;height:30px;display:block}
.spark polyline{fill:none;stroke:var(--blue);stroke-width:2;stroke-linejoin:round;stroke-linecap:round;vector-effect:non-scaling-stroke}
.spark .fill{fill:rgba(26,116,255,.1);stroke:none}

/* ---- Platform: dark "Built for complex projects" band ---- */
.dark-band{background:#031027;color:#fff;padding:88px 0}
.dark-proof-grid{display:grid;grid-template-columns:1fr 1.5fr;gap:48px;align-items:center}
.dark-band h2{font-size:clamp(28px,3.2vw,42px);line-height:1.06;margin:0 0 16px;color:#fff;font-weight:800;letter-spacing:-.035em}
.dark-band .section-lead{color:rgba(255,255,255,.72)}
.dark-band .learn{color:#5fa0ff;margin-top:8px}
/* A plain statement, not a quote: no quotation mark, no attribution. The blue
   keyline on the left carries the emphasis the quote mark used to. */
.stmt-card{border:1px solid rgba(124,174,255,.22);border-left:3px solid #2f88ff;border-radius:18px;padding:34px 36px;
  background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.02));box-shadow:0 28px 80px rgba(0,0,0,.25)}
.stmt-card p{font-size:20px;color:rgba(255,255,255,.92);margin:0;line-height:1.5;font-weight:300;letter-spacing:-.01em}

/* ---- Solution detail modal ---- */
.solution-card{cursor:pointer}
.solution-card:focus-visible{outline:2px solid var(--blue);outline-offset:3px}
.solution-card:hover .learn .ic{transform:translateX(3px)}
.sol-modal-overlay{position:fixed;inset:0;z-index:200;display:grid;place-items:center;padding:22px;background:rgba(3,10,25,.55);backdrop-filter:blur(6px);opacity:0;transition:opacity .22s ease}
.sol-modal-overlay.open{opacity:1}
.sol-modal-overlay[hidden]{display:none}
.sol-modal{width:min(860px,100%);max-height:90vh;overflow-y:auto;background:#fff;border-radius:20px;box-shadow:0 40px 120px rgba(3,10,25,.5);position:relative;transform:translateY(10px) scale(.985);transition:transform .22s ease}
.sol-modal-overlay.open .sol-modal{transform:none}
.sol-modal-close{position:absolute;top:13px;right:14px;z-index:3;width:36px;height:36px;border-radius:50%;border:0;background:rgba(255,255,255,.92);color:#0a1626;font-size:24px;line-height:1;cursor:pointer;display:grid;place-items:center;box-shadow:0 6px 18px rgba(0,0,0,.2)}
.sol-modal-close:hover{background:#fff}
.sol-modal-media{position:relative;margin:0;height:clamp(190px,32vh,300px);background:#0b1c33;overflow:hidden;border-radius:20px 20px 0 0}
.sol-modal-media img{width:100%;height:100%;object-fit:cover;object-position:top center;display:block}
/* Diagram images (Engineering Map graph) show in full instead of being cropped —
   the graph bg is light, so letterboxing on narrow/mobile banners blends in. */
.sol-modal-media.is-diagram{background:#eef1f5}
.sol-modal-media.is-diagram img{object-fit:contain;object-position:center}
/* Optional looping video (main.js only creates it when a solution defines
   `video`); layered on top of the <img>, which stays as the poster/fallback. */
.sol-modal-media video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:top center;display:block}
.sol-modal-media.is-diagram video{object-fit:contain;object-position:center}
.sol-modal-body{padding:28px 32px 30px}
.sol-modal-body .card-ic{font-size:26px;color:var(--blue);margin-bottom:14px;display:inline-flex}
.sol-modal-body h3{font-size:24px;margin:0 0 12px;font-weight:800;letter-spacing:-.03em}
.sol-modal-intro{color:var(--muted);font-size:15px;line-height:1.62;margin:0 0 20px;font-weight:300}
.sol-modal-list{list-style:none;margin:0 0 20px;padding:0;display:grid;gap:12px}
.sol-modal-list li{position:relative;padding-left:30px;font-size:14.5px;color:var(--ink);line-height:1.5}
.sol-modal-list li:before{content:"✓";position:absolute;left:0;top:0;width:20px;height:20px;border-radius:6px;background:var(--blue);color:#fff;font-size:11px;font-weight:800;line-height:20px;text-align:center}
.sol-modal-note{font-size:12px;color:var(--muted-2);margin:0 0 18px;font-weight:300}
.sol-modal-actions{display:flex}
@media (max-width:640px){
  .sol-modal-body{padding:22px 22px 26px}
  .sol-modal-body h3{font-size:21px}
}

/* ---- Page hero (solutions / industries / resources) ---- */
.page-hero{padding:calc(var(--hdr-total) + 52px) 0 12px;text-align:center}
.page-hero .wrap{max-width:820px}
.page-hero h1{font-size:clamp(32px,4.2vw,50px);line-height:1.08;margin:0 auto 16px;letter-spacing:-.04em;font-weight:800;max-width:16ch}
/* Branscher's heading is two full sentences with an authored break, so it needs
   the measure of its longer line rather than the 16ch default. */
.view[data-view="industries"] .page-hero h1{max-width:26ch}
.page-hero p{font-size:16px;color:var(--muted);max-width:620px;margin:0 auto;line-height:1.6;font-weight:300}
.section{padding:44px 0 96px}

/* ---- Solutions grid ---- */
.solution-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
.solution-card{background:#fff;border:1px solid var(--line);border-radius:16px;padding:28px 26px;box-shadow:var(--shadow-sm);transition:transform .2s ease,box-shadow .2s ease,border-color .2s ease}
.solution-card:hover{transform:translateY(-4px);box-shadow:var(--shadow);border-color:#cfe0fb}
.card-ic{font-size:26px;color:var(--blue);margin-bottom:20px;display:inline-flex}
.solution-card h3{margin:0 0 9px;font-size:18px;font-weight:700}
.solution-card p{margin:0 0 20px;color:var(--muted);font-size:14px;line-height:1.6;font-weight:300}
.learn{color:var(--blue-ink);font-weight:600;font-size:13px;display:inline-flex;align-items:center;gap:7px;cursor:pointer}
.learn .ic{font-size:15px;transition:transform .18s ease}
.learn:hover .ic{transform:translateX(3px)}

/* ---- CTA strips ---- */
.strip{margin-top:36px;background:linear-gradient(90deg,#ecf4ff,#f8fbff);border:1px solid #d9e8ff;border-radius:16px;padding:24px 28px;display:flex;align-items:center;justify-content:space-between;gap:24px}
.strip-l{display:flex;align-items:center;gap:18px}
.strip-badge{width:46px;height:46px;border-radius:12px;background:#fff;border:1px solid #cfe0fb;display:grid;place-items:center;color:var(--blue);font-size:22px;flex:none}
.strip h3{margin:0;font-size:18px;font-weight:700}
.strip p{margin:4px 0 0;color:var(--muted);font-size:14px;font-weight:300}

/* ---- Industries grid ----
   Four keyline cards, two up. The stock photography went with the two
   industries that were dropped: there is no honest manufacturing photograph in
   the asset set, and one of the four cards standing bare would have read as a
   broken image. Same card idiom as .solution-card, so the two grids match. */
.industry-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:20px}
.industry-card{display:flex;flex-direction:column;background:#fff;border:1px solid var(--line);border-radius:16px;padding:28px 26px;box-shadow:var(--shadow-sm);transition:transform .2s ease,box-shadow .2s ease,border-color .2s ease}
.industry-card:hover{transform:translateY(-4px);box-shadow:var(--shadow);border-color:#cfe0fb}
.industry-card:hover .learn .ic{transform:translateX(3px)}
.industry-card .card-ic{margin-bottom:18px}
.industry-card h3{margin:0 0 9px;font-size:18px;font-weight:700}
.industry-card p{font-size:14px;color:var(--muted);margin:0 0 20px;line-height:1.6;font-weight:300;flex:1}
.industry-card .learn{align-self:flex-start}

/* ---- Company ---- */
.company{padding:calc(var(--hdr-total) + 44px) 0 0}
.company-grid{display:grid;grid-template-columns:.92fr 1.08fr;gap:56px;align-items:center}
.company-grid .eyebrow{margin-bottom:14px}
.company-grid h1{font-size:clamp(30px,3.6vw,46px);line-height:1.06;letter-spacing:-.04em;margin:0 0 18px;font-weight:800}
.company-lead{font-size:16px;line-height:1.68;color:var(--muted);max-width:520px;font-weight:300}
.value-list{display:grid;gap:22px;margin-top:34px}
.value{display:grid;grid-template-columns:46px 1fr;gap:16px}
.value-ic{width:44px;height:44px;border-radius:13px;border:1px solid #cfe0fb;background:#f4f9ff;color:var(--blue);display:grid;place-items:center;font-size:21px}
.value h3{margin:0 0 5px;font-size:16px;font-weight:700}
.value p{margin:0;color:var(--muted);font-size:14px;line-height:1.6;font-weight:300}
.company-photo{position:relative;border-radius:18px;overflow:hidden;box-shadow:var(--shadow);aspect-ratio:4/3;background:#071327}
.company-photo img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.company-photo:after{content:"";position:absolute;inset:0;background:linear-gradient(0deg,rgba(2,9,22,.9) 0%,rgba(2,9,22,.4) 45%,rgba(2,9,22,0) 75%)}
/* The caption overlay is gone, so the heavy bottom scrim has nothing to make
   legible; it stays only as a light tint that ties the photo to the dark CTA. */
.company-photo--plain:after{background:linear-gradient(0deg,rgba(2,9,22,.3) 0%,rgba(2,9,22,.06) 55%,rgba(2,9,22,0) 100%)}
/* Three facts, no invented statistics: a fact is a claim plus the thing that
   backs it, so each card is a strong line and a plain one, nothing else. */
.fact-row{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;margin-top:64px}
.fact{padding:24px 24px;background:linear-gradient(180deg,#f8fbff,#f2f7fe);border:1px solid var(--line);border-radius:16px}
.fact strong{display:block;font-family:var(--disp);font-size:17px;font-weight:800;letter-spacing:-.02em;line-height:1.2;margin-bottom:8px}
.fact span{display:block;font-size:14px;color:var(--muted);line-height:1.6;font-weight:300}
.company-cta{margin:64px 0 0;background:linear-gradient(120deg,#031027,#06274f);color:#fff;border-radius:18px;padding:34px 40px;display:flex;align-items:center;justify-content:space-between;gap:26px}
.company-cta h3{margin:0;font-size:22px;font-weight:800}
.company-cta p{margin:6px 0 0;color:rgba(255,255,255,.76);font-size:15px;font-weight:300}

/* ============================ FOOTER ============================ */
.footer{background:#020b1a;color:#fff;padding:52px 0 calc(40px + var(--safe-bottom));margin-top:96px}
.footer-top{display:flex;justify-content:space-between;gap:40px;flex-wrap:wrap;padding-bottom:32px;border-bottom:1px solid rgba(255,255,255,.1)}
.footer-brandcol{max-width:320px}
.footer-brandcol p{margin:14px 0 0;color:rgba(255,255,255,.6);font-size:14px;line-height:1.62;font-weight:300}
.footer-cols{display:flex;gap:70px;flex-wrap:wrap}
.footer-col h4{color:#fff;font-size:13px;margin:0 0 14px;letter-spacing:.01em;font-weight:700}
.footer-col a{display:block;color:rgba(255,255,255,.62);font-size:14px;padding:5px 0;cursor:pointer;font-weight:300}
.footer-col a[hidden]{display:none}
.footer-col a:hover{color:#fff}
.footer-address{font-style:normal;color:rgba(255,255,255,.62);font-size:14px;line-height:1.9;font-weight:300}
.footer-address a{color:rgba(255,255,255,.62)}
.footer-address a:hover{color:#fff}
.footer-legal{display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap;padding-top:22px;color:rgba(255,255,255,.5);font-size:13px;font-weight:300}

/* company view has its own footer spacing (cta already dark) */
.view[data-view="company"] .footer{margin-top:0}

/* ============================ RESPONSIVE ============================ */
@media (max-width:1000px){
  /* Mobile bar = brand + hamburger only. Everything else drops into a menu. */
  .nav-links,.nav-actions{display:none}
  .mobile-menu{display:inline-flex}
  .site-header.transparent{background:linear-gradient(180deg,#020d20,#020913);box-shadow:0 8px 30px rgba(0,0,0,.22);border-bottom-color:rgba(255,255,255,.08)}
  .brand{font-size:19px;gap:9px}
  .brand-mark{height:26px}

  /* Open state: header grows and the links + actions stack full-width below. */
  .site-header.nav-open{background:#020b1a}
  .site-header.nav-open .nav{height:auto;min-height:var(--hdr-h);flex-wrap:wrap;align-items:center;row-gap:0;padding-bottom:10px}
  .site-header.nav-open .nav-links{
    display:flex;flex-direction:column;align-items:stretch;order:3;flex-basis:100%;gap:2px;
    margin-top:8px;padding-top:10px;border-top:1px solid rgba(255,255,255,.1)}
  .site-header.nav-open .nav-links a{width:100%;padding:14px 12px;border-radius:10px;font-size:16px}
  .site-header.nav-open .nav-links a.active:after{display:none}
  .site-header.nav-open .nav-links a.active{background:rgba(47,140,255,.16)}
  .site-header.nav-open .nav-links a:hover{background:rgba(255,255,255,.06)}
  .site-header.nav-open .nav-actions{
    display:flex;order:4;flex-basis:100%;align-items:center;flex-wrap:wrap;gap:14px;padding-top:12px}
  .site-header.nav-open .nav-actions .login{display:inline-block}
  /* Boka demo already lives in the hero + section CTAs; drop it from the mobile menu. */
  .site-header.nav-open .nav-actions .btn-primary{display:none}
  .mobile-menu{order:2}

  .hero-proof{grid-template-columns:repeat(2,1fr);gap:22px}
  .solution-grid{grid-template-columns:repeat(2,1fr)}
  /* 5 across becomes 3 + 2: the strip wraps on purpose rather than scrolling
     sideways, so no tile can hide off-screen. */
  .fam-strip{grid-template-columns:repeat(3,1fr)}
  .shot-grid{grid-template-columns:1fr}
  /* Sambanden: the row of four becomes two, then one on a phone. */
  .samband{padding:60px 0 64px}
  .samband .head{margin-bottom:34px}
  .samband-list{grid-template-columns:repeat(2,1fr);gap:16px 24px;margin-bottom:28px}
  .pr-foot{grid-template-columns:1fr}
  .grund-grid{grid-template-columns:1fr;gap:34px}
  .psec{padding:64px 0}
  .mt-band{padding:0 0 64px}
  .family{padding:32px 0 64px}
  .company-grid{grid-template-columns:1fr;gap:36px}
  .fact-row{grid-template-columns:1fr;gap:14px;margin-top:44px}
  .split,.dark-proof-grid{grid-template-columns:1fr;gap:40px}
  .app-window{grid-template-columns:1fr}
  .app-side{display:none}
  .dash-grid{grid-template-columns:1fr}
  .metric-grid{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:640px){
  .wrap{width:min(100% - 32px,1200px)}
  :root{--hdr-h:62px}
  .hero{padding-top:calc(var(--hdr-total) + 46px)}
  /* "anläggningsinformation" is one 22-character word: on a phone the headline
     has to scale with the viewport, or it runs into the right edge on anything
     narrower than a 390. break-word is the floor under that. */
  .hero h1{font-size:clamp(26px,7.9vw,34px);overflow-wrap:break-word}
  /* Same 22-character word in the Insikter page-hero: the desktop clamp floors
     at 32px, which is 351px of glyphs against a 328px column on a 375 phone. */
  .page-hero h1{font-size:clamp(28px,7.9vw,32px);overflow-wrap:break-word}
  .hero-proof,.solution-grid,.industry-grid{grid-template-columns:1fr}
  .fam-strip{grid-template-columns:1fr}
  /* the calc reads top to bottom on a phone; the arrow turns with it */
  .oee-calc{grid-template-columns:1fr;gap:8px}
  .oee-mid{width:auto;grid-auto-flow:column;align-items:center;justify-content:center;gap:10px}
  .oee-mid .oee-ar{transform:rotate(90deg)}
  .samband-list{grid-template-columns:1fr;gap:12px}
  .samband-list li{font-size:14.5px}
  .fam-tile{padding:18px 17px}
  .tpl-tree li{margin-left:calc(var(--d)*8px)}
  .cx-actions{align-items:flex-start;flex-direction:column;gap:16px}
  .metric-grid{grid-template-columns:1fr}
  .strip,.company-cta{flex-direction:column;align-items:flex-start}
  .footer-top{flex-direction:column;gap:28px}
  .footer-cols{gap:40px}
}

/* ============================ INSIKTER (articles) ============================ */
.insikter-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
.insikter-grid[hidden],.insikter-article[hidden]{display:none}
.insikter-card{display:flex;flex-direction:column;background:#fff;border:1px solid var(--line);border-radius:16px;overflow:hidden;box-shadow:var(--shadow-sm);cursor:pointer;transition:transform .2s ease,box-shadow .2s ease,border-color .2s ease}
.insikter-card:hover{transform:translateY(-4px);box-shadow:var(--shadow);border-color:#cfe0fb}
.insikter-card:focus-visible{outline:2px solid var(--blue);outline-offset:3px}
.insikter-card-media{position:relative;height:184px;background:#0b1c33}
.insikter-card-media img{width:100%;height:100%;object-fit:cover;display:block}
.insikter-card-body{display:flex;flex-direction:column;flex:1;padding:22px}
.insikter-kicker{font-family:var(--mono);font-size:10px;text-transform:uppercase;letter-spacing:.12em;color:var(--blue-ink);font-weight:700}
.insikter-card-body h3{font-size:18px;line-height:1.28;margin:10px 0 9px;font-weight:700;letter-spacing:-.01em}
.insikter-dek{font-size:14px;color:var(--muted);margin:0 0 18px;line-height:1.58;font-weight:300}
.insikter-foot{display:flex;align-items:center;justify-content:space-between;gap:14px;margin-top:auto}
.insikter-meta{font-family:var(--mono);font-size:11px;color:var(--muted-2);font-weight:500;letter-spacing:.02em}
.insikter-card .learn{color:var(--blue-ink);font-weight:600;font-size:13px;display:inline-flex;align-items:center;gap:7px}
.insikter-card:hover .learn .ic{transform:translateX(3px)}

/* Article reading view */
.insikter-article{max-width:720px;margin:0 auto}
.insikter-back{border:0;background:transparent;color:var(--blue-ink);font-family:var(--body);font-weight:600;font-size:14px;cursor:pointer;padding:6px 0;margin-bottom:16px}
.insikter-back:hover{text-decoration:underline}
.insikter-art-head .insikter-kicker{display:block;margin-bottom:14px}
.insikter-art-head h1{font-size:clamp(28px,3.6vw,42px);line-height:1.1;letter-spacing:-.035em;font-weight:800;margin:0 0 14px}
.insikter-art-head .insikter-meta{display:block;margin-bottom:26px}
.insikter-figure{margin:0 0 30px;border-radius:16px;overflow:hidden;border:1px solid var(--line);box-shadow:var(--shadow-sm)}
.insikter-figure img{width:100%;display:block;aspect-ratio:2/1;object-fit:cover}
.insikter-figure figcaption{font-size:12.5px;color:var(--muted-2);padding:12px 16px;background:var(--soft);font-weight:300}
.insikter-body p{font-size:17px;line-height:1.72;color:var(--ink);margin:0 0 16px;font-weight:300}
.insikter-body-h{font-size:20px;font-weight:800;letter-spacing:-.015em;line-height:1.25;color:var(--ink);margin:34px 0 14px}
.insikter-body-h:first-child{margin-top:0}
.insikter-body p + .insikter-body-h{margin-top:36px}
.insikter-body a{color:var(--blue-ink);font-weight:500;text-decoration:underline;text-underline-offset:2px}
.insikter-sources{font-family:var(--mono);font-size:12px;color:var(--muted-2);margin:30px 0 0;padding-top:18px;border-top:1px solid var(--line);font-weight:500}
/* Article signature: handwritten name (Allura, loaded in the @import above)
   over a small muted role line. The colour sits between --ink and --muted on
   purpose: Dennis wanted the signature softer than body text ("less black"). Used from article body entries via innerHTML,
   so the classes must live here, not in the SPA - the SSR article pages link
   this same stylesheet. */
.ins-sign{font-family:"Allura",cursive;font-size:44px;font-weight:400;line-height:1.1;color:#45566e;display:inline-block;margin-top:10px}
.ins-sign-role{font-size:13px;color:var(--muted);letter-spacing:.02em}
/* Signature block with portrait: used from article body entries (SPA innerHTML
   + SSR raw <p>), so it must survive being wrapped in a paragraph. */
.ins-signature{display:flex;align-items:center;gap:16px;margin-top:22px}
.ins-sign-photo{width:64px;height:64px;border-radius:50%;object-fit:cover;flex-shrink:0}
.co-founder{display:flex;align-items:center;gap:14px;margin:18px 0 6px}
.co-founder img{width:72px;height:72px;border-radius:50%;object-fit:cover;flex-shrink:0}
.co-founder .name{font-weight:700}
.co-founder .role{font-size:13px;color:var(--muted)}
.ins-list{margin:0 0 18px;padding-left:22px}
.ins-list li{margin:0 0 6px;line-height:1.6}
.insikter-art-cta{margin-top:34px}

/* News teaser strip (reuses the .strip pattern already used in Solutions/Industries/Resources).
   The other strips carry one line, so their badge is centred against it. This one carries a
   kicker as well, and a badge floating in the middle of a four-line block on a phone reads as
   unaligned, so it rides at the top with the kicker. */
.news-teaser .strip-l{align-items:flex-start}
.news-teaser .insikter-kicker{display:block;margin-bottom:6px}
.news-teaser h3{font-size:16px}

/* Manifest link on the /home hero (light, sits under the hero CTAs) */
.hero-manifest{display:inline-flex;align-items:center;margin-top:22px;color:rgba(255,255,255,.9);font-weight:600;font-size:14px;text-decoration:none;border-bottom:1px solid rgba(255,255,255,.32);padding-bottom:2px;transition:color .15s ease,border-color .15s ease}
.hero-manifest::after{content:'  \2192'}
.hero-manifest:hover{color:#fff;border-color:#fff}
.hero-manifest[hidden]{display:none}

/* Admin-only: draft/published state + one-click publish (super-admin sees these) */
.insikter-badge{position:absolute;right:14px;top:14px;border-radius:999px;font-family:var(--mono);font-size:10px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;padding:5px 10px;box-shadow:0 6px 16px rgba(8,24,53,.14)}
.insikter-manifest-badge{position:absolute;left:14px;top:14px;z-index:2;border-radius:999px;font-family:var(--mono);font-size:10px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;padding:5px 11px;background:var(--navy);color:#fff;box-shadow:0 6px 18px rgba(2,11,26,.32)}
.insikter-badge--draft{background:#fff4d6;color:#8a5a00;border:1px solid #f0d68a}
.insikter-badge--published{background:#e3f6e9;color:#1c7a43;border:1px solid #b7e4c6}
.insikter-admin{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;margin:0 0 22px;padding:12px 16px;border:1px dashed #c9d7ea;border-radius:12px;background:var(--soft)}
.insikter-status{font-family:var(--mono);font-size:12px;font-weight:600}
.insikter-status.draft{color:#8a5a00}
.insikter-status.published{color:#1c7a43}
.insikter-pub{border:0;border-radius:10px;padding:9px 16px;font-family:var(--body);font-weight:600;font-size:13px;cursor:pointer;background:var(--blue);color:#fff;transition:background .16s ease}
.insikter-pub:hover{background:var(--blue-2)}
.insikter-pub--unpub{background:#fff;color:var(--muted);border:1px solid var(--line)}
.insikter-pub--unpub:hover{background:#f0f5fd;color:var(--ink)}
.insikter-pub:disabled{opacity:.5;cursor:default}
.insikter-admin-btns{display:flex;gap:10px;flex-wrap:wrap}

/* Admin: Published / Draft preview tabs */
.insikter-tabs{display:flex;gap:8px;margin:0 0 20px;border-bottom:1px solid var(--line)}
.insikter-tabs[hidden]{display:none}
.insikter-tab{appearance:none;border:0;background:none;cursor:pointer;font:inherit;font-size:14px;font-weight:600;color:var(--muted);padding:10px 4px;margin-bottom:-1px;border-bottom:2px solid transparent}
.insikter-tab:hover{color:var(--ink)}
.insikter-tab.active{color:var(--blue-ink);border-bottom-color:var(--blue)}
.insikter-empty{color:var(--muted);font-size:15px;font-weight:300;padding:28px 4px;margin:0}

/* Admin: new-article toolbar + inline editor */
.insikter-toolbar{display:flex;justify-content:flex-end;margin:0 0 18px}
.insikter-toolbar[hidden]{display:none}
.insikter-editor-title{font-size:22px;font-weight:800;letter-spacing:-.02em;margin:0 0 20px}
.insikter-editor-img{display:flex;gap:20px;align-items:flex-start;flex-wrap:wrap;margin:0 0 24px;padding:16px;border:1px solid var(--line);border-radius:12px;background:var(--soft)}
.insikter-editor-preview{width:280px;max-width:100%;aspect-ratio:2/1;object-fit:cover;border-radius:10px;border:1px solid var(--line);background:#0b1c33}
.insikter-editor-upl{flex:1;min-width:220px;display:flex;flex-direction:column;gap:8px}
.insikter-hint{font-size:12.5px;color:var(--muted-2);margin:0;font-weight:300}
.insikter-editor-cols{display:grid;grid-template-columns:1fr 1fr;gap:28px}
.insikter-editor-col h3{font-size:13px;text-transform:uppercase;letter-spacing:.08em;color:var(--blue-ink);font-family:var(--mono);margin:0 0 14px}
.insikter-field{display:block;margin:0 0 14px}
.insikter-field-label{display:block;font-size:12px;font-weight:600;color:var(--muted);margin:0 0 5px}
.insikter-field input,.insikter-field textarea{width:100%;box-sizing:border-box;border:1px solid var(--line);border-radius:9px;padding:9px 11px;font-family:var(--body);font-size:16px;color:var(--ink);background:#fff;line-height:1.5}
.insikter-field textarea{resize:vertical}
.insikter-field input:focus,.insikter-field textarea:focus{outline:2px solid var(--blue);outline-offset:1px;border-color:var(--blue)}
.insikter-editor-adv{display:grid;grid-template-columns:1fr 1fr;gap:28px;margin-top:6px;padding-top:18px;border-top:1px solid var(--line)}
.insikter-editor-actions{display:flex;align-items:center;gap:12px;margin-top:24px;flex-wrap:wrap}
.insikter-del{color:#b4232a}
.insikter-del:hover{background:#fdecec;color:#8e1b21}
.insikter-editor-actions .insikter-del{margin-left:auto}
@media (max-width:720px){
  .insikter-editor-cols,.insikter-editor-adv{grid-template-columns:1fr}
}

/* AI scout form (modal) */
.insikter-scout-overlay{position:fixed;inset:0;z-index:200;display:grid;place-items:center;padding:22px;background:rgba(3,10,25,.55);backdrop-filter:blur(6px)}
.insikter-scout{position:relative;width:min(520px,100%);max-height:90vh;overflow-y:auto;background:#fff;border-radius:18px;box-shadow:0 40px 120px rgba(3,10,25,.5);padding:28px}
.insikter-scout-loading{position:absolute;inset:0;z-index:2;background:rgba(255,255,255,.95);border-radius:18px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;text-align:center;padding:24px}
.insikter-scout-lmsg{font-weight:600;font-size:15px;margin:0;color:var(--ink)}
.insikter-spinner{width:38px;height:38px;border:3px solid #e0e9f5;border-top-color:var(--blue);border-radius:50%;animation:insikter-spin .8s linear infinite;margin-bottom:6px}
@keyframes insikter-spin{to{transform:rotate(360deg)}}
.insikter-scout-title{font-size:20px;font-weight:800;letter-spacing:-.02em;margin:0 0 18px}
.insikter-scout .insikter-field{margin:0 0 16px}
.insikter-scout-group{margin:0 0 16px}
.insikter-scout-opts{display:flex;flex-wrap:wrap;gap:8px;margin-top:6px}
.insikter-scout-opt{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--line);border-radius:999px;padding:8px 14px;font-size:13px;cursor:pointer;transition:border-color .15s ease,background .15s ease}
.insikter-scout-opt:hover{border-color:#cfe0fb;background:#f4f9ff}
.insikter-scout-opt input{accent-color:var(--blue);margin:0}
.insikter-scout-opt:has(input:checked){border-color:var(--blue);background:#eaf2ff;color:var(--blue-ink);font-weight:600}
.insikter-scout-actions{display:flex;gap:12px;margin-top:22px}

@media (max-width:1000px){
  .insikter-grid{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:640px){
  .insikter-grid{grid-template-columns:1fr}
  .insikter-body p{font-size:16px}
}

/* ==== Relationskartan i stort format ====
   Same open/close contract as .sol-modal (main.js drives both the same way) but
   its own box: the whole point here is to read a 1600x900 screenshot, so it
   takes the width the window can give rather than the reading measure a text
   modal wants. */
.shot-modal-overlay{position:fixed;inset:0;z-index:210;display:grid;place-items:center;padding:18px;
  background:rgba(3,10,25,.72);backdrop-filter:blur(8px);opacity:0;transition:opacity .22s ease}
.shot-modal-overlay.open{opacity:1}
.shot-modal-overlay[hidden]{display:none}
.shot-modal{width:min(1680px,100%);max-height:92vh;display:flex;flex-direction:column;
  background:#fff;border-radius:20px;overflow:hidden;box-shadow:0 40px 120px rgba(3,10,25,.55);
  position:relative;transform:translateY(10px) scale(.985);transition:transform .22s ease}
.shot-modal-overlay.open .shot-modal{transform:none}
.shot-modal-media{margin:0;background:#eef1f5;min-height:0;display:flex;overflow:hidden}
/* contain, not cover: a screenshot that is cropped to fill a box is no longer
   the screenshot. The height cap leaves the footer its own room. */
.shot-modal-media img{display:block;width:100%;height:auto;max-height:calc(92vh - 168px);
  object-fit:contain;transition:opacity .18s ease;cursor:zoom-in}
.shot-modal-media.is-swapping img{opacity:.3}
/* ZOOMED: the capture at about 1.4x the size the app itself renders at, which
   is what makes the node labels readable — they are small in the product too,
   so a 1:1 view would only reproduce the problem. 2200 CSS px comes out of a
   3200px source, so it is still downsampling on a 1x screen rather than
   inventing pixels. The well scrolls and the image is dragged inside it. */
.shot-modal-media.is-zoomed{overflow:auto;cursor:grab;overscroll-behavior:contain}
/* align-self, and it is not optional: the well is a flex row, so the default
   `stretch` sets the image's HEIGHT to the well's and the 2200px width then
   describes a box far wider than the picture object-fit draws inside it. The
   result letterboxes the zoom — a smaller image with empty space beside it,
   which is the opposite of the point. flex-start lets the height follow the
   intrinsic ratio, and object-fit then has nothing left to do. */
.shot-modal-media.is-zoomed img{
  width:2200px;max-width:none;max-height:none;height:auto;
  align-self:flex-start;object-fit:fill;cursor:grab
}
.shot-modal-media.is-zoomed.is-panning,
.shot-modal-media.is-zoomed.is-panning img{cursor:grabbing}
.shot-modal-foot{display:flex;gap:26px;align-items:flex-start;justify-content:space-between;
  flex-wrap:wrap;padding:15px 20px 17px;border-top:1px solid var(--line);background:var(--soft)}
.shot-modal-copy{max-width:600px;min-width:260px;flex:1 1 320px}
.shot-modal-copy h3{margin:0 0 5px;font-size:15px;font-weight:700;letter-spacing:-.02em;color:var(--ink)}
.shot-modal-copy p{margin:0;font-size:13px;line-height:1.6;color:var(--muted);font-weight:300}
.shot-switch{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.shot-opt{display:inline-flex;align-items:center;gap:6px;padding:8px 13px;border-radius:999px;
  border:1px solid var(--line);background:#fff;color:var(--muted);cursor:pointer;
  font:inherit;font-size:12.5px;font-weight:600;line-height:1;white-space:nowrap;
  transition:border-color .16s ease,color .16s ease,background .16s ease}
.shot-opt .ic{font-size:13px}
.shot-opt:hover{color:var(--ink);border-color:var(--ink)}
.shot-opt.on{border-color:var(--blue);color:var(--blue);background:rgba(26,116,255,.08)}
.shot-opt:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
@media (max-width:860px){
  .shot-modal-overlay{padding:12px}
  .shot-modal-media img{max-height:calc(92vh - 230px)}
  .shot-modal-foot{gap:14px;padding:13px 15px 15px}
  .shot-opt{padding:7px 11px;font-size:12px}
}
@media (prefers-reduced-motion: reduce){
  .shot-modal-overlay,.shot-modal,.shot-modal-media img{transition:none}
}

/* ==== Boka en genomgång, modal form ====
   Rides on .sol-modal-overlay / .sol-modal for the shell, so there is one modal
   shape on the page and one transition. Only the form itself is new. */
.demo-modal{width:min(620px,100%)}
.demo-modal .sol-modal-body{padding:34px 34px 30px}
.demo-form{display:grid;gap:14px;margin-top:6px}
/* display:grid beats the user agent's [hidden]{display:none}, so the success
   state would render UNDER a form that was supposed to be gone. */
.demo-form[hidden],.demo-row[hidden],.demo-done[hidden]{display:none}
.demo-row{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.demo-field{display:grid;gap:6px;font-size:13px;font-weight:600;color:var(--ink)}
.demo-field input,
.demo-field textarea{
  width:100%;font:inherit;font-weight:400;font-size:15px;color:var(--ink);
  padding:11px 13px;border:1px solid var(--line);border-radius:10px;background:#fff;
  transition:border-color .16s ease,box-shadow .16s ease
}
.demo-field textarea{resize:vertical;min-height:84px}
.demo-field input:focus,
.demo-field textarea:focus{outline:0;border-color:var(--blue);box-shadow:0 0 0 3px rgba(26,116,255,.14)}
.demo-hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.demo-note{margin:2px 0 0;font-size:12.5px;line-height:1.5;color:var(--muted-2)}
.demo-actions{display:flex;align-items:center;gap:16px;flex-wrap:wrap;margin-top:4px}
.demo-alt{font-size:13px;color:var(--muted)}
.demo-alt a{color:var(--blue);font-weight:600}
.demo-error{margin:0;font-size:13.5px;color:#b3261e}
.demo-done h3{margin:0 0 10px}
.demo-done p{margin:0;color:var(--muted);font-size:15px;line-height:1.6;font-weight:300}
@media (max-width:640px){
  .demo-row{grid-template-columns:1fr}
  .demo-modal .sol-modal-body{padding:28px 22px 26px}
}

/* ==== Skyline watermark ====
   Ported from .portal-watermark in styles/shared/portal.css. Same artwork, same
   mask trick, same timing; the colour comes from this page's own accent instead
   of the app's --primary token, so the variants reskin it by overriding --wm-c.
   One width variable drives the artwork and both effect layers, because the
   moment that width lived in three places in the app it drifted. */
.home-watermark{
  --wm-w:min(460px,78%);
  --wm-c:var(--blue);
  /* The hot core of the travelling edge light. On the LIGHT pane it is the
     accent at full strength: a white core on white glass is nothing at all,
     which is why the arc read as too faint there. The dark appearances swap it
     for white in styles-variants.css, where white is the brightest thing
     available and reads as the light itself. */
  --wm-edge-core:var(--wm-c);
  /* Thickness and bloom are per-appearance, because the same arc is not the
     same arc on the two grounds. On the dark pane a bright line on near-black
     carries on its own (Dennis, on a phone: "perfect"), so that one stays close
     to what shipped. On the light pane it is a blue line on white glass with a
     white sheen over it, and it needs real weight to register at all. */
  --wm-edge-w:3px;
  --wm-edge-bloom:10px;
  --wm-edge-bloom-a:75%;
  /* Pointer parallax (main.js wmTilt). -1..1 each, both 0 at rest, so every
     rule below is written as "at rest this is the number it always was".
     The sheen's origin is a variable for the same reason: the dark variant
     redefines that gradient, and it has to be able to follow too. */
  --tilt-x:0;--tilt-y:0;
  --sheen-x:10%;--sheen-y:-12%;
  /* Glass, the way Copilot and Apple do it: a pane that is mostly what is
     behind it, lifted by one bright edge along the top, a soft diagonal sheen
     and a barely-there grain so the surface is not a flat wash. The blur needs
     something to work on, which is what .home-watermark-glow paints. */
  /* 86px of air above, and the footer's own 96px margin below, in every
     appearance. Nothing here may zero that footer margin. */
  position:relative;width:min(760px,calc(100% - 48px));margin:86px auto 0;
  padding:38px 32px 30px;border-radius:30px;
  display:flex;justify-content:center;pointer-events:none;user-select:none;
  background:
    linear-gradient(150deg,rgba(255,255,255,.72),rgba(255,255,255,.34) 46%,rgba(255,255,255,.5)),
    rgba(255,255,255,.18);
  backdrop-filter:blur(22px) saturate(170%);
  -webkit-backdrop-filter:blur(22px) saturate(170%);
  border:1px solid rgba(255,255,255,.6);
  box-shadow:
    0 26px 60px rgba(10,25,55,.12),
    0 2px 10px rgba(10,25,55,.05),
    inset 0 1px 0 rgba(255,255,255,.9),
    inset 0 -1px 0 rgba(255,255,255,.35);
  overflow:hidden;isolation:isolate;
  /* The tilt. Small on purpose: this is a pane catching the light as you pass
     it, not a card flipping. The slow curve is the RETURN; while the pointer is
     actually on it the class below shortens the transition so the pane tracks
     the hand instead of lagging a third of a second behind it. */
  transform:perspective(950px)
            rotateX(calc(var(--tilt-y) * -6deg))
            rotateY(calc(var(--tilt-x) * 4.6deg));
  transform-style:preserve-3d;
  transition:transform .55s cubic-bezier(.22,1,.36,1)
}
.home-watermark.is-tilting{transition:transform .1s linear}
/* Parallax: the artwork rides WITH the pointer and the colour wash behind it
   moves against, which is what reads as depth rather than as a moving picture.
   The pane itself is the middle plane and does not translate at all. */
/* The artwork does NOT move on its own (Dennis, 2026-09-15: "the logo inside
   the glass container is moving more than the container"). It used to carry its
   own translate on top of the pane's rotation, so it out-ran the thing it is
   printed on and read as a separate sheet sliding about inside the glass. The
   pane is the only thing that moves now; the rotation carries the logo with it,
   which is what "the container moves and the logo follows" means.

   Only the colour wash still drifts, and against the tilt — it is light behind
   the glass rather than an object on it, so it is allowed its own parallax. */
.home-watermark .home-watermark-glow{
  transform:translate3d(calc(var(--tilt-x) * -11px),calc(var(--tilt-y) * -8px),0);
  transition:transform .55s cubic-bezier(.22,1,.36,1)
}
.home-watermark.is-tilting .home-watermark-glow{transition:transform .1s linear}
/* The grain. A 140-byte fractal-noise SVG rather than a raster, so it costs
   nothing and never blurs on a retina screen. */
.home-watermark:before{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
  opacity:.05;mix-blend-mode:overlay
}
/* The sheen: one wide, very soft highlight raking from the upper left.
   Radial, and filling the pane exactly. It used to be a linear gradient in an
   oversized box (inset -40% / height 120%), which ended in a hard cut at 80% of
   the pane height: on the darker palettes that cut was plainly visible as a
   horizontal break across the lower left. A radial highlight fades in every
   direction, so there is no edge to see. */
.home-watermark:after{
  content:"";position:absolute;inset:0;border-radius:inherit;
  background:radial-gradient(125% 95% at calc(var(--sheen-x) + var(--tilt-x) * 16%) calc(var(--sheen-y) + var(--tilt-y) * 11%),rgba(255,255,255,.5),rgba(255,255,255,.1) 40%,transparent 72%);
  pointer-events:none
}
.home-watermark > *{position:relative;z-index:1}
/* The soft colour the glass has to blur. Sits behind the pane, never inside it. */
/* iOS, 2026-09-14: this layer used to be BIGGER than the pane (inset -30% / -40%)
   so its own hard edges fell outside the rounded corners. On WebKit that does not
   work: a blurred layer is composited, and a composited child is not clipped by
   the parent's border-radius, so the glow painted as a square block past the
   corners, top-left and bottom-right, where the wash behind it is brightest.
   It now sits exactly inside the pane and carries the same radius, so there is
   nothing to leak whether the clip holds or not. The softness comes from the
   gradient stops and the blur, not from being oversized. */
.home-watermark-glow{
  position:absolute;inset:0;z-index:0;pointer-events:none;border-radius:inherit;
  background:
    radial-gradient(70% 120% at 18% 18%,color-mix(in srgb,var(--blue) 24%,transparent),transparent 72%),
    radial-gradient(60% 110% at 84% 76%,color-mix(in srgb,var(--blue) 15%,transparent),transparent 74%);
  filter:blur(18px)
}
/* The edge light. One bright arc travelling the pane's border on the SAME 9s
   clock and the same easing as .wm-band sweeping the skyline, so the two read
   as one gesture rather than two loops drifting past each other: the arc runs
   its lap while the band crosses the logo (0 to 50% of the cycle), then both
   rest for the second half.

   A conic gradient cannot be moved by transform, so the ANGLE is what animates.
   @property is what lets a custom property interpolate instead of flipping at
   the halfway mark; where it is unsupported the angle simply holds still and
   the arc becomes a quiet fixed highlight on the edge, which is a weaker
   version of the effect rather than a broken one.

   The ring itself is the padding box XORed out of the border box — the standard
   way to paint a gradient border without a second element sitting behind it. */
@property --wm-angle{syntax:'<angle>';initial-value:0deg;inherits:false}
.home-watermark .home-watermark-edge{
  position:absolute;inset:0;z-index:2;pointer-events:none;border-radius:inherit;
  padding:var(--wm-edge-w);
  /* A LONG wedge, ~110deg of the lap rather than ~60 (Dennis, 2026-09-15: too
     small, and too faint on Ljust). On a pane this wide the top and bottom
     edges each take a big share of the angle, so a short wedge was a dash that
     had gone before it registered. */
  background:conic-gradient(from var(--wm-angle),
    transparent 0deg,transparent 250deg,
    color-mix(in srgb,var(--wm-c) 22%,transparent) 288deg,
    color-mix(in srgb,var(--wm-c) 70%,transparent) 330deg,
    var(--wm-edge-core) 351deg,
    color-mix(in srgb,var(--wm-c) 25%,transparent) 360deg);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
          mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;
  /* The bloom is what makes it read as a light rather than a painted stripe,
     and it is what was missing on the light pane in particular. */
  filter:drop-shadow(0 0 var(--wm-edge-bloom) color-mix(in srgb,var(--wm-c) var(--wm-edge-bloom-a),transparent));
  animation:wm-edge-run 9s cubic-bezier(.45,0,.55,1) infinite
}
@keyframes wm-edge-run{
  0%{--wm-angle:0deg}
  50%{--wm-angle:360deg}
  100%{--wm-angle:360deg}
}

/* The stage is the only sized box. Everything inside fills it, so the artwork
   and the two effect layers cannot drift apart at any width. */
.wm-stage{position:relative;width:var(--wm-w);aspect-ratio:3870.2364/1445.3023}
.home-watermark img{position:absolute;inset:0;width:100%;height:100%;opacity:.3;display:none}
.home-watermark .wm-light{display:block}
.wm-fx,.wm-wifi{position:absolute;inset:0;width:100%;height:100%;z-index:2;pointer-events:none}
.wm-fx{
  overflow:hidden;
  -webkit-mask-image:url("/assets/images/Industri_logg_svart_1024.svg");
          mask-image:url("/assets/images/Industri_logg_svart_1024.svg");
  -webkit-mask-size:100% 100%;mask-size:100% 100%;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat
}
.wm-band{
  position:absolute;top:-10%;bottom:-10%;width:26%;
  background:linear-gradient(90deg,transparent 0%,var(--wm-c) 50%,transparent 100%);
  opacity:.85;filter:blur(.5px);
  animation:wm-band-sweep 9s cubic-bezier(.45,0,.55,1) infinite
}
@keyframes wm-band-sweep{
  0%{transform:translateX(-130%)}
  50%{transform:translateX(400%)}
  100%{transform:translateX(400%)}
}
.wm-wifi{overflow:visible}
.wm-wifi .wm-arc{stroke:var(--wm-c);fill:none;stroke-width:60;opacity:0;animation:wm-wifi-pulse 9s ease-out infinite}
.wm-wifi .wm-arc-0{fill:var(--wm-c);stroke:none;animation-delay:4.45s}
.wm-wifi .wm-arc-1{animation-delay:4.65s}
.wm-wifi .wm-arc-2{animation-delay:4.9s}
@keyframes wm-wifi-pulse{
  0%{opacity:0}
  4%{opacity:1}
  22%{opacity:0}
  100%{opacity:0}
}
/* Motion is decoration here: with it off the watermark is the static logo. */
@media (prefers-reduced-motion: reduce){
  .wm-fx,.wm-wifi,.home-watermark .home-watermark-edge{display:none}
}

/* ==== AI band: typed text, then the client marks ====
   The band reads like something being answered rather than something printed,
   so the copy types itself in on first view. The text stays in the HTML and is
   only re-typed by script, which keeps it readable for anyone (and anything)
   that does not run JS. */
.ai-band .ai-type--mono{
  font-family:var(--mono),Consolas,ui-monospace,monospace;
  font-size:14.5px;line-height:1.72;letter-spacing:-.01em
}
.ai-band .section-lead.ai-type--mono{font-size:15px;line-height:1.75}
.ai-band .ai-type.is-typing:after{
  content:"";display:inline-block;width:.58em;height:1.05em;margin-left:2px;
  vertical-align:-.16em;background:var(--blue);animation:ai-caret 1s steps(1) infinite
}
@keyframes ai-caret{0%,55%{opacity:1}56%,100%{opacity:0}}
/* Reserve the height the finished paragraph will need, so typing does not push
   the page around under the reader. Only the heading is typed now, so this only
   ever applies to it. */
.ai-band .ai-type.is-pending{visibility:hidden}

/* THE WAVE (2026-09-15, Dennis: the band needs "more of a wave of the whole
   content texts and icons"). Everything under the heading arrives together
   rather than typing block after block: full text from the first frame, faded
   and lifted into place, each one AI_FLOW_STEP behind its neighbour so the band
   lands as a single movement. main.js sets --flow-i per block.

   The end state is set outright rather than left to the animation's fill, for
   the same reason the client marks below do it: an animation that never runs
   (a tab that was never painted, an embedded preview) must not leave the copy
   at opacity 0 forever. */
.ai-band .ai-type.is-flow{opacity:0;transform:translateY(12px)}
.ai-band .ai-type.is-flow.is-in{
  opacity:1;transform:none;
  animation:ai-flow-in .58s cubic-bezier(.22,1.1,.36,1) both;
  animation-delay:calc(var(--flow-i,0) * 70ms)
}
@keyframes ai-flow-in{
  0%{opacity:0;transform:translateY(12px)}
  100%{opacity:1;transform:none}
}

.ai-logos{
  display:flex;justify-content:center;flex-wrap:wrap;gap:14px;margin-top:38px
}
/* Marks only, no names (Dennis, 2026-09-14): three logos everyone recognises say
   it faster than three logos with their own names printed next to them. The name
   stays in the title attribute for anyone who does not recognise one. */
.ai-logo{
  display:inline-grid;place-items:center;width:64px;height:64px;border-radius:20px;
  border:1px solid var(--line);background:var(--card);box-shadow:var(--shadow-sm)
}
/* Visible by default and hidden only once the script has committed to bringing
   them back (.is-armed). If the typing never starts, for any reason, the marks
   are simply there rather than three invisible chips. */
.ai-logos.is-armed .ai-logo{opacity:0;transform:translateY(10px) scale(.96)}
/* The end state is set outright, not left to the animation's fill: an animation
   that never runs (a tab that was never painted, an embedded preview) would
   otherwise leave the marks at opacity 0 forever. The animation only decorates
   the way they arrive. */
.ai-logos.is-armed.is-in .ai-logo{
  opacity:1;transform:none;
  animation:ai-logo-in .62s cubic-bezier(.22,1.1,.36,1) both
}
/* The marks are the TAIL of the text wave, not a separate event afterwards:
   main.js sets --flow-base to where the last paragraph starts, and the three
   keep their own 130ms stagger on top of it. The shorthand above resets
   animation-delay, so these have to come after it. */
.ai-logos.is-armed.is-in .ai-logo{animation-delay:var(--flow-base,0ms)}
.ai-logos.is-armed.is-in .ai-logo:nth-child(2){animation-delay:calc(var(--flow-base,0ms) + .13s)}
.ai-logos.is-armed.is-in .ai-logo:nth-child(3){animation-delay:calc(var(--flow-base,0ms) + .26s)}
@keyframes ai-logo-in{
  0%{opacity:0;transform:translateY(10px) scale(.96)}
  60%{opacity:1;transform:translateY(-2px) scale(1.02)}
  100%{opacity:1;transform:none}
}
.ai-logo-mark{width:34px;height:34px;flex:none;border-radius:9px;display:grid;place-items:center;overflow:hidden}
.ai-logo-mark img{width:100%;height:100%;object-fit:contain;display:block}
.ai-logo-mark--plate{background:#fff}
.ai-logo-mark--plate img{width:76%;height:76%}
@media (max-width:640px){
  .home-watermark{--wm-w:86%;margin-top:64px;padding:26px 18px 22px;border-radius:24px}
}
@media (max-width:720px){
  .ai-logos{gap:12px;margin-top:30px}
  .ai-logo{width:56px;height:56px;border-radius:17px}
  .ai-logo-mark{width:28px;height:28px}
}
/* Motion is decoration: with it off the band is simply the finished text and
   the three marks, in place from the first paint. */
@media (prefers-reduced-motion: reduce){
  .ai-band .ai-type.is-pending{visibility:visible}
  .ai-band .ai-type.is-flow{opacity:1;transform:none}
  .ai-logos.is-armed .ai-logo{opacity:1;transform:none}
}

/* The appearance picker's glyphs come from Font Awesome solid, the same set the
   app's theme picker uses, and are filled rather than stroked like every other
   icon on this page. */
.ic--solid{fill:currentColor;stroke:none}

/* ==== Frågor och svar (Om Bimdoc) ====
   Native <details>, so it opens with no JavaScript and with a keyboard, and the
   answers sit in the HTML where a crawler and an AI client can read them without
   opening anything. */
.faq{padding:18px 0 4px}
.faq .head{max-width:800px;margin:0 0 30px}
.faq-group + .faq-group{margin-top:30px}
.faq-group-h{
  font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  font-weight:700;color:var(--muted-2);margin:0 0 12px
}
.faq-item{
  border:1px solid var(--line);border-radius:14px;background:var(--card);
  margin-bottom:10px;overflow:hidden
}
.faq-item + .faq-item{margin-top:0}
.faq-item summary{
  list-style:none;cursor:pointer;padding:16px 46px 16px 20px;position:relative;
  font-size:15.5px;font-weight:600;color:var(--ink);line-height:1.45
}
.faq-item summary::-webkit-details-marker{display:none}
.faq-item summary:after{
  content:"";position:absolute;right:20px;top:50%;width:9px;height:9px;
  border-right:2px solid var(--muted);border-bottom:2px solid var(--muted);
  transform:translateY(-70%) rotate(45deg);transition:transform .2s ease
}
.faq-item[open] summary:after{transform:translateY(-30%) rotate(225deg)}
.faq-item summary:hover{color:var(--blue-ink)}
.faq-item summary:focus-visible{outline:2px solid var(--blue);outline-offset:-2px}
.faq-a{padding:0 20px 18px;max-width:78ch}
.faq-a p{margin:0;font-size:15px;line-height:1.68;color:var(--muted);font-weight:300}
.faq-a a{color:var(--blue-ink);font-weight:600;text-decoration:underline}
.faq-strip{margin-top:34px}
@media (max-width:640px){
  .faq-item summary{font-size:14.5px;padding:14px 40px 14px 16px}
  .faq-a{padding:0 16px 16px}
}
.faq-lead{margin:0 0 8px !important}
.faq-list{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.faq-list li{
  position:relative;padding-left:16px;font-size:15px;line-height:1.6;
  color:var(--muted);font-weight:300
}
.faq-list li:before{
  content:"";position:absolute;left:0;top:9px;width:6px;height:6px;
  border-radius:999px;background:var(--blue)
}
