/* Font-family CSS variables — mirrors the values Next/font injected via
   hashed module classes in the original build. site.css already contains
   the matching @font-face rules (including metric-matched "Fallback"
   faces), this file just makes the variables available globally instead
   of scoped to a per-request class name. */
:root {
  --font-archivo: "Archivo", "Archivo Fallback";
  --font-inter-tight: "Inter Tight", "Inter Tight Fallback";
  --font-jetbrains-mono: "JetBrains Mono", "JetBrains Mono Fallback";
  --font-fraunces: "Fraunces", "Fraunces Fallback";
}

html.h-full,
body.min-h-full {
  height: 100%;
}
body.min-h-full {
  display: flex;
  flex-direction: column;
}
main {
  flex: 1 0 auto;
  padding-top: 65px; /* offset for the fixed header (data-site-header), matches its rendered height */
}
body.min-h-full > header,
body.min-h-full > footer {
  flex-shrink: 0;
}

/* ---------- Active nav item (current page), set by main.js initActiveNav ---------- */
header nav a[aria-current="page"],
#mobile-menu nav a[aria-current="page"],
.persona-menu-item[aria-current="page"] {
  color: var(--color-orange) !important;
}

/* ---------- Scroll-reveal (replaces Framer Motion mount/whileInView fades) ---------- */
[data-reveal] {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.6s cubic-bezier(0.4, 0, 0.2, 1), transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}
[data-reveal].is-visible {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ---------- Rotating phrase cross-fade (hero accent) ---------- */
.rotating-phrase {
  display: block;
  position: relative;
}
.rotating-phrase .phrase {
  position: absolute;
  left: 0;
  top: 0;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.5s cubic-bezier(0.4, 0, 0.2, 1), transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
  white-space: nowrap;
}
.rotating-phrase .phrase.is-active {
  opacity: 1;
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  .rotating-phrase .phrase {
    transition: none;
  }
}

/* ---------- Row rotator (SignalCard / NetworkPulse live rows) ----------
 * A class (not inline style.display) so JS never has to touch/clobber a
 * row's own display value (some rows are display:grid, others plain
 * block) — !important on the class wins over the row's own inline
 * display without needing to know or preserve what it was. */
.is-rotator-hidden {
  display: none !important;
}
@keyframes rotator-fade {
  from { opacity: 0; transform: translateY(-3px); }
  to { opacity: 1; transform: translateY(0); }
}
[data-rotator-item].is-fading-in {
  animation: rotator-fade 320ms ease-out;
}
@media (prefers-reduced-motion: reduce) {
  [data-rotator-item].is-fading-in { animation: none; }
}

/* ---------- Scrollytelling (HowSocxoWorks-style) ---------- */
[data-step] [data-step-num] { color: color-mix(in oklab, var(--color-navy) 18%, transparent); transition: color 320ms cubic-bezier(0.4, 0, 0.2, 1); }
[data-step] [data-step-title] { color: color-mix(in oklab, var(--color-navy) 38%, transparent); transition: color 320ms cubic-bezier(0.4, 0, 0.2, 1); }
[data-step] [data-step-title] [data-step-italic] { color: inherit; transition: color 320ms cubic-bezier(0.4, 0, 0.2, 1); }
[data-step] [data-step-body] { color: color-mix(in oklab, var(--color-navy) 30%, transparent); transition: color 320ms cubic-bezier(0.4, 0, 0.2, 1); }
[data-step].is-active [data-step-num] { color: var(--color-orange); }
[data-step].is-active [data-step-title] { color: var(--color-navy); }
[data-step].is-active [data-step-title] [data-step-italic] { color: var(--color-orange); }
[data-step].is-active [data-step-body] { color: var(--color-mute); }

[data-artifact] { opacity: 0; pointer-events: none; transition: opacity 420ms cubic-bezier(0.4, 0, 0.2, 1); }
[data-artifact].is-active { opacity: 1; pointer-events: auto; }

/* ---------- Terminal auto-scrolling feed ---------- */
@keyframes terminal-scroll {
  from { transform: translateY(0); }
  to { transform: translateY(-384px); }
}
[data-terminal-track] {
  animation: terminal-scroll 21.333s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  [data-terminal-track] { animation: none; }
}

/* ---------- Contact form success card ---------- */
[data-contact-success] {
  flex-direction: column;
}

/* ---------- Mobile nav open state ---------- */
body.menu-open {
  overflow: hidden;
}
#mobile-menu {
  display: none;
}
#mobile-menu.is-open {
  display: flex;
  animation: menu-fade 160ms ease-out;
}
@keyframes menu-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  #mobile-menu.is-open { animation: none; }
}

