:root {
  color-scheme: dark;
  --ink: #edf0f6;
  --ink-soft: #c5cad7;
  --ink-muted: #a7adbd;
  --surface: #0b0d12;
  --surface-strong: rgba(19, 23, 34, 0.84);
  --surface-stronger: rgba(12, 15, 23, 0.92);
  --surface-tint: rgba(255, 255, 255, 0.04);
  --teal: #5a8799;
  --teal-deep: #131722;
  --teal-soft: rgba(255, 255, 255, 0.06);
  --amber: #e0b63a;
  --coral: #ef4e50;
  --lime: #83bf4f;
  --sky: #4da3dc;
  --blue: 0, 174, 239;
  --green: 120, 200, 0;
  --yellow: 244, 196, 0;
  --red: 230, 0, 18;
  --line: rgba(255, 255, 255, 0.09);
  --line-strong: rgba(255, 255, 255, 0.16);
  --shadow: 0 18px 60px rgba(0, 0, 0, 0.45);
  --radius: 18px;
  --control-radius: 12px;
  --max: 1180px;
  /* Width of the black backdrop column (body::after). Deliberately WIDER than the
     content band (--max): at 1.2x, the black extends 10% of --max beyond the
     content on EACH side, so headers/footers aren't flush against the black edge.
     Content bands still use --max — this only moves the backdrop. Still clamped by
     the viewport gutter at the use site, so on a viewport narrower than this the
     black simply runs to the gutter. */
  --backdrop-max: calc(var(--max) * 1.2);
  /* Guaranteed gradient margin on EACH side of the black backdrop. This is a
     FLOOR, not a fixed value: on wide screens the midpoint term below wins and
     the gradient grows well past this. Raised from an effective 8px — at a
     ~1300px viewport the old `100% - 16px` term won, leaving a sliver of colour
     that read as no gradient at all. */
  --edge-gradient: 48px;
  /* Actual painted width of the black backdrop, the SMALLER of:
       * the viewport minus a gradient margin on both sides (narrow screens), and
       * the MIDPOINT between --backdrop-max and the viewport (wide screens),
         which keeps the generous proportional gradient there.
     NB at ~1300px the content band (--max, 1180) plus two 48px margins nearly
     fills the window, so the black has only ~12px of breathing room beyond the
     content there. Wide viewports get both comfortably; narrow ones cannot fit
     both, and this resolves in favour of the visible gradient.
     HARD FLOOR: never narrower than the content band itself. Without the max()
     below, a ~1100px viewport gives content `100% - 32px` but a backdrop of
     `100% - 96px`, i.e. black 64px NARROWER than the text sitting on it — the
     copy would spill onto the gradient at both edges. Where the two compete, the
     content wins and the gradient shrinks to the plain gutter. */
  --backdrop-band: max(
    min(100% - 32px, var(--max)),
    min(100% - (2 * var(--edge-gradient)), calc((100% + var(--backdrop-max)) / 2))
  );
  --wordmarkH: 32px;
  --wordmarkOpacity: 0.88;
  --biasY: 0.36;
  --biasR: 0.34;
  --biasG: 0.34;
  --biasB: 0.36;
  --driftA: 26s;
  --grad-ui: linear-gradient(
    90deg,
    rgba(var(--blue), 0.16),
    rgba(var(--green), 0.14),
    rgba(var(--yellow), 0.12)
  );
  --grad-ui-strong: linear-gradient(
    90deg,
    rgba(var(--blue), 0.22),
    rgba(var(--green), 0.18),
    rgba(var(--yellow), 0.14)
  );
  --grad-border: rgba(255, 255, 255, 0.12);
  --grad-border-strong: rgba(255, 255, 255, 0.16);
  /* The four-CORNER brand gradient — yellow top-left, red top-right, green
     bottom-left, blue bottom-right (same corner assignment as body::before), NOT
     a left/right sweep. Shared by the "Ask kiLM" FAB glyph and the nav sub-menu
     hover so the two can't drift apart; change it here, not at either use site.
     Each corner ellipse reaches ~92% of the way across, with a 3-stop ramp:
     strongest at the corner, half-strength mid-way, clear at the far edge. The
     four then OVERLAP around the middle, so the centre reads as a pale blend
     rather than the dark base. Previously they were 75%x95% and died out at 62%,
     leaving a large near-black hole in the middle of the pill. Keep the reach and
     the mid stop in step — pulling either back re-opens that hole. */
  --grad-brand-corners:
    radial-gradient(
      ellipse 95% 118% at 0% 0%,
      rgba(var(--yellow), 0.95),
      rgba(var(--yellow), 0.42) 48%,
      transparent 92%
    ),
    radial-gradient(
      ellipse 95% 118% at 100% 0%,
      rgba(var(--red), 0.95),
      rgba(var(--red), 0.42) 48%,
      transparent 92%
    ),
    radial-gradient(
      ellipse 95% 118% at 0% 100%,
      rgba(var(--green), 0.95),
      rgba(var(--green), 0.42) 48%,
      transparent 92%
    ),
    radial-gradient(
      ellipse 95% 118% at 100% 100%,
      rgba(var(--blue), 0.95),
      rgba(var(--blue), 0.42) 48%,
      transparent 92%
    ),
    rgba(12, 15, 23, 0.92);
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  /* In-page anchor jumps (e.g. #contact, #auto-schema) must clear the FIXED
     header (nav ~72px + ticker ~28px) so the target section's heading isn't
     hidden underneath it. One rule offsets every fragment scroll on every page. */
  scroll-padding-top: 120px;
}

body {
  margin: 0;
  min-width: 320px;
  position: relative;
  overflow-x: hidden;
  background: radial-gradient(1200px 900px at 50% 40%, rgba(20, 24, 36, 0.95), rgba(11, 13, 18, 1) 70%), #0b0d12;
  color: var(--ink);
  font-family:
    Inter, "Noto Sans JP", "Hiragino Kaku Gothic ProN", "Yu Gothic", Meiryo,
    ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  line-height: 1.5;
}

body::before {
  position: fixed;
  inset: -140px;
  z-index: -2;
  pointer-events: none;
  content: "";
  mix-blend-mode: screen;
  filter: blur(10px) saturate(1.35) contrast(1.08);
  background:
    radial-gradient(1200px 950px at 8% 10%, rgba(var(--yellow), calc(var(--biasY) * 2.2)), rgba(var(--yellow), calc(var(--biasY) * 1.1)) 34%, transparent 68%),
    radial-gradient(1200px 950px at 92% 10%, rgba(var(--red), calc(var(--biasR) * 2.2)), rgba(var(--red), calc(var(--biasR) * 1.1)) 34%, transparent 68%),
    radial-gradient(1200px 950px at 8% 90%, rgba(var(--green), calc(var(--biasG) * 2.2)), rgba(var(--green), calc(var(--biasG) * 1.1)) 34%, transparent 68%),
    radial-gradient(1200px 950px at 92% 90%, rgba(var(--blue), calc(var(--biasB) * 2.2)), rgba(var(--blue), calc(var(--biasB) * 1.1)) 34%, transparent 68%),
    radial-gradient(1000px 760px at 50% 50%, rgba(26, 30, 46, 0.5), rgba(11, 13, 18, 0.92) 72%);
  animation: drift-ambience var(--driftA) ease-in-out infinite;
}

body::after {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  content: "";
  /* Layer 1 (TOPMOST — background layers paint first-listed on top): an opaque
     BLACK column spanning exactly the content/header band, so page content reads
     against flat black while the left/right margins keep the ambient gradient
     (body::before) and vignette below.
     Width is --backdrop-band (see :root): --backdrop-max (1.2 x --max, giving the
     content black breathing room so headers/footers aren't flush against the
     edge), then widened to the midpoint of the viewport so the remaining gradient
     margin is HALF what it was. Content bands still sit at --max — this only moves
     the backdrop, the layout is unchanged.
     It is `fixed` (inherited from this pseudo-element), so the column stays put
     while the page scrolls rather than banding as sections move. */
  background:
    linear-gradient(#000, #000) 50% 0 / var(--backdrop-band) 100% no-repeat,
    radial-gradient(1000px 800px at 50% 45%, rgba(0, 0, 0, 0.08), rgba(0, 0, 0, 0.32) 76%),
    linear-gradient(to bottom, rgba(0, 0, 0, 0.08), rgba(0, 0, 0, 0.22));
}

img,
svg {
  display: block;
  max-width: 100%;
}

a {
  color: inherit;
  text-decoration: none;
}

button,
input,
select,
textarea {
  font: inherit;
}

button {
  cursor: pointer;
}

.skip-link {
  position: fixed;
  top: 12px;
  left: 12px;
  z-index: 100;
  transform: translateY(-160%);
  background: var(--surface-strong);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 10px 14px;
}

.skip-link:focus {
  transform: translateY(0);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.site-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 50;
  background: linear-gradient(180deg, rgba(11, 13, 18, 0.86), rgba(11, 13, 18, 0.62));
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  backdrop-filter: blur(18px);
  transition:
    background 180ms ease,
    border-color 180ms ease,
    box-shadow 180ms ease;
}

.site-header.is-scrolled,
.site-header.is-open {
  background: rgba(11, 13, 18, 0.9);
  border-bottom: 1px solid var(--line);
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.24);
}

/* Brand tagline ticker — a thin bar pinned under the nav, inside the fixed
   header so it floats consistently on every page. The tagline scrolls
   right-to-left in a seamless loop (two identical halves shifted by -50%). */
.site-ticker {
  overflow: hidden;
  border-top: 1px solid var(--line);
  /* Echo the page's four-corner brand gradient (yellow / red / green / blue —
     the same palette as body::before) as a horizontal band, so the ticker reads
     as part of the page background rather than a separate stripe. */
  background: linear-gradient(
    90deg,
    rgba(var(--yellow), 0.16),
    rgba(var(--red), 0.14),
    rgba(var(--green), 0.14),
    rgba(var(--blue), 0.16)
  );
}

.site-ticker-track {
  display: flex;
  align-items: center;
  width: max-content;
  padding: 7px 0;
  animation: ticker-scroll 38s linear infinite;
}

.site-ticker:hover .site-ticker-track {
  animation-play-state: paused;
}

.site-ticker-text {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-soft);
  white-space: nowrap;
}

.site-ticker-sep {
  margin: 0 2.25rem;
  font-size: 0.6rem;
  color: var(--amber);
  opacity: 0.75;
}

:lang(ja) .site-ticker-text {
  letter-spacing: 0.12em;
  text-transform: none;
}

/* Current-section strip — sits directly under the ticker and names the section
   being read. FIXED + centred on the viewport (not absolute inside the header):
   as an absolute child its horizontal centring depended on the header being its
   offset parent AND full-width, and any ancestor establishing a containing block
   (a transform/filter/backdrop-filter) silently shifted `left:0/right:0` off the
   viewport edges — the pill drifted to the right half. `position: fixed` +
   `left: 50%` + `translateX(-50%)` centres on the viewport regardless of any
   ancestor's box, so it can't drift. The vertical offset (`top`) is set from the
   live header height by positionSectionIndicator() in site.js, preserving the
   old "hangs under the ticker" placement without growing the header (its height
   still feeds `scroll-padding-top`). Hidden until a section is current, and
   pointer-events:none so it never intercepts clicks on the content beneath. */
.section-indicator {
  position: fixed;
  top: var(--section-indicator-top, 112px);
  left: 50%;
  z-index: 49; /* just beneath the fixed header (z-index: 50) */
  display: flex;
  justify-content: center;
  pointer-events: none; /* never intercept clicks on the content beneath */
  opacity: 0;
  transform: translateX(-50%) translateY(-4px);
  transition: opacity 0.25s ease, transform 0.25s ease;
}

.section-indicator.is-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

.section-indicator-label {
  /* VIEWPORT-relative cap, not `100%`: the parent (.section-indicator) is now
     position:fixed + shrink-to-fit, so a `100%` here resolved against the pill's
     OWN content width — a circular constraint that mis-sized the box and let the
     text spill. `100vw - 32px` is stable and never depends on the label itself. */
  max-width: min(100vw - 32px, var(--max));
  overflow: hidden;
  padding: 6px 16px;
  /* A self-contained floating chip (fully rounded, bordered, shadowed) now that
     it is detached from the ticker — the old flat-top / rounded-bottom "tab" only
     read correctly when it butted against the ticker as an absolute child.
     Same four-corner brand gradient as the "Ask kiLM" FAB glyph and the nav
     sub-menu hover (see --grad-brand-corners), so the brand-coloured surfaces
     read as one family. Full-ink text for legibility over the fill. */
  border: 1px solid var(--grad-border-strong);
  border-radius: 999px;
  background: var(--grad-brand-corners);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
  color: var(--ink);
  /* line-height:1 keeps the uppercase text tightly boxed so it cannot bleed past
     the chip's vertical edges. */
  line-height: 1;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-overflow: ellipsis;
  white-space: nowrap;
}

:lang(ja) .section-indicator-label {
  letter-spacing: 0.08em;
  text-transform: none;
}

@keyframes ticker-scroll {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-50%);
  }
}

/* Reduced motion: the ticker is intentionally KEPT scrolling — it's a slow,
   steady, non-flashing brand marquee (no parallax, no flashing), so it's a safe
   exception. The shorthand + !important re-asserts it over the global
   reduced-motion reset further down in this file (which would otherwise freeze
   it via `animation-duration: 0.01ms !important`). Everything else on the page
   still fully honours the reduced-motion preference. */
@media (prefers-reduced-motion: reduce) {
  .site-ticker-track {
    animation: ticker-scroll 38s linear infinite !important;
  }
}

