/* SPDX-License-Identifier: Apache-2.0 */
/*
 * software/constitution™ — motion.css
 *
 * Scroll-reveal + micro-interaction stylesheet for the OSS-track
 * landing pages. Self-contained: no imports, no external fonts, no
 * @media print rules required. The CSS lives in OSS-track because the
 * pages it dresses are themselves OSS-track (Apache 2.0).
 *
 * Pairs with assets/motion.js (IntersectionObserver bootstrap).
 *
 * Constraints (per §0.4):
 *   - every transition ≤ 300ms
 *   - no parallax
 *   - prefers-reduced-motion is honoured (instant final state)
 */

/* --- reveal-on-scroll primitives ------------------------------------ */
[data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity 280ms cubic-bezier(0.2, 0.7, 0.2, 1),
    transform 280ms cubic-bezier(0.2, 0.7, 0.2, 1);
  will-change: opacity, transform;
}
[data-reveal="in"] {
  opacity: 1;
  transform: translateY(0);
}
/* Staggered children: each child reveals 80ms after the prior. The
   data-reveal-stagger attribute on a container marks its direct
   children for staggered reveal. */
[data-reveal-stagger] > * {
  opacity: 0;
  transform: translateY(10px);
  transition:
    opacity 240ms cubic-bezier(0.2, 0.7, 0.2, 1),
    transform 240ms cubic-bezier(0.2, 0.7, 0.2, 1);
}
[data-reveal-stagger="in"] > * {
  opacity: 1;
  transform: translateY(0);
}
[data-reveal-stagger="in"] > *:nth-child(1)  { transition-delay:   0ms; }
[data-reveal-stagger="in"] > *:nth-child(2)  { transition-delay:  80ms; }
[data-reveal-stagger="in"] > *:nth-child(3)  { transition-delay: 160ms; }
[data-reveal-stagger="in"] > *:nth-child(4)  { transition-delay: 240ms; }
[data-reveal-stagger="in"] > *:nth-child(5)  { transition-delay: 280ms; }
[data-reveal-stagger="in"] > *:nth-child(6)  { transition-delay: 280ms; }
[data-reveal-stagger="in"] > *:nth-child(n+7){ transition-delay: 280ms; }

/* --- button hover lift ---------------------------------------------- */
.btn,
.nav-cta {
  transition:
    opacity 150ms ease,
    transform 180ms cubic-bezier(0.2, 0.7, 0.2, 1),
    box-shadow 180ms cubic-bezier(0.2, 0.7, 0.2, 1);
}
.btn:hover,
.nav-cta:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 18px -8px rgba(230, 57, 53, 0.45);
}
.btn:active,
.nav-cta:active {
  transform: translateY(0);
  transition-duration: 80ms;
}

/* --- card hover glow ------------------------------------------------ */
.card,
.level,
.redline,
.block-card,
.step {
  transition:
    border-color 200ms ease,
    box-shadow 220ms ease,
    transform 220ms cubic-bezier(0.2, 0.7, 0.2, 1);
}
.card:hover,
.level:hover,
.block-card:hover,
.step:hover {
  border-color: rgba(230, 57, 53, 0.45);
  box-shadow: 0 8px 28px -16px rgba(230, 57, 53, 0.35);
  transform: translateY(-2px);
}
.redline:hover {
  border-color: rgba(230, 57, 53, 0.45);
  box-shadow: 0 4px 18px -10px rgba(230, 57, 53, 0.25);
}

/* --- code-block pulse on viewport entry ----------------------------- */
@keyframes sc-code-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(230, 57, 53, 0.00); }
  35%  { box-shadow: 0 0 0 3px rgba(230, 57, 53, 0.18); }
  100% { box-shadow: 0 0 0 0 rgba(230, 57, 53, 0.00); }
}
pre.code[data-reveal="in"] {
  animation: sc-code-pulse 900ms ease-out 200ms 1;
}

/* --- hero pill subtle breath ---------------------------------------- */
@keyframes sc-pill-breath {
  0%, 100% { box-shadow: 0 0 0 0 rgba(230, 57, 53, 0.00); }
  50%      { box-shadow: 0 0 0 4px rgba(230, 57, 53, 0.10); }
}
.hero-pill {
  animation: sc-pill-breath 3400ms ease-in-out infinite;
}

/* --- stats row ------------------------------------------------------ */
.sc-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 28px;
  margin-top: 26px;
  padding: 14px 18px;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.015);
  font-size: 13px;
  color: var(--text-muted);
  align-items: baseline;
}
.sc-stats .sc-stat {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
}
.sc-stats .sc-stat .n {
  font-family: 'JetBrains Mono', SFMono-Regular, Menlo, Consolas, monospace;
  color: var(--text);
  font-weight: 700;
  font-size: 16px;
  letter-spacing: -0.2px;
}
.sc-stats .sc-stat .l {
  color: var(--text-muted);
  text-transform: lowercase;
  letter-spacing: 0.2px;
}
.sc-stats .sc-stat .v {
  color: var(--red);
  font-family: 'JetBrains Mono', SFMono-Regular, Menlo, Consolas, monospace;
  font-weight: 700;
  font-size: 13px;
}
.sc-stats .sep {
  width: 1px; height: 14px;
  background: var(--line);
  align-self: center;
}

