/* Schibsted Grotesk (variable 400-900, OFL), self-hosted so no visitor data goes to Google. */
@font-face {
  font-family: 'Schibsted Grotesk';
  font-style: normal;
  font-display: swap;
  font-weight: 400 900;
  src: url('../fonts/schibsted-grotesk-latin-ext-wght-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
    U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Schibsted Grotesk';
  font-style: normal;
  font-display: swap;
  font-weight: 400 900;
  src: url('../fonts/schibsted-grotesk-latin-wght-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
    U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Limfjord palette: misty blue-grey ground, deep fjord ink, buoy-yellow signal. */
:root {
  --fjord: #13303f;
  --fjord-soft: #3b5a69;
  --dis: #dce5e6;
  --kalk: #f5f7f6;
  --line: #b4c4c7;
  --boje: #f2c230;

  --font: 'Schibsted Grotesk', system-ui, sans-serif;
  --gutter: clamp(1.25rem, 5vw, 3rem);
  --split: minmax(0, 1.35fr) minmax(0, 1fr);
  --split-gap: 4rem;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-elastic: cubic-bezier(0.34, 1.56, 0.64, 1);
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--dis);
  color: var(--fjord);
  font-family: var(--font);
  font-size: 1.0625rem;
  line-height: 1.65;
}

img {
  display: block;
  max-width: 100%;
}

a {
  color: inherit;
}

:focus-visible {
  outline: 3px solid var(--boje);
  outline-offset: 3px;
  border-radius: 6px;
}

h1,
h2,
h3,
p {
  margin: 0;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.skip {
  position: absolute;
  left: 1rem;
  top: -4rem;
  z-index: 10;
  padding: 0.6rem 1rem;
  background: var(--fjord);
  color: var(--kalk);
  border-radius: 999px;
  text-decoration: none;
}

.skip:focus {
  top: 1rem;
}

/* Soft light that follows the pointer (set by site.js on fine pointers only). */
.spotlight {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(640px circle at var(--x, 30%) var(--y, 20%), rgb(255 255 255 / 0.55), transparent 70%);
}

/* Layout: intro across the top, then skills (left) and projects (right) side by side. */
.wrap {
  width: min(78rem, 100% - 2 * var(--gutter));
  margin-inline: auto;
}

.page {
  position: relative;
  z-index: 1;
  padding-bottom: clamp(5rem, 12vh, 8rem);
}

/* The intro splits evenly so the AI panel is wider than the projects column below; both share the
   same gap and right edge. */
.intro {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 2.5rem var(--split-gap);
  align-items: start;
  padding-block: clamp(3.5rem, 9vh, 6rem) clamp(2.5rem, 6vh, 4rem);
}

/* Microsoft Foundry's model leaderboard, top right. */
.llm {
  position: relative;
  container-type: inline-size;
  padding: 1.25rem 1.35rem 1rem;
  border-radius: 22px;
  background: var(--fjord);
  color: var(--kalk);
}

.llm-title {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: -0.005em;
}

.live-dot {
  flex: none;
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  background: var(--boje);
  animation: pulse 2.2s ease-out infinite;
}

@keyframes pulse {
  0% {
    box-shadow: 0 0 0 0 rgb(242 194 48 / 0.55);
  }
  70%,
  100% {
    box-shadow: 0 0 0 0.6rem rgb(242 194 48 / 0);
  }
}

/* Explanation bubble, placed under the hovered or focused category by site.js. */
.tooltip {
  position: absolute;
  z-index: 6;
  width: 18rem;
  padding: 0.75rem 0.9rem;
  border-radius: 12px;
  background: var(--kalk);
  color: var(--fjord);
  box-shadow: 0 12px 30px rgb(19 48 63 / 0.25);
  font-size: 0.85rem;
  line-height: 1.45;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity 0.2s, transform 0.25s var(--ease-out), visibility 0.2s;
  pointer-events: none;
}

.tooltip::before {
  content: '';
  position: absolute;
  top: -5px;
  left: var(--arrow-x, 1.5rem);
  width: 10px;
  height: 10px;
  margin-left: -5px;
  background: inherit;
  transform: rotate(45deg);
}

.tooltip strong {
  display: block;
  margin-top: 0.45rem;
  font-weight: 700;
}

.tooltip.is-visible {
  opacity: 1;
  visibility: visible;
  transform: none;
}

/* Leaderboard table. Narrow panels put each model's numbers on a second line under its name;
   from 26rem wide every model fits on one row with the numbers in columns. */
.lb {
  margin-top: 0.75rem;
}

.lb-head,
.lb-row {
  display: grid;
  grid-template-columns: 1.1rem repeat(4, minmax(0, 1fr));
  column-gap: 0.5rem;
  align-items: baseline;
}

.lb-head {
  padding-bottom: 0.45rem;
  border-bottom: 1px solid rgb(245 247 246 / 0.14);
}

.lb-head .lb-model {
  display: none;
  font-size: 0.72rem;
  font-weight: 650;
  color: rgb(245 247 246 / 0.55);
}

/* Column headers sort the table; the active one is white with a white underline. Headers and values
   are centred in their columns. */
.lb-num {
  text-align: center;
}

.lb-sort {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.15rem 0;
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  color: rgb(245 247 246 / 0.55);
  font: inherit;
  font-size: 0.72rem;
  font-weight: 650;
  cursor: pointer;
  transition: color 0.25s, border-color 0.25s;
}

.lb-sort:hover {
  color: var(--kalk);
}

.lb-head [aria-sort='ascending'] .lb-sort,
.lb-head [aria-sort='descending'] .lb-sort {
  color: #fff;
  border-bottom-color: #fff;
}

/* Info icon that says the header has an explanation; it fills in while the header is hovered.
   Narrow panels leave it out to keep the labels on one line. */
.lb-info {
  display: none;
  flex: none;
  width: 0.7rem;
  height: 0.7rem;
}

.lb-info circle {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  transition: fill 0.2s;
}

.lb-info path {
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  transition: stroke 0.2s;
}

.lb-sort:hover .lb-info circle,
.lb-sort:focus-visible .lb-info circle {
  fill: currentColor;
}

.lb-sort:hover .lb-info path,
.lb-sort:focus-visible .lb-info path {
  stroke: var(--fjord);
}

/* Three models in view; the rest scroll inside the panel. site.js sizes the window so the fourth row
   peeks out under a fade, and drops the fade once the list is scrolled to the end. The native
   scrollbar is hidden so the numbers stay lined up under their headers; .lb-scrollbar replaces it. */
.lb-body {
  max-height: 9rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: none;
  mask-image: linear-gradient(to bottom, #000 calc(100% - 2.5rem), transparent);
}

.lb-body::-webkit-scrollbar {
  display: none;
}

.lb-body.at-end {
  mask-image: none;
}

/* Our scrollbar in the card's right padding: a faint track with a light thumb that can be dragged. */
.lb-scrollbar {
  position: absolute;
  right: 0.3rem;
  width: 12px;
  cursor: pointer;
}

.lb-scrollbar[hidden] {
  display: none;
}

.lb-scrollbar::before {
  content: '';
  position: absolute;
  inset: 0 4px;
  border-radius: 2px;
  background: rgb(245 247 246 / 0.12);
}

.lb-thumb {
  position: absolute;
  top: 0;
  left: 3px;
  right: 3px;
  border-radius: 3px;
  background: rgb(245 247 246 / 0.6);
  transition: background-color 0.2s, left 0.2s, right 0.2s;
}

.lb-scrollbar:hover .lb-thumb,
.lb-thumb.is-dragging {
  left: 2px;
  right: 2px;
  background: #fff;
}

.lb-row {
  row-gap: 0.15rem;
  padding-block: 0.45rem;
  border-bottom: 1px solid rgb(245 247 246 / 0.08);
  animation: row-in 0.6s var(--ease-out) both;
  animation-delay: calc(0.75s + var(--i, 0) * 60ms);
}

.lb-row:last-child {
  border-bottom: 0;
}

/* After the first render a new sort order slides in right away instead of waiting for the page load. */
.is-live .lb-row {
  animation-delay: calc(var(--i, 0) * 45ms);
}

@keyframes row-in {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.lb-row .lb-model {
  grid-column: 2 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 0.5rem;
  min-width: 0;
}

.lb-model + .lb-num {
  grid-column-start: 2;
}

.lb-rank {
  font-weight: 700;
  color: rgb(245 247 246 / 0.55);
}

.lb-row:first-child .lb-rank {
  color: var(--boje);
}

.lb-name {
  font-size: 0.92rem;
  font-weight: 650;
  overflow-wrap: anywhere;
}

.lb-org {
  font-size: 0.75rem;
  color: rgb(245 247 246 / 0.55);
}

.lb-row .lb-num {
  font-size: 0.85rem;
  color: rgb(245 247 246 / 0.72);
}

.lb-row .lb-num.is-sorted {
  color: #fff;
  font-weight: 700;
}

@container (min-width: 26rem) {
  .lb-head,
  .lb-row {
    grid-template-columns: 1.1rem minmax(0, 1fr) repeat(4, 4.4rem);
  }

  .lb-head .lb-model {
    display: block;
  }

  .lb-row .lb-model {
    grid-column: auto;
  }

  .lb-model + .lb-num {
    grid-column-start: auto;
  }

  .lb-info {
    display: block;
  }
}

/* Placeholder rows until the first numbers arrive. */
.is-skeleton .lb-name,
.is-skeleton .lb-org,
.is-skeleton .lb-num > span {
  display: inline-block;
  height: 0.8em;
  border-radius: 4px;
  background: rgb(245 247 246 / 0.14);
  animation: shimmer 1.4s ease-in-out infinite;
}

.is-skeleton .lb-name {
  width: 7.5rem;
}

.is-skeleton .lb-org {
  width: 4rem;
}

.is-skeleton .lb-num > span {
  width: 2.2rem;
}

@keyframes shimmer {
  50% {
    opacity: 0.45;
  }
}

.llm-foot {
  margin-top: 0.85rem;
  font-size: 0.78rem;
  color: rgb(245 247 246 / 0.6);
}

.llm-foot a {
  color: var(--kalk);
  text-decoration-color: var(--boje);
  text-underline-offset: 3px;
}

.columns {
  display: grid;
  grid-template-columns: var(--split);
  gap: var(--split-gap);
  align-items: start;
  padding-top: clamp(2rem, 5vh, 3rem);
  border-top: 1px solid var(--line);
  outline: none;
}

.column-title {
  margin-bottom: 1.75rem;
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.02em;
}

/* Projects stay in view while the longer skills column scrolls past.
   The column stretches to the row height so the sticky wrapper has room to travel. */
.column-projects {
  align-self: stretch;
}

.column-sticky {
  position: sticky;
  top: 2rem;
}

/* Name: the one big typographic moment, revealed line by line on load. */
.name {
  font-size: clamp(3rem, 6.2vw, 5.5rem);
  font-weight: 700;
  line-height: 0.98;
  letter-spacing: -0.045em;
}

.name .line {
  display: block;
  overflow: hidden;
  padding-bottom: 0.08em;
}

.name .line > span {
  display: block;
  transform: translateY(105%);
  animation: rise 1.1s var(--ease-out) forwards;
}

.name .line + .line > span {
  animation-delay: 0.12s;
}

/* What Kompas AI is, right under the name. */
.role {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-top: 1rem;
  font-size: clamp(1.15rem, 1.8vw, 1.45rem);
  font-weight: 650;
  letter-spacing: -0.015em;
}

.role::before {
  content: '';
  flex: none;
  width: 1.6rem;
  height: 3px;
  border-radius: 3px;
  background: var(--boje);
}

.tagline {
  margin-top: 1.25rem;
  max-width: 28rem;
  font-size: 1.25rem;
  line-height: 1.5;
  color: var(--fjord-soft);
}

.reveal,
.reveal-late {
  opacity: 0;
  animation: fade 0.9s var(--ease-out) 0.55s forwards;
}

.reveal-late {
  animation-delay: 0.8s;
}

.reveal-late + .reveal-late {
  animation-delay: 0.95s;
}

@keyframes rise {
  to {
    transform: none;
  }
}

@keyframes fade {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.skills {
  position: relative;
  display: grid;
}

.skill-group {
  display: grid;
  grid-template-columns: 10rem 1fr;
  gap: 1rem 1.5rem;
  align-items: baseline;
  padding-block: 1.5rem;
  border-top: 1px solid var(--line);
}

.skill-group:first-child {
  border-top: 0;
  padding-top: 0;
}

.skill-group h3 {
  font-size: 1rem;
  font-weight: 650;
  line-height: 1.4;
}

.skill-body {
  display: grid;
  gap: 0.9rem;
}

.skill-body p {
  font-size: 0.975rem;
  color: var(--fjord-soft);
}

.tags {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.tags li {
  padding: 0.3rem 0.8rem;
  border-radius: 999px;
  background: var(--fjord);
  color: var(--kalk);
  font-size: 0.9rem;
  font-weight: 500;
}

/* Tags with a plain-language explanation (data-help) show it in a bubble on hover, focus or tap. */
.tags li[data-help] {
  cursor: help;
  transition: background-color 0.2s, transform 0.25s var(--ease-out);
}

.tags li[data-help]:hover,
.tags li[data-help]:focus-visible {
  background: var(--fjord-soft);
  transform: translateY(-1px);
}

.skill-tooltip {
  width: min(18rem, 100% - 1rem);
}

/* A skill's bubble holds a button, so it can be hovered and clicked while it shows. */
.skill-tooltip.is-visible {
  pointer-events: auto;
}

/* An invisible bridge over the 10px gap above the bubble (wider than the gap between rows of skills),
   so the pointer reaches the button without passing over the next skill and moving the bubble there. */
.skill-tooltip::after {
  content: '';
  position: absolute;
  right: 0;
  bottom: 100%;
  left: 0;
  height: 12px;
}

/* "Spørg chatbotten" in a skill's bubble opens the chat with a question about the skill. */
.tooltip-ask {
  display: flex;
  align-items: center;
  width: fit-content;
  min-height: 2rem;
  margin-top: 0.6rem;
  padding: 0.3rem 0.85rem;
  border: 2px solid var(--boje);
  border-radius: 999px;
  background: var(--fjord);
  color: var(--kalk);
  font: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.2s, color 0.2s;
}

.tooltip-ask:hover {
  background: #1d4458;
  color: var(--boje);
}

/* Project cards: dark fjord, the same ink as the pill fill. The hovered card lifts, the others step back. */
.projects {
  display: grid;
  gap: 1.25rem;
}

.card {
  --on-card: var(--kalk);
  --on-card-soft: rgb(245 247 246 / 0.72);
  --card-line: rgb(245 247 246 / 0.16);

  display: grid;
  gap: 1.5rem;
  padding: 1.5rem;
  border-radius: 22px;
  background: var(--fjord);
  color: var(--on-card);
  transition: background-color 0.4s, opacity 0.4s;
}

.card:hover {
  background: #1a3e50;
}

@media (hover: hover) {
  .projects:hover .card:not(:hover) {
    opacity: 0.55;
  }
}

.card-head {
  display: grid;
  grid-template-columns: 56px 1fr;
  gap: 1rem;
  align-items: start;
}

.card-head img {
  border-radius: 14px;
}

.card-head h3 {
  font-size: 1.25rem;
  font-weight: 650;
  letter-spacing: -0.01em;
  line-height: 1.2;
}

.card-head p {
  margin-top: 0.3rem;
  font-size: 1rem;
  color: var(--on-card-soft);
}

.stats {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid var(--card-line);
  padding-top: 1.25rem;
}

.stats div {
  display: flex;
  flex-direction: column-reverse;
}

.stats div + div {
  border-left: 1px solid var(--card-line);
  padding-left: 1rem;
}

.stats dd {
  margin: 0;
  font-size: 1.6rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.stats dt {
  font-size: 0.9rem;
  color: var(--on-card-soft);
}

.links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

/* Magnetic pill on the dark card: a light fill rises from below on hover,
   and the pill and its text follow the pointer. */
.pill {
  position: relative;
  display: inline-flex;
  overflow: hidden;
  padding: 0.6rem 1.2rem;
  border-radius: 999px;
  border: 1px solid rgb(245 247 246 / 0.5);
  color: var(--kalk);
  font-size: 0.95rem;
  font-weight: 600;
  text-decoration: none;
  isolation: isolate;
  transition: color 0.45s var(--ease-out), border-color 0.45s, transform 0.7s var(--ease-elastic);
}

.pill::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 100%;
  z-index: -1;
  width: 150%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--kalk);
  transform: translate(-50%, 0);
  transition: transform 0.55s var(--ease-out);
}

.pill:hover {
  color: var(--fjord);
  border-color: var(--kalk);
}

.pill:hover::before {
  transform: translate(-50%, -70%);
}

.pill-text {
  display: block;
  transition: transform 0.7s var(--ease-elastic);
}

/* While the pointer pulls, follow it quickly; on release the elastic ease springs back. */
.pill.is-pulling {
  transition-duration: 0.45s, 0.45s, 0.15s;
}

.pill.is-pulling .pill-text {
  transition-duration: 0.15s;
}


/* Chat with the AI assistant: a launcher in the bottom right opens a panel whose fjord-blue header
   meets the conversation in a drifting wave. On a phone the panel fills the screen. */
.chat {
  --chat-edge: clamp(1rem, 3vw, 2rem);
  --chat-launcher: 3.5rem;
  --chat-gap: 0.85rem;
  position: fixed;
  right: var(--chat-edge);
  bottom: var(--chat-edge);
  z-index: 50;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--chat-gap);
}

.chat-launcher[hidden],
.chat-panel[hidden] {
  display: none;
}

/* The launcher stays below the open panel, shrunk to its speech-bubble symbol, and closes the chat. */
.chat-launcher {
  display: inline-flex;
  align-items: center;
  height: var(--chat-launcher);
  padding: calc(0.4rem - 2px);
  border: 2px solid var(--boje);
  border-radius: 999px;
  background: var(--fjord);
  color: var(--kalk);
  font: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  box-shadow: 0 14px 34px rgb(19 48 63 / 0.32);
  cursor: pointer;
  transition: transform 0.45s var(--ease-elastic), background-color 0.3s, box-shadow 0.3s;
}

.chat-launcher:hover {
  background: #1a3e50;
  box-shadow: 0 18px 40px rgb(19 48 63 / 0.38);
  transform: translateY(-2px);
}

.chat-launcher:focus-visible {
  outline: 3px solid var(--boje);
  outline-offset: 3px;
}

.chat-launcher-icon {
  display: grid;
  flex: none;
  place-items: center;
  width: calc(var(--chat-launcher) - 0.8rem);
  height: calc(var(--chat-launcher) - 0.8rem);
  border-radius: 50%;
  background: var(--boje);
  color: var(--fjord);
  animation: pulse 2.2s ease-out 1.2s 3;
  transition: transform 0.45s var(--ease-elastic);
}

.chat-launcher:hover .chat-launcher-icon {
  transform: rotate(-8deg) scale(1.06);
}

.chat-launcher-icon svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linejoin: round;
}

.chat-launcher-label {
  overflow: hidden;
  max-width: 14rem;
  padding: 0 0.95rem 0 0.75rem;
  white-space: nowrap;
  transition: max-width 0.45s var(--ease-out), padding 0.45s var(--ease-out), opacity 0.25s;
}

.chat.is-open .chat-launcher-label {
  max-width: 0;
  padding: 0;
  opacity: 0;
}

.chat.is-open .chat-launcher-icon {
  animation: none;
}

/* On arrival the launcher springs up from below and sends two yellow rings out. */
.chat-launcher {
  position: relative;
  animation: chat-launcher-in 0.9s var(--ease-elastic) 0.5s backwards;
}

.chat-launcher::after {
  position: absolute;
  inset: -2px;
  border: 2px solid var(--boje);
  border-radius: inherit;
  opacity: 0;
  content: '';
  pointer-events: none;
  animation: chat-ping 1.6s ease-out 1.3s 2;
}

@keyframes chat-launcher-in {
  from {
    opacity: 0;
    transform: translateY(140%) scale(0.6);
  }
}

@keyframes chat-ping {
  0% {
    opacity: 0.8;
    transform: scale(1);
  }

  100% {
    opacity: 0;
    transform: scale(1.18, 1.7);
  }
}

/* Greeting bubble above the launcher on the first visit: "Kontakt mig her" is typed out. */
.chat-teaser {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.1rem;
  max-width: calc(100vw - 2 * var(--chat-edge));
  margin-right: 0.35rem;
  padding: 0.2rem 0.3rem 0.2rem 0.2rem;
  border: 2px solid var(--boje);
  border-radius: 18px 18px 6px 18px;
  background: var(--fjord);
  color: var(--kalk);
  box-shadow: 0 16px 36px rgb(19 48 63 / 0.35);
  transform-origin: 85% 130%;
  animation: chat-teaser-in 0.7s var(--ease-elastic) both;
}

.chat-teaser[hidden] {
  display: none;
}

.chat-teaser.is-leaving {
  animation: chat-teaser-out 0.3s ease-in forwards;
}

/* The tail points down at the launcher. */
.chat-teaser::after {
  position: absolute;
  right: 1.6rem;
  bottom: -0.55rem;
  width: 0.9rem;
  height: 0.9rem;
  border-right: 2px solid var(--boje);
  border-bottom: 2px solid var(--boje);
  background: var(--fjord);
  content: '';
  transform: rotate(45deg);
}

.chat-teaser-text {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.45rem 0.55rem 0.45rem 0.7rem;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  font-size: 1rem;
  font-weight: 700;
  cursor: pointer;
}

.chat-teaser-text:hover .chat-teaser-type {
  color: var(--boje);
}

.chat-teaser-text:focus-visible,
.chat-teaser-close:focus-visible {
  outline: 2px solid var(--boje);
  outline-offset: 2px;
  border-radius: 12px;
}

/* The site's "M" mark, as in the chat header and the favicon. */
.chat-teaser-mark {
  display: grid;
  flex: none;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 25%;
  background: var(--fjord);
  box-shadow: 0 0 0 1px rgb(242 194 48 / 0.55);
  color: var(--boje);
  animation: chat-mark-in 0.8s var(--ease-elastic) 0.25s both;
}

.chat-teaser-mark svg {
  width: 100%;
  height: 100%;
  fill: currentColor;
}

.chat-teaser-words {
  display: grid;
  text-align: left;
}

.chat-teaser-words > * {
  grid-area: 1 / 1;
  white-space: nowrap;
}

.chat-teaser-ghost {
  visibility: hidden;
}

.chat-teaser-type::after {
  display: inline-block;
  width: 2px;
  height: 1.05em;
  margin-left: 2px;
  background: var(--boje);
  content: '';
  vertical-align: -0.15em;
  animation: chat-caret 0.9s steps(1) infinite;
}

.chat-teaser-close {
  position: relative;
  z-index: 1;
  display: inline-grid;
  flex: none;
  place-items: center;
  width: 1.6rem;
  height: 1.6rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgb(245 247 246 / 0.1);
  color: var(--kalk);
  cursor: pointer;
  transition: background-color 0.2s, color 0.2s;
}

.chat-teaser-close:hover {
  background: var(--kalk);
  color: var(--fjord);
}

.chat-teaser-close svg {
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}

@keyframes chat-teaser-in {
  from {
    opacity: 0;
    transform: translateY(14px) scale(0.6) rotate(-4deg);
  }
}

@keyframes chat-teaser-out {
  to {
    opacity: 0;
    transform: translateY(10px) scale(0.85);
  }
}

@keyframes chat-mark-in {
  from {
    opacity: 0;
    transform: scale(0.3) rotate(-12deg);
  }
}

@keyframes chat-caret {
  50% {
    opacity: 0;
  }
}

/* The panel opens from the launcher, on a faint dot grid. */
.chat-panel {
  display: flex;
  flex-direction: column;
  width: min(38rem, calc(100vw - 2 * var(--chat-edge)));
  /* As tall as the screen allows, leaving a small gap at the top. */
  height: min(64rem, calc(100dvh - var(--chat-edge) - var(--chat-launcher) - var(--chat-gap) - 1rem));
  overflow: hidden;
  border-radius: 26px;
  background:
    radial-gradient(circle at 1px 1px, rgb(19 48 63 / 0.08) 1px, transparent 0) 0 0 / 22px 22px,
    var(--kalk);
  box-shadow:
    0 0 0 1px rgb(19 48 63 / 0.06),
    0 30px 70px rgb(19 48 63 / 0.35);
  transform-origin: calc(100% - var(--chat-launcher) / 2) calc(100% + var(--chat-gap) + var(--chat-launcher) / 2);
  animation: chat-in 0.5s var(--ease-out);
}

.chat-panel.is-closing {
  animation: chat-out 0.22s ease-in forwards;
}

@keyframes chat-in {
  from {
    opacity: 0;
    transform: translateY(18px) scale(0.9);
  }
}

@keyframes chat-out {
  to {
    opacity: 0;
    transform: translateY(12px) scale(0.94);
  }
}

/* Header: deep fjord with buoy-yellow light in the corner. */
.chat-head {
  position: relative;
  display: flex;
  flex: none;
  align-items: center;
  gap: 0.8rem;
  padding: 1rem 1rem 1.9rem 1.15rem;
  overflow: hidden;
  background:
    radial-gradient(120% 160% at 100% 0%, rgb(242 194 48 / 0.2), transparent 50%),
    linear-gradient(155deg, var(--fjord) 30%, #1f4a5e);
  color: var(--kalk);
}

.chat-avatar {
  display: grid;
  flex: none;
  place-items: center;
  width: 2.6rem;
  height: 2.6rem;
  border-radius: 25%;
  background: var(--fjord);
  box-shadow:
    0 0 0 1px rgb(242 194 48 / 0.55),
    0 6px 16px rgb(0 0 0 / 0.25);
  color: var(--boje);
}

/* The site's "M" mark, in the same proportions as the favicon. */
.chat-avatar svg {
  width: 100%;
  height: 100%;
  fill: currentColor;
}

@keyframes twinkle {
  50% {
    transform: scale(0.86) rotate(14deg);
  }
}

.chat-id {
  flex: 1;
  min-width: 0;
}

.chat-head h2 {
  overflow: hidden;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.25;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chat-sub {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  margin-top: 0.2rem;
  color: rgb(245 247 246 / 0.72);
  font-size: 0.8rem;
  line-height: 1.3;
}

.chat-sub .live-dot {
  width: 0.45rem;
  height: 0.45rem;
}

.chat-icon-button {
  display: inline-grid;
  flex: none;
  place-items: center;
  width: 2.3rem;
  height: 2.3rem;
  padding: 0;
  border: 1px solid rgb(245 247 246 / 0.28);
  border-radius: 50%;
  background: rgb(245 247 246 / 0.06);
  color: var(--kalk);
  cursor: pointer;
  transition: background-color 0.25s, color 0.25s, border-color 0.25s, transform 0.45s var(--ease-elastic);
}

.chat-icon-button:hover {
  border-color: var(--kalk);
  background: var(--kalk);
  color: var(--fjord);
  transform: translateY(-1px);
}

.chat-icon-button:focus-visible {
  outline: 2px solid var(--boje);
  outline-offset: 2px;
}

.chat-icon-button svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.chat-icon-button.is-spinning svg {
  animation: chat-spin 0.6s var(--ease-out);
}

@keyframes chat-spin {
  to {
    transform: rotate(360deg);
  }
}

/* Three layers of waves drift at their own speed and direction along the header's lower edge and swell
   slowly up and down, like the fjord's surface; a faint golden line on the middle one catches the light.
   The front layer only swells downwards, so it always covers the edge of the conversation. */
.chat-waves {
  position: absolute;
  right: 0;
  bottom: -1px;
  left: 0;
  height: 1.6rem;
  overflow: hidden;
  pointer-events: none;
}

.chat-swell {
  position: absolute;
  inset: 0;
  animation: chat-swell 6s ease-in-out infinite alternate;
  will-change: transform;
}

.chat-wave {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 200%;
  height: 100%;
  animation: chat-drift 18s linear infinite;
  will-change: transform;
}

.chat-swell-back {
  animation-duration: 7.5s;
}

.chat-swell-back .chat-wave {
  fill: rgb(245 247 246 / 0.16);
  animation-duration: 26s;
  animation-direction: reverse;
}

.chat-swell-mid {
  top: 0.15rem;
  animation-duration: 5.5s;
  animation-delay: -2s;
}

.chat-swell-mid .chat-wave {
  fill: rgb(245 247 246 / 0.32);
  animation-duration: 19s;
  animation-delay: -6s;
}

.chat-wave-glint {
  fill: none;
  stroke: rgb(242 194 48 / 0.35);
  stroke-width: 1.2;
  vector-effect: non-scaling-stroke;
}

.chat-swell-front {
  top: 0.35rem;
  animation-name: chat-swell-down;
  animation-duration: 6.5s;
  animation-delay: -3.5s;
}

.chat-swell-front .chat-wave {
  fill: var(--kalk);
  animation-duration: 14s;
  animation-direction: reverse;
  animation-delay: -4s;
}

@keyframes chat-drift {
  to {
    transform: translateX(-50%);
  }
}

@keyframes chat-swell {
  from {
    transform: translateY(2px);
  }

  to {
    transform: translateY(-2px);
  }
}

@keyframes chat-swell-down {
  to {
    transform: translateY(3px);
  }
}

.chat-body {
  position: relative;
  flex: 1;
  min-height: 0;
  font-size: 0.9rem;
}

.chat-webchat,
.chat-webchat > div {
  height: 100%;
}

/* Loading and error states. */
.chat-status {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  height: 100%;
  padding: 1.5rem;
  color: var(--fjord-soft);
  text-align: center;
}

.chat-dots {
  display: inline-flex;
  gap: 0.4rem;
}

.chat-dots span {
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  background: var(--fjord-soft);
  animation: chat-bounce 1.2s ease-in-out infinite;
}

.chat-dots span:nth-child(2) {
  animation-delay: 0.15s;
}

.chat-dots span:nth-child(3) {
  animation-delay: 0.3s;
}

@keyframes chat-bounce {
  0%,
  60%,
  100% {
    opacity: 0.4;
    transform: translateY(0);
  }

  30% {
    opacity: 1;
    transform: translateY(-6px);
  }
}

.chat-retry {
  padding: 0.6rem 1.2rem;
  border: 0;
  border-radius: 999px;
  background: var(--fjord);
  color: var(--kalk);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.chat-retry:hover {
  background: #1a3e50;
}

/* Web Chat inside the panel. Its own CSS-in-JS rules are specific, so these go through .chat-webchat. */
.chat-body .chat-webchat .webchat__basic-transcript__scrollable {
  scrollbar-color: var(--line) transparent;
  scrollbar-width: thin;
}

.chat-body .chat-webchat .webchat__bubble__content {
  border-radius: 18px;
  box-shadow:
    0 1px 2px rgb(19 48 63 / 0.06),
    0 8px 24px rgb(19 48 63 / 0.07);
  line-height: 1.5;
}

.chat-body .chat-webchat .webchat__bubble:not(.webchat__bubble--from-user) .webchat__bubble__content {
  border-top-left-radius: 6px;
}

.chat-body .chat-webchat .webchat__bubble.webchat__bubble--from-user .webchat__bubble__content {
  border-top-right-radius: 6px;
  background: linear-gradient(155deg, var(--fjord), #1f4a5e);
  box-shadow: 0 8px 20px rgb(19 48 63 / 0.2);
}

.chat-body .chat-webchat .webchat__render-markdown p {
  margin: 0 0 0.45em;
}

.chat-body .chat-webchat .webchat__render-markdown > :last-child {
  margin-bottom: 0;
}

/* Answers follow one form (see the agent's instructions): a short opening sentence, then up to three
   bullet points that each start with a bold topic. */
.chat-body .chat-webchat .webchat__render-markdown ul,
.chat-body .chat-webchat .webchat__render-markdown ol {
  margin: 0.45em 0 0.55em;
  padding-left: 1.15em;
}

.chat-body .chat-webchat .webchat__render-markdown li {
  line-height: 1.5;
}

.chat-body .chat-webchat .webchat__render-markdown li + li {
  margin-top: 0.3em;
}

.chat-body .chat-webchat .webchat__render-markdown li::marker {
  color: var(--boje);
}

.chat-body .chat-webchat .webchat__render-markdown li > p {
  margin: 0;
}

.chat-body .chat-webchat .webchat__render-markdown a {
  color: inherit;
  text-decoration-color: var(--boje);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}

.chat-body .chat-webchat .webchat__render-markdown img {
  display: inline-block;
}

.chat-body .chat-webchat .webchat__render-markdown__external-link-icon {
  margin-left: 0.2em;
  vertical-align: -0.1em;
  opacity: 0.6;
}

/* Follow-up suggestions: one compact row under the answer that slides sideways (Web Chat's carousel),
   so the answer itself keeps the room. */
/* The row is centred while it fits; when it is wider than the panel (and the arrow shows) the auto
   margins drop to 0, so it starts flush with the left edge of the send box below. */
.chat-body .chat-webchat .webchat__suggested-actions__carousel {
  padding: 0.15rem 0.25rem 0;
}

.chat-body .chat-webchat .webchat__suggested-actions__carousel .react-film__filmstrip__list {
  width: max-content;
  margin-inline: auto;
}

.chat-body .chat-webchat .webchat__suggested-actions__carousel .react-film__filmstrip__item {
  padding: 0.25rem 0.15rem;
}

.chat-body .chat-webchat .webchat__suggested-actions__item-box {
  padding: 0;
}

.chat-body .chat-webchat .webchat__suggested-actions__button {
  min-height: 1.9rem;
  padding: 0.2rem 0.65rem;
  box-shadow: 0 2px 8px rgb(19 48 63 / 0.06);
  font-size: 0.8rem;
  font-weight: 600;
  white-space: nowrap;
  transition: background-color 0.2s, color 0.2s, border-color 0.2s, transform 0.35s var(--ease-elastic);
}

.chat-body .chat-webchat .webchat__suggested-actions__carousel .react-film__flipper__body {
  display: grid;
  place-items: center;
  width: 1.9rem;
  height: 1.9rem;
  border: 2px solid var(--boje);
  border-radius: 50%;
  background: var(--fjord);
  color: var(--kalk);
  box-shadow: 0 4px 12px rgb(19 48 63 / 0.25);
  transition: opacity 0.2s;
}

/* Only show an arrow when there is something to slide to in that direction. */
.chat-body .chat-webchat .webchat__suggested-actions__carousel .react-film__main__slider--hide .react-film__flipper__body {
  opacity: 0;
  pointer-events: none;
}

.chat-body .chat-webchat .webchat__suggested-actions__button:hover {
  transform: translateY(-1px);
}

/* chat.js always puts the contact button first; it stands out in fjord ink with a buoy-yellow ring. */
.chat-body .chat-webchat .react-film__filmstrip__item:first-child .webchat__suggested-actions__button {
  border-color: var(--boje);
  background: var(--fjord);
  color: var(--kalk);
  box-shadow: 0 0 0 2px rgb(242 194 48 / 0.35), 0 4px 12px rgb(19 48 63 / 0.2);
}

.chat-body .chat-webchat .react-film__filmstrip__item:first-child .webchat__suggested-actions__button:hover {
  background: #1d4458;
  color: var(--boje);
}

.chat-body .chat-webchat .webchat__send-box__main {
  align-items: center;
  margin: 0.6rem 0.9rem 0.9rem;
  padding: 0.3rem 0.3rem 0.3rem 0.4rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 6px 20px rgb(19 48 63 / 0.08);
  transition: border-color 0.2s, box-shadow 0.2s;
}

.chat-body .chat-webchat .webchat__send-box__main:focus-within {
  border-color: var(--fjord);
  box-shadow:
    0 0 0 4px rgb(242 194 48 / 0.35),
    0 6px 20px rgb(19 48 63 / 0.08);
}

.chat-body .chat-webchat .webchat__send-box .webchat__send-box__button {
  flex: none;
  align-self: center;
  width: 2.6rem;
  height: 2.6rem;
  border-radius: 50%;
  background: var(--fjord);
  transition: background-color 0.2s, transform 0.35s var(--ease-elastic);
}

.chat-body .chat-webchat .webchat__send-box .webchat__send-box__button:hover {
  background: #1f4a5e;
  transform: scale(1.06);
}

.chat-body .chat-webchat .webchat__send-box .webchat__send-icon {
  width: 1.15rem;
  height: 1.15rem;
}

/* The contact form (the adaptive card chat.js shows for the contact button). Its fields and button
   shrink with the screen's height, so the whole form fits in the panel on most screens. */
.chat-body .chat-webchat .ac-adaptiveCard .ac-input {
  padding: clamp(0.4rem, 1.1dvh, 0.65rem) 0.85rem;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--kalk);
  color: var(--fjord);
  font: inherit;
  font-size: 0.95rem;
  transition: border-color 0.2s, box-shadow 0.2s, background-color 0.2s;
}

.chat-body .chat-webchat .ac-adaptiveCard .ac-input:focus {
  border-color: var(--fjord);
  background: #fff;
  box-shadow: 0 0 0 4px rgb(242 194 48 / 0.35);
  outline: none;
}

.chat-body .chat-webchat .ac-adaptiveCard .ac-multiline {
  min-height: clamp(3.25rem, 11dvh, 6.5rem);
  resize: vertical;
}

.chat-body .chat-webchat .ac-adaptiveCard .ac-pushButton,
.chat-body .chat-webchat .ac-adaptiveCard .ac-pushButton-disabled {
  min-height: clamp(2.4rem, 5.5dvh, 2.9rem);
  padding: clamp(0.45rem, 1.2dvh, 0.7rem) 1.4rem;
  border: 0;
  border-radius: 999px;
  background: var(--fjord);
  color: var(--kalk);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.2s, transform 0.35s var(--ease-elastic);
}

.chat-body .chat-webchat .ac-adaptiveCard .ac-pushButton:hover {
  background: #1f4a5e;
  transform: translateY(-1px);
}

/* A sent form's button ("Sendt"); adaptive cards give disabled buttons their own class. */
.chat-body .chat-webchat .ac-adaptiveCard .ac-pushButton-disabled {
  background: var(--line);
  color: var(--fjord);
  transform: none;
  cursor: default;
}

/* Phones: the panel fills the screen and slides up; the launcher waits behind it. */
@media (max-width: 37.5rem) {
  .chat.is-open .chat-launcher {
    display: none;
  }

  .chat-panel {
    position: fixed;
    top: var(--chat-top, 0);
    left: 0;
    width: 100%;
    height: var(--chat-vh, 100dvh);
    border-radius: 0;
    box-shadow: none;
    animation: chat-up 0.4s var(--ease-out);
  }

  .chat-panel.is-closing {
    animation: chat-down 0.25s ease-in forwards;
  }

  .chat-head {
    padding-top: calc(1rem + env(safe-area-inset-top, 0px));
  }

  .chat-body .chat-webchat .webchat__send-box__main {
    margin-bottom: calc(0.9rem + env(safe-area-inset-bottom, 0px));
  }
}

@keyframes chat-up {
  from {
    transform: translateY(100%);
  }
}

@keyframes chat-down {
  to {
    transform: translateY(100%);
  }
}

html.chat-locked,
html.chat-locked body {
  overflow: hidden;
}

/* Medium screens: skill names move above their descriptions to give the columns room. */
@media (max-width: 80rem) {
  .skill-group {
    grid-template-columns: 1fr;
    gap: 0.6rem;
  }
}

/* Small screens: everything stacks. */
@media (max-width: 56rem) {
  .intro,
  .columns {
    grid-template-columns: 1fr;
  }

  .columns {
    gap: 3.5rem;
  }

  .column-sticky {
    position: static;
  }

  .spotlight {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .name .line > span,
  .reveal,
  .reveal-late,
  .lb-row {
    animation: none;
    transform: none;
    opacity: 1;
  }

  .live-dot,
  .is-skeleton .lb-name,
  .is-skeleton .lb-org,
  .is-skeleton .lb-num > span {
    animation: none;
  }

  .pill,
  .pill-text,
  .pill::before,
  .card,
  .chat-launcher,
  .chat-launcher-icon,
  .chat-launcher-label,
  .chat-icon-button {
    transition: none;
  }

  .chat-launcher,
  .chat-launcher::after,
  .chat-teaser,
  .chat-teaser.is-leaving,
  .chat-teaser-mark,
  .chat-teaser-type::after,
  .chat-launcher-icon,
  .chat-avatar svg,
  .chat-wave,
  .chat-swell,
  .chat-dots span,
  .chat-panel,
  .chat-panel.is-closing,
  .chat-icon-button.is-spinning svg {
    animation: none;
  }
}
