Back to Footers
Inspired by:Jolocky
Added on Oct 5, 2026
components/footers/sage-headline/sage-headline-footer.tsx
"use client"

import * as React from "react"

import { CtaLink } from "./components/cta-link"
import { Headline } from "./components/headline"
import { LegalColumn } from "./components/legal-column"
import { LinkColumn } from "./components/link-column"
import { PromptColumn } from "./components/prompt-column"
import { DEFAULT_COLUMNS, DEFAULT_HEADLINE } from "./data/defaults"
import { useCanObserve } from "./hooks/use-can-observe"
import { useIntro } from "./hooks/use-intro"
import { useMediaQuery } from "./hooks/use-media-query"
import { classNames } from "./lib/class-names"
import { REDUCED_MOTION_QUERY } from "./lib/constants"
import { fadeDelay, type DelayStyle } from "./lib/delays"
import { getFadeIndexes } from "./lib/fade-indexes"
import { footerStyles } from "./styles"
import type { SageHeadlineFooterProps } from "./types"

export function SageHeadlineFooter({
  className,
  headline = DEFAULT_HEADLINE,
  ctaLabel = "Request a demo",
  ctaHref = "#",
  promptLabel = "Ready to spend less time booking?",
  columns = DEFAULT_COLUMNS,
  termsLabel = "Terms of service",
  termsShortLabel = "Terms",
  termsHref = "#",
  privacyLabel = "Privacy",
  privacyHref = "#",
  copyright = "© 2026 Jolocky",
  copyrightSuffix = " Inc.",
}: SageHeadlineFooterProps) {
  const rootRef = React.useRef<HTMLElement>(null)

  // Server render assumes motion is allowed, like a first paint before the script runs.
  const reduceMotion = useMediaQuery(REDUCED_MOTION_QUERY)
  const canObserve = useCanObserve()
  const { pending, entering } = useIntro(rootRef, !reduceMotion && canObserve)

  // Delays are set whenever motion is allowed, even without an observer.
  const motion = !reduceMotion
  const fadeStyle: DelayStyle = (index) =>
    motion ? fadeDelay(index) : undefined
  const indexes = getFadeIndexes(columns)

  return (
    <footer
      ref={rootRef}
      className={classNames(
        "sg-footer",
        pending && "sg-is-pending",
        entering && "sg-is-in",
        className
      )}
    >
      <style>{footerStyles}</style>
      <Headline lines={headline} motion={motion} />

      <div className="sg-bottom">
        <div className="sg-rule"></div>

        <div className="sg-grid">
          <CtaLink
            label={ctaLabel}
            href={ctaHref}
            mobile
            style={fadeStyle(indexes.mobileCta)}
          />
          {columns.map((column, index) => (
            <LinkColumn
              key={column.title}
              column={column}
              indexes={indexes.columns[index]}
              fadeStyle={fadeStyle}
            />
          ))}
          <PromptColumn
            promptLabel={promptLabel}
            ctaLabel={ctaLabel}
            ctaHref={ctaHref}
            indexes={indexes}
            fadeStyle={fadeStyle}
          />
          <LegalColumn
            termsLabel={termsLabel}
            termsShortLabel={termsShortLabel}
            termsHref={termsHref}
            privacyLabel={privacyLabel}
            privacyHref={privacyHref}
            copyright={copyright}
            copyrightSuffix={copyrightSuffix}
            indexes={indexes}
            fadeStyle={fadeStyle}
          />
        </div>
      </div>
    </footer>
  )
}
Sage Headline
sage-headline

Less time booking,more time caring

Editorial & Typography Architecture
Built from scratch by Jolocky, with our own layout, color and motion.
Signature Standard
Precision interaction engineering with zero external runtime bloat.
Open Source Registry
Production-ready multi-file tree built for modern Next.js and Tailwind CSS.

Engineering Breakdown

Sage Headline — A calm sage green footer led by a huge two line headline. When the footer scrolls into view, each line slides up out of its own mask, a dashed rule draws across from the left, and the link columns fade in one after another. After that everything is hover and focus: a hairline underline draws in under a link from the left and retracts to the right, the other links in that column fade back to 40%, and the arrow of the call to action nudges up and right. Tablet turns the call to action into an outlined pill and moves the legal links into a bottom bar, and mobile swaps it for a full width dark button with shortened legal wording.
Every interaction state, motion curve, and responsive edge-case has been extracted and reconstructed for seamless integration into modern React applications.
01
Zero — Primitive Dependency & Pure Standalone Pattern: pure React and scoped CSS. There is no UI primitive library, no icon package and nothing extra to install.
02
Masked Headline: every headline line sits in its own overflow mask and slides up over 1.1 seconds, 110ms after the previous line. The mask is padded so descenders are not clipped.
03
Rule and Fade Sequence: the dashed rule draws from left to right over 1.4 seconds. Every link, heading and the copyright then fades up 10px, starting at 400ms and 35ms apart in reading order.
04
Plays Once, Then Hands Over: the intro starts when 25% of the footer is visible and its classes come off after 2.2 seconds, so the hover transitions are not slowed by the intro timings.
05
Hairline Hover: the underline is a one pixel gradient whose size animates from 0 to 100%. It draws in from the left, and on leaving it retracts toward the right because the background position flips.
06
Dimming Siblings: while the pointer is over a column, every link in it except the hovered one fades to 40%. Keyboard focus shows the same underline.
07
Three Layouts: desktop uses a four column grid at 76px headline size. Tablet uses three columns at 60px and puts the legal links in a bottom bar under a dashed line. Mobile uses two link columns at 50px, a full width dark button and 46px tap rows.
08
Shortened Mobile Copy: Terms of service becomes Terms and the Inc. after the company name is dropped. The prompt column is hidden because the button already says it.
09
Reduced Motion: nothing is hidden and every transition is switched off.
Last Updated
Oct 5, 2026
Tags & Specifications
Masked Headline RevealDashed Rule DrawStaggered FadeUnderline HoverDimming SiblingsZero Primitive
Color Palette
#dfe8c4
#0e0f0c
Technology Stack
Engineered using established and reliable modern web technologies for peak runtime performance and developer ergonomics.
React
Next.js
TypeScript
Scoped CSS
Zero Primitive