/* ============================================================================
   Shared chrome: container, buttons, navigation, breadcrumbs, footer, the
   sticky mobile call to action.
   ========================================================================== */

.container {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--sp-5);
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  background: var(--navy-900);
  color: #fff;
  padding: var(--sp-3) var(--sp-4);
  border-radius: 0 0 var(--radius-sm) 0;
}
.skip-link:focus {
  left: 0;
}

/* ── Type primitives ───────────────────────────────────────────── */

h1, h2, h3, h4 {
  color: var(--text-heading);
  letter-spacing: var(--display-tracking);
  text-wrap: balance;
}
h1 { font: var(--display-xl); }
h2 { font: var(--display-lg); }
h3 { font: var(--display-md); }
h4 { font: var(--display-sm); }

.kicker {
  font: var(--kicker);
  letter-spacing: var(--kicker-tracking);
  text-transform: uppercase;
  color: var(--signal-500);
  margin-bottom: var(--sp-3);
}

.section {
  padding: var(--section-pad) 0;
}
.section--tint { background: var(--surface-section); }
.section--dark { background: var(--navy-900); color: #C9D7E4; }
.section--dark h2, .section--dark h3 { color: #fff; }
.section--dark .kicker { color: var(--signal-300); }
/* A narrow measure, aligned to the page's OWN left rail rather than centred in
   the viewport. Centring it is what `max-width` plus the container's
   `margin-inline: auto` does by default, and the result is a body of text
   starting 150px to the right of the h1 that introduces it — on /om-oss,
   /entreprenadbesiktning, /fragor-och-svar and every service page at once. It
   reads as a broken template, and it is one declaration.

   The left margin is the container's own offset (0 once the viewport is
   narrower than the container), so the narrow box starts exactly where a
   full-width one would. */
.section--narrow .container {
  max-width: calc(780px + var(--sp-5) * 2);
  margin-inline: max(0px, (100% - var(--container)) / 2) auto;
}

.section-head {
  max-width: 62ch;
  margin-bottom: var(--sp-7);
}
.section-intro {
  font: var(--body-lg);
  color: var(--text-muted);
  margin-top: var(--sp-3);
}
.section-cta {
  margin-top: var(--sp-6);
}
.group-heading {
  font: var(--display-md);
  margin-bottom: var(--sp-5);
}
.empty-note {
  color: var(--text-muted);
  font: var(--body-md);
  padding: var(--sp-6) 0;
}

/* ── Prose ─────────────────────────────────────────────────────────
   The shared stylesheet for rendered markdown outside an article: service
   bodies, audience pages, local pages, project descriptions, FAQ answers.

   The paragraph rhythm comes from the sibling selector below, and the rule
   directly above it zeroes margins with the SAME specificity so source order
   decides. Setting `margin: 0` on `.prose-body p` instead outranks the sibling
   selector and silently removes every paragraph gap on a dozen pages at once —
   which looks perfectly correct in the CMS textarea and like an unbroken wall
   on the page. */

.prose-body > * { margin: 0; }
.prose-body > * + * { margin-top: var(--sp-4); }
.prose-body { font: var(--body-md); color: var(--text-body); max-width: 68ch; }
.prose-body h2 { font: var(--display-md); margin-top: var(--sp-7); }
.prose-body h3 { font: var(--display-sm); margin-top: var(--sp-6); }
.prose-body ul, .prose-body ol { padding-left: var(--sp-5); display: grid; gap: var(--sp-2); }
.prose-body a { color: var(--link); }
.prose-body strong { color: var(--text-heading); font-weight: 600; }
.prose-body blockquote {
  border-left: 3px solid var(--signal-500);
  padding-left: var(--sp-4);
  color: var(--text-muted);
}

/* ── Page heads and the closing CTA band ──────────────────────────
   Shared by the standalone pages AND the Kunskap templates, which load
   blog.css rather than pages.css — so these belong in a sheet every public
   page gets. They lived in pages.css, and the whole /kunskap tree rendered
   its header and its call-to-action band unstyled as a result. */

.page-head {
  background: var(--paper-1);
  border-bottom: 1px solid var(--line-1);
  padding: var(--sp-8) 0;
}
.page-head h1 { max-width: 22ch; }
.page-lead {
  font: var(--body-lg);
  color: var(--text-muted);
  max-width: 62ch;
  margin-top: var(--sp-4);
}
.page-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-top: var(--sp-6);
}

/* ── Photographs ───────────────────────────────────────────────────
   Two generic frames — a wide banner under a page head, and a gallery strip —
   used by the catalogue, audience, local, campaign and project pages today and
   available to any template that grows an image tomorrow. Generic primitives
   go in the sheet every public page loads; this file already carries two
   comments about what happens when one ends up in a page-group sheet instead.

   Both render only when the owner has supplied an image; neither reserves
   space for one. Aspect-ratio rather than a fixed height so the frame is the
   same shape at every width, and object-fit: cover so a portrait upload is
   cropped rather than letterboxed into a grey field. */

.page-banner {
  width: 100%;
  aspect-ratio: 21 / 9;
  object-fit: cover;
  border-radius: var(--radius-md);
  margin-top: var(--sp-8);
}

.photo-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--sp-3);
  margin-top: var(--sp-7);
}
.photo-strip-item {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius-sm);
}

