/* ==========================================================================
   EXMP 소개(마케팅) 사이트 — pages/intro/index.html 전용.

   The console's design tokens are reused verbatim (theme-base.css + purple.css +
   dark-mode.css are loaded by theme-injector.js), so this site reads as the same
   family: purple as the brand axis, neutral canvas, shallow shadows.

   INTENTIONAL EXTENSION over the console: the console's heading scale tops out at
   24px, which is too small for a landing hero. A marketing-only DISPLAY scale is
   added below (--ax-display-*). Colors still come from tokens only — no raw hex
   except the brand gradient stops, which are the logo's own values.

   Radius strategy (the key to "same family"): marketing chrome uses the softer
   10-16px radius, but everything inside a console MOCKUP uses the console's own
   tight 3px so the product screenshots look like the real product.
   ========================================================================== */

/* ── Marketing-layer tokens ────────────────────────────────────────────────── */
:root {
  /* Display scale — fluid, marketing only. */
  --ax-display-1: clamp(1.7rem, calc(2.9vw + 2px), 2.85rem);
  --ax-display-2: clamp(1.9rem, 1.1rem + 2.6vw, 43px); /* cap 48px -> 43px (user request 2026-08-25); the fluid floor/slope are unchanged */
  --ax-display-3: clamp(1.4rem, 1rem + 1.4vw, 2rem);
  --ax-lead: clamp(1rem, 0.94rem + 0.28vw, 1.175rem);

  /* Rhythm */
  --ax-shell: 1200px;
  /* The hero breaks out of the shell so the console sample can be read; every other section
     keeps --ax-shell, so the copy still lines up with the sections below on narrow screens. */
  --ax-hero-shell: max(var(--ax-shell), min(1520px, calc(100vw - 112px)));
  --ax-gap: 24px;
  --ax-section-y: clamp(56px, 7.6vw, 100px);

  /* Marketing radius (console keeps its own 3px inside mockups) */
  --ax-r-card: var(--border-radius-radius-xl, 16px);
  --ax-r-chip: var(--border-radius-radius-full, 999px);

  /* Brand gradient — the logo's own stops (assets/images/exmp_logo.svg) */
  --ax-brand-grad: linear-gradient(135deg, var(--primary-400), var(--primary-800));
  --ax-brand-grad-text: linear-gradient(180deg, var(--primary-400), var(--primary-700));

  /* Divider on the always-dark violet surfaces (footer, ANSWER band): primary-mid at 16%. */
  --ax-violet-line: color-mix(in srgb, var(--primary-300) 16%, transparent);

  /* Surfaces derived from console tokens */
  --ax-canvas: var(--background-bg-primary);
  --ax-surface: var(--background-bg-secondary);
  --ax-line: var(--border-border-primary);
  --ax-line-soft: var(--border-border-secondary);
}

/* ── Base ─────────────────────────────────────────────────────────────────── */
*,
*::before,
*::after {
  box-sizing: border-box;
}
html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}
body {
  margin: 0;
  font-family: "Pretendard", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--ax-canvas);
  color: var(--foreground-fg-primary);
  font-size: 16px;
  line-height: 1.6;
  letter-spacing: -0.01em;
  -webkit-font-smoothing: antialiased;
  /* Korean line breaking: the default breaks between Latin and Hangul, splitting words like
     "AI의" across lines. keep-all breaks on spaces only, which is correct for Korean copy. */
  word-break: keep-all;
  overflow-wrap: break-word;
}
img,
svg {
  max-width: 100%;
  display: block;
}
a {
  color: inherit;
  text-decoration: none;
}
h1,
h2,
h3,
h4,
p,
ul,
ol,
figure {
  margin: 0;
}
ul,
ol {
  padding: 0;
  list-style: none;
}
button {
  font: inherit;
  color: inherit;
  cursor: pointer;
}
:focus-visible {
  outline: 2px solid var(--primary-500);
  outline-offset: 2px;
  border-radius: var(--border-radius-radius-xs, 4px);
}
.ax-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.ax-shell {
  width: 100%;
  max-width: var(--ax-shell);
  margin-inline: auto;
  padding-inline: var(--ax-gap);
}

/* ══════════════════════════════════════════════════════════════════════════
   TOP NAV
   ══════════════════════════════════════════════════════════════════════════ */
.ax-nav {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--ax-surface);
  border-bottom: 1px solid var(--ax-line-soft);
}
/* The bar's content tracks the HERO's wider shell (not the 1200px section shell) so the logo
   and the login button line up with the hero card directly below it. */
.ax-nav-inner {
  max-width: var(--ax-hero-shell);
  display: flex;
  align-items: center;
  gap: 20px;
  height: 64px;
}
.ax-logo {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
}
/* Real EXMP logo (assets/images/exmp_logo*.svg), same asset as the console GNB. The SVG is
   121x31, so pin the height and let the width follow; 26px keeps the console's logo-to-bar
   ratio in this taller 64px marketing bar. */
.ax-logo-img {
  display: block;
  height: 26px;
  width: auto;
}
/* Only the wordmark differs between the two files (black vs white); light is the default. */
.ax-logo-img--dark {
  display: none;
}
[data-exmp-mode="dark"] .ax-logo-img--light {
  display: none;
}
[data-exmp-mode="dark"] .ax-logo-img--dark {
  display: block;
}
.ax-logo--foot {
  margin-bottom: 12px;
}
.ax-nav-links {
  display: flex;
  align-items: center;
  gap: 2px;
  margin-left: 8px;
  overflow-x: auto;
  scrollbar-width: none;
}
.ax-nav-links::-webkit-scrollbar {
  display: none;
}
.ax-nav-link {
  padding: 7px 11px;
  border-radius: var(--border-radius-radius-s, 6px);
  font-size: 14px;
  font-weight: 500;
  color: var(--foreground-fg-secondary);
  white-space: nowrap;
  transition: background-color 0.16s ease, color 0.16s ease;
}
.ax-nav-link:hover {
  background: var(--neutral-100);
  color: var(--foreground-fg-primary);
}
/* --neutral-100 is a fixed light gray that is NOT remapped on dark, so the hover plate came out
   near-white under the dark nav and swallowed the label (user report 2026-08-25). Same fix the
   console applies to its LNB hover in dark-mode.css, and the same one .ax-mode-btn below already
   uses — re-point to the dark hover tone so only the background changes, never the text. */
[data-exmp-mode="dark"] .ax-nav-link:hover {
  background: var(--background-bg-hover);
}
/* Active item is marked by text color/weight only — no background plate. */
.ax-nav-link.is-active,
.ax-nav-link.is-active:hover {
  background: none;
  color: var(--foreground-fg-brand);
  font-weight: 600;
}
.ax-nav-right {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
.ax-icon-btn {
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border: 1px solid var(--ax-line);
  border-radius: var(--border-radius-radius-s, 6px);
  background: var(--ax-surface);
  color: var(--foreground-fg-secondary);
  transition: border-color 0.16s ease, color 0.16s ease;
}
.ax-icon-btn:hover {
  border-color: var(--primary-300);
  color: var(--foreground-fg-brand);
}
.ax-mode-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 8px;
  border: 0;
  border-radius: var(--border-radius-radius-s, 6px);
  background: transparent;
  color: var(--foreground-fg-secondary);
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  line-height: 20px;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.15s ease;
}
.ax-mode-btn:hover,
.ax-mode-btn:focus-visible {
  background: var(--neutral-100);
}
/* --neutral-100 is not remapped on dark, so the hover gets the same treatment the console
   applies in dark-mode.css. */
[data-exmp-mode="dark"] .ax-mode-btn:hover,
[data-exmp-mode="dark"] .ax-mode-btn:focus-visible {
  background: var(--background-bg-hover);
}
.ax-mode-ico {
  display: block;
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}
/* Icon shows the mode you switch TO: moon in light, sun in dark. */
.ax-mode-ico--sun {
  display: none;
}
[data-exmp-mode="dark"] .ax-mode-ico--moon {
  display: none;
}
[data-exmp-mode="dark"] .ax-mode-ico--sun {
  display: block;
}
/* GNB login CTA — filled brand on light, filled WHITE on dark (the inverse fill reads as
   the primary action against the dark bar without competing with the purple wordmark). */
/* On dark the border drops to white too, so the pill reads as one solid chip. */
[data-exmp-mode="dark"] /* Kept while the header button is out (see index.html): the console login URL is not decided yet,
   so the markup was removed on 2026-09-01 and these rules wait for it to come back. */
.ax-btn--login {
  background: var(--neutral-white);
  border-color: var(--neutral-white);
  color: var(--neutral-900);
  box-shadow: none;
}
[data-exmp-mode="dark"] .ax-btn--login:hover {
  background: var(--neutral-100);
  border-color: var(--neutral-100);
  color: var(--neutral-900);
}
.ax-nav-toggle {
  display: none;
}

/* ══════════════════════════════════════════════════════════════════════════
   BUTTONS
   ══════════════════════════════════════════════════════════════════════════ */
.ax-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  height: 44px;
  padding: 0 20px;
  border: 1px solid transparent;
  border-radius: var(--border-radius-radius-m, 8px);
  font-size: 15px;
  font-weight: 600;
  white-space: nowrap;
  transition: box-shadow 0.16s ease, background-color 0.16s ease, border-color 0.16s ease,
    color 0.16s ease;
}
.ax-btn--primary {
  background: var(--primary-600);
  color: var(--neutral-white);
  box-shadow: var(--shadow-xs-0);
}
.ax-btn--primary:hover {
  background: var(--button-primary-background-bg-hover);
}
.ax-btn--sm {
  height: 36px;
  padding: 0 14px;
  font-size: 14px;
}
/* The GNB pair: 도입 문의 carries the purple (--primary in both modes) and the login button is
   the white one, so it reads as the quieter of the two on the white bar. */
.ax-btn--login {
  background: var(--neutral-white);
  border-color: var(--ax-line);
  color: var(--neutral-900);
  /* Flat: the hairline border carries it, no drop shadow behind the white pill. */
  box-shadow: none;
}
.ax-btn--login:hover {
  background: var(--button-secondary-background-bg-hover);
  border-color: var(--neutral-300);
  color: var(--neutral-900);
}

/* ══════════════════════════════════════════════════════════════════════════
   TYPOGRAPHY BLOCKS
   ══════════════════════════════════════════════════════════════════════════ */
.ax-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 12px;
  border-radius: var(--ax-r-chip);
  background: var(--background-bg-brand-light);
  color: var(--foreground-fg-brand);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0;
}
.ax-display {
  font-size: var(--ax-display-1);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.035em;
}
.ax-h2 {
  font-size: var(--ax-display-2);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.03em;
}
.ax-lead {
  font-size: var(--ax-lead);
  line-height: 1.7;
  color: var(--foreground-fg-secondary);
}
.ax-grad-text {
  background: var(--ax-brand-grad-text);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
/* The --primary-* ramp is NOT remapped on dark, so this gradient kept bottoming out at
   --primary-700 (#4f33cf) there — only ~2.3:1 over the hero backdrop, and the accent stopped
   reading (user report 2026-08-31). Lift both stops two steps: the DARKEST end is then ~5.3:1,
   and the top ~8:1, so the accent stays legible over the aurora wash as well.
   `background-image`, not the `background` shorthand — the shorthand resets background-clip
   back to border-box and the text would paint as a solid block instead of clipped glyphs. */
[data-exmp-mode="dark"] .ax-grad-text {
  background-image: linear-gradient(180deg, var(--primary-200), var(--primary-400));
}

/* Section header block */
.ax-sec-head {
  display: flex;
  flex-direction: column;
  align-items: flex-start; /* keep inline-flex eyebrows from stretching to the column width */
  gap: 14px;
  max-width: 720px;
  margin-bottom: 44px;
}

/* ══════════════════════════════════════════════════════════════════════════
   SECTION
   ══════════════════════════════════════════════════════════════════════════ */
.ax-section {
  padding-block: var(--ax-section-y);
}
/* WHY only: the mockup compresses this band (56/64 instead of the page's --ax-section-y) so the
   six questions AND the ANSWER band fit one 1080p screen — the point of the whole sequence. */
.ax-section--why {
  padding-block: 56px 64px;
}
.ax-section--alt {
  background: var(--ax-surface);
  border-block: 1px solid var(--ax-line-soft);
}

/* ══════════════════════════════════════════════════════════════════════════
   HERO
   ══════════════════════════════════════════════════════════════════════════ */
.ax-hero .ax-shell {
  max-width: var(--ax-hero-shell);
}
.ax-hero-copy .ax-eyebrow--track {
  padding-top: 30px;
}
.ax-hero {
  position: relative;
  /* One value so the band above the hero card matches the band below it, plus 50px of extra
     breathing room on each side of the hero band (content size unchanged). */
  padding-block: calc(clamp(48px, 6vw, 88px) + 50px);
  overflow: hidden;
}
/* Aurora: very low-saturation purple light sources. Decorative only. */
.ax-hero::before,
.ax-hero::after {
  content: "";
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  opacity: 0.5;
  pointer-events: none;
  z-index: 0;
}
.ax-hero::before {
  width: 520px;
  height: 520px;
  top: -230px;
  left: -120px;
  background: var(--primary-200);
}
.ax-hero::after {
  width: 420px;
  height: 420px;
  top: -160px;
  right: -100px;
  background: var(--semantic-cyan-100, var(--primary-100));
}
.ax-hero > * {
  position: relative;
  z-index: 1;
}
.ax-hero-grid {
  display: grid;
  /* Explicit single track: without it the stacked column is auto-sized to max-content, and
     .ax-hero-copy's 660px max-width made the row 660px wide inside a 342px phone shell — which
     pushed the console right off the screen. */
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(28px, 4vw, 48px);
  align-items: center;
}
.ax-hero-copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 20px;
  max-width: 660px;
}
.ax-hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 4px;
  /* Requested breathing room around the CTAs (on top of the copy column's own 20px gap). */
  padding-block: 80px 30px;
}
/* The hero pair is the page's primary action, so it steps up from the default 44px button. */
.ax-hero-actions .ax-btn {
  height: 52px;
  padding: 0 28px;
  border-radius: var(--border-radius-radius-l, 10px);
  font-size: 16.5px;
}
.ax-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--semantic-green-400);
  flex: none;
}