/* ---------- Spine markers: hide the decorative ::before/::after (label + tick line) ---------- */
.spine[data-spine]:before,
.spine[data-spine]:after {
  content: none !important;
}
.spine[data-spine] {
  padding-left: 0 !important;
}

/* ---------- Cookie consent banner (injected by main.js initCookieBanner) ---------- */
.cookie-banner {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  background: var(--color-navy);
  color: var(--color-paper);
  padding: 18px clamp(20px, 4vw, 40px);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(16px, 3vw, 32px);
  flex-wrap: wrap;
  box-shadow: 0 -8px 30px -10px rgba(0, 0, 0, 0.35);
  transform: translateY(0);
  transition: transform 250ms cubic-bezier(0.4, 0, 0.2, 1), opacity 250ms cubic-bezier(0.4, 0, 0.2, 1);
}
.cookie-banner.is-hidden {
  transform: translateY(100%);
  opacity: 0;
  pointer-events: none;
}
.cookie-banner p {
  font-size: 13.5px;
  line-height: 1.5;
  color: color-mix(in oklab, white 88%, transparent);
  max-width: 60ch;
  margin: 0;
}
.cookie-banner a {
  color: var(--color-paper);
  text-decoration: underline;
  text-decoration-color: color-mix(in oklab, white 40%, transparent);
}
.cookie-banner a:hover {
  text-decoration-color: var(--color-paper);
}
.cookie-banner .cookie-banner-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}
.cookie-banner button {
  font-size: 13.5px;
  font-weight: 600;
  padding: 9px 18px;
  border-radius: 6px;
  cursor: pointer;
  white-space: nowrap;
  transition: all 160ms cubic-bezier(0.4, 0, 0.2, 1);
}
.cookie-banner [data-cookie-accept] {
  background: var(--color-orange);
  color: var(--color-paper);
  border: 1px solid transparent;
}
.cookie-banner [data-cookie-accept]:hover {
  background: var(--color-orange-deep);
}
.cookie-banner [data-cookie-decline] {
  background: transparent;
  color: var(--color-paper);
  border: 1px solid color-mix(in oklab, white 28%, transparent);
}
.cookie-banner [data-cookie-decline]:hover {
  border-color: color-mix(in oklab, white 50%, transparent);
}
@media (prefers-reduced-motion: reduce) {
  .cookie-banner { transition: none; }
}

/* ---------- Generic <dialog> modals: lock body scroll while one is open,
 * so the page's own scrollbar doesn't run alongside the dialog's internal
 * one (main.js toggles this class in initDialogs). ---------- */
body.dialog-open {
  overflow: hidden;
}

/* ---------- Generic <dialog> modals (data-dialog / data-dialog-open / data-dialog-close) ----------
 * The site's global reset (`* { margin: 0 }`) kills the browser's default
 * dialog-centering trick (inset:0 + margin:auto), which pins dialog[open]
 * to the top-left instead of the middle of the viewport. Center it
 * explicitly via fixed positioning + transform instead of relying on margin. */
dialog[data-dialog] {
  position: fixed;
  top: 50%;
  left: 50%;
  margin: 0;
  transform: translate(-50%, -50%);
  animation: dialog-in 180ms cubic-bezier(0.4, 0, 0.2, 1);
}
dialog[data-dialog]::backdrop {
  background: color-mix(in oklab, var(--color-navy) 55%, transparent);
  animation: dialog-backdrop-in 180ms cubic-bezier(0.4, 0, 0.2, 1);
}
@keyframes dialog-in {
  from { opacity: 0; transform: translate(-50%, -50%) translateY(10px) scale(0.98); }
  to { opacity: 1; transform: translate(-50%, -50%); }
}
@keyframes dialog-backdrop-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
[data-dialog-open]:hover {
  color: var(--color-orange-deep) !important;
}
[data-dialog-close]:hover {
  color: var(--color-navy) !important;
}
@media (prefers-reduced-motion: reduce) {
  dialog[data-dialog],
  dialog[data-dialog]::backdrop {
    animation: none;
  }
}
