@import './tokens.css';

/* ──────────────────────────────────────────────────────────────────────
 * Brand immersive — Apple-style pinned scroller
 *
 * Opt-in module for case studies that want a long, full-bleed brand
 * gallery. Pair with js/cs-brand-immersive.js. The page must include
 * both this stylesheet and the script — main.js does NOT auto-wire it.
 *
 * Core mechanic:
 *   - .cs-brand-immersive is a tall (8 × 100vh) container that the JS
 *     pins via fixed positioning while it's in view, paging through
 *     .cs-brand-immersive-image children as the user scrolls.
 *   - Slide 2 (.cs-brand-immersive-slide--suisse) is a kinetic Suisse
 *     specimen rendered via .cs-suisse markup — see below.
 * ────────────────────────────────────────────────────────────────────── */
.cs-brand-immersive {
  position: relative;
  height: 560vh; /* 4 slides × ~140vh dwell each — slower scroll so the
                    stateful slides (Suisse, badge, palette) have room to
                    read through their phases. */
  margin: var(--space-16) calc(-1 * var(--space-12));
  background: #000;
}

/* Gallery variant — image-only slides, faster dwell. Height = N × 100vh
 * for N slides. Override per-page via inline style if a different count
 * is needed. */
.cs-brand-immersive--gallery {
  height: 800vh; /* 8 image slides × 100vh — image-only, no stateful phases */
}

/* Video variant — single-slide pinned video. No phases to walk through,
 * so it gets roughly half the scroll travel of the stateful default. */
.cs-brand-immersive--video {
  height: 280vh;
}

.cs-brand-immersive-stage {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 100vh;
  overflow: hidden;
  background: #000;
}

.cs-brand-immersive.is-pinned .cs-brand-immersive-stage {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  width: 100%;
}

.cs-brand-immersive.is-past .cs-brand-immersive-stage {
  position: absolute;
  top: auto;
  bottom: 0;
}

.cs-brand-immersive-image {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  opacity: 0;
  transform: scale(1.08);
  transition:
    opacity 800ms cubic-bezier(0.22, 1, 0.36, 1),
    transform 1600ms cubic-bezier(0.22, 1, 0.36, 1);
  will-change: opacity, transform;
  /* Inactive slides are invisible (opacity 0) but still occupy the same
   * absolute box; without this, later siblings intercept clicks meant for
   * the active slide's interactive content (e.g. the badge-slide chips). */
  pointer-events: none;
}

.cs-brand-immersive-image.is-active {
  opacity: 1;
  transform: scale(1);
  pointer-events: auto;
}

.cs-brand-immersive-image:has(.cs-brand-immersive-video) {
  background: var(--color-surface-page);
}

.cs-brand-immersive-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  padding: var(--space-12);
  box-sizing: border-box;
  background: var(--color-surface-page);
  object-fit: contain;
  object-position: center;
  transform: scale(calc(1 + var(--bi-prog, 0) * 0.09));
  transform-origin: center center;
  filter: blur(var(--bi-blur, 0px));
  will-change: transform, filter;
}

.cs-brand-immersive-overlay {
  position: absolute;
  inset: 0;
  pointer-events: none;
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  padding: var(--space-12) var(--space-16);
  color: var(--color-text-inverse);
  z-index: 10;
}

.cs-brand-immersive-overlay::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at center, rgba(0,0,0,0) 55%, rgba(0,0,0,0.22) 115%);
  opacity: var(--bi-prog, 0);
  pointer-events: none;
}

.cs-brand-immersive-caption {
  position: relative;
  max-width: 520px;
  font-family: "Suisse Int'l Book", Inter, sans-serif;
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  letter-spacing: var(--letter-spacing-body);
  font-weight: var(--font-book);
  transition: opacity 500ms cubic-bezier(0.22, 1, 0.36, 1),
              transform 700ms cubic-bezier(0.22, 1, 0.36, 1);
}

.cs-brand-immersive-caption.is-leaving {
  opacity: 0;
  transform: translateY(8px);
}

.cs-brand-immersive-counter {
  position: relative;
  font-family: "Suisse Int'l Book", Inter, sans-serif;
  font-variant-numeric: tabular-nums;
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  letter-spacing: var(--letter-spacing-body);
  font-weight: var(--font-book);
  align-self: flex-end;
}

.cs-brand-immersive-counter .dim {
  opacity: 0.55;
  margin-left: 4px;
}

.cs-brand-immersive-progress {
  position: fixed;
  bottom: 0;
  left: 0;
  height: 4px;
  width: 0;
  /* Hardcoded #000 / #fff (not tokens) because the indicator's contrast
   * is bound to the SLIDE'S background (which is mostly hardcoded too:
   * white video field, light Suisse specimen, brand-red badge), not the
   * page theme. In dark mode --color-text-heading flips to white, which
   * would invert the contrast on both light slides. */
  background: #000;
  transition: width 120ms linear, background-color 280ms ease;
  z-index: 50;
  pointer-events: none;
  opacity: 0;
}

/* Show ONLY while the immersive is pinned. The earlier rule also lit the
 * bar in .is-past, which meant the prototype-video immersive (top of page)
 * left a stale full-width bar painted at the bottom of the viewport for
 * the rest of the scroll — overlapping the brand immersive's bar lower
 * down and creating color/width conflicts. */
.cs-brand-immersive.is-pinned .cs-brand-immersive-progress {
  opacity: 1;
}

/* Color flips with the active slide's background so it always contrasts.
 * Only the badge slide is dark (brand red), so it's the lone override. */
.cs-brand-immersive:has(.cs-brand-immersive-slide--badge.is-active) .cs-brand-immersive-progress {
  background: #fff;
}

/* Hide dark-mode toggle while the immersive is pinned — a fixed-position
 * overlay (chrome) competes for attention with the full-bleed imagery. */
body.is-brand-immersive-pinned .theme-toggle {
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms ease;
}

/* Match the .cs-page padding step-down at ≤768px so the immersive's
 * negative-margin bleed-out doesn't overshoot the viewport edge. The
 * .cs-page goes from var(--space-12) to var(--space-6) horizontal
 * padding at this breakpoint — without this rule the immersive (and
 * the standalone .cs-suisse below) would push 24px past the viewport
 * on each side, causing horizontal page scroll. */
@media (max-width: 768px) {
  .cs-brand-immersive {
    margin: var(--space-12) calc(-1 * var(--space-6));
  }
}

@media (max-width: 720px) {
  .cs-brand-immersive-overlay {
    padding: var(--space-5) var(--space-6);
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-3);
  }
  .cs-brand-immersive-caption {
    font-size: var(--font-size-small);
    line-height: var(--line-height-small);
    letter-spacing: var(--letter-spacing-small);
  }
  .cs-brand-immersive-counter {
    font-size: var(--font-size-caption);
    line-height: var(--line-height-caption);
    letter-spacing: var(--letter-spacing-caption);
  }
}

