/* kodecrew.com. The component layer sites/kodeleads built on the Solaris
   template, with kodecrew's palette in the alias block below and the theme's
   light effects (rays, shine border, beam) recoloured from Solaris blue
   #0065FC to kodecrew red #E85A4F. Component rules are otherwise the
   template's. kodecrew-only additions are at the very end of the file. */

:root {
  /* The shadcn tokens live in theme.css. Only the site's own names are defined
     here, and --text-muted is deliberately NOT called --muted: that name is
     Tailwind's muted BACKGROUND. */
  --brand:        var(--primary);                  /* #E85A4F */
  --brand-hover:  oklch(0.593 0.180 28.23);        /* #D4463B */
  --brand-deep:   oklch(0.531 0.164 28.42);        /* #B83A30 */
  --brand-soft:   oklch(0.651 0.178 27.51 / 12%);
  --ink:          var(--foreground);
  --text-muted:   var(--muted-foreground);
  --muted-light:  oklch(0.659 0.035 93.65);        /* #99927A */
  --border-strong:oklch(0.191 0 0 / 20%);
  --surface:      var(--card);                     /* #F7F4E9 */
  --white:        var(--card);
  --on-invert:    oklch(0.966 0.015 94.20);
  --teal:         oklch(0.514 0.031 93.31);
  --teal-soft:    oklch(0.877 0.030 80.65);
  --cyan:         oklch(0.659 0.035 93.65);
  --danger:       var(--destructive);

  --container: 1200px;
  --radius-s:  calc(var(--radius) * 0.8);
  --radius-m:  var(--radius);
  --radius-l:  calc(var(--radius) * 1.8);
  --radius-xl: calc(var(--radius) * 2.2);
  --pill:      999px;

  --chevron-down: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23141414' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9l6 6l6-6'/%3E%3C/svg%3E");
  --chevron-up:   url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23141414' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 15l6-6l6 6'/%3E%3C/svg%3E");

  --shadow-s: 0 1px 2px oklch(0.191 0.02 90 / .06);
  --shadow-m: 0 1px 3px oklch(0.191 0.02 90 / .08), 0 1px 2px oklch(0.191 0.02 90 / .05);
  --shadow-l: 0 10px 30px oklch(0.191 0.02 90 / .10);
}

/* ── Reset ─────────────────────────────────────────────────────────────── */
/* Layered, because an unlayered rule beats every layered one no matter the
   specificity: `a { color: inherit }` sitting outside a layer silently ate
   Tailwind's own .text-primary on the language picker. Anything element-level
   belongs in base so the utilities layer can still override it. */
@layer base {
*, *::before, *::after { box-sizing: border-box; }
/* Author-level display rules (.post-card is display:flex) beat the browser's
   [hidden] { display: none }, so JS toggling .hidden would do nothing without this. */
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; color-scheme: light; }
body {
  margin: 0;
  font-size: 16px;
  line-height: 1.6;
  color: var(--foreground);
  /* the page ground, not --white: that now names the lifted card surface */
  background: var(--background);
  -webkit-font-smoothing: antialiased;
}
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, h4 { margin: 0; font-weight: 500; letter-spacing: -0.03em; line-height: 1.1; }
p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }
}

/* ── Layout ────────────────────────────────────────────────────────────── */
.container { width: 100%; max-width: var(--container); margin: 0 auto; padding: 0 24px; }
.section { padding: 96px 0; }
.section--tight { padding: 64px 0; }
.section--surface { background: var(--surface); }
/* Section header, the theme's treatment: ranged left against the grid rather
   than centred in it, the copy held to a readable measure, and the blue label
   carrying the accent the theme puts inside its headings. Centres on narrow
   screens, where a left rag with nothing beside it just looks unfinished. */
.section-head { max-width: 680px; margin: 0 0 40px; text-align: left; }
.eyebrow {
  font-size: 14px; font-weight: 600; color: var(--brand);
  letter-spacing: 0; margin-bottom: 14px;
}
h2.section-title { font-size: 48px; margin-bottom: 16px; letter-spacing: -0.035em; }
.section-sub { font-size: 16px; color: var(--text-muted); text-wrap: balance; }
@media (max-width: 760px) {
  .section-head { margin-inline: auto; text-align: center; }
}
.lead { font-size: 18px; color: var(--text-muted); }

/* ── Buttons ───────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 13px 24px; border-radius: var(--radius-m);
  font-size: 15px; font-weight: 600; letter-spacing: -0.01em;
  border: 1px solid transparent; cursor: pointer;
  transition: background .15s, border-color .15s, color .15s, transform .1s;
  white-space: nowrap;
}
.btn:active { transform: translateY(1px); }
.btn--dark   { background: var(--primary); color: var(--primary-foreground); }
.btn--dark:hover { background: #24242e; }
.btn--brand  { background: var(--brand); color: var(--on-invert); }
.btn--brand:hover { background: var(--brand-hover); }
.btn--light  { background: var(--white); color: var(--ink); border-color: var(--border-strong); }
.btn--light:hover { border-color: var(--muted-light); }
.btn--sm { padding: 9px 18px; font-size: 14px; }
.btn--block { width: 100%; }

/* ── Navigation ────────────────────────────────────────────────────────── */
/* The theme floats the menu as a centred pill rather than pinning a full width
   bar to the top edge. Fixed, so it leaves the flow; .hero compensates. */
.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 999;
  padding: 16px 16px 0; background: transparent; border: 0; height: auto;
}
.nav-inner {
  max-width: 1024px; margin: 0 auto;
  background: oklch(0.205 0 0 / .55);
  backdrop-filter: saturate(180%) blur(12px);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 6px 6px 6px 12px;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.nav-inner { height: 80px; display: flex; align-items: center; gap: 32px; }
.nav-logo { display: flex; align-items: center; gap: 10px; }
.nav-logo img { height: 26px; width: auto; }
/* Badge lockup: the mark on a disc, set ahead of the wordmark. The icon is 18px
   inside a 32px disc so its ink reads at half the diameter once the artwork's
   own 2-unit margin is accounted for. --invert is for the dark footer. */
/* The mark carries the brand blue itself, so it sits on the page rather than
   on a coloured disc; a blue mark on a blue badge disappears. */
.logo-mark { width: 28px; height: 28px; flex: none; }
.logo-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; flex: none;
  border-radius: 999px; background: var(--primary);
}
.logo-badge--invert { background: var(--primary); }
.nav-logo .logo-badge img, .footer-brand .logo-badge img { height: 18px; width: 18px; margin: 0; }
.nav-logo, .footer-logo { display: flex; align-items: center; gap: 10px; }
.nav-actions { display: flex; align-items: center; gap: 10px; }

/* Language picker: a <details> so it opens without JavaScript. site.js only adds
   the click-outside-to-close behaviour. */
.footer-note { font-size: 12px; color: var(--text-muted); margin-top: 12px; max-width: 24ch; }

/* ── Hero ──────────────────────────────────────────────────────────────── */
/* The hero art is one delivered image (glow, grid, product shot) with an alpha
   channel, compositing over the white page. It is designed at 1440x900 and is
   drawn at exactly that size, centred, never scaled to the viewport: wider
   screens get white margins around it, narrower screens crop the sides. */
.hero {
  position: relative; overflow: hidden;
  padding: 168px 0 80px; text-align: center;
}
/* The glow, not a baked-in 1440x900 image: the product shot below is a real
   <img>, so it scales and stays legible instead of being cropped by viewport. */
