/* =====================================================================
   PAISTRY Agent & Channel Showcase — styles
   Neutral editorial-publisher look. Tokens copied from Bakery
   (apps/web/src/app/globals.css, :root light + .dark), oklch grayscale.
   Class-based dark mode: `.dark` on <html>.
   ===================================================================== */

:root {
  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --card: oklch(1 0 0);
  --card-foreground: oklch(0.145 0 0);
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  --secondary: oklch(0.97 0 0);
  --secondary-foreground: oklch(0.205 0 0);
  --muted: oklch(0.97 0 0);
  --muted-foreground: oklch(0.556 0 0);
  --accent: oklch(0.97 0 0);
  --accent-foreground: oklch(0.205 0 0);
  --border: oklch(0.922 0 0);
  --input: oklch(0.922 0 0);
  --ring: oklch(0.708 0 0);
  --radius: 0.625rem;
  --kb-accent: #e11d63; /* Kaufberater accent (BILD-red analogue, PAISTRY berry) */
  --font-sans: "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --serif: ui-serif, Georgia, "Times New Roman", serif;
  /* PAI-591 — ONE width for the whole page: header, article and ad units. The
     narrow reading column next to full-width ads read as two different pages
     stacked on each other. */
  --maxw: 72rem;
}

.dark {
  --background: oklch(0.145 0 0);
  --foreground: oklch(0.985 0 0);
  --card: oklch(0.205 0 0);
  --card-foreground: oklch(0.985 0 0);
  --primary: oklch(0.922 0 0);
  --primary-foreground: oklch(0.205 0 0);
  --secondary: oklch(0.269 0 0);
  --secondary-foreground: oklch(0.985 0 0);
  --muted: oklch(0.269 0 0);
  --muted-foreground: oklch(0.708 0 0);
  --accent: oklch(0.269 0 0);
  --accent-foreground: oklch(0.985 0 0);
  --border: oklch(1 0 0 / 10%);
  --input: oklch(1 0 0 / 15%);
  --ring: oklch(0.556 0 0);
}

* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }

body {
  font-family: var(--font-sans);
  background: var(--background);
  color: var(--foreground);
  -webkit-font-smoothing: antialiased;
  line-height: 1.6;
}

code {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.85em;
  background: var(--muted);
  color: var(--muted-foreground);
  padding: 0.08em 0.35em;
  border-radius: 4px;
}

/* ============ Header / control bar ============ */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in oklch, var(--background) 88%, transparent);
  backdrop-filter: saturate(180%) blur(8px);
  border-bottom: 1px solid var(--border);
}
.site-header__inner {
  max-width: 72rem;
  margin: 0 auto;
  padding: 0.65rem 1.25rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  min-width: 0;
}
.brand {
  display: inline-flex;
  align-items: baseline;
  gap: 0.5rem;
  text-decoration: none;
  color: var(--foreground);
}
.brand__logo { font-size: 1.1rem; }
.brand__name {
  font-weight: 700;
  letter-spacing: 0.06em;
  font-size: 1.05rem;
}
.brand__tag {
  font-size: 0.72rem;
  color: var(--muted-foreground);
  letter-spacing: 0.02em;
}
/* PAI-593: the control bar must not push the PAGE sideways. Two selects plus two
   buttons do not fit 390px in one row, and the demo page then scrolled
   horizontally — measured at 633px document width in a 390px viewport, which is
   pre-existing but reads as broken on the article we now show. Wrap, and let the
   selects shrink instead of dictating the width. */
.controls { display: flex; align-items: flex-end; gap: 0.6rem; flex-wrap: wrap; min-width: 0; }
.control { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; }
.control .select { max-width: 100%; }
.control__label {
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted-foreground);
  padding-left: 0.15rem;
}
.select {
  appearance: none;
  font: inherit;
  font-size: 0.85rem;
  color: var(--foreground);
  background: var(--card);
  border: 1px solid var(--input);
  border-radius: calc(var(--radius) - 2px);
  padding: 0.4rem 2rem 0.4rem 0.7rem;
  cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--muted-foreground) 50%),
                    linear-gradient(135deg, var(--muted-foreground) 50%, transparent 50%);
  background-position: calc(100% - 1rem) 55%, calc(100% - 0.7rem) 55%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.select:focus-visible { outline: 2px solid var(--ring); outline-offset: 1px; }

.icon-btn {
  height: 2.1rem;
  width: 2.1rem;
  display: inline-grid;
  place-items: center;
  border: 1px solid var(--input);
  background: var(--card);
  color: var(--foreground);
  border-radius: calc(var(--radius) - 2px);
  cursor: pointer;
  font-size: 1rem;
}
.icon-btn:hover { background: var(--accent); }
.icon-btn__moon { display: none; }
.dark .icon-btn__sun { display: none; }
.dark .icon-btn__moon { display: inline; }

.site-header__status {
  max-width: 72rem;
  margin: 0 auto;
  padding: 0 1.25rem 0.55rem;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.72rem;
}
.pill {
  display: inline-flex;
  align-items: center;
  padding: 0.12rem 0.55rem;
  border-radius: 999px;
  background: var(--primary);
  color: var(--primary-foreground);
  font-weight: 600;
  letter-spacing: 0.01em;
}
.pill--muted { background: var(--muted); color: var(--muted-foreground); }
.status-note { color: var(--muted-foreground); }