@media (max-width: 480px) {
  .cs-brand-immersive-overlay {
    padding: var(--space-4);
    gap: var(--space-2);
  }
}

@media (prefers-reduced-motion: reduce) {
  .cs-brand-immersive-image {
    transition: opacity 200ms linear, transform 200ms linear;
  }
}

/* ──────────────────────────────────────────────────────────────────────
 * Suisse kinetic specimen
 * Self-contained block: a word morphs through the family's cuts while a
 * canvas behind it draws live type-metric rules (cap, x, baseline, desc).
 * Initialised by initSuisseSpecimen() in main.js — no inline script.
 * Styles live here because the specimen is currently only used inside
 * slide 2 of the brand immersive.
 * ────────────────────────────────────────────────────────────────────── */
.cs-suisse {
  position: relative;
  height: 100vh;
  margin: var(--space-16) calc(-1 * var(--space-12));
  overflow: hidden;
  cursor: pointer;
  user-select: none;
  background: var(--color-surface-page);
}

/* Match the .cs-page padding step-down (see immersive container note). */
@media (max-width: 768px) {
  .cs-suisse {
    margin: var(--space-12) calc(-1 * var(--space-6));
  }
}

/* Slide-embedded variant — the specimen lives inside slide 2 of the
   .cs-brand-immersive scroller. Reset the standalone layout so it fills
   the slide's absolute box, paint the lightest gray background, and let
   the immersive's own caption + counter act as the slide's chrome. */
.cs-brand-immersive-slide--suisse {
  background: var(--color-surface-secondary) !important;
}

/* The default slide uses scale(1.08) → scale(1) on activation, which is
   great for hero imagery but throws the canvas-drawn type-metric guides
   out of alignment (the canvas buffer is sized once at init and the
   transform doesn't trigger ResizeObserver). Override to no transform
   for this slide — the opacity fade alone is enough on a typographic
   stage. */
.cs-brand-immersive-slide--suisse,
.cs-brand-immersive-slide--suisse.is-active {
  transform: none !important;
}

.cs-suisse--in-slide {
  position: absolute;
  inset: 0;
  height: 100%;
  margin: 0;
  background: var(--color-surface-secondary);
  cursor: default;
}

/* .cs-suisse-foot inside an immersive slide uses the shared chip-row
 * positioning at the bottom of the viewport — see the shared block. */

.cs-brand-immersive-stage:has(.cs-brand-immersive-slide--suisse.is-active) .cs-brand-immersive-overlay::before {
  display: none;
}
.cs-brand-immersive-stage:has(.cs-brand-immersive-slide--suisse.is-active) .cs-brand-immersive-caption,
.cs-brand-immersive-stage:has(.cs-brand-immersive-slide--suisse.is-active) .cs-brand-immersive-counter {
  color: var(--color-text-primary);
}
.cs-brand-immersive-stage:has(.cs-brand-immersive-slide--suisse.is-active) .cs-brand-immersive-counter .dim {
  color: var(--color-text-tertiary);
  opacity: 1;
}

.cs-suisse-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.cs-suisse-stage {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  pointer-events: none;
}

.cs-suisse-word {
  position: relative;
  z-index: 2;
  font-family: 'Suisse Int\'l Book', Inter, sans-serif;
  font-weight: 450;
  font-style: normal;
  /* Lower min so 9–10-letter words ("Stretching") don't clip on 375px
   * phones — the parent has overflow:hidden so they would otherwise be
   * silently truncated. */
  font-size: clamp(48px, 14vw, 240px);
  line-height: 0.9;
  letter-spacing: -0.05em;
  color: var(--color-text-heading);
  white-space: nowrap;
  will-change: transform;
  transform-origin: 50% 60%;
}

.cs-suisse-word .cs-suisse-letter {
  display: inline-block;
  position: relative;
  will-change: transform, opacity, filter;
  transition:
    transform 420ms cubic-bezier(.6,.05,.05,1),
    opacity   320ms cubic-bezier(.6,.05,.05,1),
    filter    420ms cubic-bezier(.6,.05,.05,1);
}

.cs-suisse-word .cs-suisse-letter.is-out {
  transform: translateY(-0.18em) scale(0.92);
  opacity: 0;
  filter: blur(14px);
}

.cs-suisse-word .cs-suisse-letter.is-in {
  transform: translateY(0.18em) scale(1.04);
  opacity: 0;
  filter: blur(14px);
}

.cs-suisse-ghost {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  pointer-events: none;
  z-index: 1;
}

.cs-suisse-ghost .cs-suisse-word {
  opacity: 0;
}

.cs-suisse-ghost .cs-suisse-word.is-ghosting {
  animation: csSuisseGhostDrift 560ms cubic-bezier(.4,0,.2,1) forwards;
}

@keyframes csSuisseGhostDrift {
  0%   { opacity: 0.18; transform: translateY(0)      scale(1);    filter: blur(0); }
  100% { opacity: 0;    transform: translateY(-0.06em) scale(1.02); filter: blur(18px); }
}

.cs-suisse-meta {
  position: absolute;
  top: var(--space-12);
  right: var(--space-16);
  z-index: 3;
  max-width: 220px;
  text-align: right;
  font-family: 'Suisse Int\'l Book', Inter, sans-serif;
  pointer-events: none;
}

.cs-suisse-meta-eyebrow {
  font-weight: var(--font-light);
  font-size: var(--font-size-caption);
  line-height: var(--line-height-caption);
  letter-spacing: var(--letter-spacing-caption);
  color: var(--color-text-tertiary);
  margin-bottom: var(--space-3);
}

.cs-suisse-meta-name {
  font-weight: var(--font-semi-bold);
  font-size: var(--font-size-h3);
  line-height: var(--line-height-h3);
  letter-spacing: var(--letter-spacing-h3);
  color: var(--color-text-heading);
  margin-bottom: var(--space-2);
  transition: opacity 280ms ease;
}

.cs-suisse-meta-style {
  font-weight: var(--font-light);
  font-size: var(--font-size-small);
  line-height: var(--line-height-small);
  color: var(--color-text-secondary);
  transition: opacity 280ms ease;
}

.cs-suisse-meta-divider {
  height: 1px;
  background: var(--color-border-default);
  margin: var(--space-4) 0;
  transform-origin: right center;
  animation: csSuisseRailSweep 2400ms cubic-bezier(.6,.05,.05,1) infinite;
}