/* Light rays from the top, the theme's raysOrigin="top-center" in #E85A4F.
   A conic gradient fanned from the top edge gives the beams, blur softens them
   into light, and the mask lets them fall away down the section. */
.hero::before {
  content: ''; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: radial-gradient(70% 55% at 50% -5%, rgba(232,90,79,.22) 0%, transparent 70%);
}
.hero::after {
  content: ''; position: absolute; z-index: 0; pointer-events: none;
  top: -140px; left: 50%; transform: translateX(-50%);
  width: 150vw; height: 900px;
  background: conic-gradient(from 168deg at 50% 0%,
    transparent 0deg,
    rgba(232,90,79,.00) 6deg,  rgba(232,90,79,.20) 9deg,  rgba(232,90,79,.00) 12deg,
    rgba(232,90,79,.00) 15deg, rgba(232,90,79,.13) 17deg, rgba(232,90,79,.00) 20deg,
    rgba(232,90,79,.00) 21deg, rgba(232,90,79,.26) 24deg, rgba(232,90,79,.00) 27deg,
    rgba(232,90,79,.00) 30deg, rgba(232,90,79,.16) 32deg, rgba(232,90,79,.00) 35deg,
    transparent 44deg);
  filter: blur(34px);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, rgba(0,0,0,.55) 45%, transparent 85%);
  mask-image: linear-gradient(to bottom, #000 0%, rgba(0,0,0,.55) 45%, transparent 85%);
  animation: rays 12s ease-in-out infinite alternate;
}
@keyframes rays {
  from { opacity: .75; transform: translateX(-50%) rotate(-1.2deg); }
  to   { opacity: 1;   transform: translateX(-50%) rotate(1.2deg); }
}
@media (prefers-reduced-motion: reduce) { .hero::after { animation: none; } }
.hero .container { position: relative; z-index: 2; }
/* The theme's browser frame: a translucent chrome bar with three dots, the
   screenshot inset inside it, and an animated gradient border drawn with the
   mask-composite trick from its ShineBorder component. */
