/* ==========================================================================
   Hakuro — stylesheet
   Shared by every page via _layouts/default.html, plus branding.html.
   Organized in three parts:
   1. Design tokens + reusable components (safe to use anywhere)
   2. Site layout: the shared header/footer chrome from _layouts/default.html,
      the one-pager's one-off index.html sections, and the .legal page
      template used by privacy-policy.html (built entirely on part 1's
      tokens/components)
   3. Style-guide-only scaffolding (documentation chrome from the
      branding.html catalog page itself — not needed anywhere else)
   ========================================================================== */

:root {
  /* ---- Sham (brand green ramp) ---- */
  --sham-025: #63f7c7;
  --sham-050: #24c791;
  --sham-100: #1e9970; /* true brand green */
  --sham-200: #1c7358;
  --sham-300: #1c4d3c;
  --sham-400: #1e2b26;
  --sham-600: #141c19; /* body background */
  --sham-800: #0c1210; /* darkest plane */

  /* ---- Sage (neutral, green-tinted) ---- */
  --sage-100: #f0f4f2;
  --sage-150: #e1e7e4; /* default offwhite text color */
  --sage-200: #d1d9d6;
  --sage-300: #b0bcb8; /* default body text */
  --sage-400: #8fa09a;
  --sage-500: #647470;
  --sage-600: #384843; /* borders/dividers */
  --sage-700: #2e3d38;
  --sage-800: #1e2e29;

  /* ---- Status (reserved, use sparingly) ---- */
  --terra-100: #c45c52;
  --terra-400: #7a3530;
  --terra-800: #180e0d;
  --amber-100: #c4853a;
  --amber-400: #7a5228;
  --amber-800: #191008;

  /* ---- Border radius: exactly 3 tiers ---- */
  --radius-m: 0.75rem;   /* medium — buttons and most bordered elements */
  --radius-l: 2.5rem;    /* large — card corners only */
  --radius-pill: 999px;  /* fully rounded — tag pills */

  /* ---- Spacing scale (layout rhythm: section/component padding, flex/grid gaps,
     block margins). Bespoke pixel geometry tied to a specific decorative effect
     — animation offsets, illustrative node positions, deck/stack transforms —
     is intentionally left as literal px, since it's part of that effect's own
     math rather than generic page spacing. ---- */
  --space-2xs: 0.25rem; /* 4px */
  --space-xs: 0.5rem; /* 8px */
  --space-sm: 0.75rem; /* 12px */
  --space-md: 1rem; /* 16px */
  --space-lg: 1.5rem; /* 24px */
  --space-xl: 2rem; /* 32px */
  --space-2xl: 3rem; /* 48px */
  --space-3xl: 4rem; /* 64px */
  --space-4xl: 5rem; /* 80px */
  --space-5xl: 7.5rem; /* 120px */
  --space-5xl: 7.5rem; /* 120px */
  --space-8xl: 10rem; /* 160px */

  /* ---- Container: exactly two shared content widths, used sitewide instead
     of one-off max-widths per selector. --container-w is the wide measure —
     every section-level row (header, footer, grids/lists spanning a full
     section) aligns to it. --container-w-narrow is the narrow measure — for
     centered text-only blocks (headings, prose, lists of copy) where a full
     -width line would be too long to read comfortably. Change widths here,
     not per-selector. ---- */
  --container-w: 1080px;
  --container-w-narrow: 640px;

  /* ---- Type ---- */
  --font-base: "Inter", sans-serif;
  --font-serif: "Source Serif 4", serif;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: var(--font-base);
  background: var(--sham-600);
  color: var(--sage-300);
  line-height: 1.5;
  font-size: 1rem;
  overflow-x: hidden;
}

h1,
h2 {
  font-family: var(--font-serif);
  color: var(--sage-400);
  font-weight: 600;
  margin: 0 0 0.4em;
}

/* Centralized heading sizes — one size per level, sitewide, set to the
   largest size previously used for that level in any single section. No
   section-specific font-size overrides for h1-h4 should exist below this;
   if a section needs a different size, it needs a different tag/class, not
   a per-section override of the same tag. */
h1 {
  font-size: 4.5rem;
  line-height: 1.2;
}

h2 {
  font-size: 1.7rem;
}

/* h3's default is what card titles used to look like as a one-off .card h3
   override — now every h3 gets it, since after the h2/h3 promotion below the
   only h3s left in the page are card titles. */
h3 {
  font-family: var(--font-base);
  font-size: 1.3rem;
  color: var(--sage-200);
  font-weight: 600;
  margin: 0 0 0.35rem;
}

h4 {
  font-size: 1.05rem;
}

.wrap {
  max-width: var(--container-w);
  margin: 0 auto;
  padding: 0 var(--space-lg);
}


/* ==========================================================================
   1. DESIGN TOKENS + REUSABLE COMPONENTS
   ========================================================================== */

/* ---------- Typography scale ---------- */
.type-display {
  font-family: var(--font-serif);
  color: var(--sage-150);
}

.type-h2 {
  font-family: var(--font-serif);
  color: var(--sage-150);
}

.type-body {
  font-family: var(--font-base);
  color: var(--sage-300);
}

.type-small {
  font-family: var(--font-base);
  color: var(--sage-300);
}

.type-tiny {
  font-family: var(--font-base);
  color: var(--sage-400);
}

.w400 {
  font-weight: 400;
}

.w500 {
  font-weight: 500;
}

.w600 {
  font-weight: 600;
}

/* Visually hidden but still readable by screen readers/AT — use whenever an
   icon alone carries meaning that sighted users get from context/layout. */
.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;
}

/* ---------- Buttons (+ layered-echo and stacked-layer modifiers) ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-base);
  font-weight: 500;
  padding: var(--space-sm) var(--space-lg);
  border-radius: var(--radius-m);
  text-decoration: none;
  cursor: pointer;
  border: none;
  transition: background-color 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}

.btn-primary {
  background: var(--sham-100);
  color: var(--sham-800);
}

.btn-primary:hover {
  background: var(--sham-050);
}

.btn-secondary {
  background: transparent;
  color: var(--sage-300);
  border: 1px solid var(--sage-400);
}

.btn-secondary:hover {
  color: var(--sage-200);
  border-color: var(--sage-300);
}

/* Same outlined/transparent structure as .btn-secondary, just green by
   default instead of on hover — used for the header's CTA, which needs to
   read as on-brand without the fully-filled weight of .btn-primary. */
.btn-secondary-green {
  color: var(--sham-050);
  border-color: var(--sham-200);
}

.btn-secondary-green:hover {
  color: var(--sham-025);
  border-color: var(--sham-100);
}

.btn-ghost {
  background: var(--sham-400);
  color: var(--sage-200);
}

.btn-ghost:hover {
  background: var(--sham-300);
}

.btn-icon {
  width: 16px;
  height: 16px;
  margin-right: var(--space-xs);
  flex-shrink: 0;
}

/* Trailing variant — icon after the label instead of before (Book-a-x CTAs).
   Nudges right on hover instead of scaling/bouncing, matching the rest of
   the system's fast, non-bouncy hover transitions. */
.btn-icon-trail {
  margin-right: 0;
  margin-left: var(--space-xs);
  transition: transform 0.15s ease-out;
}

.btn:hover .btn-icon-trail {
  transform: translateX(3px);
}

/* Fanned-outline technique shared with .framed below (declarations and the
   scroll-driven offset live there). Like .framed, this must be a bare wrapper
   around the real button rather than applied to the button itself: an
   element's own in-flow/flex content does not reliably paint above its own
   negative-z-index pseudo-elements (the same painting-order issue documented
   on .framed below), so the outline copies can end up rendering over the
   button's own label. Wrap it: <span class="btn-layered"><a class="btn ...">. */