/* ============ Article ============ */
.article {
  max-width: var(--maxw);
  margin: 2.5rem auto 4rem;
  padding: 0 1.25rem;
}
.kicker {
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--muted-foreground);
  margin: 0 0 0.5rem;
}
.headline {
  font-family: var(--serif);
  font-size: clamp(1.9rem, 4.5vw, 2.9rem);
  line-height: 1.12;
  letter-spacing: -0.02em;
  margin: 0 0 0.9rem;
}
.standfirst {
  font-size: 1.2rem;
  color: var(--muted-foreground);
  margin: 0 0 1.4rem;
}
.byline {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.85rem;
  color: var(--muted-foreground);
  padding-bottom: 1.4rem;
  border-bottom: 1px solid var(--border);
  margin-bottom: 1.8rem;
}
.byline__avatar {
  height: 2.1rem; width: 2.1rem; border-radius: 999px;
  background: linear-gradient(135deg, var(--muted), var(--accent));
  border: 1px solid var(--border);
}
.article h2 {
  font-family: var(--serif);
  font-size: 1.6rem;
  letter-spacing: -0.01em;
  margin: 2.2rem 0 0.6rem;
}
.article p { margin: 0 0 1.15rem; font-size: 1.06rem; }
.article p em { font-style: italic; color: var(--foreground); }

/* PAI-593 — the two structures the article needs beyond headings and paragraphs.
   Both are set off from the column rather than decorated: an editorial page earns
   its credibility by being quiet. */
.article-list {
  margin: 0 0 1.3rem;
  padding-left: 1.15rem;
  font-size: 1.06rem;
}
.article-list li { margin-bottom: 0.45rem; }
.article-list li::marker { color: var(--kb-accent); }

/* Pull quote: the sentence a reader should carry away. Serif and larger, with a
   rule instead of quotation marks — the text already contains its own. */
.pullquote {
  margin: 1.9rem 0;
  padding: 0.2rem 0 0.2rem 1.2rem;
  border-left: 3px solid var(--kb-accent);
  font-family: var(--serif);
  font-size: 1.32rem;
  line-height: 1.4;
  letter-spacing: -0.01em;
}

/* Placeholder images */
.ph {
  width: 100%;
  border-radius: var(--radius);
  background:
    repeating-linear-gradient(45deg, var(--muted) 0 12px, var(--accent) 12px 24px);
  border: 1px solid var(--border);
  display: grid; place-items: center;
}
.ph--16x9 { aspect-ratio: 16 / 9; }
.ph--4x3 { aspect-ratio: 4 / 3; }
.ph::after { content: "IMG"; color: var(--muted-foreground); font-size: 0.8rem; letter-spacing: 0.2em; }
figure { margin: 0 0 1.6rem; }
figcaption { font-size: 0.78rem; color: var(--muted-foreground); margin-top: 0.4rem; }
.hero { margin-bottom: 1.8rem; }
.inline-figure { max-width: 30rem; }

/* ============ Channel wrappers (demo chrome around loader surfaces) ============ */
.channel-frame {
  margin: 1.8rem 0;
  padding: 0;
}
.channel-frame__label {
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--muted-foreground);
  margin-bottom: 0.5rem;
  display: flex;
  align-items: center;
  gap: 0.4rem;
}
.channel-frame__label::before {
  content: "";
  height: 1px; flex: 0 0 1.4rem;
  background: var(--border);
}
.editorial-note {
  font-size: 0.72rem;
  color: var(--muted-foreground);
  font-style: italic;
  margin-top: 0.4rem;
}

/* Mocked ad slot — full content-column width, IAB Billboard proportions
   (standard Billboard = 970×250; here full column width × 250 to match the
   article measure). Big, impactful in-content unit. */
.ad-slot {
  margin: 2.25rem 0;
  width: 100%;
}
.ad-slot__label {
  font-size: 0.6rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  text-align: right;
  margin-bottom: 0.2rem;
}
.ad-slot__frame {
  width: 100%;
  height: 250px;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  background: var(--card);
  display: block;
  transition: height 0.3s ease;
}
/* Expandable ad: In-Slot mode grows the billboard into a usable chat height. */
.ad-slot--expanded .ad-slot__frame {
  height: min(620px, 80vh);
}
/* Stroodl ad teasers (PAI-581 S2) — real teasers in standard ad formats instead
   of one mocked creative. Each group sits in an .ad-slot, so it keeps the
   "Anzeige" label: the placement is paid even when the advertiser is us.
   Aspect ratios come from CSS, so one image URL serves every format. */
.ad-teaser-row {
  display: grid;
  gap: 1rem;
}
.ad-slot--rects .ad-teaser-row { grid-template-columns: repeat(3, 1fr); }
.ad-slot--category .ad-teaser-row { grid-template-columns: repeat(3, 1fr); }
/* The in-text unit is a single small rectangle, left-aligned rather than
   stretched across the column — a stretched 300×200 stops reading as an ad. */
.ad-slot--small .ad-teaser-row { grid-template-columns: minmax(0, 300px); }

@media (max-width: 720px) {
  /* Phones: one per row. Three 600×300 units side by side would each be ~110px
     wide, which is not an ad format, it is a thumbnail. */
  .ad-slot--rects .ad-teaser-row,
  .ad-slot--category .ad-teaser-row { grid-template-columns: 1fr; }
  .ad-slot--small .ad-teaser-row { grid-template-columns: 1fr; }
}