/* ── The empty frame ───────────────────────────────────────────────
   A missing picture renders a grey panel with an image glyph in it, in the
   SAME frame the photograph would have had — the placeholder carries the
   image's own class as well as this one, so it inherits the width, the
   aspect-ratio and the corner radius and cannot drift out of step with it.

   aria-hidden and no text: it is a hole in the page, and announcing "bild
   saknas" to a screen reader would make an absence louder for the people who
   cannot see it than for the people who can. */
.img-placeholder {
  display: grid;
  place-items: center;
  background: var(--paper-1);
  border: 1px dashed var(--line-1);
  color: var(--ink-300);
  /* The glyph's size, since it inherits 1em — set per frame below so a
     full-width banner and a card thumbnail are not marked identically. */
  font-size: 28px;
}
.page-banner.img-placeholder { font-size: 48px; }
.article-hero.img-placeholder,
.proj-hero.img-placeholder { font-size: 40px; }
.team-photo.img-placeholder,
.proj-card-img.img-placeholder,
.post-card-img.img-placeholder { font-size: 24px; }
/* On a dark band the light grey would read as a lit panel rather than as an
   empty one. */
.section--dark .img-placeholder,
.page-head--campaign .img-placeholder {
  background: rgba(255, 255, 255, .05);
  border-color: rgba(255, 255, 255, .15);
  color: rgba(255, 255, 255, .3);
}