.btn-layered {
  position: relative;
  z-index: 0;
  display: inline-flex;
}

/* Stacked-layer effect: a real top element (the button itself here; a plain
   labeled box in the standalone "Layered stack" motif below) sits solid above
   two receding, wider, fainter ::before/::after bars peeking out below it.
   Shared between .btn-stack and .stratum-wrap since the technique and
   geometry ratio are identical, only the real top element's size differs.
   Distance is scroll-driven the same way as .framed/.btn-layered below, via
   --scroll-t. */
.btn-stack,
.stratum-wrap {
  position: relative;
  z-index: 0;
  display: inline-flex;
  --scroll-t: 1;
}

.btn-stack {
  margin-bottom: 22px;
}

.btn-stack::before,
.btn-stack::after,
.stratum-wrap::before,
.stratum-wrap::after {
  content: "";
  position: absolute;
  z-index: -1;
  box-sizing: border-box;
  border-radius: var(--radius-m);
  pointer-events: none;
}

.btn-stack::before,
.stratum-wrap::before {
  opacity: 0.35;
  border: 2px solid var(--sage-700);
}

.btn-stack::after,
.stratum-wrap::after {
  opacity: 0.6;
  border: 2px solid var(--sage-600);
}

.btn-stack::before {
  height: 40px;
  left: calc(-16px * var(--scroll-t));
  right: calc(-16px * var(--scroll-t));
  bottom: calc(-22px * var(--scroll-t));
}

.btn-stack::after {
  height: 40px;
  left: calc(-8px * var(--scroll-t));
  right: calc(-8px * var(--scroll-t));
  bottom: calc(-11px * var(--scroll-t));
}

.stratum-wrap {
  margin: 0 auto;
}

.stratum-wrap::before {
  height: 34px;
  left: calc(-26px * var(--scroll-t));
  right: calc(-26px * var(--scroll-t));
  bottom: calc(-30px * var(--scroll-t));
}

.stratum-wrap::after {
  height: 34px;
  left: calc(-13px * var(--scroll-t));
  right: calc(-13px * var(--scroll-t));
  bottom: calc(-15px * var(--scroll-t));
}

.stratum-top {
  width: 114px;
  height: 34px;
  background: var(--sham-100);
  color: var(--sham-800);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  letter-spacing: 0.05em;
  border-radius: var(--radius-m);
}

/* ---------- Tags & pills ---------- */
.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-xs) var(--space-md);
  border-radius: var(--radius-pill);
  font-weight: 500;
  border: 1px solid var(--sage-600);
  color: var(--sage-200);
  background: transparent;
}

.pill-accent {
  border-color: var(--sham-100);
  color: var(--sham-050);
}

.pill .pill-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}

/* ---------- Cards ----------
   .card is the base — apply it wherever a bordered/filled content card is
   needed (see .value-item below for an example of combining it with a
   page-specific context class). Modifiers below (.card-horizontal,
   .card-accent, .card-outline) cover the variations shown in the Cards demo;
   add more modifiers here rather than hand-rolling a one-off card elsewhere. */
.card {
  background: var(--sham-400);
  /* No border at all — a visible line reads as a hard outline. Edge
     definition instead comes from a hairline INSET shadow, barely lighter
     than the card's own fill: it crisps the corner (no anti-aliased mush)
     without reading as an outline, and being inset (not offset/directional)
     it doesn't imply a light source or elevation the way a bevel would. The
     second, outer shadow layer is intentionally tiny/low-opacity — just
     enough to separate the card from the page at a subconscious level, not
     a visible drop shadow that would read as the card floating above it. */
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.06),
    0 1px 3px rgba(0, 0, 0, 0.12);
  border-radius: var(--radius-l);
  padding: var(--space-2xl);
  width: 220px;
}

/* Icons in cards sit raw on the card's own background — no badge box, border
   or fill behind them. Shared base, reused (with per-context size/margin) by
   .card, .value-item and .property-row. */
.card-icon {
  color: var(--sham-100);
  display: block;
  flex-shrink: 0;
}

.card .card-icon {
  width: 32px;
  height: 32px;
  margin-bottom: var(--space-md);
}

.card h4 {
  font-family: var(--font-serif);
  color: var(--sage-150);
  margin: 0 0 0.35rem;
}

.card p {
  color: var(--sage-400);
  margin: 0;
  line-height: 1.45;
}

.card .card-btn {
  margin-top: var(--space-md);
  padding: var(--space-xs) var(--space-md);
}

/* Modifier: icon and text laid out side by side instead of stacked. */
.card-horizontal {
  display: flex;
  align-items: flex-start;
  gap: var(--space-md);
}

.card-horizontal .card-icon {
  margin-bottom: 0;
}

/* Child pattern: a title + trailing badge/tag row, used in place of a bare h3/h4. */
.card .card-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-xs);
  margin-bottom: var(--space-xs);
}

.card .card-top h3,
.card .card-top h4 {
  margin: 0;
}

/* Layout wrapper for laying several cards out side by side — not a card itself. */
.card-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-lg);
}

/* Modifier: accent background. */
.card-accent {
  background: var(--sham-300);
  border-color: var(--sham-300);
}

.card-accent p {
  color: var(--sage-200);
}

/* Modifier: border-only, no fill. */
.card-outline {
  background: var(--sham-400);
  border: 2px solid var(--sham-100);
}

/* ---------- Scrolling logo marquee ---------- */
.marquee {
  overflow: hidden;
  width: 100%;
  -webkit-mask-image: linear-gradient(90deg, transparent, black 8%, black 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, black 8%, black 92%, transparent);
}

.marquee-track {
  display: flex;
  gap: var(--space-xl);
  width: max-content;
  animation: scroll-left 16s linear infinite;
}

.marquee-logo {
  width: 88px;
  height: 44px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--sage-600);
  border-radius: var(--radius-m);
  color: var(--sage-400);
  font-family: monospace;
  letter-spacing: 0.04em;
}

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

/* ---------- Image treatment & static backgrounds ----------
   Shared 220×140 placeholder-block sizing, reused by every static demo visual
   below (.img-block, .pattern-block, .crosshatch-block, .starfield-block,
   .contour-block, .ripple-block all use it identically) — and by a couple of
   index.html's pillar visuals, which override the size at their point of use. */
.img-block,
.pattern-block,
.crosshatch-block,
.starfield-block,
.contour-block,
.ripple-block {
  width: 220px;
  height: 140px;
  border-radius: var(--radius-m);
  border: 1px solid var(--sage-700);
}

.img-block {
  background: linear-gradient(135deg, var(--sham-300), var(--sham-400));
}

.pattern-dots {
  background-color: var(--sham-800);
  background-image: radial-gradient(var(--sage-600) 1.5px, transparent 1.5px);
  background-size: 16px 16px;
}

.crosshatch-block {
  background-color: var(--sham-800);
  background-image:
    radial-gradient(var(--sage-600) 1px, transparent 1px),
    radial-gradient(var(--sham-300) 1px, transparent 1px);
  background-size: 12px 12px, 18px 18px;
  background-position: 0 0, 6px 9px;
}