.ad-teaser {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  background: var(--card);
  min-width: 0;
}
/* 600×300 = 2:1 · 300×200 = 3:2 · category tile = 16:9, matching the row of
   three the ticket's reference showed. */
.ad-slot--rects .ad-teaser__img { aspect-ratio: 2 / 1; }
.ad-slot--small .ad-teaser__img { aspect-ratio: 3 / 2; }
.ad-slot--category .ad-teaser__img { aspect-ratio: 16 / 9; }
.ad-teaser__img { width: 100%; height: auto; object-fit: cover; display: block; }
.ad-teaser__body {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 0.75rem 0.85rem 0.9rem;
}
.ad-teaser__headline {
  font-family: var(--serif);
  font-size: 1.02rem;
  line-height: 1.25;
  margin: 0;
}
.ad-teaser__cta {
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--kb-accent);
}
.ad-teaser.kb-click { cursor: pointer; }
.ad-teaser.kb-click:hover { border-color: var(--kb-accent); }
.ad-teaser.kb-click:focus-visible { outline: 2px solid var(--kb-accent); outline-offset: 2px; }

/* While the in-slot agent is active, lock host scroll: typing inside the
   cross-origin agent iframe otherwise triggers native focus-scroll that yanks
   the (short) in-slot view off screen. Only the in-slot path sets this — the
   full-height overlay and landing surfaces are unaffected. */
html.inslot-lock, html.inslot-lock body { overflow: hidden; }