@keyframes csSuisseRailSweep {
  0%   { transform: scaleX(0); }
  55%  { transform: scaleX(1); }
  100% { transform: scaleX(0); transform-origin: left center; }
}

.cs-suisse-meta-num {
  font-weight: var(--font-light);
  font-size: var(--font-size-caption);
  line-height: var(--line-height-caption);
  letter-spacing: var(--letter-spacing-caption);
  color: var(--color-text-tertiary);
  font-variant-numeric: tabular-nums;
}

.cs-suisse-meta-num .cur { color: var(--color-text-heading); }

.cs-suisse-rail {
  position: absolute;
  top: var(--space-6);
  left: var(--space-8);
  z-index: 3;
  width: 1px;
  height: 160px;
  background: var(--color-border-default);
  pointer-events: none;
}

.cs-suisse-rail-fill {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  background: var(--color-text-heading);
  height: 0%;
  transition: height 2200ms linear;
}

.cs-suisse-rail-tick {
  position: absolute;
  left: -6px;
  width: 13px;
  height: 1px;
  background: var(--color-text-heading);
  transition: top 600ms cubic-bezier(.6,.05,.05,1);
}

/* .cs-suisse-foot + .cs-suisse-chip share base styles with .cs-bc-foot/
 * .cs-bp-foot and .cs-bc-chip/.cs-bp-chip — see the shared "Meta panel
 * + chips" block above. */

@media (prefers-reduced-motion: reduce) {
  .cs-suisse-word, .cs-suisse-letter, .cs-suisse-meta-name,
  .cs-suisse-meta-style, .cs-suisse-rail-fill, .cs-suisse-rail-tick,
  .cs-suisse-chip {
    transition: none !important;
  }
  .cs-suisse-ghost .cs-suisse-word.is-ghosting { animation: none; }
  .cs-suisse-meta-divider { animation: none; opacity: 0.5; }
}

/* ──────────────────────────────────────────────────────────────────────
 * Badge construction kinetic specimen
 *
 * Sister slide to the Suisse cuts module. The slide background is the
 * Artpilot brand red (#DB3334 — "Sticker Red" from the brand book); the
 * mark, type, and construction guides render in white.
 *
 * Animation is STATE-DRIVEN — `data-bc-state` on the slide selects one
 * of five rest states. The JS auto-advances through them on a timer,
 * and clicking a chip jumps to that state directly:
 *   grid     → master at scale 2 hero, only verticals/horizontals visible
 *   diag     → grid + diagonals + corner-radius circles
 *   badge    → full construction visible (~peak)
 *   wordmark → master recenters to "Artpilot" lockup, guides fade
 *   lockup   → master recenters to full "Artpilot Delivery" lockup
 * ────────────────────────────────────────────────────────────────────── */
.cs-brand-immersive-slide--badge {
  background: #DB3334 !important;
}
.cs-brand-immersive-slide--badge,
.cs-brand-immersive-slide--badge.is-active {
  transform: none !important;
}

/* On red, drop the gradient scrim and recolor the immersive's caption +
 * counter to white so they read against the brand color. */
.cs-brand-immersive-stage:has(.cs-brand-immersive-slide--badge.is-active) .cs-brand-immersive-overlay::before {
  display: none;
}
.cs-brand-immersive-stage:has(.cs-brand-immersive-slide--badge.is-active) .cs-brand-immersive-caption,
.cs-brand-immersive-stage:has(.cs-brand-immersive-slide--badge.is-active) .cs-brand-immersive-counter {
  color: var(--color-text-inverse);
}
.cs-brand-immersive-stage:has(.cs-brand-immersive-slide--badge.is-active) .cs-brand-immersive-counter .dim {
  color: rgba(255, 255, 255, 0.55);
  opacity: 1;
}

.cs-badge-construct {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: #DB3334;
  font-family: 'Suisse Int\'l Book', Inter, sans-serif;
  --cs-bc-guide: rgba(255, 255, 255, 0.55);
  --cs-bc-mark: #ffffff;
}

.cs-bc-stage {
  position: relative;
  width: min(88vw, 1500px);
  padding: 0 var(--space-12);
}

.cs-bc-svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* Master group — every glyph + the construction overlay live inside.
 *
 * Default state (no [data-bc-state]) is the "pull-focus" incoming pose —
 * the badge starts huge (scale 4), heavily blurred, and fully transparent,
 * as if the camera is positioned inside the mark. When state="badge" fires,
 * scale, blur and opacity all resolve together so the brand snaps into
 * focus at hero size.
 *
 * transform-box: view-box keeps the px values aligned to user-units. */
.cs-bc-master {
  transform-box: view-box;
  transform-origin: 0 0;
  transform: translate(515px, -60px) scale(4);
  filter: blur(40px);
  opacity: 0;
  transition:
    transform 1000ms cubic-bezier(0.16, 1, 0.3, 1),
    filter    900ms cubic-bezier(0.16, 1, 0.3, 1),
    opacity   700ms cubic-bezier(0.16, 1, 0.3, 1);
  will-change: transform, filter, opacity;
}

/* Once any state has been set, the master is in focus. The "filter" +
 * "opacity" reset live on a single rule so they apply across badge →
 * wordmark → lockup without re-blurring on each move. */
.cs-brand-immersive-slide--badge[data-bc-state] .cs-bc-master {
  filter: blur(0);
  opacity: 1;
}

/* Hero rest — badge centered in viewBox, scale 2. */
.cs-brand-immersive-slide--badge[data-bc-state="badge"] .cs-bc-master {
  transform: translate(695px, 105px) scale(2);
}

/* Artpilot lockup centered. Slower settle — this is a "move", not a zoom. */
.cs-brand-immersive-slide--badge[data-bc-state="wordmark"] .cs-bc-master {
  transform: translate(422px, 187.5px) scale(1);
  transition-duration: 1100ms;
  transition-timing-function: cubic-bezier(0.65, 0, 0.32, 1);
}

/* Full lockup centered. */
.cs-brand-immersive-slide--badge[data-bc-state="lockup"] .cs-bc-master {
  transform: translate(48px, 187.5px) scale(1);
  transition-duration: 1100ms;
  transition-timing-function: cubic-bezier(0.65, 0, 0.32, 1);
}

/* ── Construction overlay ──────────────────────────────────────────
 * Strokes use non-scaling-stroke so dash + width values are in CSS px,
 * not user-units. Width 1.4 renders crisp; dash patterns give clean
 * dotted lines with round caps. Visibility is state-driven, with a
 * staggered per-line transition-delay so they sweep in/out elegantly. */