.starfield-block {
  background-color: var(--sham-800);
  background-image:
    radial-gradient(2px 2px at 20px 30px, var(--sage-300), transparent),
    radial-gradient(1.5px 1.5px at 60px 80px, var(--sham-050), transparent),
    radial-gradient(2px 2px at 100px 20px, var(--sage-400), transparent),
    radial-gradient(1px 1px at 140px 65px, var(--sage-300), transparent),
    radial-gradient(2px 2px at 185px 100px, var(--sham-025), transparent),
    radial-gradient(1.5px 1.5px at 40px 115px, var(--sage-400), transparent),
    radial-gradient(1px 1px at 165px 40px, var(--sage-300), transparent),
    radial-gradient(2px 2px at 205px 70px, var(--sham-050), transparent),
    radial-gradient(1px 1px at 90px 110px, var(--sage-400), transparent);
  animation: twinkle 3s ease-in-out infinite;
}

@keyframes twinkle {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.55;
  }
}

/* ---------- Starfield section background ----------
   Same dot-field idea as .starfield-block, scaled up to tile across a whole
   section instead of one small box. Two independently-tiled layers (different
   tile size, offset and animation timing each) so stars don't all fade in
   sync — only some dim/brighten at any given moment. */
.starfield-bg {
  position: relative;
  isolation: isolate;
}

.starfield-bg > * {
  position: relative;
  z-index: 1;
}

.starfield-bg::before,
.starfield-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

.starfield-bg::before {
  background-image:
    radial-gradient(1.5px 1.5px at 15px 25px, var(--sage-300), transparent),
    radial-gradient(1px 1px at 90px 60px, var(--sham-050), transparent),
    radial-gradient(1.5px 1.5px at 150px 15px, var(--sage-400), transparent),
    radial-gradient(1px 1px at 40px 100px, var(--sham-025), transparent),
    radial-gradient(1px 1px at 120px 115px, var(--sage-300), transparent);
  background-size: 180px 140px;
  animation: twinkle-a 4s ease-in-out infinite;
}

.starfield-bg::after {
  background-image:
    radial-gradient(1px 1px at 60px 20px, var(--sage-400), transparent),
    radial-gradient(1.5px 1.5px at 20px 80px, var(--sham-050), transparent),
    radial-gradient(1px 1px at 130px 70px, var(--sage-300), transparent),
    radial-gradient(1px 1px at 165px 125px, var(--sham-025), transparent),
    radial-gradient(1.5px 1.5px at 95px 45px, var(--sage-400), transparent);
  background-size: 210px 160px;
  background-position: 45px 35px;
  animation: twinkle-b 5.5s ease-in-out infinite;
  animation-delay: 1.4s;
}

@keyframes twinkle-a {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.3;
  }
}

@keyframes twinkle-b {
  0%,
  100% {
    opacity: 0.85;
  }
  40% {
    opacity: 0.2;
  }
  70% {
    opacity: 0.85;
  }
}

.contour-block {
  position: relative;
  overflow: hidden;
  background: var(--sham-800);
}

.contour-ring {
  position: absolute;
  left: 60%;
  top: 65%;
  transform: translate(-50%, -50%);
  border-radius: 3px;
}

.contour-ring.r1 {
  width: 36px;
  height: 22px;
  border: 2px solid var(--sham-100);
}

.contour-ring.r2 {
  width: 74px;
  height: 46px;
  border: 2px solid var(--sham-200);
}

.contour-ring.r3 {
  width: 116px;
  height: 74px;
  border: 2px solid var(--sage-600);
}

.contour-ring.r4 {
  width: 164px;
  height: 106px;
  border: 2px solid var(--sage-700);
}

.contour-ring.r5 {
  width: 210px;
  height: 140px;
  border: 2px solid var(--sage-700);
}

.ripple-block {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: var(--sham-800);
}

.ripple-core {
  width: 12px;
  height: 12px;
  background: var(--sham-100);
  z-index: 2;
}

.ripple-ring {
  position: absolute;
  border: 2px solid var(--sham-100);
  width: 12px;
  height: 12px;
  animation: ripple 2.4s ease-out infinite;
}

.ripple-ring.r2 {
  animation-delay: 0.8s;
}

.ripple-ring.r3 {
  animation-delay: 1.6s;
}

@keyframes ripple {
  0% {
    width: 12px;
    height: 12px;
    opacity: 0.9;
  }
  100% {
    width: 190px;
    height: 120px;
    opacity: 0;
  }
}

/* ---------- Framing: fanned double-outline behind any element ----------
   The outline layers are pure pseudo-elements (::before/::after), never
   separate layer divs. `.framed` itself must stay a bare wrapper with no
   background of its own — an element's own background always paints before
   its own negative-z-index pseudo-elements (CSS painting order), so if the
   card/image were `.framed` directly, the outlines would paint on top of its
   fill. Wrapping it one level up sidesteps that: the real card/image becomes
   a normal in-flow child, which paints after the wrapper's negative-z-index
   pseudo-elements — genuinely behind it. .btn-layered (above, in Buttons)
   reuses this exact same pseudo-element technique for the button family, so
   the declarations are shared here via one selector list rather than
   repeated for both classes. */
.framed {
  position: relative;
  z-index: 0;
  display: inline-block;
  border-radius: var(--radius-m);
}

.framed::before,
.framed::after,
.btn-layered::before,
.btn-layered::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--radius-m);
  border: 1.5px solid var(--sage-700);
  z-index: -1;
  pointer-events: none;
}

/* Both .framed and .btn-layered scale their offset by --scroll-t instead of using a
   fixed translate (see js/scroll-effects.js): --scroll-t is 0 while the element is
   just entering view at the bottom of the viewport (outlines sit flush behind it),
   reaches 1 — the original static 10px/20px offset — once the element is vertically
   centered in the viewport, and keeps growing past 1 as it continues scrolling on
   toward and past the top. The 1 fallback keeps this identical to a static rule if
   JS never runs. */
.framed,
.btn-layered {
  --scroll-t: 1;
}

.framed::before,
.btn-layered::before {
  transform: translate(calc(10px * var(--scroll-t)), calc(-10px * var(--scroll-t)));
}

.framed::after,
.btn-layered::after {
  transform: translate(calc(20px * var(--scroll-t)), calc(-20px * var(--scroll-t)));
  opacity: 0.6;
}

/* ---------- Divider ---------- */
.hairline {
  height: 1px;
  background: var(--sage-600);
  width: 100%;
}

/* ---------- Section header pattern (eyebrow + title + subtitle) ---------- */
.header-pattern .eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--sham-050);
  font-weight: 700;
  margin-bottom: var(--space-xs);
}

.header-pattern h3 {
  margin-bottom: 0.3rem;
}

.header-pattern p {
  color: var(--sage-400);
  margin: 0;
}

/* ---------- Animation style: data-constellation + organic-blob network ---------- */
.constellation-block {
  width: 240px;
  height: 160px;
  border-radius: var(--radius-m);
  border: 1px solid var(--sage-700);
  background: var(--sham-800);
}

.constellation-block .link {
  stroke: var(--sage-600);
  stroke-width: 1.5;
}

.constellation-block .pulse {
  stroke: var(--sham-100);
  stroke-width: 2;
  stroke-dasharray: 6 120;
  animation: pulse-travel 3s linear infinite;
}

.constellation-block .node {
  fill: var(--sham-100);
}

.constellation-block .node.dim {
  fill: var(--sage-600);
}

@keyframes pulse-travel {
  to {
    stroke-dashoffset: -252;
  }
}

.hero-demo {
  position: relative;
  width: 560px;
  max-width: 100%;
  height: 260px;
  background: var(--sham-800);
  border-radius: var(--radius-m);
  border: 1px solid var(--sage-700);
  overflow: hidden;
}