.cta-band { background: var(--navy-800); padding: var(--sp-8) 0; }
.cta-band-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-5);
}
.cta-band h2 { color: #fff; }
.cta-band p { font: var(--body-md); color: #8FA6BA; margin-top: var(--sp-2); }
.cta-band-actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.cta-band .btn-ghost { border-color: rgba(255,255,255,.35); color: #fff; }
.cta-band .btn-ghost:hover { background: rgba(255,255,255,.1); }

/* ── Buttons ───────────────────────────────────────────────────────
   6px radius, never pill. .btn-primary is defined ONCE, in theme.css, because
   the backoffice uses it too — a second definition here is what gave the same
   class two different designs depending on which sheets a page loaded. */

.btn-ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  font: var(--label);
  letter-spacing: .01em;
  border-radius: var(--radius-sm);
  padding: 13px var(--sp-5);
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition: background var(--speed) var(--ease), border-color var(--speed) var(--ease), color var(--speed) var(--ease);
}
.btn-ghost {
  background: transparent;
  border-color: var(--navy-300);
  color: var(--navy-700);
}
.btn-ghost:hover { border-color: var(--navy-600); background: var(--navy-100); }
.btn-primary--sm { padding: 9px var(--sp-4); font: var(--body-sm); font-weight: 600; }
.btn-primary--block, .btn-ghost--block { display: flex; width: 100%; }

/* On a dark section the ghost button has to earn its contrast from the light
   side of the palette instead of the dark one. */
.section--dark .btn-ghost,
.page-head--campaign .btn-ghost {
  border-color: rgba(255,255,255,.35);
  color: #fff;
}
.section--dark .btn-ghost:hover,
.page-head--campaign .btn-ghost:hover {
  background: rgba(255,255,255,.1);
  border-color: rgba(255,255,255,.6);
}

/* ── Check lists ───────────────────────────────────────────────── */

.check-list {
  list-style: none;
  display: grid;
  gap: var(--sp-3);
}
.check-list li {
  display: flex;
  gap: var(--sp-3);
  align-items: flex-start;
  font: var(--body-md);
  color: var(--text-body);
}
/* Green, not the signal accent. A checkmark means "included, verified"; the
   signal amber means "look here, something is off". Painting a tick amber makes
   a list of things we CHECK read as a list of things that are WRONG — which on
   an inspector's site is the one misreading that actually costs something. The
   accent stays on kickers, chips and defect markers. */
.check-list iconify-icon {
  flex: 0 0 auto;
  margin-top: 3px;
  color: var(--success);
}
.check-list--dark li { color: #C9D7E4; }
.check-list--dark iconify-icon { color: #4FB380; }

/* ── Navigation ────────────────────────────────────────────────────
   SIX entries plus the call to action, and that number is measured.
   At the 1140px container with 24px of padding a side the bar has 1092px.
   The number that binds is the CONTAINER, not the viewport: moving the
   breakpoint does nothing for a bar that cannot get wider. Re-measure before
   adding a seventh entry or renaming one of the six to something longer. */

.site-nav {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(255,255,255,.92);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line-1);
}
.site-nav-inner {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  min-height: 68px;
}
.site-nav-brand {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  text-decoration: none;
  flex: 0 0 auto;
}
.site-nav-mark {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
  background: var(--navy-700);
  color: #fff;
}
.site-nav-word {
  font: 400 19px/1 var(--font-display);
  letter-spacing: -.01em;
  color: var(--navy-900);
  white-space: nowrap;
}
.site-nav-word strong { font-weight: 600; }

.site-nav-links {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  margin-left: auto;
}
/* A label never breaks mid-phrase — that is what makes the measurement above
   meaningful rather than a guess about where text happens to wrap. */
.site-nav-links a {
  font: var(--body-sm);
  font-weight: 500;
  color: var(--ink-700);
  text-decoration: none;
  white-space: nowrap;
  padding: var(--sp-2) 0;
  border-bottom: 2px solid transparent;
}
.site-nav-links a:hover,
.site-nav-links a[aria-current="page"] {
  color: var(--navy-700);
  border-bottom-color: var(--signal-500);
}
.site-nav-link--mobile { display: none; }

.site-nav-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 2px;
}
.site-nav-menu-toggle {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border: 0;
  background: none;
  color: var(--ink-500);
  cursor: pointer;
  border-radius: 3px;
}
.site-nav-menu-toggle:hover { color: var(--navy-700); background: var(--navy-100); }
.site-nav-item.open .site-nav-menu-toggle { transform: rotate(180deg); }

.site-nav-panel {
  position: absolute;
  top: calc(100% + 14px);
  left: 50%;
  transform: translateX(-50%);
  min-width: 560px;
  background: var(--paper-0);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-raised);
  padding: var(--sp-5);
  z-index: 110;
}
.site-nav-panel[hidden] { display: none; }
.site-nav-panel-inner {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--sp-5);
  padding: 0;
  max-width: none;
}
.site-nav-panel-heading {
  font: var(--kicker);
  letter-spacing: var(--kicker-tracking);
  text-transform: uppercase;
  color: var(--ink-500);
  margin-bottom: var(--sp-3);
}
.site-nav-panel-col ul { list-style: none; display: grid; gap: 2px; }
.site-nav-panel-col a {
  display: block;
  font: var(--body-sm);
  color: var(--ink-700);
  text-decoration: none;
  padding: 6px var(--sp-2);
  border-radius: 4px;
  border-bottom: 0;
  white-space: normal;
}
.site-nav-panel-col a:hover { background: var(--navy-100); color: var(--navy-700); }
.site-nav-panel-all {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font: var(--body-sm);
  font-weight: 600;
  color: var(--navy-700);
  text-decoration: none;
  border-bottom: 0;
}

.site-nav-actions {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  flex: 0 0 auto;
}
.site-nav-phone {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font: var(--body-sm);
  font-weight: 500;
  color: var(--ink-700);
  text-decoration: none;
  white-space: nowrap;
}
.site-nav-phone:hover { color: var(--navy-700); }

