/* haart.ai token + component overrides. Loads after haart.webflow.css. */

:root {
  /* ---- style-lab tokens. js/haart-lab.js rewrites these at runtime; the
     defaults are the Porcelain & Crimson scheme with Marcellus display over
     Lato body (Miriam's pick, locked in 2026-08-07). To lock a different lab
     choice in as the site default, copy its values here (in build_haart.py)
     and keep the DEF_THEME/DEF_FONT ids in HAART_LAB_JS in sync. ---- */
  --haart-bg: #faf7f2;
  --haart-bg2: #f1ece4;
  --haart-ink: #1d1717;
  --haart-accent: #b02434;
  --haart-accent-strong: #c94b59;
  --haart-accent-dim: #831a26;
  --haart-on-accent: #ffffff;
  --haart-hi: #1d1717; /* highlight text; the ink on light schemes, white on dark */
  --haart-font-display: 'Marcellus', Georgia, serif;
  --haart-font-body: 'Lato', Helvetica, Arial, sans-serif;
  --haart-display-weight: 400;
  --haart-logo-weight: 460;

  /* derived shades */
  --haart-ink2: color-mix(in srgb, var(--haart-ink) 86%, var(--haart-bg));
  --haart-muted: color-mix(in srgb, var(--haart-ink) 68%, var(--haart-bg));
  --haart-muted2: color-mix(in srgb, var(--haart-ink) 52%, var(--haart-bg));
  --haart-surface: color-mix(in srgb, var(--haart-accent) 10%, var(--haart-bg2));
  --haart-edge: color-mix(in srgb, var(--haart-accent) 22%, var(--haart-bg2));
  --haart-edge-run: color-mix(in srgb, var(--haart-ink) 62%, var(--haart-bg));
  --haart-border: color-mix(in srgb, var(--haart-ink) 12%, transparent);
  --haart-border-soft: color-mix(in srgb, var(--haart-ink) 8%, transparent);
  /* headings: deeper than body ink, with a whisper of the accent in it.
     haart-lab.js swaps this per scheme (dark schemes use the plain ink). */
  --haart-heading: color-mix(in srgb, var(--haart-accent) 9%, #131011);
  /* shadow base: warm near-black carrying the accent, never flat black */
  --haart-shadow: color-mix(in srgb, var(--haart-accent) 30%, #150a0c);
  /* glow color (Miriam trying white, 2026-07-30). Alternatives if it does not
     land: var(--haart-accent-strong) for a blush halo, or transparent for none */
  --haart-glow: #ffffff;

  /* map the webflow primitives onto the style-lab tokens */
  --_primitives---colors--neutral-darkest: var(--haart-bg);
  --_primitives---colors--neutral-darker: var(--haart-bg2);
  --_primitives---colors--neutral-lightest: var(--haart-ink);
  --_primitives---colors--neutral-lighter: var(--haart-ink2);
  --_primitives---colors--neutral-light: var(--haart-muted);
  --_primitives---colors--neutral: var(--haart-muted2);
  --_primitives---colors--white: var(--haart-hi);
  --_primitives---colors--royal-blue-lightest: color-mix(in srgb, var(--haart-accent) 18%, var(--haart-ink));
  --_primitives---colors--royal-blue-lighter: color-mix(in srgb, var(--haart-accent) 45%, var(--haart-ink));
  --_primitives---colors--royal-blue-light: var(--haart-accent-strong);
  --_primitives---colors--royal-blue: var(--haart-accent);
  --_primitives---colors--royal-blue-dark: var(--haart-accent-dim);
  --_primitives---colors--royal-blue-darker: color-mix(in srgb, var(--haart-accent) 45%, var(--haart-bg));
  --_primitives---colors--royal-blue-darkest: color-mix(in srgb, var(--haart-accent) 16%, var(--haart-bg));
  --_primitives---colors--dolly: var(--haart-accent);
  --_primitives---colors--dolly-dark: var(--haart-accent-dim);
  --color-scheme-2--accent: var(--_primitives---colors--royal-blue);

  /* inverse panel (footer) and gray ramps follow the scheme */
  --_primitives---colors--cod-gray-lightest: color-mix(in srgb, var(--haart-ink) 94%, var(--haart-bg));
  --_primitives---colors--cod-gray-lighter: color-mix(in srgb, var(--haart-ink) 84%, var(--haart-bg));
  --_primitives---colors--cod-gray: color-mix(in srgb, var(--haart-ink) 10%, var(--haart-bg));
  --_primitives---colors--cod-gray-darkest: color-mix(in srgb, var(--haart-ink) 4%, var(--haart-bg));
  --_primitives---colors--conch-lightest: color-mix(in srgb, var(--haart-ink) 97%, var(--haart-bg));
  --_primitives---colors--conch-lighter: color-mix(in srgb, var(--haart-ink) 93%, var(--haart-bg));

  /* translucency ramps keyed to the scheme so borders survive light schemes */
  --_primitives---opacity--white-5: color-mix(in srgb, var(--haart-hi) 5%, transparent);
  --_primitives---opacity--white-10: color-mix(in srgb, var(--haart-hi) 10%, transparent);
  --_primitives---opacity--white-15: color-mix(in srgb, var(--haart-hi) 15%, transparent);
  --_primitives---opacity--white-20: color-mix(in srgb, var(--haart-hi) 20%, transparent);
  --_primitives---opacity--white-30: color-mix(in srgb, var(--haart-hi) 30%, transparent);
  --_primitives---opacity--white-40: color-mix(in srgb, var(--haart-hi) 40%, transparent);
  --_primitives---opacity--white-50: color-mix(in srgb, var(--haart-hi) 50%, transparent);
  --_primitives---opacity--white-60: color-mix(in srgb, var(--haart-hi) 60%, transparent);
  --_primitives---opacity--neutral-darkest-5: color-mix(in srgb, var(--haart-bg) 5%, transparent);
  --_primitives---opacity--neutral-darkest-10: color-mix(in srgb, var(--haart-bg) 10%, transparent);
  --_primitives---opacity--neutral-darkest-15: color-mix(in srgb, var(--haart-bg) 15%, transparent);
  --_primitives---opacity--neutral-darkest-20: color-mix(in srgb, var(--haart-bg) 20%, transparent);
  --_primitives---opacity--neutral-darkest-30: color-mix(in srgb, var(--haart-bg) 30%, transparent);
  --_primitives---opacity--neutral-darkest-40: color-mix(in srgb, var(--haart-bg) 40%, transparent);
  --_primitives---opacity--neutral-darkest-60: color-mix(in srgb, var(--haart-bg) 60%, transparent);

  /* typography */
  --_typography---font-styles--fono: var(--haart-font-display);
  --_typography---font-styles--pro: var(--haart-font-body);
  --_typography---font-styles--mono: var(--haart-font-display);
}

h1, h2, h3, h4, h5, h6,
.heading-style-h1, .heading-style-h2, .heading-style-h3, .heading-style-h4,
.heading-style-h5, .heading-style-h6, .tagline, .logo-text {
  font-family: var(--haart-font-display);
  font-weight: var(--haart-display-weight);
  letter-spacing: -0.01em;
}

body { font-family: var(--haart-font-body); }

h1, h2, h3, h4, h5, h6,
.heading-style-h1, .heading-style-h2, .heading-style-h3, .heading-style-h4,
.heading-style-h5, .heading-style-h6 {
  color: var(--haart-heading);
}

.logo-text { font-weight: var(--haart-logo-weight); letter-spacing: 0.01em; }

/* primary button */
.button { background-color: var(--haart-accent); color: var(--haart-on-accent); }
.button:hover { background-color: var(--haart-accent-strong); border-color: var(--haart-accent-dim); }

/* accent spans: warm glow instead of blue */
.blue-span {
  text-shadow: 0 1px 4px color-mix(in srgb, var(--haart-shadow) 20%, transparent), 0 0 10px color-mix(in srgb, var(--haart-glow) 50%, transparent);
  -webkit-text-stroke-color: color-mix(in srgb, var(--haart-accent) 20%, transparent);
}
.hero-accent { color: var(--haart-accent-strong); }

/* shadows keyed to the scheme (the export used flat black + old navy/blue) */
.heading-style-h1.hero, .heading-style-h1.replaced-text {
  text-shadow: 0 1px 4px color-mix(in srgb, var(--haart-shadow) 30%, transparent);
}
.cta25_component { text-shadow: 0 0 6px color-mix(in srgb, var(--haart-glow) 20%, transparent); }

/* The navbar self-inverts against whatever is behind it (mix-blend-mode:
   difference, from the export). That trick needs white-anchored colors: white
   inverts to near-black over light schemes and stays white over dark ones.
   Scheme-ink colors here double-invert into washed-out gray, so the navbar is
   pinned to white and the blend does the theming. */
.navbar10_component .navbar10_link,
.navbar10_component .logo-text,
.navbar10_component .button.is-secondary { color: #fff; }
.navbar10_component .navbar10_link:hover { color: #fff; opacity: 1; }
.navbar10_component .button.is-secondary {
  background-color: #ffffff1f;
  border-color: #ffffff40;
}
.navbar10_component .menu-icon1_line-top,
.navbar10_component .menu-icon1_line-middle,
.navbar10_component .menu-icon1_line-middle-inner,
.navbar10_component .menu-icon1_line-bottom { background-color: #fff; }

/* footer wordmark: the white token washes out on light schemes; use ink */
.footer15_component .logo-text { color: var(--haart-ink); }

/* smart nav, take two: visible at the top, hides only while scrolling down,
   returns on scroll up (js/haart-rise.js toggles the class). Replaces the
   export's IX2 events, which also hid the nav on mouse-out with no scroll. */
.navbar10_component { transition: transform 0.35s ease, opacity 0.35s ease; }
html.haart-nav-hidden .navbar10_component { transform: translateY(-110%); opacity: 0; }
/* under difference-blending, black is a no-op; the old backdrop gradient
   would itself invert into a visible band, so it goes */
.navbar10_component.gradient { background-image: none; }

/* the two navbar layers overlap; the links layer sits on top and was
   swallowing clicks meant for the sticky layer's wordmark link underneath.
   Let clicks fall through its empty areas, but keep its own links live. */
.navbar10_component.links { pointer-events: none; }
.navbar10_component.links a,
.navbar10_component.links .w-nav-button { pointer-events: auto; }

/* closing CTA: flat porcelain panel with a dial echo rising from the bottom
   edge, in place of the template's gradient fade-out */
.section_cta25.color-scheme-1 {
  background-image: none;
  background-color: color-mix(in srgb, var(--haart-accent) 6%, var(--haart-bg));
  border-top: 1px solid var(--haart-border-soft);
  position: relative;
  overflow: hidden;
}
.section_cta25.color-scheme-1::before,
.section_cta25.color-scheme-1::after {
  content: "";
  position: absolute;
  left: 50%;
  border-radius: 50%;
  border: 1px solid var(--haart-edge);
  pointer-events: none;
}
.section_cta25.color-scheme-1::before { width: 900px; height: 900px; bottom: -640px; margin-left: -450px; }
.section_cta25.color-scheme-1::after { width: 1300px; height: 1300px; bottom: -980px; margin-left: -650px; }
.section_cta25 .cta25_component { position: relative; z-index: 1; }
.heading-style-h3.cta25 { color: var(--haart-muted); }

/* hero precision dial: ONE hand-authored SVG holds every circle (rings, bezel
   ticks, sweeps, station track), so the whole system is concentric by
   construction and scales together. Outer rings fade by stroke opacity. */
@keyframes haart-dial-turn { to { transform: rotate(360deg); } }
.haart-orbit_ring { fill: none; stroke: var(--haart-edge); stroke-width: 1px; vector-effect: non-scaling-stroke; }
.haart-orbit_ring.is-r3 { stroke-opacity: .55; }
.haart-orbit_ring.is-r4 { stroke-opacity: .32; }
.haart-orbit_ticks {
  fill: none;
  stroke: color-mix(in srgb, var(--haart-accent) 30%, var(--haart-bg2));
  stroke-width: 12px;
  vector-effect: non-scaling-stroke;
  stroke-dasharray: .6 12.56;
}
/* arcs travel their track by animating dash offset, so they follow the
   ellipse exactly (a rotated ellipse arc would drift off its own track) */
@keyframes haart-flow { to { stroke-dashoffset: var(--haart-flow-end); } }
.haart-orbit_arc {
  fill: none;
  stroke: var(--haart-accent);
  stroke-opacity: .45;
  stroke-width: 1.5px;
  vector-effect: non-scaling-stroke;
  stroke-linecap: round;
  stroke-dasharray: 120 722.8;
  --haart-flow-end: -842.8px;
  animation: haart-flow 48s linear infinite;
}
.haart-orbit_arc.is-faint {
  stroke: var(--haart-accent-strong);
  stroke-opacity: .3;
  stroke-dasharray: 146 825.9;
  --haart-flow-end: -971.9px;
  animation-duration: 76s;
  animation-direction: reverse;
}
@media (prefers-reduced-motion: reduce) { .haart-orbit_arc, .haart-orbit_pulse_arc { animation: none; } }

/* orbit stations: an HTML ring larger than the headline, five dots riding it,
   each with a square-cornered tag that pops on phrase change. Positioning uses
   the CSS `translate` longhand so GSAP owns `transform` for the pop. */
.haart-orbit {
  position: absolute;
  left: 50%;
  top: 47%;
  width: min(124vh, 82vw, 1500px);
  aspect-ratio: 7 / 5;
  translate: -50% -50%;
  z-index: 1;
  pointer-events: none;
}
.haart-orbit_svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.haart-orbit_track {
  fill: none;
  stroke: color-mix(in srgb, var(--haart-accent) 30%, var(--haart-bg2));
  stroke-width: 1px;
  vector-effect: non-scaling-stroke;
}
/* the connector pulse: a thicker crimson segment, one station-gap long,
   traveling the track and slipping behind each plaque. Two of them, opposed. */
.haart-orbit_pulse_arc {
  fill: none;
  stroke: var(--haart-accent);
  stroke-opacity: .55;
  stroke-width: 2.5px;
  vector-effect: non-scaling-stroke;
  stroke-linecap: round;
  stroke-dasharray: 151.9 607.4;
  --haart-flow-end: -759.3px;
  animation: haart-flow 26s linear infinite;
}
.haart-orbit_pulse.is-b .haart-orbit_pulse_arc { animation-delay: -13s; }
.haart-orbit_station { position: absolute; width: 0; height: 0; }
.haart-orbit_tag {
  position: absolute;
  translate: -50% -50%;
  white-space: nowrap;
  padding: .5rem .75rem;
  background-color: color-mix(in srgb, var(--haart-bg) 96%, transparent);
  border: 1px solid var(--haart-border);
  box-shadow: 0 16px 30px -22px var(--haart-shadow);
  font-family: var(--haart-font-body);
  font-size: .78rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--haart-ink2);
}
/* below the desktop breakpoint: the oval grows past the viewport, so it
   reads as arcs sweeping above and below the headline. Tablets drop the
   plaques; phones get them back on the visible arcs at compact size. */
@media (max-width: 991px) {
  .haart-orbit_station { display: none; }
  .haart-orbit { width: 170vw; }
}
@media (max-width: 767px) {
  /* phones: the oval turns upright (taller than wide), sitting low enough
     to clear the nav bar, sides passing just off the screen edges */
  .haart-orbit { width: 110vw; aspect-ratio: 5 / 7; top: 54%; }
  /* drop the headline stack low in the oval */
  .section_header23 .header23_component { translate: 0 7vh; translate: 0 7svh; }
  /* tighten the headline-to-tagline gap */
  .header23_component .margin-bottom.margin-xsmall { margin-bottom: .25rem; }
  .header23_component [data-hero-push="true"] { margin-top: .25rem; }
  .haart-orbit_station { display: block; }
  .haart-orbit_tag { font-size: .6rem; padding: .35rem .5rem; letter-spacing: .05em; }
  /* phones show three stations only — one top-left, two on the bottom arc
     (inline desktop positions are for the full pentagon, off-screen here) */
  .haart-orbit_station:nth-of-type(1) { left: 25% !important; top: 6.7% !important; }
  .haart-orbit_station:nth-of-type(3) { left: 75% !important; top: 93.3% !important; }
  .haart-orbit_station:nth-of-type(5) { left: 25% !important; top: 93.3% !important; }
  .haart-orbit_station:nth-of-type(2),
  .haart-orbit_station:nth-of-type(4) { display: none; }
}

/* process phases: numbered stations on a vertical hairline (the dial motif,
   set on a line). Replaces the template's icon timeline. */
.haart-phases { position: relative; display: flex; flex-direction: column; gap: 2.75rem; }
.haart-phases::before {
  content: "";
  position: absolute;
  top: 12px;
  bottom: 12px;
  left: 17px;
  width: 1px;
  background: var(--haart-edge);
}
/* crimson progress line drawn over the base hairline by the scroll timeline.
   Hidden (scaleY 0) only when JS runs; static pages just show the base line. */
.haart-phases_line {
  position: absolute;
  top: 12px;
  bottom: 12px;
  left: 16.5px;
  width: 2px;
  background: var(--haart-accent);
  pointer-events: none;
}
.haart-phase {
  position: relative;
  display: grid;
  grid-template-columns: 35px 1fr;
  grid-column-gap: 1.5rem;
  align-items: start;
}
.haart-phase_dot {
  width: 15px;
  height: 15px;
  border: 1.5px solid var(--haart-accent);
  border-radius: 50%;
  background-color: var(--haart-bg);
  margin: 6px 0 0 10px;
  position: relative;
  z-index: 1;
}
.haart-phase_body h3 { margin-bottom: .5rem; }

/* breathing room between the wordmark and the menu links */
@media screen and (min-width: 992px) {
  .navbar10_menu-left { margin-left: 2.75rem; }
}

/* ---------- haart components ---------- */
.haart-eyebrow {
  color: var(--haart-accent);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-family: var(--haart-font-body);
}

.haart-card-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--haart-border);
  border: 1px solid var(--haart-border);
}
.haart-card-grid.is-2col { grid-template-columns: repeat(2, 1fr); }
.haart-card {
  background: var(--_primitives---colors--neutral-darkest);
  padding: 2.75rem 2.25rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  min-height: 15rem;
}
.haart-card:hover { background: color-mix(in srgb, var(--haart-ink) 4%, var(--haart-bg)); }
.haart-card .haart-card-link {
  margin-top: auto;
  color: var(--haart-accent);
  font-size: 0.9rem;
  text-decoration: none;
}
.haart-card .haart-card-link:hover { color: var(--haart-accent-strong); }

.haart-work-item {
  display: grid;
  grid-template-columns: minmax(0, 20rem) minmax(0, 1fr);
  gap: 2rem;
  padding: 3rem 0;
  border-top: 1px solid var(--haart-border);
}
.haart-work-item:last-child { border-bottom: 1px solid var(--haart-border); }

.haart-list { margin: 0; padding: 0; list-style: none; }
.haart-list li {
  padding: 0.85rem 0 0.85rem 1.6rem;
  position: relative;
  border-bottom: 1px solid var(--haart-border-soft);
}
.haart-list li:before {
  content: "";
  position: absolute;
  left: 0;
  top: 1.45rem;
  width: 0.55rem;
  height: 1px;
  background: var(--haart-accent);
}

.haart-practice-section { border-top: 1px solid var(--haart-border); }

/* section titles: whole-block bounce-up matching the original ActionAI
   word-reveal feel (yPercent 110 / 0.8s / power3.out), minus the word
   splitting and the flash. js/haart-rise.js tags headings and flips them on
   when they scroll into view. Gated on .w-mod-js for no-JS browsers. */
.w-mod-js .haart-rise {
  opacity: 0;
  transform: translateY(1.1em);
  transition: opacity 0.45s ease-out, transform 0.8s cubic-bezier(0.165, 0.84, 0.44, 1);
}
.w-mod-js .haart-rise.haart-in {
  opacity: 1;
  transform: none;
}

.haart-contact-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 18rem);
  gap: 4rem;
  align-items: start;
}
.haart-field { display: flex; flex-direction: column; gap: 0.4rem; margin-bottom: 1.1rem; }
.haart-field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.haart-field label {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--haart-muted);
  font-family: var(--haart-font-body);
}
.haart-field input, .haart-field textarea {
  background: color-mix(in srgb, var(--haart-ink) 4%, transparent);
  border: 1px solid var(--haart-border);
  border-radius: 6px;
  padding: 0.75rem 0.9rem;
  color: var(--haart-ink);
  font-family: var(--haart-font-body);
  font-size: 1rem;
}
.haart-field input:focus, .haart-field textarea:focus { outline: none; border-color: var(--haart-accent); }
.haart-field input::placeholder, .haart-field textarea::placeholder { color: var(--haart-muted2); }
.haart-form-error { color: #d0342c; margin-bottom: 1rem; }

.haart-founder-grid {
  display: grid;
  grid-template-columns: minmax(0, 20rem) minmax(0, 1fr);
  gap: 3rem;
  align-items: start;
}
.haart-founder-photo {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  border-radius: 6px;
  border: 1px solid var(--haart-border);
}

@media screen and (max-width: 991px) {
  .haart-card-grid, .haart-card-grid.is-2col { grid-template-columns: 1fr; }
  .haart-work-item { grid-template-columns: 1fr; gap: 0.75rem; }
  .haart-founder-grid { grid-template-columns: 1fr; gap: 1.5rem; }
  .haart-founder-photo { max-width: 20rem; }
  .haart-contact-grid { grid-template-columns: 1fr; gap: 2.5rem; }
  .haart-field-row { grid-template-columns: 1fr; }

  /* mobile Safari does not apply the difference-blend reliably, leaving the
     nav white-on-white. Drop the blend on small screens and color the closed
     nav with real scheme ink; the open menu overlay stays dark with white
     links, so those keep the white anchor. */
  .navbar10_component { mix-blend-mode: normal; }
  .navbar10_component .navbar10_link,
  .navbar10_component .logo-text { color: var(--haart-ink); }
  .navbar10_component .w-nav-overlay .navbar10_link,
  .navbar10_component [data-nav-menu-open] .navbar10_link { color: #fff; }
  .navbar10_component .w-nav-overlay .button.is-secondary,
  .navbar10_component [data-nav-menu-open] .button.is-secondary {
    color: #fff;
    background-color: #ffffff1f;
    border-color: #ffffff40;
  }
  .navbar10_component .button.is-secondary {
    color: var(--haart-ink);
    background-color: color-mix(in srgb, var(--haart-ink) 10%, transparent);
    border-color: color-mix(in srgb, var(--haart-ink) 25%, transparent);
  }
  .navbar10_component .menu-icon1_line-top,
  .navbar10_component .menu-icon1_line-middle,
  .navbar10_component .menu-icon1_line-middle-inner,
  .navbar10_component .menu-icon1_line-bottom { background-color: var(--haart-ink); }
}

@media screen and (max-width: 479px) {
  /* page titles like "About Haart AI" must fit one line on phones */
  .heading-style-h1 { font-size: 2.4rem; }
}