/* Landing surface — full-bleed stage with ads around the agent embed. */
.landing-stage {
  width: 100vw;
  margin-left: calc(50% - 50vw); /* break out of the article column */
  margin-top: 0.75rem;
  margin-bottom: 2rem;
  padding: 0 clamp(1rem, 4vw, 3rem);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
}
.landing-stage__row {
  display: flex;
  gap: 1rem;
  width: 100%;
  max-width: 1180px;
  align-items: stretch;
}
.landing-frame {
  flex: 1;
  min-width: 0;
  width: 100%;
  height: min(78vh, 860px);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  display: block;
}
/* Mocked surrounding ad slots */
.lad {
  border: 1px dashed var(--border);
  border-radius: 8px;
  background: repeating-linear-gradient(45deg, var(--muted) 0 10px, var(--accent) 10px 20px);
  display: grid;
  place-items: center;
  color: var(--muted-foreground);
  font-size: 0.6rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.lad--top, .lad--bottom { width: 100%; max-width: 1180px; height: 90px; }  /* leaderboards */
.lad--sky { flex: 0 0 160px; align-self: stretch; }                         /* wide skyscrapers */
@media (max-width: 900px) {
  .landing-stage__row .lad--sky { display: none; }
}

/* Inline embedded agent — sized to fit under the sticky header so the whole
   frame (incl. its input) stays on screen; prevents host-page focus-scroll. */
.embed-frame { scroll-margin-top: 6rem; }
.embed-iframe {
  width: 100%;
  height: min(70vh, 820px);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  display: block;
}

/* Dynamic-FAB mock: our own rotating contextual bubble */
.demo-fab {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 2147483000;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.5rem;
}
/* Sit on the left edge of a right-33 overlay (33vw from the right).
   translateX(50%) centers the FAB stack on that seam. */
.demo-fab--sidebar-seam {
  right: 33vw;
  transform: translateX(50%);
  align-items: center;
}
/* Kaufberater: prompt above static icon; left edges aligned. */
.demo-fab--kb {
  align-items: stretch;
  min-width: 12rem;
}
@media (max-width: 640px) {
  .demo-fab--sidebar-seam {
    right: 1.25rem;
    transform: none;
    align-items: flex-end;
  }
  .demo-fab--kb.demo-fab--sidebar-seam {
    align-items: stretch;
  }
}
.demo-fab__bubble {
  max-width: 15rem;
  background: var(--card);
  color: var(--card-foreground);
  border: 1px solid var(--border);
  box-shadow: 0 8px 24px rgb(0 0 0 / 0.14);
  border-radius: 14px 14px 4px 14px;
  padding: 0.6rem 0.8rem;
  font-size: 0.85rem;
  cursor: pointer;
  transition: opacity 0.35s ease, transform 0.35s ease;
}
.demo-fab__bubble[hidden] { display: none; }
.demo-fab__bubble.is-swapping { opacity: 0; transform: translateY(6px); }
/* Cycling prompt — uses the former FAB pill look (clickable). */
.demo-fab__prompt {
  display: block;
  width: 100%;
  box-sizing: border-box;
  margin: 0;
  border: none;
  border-radius: 999px;
  background: var(--primary);
  color: var(--primary-foreground);
  font: inherit;
  font-weight: 600;
  font-size: 0.9rem;
  line-height: 1.3;
  text-align: left;
  padding: 0.75rem 1.1rem;
  cursor: pointer;
  box-shadow: 0 8px 24px rgb(0 0 0 / 0.2);
  transition: opacity 0.35s ease, transform 0.35s ease, filter 0.15s ease;
}
.demo-fab__prompt.is-swapping { opacity: 0; transform: translateY(6px); }
.demo-fab__prompt:hover { filter: brightness(1.08); }
body.swp-demo .demo-fab__prompt {
  background: #05a5c8;
  color: #fff;
}
.demo-fab__btn {
  height: 3.4rem;
  padding: 0 1.15rem 0 0.45rem;
  border-radius: 999px;
  border: none;
  background: var(--primary);
  color: var(--primary-foreground);
  font: inherit;
  font-weight: 600;
  font-size: 0.95rem;
  cursor: pointer;
  box-shadow: 0 8px 24px rgb(0 0 0 / 0.2);
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
}
/* Static Kaufberater icon row — grey, not interactive. */
.demo-fab__btn--static {
  width: 100%;
  box-sizing: border-box;
  justify-content: flex-start;
  background: oklch(0.45 0 0);
  color: #fff;
  cursor: default;
  pointer-events: none;
  user-select: none;
}
.dark .demo-fab__btn--static {
  background: oklch(0.38 0 0);
}
.demo-fab__logo {
  height: 2.5rem;
  width: 2.5rem;
  border-radius: 50%;
  background: #fff;
  object-fit: contain;
  padding: 2px;
  flex: 0 0 auto;
}
.demo-fab__btn:hover { filter: brightness(1.08); }
.demo-fab__btn--static:hover { filter: none; }

/* Agent overlay (ad-slot teaser + Kaufberater teaser).
   Desktop: tall floating panel with an equal vertical gap top and bottom — it
   ends just above the footer height and, using that same inset at the top,
   reaches a bit over the header. Width unchanged, horizontally centered.
   Mobile: full screen. */
.demo-overlay {
  position: fixed;
  top: var(--footer-h, 3.5rem);
  left: 0; right: 0;
  bottom: var(--footer-h, 3.5rem);
  z-index: 2147483200;
  background: rgb(0 0 0 / 0.5);
  display: none;
  align-items: stretch;      /* panel fills the available height */
  justify-content: center;   /* width stays centered */
}
.demo-overlay.is-open { display: flex; }
.demo-overlay__panel {
  width: min(820px, 100%);
  height: 100%;
  background: var(--card);
  border-radius: 16px;
  overflow: hidden;
  position: relative;
  box-shadow: 0 20px 60px rgb(0 0 0 / 0.4);
}
.demo-overlay__frame { width: 100%; height: 100%; border: 0; display: block; }
.demo-overlay__close {
  position: absolute;
  top: 0.75rem; right: 0.75rem;
  height: 2.2rem; width: 2.2rem;
  border-radius: 999px;
  border: none;
  background: var(--primary);
  color: var(--primary-foreground);
  font-size: 1.1rem;
  cursor: pointer;
  z-index: 2;
}
/* Mobile: overlay covers the whole screen. */
@media (max-width: 640px) {
  .demo-overlay { top: 0; bottom: 0; }
  .demo-overlay__panel { width: 100%; border-radius: 0; }
}
/* Full-screen variant (PAI-581 S2) — the ad-teaser entry point. Edge to edge on
   EVERY breakpoint: the inset desktop panel reads as a widget beside the page,
   and a visitor who just clicked into a consultation should have nothing else
   competing. Declared after the mobile rule so it wins on both. */
.demo-overlay--full { top: 0; bottom: 0; }
.demo-overlay--full .demo-overlay__panel {
  width: 100%;
  height: 100%;
  border-radius: 0;
}
/* Kaufberater variant: on desktop the panel spans the SAME horizontal band as
   the page content behind it — i.e. the content box of `.kb` (max-width 72rem
   minus its 1.25rem side padding). Mobile keeps the full-screen rule above. */
@media (min-width: 641px) {
  .demo-overlay--kb .demo-overlay__panel {
    width: min(69.5rem, calc(100% - 2.5rem));
  }
}
/* SWP Kaufberater: right-docked sidebar on desktop; full screen on mobile.
   Absolute docking (not just flex-end) so a wide base panel width can't look
   centered if a stale stylesheet races the JS class. */
.demo-overlay--sidebar {
  top: 0;
  bottom: 0;
  justify-content: flex-end;
  background: rgb(0 0 0 / 0.35);
}
.demo-overlay--sidebar .demo-overlay__panel {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: auto;
  /* Match loader preset right-33 (33vw) — same as paistry-stroodl tenant config. */
  width: 33vw;
  max-width: none;
  height: auto;
  margin: 0;
  border-radius: 0;
  box-shadow: -12px 0 40px rgb(0 0 0 / 0.28);
}
@media (max-width: 640px) {
  .demo-overlay--sidebar .demo-overlay__panel {
    left: 0;
    width: 100%;
    max-width: none;
    box-shadow: none;
  }
}

/* ============ Kaufberater (Produktberater) channel ============ */
.kb {
  max-width: 72rem;
  margin: 0 auto 4rem;
  padding: 0 1.25rem;
}

/* Branded masthead: PAISTRY logo + title. */
.kb-masthead {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 1.6rem 0 1.1rem;
}
.kb-masthead__logo {
  height: 2.6rem; width: 2.6rem;
  border-radius: 12px;
  background: #fff;
  object-fit: contain;
  padding: 3px;
  border: 1px solid var(--border);
  flex: 0 0 auto;
}
.kb-masthead__title {
  font-family: var(--serif);
  font-weight: 700;
  font-size: clamp(1.35rem, 3vw, 1.9rem);
  letter-spacing: -0.01em;
}

/* Banner claim. */
.kb-banner {
  background: var(--kb-accent);
  color: #fff;
  font-weight: 600;
  font-size: clamp(0.95rem, 2vw, 1.15rem);
  text-align: center;
  padding: 0.85rem 1rem;
  border-radius: 10px;
  margin-bottom: 2rem;
}

.kb-kicker {
  display: inline-block;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--kb-accent);
  margin-bottom: 0.4rem;
}