/* Hero: 2-column (copy | console mockup) from ~980px up */
@media (min-width: 980px) {
  .ax-hero-grid {
    grid-template-columns: minmax(0, 0.45fr) minmax(0, 0.55fr);
  }
  /* The tilted console needs room for the floating cards that hang outside it, so the
     hero row is centre-aligned and the stage keeps its own breathing space. */
  .ax-hero-stage {
    align-self: center;
  }
}
/* Below that breakpoint the hero stacks, so the copy spans the FULL width and runs under the
   top-right aurora. `blur(90px)` spreads roughly 270px past the 420px circle, which put a light
   cyan wash straight over the gradient headline accent — on dark its lower stop (--primary-700)
   nearly matched the washed background and the words stopped reading (user report 2026-08-31).
   Pull the blob smaller, further off-corner, dimmer, and tighten its blur so the spread stops
   short of the copy. The ≥980px two-column layout keeps the original values: there the console
   occupies the right half, so nothing legible sits under it. */
@media (max-width: 979px) {
  .ax-hero::after {
    width: 300px;
    height: 300px;
    top: -200px;
    right: -120px;
    opacity: 0.22;
    filter: blur(70px);
  }
}
/* Letter-spaced plain eyebrow — the hero uses this instead of the chip variant. */
.ax-eyebrow--track {
  display: block;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.14em;
  color: var(--foreground-fg-brand);
}

/* ══════════════════════════════════════════════════════════════════════════
   ROADMAP — horizontal timeline: one rail across the row, a marker centred over
   each phase column, heading centred under the marker, details left-aligned.
   ══════════════════════════════════════════════════════════════════════════ */
.ax-road {
  --road-gap: clamp(20px, 2.4vw, 32px);
  position: relative;
  display: grid;
  /* One column per phase — the 2027 step was folded into 2026년 내 (2026-08-27), so two.
     Keep this in step with the number of .ax-road-step items: a leftover empty column would
     strand the rail (left:0/right:0) past the last marker. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--road-gap);
}
/* One continuous brand rail across the whole row, fading out at both ends so it reads as a
   timeline that carries on rather than a bar with hard stops. The two phases are told apart by
   the MARKERS (see --live / --wip below), not by the line. */
.ax-road::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 10px;
  height: 2px;
  border-radius: 1px;
  background: linear-gradient(
    90deg,
    transparent 0,
    var(--primary-500) 7%,
    var(--primary-500) 93%,
    transparent 100%
  );
}
.ax-road-step {
  position: relative;
  /* Clears the marker so the heading starts below the rail. */
  padding-top: 44px;
}
/* Marker: ring on the rail. The two phases are deliberately different shapes — see the
   --live / --wip rules below. */
.ax-road-step::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 0;
  transform: translateX(-50%);
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--ax-surface);
  border: 2px solid var(--primary-500);
  box-shadow: inset 0 0 0 4px var(--ax-surface), inset 0 0 0 11px var(--primary-500);
}
/* 지금 사용 가능 — a SOLID brand disc with a soft halo: shipped, and the emphasis of the two. */
.ax-road-step--live::before {
  background: var(--primary-500);
  box-shadow: 0 0 0 7px color-mix(in srgb, var(--primary-500) 18%, transparent);
}
/* 2026년 내 — an OPEN dashed ring around a pale core: under construction, not landed yet. */
.ax-road-step--wip::before {
  border-style: dashed;
  border-color: var(--primary-400);
  box-shadow: inset 0 0 0 4px var(--ax-surface), inset 0 0 0 11px var(--primary-200);
}
/* …and it breathes, so "진행 중" reads at a glance. Opt-in like every other motion on this page
   (`.ax-anim`, set by intro.js only when the browser has not asked for reduced motion). */
@keyframes ax-road-wip-pulse {
  0%,
  100% {
    box-shadow: inset 0 0 0 4px var(--ax-surface), inset 0 0 0 11px var(--primary-200),
      0 0 0 0 color-mix(in srgb, var(--primary-500) 26%, transparent);
  }
  60% {
    box-shadow: inset 0 0 0 4px var(--ax-surface), inset 0 0 0 11px var(--primary-300),
      0 0 0 8px color-mix(in srgb, var(--primary-500) 0%, transparent);
  }
}
.ax-anim .ax-road-step--wip::before {
  animation: ax-road-wip-pulse 2.6s ease-in-out infinite;
}
/* Vertical rail segments — only used by the stacked variant below. */
.ax-road-step::after {
  content: none;
}
.ax-road-head {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 20px;
}
.ax-road-head h3 {
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.02em;
}
.ax-road-list {
  display: grid;
  gap: 18px;
}
.ax-road-list li {
  position: relative;
  padding-left: 16px;
  font-size: 15px;
  line-height: 1.65;
  color: var(--foreground-fg-tertiary);
}
.ax-road-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 10px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--neutral-300);
}
.ax-road-list b {
  color: var(--foreground-fg-primary);
  font-weight: 600;
}

/* Under ~860px three phases cannot hold a readable measure — stack them and stand the
   rail back up on the left. The single cross-row rail gives way to one segment per step,
   since its end has to land on the LAST marker rather than the container edge. */
/* Phone: the floating cards would cover the console they annotate.
   NOTE on the selectors: the console's base grid rules live further down this file, so a bare
   `.ax-hc-body--grid` here loses to them on source order even inside the media
   query. Every override is therefore scoped one level deeper (.ax-hc …) to outrank it. */
@media (max-width: 640px) {
  .ax-hero-stage {
    padding: 0;
  }
  .ax-hc-float {
    display: none;
  }
  .ax-hc .ax-hc-body--grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .ax-hc-body--grid > .ax-hc-card {
    grid-area: auto;
  }
  /* The chart and the per-org rails need the full console width — in a half-width cell the
     rails' fixed name/percentage columns eat the whole row and the bar collapses to 0. */
  .ax-hc-body--grid > .ax-hc-gchart,
  .ax-hc-body--grid > .ax-hc-orgs,
  .ax-hc-body--grid > .ax-hc-seats {
    grid-column: 1 / -1;
  }
  .ax-hc-orgs .ax-hc-org {
    grid-template-columns: 72px minmax(0, 1fr) 36px;
    gap: 6px;
  }
  /* Phone: the 한도/사용 amounts drop below the rail rather than squeezing it out. */
  .ax-hc-seats .ax-hc-seat {
    grid-template-columns: 64px minmax(0, 1fr);
    gap: 4px 6px;
  }
  .ax-hc-seats .ax-hc-seat .ct {
    grid-column: 2;
    font-size: 9px;
  }
}

@media (max-width: 860px) {
  .ax-road {
    --road-gap: 36px;
    grid-template-columns: minmax(0, 1fr);
  }
  .ax-road::before {
    content: none;
  }
  .ax-road-step {
    padding: 0 0 0 40px;
  }
  .ax-road-step::before {
    left: 0;
    top: 2px;
    transform: none;
  }
  .ax-road-step::after {
    content: "";
    position: absolute;
    top: 28px;
    bottom: calc(-1 * var(--road-gap));
    left: 10px;
    width: 2px;
    border-radius: 1px;
    background: var(--ax-line);
  }
  .ax-road-step:last-child::after {
    content: none;
  }
  .ax-road-head {
    justify-content: flex-start;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   HERO TICKER
   Real dashboard figures scrolling under the CTAs. The lane is duplicated in JS,
   so 50% of its width is one full pass — hence translateX(-50%).
   ══════════════════════════════════════════════════════════════════════════ */
.ax-ticker {
  margin-top: 32px;
  max-width: 560px;
  overflow: hidden;
  /* Fade both ends instead of hard-clipping the chips. */
  -webkit-mask-image: linear-gradient(90deg, transparent, var(--neutral-black) 8%, var(--neutral-black) 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, var(--neutral-black) 8%, var(--neutral-black) 92%, transparent);
}
.ax-ticker-lane {
  display: flex;
  gap: 8px;
  width: max-content;
  animation: ax-ticker-scroll 30s linear infinite;
}
.ax-ticker:hover .ax-ticker-lane,
.ax-ticker:focus-within .ax-ticker-lane {
  animation-play-state: paused;
}
@keyframes ax-ticker-scroll {
  to {
    transform: translateX(-50%);
  }
}
.ax-tk {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 14px;
  border: 1px solid var(--ax-line);
  border-radius: var(--ax-r-chip);
  background: var(--ax-surface);
  font-size: 12px;
  color: var(--foreground-fg-secondary);
  white-space: nowrap;
}
.ax-tk b {
  color: var(--foreground-fg-primary);
  font-weight: 700;
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
}
.ax-tk .dot {
  width: 5px;
  height: 5px;
  flex: none;
  border-radius: 50%;
  background: var(--foreground-fg-brand);
}
.ax-tk .up {
  color: var(--badge-foreground-label-success);
  font-weight: 700;
  font-size: 11px;
}
.ax-tk .dn {
  color: var(--badge-foreground-label-danger);
  font-weight: 700;
  font-size: 11px;
}

/* ══════════════════════════════════════════════════════════════════════════
   HERO CONSOLE — replica of pages/portal/dashboard-gpt.html
   Card chrome, KPI type roles, gauge bars and tooltip styling mirror
   assets/css/pages/dashboard-gpt.css through the same tokens; sizes are scaled
   down for the hero column. Tilted in 3D with floating glass cards on top.
   ══════════════════════════════════════════════════════════════════════════ */
.ax-hero-stage {
  /* Reserve the gutter the floating cards hang into (and the 8px the bob animation adds),
     so they stay inside the hero instead of being clipped by its overflow. */
  padding: 30px 58px 8px 0;
  /* Column so the platform switch can centre under the console. */
  display: flex;
  flex-direction: column;
  align-items: center;
}
/* Both platform decks share one grid cell so they crossfade without a fixed height. */
.ax-hc-deck {
  display: grid;
}
.ax-hc-panel {
  grid-area: 1 / 1;
  position: relative;
  /* Both decks share one grid cell, so the taller one (ChatGPT, which carries the extra
     조직별 Credit 사용률 row) sets the height. Stretching the console box and letting the Claude
     chart absorb the slack keeps the two consoles the same size across a switch. */
  display: flex;
  flex-direction: column;
  opacity: 0;
  /* The hidden deck must not swallow hover on the visible one. */
  pointer-events: none;
  transition: opacity 0.5s ease;
}
.ax-hc-panel.is-active {
  opacity: 1;
  pointer-events: auto;
}
.ax-hc {
  display: flex;
  flex-direction: column;
  flex: 1;
  border: 1px solid var(--ax-line);
  border-radius: var(--border-radius-radius-l, 10px);
  background: var(--ax-surface);
  box-shadow: var(--shadow-console-lift);
  overflow: hidden;
}
.ax-hc-chrome {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--ax-line-soft);
  background: var(--background-bg-hover);
}
.ax-hc-title {
  font-size: 12px;
  font-weight: 700;
  color: var(--foreground-fg-primary);
}
/* Same pill the console GNB puts next to the page title — and the same per-platform tone
   (layout.css: .gnb-badge--claude uses the warning fill). */
.ax-hc-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: var(--ax-r-chip);
  color: var(--neutral-white);
  font-size: 10px;
  font-weight: 700;
}
/* Its platform mark (.ax-hc-badge-logo) shares the masked-SVG rule with the screenshot mock pills —
   see .ax-mock-badge-logo further down; only the size differs. */