.cs-bc-grid line,
.cs-bc-diag line,
.cs-bc-circ circle {
  fill: none;
  stroke: var(--cs-bc-guide);
  stroke-width: 1.4;
  vector-effect: non-scaling-stroke;
  stroke-linecap: round;
  opacity: 0;
  transition: opacity 280ms ease var(--d, 0ms);
}

.cs-bc-grid line { stroke-dasharray: 1 5; }
.cs-bc-diag line {
  stroke-dasharray: 220;
  stroke-dashoffset: 220;
  transition: opacity 280ms ease var(--d, 0ms),
              stroke-dashoffset 500ms cubic-bezier(0.6, 0.05, 0.05, 1) var(--d, 0ms);
}
.cs-bc-circ circle { stroke-dasharray: 1 4; }

/* Per-line stagger — applied in user-coord order. */
.cs-bc-grid-v line:nth-child(1) { --d: 0ms; }
.cs-bc-grid-v line:nth-child(2) { --d: 60ms; }
.cs-bc-grid-v line:nth-child(3) { --d: 120ms; }
.cs-bc-grid-v line:nth-child(4) { --d: 180ms; }
.cs-bc-grid-v line:nth-child(5) { --d: 240ms; }
.cs-bc-grid-h line:nth-child(1) { --d: 80ms; }
.cs-bc-grid-h line:nth-child(2) { --d: 140ms; }
.cs-bc-grid-h line:nth-child(3) { --d: 200ms; }
.cs-bc-grid-h line:nth-child(4) { --d: 260ms; }
.cs-bc-grid-h line:nth-child(5) { --d: 320ms; }
.cs-bc-grid-h line:nth-child(6) { --d: 380ms; }
.cs-bc-diag line:nth-child(1) { --d: 0ms; }
.cs-bc-diag line:nth-child(2) { --d: 120ms; }
.cs-bc-circ circle:nth-child(1) { --d: 200ms; }
.cs-bc-circ circle:nth-child(2) { --d: 260ms; }
.cs-bc-circ circle:nth-child(3) { --d: 320ms; }

/* Construction overlay — visible only in the "badge" (Mark) state. The
 * per-element transition-delays already give a staggered fade-in/out as
 * the state changes between badge and the lockup states. */
.cs-brand-immersive-slide--badge[data-bc-state="badge"] .cs-bc-grid line {
  opacity: 0.65;
}
.cs-brand-immersive-slide--badge[data-bc-state="badge"] .cs-bc-diag line {
  opacity: 0.7;
  stroke-dashoffset: 0;
}
.cs-brand-immersive-slide--badge[data-bc-state="badge"] .cs-bc-circ circle {
  opacity: 0.7;
}

/* Lock dashoffset at 0 in later states so the diagonals don't un-draw
 * back to the dashed start when leaving the badge state. */
.cs-brand-immersive-slide--badge[data-bc-state="wordmark"] .cs-bc-diag line,
.cs-brand-immersive-slide--badge[data-bc-state="lockup"]   .cs-bc-diag line {
  stroke-dashoffset: 0;
}

/* ── Badge silhouette + wing — solid white, full opacity always ─── */
.cs-bc-frame,
.cs-bc-wing {
  fill: var(--cs-bc-mark);
}

/* ── Wordmark + Delivery letters ──────────────────────────────────── */
.cs-bc-letter {
  fill: var(--cs-bc-mark);
  opacity: 0;
  transition: opacity 360ms cubic-bezier(0.4, 0, 0.1, 1) var(--enter-d, 0ms);
}

/* "Artpilot" letters — visible from "wordmark" state onward, staggered */
.cs-bc-artpilot .cs-bc-letter:nth-child(1) { --enter-d: 200ms; }
.cs-bc-artpilot .cs-bc-letter:nth-child(2) { --enter-d: 280ms; }
.cs-bc-artpilot .cs-bc-letter:nth-child(3) { --enter-d: 360ms; }
.cs-bc-artpilot .cs-bc-letter:nth-child(4) { --enter-d: 440ms; }
.cs-bc-artpilot .cs-bc-letter:nth-child(5) { --enter-d: 520ms; }
.cs-bc-artpilot .cs-bc-letter:nth-child(6) { --enter-d: 600ms; }
.cs-bc-artpilot .cs-bc-letter:nth-child(7) { --enter-d: 680ms; }
.cs-bc-artpilot .cs-bc-letter:nth-child(8) { --enter-d: 760ms; }
.cs-brand-immersive-slide--badge[data-bc-state="wordmark"] .cs-bc-artpilot .cs-bc-letter,
.cs-brand-immersive-slide--badge[data-bc-state="lockup"]   .cs-bc-artpilot .cs-bc-letter {
  opacity: 1;
}

/* "Delivery" letters — visible only from "lockup" state, staggered */
.cs-bc-delivery .cs-bc-letter:nth-child(1) { --enter-d: 240ms; }
.cs-bc-delivery .cs-bc-letter:nth-child(2) { --enter-d: 320ms; }
.cs-bc-delivery .cs-bc-letter:nth-child(3) { --enter-d: 400ms; }
.cs-bc-delivery .cs-bc-letter:nth-child(4) { --enter-d: 480ms; }
.cs-bc-delivery .cs-bc-letter:nth-child(5) { --enter-d: 560ms; }
.cs-bc-delivery .cs-bc-letter:nth-child(6) { --enter-d: 640ms; }
.cs-bc-delivery .cs-bc-letter:nth-child(7) { --enter-d: 720ms; }
.cs-bc-delivery .cs-bc-letter:nth-child(8) { --enter-d: 800ms; }
.cs-brand-immersive-slide--badge[data-bc-state="lockup"] .cs-bc-delivery .cs-bc-letter {
  opacity: 1;
}

/* ── Meta panel + chips ──────────────────────────────────────────────
 * Shared by the badge-construction slide and the brand-palette slide.
 * Both render on a brand-red field, so the styles assume light-on-red. */
.cs-bc-meta,
.cs-bp-meta {
  position: absolute;
  top: var(--space-12);
  right: var(--space-16);
  z-index: 3;
  max-width: 240px;
  text-align: right;
  pointer-events: none;
}

.cs-bc-meta-eyebrow,
.cs-bp-meta-eyebrow {
  font-weight: var(--font-light);
  font-size: var(--font-size-caption);
  line-height: var(--line-height-caption);
  letter-spacing: var(--letter-spacing-caption);
  color: rgba(255, 255, 255, 0.7);
  margin-bottom: var(--space-3);
}

.cs-bc-meta-name,
.cs-bp-meta-name {
  font-weight: var(--font-semi-bold);
  font-size: var(--font-size-h3);
  line-height: var(--line-height-h3);
  letter-spacing: var(--letter-spacing-h3);
  color: var(--color-text-inverse);
  margin-bottom: var(--space-2);
  transition: opacity 280ms ease;
}

