/* =========================================================================
   PC & Apple IT Service — one stylesheet, no build step, no external fonts.
   Google Fonts from a CDN is a DSGVO risk in Germany and costs a round trip,
   so everything below runs on the system font stack.

   Layout rules this file keeps to, so later edits stay consistent:
     - mint is the only accent, and it is a fill, never type on a light ground
     - one radius scale: pill for anything pressable, 16px panels, 10px inputs
     - the page is light end to end. Two surfaces are saturated: the closing
       call and the tile that closes the services grid, both charcoal.
     - motion is transform, opacity and clip-path only, and every :hover rule
       is gated so a tap on a phone does not fire it.
   ========================================================================= */

/* Self-hosted, SIL Open Font License. Serving them ourselves keeps the rule
   the site was built on: no external request at runtime, which is why Google
   Fonts was rejected in the first place. Both files are variable, so one file
   covers the whole weight range. */
@font-face {
    font-family: "Space Grotesk";
    src: url("/fonts/space-grotesk.woff2") format("woff2");
    font-weight: 400 700;
    font-display: swap;
    font-style: normal;
}
@font-face {
    font-family: "Public Sans";
    src: url("/fonts/public-sans.woff2") format("woff2");
    font-weight: 400 700;
    font-display: swap;
    font-style: normal;
}

:root {
    color-scheme: light;

    /* The palette of the Stitch design, verbatim. Mint is a fill: the design
       never sets it as type on a light surface, so accents that carry text
       take charcoal instead. #D8D3CA is the one derived value, a stronger
       hairline for input borders. */
    --page: #fcfaf9;
    --surface: #ffffff;
    --surface-2: #f7f5f0;
    --surface-3: #efece6;
    --line: #e2dfd8;
    --line-strong: #d8d3ca;
    --text: #1c1e21;
    --muted: #5e5e5e;

    --ink: #1c1e21;
    --ink-2: #24272c;
    --ink-line: rgba(252, 250, 249, .20);
    --on-ink: #fcfaf9;
    --on-ink-muted: rgba(252, 250, 249, .72);

    --brand: #1c1e21;
    --brand-600: #24272c;
    --brand-fill: #48e5c2;
    --brand-fill-600: #33d5b0;
    --brand-strong: #48e5c2;
    --brand-100: #eafbf6;
    --brand-tint: rgba(72, 229, 194, .18);
    --on-fill: #1c1e21;
    --signal: #48e5c2;
    --star: #e5a93c;
    --ok: #1c1e21;

    --r-s: 3px;
    --r: 6px;
    --r-l: 10px;

    --shadow-1: 0 1px 2px rgba(28, 30, 33, .06), 0 2px 8px rgba(28, 30, 33, .05);
    --shadow-2: 0 10px 28px rgba(28, 30, 33, .10), 0 2px 6px rgba(28, 30, 33, .06);
    --shadow-3: 0 22px 54px rgba(28, 30, 33, .16);

    --wrap: 1180px;
    --sans: "Public Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --display: "Space Grotesk", "Public Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

    /* Built-in easings are too weak for UI. */
    --ease: cubic-bezier(.23, 1, .32, 1);
    --ease-in-out: cubic-bezier(.77, 0, .175, 1);
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
    }
}

body {
    margin: 0;
    font-family: var(--sans);
    font-size: clamp(1rem, .96rem + .2vw, 1.06rem);
    line-height: 1.65;
    color: var(--text);
    background: var(--page);
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
}

img, svg, canvas, video { max-width: 100%; display: block; }
a { color: var(--brand); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--brand-600); }

h1, h2, h3, h4 {
    font-family: var(--display);
    line-height: 1.08; letter-spacing: -.028em; margin: 0 0 .5em;
    font-weight: 700; color: var(--text);
}
h1 { font-size: clamp(2.3rem, 1.3rem + 3.9vw, 4.1rem); letter-spacing: -.038em; }
h2 { font-size: clamp(1.75rem, 1.15rem + 2.5vw, 2.9rem); letter-spacing: -.034em; }
h3 { font-size: clamp(1.16rem, 1.04rem + .6vw, 1.42rem); font-weight: 600; letter-spacing: -.022em; }
p { margin: 0 0 1.05em; }

.wrap { width: min(100% - 2.5rem, var(--wrap)); margin-inline: auto; }
.narrow { width: min(100% - 2.5rem, 800px); margin-inline: auto; }

.skip {
    position: absolute; left: -9999px; top: 0; z-index: 999;
    background: var(--brand); color: #fff; padding: .8rem 1.2rem; border-radius: 0 0 var(--r) 0;
}
.skip:focus { left: 0; }

:focus-visible { outline: 3px solid var(--brand); outline-offset: 3px; border-radius: 4px; }

.staging {
    margin: 0; padding: .55rem 1rem; text-align: center;
    background: #b45309; color: #1a1206;
    font-size: .85rem; font-weight: 700; letter-spacing: .01em;
    position: relative; z-index: 130;
}

/* ---------------------------------------------------------------- progress */
.progress { position: fixed; inset: 0 0 auto 0; height: 2px; z-index: 120; pointer-events: none; }
.progress i {
    display: block; height: 100%; width: 0;
    background: var(--brand-fill);
    transition: width .12s linear;
}

/* ------------------------------------------------------------------ header */
.site-head {
    position: sticky; top: 0; z-index: 100;
    background: color-mix(in srgb, var(--surface) 84%, transparent);
    backdrop-filter: saturate(180%) blur(14px);
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    border-bottom: 1px solid transparent;
    transition: border-color .25s var(--ease), box-shadow .25s var(--ease);
}
.site-head.is-scrolled { border-bottom-color: var(--line); box-shadow: var(--shadow-1); }

.site-head__inner { display: flex; align-items: center; gap: 1rem; min-height: 68px; }
.site-head.is-scrolled .site-head__inner { min-height: 58px; transition: min-height .25s var(--ease); }

.brand { display: inline-flex; align-items: center; gap: .6rem; text-decoration: none; color: var(--text); flex: 0 0 auto; }
.brand__mark { color: var(--brand); display: grid; place-items: center; }
.brand__text { display: grid; line-height: 1.05; }
.brand__text strong { font-family: var(--display); font-size: 1.05rem; font-weight: 700; letter-spacing: -.03em; }
.brand__text em { font-style: normal; font-size: .72rem; letter-spacing: .17em; text-transform: uppercase; color: var(--muted); }