.ax-hc-badge--gpt {
  background: var(--foreground-fg-brand);
}
.ax-hc-badge--claude {
  background: var(--badge-background-bg-warning);
}
.ax-hc-period {
  margin-left: auto;
  padding: 2px 10px;
  border-radius: var(--ax-r-chip);
  background: var(--background-bg-brand-light);
  color: var(--foreground-fg-brand);
  font-size: 10px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.ax-hc-body {
  display: grid;
  gap: 9px;
  padding: 12px;
  flex: 1;
}
/* The console's card: 1px hairline, 10px radius, flat. */
.ax-hc-card {
  padding: 8px 11px;
  border: 1px solid var(--ax-line);
  border-radius: var(--border-radius-radius-l, 10px);
  background: var(--ax-surface);
  transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}
/* Hover glow — the same brand-tinted lift the console cards use, kept subtle. */
.ax-hc-card:hover {
  border-color: var(--primary-300);
  box-shadow: var(--shadow-brand-lift);
  transform: translateY(-2px);
}
.ax-hc-card--accent {
  background: linear-gradient(to top, var(--primary-100) 0%, var(--ax-surface) 94%);
}
.ax-hc-kt {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--foreground-fg-tertiary);
  line-height: 1.4;
}
.ax-hc-kv {
  display: flex;
  align-items: baseline;
  gap: 3px;
  margin-top: 1px;
  font-size: 17.5px;
  line-height: 1.25;
  font-weight: 600;
  color: var(--primary-800);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
.ax-hc-kv small {
  font-size: 10.5px;
  font-weight: 500;
  color: var(--foreground-fg-tertiary);
}
/* 회수 검토 / 한도 도달 read as danger in the console. */
.ax-hc-kv--danger {
  color: var(--semantic-red-600);
}
.ax-hc-sub {
  display: flex;
  justify-content: space-between;
  gap: 6px;
  margin-top: 4px;
  font-size: 9.5px;
  color: var(--foreground-fg-tertiary);
  font-variant-numeric: tabular-nums;
}

/* Gauge bars — console geometry, scaled: 6px rail, segments for split gauges. */
.ax-hc-gauge {
  display: flex;
  height: 6px;
  margin-top: 6px;
  border-radius: var(--border-radius-radius-2xs, 3px);
  background: var(--border-border-primary);
  overflow: hidden;
}
.ax-hc-seg {
  height: 100%;
  transform: scaleX(0);
  transform-origin: left;
  animation: ax-gauge-fill 1s 0.5s cubic-bezier(0.2, 0.7, 0.2, 1) forwards;
}
.ax-hc-seg--active {
  background: var(--primary-500);
}
.ax-hc-seg--inactive {
  background: var(--semantic-red-500);
}
.ax-hc-seg--chat {
  background: var(--primary-500);
}
.ax-hc-seg--codex {
  background: var(--primary-300);
}
.ax-hc-seg--work {
  background: var(--primary-200);
}
.ax-hc-seg--remain {
  background: var(--neutral-300);
}
/* Every rail segment is a hover target for the value tooltip (initGaugeHover), so it lifts its
   own shade the way the console's stacked bars do. */
.ax-hc-seg:hover {
  filter: brightness(0.9);
}
@keyframes ax-gauge-fill {
  to {
    transform: scaleX(1);
  }
}

/* 조치 필요 대상 수: two contributing counts above one split gauge, like the console card. */
.ax-hc-split {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  margin-top: 5px;
  font-size: 9px;
  color: var(--foreground-fg-tertiary);
}
.ax-hc-split b {
  margin-left: 3px;
  color: var(--foreground-fg-primary);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.ax-hc-split i {
  display: inline-block;
  width: 5px;
  height: 5px;
  margin-right: 3px;
  border-radius: 50%;
  vertical-align: middle;
}
.ax-hc-split .is-limit {
  background: var(--semantic-red-500);
}
.ax-hc-split .is-reclaim {
  background: var(--semantic-orange-400);
}
.ax-hc-seg--limit {
  background: var(--semantic-red-500);
}
.ax-hc-seg--reclaim {
  background: var(--semantic-orange-400);
}
.ax-hc-seg--over {
  background: var(--semantic-red-500);
}

/* The console's own grid: three equal columns, the chart spanning the left two across both
   lower rows. That puts 조치 필요 대상 수 / 사용 총 Credit / 주기말 예상 사용량 all in column 3,
   so their widths line up exactly. */
.ax-hc-body--grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.ax-hc-g1 {
  grid-area: 1 / 1;
}
.ax-hc-g2 {
  grid-area: 1 / 2;
}
.ax-hc-g3 {
  grid-area: 1 / 3;
}
.ax-hc-gchart {
  grid-area: 2 / 1 / 4 / 3;
}
.ax-hc-g4 {
  grid-area: 2 / 3;
}
.ax-hc-g5 {
  grid-area: 3 / 3;
}
.ax-hc-g6 {
  grid-area: 4 / 1 / 5 / 4;
}

/* ── 조직별 Credit 사용률 — per-org stacked rails across the console's bottom row ── */
.ax-hc-orgs-head {
  display: flex;
  align-items: center;
  gap: 10px;
}
/* Page counter + chevrons, like the console card's pager (static in the sample). */
.ax-hc-pager {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 9px;
  color: var(--foreground-fg-tertiary);
  font-variant-numeric: tabular-nums;
}
.ax-hc-pager i {
  font-size: 11px;
  line-height: 1;
}
.ax-hc-org-rows {
  display: grid;
  gap: 5px;
  margin-top: 6px;
}
.ax-hc-org {
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr) 40px;
  align-items: center;
  gap: 10px;
  font-size: 9.5px;
  color: var(--foreground-fg-secondary);
  cursor: default;
}
.ax-hc-org .nm {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ax-hc-org .rail {
  display: flex;
  height: 10px;
  border-radius: var(--border-radius-radius-2xs, 3px);
  overflow: hidden;
}
.ax-hc-oseg {
  height: 100%;
  flex: 0 0 auto;
  transform: scaleX(0);
  transform-origin: left;
  animation: ax-gauge-fill 0.9s 0.6s cubic-bezier(0.2, 0.7, 0.2, 1) forwards;
  transition: filter 0.15s ease;
}
.ax-hc-oseg:hover {
  filter: brightness(0.9);
}
.ax-hc-oseg--chat {
  background: var(--primary-500);
}
.ax-hc-oseg--codex {
  background: var(--primary-300);
}
/* 잔여 = the unspent 배분 Credit. The console draws it as a hatched track rather than a product
   colour, and it takes the rail's remaining space so the row always totals exactly 100%. */
.ax-hc-oseg--remain {
  flex: 1 1 auto;
  background: repeating-linear-gradient(-45deg, var(--neutral-200) 0 3px, var(--neutral-100) 3px 6px);
}
.ax-hc-org .pc {
  text-align: right;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
/* Grade thresholds are the component's (sk-credit-usage-bar): 잔여 < 40 danger, < 60 warning. */
.ax-hc-org .pc.is-danger {
  color: var(--semantic-red-500);
}
.ax-hc-org .pc.is-warn {
  color: var(--semantic-orange-400);
}
.ax-hc-legend .is-credit-chat {
  background: var(--primary-500);
}
.ax-hc-legend .is-credit-codex {
  background: var(--primary-300);
}
.ax-hc-legend .is-credit-work {
  background: var(--primary-200);
}
.ax-hc-legend .is-credit-remain {
  background: repeating-linear-gradient(-45deg, var(--neutral-200) 0 2px, var(--neutral-100) 2px 4px);
}
/* 주기말 예상 사용량 runs over its allocation, so the console tints the whole card. */
.ax-hc-card--alert {
  background: var(--badge-background-bg-danger-light);
  border-color: var(--semantic-red-100);
}
.ax-hc-chip {
  padding: 2px 7px;
  border-radius: var(--ax-r-chip);
  background: var(--semantic-red-500);
  color: var(--neutral-white);
  font-size: 9px;
  font-weight: 700;
  white-space: nowrap;
}

/* ── Trend chart (조회 기간별 이용 현황 추이) ── */
.ax-hc-chart-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 6px;
}
.ax-hc-legend {
  display: flex;
  gap: 9px;
  margin-left: auto;
  font-size: 9px;
  color: var(--foreground-fg-tertiary);
}
.ax-hc-legend i {
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 3px;
  border-radius: 2px;
  vertical-align: middle;
}
.ax-hc-legend .is-acc {
  background: var(--semantic-blue-400);
}
.ax-hc-legend .is-usr {
  background: var(--semantic-cyan-400);
}
.ax-hc-legend .is-q {
  background: var(--primary-200);
}
.ax-hc-chart {
  display: flex;
  flex-direction: column;
}
/* Grid-stretched to the side column's height, so the plot has to grow with the card instead of
   leaving the bottom two-fifths empty. */
.ax-hc-chart-box {
  position: relative;
  flex: 1;
  min-height: 104px;
}
.ax-hc-svg {
  display: block;
  width: 100%;
  height: 100%;
}
.ax-hc-grid line {
  stroke: var(--border-border-secondary);
  stroke-width: 1;
}
.ax-hc-bar {
  fill: var(--primary-200);
  transform: scaleY(0);
  transform-origin: bottom;
  transform-box: fill-box;
  animation: ax-bar-grow 0.6s cubic-bezier(0.2, 0.7, 0.2, 1) forwards;
  transition: fill 0.15s ease;
}
@keyframes ax-bar-grow {
  to {
    transform: scaleY(1);
  }
}
.ax-hc-line {
  fill: none;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1400;
  stroke-dashoffset: 1400;
  animation: ax-line-draw 1.6s 0.35s cubic-bezier(0.3, 0.6, 0.3, 1) forwards;
}
.ax-hc-line--chat {
  stroke: var(--semantic-blue-400);
}
.ax-hc-line--codex {
  stroke: var(--semantic-cyan-400);
}
/* The console's Credit chart draws point markers; the usage chart does not. */
.ax-hc-dot {
  opacity: 0;
  animation: ax-dot-in 0.5s 1.5s ease forwards;
}
.ax-hc-dot--chat {
  fill: var(--semantic-blue-400);
}
.ax-hc-dot--codex {
  fill: var(--semantic-cyan-400);
}
/* Work Credit: the repo mock totals 0.00, so the real chart draws this series flat on the zero
   baseline. The sample gives it a small illustrative rhythm instead (user request: all three
   series must be readable) — the only figures on this page that are not from the mock. The axis
   is linear, not log: a log axis cannot plot 0, which is why only two series showed before. */
.ax-hc-line--work {
  stroke: var(--primary-500);
}
.ax-hc-dot--work {
  fill: var(--primary-500);
}
.ax-hc-base {
  stroke: var(--border-border-primary);
}
@keyframes ax-dot-in {
  to {
    opacity: 1;
  }
}
.ax-hc-legend .is-chat {
  background: var(--semantic-blue-400);
}
.ax-hc-legend .is-codex {
  background: var(--semantic-cyan-400);
}
.ax-hc-legend .is-work {
  background: var(--primary-500);
}
.ax-hc-line--acc {
  stroke: var(--semantic-blue-400);
}
.ax-hc-line--usr {
  stroke: var(--semantic-cyan-400);
}
@keyframes ax-line-draw {
  to {
    stroke-dashoffset: 0;
  }
}
/* One invisible band per day: the hover target that drives the tooltip. */
.ax-hc-band {
  fill: var(--neutral-black);
  fill-opacity: 0;
  transition: fill-opacity 0.15s ease;
}
.ax-hc-band.is-hot {
  fill-opacity: 0.05;
}
.ax-hc-bar.is-hot {
  fill: var(--primary-500);
}

/* ── Seat utilisation (조직별 좌석 활용률) ── */
.ax-hc-seats {
  position: relative;
}
.ax-hc-seat-rows {
  display: grid;
  gap: 5px;
  margin-top: 6px;
}
.ax-hc-seat {
  display: grid;
  grid-template-columns: 86px minmax(0, 1fr) 152px;
  align-items: center;
  gap: 8px;
  font-size: 9.5px;
  color: var(--foreground-fg-secondary);
  cursor: default;
}
/* The console right-aligns the org name against the bar it labels. */
.ax-hc-seat .nm {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: right;
}
.ax-hc-seat .rail {
  display: flex;
  height: 13px;
  border-radius: var(--border-radius-radius-2xs, 3px);
  overflow: hidden;
}
.ax-hc-sseg {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  transform: scaleX(0);
  transform-origin: left;
  animation: ax-gauge-fill 0.9s 0.6s cubic-bezier(0.2, 0.7, 0.2, 1) forwards;
  transition: filter 0.15s ease;
}
.ax-hc-sseg:hover {
  filter: brightness(0.9);
}
.ax-hc-sseg--used {
  flex: 0 0 auto;
  background: var(--primary-500);
}
/* 지출 한도의 남은 부분 = the gray track behind the fill; it takes the rest of the rail. */
.ax-hc-sseg--rest {
  flex: 1 1 auto;
  background: var(--background-bg-tertiary);
}
/* The rate sits inside its own segment, clipped away when the fill is too narrow for it. */
.ax-hc-sseg b {
  font-size: 8.5px;
  /* line-height 1 keeps the label inside the 13px rail (the inherited 1.5 overflowed it). */
  line-height: 1;
  font-weight: 600;
  color: var(--foreground-fg-reverse);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
}
/* 한도 / 사용 amounts, the console's right-hand count column. */
.ax-hc-seat .ct {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--foreground-fg-tertiary);
  font-variant-numeric: tabular-nums;
}
.ax-hc-legend .is-seat-used {
  background: var(--primary-500);
}
.ax-hc-legend .is-seat-limit {
  background: var(--background-bg-tertiary);
}

/* ── Two-metric card (라이선스 수 · 월간 지출 한도) ── */
.ax-hc-duo {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
}
/* Two stacked values would otherwise make this the tallest row of the console. */
.ax-hc-duo .ax-hc-kv {
  font-size: 16px;
}

/* ── Tooltip — the project's chart tooltip: dark panel, no arrow (specs §1.3). ── */
.ax-hc-tip {
  position: absolute;
  z-index: 5;
  padding: 6px 9px;
  border-radius: var(--border-radius-radius-s, 6px);
  background: var(--tooltip-background-strong);
  color: var(--tooltip-foreground);
  font-size: 10px;
  line-height: 1.5;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -100%);
  transition: opacity 0.12s ease;
}
.ax-hc-tip.is-on {
  opacity: 1;
}
.ax-hc-tip b {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ── Floating glass cards ── */
.ax-hc-float {
  position: absolute;
  padding: 12px 15px;
  border: 1px solid var(--primary-200);
  border-radius: var(--border-radius-radius-l, 10px);
  background: var(--background-overlay-light);
  backdrop-filter: blur(10px);
  box-shadow: var(--shadow-console-lift);
  /* The floats are annotations layered ON TOP of the console and overlap it by design. Making
     the whole card hit-testable meant the widget underneath never saw the pointer — the chart
     bands and seat rows on the right simply stopped responding. So the card itself is
     transparent to events and only the strip hanging in the stage gutter (.ax-hc-float-hit)
     picks up hover; :has() then animates the card. Both interactions survive. */
  pointer-events: none;
  transition: transform 0.25s cubic-bezier(0.2, 0.7, 0.2, 1), box-shadow 0.25s ease,
    border-color 0.25s ease;
}
/* Only the overhanging half is hit-testable — it never covers a console widget. */
.ax-hc-float-hit {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 54px;
  pointer-events: auto;
}
.ax-hc-float-hit--right {
  right: 0;
}
.ax-hc-float-hit--left {
  left: 0;
}
/* The hidden deck's strips must go inert too: pointer-events:auto on a child re-enables hit
   testing even inside a pointer-events:none parent, and the Claude deck sits later in the DOM —
   so its invisible strips were stacked over the ChatGPT deck's and swallowed every hover. */
.ax-hc-panel:not(.is-active) .ax-hc-float-hit {
  pointer-events: none;
}
.ax-hc-float:has(.ax-hc-float-hit:hover) {
  transform: scale(1.05);
  border-color: var(--primary-400);
  box-shadow: var(--shadow-brand-lift), var(--shadow-console-lift);
}
/* The bob keeps running, so the scale has to live on a wrapper-free property the animation
   does not touch — bob animates margin-top, transform stays free. */
.ax-hc-float .ax-hc-kv {
  font-size: 21px;
}
.ax-hc-float--1 {
  top: -24px;
  right: -28px;
  animation: ax-bob 5s ease-in-out infinite;
}
.ax-hc-float--2 {
  /* Hangs off the bottom-left corner, clearing the 조직별 Credit 사용률 rows: at a smaller offset
     the card covered the org name column, which is the point of that row. */
  bottom: -80px;
  left: -40px;
  animation: ax-bob 6s 0.8s ease-in-out infinite;
}
.ax-hc-float--3 {
  top: 40%;
  /* Sits fully in the stage's right gutter: overlapping the console would block the chart
     and seat hovers underneath it. */
  right: -56px;
  animation: ax-bob 5.5s 0.4s ease-in-out infinite;
}
@keyframes ax-bob {
  0%,
  100% {
    margin-top: 0;
  }
  50% {
    margin-top: -8px;
  }
}
.ax-hc-tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: var(--ax-r-chip);
  font-size: 10px;
  font-weight: 700;
}
.ax-hc-tag::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
}
.ax-hc-tag--ok {
  background: var(--badge-background-bg-success-light);
  color: var(--badge-foreground-label-success);
}
.ax-hc-tag--warn {
  background: var(--badge-background-bg-warning-light);
  color: var(--badge-foreground-label-warning);
}