.site-nav-burger {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 40px;
  height: 40px;
  border: 0;
  background: none;
  cursor: pointer;
  padding: 0 8px;
}
.site-nav-burger span {
  height: 2px;
  background: var(--navy-900);
  border-radius: 2px;
  transition: transform var(--speed) var(--ease), opacity var(--speed) var(--ease);
}
.site-nav-burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.site-nav-burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.site-nav-burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ── Breadcrumbs ───────────────────────────────────────────────── */

/* White, not the section tint. The page head directly below it is tinted, and
   two stacked bands of the same colour separated by a hairline read as one
   band with a stray rule through it. */
.crumbs {
  border-bottom: 1px solid var(--line-2);
  background: var(--paper-0);
}
.crumbs ol {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3) 0;
  font: var(--body-sm);
}
.crumbs li + li::before {
  content: "/";
  color: var(--ink-300);
  margin-right: var(--sp-2);
}
.crumbs a { color: var(--ink-500); text-decoration: none; }
.crumbs a:hover { color: var(--navy-700); text-decoration: underline; }
.crumbs [aria-current="page"] { color: var(--ink-700); }

/* ── Footer ────────────────────────────────────────────────────── */

.site-footer {
  background: var(--navy-900);
  color: #8FA6BA;
  margin-top: auto;
}
.cert-band {
  border-bottom: 1px solid rgba(255,255,255,.1);
  padding: var(--sp-5) 0;
}
.cert-band-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--sp-7);
}
.cert-band-logo {
  height: 40px;
  width: auto;
  opacity: .85;
  filter: brightness(0) invert(1);
}
.site-footer-inner {
  display: grid;
  grid-template-columns: 1.4fr repeat(4, minmax(0, 1fr));
  gap: var(--sp-6);
  padding: var(--sp-8) var(--sp-5);
}
.site-footer-word {
  font: 400 20px/1 var(--font-display);
  color: #fff;
  text-decoration: none;
  display: inline-block;
  margin-bottom: var(--sp-4);
}
.site-footer-word strong { font-weight: 600; }
.site-footer-brand p { font: var(--body-sm); max-width: 34ch; }
.site-footer-heading {
  font: var(--kicker);
  letter-spacing: var(--kicker-tracking);
  text-transform: uppercase;
  color: #fff;
  margin-bottom: var(--sp-4);
}
.site-footer-col ul { list-style: none; display: grid; gap: var(--sp-2); }
.site-footer-col a, .site-footer-contact li {
  font: var(--body-sm);
  color: #8FA6BA;
  text-decoration: none;
}
.site-footer-col a:hover { color: #fff; }
.site-footer-bottom {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
  justify-content: space-between;
  align-items: center;
  padding: var(--sp-5);
  border-top: 1px solid rgba(255,255,255,.1);
  font: var(--body-sm);
}
.site-footer-bottom a { color: #8FA6BA; }

/* ── Sticky mobile CTA ─────────────────────────────────────────────
   Calling is the highest-intent action a visitor on a phone can take, and it
   must never be behind a hamburger. Hidden on desktop, where the bar already
   carries both. */

.mobile-cta { display: none; }

/* ── Consent banner ────────────────────────────────────────────── */

.consent-banner {
  position: fixed;
  left: var(--sp-4);
  right: var(--sp-4);
  bottom: var(--sp-4);
  z-index: 150;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-4);
  max-width: 720px;
  margin: 0 auto;
  padding: var(--sp-4) var(--sp-5);
  background: var(--paper-0);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-raised);
}
.consent-text { font: var(--body-sm); flex: 1 1 320px; }
.consent-actions { display: flex; gap: var(--sp-3); align-items: center; }
.consent-decline {
  border: 0;
  background: none;
  font: var(--body-sm);
  color: var(--ink-500);
  cursor: pointer;
  text-decoration: underline;
}

/* ── Responsive ────────────────────────────────────────────────────
   The burger takes over at 1140px, and site-nav.js resets the panel at
   1141px — the two numbers must move together. */