.nav-shell {
  /* Header band is width-locked to the content column (--max: 1180) with the
     SAME 16px side gutter as .section (width: min(100% - 32px, --max)), so the
     brand's left edge and the language switcher's right edge line up exactly
     with the page content and footer below. (Previously the band was wider —
     min(100% - 40px, 1360px) — which pushed the language toggle ~90px past the
     content's right border; the toggle now aligns per the design.) The six nav
     items still fit on one row at desktop widths and wrap gracefully below
     ~1200px — never overflow. */
  width: min(100% - 32px, var(--max));
  min-height: 72px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.brand {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-weight: 800;
}

.brand-logo {
  height: 38px;
  width: auto !important;
  max-width: 360px;
  opacity: var(--wordmarkOpacity);
  filter: brightness(1.05) saturate(0.9);
  object-fit: contain;
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 6px;
}

.nav-links a {
  border: 1px solid transparent;
  border-radius: 10px;
  color: var(--ink-muted);
  font-size: 14px;
  font-weight: 600;
  padding: 10px 11px;
}
/* Japanese nav labels (プラットフォーム, ケイパビリティ, ユースケース …) are
   wider than the English ones; trim size + letter-spacing so all six items keep
   to one row on desktop. They still wrap cleanly on narrow/mobile widths. */
:lang(ja) .nav-links a {
  font-size: 13px;
  letter-spacing: 0;
}

.nav-links a:hover,
.nav-links a:focus-visible {
  background: rgba(255, 255, 255, 0.04);
  border-color: var(--line);
  color: var(--ink);
  outline: none;
}

/* ACTIVE PAGE — the top-level nav item for the page being viewed. Previously
   only `.nav-dropdown-menu a[aria-current="page"]` was styled, so the marker was
   set on the top-level item but rendered identically to every other item and the
   user had no idea where they were. Set by markActiveNav() in scripts/site.js
   (and by hardcoded aria-current in some pages as a no-JS fallback).
   Amber underline + full-strength ink: reads as "you are here" without competing
   with the hover background, which stays available on top. */
/* Scoped to TOP-LEVEL entries only (direct children + dropdown triggers).
   A plain `.nav-links a[aria-current]` would also hit items inside an open
   dropdown, which have their own tint rule below and would stack both. */
.nav-links > a[aria-current="page"],
.nav-links .nav-dropdown-trigger[aria-current="page"] {
  color: var(--ink);
  border-bottom-color: var(--amber);
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}
.nav-links > a[aria-current="page"]:hover,
.nav-links > a[aria-current="page"]:focus-visible,
.nav-links .nav-dropdown-trigger[aria-current="page"]:hover,
.nav-links .nav-dropdown-trigger[aria-current="page"]:focus-visible {
  border-color: var(--line);
  border-bottom-color: var(--amber);
}

/* -----------------------------------------------------------------
   Platform nav dropdown (groups Features / Integrations / Security
   under a single "Platform" trigger).
   Desktop: hover + focus-within reveals the menu beneath the trigger.
   Mobile: collapses to inline children inside the hamburger panel
   (see the @media block below — the dropdown wrapper becomes
   `display: contents` so the trigger + children flow inline).
   ----------------------------------------------------------------- */
.nav-dropdown {
  position: relative;
  display: inline-flex;
  align-items: center;
}
/* An open dropdown menu (min-width 220px) is WIDER than its trigger, so it
   overlaps the NEXT dropdown's trigger and that neighbour's 12px hover-bridge
   (.nav-dropdown::after, pointer-events:auto). Sibling wrappers stack in DOM
   order, so the LATER sibling's transparent bridge/menu painted ON TOP of this
   menu and swallowed clicks on the overlapped items — e.g. "Capabilities" items
   were dead when the cursor arrived past the adjacent "Solutions" dropdown.
   Lift the ACTIVE dropdown's whole stacking context above its siblings so the
   open menu is always the topmost, fully clickable layer.

   `:hover` MUST outrank `:focus-within`: clicking a submenu item leaves that
   dropdown `:focus-within` (its menu stays open + lifted). If the hovered
   dropdown were lifted to the SAME z-index, the tie would resolve by DOM order —
   so a later, focus-retained neighbour (e.g. "Solutions", right of
   "Capabilities") would stay on top and keep eating the clicks. Giving the
   HOVERED dropdown a higher z-index makes the one under the cursor always win. */
.nav-dropdown:focus-within {
  z-index: 200;
}
.nav-dropdown:hover {
  z-index: 300;
}
.nav-dropdown-trigger {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.nav-dropdown-caret {
  display: inline-block;
  font-size: 10px;
  line-height: 1;
  opacity: 0.7;
  transition: transform 180ms ease;
}
.nav-dropdown:hover .nav-dropdown-caret,
.nav-dropdown:focus-within .nav-dropdown-caret {
  transform: rotate(180deg);
  opacity: 1;
}
.nav-dropdown-menu {
  /* Sit flush against the trigger so cursor never crosses dead space.
     The transparent margin-top extends the hoverable region without
     visual gap (the menu's actual visible body starts after the 8px
     top padding). */
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 220px;
  display: none;
  flex-direction: column;
  gap: 4px;
  margin-top: 0;
  padding: 14px 8px 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgba(11, 13, 18, 0.96);
  box-shadow: var(--shadow);
  backdrop-filter: blur(18px);
  z-index: 100;
}
/* Bridge: pseudo-element on the wrapper makes the area between the
   trigger and the menu hoverable, so the menu doesn't disappear when
   the cursor crosses the gap. */
.nav-dropdown::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  height: 12px;
  pointer-events: auto;
}
.nav-dropdown:hover .nav-dropdown-menu,
.nav-dropdown:focus-within .nav-dropdown-menu {
  display: flex;
}
.nav-dropdown-menu a {
  border: 1px solid transparent;
  border-radius: var(--control-radius);
  color: var(--ink-muted);
  font-size: 14px;
  font-weight: 600;
  padding: 10px 14px;
  white-space: nowrap;
}
/* Sub-menu hover uses the SAME four-corner brand gradient as the "Ask kiLM" FAB
   glyph. The previous rgba(255,255,255,0.04) wash was barely visible against the
   menu's own dark panel, so there was almost no feedback about which row you were
   on. Border strengthened to match the FAB's, and the text is forced to full-ink
   so it stays legible over the brighter fill. */
.nav-dropdown-menu a:hover,
.nav-dropdown-menu a:focus-visible,
.nav-dropdown-menu a[aria-current="page"]:hover,
.nav-dropdown-menu a[aria-current="page"]:focus-visible {
  background: var(--grad-brand-corners);
  border-color: var(--grad-border-strong);
  color: var(--ink);
  outline: none;
}
/* RESTING state of the item for the page you are on — a quiet amber tint that
   reads as "you are here" without competing with the hover gradient.
   This sits AFTER the hover rules and has equal specificity to a bare
   `a:hover`, so on its own it would have won and swallowed the hover fill on the
   active row. That is why the block above also lists the
   `[aria-current="page"]:hover` variants: those add a pseudo-class and so
   outrank this. Don't drop them. */
.nav-dropdown-menu a[aria-current="page"] {
  background: rgba(224, 182, 58, 0.08);
  color: var(--ink);
}

.nav-actions {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.language-switcher {
  display: inline-grid;
  grid-template-columns: repeat(2, minmax(44px, 1fr));
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.03);
  padding: 4px;
}

.language-switcher button {
  min-height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--ink-muted);
  padding: 8px 10px;
  font-size: 12px;
  font-weight: 800;
}

.language-switcher button[aria-pressed="true"] {
  background:
    linear-gradient(135deg, rgba(90, 135, 153, 0.34), rgba(224, 182, 58, 0.22)),
    rgba(255, 255, 255, 0.06);
  border: 1px solid var(--line-strong);
  color: var(--ink);
}

.language-switcher button:focus-visible {
  outline: 3px solid rgba(15, 103, 104, 0.18);
  outline-offset: -3px;
}

/* Language switcher flags (US / Japan) — inline data-URI SVGs: no external
   request (air-gap clean) and no reliance on flag emoji (which do not render
   on Windows). Drawn as CSS backgrounds on a child span so the button keeps
   its pill + aria-pressed active-state styling; the accessible name is the
   button's aria-label and the span is decorative (aria-hidden). */
.language-switcher .flag {
  display: block;
  width: 22px;
  height: 15px;
  border-radius: 2px;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.28);
}
.flag-en {
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2030%2020'%3E%3Crect%20width='30'%20height='20'%20fill='%23fff'/%3E%3Crect%20y='0.000'%20width='30'%20height='1.538'%20fill='%23b22234'/%3E%3Crect%20y='3.077'%20width='30'%20height='1.538'%20fill='%23b22234'/%3E%3Crect%20y='6.154'%20width='30'%20height='1.538'%20fill='%23b22234'/%3E%3Crect%20y='9.231'%20width='30'%20height='1.538'%20fill='%23b22234'/%3E%3Crect%20y='12.308'%20width='30'%20height='1.538'%20fill='%23b22234'/%3E%3Crect%20y='15.385'%20width='30'%20height='1.538'%20fill='%23b22234'/%3E%3Crect%20y='18.462'%20width='30'%20height='1.538'%20fill='%23b22234'/%3E%3Crect%20width='12.000'%20height='10.769'%20fill='%233c3b6e'/%3E%3Ccircle%20cx='1.20'%20cy='1.35'%20r='0.55'%20fill='%23fff'/%3E%3Ccircle%20cx='3.60'%20cy='1.35'%20r='0.55'%20fill='%23fff'/%3E%3Ccircle%20cx='6.00'%20cy='1.35'%20r='0.55'%20fill='%23fff'/%3E%3Ccircle%20cx='8.40'%20cy='1.35'%20r='0.55'%20fill='%23fff'/%3E%3Ccircle%20cx='10.80'%20cy='1.35'%20r='0.55'%20fill='%23fff'/%3E%3Ccircle%20cx='1.20'%20cy='4.04'%20r='0.55'%20fill='%23fff'/%3E%3Ccircle%20cx='3.60'%20cy='4.04'%20r='0.55'%20fill='%23fff'/%3E%3Ccircle%20cx='6.00'%20cy='4.04'%20r='0.55'%20fill='%23fff'/%3E%3Ccircle%20cx='8.40'%20cy='4.04'%20r='0.55'%20fill='%23fff'/%3E%3Ccircle%20cx='10.80'%20cy='4.04'%20r='0.55'%20fill='%23fff'/%3E%3Ccircle%20cx='1.20'%20cy='6.73'%20r='0.55'%20fill='%23fff'/%3E%3Ccircle%20cx='3.60'%20cy='6.73'%20r='0.55'%20fill='%23fff'/%3E%3Ccircle%20cx='6.00'%20cy='6.73'%20r='0.55'%20fill='%23fff'/%3E%3Ccircle%20cx='8.40'%20cy='6.73'%20r='0.55'%20fill='%23fff'/%3E%3Ccircle%20cx='10.80'%20cy='6.73'%20r='0.55'%20fill='%23fff'/%3E%3Ccircle%20cx='1.20'%20cy='9.42'%20r='0.55'%20fill='%23fff'/%3E%3Ccircle%20cx='3.60'%20cy='9.42'%20r='0.55'%20fill='%23fff'/%3E%3Ccircle%20cx='6.00'%20cy='9.42'%20r='0.55'%20fill='%23fff'/%3E%3Ccircle%20cx='8.40'%20cy='9.42'%20r='0.55'%20fill='%23fff'/%3E%3Ccircle%20cx='10.80'%20cy='9.42'%20r='0.55'%20fill='%23fff'/%3E%3C/svg%3E");
}
.flag-ja {
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2030%2020'%3E%3Crect%20width='30'%20height='20'%20fill='%23fff'/%3E%3Ccircle%20cx='15'%20cy='10'%20r='6'%20fill='%23bc002d'/%3E%3C/svg%3E");
}

.nav-toggle {
  display: none;
  width: 44px;
  height: 44px;
  border: 1px solid var(--line);
  border-radius: var(--control-radius);
  background: rgba(255, 255, 255, 0.04);
  padding: 10px;
}

.nav-toggle-line {
  display: block;
  width: 100%;
  height: 2px;
  margin: 5px 0;
  background: var(--ink);
}

.hero {
  position: relative;
  overflow: hidden;
  /* Single-column stack: the content as a full-width horizontal band on top,
     then a wide 16:9 video carousel beneath it. No forced min-height — the
     section sizes to its content. */
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: stretch;
  justify-content: center;
  gap: clamp(20px, 3vw, 40px);
  /* Full-width container: the video + content children cap + center themselves
     (same width rule as .signal-strip) so the content band lines up exactly
     with the outer edges of the 3 signal boxes below. */
  max-width: none;
  margin: 0 auto;
  /* clears the fixed header + the tagline ticker bar that floats with it */
  padding: 140px 0 84px;
}

/* Content pages: the sec-hero is the first section under the fixed header, so
   add ticker-bar clearance on top of its own padding. Higher specificity than
   the per-page `.sec-hero` rules so the padding-top override wins. */
body .sec-hero {
  padding-top: calc(clamp(3.5rem, 8vw, 6rem) + 3.25rem);
}
/* platform.html leads with .platform-section (not .sec-hero) — give its first
   section the same fixed-header + ticker clearance so the eyebrow/title aren't
   hidden behind the pinned ticker. */
body .platform-section:first-of-type {
  padding-top: calc(clamp(3.5rem, 8vw, 6rem) + 3.25rem);
}

.hero-shade {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* ---- Hero video carousel (multiple click-to-play videos, no autoplay) ---- */
.hero-carousel {
  position: relative;
  /* Wide 16:9 video block, capped + centered; content band matches signal-strip. */
  width: min(100% - 32px, 1040px);
  margin: 0 auto;
  align-self: center;
}
.hero-carousel-viewport {
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #05070a;
  box-shadow: var(--shadow);
}
.hero-carousel-track {
  display: flex;
  margin: 0;
  padding: 0;
  list-style: none;
  transition: transform 0.45s ease;
}
.hero-slide {
  position: relative;
  flex: 0 0 100%;
  width: 100%;
  aspect-ratio: 16 / 9;
}
.hero-slide iframe,
.hero-slide video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}
/* Self-hosted clip (data-video-src): letterbox inside the 16:9 slide. */
.hero-slide video {
  object-fit: contain;
  background: #000;
}
/* Click-to-play facade (built by JS from data-video-title). */
.hero-slide-facade {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  cursor: pointer;
  border: 0;
  color: var(--ink);
  background:
    radial-gradient(120% 120% at 0% 0%, rgba(244, 196, 0, 0.16), transparent 55%),
    radial-gradient(120% 120% at 100% 0%, rgba(230, 0, 18, 0.16), transparent 55%),
    radial-gradient(120% 120% at 100% 100%, rgba(0, 174, 239, 0.16), transparent 55%),
    radial-gradient(120% 120% at 0% 100%, rgba(120, 200, 0, 0.16), transparent 55%),
    #05070a;
  transition: filter 0.2s ease;
}
.hero-slide-facade:hover {
  filter: brightness(1.08);
}
/* Video thumbnail poster behind the title + play button. Darkened so the
   white title and red play button stay legible over any thumbnail; the facade's
   gradient shows through until/if the image fails to load. */
.hero-slide-thumb {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
  filter: brightness(0.6);
  transition: filter 0.2s ease;
}
.hero-slide-facade:hover .hero-slide-thumb {
  filter: brightness(0.72);
}
.hero-slide-title {
  position: relative;
  z-index: 1;
  font-weight: 700;
  font-size: clamp(15px, 1.6vw, 20px);
  letter-spacing: 0.01em;
  text-align: center;
  padding: 0 16px;
  text-shadow: 0 2px 14px rgba(0, 0, 0, 0.85);
}
.hero-slide-playbtn {
  position: relative;
  z-index: 1;
}
.hero-slide-playbtn svg {
  display: block;
}
.hero-slide-playbtn .yt-shape {
  fill: #ff0000;
  opacity: 0.92;
  transition: opacity 0.2s ease;
}
.hero-slide-facade:hover .hero-slide-playbtn .yt-shape {
  opacity: 1;
}
.hero-carousel-nav {
  position: absolute;
  top: calc(50% - 6px);
  transform: translateY(-50%);
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: rgba(12, 15, 23, 0.7);
  color: var(--ink);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  backdrop-filter: blur(6px);
  transition: background 0.2s ease;
}
.hero-carousel-nav:hover {
  background: rgba(12, 15, 23, 0.92);
}
.hero-carousel-nav.prev {
  left: 10px;
}
.hero-carousel-nav.next {
  right: 10px;
}
.hero-carousel-dots {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin-top: 12px;
}
.hero-carousel-dot {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  border: 0;
  padding: 0;
  cursor: pointer;
  background: rgba(255, 255, 255, 0.28);
  transition: background 0.2s ease, transform 0.2s ease;
}
.hero-carousel-dot.is-active {
  background: #e0b63a;
  transform: scale(1.25);
}
/* Single-video: JS sets data-single; hide nav + dots. */
.hero-carousel[data-single] .hero-carousel-nav,
.hero-carousel[data-single] .hero-carousel-dots {
  display: none;
}
/* Slide dots for the reusable why-carousels (Why 6Ws, Chat / 3D Shape Search, and
   every other multi-slide panel) — mirrors the hero video carousel's yellow
   indicators, shown centred below the panel. */