/* --- pipeline diagram (index.html) ---------------------------------- */
.sc-diagram-wrap {
  margin-top: 30px;
  border-radius: 14px;
  border: 1px solid var(--line);
  background:
    radial-gradient(900px 240px at 50% 0%, rgba(230, 57, 53, 0.06), transparent 70%),
    var(--bg-2);
  padding: 22px 18px 6px;
}
.sc-diagram-wrap .sc-diagram-caption {
  margin: 0 0 8px;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--text-muted);
}
.sc-diagram-wrap svg { width: 100%; height: auto; display: block; }

.sc-node { fill: var(--paper); stroke: var(--line); stroke-width: 1; }
.sc-node-label {
  fill: var(--text);
  font-family: 'JetBrains Mono', SFMono-Regular, Menlo, Consolas, monospace;
  font-weight: 700;
  font-size: 12px;
}
.sc-node-sub {
  fill: var(--text-muted);
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 10px;
}
.sc-edge { stroke: var(--line); stroke-width: 1.5; fill: none; }
.sc-edge-arrow { fill: var(--line); }

/* Animated scene primitives — driven by data-scene on the SVG root. */
@keyframes sc-pulse-red {
  0%, 100% { stroke: var(--line);  stroke-width: 1.5; }
  40%, 60% { stroke: var(--red);   stroke-width: 2.5; }
}
@keyframes sc-flash-fill {
  0%, 100% { fill: var(--paper);    stroke: var(--line); }
  40%, 60% { fill: rgba(230, 57, 53, 0.18); stroke: var(--red); }
}
@keyframes sc-flash-green {
  0%, 100% { fill: var(--paper);    stroke: var(--line); }
  40%, 60% { fill: rgba(34, 197, 94, 0.18); stroke: #22c55e; }
}
@keyframes sc-dash-flow {
  to { stroke-dashoffset: -40; }
}

/* Scene 1 — declare (constitution node lights). */
[data-scene="1"] [data-anim="node-constitution"] { animation: sc-flash-fill 1400ms ease-in-out 1; }

/* Scene 2 — gate flags violation (gate node lights red + edge dashes). */
[data-scene="2"] [data-anim="node-gate"]       { animation: sc-flash-fill 1400ms ease-in-out 1; }
[data-scene="2"] [data-anim="edge-c-to-g"]     { stroke-dasharray: 6 4; animation: sc-dash-flow 900ms linear 1; }

/* Scene 3 — fix loop (loop edge pulses red). */
[data-scene="3"] [data-anim="edge-loop"]       { animation: sc-pulse-red 1400ms ease-in-out 1; }

/* Scene 4 — green merge (merge node lights green). */
[data-scene="4"] [data-anim="node-merge"]      { animation: sc-flash-green 1600ms ease-in-out 1; }
[data-scene="4"] [data-anim="edge-g-to-m"]     { stroke-dasharray: 6 4; animation: sc-dash-flow 1000ms linear 1; }

/* --- prefers-reduced-motion override -------------------------------- */
@media (prefers-reduced-motion: reduce) {
  [data-reveal],
  [data-reveal-stagger] > * {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .hero-pill,
  pre.code[data-reveal="in"],
  .sc-diagram-wrap svg * {
    animation: none !important;
  }
  .btn:hover,
  .nav-cta:hover,
  .card:hover,
  .level:hover,
  .block-card:hover,
  .step:hover,
  .redline:hover {
    transform: none !important;
    box-shadow: none !important;
  }
}

/* === 2026-05-28 visual uplift ============================================
   CEO feedback: "too much colour uneasy on the eyes" + "tiring soulless
   dead dull". Treatment:
     • soften every link from raw --red to --text with low-opacity hover
       underline, reserving red exclusively for the wordmark slash + a
       small set of intentional accent moments
     • add a sophisticated radial gradient mesh on hero + alt sections
     • lift cards on hover with restrained shadow + accent border
     • text-wrap: balance + tighter letter-spacing on h1
     • subtle glow under the wordmark slash
   Restraint discipline: no parallax, no particles, no chroma fireworks.
   ======================================================================== */

/* link discipline — ink-tone by default, accent on hover only */
.uplift a:not(.btn):not(.brand):not(.nav-cta) {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid rgba(230, 57, 53, 0.20);
  transition: border-bottom-color .18s ease, color .18s ease;
}
.uplift a:not(.btn):not(.brand):not(.nav-cta):hover {
  color: var(--red);
  border-bottom-color: var(--red);
}

/* hero gradient mesh — subtle radial in two corners, single source */
.uplift section.hero {
  position: relative;
  background:
    radial-gradient(ellipse 60% 50% at 8% 8%, rgba(230, 57, 53, 0.06), transparent 60%),
    radial-gradient(ellipse 70% 60% at 90% 100%, rgba(99, 102, 241, 0.04), transparent 65%),
    var(--bg);
  isolation: isolate;
}
.uplift section.block.alt {
  position: relative;
  background:
    radial-gradient(ellipse 80% 40% at 50% 0%, rgba(230, 57, 53, 0.025), transparent 55%),
    var(--bg-2);
}

/* hero h1 — tighter tracking + balanced wrap + subtle text rendering */
.uplift section.hero h1 {
  letter-spacing: -0.024em;
  text-wrap: balance;
  font-weight: 700;
}
.uplift section.hero h1 .slash {
  display: inline-block;
  color: var(--red);
  text-shadow: 0 0 24px rgba(230, 57, 53, 0.35);
  transform: translateY(-0.02em);
}

/* wordmark slash glow in chrome */
.uplift .brand .slash,
.uplift .brand span > span[style*="color:var(--red)"] {
  text-shadow: 0 0 12px rgba(230, 57, 53, 0.30);
}

/* card hover — restrained lift, no chroma flash */
.uplift .card,
.uplift .level {
  transition: transform .22s ease, box-shadow .22s ease, border-color .22s ease, background .22s ease;
  will-change: transform;
}
.uplift .card:hover,
.uplift .level:hover {
  transform: translateY(-3px);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.04) inset,
    0 12px 28px -10px rgba(0, 0, 0, 0.55),
    0 0 0 1px rgba(230, 57, 53, 0.12);
  border-color: rgba(230, 57, 53, 0.20);
}

/* eyebrow letter — small caps treatment */
.uplift .eyebrow {
  letter-spacing: 0.18em;
  font-size: 11px;
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 600;
}

/* h2 — tighter, balanced */
.uplift section.block h2 {
  letter-spacing: -0.018em;
  text-wrap: balance;
}

/* code block — subtle glow on viewport entry (uses existing reveal flow) */
.uplift pre.code {
  position: relative;
  background:
    linear-gradient(180deg, rgba(230, 57, 53, 0.02), transparent 30%),
    var(--paper);
  border: 1px solid var(--line);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.02) inset;
}