.cs-bc-meta-step,
.cs-bp-meta-step {
  font-weight: var(--font-light);
  font-size: var(--font-size-small);
  line-height: var(--line-height-small);
  color: rgba(255, 255, 255, 0.85);
  font-variant-numeric: tabular-nums;
  transition: opacity 280ms ease;
}

.cs-bc-foot,
.cs-bp-foot,
.cs-suisse-foot {
  position: absolute;
  left: 0;
  right: 0;
  bottom: var(--space-12);
  display: flex;
  justify-content: center;
  gap: var(--space-2);
  z-index: 3;
  /* Inactive slides paint on top of earlier ones in document order, so
   * their foot strip would otherwise eat clicks meant for the visible
   * slide below. Only the active slide's foot captures events. */
  pointer-events: none;
  /* Chips fade out faster than the slide's 800ms opacity transition so
   * they don't visibly overlap with the next slide's chip row mid-swap. */
  opacity: 0;
  transition: opacity 220ms ease;
}

.cs-brand-immersive-image.is-active .cs-bc-foot,
.cs-brand-immersive-image.is-active .cs-bp-foot,
.cs-brand-immersive-image.is-active .cs-suisse-foot {
  pointer-events: auto;
  opacity: 1;
  transition-delay: 280ms; /* let the incoming slide settle first */
}

.cs-bc-chip,
.cs-bp-chip,
.cs-suisse-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px 12px;
  border: 1px solid rgba(255, 255, 255, 0.4);
  border-radius: var(--radius-pill);
  font-family: 'Suisse Int\'l Book', Inter, sans-serif;
  font-weight: var(--font-light);
  font-size: var(--font-size-caption);
  letter-spacing: var(--letter-spacing-caption);
  color: rgba(255, 255, 255, 0.75);
  background: transparent;
  cursor: pointer;
  transition: color 220ms ease, border-color 220ms ease, background-color 220ms ease;
  -webkit-appearance: none;
  appearance: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  /* Inactive slides paint on top of earlier slides in document order, so
   * their chip rows would otherwise eat clicks meant for the visible slide
   * below. Only the active slide's chips should be interactive. */
  pointer-events: none;
}

.cs-brand-immersive-image.is-active .cs-bc-chip,
.cs-brand-immersive-image.is-active .cs-bp-chip,
.cs-brand-immersive-image.is-active .cs-suisse-chip {
  pointer-events: auto;
}

.cs-bc-chip:hover,
.cs-bp-chip:hover,
.cs-suisse-chip:hover {
  color: var(--color-text-inverse);
  border-color: rgba(255, 255, 255, 0.7);
}

.cs-bc-chip:focus-visible,
.cs-bp-chip:focus-visible,
.cs-suisse-chip:focus-visible {
  outline: 2px solid var(--color-text-inverse);
  outline-offset: 2px;
}

.cs-bc-chip.is-active,
.cs-bp-chip.is-active,
.cs-suisse-chip.is-active {
  color: #DB3334;
  background: var(--color-text-inverse);
  border-color: var(--color-text-inverse);
}

/* Touch-target compliance — coarse pointers (touchscreen, stylus) get
 * 44×44 hit areas per Apple HIG / WCAG 2.5.5 AAA. The visual pill stays
 * compact via inline-flex centering — only the hit area expands. The
 * gap between siblings stays at var(--space-2) (8px), which combined
 * with 44px targets satisfies WCAG 2.5.8 AA target spacing. */
@media (pointer: coarse) {
  .cs-bc-chip,
  .cs-bp-chip,
  .cs-suisse-chip {
    min-height: 44px;
    min-width: 44px;
    padding: var(--space-2) var(--space-4);
  }
}