/* Occupies the panel's grid cell so the stage + its dots stay one column;
   the dots then flow centred directly below the panel. */
.why-slot {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.why-dots {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin-top: 12px;
}
.why-dot {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  border: 0;
  padding: 0;
  cursor: pointer;
  background: rgba(255, 255, 255, 0.28);
  transition: background 0.2s ease, transform 0.2s ease;
}
.why-dot.is-active {
  background: #e0b63a;
  transform: scale(1.25);
}

.hero-shade {
  display: none;
  background:
    linear-gradient(90deg, rgba(247, 249, 247, 0.97) 0%, rgba(247, 249, 247, 0.78) 42%, rgba(247, 249, 247, 0.22) 74%),
    linear-gradient(0deg, rgba(247, 249, 247, 0.2), rgba(247, 249, 247, 0.2));
}

.hero-content {
  position: relative;
  z-index: 1;
  /* Same width rule as .signal-strip so the band's outer edges line up exactly
     with the 3 signal boxes below. CTAs now live in the media row beside the
     video (not in this box), so the box is just the wordmark + copy → minimal
     height with trimmed vertical padding. */
  width: min(100% - 32px, var(--max));
  max-width: var(--max);
  margin: 0 auto;
  align-self: center;
  display: flex;
  flex-flow: row wrap;
  align-items: center;
  column-gap: clamp(20px, 3vw, 48px);
  row-gap: 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  /* Slightly more translucent than --surface-strong (0.84) so the slide-2 fireworks
     bloom softly through the frosted band; light copy stays readable on the dark glass. */
  background:
    linear-gradient(145deg, rgba(255, 255, 255, 0.055), rgba(255, 255, 255, 0.02)),
    rgba(19, 23, 34, 0.72);
  box-shadow: var(--shadow);
  padding: clamp(12px, 1.5vw, 18px) clamp(20px, 2.5vw, 30px);
  backdrop-filter: blur(16px);
}

/* Band children: the left brand lockup (logo stacked ON TOP of the wordmark) is
   fixed-width + compact; the copy flexes across the rest of the band. The old
   right-hand duplicate mark (.hero-card-mark) was removed so the (enlarged) copy
   gets that width back. */
.hero-content > .hero-brand {
  order: 1;
  flex: none;
  display: flex;
  flex-flow: column nowrap;
  align-items: center;
  row-gap: 6px;
}
/* The kiLM_alone_black lockup already renders the "ki&LM" wordmark, so the separate
   #hero-title text below it was a duplicate. Keep the <h1> in the DOM (it's the
   section's aria-labelledby target + the page H1 for SEO) but hide it visually. */
.hero-content > .hero-brand > #hero-title {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.hero-content > .hero-copy {
  order: 2;
  flex: 1 1 340px;
  max-width: none;
  margin: 0;
  /* Enlarged EN lede (JA is capped separately below because its lead line is
     longer and must stay on one line to keep the copy at 3 lines). ~21px keeps EN
     at lead(1) + description(2) = 3 lines at the full-width band. */
  font-size: clamp(17px, 2vw, 21px);
  line-height: 1.5;
}
/* Media row: video carousel (left) + primary CTAs (right rail), CTAs vertically
   centered with the carousel. Same band width as .hero-content so edges align. */
.hero-media-row {
  display: flex;
  align-items: center;
  gap: clamp(20px, 4vw, 48px);
  width: min(100% - 32px, var(--max));
  margin: 0 auto;
  align-self: center;
}
.hero-media-row .hero-carousel {
  flex: 1 1 auto;
  width: auto; /* fill the row minus the CTA rail */
  max-width: 1040px;
  margin: 0; /* left-aligned within the row (was centered) */
}
.hero-media-row .hero-actions {
  flex: 0 0 auto;
  flex-flow: column nowrap; /* stack the two CTAs on the right rail */
  align-items: stretch;
  gap: 12px;
}

/* The wordmark H1 now sits BELOW the logo inside the .hero-brand column (the logo
   is a sibling img, not an inline child — see index.html), so it's a plain centered
   heading. The JA "キーLM" is still split into <span class="brand-kii">キー</span>LM
   at runtime; that inline span is unaffected by this. */
#hero-title[data-brand-wordmark] {
  display: block;
  text-align: center;
  line-height: 1;
}
/* Logo stacked ON TOP of the wordmark in the left brand lockup. Sized to match the
   wordmark's height (same clamp as #hero-title's font-size) so the mark and the
   "kiLM" text read as one compact, evenly-sized lockup. */
.hero-brand-icon {
  /* Enlarged: this lockup is now the sole brand mark on slide 2 (the duplicate
     #hero-title text is visually hidden), so it carries the wordmark on its own. */
  height: clamp(52px, 6vw, 92px);
  width: auto;
  flex: none;
}

.eyebrow {
  margin: 0 0 12px;
  color: var(--ink-muted);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

/* Emphasised highlight line inside cards / section notes (amber accent). */
.card-emphasis {
  margin: 12px 0 0;
  color: var(--amber);
}

.card-emphasis strong {
  color: var(--amber);
}

/* Align the emphasis note to the same 1080px band as the .sec-*-grid it follows.
   Without this it stretched to the full .sec-section padding box, so it hugged the
   left edge while the tier cards above sat centered in their 1080px band. Scoped
   to DIRECT section children only — a .card-emphasis nested inside a .sec-card
   (infrastructure air-gap note) is unaffected. */
.sec-section > .card-emphasis {
  max-width: 1080px;
  margin-left: auto;
  margin-right: auto;
}

/* Horizontal scroll for any wide table on narrow screens (spec/config/storage). */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* Dense spec / comparison tables — Infrastructure hardware specs, suggested
   configs, storage-IOPS and training sizing. Static English content. */
.spec-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-muted);
}
.spec-table thead th {
  text-align: left;
  color: var(--ink);
  font-weight: 800;
  font-size: 13px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.035);
  vertical-align: bottom;
}
.spec-table tbody th[scope="row"] {
  text-align: left;
  color: var(--ink);
  font-weight: 700;
  padding: 11px 14px;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
  min-width: 150px;
}
.spec-table tbody td {
  padding: 11px 14px;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}
.spec-table tbody tr:nth-child(even) { background: rgba(255, 255, 255, 0.015); }
.spec-table tbody tr:hover { background: rgba(255, 255, 255, 0.03); }
.spec-table strong { color: var(--ink); }

/* GPU VRAM planning formula — monospace callout. */
.vram-formula {
  margin: 1.2rem 0 0;
  background: var(--surface-strong);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 1.1rem 1.3rem;
  overflow-x: auto;
}
.vram-formula pre {
  margin: 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink);
  white-space: pre;
}

h1,
h2,
h3,
p {
  /* Never split a word mid-character; a word that doesn't fit wraps whole to the
     next line (only an over-long single word may break, to avoid overflow). */
  overflow-wrap: break-word;
}

/* Japanese: don't break mid-word/anywhere — use proper kinsoku line-breaking so
   headlines wrap at natural boundaries instead of snapping abruptly. */
:lang(ja) h1,
:lang(ja) h2,
:lang(ja) h3,
:lang(ja) p,
:lang(ja) .hero-copy,
:lang(ja) .section-heading p {
  overflow-wrap: normal;
  line-break: strict;
  /* Fallback: plain CJK wrapping (can split a phrase mid-word, e.g. お聞|かせ). */
  word-break: normal;
  /* Progressive enhancement: phrase-aware wrapping. Supporting browsers
   * (Chrome/Edge 119+, Safari 17.4+) break only at Japanese phrase (bunsetsu)
   * boundaries, so a phrase like "お聞かせください" stays on one line instead of
   * splitting as "お聞" / "かせください". Unsupported browsers ignore this and
   * keep the word-break:normal fallback above. */
  word-break: auto-phrase;
}

/* JA hero copy carries an explicit "\n" break (heroCopy in scripts/site.js) so it
   renders as a lead line + a description. pre-line honors that newline while still
   phrase-wrapping either line if it's too wide. */
:lang(ja) .hero-copy {
  /* white-space: pre-line is now set on .hero-copy for BOTH languages (EN gained a
     lead line too) — kept out of here so there is one source of truth. */
  /* The JA copy is 3 "\n" segments and each must render on ONE line, so
     ::first-line below bolds the WHOLE lead (it styles the first FORMATTED line,
     so a wrapped lead would only be half-bold).
     Budget at the full-width band: --max 1180 - padding ~60 - column-gap ~48 -
     wordmark ~138 => ~934px of copy. Measuring CJK/kana at ~1em and Latin at
     ~0.5em, the segments are ~42.0em (lead), ~41.5em, ~35.0em, so the widest
     needs <= ~22px to stay on one line. 15.5px therefore clears all three with
     room to spare (~651px of 934px) — this cap was 14px only while an earlier
     66-char single description line forced it down. Kept below the 19px EN
     because the wordmark shares the row.
     Below roughly a 1100px viewport the band narrows and the longer segments wrap
     regardless of size — expected responsive behaviour, and the tablet breakpoint
     stacks the band to a column which restores the width. */
  /* The JA lead grew (…主権及びニューロシンボリックAI…), but removing the right-hand
     mark widened the band enough to still bump the cap 15.5px -> 17px and keep the
     lead on one line (so the copy stays at 3 lines + the ::first-line bold works). */
  font-size: clamp(13px, 1.65vw, 17px);
  line-height: 1.55;
}

h1 {
  max-width: 650px;
  margin: 0;
  color: var(--ink);
  font-size: clamp(48px, 7vw, 76px);
  line-height: 0.98;
  letter-spacing: 0;
}

.hero-copy {
  max-width: 650px;
  margin: 22px 0 0;
  color: var(--ink-soft);
  font-size: 19px;
  text-align: center; /* centre the lede (EN + JA) */
  /* BOTH languages now carry an explicit "\n" between a lead sentence and the
     description (heroCopy in scripts/site.js), so honor those newlines. NB the
     static fallback in index.html must therefore keep its copy on ONE source line
     — pre-line would otherwise render the HTML source indentation as line breaks
     before the i18n script swaps the text in. */
  white-space: pre-line;
}
/* JA only: the first line is a distinct lead sentence, so make it bolder + a touch
   larger to read as a headline above the description.
   NB ::first-line styles the first FORMATTED line, not the first "\n" segment — so
   this is only correct while the lead fits ONE line, which the 15.5px cap above is
   sized to guarantee at the full-width band (~42em lead vs ~60em of room). If the
   JA lead grows much past ~43 chars, shrink that cap or the bold applies to half a
   sentence.
   (Making it robust would need real markup — a <span> lead — but applyLanguage()
   deliberately sets textContent, not innerHTML, so translated copy can never inject
   markup. Keeping textContent is worth more than a robust bold.)
   EN is left unbolded: its lead is 92 chars and its description 176, so at a
   readable size the description wraps and bolding just the first visual line would
   look arbitrary. */
:lang(ja) .hero-copy::first-line {
  font-weight: 700;
  font-size: 1.06em;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 34px;
}

.button {
  display: inline-flex;
  min-height: 46px;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line-strong);
  border-radius: var(--control-radius);
  padding: 12px 18px;
  color: var(--ink);
  font-weight: 800;
  transition:
    transform 160ms ease,
    background 160ms ease,
    border-color 160ms ease;
}

.button:hover,
.button:focus-visible {
  transform: translateY(-1px);
  outline: none;
}

.button-primary {
  background:
    linear-gradient(135deg, rgba(90, 135, 153, 0.46), rgba(224, 182, 58, 0.24)),
    rgba(255, 255, 255, 0.045);
  color: var(--ink);
}

.button-primary:hover,
.button-primary:focus-visible {
  background:
    linear-gradient(135deg, rgba(90, 135, 153, 0.62), rgba(224, 182, 58, 0.34)),
    rgba(255, 255, 255, 0.08);
}

.button-secondary {
  background: rgba(255, 255, 255, 0.03);
  border-color: var(--line-strong);
  color: var(--ink);
}

.signal-strip {
  width: min(100% - 32px, var(--max));
  margin: -36px auto 0;
  position: relative;
  z-index: 3;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  overflow: hidden;
  border: 0;
  border-radius: var(--radius);
}

.signal-strip div {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-strong);
  box-shadow: 0 14px 42px rgba(0, 0, 0, 0.24);
  padding: 22px;
}

.signal-strip strong,
.signal-strip span {
  display: block;
}

.signal-strip strong {
  margin-bottom: 4px;
  color: var(--ink);
}

.signal-strip span {
  color: var(--ink-muted);
  font-size: 14px;
}

.section {
  width: min(100% - 32px, var(--max));
  margin: 0 auto;
  padding: 92px 0;
}

.section-heading {
  /* Full content width: heading + intro copy span edge-to-edge (till right),
     which minimizes the number of wrapped lines. (Was capped at 780px.) */
  max-width: none;
}

.section-heading h2 {
  margin: 0;
  color: var(--ink);
  font-size: 42px;
  line-height: 1.08;
  letter-spacing: 0;
}

.section-heading p:not(.eyebrow) {
  margin: 18px 0 0;
  color: var(--ink-soft);
  font-size: 18px;
}

.video-layout,
.interactive-grid {
  display: grid;
  /* Chat (left) and contact/mail (right) share the row at equal width. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 28px;
  margin-top: 36px;
  align-items: start;
}

/* Brand Story only: the left (brand image) panel is larger and the right (pyramid)
   panel smaller, and the shorter right panel is vertically centered against the
   taller left one. Scoped to .video-section so the Why carousel + interactive grid
   keep their equal columns. The mobile breakpoint below re-stacks this to 1 column. */
.video-section .video-layout {
  grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
  align-items: center;
}
.brand-story-stage {
  min-height: 0;
  background: var(--surface-strong);
  padding: 0;
}
.brand-story-image {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius);
}

.video-stage {
  position: relative;
  min-height: 450px;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background:
    linear-gradient(135deg, rgba(255, 255, 255, 0.05), transparent 32%),
    linear-gradient(145deg, rgba(16, 35, 44, 0.74), rgba(24, 28, 42, 0.92) 54%, rgba(30, 19, 34, 0.9));
  color: var(--ink);
  box-shadow: var(--shadow);
}

.brand-video,
.video-overlay {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.brand-video {
  object-fit: cover;
  opacity: 0.64;
}

.video-overlay {
  z-index: 1;
  background:
    linear-gradient(180deg, rgba(19, 23, 34, 0.06), rgba(19, 23, 34, 0.72) 72%),
    linear-gradient(90deg, rgba(19, 23, 34, 0.72), rgba(19, 23, 34, 0.08));
}

.video-topbar {
  position: absolute;
  top: 18px;
  left: 18px;
  z-index: 3;
  display: flex;
  gap: 8px;
}

.video-topbar span {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.7);
}