/* ── Dark mode ─────────────────────────────────────────────────────────────
   The console hard-codes --primary-800 for KPI values (as the real dashboard does), and
   dark-mode.css lightens those to --primary-300 there because 800 is unreadable on a dark
   surface. The replica needs the same treatment, plus a darker accent gradient and a
   red-tinted (not red-washed) alert card. */
[data-exmp-mode="dark"] .ax-hc-kv {
  color: var(--primary-300);
}
[data-exmp-mode="dark"] .ax-hc-kv--danger {
  color: var(--semantic-red-400);
}
[data-exmp-mode="dark"] .ax-hc-card--accent {
  background: linear-gradient(to top, var(--primary-950) 0%, var(--ax-surface) 94%);
}
[data-exmp-mode="dark"] .ax-hc-card--alert {
  background: var(--background-bg-secondary);
  border-color: var(--semantic-red-600);
}
[data-exmp-mode="dark"] .ax-hc-chrome {
  background: var(--background-bg-primary);
}
/* --neutral-300/-400 are not remapped on dark, so the rails and inactive pips need help. */
[data-exmp-mode="dark"] .ax-hc-seg--remain {
  background: var(--neutral-600);
}
/* Same reason for the 잔여 hatch: the light neutrals would read as a white block on dark. */
[data-exmp-mode="dark"] .ax-hc-oseg--remain,
[data-exmp-mode="dark"] .ax-hc-legend .is-credit-remain {
  background: repeating-linear-gradient(-45deg, var(--neutral-600) 0 3px, var(--neutral-700) 3px 6px);
}
[data-exmp-mode="dark"] .ax-hc-pip::before {
  background: currentColor;
}
[data-exmp-mode="dark"] .ax-hc-float {
  background: var(--background-overlay-scrim);
  border-color: var(--primary-700);
}
/* The glass card sits on a dark page: its own text must follow the dark palette too. */
[data-exmp-mode="dark"] .ax-hc-grid line {
  stroke: var(--border-border-primary);
}

/* Platform switch — sits under the console so it never covers the screen it switches.
   Named segments rather than dots: the label tells the reader which platform they are
   looking at, which a 7px pip cannot. */
.ax-hc-switch {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  margin: 16px auto 0;
  border: 1px solid var(--ax-line);
  border-radius: var(--border-radius-radius-m, 8px);
  background: var(--ax-surface);
}
.ax-hc-deck {
  /* The stage is a flex column now — the deck still needs the full row width. */
  width: 100%;
}
.ax-hc-pip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 16px;
  border: 0;
  border-radius: var(--border-radius-radius-s, 6px);
  background: none;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--foreground-fg-tertiary);
  cursor: pointer;
  transition: background-color 0.25s ease, color 0.25s ease;
}
.ax-hc-pip::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.55;
}
.ax-hc-pip:hover {
  color: var(--foreground-fg-primary);
}
.ax-hc-pip.is-active {
  background: var(--primary-600);
  color: var(--neutral-white);
}
/* Active Claude segment carries Claude's own tone, matching its console badge. */
.ax-hc-pip--claude.is-active {
  background: var(--badge-background-bg-warning);
}
.ax-hc-pip.is-active::before {
  opacity: 1;
}
.ax-hc-pip:focus-visible {
  outline: 2px solid var(--border-border-brand);
  outline-offset: 2px;
}

/* ══════════════════════════════════════════════════════════════════════════
   PROBLEM PANEL — 3 columns inside one bordered card, split by hairlines
   ══════════════════════════════════════════════════════════════════════════ */
.ax-prob-panel {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  background: var(--ax-surface);
  border: 1px solid var(--ax-line);
  border-radius: var(--ax-r-card);
  box-shadow: var(--shadow-xs-0);
  overflow: hidden;
}
.ax-prob-col {
  padding: 30px 32px;
  border-left: 1px solid var(--ax-line-soft);
}
.ax-prob-col:first-child {
  border-left: 0;
}
.ax-prob-tag {
  display: block;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--foreground-fg-brand);
  margin-bottom: 14px;
}
.ax-prob-col h3 {
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.4;
  margin-bottom: 12px;
}
.ax-prob-col p {
  font-size: 14px;
  line-height: 1.7;
  color: var(--foreground-fg-tertiary);
}

/* ══════════════════════════════════════════════════════════════════════════
   WHY — 질문 6장 → ANSWER 밴드 (확정 시안 agenticlens-why-answer v4.6)

   Choreography (assets/js/intro.js initWhyAnswer): the badges flip ?→✓ one by one,
   the cards settle 2px, then the dark band slides up and its collage draws itself; each
   visual afterwards floats on its own cycle.

   Two structural rules the mockup depends on:
   1. The FINISHED state is the default. Every pre-animation state is gated behind
      `.ax-anim` (the same opt-in `.ax-reveal` uses), so reduced motion / no-IO / a
      zero-size viewport renders the answered section statically — motion never gates content.
   2. The entrance transform lives on .ax-why-vc and the idle float on the inner .ax-why-fl.
      Merging them onto one element would make the two transforms overwrite each other.
   ══════════════════════════════════════════════════════════════════════════ */

/* SVG paint servers (stops cannot read a token from a presentation attribute). */
.ax-why-defs {
  position: absolute;
  width: 0;
  height: 0;
}
.s-brand-light {
  stop-color: var(--primary-300);
}
.s-brand {
  stop-color: var(--primary-500);
}
.s-brand-deep {
  stop-color: var(--primary-600);
}
.s-area-top {
  stop-color: var(--primary-400);
  stop-opacity: 0.28;
}
.s-area-bottom {
  stop-color: var(--primary-400);
  stop-opacity: 0;
}

/* ── Question cards ── */
.ax-why-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}
/* Marker and title share the first row; the supporting line drops under the title (column 2),
   so the ? reads as a marker FOR the question rather than a badge stacked above it. */
.ax-why-q {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: 12px;
  align-items: start;
  padding: 20px;
  border: 1px solid var(--ax-line);
  border-radius: var(--ax-r-card);
  background: var(--ax-surface);
  box-shadow: var(--shadow-xs-0);
  transition: transform 0.4s ease, border-color 0.25s ease, box-shadow 0.25s ease;
}
.ax-why-q:hover {
  border-color: var(--primary-300);
  box-shadow: 0 0 0 3px var(--primary-50), var(--shadow-brand-lift);
}
.ax-why-badge {
  grid-area: 1 / 1;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--background-bg-brand-light);
  color: var(--foreground-fg-brand);
  /* Optically centres the 26px marker on the title's 21.75px first line. */
  margin-top: -2px;
}
.ax-why-badge .ti {
  font-size: 15px;
  line-height: 1;
}
.ax-why-q h4 {
  grid-area: 1 / 2;
  font-size: 14.5px;
  font-weight: 700;
  line-height: 1.5;
  word-break: keep-all;
}
.ax-why-q p {
  grid-area: 2 / 2;
  margin-top: 8px;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--foreground-fg-secondary);
  word-break: keep-all;
}
/* The questions settle as the answer band rises. */
.ax-anim .ax-why.is-solved .ax-why-q {
  transform: translateY(2px);
}

/* ── ANSWER band ── */
.ax-why-answer {
  position: relative;
  margin-top: 36px;
  border-radius: 20px;
  overflow: hidden;
  /* Same deep-violet surface as the footer, so the page opens and closes on the same dark tone. */
  background: linear-gradient(180deg, var(--primary-950), var(--surface-violet-deep));
}
/* Two purple light sources over the near-black surface. */
.ax-why-answer::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(
      ellipse 50% 70% at 12% 0%,
      color-mix(in srgb, var(--primary-400) 24%, transparent),
      transparent 60%
    ),
    radial-gradient(ellipse 45% 65% at 92% 100%, color-mix(in srgb, var(--primary-800) 30%, transparent), transparent 60%);
}
.ax-anim .ax-why-answer {
  opacity: 0;
  transform: translateY(36px);
  transition: opacity 0.7s 0.15s, transform 0.7s 0.15s;
}
.ax-anim .ax-why.is-solved .ax-why-answer {
  opacity: 1;
  transform: none;
}
.ax-why-answer-in {
  position: relative;
  display: grid;
  grid-template-columns: 0.9fr 1.1fr;
  gap: 52px;
  align-items: center;
  padding: 28px 44px;
}
.ax-why-cap {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--primary-400);
}
.ax-why-cap i {
  display: inline-grid;
  place-items: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  font-size: 11px;
  color: var(--semantic-green-300);
  background: color-mix(in srgb, var(--semantic-green-300) 15%, transparent);
}
.ax-why-say h3 {
  margin-top: 8px;
  font-size: clamp(20px, 2.2vw, 28px);
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.02em;
  color: var(--neutral-white);
  word-break: keep-all;
}
.ax-why-say h3 em {
  font-style: normal;
  background: linear-gradient(95deg, var(--primary-300), var(--primary-500));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.ax-why-say p {
  max-width: 520px;
  margin-top: 10px;
  /* Promoted to white at 15px (user request 2026-08-26): this line is the section's actual
     answer, so it should not read as a caption under the heading. */
  font-size: 15px;
  line-height: 1.65;
  color: var(--neutral-white);
  word-break: keep-all;
}

/* ── Floating collage ──
   No card frame: the visuals sit straight on the dark surface, and depth comes from size,
   offset and z-index only (never rotation). --neutral-* tokens are used for the on-dark text
   ramp because dark-mode.css does not remap them — this band is dark in both themes. */
.ax-why-collage {
  position: relative;
  height: 230px;
}
.ax-why-collage::before {
  content: "";
  position: absolute;
  top: 6%;
  left: 10%;
  width: 80%;
  height: 80%;
  pointer-events: none;
  background: radial-gradient(ellipse, color-mix(in srgb, var(--primary-400) 16%, transparent), transparent 68%);
  filter: blur(34px);
}
.ax-why-vc {
  position: absolute;
}
.ax-why-vc--line {
  top: 8%;
  left: 14%;
  width: 36%;
  z-index: 2;
  --bd: 6.4s;
  --bdel: 0s;
}
.ax-why-vc--gauge {
  top: 10%;
  right: 2%;
  width: 27%;
  z-index: 3;
  --bd: 5.6s;
  --bdel: 0.9s;
}
.ax-why-vc--bars {
  bottom: 6%;
  left: 2%;
  width: 23%;
  z-index: 1;
  --bd: 7s;
  --bdel: 0.4s;
}
.ax-why-vc--table {
  right: 0;
  bottom: 0;
  width: 46%;
  z-index: 2;
  --bd: 6s;
  --bdel: 1.3s;
}
/* The glow belongs to the element itself, not to a card behind it. */
.ax-why-fl {
  filter: drop-shadow(0 10px 24px color-mix(in srgb, var(--neutral-950) 45%, transparent));
}
.ax-anim .ax-why-vc {
  opacity: 0;
  transform: translateY(22px) scale(0.96);
  transition: opacity 0.6s, transform 0.6s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.ax-anim .ax-why.is-solved .ax-why-vc {
  opacity: 1;
  transform: none;
}
.ax-anim .ax-why.is-solved .ax-why-vc:nth-child(1) { transition-delay: 0.35s; }
.ax-anim .ax-why.is-solved .ax-why-vc:nth-child(2) { transition-delay: 0.5s; }
.ax-anim .ax-why.is-solved .ax-why-vc:nth-child(3) { transition-delay: 0.65s; }
.ax-anim .ax-why.is-solved .ax-why-vc:nth-child(4) { transition-delay: 0.8s; }
.ax-anim .ax-why.is-solved .ax-why-fl {
  animation: ax-why-bob var(--bd, 6s) var(--bdel, 0s) ease-in-out infinite;
}
@keyframes ax-why-bob {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-7px);
  }
}
.ax-why-pt {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 5px;
  font-size: 10px;
  font-weight: 700;
  color: var(--neutral-300);
  text-shadow: 0 1px 8px color-mix(in srgb, var(--neutral-950) 50%, transparent);
}
.ax-why-pt small {
  font-size: 9.5px;
  font-weight: 600;
  color: var(--neutral-500);
  white-space: nowrap;
}