@media (max-width: 720px) {
  .cs-bc-meta,
  .cs-bp-meta,
  .cs-suisse-meta {
    top: var(--space-4);
    right: var(--space-4);
    max-width: 140px;
  }
  /* The meta name (H4) is heavier than ideal on a 375px phone where the
   * eyebrow + step lines already carry the chrome. Step it down. */
  .cs-bc-meta-name,
  .cs-bp-meta-name,
  .cs-suisse-meta-name {
    font-size: var(--font-size-small);
    line-height: var(--line-height-small);
    letter-spacing: var(--letter-spacing-small);
  }
  /* Sit the chip row just above the bottom-left overlay caption/counter
   * stack (≈ space-5 padding + ~2 lines × 22px ≈ 64px tall) so chips and
   * overlay don't fight for the same band. */
  .cs-bc-foot,
  .cs-bp-foot,
  .cs-suisse-foot {
    bottom: var(--space-20);
    padding: 0 var(--space-3);
    flex-wrap: wrap;
    justify-content: center;
  }
  /* Drop the desktop max-width clamp and trim padding so the badge
   * SVG renders as large as the slide will allow. The palette stage
   * is overridden again below — it swaps to the mobile HTML layout. */
  .cs-bc-stage,
  .cs-bp-stage {
    box-sizing: border-box;
    width: 100%;
    padding: 0 var(--space-3);
  }

  /* Badge SVG text labels are user-space units; bump so labels read
   * at roughly caption size on a 375px phone. */
  .cs-bp-base-label { font-size: 56px; }
  .cs-bp-base-hex   { font-size: 44px; }
  .cs-bp-tile-name  { font-size: 44px; }
  .cs-bp-tile-hex   { font-size: 40px; }

  /* The vertical rail is decorative — at narrow widths it sits in the
   * margin and its tick label collides with the kinetic word. Hide it
   * rather than scale it down. */
  .cs-suisse-rail { display: none; }

  /* ── Palette: swap SVG for HTML grid on mobile ─────────────────────
   * The 1750×540 SVG is desktop-tuned; on a phone its swatches collapse
   * to slivers and labels become unreadable. Hide the SVG and render
   * the HTML grid in its place. The chip row still drives state via
   * data-bp-state on .cs-brand-immersive-slide--palette — this CSS
   * just keys off that attribute to show the right group(s). */
  .cs-bp-stage { display: none; }

  /* Reserve top space (modest — meta panel hidden on mobile, see below)
   * and bottom space for the chip row + a buffer so the centered
   * content can't slide under either. var(--space-40) clears a chip
   * row at bottom: var(--space-20) plus a comfortable gap. */
  .cs-brand-palette {
    padding: var(--space-12) var(--space-4) var(--space-40);
    box-sizing: border-box;
  }

  /* Hide the meta panel on mobile — the chip row already labels the
   * active state, and the panel was eating top real-estate. */
  .cs-bp-meta { display: none; }

  .cs-bp-mobile {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    width: 100%;
    max-width: 360px;
    margin: 0 auto;
  }

  /* Hide all groups by default; reveal by state. "all" reveals all
   * three so the autoplay sequence has something to show during that
   * beat. The :not([data-bp-state]) fallback shows the base group
   * during the brief gap between slide activation (state machine's
   * reset() removes the attr) and the first autoplay tick — without
   * it the slide renders blank on initial entry. */
  .cs-bp-m-group { display: none; }

  .cs-brand-immersive-slide--palette:not([data-bp-state])      .cs-bp-m-group--base,
  .cs-brand-immersive-slide--palette[data-bp-state="base"]     .cs-bp-m-group--base,
  .cs-brand-immersive-slide--palette[data-bp-state="all"]      .cs-bp-m-group--base,
  .cs-brand-immersive-slide--palette[data-bp-state="scales"]   .cs-bp-m-group--scales,
  .cs-brand-immersive-slide--palette[data-bp-state="all"]      .cs-bp-m-group--scales,
  .cs-brand-immersive-slide--palette[data-bp-state="accents"]  .cs-bp-m-group--accents,
  .cs-brand-immersive-slide--palette[data-bp-state="all"]      .cs-bp-m-group--accents {
    display: grid;
  }

  /* Bases — 2-col grid. Both backgrounds are dark so tile content uses
   * the inverse color via the --dark modifier. Aspect-ratio 2/1 keeps
   * tiles short enough that base + scales + accents all fit when the
   * "all" autoplay state shows everything together. */
  .cs-bp-m-group--base {
    grid-template-columns: 1fr 1fr;
    gap: var(--space-2);
  }
  .cs-bp-m-base {
    aspect-ratio: 2 / 1;
    border-radius: var(--radius-sharp);
    padding: var(--space-3);
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: var(--space-1);
    color: var(--color-text-heading);
  }
  .cs-bp-m-base--dark {
    color: var(--color-text-inverse);
  }
  .cs-bp-m-base-name {
    font-weight: var(--font-semi-bold);
    font-size: var(--font-size-small);
    line-height: var(--line-height-small);
    letter-spacing: var(--letter-spacing-small);
  }
  .cs-bp-m-base-hex {
    font-weight: var(--font-light);
    font-size: var(--font-size-caption);
    line-height: var(--line-height-caption);
    letter-spacing: var(--letter-spacing-caption);
    font-variant-numeric: tabular-nums;
    opacity: 0.75;
  }

  /* Tonal scales — 2 columns of 10 stacked stops. Each stop is a flex
   * row with its weight number on the left and hex on the right. The
   * --dark modifier on darker stops inverts the text color. */
  .cs-bp-m-group--scales {
    grid-template-columns: 1fr 1fr;
    gap: var(--space-2);
  }
  .cs-bp-m-scale {
    display: flex;
    flex-direction: column;
    border-radius: var(--radius-sharp);
    overflow: hidden;
    border: 1px solid rgba(0, 0, 0, 0.08);
  }
  .cs-bp-m-stop {
    flex: 1;
    min-height: 20px;
    padding: 0 var(--space-2);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-1);
    font-weight: var(--font-light);
    font-size: var(--font-size-caption);
    line-height: var(--line-height-caption);
    letter-spacing: var(--letter-spacing-caption);
    font-variant-numeric: tabular-nums;
    color: var(--color-text-heading);
  }
  .cs-bp-m-stop--dark {
    color: var(--color-text-inverse);
  }

  /* Accents — 2×2 grid of pastel tiles. All four backgrounds are light
   * so default heading-color text reads correctly. */
  .cs-bp-m-group--accents {
    grid-template-columns: 1fr 1fr;
    gap: var(--space-2);
  }
  .cs-bp-m-accent {
    aspect-ratio: 2 / 1;
    border-radius: var(--radius-sharp);
    padding: var(--space-3);
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: var(--space-1);
    color: var(--color-text-heading);
  }
  .cs-bp-m-accent-name {
    font-weight: var(--font-semi-bold);
    font-size: var(--font-size-small);
    line-height: var(--line-height-small);
    letter-spacing: var(--letter-spacing-small);
  }
  .cs-bp-m-accent-hex {
    font-weight: var(--font-light);
    font-size: var(--font-size-caption);
    line-height: var(--line-height-caption);
    letter-spacing: var(--letter-spacing-caption);
    font-variant-numeric: tabular-nums;
    opacity: 0.75;
  }
}

@media (max-width: 480px) {
  .cs-bc-meta,
  .cs-bp-meta,
  .cs-suisse-meta {
    max-width: 120px;
  }
  .cs-bc-foot,
  .cs-bp-foot,
  .cs-suisse-foot {
    bottom: var(--space-16);
  }
}

@media (prefers-reduced-motion: reduce) {
  .cs-bc-master,
  .cs-bc-grid line,
  .cs-bc-diag line,
  .cs-bc-circ circle,
  .cs-bc-letter,
  .cs-bp-master,
  .cs-bp-base,
  .cs-bp-scale,
  .cs-bp-office,
  .cs-bp-tile,
  .cs-bp-office-tile {
    transition-duration: 1ms !important;
    transition-delay: 0ms !important;
  }
}

/* ──────────────────────────────────────────────────────────────────────
 * Brand palette kinetic specimen
 *
 * Sister slide to the badge-construction module. Same brand red, same
 * pull-focus entrance vocabulary, same chip-driven state machine — three
 * rest states (Base · Scales · Office) walk through the palette system
 * documented in the brand book's "Base & Variants" page.
 *   base   → two large base swatches (Sticker Red + True Black) centered
 *   scales → bases shrink to scale 1, two tonal columns cascade in
 *   office → master recenters; four office-accent tiles cascade in
 * ────────────────────────────────────────────────────────────────────── */
.cs-brand-immersive-slide--palette {
  background: var(--color-surface-page) !important;
}
.cs-brand-immersive-slide--palette,
.cs-brand-immersive-slide--palette.is-active {
  transform: none !important;
}

/* On white the immersive caption + counter need dark text. */
.cs-brand-immersive-stage:has(.cs-brand-immersive-slide--palette.is-active) .cs-brand-immersive-overlay::before {
  display: none;
}
.cs-brand-immersive-stage:has(.cs-brand-immersive-slide--palette.is-active) .cs-brand-immersive-caption,
.cs-brand-immersive-stage:has(.cs-brand-immersive-slide--palette.is-active) .cs-brand-immersive-counter {
  color: var(--color-text-primary);
}
.cs-brand-immersive-stage:has(.cs-brand-immersive-slide--palette.is-active) .cs-brand-immersive-counter .dim {
  color: var(--color-text-tertiary);
  opacity: 1;
}