.frame {
  position: relative; z-index: 2; width: min(1100px, 100%); margin: 64px auto 0;
  background: oklch(0.205 0 0 / .50);
  backdrop-filter: blur(12px);
  border: 1px solid oklch(1 0 0 / .20);
  border-radius: 14px; padding: 6px;
}
.frame-bar { display: flex; align-items: center; justify-content: space-between; padding: 2px 10px 8px; }
.frame-dots { display: inline-flex; align-items: center; gap: 5px; opacity: .70; }
.frame-dots i { width: 8px; height: 8px; border-radius: 999px; background: #fff; display: block; }
.frame-tools { display: inline-flex; align-items: center; gap: 10px; opacity: .80; }
.frame-tools svg { width: 14px; height: 14px; }
.frame-shot {
  /* height:auto is load-bearing: the global img rule sets only max-width, so
     without it the height attribute is used verbatim against the box width. */
  display: block; width: 100%; height: auto;
  border-radius: 10px; border: 1px solid var(--border);
}
.shine {
  position: absolute; inset: 0; width: 100%; height: 100%;
  border-radius: inherit; pointer-events: none; padding: 2px;
  background-image: radial-gradient(circle at 50% 50%,
    transparent 0%, transparent 18%, #E85A4F 38%, #F4A199 50%, #E85A4F 62%, transparent 82%, transparent 100%);
  background-size: 300% 300%;
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  mask-composite: exclude;
  animation: shine 8s infinite linear;
  will-change: background-position;
}
@keyframes shine {
  0%   { background-position: 0% 0%; }
  50%  { background-position: 100% 100%; }
  100% { background-position: 0% 0%; }
}
@media (prefers-reduced-motion: reduce) { .shine { animation: none; } }
.hero h1 { font-size: 68px; letter-spacing: -0.045em; margin-bottom: 20px; }
.hero .lead { max-width: 560px; margin: 0 auto 32px; }
.hero-actions { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
.hero-note { margin-top: 16px; font-size: 14px; color: var(--text-muted); }

/* Sub-page hero (shorter, no product shot) */
.pagehero { padding: 128px 0 24px; text-align: center; position: relative; overflow: hidden; }
/* A section that directly follows a page hero is introduced by it, so it
   does not need its own full top padding on top of the hero's bottom. */
.pagehero + .section, .pagehero + .section--tight { padding-top: 16px; }
.pagehero::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: radial-gradient(55% 60% at 50% 0%, oklch(0.651 0.178 27.51 / .14) 0%, transparent 70%);
}
.pagehero h1 { font-size: 56px; margin-bottom: 16px; }
.pagehero .lead { max-width: 620px; margin: 0 auto; }

/* ── Image placeholders (swap for real graphics) ───────────────────────── */
.ph {
  position: relative; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 6px; text-align: center;
  background: var(--surface);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-l);
  color: var(--text-muted); padding: 24px;
}
/* The placeholder label is a note to whoever supplies the artwork, so it follows
   the page language rather than staying Danish on the translated pages. */
:root { --ph-label: 'GRAFIK MANGLER'; --ph-photo: 'FOTO'; }
html[lang="en"] { --ph-label: 'GRAPHIC MISSING'; --ph-photo: 'PHOTO'; }
html[lang="sv"] { --ph-label: 'GRAFIK SAKNAS'; --ph-photo: 'FOTO'; }
html[lang="no"] { --ph-label: 'GRAFIKK MANGLER'; --ph-photo: 'FOTO'; }
.ph::before {
  content: var(--ph-label); font-size: 11px; font-weight: 700;
  letter-spacing: .14em; color: var(--brand); opacity: .75;
}
.ph strong { font-size: 15px; font-weight: 600; color: var(--ink); }
.ph span { font-size: 13px; color: var(--text-muted); max-width: 46ch; }
.ph--wide { aspect-ratio: 16 / 7; }
.ph--card { aspect-ratio: 4 / 3; border-radius: var(--radius-m); }
.ph--square { aspect-ratio: 1 / 1; border-radius: var(--radius-m); }
.ph--avatar { width: 56px; height: 56px; border-radius: var(--pill); padding: 0; }
.ph--avatar::before { content: var(--ph-photo); font-size: 8px; letter-spacing: .08em; }
.ph--avatar strong, .ph--avatar span { display: none; }
.ph--logo { height: 40px; border-radius: var(--radius-s); padding: 8px 16px; }
.ph--logo::before { content: 'LOGO'; font-size: 9px; letter-spacing: .1em; }
.ph--logo strong { font-size: 12px; }
.ph--logo span { display: none; }

/* ── Cards ─────────────────────────────────────────────────────────────── */
.card {
  background: var(--white); border: 1px solid var(--border);
  border-radius: var(--radius-l); padding: 28px;
}
.card h3 { font-size: 20px; font-weight: 600; margin-bottom: 10px; }
.card p { font-size: 15px; color: var(--text-muted); }
/* The theme's MagicCard: a blue glow tracks the cursor, lighting a one pixel
   border ring and washing the card interior. Both layers are driven by --mx and
   --my, which site.js sets on pointermove; without JS they simply never move
   and the card is an ordinary bordered panel. */
.card, .magic, .addon, .compare-wrap, .integration, .step, .booking-embed, .company-info { --mx: 50%; --my: 0%; position: relative; }
/* .step is the one exception: its ::before is already the numbered circle, so a
   step gets the interior wash only, never the border ring. Claiming ::before
   here blanked the step numbers once. */
.card::before, .card::after,
.magic::before, .magic::after,
.addon::before, .addon::after,
.compare-wrap::before, .compare-wrap::after,
.integration::before, .integration::after,
.step::after,
.booking-embed::before, .booking-embed::after,
.company-info::before, .company-info::after {
  content: ''; position: absolute; border-radius: inherit;
  opacity: 0; transition: opacity .35s ease; pointer-events: none;
}
.card::before,
.magic::before,
.addon::before,
.compare-wrap::before,
.integration::before,
.booking-embed::before,
.company-info::before {  /* the border ring */
  inset: 0; z-index: 4; padding: 1px;
  background: radial-gradient(200px circle at var(--mx) var(--my), #E85A4F, transparent 62%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
}
.card::after,
.magic::after,
.addon::after,
.compare-wrap::after,
.integration::after,
.step::after,
.booking-embed::after,
.company-info::after {  /* the interior spotlight */
  inset: 1px; z-index: 2;
  background: radial-gradient(200px circle at var(--mx) var(--my), rgba(232,90,79,.16), transparent 66%);
}
.card:hover::before, .card:hover::after,
.magic:hover::before, .magic:hover::after,
.addon:hover::before, .addon:hover::after,
.compare-wrap:hover::before, .compare-wrap:hover::after,
.integration:hover::before, .integration:hover::after,
.step:hover::after,
.booking-embed:hover::before, .booking-embed:hover::after,
.company-info:hover::before, .company-info:hover::after { opacity: 1; }
/* On a card that is already primary-filled, a primary glow is invisible. */
.magic--onbrand::before { background: radial-gradient(200px circle at var(--mx) var(--my), rgba(255,255,255,.85), transparent 62%); }
.magic--onbrand::after  { background: radial-gradient(200px circle at var(--mx) var(--my), rgba(255,255,255,.14), transparent 66%); }
@media (hover: none) {
  .card::before, .card::after,
  .magic::before, .magic::after,
  .addon::before, .addon::after,
  .compare-wrap::before, .compare-wrap::after,
  .integration::before, .integration::after,
  .step::after,
  .booking-embed::before, .booking-embed::after,
  .company-info::before, .company-info::after { display: none; }
}

/* Feature card, the theme's treatment: the product shot bleeds off the top
   right corner and is clipped by the card, so it reads as a window onto the
   app rather than a picture pasted below the text. The card owns the clipping;
   the shot adds a soft fade so the cut edges do not end abruptly. */
.card:has(.card-visual) {
  position: relative; overflow: hidden; min-height: 420px;
  padding: 32px;
  background: linear-gradient(to bottom right, var(--surface) 0%, transparent 70%);
  transition: border-color .4s ease, box-shadow .4s ease;
}
.card:has(.card-visual):hover {
  border-color: oklch(1 0 0 / .14);
  box-shadow: 0 0 40px oklch(0.651 0.178 27.51 / .10);
}
.card:has(.card-visual) > h3,
.card:has(.card-visual) > p { position: relative; z-index: 3; max-width: 22rem; }

.card-visual {
  /* Anchored to the bottom right corner. Deliberately wide enough to run in
     under the paragraph on a ~590px card: the shot is the point of the card,
     and the mask fade below keeps the text legible where they overlap. */
  position: absolute; bottom: -32px; right: -56px; width: 480px; z-index: 1;
  transition: transform .7s ease;
  pointer-events: none;
}
.card:has(.card-visual):hover .card-visual { transform: translate(-12px, -10px) scale(1.03); }
.card-visual img {
  width: 100%; height: auto;
  border-radius: 10px; border: 1px solid oklch(1 0 0 / .10);
  box-shadow: 0 20px 50px oklch(0 0 0 / .55);
  /* Fade on the two inner edges so the crop melts into the card rather than
     stopping on a hard line. */
  -webkit-mask-image: linear-gradient(to left, #000 74%, transparent 100%),
                      linear-gradient(to top, #000 74%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(to left, #000 74%, transparent 100%),
              linear-gradient(to top, #000 74%, transparent 100%);
  mask-composite: intersect;
}
@media (max-width: 900px) {
  .card:has(.card-visual) { min-height: 0; }
  .card-visual { position: static; width: 100%; margin-top: 24px; transform: none; }
  .card-visual img { -webkit-mask-image: none; mask-image: none; }
}
.grid { display: grid; gap: 24px; }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }

.icon-badge {
  width: 44px; height: 44px; border-radius: var(--radius-m);
  background: var(--brand-soft); color: var(--brand);
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 18px;
}
.icon-badge svg { width: 22px; height: 22px; }

/* ── Social proof / stats ──────────────────────────────────────────────── */
/* No border band: the theme separates this section with space, not rules. */
.proof { padding: 56px 0; }
/* Every logo gets an identical box and is fitted inside it, which is what
   makes a row of differently proportioned wordmarks read evenly. Sizing each
   to its own intrinsic width leaves the wide ones dominating the row. */
.proof-logos {
  display: grid; grid-template-columns: repeat(3, 1fr);
  max-width: 896px; margin: 0 auto; gap: 28px 8px;
  align-items: center; justify-items: center;
}
/* Each partner mark keeps the intrinsic size it has in the design (the designer
   balanced them optically, so they are not a uniform height); max-height is only
   a guard rail. */
.proof-logos img { width: 172px; height: 40px; object-fit: contain; opacity: .9; }
@media (max-width: 720px) { .proof-logos { grid-template-columns: repeat(2, 1fr); } }
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; text-align: center; }
.stat-value { font-size: 44px; font-weight: 600; letter-spacing: -0.04em; }
.stat-label { font-size: 14px; color: var(--text-muted); margin-top: 4px; }

/* ── Steps ─────────────────────────────────────────────────────────────── */
.steps { counter-reset: step; display: grid; gap: 24px; grid-template-columns: repeat(3, 1fr); }
.step { overflow: hidden; position: relative; padding-top: 56px; }
.step::before {
  counter-increment: step; content: counter(step);
  position: absolute; top: 0; left: 0;
  width: 40px; height: 40px; border-radius: var(--pill);
  background: var(--primary); color: var(--primary-foreground);
  display: flex; align-items: center; justify-content: center;
  font-size: 15px; font-weight: 600;
}
.step h3 { font-size: 19px; font-weight: 600; margin-bottom: 8px; }
.step p { font-size: 15px; color: var(--text-muted); }

/* ── Split feature rows ────────────────────────────────────────────────── */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: center; }
.split + .split { margin-top: 96px; }
.split--flip .split-media { order: -1; }
.quote-avatar { width: 56px; height: 56px; border-radius: 10px; object-fit: cover; flex: none; }
/* The onboarding shot already is a card (own corners and shadow baked in), so it
   skips the frame the other split images get and just gets sized: portrait, so
   narrower than the column to keep the split's rows balanced. */
.split-media img.split-img--card { width: min(420px, 100%); margin: 0 auto; border: 0; box-shadow: none; border-radius: 0; }
/* Real screenshots in the split sections: full column width, framed like the
   cards so they read as product shots rather than photos. */
.split-media img {
  width: 100%; height: auto;
  border: 1px solid var(--border); border-radius: var(--radius-l);
  box-shadow: var(--shadow-m);
}
/* .split-media.magic opts a split screenshot into the same cursor-tracked glow
   as the card grids. border-radius here is what the glow ring inherits, so it
   traces the framed image's own rounded corners instead of a square edge.
   A card shot only fills 420px of the column (see .split-img--card above), so
   the glow box is shrunk to match; otherwise the ring would trace the full
   column width, leaving visible gaps on both sides of the narrower image. */
.split-media.magic:has(img.split-img--card) { width: min(420px, 100%); margin: 0 auto; }
.split-media.magic { border-radius: var(--radius-l); }
.split h3 { font-size: 34px; margin-bottom: 16px; }
.split p { color: var(--text-muted); }
.checklist { margin-top: 24px; display: grid; gap: 12px; }
.checklist li { display: flex; gap: 10px; align-items: flex-start; font-size: 15px; }
.checklist svg { width: 20px; height: 20px; flex-shrink: 0; color: var(--brand); margin-top: 1px; }

/* ── Pricing ───────────────────────────────────────────────────────────── */
.billing-toggle {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  font-size: 15px; margin-bottom: 8px;
}
.billing-toggle button {
  width: 46px; height: 26px; border-radius: var(--pill); border: 0;
  background: var(--brand); position: relative; cursor: pointer; padding: 0;
}
.billing-toggle button::after {
  content: ''; position: absolute; top: 3px; left: 3px;
  width: 20px; height: 20px; border-radius: var(--pill); background: var(--white);
  transition: transform .18s;
}
.billing-toggle[data-cycle="yearly"] button::after { transform: translateX(20px); }
.billing-toggle .dim { color: var(--text-muted); }
.billing-save { text-align: center; font-size: 14px; font-weight: 600; color: var(--teal); margin-bottom: 40px; }

.price-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; align-items: start; }
.price-card {
  background: var(--white); border: 1px solid var(--border);
  border-radius: var(--radius-xl); padding: 32px; display: flex; flex-direction: column; height: 100%;
}
.price-card--featured { background: var(--brand); border-color: var(--brand); color: var(--on-invert); }
.price-card--featured .price-desc,
.price-card--featured .price-period,
.price-card--featured .checklist li { color: rgba(255,255,255,.82); }
.price-card--featured .checklist svg { color: var(--on-invert); }
.price-name { font-size: 20px; font-weight: 600; display: flex; align-items: center; gap: 10px; }
.price-tag {
  font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  background: rgba(255,255,255,.2); padding: 4px 10px; border-radius: var(--pill);
}
.price-desc { font-size: 14px; color: var(--text-muted); margin-top: 8px; min-height: 42px; }
.price-amount { font-size: 46px; font-weight: 600; letter-spacing: -0.04em; margin-top: 24px; }
.price-amount small { font-size: 15px; font-weight: 500; letter-spacing: 0; }
.price-period { font-size: 13px; color: var(--text-muted); margin-top: 2px; }
.price-card .btn { margin-top: 24px; }
.price-card .checklist { margin-top: 24px; padding-top: 24px; border-top: 1px solid var(--border); }
.price-card--featured .checklist { border-top-color: rgba(255,255,255,.22); }

.addon-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; margin-top: 24px; }
/* Chrome and type come from the theme's pricing-card classes in the markup;
   all this rule still owns is clipping the cursor glow's border ring. */