.hero-demo .headline {
  position: absolute;
  top: 85px;
  left: 0;
  width: 100%;
  text-align: center;
  font-family: var(--font-serif);
  font-weight: 700;
  color: var(--sage-700);
  z-index: 0;
  margin: 0;
  letter-spacing: 0.02em;
}

.hero-demo svg.network {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
}

.hero-demo .network .link {
  stroke: var(--sage-600);
  stroke-width: 1.5;
  opacity: 0.55;
}

/* Visual style only — src/js/blob-wander.js spawns these dynamically on any
   line and drives their x1/y1/x2/y2 itself each frame, so no animation is
   declared here. Stroke color comes from a per-pulse gradient set inline by
   the JS (fades along the pulse's own length, not a flat color — see
   createPulseUnit), which always wins over any stroke declared here, so
   none is set in this rule. Rounded caps turn the segment into a soft
   capsule instead of a hard-edged rectangle. Glow is two chained
   drop-shadows (a tight hot halo at the same bright core color, plus a
   wider softer one a step down the ramp) — layering blur radii like this
   reads as a real bloom rather than a flat blur. mix-blend-mode: screen
   makes overlapping pulses (or a pulse crossing a base line) add light
   instead of just alpha-blending, so crossings brighten like real light
   does. */
.hero-demo .network .pulse {
  stroke-linecap: round;
  stroke-width: 1.75;
  opacity: 0.95;
  mix-blend-mode: screen;
  filter: drop-shadow(0 0 2px var(--sham-025)) drop-shadow(0 0 6px var(--sham-050));
}

.hero-node {
  position: absolute;
  z-index: 2;
  will-change: transform;
}

.hero-demo.wide {
  width: 640px;
  height: 280px;
}

.hero-demo.wide .headline {
  top: 100px;
}

.hero-demo .d1 {
  top: 22px;
  left: 25px;
  width: 66px;
  height: 66px;
}

.hero-demo .d2 {
  top: 8px;
  left: 125px;
  width: 46px;
  height: 46px;
}

.hero-demo .d3 {
  top: 38px;
  left: 205px;
  width: 78px;
  height: 78px;
}

.hero-demo .d4 {
  top: 12px;
  left: 315px;
  width: 46px;
  height: 46px;
}

.hero-demo .d5 {
  top: 28px;
  left: 415px;
  width: 68px;
  height: 68px;
}

.hero-demo .d6 {
  top: 10px;
  left: 515px;
  width: 46px;
  height: 46px;
}

.hero-demo .d7 {
  top: 55px;
  left: 575px;
  width: 62px;
  height: 62px;
}

.hero-demo .d8 {
  top: 135px;
  left: 55px;
  width: 54px;
  height: 54px;
}

.hero-demo .d9 {
  top: 125px;
  left: 165px;
  width: 46px;
  height: 46px;
}

.hero-demo .d10 {
  top: 150px;
  left: 255px;
  width: 72px;
  height: 72px;
}

.hero-demo .d11 {
  top: 118px;
  left: 375px;
  width: 46px;
  height: 46px;
}

.hero-demo .d12 {
  top: 140px;
  left: 465px;
  width: 66px;
  height: 66px;
}

.hero-demo .d13 {
  top: 195px;
  left: 555px;
  width: 54px;
  height: 54px;
}

.hero-demo .d14 {
  top: 205px;
  left: 35px;
  width: 46px;
  height: 46px;
}

.tile {
  position: relative;
  width: 100%;
  height: 100%;
}

.thumb {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
}

/* Position/size intentionally left to the generic .thumb rule (cover, centered)
   — matching how the real hero's blob-node thumbnails are cropped, with no
   per-image custom framing. Appids pinned in tools/fetch-capsules.py's
   PINNED_APPIDS (so they survive that script's regenerate cycle even if
   they fall out of that day's top-sellers list) — swap the id here and add
   the matching PINNED_APPIDS entry together, never one without the other. */
.thumb-kaz {
  background-image: url('../img/capsules/730.jpg');
}

.thumb-aoe {
  background-image: url('../img/capsules/381210.jpg');
}

.thumb-peak {
  background-image: url('../img/capsules/3240220.jpg');
}

.thumb-raft {
  background-image: url('../img/capsules/359550.jpg');
}

.icon-glyph {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--sage-300);
}

.icon-glyph svg {
  width: 44%;
  height: 44%;
}

.tile-b {
  overflow: hidden;
  background: var(--sham-800);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}

.tile-b .icon-glyph {
  color: var(--sham-100);
}

/* Background color variants for icon tiles in the "Organic blobs" .hero-demo. */
.tile-icon-a {
  background: var(--sham-100);
}

.tile-icon-a .icon-glyph {
  color: var(--sham-800);
}

.tile-icon-b {
  background: var(--sham-050);
}

.tile-icon-b .icon-glyph {
  color: var(--sham-800);
}

.tile-icon-c {
  background: var(--sage-600);
}

.tile-icon-c .icon-glyph {
  color: var(--sage-100);
}

.sq-1 {
  border-radius: 42% 58% 53% 47% / 48% 52% 42% 58%;
}

.sq-2 {
  border-radius: 62% 38% 46% 54% / 55% 42% 58% 45%;
}

.sq-3 {
  border-radius: 50% 50% 66% 34% / 38% 62% 44% 56%;
}

.sq-4 {
  border-radius: 36% 64% 40% 60% / 60% 38% 62% 40%;
}

/* ---------- Chat style (sourced citation snippet) ----------
   Colors/radii on .stage-card/.chat-user/.chat-assistant/.cite-chip below are
   deliberately literal px values, not spacing-scale tokens: they're faithful
   reproductions of computed styles measured on the live app (app.hakuro.dev), so
   they should stay pinned to those exact real-world numbers rather than snap to
   this stylesheet's own scale. Font size is the one exception — it follows the
   sitewide uniform default like everything else non-heading. .chat-assistant is
   the one deliberate departure: it's set in the serif type, not Inter, to read
   as the "considered answer" against the sans-serif .chat-user question. */
.stage-card {
  width: 100%;
  max-width: 500px;
  max-height: 400px;
  overflow: hidden;
  background: var(--sham-400);
  border: 1px solid var(--sage-700);
  border-radius: var(--radius-m);
  padding: 1.1rem;
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.35);
  font-family: var(--font-base);
}

@keyframes blink {
  50% {
    opacity: 0;
  }
}

.chat-user {
  background: var(--sham-300);
  color: var(--sage-200);
  border-radius: var(--radius-m);
  padding: 14px;
  line-height: 1.4;
  max-width: 85%;
  margin-left: auto;
  margin-bottom: 0.9rem;
}

.chat-assistant {
  color: var(--sage-300);
  font-family: var(--font-serif);
  line-height: 21px;
}

.chat-assistant b {
  color: var(--sage-150);
  font-weight: 600;
}

.cite-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--sage-150);
  font-weight: 350;
  text-decoration: none;
}

.cite-chip img {
  width: 36px;
  height: 17px;
  object-fit: cover;
  flex-shrink: 0;
}

.cite-chip svg {
  width: 10px;
  height: 10px;
  opacity: 0.7;
}

/* ---------- Chat to-do list (assistant recommendations, in their own labelled box) ----------
   Sits inside .chat-assistant like the rest of the answer, but the to-do
   panel drops back to the sans-serif base type: it's UI chrome (a literal
   checklist), not the model's own "considered answer" prose. Animation for
   the typing/reveal/check-off sequence lives further down, grouped with the
   other animated-chat keyframes. */
.stage-label {
  font-family: var(--font-base);
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--sage-500);
  margin: 0 0 0.4rem;
}