/* Line chart */
.ax-why-vc--line svg {
  display: block;
  width: 100%;
  height: 58px;
}
.ax-why-line {
  fill: none;
  stroke: url(#axWhyLineGrad);
  stroke-width: 2.5;
  stroke-linecap: round;
}
.ax-why-area {
  fill: url(#axWhyAreaGrad);
}
.ax-why-dot {
  fill: var(--neutral-white);
  stroke: var(--primary-400);
  stroke-width: 2.5;
}
.ax-why-tip rect {
  fill: color-mix(in srgb, var(--neutral-white) 10%, transparent);
}
.ax-why-tip text {
  fill: var(--neutral-white);
  font-size: 9px;
  font-weight: 700;
}
.ax-anim .ax-why-line {
  stroke-dasharray: 520;
  stroke-dashoffset: 520;
}
.ax-anim .ax-why-area,
.ax-anim .ax-why-dot,
.ax-anim .ax-why-tip {
  opacity: 0;
}
.ax-anim .ax-why.is-solved .ax-why-line {
  animation: ax-why-draw 1.1s 0.6s cubic-bezier(0.3, 0.6, 0.3, 1) forwards;
}
.ax-anim .ax-why.is-solved .ax-why-area {
  animation: ax-why-fade 0.5s 1.35s forwards;
}
.ax-anim .ax-why.is-solved .ax-why-dot {
  animation: ax-why-fade 0.3s 1.55s forwards;
}
.ax-anim .ax-why.is-solved .ax-why-tip {
  animation: ax-why-fade 0.3s 1.6s forwards;
}
@keyframes ax-why-draw {
  to {
    stroke-dashoffset: 0;
  }
}
@keyframes ax-why-fade {
  to {
    opacity: 1;
  }
}

/* Donut gauge */
.ax-why-gwrap {
  display: flex;
  align-items: center;
  gap: 12px;
}
.ax-why-gd {
  position: relative;
  flex-shrink: 0;
  width: 56px;
  height: 56px;
}
.ax-why-gd svg {
  width: 100%;
  height: 100%;
  transform: rotate(-90deg);
}
.ax-why-trk {
  fill: none;
  stroke: color-mix(in srgb, var(--neutral-white) 10%, transparent);
  stroke-width: 9;
}
/* 189 = the r=30 circumference; the resting offset is the 71% arc. */
.ax-why-val {
  fill: none;
  stroke: url(#axWhyGaugeGrad);
  stroke-width: 9;
  stroke-linecap: round;
  stroke-dasharray: 189;
  stroke-dashoffset: calc(189 - 189 * 0.71);
}
.ax-anim .ax-why-val {
  stroke-dashoffset: 189;
}
.ax-anim .ax-why.is-solved .ax-why-val {
  animation: ax-why-gauge 1.2s 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) forwards;
}
@keyframes ax-why-gauge {
  to {
    stroke-dashoffset: calc(189 - 189 * 0.71);
  }
}
.ax-why-gc {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.ax-why-gc .gn {
  font-size: 13px;
  font-weight: 700;
  line-height: 1.1;
  color: var(--neutral-white);
  font-variant-numeric: tabular-nums;
}
.ax-why-gc .gs {
  font-size: 8.5px;
  font-weight: 600;
  color: var(--neutral-500);
}
.ax-why-legend {
  display: grid;
  flex: 1;
  min-width: 0;
  gap: 6px;
}
.ax-why-lg {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 9.5px;
  color: var(--neutral-400);
}
.ax-why-lg i {
  width: 7px;
  height: 7px;
  flex-shrink: 0;
  border-radius: 2px;
}
.ax-why-lg .is-chat {
  background: var(--primary-300);
}
.ax-why-lg .is-codex {
  background: var(--primary-500);
}
.ax-why-lg .is-rest {
  background: color-mix(in srgb, var(--neutral-white) 35%, transparent);
}
.ax-why-lg b {
  margin-left: auto;
  font-size: 10px;
  color: var(--neutral-white);
  font-variant-numeric: tabular-nums;
}
.ax-anim .ax-why-lg {
  opacity: 0;
  transform: translateX(8px);
  transition: opacity 0.4s, transform 0.4s;
}
.ax-anim .ax-why.is-solved .ax-why-lg {
  opacity: 1;
  transform: none;
}
.ax-anim .ax-why.is-solved .ax-why-lg:nth-child(1) { transition-delay: 0.95s; }
.ax-anim .ax-why.is-solved .ax-why-lg:nth-child(2) { transition-delay: 1.05s; }
.ax-anim .ax-why.is-solved .ax-why-lg:nth-child(3) { transition-delay: 1.15s; }

/* Bar chart */
.ax-why-bwrap {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 42px;
  padding-top: 3px;
}
.ax-why-bcol {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 4px;
  height: 100%;
}
.ax-why-bcol .bv {
  font-size: 8.5px;
  font-weight: 700;
  color: var(--neutral-500);
  font-variant-numeric: tabular-nums;
}
.ax-why-bcol .bar {
  width: 100%;
  height: var(--h);
  border-radius: 4px 4px 2px 2px;
  transform-origin: bottom;
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--primary-300) 50%, transparent),
    color-mix(in srgb, var(--primary-300) 22%, transparent)
  );
}
.ax-why-bcol .bar.is-hi {
  background: linear-gradient(180deg, var(--primary-300), var(--primary-500));
  box-shadow: 0 0 14px color-mix(in srgb, var(--primary-400) 40%, transparent);
}
.ax-anim .ax-why-bcol .bar {
  transform: scaleY(0);
  transition: transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.ax-anim .ax-why-bcol .bv {
  opacity: 0;
  transition: opacity 0.3s;
}
.ax-anim .ax-why.is-solved .ax-why-bcol .bar {
  transform: scaleY(1);
}
.ax-anim .ax-why.is-solved .ax-why-bcol:nth-child(1) .bar { transition-delay: 0.75s; }
.ax-anim .ax-why.is-solved .ax-why-bcol:nth-child(2) .bar { transition-delay: 0.83s; }
.ax-anim .ax-why.is-solved .ax-why-bcol:nth-child(3) .bar { transition-delay: 0.91s; }
.ax-anim .ax-why.is-solved .ax-why-bcol:nth-child(4) .bar { transition-delay: 0.99s; }
.ax-anim .ax-why.is-solved .ax-why-bcol:nth-child(5) .bar { transition-delay: 1.07s; }
.ax-anim .ax-why.is-solved .ax-why-bcol .bv {
  opacity: 1;
  transition-delay: 1.25s;
}
.ax-why-bx {
  display: flex;
  gap: 8px;
  margin-top: 5px;
}
.ax-why-bx span {
  flex: 1;
  overflow: hidden;
  font-size: 8px;
  font-weight: 600;
  /* One step up from the mockup's dimmest grey: the violet surface is lighter than the
     near-black it was drawn on, and neutral-600 turned muddy against it. */
  color: var(--neutral-500);
  text-align: center;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Status table */
.ax-why-trw {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 9px;
  align-items: center;
  padding: 5px 2px;
  font-size: 10.5px;
  color: var(--neutral-300);
  border-bottom: 1px solid color-mix(in srgb, var(--neutral-white) 8%, transparent);
}
.ax-why-trw:last-child {
  border-bottom: none;
}
.ax-why-trw b {
  font-size: 12px;
  font-weight: 700;
  color: var(--neutral-white);
  font-variant-numeric: tabular-nums;
}
.ax-anim .ax-why-trw {
  opacity: 0;
  transform: translateX(10px);
  transition: opacity 0.4s, transform 0.4s;
}
.ax-anim .ax-why.is-solved .ax-why-trw {
  opacity: 1;
  transform: none;
}
.ax-anim .ax-why.is-solved .ax-why-trw:nth-child(2) { transition-delay: 0.9s; }
.ax-anim .ax-why.is-solved .ax-why-trw:nth-child(3) { transition-delay: 1s; }
.ax-anim .ax-why.is-solved .ax-why-trw:nth-child(4) { transition-delay: 1.1s; }
.ax-why-pill {
  display: inline-flex;
  align-items: center;
  justify-self: end;
  gap: 4px;
  padding: 2.5px 9px;
  border-radius: var(--ax-r-chip);
  font-size: 9.5px;
  font-weight: 700;
  white-space: nowrap;
}
.ax-why-pill i {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: currentColor;
}
.ax-why-pill--ok {
  color: var(--semantic-green-300);
  background: color-mix(in srgb, var(--semantic-green-300) 12%, transparent);
}
.ax-why-pill--warn {
  color: var(--semantic-orange-300);
  background: color-mix(in srgb, var(--semantic-orange-300) 12%, transparent);
}
.ax-why-pill--bad {
  color: var(--semantic-red-300);
  background: color-mix(in srgb, var(--semantic-red-300) 12%, transparent);
}

/* Below 1024 the collage gives up absolute placement (and the float with it) and becomes a
   plain two-column grid, so nothing overlaps in the stacked band. */
@media (max-width: 1024px) {
  .ax-why-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .ax-why-answer-in {
    grid-template-columns: minmax(0, 1fr);
    gap: 32px;
    padding: 32px 28px;
  }
  .ax-why-collage {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 18px;
    height: auto;
    max-width: 520px;
  }
  .ax-why-vc {
    position: static;
    width: auto;
  }
  .ax-anim .ax-why.is-solved .ax-why-fl {
    animation: none;
  }
}
@media (max-width: 640px) {
  .ax-why-grid {
    grid-template-columns: minmax(0, 1fr);
  }
  .ax-why-answer-in {
    padding: 26px 20px;
  }
  /* One column below 640: at two columns the gauge legend and the status pills no longer fit
     their track and spill out of the band (the mockup stops at the 1024 breakpoint). */
  .ax-why-collage {
    grid-template-columns: minmax(0, 1fr);
  }
}/* ══════════════════════════════════════════════════════════════════════════
   CARDS / BENTO
   ══════════════════════════════════════════════════════════════════════════ */
.ax-card {
  background: var(--ax-surface);
  border: 1px solid var(--ax-line);
  border-radius: var(--ax-r-card);
  padding: 24px;
  box-shadow: var(--shadow-xs-0);
  transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}
.ax-card--hover:hover {
  transform: translateY(-3px);
  border-color: var(--primary-200);
  box-shadow: var(--shadow-m-0);
}
.ax-card-ico {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: var(--border-radius-radius-m, 8px);
  background: var(--background-bg-brand-light);
  color: var(--foreground-fg-brand);
  font-size: 20px;
  margin-bottom: 16px;
}
/* Card typography is aligned with THE PROBLEM's columns (.ax-prob-col) so every
   section reads with one voice: 17/1.4 bold title over 14/1.7 tertiary body. */
.ax-card h3 {
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.4;
  margin-bottom: 12px;
}
.ax-card p {
  font-size: 14px;
  line-height: 1.7;
  color: var(--foreground-fg-tertiary);
}

/* Generic auto grids */
.ax-grid-3 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--ax-gap);
}

/* ══════════════════════════════════════════════════════════════════════════
   FEATURES — ZOOM CALLOUT
   Five UI miniatures in a row, joined by "magnifier" bridge lines: the piece
   highlighted in one frame is what the next frame zooms into. Everything is
   HTML/CSS/SVG skeleton — no screenshots, no data. One frame is active at a
   time (auto-cycled by intro.js); the step buttons below are the labels AND
   the manual control.
   Colours follow the reference tone through ui-exmp tokens only: brand purple
   = --foreground-fg-brand / --border-border-brand, its soft fill =
   --background-bg-brand-light, mid purple = --primary-300, skeleton grey =
   --border-border-primary, soft panel = --background-bg-hover. All of those
   are remapped in dark-mode.css, so the whole board follows the theme.
   ══════════════════════════════════════════════════════════════════════════ */
.ax-zoom {
  background: var(--ax-surface);
  border: 1px solid var(--ax-line);
  border-radius: var(--ax-r-card);
  box-shadow: var(--shadow-xs-0);
  /* Roomier top/bottom than the sides (user request 2026-08-26): the miniatures carry a hover
     lift and the active frame a glow, both of which crowded the box edge at the old 44/30. */
  padding: 64px 36px 56px;
  overflow: hidden;
}
.ax-zoom-chain {
  display: flex;
  /* stretch, not center: the five miniatures hold different amounts of skeleton, so centering
     sized each one to its own content and left their top/bottom edges misaligned by 2-11px
     (measured 131/122/122/126/120). Stretch makes the row one height. The bridges set their own
     `align-self: stretch`, so they are unaffected either way. */
  align-items: stretch;
}
.ax-zoom-frame {
  flex: 1;
  min-width: 0;
  /* Column so .ax-zoom-mk can take the leftover height — the frames share one height (the tallest
     card's), so without this the shorter skeletons left up to 45px of dead space under them
     (user report 2026-09-01). */
  display: flex;
  flex-direction: column;
  padding: 10px;
  border: 1.5px solid var(--ax-line);
  border-radius: var(--border-radius-radius-l, 10px);
  background: var(--background-bg-hover);
  transition: transform 0.4s cubic-bezier(0.2, 0.7, 0.2, 1),
    border-color 0.4s cubic-bezier(0.2, 0.7, 0.2, 1),
    background-color 0.4s cubic-bezier(0.2, 0.7, 0.2, 1),
    box-shadow 0.4s cubic-bezier(0.2, 0.7, 0.2, 1);
}
/* Active frame lifts out of the row — the "zoomed" step. */
.ax-zoom-frame.is-active {
  border-color: var(--border-border-brand);
  background: var(--ax-surface);
  transform: scale(1.07);
  box-shadow: var(--shadow-brand-lift);
  position: relative;
  z-index: 2;
}
/* On dark the board itself is --ax-surface, so "active = surface" would sink INTO the board
   while the inactive frames (one step above it) floated. Flip the two: inactive recedes to the
   page backdrop, active rises one step. */
[data-exmp-mode="dark"] .ax-zoom-frame {
  background: var(--background-bg-primary);
}
/* --background-bg-tertiary, NOT --background-bg-hover: this is a SURFACE lift, not a hover state.
   Both resolved to --neutral-700 on dark until the console retuned the hover token to a 25% mix
   toward the card colour (2026-08-31) — correct for "control hover on a plain surface", but it cut
   this frame's lift from 24 to 6 per channel and sank the active step back into the board, which is
   exactly what the flip above exists to prevent. The tertiary token means "one step above the card"
   and still resolves to --neutral-700, so the intent survives the next token refresh. */
[data-exmp-mode="dark"] .ax-zoom-frame.is-active {
  background: var(--background-bg-tertiary);
}
/* …but that lift lands the ACTIVE frame on --neutral-700, which is exactly what the skeleton
   fills inside it use (--border-border-primary flips to --neutral-700 on dark). Same colour on
   same colour = the mock's rows/bars/chips simply disappear the moment a step is focused. Raise
   the fills two steps inside the active frame so the mock stays legible in every state; the
   highlighted (.is-hl) pieces already carry their own brand colours and are left alone. */
[data-exmp-mode="dark"] .ax-zoom-frame.is-active .ax-zoom-bar:not(.is-hl),
[data-exmp-mode="dark"] .ax-zoom-frame.is-active .ax-zoom-cell:not(.is-hl),
[data-exmp-mode="dark"] .ax-zoom-frame.is-active .ax-zoom-kpis i:not(.is-hl),
[data-exmp-mode="dark"] .ax-zoom-frame.is-active .ax-zoom-chip:not(.is-hl) {
  background: var(--neutral-500);
}
/* The log lines are an inset code block: on the lifted frame they go DARKER, not lighter, so
   they keep reading as carved-in rather than as another bar. */
[data-exmp-mode="dark"] .ax-zoom-frame.is-active .ax-zoom-log {
  background: var(--background-bg-secondary);
}
.ax-zoom-flabel {
  display: block;
  margin-bottom: 6px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--foreground-fg-tertiary);
  transition: color 0.4s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.ax-zoom-frame.is-active .ax-zoom-flabel {
  color: var(--foreground-fg-brand);
}

/* Bridge: two dashed lines splaying apart, like a magnifier callout. */
/* 28px, not the original 44: the chain went from five cards to six, and the callout lines are the
   cheapest place to buy back width — the cards read better wide-and-short (user request
   2026-09-01), and at the wider card the tool chips fall into 2 rows instead of 3, which is what
   actually lets the shared height come down. */
.ax-zoom-bridge {
  width: 28px;
  flex-shrink: 0;
  align-self: stretch;
  position: relative;
}
.ax-zoom-bridge svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.ax-zoom-bridge line {
  stroke: var(--ax-line);
  stroke-width: 1.5;
  stroke-dasharray: 3 4;
  transition: stroke 0.4s cubic-bezier(0.2, 0.7, 0.2, 1);
}
/* Only the bridge feeding the active frame is drawn in brand purple. */
.ax-zoom-bridge.is-active line {
  stroke: var(--primary-300);
}

