:root{
  /* ===== FOUNDATION -- editorial, restrained, mostly monochrome ===== */
  --ink:#1A1A1A;
  --ivory:#FAFAF8;      /* page background -- warm off-white, never pure white */
  --white:#FFFFFF;      /* cards */
  --stone:#F2F1EE;      /* alternate section background, one step off the page bg */
  --border:#E7E7E5;     /* card borders, dividers, hairlines */
  --graphite:#666666;   /* secondary text */

  /* ===== ACCENT GRADIENT -- Bloom's one signature color moment. used sparingly:
     a thin top line, a small dot, a CTA underline or hover glow, a section
     indicator. never a large block of color, never all four at once outside
     the gradient itself. everything else on the site stays monochrome. ===== */
  --coral:#FF6B6B;
  --orange:#FF8A3D;
  --lavender:#9B8CFF;
  --blue:#3B82F6;
  --gradient-bloom: linear-gradient(90deg, var(--coral), var(--orange), var(--lavender), var(--blue));
  /* retired -- no longer part of the active palette, kept defined only so nothing silently breaks */
  --sage:#7FAE8C;
  --peony:#F06292;
  --marigold:#F6B73C;

  /* legacy alias so nothing silently breaks */
  --muted:#666666;

  /* one typeface family, not two -- Anton for every bold condensed display
     headline and manifesto moment, Inter for everything else (body copy,
     UI, supporting lines). emphasis comes from scale, weight, spacing, and
     whitespace, not from switching to a second typographic voice -- a
     serif/italic pass was tried and pulled back out; it was becoming a
     second identity competing with the ink and the condensed type instead
     of reinforcing them. */
  --display: 'Anton', Impact, 'Arial Narrow', sans-serif;
  --sans: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
}