.addon { overflow: hidden; }

/* ── Integrations ──────────────────────────────────────────────────────── */
.integration-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.integration { overflow: hidden;
  border: 1px solid var(--border); border-radius: var(--radius-l);
  padding: 24px; display: flex; gap: 16px; align-items: flex-start;
  transition: border-color .15s, box-shadow .15s;
}
.integration:hover { border-color: var(--border-strong); box-shadow: var(--shadow-m); }
.integration h4 { font-size: 17px; font-weight: 600; margin-bottom: 4px; }
.integration p { font-size: 14px; color: var(--text-muted); }
.integration .ph--logo { flex-shrink: 0; width: 48px; height: 48px; border-radius: var(--radius-m); padding: 0; }
/* Real integration marks sit in the same 48px chip the placeholder used. contain
   keeps each brand's own proportions, and the white ground stops the darker marks
   from reading as holes in the card. */
.int-logo {
  flex-shrink: 0; width: 48px; height: 48px;
  object-fit: contain; padding: 6px;
  background: var(--white); border: 1px solid var(--border);
  border-radius: var(--radius-m);
}
.tag {
  display: inline-block; font-size: 11px; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; padding: 3px 9px; border-radius: var(--pill);
  background: var(--surface); color: var(--text-muted); border: 1px solid var(--border);
  margin-top: 10px;
}
.tag--live { background: var(--teal-soft); color: #0f7a63; border-color: transparent; }
.tag--soon { background: var(--brand-soft); color: var(--brand-deep); border-color: transparent; }

/* ── Background grid ───────────────────────────────────────────────────── */
/* The theme's footer backdrop (footer.tsx), same 1px lines, same #222222, same
   4rem cell. Its own mask fades the grid in downwards, which suits a footer;
   a band in the middle of the page gets .gridbg--band instead so it fades out
   at both ends rather than stopping on a hard edge. */
.gridbg { position: relative; }
.gridbg > * { position: relative; z-index: 1; }
.gridbg::before {
  content: ''; position: absolute; inset: 0; left: -2px; z-index: 0;
  pointer-events: none; opacity: .5;
  background-image:
    linear-gradient(to right, #222222 1px, transparent 1px),
    linear-gradient(to bottom, #222222 1px, transparent 1px);
  background-size: 4rem 4rem;
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000);
          mask-image: linear-gradient(to bottom, transparent, #000);
}
.gridbg--band::before {
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 22%, #000 78%, transparent);
          mask-image: linear-gradient(to bottom, transparent, #000 22%, #000 78%, transparent);
}

/* ── Testimonials ──────────────────────────────────────────────────────── */
/* Testimonials, the theme's treatment: one quote at a time set large, with a
   square avatar floated into the opening line rather than a row of small
   cards. Without JS every quote is simply visible and stacked, which reads
   fine and keeps all three in the markup for crawlers. */
/* Keyed off :has() so the four locales' index.html need no extra class. */
.section:has(.quotes) { padding: 160px 0; overflow: hidden; }
.quotes { max-width: 900px; margin: 0 auto; position: relative; }
.quote-card { background: transparent; border: 0; padding: 0; }
.quotes[data-ready] .quote-card { display: none; }
.quotes[data-ready] .quote-card.is-active { display: block; animation: quoteIn .5s ease both; }
@keyframes quoteIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.quote-card p {
  font-size: clamp(24px, 3.1vw, 40px); line-height: 1.15;
  letter-spacing: -0.03em; color: var(--foreground);
}
.quote-card > p::before { content: none; }
.quote-author { display: flex; align-items: center; gap: 12px; margin-top: 32px; }
.quote-author strong { display: block; font-size: 15px; font-weight: 600; }
.quote-author span { font-size: 13px; color: var(--text-muted); }

/* ── FAQ ───────────────────────────────────────────────────────────────── */
/* accordion.tsx: a flat list, each item separated by a rule rather than drawn
   as its own card, the trigger text-sm font-medium at py-4 with hover:underline,
   and tabler's own chevron-down/chevron-up in muted-foreground. The chevron is
   a mask rather than a background image so it still takes currentColor. */
.faq-list { max-width: 820px; margin: 0 auto; display: flex; width: 100%; flex-direction: column; }
.faq-item:not(:last-child) { border-bottom: 1px solid var(--border); }
.faq-item summary {
  cursor: pointer; list-style: none; padding: 16px 0;
  font-size: 14px; font-weight: 500; display: flex; align-items: flex-start;
  justify-content: space-between; gap: 16px; transition: all .15s;
}
.faq-item summary:hover { text-decoration: underline; }
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
  content: ''; flex: none; width: 16px; height: 16px; margin-top: 2px;
  background-color: var(--muted-foreground);
  -webkit-mask: var(--chevron-down) center / 16px 16px no-repeat;
          mask: var(--chevron-down) center / 16px 16px no-repeat;
}
.faq-item[open] summary::after {
  -webkit-mask-image: var(--chevron-up);
          mask-image: var(--chevron-up);
}
.faq-item .faq-body { padding: 0 0 16px; font-size: 14px; color: var(--muted-foreground); }

/* ── Footer ────────────────────────────────────────────────────────────── */
.footer { background: var(--card); color: var(--foreground); border-top: 1px solid var(--border); padding: 72px 0 32px; }
.footer-top { display: grid; grid-template-columns: 1.4fr repeat(3, 1fr); gap: 40px; }
.footer-logo { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; }
.footer-brand img { height: 26px; }
.footer-brand p { font-size: 14px; color: var(--text-muted); max-width: 30ch; }
.footer h3 { font-size: 14px; font-weight: 500; color: var(--text-muted); margin-bottom: 16px; }
.footer-col a { display: block; font-size: 14px; color: rgba(255,255,255,.86); padding: 5px 0; transition: color .15s; }
.footer-col a:hover { color: var(--on-invert); }
.footer-bottom {
  margin-top: 56px; padding-top: 24px; border-top: 1px solid rgba(255,255,255,.12);
  display: flex; justify-content: space-between; align-items: center; gap: 16px; flex-wrap: wrap;
  font-size: 13px; color: var(--text-muted);
}
.footer-bottom a { color: var(--text-muted); }
.footer-bottom a:hover { color: var(--on-invert); }
.footer-social { display: flex; gap: 16px; }
.footer-social svg { width: 18px; height: 18px; }

/* ── Legal / prose pages ───────────────────────────────────────────────── */
.prose { max-width: 760px; margin: 0 auto; }
.prose h2 { font-size: 26px; margin: 40px 0 12px; }
.prose h3 { font-size: 19px; font-weight: 600; margin: 24px 0 8px; }
.prose p, .prose li { font-size: 16px; color: var(--text-muted); }
.prose p + p { margin-top: 12px; }
.prose ul { margin: 12px 0; display: grid; gap: 8px; }
.prose ul li { padding-left: 20px; position: relative; }
.prose ul li::before { content: ''; position: absolute; left: 4px; top: 11px; width: 5px; height: 5px; border-radius: 50%; background: var(--brand); }
.prose table { width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 15px; }
.prose th, .prose td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--border); }
.prose th { font-weight: 600; }
.prose td { color: var(--text-muted); }

/* ── Contact ───────────────────────────────────────────────────────────── */
.contact-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: start; }
.field { display: grid; gap: 6px; margin-bottom: 16px; }
.field label { font-size: 14px; font-weight: 500; }
.field input, .field textarea, .field select {
  font-family: inherit; font-size: 15px; color: var(--ink);
  padding: 12px 14px; border: 1px solid var(--border-strong);
  border-radius: var(--radius-m); background: var(--white); outline: none;
  transition: border-color .15s, box-shadow .15s;
}
.field input:focus, .field textarea:focus, .field select:focus {
  border-color: var(--brand); box-shadow: 0 0 0 3px rgba(95,87,255,.15);
}
.field textarea { resize: vertical; min-height: 130px; }
.contact-detail { display: flex; gap: 14px; align-items: flex-start; padding: 18px 0; border-bottom: 1px solid var(--border); }
.contact-detail:last-child { border-bottom: 0; }
.contact-detail strong { display: block; font-size: 15px; font-weight: 600; }
.contact-detail span, .contact-detail a { font-size: 15px; color: var(--text-muted); }
.contact-detail a:hover { color: var(--brand); }
.form-note { font-size: 13px; color: var(--text-muted); margin-top: 10px; }