/* ── Miniature contents (skeleton) ── */
.ax-zoom-mk {
  display: grid;
  gap: 4px;
  /* Fill the frame and distribute the rows, so every card's skeleton reaches its bottom edge
     instead of stacking at the top with a gap under it. */
  flex: 1;
  align-content: space-between;
}
.ax-zoom-bar {
  height: 7px;
  border-radius: var(--border-radius-radius-2xs, 3px);
  background: var(--border-border-primary);
}
.ax-zoom-bar.is-hl {
  background: var(--primary-300);
}
.ax-zoom-mk--kpi .ax-zoom-bar:nth-of-type(1) {
  width: 82%;
}
.ax-zoom-mk--kpi .ax-zoom-bar:nth-of-type(2) {
  width: 64%;
}
.ax-zoom-mk--kpi .ax-zoom-bar:nth-of-type(3) {
  width: 45%;
}
.ax-zoom-mk--tool .ax-zoom-bar:nth-of-type(1) {
  width: 70%;
  margin-top: 4px;
}
.ax-zoom-mk--tool .ax-zoom-bar:nth-of-type(2) {
  width: 34%;
}
.ax-zoom-row {
  display: flex;
  align-items: center;
  gap: 5px;
}
.ax-zoom-cell {
  flex: 1;
  height: 12px;
  border-radius: var(--border-radius-radius-2xs, 3px);
  background: var(--border-border-primary);
}
.ax-zoom-cell--num {
  flex: none;
  width: 26px;
}
.ax-zoom-cell.is-hl {
  background: var(--background-bg-brand-light);
  border: 1px solid var(--primary-300);
}
/* 조직별 miniature: depth indent + a short "└" tick, the same device the console's 조직 tree cell
   uses (rules/06 §6.1.0.2). Indent only — no extra height, so the shared card height is unchanged. */
.ax-zoom-mk--org .ax-zoom-row[data-depth="1"] {
  padding-left: 8px;
}
.ax-zoom-mk--org .ax-zoom-row[data-depth="2"] {
  padding-left: 16px;
}
.ax-zoom-tick {
  width: 5px;
  height: 5px;
  flex-shrink: 0;
  border-left: 1px solid var(--border-border-primary);
  border-bottom: 1px solid var(--border-border-primary);
  margin-right: -1px;
  transform: translateY(-2px);
}
/* 사용자별 miniature: per-row activity pip. Semantic colours by meaning, so they are the raw ramp
   on purpose (rules/05 §5.2.0 exception) — 활성 green, 저활성 yellow, 미사용 red. */
.ax-zoom-pip {
  width: 12px;
  height: 6px;
  flex-shrink: 0;
  border-radius: 999px;
  background: var(--border-border-primary);
}
.ax-zoom-pip.is-on {
  background: var(--semantic-green-400);
}
.ax-zoom-pip.is-low {
  background: var(--semantic-yellow-400);
}
.ax-zoom-pip.is-off {
  background: var(--semantic-red-400);
}
.ax-zoom-dot {
  width: 10px;
  height: 10px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--foreground-fg-tertiary);
  opacity: 0.4;
}
.ax-zoom-dot.is-hl {
  background: var(--foreground-fg-brand);
  opacity: 1;
}
.ax-zoom-kpis {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
}
.ax-zoom-kpis i {
  display: block;
  height: 17px;
  border-radius: var(--border-radius-radius-s, 6px);
  background: var(--border-border-primary);
}
.ax-zoom-kpis i.is-hl {
  background: var(--background-bg-brand-light);
  border: 1px solid var(--primary-300);
}
.ax-zoom-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.ax-zoom-chip {
  /* inline-flex so a chip may carry a glyph beside its label (the 비용·스케줄링 miniature's
     clock/주기 chip); text-only chips are unaffected. */
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px 6px;
  border-radius: var(--ax-r-chip);
  background: var(--border-border-primary);
  color: var(--foreground-fg-secondary);
  font-size: 9px;
  font-weight: 700;
}
.ax-zoom-chip .ti {
  font-size: 10px;
  line-height: 1;
}
.ax-zoom-chip.is-hl {
  background: var(--background-bg-brand-light);
  border: 1px solid var(--primary-300);
  color: var(--foreground-fg-brand);
}
/* Log lines are <code>, the one place rules/05 §5.3 allows a monospace face. */
.ax-zoom-log {
  display: block;
  padding: 2px 6px;
  border-left: 2px solid var(--ax-line);
  border-radius: 0 var(--border-radius-radius-2xs, 3px) var(--border-radius-radius-2xs, 3px) 0;
  background: var(--background-bg-hover);
  color: var(--foreground-fg-tertiary);
  font-size: 8.5px;
  white-space: nowrap;
  overflow: hidden;
  transition: border-color 0.4s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.ax-zoom-frame.is-active .ax-zoom-log {
  border-left-color: var(--border-border-brand);
}

/* ── Step labels: the accessible half of the chain, and the manual control ── */
.ax-zoom-steps {
  display: flex;
  gap: 12px;
  margin-top: 26px;
}
.ax-zoom-step {
  flex: 1;
  display: block;
  padding: 14px 8px;
  border: 1px solid transparent;
  border-radius: var(--border-radius-radius-l, 10px);
  background: transparent;
  font-family: inherit;
  text-align: center;
  cursor: pointer;
  transition: background-color 0.4s cubic-bezier(0.2, 0.7, 0.2, 1),
    border-color 0.4s cubic-bezier(0.2, 0.7, 0.2, 1),
    box-shadow 0.4s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.ax-zoom-step .lv {
  display: block;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--foreground-fg-tertiary);
}
.ax-zoom-step .nm {
  display: block;
  margin-top: 2px;
  font-size: 14.5px;
  font-weight: 700;
  color: var(--foreground-fg-primary);
  transition: color 0.4s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.ax-zoom-step .ds {
  display: block;
  margin-top: 3px;
  font-size: 12px;
  line-height: 1.45;
  color: var(--foreground-fg-tertiary);
}
/* "2026 예정" status flag on the levels that have not shipped yet. Its own line under the
   description so it reads as a status footnote rather than part of the name; .ax-b is inline-flex,
   so the button's text-align:center places it. */
.ax-zoom-step .sc {
  margin-top: 8px;
}
.ax-zoom-step.is-active {
  background: var(--ax-surface);
  border-color: var(--primary-300);
  box-shadow: var(--shadow-xs-0);
}
.ax-zoom-step.is-active .nm {
  color: var(--foreground-fg-brand);
}
.ax-zoom-step:focus-visible {
  outline: 2px solid var(--border-border-brand);
  outline-offset: 2px;
}

/* Hero: no scroll, no draw, no bob — the console renders in its finished state and the
   tilt is kept as a static angle (a transform is not motion). */
@media (prefers-reduced-motion: reduce) {
  .ax-ticker-lane,
  .ax-hc-float {
    animation: none;
  }
  .ax-hc-seg,
  .ax-hc-bar,
  .ax-hc-seat .rail i {
    animation: none;
    transform: scaleX(1) scaleY(1);
  }
  .ax-hc-line {
    animation: none;
    stroke-dashoffset: 0;
  }
  .ax-hc-card,
  .ax-hc-float,
  .ax-hc-panel {
    transition: none;
  }
  .ax-hc-float:has(.ax-hc-float-hit:hover) {
    transform: none;
  }
}

/* Static, single-state rendering when motion is not wanted (intro.js also skips
   the auto-cycle, so whatever the reader lands on simply stays put). */
@media (prefers-reduced-motion: reduce) {
  .ax-zoom-frame,
  .ax-zoom-flabel,
  .ax-zoom-bridge line,
  .ax-zoom-step,
  .ax-zoom-step .nm,
  .ax-zoom-log {
    transition: none;
  }
  .ax-zoom-frame.is-active {
    transform: none;
    box-shadow: none;
  }
}/* ══════════════════════════════════════════════════════════════════════════
   PROBLEM LIST (quote-style)
   ══════════════════════════════════════════════════════════════════════════ *//* ══════════════════════════════════════════════════════════════════════════
   PLATFORM TABLE
   ══════════════════════════════════════════════════════════════════════════ */
.ax-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.ax-chip {
  padding: 4px 10px;
  border-radius: var(--border-radius-radius-2xs, 3px);
  background: var(--background-bg-brand-light);
  color: var(--foreground-fg-brand);
  font-size: 12px;
  font-weight: 600;
}

/* ══════════════════════════════════════════════════════════════════════════
   기능 밴드 — one full-bleed band per feature (reference: axgenticlens-features-4.html, B안)

   The zigzag is the same as before; what is new are the three devices that mark the boundary
   between two features, so that no divider is needed:
     ① background alternation — odd bands sit on --ax-surface, even bands on --ax-canvas
     ② a numbered header line — "01 — DASHBOARD" + a gradient rule running to the right edge
     ③ an oversized ghost number bleeding off the top corner (right on odd, left on even)
   Reference hexes map to project tokens: primary #6750E0 → --primary-600, 연보라 #B9AEF3 →
   --primary-200, soft #F8F9FC → --ax-canvas (--background-bg-primary, #f9fafb).
   ══════════════════════════════════════════════════════════════════════════ */
.ax-band {
  position: relative;
  padding-block: 96px;
  /* Clips the ghost number's deliberate overhang. */
  overflow: hidden;
  background: var(--ax-surface);
}
.ax-band--alt {
  background: var(--ax-canvas);
}
/* Ghost number: a background element, never an overlay. It is pinned to z-index 0 while the
   band's content sits at 1, so it can never wash over a heading, a table or a capture. */
/* Gradient fade top→bottom via background-clip:text, not a flat tint — the number reads as a
   watermark printed into the band rather than a pale glyph sitting on it. */
.ax-band-ghost {
  position: absolute;
  z-index: 0;
  top: 20px;
  right: -10px;
  font-size: clamp(140px, 19vw, 260px);
  font-weight: 800;
  line-height: 0.85;
  letter-spacing: -0.05em;
  font-variant-numeric: tabular-nums;
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--primary-600) 10%, transparent),
    color-mix(in srgb, var(--primary-600) 2%, transparent)
  );
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  pointer-events: none;
  user-select: none;
}
.ax-band--rev .ax-band-ghost {
  right: auto;
  left: -10px;
}
.ax-band-in {
  position: relative;
  z-index: 1;
}
.ax-band-head {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 52px;
}
.ax-band-no {
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.12em;
  color: var(--foreground-fg-brand);
  white-space: nowrap;
}
.ax-band-rule {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, var(--primary-200), transparent);
}
.ax-band-grid {
  display: grid;
  grid-template-columns: 0.92fr 1.08fr;
  gap: 80px;
  align-items: center;
  position: relative;
}
/* Even bands mirror the row: visual left, copy right. */
.ax-band--rev .ax-band-grid {
  grid-template-columns: 1.08fr 0.92fr;
}
.ax-band--rev .ax-band-txt {
  order: 2;
}
.ax-band-txt h3 {
  margin: 0;
  font-size: clamp(26px, 3.2vw, 40px);
  font-weight: 800;
  line-height: 1.25;
  letter-spacing: -0.02em;
  word-break: keep-all;
}
/* Status flag beside a band title (e.g. 2026 예정): sized independently of the display-scale
   heading and nudged up so it sits with the cap height, not the baseline. */
.ax-band-txt h3 .ax-b {
  position: relative;
  top: -0.28em;
  margin-left: 6px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0;
  vertical-align: middle;
}
.ax-band-txt p {
  max-width: 460px;
  margin-top: 16px;
  font-size: 15.5px;
  line-height: 1.8;
  color: var(--foreground-fg-secondary);
  word-break: keep-all;
}
/* Roadmap note under a band's lead paragraph — the band ships today, but one part of it is
   still ahead (플랫폼 종합 Dashboard). Same badge vocabulary as the roadmap cards. The selector
   is qualified to clear `.ax-band-txt p` above, which owns the lead paragraph's size/colour. */
.ax-band-txt p.ax-band-note {
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: 460px;
  margin-top: 12px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--foreground-fg-tertiary);
}
.ax-band-tags {
  margin-top: 22px;
}
/* Pill, unlike the square .ax-chip used INSIDE the mock panels — the two sit close together in
   a band, and the shape difference is what separates "this feature's tags" from "chips drawn in
   the product replica". */
.ax-band-tags .ax-chip {
  border-radius: 999px;
  padding: 5px 12px;
}
/* ── Collage mockup (reference: axgenticlens-band-refined_5.html) ────────────────────────
   Two screens overlap instead of stacking, so the visual column keeps the copy column's
   height: a main shot top-left, a sub shot dropped to 34% so it clearly overlaps the main's
   lower half, and one floating chip on top. Depth is carried by three shadow tiers
   (main < sub < chip) and z-index only — never rotation. */
.ax-collage {
  position: relative;
  min-height: 560px;
}
/* The shots are absolutely positioned, so the box cannot size to its content: each band that
   ends higher (or lower) than the 560px default states its own height, keeping the slack under
   the stack at roughly 20px everywhere. */
.ax-collage--tall {
  min-height: 592px;
}
.ax-collage--mid {
  min-height: 500px;
}
.ax-collage--short {
  min-height: 435px;
}
/* Violet light pooled behind the stack, so the shots read as lifted off the band. */
.ax-collage::before {
  content: "";
  position: absolute;
  inset: -8% -6%;
  pointer-events: none;
  background: radial-gradient(
    ellipse 60% 55% at 50% 45%,
    color-mix(in srgb, var(--primary-400) 14%, transparent),
    transparent 70%
  );
}
.ax-shot {
  position: absolute;
  display: grid;
  gap: 12px;
  padding: 20px;
  border: 1px solid var(--ax-line);
  border-radius: var(--ax-r-card);
  background: var(--ax-surface);
}
.ax-shot--main {
  top: 0;
  left: 0;
  width: 78%;
  z-index: 2;
  box-shadow: 0 24px 60px -18px color-mix(in srgb, var(--surface-violet-deep) 28%, transparent),
    0 4px 16px color-mix(in srgb, var(--surface-violet-deep) 8%, transparent);
}
/* The overlap is tuned ONLY by this top% — the widths stay fixed. */
.ax-shot--sub {
  top: 34%;
  right: 0;
  width: 62%;
  z-index: 3;
  box-shadow: 0 18px 48px -16px color-mix(in srgb, var(--surface-violet-deep) 30%, transparent),
    0 3px 12px color-mix(in srgb, var(--surface-violet-deep) 8%, transparent);
}
/* Wider sub for a table whose first column holds full email addresses (06 배분 이력) — at 62%
   the four columns crowded and the numbers stopped lining up. */