.video-frame {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: grid;
  align-content: end;
  gap: 10px;
  opacity: 0;
  padding: 84px 42px 88px;
  transform: translateY(14px);
  transition:
    opacity 420ms ease,
    transform 420ms ease;
}

.video-frame.is-active {
  opacity: 1;
  transform: translateY(0);
}

.video-frame h3 {
  max-width: 560px;
  margin: 0;
  font-size: 32px;
  line-height: 1.08;
}

.video-frame p {
  max-width: 560px;
  margin: 0;
  color: var(--ink-soft);
  font-size: 17px;
}

.stream,
.node-map,
.knowledge-core,
.citation-ribbons,
.control-grid {
  position: absolute;
  pointer-events: none;
}

.stream {
  top: 98px;
  width: 42%;
  height: 3px;
  background: linear-gradient(90deg, transparent, var(--amber), transparent);
  animation: drift 3.4s infinite linear;
}

.stream-left {
  left: 5%;
}

.stream-right {
  right: 5%;
  animation-delay: 1.2s;
}

.node-map {
  top: 96px;
  right: 12%;
  width: 260px;
  height: 170px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
}

.node-map span {
  position: absolute;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--sky);
  box-shadow: 0 0 0 8px rgba(77, 163, 220, 0.08);
}

.node-map span:nth-child(1) { top: 22%; left: 18%; }
.node-map span:nth-child(2) { top: 42%; left: 42%; }
.node-map span:nth-child(3) { top: 18%; left: 72%; }
.node-map span:nth-child(4) { top: 68%; left: 28%; }
.node-map span:nth-child(5) { top: 72%; left: 68%; }

.knowledge-core {
  top: 78px;
  right: 13%;
  width: 210px;
  height: 210px;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  background:
    linear-gradient(90deg, transparent 49%, rgba(255, 255, 255, 0.18) 50%, transparent 51%),
    linear-gradient(0deg, transparent 49%, rgba(255, 255, 255, 0.18) 50%, transparent 51%),
    rgba(255, 255, 255, 0.05);
  animation: slow-turn 9s infinite linear;
}

.citation-ribbons {
  top: 95px;
  right: 10%;
  display: grid;
  gap: 14px;
  width: 320px;
}

.citation-ribbons span {
  height: 44px;
  border: 1px solid var(--line-strong);
  border-left: 5px solid var(--amber);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.08);
}

.control-grid {
  top: 92px;
  right: 9%;
  display: grid;
  grid-template-columns: repeat(2, minmax(110px, 1fr));
  gap: 12px;
  width: 280px;
}

.control-grid span {
  height: 82px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.08);
}

.video-controls {
  position: absolute;
  inset: auto 22px 22px;
  z-index: 5;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 14px;
  align-items: center;
}

.icon-button {
  min-height: 38px;
  border: 1px solid var(--line-strong);
  border-radius: var(--control-radius);
  background: rgba(255, 255, 255, 0.1);
  color: var(--ink);
  padding: 8px 12px;
  font-weight: 800;
}

.progress-track {
  height: 8px;
  overflow: hidden;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.12);
}

.progress-track span {
  display: block;
  width: 0;
  height: 100%;
  border-radius: inherit;
  background: var(--amber);
}

.story-points,
.contact-panel,
.chat-panel {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-strong);
  box-shadow: var(--shadow);
  backdrop-filter: blur(16px);
}

.story-points {
  padding: 28px;
}

.story-brand-image {
  width: 100%;
  /* 16:9 to match the pyramid loop + poster exactly, and object-fit: contain so
     the FULL frame — including the CRM/ERP/MES/PLM… system names along the base —
     is always visible and never cropped. */
  aspect-ratio: 16 / 9;
  margin: 0; /* was 0 0 22px — the heading + bullet list below it were removed */
  border: 1px solid var(--line);
  border-radius: var(--radius);
  object-fit: contain;
}
/* The kiLM-story loop <video> paints the pyramid IMAGE as its element
   background, so the panel shows the pyramid (never a black box) before the
   video plays — while it loads, when muted-autoplay is blocked, or under
   prefers-reduced-motion. The video frames simply play on top. Root-absolute
   URL so it resolves from /, /en/ and /ja/ alike. */
.story-brand-video {
  background: #0b0d12 url("/assets/kilm/kiLM_Pyramid_poster.webp") center / contain no-repeat;
}

.story-points h3,
.contact-panel h2 {
  margin: 0 0 12px;
  font-size: 24px;
}

.story-points ul {
  display: grid;
  gap: 12px;
  margin: 18px 0 0;
  padding-left: 20px;
  color: var(--ink-soft);
}

.platform-flow {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-top: 36px;
}

.platform-flow article,
.feature-card {
  min-height: 230px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background:
    linear-gradient(145deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0.012)),
    var(--surface-strong);
  box-shadow: 0 14px 42px rgba(0, 0, 0, 0.26);
  padding: 24px;
}

.platform-flow span {
  display: inline-grid;
  width: 38px;
  height: 38px;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: 10px;
  background:
    linear-gradient(135deg, rgba(224, 182, 58, 0.2), rgba(77, 163, 220, 0.14)),
    rgba(255, 255, 255, 0.045);
  color: var(--ink);
  font-weight: 900;
}

.platform-flow h3,
.feature-card h3 {
  margin: 22px 0 10px;
  color: var(--ink);
  font-size: 23px;
}

.platform-flow p,
.feature-card p {
  margin: 0;
  color: var(--ink-muted);
}

.features-section {
  border-top: 1px solid var(--line);
}

.feature-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin-top: 36px;
}

.capability-table {
  margin-top: 32px;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-strong);
  box-shadow: var(--shadow);
}

.capability-table [role="row"] {
  display: grid;
  grid-template-columns: 0.85fr 1.45fr 0.9fr;
  border-top: 1px solid var(--line);
}

.capability-table [role="row"]:first-child {
  border-top: 0;
}

.capability-table span {
  padding: 16px 18px;
  color: var(--ink-muted);
}

.capability-table span:first-child {
  color: var(--ink);
  font-weight: 800;
}

.capability-table .table-head {
  background: rgba(255, 255, 255, 0.055);
}

.capability-table .table-head span {
  color: var(--ink);
}

.chat-contact-section {
  border-top: 1px solid var(--line);
}

.chat-panel {
  display: grid;
  min-height: 590px;
  grid-template-rows: 1fr auto auto;
  overflow: hidden;
}

/* Loader shown while the assistant is warming (cold start) or generating — the
   pulsing Polycracy mark (same as the page preloader #kilm-preloader / kilm-pulse),
   appended as a bot bubble with .is-loading, swapped for text on reply. */
.chat-loading-row {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
.chat-loading-mark {
  width: 26px;
  height: 26px;
  flex: none;
  display: inline-block;
  /* Circular kiLM mark — matches the hero neural-net badge. */
  object-fit: cover;
  border-radius: 50%;
  animation: kilm-pulse 1.25s ease-in-out infinite;
}
.chat-loading-label {
  font-size: 13px;
  line-height: 1.3;
  opacity: 0.85;
}
/* Classic three-dot "typing" indicator so the bubble reads as actively
   working, not stalled. currentColor keeps it on-theme in the bot bubble. */
.chat-loading-dots {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.chat-loading-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.35;
  animation: kilm-typing 1.2s ease-in-out infinite;
}
.chat-loading-dot:nth-child(2) { animation-delay: 0.18s; }
.chat-loading-dot:nth-child(3) { animation-delay: 0.36s; }
@keyframes kilm-typing {
  0%, 80%, 100% { transform: translateY(0); opacity: 0.35; }
  40%           { transform: translateY(-4px); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .chat-loading-mark { animation: none; }
  .chat-loading-dot { animation: none; opacity: 0.6; }
}

.chat-window {
  display: grid;
  align-content: start;
  gap: 12px;
  max-height: 300px;
  overflow: auto;
  padding: 22px;
  background:
    linear-gradient(180deg, rgba(77, 163, 220, 0.1), transparent 46%),
    rgba(5, 7, 11, 0.26);
}

.message {
  max-width: min(86%, 580px);
  border-radius: 8px;
  padding: 12px 14px;
}

.message p {
  margin: 0;
}

.message.bot {
  justify-self: start;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.06);
  color: var(--ink);
}

.message.user {
  justify-self: end;
  border: 1px solid rgba(77, 163, 220, 0.28);
  background: rgba(77, 163, 220, 0.18);
  color: var(--ink);
}

.chat-form {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 10px;
  border-top: 1px solid var(--line);
  padding: 16px;
}

.chat-form input,
.contact-form input,
.contact-form select,
.contact-form textarea {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--control-radius);
  background: rgba(255, 255, 255, 0.045);
  color: var(--ink);
  padding: 12px 13px;
}

.chat-form input:focus,
.contact-form input:focus,
.contact-form select:focus,
.contact-form textarea:focus {
  border-color: var(--line-strong);
  outline: 3px solid rgba(77, 163, 220, 0.2);
}

.chat-form input::placeholder,
.contact-form textarea::placeholder {
  color: rgba(237, 240, 246, 0.48);
}

.prompt-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 0 16px 16px;
}

.prompt-row button {
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.04);
  color: var(--ink);
  padding: 8px 12px;
  font-size: 13px;
  font-weight: 800;
}

/* Email + one-time-code gate on the "Ask kiLM" chat. Mirrors .chat-form so the
   gate reads as part of the same panel. Hidden entirely when the gate flag is
   off (site.js sets display:none). */
.chat-gate {
  border-top: 1px solid var(--line);
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.chat-gate-copy {
  color: var(--ink-muted);
  font-size: 0.9rem;
  margin: 0;
}

.chat-gate-form {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 10px;
  align-items: center;
}

.chat-gate-form[hidden] {
  display: none;
}

.chat-gate-form input {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--control-radius);
  background: rgba(255, 255, 255, 0.045);
  color: var(--ink);
  padding: 12px 13px;
}

.chat-gate-form input:focus {
  border-color: var(--line-strong);
  outline: 3px solid rgba(77, 163, 220, 0.2);
}

.chat-gate-form input::placeholder {
  color: rgba(237, 240, 246, 0.48);
}

/* The code step has a Verify + a Resend button; let them sit side by side in
   the "auto" column without stretching the input column. */
.chat-gate-form[data-chat-gate-code-form] {
  grid-template-columns: 1fr auto auto;
}

.chat-gate .button-ghost {
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.04);
  color: var(--ink);
}

.chat-gate-status {
  color: var(--ink-muted);
  font-size: 0.82rem;
  margin: 0;
  min-height: 1em;
}

.contact-panel {
  padding: 26px;
}

.contact-panel p {
  color: var(--ink-muted);
}

.contact-form {
  display: grid;
  gap: 16px;
  margin-top: 22px;
}

.contact-form label {
  display: grid;
  gap: 7px;
  color: var(--ink);
  font-size: 14px;
  font-weight: 800;
}

.field-pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

.contact-form textarea {
  resize: vertical;
  min-height: 116px;
}

.form-status {
  min-height: 24px;
  margin: 0;
  color: var(--ink-soft);
  font-weight: 800;
}