@media (max-width: 1140px) {
  .site-nav-links {
    position: fixed;
    inset: 68px 0 auto 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--paper-0);
    border-bottom: 1px solid var(--line-1);
    box-shadow: var(--shadow-card);
    padding: var(--sp-3) var(--sp-5) var(--sp-5);
    max-height: calc(100dvh - 68px);
    overflow-y: auto;
    display: none;
  }
  .site-nav[data-open] .site-nav-links { display: flex; }
  .site-nav-links a {
    padding: var(--sp-4) 0;
    border-bottom: 1px solid var(--line-2);
    font-size: 16px;
  }
  .site-nav-links a[aria-current="page"] { border-bottom-color: var(--signal-500); }
  .site-nav-item { flex-direction: row; justify-content: space-between; }
  .site-nav-item > a { flex: 1; }
  .site-nav-panel {
    position: static;
    transform: none;
    min-width: 0;
    box-shadow: none;
    border: 0;
    border-radius: 0;
    padding: 0 0 var(--sp-4) var(--sp-4);
  }
  .site-nav-item.open { flex-wrap: wrap; }
  .site-nav-item.open .site-nav-panel { flex-basis: 100%; }
  .site-nav-link--mobile { display: flex; align-items: center; gap: var(--sp-2); }
  .site-nav-link--cta {
    margin-top: var(--sp-4);
    background: var(--navy-700);
    color: #fff;
    border-radius: var(--radius-sm);
    justify-content: center;
    border-bottom: 0;
  }
  .site-nav-actions { display: none; }
  .site-nav-burger { display: flex; margin-left: auto; }
}

@media (max-width: 860px) {
  :root { --section-pad: 64px; }
  .site-footer-inner { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 640px) {
  .site-footer-inner { grid-template-columns: 1fr; }
  /* The sticky bar covers the last inch of the page, so the footer needs room
     to clear it — otherwise the copyright line sits permanently underneath. */
  body { padding-bottom: 62px; }
  .mobile-cta {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 120;
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 1px;
    background: var(--line-1);
    border-top: 1px solid var(--line-1);
  }
  .mobile-cta a {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2);
    padding: 16px;
    font: var(--label);
    text-decoration: none;
  }
  .mobile-cta-call { background: var(--paper-0); color: var(--navy-700); }
  .mobile-cta-book { background: var(--navy-700); color: #fff; }
  .consent-banner { bottom: 70px; }
}

/* ── The assistant ─────────────────────────────────────────────────
   A launcher pinned bottom-right and a panel that opens above it. It sits
   under the consent banner (150) and over the sticky mobile CTA (120): a
   visitor who has not yet answered the cookie question should answer that
   first, and a chat panel must never bury the phone number.

   Nothing here is decoration for its own sake. The panel is deliberately
   sober — same navy, same type, same hairlines as the rest of the site — so
   it reads as part of the company rather than as a bolted-on chat product. */

/* Hidden from sight, present for a screen reader. The public sheets had no such
   utility, which is how the assistant's input label shipped as a visible "Din
   fråga" sitting beside the field it labels. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.assistant {
  position: fixed;
  right: var(--sp-5);
  bottom: var(--sp-5);
  z-index: 130;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--sp-3);
}

.assistant-launcher {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 12px 18px;
  font: var(--label);
  color: #fff;
  background: var(--navy-700);
  border: 1px solid var(--navy-800);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-raised);
  cursor: pointer;
  transition: background var(--speed) var(--ease), transform var(--speed) var(--ease);
}
.assistant-launcher:hover { background: var(--navy-800); }
.assistant-launcher:active { transform: translateY(1px); }
.assistant-launcher:focus-visible { outline: none; box-shadow: var(--shadow-raised), var(--focus-ring); }

/* Panel. Ordered bottom-up so the launcher stays where it was when the panel
   opens — a control that moves out from under the cursor as it is clicked is
   the fastest way to make a widget feel broken. */
.assistant-panel {
  order: -1;
  display: flex;
  flex-direction: column;
  width: min(400px, calc(100vw - var(--sp-5) * 2));
  max-height: min(620px, calc(100vh - 140px));
  background: var(--paper-0);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-raised);
  overflow: hidden;
}