.stage-block + .stage-block {
  margin-top: 0.75rem;
}

.todo-box {
  font-family: var(--font-base);
  border: 1px solid var(--sage-700);
  border-radius: var(--radius-m);
  padding: 0.75rem 0.9rem;
}

.todo-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.todo-item {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
}

.todo-toggle {
  position: relative;
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  margin-top: 0.15rem;
  border-radius: 50%;
  border: 1.5px solid var(--sham-100);
}

.todo-toggle .todo-icon-add,
.todo-toggle .todo-icon-done {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 11px;
  height: 11px;
  transform: translate(-50%, -50%);
}

.todo-toggle .todo-icon-add {
  color: var(--sham-100);
}

.todo-toggle .todo-icon-done {
  color: var(--sham-800);
  opacity: 0;
}

.todo-title {
  color: var(--sage-200);
  font-weight: 600;
  line-height: 1.35;
}

/* ---------- Animated chat: typed question, then answer revealed piece by piece ----------
   One shared 9s cycle, looping forever. The user line types out first (0–20% of the
   cycle); the assistant's reveal-seg pieces then fade in one at a time via staggered
   animation-delay (same keyframe, same 9s duration — only the delay differs per piece,
   the same pattern used elsewhere in this system, e.g. the tally-chase accent). */
.hero-chat-user-text {
  display: inline-block;
  overflow: hidden;
  white-space: nowrap;
  vertical-align: bottom;
  width: 0;
  max-width: 100%;
  animation: hero-type 9s infinite;
}

@keyframes hero-type {
  0% {
    width: 0;
    animation-timing-function: steps(39, end);
  }
  20% {
    width: 44ch; /* the line is 39 characters; 44ch leaves safe buffer so `overflow:hidden` never clips a glyph */
  }
  97% {
    width: 44ch;
  }
  100% {
    width: 0;
  }
}

.hero-chat-cursor {
  display: inline-block;
  width: 8px;
  height: 1em;
  background: var(--sham-100);
  margin-left: 2px;
  vertical-align: text-bottom;
  animation: blink 0.9s steps(1) infinite, hero-cursor-window 9s infinite;
}

@keyframes hero-cursor-window {
  0% {
    visibility: visible;
  }
  19% {
    visibility: visible;
    animation-timing-function: steps(1, end);
  }
  21% {
    visibility: hidden;
  }
  100% {
    visibility: hidden;
  }
}

.reveal-seg {
  opacity: 0;
  animation: hero-reveal 9s ease-out infinite;
}

span.reveal-seg {
  display: inline-block;
}

@keyframes hero-reveal {
  0% {
    opacity: 0;
    transform: translateY(4px);
  }
  4% {
    opacity: 1;
    transform: translateY(0);
  }
  97% {
    opacity: 1;
    transform: translateY(0);
  }
  100% {
    opacity: 0;
    transform: translateY(4px);
  }
}

.chat-assistant .reveal-seg:nth-child(1) {
  animation-delay: 1.8s;
}

.chat-assistant .reveal-seg:nth-child(2) {
  animation-delay: 2.2s;
}

.chat-assistant .reveal-seg:nth-child(3) {
  animation-delay: 2.6s;
}

.chat-assistant .reveal-seg:nth-child(4) {
  animation-delay: 3.0s;
}

.chat-assistant .reveal-seg:nth-child(5) {
  animation-delay: 3.4s;
}

/* ---------- Animated to-do demo: typed question, staggered insight/to-do reveal, then checking each item off ----------
   Same technique as the hero-chat cards above, just a longer 13s cycle to
   leave room for more content — hero-type/hero-reveal/hero-cursor-window are
   pure percentage keyframes (no absolute time baked in) so they're reused
   here unchanged rather than duplicated. .todo-demo-question/-cursor restate
   the .hero-chat-user-text/.hero-chat-cursor rules at the new duration
   instead of overriding them in place, so this card can't drift the timing
   of the unrelated cards that still use the 9s original.
   The to-do check-off is new: the toggle circle and its two icons each get
   the same keyframe shape — unchecked for the first half of their own cycle,
   checked for the second half — and .todo-list .todo-item:nth-child(n)
   below shifts *when* that halfway point falls in real time via
   animation-delay (negative delays included, to pull the switch earlier
   than the keyframe's own midpoint). */
.todo-demo-question {
  display: inline-block;
  overflow: hidden;
  white-space: nowrap;
  vertical-align: bottom;
  width: 0;
  max-width: 100%;
  animation: hero-type 13s infinite;
}

.todo-demo-cursor {
  display: inline-block;
  width: 8px;
  height: 1em;
  background: var(--sham-100);
  margin-left: 2px;
  vertical-align: text-bottom;
  animation: blink 0.9s steps(1) infinite, hero-cursor-window 13s infinite;
}

.todo-demo-reveal {
  opacity: 0;
  animation: hero-reveal 13s ease-out infinite;
}

.todo-demo-insights > *:nth-child(1),
.todo-demo-insights > *:nth-child(2) {
  animation-delay: 2.6s;
}

.todo-demo-insights > *:nth-child(3) {
  animation-delay: 3.6s;
}

.todo-box {
  animation-delay: 4.6s;
}

.todo-list .todo-item:nth-child(1) {
  animation-delay: 4.6s;
}

.todo-list .todo-item:nth-child(2) {
  animation-delay: 6.4s;
}

.todo-list .todo-item:nth-child(3) {
  animation-delay: 8.2s;
}

.todo-demo .todo-toggle {
  animation: todo-demo-check-fill 13s linear infinite;
}

.todo-demo .todo-icon-add {
  animation: todo-demo-check-fade-out 13s linear infinite;
}

.todo-demo .todo-icon-done {
  animation: todo-demo-check-fade-in 13s linear infinite;
}

@keyframes todo-demo-check-fill {
  0%, 49.9% {
    background: transparent;
  }
  50%, 100% {
    background: var(--sham-100);
  }
}

@keyframes todo-demo-check-fade-out {
  0%, 49.9% {
    opacity: 1;
  }
  50%, 100% {
    opacity: 0;
  }
}

@keyframes todo-demo-check-fade-in {
  0%, 49.9% {
    opacity: 0;
  }
  50%, 100% {
    opacity: 1;
  }
}

.todo-list .todo-item:nth-child(1) .todo-toggle,
.todo-list .todo-item:nth-child(1) .todo-icon-add,
.todo-list .todo-item:nth-child(1) .todo-icon-done {
  animation-delay: -0.9s; /* 13s*50% baseline (6.5s) shifted to check at 5.6s, just after the row itself reveals at 4.6s */
}

.todo-list .todo-item:nth-child(2) .todo-toggle,
.todo-list .todo-item:nth-child(2) .todo-icon-add,
.todo-list .todo-item:nth-child(2) .todo-icon-done {
  animation-delay: 0.9s; /* checks at 7.4s, after the row reveals at 6.4s */
}

.todo-list .todo-item:nth-child(3) .todo-toggle,
.todo-list .todo-item:nth-child(3) .todo-icon-add,
.todo-list .todo-item:nth-child(3) .todo-icon-done {
  animation-delay: 2.7s; /* checks at 9.2s, after the row reveals at 8.2s */
}


/* ==========================================================================
   2. SITE LAYOUT
   Header/footer chrome shared by every page via _layouts/default.html, the
   one-pager's one-off index.html section layout, and other page-specific
   layouts (e.g. .legal). All built entirely on the tokens and reusable
   components in part 1 above.
   ========================================================================== */