/* Hero: big lead card + side rail. */
.kb-hero {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 1.25rem;
  margin-bottom: 2.6rem;
}
.kb-hero__main { display: flex; flex-direction: column; }
.kb-hero__img { height: clamp(240px, 34vw, 420px); border-radius: 12px; }
.kb-hero__body { padding-top: 0.9rem; }
.kb-hero__headline {
  font-family: var(--serif);
  font-size: clamp(1.5rem, 3.4vw, 2.4rem);
  line-height: 1.12;
  letter-spacing: -0.02em;
  margin: 0;
}
.kb-hero__rail { display: flex; flex-direction: column; gap: 1.25rem; }
.kb-card { display: flex; flex-direction: column; }
.kb-card__img { height: clamp(120px, 16vw, 170px); border-radius: 10px; }
.kb-card__headline {
  font-family: var(--serif);
  font-size: 1.15rem;
  line-height: 1.2;
  margin: 0.6rem 0 0;
}

/* Horizontal gallery: "Aktuelle Produktberater". */
.kb-gallery { margin-bottom: 2.6rem; }
.kb-section-title {
  display: flex;
  align-items: center;
  gap: 1rem;
  font-size: 1.05rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0 0 1rem;
}
.kb-section-title::after {
  content: "";
  flex: 1;
  height: 3px;
  background: var(--kb-accent);
  border-radius: 2px;
}
.kb-gallery__row {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(210px, 1fr);
  gap: 1rem;
  overflow-x: auto;
  padding-bottom: 0.5rem;
  scroll-snap-type: x mandatory;
}
.kb-tile { scroll-snap-align: start; }
.kb-tile__img { height: 140px; border-radius: 10px; }
.kb-tile__headline {
  font-family: var(--serif);
  font-size: 1rem;
  line-height: 1.2;
  margin: 0.55rem 0 0;
}

/* Teaser: image + copy + CTA (carries the product category). */
.kb-teaser {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: 1.5rem;
  align-items: center;
  background: var(--muted);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 1.5rem;
}
.kb-teaser__art { height: clamp(200px, 24vw, 280px); border-radius: 10px; }
.kb-teaser__body h3 {
  font-family: var(--serif);
  font-size: clamp(1.4rem, 3vw, 2rem);
  line-height: 1.15;
  margin: 0.3rem 0 0.6rem;
}
.kb-teaser__body p { color: var(--muted-foreground); margin: 0 0 1.1rem; font-size: 1.02rem; }
.kb-teaser__cta {
  border: none;
  border-radius: 999px;
  background: var(--kb-accent);
  color: #fff;
  font: inherit;
  font-weight: 700;
  font-size: 1rem;
  padding: 0.8rem 1.4rem;
  cursor: pointer;
}
.kb-teaser__cta:hover { filter: brightness(1.08); }

/* Top-teaser hero extras (hook + ONE promise + example-question CTA). */
.kb-hero__text {
  color: var(--muted-foreground);
  font-size: 1.05rem;
  margin: 0.6rem 0 1.1rem;
}
.kb-hero__body .kb-teaser__cta { display: block; }
.kb-hero__how {
  display: block;
  margin-top: 0.7rem;
  padding: 0;
  border: none;
  background: none;
  color: var(--muted-foreground);
  font: inherit;
  font-size: 0.88rem;
  text-decoration: underline;
  cursor: pointer;
}
.kb-hero__how:hover { color: var(--kb-accent); }

/* Question-led teaser sections (seasonal categories). */
.kb-sec { margin-bottom: 2.6rem; }
.kb-badge {
  background: var(--kb-accent);
  color: #fff;
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.22rem 0.6rem;
  border-radius: 999px;
  white-space: nowrap;
}
/* Hotlinked teaser images: 16:9, cover, rounded like the existing tiles.
   Also sizes the .ph fallback swapped in on image error. */
.kb-sec__img {
  width: 100%;
  aspect-ratio: 16 / 9;
  height: auto;
  object-fit: cover;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--muted);
  display: block;
}

/* PAI-522 — AI-disclosure mark on generated imagery (EU AI Act Art. 50(4)).
   .kb-figure is a shrink-wrap positioning context around an image that keeps
   the image itself the sized element, so every card keeps the height its own
   img class gives it. The mark sits bottom-right (subjects sit high in a framed
   photo), stays half-opaque so it never competes with the artwork, and never
   intercepts a click meant for the card. Its meaning lives in .kb-ai-legend. */
.kb-figure { position: relative; display: block; }
.kb-ai {
  position: absolute;
  bottom: 0.3125rem;
  right: 0.3125rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 0.875rem;
  height: 0.875rem;
  border-radius: 999px;
  /* Dark disc + white glyph reads on a photo of any brightness. */
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-size: 0.5rem;
  line-height: 1;
  opacity: 0.5;
  pointer-events: none;
}
/* The footer row is space-between; an auto margin absorbs the free space first,
   so the legend lands against the right-hand group instead of floating in the
   middle as a third evenly-spaced column. */