.form-status a {
  color: var(--sky);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.footer {
  width: min(100% - 32px, var(--max));
  margin: 0 auto;
  padding: 18px 0;
  margin-bottom: 18px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  color: var(--ink-muted);
}

.footerInner {
  display: flex;
  align-items: center;
  width: 100%;
  /* Wrap so the links drop below the brand on phones/tablets instead of
     forcing horizontal page scroll (was a whole-page overflow on <=768px). */
  flex-wrap: wrap;
  row-gap: 12px;
}

.footerBrand {
  display: flex;
  align-items: center;
}

.footerWordmark {
  height: var(--wordmarkH);
  width: auto;
  max-width: 520px;
  opacity: var(--wordmarkOpacity);
  filter: none;
  pointer-events: none;
  display: block;
  object-fit: contain;
}

.footerLinks {
  display: flex;
  /* Let the individual links wrap to multiple rows on narrow screens. */
  flex-wrap: wrap;
  gap: 14px;
  margin-left: auto;
  font-size: 13px;
}

.footerLinks a {
  padding: 6px 10px;
  border: 1px solid transparent;
  border-radius: 10px;
  color: var(--ink-muted);
  transition:
    background 160ms ease,
    border-color 160ms ease,
    color 160ms ease;
}

.footerLinks a:hover,
.footerLinks a:focus-visible {
  background: var(--grad-ui);
  border-color: var(--grad-border);
  color: var(--ink);
  outline: none;
  text-decoration: none;
}

.footerLegal {
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.footerLegalInner {
  display: flex;
  align-items: center;
  width: 100%;
}

.footerLegalBlock {
  min-width: 260px;
}

.footerLegalTitle {
  color: var(--ink);
  font-size: 12px;
  font-weight: 800;
}

.footerLegalLine,
.footerLegalNote {
  color: var(--ink-muted);
  font-size: 12px;
}

.footerLegalLine {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 2px;
}

.footerLegalName {
  color: var(--ink-soft);
  font-weight: 700;
}

.footerLegalNote {
  margin-top: 6px;
}

@keyframes drift {
  0% { transform: translateX(-20%); opacity: 0; }
  20% { opacity: 1; }
  80% { opacity: 1; }
  100% { transform: translateX(20%); opacity: 0; }
}

@keyframes slow-turn {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

@keyframes drift-ambience {
  0% { transform: translate3d(-6px, 5px, 0) scale(1.01); }
  50% { transform: translate3d(7px, -6px, 0) scale(1.015); }
  100% { transform: translate3d(-6px, 5px, 0) scale(1.01); }
}

@media (max-width: 940px) {
  .nav-toggle {
    display: block;
  }

  .nav-links {
    position: absolute;
    top: 72px;
    right: 16px;
    left: 16px;
    display: none;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: rgba(11, 13, 18, 0.96);
    padding: 10px;
    box-shadow: var(--shadow);
    backdrop-filter: blur(18px);
  }

  .nav-links.is-open {
    display: grid;
  }

  .nav-links a {
    border-radius: var(--control-radius);
  }

  /* On mobile, the dropdown collapses into its parent (hamburger
     menu). display: contents lets the trigger + children flow as
     siblings of the other nav links; the children get a small
     indent + left border to signal hierarchy. */
  .nav-dropdown {
    display: contents;
  }
  .nav-dropdown-menu {
    position: static;
    display: flex;
    min-width: 0;
    padding: 4px 0 4px 18px;
    margin-left: 14px;
    border: none;
    border-left: 2px solid var(--line);
    border-radius: 0;
    background: transparent;
    backdrop-filter: none;
    box-shadow: none;
    z-index: auto;
  }
  .nav-dropdown-caret {
    display: none;
  }

  .language-switcher {
    background: rgba(255, 255, 255, 0.04);
  }

  h1 {
    font-size: 58px;
  }

  .hero-copy {
    font-size: 19px;
  }

  .signal-strip,
  .platform-flow,
  .feature-grid,
  .video-layout,
  .video-section .video-layout,
  .interactive-grid {
    grid-template-columns: 1fr;
  }

  /* Tablet/mobile: stack the hero to one column; video becomes a full-width
     16:9 block below the content card (not a stretched grid cell). */
  .hero {
    grid-template-columns: 1fr;
  }

  /* Media row stacks to a column: carousel on top, CTAs below (side by side). */
  .hero-media-row {
    flex-direction: column;
    align-items: stretch;
    width: min(100% - 32px, 760px);
    margin: 0 auto;
    gap: 20px;
  }

  .hero-media-row .hero-carousel {
    width: 100%;
    max-width: none;
  }

  .hero-media-row .hero-actions {
    flex-flow: row wrap;
    justify-content: center;
  }

  .hero-content {
    width: min(100% - 32px, 760px);
    margin: 0 auto;
    /* stack the band back to a column on tablet/mobile */
    flex-flow: column nowrap;
    align-items: flex-start;
    row-gap: 0;
    padding-right: clamp(20px, 2.5vw, 30px);
  }

  .hero-content > .hero-copy {
    flex: 0 1 auto;
    margin: 22px 0 0;
  }

  .platform-flow article,
  .feature-card {
    min-height: auto;
  }

  .capability-table,
  .capability-table [role="row"],
  .capability-table span {
    display: block;
  }

  .capability-table [role="row"] {
    padding: 12px 0;
  }

  .capability-table .table-head {
    display: none;
  }

  /* Wide data tables scroll horizontally instead of forcing whole-page
     overflow on phones/tablets (the marketing CSS has no .table-scroll
     wrapper like the portal does). display:block turns the <table> into a
     horizontal scroll container; it only scrolls when the table is wider
     than the screen, so narrow tables are unaffected. */
  .infra-table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
}

@media (max-width: 620px) {
  .nav-shell,
  .section,
  .signal-strip,
  .footer,
  .hero-content {
    width: min(100% - 24px, var(--max));
  }

  /* Phone widths: a 48px margin per side would eat most of a ~360px screen, so
     scale the gradient edge down here rather than starving the content. Only the
     FIRST layer's size changes; the vignette layers keep their default (auto). */
  body::after {
    background-size: min(100% - 32px, calc((100% + var(--backdrop-max)) / 2)) 100%, auto, auto;
  }

  .hero {
    min-height: 720px;
    padding-top: 112px;
  }

  .hero-shade {
    display: none;
  }

  h1 {
    font-size: 48px;
  }

  .hero-content {
    padding: 24px;
  }

  .hero-copy {
    font-size: 17px;
  }

  .brand-logo {
    height: 24px;
    max-width: calc(100vw - 176px);
  }

  .footerWordmark {
    height: 28px;
    max-width: min(86vw, 300px);
  }

  .language-switcher {
    grid-template-columns: repeat(2, minmax(40px, 1fr));
  }

  .language-switcher button {
    min-height: 36px;
    padding: 7px 8px;
    font-size: 12px;
  }

  .section {
    padding: 68px 0;
  }

  .section-heading h2 {
    font-size: 32px;
  }

  .video-stage {
    min-height: 560px;
  }

  .video-frame {
    padding: 76px 24px 90px;
  }

  .video-frame h3 {
    font-size: 25px;
  }

  .node-map,
  .citation-ribbons,
  .control-grid,
  .knowledge-core {
    top: 86px;
    right: 24px;
    left: 24px;
    width: auto;
  }

  .knowledge-core {
    left: auto;
    width: 180px;
    height: 180px;
  }

  .chat-form,
  .field-pair {
    grid-template-columns: 1fr;
  }

  .footerInner {
    row-gap: 14px;
    text-align: center;
    flex-direction: column;
  }

  .footerLinks {
    margin-left: 0;
    justify-content: center;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ===========================================================================
 * Cookie & storage settings modal (slice 0099-portal item #4)
 * ===========================================================================
 * Triggered from the footer "Cookie Settings" link. Stores consent in
 * localStorage under `kilm.consent.v1`. No third-party scripts load
 * before consent is recorded; window.kilmConsent exposes the current
 * state for any future analytics loaders.
 */
.cookieBackdrop {
  position: fixed;
  inset: 0;
  background: rgba(8, 22, 28, 0.6);
  backdrop-filter: blur(4px);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 20px;
}
.cookieBackdrop[data-open="true"] {
  display: flex;
}
.cookieDialog {
  background: #ffffff;
  color: #14282d;
  border-radius: 14px;
  width: min(560px, 100%);
  max-height: 92vh;
  overflow-y: auto;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35);
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.cookieDialog h2 {
  margin: 0;
  font-size: 1.1rem;
  font-weight: 600;
}
.cookieDialog p.cookieIntro {
  margin: 0;
  font-size: 0.9rem;
  color: #3b5760;
  line-height: 1.45;
}
.cookieCategory {
  border: 1px solid #d9e2e5;
  border-radius: 10px;
  padding: 12px 14px;
  display: flex;
  gap: 12px;
  align-items: flex-start;
}
.cookieCategory input[type="checkbox"] {
  margin-top: 2px;
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  accent-color: #0f3b3e;
}
.cookieCategory input[type="checkbox"]:disabled {
  opacity: 0.6;
}
.cookieCategoryBody {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.cookieCategoryTitle {
  font-weight: 600;
  font-size: 0.92rem;
}
.cookieCategoryDesc {
  font-size: 0.82rem;
  color: #4b6770;
  line-height: 1.45;
}
.cookieButtons {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 4px;
}
.cookieButtons button {
  font-family: inherit;
  font-size: 0.88rem;
  font-weight: 500;
  padding: 8px 14px;
  border-radius: 8px;
  border: 1px solid #0f3b3e;
  background: #ffffff;
  color: #0f3b3e;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.cookieButtons button:hover {
  background: #f1f5f6;
}
.cookieButtons button[data-cookie-primary] {
  background: #0f3b3e;
  color: #ffffff;
}
.cookieButtons button[data-cookie-primary]:hover {
  background: #185055;
}
.cookieToast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  background: #14282d;
  color: #ffffff;
  padding: 10px 18px;
  border-radius: 10px;
  font-size: 0.88rem;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.25);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
  z-index: 1001;
}
.cookieToast[data-show="true"] {
  opacity: 1;
}

/* First-visit consent banner — slim bottom bar (JS-injected by
   injectConsentBanner() in site.js). Dark-theme tokens so it reads as part of
   the site (the older .cookieDialog is light by legacy). Sits above content but
   below the modal (z 1000) / toast (z 1001); nudges the "Ask kiLM" FAB up while
   visible so the two don't collide. */
.cookieBar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 900;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 12px 18px;
  padding: 12px clamp(14px, 4vw, 28px);
  background: var(--surface-stronger);
  border-top: 1px solid var(--line-strong);
  box-shadow: 0 -8px 28px rgba(0, 0, 0, 0.38);
  backdrop-filter: blur(8px);
}
.cookieBar__text {
  margin: 0;
  flex: 1 1 320px;
  max-width: 760px;
  font-size: 0.84rem;
  line-height: 1.45;
  color: var(--ink-soft);
}
.cookieBar__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
.cookieBar__btn {
  font-family: inherit;
  font-size: 0.85rem;
  font-weight: 500;
  padding: 8px 16px;
  border-radius: 999px;
  border: 1px solid var(--grad-border-strong);
  background: var(--surface-tint);
  color: var(--ink);
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.cookieBar__btn:hover { background: rgba(255, 255, 255, 0.08); }
.cookieBar__btn:focus-visible { outline: 2px solid var(--line-strong); outline-offset: 2px; }
.cookieBar__btn--primary {
  background: var(--ink);
  color: var(--surface);
  border-color: var(--ink);
}
.cookieBar__btn--primary:hover { background: #ffffff; }
.cookieBar__btn--ghost {
  border-color: transparent;
  background: transparent;
  color: var(--ink-muted);
  text-decoration: underline;
  padding-inline: 8px;
}
.cookieBar__btn--ghost:hover { color: var(--ink); background: transparent; }
.cookieBar__close {
  background: none;
  border: none;
  color: var(--ink-muted);
  font-size: 1.05rem;
  line-height: 1;
  padding: 4px 8px;
  border-radius: 8px;
  cursor: pointer;
}
.cookieBar__close:hover { color: var(--ink); background: rgba(255, 255, 255, 0.06); }
.cookieBar__close:focus-visible { outline: 2px solid var(--line-strong); outline-offset: 2px; }
/* Keep the "Ask kiLM" FAB clear of the bar while it's showing. */
body.consent-bar-open .chat-fab { bottom: 92px; }
/* ...and the site-search pill, which stacks directly ABOVE the FAB, must rise
   with it — otherwise the two overlap while the consent bar is open. */
body.consent-bar-open .site-search { bottom: 142px; }
@media (max-width: 720px) {
  .cookieBar { justify-content: flex-start; gap: 10px; }
  .cookieBar__actions { width: 100%; }
  body.consent-bar-open .chat-fab { bottom: 136px; }
  body.consent-bar-open .site-search { bottom: 190px; }
}

/* Slice 0105 -- Trial request modal */
.trialBackdrop {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.55);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 1050;
  padding: 1rem;
}
.trialBackdrop[data-open="true"] { display: flex; }
/* Dark-theme modal to match the site (mirrors .chat-dialog). The old hardcoded
   light theme (#fff bg, dark text) looked out of place on the dark site and left
   the h2/description invisible (they inherited the near-white heading color). */
.trialModal {
  background: var(--surface-stronger);
  color: var(--ink);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  width: min(480px, calc(100vw - 2rem));
  padding: 1.75rem 1.75rem 1.5rem;
  box-shadow: var(--shadow);
  position: relative;
  /* User-resizable (parity with the chat dialog) — drag the bottom-right corner.
     overflow:auto is required for the CSS resizer; min/max keep it usable + on-screen.
     max-width raised from the 480px default so the resize can actually grow it. */
  resize: both;
  overflow: auto;
  min-width: 300px;
  min-height: 220px;
  max-width: calc(100vw - 2rem);
  max-height: calc(100vh - 2rem);
}
.trialModal h2 { color: var(--ink); margin: 0 0 0.4rem; }
#trialDescription { color: var(--ink-muted); }
.trialClose {
  position: absolute;
  top: 0.5rem;
  right: 0.75rem;
  background: transparent;
  border: 0;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  color: var(--ink-muted);
}
.trialClose:hover { color: var(--ink); }
.trialForm label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  margin-top: 0.85rem;
  font-size: 0.85rem;
  color: var(--ink-soft);
}
.trialForm input,
.trialForm textarea {
  font: inherit;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--line);
  border-radius: var(--control-radius);
  background: rgba(255, 255, 255, 0.045);
  color: var(--ink);
  width: 100%;
  box-sizing: border-box;
}
.trialForm input:focus,
.trialForm textarea:focus {
  border-color: var(--line-strong);
  outline: 3px solid rgba(77, 163, 220, 0.2);
}
.trialForm input::placeholder,
.trialForm textarea::placeholder { color: rgba(237, 240, 246, 0.48); }
.trialForm textarea { resize: vertical; min-height: 70px; }
.trialActions {
  display: flex;
  gap: 0.75rem;
  justify-content: flex-end;
  margin-top: 1.25rem;
}
.trialStatus {
  margin-top: 0.75rem;
  font-size: 0.9rem;
  color: #4ade80;
  min-height: 1.25rem;
}
body.trial-open { overflow: hidden; }

/* ===========================================================================
 * Page preloader — Polycracy mark, shown until window 'load', then fades out.
 * Markup injected after <body>; hidden by scripts/site.js. Matches the dark
 * theme background so there is no flash.
 * ======================================================================== */
#kilm-preloader {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(1200px 900px at 50% 40%, rgba(20, 24, 36, 0.95), rgba(11, 13, 18, 1) 70%),
    #0b0d12;
  transition: opacity 0.45s ease, visibility 0.45s ease;
}
#kilm-preloader.is-done { opacity: 0; visibility: hidden; }
#kilm-preloader img {
  width: 88px;
  height: 88px;
  /* Circular kiLM mark — matches the hero neural-net badge. */
  object-fit: cover;
  border-radius: 50%;
  animation: kilm-pulse 1.25s ease-in-out infinite;
}
@keyframes kilm-pulse {
  0%, 100% { transform: scale(0.88); opacity: 0.55; }
  50%      { transform: scale(1.06); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  #kilm-preloader img { animation: none; }
}

/* Beta badge — kiLM is in beta; shown beside the wordmark in the header. */
.beta-badge {
  display: inline-flex;
  align-items: center;
  margin-left: 10px;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1;
  color: var(--ink);
  background: linear-gradient(135deg, rgba(224, 182, 58, 0.30), rgba(90, 135, 153, 0.22));
  border: 1px solid var(--line-strong);
}

/* Brand mark: render the "キー" in the Japanese mark "キーLM" at ~half the size
 * of "LM" (applied to text nodes at runtime by scripts/site.js::styleBrandKii). */
.brand-kii {
  font-size: 0.62em;
  font-weight: inherit;
  /* Optically lift the small キー toward the cap-height of "LM" so it reads as an
   * intentional brand mark, not a baseline subscript. */
  vertical-align: 0.18em;
  letter-spacing: 0;
}

/* ---------------------------------------------------------------------------
 * kiLM mark in the TOP-RIGHT corner of the Chat, Contact, and RFQ-step cards
 * (2026-06-28). Implemented as a decorative ::after so NO markup or locale
 * regeneration is needed — this stylesheet is shared by EN (styles.css) and
 * JA (../styles.css), and the url() resolves relative to THIS file => site/assets,
 * so every locale + quote.html get it automatically. Proportional via
 * aspect-ratio (kiLM_alone_black.webp is 670x194 ≈ 3.45:1); decorative + non-blocking.
 * ------------------------------------------------------------------------- */
.chat-panel,
.contact-panel,
.qt-fieldset {
  position: relative;
  /* A <fieldset> defaults to min-width:min-content and refuses to shrink
     below its widest control, overflowing the viewport on phones. */
  min-width: 0;
}
/* Form controls aren't covered by the global img/svg max-width:100% rule; a
   <select> with a long option would otherwise force horizontal page scroll. */
.qt-field select,
.qt-field input,
.qt-field textarea {
  max-width: 100%;
  box-sizing: border-box;
}
.chat-panel::after,
.contact-panel::after,
.qt-fieldset::after {
  content: "";
  position: absolute;
  top: 14px;
  right: 16px;
  width: 84px;                 /* aspect-ratio derives the height -> proportional */
  aspect-ratio: 1760 / 576;
  background: url("assets/kilm/kiLM_alone_black.webp") no-repeat center / contain;
  opacity: 0.9;
  pointer-events: none;        /* purely decorative; never intercepts clicks */
}
/* Vertically centre the mark on the contact panel's heading line ("Request a
   license or demo"): panel padding 26px + ~30px h2 line → centre ≈ 41px; mark is
   ~27.5px tall, so top ≈ 27px lines its centre up with the heading. */
.contact-panel::after { top: 27px; }
@media (max-width: 640px) {
  .chat-panel::after,
  .contact-panel::after,
  .qt-fieldset::after { width: 60px; top: 10px; right: 10px; }
}

/* ---------------------------------------------------------------------------
 * Approach section (2026-07-05) — a locale-aware overview banner (Step 0)
 * followed by five steps stacked VERTICALLY, each a FULL-WIDTH <img> placard
 * (.approach-media > img) with its step label centered ABOVE. Images live at
 * assets/kilm/approach/Approach_Steps0/_Step1..5_{en,jp}.webp and are swapped
 * per language by scripts/site.js via data-i18n-src. The <img> sizes the
 * placard (no fixed aspect-ratio / cropping); source art is 2752x1536.
 * ------------------------------------------------------------------------- */
.approach-overview {
  margin: 32px 0 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-strong);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.approach-steps {
  list-style: none;
  margin: 32px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 48px;
}
.approach-step {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.approach-media {
  position: relative;
  width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-strong);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.approach-overview { position: relative; }
.approach-media img,
.approach-overview img {
  display: block;
  width: 100%;
  height: auto;
}
/* The Approach images are now 2-slide carousels (.why-stage). The global
   .why-stage aspect-ratio (1000/546 ≈ 1.83, sized for the old 2752x1536 art)
   left the 1600x1000 v2 step images short/cut. Size the stage to the v2 aspect
   (1.6) so the whole infographic shows at full height; the slide img is
   object-fit:contain so the wider old slide just letterboxes, never crops. */
.approach-section .why-stage {
  aspect-ratio: 1600 / 1000;
}
/* Capabilities carousels (image-search / MCP / Ontology / Federated) interleave a
   1600x1000 (1.6) v2 slide with a wider ~1.83 original. The global .why-stage 1.83
   box left the 1.6 primary slide short/cut; size to 1.6 so it shows at full height
   (the wider original just letterboxes, object-fit:contain never crops). */
.solution-carousel .why-stage {
  aspect-ratio: 1600 / 1000;
}
/* kiLM mark, bottom-center of every step image + the overview banner. Rendered at
   the wordmark's NATIVE ratio (670x194 ≈ 3.45:1) and filling its box edge-to-edge
   — same proportion as the "Ask kiLM" FAB glyph (.chat-fab-logo). No white plate
   / border; a whisper-light drop-shadow keeps the black mark legible over the
   light sky artwork. Root-absolute asset path so it resolves from /, /en/, /ja/. */
.approach-media::before,
.approach-overview::before {
  content: "";
  position: absolute;
  bottom: clamp(8px, 1.8%, 18px);
  left: 50%;
  transform: translateX(-50%);
  width: clamp(70px, 11%, 120px);
  aspect-ratio: 670 / 194;
  background: url("/assets/kilm/kiLM_alone_black.webp") no-repeat center / contain;
  filter: drop-shadow(0 1px 2px rgba(255, 255, 255, 0.6));
  opacity: 0.3; /* 70% transparent (30% opaque) */
  z-index: 2;
  pointer-events: none;
}
.approach-num { display: none; }
.approach-label {
  margin: 0;
  text-align: center;
  font-weight: 600;
  font-size: clamp(1.05rem, 2.2vw, 1.4rem);
  color: var(--ink);
}
@media (max-width: 720px) {
  .approach-steps { gap: 32px; }
}

/* Solutions section infographic (e.g. Time-series / Operational Data). Full-width
   bordered figure matching the .approach-media card treatment. */
.solution-figure {
  margin: 24px 0 0;
}
/* Small italic caption under an illustrative image (figcaption). */
.figure-note {
  margin: 8px 0 0;
  font-size: 0.8rem;
  color: var(--muted, #64748b);
  text-align: center;
  font-style: italic;
}
/* Wrapper for the Chat/Image-Search carousel — same top spacing as a static
   solution-figure, but WITHOUT `.solution-figure img` (which would frame each
   carousel slide individually); the `.why-stage` box is the frame. */
.solution-carousel {
  margin: 24px 0 0;
}
.solution-figure img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  background: var(--surface-strong);
}

/* ---- Floating "Ask kiLM" chat (FAB + dialog) ---------------------------- */
.interactive-grid-single {
  grid-template-columns: minmax(0, 1fr);
  max-width: 720px;
  margin-inline: auto;
}

.chat-fab {
  position: fixed;
  right: 22px;
  bottom: 22px;
  z-index: 60;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  /* Slim vertical padding — the 26px kiLM logo sets the height; keep only a
     small top/bottom buffer so the pill isn't taller than it needs to be. */
  padding: 6px 18px;
  border: 1px solid var(--grad-border-strong);
  border-radius: 999px;
  cursor: pointer;
  color: var(--ink);
  /* Echo the page's four-CORNER brand gradient (see --grad-brand-corners). */
  background: var(--grad-brand-corners);
  box-shadow: var(--shadow);
  font: inherit;
  font-weight: 600;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.chat-fab:hover { transform: translateY(-2px); }
.chat-fab:focus-visible { outline: 2px solid var(--line-strong); outline-offset: 2px; }

@media (max-width: 560px) {
  /* Compact to an icon-only bubble on small screens. */
  .chat-fab { right: 16px; bottom: 16px; padding: 10px; }
  .chat-fab-label { display: none; }
}

/* --- Site search: pill box that sits directly ABOVE the "Ask kiLM" FAB ------
   Same bottom-right anchor + rounded-pill shape as .chat-fab; results stack
   UPWARD (column-reverse) above the input so they never overlap the FAB. */
.site-search {
  position: fixed;
  right: 22px;
  bottom: 72px; /* clears the slimmed 22px-bottom FAB + its height + a gap */
  z-index: 60;
  /* Fallback width until JS matches it to the FAB's measured width (so the box
     is exactly as wide as the chat glyph). JS sets an inline width on desktop. */
  width: min(320px, calc(100vw - 44px));
}
.site-search-box {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 12px;
  border: 1px solid var(--grad-border-strong);
  border-radius: 999px;
  background: var(--surface-stronger);
  box-shadow: var(--shadow);
  transition: box-shadow 0.15s ease, border-color 0.15s ease;
}
.site-search-box:focus-within {
  border-color: var(--line-strong);
  box-shadow: var(--shadow), 0 0 0 3px var(--surface-tint);
}
.site-search-icon { flex: none; color: var(--ink-soft); }
.site-search-input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  outline: none;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 0.95rem;
  padding: 2px 0;
}
.site-search-input::placeholder { color: var(--ink-muted); }
/* Hide the native search "×" so only our themed clear button shows. */
.site-search-input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.site-search-clear {
  flex: none;
  width: 22px;
  height: 22px;
  border: 0;
  border-radius: 50%;
  background: var(--surface-tint);
  color: var(--ink-soft);
  cursor: pointer;
  font-size: 0.8rem;
  line-height: 1;
}
.site-search-clear:hover { color: var(--ink); }

/* Results panel: anchored to the box, growing UPWARD. column-reverse puts the
   best match (DOM index 0) nearest the input. */
.site-search-results {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 0;
  right: 0;
  display: flex;
  flex-direction: column-reverse;
  margin: 0;
  padding: 6px;
  list-style: none;
  max-height: min(60vh, 420px);
  overflow-y: auto;
  border: 1px solid var(--line-strong);
  border-radius: 14px;
  background: var(--surface-stronger);
  box-shadow: var(--shadow);
}
.site-search-results[hidden] { display: none; }
.site-search-result { margin: 0; }
.site-search-result > a {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 8px 10px;
  border-radius: 9px;
  text-decoration: none;
  color: var(--ink);
}
.site-search-result:hover > a,
.site-search-result[aria-selected="true"] > a {
  background: var(--surface-tint);
}
.site-search-title { font-weight: 600; font-size: 0.92rem; line-height: 1.25; }
.site-search-page {
  font-size: 0.72rem;
  color: var(--ink-muted);
  text-transform: capitalize;
  letter-spacing: 0.01em;
}
.site-search-empty {
  padding: 10px 12px;
  color: var(--ink-muted);
  font-size: 0.88rem;
  text-align: center;
}
@media (max-width: 560px) {
  /* Ride just above the compacted icon-only FAB (bottom:16px). Full-width here
     (JS leaves the width to CSS below 560px, where the FAB is a tiny icon). */
  .site-search { right: 16px; bottom: 66px; width: calc(100vw - 32px); }
}
@media (prefers-reduced-motion: reduce) {
  .site-search-box { transition: none; }
}

.chat-dialog {
  width: min(528px, calc(100vw - 32px));
  height: min(86vh, 560px);
  margin: auto;
  padding: 20px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--surface-stronger);
  color: var(--ink);
  box-shadow: var(--shadow);
  overflow: auto;
  /* User-resizable: drag the bottom-right corner to grow/shrink the window.
     resize needs a non-visible overflow (we have auto) + explicit sizing; the
     min/max keep it usable and on-screen. width/height above are the initial
     size; the user's drag overrides within these bounds. */
  resize: both;
  min-width: 320px;
  min-height: 320px;
  max-width: calc(100vw - 24px);
  max-height: 92vh;
}
.chat-dialog::backdrop { background: rgba(0, 0, 0, 0.55); }
.chat-dialog:not([open]) { display: none; }
/* Open as a flex column so the message panel fills the remaining height — this
   is what makes the `resize: both` handle useful: dragging the dialog taller
   grows the transcript instead of just adding blank space below it. */
.chat-dialog[open] { display: flex; flex-direction: column; }
.chat-dialog-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}
/* Keep brand casing ("Ask kiLM"), not the global uppercase ("ASK KILM"). */
.chat-dialog-head .eyebrow { margin: 0 0 2px; text-transform: none; letter-spacing: 0.02em; }
.chat-dialog-head h2 { margin: 0; font-size: clamp(1.05rem, 2.4vw, 1.35rem); }
.chat-dialog-copy { color: var(--ink-muted); font-size: 0.9rem; margin: 8px 0 14px; }
.chat-dialog-close {
  flex: none;
  width: 34px;
  height: 34px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface-tint);
  color: var(--ink-soft);
  cursor: pointer;
  font-size: 1rem;
  line-height: 1;
}
.chat-dialog-close:hover { color: var(--ink); border-color: var(--line-strong); }
.chat-dialog .chat-panel { border: 0; padding: 0; background: transparent; box-shadow: none; }
/* Inside the resizable dialog, drop the standalone panel's fixed 590px min-height
   and let it + the transcript flex to the dialog's current (draggable) height. */