*{ box-sizing:border-box; margin:0; padding:0; }
html{ scroll-behavior:smooth; }
body{
  background:var(--ivory);
  color:var(--ink);
  font-family:var(--sans);
  overflow-x:hidden;
  cursor:auto;
  position:relative;
}
/* subtle grain so the interface doesn't read as overly flat */
body::before{
  content:'';
  position:fixed; inset:0;
  z-index:40;
  pointer-events:none;
  opacity:.035;
  mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
a{ text-decoration:none; color:inherit; }
ul{ list-style:none; }
img,video{ max-width:100%; display:block; }
.wrap{ max-width:1240px; margin:0 auto; padding:0 6vw; position:relative; }

/* ===== custom cursor ===== */
.cursor-dot{
  position:fixed;
  top:0; left:0;
  width:14px; height:14px;
  border-radius:50%;
  background:var(--coral);
  pointer-events:none;
  z-index:9999;
  transform:translate(-50%,-50%);
  transition:width .2s ease, height .2s ease, background .2s ease, opacity .2s ease;
  opacity:0;
  mix-blend-mode:difference;
}
.cursor-dot.active{ opacity:1; }
.cursor-dot.hover{ width:44px; height:44px; background:var(--ivory); }
@media (pointer:coarse){ .cursor-dot{ display:none; } }

/* ===== progress bar -- the accent gradient, the one place all four colors
   appear together, and only as a 3px hairline ===== */
.progress-bar{
  position:fixed; top:0; left:0; height:3px; width:0%;
  background:var(--gradient-bloom);
  z-index:1000;
  transition:width .1s linear;
}

/* ===== nav -- minimal, smaller, elegant, with room to breathe ===== */
.nav{
  position:fixed; top:0; left:0; right:0; z-index:500;
  padding:24px 0;
  transition:background .3s ease, box-shadow .3s ease, padding .3s ease;
}
/* a tiny, almost-imperceptible hint of ink behind the nav -- independent of
   the big page-level ink layers (which scroll away with the document), this
   lives on the fixed nav itself so it's always there, at any scroll depth,
   never fully detached from the rest of the identity. deliberately far
   fainter than anything else on the page. */
.nav::before{
  content:'';
  position:absolute; inset:-40% -6% -40% -6%;
  background:radial-gradient(ellipse 60% 100% at 18% 40%, rgba(255,107,107,.05), transparent 65%),
             radial-gradient(ellipse 50% 90% at 82% 60%, rgba(155,140,255,.04), transparent 70%);
  filter:blur(18px);
  z-index:-1;
  pointer-events:none;
  animation:navInkDrift 46s ease-in-out infinite alternate;
}
@keyframes navInkDrift{
  0%{ transform:translateX(0) scale(1); }
  100%{ transform:translateX(2.5%) scale(1.05); }
}
.nav.scrolled{
  background:rgba(250,250,248,0.9);
  backdrop-filter:blur(10px);
  box-shadow:0 1px 0 var(--border);
  padding:16px 0;
}
.nav-inner{
  max-width:1240px; margin:0 auto; padding:0 6vw;
  display:flex; align-items:center; justify-content:space-between;
}
.wordmark{
  font-family:var(--display);
  font-size:21px; font-weight:500;
  letter-spacing:.2px;
  color:var(--ink);
  text-transform:lowercase;
}
/* the logo stays monochrome -- "bloom" reads as a weight shift, not a color */
.bloom-accent{ color:var(--graphite); }
/* the hero's secondary brand lockup gets a touch of the philosophy-section lavender --
   the nav wordmark above stays fully monochrome per the logo rule */
.hero-kicker-brand .bloom-accent{ color:var(--lavender); }
.nav-links{ display:flex; gap:46px; }
.nav-links a{
  font-family:var(--sans);
  font-size:13px; font-weight:500; color:var(--ink);
  position:relative; padding-bottom:4px;
  letter-spacing:.2px;
}
.nav-links a::after{
  content:''; position:absolute; bottom:0; left:0; width:0; height:1px;
  background:var(--ink); transition:width .25s ease;
}
.nav-links a:hover::after{ width:100%; }
/* primary button family -- black pill, white text, understated. on hover, a
   soft blurred wash of the accent gradient appears behind it instead of a
   color swap or an expanding shape. */
.nav-cta{
  position:relative;
  background:var(--ink); color:var(--white);
  padding:10px 22px; border-radius:999px;
  font-family:var(--sans);
  font-size:13.5px; font-weight:500;
  /* the lift + expand on hover use the standalone `translate`/`scale`
     properties (not the `transform` shorthand) on purpose -- this button is
     also .magnetic, and script.js's magnetic effect writes an inline
     `style.transform` on every mousemove, which would silently clobber any
     transform set from a stylesheet :hover rule the instant the cursor
     moves. translate/scale are separate CSS properties, so they keep
     working underneath the magnetic offset instead of fighting it. */
  translate:0 0; scale:1;
  transition:translate .3s cubic-bezier(.16,1,.3,1), scale .3s cubic-bezier(.16,1,.3,1);
}
.nav-cta::before{
  content:'';
  position:absolute; inset:-3px;
  border-radius:999px;
  background:var(--gradient-bloom);
  opacity:0; z-index:-1;
  filter:blur(12px);
  transition:opacity .45s ease;
}
.nav-cta span{ position:relative; z-index:2; }
.nav-cta:hover{ translate:0 -1px; scale:1.03; }
.nav-cta:hover::before{ opacity:.5; }
.nav-cta:hover::before{ transform:scale(11); }
.nav-cta:hover span{ color:var(--ink); }
@media (max-width:720px){ .nav-mobile-hide{ display:none; } }

/* ===== hero -- the first bloom: coral. no background color of its own
   anymore -- it inherits the page's ivory from body, so the ink atmosphere
   (now a page-level element behind everything, not a child of hero) can
   show through it with nothing to occlude it. ===== */
.hero{
  position:relative;
  min-height:96vh;
  display:flex; flex-direction:column; align-items:flex-start; justify-content:center;
  text-align:left;
  padding-top:90px; padding-bottom:56px;
  overflow:hidden;
}

/* ===== ink layers -- three independent layers, not one field. lives at the
   page level (see index.html, placed right before the nav), not nested
   inside the hero, so nothing clips it -- .hero has overflow:hidden, which
   was the real source of the earlier "horizontal cutoff": anything the
   mask hadn't finished fading before hitting the section's own edge was
   getting hard-clipped there. here there's no cropping element at all.

   composition is deliberately restrained now: one concentrated bloom of
   ink sitting behind and around the word "bloom" in the headline, with
   most of the hero left as clean, empty ivory. each layer shares the same
   focal point and the same box height so they stay lined up, but differs
   in reach, opacity, blur/saturation, and drift speed:
     - bg:  a huge, almost-imperceptible haze (barely there)
     - mid: two or three flowing cloud shapes, moderate presence
     - fg:  small, high-contrast tendrils right at the focal point
   each mask (ink-mask-bg/mid/fg.svg) pushes a soft base shape through
   feTurbulence + feDisplacementMap rather than a plain blur, so edges curl
   and fork like diffusing ink instead of softening into a uniform blob --
   the fg layer runs the displacement twice, at two scales, for the kind of
   fine branching real ink-in-water footage has. */
.ink-layer{
  position:absolute;
  top:0; left:50%;
  width:100vw;
  /* ~32% larger than before, matching the requested scale increase -- each
     mask now traces an S-curve (see ink-mask-*.svg): starting small and
     faint behind the nav wordmark, blooming outward -- densest -- right
     behind the word "bloom," then arcing up toward the top right and
     dissolving to nothing. the path leaves real gaps of full transparency
     between its nodes on purpose, so most of the hero stays untouched. */
  height:1120px;
  transform:translateX(-50%);
  z-index:-1;
  pointer-events:none;
  /* explicit page-color background so each layer's multiply-blended video
     has something real to blend against -- an element with mask-image
     creates its own isolated compositing group in most browsers, which
     otherwise silently cuts a blend-mode child off from the true page
     background behind it. */
  background:var(--ivory);
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
  -webkit-mask-size:100% 100%; mask-size:100% 100%;
  mask-mode:alpha;
  /* the standalone `translate` property (distinct from `transform`) carries
     the mouse-follow offset set in script.js -- it composes with the
     keyframe drift below rather than fighting it, since they're separate
     CSS properties. long, floaty easing so the motion reads as ambient,
     not reactive. */
  translate:0 0;
  scale:1;
  /* the scale transition is what powers the brief navigation "ripple" --
     script.js nudges scale up a couple percent and straight back down on
     every route change; because it's a transition (not a keyframe
     animation), it never touches -- or restarts -- the drift animation
     below. */
  transition:translate 1.6s cubic-bezier(.16,1,.3,1), scale 1.4s cubic-bezier(.16,1,.3,1);
}
.ink-layer video{
  width:100%; height:100%;
  object-fit:cover;
  object-position:center 12%;
  display:block;
  /* multiply blend (verified against the source footage's pure-white
     background) is what makes that white vanish into the ivory backdrop
     while the ink itself keeps its full color -- screen/lighten would do
     the opposite here and wash the ink out, since it's dark content on a
     light background. no blur/filter on the *layer* itself -- that would
     isolate this blend mode further and break it; blur lives on the video
     element, which carries its own blend mode already. */
  mix-blend-mode:multiply;
}
/* slowed down considerably -- restrained, deliberate motion reads as more
   luxury than something that visibly hurries. */
.ink-layer-bg{
  -webkit-mask-image:url("ink-mask-bg.svg");
  mask-image:url("ink-mask-bg.svg");
  animation:inkDriftSlow 85s ease-in-out infinite alternate;
}
.ink-layer-bg video{ opacity:.4; filter:blur(5px) saturate(1.1) contrast(1) brightness(1.03); }
.ink-layer-mid{
  -webkit-mask-image:url("ink-mask-mid.svg");
  mask-image:url("ink-mask-mid.svg");
  animation:inkDriftMid 52s ease-in-out infinite alternate;
}
/* contrast pulled back and brightness lifted slightly -- the previous pass
   was crushing the darkest ink toward charcoal/black; this keeps it a deep,
   rich maroon instead, without losing the contrast against clean space. */
.ink-layer-mid video{ opacity:.6; filter:blur(1px) saturate(1.3) contrast(1.02) brightness(1.06); }
.ink-layer-fg{
  -webkit-mask-image:url("ink-mask-fg.svg");
  mask-image:url("ink-mask-fg.svg");
  animation:inkDriftFast 34s ease-in-out infinite alternate;
}
.ink-layer-fg video{ opacity:.78; filter:blur(.15px) saturate(1.55) contrast(1.06) brightness(1.1); }

/* the video's own opacity is the one thing that changes between "pages" --
   same DOM, same path, same drift, just a different mood. transitions
   smoothly (see .ink-layer video opacity transition below) so moving
   between pages feels like the same living field settling, not a swap. */
.ink-layer video{ transition:opacity 2.2s ease, filter 1.1s ease; }
/* founder page: calmer, more white space -- the ink recedes rather than
   disappearing. */
body[data-page="founder"] .ink-layer-fg video{ opacity:.5; }
body[data-page="founder"] .ink-layer-mid video{ opacity:.38; }
body[data-page="founder"] .ink-layer-bg video{ opacity:.28; }

/* per-destination nav reactions (script.js's reactInk()) -- distinct from
   the founder/home settle handled via translate+scale below. "shape-shift"
   is the brief, temporary reaction to clicking How We Help: the foreground
   tendrils richen for a beat, reading as the dominant bloom shape changing,
   then ease straight back. class is added/removed by JS; the transition
   above is what makes it read as a shift rather than a snap. */
.ink-shape-shift .ink-layer-fg video{
  filter:blur(.15px) saturate(2) contrast(1.1) brightness(1.14);
}
.ink-shape-shift .ink-layer-mid video{
  filter:blur(1px) saturate(1.55) contrast(1.06) brightness(1.08);
}

@keyframes inkDriftSlow{
  0%{ transform:translate(-50%,0) scale(1); }
  100%{ transform:translate(calc(-50% + .4%), -.5%) scale(1.008); }
}
@keyframes inkDriftMid{
  0%{ transform:translate(-50%,0) scale(1); }
  100%{ transform:translate(calc(-50% + .9%), -1.1%) scale(1.016); }
}
@keyframes inkDriftFast{
  0%{ transform:translate(-50%,0) scale(1); }
  100%{ transform:translate(calc(-50% + 1.6%), -1.9%) scale(1.026); }
}

.pill-row .pill{ border-radius:999px; }

.hero-eyebrow{
  max-width:640px;
  font-family:var(--sans);
  font-size:13px; font-weight:500; letter-spacing:.15em;
  color:var(--graphite);
  margin-bottom:20px;
  text-transform:uppercase;
}
/* small, secondary brand lockup -- sits above the giant headline instead of being it */
.hero-kicker-brand{
  font-family:var(--display);
  font-size:clamp(19px, 2.2vw, 26px);
  font-weight:500;
  text-transform:lowercase;
  letter-spacing:.1px;
  color:var(--ink);
  margin-bottom:20px;
  opacity:0;
  animation:fadeUp .7s ease forwards;
  animation-delay:.05s;
}
.hero-headline{
  font-family:var(--display);
  font-weight:500;
  font-size:clamp(42px, 6.4vw, 72px);
  line-height:1.08;
  letter-spacing:-.01em;
  text-transform:lowercase;
  color:var(--ink);
  margin-bottom:28px;
  max-width:100%;
}
.hero-headline .char{
  display:inline-block;
  opacity:0;
  transform:translateY(16px);
  animation:charIn .6s cubic-bezier(.2,.8,.2,1) forwards;
}
/* "bloom" in coral -- the site's one deliberate accent moment in the headline,
   flat and confident, no drop shadow / echo effect */
.hero-headline .bloom-char{ color:var(--coral); }
.hero-headline .dot{ color:var(--ink); }
@keyframes charIn{ to{ opacity:1; transform:translateY(0); } }

.hero-sub{
  position:relative;
  max-width:520px;
  font-family:var(--sans);
  font-size:18px;
  line-height:1.7;
  letter-spacing:0;
  color:var(--ink);
  font-weight:400;
  opacity:0;
  animation:fadeUp .8s ease forwards;
  animation-delay:.4s;
}
/* a quiet "window" of lighter ivory behind the paragraph -- not a solid
   card, just enough lift that reading doesn't take effort when the ink
   happens to pass underneath. sits behind the text (z-index:-1 within the
   paragraph's own stacking context) but still above the page-level ink
   layers, since .hero-sub itself is ordinary in-flow hero content. */
.hero-sub::before{
  content:'';
  position:absolute;
  inset:-22px -34px;
  background:radial-gradient(ellipse 90% 100% at 30% 50%,
    rgba(250,248,243,.62) 0%,
    rgba(250,248,243,.4) 46%,
    rgba(250,248,243,.14) 72%,
    transparent 100%);
  filter:blur(10px);
  z-index:-1;
  pointer-events:none;
}
@keyframes fadeUp{ from{ opacity:0; transform:translateY(16px); } to{ opacity:1; transform:translateY(0); } }

/* primary CTA -- black pill, white text; a soft blurred wash of the accent
   gradient appears behind it on hover instead of a color swap */
.hero-cta{
  display:inline-block;
  position:relative;
  margin-top:36px;
  background:var(--ink); color:var(--white);
  padding:15px 30px; border-radius:999px;
  font-family:var(--sans);
  font-weight:500; font-size:14.5px;
  opacity:0;
  animation:fadeUp .8s ease forwards;
  animation-delay:.55s;
  /* translate/scale, not transform -- see the long comment on .nav-cta for
     why (this button is also .magnetic). */
  translate:0 0; scale:1;
  transition:translate .3s cubic-bezier(.16,1,.3,1), scale .3s cubic-bezier(.16,1,.3,1);
}
.hero-cta::before{
  content:'';
  position:absolute; inset:-3px;
  border-radius:999px;
  background:var(--gradient-bloom);
  opacity:0; z-index:-1;
  filter:blur(14px);
  transition:opacity .45s ease;
}
/* a small ink bloom that travels under the label on hover, instead of a
   flashy color swap -- shared across every primary/secondary CTA on the
   site (hero, nav, offer) so the interaction reads as one signature, not a
   one-off. sits above ::before (the outer glow wash) but below the label
   text itself. */
.hero-cta::after,
.nav-cta::after,
.offer-cta::after{
  content:'';
  position:absolute; top:50%; left:10%;
  width:16px; height:16px;
  border-radius:50%;
  background:var(--coral);
  filter:blur(7px);
  opacity:0;
  transform:translate(-50%,-50%);
  z-index:1;
  pointer-events:none;
  transition:left 1.1s cubic-bezier(.16,1,.3,1), opacity .4s ease;
}
.hero-cta:hover::after,
.nav-cta:hover::after,
.offer-cta:hover::after{
  opacity:.5;
  left:88%;
}
.hero-cta span{ position:relative; z-index:2; }
.hero-cta:hover{ translate:0 -2px; scale:1.035; }
.hero-cta:hover::before{ opacity:.55; }

/* scroll cue -- a tiny ink droplet instead of a "SCROLL" label. it falls,
   meets an invisible surface, and sends out one ripple, on a 6s loop --
   teaching people to scroll without a single word. */
.hero-scroll{
  position:absolute; bottom:40px; left:6vw;
  z-index:2;
}
.scroll-droplet-wrap{
  position:relative;
  display:block;
  width:16px; height:46px;
}
.scroll-droplet{
  position:absolute; left:50%; top:0;
  width:6px; height:6px; border-radius:50% 50% 50% 0;
  background:var(--coral);
  transform:translate(-50%,0) rotate(45deg);
  animation:dropletFall 6s cubic-bezier(.6,0,.9,.4) infinite;
}
.scroll-ripple{
  position:absolute; left:50%; bottom:2px;
  width:5px; height:5px; border-radius:50%;
  border:1px solid var(--coral);
  transform:translate(-50%,50%) scale(0);
  opacity:0;
  animation:dropletRipple 6s ease-out infinite;
}
.visually-hidden{
  position:absolute; width:1px; height:1px;
  padding:0; margin:-1px; overflow:hidden;
  clip:rect(0,0,0,0); white-space:nowrap; border:0;
}
@keyframes dropletFall{
  0%{ top:0; opacity:0; transform:translate(-50%,0) rotate(45deg) scale(.7); }
  10%{ opacity:.85; transform:translate(-50%,0) rotate(45deg) scale(1); }
  45%{ top:34px; opacity:.85; }
  50%{ top:34px; opacity:0; }
  100%{ top:34px; opacity:0; }
}
@keyframes dropletRipple{
  0%, 46%{ transform:translate(-50%,50%) scale(0); opacity:0; }
  50%{ transform:translate(-50%,50%) scale(1); opacity:.55; }
  66%{ transform:translate(-50%,50%) scale(2.8); opacity:0; }
  100%{ opacity:0; }
}

/* ===== trust strip -- foundation only, no bloom. as it approaches, the ink
   briefly hushes to almost nothing (see body.ink-hush below) -- a beat of
   pure white and silence -- then this line fades in a little after, like
   taking a breath. one-shot, triggered by script.js's own dedicated
   IntersectionObserver, not the generic .reveal system, so the timing
   between the hush and the fade-in can be deliberately staggered. ===== */
.trust-strip{
  padding:30px 0;
  text-align:center;
  border-top:1px solid var(--border);
  border-bottom:1px solid var(--border);
}
.divider-line{
  font-family:var(--sans);
  font-size:12px; letter-spacing:.15em; text-transform:uppercase; color:var(--graphite); font-weight:500;
  opacity:0; transform:translateY(8px);
  transition:opacity 1.1s cubic-bezier(.16,1,.3,1), transform 1.1s cubic-bezier(.16,1,.3,1);
}
.divider-line.in-view{ opacity:1; transform:translateY(0); }
/* the "breath" -- all three ink layers hush to near-zero for a moment.
   !important because it needs to override the per-page and per-zone opacity
   rules elsewhere; it's brief and self-removing (script.js clears the class
   itself), so it never permanently fights those. */
body.ink-hush .ink-layer video{ opacity:.03 !important; }

/* ===== story / philosophy -- bloom: lavender (editorial, quotes) ===== */
/* almost full-screen now -- an intermission, not just another section.
   visitors should sit here a beat before continuing. */
.story{
  position:relative;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  min-height:100vh;
  padding:160px 6vw;
  background:var(--ivory);
  overflow:hidden;
}
.story::before{
  content:'';
  position:absolute;
  width:600px; height:600px;
  border-radius:50%;
  background:radial-gradient(circle, rgba(155,140,255,0.07), transparent 70%);
  top:50%; left:50%;
  transform:translate(-50%,-50%);
  pointer-events:none;
}
.story > *{ position:relative; z-index:1; }

/* the manifesto -- three lines rather than a paragraph, each staggered
   left/center/right for quiet asymmetric tension instead of one centered
   block, and each with more room than the last -- "something" (the
   emotional payoff, and deliberately left open, no period) gets the most
   breathing room of the three. same condensed display family as every other
   headline on the site (a serif pass was tried here and pulled back out --
   see the --display comment up in :root) -- the emphasis this section needs
   comes from scale, the staggered composition, and a lot of surrounding
   whitespace instead of a second typeface. sized down from the giant
   hero-scale version this started as, since Anton reads much heavier than
   a light serif did at the same size. the page-level ink (.ink-layer) has
   always fully scrolled out of view by the time this section reaches the
   middle of the viewport, so it's genuinely pure white here -- then a small
   bloom forms behind "becoming" as its line reveals (see .ink-word handling
   in script.js) and a second, broader ambient bloom builds behind the whole
   line as "something" lands a beat later, reaching full bloom before
   settling back down -- see .story-ambient-bloom below. */
.story-giant{
  position:relative;
  display:flex; flex-direction:column;
  width:100%;
  font-family:var(--display);
  font-weight:500;
  font-size:clamp(34px, 6.6vw, 96px);
  line-height:1.12;
  letter-spacing:-.005em;
  text-transform:lowercase;
  color:var(--ink);
}
.story-giant-line{ position:relative; display:block; }
.story-giant-line:nth-child(1){ align-self:flex-start; text-align:left; }
.story-giant-line:nth-child(2){ align-self:center; text-align:center; margin-left:4%; margin-top:.22em; }
.story-giant-line:nth-child(3){ align-self:flex-end; text-align:right; margin-top:.55em; }

/* "becoming" is the brand idea -- the one word in this section that keeps
   moving on its own, slowly and continuously, once it's revealed. subtle on
   purpose: a slow letter-spacing breathe and a faint opacity dip, nothing
   that reads as flashy. */
.becoming-word{ position:relative; display:inline-block; }
.becoming-word.in-view{ animation:becomingBreathe 7s ease-in-out infinite; }
@keyframes becomingBreathe{
  0%, 100%{ letter-spacing:0; opacity:1; }
  50%{ letter-spacing:.012em; opacity:.87; }
}
.becoming-bloom{
  position:absolute;
  left:50%; top:50%;
  width:240%; height:340%;
  transform:translate(-50%,-50%) scale(.35);
  border-radius:50%;
  background:radial-gradient(ellipse at center,
    rgba(255,107,107,.4) 0%,
    rgba(255,138,61,.24) 36%,
    rgba(155,140,255,.12) 60%,
    transparent 78%);
  filter:blur(28px);
  opacity:0;
  z-index:-1;
  pointer-events:none;
  transition:opacity 1.7s cubic-bezier(.16,1,.3,1), transform 1.9s cubic-bezier(.16,1,.3,1);
}
.becoming-word.in-view .becoming-bloom{ opacity:1; transform:translate(-50%,-50%) scale(1); }

/* broader ambient bloom behind the whole line -- builds as "something"
   (.story-finale) lands, overshoots to a full bloom, then eases back to a
   quiet resting glow rather than vanishing, so the section settles instead
   of snapping back to bare white. */
.story-ambient-bloom{
  position:absolute;
  left:50%; top:50%;
  width:120%; height:170%;
  transform:translate(-50%,-50%) scale(.5);
  border-radius:50%;
  background:radial-gradient(ellipse at center,
    rgba(255,107,107,.16) 0%,
    rgba(255,138,61,.1) 40%,
    rgba(155,140,255,.06) 66%,
    transparent 80%);
  filter:blur(64px);
  opacity:0;
  z-index:-1;
  pointer-events:none;
}
.story-finale.in-view ~ .story-ambient-bloom{
  animation:storyAmbientBloom 3.6s cubic-bezier(.16,1,.3,1) forwards;
}
@keyframes storyAmbientBloom{
  0%{ opacity:0; transform:translate(-50%,-50%) scale(.5); }
  55%{ opacity:1; transform:translate(-50%,-50%) scale(1.08); }
  100%{ opacity:.35; transform:translate(-50%,-50%) scale(1); }
}

.story-whisper{
  margin:64px auto 0;
  max-width:520px;
  font-family:var(--sans);
  font-size:18px; letter-spacing:.02em;
  color:var(--graphite);
  text-align:center;
}

/* ===== oversized dark statement band -- the "manifesto moment," a full-
   screen pause. deliberately pure black/white now -- no orange -- since the
   contrast alone already carries it; the one color moment is an ink bloom
   that forms behind "your brand" instead of a text-color swap. the first
   line dissolves (blur + near-zero opacity, not a full disappear) and the
   second blooms in a beat later, once .in-view is added by script.js's
   single-fire IntersectionObserver -- reduced-motion just shows the final
   state immediately. ===== */
.statement-band{
  position:relative;
  overflow:hidden;
  background:var(--ink);
  color:var(--white);
  min-height:100vh;
  display:flex; align-items:center;
  padding:140px 0;
  text-align:left;
}
.statement-stage{ display:flex; flex-direction:column; gap:8px; }
.statement-text{
  position:relative;
  font-family:var(--display);
  font-weight:500;
  font-size:clamp(28px, 4.2vw, 52px);
  line-height:1.2;
  text-transform:lowercase;
  max-width:820px;
  margin:0;
  transition:opacity 1.3s cubic-bezier(.16,1,.3,1), filter 1.3s cubic-bezier(.16,1,.3,1), transform 1.3s cubic-bezier(.16,1,.3,1);
}
.statement-out{ opacity:1; filter:blur(0); transform:translateY(0); }
.statement-band.in-view .statement-out{ opacity:.12; filter:blur(7px); transform:translateY(-6px) scale(.98); }
.statement-in{
  opacity:0; filter:blur(5px); transform:translateY(10px);
  transition-delay:.3s;
}
.statement-band.in-view .statement-in{ opacity:1; filter:blur(0); transform:translateY(0); transition-delay:.3s; }
.brand-word{ position:relative; display:inline-block; }
.brand-bloom{
  position:absolute;
  left:50%; top:50%;
  width:220%; height:340%;
  transform:translate(-50%,-50%) scale(.4);
  border-radius:50%;
  background:radial-gradient(ellipse at center,
    rgba(255,107,107,.5) 0%,
    rgba(255,138,61,.22) 40%,
    rgba(155,140,255,.14) 64%,
    transparent 80%);
  filter:blur(30px);
  opacity:0;
  z-index:-1;
  pointer-events:none;
  transition:opacity 1.6s cubic-bezier(.16,1,.3,1) .5s, transform 1.8s cubic-bezier(.16,1,.3,1) .5s;
}
.statement-band.in-view .brand-bloom{ opacity:1; transform:translate(-50%,-50%) scale(1); }

/* ===== generic section rhythm ===== */
.eyebrow{
  font-family:var(--sans);
  font-size:13px; font-weight:500; letter-spacing:.15em; text-transform:uppercase;
  color:var(--graphite);
  margin-bottom:14px;
}
.section-pad{ padding:300px 0; }
.section-title{
  font-family:var(--display);
  font-weight:500;
  font-size:clamp(32px, 3.2vw, 48px);
  line-height:1.15;
  text-transform:lowercase;
  max-width:820px;
  margin-bottom:20px;
}
.section-intro{
  max-width:520px;
  font-family:var(--sans);
  color:var(--graphite);
  font-size:18px;
  line-height:1.7;
}

/* ===== about -- foundation only, no bloom color (restraint is the point) ===== */
.about-section{
  position:relative;
  overflow:hidden;
  background:var(--stone);
}
.about-section::before{
  content:'';
  position:absolute;
  width:640px; height:640px;
  border-radius:50%;
  background:radial-gradient(circle, rgba(36,34,32,0.05), transparent 70%);
  top:-220px; right:-180px;
  pointer-events:none;
}
.about-section .wrap{ position:relative; z-index:1; }
/* the section's one deliberate touch of color -- a quiet coral underline, not a
   bloom color assignment. everything else here stays monochrome on purpose. */
.about-eyebrow{ position:relative; padding-bottom:10px; }
.about-eyebrow::after{
  content:''; position:absolute; left:0; bottom:0; width:28px; height:2px;
  background:var(--coral);
}
.about-grid{
  display:grid;
  grid-template-columns:.95fr 1.1fr;
  gap:100px;
  align-items:start;
}
/* the left column stays pinned while the principles scroll past on the
   right -- simplified to headline + one short lede, deliberately
   uncrowded, so the three principles carry the section instead of
   competing with a paragraph for attention. top offset clears the fixed
   nav; the sticky range is naturally bounded by .about-section's own
   height, so it un-pins gracefully once the section ends. */
.about-grid > div:first-child{
  position:sticky;
  top:130px;
}
/* short lede paragraph -- deliberately its own class (not the shared
   .about-copy used on the founder page) so tightening it here can't shift
   spacing on founder.html's "my approach" section. */
.about-lede{
  font-family:var(--sans);
  font-size:17px; line-height:1.75; color:var(--graphite);
  max-width:420px;
  margin-top:36px;
}

/* three numbered principles -- the section's dominant visual element, not a
   supporting bullet list. as each scrolls into view (see script.js) it
   becomes the sole "active" one: darkens from graphite to ink and gets a
   soft coral/lavender ink bloom behind it, while the previous principle
   fades back to gray. */
.principle-list{ display:flex; flex-direction:column; gap:68px; padding-top:6px; }
.principle{
  position:relative;
  color:var(--graphite);
  transition:color .9s cubic-bezier(.16,1,.3,1);
}
.principle.active{ color:var(--ink); }
.principle-bloom{
  position:absolute;
  left:-44px; top:-34px;
  width:190px; height:190px;
  border-radius:50%;
  background:radial-gradient(ellipse at center,
    rgba(255,107,107,.3) 0%,
    rgba(155,140,255,.16) 46%,
    transparent 76%);
  filter:blur(32px);
  opacity:0;
  z-index:-1;
  pointer-events:none;
  transition:opacity 1.1s ease;
}
.principle.active .principle-bloom{ opacity:1; }
.principle-num{
  display:block;
  font-family:var(--display);
  font-weight:500;
  font-size:14px; letter-spacing:.12em;
  color:inherit; opacity:.55;
  margin-bottom:10px;
}
.principle-title{
  font-family:var(--display);
  font-weight:500;
  font-size:clamp(23px, 2.3vw, 31px);
  text-transform:lowercase;
  line-height:1.2;
  color:inherit;
  margin-bottom:10px;
}
.principle-copy{
  font-family:var(--sans);
  font-size:15.5px; line-height:1.65;
  color:inherit; opacity:.82;
  max-width:380px;
}
@media (max-width:820px){ .about-grid{ grid-template-columns:1fr; } .about-grid > div:first-child{ position:static; } .principle-list{ margin-top:36px; } }

/* ===== "how brands bloom" -- the site's single signature framework
   (Intentional -> Memorable -> Trusted -> Discoverable -> Sustainable), a
   card-grid replaced with one evolving word. previously this pinned the
   page and required 260vh of scroll to step through all five stages, which
   ended up feeling like the site had gotten stuck rather than being in
   motion. now it's a normal-height section -- scrolling past it works like
   any other part of the page -- and the five stages are switched by
   clicking (or hovering/keyboard-focusing, for a quick preview) the dots
   below, via script.js's setCapabilityStage(). the active stage also gets a
   brighter, tighter ink highlight directly behind it (.capability-stage-
   highlight) on top of the section's ambient mood wash
   (.capability-ink-accent), so it's unmistakable which one is "being
   read." */
.capability-pin{
  position:relative;
}
.capability-stage-viewport{
  position:relative;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  padding:180px 0;
  background:var(--ivory);
  overflow:hidden;
}
/* the header -- eyebrow, "growth isn't a service. it's a system.", and the
   supporting line -- is the thought this section wants remembered, so it
   stays the largest, most dominant type on screen the entire time; it never
   crossfades or resizes as the stage word below it changes. a thin rule
   separates it from the evolving word, echoing the section's own progress
   line rather than introducing a new motif. */
.capability-header{ margin-bottom:8px; }
.capability-header .section-title{ max-width:720px; }
.capability-header .section-intro{ max-width:520px; margin-left:auto; margin-right:auto; }
.capability-divider{
  width:64px; height:1px;
  background:var(--border);
  margin:36px auto 0;
}

/* local, section-scoped ink accent -- the page-level ink layers are long
   scrolled out of view by the time visitors reach this section, so this is
   a small, independent CSS-only bloom rather than the video layers, whose
   color/shape/reach shifts with the active stage's mood via the
   data-mood attribute (set by script.js). */
.capability-ink-accent{
  position:absolute; inset:0; z-index:-1; pointer-events:none;
  opacity:.5;
  transition:opacity .9s ease, background 1s ease, filter 1s ease;
}
.capability-stage-viewport[data-mood="intentional"] .capability-ink-accent{
  background:radial-gradient(ellipse 30% 34% at 50% 42%, rgba(255,107,107,.12), transparent 72%);
  filter:blur(60px); opacity:.45;
}
.capability-stage-viewport[data-mood="memorable"] .capability-ink-accent{
  background:radial-gradient(ellipse 56% 60% at 50% 48%, rgba(255,107,107,.24), rgba(255,138,61,.15) 46%, transparent 76%);
  filter:blur(38px); opacity:.6;
}
.capability-stage-viewport[data-mood="trusted"] .capability-ink-accent{
  background:radial-gradient(ellipse 40% 46% at 50% 46%, rgba(155,140,255,.17), transparent 74%);
  filter:blur(52px); opacity:.4;
}
.capability-stage-viewport[data-mood="discoverable"] .capability-ink-accent{
  background:radial-gradient(ellipse 44% 50% at 38% 44%, rgba(59,130,246,.17), transparent 70%),
             radial-gradient(ellipse 28% 38% at 66% 56%, rgba(255,107,107,.15), transparent 72%);
  filter:blur(36px); opacity:.55;
}
.capability-stage-viewport[data-mood="sustainable"] .capability-ink-accent{
  background:radial-gradient(ellipse 60% 60% at 50% 50%, rgba(255,107,107,.05), transparent 78%);
  filter:blur(74px); opacity:.22;
}

/* a tighter, brighter spotlight directly behind the active stage -- distinct
   from the diffuse full-section .capability-ink-accent wash above. this is
   what makes the currently-selected stage read as highlighted/being read,
   not just "currently visible." always-on (not mood-colored) so it doesn't
   compete with the ambient accent's own color story. */
.capability-stage-highlight{
  position:absolute;
  left:50%; top:50%;
  width:74%; height:150%;
  transform:translate(-50%,-50%);
  border-radius:50%;
  background:radial-gradient(ellipse at center,
    rgba(255,107,107,.16) 0%,
    rgba(255,138,61,.09) 44%,
    transparent 78%);
  filter:blur(46px);
  opacity:.85;
  z-index:-1;
  pointer-events:none;
}

/* the evolving word -- deliberately restrained now, not a fifth "giant
   word." font-size sits *below* the pinned headline's, so the hierarchy
   always reads header-first, word-second. one word changes at a time; nothing
   else in this stack competes for attention with it. */
.capability-stage-stack{ position:relative; min-height:220px; margin-top:0; }
.capability-stage{
  position:absolute; inset:0;
  display:flex; flex-direction:column; align-items:center; text-align:center;
  opacity:0;
  transform:translateY(14px);
  pointer-events:none;
  /* quicker than the site's usual reveal pace on purpose -- with less scroll
     distance per stage now, a slower crossfade would visibly lag behind how
     fast the words are advancing. */
  transition:opacity .5s cubic-bezier(.16,1,.3,1), transform .5s cubic-bezier(.16,1,.3,1);
}
.capability-stage.active{
  opacity:1; transform:translateY(0);
  pointer-events:auto;
}
.capability-stage-num{
  font-family:var(--sans); font-size:12px; letter-spacing:.22em; color:var(--graphite);
  margin-bottom:14px;
}
.capability-stage-title{
  font-family:var(--display); font-weight:500;
  font-size:clamp(28px, 3vw, 40px);
  text-transform:lowercase; line-height:1.1;
  color:var(--ink);
  margin-bottom:16px;
}
/* sans, regular, no italics -- the serif is reserved for the manifesto
   section only, so this stays plainly in the site's working voice rather
   than borrowing that section's mood. */
.capability-stage-copy{
  font-family:var(--sans); font-weight:400;
  font-size:16px; line-height:1.6;
  color:var(--graphite);
  margin-bottom:22px;
}
/* plain stacked words, not pills -- the framework titles above already
   said what this is; these are just the quiet, unbulleted specifics. */
.capability-stage-tags{ display:flex; flex-direction:column; gap:4px; align-items:center; }
.capability-stage-tags span{
  font-family:var(--sans); font-size:13px; font-weight:500; letter-spacing:.02em;
  color:var(--graphite); opacity:.75;
}

/* editorial progress indicator -- a connected line of dots, not pills. now
   real interactive controls (<button>, see index.html) instead of decorative
   spans: click selects a stage, hover/focus previews one without changing
   the selection (see script.js). */
.capability-progress{
  position:relative;
  margin-top:52px;
  display:flex; flex-direction:column; align-items:center; gap:10px;
  z-index:2;
}
.capability-progress-track{ display:flex; align-items:center; }
.capability-dot{
  width:7px; height:7px; border-radius:50%;
  background:var(--border);
  position:relative;
  display:inline-block;
  border:none; margin:0; padding:0; -webkit-appearance:none; appearance:none;
  outline:none;
  cursor:pointer;
  transition:background .35s ease, transform .35s ease;
}
.capability-dot + .capability-dot{ margin-left:32px; }
.capability-dot::before{
  content:''; position:absolute; top:50%; right:100%;
  width:32px; height:1px;
  background:var(--border);
  transform:translateY(-50%);
}
.capability-dot:first-child::before{ display:none; }
.capability-dot:hover{ background:var(--graphite); transform:scale(1.25); }
.capability-dot.active{ background:var(--ink); transform:scale(1.4); }
.capability-dot:focus-visible{ outline:2px solid var(--coral); outline-offset:5px; }
.capability-progress-label{
  font-family:var(--sans); font-size:11px; letter-spacing:.16em; text-transform:uppercase; color:var(--graphite);
}

@media (prefers-reduced-motion: reduce){
  .capability-stage{ transition:none !important; }
  .capability-ink-accent, .capability-stage-highlight{ transition:none !important; }
}
@media (max-width:820px){
  .capability-stage-viewport{ padding:130px 0; }
  .capability-stage-title{ font-size:clamp(24px, 8vw, 32px); }
}

/* ===== process -- the one place all four accent colors appear in sequence,
   one per stage, to visualize progression ===== */
.process-band{ background:var(--stone); }
.process-grid{
  margin-top:70px;
  display:grid;
  grid-template-columns:repeat(4, 1fr);
  gap:32px;
}
.process-step{ text-align:left; }
.process-ring{
  width:42px; height:42px; border-radius:50%;
  font-weight:600; font-size:15px;
  display:flex; align-items:center; justify-content:center;
  margin-bottom:18px;
}
.process-step h3{
  font-family:var(--sans); font-weight:600; font-size:18px; text-transform:lowercase; margin-bottom:8px;
}
.process-step p{ font-family:var(--sans); font-size:16px; color:var(--graphite); line-height:1.6; }
@media (max-width:900px){ .process-grid{ grid-template-columns:repeat(2, 1fr); } }
@media (max-width:520px){ .process-grid{ grid-template-columns:1fr; } }

/* ===== work / growth stories -- bloom: blue ===== */
.badge-wrap{
  position:relative; width:132px; height:132px; flex-shrink:0;
  display:flex; align-items:center; justify-content:center;
}
.badge-ring{ animation:spin 30s linear infinite; }
@keyframes spin{ to{ transform:rotate(360deg); } }
.badge-center{
  position:absolute; width:46px; height:46px; border-radius:50%;
  background:var(--blue); color:var(--white);
  display:flex; align-items:center; justify-content:center;
  font-size:18px;
}
.work-grid{
  margin-top:60px;
  display:grid;
  grid-template-columns:repeat(3, 1fr);
  gap:28px;
}
.work-tile{
  position:relative;
  aspect-ratio:4/5;
  border-radius:20px;
  overflow:hidden;
  padding:26px;
  display:flex; align-items:flex-end;
  transition:transform .4s cubic-bezier(.16,1,.3,1);
}
.work-tile:hover{ transform:translateY(-6px); }
/* foundation-toned tiles with a soft blue glow in one corner -- one deliberate
   moment of color before the final CTA */
.work-tile::after{
  content:'';
  position:absolute; inset:0;
  background:radial-gradient(circle at 85% 15%, rgba(59,130,246,0.30), transparent 55%);
  pointer-events:none;
}
.tile-1{ background:linear-gradient(150deg, #2A2A2A, var(--ink)); }
.tile-2{ background:linear-gradient(150deg, #3A3A3A, var(--ink)); }
.tile-3{ background:linear-gradient(150deg, #333333, var(--ink)); }
.work-tile-label{ color:var(--white); }
.work-kicker{
  font-family:var(--sans); font-weight:500; font-size:10.5px;
  letter-spacing:.15em; text-transform:uppercase;
  color:var(--blue); opacity:.95; margin-bottom:12px;
}
.work-cat{
  font-family:var(--sans);
  font-size:11px; letter-spacing:.15em; text-transform:uppercase;
  font-weight:500; opacity:.75; margin-bottom:14px;
}
.work-name{
  font-family:var(--display); font-weight:500; font-size:22px; text-transform:lowercase;
  line-height:1.2; margin-bottom:8px;
}
.work-eta{ font-family:var(--sans); font-size:13px; opacity:.8; }
@media (max-width:820px){ .work-grid{ grid-template-columns:1fr; } }

/* ===== offer card -- CTA family, black + white with a gradient glow ===== */
.offer-section{ padding:0 6vw 280px; }
.offer-card{
  position:relative;
  background:var(--ink);
  color:var(--white);
  border-radius:26px;
  padding:70px 56px;
  display:grid;
  grid-template-columns:1fr auto;
  gap:40px;
  align-items:center;
  overflow:hidden;
}
.offer-eyebrow{ font-family:var(--sans); font-size:13px; letter-spacing:.15em; text-transform:uppercase; opacity:.7; margin-bottom:16px; }
.offer-title{
  font-family:var(--display); font-weight:500; font-size:clamp(26px, 3.2vw, 38px);
  text-transform:lowercase; line-height:1.2; margin-bottom:24px; max-width:520px;
}
.offer-perks li{
  font-family:var(--sans);
  font-size:15px; line-height:1.7; padding-left:22px; position:relative; opacity:.85;
}
.offer-perks li::before{ content:'—'; position:absolute; left:0; opacity:.6; }
.offer-cta{
  display:inline-block;
  position:relative;
  background:var(--white); color:var(--ink);
  padding:15px 28px; border-radius:999px;
  font-family:var(--sans);
  font-weight:500; font-size:14.5px; white-space:nowrap;
  /* translate/scale, not transform -- see the comment on .nav-cta. */
  translate:0 0; scale:1;
  transition:translate .3s cubic-bezier(.16,1,.3,1), scale .3s cubic-bezier(.16,1,.3,1);
}
.offer-cta::before{
  content:'';
  position:absolute; inset:-3px;
  border-radius:999px;
  background:var(--gradient-bloom);
  opacity:0; z-index:-1;
  filter:blur(14px);
  transition:opacity .45s ease;
}
.offer-cta span{ position:relative; z-index:2; }
.offer-cta:hover{ translate:0 -2px; scale:1.03; }
.offer-cta:hover::before{ opacity:.6; }
@media (max-width:720px){ .offer-card{ grid-template-columns:1fr; padding:44px 28px; } }

/* ===== contact -- coral + lavender blended together, like the start of
   another bloom -- the site's closing gesture, back where the hero began ===== */
.contact{
  position:relative;
  background:var(--ivory);
  padding:0 0 160px;
  overflow:hidden;
}
.contact-title{
  font-family:var(--display);
  font-weight:500;
  font-size:clamp(32px, 5vw, 60px);
  text-transform:lowercase;
  line-height:1.15;
  max-width:820px;
  margin-bottom:60px;
}
.contact-title em{
  font-style:normal;
  background:linear-gradient(90deg, var(--coral), var(--lavender));
  -webkit-background-clip:text;
  background-clip:text;
  color:transparent;
}
.contact-row{
  display:flex; justify-content:space-between; align-items:flex-end; flex-wrap:wrap; gap:24px;
  padding-top:44px; border-top:1px solid var(--border);
}
.contact-email{
  font-family:var(--display);
  font-weight:500;
  font-size:clamp(20px, 2.8vw, 28px);
  text-transform:lowercase;
  position:relative;
}
.contact-email::after{
  content:''; position:absolute; left:0; right:0; bottom:-4px; height:1px;
  background:linear-gradient(90deg, var(--coral), var(--lavender));
  transform:scaleX(0); transform-origin:left; transition:transform .3s ease;
}
.contact-email:hover::after{ transform:scaleX(1); }
.footer-meta{
  font-family:var(--sans);
  display:flex; flex-direction:column; gap:6px; text-align:right;
  font-size:13px; color:var(--graphite);
}

/* ===== growth line -- a small ownable motion motif: a dot grows first, then a
   thin line extends from it, like a branch. used as a section-opening divider
   in place of a static rule. color follows the section's bloom color via the
   --gl-color custom property (falls back to coral). ===== */
.growth-line{
  display:flex; align-items:center;
  margin-bottom:26px;
}
.growth-line::before{
  content:'';
  width:8px; height:8px; border-radius:50%; flex-shrink:0;
  background:var(--gl-color, var(--coral));
  transform:scale(0);
  transition:transform .5s cubic-bezier(.16,1,.3,1);
}
.growth-line::after{
  content:'';
  height:1px; flex:1; margin-left:10px;
  background:rgba(36,34,32,0.18);
  transform:scaleX(0); transform-origin:left;
  transition:transform .8s cubic-bezier(.16,1,.3,1) .15s;
}
.growth-line.in-view::before{ transform:scale(1); }
.growth-line.in-view::after{ transform:scaleX(1); }

/* ===== hover blooms -- a soft radial wash spreads from behind on hover instead
   of a hard color swap or scale, reused across cards/badges site-wide ===== */
.belief-card{ overflow:hidden; }
.belief-card::after{
  content:'';
  position:absolute; left:50%; bottom:-30%;
  width:150%; padding-bottom:150%;
  border-radius:50%;
  background:radial-gradient(circle, rgba(255,107,107,0.16), transparent 70%);
  transform:translate(-50%, 16%) scale(.55);
  opacity:0;
  transition:transform .6s cubic-bezier(.16,1,.3,1), opacity .5s ease;
  pointer-events:none; z-index:0;
}
.belief-card:hover::after{ opacity:1; transform:translate(-50%, 16%) scale(1); }
.belief-card > *{ position:relative; z-index:1; }

.process-ring{ transition:transform .45s cubic-bezier(.16,1,.3,1), box-shadow .45s cubic-bezier(.16,1,.3,1); }
.process-step:hover .process-ring{ transform:scale(1.08); box-shadow:0 0 0 10px rgba(26,26,26,0.06); }

/* ===== scroll reveal -- an organic "bloom open" ease rather than a flat fade ===== */
.reveal{
  opacity:0; transform:translateY(28px);
  transition:opacity .8s cubic-bezier(.16,1,.3,1), transform .8s cubic-bezier(.16,1,.3,1);
}
.reveal.in-view{ opacity:1; transform:translateY(0); }
.reveal-delay-1.in-view{ transition-delay:.08s; }
.reveal-delay-2.in-view{ transition-delay:.16s; }
.reveal-delay-3.in-view{ transition-delay:.24s; }
.reveal-delay-4.in-view{ transition-delay:.32s; }

/* used further down the page (growth stories, offer) -- a bit more expressive,
   scaling open rather than just sliding up, so the page feels more alive the
   deeper you scroll */
.reveal-bloom{
  opacity:0; transform:translateY(20px) scale(.94);
  transition:opacity .9s cubic-bezier(.16,1,.3,1), transform .9s cubic-bezier(.16,1,.3,1);
}
.reveal-bloom.in-view{ opacity:1; transform:translateY(0) scale(1); }

/* ===== reduced motion ===== */
@media (prefers-reduced-motion: reduce){
  .ink-layer{ display:none; }
  .ink-layer-bg, .ink-layer-mid, .ink-layer-fg{ animation:none !important; }
  .hero-headline .char, .hero-sub, .hero-kicker-brand, .hero-cta, .badge-ring{ animation:none !important; opacity:1 !important; transform:none !important; }
  .reveal, .reveal-bloom{ opacity:1 !important; transform:none !important; }
  .becoming-bloom{ transition:none !important; opacity:.45 !important; transform:translate(-50%,-50%) scale(1) !important; }
  .statement-out{ opacity:.12 !important; filter:blur(7px) !important; }
  .statement-in{ opacity:1 !important; filter:blur(0) !important; transform:none !important; }
  .brand-bloom{ transition:none !important; opacity:.4 !important; transform:translate(-50%,-50%) scale(1) !important; }
  .principle{ color:var(--ink) !important; }
  .principle-bloom{ transition:none !important; }
  .scroll-droplet, .scroll-ripple{ animation:none !important; }
  .divider-line{ opacity:1 !important; transform:none !important; }
  body.ink-hush .ink-layer video{ opacity:inherit !important; }
  .becoming-word.in-view{ animation:none !important; letter-spacing:0 !important; opacity:1 !important; }
  .story-finale.in-view ~ .story-ambient-bloom{ animation:none !important; opacity:.35 !important; transform:translate(-50%,-50%) scale(1) !important; }
  .approach-company{ position:static; opacity:1 !important; transform:none !important; display:block; margin-bottom:6px; }
  .approach-companies{ min-height:auto; }
  .approach-line-fill{ transition:none !important; width:100% !important; }
  .approach-fade{ opacity:1 !important; transform:none !important; }
}

@media (max-width:720px){
  .section-pad{ padding:130px 0; }
  .hero{ padding-top:120px; min-height:auto; }
  .ink-layer{ height:900px; }
  .hero-headline{ font-size:clamp(40px, 14vw, 80px); }
  .statement-band{ padding:130px 0; text-align:left; }
  .story{ padding:130px 6vw; }
  .story-giant-line:nth-child(1),
  .story-giant-line:nth-child(2),
  .story-giant-line:nth-child(3){ align-self:flex-start; text-align:left; margin-left:0; }
}

/* ===================================================================
   FOUNDER PAGE -- editorial profile, not a resume. restrained motion,
   same "one bloom color per section" rule as the rest of the site.
   =================================================================== */
.nav-links a.nav-link-active{ color:var(--coral); }

.founder-hero{ padding:190px 0 120px; }
.founder-hero-grid{
  display:grid;
  grid-template-columns:1fr 0.85fr;
  gap:72px;
  align-items:center;
}
.founder-name{
  font-family:var(--display);
  font-weight:500;
  font-size:clamp(36px, 5vw, 56px);
  text-transform:lowercase;
  line-height:1.1;
  color:var(--ink);
  margin-bottom:14px;
}
.founder-role{
  font-family:var(--sans);
  font-size:14px; font-weight:500; color:var(--graphite);
  margin-bottom:26px;
}
.founder-intro-copy{
  max-width:520px;
  font-family:var(--sans);
  font-size:18px; line-height:1.7; color:var(--ink);
}
.founder-portrait{
  position:relative;
  aspect-ratio:4/5;
  border-radius:22px;
  overflow:hidden;
  background:linear-gradient(160deg, var(--stone), var(--ivory));
  display:flex; align-items:center; justify-content:center;
}
.founder-portrait::before{
  content:'';
  position:absolute; inset:0;
  background:
    radial-gradient(circle at 28% 22%, rgba(255,107,107,0.28), transparent 55%),
    radial-gradient(circle at 76% 68%, rgba(155,140,255,0.24), transparent 58%),
    radial-gradient(circle at 50% 102%, rgba(59,130,246,0.18), transparent 55%);
  filter:blur(6px);
}
.founder-monogram{
  position:relative; z-index:1;
  font-family:var(--display);
  font-weight:500;
  font-size:clamp(120px, 16vw, 200px);
  color:var(--ivory);
  text-shadow:0 4px 30px rgba(26,26,26,0.2);
}
.founder-photo-note{
  position:absolute; z-index:1; bottom:18px; left:18px;
  font-family:var(--sans);
  font-size:11px; letter-spacing:.05em; color:var(--ivory);
  background:rgba(26,26,26,0.55);
  padding:6px 12px; border-radius:999px;
}

/* ===== why bloom -- bloom: lavender, a single centered pull-quote. same
   condensed display family as the rest of the site (no serif) -- "becoming"
   is emphasized with color, not a typeface change. ===== */
.why-bloom-band{ padding:60px 0 180px; text-align:center; }
.pull-quote{
  font-family:var(--display); font-weight:500;
  font-size:clamp(26px, 3.6vw, 44px);
  line-height:1.25;
  letter-spacing:-.005em;
  text-transform:lowercase;
  max-width:780px;
  margin:0 auto;
  color:var(--ink);
}
.pull-quote-mark{ color:var(--lavender); font-weight:500; }

/* ===== what I believe -- bloom: coral ===== */
.belief-grid{
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(220px, 1fr));
  gap:24px;
  margin-top:48px;
}
.belief-card{
  padding:32px 28px;
  border-radius:22px;
  background:var(--white);
  border:1px solid var(--border);
  box-shadow:0 1px 2px rgba(26,26,26,0.03), 0 10px 28px rgba(26,26,26,0.04);
  position:relative;
}
.belief-card::before{
  content:'';
  display:block;
  width:8px; height:8px; border-radius:50%;
  background:var(--coral);
  margin-bottom:20px;
}
.belief-text{
  font-family:var(--sans); font-weight:500;
  font-size:17px; line-height:1.5;
  color:var(--ink);
}

/* ===== approach -- monochrome, quiet ===== */
.approach-band{ background:var(--stone); }

/* the company sequence -- one name active at a time, a thin line growing
   beneath it in sync (script.js drives both off the same timing). not ink
   here on purpose -- a single continuous line reads as "strategy, followed
   through" without borrowing the site's ink motif. fades out as a whole
   once the sequence finishes, right before the headline/paragraph reveal
   (.approach-fade). */
.approach-journey{
  opacity:1;
  margin:8px 0 52px;
  transition:opacity .6s ease;
}
.approach-journey.fading{ opacity:0; }
.approach-companies{
  position:relative;
  min-height:64px;
  list-style:none; padding:0; margin:0 0 22px;
}
.approach-company{
  position:absolute; top:0; left:0;
  opacity:0;
  transform:translateY(10px);
  font-family:var(--display); font-weight:500;
  font-size:clamp(28px, 4.6vw, 52px);
  line-height:1;
  color:var(--ink);
  transition:opacity .5s ease, transform .5s ease;
}
.approach-company.active{ opacity:1; transform:translateY(0); }
.approach-line{
  width:100%; max-width:280px;
  height:1px;
  background:var(--border);
  overflow:hidden;
}
.approach-line-fill{
  display:block; height:100%; width:0%;
  background:var(--ink);
  transition:width 3.25s linear;
}
.approach-journey.in-view .approach-line-fill{ width:100%; }

/* the headline and paragraph stay hidden until the company sequence above
   finishes and fades out -- its own fade system (not the generic .reveal
   observer, which would trigger on scroll-into-view immediately and step on
   the timed sequence), driven by the same playApproachSequence() in
   script.js. */
.approach-fade{
  opacity:0;
  transform:translateY(20px);
  transition:opacity .8s cubic-bezier(.16,1,.3,1), transform .8s cubic-bezier(.16,1,.3,1);
}
.approach-fade.in-view{ opacity:1; transform:translateY(0); }
.approach-fade-delay.in-view{ transition-delay:.12s; }

.founder-footer{
  font-family:var(--sans);
  display:flex; justify-content:space-between; flex-wrap:wrap; gap:12px;
  padding:0 6vw 70px;
  font-size:13px; color:var(--muted);
}

@media (max-width:820px){
  .founder-hero-grid{ grid-template-columns:1fr; }
  .founder-portrait{ order:-1; aspect-ratio:16/10; }
}
@media (max-width:720px){
  .founder-hero{ padding:140px 0 80px; }
  .why-bloom-band{ padding:40px 0 100px; }
}