/* pill — subtle pulse on the dot only */
.uplift .hero-pill {
  background: rgba(230, 57, 53, 0.06);
  border: 1px solid rgba(230, 57, 53, 0.16);
  color: var(--text-muted);
}
.uplift .hero-pill > span[aria-hidden] {
  color: var(--red);
  animation: scupl-pulse 2.4s ease-in-out infinite;
}
@keyframes scupl-pulse {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: 0.6; transform: scale(0.9); }
}

/* btn-primary — softer red, lift on hover */
.uplift .btn-primary {
  background: var(--red);
  border-color: var(--red);
  box-shadow: 0 0 0 1px rgba(230, 57, 53, 0.20), 0 8px 22px -10px rgba(230, 57, 53, 0.50);
  transition: transform .18s ease, box-shadow .18s ease;
}
.uplift .btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 0 0 1px rgba(230, 57, 53, 0.30), 0 14px 28px -10px rgba(230, 57, 53, 0.60);
}

@media (prefers-reduced-motion: reduce) {
  .uplift .card:hover,
  .uplift .level:hover,
  .uplift .btn-primary:hover {
    transform: none !important;
    box-shadow: none !important;
  }
  .uplift .hero-pill > span[aria-hidden] {
    animation: none !important;
  }
}

/* === Canonical wordmark — `<software/constitution™>` =====================
   Single source of truth for the OSS brand mark across index / principles /
   adoption. Per §0 the markup pattern is identical on every page (header +
   footer); per the 2026-05-28 CEO note "logo not fixed" this restores the
   bracketed identity the wordmark always wanted. Brackets in restrained
   red, slash in red, ™ subtle. No glow on the brackets — the "fewer harsh
   colours" feedback rules out chroma fireworks on the chrome.
   ======================================================================== */
.brand-mark            { font-family: inherit; letter-spacing: -0.005em; }
.brand-mark .bracket   { color: var(--red); font-weight: 700; padding: 0 1px; }
.brand-mark .slash     { color: var(--red); font-weight: 700; }
.brand-mark .tm        { font-size: 0.55em; opacity: 0.7; vertical-align: super; margin-left: 1px; font-weight: 400; }
/* Wordmark i-tittles: the dot on every "i" in <software/constitution(tm)> is red.
   Technique (font-agnostic): the stem is a dotless-i (U+0131 'ı'); the tittle is a
   red ::before dot positioned over it. JetBrains Mono monospace → the stem is
   centred in the glyph box, so left:50% aligns the dot. (< / > are already red via
   .bracket/.slash.) */
.brand-mark .dot-i, .foot-mark .dot-i, .family-mark .dot-i { position: relative; }
.brand-mark .dot-i::before, .foot-mark .dot-i::before, .family-mark .dot-i::before {
  content: "";
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: 0.62em;
  width: 0.14em;
  height: 0.14em;
  border-radius: 50%;
  background: var(--red);
}
/* Subtle glow under brackets only inside the .uplift body class. */
.uplift .brand-mark .bracket { text-shadow: 0 0 8px rgba(230, 57, 53, 0.25); }
.uplift .brand-mark .slash   { text-shadow: 0 0 8px rgba(230, 57, 53, 0.20); }