.chat-dialog .chat-panel { min-height: 0; flex: 1 1 auto; }
.chat-dialog .chat-window { max-height: none; min-height: 120px; }
/* Suppress the decorative corner kiLM mark inside the dialog — the dialog
   header already carries the brand, and the mark overlapped the first message. */
.chat-dialog .chat-panel::after { content: none; }
/* Top-right header group: brand mark sits just before the × close button. */
.chat-dialog-head-right { display: flex; align-items: center; gap: 8px; flex: none; }
.chat-dialog-headmark { height: 24px; width: auto; display: block; opacity: 0.9; }
/* kiLM logo on the FAB — 26px to match the portal's .chat-fab-logo. */
.chat-fab-logo { height: 26px; width: auto; display: block; }

/* LLM-usage: subheads separating the two recommendation tables. */
.llm-rec-subhead { margin: 28px 0 12px; font-size: clamp(1rem, 2.2vw, 1.2rem); }

/* (Platform section pager removed 2026-07-23 — separate pages, no prev/next.) */

/* ==========================================================================
   6Ws sections — Why carousel, Where grid, Who grid, When list
   The Why stage deliberately reuses .video-stage / .video-topbar /
   .video-controls / .progress-track so it reads as a sibling of the Brand
   Story panel rather than a new component; only the slide layer is new.
   ========================================================================== */

.why-stage {
  display: grid;
  /* The Why slides are INFOGRAPHICS with text, not a video — `object-fit: cover`
     inside the inherited 450-560px `.video-stage` box cropped their edges. Drop
     the tall min-height and let the stage follow the image's aspect ratio
     (2000x1092 ≈ 1.832) so the whole infographic shows with no crop. */
  aspect-ratio: 1000 / 546;
  min-height: 0;
}
.why-stage > .why-slide {
  grid-area: 1 / 1;
  opacity: 0;
  transition: opacity 600ms ease;
  pointer-events: none;
}
.why-stage > .why-slide.is-active { opacity: 1; pointer-events: auto; }
.why-slide img {
  width: 100%;
  height: 100%;
  /* contain (not cover) — never crop an infographic; the aspect-ratio above
     keeps letterboxing to ~0. */
  object-fit: contain;
  object-position: center;
  display: block;
  border-radius: inherit;
}
/* Bigger image panel, narrower text panel (operator request). Desktop-only so
   the max-width:940px stack below is untouched — a `.why-section .video-layout`
   rule would otherwise out-specify that stack and keep two columns on mobile. */
@media (min-width: 941px) {
  .why-section .video-layout {
    /* Bigger image panel, narrower text panel, and STRETCH both columns to the
       same height so the infographic matches the story panel on the right
       (operator request) — the interleaved v2 images are 1600x1000 (taller than
       the old 2000x1092), so a fixed aspect ratio left them short. */
    grid-template-columns: minmax(0, 2.2fr) minmax(0, 0.85fr);
    align-items: stretch;
  }
  /* Let the carousel fill the stretched row height instead of its own aspect
     ratio; the slide img is object-fit:contain so nothing is cropped. */
  .why-section .why-slot {
    height: 100%;
  }
  .why-section .why-stage {
    aspect-ratio: auto;
    flex: 1 1 auto;
    min-height: 0;
  }
}
/* The stage is a grid, so the chrome must be lifted above the slide layer. */
.why-stage > .video-topbar,
.why-stage > .video-controls { grid-area: 1 / 1; z-index: 2; }
.why-stage > .video-controls { align-self: end; }
.why-stage > .video-topbar { align-self: start; }

/* --- Why carousel prev/next arrows + position counter -------------------- */
/* Manual navigation so a visitor can flip through all four Why infographics
   (the auto-advance + Pause alone left no obvious way to step between them).
   The arrows sit ON the stage, vertically centred, high-contrast, always
   visible. */
.why-stage > .why-nav {
  grid-area: 1 / 1;
  z-index: 4;
  align-self: center;
  width: 52px;
  height: 52px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.55);
  border-radius: 999px;
  background: rgba(11, 13, 18, 0.66);
  color: #fff;
  cursor: pointer;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(4px);
  transition: background 160ms ease, transform 160ms ease, border-color 160ms ease;
}
.why-stage > .why-nav:hover {
  background: rgba(11, 13, 18, 0.9);
  border-color: #fff;
  transform: scale(1.06);
}
.why-stage > .why-nav:active { transform: scale(0.96); }
.why-stage > .why-nav:focus-visible {
  outline: 3px solid var(--amber);
  outline-offset: 3px;
}
.why-nav-prev { justify-self: start; margin-left: 14px; }
.why-nav-next { justify-self: end; margin-right: 14px; }

.why-stage > .why-counter {
  grid-area: 1 / 1;
  z-index: 4;
  align-self: start;
  justify-self: end;
  margin: 14px;
  padding: 4px 11px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.35);
  background: rgba(11, 13, 18, 0.66);
  color: #fff;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.02em;
  backdrop-filter: blur(4px);
}

@media (prefers-reduced-motion: reduce) {
  .why-stage > .why-slide { transition: none; }
}