/* ---------- Header ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 30;
  background: var(--sham-800);
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-sm) 0; /* horizontal gutter — .site-header itself has none */
  max-width: var(--container-w);
  margin: 0 auto;
}

.logo {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  font-family: var(--font-serif);
  font-weight: 600;
}

.logo .mark {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  color: var(--sage-300);
}

.logo-text {
  font-size: 22px;
  font-family: var(--font-serif);
  color: var(--sage-300);
  font-weight: 600;
}

nav.main-nav ul {
  list-style: none;
  display: flex;
  gap: var(--space-lg);
  margin: 0;
  padding: 0;
}

nav.main-nav a {
  text-decoration: none;
  color: var(--sage-200);
  transition: color 0.12s ease;
}

nav.main-nav a:hover {
  color: var(--sham-050);
}

.header-right {
  display: flex;
  align-items: center;
  gap: var(--space-lg);
}

.login-link {
  text-decoration: none;
  color: var(--sage-200);
  transition: color 0.12s ease;
}

.login-link:hover {
  color: var(--sham-050);
}

/* ---------- Shared section heading ---------- */
.heading {
  text-align: center;
  max-width: var(--container-w-narrow);
  margin: 0 auto var(--space-4xl);
}

.heading h1 {
  margin-bottom: var(--space-xs);
}

.heading p {
  color: var(--sage-400);
  margin-top: var(--space-lg)
}

/* Shared section padding rhythm — every full-width content section below (pillars included) uses this. */
.hero,
.pillars,
.value-add,
.use-cases,
.properties,
.cta-band,
.faq {
  padding: var(--space-8xl) var(--space-lg);
}

/* Shared CTA button row — identical in both .hero and .cta-band, so defined once. */
.cta-row {
  display: flex;
  gap: var(--space-md);
  justify-content: center;
}

/* ---------- Hero: organic node-graph cluster surrounding centered copy ----------
   teamworkgraph.com-style: nodes are placed by real randomized sampling (fixed
   seed, so it's reproducible) within an organic, irregularly-lobed annular
   region — not a grid, and not filling the full rectangle — leaving a clear,
   irregularly-shaped gap in the middle for the headline. Every node connects
   to its 4-5 nearest neighbors (a real k-nearest-neighbor graph, topped up so
   no node ends up under 4), so both placement and connections follow the same
   organic randomness rather than a fixed frame/grid pattern. */
.hero {
  position: relative;
  overflow: hidden;
  min-height: 85vh;
  background: var(--sham-600);
  text-align: center;
  display: flex;
  align-items: center;
  justify-content: center;
}

.hero-blobs {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transform-origin: 50% 50%;
  will-change: transform, filter;
  z-index: 0;
  pointer-events: none;
}

/* width/height:100% is required in addition to inset:0 here: .hero-lines is an
   <svg> (a replaced element with a 1:1 intrinsic aspect ratio from its square
   viewBox), and inset:0 alone does not override that intrinsic ratio — without
   an explicit size the browser rendered it as a perfect square instead of
   stretching to .hero-blobs's actual (wide, non-square) box, which silently
   threw off every line coordinate relative to the node divs. */
.hero-lines {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transform-origin: 50% 50%;
  will-change: transform, filter;
}

.hero-copy {
  position: relative;
  z-index: 2;
  max-width: var(--container-w-narrow);
  margin: 0 auto;
}

.hero .eyebrow {
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sham-050);
  font-weight: 700;
  margin-bottom: var(--space-sm);
}

.hero h1 {
  margin: 0 0 var(--space-lg);
}

.hero .sub {
  color: var(--sage-300);
  margin: 0 auto var(--space-lg);
}

/* Connecting lines: the real KNN-graph edges (~130 of them, ~4-5 per node),
   drawn as percentage-coordinate SVG (viewBox 0 0 100 100, preserveAspectRatio
   none) so it tracks the node divs' own top/left % positioning exactly.
   non-scaling-stroke keeps line thickness constant despite the distorted
   (non-square) coordinate system. About a quarter of edges get the traveling
   "pulse" treatment — a bright dash animating along the line via
   stroke-dashoffset — reusing the same technique as the data-constellation
   mechanic in the branding catalog. */
.hero-lines {
  z-index: 0;
}

.hero-lines line {
  stroke: var(--sage-600);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
  opacity: 0.55;
}

/* Visual style only — src/js/blob-wander.js spawns these dynamically on any
   line (about 5/sec) and drives their x1/y1/x2/y2 itself each frame, so no
   animation is declared here. Stroke color comes from a per-pulse gradient
   set inline by the JS (fades along the pulse's own length, not a flat
   color — see createPulseUnit), which always wins over any stroke declared
   here, so none is set in this rule. Rounded caps turn the segment into a
   soft capsule instead of a hard-edged rectangle. Glow is two chained
   drop-shadows (a tight hot halo at the same bright core color, plus a
   wider softer one a step down the ramp) — layering blur radii like this
   reads as a real bloom rather than a flat blur. mix-blend-mode: screen
   makes overlapping pulses (or a pulse crossing a base line) add light
   instead of just alpha-blending, so crossings brighten like real light
   does. */
.hero-lines line.pulse {
  stroke-linecap: round;
  stroke-width: 1.75;
  opacity: 0.95;
  mix-blend-mode: screen;
  filter: drop-shadow(0 0 2px var(--sham-025)) drop-shadow(0 0 6px var(--sham-050));
}

/* Blob field: ~58 nodes, each a squircle-clipped thumbnail or icon tile, drawn
   above the lines. Position/size/animation-delay are set per node via inline
   style (generated); only the reusable per-variant rules live here. */
/* translate(-50%,-50%) centers the node exactly on its own top/left point
   (the browser computes the offset from the node's own actual rendered size,
   no assumed-viewport-size approximation needed) — top/left is set to the
   SAME percentage the matching SVG line endpoint uses, so the two always
   meet exactly regardless of viewport width. */
.blob-node {
  position: absolute;
  z-index: 1;
  overflow: hidden;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
  transform: translate(-50%, -50%);
}

.bg-1 {
  background: var(--sage-600);
}

.bg-2 {
  background: var(--sage-500);
}

.bg-3 {
  background: var(--sage-700);
}
.bg-4 {
  background: var(--sham-300);
}
.bg-5 {
  background: var(--amber-400);
}
.bg-6 {
  background: var(--terra-400);
}

/* Use cases value-prop switcher demo panel reuses the same .stage-card chat
   component as the Pillars interface pillar — but unlike there, it sits
   directly on the switcher's own card background rather than being framed
   as its own separate card, so it reads as part of the switcher rather than
   a nested demo box. */
.switcher-stage .stage-card {
  background: none;
  border: none;
  box-shadow: none;
  padding: 0;
}

.switcher-stage .chat-user {
  width: 100%;
  max-width: 100%;
}

/* ---------- Pillars (data ecosystem / industry expertise / model / platform) ----------
   Four alternating copy+visual rows, each making one differentiator concrete.
   Visuals reuse existing design-system placeholder blocks (starfield, contour,
   constellation) plus the real .stage-card chat mockup for the interface
   pillar, each wrapped in .framed for the same fanned-outline treatment used
   elsewhere on the page. */
.pillars {
  background: var(--sham-600); /* matches .hero so bottom-row blob nodes never sit on a color seam */
  padding-top: var(--space-xl);
}

.pillar-list {
  max-width: var(--container-w);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: calc(var(--space-2xl) * 2.25);
}

.pillar-row {
  display: flex;
  align-items: center;
  gap: var(--space-2xl);
}

.pillar-row.reverse {
  flex-direction: row-reverse;
}

.pillar-copy {
  flex: 1 1 50%;
}