.cs-brand-palette {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: var(--color-surface-page);
  font-family: 'Suisse Int\'l Book', Inter, sans-serif;
}

.cs-bp-stage {
  position: relative;
  width: min(88vw, 1500px);
  padding: 0 var(--space-12);
}

/* Mobile-only HTML palette layout — see the @media (max-width: 720px)
 * block above for the layout. Hidden on desktop; the SVG renders.
 * Wrapped in a min-width media query so it doesn't fight the
 * mobile-block's `display: flex` rule on source-order grounds (media
 * queries don't bump specificity, so a later base rule would win). */
@media (min-width: 721px) {
  .cs-bp-mobile { display: none; }
}

.cs-bp-svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* Master group — pull-focus entrance, then 4 centered rest states.
 *
 * Each state ISOLATES one group of swatches centered in the viewBox; the
 * fourth ("all") shows everything. Master translates are derived as
 * (875,270) − scaledCenter for the visible group's natural-coord center.
 *
 *   base    scale 1.6, bases      (natural span x:0..530,    center 265,145)
 *   scales  scale 1.2, tonals+lbl (natural span x:600..1010, center 805,120)
 *   accents scale 1.8, accents    (natural span x:1060..1240,center 1150,120)
 *   all     scale 1.0, everything (natural span x:0..1240,   center 620,120) */
.cs-bp-master {
  transform-box: view-box;
  transform-origin: 0 0;
  transform: translate(80px, -150px) scale(3);
  filter: blur(40px);
  opacity: 0;
  transition:
    transform 1000ms cubic-bezier(0.16, 1, 0.3, 1),
    filter    900ms cubic-bezier(0.16, 1, 0.3, 1),
    opacity   700ms cubic-bezier(0.16, 1, 0.3, 1);
  will-change: transform, filter, opacity;
}

.cs-brand-immersive-slide--palette[data-bp-state] .cs-bp-master {
  filter: blur(0);
  opacity: 1;
}

.cs-brand-immersive-slide--palette[data-bp-state="base"] .cs-bp-master {
  transform: translate(451px, 38px) scale(1.6);
}

.cs-brand-immersive-slide--palette[data-bp-state="scales"] .cs-bp-master {
  transform: translate(-91px, 126px) scale(1.2);
  transition-duration: 1100ms;
  transition-timing-function: cubic-bezier(0.65, 0, 0.32, 1);
}

.cs-brand-immersive-slide--palette[data-bp-state="accents"] .cs-bp-master {
  transform: translate(-1195px, 54px) scale(1.8);
  transition-duration: 1100ms;
  transition-timing-function: cubic-bezier(0.65, 0, 0.32, 1);
}

.cs-brand-immersive-slide--palette[data-bp-state="all"] .cs-bp-master {
  transform: translate(255px, 150px) scale(1);
  transition-duration: 1100ms;
  transition-timing-function: cubic-bezier(0.65, 0, 0.32, 1);
}

/* ── Group visibility — each state isolates one group; "all" shows
 * everything. Group-level opacity + per-element opacity multiply, so the
 * cascade-staggered tiles still play when their group becomes visible. */
.cs-bp-base,
.cs-bp-scale,
.cs-bp-office {
  opacity: 0;
  transition: opacity 320ms ease;
}

.cs-brand-immersive-slide--palette[data-bp-state="base"] .cs-bp-base,
.cs-brand-immersive-slide--palette[data-bp-state="all"]  .cs-bp-base {
  opacity: 1;
}
.cs-brand-immersive-slide--palette[data-bp-state="scales"] .cs-bp-scale,
.cs-brand-immersive-slide--palette[data-bp-state="all"]    .cs-bp-scale {
  opacity: 1;
}
.cs-brand-immersive-slide--palette[data-bp-state="accents"] .cs-bp-office,
.cs-brand-immersive-slide--palette[data-bp-state="all"]     .cs-bp-office {
  opacity: 1;
}