/* --- Where / Who card grids ---------------------------------------------- */
.where-grid,
.who-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1.25rem;
  margin-top: 2rem;
}
.where-card,
.who-card {
  padding: 1.5rem;
  border: 1px solid var(--border, rgba(148, 163, 184, 0.25));
  border-radius: 14px;
  background: var(--surface, rgba(255, 255, 255, 0.03));
}
.where-card h3,
.who-card h3 { margin: 0 0 0.6rem; }
.where-card p,
.who-card p { margin: 0 0 0.5rem; }
.where-note {
  font-size: 0.9rem;
  opacity: 0.75;
  margin-bottom: 0 !important;
}
.where-footnote { margin-top: 1.75rem; opacity: 0.8; }

/* --- Who: fit / not-yet columns ------------------------------------------ */
.who-fit {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1.5rem;
  margin-top: 2rem;
}
.who-fit-col h3 { margin: 0 0 0.75rem; }
.who-fit-col ul { margin: 0; padding-left: 1.1rem; }
.who-fit-col li { margin-bottom: 0.5rem; }

/* --- When: numbered reasons ---------------------------------------------- */
.when-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1.5rem;
  margin-top: 2rem;
  padding-left: 0;
  list-style: none;
  counter-reset: when;
}
.when-item {
  counter-increment: when;
  padding: 1.5rem;
  border-radius: 14px;
  border: 1px solid var(--border, rgba(148, 163, 184, 0.25));
  background: var(--surface, rgba(255, 255, 255, 0.03));
}
.when-item::before {
  content: counter(when);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  margin-bottom: 0.75rem;
  border-radius: 999px;
  font-weight: 700;
  background: var(--accent-soft, rgba(56, 189, 248, 0.15));
}
.when-item h3 { margin: 0 0 0.5rem; }
.when-item p { margin: 0; }
.when-closing {
  margin-top: 2rem;
  font-size: 1.05rem;
  font-weight: 500;
}

/* ==========================================================================
   Hero text-pane slider (data-hero-slider). Slide 1 = flashy "Introducing"
   intro (fireworks bg + gradient title + word highlight); slide 2 = the
   ORIGINAL hero copy band. Video row + CTAs sit BELOW, unchanged. Autoplay 10s.
   ========================================================================== */
.hero-slider { position: relative; width: 100%; }
.hero-slider-viewport { overflow: hidden; }
.hero-slider-track {
  display: flex;
  align-items: stretch;
  transition: transform 700ms cubic-bezier(0.4, 0, 0.2, 1);
  will-change: transform;
}
.hero-panel { flex: 0 0 100%; min-width: 100%; }
/* position:relative + overflow:hidden so the slide-2 fireworks canvas (an absolutely
   positioned first child) fills the panel behind the content band and is clipped.
   Vertical padding opens a margin above/below the band so the fireworks read clearly
   as a background (the band itself is translucent, so bursts also bloom through it). */
.hero-panel-main {
  position: relative;
  overflow: hidden;
  display: grid;
  align-content: center;
  padding: clamp(18px, 3vw, 40px) 0;
}

/* Slide 1 — flashy intro band: badge on top, then [icon | title | wordmark]. */
.hero-panel-intro { display: flex; flex-direction: column; justify-content: center; }
.hero-intro-card {
  position: relative;
  overflow: hidden;                     /* clips fireworks + ring to the rounded box */
  width: min(100% - 32px, var(--max));
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: clamp(9px, 1.3vw, 15px);
  padding: clamp(14px, 1.8vw, 22px) clamp(20px, 2.5vw, 34px);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background:
    radial-gradient(130% 200% at 8% 0%, rgba(90, 135, 153, 0.28), transparent 55%),
    radial-gradient(130% 200% at 100% 100%, rgba(224, 182, 58, 0.14), transparent 55%),
    linear-gradient(150deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.012)),
    #05070c;
  box-shadow: var(--shadow), inset 0 0 0 1px rgba(255, 255, 255, 0.03);
}
.hero-intro-card::after {                /* glowing gradient ring */
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(120deg, rgba(90, 135, 153, 0.7), rgba(77, 163, 220, 0.5), rgba(224, 182, 58, 0.6));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  opacity: 0.6;
  pointer-events: none;
  z-index: 2;
}
.hero-fw-canvas {                        /* fireworks — behind content, rounded to card */
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  z-index: 0;
  pointer-events: none;
}

/* icon + title + wordmark row — icon vertically CENTERED with the title */
.hero-intro-main {
  position: relative;
  z-index: 1;
  display: flex;
  flex-flow: row nowrap;
  align-items: center;
  gap: clamp(12px, 1.8vw, 20px);
  width: 100%;
}
.hero-intro-icon {
  flex: none;
  align-self: center;
  width: clamp(54px, 6.5vw, 86px);
  /* The wordmark image above has asymmetric transparent padding (49px left vs
     7px right of 1100px), so its VISIBLE content is centred at 51.9% of the box,
     not 50%. align-items:center centres this circle on the box, leaving it ~4px
     LEFT of the wordmark's visible centre (the "left-leaning" look). Nudge right
     by 1.905% of the wordmark's displayed width (= 0.312vw, tracks its clamped
     height), clamped to the wordmark's min/max. position (not transform) so it
     doesn't fight the heroIconGlow animation. */
  position: relative;
  left: clamp(2.86px, 0.312vw, 4.17px);
  /* Circular badge: clip the square favicon tile to a circle. aspect-ratio +
     object-fit keep it a perfect round crop (not an oval) at every clamp size. */
  aspect-ratio: 1 / 1;
  height: auto;
  object-fit: cover;
  border-radius: 50%;
  filter: drop-shadow(0 4px 16px rgba(90, 135, 153, 0.65));
  animation: heroIconGlow 4.5s ease-in-out infinite;
  /* Centred under the ENTIRE wordmark above (mark + kiLM + tagline). */
}
/* Center column: kicker ("a Sovereign & Neurosymbolic", top-pinned to the
   Introducing-badge level) → big "AI Platform" title → blinking tagline. */
.hero-intro-center {
  flex: 1 1 0;
  min-width: 0;
  align-self: flex-start;   /* first line (kicker) lines up with the Introducing badge + wordmark */
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: clamp(5px, 0.8vw, 11px);
}
.hero-intro-wordmark {
  flex: none;
  align-self: center;
  height: clamp(22px, 2.4vw, 32px);
  width: auto;
  opacity: 0.9;
  margin-left: 0;
}

.hero-flag {
  display: inline-block;
  width: 1.08em;                 /* 3:2 flag ratio at 0.72em tall */
  height: 0.72em;
  margin: 0 0.16em;
  vertical-align: 0.01em;         /* centered on the CJK ink (measured, not baseline) */
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.3);
}
.hero-intro-left {
  flex: none;
  align-self: flex-start;         /* pin to the top of the row → badge level with the right wordmark */
  display: flex;
  flex-direction: column;
  align-items: center;            /* glyph centers under the Introducing badge */
  gap: clamp(10px, 1.4vw, 16px);
}
/* Right column: kiLM wordmark on top (level with "Introducing"), neural-net icon
   centered below it. */
.hero-intro-right {
  flex: none;
  align-self: flex-start;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(10px, 1.4vw, 16px);
}
/* Chat glyph (the ki&LM lockup) below the "Introducing" badge. Its artwork carries
   a dark ground that blends into the card; a soft rounded frame keeps it tidy. */
.hero-intro-glyph {
  width: clamp(128px, 15vw, 188px);
  height: auto;
  border-radius: 10px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45);
  /* Both columns are top-pinned, but the right-hand neural icon (square, up to
     86px) is taller than this glyph (up to ~54px), so its centre sits ~18px
     lower. Drop the glyph by (iconH-glyphH)/2 + (wordmarkH-badgeH) so the two
     lower icons share a horizontal centre line. Fitted across the responsive
     range; clamps to 18.3px at desktop (card capped at --max, all clamps maxed)
     and collapses to 0 below ~785px, before the 640px wrap kicks in. */
  position: relative;
  top: clamp(0px, calc(3.26vw - 25.6px), 18.3px);
}
.hero-intro-badge {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 14px;
  font-size: clamp(11px, 1.1vw, 13px);
  font-weight: 800;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #0b0d12;
  background: linear-gradient(135deg, var(--amber), #f2cf6b);
  border-radius: 999px;
  box-shadow: 0 6px 20px rgba(224, 182, 58, 0.35);
}
.hero-intro-badge::before { content: "\2726"; font-size: 12px; }

/* Big GRADIENT title (yellow/green/red/blue, echoing the fireworks + bg edges). */
.hero-intro-title {
  position: relative;
  margin: 0;
  /* Sized to keep the (longer) "a Sovereign & Neurosymbolic" on ONE line inside
     the center column; white-space:nowrap is the hard guarantee it never wraps. */
  font-size: clamp(15px, 2.4vw, 30px);
  white-space: nowrap;
  line-height: 1.14;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: #e6ecf3;                        /* fallback if background-clip:text unsupported */
}
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .hero-intro-title {
    background: linear-gradient(100deg, #e0b63a 0%, #83bf4f 34%, #ef4e50 66%, #4da3dc 100%);
    background-size: 220% 100%;                 /* wider than the text so the sheen can travel */
    -webkit-background-clip: text;
            background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
    animation: heroTitleShimmer 7s ease-in-out infinite alternate;
  }
}
/* Sparkling sheen: pan the gradient back and forth so light drifts across the text. */
/* Kicker above the big title — sits at the Introducing-badge level. */
.hero-intro-kicker {
  font-size: clamp(13px, 1.6vw, 21px);
  font-weight: 700;
  letter-spacing: 0.01em;
  line-height: 1.2;
  color: var(--ink-soft);
}
/* Tagline below "AI Platform". Its three phrases ("Your Data" / "Your LLM" /
   "Your Intellectual Property") are wrapped in .hero-tagline-word spans by JS
   (taglineBlink) and lit one-by-one in order; separators stay steady. Without
   JS every phrase renders full-opacity (progressive enhancement). */
.hero-intro-tagline {
  display: block;
  font-size: clamp(12px, 1.35vw, 18px);
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.03em;
  color: var(--amber);
}
.hero-intro-tagline .hero-tagline-word {
  transition: opacity 0.4s ease, text-shadow 0.4s ease;
}
.hero-intro-tagline[data-blink-ready] .hero-tagline-word { opacity: 0.35; }
.hero-intro-tagline[data-blink-ready] .hero-tagline-word.is-blink {
  opacity: 1;
  text-shadow: 0 0 12px rgba(224, 182, 58, 0.55);
}
@media (prefers-reduced-motion: reduce) {
  .hero-intro-tagline[data-blink-ready] .hero-tagline-word {
    opacity: 1;
    text-shadow: none;
  }
}

@keyframes heroTitleShimmer {
  0%   { background-position: 0% 50%; }
  100% { background-position: 100% 50%; }
}
/* per-word highlight sweep. Base words keep the parent gradient (NO opacity/filter/
   transform on the span — those isolate it from background-clip:text and blank it out).
   The lit word overrides its text fill to bright white + glow, which does not isolate. */
.hero-word { transition: color 0.3s ease, text-shadow 0.3s ease, -webkit-text-fill-color 0.3s ease; }
.hero-word.is-lit {
  color: #ffffff;
  -webkit-text-fill-color: #ffffff;
  text-shadow: 0 0 20px rgba(255, 255, 255, 0.75), 0 0 8px rgba(120, 200, 255, 0.6);
}

/* Twinkling star sparkles scattered over the title. Rendered as pseudo-element
   backgrounds (NOT DOM children), so the wordSweep split() — which rewrites the
   title's textContent — never disturbs them. background-clip:text on the title
   applies only to the element's own text fill, not to these pseudo boxes. */
.hero-intro-title::before,
.hero-intro-title::after {
  content: "";
  position: absolute;
  left: -2%;
  top: -24%;
  width: 104%;
  height: 148%;
  z-index: 3;
  pointer-events: none;
  background-repeat: no-repeat;
}
.hero-intro-title::before {
  background-image:
    radial-gradient(circle, rgba(255, 255, 255, 0.95) 0, rgba(255, 255, 255, 0.95) 1.3px, transparent 2.6px),
    radial-gradient(circle, rgba(180, 225, 255, 0.9) 0, rgba(180, 225, 255, 0.9) 1px, transparent 2.2px),
    radial-gradient(circle, rgba(255, 236, 170, 0.9) 0, rgba(255, 236, 170, 0.9) 1px, transparent 2.2px);
  background-position: 11% 26%, 63% 14%, 39% 84%;
  background-size: 7px 7px, 6px 6px, 6px 6px;
  animation: heroTwinkleA 2.6s ease-in-out infinite;
}
.hero-intro-title::after {
  background-image:
    radial-gradient(circle, rgba(255, 255, 255, 0.95) 0, rgba(255, 255, 255, 0.95) 1.3px, transparent 2.6px),
    radial-gradient(circle, rgba(190, 255, 205, 0.9) 0, rgba(190, 255, 205, 0.9) 1px, transparent 2.2px),
    radial-gradient(circle, rgba(255, 190, 190, 0.9) 0, rgba(255, 190, 190, 0.9) 1px, transparent 2.2px);
  background-position: 86% 66%, 27% 8%, 54% 44%;
  background-size: 7px 7px, 6px 6px, 6px 6px;
  animation: heroTwinkleB 3.1s ease-in-out infinite;
}
@keyframes heroTwinkleA {
  0%, 100% { opacity: 0.12; }
  50%      { opacity: 1; }
}
@keyframes heroTwinkleB {
  0%, 100% { opacity: 1; }
  45%      { opacity: 0.15; }
}

/* pagination dots */
.hero-slider-dots { display: flex; justify-content: center; gap: 10px; margin: clamp(12px, 1.6vw, 18px) auto 0; }
.hero-slider-dot {
  width: 10px; height: 10px; padding: 0; border: 0; border-radius: 999px; cursor: pointer;
  background: var(--line-strong);
  transition: transform 0.2s ease, background 0.2s ease, width 0.2s ease;
}
.hero-slider-dot.is-active { width: 26px; background: linear-gradient(90deg, var(--teal), var(--sky)); }
.hero-slider-dot:hover { background: var(--ink-muted); }
.hero-slider-dot:focus-visible { outline: 2px solid var(--sky); outline-offset: 3px; }

@keyframes heroIconGlow {
  0%, 100% { filter: drop-shadow(0 4px 16px rgba(90, 135, 153, 0.5)); }
  50%      { filter: drop-shadow(0 6px 24px rgba(77, 163, 220, 0.85)); }
}

:lang(ja) .hero-intro-title { font-size: clamp(15px, 2.2vw, 28px); letter-spacing: 0; }

@media (max-width: 640px) {
  .hero-intro-main { justify-content: center; flex-wrap: wrap; }
  .hero-intro-wordmark { margin-left: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-slider-track { transition: none; }
  .hero-intro-icon { animation: none; }
  .hero-word { transition: none; }
}


/* === use-case detail cards (use-cases.html) === */
.uc-detail {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
  margin-top: 30px;
}
.uc-detail .uc-block {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background:
    linear-gradient(145deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0.012)),
    var(--surface-strong);
  padding: 22px;
}
.uc-detail .uc-block h3 {
  margin: 0 0 12px;
  color: var(--ink-soft);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}
.uc-detail .uc-block p {
  margin: 0;
  color: var(--ink-muted);
  font-size: 15px;
  line-height: 1.55;
}
.uc-detail .uc-block ul {
  margin: 0;
  padding-left: 18px;
  color: var(--ink-muted);
  font-size: 15px;
  line-height: 1.5;
}
.uc-detail .uc-block ul li { margin: 0 0 8px; }
.uc-detail .uc-block ul li:last-child { margin-bottom: 0; }
@media (max-width: 900px) {
  .uc-detail { grid-template-columns: 1fr; gap: 14px; margin-top: 22px; }
}


/* === platform.html: lifecycle, pillars, differentiators, product views === */
.platform-flow-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
@media (max-width: 1100px) { .platform-flow-6 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 680px)  { .platform-flow-6 { grid-template-columns: 1fr; } }

.governance-rail {
  display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: center; justify-content: center;
  margin-top: 20px; padding: 14px 18px;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface-tint);
}
.governance-rail span {
  position: relative; padding-left: 18px;
  color: var(--ink-soft); font-size: 13px; font-weight: 600; letter-spacing: 0.02em;
}
.governance-rail span::before {
  content: ""; position: absolute; left: 0; top: 50%; width: 9px; height: 9px; margin-top: -4px;
  border-radius: 50%; background: rgba(var(--green), 0.85);
}