.assistant-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  background: var(--navy-700);
  color: #fff;
}
.assistant-title { margin: 0; font: var(--display-sm); letter-spacing: var(--display-tracking); }
.assistant-intro { margin: 4px 0 0; font: var(--body-sm); color: var(--navy-200); }
.assistant-close {
  flex: none;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  color: #fff;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, .25);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.assistant-close:hover { background: rgba(255, 255, 255, .12); }

.assistant-log {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  background: var(--paper-1);
}

.assistant-msg {
  max-width: 90%;
  padding: 10px 14px;
  border-radius: var(--radius-md);
  font: var(--body-sm);
}
.assistant-msg p { margin: 0; }
.assistant-msg p + p { margin-top: var(--sp-2); }
.assistant-msg--bot {
  align-self: flex-start;
  color: var(--ink-700);
  background: var(--paper-0);
  border: 1px solid var(--line-1);
}
.assistant-msg--user {
  align-self: flex-end;
  color: #fff;
  background: var(--navy-600);
}

.assistant-starters { display: flex; flex-direction: column; gap: var(--sp-2); }
.assistant-starter {
  text-align: left;
  padding: 9px 13px;
  font: var(--body-sm);
  color: var(--navy-700);
  background: var(--paper-0);
  border: 1px solid var(--navy-200);
  border-radius: var(--radius-md);
  cursor: pointer;
}
.assistant-starter:hover { background: var(--navy-100); border-color: var(--navy-300); }

/* The conversion. Amber rather than navy because this is the one element in
   the panel that is not conversation — it is the way out of it. */
.assistant-cta {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 10px 16px;
  font: var(--label);
  color: #fff;
  text-decoration: none;
  background: var(--signal-500);
  border-radius: var(--radius-md);
}
.assistant-cta:hover { background: var(--signal-600); }

.assistant-typing { display: flex; gap: 5px; padding: 6px 4px; }
.assistant-typing span {
  width: 6px;
  height: 6px;
  background: var(--ink-300);
  border-radius: 50%;
  animation: assistant-blink 1.2s infinite ease-in-out;
}
.assistant-typing span:nth-child(2) { animation-delay: .18s; }
.assistant-typing span:nth-child(3) { animation-delay: .36s; }
@keyframes assistant-blink {
  0%, 80%, 100% { opacity: .25; }
  40% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .assistant-typing span { animation: none; opacity: .5; }
}

.assistant-error {
  margin: 0;
  font: var(--body-sm);
  color: var(--danger);
}

.assistant-form {
  display: flex;
  align-items: flex-end;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  background: var(--paper-0);
  border-top: 1px solid var(--line-1);
}
.assistant-form textarea {
  flex: 1;
  min-width: 0;
  resize: none;
  padding: 9px 12px;
  font: var(--body-sm);
  color: var(--ink-900);
  background: var(--paper-0);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-md);
}
.assistant-form textarea:focus-visible { outline: none; border-color: var(--navy-400); box-shadow: var(--focus-ring); }
.assistant-send {
  flex: none;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  color: #fff;
  background: var(--navy-700);
  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;
}
.assistant-send:hover { background: var(--navy-800); }
.assistant-send[disabled] { opacity: .45; cursor: default; }

.assistant-note {
  margin: 0;
  padding: 0 var(--sp-4) var(--sp-4);
  font: var(--body-sm);
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-muted);
  background: var(--paper-0);
}

@media (max-width: 860px) {
  /* Clear of the sticky call/book bar, which is the higher-intent control. */
  .assistant { right: var(--sp-4); bottom: 74px; }
  /* Short enough to leave the site header uncovered. The subtrahend is the sum
     of what sits below and above it — the CTA bar, the launcher and its gap,
     the sticky nav, and a little air — measured rather than guessed, because a
     panel that buries the navigation makes the site feel like it has been
     replaced by the widget. dvh so a mobile browser's collapsing toolbar does
     not push the panel under the nav mid-scroll; vh first for anything that
     does not know the unit. */
  .assistant-panel { max-height: calc(100vh - 210px); }
  @supports (height: 100dvh) {
    .assistant-panel { max-height: calc(100dvh - 210px); }
  }
  /* The label is the first thing to go: on a phone the icon plus the panel it
     opens is enough, and a wide pill crowds the bar underneath it. */
  .assistant-launcher-label { display: none; }
  .assistant-launcher { width: 48px; height: 48px; padding: 0; justify-content: center; }
}