.kb-ai-legend { white-space: nowrap; margin-left: auto; }

/* Minimal inline modal: "Wie funktioniert der Kaufberater?" */
.kb-modal {
  position: fixed;
  inset: 0;
  z-index: 2147483210; /* above the agent overlay backdrop level */
  display: none;
  place-items: center;
  padding: 1rem;
  background: rgb(0 0 0 / 0.55);
}
.kb-modal.is-open { display: grid; }
.kb-modal__panel {
  position: relative;
  width: 100%;
  max-width: 26rem;
  background: var(--background);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 1.5rem 1.6rem;
  box-shadow: 0 20px 60px rgb(0 0 0 / 0.25);
}
.kb-modal__panel h3 {
  font-family: var(--serif);
  font-size: 1.25rem;
  margin: 0 0 0.8rem;
  padding-right: 2rem;
}
.kb-modal__panel ul { margin: 0; padding-left: 1.2rem; }
.kb-modal__panel li { margin-bottom: 0.45rem; }
.kb-modal__panel li:last-child { margin-bottom: 0; }
.kb-modal__close {
  position: absolute;
  top: 0.6rem;
  right: 0.7rem;
  border: none;
  background: none;
  color: var(--muted-foreground);
  font-size: 1.5rem;
  line-height: 1;
  padding: 0.2rem;
  cursor: pointer;
}
.kb-modal__close:hover { color: var(--foreground); }

/* Clickable cards/teaser → open the agent overlay. */
.kb-click { cursor: pointer; }
.kb-click:hover .kb-hero__headline,
.kb-click:hover .kb-card__headline,
.kb-click:hover .kb-tile__headline,
.kb-hero__headline.kb-click:hover { color: var(--kb-accent); }
/* The hero headline is clickable itself — keep the hit area on the text, not on
   the empty column beside it. */
.kb-hero__headline.kb-click { width: fit-content; }
.kb-click:focus-visible { outline: 2px solid var(--kb-accent); outline-offset: 3px; border-radius: 6px; }
.kb-click .ph { transition: filter 0.2s ease; }
.kb-click:hover .ph { filter: brightness(0.96); }

@media (max-width: 800px) {
  .kb-hero { grid-template-columns: 1fr; }
  .kb-teaser { grid-template-columns: 1fr; }
}

/* ============ Kaufberater SWP (publisher shell showcase) ============ */
/* Tokens from live swp.de screenshots: teal #05a5c8, light white / dark #000. */
.kb-swp {
  --kb-accent: #05a5c8;
  --swp-primary: #05a5c8;
  --swp-primary-dark: #03677d;
  --swp-bg: #ffffff;
  --swp-surface: #ffffff;
  --swp-ink: #000000;
  --swp-muted: #4a4a4a;
  --swp-header-bg: #121212;
  --swp-header-fg: #ffffff;
  --swp-font: "Roboto", ui-sans-serif, system-ui, sans-serif;
  --swp-serif: "Roboto Serif", Georgia, "Times New Roman", serif;
  max-width: none;
  margin: 0 0 4rem;
  padding: 0;
  background: var(--swp-bg);
  color: var(--swp-ink);
  font-family: var(--swp-font);
}
/* Dark mode: pure black behind teasers (not grey), matching swp.de. */
.dark .kb-swp {
  --swp-bg: #000000;
  --swp-surface: #000000;
  --swp-ink: #ffffff;
  --swp-muted: #b0b0b0;
  --swp-header-bg: #0a0a0a;
  --swp-header-fg: #ffffff;
  --swp-primary-dark: #05a5c8;
  background: #000000;
  color: var(--swp-ink);
}
body.swp-demo {
  background: #ffffff;
}
.dark body.swp-demo {
  background: #000000;
}
.dark body.swp-demo .site-footer {
  background: #000000;
  border-top-color: rgb(255 255 255 / 12%);
}

/* SWP top bar — stylized wordmark, no scraped logo assets. */
.swp-header {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  background: var(--swp-header-bg);
  color: var(--swp-header-fg);
  padding: 0.7rem clamp(0.85rem, 3vw, 1.5rem);
  /* Not sticky: DEMO POST controls already occupy sticky top. */
  position: relative;
  z-index: 1;
}
.swp-header__menu {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  width: 2rem;
  height: 2rem;
  padding: 0.35rem;
  border: none;
  background: transparent;
  cursor: default;
  flex: 0 0 auto;
}
.swp-header__menu span {
  display: block;
  height: 2px;
  background: var(--swp-header-fg);
  border-radius: 1px;
}
.swp-header__brand {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  color: inherit;
  text-decoration: none;
  min-width: 0;
}
.swp-header__wordmark {
  font-family: var(--swp-serif);
  font-weight: 700;
  font-size: clamp(0.95rem, 2.4vw, 1.15rem);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.swp-header__badge {
  flex: 0 0 auto;
  display: inline-grid;
  place-items: center;
  width: 1.65rem;
  height: 1.65rem;
  border-radius: 50%;
  background: var(--swp-primary);
  color: #fff;
  font-size: 0.55rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: lowercase;
}
.swp-header__demo {
  margin-left: auto;
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--swp-primary);
  border: 1px solid color-mix(in srgb, var(--swp-primary) 55%, transparent);
  border-radius: 4px;
  padding: 0.2rem 0.45rem;
}