.badge-legend { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 26px; }
.badge-legend .legend-intro { color: var(--ink-muted); font-size: 13px; margin-right: 4px; }
.badge-legend .legend-dim { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; flex-basis: 100%; }
.badge-legend .legend-dim-label { color: var(--ink-muted); font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; margin-right: 2px; }

.uc-badge {
  display: inline-block; font-size: 11px; font-weight: 700; letter-spacing: 0.04em;
  text-transform: uppercase; padding: 3px 9px; border-radius: 999px; white-space: nowrap;
  border: 1px solid transparent;
}
.badge-available { background: rgba(120, 200, 0, 0.14); color: #a6e05a; border-color: rgba(120, 200, 0, 0.30); }
.badge-optional  { background: rgba(90, 135, 153, 0.18); color: #9fc3d4; border-color: rgba(90, 135, 153, 0.35); }
.badge-connector { background: rgba(224, 182, 58, 0.14); color: #e0b63a; border-color: rgba(224, 182, 58, 0.32); }
.badge-preview   { background: rgba(224, 182, 58, 0.16); color: #f0c860; border-color: rgba(224, 182, 58, 0.34); }
.badge-roadmap   { background: rgba(255, 255, 255, 0.06); color: var(--ink-muted); border-color: var(--line); }

.pillar-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; margin-top: 26px; }
@media (max-width: 980px) { .pillar-grid { grid-template-columns: 1fr; } }
.pillar-card {
  display: flex; flex-direction: column;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: linear-gradient(145deg, rgba(255,255,255,0.035), rgba(255,255,255,0.012)), var(--surface-strong);
  padding: 22px;
}
.pillar-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.pillar-head h3 { margin: 0; color: var(--ink); font-size: 19px; line-height: 1.25; }
.pillar-card ul { margin: 0 0 16px; padding-left: 18px; color: var(--ink-muted); font-size: 14.5px; line-height: 1.5; }
.pillar-card ul li { margin: 0 0 8px; }
.pillar-card ul li:last-child { margin-bottom: 0; }
.pillar-link { margin-top: auto; color: var(--teal); font-size: 14px; font-weight: 600; text-decoration: none; }
.pillar-link::after { content: " \2192"; }
.pillar-link:hover { text-decoration: underline; }

.diff-grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 16px; margin-top: 26px; }
@media (max-width: 1100px) { .diff-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px)  { .diff-grid { grid-template-columns: 1fr; } }
.diff-item { border-top: 2px solid rgba(var(--green), 0.5); padding-top: 14px; }
.diff-item h3 { margin: 0 0 8px; color: var(--ink); font-size: 16px; }
.diff-item p { margin: 0; color: var(--ink-muted); font-size: 14px; line-height: 1.5; }

/* "Explore the Platform" — scroll-through overview of the Platform sub-pages.
   Each card reuses the target page's own title + lede (auto-synced via i18n) and
   links out to the full page; the heavy pages stay separate. */
.plat-explore-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
  margin-top: 26px;
}
@media (max-width: 720px) { .plat-explore-grid { grid-template-columns: 1fr; } }
.plat-explore-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 22px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgba(var(--green), 0.03);
}
.plat-explore-card h3 { margin: 0; color: var(--ink); font-size: 18px; }
.plat-explore-card p {
  margin: 0;
  flex: 1 1 auto;
  color: var(--ink-muted);
  font-size: 14px;
  line-height: 1.55;
}
.plat-explore-link {
  margin-top: 4px;
  align-self: flex-start;
  font-weight: 600;
  font-size: 14px;
  color: rgb(var(--green));
  text-decoration: none;
}
.plat-explore-link:hover { text-decoration: underline; }

.product-view-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; margin-top: 26px; }
@media (max-width: 980px) { .product-view-grid { grid-template-columns: 1fr; } }
.product-view { margin: 0; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--surface-strong); }
.product-view-frame {
  aspect-ratio: 16 / 10; display: flex; align-items: center; justify-content: center;
  background:
    repeating-linear-gradient(45deg, rgba(255,255,255,0.03) 0 10px, rgba(255,255,255,0.015) 10px 20px),
    var(--surface-tint);
  border-bottom: 1px solid var(--line);
}
.pv-badge {
  color: var(--ink-muted); font-size: 12px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  border: 1px dashed var(--line); border-radius: 999px; padding: 5px 12px;
}
/* Product-view screenshots: full image shown (no crop) on a dark frame; the
   striped placeholder bg is dropped once an <img> is present. */
.product-view-frame img { width: 100%; height: 100%; object-fit: contain; display: block; }
.product-view-frame:has(img) { background: #0b0e16; }
.product-view figcaption { padding: 16px 18px; }
.product-view figcaption h3 { margin: 0 0 6px; color: var(--ink); font-size: 15px; }
.product-view figcaption p { margin: 0; color: var(--ink-muted); font-size: 13.5px; line-height: 1.5; }

.platform-cta { text-align: center; }
.platform-cta .hero-actions { justify-content: center; }


/* === solutions.html (Capabilities): selector, sub-nav, families === */
.cap-selector { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; margin-top: 4px; }
@media (max-width: 900px) { .cap-selector { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .cap-selector { grid-template-columns: 1fr; } }
.cap-select-card {
  display: flex; flex-direction: column; gap: 8px; text-decoration: none;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: linear-gradient(145deg, rgba(255,255,255,0.035), rgba(255,255,255,0.012)), var(--surface-strong);
  padding: 18px; transition: border-color 0.15s ease, transform 0.15s ease;
}
.cap-select-card:hover { border-color: var(--teal); transform: translateY(-2px); }
.cap-select-title { color: var(--ink); font-weight: 700; font-size: 16px; line-height: 1.25; }
.cap-select-tag { color: var(--ink-muted); font-size: 13px; line-height: 1.45; }

.cap-subnav {
  position: sticky; top: 72px; z-index: 20;
  display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; align-items: center;
  margin: 0 auto 8px; padding: 8px 10px; width: min(100% - 32px, var(--max));
  background: var(--surface-stronger); border: 1px solid var(--line); border-radius: 999px;
  backdrop-filter: blur(8px);
}
.cap-subnav a {
  color: var(--ink-soft); text-decoration: none; font-size: 13px; font-weight: 600;
  padding: 6px 12px; border-radius: 999px;
}
.cap-subnav a:hover { color: var(--ink); background: var(--surface-tint); }

.cap-family { border-top: 1px solid var(--line); padding-bottom: 16px; }
.cap-family .section-heading h2 { font-size: 30px; }
.cap-usecase-link { display: inline-block; margin-top: 12px; color: var(--teal); font-weight: 600; font-size: 14px; text-decoration: none; }
.cap-usecase-link::after { content: " \2192"; }
.cap-usecase-link:hover { text-decoration: underline; }


/* === left/right inset for new Platform + Capabilities sections === */
/* .sec-section (security.css) already insets content by clamp(1.5rem,4vw,4rem);
   these newer sections only carry .section (0 horizontal padding), so their
   headings/text hugged the content-band's left edge. Match the same inset so
   every section's text lines up. */
.platform-flow-section,
.ip-section,
.pillars-section,
.diff-section,
.product-views-section,
.platform-cta,
.cap-selector-section,
.cap-family {
  padding-left: clamp(1.5rem, 4vw, 4rem);
  padding-right: clamp(1.5rem, 4vw, 4rem);
}

/* Platform lifecycle row — the 6 flow cards need more width than the 1180px
   prose band gives them. Break out to a wider centred column and trim the side
   buffer so all 6 cards get real width: fixes EN "Normalize" wrapping mid-word
   and the JA cards (wider min-content) overflowing / clipping card 6. Pairs with
   .platform-flow-6 minmax(0,1fr) above. Still fits any viewport (min with
   100%-48px) and collapses to 3/1 cols at the existing breakpoints. */
.platform-flow-section {
  width: min(100% - 48px, 1680px);
  max-width: none;
  padding-left: clamp(1rem, 2.5vw, 2rem);
  padding-right: clamp(1rem, 2.5vw, 2rem);
}

/* Keep the 6 cards on the wide 1680 band, but return the eyebrow/title/intro to
   the normal 1180 content band so the header lines up with the sections above
   and below (it was hugging the wide band's left edge). Capping to --max and
   auto side-margins re-centres the heading on the same viewport centre as a
   normal .section; the padding matches the .sec-section text inset. */
.platform-flow-section .section-heading {
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: clamp(1.5rem, 4vw, 4rem);
}

/* platform.html hero uses .section-heading (not .sec-hero), so the global
   h1 max-width:650px capped the headline ~55% wide while the lede paragraph
   had NO cap and ran the full 1180 band. Bring both to 75% of the band (885px)
   to match the .sec-hero fix on every other page. Eyebrow is excluded. */
.platform-hero .section-heading h1 { max-width: 885px; }
.platform-hero .section-heading p:not(.eyebrow) { max-width: 885px; }


/* === services.html (Solutions): planned badge + family head/meta === */
.badge-planned { background: transparent; color: var(--ink-muted); border-color: var(--line); border-style: dashed; }
.cap-fam-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.cap-fam-meta { color: var(--ink-muted); font-size: 13px; line-height: 1.5; margin: 10px 0 0; }
/* IP-section legal note: align its left edge to the .sec-audit-list box above it
   (same 880px centred band) and give it a clear gap instead of hugging the box. */
.ip-section .cap-fam-meta { max-width: 880px; margin: 1.75rem auto 0; }
/* Symmetric buffer: the note below the boxes sits 1.75rem under them; give the
   box list the same 1.75rem gap from the intro copy above it. */
.ip-section .sec-audit-list { margin-top: 1.75rem; }

/* ---------------------------------------------------------------
   Collapsible sections (SITE-WIDE). <details class="sec-collapse">
   / <summary class="sec-summary"> fold a section under its <h2>.
   Native HTML5; the Collapse-all / Expand-all toolbar is
   JS-augmented (initSectionCollapseControls in site.js) and
   degrades gracefully. Lives here (not integrations.css) so every
   page can use it; integrations.css keeps only its .intg-grid packing.
   --------------------------------------------------------------- */
.sec-collapse { display: block; }
.sec-collapse .section-heading { max-width: none; margin: 0 0 1.6rem; text-align: left; }
.sec-summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.25rem 0;
  outline: none;
  -webkit-tap-highlight-color: transparent;
}
.sec-summary::-webkit-details-marker { display: none; }
.sec-summary::marker { content: ""; }
.sec-summary h2 { margin: 0; flex: 1 1 auto; }
.sec-summary::after {
  content: "";
  flex: 0 0 auto;
  width: 0.85rem;
  height: 0.85rem;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transform-origin: 60% 60%;
  transition: transform 180ms ease;
  opacity: 0.55;
  margin-right: 0.4rem;
}
details[open] > .sec-summary::after { transform: rotate(-135deg); opacity: 0.8; }
.sec-summary:hover::after,
.sec-summary:focus-visible::after { opacity: 1; }
.sec-summary:focus-visible {
  outline: 2px solid rgba(120, 180, 220, 0.55);
  outline-offset: 4px;
  border-radius: 6px;
}
.sec-summary:hover h2 { color: var(--ink-bright, #ffffff); }
.sec-collapse-controls {
  /* Sticky so the bulk toggle stays reachable as the visitor scrolls. Sits just
     below the fixed .site-header (z-index 50); this bar is z-index 20 so the
     header still overlaps it. `top` tracks the header height across breakpoints. */
  position: sticky;
  top: clamp(64px, 8vw, 100px);
  z-index: 20;
  width: min(100% - 32px, var(--max));
  margin: 0.9rem auto 1.4rem;
  padding: 0.45rem 1rem;
  display: flex;
  gap: 0.6rem;
  justify-content: flex-end;
  flex-wrap: wrap;
  background: rgba(11, 13, 18, 0.72);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 12px;
}
/* JS hides the redundant button: all-expanded shows only Collapse all,
   all-collapsed shows only Expand all, mixed shows both. */
.sec-collapse-controls button[hidden] { display: none; }
.sec-collapse-controls button {
  background: transparent;
  color: var(--ink-muted);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 999px;
  padding: 0.35rem 0.9rem;
  font-size: 0.82rem;
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease, border-color 150ms ease;
}
.sec-collapse-controls button:hover,
.sec-collapse-controls button:focus-visible {
  color: var(--ink, #f0f4f7);
  border-color: rgba(255, 255, 255, 0.32);
  background: rgba(255, 255, 255, 0.04);
  outline: none;
}


/* --- Hero: EI (Enterprise Intelligence) Platform + slide-2 copy effects --- */
.hero-intro-kicker { text-align: center; white-space: nowrap; }
.hero-intro-kicker .ei-expand { display: inline; font-size: 0.58em; font-weight: 600; letter-spacing: 0.02em; opacity: 0.85; vertical-align: middle; }
.hero-copy .hc-blink { transition: color 0.3s ease, text-shadow 0.3s ease; }
.hero-copy .hc-hl { color: var(--amber); }            /* persistent highlight = tagline "Your LLM" */
.hero-copy[data-blink-ready] .hc-blink.is-blink {
  background: linear-gradient(100deg, #d66257 0%, #d55e5d 30%, #c1666f 55%, #b76b78 72%, #a3748a 100%);
  background-size: 220% 100%;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  text-shadow: none;
  animation: heroTitleShimmer 7s ease-in-out infinite alternate;
}
@media (prefers-reduced-motion: reduce) {
  .hero-copy[data-blink-ready] .hc-blink.is-blink { color: inherit; text-shadow: none; }
  .hero-copy .hc-hl { color: var(--amber); }
}

/* kiLM Story pyramid: alternate the static still with the loop clip (5s each) */
.story-brand-stage { width: 100%; }
.story-brand-stage > [hidden] { display: none !important; }