/* ── Responsive ────────────────────────────────────────────────────────── */
@media (max-width: 1024px) {
  .grid--4 { grid-template-columns: repeat(2, 1fr); }
  .price-grid { grid-template-columns: 1fr; max-width: 560px; margin: 0 auto; }
  .integration-grid, .addon-grid, .steps { grid-template-columns: repeat(2, 1fr); }
  .split { gap: 40px; }
  .hero h1 { font-size: 54px; }
  h2.section-title { font-size: 36px; }
  .pagehero h1 { font-size: 44px; }
}

@media (max-width: 820px) {
  .nav-inner { justify-content: space-between; }
  .nav-actions { order: 2; margin-left: auto; }
  .nav-actions .btn--sm.hide-mobile { display: none; }

  .section { padding: 64px 0; }
  .grid--2, .grid--3, .grid--4, .integration-grid, .addon-grid, .steps,
  .split, .contact-grid, .stats { grid-template-columns: 1fr; }
  .split + .split { margin-top: 56px; }
  .split--flip .split-media { order: 0; }
  .stats { gap: 32px; }
  .hero { padding-top: 64px; }
  .hero h1 { font-size: 40px; }
  .pagehero h1 { font-size: 34px; }
  h2.section-title { font-size: 30px; }
  .split h3 { font-size: 26px; }
  .footer-top { grid-template-columns: 1fr 1fr; gap: 32px; }
}

@media (max-width: 520px) {
  .footer-top { grid-template-columns: 1fr; }
  .hero-actions .btn { width: 100%; }
}

/* ── Blog ───────────────────────────────────────────────────────────────────
   Ported from the Figma Blog and Blog Detail frames. Sizes are the design's:
   featured hero 88px padding with a 500x450 illustration, 280px topic rail,
   408px cards with a 210px image, and a 920px measure on article pages. */