/* Dummy city strip (non-navigating). */
.swp-cities {
  background: var(--swp-header-bg);
  border-top: 1px solid rgb(255 255 255 / 8%);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}
.swp-cities__list {
  list-style: none;
  margin: 0;
  padding: 0.45rem clamp(0.85rem, 3vw, 1.5rem) 0.7rem;
  display: flex;
  gap: 1.1rem;
  white-space: nowrap;
}
.swp-cities a {
  color: var(--swp-header-fg);
  text-decoration: none;
  font-size: 0.82rem;
  font-weight: 500;
  opacity: 0.85;
}
.swp-cities a:hover { opacity: 1; color: var(--swp-primary); }

/* Ad placeholders: banner, skyscraper, fireplace surround. */
.swp-ad {
  border: 1px dashed color-mix(in srgb, var(--swp-primary) 45%, var(--swp-muted));
  background:
    repeating-linear-gradient(
      -45deg,
      color-mix(in srgb, var(--swp-primary) 8%, transparent) 0 8px,
      color-mix(in srgb, var(--swp-surface) 90%, transparent) 8px 16px
    );
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
  color: var(--swp-muted);
  text-align: center;
  padding: 0.5rem;
  box-sizing: border-box;
}
.swp-ad__label {
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--swp-primary-dark);
}
.swp-ad__format {
  font-size: 0.7rem;
  letter-spacing: 0.02em;
}
.swp-ad--banner {
  width: min(970px, calc(100% - 2rem));
  max-width: 970px;
  height: 90px;
  margin: 0.85rem auto;
  border-radius: 4px;
}
.swp-ad--bottom { margin-bottom: 1.5rem; }
.swp-ad--sky {
  flex: 0 0 160px;
  width: 160px;
  min-height: 600px;
  align-self: flex-start;
  position: sticky;
  top: 5.5rem; /* clear DEMO POST sticky header */
  border-radius: 4px;
}

.swp-fireplace {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  width: 100%;
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 clamp(0.75rem, 2vw, 1.25rem) 1rem;
  box-sizing: border-box;
}
.swp-fireplace__main {
  flex: 1;
  min-width: 0;
}
.swp-page-heading {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.35rem;
  margin: 0.2rem 0 1.35rem;
}
.swp-page-kicker {
  color: var(--swp-primary);
  font-family: var(--swp-font);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}
.swp-page-title {
  font-family: var(--swp-font);
  font-weight: 700;
  font-size: clamp(1.5rem, 2.6vw, 1.9rem);
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin: 0;
  color: var(--swp-ink);
}
.swp-page-lead {
  margin: 0 0 1.5rem;
  color: var(--swp-muted);
  font-size: 0.95rem;
  max-width: 40rem;
}

/* Restyle shared .kb-* chrome under SWP (teal accents, Roboto, less BILD). */
.kb-swp .kb-kicker {
  color: var(--swp-primary);
  font-family: var(--swp-font);
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  text-transform: none;
  margin-bottom: 0.35rem;
}
.kb-swp .kb-hero__headline,
.kb-swp .kb-card__headline,
.kb-swp .kb-tile__headline,
.kb-swp .kb-teaser__body h3 {
  font-family: var(--swp-font);
  font-weight: 700;
  color: var(--swp-ink);
  letter-spacing: -0.015em;
  line-height: 1.2;
}
.kb-swp .kb-hero__headline {
  font-size: clamp(1.35rem, 2.6vw, 1.85rem);
  margin: 0 0 0.55rem;
}
.kb-swp .kb-card__headline,
.kb-swp .kb-tile__headline {
  font-size: clamp(1.05rem, 1.6vw, 1.25rem);
  margin: 0 0 0.45rem;
}
.kb-swp .kb-hero__text,
.kb-swp .swp-teaser__text {
  color: var(--swp-muted);
  font-size: 0.95rem;
  line-height: 1.45;
  margin: 0 0 0.85rem;
}
.kb-swp .kb-section-title {
  text-transform: none;
  letter-spacing: -0.01em;
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--swp-ink);
}
.kb-swp .kb-section-title::after { background: var(--swp-primary); }
.kb-swp .kb-badge {
  background: var(--swp-primary);
  border-radius: 2px;
  font-weight: 600;
}
.kb-swp .kb-teaser__cta {
  background: var(--swp-primary);
  color: #fff;
  border-radius: 2px;
  font-family: var(--swp-font);
  font-size: 0.9rem;
  font-weight: 600;
  margin-bottom: 0.85rem;
}

/* Lead teaser: one full-width row (image | copy), matching swp.de.
   Images follow u-base-image__image = 720×405 → 16 / 9. */
.kb-swp .kb-hero--swp-lead {
  display: block;
  margin-bottom: 2rem;
}
.kb-swp .swp-hero {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(15rem, 1fr);
  gap: 1.5rem;
  align-items: end;
  width: 100%;
}
.kb-swp .swp-hero > .kb-figure {
  display: block;
  width: 100%;
  line-height: 0;
}
.kb-swp .swp-hero .kb-hero__img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: 0;
}
.kb-swp .swp-hero .kb-hero__body {
  padding-top: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 0.15rem;
  min-width: 0;
  align-self: end;
}
.kb-swp .swp-hero .kb-hero__text {
  font-size: 0.95rem;
  line-height: 1.45;
  margin: 0 0 0.9rem;
  max-width: 32rem;
}
.kb-swp .swp-hero .kb-teaser__cta {
  display: inline-flex;
  align-items: center;
  width: fit-content;
  max-width: 100%;
  padding: 0.65rem 0.95rem;
  margin: 0 0 0.55rem;
  white-space: normal;
  text-align: left;
  line-height: 1.25;
  font-size: 0.88rem;
}
.kb-swp .swp-hero .kb-hero__how {
  align-self: flex-start;
  margin-bottom: 0;
  font-size: 0.9rem;
}
.kb-swp .swp-deals { margin-bottom: 2.4rem; }
.kb-swp .swp-teaser--placeholder {
  opacity: 0.72;
  pointer-events: none;
}
.kb-swp .swp-teaser__ph {
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 0;
  min-height: 0;
}