.ax-shot--sub.ax-shot--wide {
  width: 76%;
}
/* One band drops its sub lower still (05): the over-chip sits on the main shot's top edge, so
   the sub has to clear the taller main card without leaving a gap under itself. */
.ax-collage--low {
  min-height: 440px;
}
.ax-collage--low .ax-shot--sub {
  top: 55%;
}
.ax-shot-h {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11.5px;
  font-weight: 700;
  color: var(--foreground-fg-secondary);
}
.ax-shot-h .ax-mock-badge {
  padding: 1px 8px;
  font-size: 9.5px;
  line-height: 14px;
}
.ax-shot-h .ax-mock-badge-logo {
  width: 10px;
  height: 10px;
}
/* Floating chip — the one figure worth reading before the shots. */
.ax-fchip {
  position: absolute;
  z-index: 4;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 11px 15px;
  border: 1px solid var(--ax-line);
  border-radius: var(--border-radius-radius-l, 12px);
  background: var(--ax-surface);
  box-shadow: 0 12px 32px -10px color-mix(in srgb, var(--surface-violet-deep) 25%, transparent);
}
/* Chip anchors: bottom-left is the default, with --under / --over for the two bands whose
   stacks leave no room there. */
.ax-fchip--bl {
  bottom: 6%;
  left: 2%;
}
/* 01 DASHBOARD only: its stack is the tallest, so the chip is raised clear of the sub shot's
   bottom edge and pushed past the collage's left edge to sit against the copy column. */
.ax-fchip--lift {
  bottom: calc(6% + 70px);
  left: calc(2% - 20px);
}
/* Below the main shot, clear of the sub — for bands where the chip at 48% covered the sub's
   content instead of framing it (03 Tool). Left-aligned under the main shot's own column, and
   low enough that no dead band is left under it. */
.ax-fchip--under {
  top: 83%;
  left: 0;
}
/* Straddles the BOTTOM-LEFT corner of the main shot (05 비용 관리 · 조직 배분 현황): left of the
   sub shot, so it nicks the card it belongs to instead of blanketing the one underneath. */
.ax-fchip--over {
  top: calc(58% + 120px);
  left: -30px;
}
/* Phone: the collage narrows until the chip is wider than the sub's own left offset, so the
   card's bottom-left corner sits inside the sub — the chip there would cover its month-label
   column. Raised clear above the sub's top edge instead; the corner anchor returns above 520px. */
@media (max-width: 520px) {
  .ax-fchip--over {
    top: 38%;
  }
}
.ax-fchip-ic {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  border-radius: 8px;
  background: var(--badge-background-bg-danger-light, var(--background-bg-brand-light));
  color: var(--semantic-red-500);
  font-size: 14px;
}
.ax-fchip-ic--brand {
  background: var(--background-bg-brand-light);
  color: var(--foreground-fg-brand);
}
.ax-fchip b {
  display: block;
  font-size: 13px;
  line-height: 1.25;
}
.ax-fchip span {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--foreground-fg-tertiary);
}

/* ── Shot internals ── */
.ax-srow {
  display: grid;
  grid-template-columns: 1.15fr 0.55fr 0.55fr 0.8fr;
  gap: 8px;
  align-items: center;
  padding: 7px 8px;
  border-bottom: 1px solid var(--ax-line);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}
.ax-srow--h {
  font-size: 10px;
  font-weight: 700;
  color: var(--foreground-fg-tertiary);
}
/* Wider first column for a table whose leading value is a full email address (06 배분 이력). */
.ax-srow--wide {
  grid-template-columns: 1.9fr 0.7fr 0.6fr 0.6fr;
}
/* Same row highlight the console table uses. */
.ax-srow:not(.ax-srow--h):hover {
  background: var(--background-bg-table-hover);
}
/* First column of a data row carries a name/label — it stays left. */
.ax-srow > :first-child {
  text-align: left;
}
.ax-srow > :not(:first-child) {
  text-align: center;
}
/* EVERY header label is centred, including the first — sk-table-local's `align` defaults to
   center and a left-aligned column keeps a centred header (rules/06 §6.6.3). Declared after the
   data-cell rules above because they share specificity. */
.ax-srow--h > *,
.ax-srow--h > :first-child {
  text-align: center;
}
.ax-srow b {
  font-weight: 700;
}
.ax-srow .is-bad {
  color: var(--semantic-red-500);
}
.ax-srow .is-warn {
  color: var(--semantic-orange-500);
}
/* Mini trend chart inside a shot. */
.ax-mline {
  position: relative;
  height: 78px;
  border: 1px solid var(--ax-line);
  border-radius: 8px;
  overflow: hidden;
}
.ax-mline-t {
  position: absolute;
  top: 7px;
  left: 10px;
  font-size: 10px;
  font-weight: 700;
  color: var(--foreground-fg-secondary);
}
.ax-mline svg {
  position: absolute;
  left: 8px;
  right: 8px;
  bottom: 6px;
  width: calc(100% - 16px);
  height: 46px;
}
.ax-mline path {
  fill: none;
  stroke-width: 1.8;
  stroke-linecap: round;
}
/* 4-cell status strip. Padding is asymmetric (11/10) and the label gap 3px so the pair reads
   optically centred against the taller number. */
.ax-strip {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
  align-items: center;
  padding: 11px 6px 10px;
  border: 1px solid var(--ax-line);
  border-radius: 8px;
  background: var(--ax-canvas);
}
.ax-strip div {
  text-align: center;
}
.ax-strip b {
  display: block;
  font-size: 14px;
  font-weight: 800;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}
.ax-strip span {
  display: block;
  margin-top: 3px;
  font-size: 9px;
  font-weight: 600;
  color: var(--foreground-fg-tertiary);
}
.ax-strip .is-bad {
  color: var(--semantic-red-500);
}
.ax-strip .is-warn {
  color: var(--semantic-orange-500);
}
/* Cost composition: headline + segmented stack + legend. */
.ax-cost {
  display: grid;
  gap: 7px;
  padding: 10px 12px;
  border: 1px solid var(--ax-line);
  border-radius: 8px;
}
.ax-cost-l {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.ax-cost-l > span {
  font-size: 10px;
  font-weight: 700;
  color: var(--foreground-fg-secondary);
}
.ax-cost-l > b {
  font-size: 9.5px;
  font-weight: 600;
  color: var(--foreground-fg-tertiary);
}
.ax-cost-l em {
  font-style: normal;
  font-size: 11px;
  font-weight: 800;
  color: var(--foreground-fg-primary);
}
.ax-cost-l em.is-pct {
  color: var(--semantic-red-500);
}
.ax-cost-seg {
  display: flex;
  gap: 1.5px;
  height: 10px;
  border-radius: 5px;
  overflow: hidden;
}
.ax-cost-seg i {
  display: block;
  height: 100%;
}
.ax-cost-lg {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.ax-cost-lg span {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 9px;
  font-weight: 600;
  color: var(--foreground-fg-secondary);
}
.ax-cost-lg i {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 2px;
}
/* Labelled bar rows (사용자 Top 10, 도구 종류별 집계 …). */
/* ONE grid for the whole list (rows are display:contents) so the three columns are shared
   tracks: the value track is max-content, which makes every bar start and end at the same x —
   with a per-row flex box the bars drifted a few px apart whenever the values differed in
   length, which is fatal for a chart whose only variable is bar length. */
.ax-ulist {
  display: grid;
  grid-template-columns: clamp(64px, 32%, 108px) minmax(52px, 1fr) max-content;
  align-items: center;
  column-gap: 9px;
  row-gap: 8px;
}
.ax-ulist--tight {
  grid-template-columns: clamp(28px, 12%, 44px) minmax(52px, 1fr) max-content;
}
.ax-ulist-h {
  grid-column: 1 / -1;
  display: flex;
  justify-content: space-between;
  padding-bottom: 2px;
  font-size: 9.5px;
  font-weight: 700;
  color: var(--foreground-fg-tertiary);
}
.ax-ulist-row {
  display: contents;
  font-size: 10.5px;
}
/* The label track is PROPORTIONAL (clamped), not fixed: these lists sit in a collage shot whose
   width tracks the viewport, and with a fixed 108px label the bar — the only flexible track —
   was the first to collapse (33px at 1030px, 2px on a phone). */
.ax-ulist-row > span:first-child {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
  color: var(--foreground-fg-secondary);
}
.ax-ulist-g {
  min-width: 0;
  height: 9px;
  border: 1px solid var(--ax-line);
  border-radius: 5px;
  background: var(--ax-canvas);
  overflow: hidden;
}
.ax-ulist-g i {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--primary-400), var(--primary-800));
}
.ax-ulist-g i.is-bad {
  background: var(--semantic-red-400);
}
/* The value keeps its "536% (2,682/500)" on ONE line — hence the nowrap; the max-content track
   above sizes to the longest one in the list. */
.ax-ulist-row > b {
  text-align: right;
  font-size: 10.5px;
  white-space: nowrap;
}
.ax-ulist-row > b small {
  margin-left: 2px;
  font-size: 8.5px;
  font-weight: 600;
  color: var(--foreground-fg-tertiary);
}
.ax-ulist-row > b.is-bad {
  color: var(--semantic-red-500);
}
/* Phone: the parenthetical (96,200/110,000) is the only part of these mock rows that cannot
   shrink, and keeping it would starve the bar again. The percentage carries the point. */
@media (max-width: 520px) {
  .ax-ulist-row > b small {
    display: none;
  }
}