.nav { margin-left: auto; }
.nav ul { display: flex; gap: .1rem; list-style: none; margin: 0; padding: 0; }
.nav a {
    display: block; padding: .5rem .7rem; border-radius: var(--r-s); font-size: .92rem; font-weight: 600;
    color: var(--text); text-decoration: none; position: relative; white-space: nowrap;
}
.nav a::after {
    content: ""; position: absolute; left: .7rem; right: .7rem; bottom: .3rem; height: 2px;
    background: var(--brand); border-radius: 2px;
    transform: scaleX(0); transform-origin: left center;
    transition: transform .24s var(--ease);
}
.nav a.is-active::after { transform: scaleX(1); }
.nav a.is-active { color: var(--brand); }
@media (hover: hover) and (pointer: fine) {
    .nav a:hover::after { transform: scaleX(1); }
}

.head-actions { display: flex; align-items: center; gap: .6rem; }
.tel { white-space: nowrap; display: inline-flex; align-items: center; gap: .35rem; font-weight: 700; font-size: .92rem; text-decoration: none; color: var(--text); }
.tel:hover { color: var(--brand); }

.burger { display: none; width: 42px; height: 38px; border: 1px solid var(--line); background: var(--surface); border-radius: var(--r-s); cursor: pointer; padding: 0; }
.burger span { display: block; width: 18px; height: 2px; margin: 3px auto; background: var(--text); border-radius: 2px; transition: transform .25s var(--ease), opacity .18s; }
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }

@media (max-width: 1040px) {
    .burger { display: block; }
    .tel__num { display: none; }
    .nav {
        position: fixed; inset: 68px 0 auto 0; background: var(--surface); border-bottom: 1px solid var(--line);
        padding: .6rem 1.25rem 1.1rem; box-shadow: var(--shadow-2);
        clip-path: inset(0 0 100% 0); transition: clip-path .32s var(--ease); margin: 0;
    }
    .nav.is-open { clip-path: inset(0 0 0 0); }
    .nav ul { flex-direction: column; gap: .1rem; }
    .nav a { padding: .72rem .4rem; font-size: 1.02rem; border-bottom: 1px solid var(--line); border-radius: 0; }
    .nav a::after { display: none; }
}

/* ------------------------------------------------------------------ crumbs */
.crumbs { padding: .9rem 0 0; font-size: .84rem; color: var(--muted); }
.crumbs ol { display: flex; flex-wrap: wrap; gap: .3rem .55rem; list-style: none; margin: 0; padding: 0; }
.crumbs li + li::before { content: "›"; margin-right: .55rem; color: var(--line-strong); }
.crumbs a { color: var(--muted); text-decoration: none; }
.crumbs a:hover { color: var(--brand); text-decoration: underline; }

/* ----------------------------------------------------------------- buttons */
.btn {
    font-family: var(--display);
    display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
    padding: .8rem 1.4rem; border-radius: 999px; border: 1px solid transparent;
    background: var(--brand-fill); color: var(--on-fill); font-weight: 700; font-size: .95rem;
    text-decoration: none; cursor: pointer; white-space: nowrap;
    transition: transform .16s var(--ease), background .2s var(--ease), box-shadow .2s var(--ease);
    box-shadow: 0 4px 14px rgba(28, 30, 33, .16);
}
.btn:hover { color: var(--on-fill); }
@media (hover: hover) and (pointer: fine) {
    .btn:hover { background: var(--brand-fill-600); box-shadow: 0 6px 18px rgba(28, 30, 33, .20); }
}
.btn:active { transform: scale(.97); }
.btn--lg { padding: .98rem 1.75rem; font-size: 1.02rem; }
.btn--sm { padding: .55rem 1.05rem; font-size: .88rem; box-shadow: none; }
.btn--ghost { background: transparent; border-color: var(--line-strong); color: var(--text); box-shadow: none; }
.btn--outline { background: transparent; border-color: var(--line-strong); color: var(--text); box-shadow: none; }
@media (hover: hover) and (pointer: fine) {
    .btn--ghost:hover { background: var(--brand-tint); border-color: var(--brand); color: var(--brand-600); box-shadow: none; }
    .btn--outline:hover { border-color: var(--brand); color: var(--brand-600); background: var(--brand-tint); box-shadow: none; }
}
/* On the blue band both buttons have to invert. A blue fill on a blue
   surface is not a button, and a ghost without a stroke is not either. */