.pillar-visual {
  flex: 1 1 50%;
  display: flex;
  justify-content: center;
}

.pillar-copy h2 {
  margin-bottom: var(--space-xs);
}

.pillar-subtitle {
  color: var(--sham-100);
  font-weight: 600;
  margin: 0 0 var(--space-sm);
}

.pillar-copy > p:last-child {
  color: var(--sage-400);
  margin: 0;
}

/* Placeholder visuals sized up 50% (from the shared design-system defaults) for more presence in this section */
.pillar-visual .starfield-block,
.pillar-visual .contour-block {
  width: 330px;
  height: 210px;
}

.pillar-visual .constellation-block {
  width: 360px;
  height: 240px;
}

.pillar-visual .contour-ring.r1 {
  width: 54px;
  height: 33px;
}

.pillar-visual .contour-ring.r2 {
  width: 111px;
  height: 69px;
}

.pillar-visual .contour-ring.r3 {
  width: 174px;
  height: 111px;
}

.pillar-visual .contour-ring.r4 {
  width: 246px;
  height: 159px;
}

.pillar-visual .contour-ring.r5 {
  width: 315px;
  height: 210px;
}

/* ---------- Value add ---------- */
/* .value-add and .use-cases share this same plain background color, so the
   seam between them stays invisible. */
.value-add,
.use-cases {
  background-color: var(--sham-800);
}

.value-add {
  /* darker plane, differentiated from .pillars above it */
  /* .use-cases right below shares this same background — tighten the shared
     seam so the two don't read as one oversized gap of empty color. */
  padding-bottom: var(--space-xl);
}

.value-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-xl);
  max-width: var(--container-w);
  margin: 0 auto;
}

/* Combines with the base .card (see Cards, above) — this only adds the
   deltas specific to sitting in the Value add grid: fills the grid cell
   instead of the card default's fixed width, a larger icon, transparent
   fill with a real hairline border instead of the base card's inset-shadow
   trick (redundant once there's an actual border), and extra breathing
   room between the title and body copy. */
.value-item {
  width: auto;
  background: transparent;
  border: 1px solid var(--sage-700);
  box-shadow: none;
}

.value-item .card-icon {
  width: 40px;
  height: 40px;
  color: var(--sage-500);
}

.value-item h3 {
  margin-bottom: var(--space-md);
}

/* ---------- Use cases: value-prop switcher (immutable.com-style) ----------
   A horizontal bar of selectable pills sits above a 1/3 (sales copy) + 2/3
   (chat demo) content area; picking a pill updates both sides together.
   CSS-only, same philosophy as the FAQ accordion: real <input type="radio">
   elements (one shared `name`) drive which panels show, via the general
   sibling combinator. Visually hidden but still focusable/keyboard-operable —
   arrow keys move between radios natively (real radio-group behavior), and
   clicking any pill label checks its input. Because panels are toggled with
   display:none/block (not opacity/visibility), the demo's typing/reveal
   animation genuinely restarts every time you switch to it. */
.use-cases {
  /* Mirrors .value-add's padding-bottom trim above — same shared background,
     so the seam between the two should feel like one section, not a gap. */
  padding-top: var(--space-4xl);
}

/* The switcher (tab bar + copy/stage content) sits inside one card spanning
   the full content width, instead of floating directly on the section
   background. Combines with the base .card (see Cards, above). */
.use-cases-card {
  width: 100%;
  max-width: var(--container-w);
  margin: 0 auto;
  padding-bottom: var(--space-3xl);
}

.switcher-radio {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.switcher-tabbar {
  position: relative; /* anchors .switcher-progress */
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-xl);
  margin-bottom: var(--space-xl);
  border-bottom: 1px solid var(--sage-600);
}

/* Auto-advance progress fill: js/app.js positions/sizes this to match the
   active tab's label and animates its scaleX from 0 to 1 over the 5s dwell
   time, restarting on every tab change (auto-advance or manual click) —
   the "border bottom filling from empty to full" indicator. Replaces a
   static full-color active-tab border, since the growing fill itself is
   now what shows which tab is active. */
.switcher-progress {
  position: absolute;
  bottom: -1px;
  left: 0;
  height: 2px;
  width: 0;
  background: var(--sham-100);
  transform-origin: left center;
  transform: scaleX(0);
  pointer-events: none;
}

.switcher-tabbtn {
  display: inline-block;
  cursor: pointer;
  white-space: nowrap;
  padding: var(--space-sm) 0;
  border-bottom: 1px solid transparent;
  color: var(--sage-300);
  font-weight: 500;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.switcher-tabbtn:hover {
  color: var(--sham-050);
}

.switcher-content {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2xl);
}

.switcher-copy {
  flex: 1 1 50%;
}

.switcher-stage {
  flex: 1 1 50%;
  display: flex;
  justify-content: center;
}

.switcher-panel {
  display: none; /* both copy and stage panels share this class; shown per data-panel below */
}

.switcher-copy h2 {
  margin-bottom: var(--space-sm);
}

.switcher-copy p {
  color: var(--sage-300);
  margin: 0 0 var(--space-md);
}

.switcher-copy ul {
  margin: 0;
  padding-left: 1.1em;
  color: var(--sage-400);
}

.switcher-copy li {
  margin-bottom: var(--space-xs);
}

#uc-1:checked ~ .switcher-content .switcher-panel[data-panel="1"],
#uc-2:checked ~ .switcher-content .switcher-panel[data-panel="2"],
#uc-3:checked ~ .switcher-content .switcher-panel[data-panel="3"] {
  display: block;
}

#uc-1:checked ~ .switcher-tabbar label[for="uc-1"],
#uc-2:checked ~ .switcher-tabbar label[for="uc-2"],
#uc-3:checked ~ .switcher-tabbar label[for="uc-3"] {
  color: var(--sage-150); /* persistent active indicator; .switcher-progress shows the countdown */
}

#uc-1:focus-visible ~ .switcher-tabbar label[for="uc-1"],
#uc-2:focus-visible ~ .switcher-tabbar label[for="uc-2"],
#uc-3:focus-visible ~ .switcher-tabbar label[for="uc-3"] {
  outline: 2px solid var(--sham-050);
  outline-offset: 4px;
}

/* ---------- Why Hakuro / properties ---------- */
.properties {
  background: var(--sham-600);
}

.property-list {
  max-width: var(--container-w-narrow);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
}

.property-row {
  display: flex;
  gap: var(--space-2xl);
  align-items: center;
  padding: var(--space-xl) 0;
  border-bottom: 1px solid var(--sage-800);
}

.property-row:first-child {
  padding-top: 0;
}

.property-row:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.property-row .card-icon {
  width: 28px;
  height: 28px;
}

.property-row h2 {
  margin-bottom: var(--space-xs);
}

.property-row p {
  color: var(--sage-500);
  margin: 0;
}

/* Generic-AI-vs-Hakuro comparison table: content sourced from the deck's own
   "core value" slide. Row labels are icon-only (title lives outside the
   card); each cell leads with a cross (generic AI) or check (Hakuro) instead
   of a column divider, so the Hakuro column reads as the clear win at a
   glance without needing a vertical rule to separate the two. */

.comparison-card {
  width: 100%;
  max-width: var(--container-w);
  margin: 0 auto;
  margin-top: var(--space-5xl);
}

.comparison-scroll {
  overflow-x: auto;
}

.comparison-table {
  width: 100%;
  min-width: 560px;
  border-collapse: collapse;
}