/* 3-column teaser grid — 16:9 images like swp.de u-base-image__image */
.kb-swp .swp-teaser-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.75rem 1.25rem;
  margin: 0 0 0.25rem;
}
.kb-swp .swp-teaser {
  display: flex;
  flex-direction: column;
  background: transparent;
  min-width: 0;
}
.kb-swp .swp-teaser .kb-sec__img,
.kb-swp .swp-teaser .kb-tile__img,
.kb-swp .swp-teaser .kb-card__img,
.kb-swp .swp-teaser .kb-figure {
  width: 100%;
}
.kb-swp .swp-teaser .kb-sec__img,
.kb-swp .swp-teaser .kb-tile__img,
.kb-swp .swp-teaser .kb-card__img {
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: 0;
}
.kb-swp .kb-hero__img,
.kb-swp .kb-card__img,
.kb-swp .kb-tile__img,
.kb-swp .kb-sec__img,
.kb-swp .kb-teaser__art {
  border-radius: 0;
}
.kb-swp .swp-teaser__body {
  display: flex;
  flex-direction: column;
  padding-top: 0.75rem;
  flex: 1;
}
.kb-swp .swp-teaser__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: auto;
  padding-top: 0.35rem;
}
.kb-swp .swp-teaser__foot:not(:has(.swp-deal)) {
  justify-content: flex-end;
}
.kb-swp .swp-deal {
  display: inline-block;
  background: var(--swp-primary);
  color: #fff;
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1;
  padding: 0.35rem 0.5rem;
  border-radius: 2px;
}
.kb-swp .swp-bookmark {
  color: var(--swp-muted);
  display: inline-flex;
  opacity: 0.85;
}

.kb-swp .kb-click:hover .kb-hero__headline,
.kb-swp .kb-click:hover .kb-card__headline,
.kb-swp .kb-click:hover .kb-tile__headline,
.kb-swp .kb-hero__headline.kb-click:hover {
  color: var(--swp-primary);
}
.kb-swp .kb-click:focus-visible {
  outline-color: var(--swp-primary);
}
.kb-swp .kb-hero__how {
  color: var(--swp-muted);
}
.kb-swp .kb-hero__how:hover { color: var(--swp-primary); }

@media (max-width: 1100px) {
  .swp-fireplace .swp-ad--sky { display: none; }
  .swp-fireplace { padding-left: 1rem; padding-right: 1rem; }
  .kb-swp .swp-teaser-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 800px) {
  .kb-swp .swp-hero { grid-template-columns: 1fr; }
  .kb-swp .swp-teaser-grid { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .swp-ad--banner { height: 70px; width: calc(100% - 1.5rem); }
  .swp-header__wordmark { font-size: 0.9rem; }
}

/* ============ Footer ============ */
.site-footer {
  border-top: 1px solid var(--border);
  margin-top: 3rem;
}
.site-footer__inner {
  max-width: 72rem;
  margin: 0 auto;
  padding: 1.4rem 1.25rem;
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  font-size: 0.78rem;
  color: var(--muted-foreground);
}
.muted { color: var(--muted-foreground); }

@media (max-width: 640px) {
  .brand__tag { display: none; }
  .site-header__inner { gap: 0.6rem; }
}

/* PAI-599 (Kai, 2026-07-30): on a phone the sticky header took half the screen
   — it wraps onto three rows and never gets out of the way. Two changes, both
   phone-only:
     1. it stays ONE row (the status line and the nav wrap out of existence),
     2. it SLIDES AWAY while scrolling down and comes back on the way up —
        the pattern every mobile news site uses, so it costs no explanation.
   `data-scrolled-down` is set by demo-shell; without JS the header simply
   stays put, which is the safe failure. */
@media (max-width: 700px) {
  .site-header__inner {
    flex-wrap: nowrap;
    padding: 0.45rem 1rem;
  }
  .site-header__status { display: none; }
  .site-header {
    transition: transform 220ms ease;
    will-change: transform;
  }
  .site-header[data-scrolled-down="true"] {
    transform: translateY(-100%);
  }
}
@media (prefers-reduced-motion: reduce) {
  .site-header { transition: none; }
}

/* PAI-593 — the article's own imagery, swapped in for the grey placeholders by
   demo-shell. Same rounding and ratios the placeholders had, so the page does
   not reflow when they load. */
.article-img { border-radius: var(--radius); border: 1px solid var(--border); display: block; }
.article-img--hero { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }
.article-img--inline { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
/* The ✦ wrapper must not collapse the figure it wraps. */
.hero .kb-figure, .inline-figure .kb-figure { display: block; width: 100%; }