/* ── Collage reveal: main -> sub -> chip, then the chip alone keeps floating ── */
.ax-anim .ax-rvi {
  opacity: 0;
  transform: translateY(20px) scale(0.98);
  transition: opacity 0.7s cubic-bezier(0.2, 0.6, 0.2, 1), transform 0.7s cubic-bezier(0.2, 0.6, 0.2, 1);
}
.ax-anim .ax-reveal.is-in .ax-rvi {
  opacity: 1;
  transform: none;
}
.ax-collage .ax-shot--main {
  transition-delay: 0.05s;
}
.ax-collage .ax-shot--sub {
  transition-delay: 0.18s;
}
.ax-collage .ax-fchip {
  transition-delay: 0.32s;
}
@keyframes ax-floaty {
  0%,
  100% {
    translate: 0 0;
  }
  50% {
    translate: 0 -7px;
  }
}
.ax-anim .ax-reveal.is-in .ax-fchip {
  animation: ax-floaty 6s ease-in-out 1.2s infinite;
}
@media (prefers-reduced-motion: reduce) {
  .ax-rvi {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .ax-reveal.is-in .ax-fchip {
    animation: none;
  }
}

/* Grid items default to min-width:auto — without this the collage's absolutely-positioned
   shots would size the column off their content instead of the grid track. */
.ax-band-vis {
  min-width: 0;
}
/* Several hero cards stacked in one shot — they are separate cards, so they need air between
   them (in the hero the parent grid supplied it). */
.ax-hc--cards {
  display: grid;
  gap: 10px;
}
/* 주기말 예상 사용량: the 부족 chip is pushed to the card's right edge here (value left,
   chip right) — the shot is narrower than the hero card, so trailing the value directly
   left it stranded mid-card. */
.ax-hc--cards .ax-hc-kv .ax-hc-chip {
  margin-left: auto;
}
/* The console shell is reused only as a style context here — no chrome bar, no lift, no border
   of its own (the .ax-shot frame around it already provides those). */
.ax-hc--bare {
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  overflow: visible;
}
.ax-hc--bare .ax-hc-chart {
  /* Taller than in the hero, where the card shares a 3-column grid with five others. */
  min-height: 208px;
}
.ax-cap-logs {
  display: grid;
  gap: 6px;
}
@media (max-width: 1024px) {
  .ax-band {
    padding-block: 64px;
  }
  .ax-band-grid,
  .ax-band--rev .ax-band-grid {
    grid-template-columns: 1fr;
    gap: 44px;
  }
  .ax-collage {
    min-height: 440px;
  }
  /* Stacked: copy always leads its own visual again. */
  .ax-band--rev .ax-band-txt {
    order: 0;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   CONSOLE MOCKUP — HTML/CSS/SVG replica of the real product.
   Everything inside keeps the console's own tight radius + 12/14px type.
   ══════════════════════════════════════════════════════════════════════════ */
.ax-mock {
  border: 1px solid var(--ax-line);
  border-radius: var(--border-radius-radius-l, 10px);
  background: var(--ax-surface);
  box-shadow: var(--shadow-m-0);
  overflow: hidden;
  font-size: 12px;
}
/* Same anatomy as the console's own page-title badge (.gnb-badge in layout/layout.css):
   22px pill, 4px gap, 12/500 white label. Kept at 11px here because the mock chrome runs one
   step smaller than the real GNB. A non-brand label (플랫폼 관리, 원본 기록…) keeps the default
   purple pill and has no glyph. */
.ax-mock-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 8px;
  border-radius: 20px;
  background: var(--primary-600);
  color: var(--neutral-white);
  font-size: 11px;
  font-weight: 500;
  line-height: 14px;
  white-space: nowrap;
}
/* Brand pills use the console's own brand background tokens. */
.ax-mock-badge--chatgpt {
  background: var(--badge-background-bg-primary);
}
.ax-mock-badge--claude {
  background: var(--badge-background-bg-warning);
}
/* Masked SVG painted in the pill's white text colour — the same technique the console badge
   and .exmp-icon-info-filled use, so one asset serves both light and dark.
   Shared by the two badge families so each brand asset is declared ONCE (rules/05 §5.4): the
   screenshot mock pills (.ax-mock-badge, 11px text) and the hero console chrome pill
   (.ax-hc-badge, 10px text) — the smaller pill just overrides the size hook. */
.ax-mock-badge-logo,
.ax-hc-badge-logo {
  width: var(--ax-mock-badge-logo-size, 13px);
  height: var(--ax-mock-badge-logo-size, 13px);
  flex-shrink: 0;
  background-color: currentColor;
  -webkit-mask: var(--ax-mock-badge-logo-img) center / contain no-repeat;
  mask: var(--ax-mock-badge-logo-img) center / contain no-repeat;
}
.ax-hc-badge-logo {
  --ax-mock-badge-logo-size: 11px;
}
.ax-mock-badge--chatgpt .ax-mock-badge-logo,
.ax-hc-badge--gpt .ax-hc-badge-logo {
  --ax-mock-badge-logo-img: url("../icons/logo-chatgpt.svg");
}
.ax-mock-badge--claude .ax-mock-badge-logo,
.ax-hc-badge--claude .ax-hc-badge-logo {
  --ax-mock-badge-logo-img: url("../icons/logo-claude.svg");
}

/* Mock panel (chart container) */
.ax-panel {
  border: 1px solid var(--ax-line);
  border-radius: var(--border-radius-radius-2xs, 3px);
  background: var(--ax-surface);
  padding: 14px;
}

/* Mock data table — mirrors sk-table-local */
.ax-tbl {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
}
.ax-tbl th {
  padding: 9px 10px;
  text-align: center;
  font-weight: 500;
  font-size: 11.5px;
  color: var(--foreground-fg-table-header);
  /* Must FLIP with the theme: --foreground-fg-table-header goes white on dark, so a fixed
     --neutral-50 here rendered white-on-white. This is the token the console's own table
     header uses. */
  background: var(--background-bg-primary);
  border-bottom: 1px solid var(--ax-line);
  white-space: nowrap;
}
.ax-tbl td {
  padding: 10px;
  text-align: center;
  border-bottom: 1px solid var(--ax-line-soft);
  color: var(--foreground-fg-secondary);
  white-space: nowrap;
}
.ax-tbl td.is-left,
.ax-tbl th.is-left {
  text-align: left;
}
.ax-tbl td.is-right {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.ax-tbl tbody tr:last-child td {
  border-bottom: 0;
}
.ax-tbl tbody tr:hover td {
  background: var(--background-bg-table-hover);
}

/* Mock badge — same soft palette as the console's sk-badge */
.ax-b {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: var(--border-radius-radius-2xs, 3px);
  font-size: 11px;
  font-weight: 600;
  line-height: 16px;
  white-space: nowrap;
}
.ax-b--primary {
  background: var(--badge-background-bg-primary-light);
  color: var(--badge-foreground-label-brand);
}
.ax-b--success {
  background: var(--badge-background-bg-success-light);
  color: var(--badge-foreground-label-success);
}
.ax-b--neutral {
  background: var(--badge-background-bg-neutral-light);
  color: var(--badge-foreground-label-neutral);
}/* ══════════════════════════════════════════════════════════════════════════
   FEATURE PAGE PARTS
   ══════════════════════════════════════════════════════════════════════════ */

/* ══════════════════════════════════════════════════════════════════════════
   FOOTER — three tonal layers (reference: agenticlens-footer-clean_5.html)

   ① .ax-footer-band  full-bleed CTA, lightest violet
   ② .ax-footer-mid   footer body gradient + two soft light sources
   ③ .ax-footer-legal fine print

   Separation is by TONE, not by rules: the whole footer carries exactly ONE border, above ③.
   The light page section above needs no border-top either — the colour step is the boundary.
   Every colour is pinned to the --primary-* ramp / the violet surface tokens rather than the
   theme-swapping semantics, because this surface is dark in BOTH themes.
   Contrast on the darkest stop: nav 10.2:1, legal 7.3:1, band title 16:1 — all past WCAG AA.
   ══════════════════════════════════════════════════════════════════════════ */
.ax-footer {
  position: relative;
  overflow: hidden;
  /* Nearest project tokens to the reference's deep-violet pair (191046 → 120B33). */
  background: linear-gradient(180deg, var(--primary-950), var(--surface-violet-deep));
  padding-block: 0 40px;
}
/* Two light sources — kept gentle because the surface is already violet. */
.ax-footer::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(
      ellipse 45% 55% at 12% 0%,
      color-mix(in srgb, var(--primary-400) 18%, transparent),
      transparent 60%
    ),
    radial-gradient(ellipse 40% 50% at 92% 100%, color-mix(in srgb, var(--primary-800) 30%, transparent), transparent 60%);
}
/* Lift every layer above the ::before wash. */
.ax-footer > * {
  position: relative;
}

/* ── ① CTA band ─────────────────────────────────────────────────────────────
   Full-bleed colour field; only the content inside is held to the content column, so the
   band reads as a layer of the page rather than a card. No glow/border/radius/shadow. */
.ax-footer-band {
  background: linear-gradient(120deg, var(--surface-violet-band-a), var(--surface-violet-band-b));
}
.ax-footer-band-in {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 32px;
  /* Band height +40% (user request 2026-08-26): 126px -> 176px. The row content is 38px, so the
     vertical padding carries the whole increase — 44 -> 69 each side. */
  padding: 69px 0;
}
.ax-footer-band-in h2 {
  font-size: clamp(20px, 2.4vw, 29px);
  font-weight: 800;
  line-height: 1.3;
  letter-spacing: -0.02em;
  color: var(--neutral-white);
  word-break: keep-all;
}
/* The email link is the band's only action — no button. */
.ax-footer-mail {
  flex-shrink: 0;
  font-size: 15px;
  color: var(--primary-300);
}
.ax-footer-mail a {
  font-weight: 600;
  color: var(--primary-100);
  border-bottom: 1px solid color-mix(in srgb, var(--primary-100) 40%, transparent);
  transition: color 0.15s ease, border-color 0.15s ease;
}
.ax-footer-mail a:hover,
.ax-footer-mail a:focus-visible {
  color: var(--neutral-white);
  border-color: var(--neutral-white);
}

/* ── ② Logo · nav, one row ─────────────────────────────────────────────────── */
.ax-footer-mid {
  margin-top: 52px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 40px;
}
.ax-footer-links {
  display: flex;
  flex-wrap: wrap;
  /* Baseline, not the flex default: Latin-only labels sit on a shorter line box than the
     Korean ones and rendered 8px high in the row. */
  align-items: baseline;
  gap: 12px 34px;
}
.ax-footer-links a {
  font-size: 13.5px;
  font-weight: 500;
  color: var(--primary-200);
  transition: color 0.15s ease;
}
.ax-footer-links a:hover {
  color: var(--neutral-white);
}

/* ── ③ The one divider + legal information ─────────────────────────────────── */
.ax-footer-legal {
  margin-top: 36px;
  padding-top: 24px;
  border-top: 1px solid var(--ax-violet-line);
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--primary-300);
}
.ax-footer-corp {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 0;
  margin: 0;
  font-style: normal; /* <address> italicises by default */
}
/* Field separators drawn in CSS so they are decoration, not content — and so a wrapped row
   never starts with a stray "|". */
.ax-footer-corp span + span::before {
  content: "|";
  margin: 0 12px;
  color: color-mix(in srgb, var(--primary-300) 40%, transparent);
}
.ax-footer-legal-row {
  margin-top: 10px;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px 24px;
}
/* Half a tone under the legal text — it is an aside about the mock data, not a legal notice. */
.ax-footer-note {
  margin-left: auto;
  color: color-mix(in srgb, var(--primary-300) 72%, var(--surface-violet-deep));
}

/* Phone: each of the three layers stacks. */
@media (max-width: 900px) {
  .ax-footer-band-in {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
    /* Scaled by the same ratio as the desktop padding. */
    padding: 50px 0;
  }
  .ax-footer-mid {
    flex-direction: column;
    align-items: flex-start;
    gap: 24px;
  }
  .ax-footer-legal-row {
    flex-direction: column;
    gap: 6px;
  }
  .ax-footer-note {
    margin-left: 0;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   MOTION — scroll reveal. Respects prefers-reduced-motion.
   ══════════════════════════════════════════════════════════════════════════ */
/* Reveal is OPT-IN: the hidden state only applies once the page JS has confirmed it can
   actually drive the animation (IntersectionObserver present AND a real viewport). Without
   that confirmation — no JS, IO unavailable, or a zero-sized viewport — content simply
   renders visible. Hiding by default would risk a permanently blank page. */
.ax-anim .ax-reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.6s cubic-bezier(0.22, 1, 0.36, 1),
    transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
.ax-anim .ax-reveal.is-in {
  opacity: 1;
  transform: none;
}
.ax-anim .ax-reveal[data-delay="1"] { transition-delay: 0.07s; }
.ax-anim .ax-reveal[data-delay="2"] { transition-delay: 0.14s; }
.ax-anim .ax-reveal[data-delay="3"] { transition-delay: 0.21s; }

/* SVG line-draw for the trend chart — same opt-in rule as .ax-reveal */
.ax-anim .ax-spark path.ln {
  stroke-dasharray: var(--len, 900);
  stroke-dashoffset: var(--len, 900);
  transition: stroke-dashoffset 1.4s cubic-bezier(0.22, 1, 0.36, 1);
}
.ax-anim .is-in .ax-spark path.ln,
.ax-anim .ax-spark.is-in path.ln {
  stroke-dashoffset: 0;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  .ax-reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .ax-spark path.ln {
    stroke-dasharray: none;
    stroke-dashoffset: 0;
    transition: none;
  }
}

/* Bold runs inside body copy lift to the primary ink (the surrounding text is secondary/tertiary),
   which is how the reference marks the one phrase that carries each card's point. */
.ax-lead b,
.ax-card p b {
  color: var(--foreground-fg-primary);
  font-weight: 700;
}/* ══════════════════════════════════════════════════════════════════════════
   DASHBOARD VIEW — product screenshots + the union-math explainer
   ══════════════════════════════════════════════════════════════════════════ */

/* ══════════════════════════════════════════════════════════════════════════
   RESPONSIVE
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 1024px) {
  /* Stacked: the third floating card has no gutter left to hang in. */
  .ax-hc-float--3 {
    display: none;
  }
  .ax-hero-stage {
    padding: 26px 16px 28px;
  }
  .ax-hc-float--1 {
    top: -14px;
    right: -8px;
  }
  /* Narrow: the console's bottom edge is where the platform switch and the 조직별 Credit
     사용률 rows are, so this card moves up beside the chart instead of hanging under it. */
  .ax-hc-float--2 {
    top: 44%;
    bottom: auto;
    left: -8px;
  }
  .ax-ticker {
    max-width: 100%;
  }
  /* Five frames in a row stop being legible here: drop the bridges (they only read as a
     chain when the frames are side by side) and wrap to two columns. */
  .ax-zoom {
    padding: 24px 14px 20px;
  }
  /* ONE LEVEL PER ROW — miniature on the left, its own label on the right.
     The previous narrow layout was a 2-column card grid with the six labels in a separate block
     underneath, so it read 01 / 23 / 45: a gallery, not a drill-down, and no card was visibly tied
     to the words that explain it (user report 2026-09-01). Pairing each card with its label on one
     row and running the levels top to bottom restores the L0→L5 reading the wide chain gets from
     its bridges.
     `display: contents` dissolves the two wrappers so the frames and the step buttons become items
     of ONE grid without touching the DOM (page JS still finds them under #axZoomChain / #axZoomSteps).
     `grid-auto-flow: dense` is what interleaves them: the six frames are pinned to column 1 and fill
     rows 1-6, then each step — pinned to column 2 — backfills the first row whose column 2 is free,
     i.e. its own. Dense keeps this working if a level is ever added or removed; explicit per-index
     grid-row rules would all have to be renumbered. */
  .ax-zoom {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-auto-flow: dense;
    align-items: center;
    column-gap: 18px;
    row-gap: 16px;
  }
  .ax-zoom-chain,
  .ax-zoom-steps {
    display: contents;
  }
  .ax-zoom-frame {
    grid-column: 1;
    min-height: 132px;
    position: relative;
  }
  /* Vertical dashed connector down to the next level. The horizontal bridges are hidden at this
     width, so this is what keeps the rows reading as one flow instead of a stack of cards; it is
     the bridge's dash pattern, turned 90°. */
  .ax-zoom-frame:not(:last-of-type)::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 100%;
    /* Exactly the 16px row-gap, so the line REACHES the next card instead of stopping short and
       reading as two unrelated marks (user report 2026-09-01). It was 12px to avoid nicking the
       card below; that gap is what broke the flow. */
    height: 16px;
    border-left: 1.5px dashed var(--ax-line);
  }
  /* (1) At rest the dash sits at --ax-line like the wide bridges, which is faint on dark. Light it
     in the SAME colour the card's own outline takes when it is hovered/active, so hovering a level
     lights the card and the line out of it as one gesture. */
  .ax-zoom-frame.is-active::after {
    border-left-color: var(--border-border-brand);
  }
  /* …but do NOT spread the skeleton into that extra height here. `align-content: space-between`
     earns its keep on the wide card, where the leftover is a few px; at 406x132 the leftover is
     30-50px and it lands entirely in the 2-3 gaps — the log lines drifted 18px apart and the tool
     card 28px (user report 2026-09-01). Centre the block instead: the gaps stay at the base 4px and
     the leftover splits evenly above and below, so the card still reads as filled rather than as
     content stacked at the top with a hole under it. */
  .ax-zoom-mk {
    align-content: center;
  }
  .ax-zoom-frame.is-active {
    transform: scale(1.03);
  }
  .ax-zoom-bridge {
    display: none;
  }
  /* The label now sits BESIDE its card rather than in a row of six, so it left-aligns against the
     card and has room for the description again (it was hidden when six labels shared one line). */
  .ax-zoom-step {
    grid-column: 2;
    text-align: left;
    /* +10px on the left: the label sits beside the card now, and its hover/active outline was
       running right up against the text (user report 2026-09-01). */
    padding: 10px 12px 10px 22px;
  }
  .ax-zoom-step .sc {
    margin-top: 6px;
  }
}

@media (max-width: 900px) {
  .ax-prob-panel {
    grid-template-columns: 1fr;
  }
  .ax-prob-col {
    border-left: 0;
    border-top: 1px solid var(--ax-line-soft);
  }
  .ax-prob-col:first-child {
    border-top: 0;
  }
}

@media (max-width: 860px) {
  .ax-nav-toggle {
    display: grid;
  }
  .ax-nav-links {
    position: absolute;
    top: 64px;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    margin: 0;
    padding: 10px var(--ax-gap) 16px;
    background: var(--ax-surface);
    border-bottom: 1px solid var(--ax-line);
    box-shadow: var(--shadow-m-0);
    display: none;
  }
  .ax-nav-links.is-open {
    display: flex;
  }
  .ax-nav-link {
    padding: 11px 12px;
  }
  /* Phone: the step row is down to the names. */
  .ax-zoom-step {
    /* Left inset kept (see the 1024px block) — only the other sides tighten on a phone. */
    padding: 10px 6px 10px 16px;
  }
  .ax-zoom-step .lv {
    display: none;
  }
  .ax-zoom-step .nm {
    font-size: 13px;
  }
}

@media (max-width: 560px) {
  .ax-hero-actions .ax-btn {
    flex: 1 1 100%;
  }
  .ax-tbl {
    min-width: 520px;
  }
}