.blog-hero { padding: 0 32px 32px; }
.blog-hero-inner {
  display: flex; gap: 80px; align-items: flex-start; padding: 88px;
  border-radius: var(--radius-l); overflow: hidden;
  background: linear-gradient(180deg, rgba(232,90,79,.16) 0%, var(--card) 100%);
}
.blog-hero-text { flex: 1 0 0; min-width: 0; display: flex; flex-direction: column; gap: 40px; }
.blog-hero-text .kicker { font-size: 18px; font-weight: 600; color: var(--brand); }
.blog-hero-text h1 { font-size: 52px; line-height: 1.25; margin: 16px 0; }
.blog-hero-text .lead { max-width: 588px; }
.blog-hero-media { flex: none; width: 500px; height: 450px; border: 1px solid #eceff3; border-radius: 16px; overflow: hidden; background: var(--white); }
.blog-hero-media .ph { height: 100%; border: 0; border-radius: 16px; }

/* Byline: avatar, name, dot, date */
.byline { display: flex; gap: 12px; align-items: center; color: var(--text-muted); font-size: 18px; }
.byline .ph--avatar { width: 32px; height: 32px; }
.byline .dot { width: 6px; height: 6px; border-radius: var(--pill); background: #c1c7d0; flex: none; }

.blog-layout { display: grid; grid-template-columns: 280px 1fr; gap: 64px; align-items: start; }
.topics { display: flex; flex-direction: column; gap: 24px; position: sticky; top: 104px; }
.topics h2 { font-size: 20px; line-height: 1.4; }
.topic-search {
  display: flex; gap: 8px; align-items: center; height: 40px; padding: 6px 12px;
  background: var(--white); border: 0; border-radius: 8px;
  box-shadow: 0 1px 2px rgba(18,55,105,.08), 0 0 0 1px rgba(9,25,72,.13);
  font-family: inherit; font-size: 16px; color: var(--ink); width: 100%;
}
.topic-search::placeholder { color: #a4acb9; }
.topic-list { display: flex; flex-direction: column; gap: 8px; }
.topic-list button {
  display: flex; align-items: center; height: 32px; padding: 6px 16px;
  background: none; border: 0; border-left: 1.5px solid transparent; cursor: pointer;
  font-family: inherit; font-size: 16px; font-weight: 500; color: #818898; text-align: left; width: 100%;
}
.topic-list button:hover { color: var(--ink); }
.topic-list button[aria-current="true"] { border-left-color: var(--brand); color: var(--brand); }

.post-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 48px 40px; }
.post-card { display: flex; flex-direction: column; gap: 20px; }
.post-card-media { border-radius: 12px; overflow: hidden; background: var(--surface); aspect-ratio: 408 / 210; }
.post-card-media .ph { height: 100%; border: 0; border-radius: 12px; }
.post-card .kicker { font-size: 16px; font-weight: 500; color: var(--brand); }
.post-card h3 { font-size: 24px; line-height: 1.3; margin: 8px 0; }
.post-card p { font-size: 16px; color: var(--text-muted); }
.post-card .byline { font-size: 16px; gap: 8px; }
.post-card .byline .ph--avatar { width: 24px; height: 24px; }
.post-card a.post-link { color: inherit; }
.post-card a.post-link:hover h3 { color: var(--brand); }
/* Product screenshot standing on its own, outside a .split-media pair. */
.shot { width: min(420px, 100%); height: auto; display: block; margin: 48px auto 0;
  border: 1px solid var(--border); border-radius: var(--radius-l, 16px); box-shadow: var(--shadow-m); }

/* Authored SVG figures on the comparison pages. The labels stop being legible
   below about 640px, so the figure scrolls inside itself rather than squashing;
   the page never scrolls sideways. */
.chart { margin: 48px 0 0; overflow-x: auto; }
/* Below about 800px the labels inside the figure stop being readable, so it
   scrolls inside its own box rather than shrinking into illegibility. The page
   itself never scrolls sideways. */
.chart img { width: 100%; min-width: 800px; height: auto; display: block; border-radius: var(--radius-l, 16px); }
.chart figcaption { margin-top: 8px; font-size: 14px; color: var(--text-muted); text-align: center; }

.post-empty { grid-column: 1 / -1; padding: 48px 0; color: var(--text-muted); text-align: center; }

/* Article page */
/* 72 here plus the hero's own 56 clears the fixed header, same as .pagehero. */
.article { padding: 72px 32px 32px; }
.article-hero {
  display: flex; flex-direction: column; align-items: center; gap: 48px;
  padding: 56px 88px; border-radius: var(--radius-l);
  background: linear-gradient(180deg, rgba(232,90,79,.10) 0%, var(--card) 100%);
}
.article-measure { width: min(920px, 100%); }
.article-hero .kicker { font-size: 16px; font-weight: 600; color: var(--brand); }
.article-hero h1 { font-size: 52px; line-height: 1.25; margin-top: 16px; }
.article-figure { border: 1px solid #eceff3; border-radius: 16px; overflow: hidden; background: var(--white); aspect-ratio: 920 / 520; }
.article-figure .ph { height: 100%; border: 0; border-radius: 16px; }
.article-body { width: min(920px, 100%); margin: 56px auto 0; display: flex; flex-direction: column; gap: 20px; }
.article-body h2 { font-size: 32px; line-height: 1.35; margin-top: 28px; }
.article-body h3 { font-size: 20px; line-height: 1.4; margin-top: 12px; }
.article-body p { font-size: 18px; line-height: 1.55; color: var(--text-muted); }
.article-body a { color: var(--brand); text-decoration: underline; }
.article-body ul { display: flex; flex-direction: column; gap: 10px; }
.article-body ul li { font-size: 18px; line-height: 1.55; color: var(--text-muted); padding-left: 22px; position: relative; }
.article-body ul li::before { content: ''; position: absolute; left: 4px; top: 12px; width: 6px; height: 6px; border-radius: var(--pill); background: var(--brand); }
.article-back { margin-top: 56px; }

@media (max-width: 900px) {
  .hero h1 { font-size: 40px; }
  .blog-hero-inner { flex-direction: column; gap: 40px; padding: 40px 24px; }
  .blog-hero-media { width: 100%; height: auto; aspect-ratio: 500 / 450; }
  .blog-hero-text h1 { font-size: 36px; }
  .blog-layout { grid-template-columns: 1fr; gap: 40px; }
  .topics { position: static; }
  .post-grid { grid-template-columns: 1fr; gap: 40px; }
  .article-hero { padding: 32px 24px; }
  .article-hero h1 { font-size: 34px; }
  .article-body h2 { font-size: 26px; }
}

/* Translated legal documents carry a line naming the authoritative version. */
.legal-note {
  margin-bottom: 28px; padding: 14px 18px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-m);
  font-size: 14px; color: var(--text-muted);
}
.legal-note a { color: var(--brand); text-decoration: underline; }

/* ── Pricing extras ─────────────────────────────────────────────────────── */
.price-approx { font-size: 13px; color: var(--text-muted); margin-top: 4px; }
.addon-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 860px; margin: 0 auto; }

/* Competitor comparison. The Kodeleads column is tinted; the wrap scrolls
   sideways on narrow screens instead of squeezing seven columns. */
/* table.tsx: text-sm throughout, rows separated by border-b and lit by
   hover:bg-muted/50, a header that is plain foreground type rather than a
   filled band, and the caption muted below the table. The horizontal padding
   is wider than the theme's p-2, which is sized for a dense data grid; the
   vertical rhythm (h-10 header, py-2 cells) is the theme's own. The tinted
   Kodeleads column has no counterpart in the theme and stays as it was. */
.compare-wrap {
  overflow: hidden; overflow-x: auto; border: 1px solid var(--border);
  border-radius: 0.75rem; background: color-mix(in oklab, var(--muted) 50%, transparent);
}
.compare-table { width: 100%; min-width: 820px; border-collapse: collapse; font-size: 14px; }
.compare-table th, .compare-table td { padding: 8px 16px; text-align: center; border-bottom: 1px solid var(--border); vertical-align: middle; }
.compare-table thead th { height: 40px; font-weight: 500; color: var(--foreground); white-space: nowrap; }
.compare-table tbody th { text-align: left; font-weight: 400; color: var(--muted-foreground); white-space: nowrap; }
.compare-table tbody tr { transition: background-color .15s; }
.compare-table tbody tr:hover { background: color-mix(in oklab, var(--muted) 50%, transparent); }
.compare-table tr:last-child th, .compare-table tr:last-child td { border-bottom: 0; }
.compare-table .cmp-us, .compare-table td:nth-child(2) {
  background: color-mix(in oklab, var(--primary) 14%, transparent);
  color: var(--primary); font-weight: 500;
}
.compare-table .cmp-price td { white-space: nowrap; }
.compare-legend { margin-top: 16px; text-align: center; font-size: 14px; color: var(--muted-foreground); line-height: 1.8; }
@media (max-width: 700px) { .addon-grid--2 { grid-template-columns: 1fr; } }

/* ── Blog cover images ───────────────────────────────────────────────────────
   Posts with a cover put a real <img> in the media slots; posts without one
   render placeholder boxes. The slots are fixed-ratio, so the image fills
   and crops rather than reflowing the layout. */
.blog-hero-media img, .post-card-media img, .article-figure img {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.article-body img { max-width: 100%; height: auto; border-radius: 12px; }
.article-body blockquote {
  margin: 0; padding: 4px 24px; border-left: 3px solid var(--brand);
  color: var(--text-muted); font-size: 18px; line-height: 1.55;
}
.article-body ol { display: flex; flex-direction: column; gap: 10px; padding-left: 26px; }
.article-body ol li { font-size: 18px; line-height: 1.55; color: var(--text-muted); }
.article-body .faq-list { margin: 0; }

/* Real author photo in the byline; the ph--avatar placeholder remains for
   authors without one. Sized to match .byline .ph--avatar exactly. */
.byline .avatar-img { width: 32px; height: 32px; border-radius: var(--pill); object-fit: cover; flex: none; }
/* Booking CTA on the contact pages, in place of the old lead form. Same card
   treatment as the pricing panels so the page keeps its rhythm. */
.booking-cta { background: var(--surface); border-radius: var(--radius-l, 16px); padding: 32px; }
.booking-cta h2 { margin: 0 0 12px; }
.booking-cta p { margin: 0 0 20px; }
.booking-cta .form-note { margin: 16px 0 0; }

/* Contact page team photo. Portrait as shot, so the frame follows the image
   rather than cropping faces to fit a landscape slot. */
.team-photo { width: 100%; height: auto; border-radius: var(--radius-l, 16px); display: block; }

/* Contact page: booking calendar left at a fixed 472px, company information
   right. The calendar is a fixed size on purpose. Left to stretch it reflowed
   into enormous day circles with acres of whitespace, and embed.js sets
   width:100% inline, so the width is controlled by the column instead. */
.booking-grid {
  display: grid;
  grid-template-columns: 472px 1fr;
  gap: 64px;
  align-items: start;
}
.booking-embed { max-width: 472px; }
.booking-embed h2, .company-info h2 { margin: 0 0 12px; }
.booking-embed p { margin: 0 0 20px; }
.booking-embed .form-note { margin: 16px 0 0; }
/* min-height beats the inline height embed.js sets. The booking page reports
   about 207px over postMessage while the month grid at this width needs about
   500px, so the floor keeps it from clipping; a correct larger report still
   grows the frame. Drop the floor once the app reports its real height. */
.booking-embed iframe {
  border-radius: var(--radius-l, 16px);
  background: var(--surface);
  min-height: 520px;
}
.company-info .team-photo { max-width: 340px; }
@media (max-width: 900px) {
  .booking-grid { grid-template-columns: 1fr; gap: 48px; }
}
.booking-embed .form-note { margin: 16px 0 0; }

/* The picker is a <details>; hide the default marker so the globe stands alone. */
.langpick > summary::-webkit-details-marker { display: none; }

/* ══ kodecrew ═══════════════════════════════════════════════════════════════
   Everything above is the Solaris component layer as sites/kodeleads carries
   it. Below: the handful of rules that were written against a near-black page
   and need a light one, and the few components kodecrew has that kodeleads
   does not. */

/* Inlined FontAwesome (Jelly) icons take the text colour. */
svg.fa { fill: currentColor; display: inline-block; }

/* The window frame and nav were translucent black with white hairlines. */
.frame { background: color-mix(in oklab, var(--card) 60%, transparent); border-color: var(--border); }
.frame-dots i { background: var(--foreground); }
.nav-inner { background: color-mix(in oklab, var(--card) 70%, transparent); }
.card:has(.card-visual):hover { border-color: var(--border-strong); }
.card-visual img { border-color: var(--border); box-shadow: var(--shadow-l); }
.blog-hero-media, .article-figure { border-color: var(--border); }
.byline .dot { background: var(--muted-light); }
.topic-search { box-shadow: 0 0 0 1px var(--border-strong); }

/* kodecrew's footer is its own near-black band, with the white lockup. */
.footer { background: #141414; color: #fff; border-top: 0; }
.footer h4 { color: #fff; font-size: 14px; font-weight: 600; margin-bottom: 12px; }
.footer-top { grid-template-columns: 1.6fr repeat(2, 1fr); }
.footer-logo-img { height: 28px; width: auto; margin-bottom: 20px; }
.footer-social { align-items: center; margin-bottom: 20px; }
.footer-social img { height: 36px; width: 36px; }
.footer-stores { display: flex; flex-wrap: wrap; gap: 12px; }
.footer-stores img { height: 44px; width: auto; }
.footer-bottom { color: rgba(255,255,255,.6); font-size: 13px; }
.footer--bare { padding: 48px 0; }
@media (max-width: 760px) { .footer-top { grid-template-columns: 1fr 1fr; } .footer-brand { grid-column: 1 / -1; } }

.section-head--center { margin-inline: auto; text-align: center; }
.section-title--sm { font-size: 32px !important; }
.section--first { padding-top: 168px; }
.section-head + .split { margin-top: 56px; }
.split--top { align-items: start; }
.split-media video, .media-frame video {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--border); border-radius: var(--radius-l);
  box-shadow: var(--shadow-m); background: var(--card);
}
.split-media--bare img { border: 0; box-shadow: none; border-radius: 0; }
.card--accent { border-color: var(--brand); }
.card .stat-value { line-height: 1; }
.grid--4 .card { padding: 22px; }

/* Two tiers, not three. The featured card is solid kodecrew red. */
.price-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 1080px; margin: 0 auto; }
/* A plan whose "price" is a sentence ("lad os tale sammen") keeps it on one
   line: the boxes are wider, and where the page is too narrow for that the
   sentence gives a little instead of breaking in two. */
@media (min-width: 901px) and (max-width: 1100px) { .price-amount--text { font-size: 4.2vw; } }
@media (max-width: 480px) { .price-amount--text { font-size: 32px; } }
.price-card .checklist svg { color: var(--brand); }
.price-card--featured .checklist svg { color: #fff; }
.price-card .checklist strong { font-weight: 600; }
.price-card--featured .btn--light { border-color: transparent; }

/* The closing call to action: a card lit from below in kodecrew red. */
.cta-card {
  position: relative; overflow: hidden; text-align: center;
  padding: 72px 24px; border: 1px solid var(--border); border-radius: var(--radius-xl);
  background:
    radial-gradient(60% 90% at 50% 115%, rgba(232,90,79,.30) 0%, transparent 70%),
    var(--card);
}
.cta-card .section-title { max-width: 22ch; margin-inline: auto; }
.cta-card .section-sub { max-width: 56ch; margin-inline: auto; }

/* Contact page. */
.contact-detail { display: flex; gap: 14px; align-items: flex-start; margin-bottom: 18px; font-size: 15px; }
.contact-detail a:hover { color: var(--brand); }
.contact-map { width: 100%; height: auto; margin-top: 12px; border: 1px solid var(--border); border-radius: var(--radius-l); }
/* Embedded Kodeleads forms sit in the site's card, like every other box. The
   frame's own page is white, so the card keeps a narrow margin and the frame
   is rounded to follow the card's corner. */
.embed-card { padding: 12px; }
.embed-card iframe { width: 100%; border: 0; border-radius: calc(var(--radius-l) - 12px); background: #fff; }
.booking-embed { min-height: 520px; }
.booking-embed--center { max-width: 760px; margin-inline: auto; }
.form-embed { max-width: 480px; }

/* Testimonials: the quote is the card's content, so it reads at body size and
   in the text colour rather than as a card's muted caption. */
.note-card blockquote p { font-size: 17px; line-height: 1.55; color: var(--ink); letter-spacing: -0.01em; }

/* SCARF: a two-column table, stacked on a phone. */
.scarf { width: 100%; border-collapse: collapse; font-size: 15px; }
.scarf th, .scarf td { text-align: left; vertical-align: top; padding: 18px 20px; border-bottom: 1px solid var(--border); }
.scarf thead th { font-weight: 600; background: color-mix(in oklab, var(--card) 70%, transparent); }
.scarf tbody tr:last-child td { border-bottom: 0; }
.scarf td strong { display: block; color: var(--foreground); font-weight: 600; margin-bottom: 2px; }
.scarf td { color: var(--text-muted); width: 50%; }
.compare-wrap { border: 1px solid var(--border); border-radius: var(--radius-l); overflow: hidden; background: var(--card); }
@media (max-width: 640px) { .scarf th, .scarf td { padding: 14px; font-size: 14px; } }

/* Changelog and help. */
.changelog { display: grid; gap: 24px; max-width: 860px; margin: 0 auto; }
.prose--card { max-width: none; margin: 0; }
.prose--card p, .prose--card li { font-size: 15px; }
.prose--center { text-align: center; margin-top: 16px; }
.pagehero--author { padding-bottom: 48px; }
.author-photo { width: 120px; height: 120px; border-radius: 999px; object-fit: cover; object-position: top; margin: 0 auto 20px; border: 1px solid var(--border); }
.post-grid--wide { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.avatar-img { width: 32px; height: 32px; border-radius: 999px; object-fit: cover; object-position: top; }
.related { display: grid; gap: 10px; margin: 12px 0 0; }
.related a { color: var(--brand); }
.related a:hover { text-decoration: underline; }

@media (max-width: 900px) {
  .grid--2, .grid--3, .grid--4, .steps, .price-grid--2, .post-grid--wide { grid-template-columns: 1fr; }
  .split, .contact-grid { grid-template-columns: 1fr; gap: 40px; }
  .split--flip .split-media { order: 0; }
  h2.section-title { font-size: 34px; }
  .section { padding: 64px 0; }
  .pagehero h1 { font-size: 40px; }
}
.card p.stat-value { font-size: 44px; font-weight: 500; letter-spacing: -0.04em; color: var(--foreground); }

/* Sections in the kodeleads page structure, where kodecrew's content needs a
   different count than kodeleads' own: ten customer logos, three stats. */
.proof-logos--5 { grid-template-columns: repeat(5, 1fr); max-width: 1080px; }
@media (max-width: 900px) { .proof-logos--5 { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 520px) { .proof-logos--5 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 821px) { .stats--3 { grid-template-columns: repeat(3, 1fr); } }
.pagehero .eyebrow { margin-bottom: 14px; }
.integration h4 { margin: 12px 0 0; }

/* The article body sits in the article's own column, under the title. */
.article-body--column { width: 100%; margin-top: 0; }
.post-empty { color: var(--text-muted); text-align: center; padding: 24px 0; }

/* The typed headline's caret (shadcn.io typing-text): it blinks only while a
   line is held, as a real caret does. */
@keyframes typing-text-cursor { 50% { opacity: 0; } }
@media (prefers-reduced-motion: no-preference) {
  [data-typing][data-state="idle"] .typing-caret { animation: typing-text-cursor 1s steps(1, end) infinite; }
}
/* kodecrew's integration logos are wordmarks, not square marks, so their chip
   is wide enough to read them. */
.int-logo--wide { width: 128px; height: 56px; padding: 10px 14px; }
.integration:has(.int-logo--wide) { align-items: center; }
.integration:has(.int-logo--wide) h4 { margin: 0; }

/* ── Hero slider ───────────────────────────────────────────────────────────
   The app window in the hero shows one screenshot per feature. The screens
   are stacked and cross-fade; each has a tab above the window whose bar fills
   while its screen is showing. The bar's own animation is the timer: site.js
   moves on when it ends, so pausing the animation pauses the slider. */
.hero-screens { aspect-ratio: 16 / 10; background: #141311; }
.hero-screen {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: left top;
  opacity: 0; transition: opacity .5s ease;
}
.hero-screen.is-active { opacity: 1; }
.hero-tabs { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 6px; padding: 0 0 12px; }
.hero-tab {
  display: flex; flex-direction: column; gap: 6px; text-align: left;
  padding: 10px 12px 12px; border-radius: var(--radius-m);
  color: var(--text-muted); cursor: pointer;
  transition: background-color .2s ease;
}
.hero-tab:hover, .hero-tab.is-active { background: color-mix(in oklab, var(--foreground) 5%, transparent); }
.hero-tab:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.hero-tab-bar { display: block; height: 3px; margin-bottom: 4px; border-radius: 3px; background: var(--border); overflow: hidden; }
.hero-tab-bar > span { display: block; width: 0; height: 100%; border-radius: inherit; background: var(--primary); }
.hero-tab.is-active .hero-tab-bar > span { width: 100%; }
.hero-slider.is-running .hero-tab.is-active .hero-tab-bar > span { animation: hero-progress var(--slide-ms, 6000ms) linear forwards; }
@media (hover: hover) {
  .hero-slider.is-running:hover .hero-tab.is-active .hero-tab-bar > span { animation-play-state: paused; }
}
@keyframes hero-progress { from { width: 0; } to { width: 100%; } }
.hero-tab-title { font-size: 14px; font-weight: 600; letter-spacing: -0.01em; color: var(--ink); }
.hero-tab-text { font-size: 12.5px; line-height: 1.45; }
.hero-caption { display: none; }
/* Narrow screens: six bars in a row, and one caption for the screen showing.
   The tab's own text stays in the accessibility tree as the button's name. */
@media (max-width: 1023px) {
  .hero-tabs { gap: 4px; padding: 0 2px; }
  .hero-tab { padding: 8px 0; background: none !important; }
  .hero-tab-bar { margin: 0; }
  .hero-tab-title, .hero-tab-text {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
  }
  .hero-caption {
    display: flex; flex-direction: column; gap: 2px; text-align: left;
    padding: 2px 4px 12px; min-height: 72px;
    font-size: 13px; line-height: 1.45; color: var(--text-muted);
  }
  .hero-caption strong { font-size: 14px; font-weight: 600; color: var(--ink); }
}

/* A screenshot shown as a crop: the frame has the app window's 16:10 shape,
   the shot is drawn at 165% of it and --fx / --fy (0 to 1) say which part is
   in view. A whole 1440 px window in a 540 px column is too small to read. */
.appshot {
  position: relative; width: 100%; margin: 0; overflow: hidden; aspect-ratio: 16 / 10; background: #141311;
  border: 1px solid var(--border); border-radius: var(--radius-l); box-shadow: var(--shadow-m);
}
.appshot img {
  position: absolute; display: block; width: 165%; max-width: none; height: auto;
  left: calc(var(--fx, .5) * -65%); top: calc(var(--fy, 0) * -65%);
  border: 0; border-radius: 0; box-shadow: none;
  -webkit-mask-image: none; mask-image: none;
}
.card > .appshot { border-radius: var(--radius-m); box-shadow: none; }
/* In a card with a visual the frame is crisp: a dark shot fading into a light
   card turns grey, so the fade the theme puts on that image is not used. */
.card-visual .appshot { border-radius: 10px; box-shadow: var(--shadow-l); }
/* An integration with a line of text under its name: logo on top. */
.integration--stack { flex-direction: column; align-items: flex-start !important; gap: 18px; }
.integration--stack h4 { margin: 0 0 6px !important; }
/* Room for the card's text above its crisp screenshot. */
@media (min-width: 901px) { .card:has(.card-visual .appshot) { min-height: 500px; } }
/* The provider's logo stands on the card itself, with no chip around it. */
.integration--stack .int-logo {
  width: auto; height: 34px; max-width: 170px; padding: 0;
  background: none; border: 0; border-radius: 0;
  object-fit: contain; object-position: left center;
}