/* ── Base swatches + labels ─────────────────────────────────────── */
.cs-bp-base-label,
.cs-bp-base-hex {
  font-family: 'Suisse Int\'l Book', Inter, sans-serif;
  fill: var(--color-text-heading);
}
.cs-bp-base-label {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.cs-bp-base-hex {
  font-size: 11px;
  font-weight: 300;
  opacity: 0.7;
  font-variant-numeric: tabular-nums;
}

/* ── Tonal + accent tiles ────────────────────────────────────────────
 * Each tile is a <g> wrapping a <rect>, a name <text>, and a hex <text>
 * — name above hex, both sitting beside the swatch. Mirrors the base
 * treatment (name then hex) scaled down to fit a 100×40 swatch row.
 * A subtle stroke on the rect keeps #ffffff tiles distinguishable on
 * the white field. Per-tile opacity drives the cascade stagger when
 * each group fades in. */
.cs-bp-tile-rect,
.cs-bp-office-tile-rect {
  stroke: rgba(0, 0, 0, 0.08);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}

.cs-bp-tile-name,
.cs-bp-tile-hex {
  font-family: 'Suisse Int\'l Book', Inter, sans-serif;
  fill: var(--color-text-heading);
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}

.cs-bp-tile-name {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.cs-bp-tile-hex {
  font-size: 10px;
  font-weight: 300;
  opacity: 0.7;
}

.cs-bp-tile,
.cs-bp-office-tile {
  opacity: 0;
  transition: opacity 320ms cubic-bezier(0.4, 0, 0.1, 1) var(--enter-d, 0ms);
}

.cs-bp-scale .cs-bp-tile:nth-child(1)  { --enter-d: 60ms;  }
.cs-bp-scale .cs-bp-tile:nth-child(2)  { --enter-d: 120ms; }
.cs-bp-scale .cs-bp-tile:nth-child(3)  { --enter-d: 180ms; }
.cs-bp-scale .cs-bp-tile:nth-child(4)  { --enter-d: 240ms; }
.cs-bp-scale .cs-bp-tile:nth-child(5)  { --enter-d: 300ms; }
.cs-bp-scale .cs-bp-tile:nth-child(6)  { --enter-d: 360ms; }
.cs-bp-scale .cs-bp-tile:nth-child(7)  { --enter-d: 420ms; }
.cs-bp-scale .cs-bp-tile:nth-child(8)  { --enter-d: 480ms; }
.cs-bp-scale .cs-bp-tile:nth-child(9)  { --enter-d: 540ms; }
.cs-bp-scale .cs-bp-tile:nth-child(10) { --enter-d: 600ms; }

.cs-bp-office .cs-bp-office-tile:nth-child(1) { --enter-d: 100ms; }
.cs-bp-office .cs-bp-office-tile:nth-child(2) { --enter-d: 180ms; }
.cs-bp-office .cs-bp-office-tile:nth-child(3) { --enter-d: 260ms; }
.cs-bp-office .cs-bp-office-tile:nth-child(4) { --enter-d: 340ms; }

.cs-brand-immersive-slide--palette[data-bp-state="scales"] .cs-bp-tile,
.cs-brand-immersive-slide--palette[data-bp-state="all"]    .cs-bp-tile {
  opacity: 1;
}

.cs-brand-immersive-slide--palette[data-bp-state="accents"] .cs-bp-office-tile,
.cs-brand-immersive-slide--palette[data-bp-state="all"]     .cs-bp-office-tile {
  opacity: 1;
}

/* ── Light-theme chip overrides ──────────────────────────────────────
 * The palette and Suisse slides live on light backgrounds, so the chip
 * row and meta panel that share styles with the (red) badge slide need
 * dark tones here. These rules sit after the shared block to win on
 * source-order specificity (no !important needed). */
.cs-bp-meta-eyebrow {
  color: var(--color-text-tertiary);
}
.cs-bp-meta-name {
  color: var(--color-text-heading);
}
.cs-bp-meta-step {
  color: var(--color-text-secondary);
}

.cs-bp-chip,
.cs-suisse-chip {
  border-color: var(--color-border-default);
  color: var(--color-text-secondary);
}
.cs-bp-chip:hover,
.cs-suisse-chip:hover {
  color: var(--color-text-primary);
  border-color: var(--color-text-tertiary);
}
.cs-bp-chip:focus-visible,
.cs-suisse-chip:focus-visible {
  outline-color: var(--color-text-heading);
}
.cs-bp-chip.is-active,
.cs-suisse-chip.is-active {
  color: var(--color-text-inverse);
  background: var(--color-text-heading);
  border-color: var(--color-text-heading);
}

/* ── Inline mark-loop module ────────────────────────────────────────────
 * Standalone variant of the badge construction. Reuses the same SVG +
 * .cs-bc-* internals as the immersive's badge slide, but renders inline
 * inside a section (not pinned), on the page surface (not brand red),
 * with the mark drawn in heading colour. Auto-cycles Mark → Wordmark →
 * Lockup on a loop; chips remain interactive and pause/restart the cycle. */
.cs-mark-loop {
  width: 100%;
  margin: var(--space-6) 0;
}

.cs-badge-construct--inline {
  position: relative;
  inset: auto;
  display: grid;
  place-items: center;
  background: var(--color-surface-page);
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-sharp);
  height: 480px;
  overflow: hidden;
  --cs-bc-guide: var(--color-border-default);
  --cs-bc-mark: var(--color-text-heading);
}

/* Parallel state machine — mirrors the rules scoped to
 * .cs-brand-immersive-slide--badge[data-bc-state="..."], but keyed off
 * data-bc-state on the inline wrapper itself. The base .cs-bc-master rule
 * (transform/blur/opacity in pre-state) still applies; once any state is
 * set, blur clears and the master moves between rest poses. */
.cs-badge-construct--inline[data-bc-state] .cs-bc-master {
  filter: blur(0);
  opacity: 1;
}
.cs-badge-construct--inline[data-bc-state="badge"] .cs-bc-master {
  transform: translate(695px, 105px) scale(2);
}
.cs-badge-construct--inline[data-bc-state="wordmark"] .cs-bc-master {
  transform: translate(422px, 187.5px) scale(1);
  transition-duration: 1100ms;
  transition-timing-function: cubic-bezier(0.65, 0, 0.32, 1);
}
.cs-badge-construct--inline[data-bc-state="lockup"] .cs-bc-master {
  transform: translate(48px, 187.5px) scale(1);
  transition-duration: 1100ms;
  transition-timing-function: cubic-bezier(0.65, 0, 0.32, 1);
}

/* Construction overlay — visible only on the badge state. */
.cs-badge-construct--inline[data-bc-state="badge"] .cs-bc-grid line {
  opacity: 0.65;
}
.cs-badge-construct--inline[data-bc-state="badge"] .cs-bc-diag line {
  opacity: 0.7;
  stroke-dashoffset: 0;
}
.cs-badge-construct--inline[data-bc-state="badge"] .cs-bc-circ circle {
  opacity: 0.7;
}
.cs-badge-construct--inline[data-bc-state="wordmark"] .cs-bc-diag line,
.cs-badge-construct--inline[data-bc-state="lockup"]   .cs-bc-diag line {
  stroke-dashoffset: 0;
}

/* Wordmark + Delivery letters fade in on their respective states. */
.cs-badge-construct--inline[data-bc-state="wordmark"] .cs-bc-artpilot .cs-bc-letter,
.cs-badge-construct--inline[data-bc-state="lockup"]   .cs-bc-artpilot .cs-bc-letter {
  opacity: 1;
}
.cs-badge-construct--inline[data-bc-state="lockup"] .cs-bc-delivery .cs-bc-letter {
  opacity: 1;
}

/* Chips — invert from the immersive's white-on-red defaults so they read
 * on a light field. Scoped via .cs-badge-construct--inline so the original
 * red-field copies keep their existing styles.
 *
 * The immersive's badge slide also has a top-right meta panel (eyebrow +
 * name + step). The inline variant omits it — what's shown is self-evident
 * from the chip row + the kinetic transformation itself. */

/* Chips: the immersive gates visibility on .cs-brand-immersive-image.is-active.
 * Inline lives outside that scoping, so force the foot strip visible and
 * interactive on its own. */
.cs-badge-construct--inline .cs-bc-foot {
  bottom: var(--space-6);
  opacity: 1;
  pointer-events: auto;
}
.cs-badge-construct--inline .cs-bc-chip {
  pointer-events: auto;
  border-color: var(--color-border-default);
  color: var(--color-text-secondary);
}
.cs-badge-construct--inline .cs-bc-chip:hover {
  color: var(--color-text-primary);
  border-color: var(--color-text-tertiary);
}
.cs-badge-construct--inline .cs-bc-chip:focus-visible {
  outline-color: var(--color-text-heading);
}
.cs-badge-construct--inline .cs-bc-chip.is-active {
  color: var(--color-text-inverse);
  background: var(--color-text-heading);
  border-color: var(--color-text-heading);
}

@media (max-width: 1024px) {
  .cs-badge-construct--inline {
    height: 420px;
  }
}
@media (max-width: 768px) {
  .cs-badge-construct--inline {
    height: 360px;
  }
}
@media (max-width: 480px) {
  .cs-badge-construct--inline {
    height: 280px;
  }
  .cs-badge-construct--inline .cs-bc-foot {
    bottom: var(--space-4);
  }
}