.on-ink .btn { background: var(--signal); color: var(--on-fill); box-shadow: 0 6px 18px rgba(0, 0, 0, .30); }
.on-ink .btn--ghost { background: transparent; border-color: rgba(255, 255, 255, .55); color: #fff; box-shadow: none; }
@media (hover: hover) and (pointer: fine) {
    .on-ink .btn:hover { background: #fff; color: var(--on-fill); box-shadow: 0 8px 22px rgba(0, 0, 0, .34); }
    .on-ink .btn--ghost:hover { background: rgba(255, 255, 255, .12); border-color: #fff; color: #fff; box-shadow: none; }
}

/* -------------------------------------------------------------------- hero */
.hero {
    position: relative; isolation: isolate; overflow: hidden;
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    padding: clamp(2.2rem, 4vw, 3.4rem) 0 clamp(3.4rem, 6vw, 5rem);
}
/* One restrained warm wash behind the media panel. No canvas, no drifting
   particles: motion behind a headline reads as marketing, and this page is
   asking to be believed rather than admired. */
/* The wash behind the hero is gone: flat colour only. */

.hero__inner {
    display: grid; gap: clamp(1.8rem, 4vw, 3.2rem);
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
    align-items: center;
}
.hero__inner--single { grid-template-columns: minmax(0, 1fr); max-width: 60ch; }
@media (max-width: 960px) { .hero__inner { grid-template-columns: 1fr; } }

.kicker {
    font-family: var(--display);
    display: inline-flex; align-items: center; gap: .6rem; margin-bottom: 1.3rem;
    font-size: .74rem; font-weight: 600; letter-spacing: .18em; text-transform: uppercase;
    color: var(--muted);
}
/* The live dot from the original design, in mint rather than green. */
.kicker::before {
    content: ""; width: 8px; height: 8px; border-radius: 50%;
    background: var(--brand-fill); flex: 0 0 auto;
    box-shadow: 0 0 0 3px rgba(72, 229, 194, .35);
    animation: pulse 2.6s infinite;
}
@keyframes pulse {
    0%, 100% { box-shadow: 0 0 0 3px rgba(72, 229, 194, .40); }
    50%      { box-shadow: 0 0 0 9px rgba(72, 229, 194, 0); }
}

.hero h1 { margin-bottom: .45em; max-width: 17ch; }
/* The editor marks an emphasis span with *asterisks*. A flat brand colour
   survives a line break and a low-quality screen; a gradient fill does not. */
/* The marked phrase sits on a solid mint block. Mint cannot carry text on the
   off-white, but charcoal on mint is 8:1, so inverting it is the honest way to
   use the brightest colour in the palette at headline size. */
.hero h1 .grad {
    color: var(--text);
    background: var(--brand-fill);
    padding: .02em .14em;
    box-decoration-break: clone; -webkit-box-decoration-break: clone;
}
.hero__lead { font-size: clamp(1.06rem, 1rem + .45vw, 1.2rem); color: var(--muted); max-width: 42ch; }
.hero__actions { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 1.7rem; }

/* The media panel and the price card share one column and overlap slightly,
   so the two read as one object instead of two stacked boxes. */
.hero__col { display: block; min-width: 0; }
.hero__media {
    position: relative; border-radius: var(--r-l); overflow: hidden;
    background: var(--surface-2); aspect-ratio: 16 / 10;
    box-shadow: var(--shadow-3); border: 1px solid var(--line);
}
.hero__media video, .hero__media img { width: 100%; height: 100%; object-fit: cover; }
/* The still is only for the reduced-motion case; normally the clip's own
   poster attribute covers the load. */
.hero__poster { display: none; position: absolute; inset: 0; }
/* A warm scrim keeps the frame in the palette and stops a bright frame from
   fighting the headline next to it. */
/* No scrim over the clip: the design keeps the frame clean. */
.hero-card {
    will-change: transform;
    position: relative; z-index: 2; margin: -2.6rem 1.4rem 0 auto; width: calc(100% - 2.8rem);
    background: var(--surface); border: 1px solid var(--line);
    border-radius: var(--r); padding: 1.25rem 1.35rem;
    box-shadow: var(--shadow-2);
}
@media (max-width: 960px) {
    .hero-card { margin: -2.2rem auto 0; width: calc(100% - 2rem); }
}
/* On a phone the clip sits under the headline and the two buttons, so it has
   to be short enough to reach the first screen. */
@media (max-width: 620px) {
    .hero { padding-top: clamp(1.4rem, 3vw, 2rem); }
    .hero__media { aspect-ratio: 16 / 9; }
    .hero__inner { gap: 1.4rem; }
    .hero__actions { margin-top: 1.3rem; }
}
/* Without a clip above it the card has nothing to overlap. */
.hero-card--flat { margin: 0; width: 100%; box-shadow: var(--shadow-1); }
.hero-card h2 { font-size: .95rem; font-weight: 800; letter-spacing: -.01em; margin-bottom: .75rem; }
.hero-card ul { list-style: none; margin: 0; padding: 0; display: grid; }
.hero-card li {
    display: flex; justify-content: space-between; gap: 1rem;
    padding: .5rem 0; border-bottom: 1px solid var(--line);
    font-size: .92rem; color: var(--muted);
}
.hero-card li:last-child { border-bottom: 0; }
.hero-card b { font-family: var(--display); color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; }
.hero-card__foot { margin: .8rem 0 0; font-size: .78rem; color: var(--muted); }

/* ------------------------------------------------------------- terms strip */
/* The row under the hero carries the claims a wavering visitor is actually
   weighing: local, fixed price, both platforms, when he answers the phone.
   Pulled up over the hero edge so the page has a seam instead of a stack. */
.terms {
    display: flex; flex-wrap: wrap;
    margin: clamp(-3.2rem, -4vw, -2.4rem) 0 clamp(1.6rem, 3.5vw, 2.6rem);
    padding: 0; list-style: none; position: relative; z-index: 3;
    background: var(--surface); border: 1px solid var(--line);
    border-radius: var(--r); box-shadow: var(--shadow-2); overflow: hidden;
}
.terms li {
    flex: 1 1 0; min-width: 190px;
    display: flex; align-items: center; gap: .55rem;
    padding: 1.15rem 1.35rem; font-size: .88rem; font-weight: 600; line-height: 1.45;
    border-left: 1px solid var(--line);
}
.terms li:first-child { border-left: 0; }
.terms li::before {
    content: ""; flex: 0 0 auto; width: 6px; height: 6px; border-radius: 50%;
    background: var(--brand-fill);
}
@media (max-width: 900px) {
    .terms li { flex-basis: 50%; min-width: 0; }
    .terms li:nth-child(odd) { border-left: 0; }
    .terms li:nth-child(n + 3) { border-top: 1px solid var(--line); }
}
@media (max-width: 560px) {
    .terms li { flex-basis: 100%; border-left: 0; border-top: 1px solid var(--line); }
    .terms li:first-child { border-top: 0; }
}
/* When the phone is answered belongs on the plate, but on its own line: it is
   a fact, not a claim. */
/* The opening windows are a list, one bullet each. */
.terms .terms__hours {
    flex: 1 1 100%; border-left: 0; border-top: 1px solid var(--line);
    background: var(--surface-2); font-weight: 600; color: var(--text); font-size: .88rem;
    padding-block: .8rem;
}
.terms .terms__hours + .terms__hours { border-top: 1px solid rgba(28, 30, 33, .10); }
.terms .terms__hours::before { background: var(--muted); }

/* Loose pills, still used on the inner pages. */
.chips { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0 0 1rem; padding: 0; list-style: none; }
.chips li {
    display: inline-flex; align-items: center; gap: .45rem; padding: .38rem .8rem; border-radius: 999px;
    background: var(--surface); border: 1px solid var(--line); font-size: .84rem; color: var(--text);
}
.chips li::before { content: "✓"; color: var(--ok); font-weight: 800; }

/* ------------------------------------------------------------ answer block */
/* The direct answer a search engine or a language model quotes. It earns the
   largest body type on the page, so it needs no label above it. */
.answer {
    margin: 0 0 2rem; padding: .2rem 0 .2rem 1.4rem;
    border-left: 3px solid var(--brand);
    max-width: 68ch;
}
.answer p { margin: 0; font-size: clamp(1.1rem, 1.02rem + .45vw, 1.28rem); line-height: 1.55; color: var(--text); }

/* ---------------------------------------------------------------- sections */
.section { padding: clamp(2.6rem, 5.5vw, 4.4rem) 0; }
.section--tight { padding: clamp(1.6rem, 3vw, 2.4rem) 0; }
.section--alt { background: var(--surface-2); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.section__head { max-width: 58ch; margin-bottom: clamp(1.6rem, 3vw, 2.4rem); }
.section__head p { color: var(--muted); font-size: 1.04rem; margin-bottom: 0; }
.section__head h2 { margin-bottom: .35em; }

.eyebrow {
    font-family: var(--display);
    display: inline-flex; align-items: center; gap: .6rem; margin-bottom: .8rem;
    font-size: .74rem; font-weight: 600; letter-spacing: .18em; text-transform: uppercase; color: var(--muted);
}
.eyebrow::before {
    content: ""; width: 1.6rem; height: 2px; background: var(--brand-fill); border-radius: 2px;
    transform-origin: left center;
}
/* It draws out as the heading arrives, as it did before the redesign. */
.js .reveal .eyebrow::before { transform: scaleX(0); transition: transform .6s var(--ease-out) .2s; }
.js .reveal.is-in .eyebrow::before { transform: scaleX(1); }

/* ------------------------------------------------------------------- cards */
.grid { display: grid; gap: clamp(1rem, 2vw, 1.4rem); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.grid--split { grid-template-columns: minmax(0, 1.65fr) minmax(280px, .95fr); }
@media (max-width: 900px) { .grid--split { grid-template-columns: minmax(0, 1fr); } }

.card {
    position: relative; display: flex; flex-direction: column; gap: .5rem;
    isolation: isolate;
    padding: 1.5rem; border-radius: var(--r); background: var(--surface);
    border: 1px solid var(--line); overflow: hidden;
    transition: transform .22s var(--ease), box-shadow .22s var(--ease), border-color .22s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
    .card:hover { transform: translateY(-2px); box-shadow: var(--shadow-2); border-color: var(--line-strong); }
}

/* The cursor glow from the original design: a soft mint light that follows the
   pointer across a card. The coordinates come from site.js. */
/* No cursor glow: the design keeps every surface flat. */
.card::before { display: none; }
@media (hover: hover) and (pointer: fine) {
    .card:hover::before { opacity: 1; }
}
.card h3 { margin-bottom: .1rem; }
.card h3 a { color: inherit; text-decoration: none; }
.card h3 a::after { content: ""; position: absolute; inset: 0; }
.card p { color: var(--muted); margin: 0; font-size: .96rem; }
.card__icon {
    width: 42px; height: 42px; border-radius: var(--r-s); display: grid; place-items: center; margin-bottom: .45rem;
    background: var(--brand-100); border: 1px solid color-mix(in srgb, var(--brand) 16%, transparent);
    color: var(--brand); flex: 0 0 auto;
    transition: transform .25s var(--ease);
}
.card__icon svg { width: 21px; height: 21px; display: block; }
.card__price { font-family: var(--display); margin-top: auto; padding-top: .9rem; font-weight: 800; color: var(--text); font-variant-numeric: tabular-nums; }
.card__price small { display: block; font-weight: 500; font-size: .78rem; color: var(--muted); }
.card__more { margin-top: .75rem; font-weight: 700; font-size: .91rem; color: var(--brand); }
.card__more::after { content: " →"; transition: margin .2s var(--ease); }
@media (hover: hover) and (pointer: fine) {
    .card:hover .card__more::after { margin-left: .25rem; }
    .card:hover .card__icon { transform: translateY(-2px); }
}

/* -------------------------------------------------------------------ic bento */
/* Six equal cards in two rows is the layout every template ships with. The
   first service gets the wide tile, the closing tile carries the link to the
   full list, and the cell count matches the item count exactly. */
.bento { display: grid; gap: clamp(.9rem, 1.8vw, 1.3rem); grid-template-columns: repeat(3, minmax(0, 1fr)); grid-auto-flow: row dense; }
@media (max-width: 980px) { .bento { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .bento { grid-template-columns: minmax(0, 1fr); } }

.bento > .card:first-child { grid-column: span 2; background: var(--surface-2); border-color: var(--surface-2); }
@media (max-width: 640px) { .bento > .card:first-child { grid-column: span 1; } }
.bento > .card:first-child h3 { font-size: clamp(1.3rem, 1.1rem + .8vw, 1.65rem); }
.bento > .card:first-child .card__icon { width: 50px; height: 50px; }
.bento > .card:first-child .card__icon svg { width: 25px; height: 25px; }

/* The closing tile: graphite, so the grid ends on a note instead of trailing
   off, and so the section is not six white boxes on a white page. */
.tile--all {
    grid-column: span 2; display: flex; flex-direction: column; justify-content: center; gap: .6rem;
    padding: 1.6rem; border-radius: var(--r); text-decoration: none;
    background: var(--ink);
    color: var(--on-ink); border: 1px solid transparent;
    transition: transform .22s var(--ease), background .22s var(--ease);
}
@media (max-width: 640px) { .tile--all { grid-column: span 1; } }
.tile--all strong { font-family: var(--display); display: block; font-size: 1.25rem; font-weight: 800; letter-spacing: -.02em; color: #fff; }
.tile--all span { color: var(--on-ink-muted); font-size: .95rem; max-width: 46ch; }
.tile--all em { font-style: normal; font-weight: 700; color: var(--signal); }
.tile--all em::after { content: "→"; margin-left: .35rem; transition: margin .2s var(--ease); display: inline-block; }
@media (hover: hover) and (pointer: fine) {
    .tile--all:hover { background: var(--ink-2); transform: translateY(-2px); color: var(--on-ink); }
    .tile--all:hover em::after { margin-left: .6rem; }
}
.tile--all:active { transform: scale(.995); }

/* ---------------------------------------------------------------- timeline */
/* Four boxed rows read as four unrelated notices. One rail with a connector
   reads as a sequence, which is what the section is actually describing. */
.timeline { counter-reset: step; list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.timeline li {
    counter-increment: step; position: relative;
    padding: 0 0 1.9rem 3.6rem;
}
.timeline li:last-child { padding-bottom: 0; }
.timeline li::before {
    content: counter(step); position: absolute; left: 0; top: -.15rem;
    width: 2.3rem; height: 2.3rem; border-radius: 50%; display: grid; place-items: center;
    background: var(--surface); color: var(--muted); border: 1px solid var(--line-strong);
    font-weight: 800; font-size: .92rem; font-variant-numeric: tabular-nums;
    transition: background .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
/* The connector stops short of the next number rather than running under it. */
.timeline li::after {
    content: ""; position: absolute; left: 1.15rem; top: 2.45rem; bottom: .45rem;
    width: 1px; background: var(--line);
}
.timeline li:last-child::after { display: none; }
.timeline h3 { margin: 0 0 .2rem; font-size: 1.08rem; }
.timeline p { margin: 0; color: var(--muted); font-size: .97rem; max-width: 62ch; }
.js .timeline li.is-reached::before { background: var(--brand-fill); border-color: var(--brand-fill); color: var(--on-fill); }

/* ----------------------------------------------------------------- figures */
/* The trust numbers, on graphite, with hairlines instead of four cards. */
.figures { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0; margin-top: clamp(1.4rem, 3vw, 2.2rem); }
@media (max-width: 860px) { .figures { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 460px) { .figures { grid-template-columns: minmax(0, 1fr); } }
.figure { padding: 1.2rem 1.5rem; border-left: 1px solid var(--line); }
.figure:first-child { border-left: 0; padding-left: 0; }
@media (max-width: 860px) {
    .figure:nth-child(odd) { border-left: 0; padding-left: 0; }
    .figure:nth-child(n + 3) { border-top: 1px solid var(--line); padding-top: 1.5rem; }
}
@media (max-width: 460px) {
    .figure { border-left: 0; padding-left: 0; }
    .figure + .figure { border-top: 1px solid var(--line); padding-top: 1.5rem; }
}
.figure b {
    font-family: var(--display);
    display: block; font-size: clamp(2.1rem, 1.4rem + 2.4vw, 3rem); font-weight: 800;
    letter-spacing: -.04em; color: var(--brand); font-variant-numeric: tabular-nums; line-height: 1.05;
}
.figure span { display: block; margin-top: .45rem; font-size: .92rem; color: var(--muted); max-width: 26ch; }

/* -------------------------------------------------------------------- bands */
.band {
    position: relative; isolation: isolate; overflow: hidden;
    background: var(--surface-2); padding: clamp(2.8rem, 5.5vw, 4.4rem) 0;
    border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
/* The closing call is the one saturated surface on the page: a real blue,
   bright rather than dark, so the page never drops into night halfway down. */
.band--ink {
    background: var(--ink);
    color: var(--on-ink); border-color: transparent;
}
.band--ink::before {
    content: ""; position: absolute; z-index: -1; pointer-events: none;
    width: 50vw; height: 50vw; max-width: 680px; max-height: 680px;
    top: -34%; left: -10%; border-radius: 50%;
    background: #ffffff; opacity: .16; filter: blur(110px);
}
.band--ink h2, .band--ink h3 { color: #fff; }
.band--ink p { color: var(--on-ink-muted); }
.band--ink a:not(.btn) { color: #fff; }

/* The figures sit on a light sky wash: still a distinct surface, still bright. */
.band--sky {
    background: var(--surface-2);
    border-color: var(--line);
}
.band--sky .figure b { color: var(--text); }
.band--sky .figure b::after {
    content: ""; display: block; width: 2.4rem; height: 7px; margin-top: .55rem;
    background: var(--brand-fill); border-radius: 4px;
}
.band--sky .eyebrow { color: var(--brand); }

/* The closing call. Left-aligned: a centred block of marketing copy is the
   one shape every visitor has learned to scroll past. */
.band__inner { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, .75fr); gap: clamp(1.4rem, 3vw, 2.6rem); align-items: end; }
@media (max-width: 860px) { .band__inner { grid-template-columns: 1fr; align-items: start; } }
.band__inner h2 { margin-bottom: .4em; max-width: 18ch; }
.band__inner > div > p { max-width: 52ch; margin-bottom: 0; }
.band__actions { display: flex; flex-wrap: wrap; gap: .75rem; }
.band__hours { margin: 1rem 0 0; font-size: .86rem; color: var(--on-ink-muted); }

/* ------------------------------------------------------------- the owner */
/* A named, reachable person is the strongest trust signal a one-man service
   has. The monogram is a deliberate placeholder: a real photograph belongs
   here, and inventing a stock face would undo the point of the block. */
.owner {
    display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 1.5rem; align-items: start;
    padding: clamp(1.4rem, 3vw, 2rem) 0;
    border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
@media (max-width: 560px) { .owner { grid-template-columns: 1fr; gap: 1rem; } }
.owner__face {
    flex: 0 0 auto; width: 96px; height: 96px; border-radius: 50%;
    display: grid; place-items: center; object-fit: cover;
    background: var(--brand-100); border: 1px solid color-mix(in srgb, var(--brand) 20%, transparent);
    color: var(--brand); font-size: 1.8rem; font-weight: 800; letter-spacing: .01em;
}
.owner__body p {
    margin: 0 0 .7rem; color: var(--text); font-size: clamp(1.04rem, 1rem + .35vw, 1.18rem);
    line-height: 1.55; max-width: 58ch;
}
.owner__name { display: block; font-weight: 800; color: var(--text); font-size: 1.05rem; margin-bottom: .1rem; letter-spacing: -.01em; }
.owner__role { display: block; font-size: .74rem; letter-spacing: .16em; text-transform: uppercase; color: var(--muted); margin-bottom: .9rem; }
.owner__links { display: flex; flex-wrap: wrap; gap: .5rem 1.3rem; font-size: .94rem; font-weight: 700; }

/* --------------------------------------------------------------- locations */
.places { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: clamp(1rem, 2vw, 1.4rem); }
.place {
    position: relative; padding: 1.5rem; border-radius: var(--r);
    background: var(--surface); border: 1px solid var(--line);
    transition: border-color .22s var(--ease), transform .22s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
    .place:hover { border-color: var(--line-strong); transform: translateY(-2px); }
}
.place h3 { margin-bottom: .3rem; }
.place h3 a { color: inherit; text-decoration: none; }
.place h3 a::after { content: ""; position: absolute; inset: 0; }
.place__addr { color: var(--text); font-weight: 600; margin: 0 0 .9rem; font-size: .98rem; }
.place__area { display: flex; flex-wrap: wrap; gap: .4rem; margin: 0 0 1rem; padding: 0; list-style: none; }
.place__area li { font-size: .82rem; color: var(--muted); background: var(--surface-2); border-radius: 999px; padding: .25rem .7rem; }
.place__more { font-weight: 700; font-size: .91rem; color: var(--brand); }
.place__more::after { content: " →"; }

/* --------------------------------------------------------------- price list */
.prices { display: grid; gap: .8rem; }
.price {
    display: grid; grid-template-columns: 1fr auto; gap: .3rem 1.5rem; align-items: start;
    padding: 1.3rem 1.4rem; border-radius: var(--r); background: var(--surface);
    border: 1px solid var(--line);
    transition: border-color .2s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
    .price:hover { border-color: var(--line-strong); }
}
.price__name { font-weight: 750; font-size: 1.06rem; }
.price__value { font-family: var(--display); font-size: 1.36rem; font-weight: 800; color: var(--brand); white-space: nowrap; font-variant-numeric: tabular-nums; }
.price__value small { display: block; text-align: right; font-size: .72rem; font-weight: 600; color: var(--muted); }
.price__desc { grid-column: 1 / -1; color: var(--muted); font-size: .95rem; margin: .35rem 0 0; }
.price__list { grid-column: 1 / -1; margin: .7rem 0 0; padding: 0; list-style: none; display: grid; gap: .3rem; }
.price__list li { position: relative; padding-left: 1.5rem; font-size: .93rem; color: var(--muted); }
.price__list li::before { content: "✓"; position: absolute; left: 0; color: var(--ok); font-weight: 800; }

.ratecard { width: 100%; border-collapse: collapse; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.ratecard caption { text-align: left; font-weight: 750; padding: 0 0 .7rem; }
.ratecard th, .ratecard td { padding: .85rem 1.1rem; text-align: left; border-bottom: 1px solid var(--line); font-size: .95rem; }
.ratecard th { background: var(--surface-2); font-weight: 700; }
.ratecard td:last-child { text-align: right; font-weight: 800; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ratecard tr:last-child td { border-bottom: 0; }
.table-scroll { overflow-x: auto; }

/* --------------------------------------------------------------------- faq */
/* Hairline rows, not a stack of bordered boxes: the questions are a list, and
   a list of twelve boxes is heavier than the content inside it. */
.faq { display: grid; gap: 0; border-top: 1px solid var(--line); }
.faq__item { border-bottom: 1px solid var(--line); }
.faq__q {
    width: 100%; display: flex; justify-content: space-between; align-items: center; gap: 1rem;
    padding: 1.15rem .2rem; background: none; border: 0; cursor: pointer; text-align: left;
    font: inherit; font-weight: 700; font-size: 1.04rem; color: var(--text);
    transition: color .2s var(--ease);
}
.faq__q:hover { color: var(--brand); }
.faq__q i { flex: 0 0 auto; width: 20px; height: 20px; position: relative; }
.faq__q i::before, .faq__q i::after {
    content: ""; position: absolute; inset: 50% 1px auto 1px; height: 2px; background: var(--brand); border-radius: 2px;
    transition: transform .22s var(--ease);
}
.faq__q i::after { transform: rotate(90deg); }
.faq__q[aria-expanded="true"] i::after { transform: rotate(0); }
.faq__a { padding: 0 .2rem; max-height: 0; overflow: hidden; transition: max-height .28s var(--ease); }
.faq__a p { margin: 0 0 1.15rem; color: var(--muted); max-width: 70ch; }
.faq__item.is-open .faq__a { padding-top: .1rem; }

/* ------------------------------------------------------------------ quotes */
/* Real references run to different lengths. Columns let them keep their own
   length instead of being padded into a row of equal boxes. */
.quotes { columns: 2; column-gap: clamp(1rem, 2vw, 1.5rem); }
@media (max-width: 760px) { .quotes { columns: 1; } }
.quote {
    break-inside: avoid; margin: 0 0 clamp(1rem, 2vw, 1.5rem);
    padding: 1.4rem 1.5rem; border-radius: var(--r);
    background: var(--surface); border: 1px solid var(--line);
}
.quote:first-child { border-left: 3px solid var(--brand); }
.quote__stars { color: var(--star); letter-spacing: .1em; font-size: .9rem; margin-bottom: .6rem; }
.quote blockquote { margin: 0 0 .9rem; font-size: 1.01rem; line-height: 1.6; color: var(--text); }
.quote figcaption { font-size: .88rem; color: var(--muted); }
.quote figcaption b { display: block; color: var(--text); font-size: .95rem; }

.reflist { columns: 2; column-gap: 2.2rem; list-style: none; margin: 0; padding: 0; }
@media (max-width: 640px) { .reflist { columns: 1; } }
.reflist li { break-inside: avoid; padding: .42rem 0 .42rem 1.4rem; position: relative; font-size: .95rem; }
.reflist li::before { content: "·"; position: absolute; left: .3rem; color: var(--brand); font-weight: 800; }
.reflist b { font-weight: 700; }

/* ------------------------------------------------------------------- prose */
.prose { max-width: 70ch; }
.prose h2 { margin-top: 2em; }
.prose h3 { margin-top: 1.7em; }
.prose ul, .prose ol { padding-left: 1.3em; }
.prose li { margin-bottom: .4em; }
.prose blockquote { margin: 1.6em 0; padding: .2rem 0 .2rem 1.3rem; border-left: 3px solid var(--brand); color: var(--muted); font-style: italic; }
.prose table { width: 100%; border-collapse: collapse; margin: 1.5em 0; }
.prose th, .prose td { border: 1px solid var(--line); padding: .6rem .8rem; text-align: left; }
.prose th { background: var(--surface-2); }
.prose--legal { max-width: 78ch; font-size: .96rem; }
.prose--legal h2 { font-size: 1.22rem; margin-top: 2em; }
.prose--legal h3 { font-size: 1.05rem; }

/* -------------------------------------------------------------------- team */
/* Real faces, one crop, one size. The roster wraps where it wants to; it is a
   list of people, not a grid that has to come out even. */
.team {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: clamp(1rem, 2.5vw, 1.6rem); margin: 2rem 0 2.4rem; padding: 0;
}
.team__member { margin: 0; }
.team__member img {
    width: 100%; aspect-ratio: 4 / 5; object-fit: cover;
    border-radius: var(--r); border: 1px solid var(--line); background: var(--surface-2);
}
.team__member figcaption { display: grid; gap: .15rem; margin-top: .7rem; }
.team__member b { font-size: 1.02rem; letter-spacing: -.01em; color: var(--text); }
.team__member span { font-size: .88rem; color: var(--muted); line-height: 1.45; }
.team__member a { font-size: .88rem; font-weight: 700; text-decoration: none; }

/* The three counts, as figures rather than three more boxes. */
.tally {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 1rem 2rem; margin: 1.8rem 0; padding: 1.3rem 0;
    list-style: none; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.tally li { margin: 0; }
.tally b {
    font-family: var(--display);
    display: block; font-size: clamp(1.7rem, 1.2rem + 1.6vw, 2.3rem); font-weight: 800;
    letter-spacing: -.035em; line-height: 1.1; color: var(--text);
}
.tally span { display: block; margin-top: .2rem; font-size: .9rem; color: var(--muted); }

/* Twenty-one entries want two columns and a date rail, not twenty-one bullets. */
.training {
    columns: 2; column-gap: 2.4rem; list-style: none; margin: 1.4rem 0 0; padding: 0;
}
@media (max-width: 640px) { .training { columns: 1; } }
.training li {
    break-inside: avoid; display: grid; grid-template-columns: 4.6rem 1fr; gap: .6rem;
    padding: .38rem 0; font-size: .94rem; margin: 0;
}
.training__date { color: var(--muted); font-variant-numeric: tabular-nums; font-size: .88rem; }

/* ----------------------------------------------------------------- contact */
.contact-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: clamp(1.2rem, 3vw, 2.4rem); align-items: start; }
.nap { display: grid; gap: 1rem; padding: 1.6rem; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); }
.nap dl { margin: 0; display: grid; gap: .8rem; }
.nap dt { font-size: .74rem; letter-spacing: .15em; text-transform: uppercase; color: var(--muted); font-weight: 800; }
.nap dd { margin: .15rem 0 0; font-size: 1.04rem; font-weight: 600; }
.nap dd a { text-decoration: none; }

.form { display: grid; gap: 1rem; padding: 1.6rem; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); }
.form label { display: grid; gap: .35rem; font-size: .88rem; font-weight: 700; color: var(--text); }
.form input, .form textarea, .form select {
    font: inherit; padding: .72rem .9rem; border-radius: var(--r-s); border: 1px solid var(--line-strong);
    background: var(--surface); color: var(--text); width: 100%;
    transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.form input::placeholder, .form textarea::placeholder { color: var(--muted); opacity: 1; }
.form input:focus, .form textarea:focus { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-100); outline: none; }
.form textarea { min-height: 130px; resize: vertical; }
.form .hint { font-size: .8rem; color: var(--muted); font-weight: 500; }
.form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
@media (max-width: 560px) { .form__row { grid-template-columns: 1fr; } }
.form__check { display: flex; gap: .6rem; align-items: flex-start; font-size: .88rem; font-weight: 400; }
.form__check input { width: auto; margin-top: .25rem; }

/* ------------------------------------------------------------------ footer */
/* Light, like the rest of the page. The blue band above it is contrast
   enough; a dark footer under a bright band reads as two websites. */
.site-foot { background: var(--surface-2); color: var(--muted); padding: clamp(2.4rem, 5vw, 3.6rem) 0 1.5rem; border-top: 1px solid var(--line); }
.site-foot__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 2rem; }
.site-foot h3 { color: var(--text); font-size: .74rem; letter-spacing: .16em; text-transform: uppercase; margin-bottom: .9rem; }
.site-foot p { margin: 0 0 .4rem; font-size: .92rem; }
.site-foot a { color: var(--text); text-decoration: none; }
.site-foot a:hover { color: var(--brand); text-decoration: underline; }
.foot-brand { color: var(--text); font-weight: 800; font-size: 1.06rem; letter-spacing: -.02em; }
.foot-owner { color: var(--muted); font-size: .86rem; }
.foot-links { list-style: none; margin: 0; padding: 0; display: grid; gap: .4rem; font-size: .92rem; }
.site-foot__bottom {
    display: flex; flex-wrap: wrap; justify-content: space-between; gap: .6rem;
    margin-top: 2.4rem; padding-top: 1.3rem; border-top: 1px solid var(--line);
    font-size: .83rem; color: var(--muted);
}
.site-foot__bottom p { margin: 0; }

/* ------------------------------------------------------------ mobile call */
.callbar {
    position: fixed; left: 50%; bottom: 1rem; transform: translate(-50%, 150%); z-index: 90;
    display: none; align-items: center; gap: .5rem;
    padding: .85rem 1.5rem; border-radius: 999px; background: var(--brand-fill); color: var(--on-fill);
    font-weight: 750; text-decoration: none; box-shadow: 0 12px 30px rgba(28, 30, 33, .26);
    transition: transform .35s var(--ease);
}
.callbar.is-in { transform: translate(-50%, 0); }
.callbar:active { transform: translate(-50%, 0) scale(.97); }
@media (max-width: 760px) { .callbar { display: inline-flex; } }

/* ============================================================== motion =====
   Louder than the first pass, on purpose. Every effect still answers the same
   question: what does this animation tell the visitor?
     - hero words rise per word          -> the page has arrived, read here first
     - section headings wipe open        -> a new topic begins
     - cards lift and settle in sequence -> these are separate, comparable items
     - the process pins and stacks       -> these steps happen in order
     - figures draw their rule           -> this number is the point
   Initial hidden states are gated on .js, set inline in <head>, so a visitor
   with scripting off gets a finished page rather than an invisible one.
   Everything below collapses under prefers-reduced-motion, at the end of file.
   ========================================================================= */

:root {
    --ease-out: cubic-bezier(.16, 1, .3, 1);
    --ease-spring: cubic-bezier(.34, 1.4, .5, 1);
}

/* ---- groups that arrive in sequence ---- */
.js .reveal { opacity: 0; transform: translateY(38px); transition: opacity .6s var(--ease-out), transform .7s var(--ease-out); }
.js .reveal.is-in { opacity: 1; transform: none; }
.reveal[data-delay="1"] { transition-delay: .09s; }
.reveal[data-delay="2"] { transition-delay: .18s; }
.reveal[data-delay="3"] { transition-delay: .27s; }
.reveal[data-delay="4"] { transition-delay: .36s; }
.reveal[data-delay="5"] { transition-delay: .45s; }

/* Cards do not just fade: they rise, un-tilt and settle with a little
   overshoot, which is what makes a grid read as a deck being dealt. */
.js .anim-item {
    opacity: 0;
    transform: translateY(46px) scale(.94) rotate(-1.2deg);
    transition: opacity .5s var(--ease-out), transform .78s var(--ease-spring),
                border-color .22s var(--ease-out), box-shadow .22s var(--ease-out);
}
.js .anim-item.is-in { opacity: 1; transform: none; }
@media (hover: hover) and (pointer: fine) {
    .js .card.anim-item.is-in:hover { transform: translateY(-4px); }
}

/* ---- section headings wipe open from the baseline up ---- */
.js .reveal h2 { clip-path: inset(0 0 105% 0); transition: clip-path .85s var(--ease-out) .05s; }
.js .reveal.is-in h2 { clip-path: inset(-20% -20% -20% -20%); }

/* ---- hero: word by word, above the fold, on load ---- */
.hero h1 .w { display: inline-block; white-space: pre; }
@keyframes wordUp {
    from { opacity: 0; transform: translateY(.85em) rotate(4deg); }
    to   { opacity: 1; transform: none; }
}
@keyframes heroRise {
    from { opacity: 0; transform: translateY(26px); }
    to   { opacity: 1; transform: none; }
}
@keyframes heroMedia {
    from { opacity: 0; transform: translateY(40px) scale(.93); clip-path: inset(0 0 100% 0); }
    to   { opacity: 1; transform: none; clip-path: inset(0 0 0 0); }
}
/* A long delay rather than a bare opacity:0, so a script that never runs costs
   a late hero instead of a permanently invisible one. */
.js .hero .reveal > * { animation: heroRise .7s var(--ease-out) 6s backwards; }
.js .hero .hero__col { animation: heroMedia .9s var(--ease-out) 6s backwards; }
.js .hero.is-in .reveal > * { animation: heroRise .7s var(--ease-out) backwards; }
.js .hero.is-in .reveal > *:nth-child(1) { animation-delay: .05s; }
.js .hero.is-in .reveal > *:nth-child(2) { animation-delay: 0s; }
.js .hero.is-in .reveal > *:nth-child(3) { animation-delay: .42s; }
.js .hero.is-in .reveal > *:nth-child(4) { animation-delay: .52s; }
.js .hero.is-in h1 .w { animation: wordUp .72s var(--ease-spring) backwards; animation-delay: calc(.08s + var(--i) * .055s); }
.js .hero.is-in .hero__col { animation: heroMedia .9s var(--ease-out) .25s backwards; }

/* The highlighter behind the marked words draws itself after the line lands. */
.js .hero h1 .grad { clip-path: inset(0 100% 0 0); transition: clip-path .75s var(--ease-out) .7s; }
.js .hero.is-in h1 .grad { clip-path: inset(0 0 0 0); }

/* ---- the clip drifts while you scroll past it ---- */
@supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
        .hero__media video, .hero__media img { animation: mediaDrift linear both; animation-timeline: view(); animation-range: entry 0% exit 100%; }
        @keyframes mediaDrift { from { transform: scale(1.12) translateY(-2.5%); } to { transform: scale(1.12) translateY(2.5%); } }
    }
}

/* ---- the process pins and stacks, because the steps happen in order ---- */
@media (min-width: 861px) {
    .timeline { --pin: 96px; }
    .js .timeline li {
        position: sticky; top: var(--pin);
        background: var(--page);
        min-height: 26vh;
        padding-block: 1.1rem 1.9rem;
        transition: opacity .4s var(--ease-out), transform .4s var(--ease-out);
    }
    .js .timeline li::after { display: none; }
    .js .timeline li.is-passed { opacity: .32; transform: scale(.97); }
}

/* ---- figures draw their rule when the number arrives ---- */
.band--sky .figure b::after { transform: scaleX(0); transform-origin: left center; transition: transform .7s var(--ease-out) .15s; }
.js .figure.is-in b::after, .js .anim-item.is-in b::after { transform: scaleX(1); }

/* ---- one marquee, and only one: the coverage strip ---- */
.ticker {
    overflow: hidden; border: 1px solid var(--ink); border-radius: var(--r);
    background: var(--ink); padding: 1rem 0;
    margin-bottom: clamp(1.6rem, 3.5vw, 2.6rem);
}
.ticker__track { display: flex; gap: 2.6rem; width: max-content; animation: tick 38s linear infinite; }
.ticker__track > span { font-family: var(--display); display: inline-flex; align-items: center; gap: 2.6rem; font-weight: 500; letter-spacing: -.02em; font-size: clamp(1rem, .9rem + .5vw, 1.3rem); color: var(--on-ink); white-space: nowrap; }
.ticker__track > span::after { content: ""; width: 9px; height: 9px; border-radius: 50%; background: var(--brand-fill); }
.ticker:hover .ticker__track { animation-play-state: paused; }
@keyframes tick { from { transform: translateX(0); } to { transform: translateX(-50%); } }


/* ---- a long list collapses to six, with everything still in the markup ---- */
.js .is-collapsed .is-extra { display: none; }
.more-wrap { margin: clamp(1.4rem, 3vw, 2.2rem) 0 0; }
/* The rest arrive in sequence rather than appearing all at once. */
.js .is-expanded .is-extra { animation: extraIn .5s var(--ease-out) backwards; }
.js .is-expanded .is-extra:nth-of-type(8) { animation-delay: .05s; }
.js .is-expanded .is-extra:nth-of-type(9) { animation-delay: .10s; }
.js .is-expanded .is-extra:nth-of-type(10) { animation-delay: .15s; }
.js .is-expanded .is-extra:nth-of-type(11) { animation-delay: .20s; }
.js .is-expanded .is-extra:nth-of-type(12) { animation-delay: .25s; }
@keyframes extraIn {
    from { opacity: 0; transform: translateY(26px) scale(.97); }
    to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
    .js .is-expanded .is-extra { animation: none; }
}

/* ---- service icons draw themselves on ---- */
.js .anim-item .card__icon svg > * { transition: stroke-dashoffset .9s var(--ease-out) .1s; }
.js .anim-item.is-in .card__icon svg > * { stroke-dashoffset: 0 !important; }
.card__icon { transition: transform .3s var(--ease-spring), background .3s var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
    .card:hover .card__icon { transform: translateY(-3px) rotate(-6deg) scale(1.06); background: var(--brand-fill); }
}

/* ---- stars land one after another ---- */
.quote__stars i { font-style: normal; display: inline-block; }
.js .quote__stars i {
    opacity: 0; transform: scale(.4) rotate(-20deg);
    transition: opacity .3s var(--ease-out), transform .45s var(--ease-spring);
}
.js .quote__stars.is-in i { opacity: 1; transform: none; }


/* ---- the owner portrait settles in (was the monogram) ---- */
@keyframes settle {
    from { opacity: 0; transform: scale(.82); }
    to   { opacity: 1; transform: none; }
}
.js .reveal.is-in .owner__face { animation: settle .6s var(--ease-spring) .12s backwards; }

/* ---- the warm wash behind the hero scales in on load ---- */

/* ---- buttons acknowledge the press, the call bar breathes once on arrival ---- */
.btn:active { transform: scale(.96); }
.callbar:active { transform: translate(-50%, 0) scale(.96); }

/* ---- the answer fades in behind the accordion opening ---- */
.faq__a p { opacity: 0; transition: opacity .25s var(--ease-out) .1s; }
.faq__item.is-open .faq__a p { opacity: 1; }

/* A visitor who asked for less motion gets the finished page: no drift, no
   pinning, no marquee, no half-drawn icons. */
@media (prefers-reduced-motion: reduce) {
    .js .reveal, .js .anim-item, .js .hero .reveal > *, .js .hero .hero__col { opacity: 1; transform: none; }
    .js .reveal h2, .js .reveal.is-in h2 { clip-path: none; }
    .js .hero h1 .w { animation: none; opacity: 1; transform: none; }
    .js .hero h1 .grad, .js .hero.is-in h1 .grad { background-size: 100% 100%; }
    .card__icon svg > * { stroke-dasharray: none !important; stroke-dashoffset: 0 !important; }
    .js .quote__stars i { opacity: 1; transform: none; }
    .js .timeline li { position: static; opacity: 1; transform: none; }
    .js .timeline li::before { background: var(--brand-fill); border-color: var(--brand-fill); color: var(--on-fill); }
    .band--sky .figure b::after { transform: scaleX(1); }
    .ticker__track { animation: none; flex-wrap: wrap; }
    .faq__a p { opacity: 1; }
    .kicker::before { animation: none; box-shadow: 0 0 0 3px rgba(72, 229, 194, .40); }
    .js .reveal .eyebrow::before, .js .reveal.is-in .eyebrow::before { transform: none; }
    .js .reveal.is-in .owner__face { animation: none; }
    .card::before { display: none; }
    .hero__media video { display: none; }
    .hero__media img.hero__poster { display: block; }
}