.comparison-table th,
.comparison-table td {
  text-align: left;
  vertical-align: top;
  padding: var(--space-lg) var(--space-md);
  border-bottom: 1px solid var(--sage-600);
}

.comparison-table thead th {
  font-family: var(--font-base);
  color: var(--sage-300);
  font-weight: 500;
  padding-top: 0;
  padding-bottom: var(--space-sm);
  border-bottom: 1px solid var(--sage-600);
}

.comparison-table thead th:last-child {
  color: var(--sham-050);
  font-weight: 600;
}

.comparison-table thead th:first-child,
.comparison-table tbody th {
  width: 56px;
  text-align: center;
}

.comparison-table tbody th {
  vertical-align: middle;
}

.comparison-table tbody th .card-icon {
  width: 20px;
  height: 20px;
  margin: 0 auto;
  color: var(--sage-500);
}

.comparison-table tbody td {
  color: var(--sage-300);
}

.compare-cell {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.comparison-table tr:last-child th,
.comparison-table tr:last-child td {
  border-bottom: none;
}

.compare-mark {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

.compare-cross {
  color: var(--terra-100);
}

.compare-check {
  color: var(--sham-100);
}

/* ---------- CTA band ---------- */
.cta-band {
  text-align: center;
  background: var(--sham-300);
  color: var(--sham-600);
}

.cta-mark {
  display: block;
  width: 48px;
  height: 48px;
  margin: 0 auto var(--space-md);
}

.cta-band h1{
  color: var(--sham-600);
}
.cta-band p {
  margin: 0 0 var(--space-lg);
}

/* ---------- FAQ ---------- */
.faq {
  background: var(--sham-600);
}

.faq-list {
  max-width: var(--container-w-narrow);
  margin: 0 auto;
}

.faq-list details {
  border-bottom: 1px solid var(--sage-800);
}

.faq-list details[open] {
  padding-bottom: var(--space-lg); /* gap between the answer and the divider below, while open */
}

/* Padding lives on the summary itself (not on .faq-list details) so the
   clickable row includes the space above/below the question text, not just
   the text's own baseline — clicking that padding still lands inside
   <summary>, which is what actually toggles the disclosure. The answer
   below has its own separate padding, so clicking it never toggles. */
.faq-list summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-lg) 0;
}

.faq-list summary::-webkit-details-marker {
  display: none;
}

.faq-icon {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  color: var(--sage-400);
  margin-left: var(--space-md);
}

.faq-icon-up {
  display: none;
}

.faq-list details[open] .faq-icon-down {
  display: none;
}

.faq-list details[open] .faq-icon-up {
  display: block;
}

/* overflow:hidden + no padding/margin of its own so js/app.js can animate
   height cleanly from 0 to its natural content height (the "fitting"
   open/close animation) — with box-sizing:border-box, any padding here
   would stop height:0 from actually reaching 0. The gap below the answer
   (before the divider) lives on details[open] above instead. */
.faq-list .answer {
  overflow: hidden;
  color: var(--sage-400);
  margin: 0;
}

/* ---------- Footer ---------- */
.site-footer {
  padding: var(--space-xl) var(--space-lg);
  background: var(--sham-800);
}

.footer-inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  max-width: var(--container-w);
  margin: 0 auto;
}

.footer-inner .logo {
  color: var(--sage-400);
  gap: 5px; /* header logo's gap:icon-size ratio (8px : 22px) scaled to the footer's 14px icon */
}

.footer-inner .logo .mark {
  width: 14px;
  height: 14px; /* icon:text 1:1 ratio from the header logo, scaled to the footer's 14px text */
}

.footer-inner .logo-text {
  font-size: 14px;
}

.footer-links {
  display: flex;
  gap: var(--space-lg);
}

.footer-links a {
  color: var(--sage-400);
  text-decoration: none;
}

.footer-links a:hover {
  color: var(--sage-200);
}

@media (max-width: 900px) {
  .blob-node:nth-child(4n) {
    display: none; /* thin out the field on narrow screens */
  }
  .switcher-content {
    flex-direction: column;
  }
}

@media (max-width: 800px) {
  .pillar-row,
  .pillar-row.reverse {
    flex-direction: column;
  }
  nav.main-nav {
    display: none;
  }
  .value-grid {
    grid-template-columns: 1fr;
  }
}

/* ---------- Legal pages (privacy-policy.html, and any future terms page) ---------- */
.legal {
  padding: var(--space-5xl) var(--space-lg);
}

.legal-content {
  max-width: var(--container-w-narrow);
}

.legal-content h1 {
  margin-bottom: var(--space-xs);
}

.legal-updated {
  color: var(--sage-500);
  margin-bottom: var(--space-2xl);
}

.legal-content h2 {
  margin-top: var(--space-2xl);
}

.legal-content ul {
  padding-left: 1.2em;
}

.legal-content li {
  margin-bottom: var(--space-xs);
}

.legal-content a {
  color: var(--sham-050);
}


/* ==========================================================================
   3. STYLE-GUIDE-ONLY SCAFFOLDING
   Documentation chrome from the branding.html catalog page itself —
   swatches, demo frames, captions, subsection labels. Not needed on index.html
   unless you're building another reference/catalog page.
   ========================================================================== */

.intro {
  padding: var(--space-2xl) var(--space-lg) var(--space-xl);
  border-bottom: 1px solid var(--sage-600);
}

.intro p {
  max-width: var(--container-w-narrow);
  color: var(--sage-400);
}

.intro code {
  background: var(--sham-400);
  padding: 0.1em 0.4em;
  border-radius: var(--radius-m);
  color: var(--sham-025);
}

.demo-section {
  padding: var(--space-2xl) var(--space-lg);
  border-bottom: 1px solid var(--sage-600);
}

.demo-section > .wrap > h2 {
  display: flex;
  align-items: baseline;
  gap: var(--space-xs);
}

.demo-section .tag {
  font-family: var(--font-base);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--sham-050);
}

.demo-section > .wrap > .desc {
  color: var(--sage-400);
  max-width: var(--container-w-narrow);
  margin-bottom: var(--space-lg);
}

.demo-canvas {
  background: var(--sham-800);
  border: 1px solid var(--sage-700);
  border-radius: var(--radius-m);
  padding: var(--space-xl);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xl);
}

.caption {
  margin-top: var(--space-md);
  color: var(--sham-050);
}

.caption b {
  color: var(--sage-200);
}

.subsection {
  margin-top: var(--space-xl);
}

.subsection:first-of-type {
  margin-top: 0;
}

.subsection .sub-label {
  font-family: var(--font-base);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--sage-400);
  margin: 0 0 var(--space-xs);
}

.subsection .desc {
  color: var(--sage-400);
  max-width: var(--container-w-narrow);
  margin: 0 0 var(--space-md);
}

.swatch-group {
  margin-bottom: var(--space-lg);
}

.swatch-group h4 {
  font-family: var(--font-base);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--sage-400);
  margin: 0 0 var(--space-xs);
}

.swatch-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
}

.swatch {
  width: 96px;
}

.swatch .chip {
  height: 56px;
  border-radius: var(--radius-m);
  border: 1px solid rgba(255, 255, 255, 0.08);
}

.swatch .label {
  color: var(--sage-400);
  margin-top: var(--space-xs);
}

.swatch .hex {
  color: var(--sage-200);
  font-family: monospace;
}

.type-row {
  margin-bottom: var(--space-lg);
}

.type-row .meta {
  color: var(--sage-400);
  font-family: monospace;
  margin-bottom: var(--space-2xs);
}

@media (max-width: 700px) {
  .demo-canvas {
    flex-direction: column;
    align-items: flex-start;
  }
}
